Compare commits
218 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
66692f90e3 | ||
|
|
a964431c21 | ||
|
|
496a8a4f7c | ||
|
|
24056dc98b | ||
|
|
6772c9d2b6 | ||
|
|
e3dbd79543 | ||
|
|
d9c48e70a9 | ||
|
|
51bb311565 | ||
|
|
f4e30664e6 | ||
|
|
44d523518a | ||
|
|
8c39392eaa | ||
|
|
884410501e | ||
|
|
a87d7a1296 | ||
|
|
f0152790cf | ||
|
|
8452c0869d | ||
|
|
20e748205e | ||
|
|
649d45a2d4 | ||
|
|
0ae861d7d7 | ||
|
|
511481e8d9 | ||
|
|
1676e70dfe | ||
|
|
46b5fe5acd | ||
|
|
089f5403a7 | ||
|
|
1597e33549 | ||
|
|
121c6b4835 | ||
|
|
a764eb5dc7 | ||
|
|
d22bdb5095 | ||
|
|
a2aadb78a9 | ||
|
|
71adb37fa8 | ||
|
|
6591f8a592 | ||
|
|
3724a38ab4 | ||
|
|
54e6c26def | ||
|
|
0907d5d69e | ||
|
|
53d3f46add | ||
|
|
d657b76dba | ||
|
|
253e2ed699 | ||
|
|
1121919b57 | ||
|
|
61ce884336 | ||
|
|
71fdc24f5c | ||
|
|
aa51b83fdc | ||
|
|
b321c0a932 | ||
|
|
3f901d313b | ||
|
|
67cfe34e67 | ||
|
|
643cc7a0ee | ||
|
|
b3cb99036c | ||
|
|
9602227eb6 | ||
|
|
5e103f2b2e | ||
|
|
d49d44923d | ||
|
|
cbe0841bc9 | ||
|
|
596af3f600 | ||
|
|
8f0d6d6b5c | ||
|
|
a08360e3cd | ||
|
|
06f639b8f3 | ||
|
|
ba3dfe4121 | ||
|
|
67cfac0cf1 | ||
|
|
8ad8bd6282 | ||
|
|
045a44b1af | ||
|
|
d321d23afe | ||
|
|
e3f60ce06f | ||
|
|
4b96a78039 | ||
|
|
19a5e606b3 | ||
|
|
a18f4964cf | ||
|
|
f5c310d9d4 | ||
|
|
a6c93ce875 | ||
|
|
1b8f91a0db | ||
|
|
7371c7662a | ||
|
|
f3a4860635 | ||
|
|
43c303e27a | ||
|
|
e51be5f4a7 | ||
|
|
59f683066a | ||
|
|
b19e564317 | ||
|
|
e881f35fbb | ||
|
|
59a841d69c | ||
|
|
e7439efc74 | ||
|
|
0054afd39b | ||
|
|
7f699fca9a | ||
|
|
e5e951d92c | ||
|
|
5a653ef96f | ||
|
|
165f193f78 | ||
|
|
6eecbc95e4 | ||
|
|
a9f4d7a29c | ||
|
|
c54e0953d0 | ||
|
|
b575bf2524 | ||
|
|
30f59370d3 | ||
|
|
73491cceed | ||
|
|
28c7bb99bf | ||
|
|
551727cd19 | ||
|
|
bde26a8282 | ||
|
|
11c4a2cfd0 | ||
|
|
93b930b937 | ||
|
|
b53b871669 | ||
|
|
0a29842caf | ||
|
|
49fbe0ddb4 | ||
|
|
46fea74726 | ||
|
|
69b551c516 | ||
|
|
fa0621b486 | ||
|
|
84a1a0a729 | ||
|
|
b891291135 | ||
|
|
d8d6e8a304 | ||
|
|
e3c1466047 | ||
|
|
df30b1c832 | ||
|
|
3d3e0ea4f3 | ||
|
|
c7a457f9ee | ||
|
|
31bf25d05e | ||
|
|
eecaa3d9dd | ||
|
|
e38e8ae987 | ||
|
|
6dbe25360e | ||
|
|
6483470ec5 | ||
|
|
83fad75e22 | ||
|
|
7cd44c1a81 | ||
|
|
f8b6bc8d11 | ||
|
|
0020afaf67 | ||
|
|
b8b4517211 | ||
|
|
824d7190c2 | ||
|
|
30d64444a0 | ||
|
|
9904700dfd | ||
|
|
49dbae65c9 | ||
|
|
b056c243e4 | ||
|
|
c00158b238 | ||
|
|
794419852b | ||
|
|
fbafd22124 | ||
|
|
b9cd66d510 | ||
|
|
b310efc50f | ||
|
|
0fdf883cbd | ||
|
|
1382dc976c | ||
|
|
54e4dcf454 | ||
|
|
f6b1344722 | ||
|
|
5ffd59e7b8 | ||
|
|
0889b5aef1 | ||
|
|
59ca92b10b | ||
|
|
956f337046 | ||
|
|
a6a6bf007a | ||
|
|
2e9890bbe6 | ||
|
|
f2427a7320 | ||
|
|
2a6dbd068e | ||
|
|
d092977f4a | ||
|
|
e3f229225c | ||
|
|
ee9d46c825 | ||
|
|
dbd8c400ce | ||
|
|
29a740ec8c | ||
|
|
c2d3afdeee | ||
|
|
9155c9ee37 | ||
|
|
0d1d437bd3 | ||
|
|
b15f20520f | ||
|
|
172e2f4e76 | ||
|
|
23cd1b1954 | ||
|
|
cade14c58c | ||
|
|
1e222d52e6 | ||
|
|
f9ae9afaac | ||
|
|
09bbfc1d56 | ||
|
|
79511ecce2 | ||
|
|
2fe75a62be | ||
|
|
da414fd509 | ||
|
|
f2891e7738 | ||
|
|
fbefa8273b | ||
|
|
ceccfe02d0 | ||
|
|
129de26032 | ||
|
|
43a6fa1d01 | ||
|
|
cc8246206d | ||
|
|
551696bb45 | ||
|
|
ded16d3529 | ||
|
|
2e6dce434f | ||
|
|
9888f95068 | ||
|
|
8bbb88ea4e | ||
|
|
69d83e1548 | ||
|
|
d3e7a52933 | ||
|
|
aa695e92f7 | ||
|
|
0ddd1ce0b7 | ||
|
|
cc18ab12f8 | ||
|
|
2c3f6aaa87 | ||
|
|
5dedacca3c | ||
|
|
ad2f0a1290 | ||
|
|
bd3b9f79c2 | ||
|
|
ed148eba32 | ||
|
|
06f41bb017 | ||
|
|
a27d33cb63 | ||
|
|
22c325aa5a | ||
|
|
ac2fcbe224 | ||
|
|
63b6b9cdce | ||
|
|
de55110247 | ||
|
|
b9d22aa821 | ||
|
|
de927adf27 | ||
|
|
79395bc7db | ||
|
|
c81f37cf82 | ||
|
|
25b4160434 | ||
|
|
32c464ad1f | ||
|
|
d5aceb6d95 | ||
|
|
81f7e9b462 | ||
|
|
8383bde768 | ||
|
|
d114713694 | ||
|
|
cad2bf5b08 | ||
|
|
247c66b3fe | ||
|
|
73c2162ff6 | ||
|
|
889ce36afa | ||
|
|
c3d4b66953 | ||
|
|
234b29cf66 | ||
|
|
31827b0286 | ||
|
|
df121a7cd0 | ||
|
|
03df03b269 | ||
|
|
f1522e6204 | ||
|
|
87bce90086 | ||
|
|
4a29a7f92c | ||
|
|
0149265ee8 | ||
|
|
0844e5951c | ||
|
|
251d1b8fbb | ||
|
|
7f0f5060ec | ||
|
|
d179f2cce9 | ||
|
|
5d0778014d | ||
|
|
4c10826caa | ||
|
|
873c9098d8 | ||
|
|
6ce5080049 | ||
|
|
b9546d12f2 | ||
|
|
a49c524c9e | ||
|
|
b7f1fc116e | ||
|
|
28aa8010b2 | ||
|
|
c09eb00031 | ||
|
|
1113b3b6eb | ||
|
|
a81a16f22f | ||
|
|
8428b25939 |
@@ -123,6 +123,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
availableMethods["admin_region_query"] = XmlRpcRegionQueryMethod;
|
||||
availableMethods["admin_shutdown"] = XmlRpcShutdownMethod;
|
||||
availableMethods["admin_broadcast"] = XmlRpcAlertMethod;
|
||||
availableMethods["admin_dialog"] = XmlRpcDialogMethod;
|
||||
availableMethods["admin_restart"] = XmlRpcRestartMethod;
|
||||
availableMethods["admin_load_heightmap"] = XmlRpcLoadHeightmapMethod;
|
||||
// User management
|
||||
@@ -212,9 +213,59 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
if (!m_app.SceneManager.TryGetScene(regionID, out rebootedScene))
|
||||
throw new Exception("region not found");
|
||||
|
||||
int timeout = 30000;
|
||||
string message;
|
||||
|
||||
if (requestData.ContainsKey("restart")
|
||||
&& ((string)requestData["restart"] == "delayed")
|
||||
&& requestData.ContainsKey("milliseconds"))
|
||||
{
|
||||
timeout = Int32.Parse(requestData["milliseconds"].ToString());
|
||||
|
||||
if (timeout < 15000)
|
||||
{
|
||||
//It must be at least 15 seconds or we'll cancel the reboot request
|
||||
timeout = 15000;
|
||||
}
|
||||
|
||||
message
|
||||
= "Region is restarting in " + ((int)(timeout / 1000)).ToString()
|
||||
+ " second(s). Please save what you are doing and log out.";
|
||||
}
|
||||
else
|
||||
{
|
||||
message = "Region is restarting in 30 second(s). Please save what you are doing and log out.";
|
||||
}
|
||||
|
||||
if (requestData.ContainsKey("noticetype")
|
||||
&& ((string)requestData["noticetype"] == "dialog"))
|
||||
{
|
||||
m_app.SceneManager.ForEachScene(
|
||||
delegate(Scene scene)
|
||||
{
|
||||
IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
|
||||
if (dialogModule != null)
|
||||
dialogModule.SendNotificationToUsersInRegion(UUID.Zero, "System", message);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!requestData.ContainsKey("noticetype")
|
||||
|| ((string)requestData["noticetype"] != "none"))
|
||||
{
|
||||
m_app.SceneManager.ForEachScene(
|
||||
delegate(Scene scene)
|
||||
{
|
||||
IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
|
||||
if (dialogModule != null)
|
||||
dialogModule.SendGeneralAlert(message);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
responseData["rebooting"] = true;
|
||||
response.Value = responseData;
|
||||
rebootedScene.Restart(30);
|
||||
rebootedScene.Restart(timeout / 1000,false);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -277,6 +328,53 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
m_log.Info("[RADMIN]: Alert request complete");
|
||||
return response;
|
||||
}
|
||||
public XmlRpcResponse XmlRpcDialogMethod(XmlRpcRequest request, IPEndPoint remoteClient)
|
||||
{
|
||||
XmlRpcResponse response = new XmlRpcResponse();
|
||||
Hashtable responseData = new Hashtable();
|
||||
|
||||
m_log.Info("[RADMIN]: Dialog request started");
|
||||
|
||||
try
|
||||
{
|
||||
Hashtable requestData = (Hashtable)request.Params[0];
|
||||
|
||||
checkStringParameters(request, new string[] { "password", "from", "message" });
|
||||
|
||||
if (m_requiredPassword != String.Empty &&
|
||||
(!requestData.Contains("password") || (string)requestData["password"] != m_requiredPassword))
|
||||
throw new Exception("wrong password");
|
||||
|
||||
string message = (string)requestData["message"];
|
||||
string fromuuid = (string)requestData["from"];
|
||||
m_log.InfoFormat("[RADMIN]: Broadcasting: {0}", message);
|
||||
|
||||
responseData["accepted"] = true;
|
||||
responseData["success"] = true;
|
||||
response.Value = responseData;
|
||||
|
||||
m_app.SceneManager.ForEachScene(
|
||||
delegate(Scene scene)
|
||||
{
|
||||
IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
|
||||
if (dialogModule != null)
|
||||
dialogModule.SendNotificationToUsersInRegion(UUID.Zero, fromuuid, message);
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[RADMIN]: Broadcasting: failed: {0}", e.Message);
|
||||
m_log.DebugFormat("[RADMIN]: Broadcasting: failed: {0}", e.ToString());
|
||||
|
||||
responseData["accepted"] = false;
|
||||
responseData["success"] = false;
|
||||
responseData["error"] = e.Message;
|
||||
response.Value = responseData;
|
||||
}
|
||||
|
||||
m_log.Info("[RADMIN]: Alert request complete");
|
||||
return response;
|
||||
}
|
||||
|
||||
public XmlRpcResponse XmlRpcLoadHeightmapMethod(XmlRpcRequest request, IPEndPoint remoteClient)
|
||||
{
|
||||
@@ -384,13 +482,33 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
message = "Region is going down now.";
|
||||
}
|
||||
|
||||
m_app.SceneManager.ForEachScene(
|
||||
if (requestData.ContainsKey("noticetype")
|
||||
&& ((string) requestData["noticetype"] == "dialog"))
|
||||
{
|
||||
m_app.SceneManager.ForEachScene(
|
||||
delegate(Scene scene)
|
||||
{
|
||||
IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
|
||||
if (dialogModule != null)
|
||||
dialogModule.SendNotificationToUsersInRegion(UUID.Zero, "System", message);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!requestData.ContainsKey("noticetype")
|
||||
|| ((string)requestData["noticetype"] != "none"))
|
||||
{
|
||||
m_app.SceneManager.ForEachScene(
|
||||
delegate(Scene scene)
|
||||
{
|
||||
IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
|
||||
if (dialogModule != null)
|
||||
dialogModule.SendGeneralAlert(message);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Perform shutdown
|
||||
System.Timers.Timer shutdownTimer = new System.Timers.Timer(timeout); // Wait before firing
|
||||
|
||||
@@ -921,7 +921,7 @@ namespace OpenSim.Client.MXP.ClientStack
|
||||
// Need to translate to MXP somehow
|
||||
}
|
||||
|
||||
public void SendGenericMessage(string method, List<string> message)
|
||||
public void SendGenericMessage(string method, List<byte[]> message)
|
||||
{
|
||||
// Need to translate to MXP somehow
|
||||
}
|
||||
|
||||
@@ -495,7 +495,7 @@ namespace OpenSim.Client.Sirikata.ClientStack
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void SendGenericMessage(string method, List<string> message)
|
||||
public void SendGenericMessage(string method, List<Byte[]> message)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
@@ -502,7 +502,7 @@ namespace OpenSim.Client.VWoHTTP.ClientStack
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void SendGenericMessage(string method, List<string> message)
|
||||
public void SendGenericMessage(string method, List<byte[]> message)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
@@ -671,7 +671,16 @@ VALUES
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID)
|
||||
{
|
||||
//This connector doesn't support the windlight module yet
|
||||
//Return default LL windlight settings
|
||||
return new RegionMeta7WindlightData();
|
||||
}
|
||||
public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl)
|
||||
{
|
||||
//This connector doesn't support the windlight module yet
|
||||
}
|
||||
/// <summary>
|
||||
/// Loads the settings of a region.
|
||||
/// </summary>
|
||||
@@ -696,7 +705,7 @@ VALUES
|
||||
}
|
||||
}
|
||||
|
||||
//If comes here then there is now region setting for that region
|
||||
//If we reach this point then there are new region settings for that region
|
||||
regionSettings = new RegionSettings();
|
||||
regionSettings.RegionUUID = regionUUID;
|
||||
regionSettings.OnSave += StoreRegionSettings;
|
||||
|
||||
@@ -693,6 +693,97 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
}
|
||||
|
||||
public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID)
|
||||
{
|
||||
RegionMeta7WindlightData nWP = new RegionMeta7WindlightData();
|
||||
nWP.OnSave += StoreRegionWindlightSettings;
|
||||
lock (m_Connection)
|
||||
{
|
||||
|
||||
string command = "select * from `regionwindlight` where region_id = ?regionID";
|
||||
|
||||
MySqlCommand cmd = new MySqlCommand(command);
|
||||
|
||||
cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString());
|
||||
|
||||
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
|
||||
{
|
||||
UUID.TryParse(result["region_id"].ToString(), out nWP.regionID);
|
||||
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"]);
|
||||
}
|
||||
}
|
||||
return nWP;
|
||||
}
|
||||
|
||||
public RegionSettings LoadRegionSettings(UUID regionUUID)
|
||||
{
|
||||
RegionSettings rs = null;
|
||||
@@ -726,6 +817,107 @@ namespace OpenSim.Data.MySQL
|
||||
return rs;
|
||||
}
|
||||
|
||||
public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl)
|
||||
{
|
||||
lock (m_Connection)
|
||||
{
|
||||
using (MySqlCommand cmd = m_Connection.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, ";
|
||||
cmd.CommandText += "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, ";
|
||||
cmd.CommandText += "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, ";
|
||||
cmd.CommandText += "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, ";
|
||||
cmd.CommandText += "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, ";
|
||||
cmd.CommandText += "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, ";
|
||||
cmd.CommandText += "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, ";
|
||||
cmd.CommandText += "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, ";
|
||||
cmd.CommandText += "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, ";
|
||||
cmd.CommandText += "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, ";
|
||||
cmd.CommandText += "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, ";
|
||||
cmd.CommandText += "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, ";
|
||||
cmd.CommandText += "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, ";
|
||||
cmd.CommandText += "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, ";
|
||||
cmd.CommandText += "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, ";
|
||||
cmd.CommandText += "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, ";
|
||||
cmd.CommandText += "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, ";
|
||||
cmd.CommandText += "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, ";
|
||||
cmd.CommandText += "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, ";
|
||||
cmd.CommandText += "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, ";
|
||||
cmd.CommandText += "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, ";
|
||||
cmd.CommandText += "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, ";
|
||||
cmd.CommandText += "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, ";
|
||||
cmd.CommandText += "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, ";
|
||||
cmd.CommandText += "?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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void StoreRegionSettings(RegionSettings rs)
|
||||
{
|
||||
lock (m_Connection)
|
||||
|
||||
70
OpenSim/Data/MySQL/Resources/032_RegionStore.sql
Normal file
70
OpenSim/Data/MySQL/Resources/032_RegionStore.sql
Normal file
@@ -0,0 +1,70 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE `regionwindlight` (
|
||||
`region_id` varchar(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000',
|
||||
`water_color_r` float(9,6) unsigned NOT NULL DEFAULT '4.000000',
|
||||
`water_color_g` float(9,6) unsigned NOT NULL DEFAULT '38.000000',
|
||||
`water_color_b` float(9,6) unsigned NOT NULL DEFAULT '64.000000',
|
||||
`water_fog_density_exponent` float(3,1) unsigned NOT NULL DEFAULT '4.0',
|
||||
`underwater_fog_modifier` float(3,2) unsigned NOT NULL DEFAULT '0.25',
|
||||
`reflection_wavelet_scale_1` float(3,1) unsigned NOT NULL DEFAULT '2.0',
|
||||
`reflection_wavelet_scale_2` float(3,1) unsigned NOT NULL DEFAULT '2.0',
|
||||
`reflection_wavelet_scale_3` float(3,1) unsigned NOT NULL DEFAULT '2.0',
|
||||
`fresnel_scale` float(3,2) unsigned NOT NULL DEFAULT '0.40',
|
||||
`fresnel_offset` float(3,2) unsigned NOT NULL DEFAULT '0.50',
|
||||
`refract_scale_above` float(3,2) unsigned NOT NULL DEFAULT '0.03',
|
||||
`refract_scale_below` float(3,2) unsigned NOT NULL DEFAULT '0.20',
|
||||
`blur_multiplier` float(4,3) unsigned NOT NULL DEFAULT '0.040',
|
||||
`big_wave_direction_x` float(3,2) NOT NULL DEFAULT '1.05',
|
||||
`big_wave_direction_y` float(3,2) NOT NULL DEFAULT '-0.42',
|
||||
`little_wave_direction_x` float(3,2) NOT NULL DEFAULT '1.11',
|
||||
`little_wave_direction_y` float(3,2) NOT NULL DEFAULT '-1.16',
|
||||
`normal_map_texture` varchar(36) NOT NULL DEFAULT '822ded49-9a6c-f61c-cb89-6df54f42cdf4',
|
||||
`horizon_r` float(3,2) unsigned NOT NULL DEFAULT '0.25',
|
||||
`horizon_g` float(3,2) unsigned NOT NULL DEFAULT '0.25',
|
||||
`horizon_b` float(3,2) unsigned NOT NULL DEFAULT '0.32',
|
||||
`horizon_i` float(3,2) unsigned NOT NULL DEFAULT '0.32',
|
||||
`haze_horizon` float(3,2) unsigned NOT NULL DEFAULT '0.19',
|
||||
`blue_density_r` float(3,2) unsigned NOT NULL DEFAULT '0.12',
|
||||
`blue_density_g` float(3,2) unsigned NOT NULL DEFAULT '0.22',
|
||||
`blue_density_b` float(3,2) unsigned NOT NULL DEFAULT '0.38',
|
||||
`blue_density_i` float(3,2) unsigned NOT NULL DEFAULT '0.38',
|
||||
`haze_density` float(3,2) unsigned NOT NULL DEFAULT '0.70',
|
||||
`density_multiplier` float(3,2) unsigned NOT NULL DEFAULT '0.18',
|
||||
`distance_multiplier` float(4,1) unsigned NOT NULL DEFAULT '0.8',
|
||||
`max_altitude` int(4) unsigned NOT NULL DEFAULT '1605',
|
||||
`sun_moon_color_r` float(3,2) unsigned NOT NULL DEFAULT '0.24',
|
||||
`sun_moon_color_g` float(3,2) unsigned NOT NULL DEFAULT '0.26',
|
||||
`sun_moon_color_b` float(3,2) unsigned NOT NULL DEFAULT '0.30',
|
||||
`sun_moon_color_i` float(3,2) unsigned NOT NULL DEFAULT '0.30',
|
||||
`sun_moon_position` float(4,3) unsigned NOT NULL DEFAULT '0.317',
|
||||
`ambient_r` float(3,2) unsigned NOT NULL DEFAULT '0.35',
|
||||
`ambient_g` float(3,2) unsigned NOT NULL DEFAULT '0.35',
|
||||
`ambient_b` float(3,2) unsigned NOT NULL DEFAULT '0.35',
|
||||
`ambient_i` float(3,2) unsigned NOT NULL DEFAULT '0.35',
|
||||
`east_angle` float(3,2) unsigned NOT NULL DEFAULT '0.00',
|
||||
`sun_glow_focus` float(3,2) unsigned NOT NULL DEFAULT '0.10',
|
||||
`sun_glow_size` float(3,2) unsigned NOT NULL DEFAULT '1.75',
|
||||
`scene_gamma` float(4,2) unsigned NOT NULL DEFAULT '1.00',
|
||||
`star_brightness` float(3,2) unsigned NOT NULL DEFAULT '0.00',
|
||||
`cloud_color_r` float(3,2) unsigned NOT NULL DEFAULT '0.41',
|
||||
`cloud_color_g` float(3,2) unsigned NOT NULL DEFAULT '0.41',
|
||||
`cloud_color_b` float(3,2) unsigned NOT NULL DEFAULT '0.41',
|
||||
`cloud_color_i` float(3,2) unsigned NOT NULL DEFAULT '0.41',
|
||||
`cloud_x` float(3,2) unsigned NOT NULL DEFAULT '1.00',
|
||||
`cloud_y` float(3,2) unsigned NOT NULL DEFAULT '0.53',
|
||||
`cloud_density` float(3,2) unsigned NOT NULL DEFAULT '1.00',
|
||||
`cloud_coverage` float(3,2) unsigned NOT NULL DEFAULT '0.27',
|
||||
`cloud_scale` float(3,2) unsigned NOT NULL DEFAULT '0.42',
|
||||
`cloud_detail_x` float(3,2) unsigned NOT NULL DEFAULT '1.00',
|
||||
`cloud_detail_y` float(3,2) unsigned NOT NULL DEFAULT '0.53',
|
||||
`cloud_detail_density` float(3,2) unsigned NOT NULL DEFAULT '0.12',
|
||||
`cloud_scroll_x` float(3,2) unsigned NOT NULL DEFAULT '0.20',
|
||||
`cloud_scroll_x_lock` tinyint(1) unsigned NOT NULL DEFAULT '0',
|
||||
`cloud_scroll_y` float(3,2) unsigned NOT NULL DEFAULT '0.01',
|
||||
`cloud_scroll_y_lock` tinyint(1) unsigned NOT NULL DEFAULT '0',
|
||||
`draw_classic_clouds` tinyint(1) unsigned NOT NULL DEFAULT '1',
|
||||
PRIMARY KEY (`region_id`)
|
||||
);
|
||||
|
||||
COMMIT;
|
||||
@@ -50,7 +50,16 @@ namespace OpenSim.Data.Null
|
||||
public void StoreRegionSettings(RegionSettings rs)
|
||||
{
|
||||
}
|
||||
|
||||
public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID)
|
||||
{
|
||||
//This connector doesn't support the windlight module yet
|
||||
//Return default LL windlight settings
|
||||
return new RegionMeta7WindlightData();
|
||||
}
|
||||
public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl)
|
||||
{
|
||||
//This connector doesn't support the windlight module yet
|
||||
}
|
||||
public RegionSettings LoadRegionSettings(UUID regionUUID)
|
||||
{
|
||||
return null;
|
||||
|
||||
@@ -272,7 +272,16 @@ namespace OpenSim.Data.SQLite
|
||||
Commit();
|
||||
}
|
||||
}
|
||||
|
||||
public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID)
|
||||
{
|
||||
//This connector doesn't support the windlight module yet
|
||||
//Return default LL windlight settings
|
||||
return new RegionMeta7WindlightData();
|
||||
}
|
||||
public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl)
|
||||
{
|
||||
//This connector doesn't support the windlight module yet
|
||||
}
|
||||
public RegionSettings LoadRegionSettings(UUID regionUUID)
|
||||
{
|
||||
lock (ds)
|
||||
@@ -320,7 +329,7 @@ namespace OpenSim.Data.SQLite
|
||||
{
|
||||
foreach (SceneObjectPart prim in obj.Children.Values)
|
||||
{
|
||||
m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID);
|
||||
// m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID);
|
||||
addPrim(prim, obj.UUID, regionUUID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1138,7 +1138,7 @@ namespace OpenSim.Framework
|
||||
|
||||
void SendInstantMessage(GridInstantMessage im);
|
||||
|
||||
void SendGenericMessage(string method, List<string> message);
|
||||
void SendGenericMessage(string method, List<byte[]> message);
|
||||
|
||||
void SendLayerData(float[] map);
|
||||
void SendLayerData(int px, int py, float[] map);
|
||||
|
||||
@@ -36,8 +36,295 @@ using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Framework.Console;
|
||||
|
||||
|
||||
namespace OpenSim.Framework
|
||||
{
|
||||
{
|
||||
public class RegionMeta7WindlightData : ICloneable
|
||||
{
|
||||
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(RegionMeta7WindlightData wl);
|
||||
public event SaveDelegate OnSave;
|
||||
public void Save()
|
||||
{
|
||||
if (OnSave != null)
|
||||
OnSave(this);
|
||||
}
|
||||
public object Clone()
|
||||
{
|
||||
return this.MemberwiseClone(); // call clone method
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class SimpleRegionInfo
|
||||
{
|
||||
// private static readonly log4net.ILog m_log
|
||||
// = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// The port by which http communication occurs with the region (most noticeably, CAPS communication)
|
||||
/// </summary>
|
||||
public uint HttpPort
|
||||
{
|
||||
get { return m_httpPort; }
|
||||
set { m_httpPort = value; }
|
||||
}
|
||||
protected uint m_httpPort;
|
||||
|
||||
/// <summary>
|
||||
/// A well-formed URI for the host region server (namely "http://" + ExternalHostName)
|
||||
/// </summary>
|
||||
public string ServerURI
|
||||
{
|
||||
get { return m_serverURI; }
|
||||
set { m_serverURI = value; }
|
||||
}
|
||||
protected string m_serverURI;
|
||||
|
||||
public string RegionName
|
||||
{
|
||||
get { return m_regionName; }
|
||||
set { m_regionName = value; }
|
||||
}
|
||||
protected string m_regionName = String.Empty;
|
||||
|
||||
protected bool Allow_Alternate_Ports;
|
||||
public bool m_allow_alternate_ports;
|
||||
protected string m_externalHostName;
|
||||
|
||||
protected IPEndPoint m_internalEndPoint;
|
||||
protected uint? m_regionLocX;
|
||||
protected uint? m_regionLocY;
|
||||
protected uint m_remotingPort;
|
||||
public UUID RegionID = UUID.Zero;
|
||||
public string RemotingAddress;
|
||||
public UUID ScopeID = UUID.Zero;
|
||||
|
||||
public SimpleRegionInfo()
|
||||
{
|
||||
}
|
||||
|
||||
public SimpleRegionInfo(uint regionLocX, uint regionLocY, IPEndPoint internalEndPoint, string externalUri)
|
||||
{
|
||||
m_regionLocX = regionLocX;
|
||||
m_regionLocY = regionLocY;
|
||||
|
||||
m_internalEndPoint = internalEndPoint;
|
||||
m_externalHostName = externalUri;
|
||||
}
|
||||
|
||||
public SimpleRegionInfo(uint regionLocX, uint regionLocY, string externalUri, uint port)
|
||||
{
|
||||
m_regionLocX = regionLocX;
|
||||
m_regionLocY = regionLocY;
|
||||
|
||||
m_externalHostName = externalUri;
|
||||
|
||||
m_internalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int) port);
|
||||
}
|
||||
|
||||
public SimpleRegionInfo(RegionInfo ConvertFrom)
|
||||
{
|
||||
m_regionName = ConvertFrom.RegionName;
|
||||
m_regionLocX = ConvertFrom.RegionLocX;
|
||||
m_regionLocY = ConvertFrom.RegionLocY;
|
||||
m_internalEndPoint = ConvertFrom.InternalEndPoint;
|
||||
m_externalHostName = ConvertFrom.ExternalHostName;
|
||||
m_remotingPort = ConvertFrom.RemotingPort;
|
||||
m_httpPort = ConvertFrom.HttpPort;
|
||||
m_allow_alternate_ports = ConvertFrom.m_allow_alternate_ports;
|
||||
RemotingAddress = ConvertFrom.RemotingAddress;
|
||||
RegionID = UUID.Zero;
|
||||
ServerURI = ConvertFrom.ServerURI;
|
||||
}
|
||||
|
||||
public uint RemotingPort
|
||||
{
|
||||
get { return m_remotingPort; }
|
||||
set { m_remotingPort = value; }
|
||||
}
|
||||
|
||||
/// <value>
|
||||
/// This accessor can throw all the exceptions that Dns.GetHostAddresses can throw.
|
||||
///
|
||||
/// XXX Isn't this really doing too much to be a simple getter, rather than an explict method?
|
||||
/// </value>
|
||||
public IPEndPoint ExternalEndPoint
|
||||
{
|
||||
get
|
||||
{
|
||||
// Old one defaults to IPv6
|
||||
//return new IPEndPoint(Dns.GetHostAddresses(m_externalHostName)[0], m_internalEndPoint.Port);
|
||||
|
||||
IPAddress ia = null;
|
||||
// If it is already an IP, don't resolve it - just return directly
|
||||
if (IPAddress.TryParse(m_externalHostName, out ia))
|
||||
return new IPEndPoint(ia, m_internalEndPoint.Port);
|
||||
|
||||
// Reset for next check
|
||||
ia = null;
|
||||
try
|
||||
{
|
||||
foreach (IPAddress Adr in Dns.GetHostAddresses(m_externalHostName))
|
||||
{
|
||||
if (ia == null)
|
||||
ia = Adr;
|
||||
|
||||
if (Adr.AddressFamily == AddressFamily.InterNetwork)
|
||||
{
|
||||
ia = Adr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SocketException e)
|
||||
{
|
||||
throw new Exception(
|
||||
"Unable to resolve local hostname " + m_externalHostName + " innerException of type '" +
|
||||
e + "' attached to this exception", e);
|
||||
}
|
||||
|
||||
return new IPEndPoint(ia, m_internalEndPoint.Port);
|
||||
}
|
||||
|
||||
set { m_externalHostName = value.ToString(); }
|
||||
}
|
||||
|
||||
public string ExternalHostName
|
||||
{
|
||||
get { return m_externalHostName; }
|
||||
set { m_externalHostName = value; }
|
||||
}
|
||||
|
||||
public IPEndPoint InternalEndPoint
|
||||
{
|
||||
get { return m_internalEndPoint; }
|
||||
set { m_internalEndPoint = value; }
|
||||
}
|
||||
|
||||
public uint RegionLocX
|
||||
{
|
||||
get { return m_regionLocX.Value; }
|
||||
set { m_regionLocX = value; }
|
||||
}
|
||||
|
||||
public uint RegionLocY
|
||||
{
|
||||
get { return m_regionLocY.Value; }
|
||||
set { m_regionLocY = value; }
|
||||
}
|
||||
|
||||
public ulong RegionHandle
|
||||
{
|
||||
get { return Util.UIntsToLong((RegionLocX * (uint) Constants.RegionSize), (RegionLocY * (uint) Constants.RegionSize)); }
|
||||
}
|
||||
|
||||
public int getInternalEndPointPort()
|
||||
{
|
||||
return m_internalEndPoint.Port;
|
||||
}
|
||||
|
||||
public Dictionary<string, object> ToKeyValuePairs()
|
||||
{
|
||||
Dictionary<string, object> kvp = new Dictionary<string, object>();
|
||||
kvp["uuid"] = RegionID.ToString();
|
||||
kvp["locX"] = RegionLocX.ToString();
|
||||
kvp["locY"] = RegionLocY.ToString();
|
||||
kvp["external_ip_address"] = ExternalEndPoint.Address.ToString();
|
||||
kvp["external_port"] = ExternalEndPoint.Port.ToString();
|
||||
kvp["external_host_name"] = ExternalHostName;
|
||||
kvp["http_port"] = HttpPort.ToString();
|
||||
kvp["internal_ip_address"] = InternalEndPoint.Address.ToString();
|
||||
kvp["internal_port"] = InternalEndPoint.Port.ToString();
|
||||
kvp["alternate_ports"] = m_allow_alternate_ports.ToString();
|
||||
kvp["server_uri"] = ServerURI;
|
||||
|
||||
return kvp;
|
||||
}
|
||||
|
||||
public SimpleRegionInfo(Dictionary<string, object> kvp)
|
||||
{
|
||||
if ((kvp["external_ip_address"] != null) && (kvp["external_port"] != null))
|
||||
{
|
||||
int port = 0;
|
||||
Int32.TryParse((string)kvp["external_port"], out port);
|
||||
IPEndPoint ep = new IPEndPoint(IPAddress.Parse((string)kvp["external_ip_address"]), port);
|
||||
ExternalEndPoint = ep;
|
||||
}
|
||||
else
|
||||
ExternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0);
|
||||
|
||||
if (kvp["external_host_name"] != null)
|
||||
ExternalHostName = (string)kvp["external_host_name"];
|
||||
|
||||
if (kvp["http_port"] != null)
|
||||
{
|
||||
UInt32 port = 0;
|
||||
UInt32.TryParse((string)kvp["http_port"], out port);
|
||||
HttpPort = port;
|
||||
}
|
||||
|
||||
if ((kvp["internal_ip_address"] != null) && (kvp["internal_port"] != null))
|
||||
{
|
||||
int port = 0;
|
||||
Int32.TryParse((string)kvp["internal_port"], out port);
|
||||
IPEndPoint ep = new IPEndPoint(IPAddress.Parse((string)kvp["internal_ip_address"]), port);
|
||||
InternalEndPoint = ep;
|
||||
}
|
||||
else
|
||||
InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0);
|
||||
|
||||
if (kvp["alternate_ports"] != null)
|
||||
{
|
||||
bool alts = false;
|
||||
Boolean.TryParse((string)kvp["alternate_ports"], out alts);
|
||||
m_allow_alternate_ports = alts;
|
||||
}
|
||||
|
||||
if (kvp["server_uri"] != null)
|
||||
ServerURI = (string)kvp["server_uri"];
|
||||
}
|
||||
}
|
||||
|
||||
public class RegionInfo
|
||||
{
|
||||
// private static readonly log4net.ILog m_log
|
||||
@@ -73,6 +360,7 @@ namespace OpenSim.Framework
|
||||
private bool m_clampPrimSize = false;
|
||||
private int m_objectCapacity = 0;
|
||||
private string m_regionType = String.Empty;
|
||||
private RegionMeta7WindlightData m_windlight = new RegionMeta7WindlightData();
|
||||
protected uint m_httpPort;
|
||||
protected string m_serverURI;
|
||||
protected string m_regionName = String.Empty;
|
||||
@@ -211,6 +499,21 @@ namespace OpenSim.Framework
|
||||
set { m_regionSettings = value; }
|
||||
}
|
||||
|
||||
public RegionMeta7WindlightData WindlightSettings
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_windlight == null)
|
||||
{
|
||||
m_windlight = new RegionMeta7WindlightData();
|
||||
}
|
||||
|
||||
return m_windlight;
|
||||
}
|
||||
|
||||
set { m_windlight = value; }
|
||||
}
|
||||
|
||||
public int NonphysPrimMax
|
||||
{
|
||||
get { return m_nonphysPrimMax; }
|
||||
|
||||
@@ -29,9 +29,8 @@ namespace OpenSim
|
||||
{
|
||||
public class VersionInfo
|
||||
{
|
||||
private const string VERSION_NUMBER = "0.6.9";
|
||||
private const string VERSION_NUMBER = "0.6.8CM";
|
||||
private const Flavour VERSION_FLAVOUR = Flavour.Dev;
|
||||
|
||||
public enum Flavour
|
||||
{
|
||||
Unknown,
|
||||
|
||||
@@ -27,9 +27,12 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Reflection;
|
||||
using System.Xml;
|
||||
using System.Xml.Schema;
|
||||
using System.Xml.Serialization;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Framework
|
||||
@@ -45,6 +48,111 @@ namespace OpenSim.Framework
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private static XmlSerializer tiiSerializer = new XmlSerializer(typeof (TaskInventoryItem));
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Thread LockedByThread;
|
||||
/// <value>
|
||||
/// An advanced lock for inventory data
|
||||
/// </value>
|
||||
private System.Threading.ReaderWriterLockSlim m_itemLock = new System.Threading.ReaderWriterLockSlim();
|
||||
|
||||
/// <summary>
|
||||
/// Are we readlocked by the calling thread?
|
||||
/// </summary>
|
||||
public bool IsReadLockedByMe()
|
||||
{
|
||||
if (m_itemLock.RecursiveReadCount > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lock our inventory list for reading (many can read, one can write)
|
||||
/// </summary>
|
||||
public void LockItemsForRead(bool locked)
|
||||
{
|
||||
if (locked)
|
||||
{
|
||||
if (m_itemLock.IsWriteLockHeld && LockedByThread != null)
|
||||
{
|
||||
if (!LockedByThread.IsAlive)
|
||||
{
|
||||
//Locked by dead thread, reset.
|
||||
m_itemLock = new System.Threading.ReaderWriterLockSlim();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_itemLock.RecursiveReadCount > 0)
|
||||
{
|
||||
m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
|
||||
m_itemLock.ExitReadLock();
|
||||
}
|
||||
if (m_itemLock.RecursiveWriteCount > 0)
|
||||
{
|
||||
m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed.");
|
||||
m_itemLock.ExitWriteLock();
|
||||
}
|
||||
|
||||
while (!m_itemLock.TryEnterReadLock(60000))
|
||||
{
|
||||
m_log.Error("Thread lock detected while trying to aquire READ lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
|
||||
if (m_itemLock.IsWriteLockHeld)
|
||||
{
|
||||
m_itemLock = new System.Threading.ReaderWriterLockSlim();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_itemLock.RecursiveReadCount>0)
|
||||
{
|
||||
m_itemLock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lock our inventory list for writing (many can read, one can write)
|
||||
/// </summary>
|
||||
public void LockItemsForWrite(bool locked)
|
||||
{
|
||||
if (locked)
|
||||
{
|
||||
//Enter a write lock, wait indefinately for one to open.
|
||||
if (m_itemLock.RecursiveReadCount > 0)
|
||||
{
|
||||
m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
|
||||
m_itemLock.ExitReadLock();
|
||||
}
|
||||
if (m_itemLock.RecursiveWriteCount > 0)
|
||||
{
|
||||
m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed.");
|
||||
m_itemLock.ExitWriteLock();
|
||||
}
|
||||
while (!m_itemLock.TryEnterWriteLock(60000))
|
||||
{
|
||||
m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
|
||||
if (m_itemLock.IsWriteLockHeld)
|
||||
{
|
||||
m_itemLock = new System.Threading.ReaderWriterLockSlim();
|
||||
}
|
||||
}
|
||||
|
||||
LockedByThread = Thread.CurrentThread;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_itemLock.RecursiveWriteCount > 0)
|
||||
{
|
||||
m_itemLock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region ICloneable Members
|
||||
|
||||
@@ -52,13 +160,12 @@ namespace OpenSim.Framework
|
||||
{
|
||||
TaskInventoryDictionary clone = new TaskInventoryDictionary();
|
||||
|
||||
lock (this)
|
||||
m_itemLock.EnterReadLock();
|
||||
foreach (UUID uuid in Keys)
|
||||
{
|
||||
foreach (UUID uuid in Keys)
|
||||
{
|
||||
clone.Add(uuid, (TaskInventoryItem) this[uuid].Clone());
|
||||
}
|
||||
clone.Add(uuid, (TaskInventoryItem) this[uuid].Clone());
|
||||
}
|
||||
m_itemLock.ExitReadLock();
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
@@ -990,19 +990,19 @@ namespace OpenSim.Framework
|
||||
{
|
||||
string os = String.Empty;
|
||||
|
||||
if (Environment.OSVersion.Platform != PlatformID.Unix)
|
||||
{
|
||||
os = Environment.OSVersion.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
os = ReadEtcIssue();
|
||||
}
|
||||
|
||||
if (os.Length > 45)
|
||||
{
|
||||
os = os.Substring(0, 45);
|
||||
}
|
||||
// if (Environment.OSVersion.Platform != PlatformID.Unix)
|
||||
// {
|
||||
// os = Environment.OSVersion.ToString();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// os = ReadEtcIssue();
|
||||
// }
|
||||
//
|
||||
// if (os.Length > 45)
|
||||
// {
|
||||
// os = os.Substring(0, 45);
|
||||
// }
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
@@ -812,16 +812,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
}
|
||||
}
|
||||
|
||||
public void SendGenericMessage(string method, List<string> message)
|
||||
public void SendGenericMessage(string method, List<byte[]> message)
|
||||
{
|
||||
GenericMessagePacket gmp = new GenericMessagePacket();
|
||||
gmp.MethodData.Method = Util.StringToBytes256(method);
|
||||
gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count];
|
||||
int i = 0;
|
||||
foreach (string val in message)
|
||||
foreach (byte[] val in message)
|
||||
{
|
||||
gmp.ParamList[i] = new GenericMessagePacket.ParamListBlock();
|
||||
gmp.ParamList[i++].Parameter = Util.StringToBytes256(val);
|
||||
gmp.ParamList[i++].Parameter = val;
|
||||
}
|
||||
OutPacket(gmp, ThrottleOutPacketType.Task);
|
||||
}
|
||||
@@ -1020,6 +1020,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
public virtual void SendLayerData(float[] map)
|
||||
{
|
||||
Util.FireAndForget(DoSendLayerData, map);
|
||||
|
||||
// Send it sync, and async. It's not that much data
|
||||
// and it improves user experience just so much!
|
||||
DoSendLayerData(map);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1032,16 +1036,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
try
|
||||
{
|
||||
//for (int y = 0; y < 16; y++)
|
||||
//{
|
||||
// for (int x = 0; x < 16; x++)
|
||||
// {
|
||||
// SendLayerData(x, y, map);
|
||||
// }
|
||||
//}
|
||||
|
||||
// Send LayerData in a spiral pattern. Fun!
|
||||
SendLayerTopRight(map, 0, 0, 15, 15);
|
||||
for (int y = 0; y < 16; y++)
|
||||
{
|
||||
for (int x = 0; x < 16; x+=4)
|
||||
{
|
||||
SendLayerPacket(x, y, map);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -1049,51 +1050,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
}
|
||||
}
|
||||
|
||||
private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
|
||||
{
|
||||
// Row
|
||||
for (int i = x1; i <= x2; i++)
|
||||
SendLayerData(i, y1, map);
|
||||
|
||||
// Column
|
||||
for (int j = y1 + 1; j <= y2; j++)
|
||||
SendLayerData(x2, j, map);
|
||||
|
||||
if (x2 - x1 > 0)
|
||||
SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
|
||||
}
|
||||
|
||||
void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
|
||||
{
|
||||
// Row in reverse
|
||||
for (int i = x2; i >= x1; i--)
|
||||
SendLayerData(i, y2, map);
|
||||
|
||||
// Column in reverse
|
||||
for (int j = y2 - 1; j >= y1; j--)
|
||||
SendLayerData(x1, j, map);
|
||||
|
||||
if (x2 - x1 > 0)
|
||||
SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a set of four patches (x, x+1, ..., x+3) to the client
|
||||
/// </summary>
|
||||
/// <param name="map">heightmap</param>
|
||||
/// <param name="px">X coordinate for patches 0..12</param>
|
||||
/// <param name="py">Y coordinate for patches 0..15</param>
|
||||
// private void SendLayerPacket(float[] map, int y, int x)
|
||||
// {
|
||||
// int[] patches = new int[4];
|
||||
// patches[0] = x + 0 + y * 16;
|
||||
// patches[1] = x + 1 + y * 16;
|
||||
// patches[2] = x + 2 + y * 16;
|
||||
// patches[3] = x + 3 + y * 16;
|
||||
private void SendLayerPacket(int x, int y, float[] map)
|
||||
{
|
||||
int[] patches = new int[4];
|
||||
patches[0] = x + 0 + y * 16;
|
||||
patches[1] = x + 1 + y * 16;
|
||||
patches[2] = x + 2 + y * 16;
|
||||
patches[3] = x + 3 + y * 16;
|
||||
|
||||
// Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches);
|
||||
// OutPacket(layerpack, ThrottleOutPacketType.Land);
|
||||
// }
|
||||
float[] heightmap = (map.Length == 65536) ?
|
||||
map :
|
||||
LLHeightFieldMoronize(map);
|
||||
|
||||
try
|
||||
{
|
||||
Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
|
||||
OutPacket(layerpack, ThrottleOutPacketType.Land);
|
||||
}
|
||||
catch
|
||||
{
|
||||
for (int px = x ; px < x + 4 ; px++)
|
||||
SendLayerData(px, y, map);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a specified patch to a client
|
||||
@@ -3371,7 +3356,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
|
||||
objupdate.ObjectData[0] = CreateAvatarUpdateBlock(data);
|
||||
|
||||
OutPacket(objupdate, ThrottleOutPacketType.Task);
|
||||
}
|
||||
|
||||
@@ -3422,8 +3406,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue();
|
||||
}
|
||||
|
||||
// HACK: Using the task category until the tiered reprioritization code is in
|
||||
OutPacket(terse, ThrottleOutPacketType.Task);
|
||||
OutPacket(terse, ThrottleOutPacketType.State);
|
||||
}
|
||||
|
||||
public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
|
||||
@@ -4824,6 +4807,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
(x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
|
||||
(x.CameraUpAxis != lastarg.CameraUpAxis) ||
|
||||
(x.ControlFlags != lastarg.ControlFlags) ||
|
||||
(x.ControlFlags != 0) ||
|
||||
(x.Far != lastarg.Far) ||
|
||||
(x.Flags != lastarg.Flags) ||
|
||||
(x.State != lastarg.State) ||
|
||||
|
||||
@@ -49,7 +49,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
|
||||
private int m_shoutdistance = 100;
|
||||
private int m_whisperdistance = 10;
|
||||
private List<Scene> m_scenes = new List<Scene>();
|
||||
|
||||
private List<string> FreezeCache = new List<string>();
|
||||
private string m_adminPrefix = "";
|
||||
internal object m_syncy = new object();
|
||||
|
||||
internal IConfig m_config;
|
||||
@@ -76,6 +77,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
|
||||
m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance);
|
||||
m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance);
|
||||
m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance);
|
||||
m_adminPrefix = config.Configs["Chat"].GetString("admin_prefix", "");
|
||||
}
|
||||
|
||||
public virtual void AddRegion(Scene scene)
|
||||
@@ -171,7 +173,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
|
||||
return;
|
||||
}
|
||||
|
||||
DeliverChatToAvatars(ChatSourceType.Agent, c);
|
||||
if (FreezeCache.Contains(c.Sender.AgentId.ToString()))
|
||||
{
|
||||
if (c.Type != ChatTypeEnum.StartTyping || c.Type != ChatTypeEnum.StopTyping)
|
||||
c.Sender.SendAgentAlertMessage("You may not talk as you are frozen.", false);
|
||||
}
|
||||
else
|
||||
{
|
||||
DeliverChatToAvatars(ChatSourceType.Agent, c);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void OnChatFromWorld(Object sender, OSChatMessage c)
|
||||
@@ -185,6 +195,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
|
||||
protected virtual void DeliverChatToAvatars(ChatSourceType sourceType, OSChatMessage c)
|
||||
{
|
||||
string fromName = c.From;
|
||||
string fromNamePrefix = "";
|
||||
UUID fromID = UUID.Zero;
|
||||
string message = c.Message;
|
||||
IScene scene = c.Scene;
|
||||
@@ -207,7 +218,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
|
||||
fromPos = avatar.AbsolutePosition;
|
||||
fromName = avatar.Name;
|
||||
fromID = c.Sender.AgentId;
|
||||
|
||||
if (avatar.GodLevel > 200)
|
||||
{
|
||||
fromNamePrefix = m_adminPrefix;
|
||||
}
|
||||
break;
|
||||
|
||||
case ChatSourceType.Object:
|
||||
@@ -227,7 +241,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
|
||||
s.ForEachScenePresence(
|
||||
delegate(ScenePresence presence)
|
||||
{
|
||||
TrySendChatMessage(presence, fromPos, regionPos, fromID, fromName, c.Type, message, sourceType);
|
||||
ILandObject Presencecheck = s.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y);
|
||||
if (Presencecheck != null)
|
||||
{
|
||||
if (Presencecheck.IsEitherBannedOrRestricted(c.SenderUUID) != true)
|
||||
{
|
||||
TrySendChatMessage(presence, fromPos, regionPos, fromID, fromNamePrefix+fromName, c.Type, message, sourceType);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -266,25 +288,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType);
|
||||
|
||||
((Scene)c.Scene).ForEachScenePresence(
|
||||
delegate(ScenePresence presence)
|
||||
{
|
||||
// ignore chat from child agents
|
||||
if (presence.IsChildAgent) return;
|
||||
|
||||
IClientAPI client = presence.ControllingClient;
|
||||
|
||||
// don't forward SayOwner chat from objects to
|
||||
// non-owner agents
|
||||
if ((c.Type == ChatTypeEnum.Owner) &&
|
||||
(null != c.SenderObject) &&
|
||||
(((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId))
|
||||
return;
|
||||
|
||||
client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID,
|
||||
(byte)sourceType, (byte)ChatAudibleLevel.Fully);
|
||||
});
|
||||
if (c.Scene != null)
|
||||
{
|
||||
((Scene)c.Scene).ForEachScenePresence
|
||||
(
|
||||
delegate(ScenePresence presence)
|
||||
{
|
||||
// ignore chat from child agents
|
||||
if (presence.IsChildAgent) return;
|
||||
|
||||
IClientAPI client = presence.ControllingClient;
|
||||
|
||||
// don't forward SayOwner chat from objects to
|
||||
// non-owner agents
|
||||
if ((c.Type == ChatTypeEnum.Owner) &&
|
||||
(null != c.SenderObject) &&
|
||||
(((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId))
|
||||
return;
|
||||
|
||||
client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID,
|
||||
(byte)sourceType, (byte)ChatAudibleLevel.Fully);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -313,5 +339,35 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
|
||||
presence.ControllingClient.SendChatMessage(message, (byte) type, fromPos, fromName,
|
||||
fromAgentID,(byte)src,(byte)ChatAudibleLevel.Fully);
|
||||
}
|
||||
|
||||
Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>();
|
||||
public void ParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
|
||||
{
|
||||
System.Threading.Timer Timer;
|
||||
if (flags == 0)
|
||||
{
|
||||
FreezeCache.Add(target.ToString());
|
||||
System.Threading.TimerCallback timeCB = new System.Threading.TimerCallback(OnEndParcelFrozen);
|
||||
Timer = new System.Threading.Timer(timeCB, target, 30000, 0);
|
||||
Timers.Add(target, Timer);
|
||||
}
|
||||
else
|
||||
{
|
||||
FreezeCache.Remove(target.ToString());
|
||||
Timers.TryGetValue(target, out Timer);
|
||||
Timers.Remove(target);
|
||||
Timer.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEndParcelFrozen(object avatar)
|
||||
{
|
||||
UUID target = (UUID)avatar;
|
||||
FreezeCache.Remove(target.ToString());
|
||||
System.Threading.Timer Timer;
|
||||
Timers.TryGetValue(target, out Timer);
|
||||
Timers.Remove(target);
|
||||
Timer.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,19 +168,22 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
List<GridInstantMessage>msglist = SynchronousRestObjectPoster.BeginPostObject<UUID, List<GridInstantMessage>>(
|
||||
"POST", m_RestURL+"/RetrieveMessages/", client.AgentId);
|
||||
|
||||
foreach (GridInstantMessage im in msglist)
|
||||
if (msglist != null)
|
||||
{
|
||||
// client.SendInstantMessage(im);
|
||||
foreach (GridInstantMessage im in msglist)
|
||||
{
|
||||
// client.SendInstantMessage(im);
|
||||
|
||||
// Send through scene event manager so all modules get a chance
|
||||
// to look at this message before it gets delivered.
|
||||
//
|
||||
// Needed for proper state management for stored group
|
||||
// invitations
|
||||
//
|
||||
Scene s = FindScene(client.AgentId);
|
||||
if (s != null)
|
||||
s.EventManager.TriggerIncomingInstantMessage(im);
|
||||
// Send through scene event manager so all modules get a chance
|
||||
// to look at this message before it gets delivered.
|
||||
//
|
||||
// Needed for proper state management for stored group
|
||||
// invitations
|
||||
//
|
||||
Scene s = FindScene(client.AgentId);
|
||||
if (s != null)
|
||||
s.EventManager.TriggerIncomingInstantMessage(im);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -389,7 +389,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
|
||||
{
|
||||
// Check if this is ours to handle
|
||||
//
|
||||
m_log.Info("OnFridInstantMessage");
|
||||
//m_log.Info("OnFridInstantMessage");
|
||||
if (msg.dialog != (byte) InstantMessageDialog.InventoryOffered)
|
||||
return;
|
||||
|
||||
|
||||
@@ -331,12 +331,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Interregion
|
||||
{
|
||||
//m_log.Debug("[CONNECTION DEBUGGING]: AgentHandler Called");
|
||||
|
||||
m_log.Debug("---------------------------");
|
||||
/* m_log.Debug("---------------------------");
|
||||
m_log.Debug(" >> uri=" + request["uri"]);
|
||||
m_log.Debug(" >> content-type=" + request["content-type"]);
|
||||
m_log.Debug(" >> http-method=" + request["http-method"]);
|
||||
m_log.Debug("---------------------------\n");
|
||||
|
||||
m_log.Debug("---------------------------\n"); */
|
||||
Hashtable responsedata = new Hashtable();
|
||||
responsedata["content_type"] = "text/html";
|
||||
responsedata["keepalive"] = false;
|
||||
@@ -581,11 +580,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Interregion
|
||||
{
|
||||
m_log.Debug("[CONNECTION DEBUGGING]: ObjectHandler Called");
|
||||
|
||||
m_log.Debug("---------------------------");
|
||||
/* m_log.Debug("---------------------------");
|
||||
m_log.Debug(" >> uri=" + request["uri"]);
|
||||
m_log.Debug(" >> content-type=" + request["content-type"]);
|
||||
m_log.Debug(" >> http-method=" + request["http-method"]);
|
||||
m_log.Debug("---------------------------\n");
|
||||
m_log.Debug("---------------------------\n"); */
|
||||
|
||||
Hashtable responsedata = new Hashtable();
|
||||
responsedata["content_type"] = "text/html";
|
||||
|
||||
@@ -247,21 +247,20 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||
// Fix ownership/creator of inventory items
|
||||
// Not doing so results in inventory items
|
||||
// being no copy/no mod for everyone
|
||||
lock (part.TaskInventory)
|
||||
part.TaskInventory.LockItemsForRead(true);
|
||||
TaskInventoryDictionary inv = part.TaskInventory;
|
||||
foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv)
|
||||
{
|
||||
TaskInventoryDictionary inv = part.TaskInventory;
|
||||
foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv)
|
||||
if (!ResolveUserUuid(kvp.Value.OwnerID))
|
||||
{
|
||||
if (!ResolveUserUuid(kvp.Value.OwnerID))
|
||||
{
|
||||
kvp.Value.OwnerID = masterAvatarId;
|
||||
}
|
||||
if (!ResolveUserUuid(kvp.Value.CreatorID))
|
||||
{
|
||||
kvp.Value.CreatorID = masterAvatarId;
|
||||
}
|
||||
kvp.Value.OwnerID = masterAvatarId;
|
||||
}
|
||||
if (!ResolveUserUuid(kvp.Value.CreatorID))
|
||||
{
|
||||
kvp.Value.CreatorID = masterAvatarId;
|
||||
}
|
||||
}
|
||||
part.TaskInventory.LockItemsForRead(false);
|
||||
}
|
||||
|
||||
if (m_scene.AddRestoredSceneObject(sceneObject, true, false))
|
||||
|
||||
@@ -81,6 +81,8 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||
private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
|
||||
|
||||
private bool m_allowedForcefulBans = true;
|
||||
private UUID DefaultGodParcelGroup;
|
||||
private string DefaultGodParcelName;
|
||||
|
||||
// caches ExtendedLandData
|
||||
private Cache parcelInfoCache;
|
||||
@@ -94,6 +96,12 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||
|
||||
public void Initialise(IConfigSource source)
|
||||
{
|
||||
IConfig cnf = source.Configs["LandManagement"];
|
||||
if (cnf == null)
|
||||
{
|
||||
DefaultGodParcelGroup = new UUID(cnf.GetString("DefaultAdministratorGroupUUID", UUID.Zero.ToString()));
|
||||
DefaultGodParcelName = cnf.GetString("DefaultAdministratorParcelName", "Default Parcel");
|
||||
}
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
@@ -153,6 +161,10 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||
client.OnParcelInfoRequest += ClientOnParcelInfoRequest;
|
||||
client.OnParcelDwellRequest += ClientOnParcelDwellRequest;
|
||||
client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup;
|
||||
client.OnParcelGodMark += ClientOnParcelGodMark;
|
||||
client.OnSimWideDeletes += ClientOnSimWideDeletes;
|
||||
client.OnParcelFreezeUser += ClientOnParcelFreezeUser;
|
||||
client.OnParcelEjectUser += ClientOnParcelEjectUser;
|
||||
|
||||
EntityBase presenceEntity;
|
||||
if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence)
|
||||
@@ -264,20 +276,103 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||
return parcelsNear;
|
||||
}
|
||||
|
||||
public void SendYouAreBannedNotice(ScenePresence avatar)
|
||||
|
||||
public void MoveUserOutOfParcel(ScenePresence avatar)
|
||||
{
|
||||
if (AllowedForcefulBans)
|
||||
if (avatar.GodLevel == 0)
|
||||
{
|
||||
avatar.ControllingClient.SendAlertMessage(
|
||||
"You are not allowed on this parcel because you are banned. Please go away.");
|
||||
ILandObject land = m_scene.LandChannel.GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
|
||||
List<ILandObject> parcelsNear = new List<ILandObject>();
|
||||
|
||||
avatar.PhysicsActor.Position = avatar.lastKnownAllowedPosition;
|
||||
avatar.PhysicsActor.Velocity = Vector3.Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
avatar.ControllingClient.SendAlertMessage(
|
||||
"You are not allowed on this parcel because you are banned; however, the grid administrator has disabled ban lines globally. Please obey the land owner's requests or you can be banned from the entire sim!");
|
||||
for (int x = -2; x <= 2; x += 2)
|
||||
{
|
||||
ILandObject check = GetLandObject(avatar.AbsolutePosition.X + x, avatar.AbsolutePosition.Y);
|
||||
if (check != null)
|
||||
{
|
||||
if (check.IsEitherBannedOrRestricted(avatar.UUID) != true)
|
||||
{
|
||||
Vector3 target = new Vector3(avatar.AbsolutePosition.X + x, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z);
|
||||
avatar.TeleportWithMomentum(target);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int y = -2; y <= 2; y += 2)
|
||||
{
|
||||
ILandObject check = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y + y);
|
||||
if (check != null)
|
||||
{
|
||||
if (check.IsEitherBannedOrRestricted(avatar.UUID) != true)
|
||||
{
|
||||
Vector3 target = new Vector3(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y + y, avatar.AbsolutePosition.Z);
|
||||
avatar.TeleportWithMomentum(target);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
List<ILandObject> allParcels = new List<ILandObject>();
|
||||
allParcels = AllParcels();
|
||||
if (allParcels.Count != 1)
|
||||
{
|
||||
foreach (ILandObject parcel in allParcels)
|
||||
{
|
||||
if (parcel.IsEitherBannedOrRestricted(avatar.UUID) != true)
|
||||
{
|
||||
Vector3 temptarget = parcel.LandData.UserLocation;
|
||||
if (parcel.ContainsPoint((int)parcel.LandData.UserLocation.X, (int)parcel.LandData.UserLocation.Y))
|
||||
{
|
||||
avatar.TeleportWithMomentum(temptarget);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int x = 0; x <= Constants.RegionSize / 3; x += 3)
|
||||
{
|
||||
for (int y = 0; y <= Constants.RegionSize / 3; y += 3)
|
||||
{
|
||||
if (parcel.ContainsPoint(x, y))
|
||||
{
|
||||
temptarget = new Vector3(x, y, avatar.AbsolutePosition.Z);
|
||||
avatar.TeleportWithMomentum(temptarget);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//Move to region side
|
||||
if (avatar.AbsolutePosition.X > avatar.AbsolutePosition.Y)
|
||||
{
|
||||
if (avatar.AbsolutePosition.X > .5 * Constants.RegionSize)
|
||||
{
|
||||
Vector3 target = new Vector3(Constants.RegionSize, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z); ;
|
||||
avatar.TeleportWithMomentum(target);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector3 target = new Vector3(0, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z); ;
|
||||
avatar.TeleportWithMomentum(target);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (avatar.AbsolutePosition.Y > .5 * Constants.RegionSize)
|
||||
{
|
||||
Vector3 target = new Vector3(avatar.AbsolutePosition.X, Constants.RegionSize, avatar.AbsolutePosition.Z); ;
|
||||
avatar.TeleportWithMomentum(target);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector3 target = new Vector3(avatar.AbsolutePosition.X, 0, avatar.AbsolutePosition.Z); ;
|
||||
avatar.TeleportWithMomentum(target);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,16 +392,7 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||
{
|
||||
if (parcelAvatarIsEntering.IsBannedFromLand(avatar.UUID))
|
||||
{
|
||||
SendYouAreBannedNotice(avatar);
|
||||
}
|
||||
else if (parcelAvatarIsEntering.IsRestrictedFromLand(avatar.UUID))
|
||||
{
|
||||
avatar.ControllingClient.SendAlertMessage(
|
||||
"You are not allowed on this parcel because the land owner has restricted access. For now, you can enter, but please respect the land owner's decisions (or he can ban you!).");
|
||||
}
|
||||
else
|
||||
{
|
||||
avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
|
||||
MoveUserOutOfParcel(avatar);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -317,28 +403,47 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||
}
|
||||
}
|
||||
|
||||
public void SendOutNearestBanLine(IClientAPI avatar)
|
||||
public void SendOutNearestBanLine(ScenePresence avatar)
|
||||
{
|
||||
List<ScenePresence> avatars = m_scene.GetAvatars();
|
||||
foreach (ScenePresence presence in avatars)
|
||||
ILandObject checkBan = null;
|
||||
for (int x = -2; x <= 2; x += 2)
|
||||
{
|
||||
if (presence.UUID == avatar.AgentId)
|
||||
checkBan = GetLandObject(avatar.AbsolutePosition.X + x, avatar.AbsolutePosition.Y);
|
||||
if (checkBan != null)
|
||||
{
|
||||
List<ILandObject> checkLandParcels = ParcelsNearPoint(presence.AbsolutePosition);
|
||||
foreach (ILandObject checkBan in checkLandParcels)
|
||||
if (avatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT)
|
||||
{
|
||||
if (checkBan.IsBannedFromLand(avatar.AgentId))
|
||||
if (checkBan.IsRestrictedFromLand(avatar.ControllingClient.AgentId))
|
||||
{
|
||||
checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionBanned, false, (int)ParcelResult.Single, avatar);
|
||||
return; //Only send one
|
||||
checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionNotOnAccessList, true, (int)ParcelResult.Multiple, avatar.ControllingClient);
|
||||
return;
|
||||
}
|
||||
if (checkBan.IsRestrictedFromLand(avatar.AgentId))
|
||||
if (checkBan.IsBannedFromLand(avatar.ControllingClient.AgentId))
|
||||
{
|
||||
checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionNotOnAccessList, false, (int)ParcelResult.Single, avatar);
|
||||
return; //Only send one
|
||||
checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionBanned, true, (int)ParcelResult.Multiple, avatar.ControllingClient);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int y = -2; y <= 2; y += 2)
|
||||
{
|
||||
checkBan = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y + y);
|
||||
if (checkBan != null)
|
||||
{
|
||||
if (avatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT)
|
||||
{
|
||||
if (checkBan.IsRestrictedFromLand(avatar.ControllingClient.AgentId))
|
||||
{
|
||||
checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionNotOnAccessList, true, (int)ParcelResult.Multiple, avatar.ControllingClient);
|
||||
return;
|
||||
}
|
||||
if (checkBan.IsBannedFromLand(avatar.ControllingClient.AgentId))
|
||||
{
|
||||
checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionBanned, true, (int)ParcelResult.Multiple, avatar.ControllingClient);
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -385,25 +490,14 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||
if (clientAvatar != null)
|
||||
{
|
||||
SendLandUpdate(clientAvatar);
|
||||
SendOutNearestBanLine(remote_client);
|
||||
SendOutNearestBanLine(clientAvatar);
|
||||
ILandObject parcel = GetLandObject(clientAvatar.AbsolutePosition.X, clientAvatar.AbsolutePosition.Y);
|
||||
if (parcel != null)
|
||||
{
|
||||
if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT &&
|
||||
clientAvatar.sentMessageAboutRestrictedParcelFlyingDown)
|
||||
{
|
||||
EventManagerOnAvatarEnteringNewParcel(clientAvatar, parcel.LandData.LocalID,
|
||||
m_scene.RegionInfo.RegionID);
|
||||
//They are going under the safety line!
|
||||
if (!parcel.IsBannedFromLand(clientAvatar.UUID))
|
||||
{
|
||||
clientAvatar.sentMessageAboutRestrictedParcelFlyingDown = false;
|
||||
}
|
||||
}
|
||||
else if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT &&
|
||||
parcel.IsBannedFromLand(clientAvatar.UUID))
|
||||
{
|
||||
SendYouAreBannedNotice(clientAvatar);
|
||||
MoveUserOutOfParcel(clientAvatar);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -451,9 +545,21 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||
|
||||
if (land != null)
|
||||
{
|
||||
if (agentID == land.LandData.OwnerID)
|
||||
if (m_scene.Permissions.CanEditParcel(agentID, land))
|
||||
{
|
||||
land.UpdateAccessList(flags, entries, remote_client);
|
||||
List<ScenePresence> presences = ((Scene)remote_client.Scene).GetAvatars();
|
||||
foreach (ScenePresence presence in presences)
|
||||
{
|
||||
land = GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y);
|
||||
if (land != null)
|
||||
{
|
||||
if (land.IsEitherBannedOrRestricted(presence.UUID))
|
||||
{
|
||||
MoveUserOutOfParcel(presence);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1019,7 +1125,25 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||
m_landList.TryGetValue(localID, out land);
|
||||
}
|
||||
|
||||
if (land != null) land.UpdateLandProperties(args, remote_client);
|
||||
if (land != null)
|
||||
{
|
||||
land.UpdateLandProperties(args, remote_client);
|
||||
if ((args.ParcelFlags & (uint)(ParcelFlags.UseBanList | ParcelFlags.UseAccessList | ParcelFlags.UseAccessGroup | ParcelFlags.UsePassList)) != 0)
|
||||
{
|
||||
List<ScenePresence> presences = ((Scene)remote_client.Scene).GetAvatars();
|
||||
foreach (ScenePresence presence in presences)
|
||||
{
|
||||
land = GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y);
|
||||
if (land != null)
|
||||
{
|
||||
if (land.IsEitherBannedOrRestricted(presence.UUID))
|
||||
{
|
||||
MoveUserOutOfParcel(presence);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ClientOnParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client)
|
||||
@@ -1437,5 +1561,319 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||
|
||||
UpdateLandObject(localID, land.LandData);
|
||||
}
|
||||
public void ClientOnParcelGodMark(IClientAPI client, UUID god, int landID)
|
||||
{
|
||||
ILandObject land = null;
|
||||
List<ILandObject> Land = ((Scene)client.Scene).LandChannel.AllParcels();
|
||||
foreach (ILandObject landObject in Land)
|
||||
{
|
||||
if (landObject.LandData.LocalID == landID)
|
||||
{
|
||||
land = landObject;
|
||||
}
|
||||
}
|
||||
land.DeedToGroup(DefaultGodParcelGroup);
|
||||
land.LandData.Name = DefaultGodParcelName;
|
||||
land.SendLandUpdateToAvatarsOverMe();
|
||||
}
|
||||
private void ClientOnSimWideDeletes(IClientAPI client, UUID agentID, int flags, UUID targetID)
|
||||
{
|
||||
ScenePresence SP;
|
||||
((Scene)client.Scene).TryGetAvatar(client.AgentId, out SP);
|
||||
List<SceneObjectGroup> returns = new List<SceneObjectGroup>();
|
||||
if (SP.GodLevel != 0)
|
||||
{
|
||||
if (flags == 0) //All parcels, scripted or not
|
||||
{
|
||||
((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
|
||||
{
|
||||
if (e.OwnerID == targetID)
|
||||
{
|
||||
returns.Add(e);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
if (flags == 4) //All parcels, scripted object
|
||||
{
|
||||
((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
|
||||
{
|
||||
if (e.OwnerID == targetID)
|
||||
{
|
||||
if (e.scriptScore >= 0.01)
|
||||
{
|
||||
returns.Add(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
if (flags == 4) //not target parcel, scripted object
|
||||
{
|
||||
((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
|
||||
{
|
||||
if (e.OwnerID == targetID)
|
||||
{
|
||||
ILandObject landobject = ((Scene)client.Scene).LandChannel.GetLandObject(e.AbsolutePosition.X, e.AbsolutePosition.Y);
|
||||
if (landobject.LandData.OwnerID != e.OwnerID)
|
||||
{
|
||||
if (e.scriptScore >= 0.01)
|
||||
{
|
||||
returns.Add(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
foreach (SceneObjectGroup ol in returns)
|
||||
{
|
||||
ReturnObject(ol, client);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void ReturnObject(SceneObjectGroup obj, IClientAPI client)
|
||||
{
|
||||
SceneObjectGroup[] objs = new SceneObjectGroup[1];
|
||||
objs[0] = obj;
|
||||
((Scene)client.Scene).returnObjects(objs, client.AgentId);
|
||||
}
|
||||
|
||||
Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>();
|
||||
|
||||
public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
|
||||
{
|
||||
ScenePresence targetAvatar = null;
|
||||
((Scene)client.Scene).TryGetAvatar(target, out targetAvatar);
|
||||
ScenePresence parcelManager = null;
|
||||
((Scene)client.Scene).TryGetAvatar(client.AgentId, out parcelManager);
|
||||
System.Threading.Timer Timer;
|
||||
|
||||
if (targetAvatar.GodLevel == 0)
|
||||
{
|
||||
ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y);
|
||||
if (!((Scene)client.Scene).Permissions.CanEditParcel(client.AgentId, land))
|
||||
return;
|
||||
if (flags == 0)
|
||||
{
|
||||
targetAvatar.AllowMovement = false;
|
||||
targetAvatar.ControllingClient.SendAlertMessage(parcelManager.Firstname + " " + parcelManager.Lastname + " has frozen you for 30 seconds. You cannot move or interact with the world.");
|
||||
parcelManager.ControllingClient.SendAlertMessage("Avatar Frozen.");
|
||||
System.Threading.TimerCallback timeCB = new System.Threading.TimerCallback(OnEndParcelFrozen);
|
||||
Timer = new System.Threading.Timer(timeCB, targetAvatar, 30000, 0);
|
||||
Timers.Add(targetAvatar.UUID, Timer);
|
||||
}
|
||||
else
|
||||
{
|
||||
targetAvatar.AllowMovement = true;
|
||||
targetAvatar.ControllingClient.SendAlertMessage(parcelManager.Firstname + " " + parcelManager.Lastname + " has unfrozen you.");
|
||||
parcelManager.ControllingClient.SendAlertMessage("Avatar Unfrozen.");
|
||||
Timers.TryGetValue(targetAvatar.UUID, out Timer);
|
||||
Timers.Remove(targetAvatar.UUID);
|
||||
Timer.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
private void OnEndParcelFrozen(object avatar)
|
||||
{
|
||||
ScenePresence targetAvatar = (ScenePresence)avatar;
|
||||
targetAvatar.AllowMovement = true;
|
||||
System.Threading.Timer Timer;
|
||||
Timers.TryGetValue(targetAvatar.UUID, out Timer);
|
||||
Timers.Remove(targetAvatar.UUID);
|
||||
targetAvatar.ControllingClient.SendAgentAlertMessage("The freeze has worn off; you may go about your business.", false);
|
||||
}
|
||||
|
||||
|
||||
public void ClientOnParcelEjectUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
|
||||
{
|
||||
ScenePresence targetAvatar = null;
|
||||
((Scene)client.Scene).TryGetAvatar(target, out targetAvatar);
|
||||
ScenePresence parcelManager = null;
|
||||
((Scene)client.Scene).TryGetAvatar(client.AgentId, out parcelManager);
|
||||
//Just eject
|
||||
if (flags == 0)
|
||||
{
|
||||
if (targetAvatar.GodLevel == 0)
|
||||
{
|
||||
ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y);
|
||||
if (!((Scene)client.Scene).Permissions.CanEditParcel(client.AgentId, land))
|
||||
return;
|
||||
|
||||
Vector3 position = new Vector3(0, 0, 0);
|
||||
List<ILandObject> allParcels = new List<ILandObject>();
|
||||
allParcels = AllParcels();
|
||||
if (allParcels.Count != 1)
|
||||
{
|
||||
foreach (ILandObject parcel in allParcels)
|
||||
{
|
||||
if (parcel.LandData.GlobalID != land.LandData.GlobalID)
|
||||
{
|
||||
if (parcel.IsEitherBannedOrRestricted(targetAvatar.UUID) != true)
|
||||
{
|
||||
for (int x = 1; x <= Constants.RegionSize; x += 2)
|
||||
{
|
||||
for (int y = 1; y <= Constants.RegionSize; y += 2)
|
||||
{
|
||||
if (parcel.ContainsPoint(x, y))
|
||||
{
|
||||
position = new Vector3(x, y, targetAvatar.AbsolutePosition.Z);
|
||||
targetAvatar.TeleportWithMomentum(position);
|
||||
targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname);
|
||||
parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Vector3 targetVector;
|
||||
if (targetAvatar.AbsolutePosition.X > targetAvatar.AbsolutePosition.Y)
|
||||
{
|
||||
if (targetAvatar.AbsolutePosition.X > .5 * Constants.RegionSize)
|
||||
{
|
||||
targetVector = new Vector3(Constants.RegionSize, targetAvatar.AbsolutePosition.Y, targetAvatar.AbsolutePosition.Z); ;
|
||||
targetAvatar.TeleportWithMomentum(targetVector);
|
||||
targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname);
|
||||
parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected.");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetVector = new Vector3(0, targetAvatar.AbsolutePosition.Y, targetAvatar.AbsolutePosition.Z); ;
|
||||
targetAvatar.TeleportWithMomentum(targetVector);
|
||||
targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname);
|
||||
parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (targetAvatar.AbsolutePosition.Y > .5 * Constants.RegionSize)
|
||||
{
|
||||
targetVector = new Vector3(targetAvatar.AbsolutePosition.X, Constants.RegionSize, targetAvatar.AbsolutePosition.Z); ;
|
||||
targetAvatar.TeleportWithMomentum(targetVector);
|
||||
targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname);
|
||||
parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected.");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetVector = new Vector3(targetAvatar.AbsolutePosition.X, 0, targetAvatar.AbsolutePosition.Z); ;
|
||||
targetAvatar.TeleportWithMomentum(targetVector);
|
||||
targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname);
|
||||
parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//Eject and ban
|
||||
if (flags == 1)
|
||||
{
|
||||
if (targetAvatar.GodLevel == 0)
|
||||
{
|
||||
ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y);
|
||||
if (!((Scene)client.Scene).Permissions.CanEditParcel(client.AgentId, land))
|
||||
return;
|
||||
|
||||
Vector3 position = new Vector3(0, 0, 0);
|
||||
List<ILandObject> allParcels = new List<ILandObject>();
|
||||
allParcels = AllParcels();
|
||||
if (allParcels.Count != 1)
|
||||
{
|
||||
foreach (ILandObject parcel in allParcels)
|
||||
{
|
||||
if (parcel.LandData.GlobalID != land.LandData.GlobalID)
|
||||
{
|
||||
if (parcel.IsEitherBannedOrRestricted(targetAvatar.UUID) != true)
|
||||
{
|
||||
for (int x = 1; x <= Constants.RegionSize; x += 2)
|
||||
{
|
||||
for (int y = 1; y <= Constants.RegionSize; y += 2)
|
||||
{
|
||||
if (parcel.ContainsPoint(x, y))
|
||||
{
|
||||
position = new Vector3(x, y, targetAvatar.AbsolutePosition.Z);
|
||||
targetAvatar.TeleportWithMomentum(position);
|
||||
targetAvatar.ControllingClient.SendAlertMessage("You have been ejected and banned by " + parcelManager.Firstname + " " + parcelManager.Lastname);
|
||||
parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected and Banned.");
|
||||
ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
|
||||
entry.AgentID = targetAvatar.UUID;
|
||||
entry.Flags = AccessList.Ban;
|
||||
entry.Time = new DateTime();
|
||||
land.LandData.ParcelAccessList.Add(entry);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Vector3 targetVector;
|
||||
if (targetAvatar.AbsolutePosition.X > targetAvatar.AbsolutePosition.Y)
|
||||
{
|
||||
if (targetAvatar.AbsolutePosition.X > .5 * Constants.RegionSize)
|
||||
{
|
||||
targetVector = new Vector3(Constants.RegionSize, targetAvatar.AbsolutePosition.Y, targetAvatar.AbsolutePosition.Z); ;
|
||||
targetAvatar.TeleportWithMomentum(targetVector);
|
||||
targetAvatar.ControllingClient.SendAlertMessage("You have been ejected and banned by " + parcelManager.Firstname + " " + parcelManager.Lastname);
|
||||
parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected and Banned.");
|
||||
ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
|
||||
entry.AgentID = targetAvatar.UUID;
|
||||
entry.Flags = AccessList.Ban;
|
||||
entry.Time = new DateTime();
|
||||
land.LandData.ParcelAccessList.Add(entry);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetVector = new Vector3(0, targetAvatar.AbsolutePosition.Y, targetAvatar.AbsolutePosition.Z); ;
|
||||
targetAvatar.TeleportWithMomentum(targetVector);
|
||||
targetAvatar.ControllingClient.SendAlertMessage("You have been ejected and banned by " + parcelManager.Firstname + " " + parcelManager.Lastname);
|
||||
parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected and Banned.");
|
||||
ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
|
||||
entry.AgentID = targetAvatar.UUID;
|
||||
entry.Flags = AccessList.Ban;
|
||||
entry.Time = new DateTime();
|
||||
land.LandData.ParcelAccessList.Add(entry);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (targetAvatar.AbsolutePosition.Y > .5 * Constants.RegionSize)
|
||||
{
|
||||
targetVector = new Vector3(targetAvatar.AbsolutePosition.X, Constants.RegionSize, targetAvatar.AbsolutePosition.Z); ;
|
||||
targetAvatar.TeleportWithMomentum(targetVector);
|
||||
targetAvatar.ControllingClient.SendAlertMessage("You have been ejected and banned by " + parcelManager.Firstname + " " + parcelManager.Lastname);
|
||||
parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected and Banned.");
|
||||
ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
|
||||
entry.AgentID = targetAvatar.UUID;
|
||||
entry.Flags = AccessList.Ban;
|
||||
entry.Time = new DateTime();
|
||||
land.LandData.ParcelAccessList.Add(entry);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetVector = new Vector3(targetAvatar.AbsolutePosition.X, 0, targetAvatar.AbsolutePosition.Z); ;
|
||||
targetAvatar.TeleportWithMomentum(targetVector);
|
||||
targetAvatar.ControllingClient.SendAlertMessage("You have been ejected and banned by " + parcelManager.Firstname + " " + parcelManager.Lastname);
|
||||
parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected and Banned.");
|
||||
ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
|
||||
entry.AgentID = targetAvatar.UUID;
|
||||
entry.Flags = AccessList.Ban;
|
||||
entry.Time = new DateTime();
|
||||
land.LandData.ParcelAccessList.Add(entry);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,11 +267,7 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||
|
||||
public bool IsEitherBannedOrRestricted(UUID avatar)
|
||||
{
|
||||
if (IsBannedFromLand(avatar))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (IsRestrictedFromLand(avatar))
|
||||
if (IsRestrictedFromLand(avatar) || IsBannedFromLand(avatar))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -280,7 +276,8 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||
|
||||
public bool IsBannedFromLand(UUID avatar)
|
||||
{
|
||||
if ((LandData.Flags & (uint) ParcelFlags.UseBanList) > 0)
|
||||
ScenePresence SP = m_scene.GetScenePresence(avatar);
|
||||
if ((LandData.Flags & (uint)ParcelFlags.UseBanList) > 0)
|
||||
{
|
||||
ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
|
||||
entry.AgentID = avatar;
|
||||
@@ -288,8 +285,22 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||
entry.Time = new DateTime();
|
||||
if (LandData.ParcelAccessList.Contains(entry))
|
||||
{
|
||||
//They are banned, so lets send them a notice about this parcel
|
||||
return true;
|
||||
if ((LandData.Flags & (uint)ParcelFlags.UseAccessGroup) > 0)
|
||||
{
|
||||
if (LandData.GroupID == SP.ControllingClient.ActiveGroupId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -297,7 +308,8 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||
|
||||
public bool IsRestrictedFromLand(UUID avatar)
|
||||
{
|
||||
if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) > 0)
|
||||
ScenePresence SP = m_scene.GetScenePresence(avatar);
|
||||
if ((LandData.Flags & (uint)ParcelFlags.UseAccessList) > 0)
|
||||
{
|
||||
ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
|
||||
entry.AgentID = avatar;
|
||||
@@ -305,8 +317,22 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||
entry.Time = new DateTime();
|
||||
if (!LandData.ParcelAccessList.Contains(entry))
|
||||
{
|
||||
//They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel
|
||||
return true;
|
||||
if ((LandData.Flags & (uint)ParcelFlags.UseAccessGroup) > 0)
|
||||
{
|
||||
if (LandData.GroupID == SP.ControllingClient.ActiveGroupId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -0,0 +1,274 @@
|
||||
/*
|
||||
* Copyright (c) Thomas Grimshaw and Magne Metaverse Research
|
||||
*
|
||||
* This module is not open source. All rights reserved.
|
||||
* Unauthorised copying, distribution or public display is prohibited.
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using OpenMetaverse;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenSim.Data;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.CoreModules.Framework.InterfaceCommander;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
|
||||
|
||||
namespace OpenSim.Region.CoreModules.World.Meta7Windlight
|
||||
{
|
||||
public class Meta7WindlightModule : IRegionModule, 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 IRegionModule Members
|
||||
|
||||
public static bool EnableWindlight
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_enableWindlight;
|
||||
}
|
||||
set
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
m_scene = scene;
|
||||
m_scene.RegisterModuleInterface<IRegionModule>(this);
|
||||
m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole;
|
||||
|
||||
// ini file settings
|
||||
try
|
||||
{
|
||||
m_enableWindlight = config.Configs["Meta7Windlight"].GetBoolean("enable_windlight", false);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
m_log.Debug("[WINDLIGHT]: ini failure for enable_windlight - using default");
|
||||
}
|
||||
|
||||
if (m_enableWindlight)
|
||||
{
|
||||
m_scene.EventManager.OnMakeRootAgent += EventManager_OnMakeRootAgent;
|
||||
m_scene.EventManager.OnSaveNewWindlightProfile += EventManager_OnSaveNewWindlightProfile;
|
||||
m_scene.EventManager.OnSendNewWindlightProfileTargeted += EventManager_OnSendNewWindlightProfileTargeted;
|
||||
}
|
||||
|
||||
InstallCommands();
|
||||
|
||||
m_log.Debug("[WINDLIGHT]: Initialised windlight module");
|
||||
}
|
||||
|
||||
private List<byte[]> compileWindlightSettings(RegionMeta7WindlightData 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<byte[]> param = new List<byte[]>();
|
||||
param.Add(mBlock);
|
||||
return param;
|
||||
}
|
||||
public void SendProfileToClient(ScenePresence presence)
|
||||
{
|
||||
IClientAPI client = presence.ControllingClient;
|
||||
if (m_enableWindlight)
|
||||
{
|
||||
if (presence.IsChildAgent == false)
|
||||
{
|
||||
List<byte[]> param = compileWindlightSettings(m_scene.RegionInfo.WindlightSettings);
|
||||
client.SendGenericMessage("Windlight", param);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//We probably don't want to spam chat with this.. probably
|
||||
//m_log.Debug("[WINDLIGHT]: Module disabled");
|
||||
}
|
||||
}
|
||||
public void SendProfileToClient(ScenePresence presence, RegionMeta7WindlightData wl)
|
||||
{
|
||||
IClientAPI client = presence.ControllingClient;
|
||||
if (m_enableWindlight)
|
||||
{
|
||||
if (presence.IsChildAgent == false)
|
||||
{
|
||||
List<byte[]> param = compileWindlightSettings(wl);
|
||||
client.SendGenericMessage("Windlight", param);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//We probably don't want to spam chat with this.. probably
|
||||
//m_log.Debug("[WINDLIGHT]: Module disabled");
|
||||
}
|
||||
}
|
||||
private void EventManager_OnMakeRootAgent(ScenePresence presence)
|
||||
{
|
||||
m_log.Debug("[WINDLIGHT]: Sending windlight scene to new client");
|
||||
SendProfileToClient(presence);
|
||||
}
|
||||
private void EventManager_OnSendNewWindlightProfileTargeted(RegionMeta7WindlightData wl, UUID pUUID)
|
||||
{
|
||||
ScenePresence Sc;
|
||||
if (m_scene.TryGetAvatar(pUUID,out Sc))
|
||||
{
|
||||
SendProfileToClient(Sc,wl);
|
||||
}
|
||||
}
|
||||
private void EventManager_OnSaveNewWindlightProfile()
|
||||
{
|
||||
m_scene.ForEachScenePresence(SendProfileToClient);
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "Meta7WindlightModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region events
|
||||
|
||||
#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, "Enable 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes commandline input. Do not call directly.
|
||||
/// </summary>
|
||||
/// <param name="args">Commandline arguments</param>
|
||||
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
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -453,7 +453,7 @@ namespace OpenSim.Region.Examples.SimpleModule
|
||||
|
||||
}
|
||||
|
||||
public void SendGenericMessage(string method, List<string> message)
|
||||
public void SendGenericMessage(string method, List<byte[]> message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -103,6 +103,8 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
|
||||
void StoreRegionSettings(RegionSettings rs);
|
||||
RegionSettings LoadRegionSettings(UUID regionUUID);
|
||||
RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID);
|
||||
void StoreRegionWindlightSettings(RegionMeta7WindlightData wl);
|
||||
|
||||
void Shutdown();
|
||||
}
|
||||
|
||||
@@ -53,8 +53,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation
|
||||
{
|
||||
get { return m_movementAnimation; }
|
||||
}
|
||||
protected string m_movementAnimation = "DEFAULT";
|
||||
|
||||
// protected string m_movementAnimation = "DEFAULT"; //KF: 'DEFAULT' does not exist!
|
||||
protected string m_movementAnimation = "CROUCH"; //KF: CROUCH ensures reliable Av Anim. init.
|
||||
private int m_animTickFall;
|
||||
private int m_animTickJump;
|
||||
|
||||
@@ -123,17 +123,22 @@ namespace OpenSim.Region.Framework.Scenes.Animation
|
||||
/// </summary>
|
||||
public void TrySetMovementAnimation(string anim)
|
||||
{
|
||||
//m_log.DebugFormat("Updating movement animation to {0}", anim);
|
||||
//Console.WriteLine("Updating movement animation to {0}", anim);
|
||||
|
||||
if (!m_scenePresence.IsChildAgent)
|
||||
{
|
||||
if (m_animations.TrySetDefaultAnimation(
|
||||
anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID))
|
||||
{
|
||||
//Console.WriteLine("TSMA {0} success.", anim);
|
||||
// 16384 is CHANGED_ANIMATION
|
||||
m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { 16384 });
|
||||
SendAnimPack();
|
||||
}
|
||||
else
|
||||
{
|
||||
//Console.WriteLine("TSMA {0} fail.", anim);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,10 +151,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
|
||||
const float PREJUMP_DELAY = 0.25f;
|
||||
|
||||
#region Inputs
|
||||
if (m_scenePresence.SitGround)
|
||||
{
|
||||
return "SIT_GROUND_CONSTRAINED";
|
||||
}
|
||||
|
||||
AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags;
|
||||
PhysicsActor actor = m_scenePresence.PhysicsActor;
|
||||
|
||||
@@ -159,11 +161,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation
|
||||
Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix);
|
||||
|
||||
// Check control flags
|
||||
bool heldForward =
|
||||
(((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) || ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS));
|
||||
bool heldBack = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG;
|
||||
bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS;
|
||||
bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG;
|
||||
bool heldForward = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS);
|
||||
bool heldBack = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG);
|
||||
bool heldLeft = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS);
|
||||
bool heldRight = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG);
|
||||
//bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
|
||||
//bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
|
||||
bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS;
|
||||
@@ -316,7 +317,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
|
||||
public void UpdateMovementAnimations()
|
||||
{
|
||||
m_movementAnimation = GetMovementAnimation();
|
||||
|
||||
//Console.WriteLine("UMA got {0}", m_movementAnimation);
|
||||
if (m_movementAnimation == "PREJUMP" && !m_scenePresence.Scene.m_usePreJump)
|
||||
{
|
||||
// This was the previous behavior before PREJUMP
|
||||
@@ -454,4 +455,4 @@ namespace OpenSim.Region.Framework.Scenes.Animation
|
||||
m_scenePresence = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
private readonly Dictionary<UUID,EntityBase> m_eb_uuid = new Dictionary<UUID, EntityBase>();
|
||||
private readonly Dictionary<uint, EntityBase> m_eb_localID = new Dictionary<uint, EntityBase>();
|
||||
//private readonly Dictionary<UUID, ScenePresence> m_pres_uuid = new Dictionary<UUID, ScenePresence>();
|
||||
private readonly Object m_lock = new Object();
|
||||
private System.Threading.ReaderWriterLockSlim m_lock = new System.Threading.ReaderWriterLockSlim();
|
||||
|
||||
[Obsolete("Use Add() instead.")]
|
||||
public void Add(UUID id, EntityBase eb)
|
||||
@@ -50,7 +50,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
public void Add(EntityBase entity)
|
||||
{
|
||||
lock (m_lock)
|
||||
m_lock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -62,11 +63,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
m_log.ErrorFormat("Add Entity failed: {0}", e.Message);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_lock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
public void InsertOrReplace(EntityBase entity)
|
||||
{
|
||||
lock (m_lock)
|
||||
m_lock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -78,15 +84,24 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
m_log.ErrorFormat("Insert or Replace Entity failed: {0}", e.Message);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_lock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
lock (m_lock)
|
||||
m_lock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
m_eb_uuid.Clear();
|
||||
m_eb_localID.Clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_lock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
public int Count
|
||||
@@ -123,7 +138,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
public bool Remove(uint localID)
|
||||
{
|
||||
lock (m_lock)
|
||||
m_lock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -141,11 +157,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
return false;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_lock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
public bool Remove(UUID id)
|
||||
{
|
||||
lock (m_lock)
|
||||
m_lock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -163,13 +184,18 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
return false;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_lock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
public List<EntityBase> GetAllByType<T>()
|
||||
{
|
||||
List<EntityBase> tmp = new List<EntityBase>();
|
||||
|
||||
lock (m_lock)
|
||||
m_lock.EnterReadLock();
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -187,23 +213,33 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
tmp = null;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_lock.ExitReadLock();
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
public List<EntityBase> GetEntities()
|
||||
{
|
||||
lock (m_lock)
|
||||
m_lock.EnterReadLock();
|
||||
try
|
||||
{
|
||||
return new List<EntityBase>(m_eb_uuid.Values);
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_lock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
public EntityBase this[UUID id]
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (m_lock)
|
||||
m_lock.EnterReadLock();
|
||||
try
|
||||
{
|
||||
EntityBase entity;
|
||||
if (m_eb_uuid.TryGetValue(id, out entity))
|
||||
@@ -211,6 +247,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
else
|
||||
return null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_lock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
@@ -222,7 +262,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (m_lock)
|
||||
m_lock.EnterReadLock();
|
||||
try
|
||||
{
|
||||
EntityBase entity;
|
||||
if (m_eb_localID.TryGetValue(localID, out entity))
|
||||
@@ -230,6 +271,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
else
|
||||
return null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_lock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
@@ -239,18 +284,28 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
public bool TryGetValue(UUID key, out EntityBase obj)
|
||||
{
|
||||
lock (m_lock)
|
||||
m_lock.EnterReadLock();
|
||||
try
|
||||
{
|
||||
return m_eb_uuid.TryGetValue(key, out obj);
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_lock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetValue(uint key, out EntityBase obj)
|
||||
{
|
||||
lock (m_lock)
|
||||
m_lock.EnterReadLock();
|
||||
try
|
||||
{
|
||||
return m_eb_localID.TryGetValue(key, out obj);
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_lock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -205,7 +205,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
public event OnMakeChildAgentDelegate OnMakeChildAgent;
|
||||
|
||||
public delegate void OnMakeRootAgentDelegate(ScenePresence presence);
|
||||
public delegate void OnSaveNewWindlightProfileDelegate();
|
||||
public delegate void OnSendNewWindlightProfileTargetedDelegate(RegionMeta7WindlightData wl, UUID user);
|
||||
public event OnMakeRootAgentDelegate OnMakeRootAgent;
|
||||
public event OnSendNewWindlightProfileTargetedDelegate OnSendNewWindlightProfileTargeted;
|
||||
public event OnSaveNewWindlightProfileDelegate OnSaveNewWindlightProfile;
|
||||
|
||||
public delegate void NewInventoryItemUploadComplete(UUID avatarID, UUID assetID, string name, int userlevel);
|
||||
|
||||
@@ -425,6 +429,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
private IncomingInstantMessage handlerUnhandledInstantMessage = null; //OnUnhandledInstantMessage;
|
||||
private ClientClosed handlerClientClosed = null; //OnClientClosed;
|
||||
private OnMakeChildAgentDelegate handlerMakeChildAgent = null; //OnMakeChildAgent;
|
||||
private OnSaveNewWindlightProfileDelegate handlerSaveNewWindlightProfile = null; //OnSaveNewWindlightProfile;
|
||||
private OnSendNewWindlightProfileTargetedDelegate handlerSendNewWindlightProfileTargeted = null; //OnSendNewWindlightProfileTargeted;
|
||||
private OnMakeRootAgentDelegate handlerMakeRootAgent = null; //OnMakeRootAgent;
|
||||
private OnTerrainTickDelegate handlerTerrainTick = null; // OnTerainTick;
|
||||
private RegisterCapsEvent handlerRegisterCaps = null; // OnRegisterCaps;
|
||||
@@ -789,6 +795,24 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
public void TriggerOnSendNewWindlightProfileTargeted(RegionMeta7WindlightData wl, UUID user)
|
||||
{
|
||||
handlerSendNewWindlightProfileTargeted = OnSendNewWindlightProfileTargeted;
|
||||
if (handlerSendNewWindlightProfileTargeted != null)
|
||||
{
|
||||
handlerSendNewWindlightProfileTargeted(wl, user);
|
||||
}
|
||||
}
|
||||
|
||||
public void TriggerOnSaveNewWindlightProfile()
|
||||
{
|
||||
handlerSaveNewWindlightProfile = OnSaveNewWindlightProfile;
|
||||
if (handlerSaveNewWindlightProfile != null)
|
||||
{
|
||||
handlerSaveNewWindlightProfile();
|
||||
}
|
||||
}
|
||||
|
||||
public void TriggerOnMakeRootAgent(ScenePresence presence)
|
||||
{
|
||||
handlerMakeRootAgent = OnMakeRootAgent;
|
||||
|
||||
@@ -846,8 +846,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID)
|
||||
{
|
||||
SceneObjectPart part = GetSceneObjectPart(localID);
|
||||
SceneObjectGroup group = part.ParentGroup;
|
||||
if (group != null)
|
||||
SceneObjectGroup group = null;
|
||||
if (part != null)
|
||||
{
|
||||
group = part.ParentGroup;
|
||||
}
|
||||
if (part != null && group != null)
|
||||
{
|
||||
TaskInventoryItem item = group.GetInventoryItem(localID, itemID);
|
||||
if (item == null)
|
||||
@@ -1799,8 +1803,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
else
|
||||
{
|
||||
item.BasePermissions = objectGroup.GetEffectivePermissions();
|
||||
item.CurrentPermissions = objectGroup.GetEffectivePermissions();
|
||||
uint ownerPerms = objectGroup.GetEffectivePermissions();
|
||||
if ((objectGroup.RootPart.OwnerMask & (uint)PermissionMask.Modify) != 0)
|
||||
ownerPerms |= (uint)PermissionMask.Modify;
|
||||
|
||||
item.BasePermissions = ownerPerms;
|
||||
item.CurrentPermissions = ownerPerms;
|
||||
|
||||
item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
|
||||
item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask;
|
||||
item.GroupPermissions = objectGroup.RootPart.GroupMask;
|
||||
|
||||
@@ -539,6 +539,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
// Load region settings
|
||||
m_regInfo.RegionSettings = m_storageManager.DataStore.LoadRegionSettings(m_regInfo.RegionID);
|
||||
m_regInfo.WindlightSettings = m_storageManager.DataStore.LoadRegionWindlightSettings(m_regInfo.RegionID);
|
||||
|
||||
if (m_storageManager.EstateDataStore != null)
|
||||
{
|
||||
m_regInfo.EstateSettings = m_storageManager.EstateDataStore.LoadEstateSettings(m_regInfo.RegionID);
|
||||
@@ -885,6 +887,15 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </summary>
|
||||
/// <param name="seconds">float indicating duration before restart.</param>
|
||||
public virtual void Restart(float seconds)
|
||||
{
|
||||
Restart(seconds, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Given float seconds, this will restart the region. showDialog will optionally alert the users.
|
||||
/// </summary>
|
||||
/// <param name="seconds">float indicating duration before restart.</param>
|
||||
public virtual void Restart(float seconds, bool showDialog)
|
||||
{
|
||||
// notifications are done in 15 second increments
|
||||
// so .. if the number of seconds is less then 15 seconds, it's not really a restart request
|
||||
@@ -906,8 +917,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
m_restartTimer.Elapsed += new ElapsedEventHandler(RestartTimer_Elapsed);
|
||||
m_log.Info("[REGION]: Restarting Region in " + (seconds / 60) + " minutes");
|
||||
m_restartTimer.Start();
|
||||
m_dialogModule.SendNotificationToUsersInRegion(
|
||||
if (showDialog)
|
||||
{
|
||||
m_dialogModule.SendNotificationToUsersInRegion(
|
||||
UUID.Random(), String.Empty, RegionInfo.RegionName + String.Format(": Restarting in {0} Minutes", (int)(seconds / 60.0)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1189,16 +1203,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// Check if any objects have reached their targets
|
||||
CheckAtTargets();
|
||||
|
||||
// Update SceneObjectGroups that have scheduled themselves for updates
|
||||
// Objects queue their updates onto all scene presences
|
||||
if (m_frame % m_update_objects == 0)
|
||||
m_sceneGraph.UpdateObjectGroups();
|
||||
|
||||
// Run through all ScenePresences looking for updates
|
||||
// Presence updates and queued object updates for each presence are sent to clients
|
||||
if (m_frame % m_update_presences == 0)
|
||||
m_sceneGraph.UpdatePresences();
|
||||
|
||||
// Update SceneObjectGroups that have scheduled themselves for updates
|
||||
// Objects queue their updates onto all scene presences
|
||||
if (m_frame % m_update_objects == 0)
|
||||
m_sceneGraph.UpdateObjectGroups();
|
||||
|
||||
int tmpPhysicsMS2 = Util.EnvironmentTickCount();
|
||||
if ((m_frame % m_update_physics == 0) && m_physics_enabled)
|
||||
m_sceneGraph.UpdatePreparePhysics();
|
||||
@@ -1509,6 +1523,19 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
public void SaveTerrain()
|
||||
{
|
||||
m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
|
||||
}
|
||||
|
||||
public void StoreWindlightProfile(RegionMeta7WindlightData wl)
|
||||
{
|
||||
m_regInfo.WindlightSettings = wl;
|
||||
m_storageManager.DataStore.StoreRegionWindlightSettings(wl);
|
||||
m_eventManager.TriggerOnSaveNewWindlightProfile();
|
||||
}
|
||||
|
||||
public void LoadWindlightProfile()
|
||||
{
|
||||
m_regInfo.WindlightSettings = m_storageManager.DataStore.LoadRegionWindlightSettings(RegionInfo.RegionID);
|
||||
m_eventManager.TriggerOnSaveNewWindlightProfile();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -3391,6 +3418,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
CapsModule.AddCapsHandler(agent.AgentID);
|
||||
|
||||
if ((teleportFlags & ((uint)TeleportFlags.ViaLandmark | (uint)TeleportFlags.ViaLocation | (uint)TeleportFlags.ViaLandmark | (uint)TeleportFlags.Default)) != 0)
|
||||
System.Threading.Thread.Sleep(2000);
|
||||
|
||||
if (!agent.child)
|
||||
{
|
||||
if (TestBorderCross(agent.startpos,Cardinals.E))
|
||||
@@ -3449,6 +3479,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
// Honor parcel landing type and position.
|
||||
/*
|
||||
ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
|
||||
if (land != null)
|
||||
{
|
||||
@@ -3457,6 +3488,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
agent.startpos = land.LandData.UserLocation;
|
||||
}
|
||||
}
|
||||
*/// This is now handled properly in ScenePresence.MakeRootAgent
|
||||
}
|
||||
|
||||
m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
|
||||
|
||||
@@ -699,17 +699,42 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation {0} within {1}",
|
||||
position, m_regionInfo.RegionName);
|
||||
|
||||
// Teleport within the same region
|
||||
if (IsOutsideRegion(avatar.Scene, position) || position.Z < 0)
|
||||
{
|
||||
Vector3 emergencyPos = new Vector3(128, 128, 128);
|
||||
|
||||
m_log.WarnFormat(
|
||||
"[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}",
|
||||
position, avatar.Name, avatar.UUID, emergencyPos);
|
||||
position = emergencyPos;
|
||||
position, m_regionInfo.RegionName);
|
||||
|
||||
// Teleport within the same region
|
||||
if (IsOutsideRegion(avatar.Scene, position) || position.Z < 0)
|
||||
{
|
||||
Vector3 emergencyPos = new Vector3(128, 128, 128);
|
||||
|
||||
m_log.WarnFormat(
|
||||
"[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}",
|
||||
position, avatar.Name, avatar.UUID, emergencyPos);
|
||||
position = emergencyPos;
|
||||
}
|
||||
|
||||
Vector3 currentPos = avatar.AbsolutePosition;
|
||||
ILandObject srcLand = m_scene.LandChannel.GetLandObject(currentPos.X, currentPos.Y);
|
||||
ILandObject destLand = m_scene.LandChannel.GetLandObject(position.X, position.Y);
|
||||
if (srcLand != null && destLand != null && (teleportFlags & (uint)TeleportFlags.ViaLure) == 0 && (teleportFlags & (uint)TeleportFlags.ViaGodlikeLure) == 0)
|
||||
{
|
||||
if (srcLand.LandData.LocalID == destLand.LandData.LocalID)
|
||||
{
|
||||
//TPing within the same parcel. If the landing point is restricted, block the TP.
|
||||
//Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
|
||||
if (destLand.LandData.LandingType == (byte)1 && destLand.LandData.UserLocation != Vector3.Zero && avatar.GodLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar.UUID) && destLand.LandData.OwnerID != avatar.UUID)
|
||||
{
|
||||
avatar.ControllingClient.SendAgentAlertMessage("Can't TP to the destination; landing point set.", false);
|
||||
position = currentPos;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Tping to a different parcel. Respect the landing point on the destination parcel.
|
||||
if (destLand.LandData.LandingType == (byte)1 && destLand.LandData.UserLocation != Vector3.Zero && avatar.GodLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar.UUID) && destLand.LandData.OwnerID != avatar.UUID)
|
||||
{
|
||||
position = destLand.LandData.UserLocation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Get proper AVG Height
|
||||
|
||||
@@ -222,6 +222,30 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
protected internal bool AddRestoredSceneObject(
|
||||
SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted)
|
||||
{
|
||||
// KF: Check for out-of-region, move inside and make static.
|
||||
Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X,
|
||||
sceneObject.RootPart.GroupPosition.Y,
|
||||
sceneObject.RootPart.GroupPosition.Z);
|
||||
if (!(((sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) && (sceneObject.RootPart.Shape.State != 0))) && (npos.X < 0.0 || npos.Y < 0.0 || npos.Z < 0.0 ||
|
||||
npos.X > Constants.RegionSize ||
|
||||
npos.Y > Constants.RegionSize))
|
||||
{
|
||||
if (npos.X < 0.0) npos.X = 1.0f;
|
||||
if (npos.Y < 0.0) npos.Y = 1.0f;
|
||||
if (npos.Z < 0.0) npos.Z = 0.0f;
|
||||
if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f;
|
||||
if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f;
|
||||
|
||||
foreach (SceneObjectPart part in sceneObject.Children.Values)
|
||||
{
|
||||
part.GroupPosition = npos;
|
||||
}
|
||||
sceneObject.RootPart.Velocity = Vector3.Zero;
|
||||
sceneObject.RootPart.AngularVelocity = Vector3.Zero;
|
||||
sceneObject.RootPart.Acceleration = Vector3.Zero;
|
||||
sceneObject.RootPart.Velocity = Vector3.Zero;
|
||||
}
|
||||
|
||||
if (!alreadyPersisted)
|
||||
{
|
||||
sceneObject.ForceInventoryPersistence();
|
||||
@@ -542,6 +566,18 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
if (group.GetFromItemID() == itemID)
|
||||
{
|
||||
m_parentScene.SendAttachEvent(group.LocalId, itemID, UUID.Zero);
|
||||
bool hasScripts = false;
|
||||
foreach (SceneObjectPart part in group.Children.Values)
|
||||
{
|
||||
if (part.Inventory.ContainsScripts())
|
||||
{
|
||||
hasScripts = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasScripts) // Allow the object to execute the attach(NULL_KEY) event
|
||||
System.Threading.Thread.Sleep(100);
|
||||
group.DetachToInventoryPrep();
|
||||
m_log.Debug("[DETACH]: Saving attachpoint: " +
|
||||
((uint)group.GetAttachmentPoint()).ToString());
|
||||
|
||||
@@ -46,12 +46,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </summary>
|
||||
public void ForceInventoryPersistence()
|
||||
{
|
||||
lock (m_parts)
|
||||
lockPartsForRead(true);
|
||||
List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
|
||||
lockPartsForRead(false);
|
||||
foreach (SceneObjectPart part in values)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
{
|
||||
part.Inventory.ForceInventoryPersistence();
|
||||
}
|
||||
part.Inventory.ForceInventoryPersistence();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,14 +75,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// Stop the scripts contained in all the prims in this group
|
||||
/// </summary>
|
||||
public void RemoveScriptInstances()
|
||||
{
|
||||
lock (m_parts)
|
||||
{
|
||||
lockPartsForRead(true);
|
||||
List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
|
||||
lockPartsForRead(false);
|
||||
|
||||
foreach (SceneObjectPart part in values)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
{
|
||||
part.Inventory.RemoveScriptInstances();
|
||||
}
|
||||
part.Inventory.RemoveScriptInstances();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -109,7 +109,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
// TODO: This needs to be persisted in next XML version update!
|
||||
[XmlIgnore]
|
||||
public readonly int[] PayPrice = {-2,-2,-2,-2,-2};
|
||||
public int[] PayPrice = {-2,-2,-2,-2,-2};
|
||||
[XmlIgnore]
|
||||
public PhysicsActor PhysActor;
|
||||
|
||||
@@ -224,6 +224,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
private Quaternion m_sitTargetOrientation = Quaternion.Identity;
|
||||
private Vector3 m_sitTargetPosition;
|
||||
private string m_sitAnimation = "SIT";
|
||||
private bool m_occupied; // KF if any av is sitting on this prim
|
||||
private string m_text = String.Empty;
|
||||
private string m_touchName = String.Empty;
|
||||
private readonly UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5);
|
||||
@@ -401,12 +402,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
|
||||
/// <value>
|
||||
/// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes
|
||||
/// Get the inventory list
|
||||
/// </value>
|
||||
public TaskInventoryDictionary TaskInventory
|
||||
{
|
||||
get { return m_inventory.Items; }
|
||||
set { m_inventory.Items = value; }
|
||||
get {
|
||||
return m_inventory.Items;
|
||||
}
|
||||
set {
|
||||
m_inventory.Items = value;
|
||||
}
|
||||
}
|
||||
|
||||
public uint ObjectFlags
|
||||
@@ -550,7 +555,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
StoreUndoState();
|
||||
|
||||
m_groupPosition = value;
|
||||
|
||||
PhysicsActor actor = PhysActor;
|
||||
if (actor != null)
|
||||
{
|
||||
@@ -860,7 +864,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
if (IsAttachment)
|
||||
return GroupPosition;
|
||||
|
||||
return m_offsetPosition + m_groupPosition; }
|
||||
// return m_offsetPosition + m_groupPosition; }
|
||||
return m_groupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset) ; } //KF: Rotation was ignored!
|
||||
}
|
||||
|
||||
public SceneObjectGroup ParentGroup
|
||||
@@ -1012,6 +1017,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
get { return _flags; }
|
||||
set { _flags = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore]
|
||||
public bool IsOccupied // KF If an av is sittingon this prim
|
||||
{
|
||||
get { return m_occupied; }
|
||||
set { m_occupied = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore]
|
||||
public UUID SitTargetAvatar
|
||||
@@ -1087,14 +1099,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear all pending updates of parts to clients
|
||||
/// </summary>
|
||||
private void ClearUpdateSchedule()
|
||||
{
|
||||
m_updateFlag = 0;
|
||||
}
|
||||
|
||||
private void SendObjectPropertiesToClient(UUID AgentID)
|
||||
{
|
||||
ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
|
||||
@@ -1773,12 +1777,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
public Vector3 GetWorldPosition()
|
||||
{
|
||||
Quaternion parentRot = ParentGroup.RootPart.RotationOffset;
|
||||
|
||||
Vector3 axPos = OffsetPosition;
|
||||
|
||||
axPos *= parentRot;
|
||||
Vector3 translationOffsetPosition = axPos;
|
||||
return GroupPosition + translationOffsetPosition;
|
||||
if(_parentID == 0)
|
||||
{
|
||||
return GroupPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ParentGroup.AbsolutePosition + translationOffsetPosition; //KF: Fix child prim position
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1789,7 +1798,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
Quaternion newRot;
|
||||
|
||||
if (this.LinkNum == 0)
|
||||
if (this.LinkNum < 2) //KF Single or root prim
|
||||
{
|
||||
newRot = RotationOffset;
|
||||
}
|
||||
@@ -2446,17 +2455,18 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
//Trys to fetch sound id from prim's inventory.
|
||||
//Prim's inventory doesn't support non script items yet
|
||||
|
||||
lock (TaskInventory)
|
||||
TaskInventory.LockItemsForRead(true);
|
||||
|
||||
foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
|
||||
{
|
||||
foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
|
||||
if (item.Value.Name == sound)
|
||||
{
|
||||
if (item.Value.Name == sound)
|
||||
{
|
||||
soundID = item.Value.ItemID;
|
||||
break;
|
||||
}
|
||||
soundID = item.Value.ItemID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TaskInventory.LockItemsForRead(false);
|
||||
}
|
||||
|
||||
List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars();
|
||||
@@ -2731,8 +2741,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
const float ROTATION_TOLERANCE = 0.01f;
|
||||
const float VELOCITY_TOLERANCE = 0.001f;
|
||||
const float POSITION_TOLERANCE = 0.05f;
|
||||
const int TIME_MS_TOLERANCE = 3000;
|
||||
const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
|
||||
const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
|
||||
|
||||
if (m_updateFlag == 1)
|
||||
{
|
||||
@@ -2746,7 +2756,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE)
|
||||
{
|
||||
AddTerseUpdateToAllAvatars();
|
||||
ClearUpdateSchedule();
|
||||
|
||||
|
||||
// This causes the Scene to 'poll' physical objects every couple of frames
|
||||
// bad, so it's been replaced by an event driven method.
|
||||
@@ -2764,16 +2774,18 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
m_lastAngularVelocity = AngularVelocity;
|
||||
m_lastTerseSent = Environment.TickCount;
|
||||
}
|
||||
//Moved this outside of the if clause so updates don't get blocked.. *sigh*
|
||||
m_updateFlag = 0; //Why were we calling a function to do this? Inefficient! *screams*
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes
|
||||
{
|
||||
AddFullUpdateToAllAvatars();
|
||||
ClearUpdateSchedule();
|
||||
m_updateFlag = 0; //Same here
|
||||
}
|
||||
}
|
||||
ClearUpdateSchedule();
|
||||
m_updateFlag = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -2800,17 +2812,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
if (!UUID.TryParse(sound, out soundID))
|
||||
{
|
||||
// search sound file from inventory
|
||||
lock (TaskInventory)
|
||||
TaskInventory.LockItemsForRead(true);
|
||||
foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
|
||||
{
|
||||
foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
|
||||
if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound)
|
||||
{
|
||||
if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound)
|
||||
{
|
||||
soundID = item.Value.ItemID;
|
||||
break;
|
||||
}
|
||||
soundID = item.Value.ItemID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
TaskInventory.LockItemsForRead(false);
|
||||
}
|
||||
|
||||
if (soundID == UUID.Zero)
|
||||
|
||||
@@ -82,7 +82,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </value>
|
||||
protected internal TaskInventoryDictionary Items
|
||||
{
|
||||
get { return m_items; }
|
||||
get {
|
||||
return m_items;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_items = value;
|
||||
@@ -118,22 +120,25 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <param name="linkNum">Link number for the part</param>
|
||||
public void ResetInventoryIDs()
|
||||
{
|
||||
lock (Items)
|
||||
m_items.LockItemsForWrite(true);
|
||||
|
||||
if (0 == Items.Count)
|
||||
{
|
||||
if (0 == Items.Count)
|
||||
return;
|
||||
|
||||
HasInventoryChanged = true;
|
||||
m_part.ParentGroup.HasGroupChanged = true;
|
||||
IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
|
||||
Items.Clear();
|
||||
|
||||
foreach (TaskInventoryItem item in items)
|
||||
{
|
||||
item.ResetIDs(m_part.UUID);
|
||||
Items.Add(item.ItemID, item);
|
||||
}
|
||||
m_items.LockItemsForWrite(false);
|
||||
return;
|
||||
}
|
||||
|
||||
HasInventoryChanged = true;
|
||||
m_part.ParentGroup.HasGroupChanged = true;
|
||||
IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
|
||||
Items.Clear();
|
||||
|
||||
foreach (TaskInventoryItem item in items)
|
||||
{
|
||||
item.ResetIDs(m_part.UUID);
|
||||
Items.Add(item.ItemID, item);
|
||||
}
|
||||
m_items.LockItemsForWrite(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -142,25 +147,25 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <param name="ownerId"></param>
|
||||
public void ChangeInventoryOwner(UUID ownerId)
|
||||
{
|
||||
lock (Items)
|
||||
m_items.LockItemsForWrite(true);
|
||||
if (0 == Items.Count)
|
||||
{
|
||||
if (0 == Items.Count)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_items.LockItemsForWrite(false);
|
||||
return;
|
||||
}
|
||||
|
||||
HasInventoryChanged = true;
|
||||
m_part.ParentGroup.HasGroupChanged = true;
|
||||
IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
|
||||
foreach (TaskInventoryItem item in items)
|
||||
HasInventoryChanged = true;
|
||||
m_part.ParentGroup.HasGroupChanged = true;
|
||||
IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
|
||||
foreach (TaskInventoryItem item in items)
|
||||
{
|
||||
if (ownerId != item.OwnerID)
|
||||
{
|
||||
if (ownerId != item.OwnerID)
|
||||
{
|
||||
item.LastOwnerID = item.OwnerID;
|
||||
item.OwnerID = ownerId;
|
||||
}
|
||||
item.LastOwnerID = item.OwnerID;
|
||||
item.OwnerID = ownerId;
|
||||
}
|
||||
}
|
||||
m_items.LockItemsForWrite(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -169,24 +174,24 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <param name="groupID"></param>
|
||||
public void ChangeInventoryGroup(UUID groupID)
|
||||
{
|
||||
lock (Items)
|
||||
m_items.LockItemsForWrite(true);
|
||||
if (0 == Items.Count)
|
||||
{
|
||||
if (0 == Items.Count)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_items.LockItemsForWrite(false);
|
||||
return;
|
||||
}
|
||||
|
||||
HasInventoryChanged = true;
|
||||
m_part.ParentGroup.HasGroupChanged = true;
|
||||
IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
|
||||
foreach (TaskInventoryItem item in items)
|
||||
HasInventoryChanged = true;
|
||||
m_part.ParentGroup.HasGroupChanged = true;
|
||||
IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
|
||||
foreach (TaskInventoryItem item in items)
|
||||
{
|
||||
if (groupID != item.GroupID)
|
||||
{
|
||||
if (groupID != item.GroupID)
|
||||
{
|
||||
item.GroupID = groupID;
|
||||
}
|
||||
item.GroupID = groupID;
|
||||
}
|
||||
}
|
||||
m_items.LockItemsForWrite(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -194,14 +199,14 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </summary>
|
||||
public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
|
||||
{
|
||||
lock (m_items)
|
||||
Items.LockItemsForRead(true);
|
||||
IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
|
||||
Items.LockItemsForRead(false);
|
||||
foreach (TaskInventoryItem item in items)
|
||||
{
|
||||
foreach (TaskInventoryItem item in Items.Values)
|
||||
if ((int)InventoryType.LSL == item.InvType)
|
||||
{
|
||||
if ((int)InventoryType.LSL == item.InvType)
|
||||
{
|
||||
CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
|
||||
}
|
||||
CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -232,17 +237,20 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </summary>
|
||||
public void RemoveScriptInstances()
|
||||
{
|
||||
lock (Items)
|
||||
Items.LockItemsForRead(true);
|
||||
IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
|
||||
Items.LockItemsForRead(false);
|
||||
|
||||
foreach (TaskInventoryItem item in items)
|
||||
{
|
||||
foreach (TaskInventoryItem item in Items.Values)
|
||||
if ((int)InventoryType.LSL == item.InvType)
|
||||
{
|
||||
if ((int)InventoryType.LSL == item.InvType)
|
||||
{
|
||||
RemoveScriptInstance(item.ItemID);
|
||||
m_part.RemoveScriptEvents(item.ItemID);
|
||||
}
|
||||
RemoveScriptInstance(item.ItemID);
|
||||
m_part.RemoveScriptEvents(item.ItemID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -267,8 +275,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
if (stateSource == 1 && // Prim crossing
|
||||
m_part.ParentGroup.Scene.m_trustBinaries)
|
||||
{
|
||||
m_items.LockItemsForWrite(true);
|
||||
m_items[item.ItemID].PermsMask = 0;
|
||||
m_items[item.ItemID].PermsGranter = UUID.Zero;
|
||||
m_items.LockItemsForWrite(false);
|
||||
m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
|
||||
m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
|
||||
m_part.ParentGroup.AddActiveScriptCount(1);
|
||||
@@ -290,8 +300,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
if (m_part.ParentGroup.m_savedScriptState != null)
|
||||
RestoreSavedScriptState(item.OldItemID, item.ItemID);
|
||||
m_items.LockItemsForWrite(true);
|
||||
m_items[item.ItemID].PermsMask = 0;
|
||||
m_items[item.ItemID].PermsGranter = UUID.Zero;
|
||||
m_items.LockItemsForWrite(false);
|
||||
string script = Utils.BytesToString(asset.Data);
|
||||
m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
|
||||
m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
|
||||
@@ -367,14 +379,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </param>
|
||||
public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
|
||||
{
|
||||
lock (m_items)
|
||||
m_items.LockItemsForRead(true);
|
||||
if (m_items.ContainsKey(itemId))
|
||||
{
|
||||
if (m_items.ContainsKey(itemId))
|
||||
{
|
||||
m_items.LockItemsForRead(false);
|
||||
CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_items.LockItemsForRead(false);
|
||||
m_log.ErrorFormat(
|
||||
"[PRIM INVENTORY]: " +
|
||||
"Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
|
||||
@@ -382,6 +397,15 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_items.LockItemsForRead(false);
|
||||
m_log.ErrorFormat(
|
||||
"[PRIM INVENTORY]: " +
|
||||
"Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2}",
|
||||
itemId, m_part.Name, m_part.UUID);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -413,11 +437,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <returns></returns>
|
||||
private bool InventoryContainsName(string name)
|
||||
{
|
||||
foreach (TaskInventoryItem item in Items.Values)
|
||||
m_items.LockItemsForRead(true);
|
||||
foreach (TaskInventoryItem item in m_items.Values)
|
||||
{
|
||||
if (item.Name == name)
|
||||
{
|
||||
m_items.LockItemsForRead(false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
m_items.LockItemsForRead(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -459,7 +488,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <param name="item"></param>
|
||||
public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
|
||||
{
|
||||
m_items.LockItemsForRead(true);
|
||||
List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
|
||||
m_items.LockItemsForRead(false);
|
||||
foreach (TaskInventoryItem i in il)
|
||||
{
|
||||
if (i.Name == item.Name)
|
||||
@@ -496,15 +527,14 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
item.ParentPartID = m_part.UUID;
|
||||
item.Name = name;
|
||||
|
||||
lock (m_items)
|
||||
{
|
||||
m_items.Add(item.ItemID, item);
|
||||
|
||||
m_items.LockItemsForWrite(true);
|
||||
m_items.Add(item.ItemID, item);
|
||||
m_items.LockItemsForWrite(false);
|
||||
if (allowedDrop)
|
||||
m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
|
||||
else
|
||||
m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
|
||||
}
|
||||
|
||||
|
||||
m_inventorySerial++;
|
||||
//m_inventorySerial += 2;
|
||||
@@ -521,14 +551,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <param name="items"></param>
|
||||
public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
|
||||
{
|
||||
lock (m_items)
|
||||
m_items.LockItemsForWrite(true);
|
||||
foreach (TaskInventoryItem item in items)
|
||||
{
|
||||
foreach (TaskInventoryItem item in items)
|
||||
{
|
||||
m_items.Add(item.ItemID, item);
|
||||
m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
|
||||
}
|
||||
m_items.Add(item.ItemID, item);
|
||||
m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
|
||||
}
|
||||
m_items.LockItemsForWrite(false);
|
||||
|
||||
m_inventorySerial++;
|
||||
}
|
||||
@@ -541,8 +570,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
public TaskInventoryItem GetInventoryItem(UUID itemId)
|
||||
{
|
||||
TaskInventoryItem item;
|
||||
m_items.LockItemsForRead(true);
|
||||
m_items.TryGetValue(itemId, out item);
|
||||
|
||||
m_items.LockItemsForRead(false);
|
||||
return item;
|
||||
}
|
||||
|
||||
@@ -554,46 +584,46 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <returns>false if the item did not exist, true if the update occurred successfully</returns>
|
||||
public bool UpdateInventoryItem(TaskInventoryItem item)
|
||||
{
|
||||
lock (m_items)
|
||||
m_items.LockItemsForWrite(true);
|
||||
|
||||
if (m_items.ContainsKey(item.ItemID))
|
||||
{
|
||||
if (m_items.ContainsKey(item.ItemID))
|
||||
item.ParentID = m_part.UUID;
|
||||
item.ParentPartID = m_part.UUID;
|
||||
item.Flags = m_items[item.ItemID].Flags;
|
||||
if (item.AssetID == UUID.Zero)
|
||||
{
|
||||
item.ParentID = m_part.UUID;
|
||||
item.ParentPartID = m_part.UUID;
|
||||
item.Flags = m_items[item.ItemID].Flags;
|
||||
if (item.AssetID == UUID.Zero)
|
||||
{
|
||||
item.AssetID = m_items[item.ItemID].AssetID;
|
||||
}
|
||||
else if ((InventoryType)item.Type == InventoryType.Notecard)
|
||||
{
|
||||
ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
|
||||
|
||||
if (presence != null)
|
||||
{
|
||||
presence.ControllingClient.SendAgentAlertMessage(
|
||||
"Notecard saved", false);
|
||||
}
|
||||
}
|
||||
|
||||
m_items[item.ItemID] = item;
|
||||
m_inventorySerial++;
|
||||
m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
|
||||
|
||||
HasInventoryChanged = true;
|
||||
m_part.ParentGroup.HasGroupChanged = true;
|
||||
|
||||
return true;
|
||||
item.AssetID = m_items[item.ItemID].AssetID;
|
||||
}
|
||||
else
|
||||
else if ((InventoryType)item.Type == InventoryType.Notecard)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[PRIM INVENTORY]: " +
|
||||
"Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
|
||||
item.ItemID, m_part.Name, m_part.UUID,
|
||||
m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
|
||||
ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
|
||||
|
||||
if (presence != null)
|
||||
{
|
||||
presence.ControllingClient.SendAgentAlertMessage(
|
||||
"Notecard saved", false);
|
||||
}
|
||||
}
|
||||
|
||||
m_items[item.ItemID] = item;
|
||||
m_inventorySerial++;
|
||||
m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
|
||||
|
||||
HasInventoryChanged = true;
|
||||
m_part.ParentGroup.HasGroupChanged = true;
|
||||
m_items.LockItemsForWrite(false);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[PRIM INVENTORY]: " +
|
||||
"Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
|
||||
item.ItemID, m_part.Name, m_part.UUID,
|
||||
m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
|
||||
}
|
||||
m_items.LockItemsForWrite(false);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -606,52 +636,54 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// in this prim's inventory.</returns>
|
||||
public int RemoveInventoryItem(UUID itemID)
|
||||
{
|
||||
lock (m_items)
|
||||
m_items.LockItemsForRead(true);
|
||||
|
||||
if (m_items.ContainsKey(itemID))
|
||||
{
|
||||
if (m_items.ContainsKey(itemID))
|
||||
int type = m_items[itemID].InvType;
|
||||
m_items.LockItemsForRead(false);
|
||||
if (type == 10) // Script
|
||||
{
|
||||
int type = m_items[itemID].InvType;
|
||||
if (type == 10) // Script
|
||||
{
|
||||
m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
|
||||
}
|
||||
m_items.Remove(itemID);
|
||||
m_inventorySerial++;
|
||||
m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
|
||||
|
||||
HasInventoryChanged = true;
|
||||
m_part.ParentGroup.HasGroupChanged = true;
|
||||
|
||||
int scriptcount = 0;
|
||||
lock (m_items)
|
||||
{
|
||||
foreach (TaskInventoryItem item in m_items.Values)
|
||||
{
|
||||
if (item.Type == 10)
|
||||
{
|
||||
scriptcount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (scriptcount <= 0)
|
||||
{
|
||||
m_part.RemFlag(PrimFlags.Scripted);
|
||||
}
|
||||
|
||||
m_part.ScheduleFullUpdate();
|
||||
|
||||
return type;
|
||||
m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
|
||||
}
|
||||
else
|
||||
m_items.LockItemsForWrite(true);
|
||||
m_items.Remove(itemID);
|
||||
m_items.LockItemsForWrite(false);
|
||||
m_inventorySerial++;
|
||||
m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
|
||||
|
||||
HasInventoryChanged = true;
|
||||
m_part.ParentGroup.HasGroupChanged = true;
|
||||
|
||||
int scriptcount = 0;
|
||||
m_items.LockItemsForRead(true);
|
||||
foreach (TaskInventoryItem item in m_items.Values)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[PRIM INVENTORY]: " +
|
||||
"Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
|
||||
itemID, m_part.Name, m_part.UUID,
|
||||
m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
|
||||
if (item.Type == 10)
|
||||
{
|
||||
scriptcount++;
|
||||
}
|
||||
}
|
||||
m_items.LockItemsForRead(false);
|
||||
|
||||
|
||||
if (scriptcount <= 0)
|
||||
{
|
||||
m_part.RemFlag(PrimFlags.Scripted);
|
||||
}
|
||||
|
||||
m_part.ScheduleFullUpdate();
|
||||
|
||||
return type;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[PRIM INVENTORY]: " +
|
||||
"Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
|
||||
itemID, m_part.Name, m_part.UUID);
|
||||
}
|
||||
m_items.LockItemsForWrite(false);
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -704,52 +736,53 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// isn't available (such as drag from prim inventory to agent inventory)
|
||||
InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
|
||||
|
||||
lock (m_items)
|
||||
m_items.LockItemsForRead(true);
|
||||
|
||||
foreach (TaskInventoryItem item in m_items.Values)
|
||||
{
|
||||
foreach (TaskInventoryItem item in m_items.Values)
|
||||
{
|
||||
UUID ownerID = item.OwnerID;
|
||||
uint everyoneMask = 0;
|
||||
uint baseMask = item.BasePermissions;
|
||||
uint ownerMask = item.CurrentPermissions;
|
||||
UUID ownerID = item.OwnerID;
|
||||
uint everyoneMask = 0;
|
||||
uint baseMask = item.BasePermissions;
|
||||
uint ownerMask = item.CurrentPermissions;
|
||||
|
||||
invString.AddItemStart();
|
||||
invString.AddNameValueLine("item_id", item.ItemID.ToString());
|
||||
invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
|
||||
invString.AddItemStart();
|
||||
invString.AddNameValueLine("item_id", item.ItemID.ToString());
|
||||
invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
|
||||
|
||||
invString.AddPermissionsStart();
|
||||
invString.AddPermissionsStart();
|
||||
|
||||
invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
|
||||
invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
|
||||
invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0));
|
||||
invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
|
||||
invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
|
||||
invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
|
||||
invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
|
||||
invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0));
|
||||
invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
|
||||
invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
|
||||
|
||||
invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
|
||||
invString.AddNameValueLine("owner_id", ownerID.ToString());
|
||||
invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
|
||||
invString.AddNameValueLine("owner_id", ownerID.ToString());
|
||||
|
||||
invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
|
||||
invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
|
||||
|
||||
invString.AddNameValueLine("group_id", item.GroupID.ToString());
|
||||
invString.AddSectionEnd();
|
||||
invString.AddNameValueLine("group_id", item.GroupID.ToString());
|
||||
invString.AddSectionEnd();
|
||||
|
||||
invString.AddNameValueLine("asset_id", item.AssetID.ToString());
|
||||
invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
|
||||
invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
|
||||
invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
|
||||
invString.AddNameValueLine("asset_id", item.AssetID.ToString());
|
||||
invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
|
||||
invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
|
||||
invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
|
||||
|
||||
invString.AddSaleStart();
|
||||
invString.AddNameValueLine("sale_type", "not");
|
||||
invString.AddNameValueLine("sale_price", "0");
|
||||
invString.AddSectionEnd();
|
||||
invString.AddSaleStart();
|
||||
invString.AddNameValueLine("sale_type", "not");
|
||||
invString.AddNameValueLine("sale_price", "0");
|
||||
invString.AddSectionEnd();
|
||||
|
||||
invString.AddNameValueLine("name", item.Name + "|");
|
||||
invString.AddNameValueLine("desc", item.Description + "|");
|
||||
invString.AddNameValueLine("name", item.Name + "|");
|
||||
invString.AddNameValueLine("desc", item.Description + "|");
|
||||
|
||||
invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
|
||||
invString.AddSectionEnd();
|
||||
}
|
||||
invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
|
||||
invString.AddSectionEnd();
|
||||
}
|
||||
int count = m_items.Count;
|
||||
m_items.LockItemsForRead(false);
|
||||
|
||||
fileData = Utils.StringToBytes(invString.BuildString);
|
||||
|
||||
@@ -770,10 +803,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
if (HasInventoryChanged)
|
||||
{
|
||||
lock (Items)
|
||||
{
|
||||
datastore.StorePrimInventory(m_part.UUID, Items.Values);
|
||||
}
|
||||
Items.LockItemsForRead(true);
|
||||
datastore.StorePrimInventory(m_part.UUID, Items.Values);
|
||||
Items.LockItemsForRead(false);
|
||||
|
||||
HasInventoryChanged = false;
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// {
|
||||
// m_log.Debug("[ScenePresence] Destructor called");
|
||||
// }
|
||||
|
||||
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
|
||||
@@ -89,7 +89,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
|
||||
/// issue #1716
|
||||
/// </summary>
|
||||
private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
|
||||
// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
|
||||
// Value revised by KF 091121 by comparison with SL.
|
||||
private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
|
||||
|
||||
public UUID currentParcelUUID = UUID.Zero;
|
||||
|
||||
@@ -113,8 +115,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
public Vector3 lastKnownAllowedPosition;
|
||||
public bool sentMessageAboutRestrictedParcelFlyingDown;
|
||||
public Vector4 CollisionPlane = Vector4.UnitW;
|
||||
|
||||
private Vector3 m_lastPosition;
|
||||
|
||||
private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
|
||||
private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
|
||||
private Vector3 m_lastPosition;
|
||||
private Vector3 m_lastWorldPosition;
|
||||
private Quaternion m_lastRotation;
|
||||
private Vector3 m_lastVelocity;
|
||||
//private int m_lastTerseSent;
|
||||
@@ -124,7 +129,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
private Vector3? m_forceToApply;
|
||||
private uint m_requestedSitTargetID;
|
||||
private UUID m_requestedSitTargetUUID;
|
||||
public bool SitGround = false;
|
||||
|
||||
private SendCourseLocationsMethod m_sendCourseLocationsMethod;
|
||||
|
||||
@@ -146,7 +150,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
private int m_perfMonMS;
|
||||
|
||||
private bool m_setAlwaysRun;
|
||||
|
||||
private bool m_forceFly;
|
||||
private bool m_flyDisabled;
|
||||
|
||||
@@ -170,7 +173,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
protected RegionInfo m_regionInfo;
|
||||
protected ulong crossingFromRegion;
|
||||
|
||||
private readonly Vector3[] Dir_Vectors = new Vector3[9];
|
||||
private readonly Vector3[] Dir_Vectors = new Vector3[11];
|
||||
private bool m_isNudging = false;
|
||||
|
||||
// Position of agent's camera in world (region cordinates)
|
||||
protected Vector3 m_CameraCenter;
|
||||
@@ -195,6 +199,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
private bool m_autopilotMoving;
|
||||
private Vector3 m_autoPilotTarget;
|
||||
private bool m_sitAtAutoTarget;
|
||||
private Vector3 m_initialSitTarget; //KF: First estimate of where to sit
|
||||
|
||||
private string m_nextSitAnimation = String.Empty;
|
||||
|
||||
@@ -205,6 +210,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
private bool m_followCamAuto;
|
||||
|
||||
private int m_movementUpdateCount;
|
||||
private int m_lastColCount = -1; //KF: Look for Collision chnages
|
||||
private int m_updateCount = 0; //KF: Update Anims for a while
|
||||
private static readonly int UPDATE_COUNT = 10; // how many frames to update for
|
||||
|
||||
private const int NumMovementsBetweenRayCast = 5;
|
||||
|
||||
@@ -235,7 +243,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
|
||||
DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
|
||||
DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
|
||||
DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
|
||||
DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
|
||||
DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
|
||||
DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
|
||||
DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
|
||||
}
|
||||
|
||||
@@ -661,10 +671,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
|
||||
AdjustKnownSeeds();
|
||||
|
||||
// TODO: I think, this won't send anything, as we are still a child here...
|
||||
Animator.TrySetMovementAnimation("STAND");
|
||||
|
||||
// we created a new ScenePresence (a new child agent) in a fresh region.
|
||||
// Request info about all the (root) agents in this region
|
||||
// Note: This won't send data *to* other clients in that region (children don't send)
|
||||
@@ -720,25 +727,47 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
|
||||
Dir_Vectors[4] = Vector3.UnitZ; //UP
|
||||
Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
|
||||
Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
|
||||
Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD
|
||||
Dir_Vectors[7] = -Vector3.UnitX; //BACK
|
||||
Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
|
||||
Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
|
||||
Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
|
||||
Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
|
||||
Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
|
||||
}
|
||||
|
||||
private Vector3[] GetWalkDirectionVectors()
|
||||
{
|
||||
Vector3[] vector = new Vector3[9];
|
||||
Vector3[] vector = new Vector3[11];
|
||||
vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
|
||||
vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
|
||||
vector[2] = Vector3.UnitY; //LEFT
|
||||
vector[3] = -Vector3.UnitY; //RIGHT
|
||||
vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
|
||||
vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
|
||||
vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge
|
||||
vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge
|
||||
vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge
|
||||
vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
|
||||
vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
|
||||
vector[8] = Vector3.UnitY; //LEFT_NUDGE
|
||||
vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
|
||||
vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
|
||||
return vector;
|
||||
}
|
||||
|
||||
private bool[] GetDirectionIsNudge()
|
||||
{
|
||||
bool[] isNudge = new bool[11];
|
||||
isNudge[0] = false; //FORWARD
|
||||
isNudge[1] = false; //BACK
|
||||
isNudge[2] = false; //LEFT
|
||||
isNudge[3] = false; //RIGHT
|
||||
isNudge[4] = false; //UP
|
||||
isNudge[5] = false; //DOWN
|
||||
isNudge[6] = true; //FORWARD_NUDGE
|
||||
isNudge[7] = true; //BACK_NUDGE
|
||||
isNudge[8] = true; //LEFT_NUDGE
|
||||
isNudge[9] = true; //RIGHT_NUDGE
|
||||
isNudge[10] = true; //DOWN_Nudge
|
||||
return isNudge;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -807,9 +836,24 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
|
||||
pos.Y = crossedBorder.BorderLine.Z - 1;
|
||||
}
|
||||
|
||||
//If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
|
||||
//This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
|
||||
//they'll bypass the landing point. But I can't think of any decent way of fixing this.
|
||||
if (KnownChildRegionHandles.Count == 0)
|
||||
{
|
||||
ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
|
||||
if (land != null)
|
||||
{
|
||||
//Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
|
||||
if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && m_godlevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid)
|
||||
{
|
||||
pos = land.LandData.UserLocation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
|
||||
{
|
||||
Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
|
||||
@@ -944,9 +988,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
public void Teleport(Vector3 pos)
|
||||
{
|
||||
bool isFlying = false;
|
||||
if (m_physicsActor != null)
|
||||
isFlying = m_physicsActor.Flying;
|
||||
|
||||
if (m_physicsActor != null)
|
||||
isFlying = m_physicsActor.Flying;
|
||||
|
||||
RemoveFromPhysicalScene();
|
||||
Velocity = Vector3.Zero;
|
||||
AbsolutePosition = pos;
|
||||
@@ -957,7 +1002,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
SetHeight(m_appearance.AvatarHeight);
|
||||
}
|
||||
|
||||
SendTerseUpdateToAllClients();
|
||||
SendTerseUpdateToAllClients();
|
||||
|
||||
}
|
||||
|
||||
public void TeleportWithMomentum(Vector3 pos)
|
||||
@@ -1002,7 +1048,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
|
||||
}
|
||||
|
||||
|
||||
m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
|
||||
|
||||
ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
|
||||
AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
|
||||
}
|
||||
@@ -1237,7 +1285,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
|
||||
}
|
||||
}
|
||||
|
||||
lock (scriptedcontrols)
|
||||
{
|
||||
if (scriptedcontrols.Count > 0)
|
||||
@@ -1252,12 +1299,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
|
||||
{
|
||||
// TODO: This doesn't prevent the user from walking yet.
|
||||
// Setting parent ID would fix this, if we knew what value
|
||||
// to use. Or we could add a m_isSitting variable.
|
||||
//Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
|
||||
SitGround = true;
|
||||
|
||||
m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
|
||||
Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
|
||||
}
|
||||
|
||||
// In the future, these values might need to go global.
|
||||
@@ -1301,6 +1344,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
update_rotation = true;
|
||||
}
|
||||
|
||||
//guilty until proven innocent..
|
||||
bool Nudging = true;
|
||||
//Basically, if there is at least one non-nudge control then we don't need
|
||||
//to worry about stopping the avatar
|
||||
|
||||
if (m_parentID == 0)
|
||||
{
|
||||
bool bAllowUpdateMoveToPosition = false;
|
||||
@@ -1315,9 +1363,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
else
|
||||
dirVectors = Dir_Vectors;
|
||||
|
||||
// The fact that m_movementflag is a byte needs to be fixed
|
||||
// it really should be a uint
|
||||
uint nudgehack = 250;
|
||||
bool[] isNudge = GetDirectionIsNudge();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
|
||||
{
|
||||
if (((uint)flags & (uint)DCF) != 0)
|
||||
@@ -1327,40 +1378,28 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
try
|
||||
{
|
||||
agent_control_v3 += dirVectors[i];
|
||||
//m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]);
|
||||
if (isNudge[i] == false)
|
||||
{
|
||||
Nudging = false;
|
||||
}
|
||||
}
|
||||
catch (IndexOutOfRangeException)
|
||||
{
|
||||
// Why did I get this?
|
||||
}
|
||||
|
||||
if ((m_movementflag & (byte)(uint)DCF) == 0)
|
||||
if ((m_movementflag & (uint)DCF) == 0)
|
||||
{
|
||||
if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
|
||||
{
|
||||
m_movementflag |= (byte)nudgehack;
|
||||
}
|
||||
m_movementflag += (byte)(uint)DCF;
|
||||
update_movementflag = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((m_movementflag & (byte)(uint)DCF) != 0 ||
|
||||
((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
|
||||
&& ((m_movementflag & (byte)nudgehack) == nudgehack))
|
||||
) // This or is for Nudge forward
|
||||
if ((m_movementflag & (uint)DCF) != 0)
|
||||
{
|
||||
m_movementflag -= ((byte)(uint)DCF);
|
||||
|
||||
m_movementflag -= (byte)(uint)DCF;
|
||||
update_movementflag = true;
|
||||
/*
|
||||
if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
|
||||
&& ((m_movementflag & (byte)nudgehack) == nudgehack))
|
||||
{
|
||||
m_log.Debug("Removed Hack flag");
|
||||
}
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1404,6 +1443,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// Ignore z component of vector
|
||||
Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
|
||||
LocalVectorToTarget2D.Normalize();
|
||||
|
||||
//We're not nudging
|
||||
Nudging = false;
|
||||
agent_control_v3 += LocalVectorToTarget2D;
|
||||
|
||||
// update avatar movement flags. the avatar coordinate system is as follows:
|
||||
@@ -1492,13 +1534,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// m_log.DebugFormat(
|
||||
// "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
|
||||
|
||||
AddNewMovement(agent_control_v3, q);
|
||||
AddNewMovement(agent_control_v3, q, Nudging);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround)
|
||||
if (update_movementflag)
|
||||
Animator.UpdateMovementAnimations();
|
||||
|
||||
m_scene.EventManager.TriggerOnClientMovement(this);
|
||||
@@ -1513,7 +1555,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
m_sitAtAutoTarget = false;
|
||||
PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
|
||||
//proxy.PCode = (byte)PCode.ParticleSystem;
|
||||
|
||||
proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
|
||||
proxyObjectGroup.AttachToScene(m_scene);
|
||||
|
||||
@@ -1555,7 +1596,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
m_moveToPositionInProgress = true;
|
||||
m_moveToPositionTarget = new Vector3(locx, locy, locz);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//Why did I get this error?
|
||||
@@ -1577,7 +1618,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
Velocity = Vector3.Zero;
|
||||
SendFullUpdateToAllClients();
|
||||
|
||||
//HandleAgentSit(ControllingClient, m_requestedSitTargetUUID);
|
||||
HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
|
||||
}
|
||||
//ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
|
||||
m_requestedSitTargetUUID = UUID.Zero;
|
||||
@@ -1610,55 +1651,84 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </summary>
|
||||
public void StandUp()
|
||||
{
|
||||
if (SitGround)
|
||||
SitGround = false;
|
||||
|
||||
if (m_parentID != 0)
|
||||
{
|
||||
m_log.Debug("StandupCode Executed");
|
||||
SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
|
||||
if (part != null)
|
||||
{
|
||||
part.TaskInventory.LockItemsForRead(true);
|
||||
TaskInventoryDictionary taskIDict = part.TaskInventory;
|
||||
if (taskIDict != null)
|
||||
{
|
||||
lock (taskIDict)
|
||||
foreach (UUID taskID in taskIDict.Keys)
|
||||
{
|
||||
foreach (UUID taskID in taskIDict.Keys)
|
||||
{
|
||||
UnRegisterControlEventsToScript(LocalId, taskID);
|
||||
taskIDict[taskID].PermsMask &= ~(
|
||||
2048 | //PERMISSION_CONTROL_CAMERA
|
||||
4); // PERMISSION_TAKE_CONTROLS
|
||||
}
|
||||
UnRegisterControlEventsToScript(LocalId, taskID);
|
||||
taskIDict[taskID].PermsMask &= ~(
|
||||
2048 | //PERMISSION_CONTROL_CAMERA
|
||||
4); // PERMISSION_TAKE_CONTROLS
|
||||
}
|
||||
|
||||
}
|
||||
part.TaskInventory.LockItemsForRead(false);
|
||||
// Reset sit target.
|
||||
if (part.GetAvatarOnSitTarget() == UUID)
|
||||
part.SetAvatarOnSitTarget(UUID.Zero);
|
||||
|
||||
m_parentPosition = part.GetWorldPosition();
|
||||
ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
|
||||
}
|
||||
// part.GetWorldRotation() is the rotation of the object being sat on
|
||||
// Rotation is the sittiing Av's rotation
|
||||
|
||||
if (m_physicsActor == null)
|
||||
{
|
||||
AddToPhysicalScene(false);
|
||||
Quaternion partRot;
|
||||
// if (part.LinkNum == 1)
|
||||
// { // Root prim of linkset
|
||||
// partRot = part.ParentGroup.RootPart.RotationOffset;
|
||||
// }
|
||||
// else
|
||||
// { // single or child prim
|
||||
|
||||
// }
|
||||
if (part == null) //CW: Part may be gone. llDie() for example.
|
||||
{
|
||||
partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
partRot = part.GetWorldRotation();
|
||||
}
|
||||
|
||||
m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight);
|
||||
m_parentPosition = Vector3.Zero;
|
||||
Quaternion partIRot = Quaternion.Inverse(partRot);
|
||||
|
||||
m_parentID = 0;
|
||||
Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
|
||||
Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
|
||||
|
||||
|
||||
if (m_physicsActor == null)
|
||||
{
|
||||
AddToPhysicalScene(false);
|
||||
}
|
||||
//CW: If the part isn't null then we can set the current position
|
||||
if (part != null)
|
||||
{
|
||||
Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
|
||||
AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
|
||||
part.IsOccupied = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//CW: Since the part doesn't exist, a coarse standup position isn't an issue
|
||||
AbsolutePosition = m_lastWorldPosition;
|
||||
}
|
||||
|
||||
m_parentPosition = Vector3.Zero;
|
||||
m_parentID = 0;
|
||||
SendFullUpdateToAllClients();
|
||||
m_requestedSitTargetID = 0;
|
||||
|
||||
if ((m_physicsActor != null) && (m_avHeight > 0))
|
||||
{
|
||||
SetHeight(m_avHeight);
|
||||
}
|
||||
}
|
||||
|
||||
Animator.TrySetMovementAnimation("STAND");
|
||||
}
|
||||
|
||||
@@ -1689,13 +1759,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
Vector3 avSitOffSet = part.SitTargetPosition;
|
||||
Quaternion avSitOrientation = part.SitTargetOrientation;
|
||||
UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
|
||||
|
||||
bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
|
||||
bool SitTargetisSet =
|
||||
(!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
|
||||
avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
|
||||
|
||||
if (SitTargetisSet && SitTargetUnOccupied)
|
||||
bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
|
||||
bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
|
||||
if (SitTargetisSet && !SitTargetOccupied)
|
||||
{
|
||||
//switch the target to this prim
|
||||
return part;
|
||||
@@ -1709,84 +1775,152 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
|
||||
{
|
||||
bool autopilot = true;
|
||||
Vector3 autopilotTarget = new Vector3();
|
||||
Quaternion sitOrientation = Quaternion.Identity;
|
||||
Vector3 pos = new Vector3();
|
||||
Quaternion sitOrientation = pSitOrientation;
|
||||
Vector3 cameraEyeOffset = Vector3.Zero;
|
||||
Vector3 cameraAtOffset = Vector3.Zero;
|
||||
bool forceMouselook = false;
|
||||
|
||||
//SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
|
||||
SceneObjectPart part = FindNextAvailableSitTarget(targetID);
|
||||
if (part != null)
|
||||
if (part == null) return;
|
||||
|
||||
// TODO: determine position to sit at based on scene geometry; don't trust offset from client
|
||||
// see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
|
||||
|
||||
// part is the prim to sit on
|
||||
// offset is the world-ref vector distance from that prim center to the click-spot
|
||||
// UUID is the UUID of the Avatar doing the clicking
|
||||
|
||||
m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
|
||||
|
||||
// Is a sit target available?
|
||||
Vector3 avSitOffSet = part.SitTargetPosition;
|
||||
Quaternion avSitOrientation = part.SitTargetOrientation;
|
||||
|
||||
bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
|
||||
// Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
|
||||
Quaternion partRot;
|
||||
// if (part.LinkNum == 1)
|
||||
// { // Root prim of linkset
|
||||
// partRot = part.ParentGroup.RootPart.RotationOffset;
|
||||
// }
|
||||
// else
|
||||
// { // single or child prim
|
||||
partRot = part.GetWorldRotation();
|
||||
// }
|
||||
Quaternion partIRot = Quaternion.Inverse(partRot);
|
||||
//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
|
||||
// Sit analysis rewritten by KF 091125
|
||||
if (SitTargetisSet) // scipted sit
|
||||
{
|
||||
// TODO: determine position to sit at based on scene geometry; don't trust offset from client
|
||||
// see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
|
||||
if (!part.IsOccupied)
|
||||
{
|
||||
//Console.WriteLine("Scripted, unoccupied");
|
||||
part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
|
||||
offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
|
||||
sitOrientation = avSitOrientation; // Change rotatione to the scripted one
|
||||
autopilot = false; // Jump direct to scripted llSitPos()
|
||||
}
|
||||
else
|
||||
{
|
||||
//Console.WriteLine("Scripted, occupied");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else // Not Scripted
|
||||
{
|
||||
if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
|
||||
{
|
||||
// large prim & offset, ignore if other Avs sitting
|
||||
// offset.Z -= 0.05f;
|
||||
m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
|
||||
autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
|
||||
|
||||
//Console.WriteLine(" offset ={0}", offset);
|
||||
//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
|
||||
//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
|
||||
|
||||
}
|
||||
else // small offset
|
||||
{
|
||||
//Console.WriteLine("Small offset");
|
||||
if (!part.IsOccupied)
|
||||
{
|
||||
m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
|
||||
autopilotTarget = part.AbsolutePosition;
|
||||
}
|
||||
else return; // occupied small
|
||||
} // end large/small
|
||||
} // end Scripted/not
|
||||
cameraAtOffset = part.GetCameraAtOffset();
|
||||
cameraEyeOffset = part.GetCameraEyeOffset();
|
||||
forceMouselook = part.GetForceMouselook();
|
||||
if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
|
||||
if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
|
||||
|
||||
// Is a sit target available?
|
||||
Vector3 avSitOffSet = part.SitTargetPosition;
|
||||
Quaternion avSitOrientation = part.SitTargetOrientation;
|
||||
UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
|
||||
|
||||
bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
|
||||
bool SitTargetisSet =
|
||||
(!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f &&
|
||||
(
|
||||
avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion
|
||||
|| avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point
|
||||
|| avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion
|
||||
)
|
||||
));
|
||||
|
||||
if (SitTargetisSet && SitTargetUnOccupied)
|
||||
{
|
||||
part.SetAvatarOnSitTarget(UUID);
|
||||
offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z);
|
||||
sitOrientation = avSitOrientation;
|
||||
autopilot = false;
|
||||
}
|
||||
|
||||
pos = part.AbsolutePosition + offset;
|
||||
//if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1)
|
||||
//{
|
||||
// offset = pos;
|
||||
//autopilot = false;
|
||||
//}
|
||||
if (m_physicsActor != null)
|
||||
{
|
||||
// If we're not using the client autopilot, we're immediately warping the avatar to the location
|
||||
// We can remove the physicsActor until they stand up.
|
||||
m_sitAvatarHeight = m_physicsActor.Size.Z;
|
||||
|
||||
if (autopilot)
|
||||
{
|
||||
if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5)
|
||||
{
|
||||
autopilot = false;
|
||||
|
||||
RemoveFromPhysicalScene();
|
||||
AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (m_physicsActor != null)
|
||||
{
|
||||
// If we're not using the client autopilot, we're immediately warping the avatar to the location
|
||||
// We can remove the physicsActor until they stand up.
|
||||
m_sitAvatarHeight = m_physicsActor.Size.Z;
|
||||
if (autopilot)
|
||||
{ // its not a scripted sit
|
||||
// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
|
||||
if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
|
||||
{
|
||||
autopilot = false; // close enough
|
||||
m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
|
||||
Not using the part's position because returning the AV to the last known standing
|
||||
position is likely to be more friendly, isn't it? */
|
||||
RemoveFromPhysicalScene();
|
||||
}
|
||||
AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
|
||||
} // else the autopilot will get us close
|
||||
}
|
||||
else
|
||||
{ // its a scripted sit
|
||||
m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
|
||||
I *am* using the part's position this time because we have no real idea how far away
|
||||
the avatar is from the sit target. */
|
||||
RemoveFromPhysicalScene();
|
||||
}
|
||||
|
||||
cameraAtOffset = part.GetCameraAtOffset();
|
||||
cameraEyeOffset = part.GetCameraEyeOffset();
|
||||
forceMouselook = part.GetForceMouselook();
|
||||
}
|
||||
else return; // physactor is null!
|
||||
|
||||
ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
|
||||
m_requestedSitTargetUUID = targetID;
|
||||
Vector3 offsetr; // = offset * partIRot;
|
||||
// KF: In a linkset, offsetr needs to be relative to the group root! 091208
|
||||
// offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
|
||||
// if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
|
||||
// { // Single, or Root prim of linkset, target is ClickOffset * RootRot
|
||||
offsetr = offset * partIRot;
|
||||
//
|
||||
// else
|
||||
// { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
|
||||
// offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
|
||||
// (offset * partRot);
|
||||
// }
|
||||
|
||||
//Console.WriteLine(" ");
|
||||
//Console.WriteLine("link number ={0}", part.LinkNum);
|
||||
//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
|
||||
//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
|
||||
//Console.WriteLine("Click offst ={0}", offset);
|
||||
//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
|
||||
//Console.WriteLine("offsetr ={0}", offsetr);
|
||||
//Console.WriteLine("Camera At ={0}", cameraAtOffset);
|
||||
//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
|
||||
|
||||
ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
|
||||
m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
|
||||
// This calls HandleAgentSit twice, once from here, and the client calls
|
||||
// HandleAgentSit itself after it gets to the location
|
||||
// It doesn't get to the location until we've moved them there though
|
||||
// which happens in HandleAgentSit :P
|
||||
m_autopilotMoving = autopilot;
|
||||
m_autoPilotTarget = pos;
|
||||
m_autoPilotTarget = autopilotTarget;
|
||||
m_sitAtAutoTarget = autopilot;
|
||||
m_initialSitTarget = autopilotTarget;
|
||||
if (!autopilot)
|
||||
HandleAgentSit(remoteClient, UUID);
|
||||
}
|
||||
@@ -2081,31 +2215,65 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
if (part != null)
|
||||
{
|
||||
//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
|
||||
if (part.GetAvatarOnSitTarget() == UUID)
|
||||
{
|
||||
//Console.WriteLine("Scripted Sit");
|
||||
// Scripted sit
|
||||
Vector3 sitTargetPos = part.SitTargetPosition;
|
||||
Quaternion sitTargetOrient = part.SitTargetOrientation;
|
||||
|
||||
//Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
|
||||
//Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
|
||||
|
||||
//Quaternion result = (sitTargetOrient * vq) * nq;
|
||||
|
||||
m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
|
||||
m_pos += SIT_TARGET_ADJUSTMENT;
|
||||
m_bodyRot = sitTargetOrient;
|
||||
//Rotation = sitTargetOrient;
|
||||
m_parentPosition = part.AbsolutePosition;
|
||||
|
||||
//SendTerseUpdateToAllClients();
|
||||
part.IsOccupied = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pos -= part.AbsolutePosition;
|
||||
// if m_avUnscriptedSitPos is zero then Av sits above center
|
||||
// Else Av sits at m_avUnscriptedSitPos
|
||||
|
||||
// Non-scripted sit by Kitto Flora 21Nov09
|
||||
// Calculate angle of line from prim to Av
|
||||
Quaternion partIRot;
|
||||
// if (part.LinkNum == 1)
|
||||
// { // Root prim of linkset
|
||||
// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
|
||||
// }
|
||||
// else
|
||||
// { // single or child prim
|
||||
partIRot = Quaternion.Inverse(part.GetWorldRotation());
|
||||
// }
|
||||
Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
|
||||
float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
|
||||
float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
|
||||
if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
|
||||
if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
|
||||
float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
|
||||
// NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
|
||||
// Av sits at world euler <0,0, z>, translated by part rotation
|
||||
m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
|
||||
|
||||
m_parentPosition = part.AbsolutePosition;
|
||||
}
|
||||
part.IsOccupied = true;
|
||||
m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
|
||||
(new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
|
||||
(new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
|
||||
m_avUnscriptedSitPos; // adds click offset, if any
|
||||
//Set up raytrace to find top surface of prim
|
||||
Vector3 size = part.Scale;
|
||||
float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
|
||||
Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
|
||||
Vector3 down = new Vector3(0f, 0f, -1f);
|
||||
//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
|
||||
m_scene.PhysicsScene.RaycastWorld(
|
||||
start, // Vector3 position,
|
||||
down, // Vector3 direction,
|
||||
mag, // float length,
|
||||
SitAltitudeCallback); // retMethod
|
||||
} // end scripted/not
|
||||
}
|
||||
else
|
||||
else // no Av
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -2117,11 +2285,36 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
Animator.TrySetMovementAnimation(sitAnimation);
|
||||
SendFullUpdateToAllClients();
|
||||
// This may seem stupid, but Our Full updates don't send avatar rotation :P
|
||||
// So we're also sending a terse update (which has avatar rotation)
|
||||
// [Update] We do now.
|
||||
//SendTerseUpdateToAllClients();
|
||||
}
|
||||
|
||||
public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
|
||||
{
|
||||
// KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
|
||||
// sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
|
||||
if(hitYN)
|
||||
{
|
||||
// m_pos = Av offset from prim center to make look like on center
|
||||
// m_parentPosition = Actual center pos of prim
|
||||
// collisionPoint = spot on prim where we want to sit
|
||||
// collisionPoint.Z = global sit surface height
|
||||
SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
|
||||
Quaternion partIRot;
|
||||
// if (part.LinkNum == 1)
|
||||
/// { // Root prim of linkset
|
||||
// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
|
||||
// }
|
||||
// else
|
||||
// { // single or child prim
|
||||
partIRot = Quaternion.Inverse(part.GetWorldRotation());
|
||||
// }
|
||||
float offZ = collisionPoint.Z - m_initialSitTarget.Z;
|
||||
Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
|
||||
//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
|
||||
m_pos += offset;
|
||||
// ControllingClient.SendClearFollowCamProperties(part.UUID);
|
||||
|
||||
}
|
||||
} // End SitAltitudeCallback KF.
|
||||
|
||||
/// <summary>
|
||||
/// Event handler for the 'Always run' setting on the client
|
||||
@@ -2151,7 +2344,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </summary>
|
||||
/// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
|
||||
/// <param name="rotation">The direction in which this avatar should now face.
|
||||
public void AddNewMovement(Vector3 vec, Quaternion rotation)
|
||||
public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
|
||||
{
|
||||
if (m_isChildAgent)
|
||||
{
|
||||
@@ -2225,7 +2418,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
// TODO: Add the force instead of only setting it to support multiple forces per frame?
|
||||
m_forceToApply = direc;
|
||||
|
||||
m_isNudging = Nudging;
|
||||
m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
|
||||
}
|
||||
|
||||
@@ -2240,7 +2433,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
const float POSITION_TOLERANCE = 0.05f;
|
||||
//const int TIME_MS_TOLERANCE = 3000;
|
||||
|
||||
SendPrimUpdates();
|
||||
|
||||
|
||||
if (m_newCoarseLocations)
|
||||
{
|
||||
@@ -2276,6 +2469,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
CheckForBorderCrossing();
|
||||
CheckForSignificantMovement(); // sends update to the modules.
|
||||
}
|
||||
|
||||
//Sending prim updates AFTER the avatar terse updates are sent
|
||||
SendPrimUpdates();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -3129,14 +3325,25 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
if (m_forceToApply.HasValue)
|
||||
{
|
||||
Vector3 force = m_forceToApply.Value;
|
||||
|
||||
Vector3 force = m_forceToApply.Value;
|
||||
m_updateflag = true;
|
||||
// movementvector = force;
|
||||
Velocity = force;
|
||||
|
||||
m_forceToApply = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_isNudging)
|
||||
{
|
||||
Vector3 force = Vector3.Zero;
|
||||
|
||||
m_updateflag = true;
|
||||
Velocity = force;
|
||||
m_isNudging = false;
|
||||
m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetText(string text, Vector3 color, double alpha)
|
||||
@@ -3188,18 +3395,29 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
if (e == null)
|
||||
return;
|
||||
|
||||
//if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
|
||||
// The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
|
||||
|
||||
// The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
|
||||
// as of this comment the interval is set in AddToPhysicalScene
|
||||
if (Animator!=null)
|
||||
Animator.UpdateMovementAnimations();
|
||||
{
|
||||
if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
|
||||
{ // else its will lock out other animation changes, like ground sit.
|
||||
Animator.UpdateMovementAnimations();
|
||||
m_updateCount--;
|
||||
}
|
||||
}
|
||||
|
||||
CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
|
||||
Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
|
||||
|
||||
CollisionPlane = Vector4.UnitW;
|
||||
|
||||
if (m_lastColCount != coldata.Count)
|
||||
{
|
||||
m_updateCount = UPDATE_COUNT;
|
||||
m_lastColCount = coldata.Count;
|
||||
}
|
||||
|
||||
if (coldata.Count != 0 && Animator != null)
|
||||
{
|
||||
switch (Animator.CurrentMovementAnimation)
|
||||
@@ -3847,5 +4065,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
m_reprioritization_called = false;
|
||||
}
|
||||
}
|
||||
|
||||
private Vector3 Quat2Euler(Quaternion rot){
|
||||
float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
|
||||
(double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
|
||||
float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
|
||||
float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
|
||||
(double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
|
||||
return(new Vector3(x,y,z));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,16 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID)
|
||||
{
|
||||
//This connector doesn't support the windlight module yet
|
||||
//Return default LL windlight settings
|
||||
return new RegionMeta7WindlightData();
|
||||
}
|
||||
public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl)
|
||||
{
|
||||
//This connector doesn't support the windlight module yet
|
||||
}
|
||||
public RegionSettings LoadRegionSettings(UUID regionUUID)
|
||||
{
|
||||
return null;
|
||||
|
||||
@@ -955,7 +955,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
|
||||
// TODO
|
||||
}
|
||||
|
||||
public void SendGenericMessage(string method, List<string> message)
|
||||
public void SendGenericMessage(string method, List<byte[]> message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -542,7 +542,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||
|
||||
}
|
||||
|
||||
public void SendGenericMessage(string method, List<string> message)
|
||||
public void SendGenericMessage(string method, List<byte[]> message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -619,8 +619,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
|
||||
{
|
||||
set { return; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override Quaternion APIDTarget
|
||||
{
|
||||
set { return; }
|
||||
|
||||
58
OpenSim/Region/Physics/ChOdePlugin/AssemblyInfo.cs
Normal file
58
OpenSim/Region/Physics/ChOdePlugin/AssemblyInfo.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Information about this assembly is defined by the following
|
||||
// attributes.
|
||||
//
|
||||
// change them to the information which is associated with the assembly
|
||||
// you compile.
|
||||
|
||||
[assembly : AssemblyTitle("OdePlugin")]
|
||||
[assembly : AssemblyDescription("")]
|
||||
[assembly : AssemblyConfiguration("")]
|
||||
[assembly : AssemblyCompany("http://opensimulator.org")]
|
||||
[assembly : AssemblyProduct("OdePlugin")]
|
||||
[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")]
|
||||
[assembly : AssemblyTrademark("")]
|
||||
[assembly : AssemblyCulture("")]
|
||||
|
||||
// This sets the default COM visibility of types in the assembly to invisible.
|
||||
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
|
||||
|
||||
[assembly : ComVisible(false)]
|
||||
|
||||
// The assembly version has following format :
|
||||
//
|
||||
// Major.Minor.Build.Revision
|
||||
//
|
||||
// You can specify all values by your own or you can build default build and revision
|
||||
// numbers with the '*' character (the default):
|
||||
|
||||
[assembly : AssemblyVersion("0.6.5.*")]
|
||||
1353
OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs
Normal file
1353
OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs
Normal file
File diff suppressed because it is too large
Load Diff
630
OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.c_comments
Normal file
630
OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.c_comments
Normal file
@@ -0,0 +1,630 @@
|
||||
/*
|
||||
* Revised August 26 2009 by Kitto Flora. ODEDynamics.cs replaces
|
||||
* ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised:
|
||||
* ODEPrim.cs contains methods dealing with Prim editing, Prim
|
||||
* characteristics and Kinetic motion.
|
||||
* ODEDynamics.cs contains methods dealing with Prim Physical motion
|
||||
* (dynamics) and the associated settings. Old Linear and angular
|
||||
* motors for dynamic motion have been replace with MoveLinear()
|
||||
* and MoveAngular(); 'Physical' is used only to switch ODE dynamic
|
||||
* simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
|
||||
* switch between 'VEHICLE' parameter use and general dynamics
|
||||
* settings use.
|
||||
*
|
||||
* 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 System.Runtime.InteropServices;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using Ode.NET;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
|
||||
namespace OpenSim.Region.Physics.OdePlugin
|
||||
{
|
||||
public class ODEDynamics
|
||||
{
|
||||
public Vehicle Type
|
||||
{
|
||||
get { return m_type; }
|
||||
}
|
||||
|
||||
public IntPtr Body
|
||||
{
|
||||
get { return m_body; }
|
||||
}
|
||||
|
||||
private int frcount = 0; // Used to limit dynamics debug output to
|
||||
// every 100th frame
|
||||
|
||||
// private OdeScene m_parentScene = null;
|
||||
private IntPtr m_body = IntPtr.Zero;
|
||||
private IntPtr m_jointGroup = IntPtr.Zero;
|
||||
private IntPtr m_aMotor = IntPtr.Zero;
|
||||
|
||||
|
||||
// Vehicle properties
|
||||
private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind
|
||||
// private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier
|
||||
private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings:
|
||||
// HOVER_TERRAIN_ONLY
|
||||
// HOVER_GLOBAL_HEIGHT
|
||||
// NO_DEFLECTION_UP
|
||||
// HOVER_WATER_ONLY
|
||||
// HOVER_UP_ONLY
|
||||
// LIMIT_MOTOR_UP
|
||||
// LIMIT_ROLL_ONLY
|
||||
|
||||
// Linear properties
|
||||
private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time
|
||||
private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL
|
||||
private Vector3 m_dir = Vector3.Zero; // velocity applied to body
|
||||
private Vector3 m_linearFrictionTimescale = Vector3.Zero;
|
||||
private float m_linearMotorDecayTimescale = 0;
|
||||
private float m_linearMotorTimescale = 0;
|
||||
private Vector3 m_lastLinearVelocityVector = Vector3.Zero;
|
||||
// private bool m_LinearMotorSetLastFrame = false;
|
||||
// private Vector3 m_linearMotorOffset = Vector3.Zero;
|
||||
|
||||
//Angular properties
|
||||
private Vector3 m_angularMotorDirection = Vector3.Zero;
|
||||
private Vector3 m_angularMotorDirectionLASTSET = Vector3.Zero;
|
||||
private Vector3 m_angularFrictionTimescale = Vector3.Zero;
|
||||
private float m_angularMotorDecayTimescale = 0;
|
||||
private float m_angularMotorTimescale = 0;
|
||||
private Vector3 m_lastAngularVelocityVector = Vector3.Zero;
|
||||
|
||||
//Deflection properties
|
||||
// private float m_angularDeflectionEfficiency = 0;
|
||||
// private float m_angularDeflectionTimescale = 0;
|
||||
// private float m_linearDeflectionEfficiency = 0;
|
||||
// private float m_linearDeflectionTimescale = 0;
|
||||
|
||||
//Banking properties
|
||||
// private float m_bankingEfficiency = 0;
|
||||
// private float m_bankingMix = 0;
|
||||
// private float m_bankingTimescale = 0;
|
||||
|
||||
//Hover and Buoyancy properties
|
||||
private float m_VhoverHeight = 0f;
|
||||
private float m_VhoverEfficiency = 0f;
|
||||
private float m_VhoverTimescale = 0f;
|
||||
private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height
|
||||
private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle.
|
||||
// Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity)
|
||||
// KF: So far I have found no good method to combine a script-requested .Z velocity and gravity.
|
||||
// Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity.
|
||||
|
||||
//Attractor properties
|
||||
private float m_verticalAttractionEfficiency = 0;
|
||||
private float m_verticalAttractionTimescale = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
|
||||
{
|
||||
switch (pParam)
|
||||
{
|
||||
case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
// m_angularDeflectionEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
// m_angularDeflectionTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
m_angularMotorDecayTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
m_angularMotorTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.BANKING_EFFICIENCY:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
// m_bankingEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.BANKING_MIX:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
// m_bankingMix = pValue;
|
||||
break;
|
||||
case Vehicle.BANKING_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
// m_bankingTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.BUOYANCY:
|
||||
if (pValue < -1f) pValue = -1f;
|
||||
if (pValue > 1f) pValue = 1f;
|
||||
m_VehicleBuoyancy = pValue;
|
||||
break;
|
||||
case Vehicle.HOVER_EFFICIENCY:
|
||||
if (pValue < 0f) pValue = 0f;
|
||||
if (pValue > 1f) pValue = 1f;
|
||||
m_VhoverEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.HOVER_HEIGHT:
|
||||
m_VhoverHeight = pValue;
|
||||
break;
|
||||
case Vehicle.HOVER_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
m_VhoverTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
// m_linearDeflectionEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
// m_linearDeflectionTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
m_linearMotorDecayTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
m_linearMotorTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
|
||||
if (pValue < 0.0f) pValue = 0.0f;
|
||||
if (pValue > 1.0f) pValue = 1.0f;
|
||||
m_verticalAttractionEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
m_verticalAttractionTimescale = pValue;
|
||||
break;
|
||||
|
||||
// These are vector properties but the engine lets you use a single float value to
|
||||
// set all of the components to the same value
|
||||
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||
m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
||||
m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||
m_angularMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue);
|
||||
break;
|
||||
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||
m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
||||
m_linearMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||
m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue);
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||
// m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}//end ProcessFloatVehicleParam
|
||||
|
||||
internal void ProcessVectorVehicleParam(Vehicle pParam, PhysicsVector pValue)
|
||||
{
|
||||
switch (pParam)
|
||||
{
|
||||
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||
m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
||||
m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
m_angularMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
break;
|
||||
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||
m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
||||
m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||
// m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
break;
|
||||
}
|
||||
|
||||
}//end ProcessVectorVehicleParam
|
||||
|
||||
internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
|
||||
{
|
||||
switch (pParam)
|
||||
{
|
||||
case Vehicle.REFERENCE_FRAME:
|
||||
// m_referenceFrame = pValue;
|
||||
break;
|
||||
}
|
||||
|
||||
}//end ProcessRotationVehicleParam
|
||||
|
||||
internal void ProcessTypeChange(Vehicle pType)
|
||||
{
|
||||
Console.WriteLine("ProcessTypeChange to " + pType);
|
||||
|
||||
// Set Defaults For Type
|
||||
m_type = pType;
|
||||
switch (pType)
|
||||
{
|
||||
case Vehicle.TYPE_SLED:
|
||||
m_linearFrictionTimescale = new Vector3(30, 1, 1000);
|
||||
m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||
m_linearMotorDirection = Vector3.Zero;
|
||||
m_linearMotorTimescale = 1000;
|
||||
m_linearMotorDecayTimescale = 120;
|
||||
m_angularMotorDirection = Vector3.Zero;
|
||||
m_angularMotorTimescale = 1000;
|
||||
m_angularMotorDecayTimescale = 120;
|
||||
m_VhoverHeight = 0;
|
||||
m_VhoverEfficiency = 1;
|
||||
m_VhoverTimescale = 10;
|
||||
m_VehicleBuoyancy = 0;
|
||||
// m_linearDeflectionEfficiency = 1;
|
||||
// m_linearDeflectionTimescale = 1;
|
||||
// m_angularDeflectionEfficiency = 1;
|
||||
// m_angularDeflectionTimescale = 1000;
|
||||
// m_bankingEfficiency = 0;
|
||||
// m_bankingMix = 1;
|
||||
// m_bankingTimescale = 10;
|
||||
// m_referenceFrame = Quaternion.Identity;
|
||||
m_flags &=
|
||||
~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
|
||||
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
||||
break;
|
||||
case Vehicle.TYPE_CAR:
|
||||
m_linearFrictionTimescale = new Vector3(100, 2, 1000);
|
||||
m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||
m_linearMotorDirection = Vector3.Zero;
|
||||
m_linearMotorTimescale = 1;
|
||||
m_linearMotorDecayTimescale = 60;
|
||||
m_angularMotorDirection = Vector3.Zero;
|
||||
m_angularMotorTimescale = 1;
|
||||
m_angularMotorDecayTimescale = 0.8f;
|
||||
m_VhoverHeight = 0;
|
||||
m_VhoverEfficiency = 0;
|
||||
m_VhoverTimescale = 1000;
|
||||
m_VehicleBuoyancy = 0;
|
||||
// // m_linearDeflectionEfficiency = 1;
|
||||
// // m_linearDeflectionTimescale = 2;
|
||||
// // m_angularDeflectionEfficiency = 0;
|
||||
// m_angularDeflectionTimescale = 10;
|
||||
m_verticalAttractionEfficiency = 1;
|
||||
m_verticalAttractionTimescale = 10;
|
||||
// m_bankingEfficiency = -0.2f;
|
||||
// m_bankingMix = 1;
|
||||
// m_bankingTimescale = 1;
|
||||
// m_referenceFrame = Quaternion.Identity;
|
||||
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_UP_ONLY |
|
||||
VehicleFlag.LIMIT_MOTOR_UP);
|
||||
break;
|
||||
case Vehicle.TYPE_BOAT:
|
||||
m_linearFrictionTimescale = new Vector3(10, 3, 2);
|
||||
m_angularFrictionTimescale = new Vector3(10,10,10);
|
||||
m_linearMotorDirection = Vector3.Zero;
|
||||
m_linearMotorTimescale = 5;
|
||||
m_linearMotorDecayTimescale = 60;
|
||||
m_angularMotorDirection = Vector3.Zero;
|
||||
m_angularMotorTimescale = 4;
|
||||
m_angularMotorDecayTimescale = 4;
|
||||
m_VhoverHeight = 0;
|
||||
m_VhoverEfficiency = 0.5f;
|
||||
m_VhoverTimescale = 2;
|
||||
m_VehicleBuoyancy = 1;
|
||||
// m_linearDeflectionEfficiency = 0.5f;
|
||||
// m_linearDeflectionTimescale = 3;
|
||||
// m_angularDeflectionEfficiency = 0.5f;
|
||||
// m_angularDeflectionTimescale = 5;
|
||||
m_verticalAttractionEfficiency = 0.5f;
|
||||
m_verticalAttractionTimescale = 5;
|
||||
// m_bankingEfficiency = -0.3f;
|
||||
// m_bankingMix = 0.8f;
|
||||
// m_bankingTimescale = 1;
|
||||
// m_referenceFrame = Quaternion.Identity;
|
||||
m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.LIMIT_ROLL_ONLY |
|
||||
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
|
||||
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY |
|
||||
VehicleFlag.LIMIT_MOTOR_UP);
|
||||
break;
|
||||
case Vehicle.TYPE_AIRPLANE:
|
||||
m_linearFrictionTimescale = new Vector3(200, 10, 5);
|
||||
m_angularFrictionTimescale = new Vector3(20, 20, 20);
|
||||
m_linearMotorDirection = Vector3.Zero;
|
||||
m_linearMotorTimescale = 2;
|
||||
m_linearMotorDecayTimescale = 60;
|
||||
m_angularMotorDirection = Vector3.Zero;
|
||||
m_angularMotorTimescale = 4;
|
||||
m_angularMotorDecayTimescale = 4;
|
||||
m_VhoverHeight = 0;
|
||||
m_VhoverEfficiency = 0.5f;
|
||||
m_VhoverTimescale = 1000;
|
||||
m_VehicleBuoyancy = 0;
|
||||
// m_linearDeflectionEfficiency = 0.5f;
|
||||
// m_linearDeflectionTimescale = 3;
|
||||
// m_angularDeflectionEfficiency = 1;
|
||||
// m_angularDeflectionTimescale = 2;
|
||||
m_verticalAttractionEfficiency = 0.9f;
|
||||
m_verticalAttractionTimescale = 2;
|
||||
// m_bankingEfficiency = 1;
|
||||
// m_bankingMix = 0.7f;
|
||||
// m_bankingTimescale = 2;
|
||||
// m_referenceFrame = Quaternion.Identity;
|
||||
m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
||||
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
|
||||
break;
|
||||
case Vehicle.TYPE_BALLOON:
|
||||
m_linearFrictionTimescale = new Vector3(5, 5, 5);
|
||||
m_angularFrictionTimescale = new Vector3(10, 10, 10);
|
||||
m_linearMotorDirection = Vector3.Zero;
|
||||
m_linearMotorTimescale = 5;
|
||||
m_linearMotorDecayTimescale = 60;
|
||||
m_angularMotorDirection = Vector3.Zero;
|
||||
m_angularMotorTimescale = 6;
|
||||
m_angularMotorDecayTimescale = 10;
|
||||
m_VhoverHeight = 5;
|
||||
m_VhoverEfficiency = 0.8f;
|
||||
m_VhoverTimescale = 10;
|
||||
m_VehicleBuoyancy = 1;
|
||||
// m_linearDeflectionEfficiency = 0;
|
||||
// m_linearDeflectionTimescale = 5;
|
||||
// m_angularDeflectionEfficiency = 0;
|
||||
// m_angularDeflectionTimescale = 5;
|
||||
m_verticalAttractionEfficiency = 1;
|
||||
m_verticalAttractionTimescale = 1000;
|
||||
// m_bankingEfficiency = 0;
|
||||
// m_bankingMix = 0.7f;
|
||||
// m_bankingTimescale = 5;
|
||||
// m_referenceFrame = Quaternion.Identity;
|
||||
m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
||||
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||
break;
|
||||
|
||||
}
|
||||
}//end SetDefaultsForType
|
||||
|
||||
internal void Enable(IntPtr pBody, OdeScene pParentScene)
|
||||
{
|
||||
//Console.WriteLine("Enable m_type=" + m_type + " m_VehicleBuoyancy=" + m_VehicleBuoyancy);
|
||||
if (m_type == Vehicle.TYPE_NONE)
|
||||
return;
|
||||
|
||||
m_body = pBody;
|
||||
//KF: This used to set up the linear and angular joints
|
||||
}
|
||||
|
||||
internal void Step(float pTimestep, OdeScene pParentScene)
|
||||
{
|
||||
if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE)
|
||||
return;
|
||||
frcount++; // used to limit debug comment output
|
||||
if (frcount > 100)
|
||||
frcount = 0;
|
||||
|
||||
MoveLinear(pTimestep, pParentScene);
|
||||
MoveAngular(pTimestep);
|
||||
}// end Step
|
||||
|
||||
private void MoveLinear(float pTimestep, OdeScene _pParentScene)
|
||||
{
|
||||
if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) // requested m_linearMotorDirection is significant
|
||||
{
|
||||
if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body);
|
||||
|
||||
// add drive to body
|
||||
Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep);
|
||||
m_lastLinearVelocityVector += (addAmount*10); // lastLinearVelocityVector is the current body velocity vector?
|
||||
|
||||
// This will work temporarily, but we really need to compare speed on an axis
|
||||
// KF: Limit body velocity to applied velocity?
|
||||
if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X))
|
||||
m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X;
|
||||
if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y))
|
||||
m_lastLinearVelocityVector.Y = m_linearMotorDirectionLASTSET.Y;
|
||||
if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z))
|
||||
m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z;
|
||||
|
||||
// decay applied velocity
|
||||
Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep)));
|
||||
//Console.WriteLine("decay: " + decayfraction);
|
||||
m_linearMotorDirection -= m_linearMotorDirection * decayfraction;
|
||||
//Console.WriteLine("actual: " + m_linearMotorDirection);
|
||||
}
|
||||
else
|
||||
{ // requested is not significant
|
||||
// if what remains of applied is small, zero it.
|
||||
if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f))
|
||||
m_lastLinearVelocityVector = Vector3.Zero;
|
||||
}
|
||||
|
||||
|
||||
// convert requested object velocity to world-referenced vector
|
||||
m_dir = m_lastLinearVelocityVector;
|
||||
d.Quaternion rot = d.BodyGetQuaternion(Body);
|
||||
Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object
|
||||
m_dir *= rotq; // apply obj rotation to velocity vector
|
||||
|
||||
// add Gravity andBuoyancy
|
||||
// KF: So far I have found no good method to combine a script-requested
|
||||
// .Z velocity and gravity. Therefore only 0g will used script-requested
|
||||
// .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only.
|
||||
Vector3 grav = Vector3.Zero;
|
||||
if(m_VehicleBuoyancy < 1.0f)
|
||||
{
|
||||
// There is some gravity, make a gravity force vector
|
||||
// that is applied after object velocity.
|
||||
d.Mass objMass;
|
||||
d.BodyGetMass(Body, out objMass);
|
||||
// m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
|
||||
grav.Z = _pParentScene.gravityz * objMass.mass * (1f - m_VehicleBuoyancy);
|
||||
// Preserve the current Z velocity
|
||||
d.Vector3 vel_now = d.BodyGetLinearVel(Body);
|
||||
m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity
|
||||
} // else its 1.0, no gravity.
|
||||
|
||||
// Check if hovering
|
||||
if( (m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
|
||||
{
|
||||
// We should hover, get the target height
|
||||
d.Vector3 pos = d.BodyGetPosition(Body);
|
||||
if((m_flags & VehicleFlag.HOVER_WATER_ONLY) == VehicleFlag.HOVER_WATER_ONLY)
|
||||
{
|
||||
m_VhoverTargetHeight = _pParentScene.GetWaterLevel() + m_VhoverHeight;
|
||||
}
|
||||
else if((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) == VehicleFlag.HOVER_TERRAIN_ONLY)
|
||||
{
|
||||
m_VhoverTargetHeight = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight;
|
||||
}
|
||||
else if((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) == VehicleFlag.HOVER_GLOBAL_HEIGHT)
|
||||
{
|
||||
m_VhoverTargetHeight = m_VhoverHeight;
|
||||
}
|
||||
|
||||
if((m_flags & VehicleFlag.HOVER_UP_ONLY) == VehicleFlag.HOVER_UP_ONLY)
|
||||
{
|
||||
// If body is aready heigher, use its height as target height
|
||||
if(pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z;
|
||||
}
|
||||
|
||||
// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped
|
||||
// m_VhoverTimescale = 0f; // time to acheive height
|
||||
// pTimestep is time since last frame,in secs
|
||||
float herr0 = pos.Z - m_VhoverTargetHeight;
|
||||
//if(frcount == 0) Console.WriteLine("herr0=" + herr0);
|
||||
// Replace Vertical speed with correction figure if significant
|
||||
if(Math.Abs(herr0) > 0.01f )
|
||||
{
|
||||
d.Mass objMass;
|
||||
d.BodyGetMass(Body, out objMass);
|
||||
m_dir.Z = - ( (herr0 * pTimestep * 50.0f) / m_VhoverTimescale);
|
||||
// m_VhoverEfficiency is not yet implemented
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dir.Z = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply velocity
|
||||
d.BodySetLinearVel(Body, m_dir.X, m_dir.Y, m_dir.Z);
|
||||
//if(frcount == 0) Console.WriteLine("Move " + Body + ":"+ m_dir.X + " " + m_dir.Y + " " + m_dir.Z);
|
||||
// apply gravity force
|
||||
d.BodyAddForce(Body, grav.X, grav.Y, grav.Z);
|
||||
//if(frcount == 0) Console.WriteLine("Force " + Body + ":" + grav.X + " " + grav.Y + " " + grav.Z);
|
||||
|
||||
|
||||
// apply friction
|
||||
Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep);
|
||||
m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount;
|
||||
} // end MoveLinear()
|
||||
|
||||
private void MoveAngular(float pTimestep)
|
||||
{
|
||||
|
||||
// m_angularMotorDirection is the latest value from the script, and is decayed here
|
||||
// m_angularMotorDirectionLASTSET is the latest value from the script
|
||||
// m_lastAngularVelocityVector is what is being applied to the Body, varied up and down here
|
||||
|
||||
if (!m_angularMotorDirection.ApproxEquals(Vector3.Zero, 0.01f))
|
||||
{
|
||||
if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body);
|
||||
// ramp up to new value
|
||||
Vector3 addAmount = m_angularMotorDirection / (m_angularMotorTimescale / pTimestep);
|
||||
m_lastAngularVelocityVector += (addAmount * 10f);
|
||||
//if(frcount == 0) Console.WriteLine("add: " + addAmount);
|
||||
|
||||
// limit applied value to what was set by script
|
||||
// This will work temporarily, but we really need to compare speed on an axis
|
||||
if (Math.Abs(m_lastAngularVelocityVector.X) > Math.Abs(m_angularMotorDirectionLASTSET.X))
|
||||
m_lastAngularVelocityVector.X = m_angularMotorDirectionLASTSET.X;
|
||||
if (Math.Abs(m_lastAngularVelocityVector.Y) > Math.Abs(m_angularMotorDirectionLASTSET.Y))
|
||||
m_lastAngularVelocityVector.Y = m_angularMotorDirectionLASTSET.Y;
|
||||
if (Math.Abs(m_lastAngularVelocityVector.Z) > Math.Abs(m_angularMotorDirectionLASTSET.Z))
|
||||
m_lastAngularVelocityVector.Z = m_angularMotorDirectionLASTSET.Z;
|
||||
|
||||
// decay the requested value
|
||||
Vector3 decayfraction = ((Vector3.One / (m_angularMotorDecayTimescale / pTimestep)));
|
||||
//Console.WriteLine("decay: " + decayfraction);
|
||||
m_angularMotorDirection -= m_angularMotorDirection * decayfraction;
|
||||
//Console.WriteLine("actual: " + m_linearMotorDirection);
|
||||
}
|
||||
// KF: m_lastAngularVelocityVector is rotational speed in rad/sec ?
|
||||
|
||||
// Vertical attractor section
|
||||
|
||||
// d.Mass objMass;
|
||||
// d.BodyGetMass(Body, out objMass);
|
||||
// float servo = 100f * objMass.mass * m_verticalAttractionEfficiency / (m_verticalAttractionTimescale * pTimestep);
|
||||
float servo = 0.1f * m_verticalAttractionEfficiency / (m_verticalAttractionTimescale * pTimestep);
|
||||
// get present body rotation
|
||||
d.Quaternion rot = d.BodyGetQuaternion(Body);
|
||||
Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W);
|
||||
// make a vector pointing up
|
||||
Vector3 verterr = Vector3.Zero;
|
||||
verterr.Z = 1.0f;
|
||||
// rotate it to Body Angle
|
||||
verterr = verterr * rotq;
|
||||
// verterr.X and .Y are the World error ammounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1.
|
||||
// As the body leans to its side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall and .Z will go
|
||||
// negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body.
|
||||
if (verterr.Z < 0.0f)
|
||||
{
|
||||
verterr.X = 2.0f - verterr.X;
|
||||
verterr.Y = 2.0f - verterr.Y;
|
||||
}
|
||||
// Error is 0 (no error) to +/- 2 (max error)
|
||||
// scale it by servo
|
||||
verterr = verterr * servo;
|
||||
|
||||
// rotate to object frame
|
||||
// verterr = verterr * rotq;
|
||||
|
||||
// As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so
|
||||
// Change Body angular velocity X based on Y, and Y based on X. Z is not changed.
|
||||
m_lastAngularVelocityVector.X += verterr.Y;
|
||||
m_lastAngularVelocityVector.Y -= verterr.X;
|
||||
/*
|
||||
if(frcount == 0)
|
||||
{
|
||||
// Console.WriteLine("AngleMotor " + m_lastAngularVelocityVector);
|
||||
Console.WriteLine(String.Format("VA Body:{0} servo:{1} err:<{2},{3},{4}> VAE:{5}",
|
||||
Body, servo, verterr.X, verterr.Y, verterr.Z, m_verticalAttractionEfficiency));
|
||||
}
|
||||
*/
|
||||
d.BodySetAngularVel (Body, m_lastAngularVelocityVector.X, m_lastAngularVelocityVector.Y, m_lastAngularVelocityVector.Z);
|
||||
// apply friction
|
||||
Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / pTimestep);
|
||||
m_lastAngularVelocityVector -= m_lastAngularVelocityVector * decayamount;
|
||||
|
||||
} //end MoveAngular
|
||||
}
|
||||
}
|
||||
712
OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs
Normal file
712
OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs
Normal file
@@ -0,0 +1,712 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces
|
||||
* ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised:
|
||||
* ODEPrim.cs contains methods dealing with Prim editing, Prim
|
||||
* characteristics and Kinetic motion.
|
||||
* ODEDynamics.cs contains methods dealing with Prim Physical motion
|
||||
* (dynamics) and the associated settings. Old Linear and angular
|
||||
* motors for dynamic motion have been replace with MoveLinear()
|
||||
* and MoveAngular(); 'Physical' is used only to switch ODE dynamic
|
||||
* simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
|
||||
* switch between 'VEHICLE' parameter use and general dynamics
|
||||
* settings use.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces
|
||||
* ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised:
|
||||
* ODEPrim.cs contains methods dealing with Prim editing, Prim
|
||||
* characteristics and Kinetic motion.
|
||||
* ODEDynamics.cs contains methods dealing with Prim Physical motion
|
||||
* (dynamics) and the associated settings. Old Linear and angular
|
||||
* motors for dynamic motion have been replace with MoveLinear()
|
||||
* and MoveAngular(); 'Physical' is used only to switch ODE dynamic
|
||||
* simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
|
||||
* switch between 'VEHICLE' parameter use and general dynamics
|
||||
* settings use.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using Ode.NET;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
|
||||
namespace OpenSim.Region.Physics.OdePlugin
|
||||
{
|
||||
public class ODEDynamics
|
||||
{
|
||||
public Vehicle Type
|
||||
{
|
||||
get { return m_type; }
|
||||
}
|
||||
|
||||
public IntPtr Body
|
||||
{
|
||||
get { return m_body; }
|
||||
}
|
||||
|
||||
private int frcount = 0; // Used to limit dynamics debug output to
|
||||
// every 100th frame
|
||||
|
||||
// private OdeScene m_parentScene = null;
|
||||
private IntPtr m_body = IntPtr.Zero;
|
||||
// private IntPtr m_jointGroup = IntPtr.Zero;
|
||||
// private IntPtr m_aMotor = IntPtr.Zero;
|
||||
|
||||
// Vehicle properties
|
||||
private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind
|
||||
// private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier
|
||||
private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings:
|
||||
// HOVER_TERRAIN_ONLY
|
||||
// HOVER_GLOBAL_HEIGHT
|
||||
// NO_DEFLECTION_UP
|
||||
// HOVER_WATER_ONLY
|
||||
// HOVER_UP_ONLY
|
||||
// LIMIT_MOTOR_UP
|
||||
// LIMIT_ROLL_ONLY
|
||||
|
||||
// Linear properties
|
||||
private Vector3 m_linearMotorDirection = Vector3.Zero; // (was m_linearMotorDirectionLASTSET) the (local) Velocity
|
||||
//requested by LSL
|
||||
private float m_linearMotorTimescale = 0; // Motor Attack rate set by LSL
|
||||
private float m_linearMotorDecayTimescale = 0; // Motor Decay rate set by LSL
|
||||
private Vector3 m_linearFrictionTimescale = Vector3.Zero; // General Friction set by LSL
|
||||
|
||||
private Vector3 m_lLinMotorDVel = Vector3.Zero; // decayed motor
|
||||
private Vector3 m_lLinObjectVel = Vector3.Zero; // local frame object velocity
|
||||
private Vector3 m_wLinObjectVel = Vector3.Zero; // world frame object velocity
|
||||
|
||||
//Angular properties
|
||||
private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor
|
||||
private int m_angularMotorApply = 0; // application frame counter
|
||||
private Vector3 m_angularMotorVelocity = Vector3.Zero; // current angular motor velocity
|
||||
private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate
|
||||
private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate
|
||||
private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate
|
||||
private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body
|
||||
// private Vector3 m_lastVertAttractor = Vector3.Zero; // what VA was last applied to body
|
||||
|
||||
//Deflection properties
|
||||
// private float m_angularDeflectionEfficiency = 0;
|
||||
// private float m_angularDeflectionTimescale = 0;
|
||||
// private float m_linearDeflectionEfficiency = 0;
|
||||
// private float m_linearDeflectionTimescale = 0;
|
||||
|
||||
//Banking properties
|
||||
// private float m_bankingEfficiency = 0;
|
||||
// private float m_bankingMix = 0;
|
||||
// private float m_bankingTimescale = 0;
|
||||
|
||||
//Hover and Buoyancy properties
|
||||
private float m_VhoverHeight = 0f;
|
||||
// private float m_VhoverEfficiency = 0f;
|
||||
private float m_VhoverTimescale = 0f;
|
||||
private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height
|
||||
private float m_VehicleBuoyancy = 0f; // Set by VEHICLE_BUOYANCY, for a vehicle.
|
||||
// Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity)
|
||||
// KF: So far I have found no good method to combine a script-requested .Z velocity and gravity.
|
||||
// Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity.
|
||||
|
||||
//Attractor properties
|
||||
private float m_verticalAttractionEfficiency = 1.0f; // damped
|
||||
private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
|
||||
{
|
||||
switch (pParam)
|
||||
{
|
||||
case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
// m_angularDeflectionEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
// m_angularDeflectionTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
m_angularMotorDecayTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
m_angularMotorTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.BANKING_EFFICIENCY:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
// m_bankingEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.BANKING_MIX:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
// m_bankingMix = pValue;
|
||||
break;
|
||||
case Vehicle.BANKING_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
// m_bankingTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.BUOYANCY:
|
||||
if (pValue < -1f) pValue = -1f;
|
||||
if (pValue > 1f) pValue = 1f;
|
||||
m_VehicleBuoyancy = pValue;
|
||||
break;
|
||||
// case Vehicle.HOVER_EFFICIENCY:
|
||||
// if (pValue < 0f) pValue = 0f;
|
||||
// if (pValue > 1f) pValue = 1f;
|
||||
// m_VhoverEfficiency = pValue;
|
||||
// break;
|
||||
case Vehicle.HOVER_HEIGHT:
|
||||
m_VhoverHeight = pValue;
|
||||
break;
|
||||
case Vehicle.HOVER_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
m_VhoverTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
// m_linearDeflectionEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
// m_linearDeflectionTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
m_linearMotorDecayTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
m_linearMotorTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
|
||||
if (pValue < 0.1f) pValue = 0.1f; // Less goes unstable
|
||||
if (pValue > 1.0f) pValue = 1.0f;
|
||||
m_verticalAttractionEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
m_verticalAttractionTimescale = pValue;
|
||||
break;
|
||||
|
||||
// These are vector properties but the engine lets you use a single float value to
|
||||
// set all of the components to the same value
|
||||
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||
m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
||||
m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||
m_angularMotorApply = 10;
|
||||
break;
|
||||
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||
m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
||||
m_linearMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||
UpdateLinDecay();
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||
// m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}//end ProcessFloatVehicleParam
|
||||
|
||||
internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue)
|
||||
{
|
||||
switch (pParam)
|
||||
{
|
||||
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||
m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
||||
m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
// Limit requested angular speed to 2 rps= 4 pi rads/sec
|
||||
if(m_angularMotorDirection.X > 12.56f) m_angularMotorDirection.X = 12.56f;
|
||||
if(m_angularMotorDirection.X < - 12.56f) m_angularMotorDirection.X = - 12.56f;
|
||||
if(m_angularMotorDirection.Y > 12.56f) m_angularMotorDirection.Y = 12.56f;
|
||||
if(m_angularMotorDirection.Y < - 12.56f) m_angularMotorDirection.Y = - 12.56f;
|
||||
if(m_angularMotorDirection.Z > 12.56f) m_angularMotorDirection.Z = 12.56f;
|
||||
if(m_angularMotorDirection.Z < - 12.56f) m_angularMotorDirection.Z = - 12.56f;
|
||||
m_angularMotorApply = 10;
|
||||
break;
|
||||
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||
m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
||||
m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); // velocity requested by LSL, for max limiting
|
||||
UpdateLinDecay();
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||
// m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
break;
|
||||
}
|
||||
|
||||
}//end ProcessVectorVehicleParam
|
||||
|
||||
internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
|
||||
{
|
||||
switch (pParam)
|
||||
{
|
||||
case Vehicle.REFERENCE_FRAME:
|
||||
// m_referenceFrame = pValue;
|
||||
break;
|
||||
}
|
||||
|
||||
}//end ProcessRotationVehicleParam
|
||||
|
||||
internal void ProcessTypeChange(Vehicle pType)
|
||||
{
|
||||
// Set Defaults For Type
|
||||
m_type = pType;
|
||||
switch (pType)
|
||||
{
|
||||
case Vehicle.TYPE_SLED:
|
||||
m_linearFrictionTimescale = new Vector3(30, 1, 1000);
|
||||
m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||
// m_lLinMotorVel = Vector3.Zero;
|
||||
m_linearMotorTimescale = 1000;
|
||||
m_linearMotorDecayTimescale = 120;
|
||||
m_angularMotorDirection = Vector3.Zero;
|
||||
m_angularMotorTimescale = 1000;
|
||||
m_angularMotorDecayTimescale = 120;
|
||||
m_VhoverHeight = 0;
|
||||
// m_VhoverEfficiency = 1;
|
||||
m_VhoverTimescale = 10;
|
||||
m_VehicleBuoyancy = 0;
|
||||
// m_linearDeflectionEfficiency = 1;
|
||||
// m_linearDeflectionTimescale = 1;
|
||||
// m_angularDeflectionEfficiency = 1;
|
||||
// m_angularDeflectionTimescale = 1000;
|
||||
// m_bankingEfficiency = 0;
|
||||
// m_bankingMix = 1;
|
||||
// m_bankingTimescale = 10;
|
||||
// m_referenceFrame = Quaternion.Identity;
|
||||
m_flags &=
|
||||
~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
|
||||
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
||||
break;
|
||||
case Vehicle.TYPE_CAR:
|
||||
m_linearFrictionTimescale = new Vector3(100, 2, 1000);
|
||||
m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||
// m_lLinMotorVel = Vector3.Zero;
|
||||
m_linearMotorTimescale = 1;
|
||||
m_linearMotorDecayTimescale = 60;
|
||||
m_angularMotorDirection = Vector3.Zero;
|
||||
m_angularMotorTimescale = 1;
|
||||
m_angularMotorDecayTimescale = 0.8f;
|
||||
m_VhoverHeight = 0;
|
||||
// m_VhoverEfficiency = 0;
|
||||
m_VhoverTimescale = 1000;
|
||||
m_VehicleBuoyancy = 0;
|
||||
// // m_linearDeflectionEfficiency = 1;
|
||||
// // m_linearDeflectionTimescale = 2;
|
||||
// // m_angularDeflectionEfficiency = 0;
|
||||
// m_angularDeflectionTimescale = 10;
|
||||
m_verticalAttractionEfficiency = 1f;
|
||||
m_verticalAttractionTimescale = 10f;
|
||||
// m_bankingEfficiency = -0.2f;
|
||||
// m_bankingMix = 1;
|
||||
// m_bankingTimescale = 1;
|
||||
// m_referenceFrame = Quaternion.Identity;
|
||||
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_UP_ONLY |
|
||||
VehicleFlag.LIMIT_MOTOR_UP);
|
||||
break;
|
||||
case Vehicle.TYPE_BOAT:
|
||||
m_linearFrictionTimescale = new Vector3(10, 3, 2);
|
||||
m_angularFrictionTimescale = new Vector3(10,10,10);
|
||||
// m_lLinMotorVel = Vector3.Zero;
|
||||
m_linearMotorTimescale = 5;
|
||||
m_linearMotorDecayTimescale = 60;
|
||||
m_angularMotorDirection = Vector3.Zero;
|
||||
m_angularMotorTimescale = 4;
|
||||
m_angularMotorDecayTimescale = 4;
|
||||
m_VhoverHeight = 0;
|
||||
// m_VhoverEfficiency = 0.5f;
|
||||
m_VhoverTimescale = 2;
|
||||
m_VehicleBuoyancy = 1;
|
||||
// m_linearDeflectionEfficiency = 0.5f;
|
||||
// m_linearDeflectionTimescale = 3;
|
||||
// m_angularDeflectionEfficiency = 0.5f;
|
||||
// m_angularDeflectionTimescale = 5;
|
||||
m_verticalAttractionEfficiency = 0.5f;
|
||||
m_verticalAttractionTimescale = 5f;
|
||||
// m_bankingEfficiency = -0.3f;
|
||||
// m_bankingMix = 0.8f;
|
||||
// m_bankingTimescale = 1;
|
||||
// m_referenceFrame = Quaternion.Identity;
|
||||
m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.LIMIT_ROLL_ONLY |
|
||||
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
|
||||
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY |
|
||||
VehicleFlag.LIMIT_MOTOR_UP);
|
||||
break;
|
||||
case Vehicle.TYPE_AIRPLANE:
|
||||
m_linearFrictionTimescale = new Vector3(200, 10, 5);
|
||||
m_angularFrictionTimescale = new Vector3(20, 20, 20);
|
||||
// m_lLinMotorVel = Vector3.Zero;
|
||||
m_linearMotorTimescale = 2;
|
||||
m_linearMotorDecayTimescale = 60;
|
||||
m_angularMotorDirection = Vector3.Zero;
|
||||
m_angularMotorTimescale = 4;
|
||||
m_angularMotorDecayTimescale = 4;
|
||||
m_VhoverHeight = 0;
|
||||
// m_VhoverEfficiency = 0.5f;
|
||||
m_VhoverTimescale = 1000;
|
||||
m_VehicleBuoyancy = 0;
|
||||
// m_linearDeflectionEfficiency = 0.5f;
|
||||
// m_linearDeflectionTimescale = 3;
|
||||
// m_angularDeflectionEfficiency = 1;
|
||||
// m_angularDeflectionTimescale = 2;
|
||||
m_verticalAttractionEfficiency = 0.9f;
|
||||
m_verticalAttractionTimescale = 2f;
|
||||
// m_bankingEfficiency = 1;
|
||||
// m_bankingMix = 0.7f;
|
||||
// m_bankingTimescale = 2;
|
||||
// m_referenceFrame = Quaternion.Identity;
|
||||
m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
||||
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
|
||||
break;
|
||||
case Vehicle.TYPE_BALLOON:
|
||||
m_linearFrictionTimescale = new Vector3(5, 5, 5);
|
||||
m_angularFrictionTimescale = new Vector3(10, 10, 10);
|
||||
m_linearMotorTimescale = 5;
|
||||
m_linearMotorDecayTimescale = 60;
|
||||
m_angularMotorDirection = Vector3.Zero;
|
||||
m_angularMotorTimescale = 6;
|
||||
m_angularMotorDecayTimescale = 10;
|
||||
m_VhoverHeight = 5;
|
||||
// m_VhoverEfficiency = 0.8f;
|
||||
m_VhoverTimescale = 10;
|
||||
m_VehicleBuoyancy = 1;
|
||||
// m_linearDeflectionEfficiency = 0;
|
||||
// m_linearDeflectionTimescale = 5;
|
||||
// m_angularDeflectionEfficiency = 0;
|
||||
// m_angularDeflectionTimescale = 5;
|
||||
m_verticalAttractionEfficiency = 1f;
|
||||
m_verticalAttractionTimescale = 100f;
|
||||
// m_bankingEfficiency = 0;
|
||||
// m_bankingMix = 0.7f;
|
||||
// m_bankingTimescale = 5;
|
||||
// m_referenceFrame = Quaternion.Identity;
|
||||
m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
||||
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||
break;
|
||||
|
||||
}
|
||||
}//end SetDefaultsForType
|
||||
|
||||
internal void Enable(IntPtr pBody, OdeScene pParentScene)
|
||||
{
|
||||
if (m_type == Vehicle.TYPE_NONE)
|
||||
return;
|
||||
|
||||
m_body = pBody;
|
||||
}
|
||||
|
||||
internal void Step(float pTimestep, OdeScene pParentScene)
|
||||
{
|
||||
if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE)
|
||||
return;
|
||||
frcount++; // used to limit debug comment output
|
||||
if (frcount > 24)
|
||||
frcount = 0;
|
||||
|
||||
MoveLinear(pTimestep, pParentScene);
|
||||
MoveAngular(pTimestep);
|
||||
}// end Step
|
||||
|
||||
internal void Halt()
|
||||
{ // Kill all motions, when non-physical
|
||||
m_linearMotorDirection = Vector3.Zero;
|
||||
m_lLinMotorDVel = Vector3.Zero;
|
||||
m_lLinObjectVel = Vector3.Zero;
|
||||
m_wLinObjectVel = Vector3.Zero;
|
||||
m_angularMotorDirection = Vector3.Zero;
|
||||
m_angularMotorVelocity = Vector3.Zero;
|
||||
m_lastAngularVelocity = Vector3.Zero;
|
||||
}
|
||||
|
||||
private void UpdateLinDecay()
|
||||
{
|
||||
if (Math.Abs(m_linearMotorDirection.X) > Math.Abs(m_lLinMotorDVel.X)) m_lLinMotorDVel.X = m_linearMotorDirection.X;
|
||||
if (Math.Abs(m_linearMotorDirection.Y) > Math.Abs(m_lLinMotorDVel.Y)) m_lLinMotorDVel.Y = m_linearMotorDirection.Y;
|
||||
if (Math.Abs(m_linearMotorDirection.Z) > Math.Abs(m_lLinMotorDVel.Z)) m_lLinMotorDVel.Z = m_linearMotorDirection.Z;
|
||||
} // else let the motor decay on its own
|
||||
|
||||
private void MoveLinear(float pTimestep, OdeScene _pParentScene)
|
||||
{
|
||||
Vector3 acceleration = new Vector3(0f, 0f, 0f);
|
||||
|
||||
d.Quaternion rot = d.BodyGetQuaternion(Body);
|
||||
Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object
|
||||
Quaternion irotq = Quaternion.Inverse(rotq);
|
||||
d.Vector3 velnow = d.BodyGetLinearVel(Body); // this is in world frame
|
||||
Vector3 vel_now = new Vector3(velnow.X, velnow.Y, velnow.Z);
|
||||
acceleration = vel_now - m_wLinObjectVel;
|
||||
m_lLinObjectVel = vel_now * irotq;
|
||||
|
||||
if (m_linearMotorDecayTimescale < 300.0f) //setting of 300 or more disables decay rate
|
||||
{
|
||||
if ( Vector3.Mag(m_lLinMotorDVel) < 1.0f)
|
||||
{
|
||||
float decayfactor = m_linearMotorDecayTimescale/pTimestep;
|
||||
Vector3 decayAmount = (m_lLinMotorDVel/decayfactor);
|
||||
m_lLinMotorDVel -= decayAmount;
|
||||
}
|
||||
else
|
||||
{
|
||||
float decayfactor = 3.0f - (0.57f * (float)Math.Log((double)(m_linearMotorDecayTimescale)));
|
||||
Vector3 decel = Vector3.Normalize(m_lLinMotorDVel) * decayfactor * pTimestep;
|
||||
m_lLinMotorDVel -= decel;
|
||||
}
|
||||
if (m_lLinMotorDVel.ApproxEquals(Vector3.Zero, 0.01f))
|
||||
{
|
||||
m_lLinMotorDVel = Vector3.Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Math.Abs(m_lLinMotorDVel.X) < Math.Abs(m_lLinObjectVel.X)) m_lLinObjectVel.X = m_lLinMotorDVel.X;
|
||||
if (Math.Abs(m_lLinMotorDVel.Y) < Math.Abs(m_lLinObjectVel.Y)) m_lLinObjectVel.Y = m_lLinMotorDVel.Y;
|
||||
if (Math.Abs(m_lLinMotorDVel.Z) < Math.Abs(m_lLinObjectVel.Z)) m_lLinObjectVel.Z = m_lLinMotorDVel.Z;
|
||||
}
|
||||
}
|
||||
|
||||
if ( (! m_lLinMotorDVel.ApproxEquals(Vector3.Zero, 0.01f)) || (! m_lLinObjectVel.ApproxEquals(Vector3.Zero, 0.01f)) )
|
||||
{
|
||||
if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body);
|
||||
if (m_linearMotorTimescale < 300.0f)
|
||||
{
|
||||
Vector3 attack_error = m_lLinMotorDVel - m_lLinObjectVel;
|
||||
float linfactor = m_linearMotorTimescale/pTimestep;
|
||||
Vector3 attackAmount = (attack_error/linfactor) * 1.3f;
|
||||
m_lLinObjectVel += attackAmount;
|
||||
}
|
||||
if (m_linearFrictionTimescale.X < 300.0f)
|
||||
{
|
||||
float fricfactor = m_linearFrictionTimescale.X / pTimestep;
|
||||
float fricX = m_lLinObjectVel.X / fricfactor;
|
||||
m_lLinObjectVel.X -= fricX;
|
||||
}
|
||||
if (m_linearFrictionTimescale.Y < 300.0f)
|
||||
{
|
||||
float fricfactor = m_linearFrictionTimescale.Y / pTimestep;
|
||||
float fricY = m_lLinObjectVel.Y / fricfactor;
|
||||
m_lLinObjectVel.Y -= fricY;
|
||||
}
|
||||
if (m_linearFrictionTimescale.Z < 300.0f)
|
||||
{
|
||||
float fricfactor = m_linearFrictionTimescale.Z / pTimestep;
|
||||
float fricZ = m_lLinObjectVel.Z / fricfactor;
|
||||
m_lLinObjectVel.Z -= fricZ;
|
||||
}
|
||||
}
|
||||
m_wLinObjectVel = m_lLinObjectVel * rotq;
|
||||
// Add Gravity and Buoyancy
|
||||
Vector3 grav = Vector3.Zero;
|
||||
if(m_VehicleBuoyancy < 1.0f)
|
||||
{
|
||||
// There is some gravity, make a gravity force vector
|
||||
// that is applied after object velocity.
|
||||
d.Mass objMass;
|
||||
d.BodyGetMass(Body, out objMass);
|
||||
// m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
|
||||
grav.Z = _pParentScene.gravityz * objMass.mass * (1f - m_VehicleBuoyancy); // Applied later as a force
|
||||
} // else its 1.0, no gravity.
|
||||
|
||||
// Check if hovering
|
||||
if( (m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
|
||||
{
|
||||
// We should hover, get the target height
|
||||
d.Vector3 pos = d.BodyGetPosition(Body);
|
||||
if((m_flags & VehicleFlag.HOVER_WATER_ONLY) == VehicleFlag.HOVER_WATER_ONLY)
|
||||
{
|
||||
m_VhoverTargetHeight = _pParentScene.GetWaterLevel() + m_VhoverHeight;
|
||||
}
|
||||
else if((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) == VehicleFlag.HOVER_TERRAIN_ONLY)
|
||||
{
|
||||
m_VhoverTargetHeight = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight;
|
||||
}
|
||||
else if((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) == VehicleFlag.HOVER_GLOBAL_HEIGHT)
|
||||
{
|
||||
m_VhoverTargetHeight = m_VhoverHeight;
|
||||
}
|
||||
|
||||
if((m_flags & VehicleFlag.HOVER_UP_ONLY) == VehicleFlag.HOVER_UP_ONLY)
|
||||
{
|
||||
// If body is aready heigher, use its height as target height
|
||||
if(pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z;
|
||||
}
|
||||
|
||||
// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped
|
||||
// m_VhoverTimescale = 0f; // time to acheive height
|
||||
// pTimestep is time since last frame,in secs
|
||||
float herr0 = pos.Z - m_VhoverTargetHeight;
|
||||
// Replace Vertical speed with correction figure if significant
|
||||
if(Math.Abs(herr0) > 0.01f )
|
||||
{
|
||||
d.Mass objMass;
|
||||
d.BodyGetMass(Body, out objMass);
|
||||
m_wLinObjectVel.Z = - ( (herr0 * pTimestep * 50.0f) / m_VhoverTimescale);
|
||||
//KF: m_VhoverEfficiency is not yet implemented
|
||||
}
|
||||
else
|
||||
{
|
||||
m_wLinObjectVel.Z = 0f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // not hovering, Gravity rules
|
||||
m_wLinObjectVel.Z = vel_now.Z;
|
||||
//if(frcount == 0) Console.WriteLine(" Z {0} a.Z {1}", m_wLinObjectVel.Z, acceleration.Z);
|
||||
}
|
||||
// Apply velocity
|
||||
d.BodySetLinearVel(Body, m_wLinObjectVel.X, m_wLinObjectVel.Y, m_wLinObjectVel.Z);
|
||||
// apply gravity force
|
||||
d.BodyAddForce(Body, grav.X, grav.Y, grav.Z);
|
||||
//if(frcount == 0) Console.WriteLine("Grav {0}", grav);
|
||||
} // end MoveLinear()
|
||||
|
||||
private void MoveAngular(float pTimestep)
|
||||
{
|
||||
/*
|
||||
private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor
|
||||
private int m_angularMotorApply = 0; // application frame counter
|
||||
private float m_angularMotorVelocity = 0; // current angular motor velocity (ramps up and down)
|
||||
private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate
|
||||
private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate
|
||||
private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate
|
||||
private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body
|
||||
*/
|
||||
//if(frcount == 0) Console.WriteLine("MoveAngular ");
|
||||
|
||||
// Get what the body is doing, this includes 'external' influences
|
||||
d.Vector3 angularVelocity = d.BodyGetAngularVel(Body);
|
||||
// Vector3 angularVelocity = Vector3.Zero;
|
||||
|
||||
if (m_angularMotorApply > 0)
|
||||
{
|
||||
// ramp up to new value
|
||||
// current velocity += error / ( time to get there / step interval )
|
||||
// requested speed - last motor speed
|
||||
m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / pTimestep);
|
||||
m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep);
|
||||
m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep);
|
||||
|
||||
m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected
|
||||
// velocity may still be acheived.
|
||||
}
|
||||
else
|
||||
{
|
||||
// no motor recently applied, keep the body velocity
|
||||
/* m_angularMotorVelocity.X = angularVelocity.X;
|
||||
m_angularMotorVelocity.Y = angularVelocity.Y;
|
||||
m_angularMotorVelocity.Z = angularVelocity.Z; */
|
||||
|
||||
// and decay the velocity
|
||||
m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep);
|
||||
} // end motor section
|
||||
|
||||
|
||||
// Vertical attractor section
|
||||
Vector3 vertattr = Vector3.Zero;
|
||||
|
||||
if(m_verticalAttractionTimescale < 300)
|
||||
{
|
||||
float VAservo = 0.0167f / (m_verticalAttractionTimescale * pTimestep);
|
||||
// get present body rotation
|
||||
d.Quaternion rot = d.BodyGetQuaternion(Body);
|
||||
Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W);
|
||||
// make a vector pointing up
|
||||
Vector3 verterr = Vector3.Zero;
|
||||
verterr.Z = 1.0f;
|
||||
// rotate it to Body Angle
|
||||
verterr = verterr * rotq;
|
||||
// verterr.X and .Y are the World error ammounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1.
|
||||
// As the body leans to its side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall and .Z will go
|
||||
// negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body.
|
||||
if (verterr.Z < 0.0f)
|
||||
{
|
||||
verterr.X = 2.0f - verterr.X;
|
||||
verterr.Y = 2.0f - verterr.Y;
|
||||
}
|
||||
// Error is 0 (no error) to +/- 2 (max error)
|
||||
// scale it by VAservo
|
||||
verterr = verterr * VAservo;
|
||||
//if(frcount == 0) Console.WriteLine("VAerr=" + verterr);
|
||||
|
||||
// As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so
|
||||
// Change Body angular velocity X based on Y, and Y based on X. Z is not changed.
|
||||
vertattr.X = verterr.Y;
|
||||
vertattr.Y = - verterr.X;
|
||||
vertattr.Z = 0f;
|
||||
|
||||
// scaling appears better usingsquare-law
|
||||
float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency);
|
||||
vertattr.X += bounce * angularVelocity.X;
|
||||
vertattr.Y += bounce * angularVelocity.Y;
|
||||
|
||||
} // else vertical attractor is off
|
||||
|
||||
// m_lastVertAttractor = vertattr;
|
||||
|
||||
// Bank section tba
|
||||
// Deflection section tba
|
||||
|
||||
// Sum velocities
|
||||
m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // tba: + bank + deflection
|
||||
|
||||
if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
|
||||
{
|
||||
if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero.
|
||||
}
|
||||
|
||||
// apply friction
|
||||
Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / pTimestep);
|
||||
m_lastAngularVelocity -= m_lastAngularVelocity * decayamount;
|
||||
|
||||
// Apply to the body
|
||||
d.BodySetAngularVel (Body, m_lastAngularVelocity.X, m_lastAngularVelocity.Y, m_lastAngularVelocity.Z);
|
||||
|
||||
} //end MoveAngular
|
||||
}
|
||||
}
|
||||
3277
OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
Normal file
3277
OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
Normal file
File diff suppressed because it is too large
Load Diff
375
OpenSim/Region/Physics/ChOdePlugin/ODERayCastRequestManager.cs
Normal file
375
OpenSim/Region/Physics/ChOdePlugin/ODERayCastRequestManager.cs
Normal file
@@ -0,0 +1,375 @@
|
||||
/*
|
||||
* 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 System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
using Ode.NET;
|
||||
using log4net;
|
||||
|
||||
namespace OpenSim.Region.Physics.OdePlugin
|
||||
{
|
||||
/// <summary>
|
||||
/// Processes raycast requests as ODE is in a state to be able to do them.
|
||||
/// This ensures that it's thread safe and there will be no conflicts.
|
||||
/// Requests get returned by a different thread then they were requested by.
|
||||
/// </summary>
|
||||
public class ODERayCastRequestManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Pending Raycast Requests
|
||||
/// </summary>
|
||||
protected List<ODERayCastRequest> m_PendingRequests = new List<ODERayCastRequest>();
|
||||
|
||||
/// <summary>
|
||||
/// Scene that created this object.
|
||||
/// </summary>
|
||||
private OdeScene m_scene;
|
||||
|
||||
/// <summary>
|
||||
/// ODE contact array to be filled by the collision testing
|
||||
/// </summary>
|
||||
d.ContactGeom[] contacts = new d.ContactGeom[5];
|
||||
|
||||
/// <summary>
|
||||
/// ODE near callback delegate
|
||||
/// </summary>
|
||||
private d.NearCallback nearCallback;
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private List<ContactResult> m_contactResults = new List<ContactResult>();
|
||||
|
||||
|
||||
public ODERayCastRequestManager(OdeScene pScene)
|
||||
{
|
||||
m_scene = pScene;
|
||||
nearCallback = near;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queues a raycast
|
||||
/// </summary>
|
||||
/// <param name="position">Origin of Ray</param>
|
||||
/// <param name="direction">Ray normal</param>
|
||||
/// <param name="length">Ray length</param>
|
||||
/// <param name="retMethod">Return method to send the results</param>
|
||||
public void QueueRequest(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
|
||||
{
|
||||
lock (m_PendingRequests)
|
||||
{
|
||||
ODERayCastRequest req = new ODERayCastRequest();
|
||||
req.callbackMethod = retMethod;
|
||||
req.length = length;
|
||||
req.Normal = direction;
|
||||
req.Origin = position;
|
||||
|
||||
m_PendingRequests.Add(req);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process all queued raycast requests
|
||||
/// </summary>
|
||||
/// <returns>Time in MS the raycasts took to process.</returns>
|
||||
public int ProcessQueuedRequests()
|
||||
{
|
||||
int time = System.Environment.TickCount;
|
||||
lock (m_PendingRequests)
|
||||
{
|
||||
if (m_PendingRequests.Count > 0)
|
||||
{
|
||||
ODERayCastRequest[] reqs = m_PendingRequests.ToArray();
|
||||
for (int i = 0; i < reqs.Length; i++)
|
||||
{
|
||||
if (reqs[i].callbackMethod != null) // quick optimization here, don't raycast
|
||||
RayCast(reqs[i]); // if there isn't anyone to send results
|
||||
}
|
||||
/*
|
||||
foreach (ODERayCastRequest req in m_PendingRequests)
|
||||
{
|
||||
if (req.callbackMethod != null) // quick optimization here, don't raycast
|
||||
RayCast(req); // if there isn't anyone to send results to
|
||||
|
||||
}
|
||||
*/
|
||||
m_PendingRequests.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
lock (m_contactResults)
|
||||
m_contactResults.Clear();
|
||||
|
||||
return System.Environment.TickCount - time;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method that actually initiates the raycast
|
||||
/// </summary>
|
||||
/// <param name="req"></param>
|
||||
private void RayCast(ODERayCastRequest req)
|
||||
{
|
||||
// Create the ray
|
||||
IntPtr ray = d.CreateRay(m_scene.space, req.length);
|
||||
d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
|
||||
|
||||
// Collide test
|
||||
d.SpaceCollide2(m_scene.space, ray, IntPtr.Zero, nearCallback);
|
||||
|
||||
// Remove Ray
|
||||
d.GeomDestroy(ray);
|
||||
|
||||
|
||||
// Define default results
|
||||
bool hitYN = false;
|
||||
uint hitConsumerID = 0;
|
||||
float distance = 999999999999f;
|
||||
Vector3 closestcontact = new Vector3(99999f, 99999f, 99999f);
|
||||
Vector3 snormal = Vector3.Zero;
|
||||
|
||||
// Find closest contact and object.
|
||||
lock (m_contactResults)
|
||||
{
|
||||
foreach (ContactResult cResult in m_contactResults)
|
||||
{
|
||||
if (Vector3.Distance(req.Origin, cResult.Pos) < Vector3.Distance(req.Origin, closestcontact))
|
||||
{
|
||||
closestcontact = cResult.Pos;
|
||||
hitConsumerID = cResult.ConsumerID;
|
||||
distance = cResult.Depth;
|
||||
hitYN = true;
|
||||
snormal = cResult.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
m_contactResults.Clear();
|
||||
}
|
||||
|
||||
// Return results
|
||||
if (req.callbackMethod != null)
|
||||
req.callbackMethod(hitYN, closestcontact, hitConsumerID, distance, snormal);
|
||||
}
|
||||
|
||||
// This is the standard Near. Uses space AABBs to speed up detection.
|
||||
private void near(IntPtr space, IntPtr g1, IntPtr g2)
|
||||
{
|
||||
|
||||
//Don't test against heightfield Geom, or you'll be sorry!
|
||||
|
||||
/*
|
||||
terminate called after throwing an instance of 'std::bad_alloc'
|
||||
what(): std::bad_alloc
|
||||
Stacktrace:
|
||||
|
||||
at (wrapper managed-to-native) Ode.NET.d.Collide (intptr,intptr,int,Ode.NET.d/ContactGeom[],int) <0x00004>
|
||||
at (wrapper managed-to-native) Ode.NET.d.Collide (intptr,intptr,int,Ode.NET.d/ContactGeom[],int) <0xffffffff>
|
||||
at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.near (intptr,intptr,intptr) <0x00280>
|
||||
at (wrapper native-to-managed) OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.near (intptr,intptr,intptr) <0xfff
|
||||
fffff>
|
||||
at (wrapper managed-to-native) Ode.NET.d.SpaceCollide2 (intptr,intptr,intptr,Ode.NET.d/NearCallback) <0x00004>
|
||||
at (wrapper managed-to-native) Ode.NET.d.SpaceCollide2 (intptr,intptr,intptr,Ode.NET.d/NearCallback) <0xffffffff>
|
||||
at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.RayCast (OpenSim.Region.Physics.OdePlugin.ODERayCastRequest) <
|
||||
0x00114>
|
||||
at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.ProcessQueuedRequests () <0x000eb>
|
||||
at OpenSim.Region.Physics.OdePlugin.OdeScene.Simulate (single) <0x017e6>
|
||||
at OpenSim.Region.Framework.Scenes.SceneGraph.UpdatePhysics (double) <0x00042>
|
||||
at OpenSim.Region.Framework.Scenes.Scene.Update () <0x0039e>
|
||||
at OpenSim.Region.Framework.Scenes.Scene.Heartbeat (object) <0x00019>
|
||||
at (wrapper runtime-invoke) object.runtime_invoke_void__this___object (object,intptr,intptr,intptr) <0xffffffff>
|
||||
|
||||
Native stacktrace:
|
||||
|
||||
mono [0x80d2a42]
|
||||
[0xb7f5840c]
|
||||
/lib/i686/cmov/libc.so.6(abort+0x188) [0xb7d1a018]
|
||||
/usr/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x158) [0xb45fc988]
|
||||
/usr/lib/libstdc++.so.6 [0xb45fa865]
|
||||
/usr/lib/libstdc++.so.6 [0xb45fa8a2]
|
||||
/usr/lib/libstdc++.so.6 [0xb45fa9da]
|
||||
/usr/lib/libstdc++.so.6(_Znwj+0x83) [0xb45fb033]
|
||||
/usr/lib/libstdc++.so.6(_Znaj+0x1d) [0xb45fb11d]
|
||||
libode.so(_ZN13dxHeightfield23dCollideHeightfieldZoneEiiiiP6dxGeomiiP12dContactGeomi+0xd04) [0xb46678e4]
|
||||
libode.so(_Z19dCollideHeightfieldP6dxGeomS0_iP12dContactGeomi+0x54b) [0xb466832b]
|
||||
libode.so(dCollide+0x102) [0xb46571b2]
|
||||
[0x95cfdec9]
|
||||
[0x8ea07fe1]
|
||||
[0xab260146]
|
||||
libode.so [0xb465a5c4]
|
||||
libode.so(_ZN11dxHashSpace8collide2EPvP6dxGeomPFvS0_S2_S2_E+0x75) [0xb465bcf5]
|
||||
libode.so(dSpaceCollide2+0x177) [0xb465ac67]
|
||||
[0x95cf978e]
|
||||
[0x8ea07945]
|
||||
[0x95cf2bbc]
|
||||
[0xab2787e7]
|
||||
[0xab419fb3]
|
||||
[0xab416657]
|
||||
[0xab415bda]
|
||||
[0xb609b08e]
|
||||
mono(mono_runtime_delegate_invoke+0x34) [0x8192534]
|
||||
mono [0x81a2f0f]
|
||||
mono [0x81d28b6]
|
||||
mono [0x81ea2c6]
|
||||
/lib/i686/cmov/libpthread.so.0 [0xb7e744c0]
|
||||
/lib/i686/cmov/libc.so.6(clone+0x5e) [0xb7dcd6de]
|
||||
*/
|
||||
|
||||
// Exclude heightfield geom
|
||||
|
||||
if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
|
||||
return;
|
||||
if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass || d.GeomGetClass(g2) == d.GeomClassID.HeightfieldClass)
|
||||
return;
|
||||
|
||||
// Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms.
|
||||
if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2))
|
||||
{
|
||||
if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
|
||||
return;
|
||||
|
||||
// Separating static prim geometry spaces.
|
||||
// We'll be calling near recursivly if one
|
||||
// of them is a space to find all of the
|
||||
// contact points in the space
|
||||
try
|
||||
{
|
||||
d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback);
|
||||
}
|
||||
catch (AccessViolationException)
|
||||
{
|
||||
m_log.Warn("[PHYSICS]: Unable to collide test a space");
|
||||
return;
|
||||
}
|
||||
//Colliding a space or a geom with a space or a geom. so drill down
|
||||
|
||||
//Collide all geoms in each space..
|
||||
//if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback);
|
||||
//if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback);
|
||||
return;
|
||||
}
|
||||
|
||||
if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
|
||||
return;
|
||||
|
||||
int count = 0;
|
||||
try
|
||||
{
|
||||
|
||||
if (g1 == g2)
|
||||
return; // Can't collide with yourself
|
||||
|
||||
lock (contacts)
|
||||
{
|
||||
count = d.Collide(g1, g2, contacts.GetLength(0), contacts, d.ContactGeom.SizeOf);
|
||||
}
|
||||
}
|
||||
catch (SEHException)
|
||||
{
|
||||
m_log.Error("[PHYSICS]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
PhysicsActor p1 = null;
|
||||
PhysicsActor p2 = null;
|
||||
|
||||
if (g1 != IntPtr.Zero)
|
||||
m_scene.actor_name_map.TryGetValue(g1, out p1);
|
||||
|
||||
if (g2 != IntPtr.Zero)
|
||||
m_scene.actor_name_map.TryGetValue(g1, out p2);
|
||||
|
||||
// Loop over contacts, build results.
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (p1 != null) {
|
||||
if (p1 is OdePrim)
|
||||
{
|
||||
ContactResult collisionresult = new ContactResult();
|
||||
|
||||
collisionresult.ConsumerID = ((OdePrim)p1).m_localID;
|
||||
collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z);
|
||||
collisionresult.Depth = contacts[i].depth;
|
||||
collisionresult.Normal = new Vector3(contacts[i].normal.X, contacts[i].normal.Y,
|
||||
contacts[i].normal.Z);
|
||||
lock (m_contactResults)
|
||||
m_contactResults.Add(collisionresult);
|
||||
}
|
||||
}
|
||||
|
||||
if (p2 != null)
|
||||
{
|
||||
if (p2 is OdePrim)
|
||||
{
|
||||
ContactResult collisionresult = new ContactResult();
|
||||
|
||||
collisionresult.ConsumerID = ((OdePrim)p2).m_localID;
|
||||
collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z);
|
||||
collisionresult.Depth = contacts[i].depth;
|
||||
collisionresult.Normal = new Vector3(contacts[i].normal.X, contacts[i].normal.Y,
|
||||
contacts[i].normal.Z);
|
||||
|
||||
lock (m_contactResults)
|
||||
m_contactResults.Add(collisionresult);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dereference the creator scene so that it can be garbage collected if needed.
|
||||
/// </summary>
|
||||
internal void Dispose()
|
||||
{
|
||||
m_scene = null;
|
||||
}
|
||||
}
|
||||
|
||||
public struct ODERayCastRequest
|
||||
{
|
||||
public Vector3 Origin;
|
||||
public Vector3 Normal;
|
||||
public float length;
|
||||
public RaycastCallback callbackMethod;
|
||||
}
|
||||
|
||||
public struct ContactResult
|
||||
{
|
||||
public Vector3 Pos;
|
||||
public float Depth;
|
||||
public uint ConsumerID;
|
||||
public Vector3 Normal;
|
||||
}
|
||||
}
|
||||
48
OpenSim/Region/Physics/ChOdePlugin/OdePhysicsJoint.cs
Normal file
48
OpenSim/Region/Physics/ChOdePlugin/OdePhysicsJoint.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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 OpenMetaverse;
|
||||
using Ode.NET;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
using OpenSim.Region.Physics.OdePlugin;
|
||||
|
||||
namespace OpenSim.Region.Physics.OdePlugin
|
||||
{
|
||||
class OdePhysicsJoint : PhysicsJoint
|
||||
{
|
||||
public override bool IsInPhysicsEngine
|
||||
{
|
||||
get
|
||||
{
|
||||
return (jointID != IntPtr.Zero);
|
||||
}
|
||||
}
|
||||
public IntPtr jointID;
|
||||
}
|
||||
}
|
||||
3874
OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs
Normal file
3874
OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs
Normal file
File diff suppressed because it is too large
Load Diff
122
OpenSim/Region/Physics/ChOdePlugin/Tests/ODETestClass.cs
Normal file
122
OpenSim/Region/Physics/ChOdePlugin/Tests/ODETestClass.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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 Nini.Config;
|
||||
using NUnit.Framework;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
using log4net;
|
||||
using System.Reflection;
|
||||
|
||||
namespace OpenSim.Region.Physics.OdePlugin
|
||||
{
|
||||
[TestFixture]
|
||||
public class ODETestClass
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private OdePlugin cbt;
|
||||
private PhysicsScene ps;
|
||||
private IMeshingPlugin imp;
|
||||
|
||||
[SetUp]
|
||||
public void Initialize()
|
||||
{
|
||||
// Loading ODEPlugin
|
||||
cbt = new OdePlugin();
|
||||
// Loading Zero Mesher
|
||||
imp = new ZeroMesherPlugin();
|
||||
// Getting Physics Scene
|
||||
ps = cbt.GetScene("test");
|
||||
// Initializing Physics Scene.
|
||||
ps.Initialise(imp.GetMesher(),null);
|
||||
float[] _heightmap = new float[(int)Constants.RegionSize * (int)Constants.RegionSize];
|
||||
for (int i = 0; i < ((int)Constants.RegionSize * (int)Constants.RegionSize); i++)
|
||||
{
|
||||
_heightmap[i] = 21f;
|
||||
}
|
||||
ps.SetTerrain(_heightmap);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void Terminate()
|
||||
{
|
||||
ps.DeleteTerrain();
|
||||
ps.Dispose();
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreateAndDropPhysicalCube()
|
||||
{
|
||||
PrimitiveBaseShape newcube = PrimitiveBaseShape.CreateBox();
|
||||
Vector3 position = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f), 128f);
|
||||
Vector3 size = new Vector3(0.5f, 0.5f, 0.5f);
|
||||
Quaternion rot = Quaternion.Identity;
|
||||
PhysicsActor prim = ps.AddPrimShape("CoolShape", newcube, position, size, rot, true);
|
||||
OdePrim oprim = (OdePrim)prim;
|
||||
OdeScene pscene = (OdeScene) ps;
|
||||
|
||||
Assert.That(oprim.m_taintadd);
|
||||
|
||||
prim.LocalID = 5;
|
||||
|
||||
for (int i = 0; i < 58; i++)
|
||||
{
|
||||
ps.Simulate(0.133f);
|
||||
|
||||
Assert.That(oprim.prim_geom != (IntPtr)0);
|
||||
|
||||
Assert.That(oprim.m_targetSpace != (IntPtr)0);
|
||||
|
||||
//Assert.That(oprim.m_targetSpace == pscene.space);
|
||||
m_log.Info("TargetSpace: " + oprim.m_targetSpace + " - SceneMainSpace: " + pscene.space);
|
||||
|
||||
Assert.That(!oprim.m_taintadd);
|
||||
m_log.Info("Prim Position (" + oprim.m_localID + "): " + prim.Position.ToString());
|
||||
|
||||
// Make sure we're above the ground
|
||||
//Assert.That(prim.Position.Z > 20f);
|
||||
//m_log.Info("PrimCollisionScore (" + oprim.m_localID + "): " + oprim.m_collisionscore);
|
||||
|
||||
// Make sure we've got a Body
|
||||
Assert.That(oprim.Body != (IntPtr)0);
|
||||
//m_log.Info(
|
||||
}
|
||||
|
||||
// Make sure we're not somewhere above the ground
|
||||
Assert.That(prim.Position.Z < 21.5f);
|
||||
|
||||
ps.RemovePrim(prim);
|
||||
Assert.That(oprim.m_taintremove);
|
||||
ps.Simulate(0.133f);
|
||||
Assert.That(oprim.Body == (IntPtr)0);
|
||||
}
|
||||
}
|
||||
}
|
||||
98
OpenSim/Region/Physics/ChOdePlugin/drawstuff.cs
Normal file
98
OpenSim/Region/Physics/ChOdePlugin/drawstuff.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright ODE
|
||||
* Ode.NET - .NET bindings for ODE
|
||||
* Jason Perkins (starkos@industriousone.com)
|
||||
* Licensed under the New BSD
|
||||
* Part of the OpenDynamicsEngine
|
||||
Open Dynamics Engine
|
||||
Copyright (c) 2001-2007, Russell L. Smith.
|
||||
All rights reserved.
|
||||
|
||||
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 names of ODE's copyright owner 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 COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"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 COPYRIGHT
|
||||
OWNER OR 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.Runtime.InteropServices;
|
||||
using Ode.NET;
|
||||
|
||||
namespace Drawstuff.NET
|
||||
{
|
||||
#if dDOUBLE
|
||||
using dReal = System.Double;
|
||||
#else
|
||||
using dReal = System.Single;
|
||||
#endif
|
||||
|
||||
public static class ds
|
||||
{
|
||||
public const int VERSION = 2;
|
||||
|
||||
public enum Texture
|
||||
{
|
||||
None,
|
||||
Wood
|
||||
}
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void CallbackFunction(int arg);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Functions
|
||||
{
|
||||
public int version;
|
||||
public CallbackFunction start;
|
||||
public CallbackFunction step;
|
||||
public CallbackFunction command;
|
||||
public CallbackFunction stop;
|
||||
public string path_to_textures;
|
||||
}
|
||||
|
||||
[DllImport("drawstuff", EntryPoint = "dsDrawBox")]
|
||||
public static extern void DrawBox(ref d.Vector3 pos, ref d.Matrix3 R, ref d.Vector3 sides);
|
||||
|
||||
[DllImport("drawstuff", EntryPoint = "dsDrawCapsule")]
|
||||
public static extern void DrawCapsule(ref d.Vector3 pos, ref d.Matrix3 R, dReal length, dReal radius);
|
||||
|
||||
[DllImport("drawstuff", EntryPoint = "dsDrawConvex")]
|
||||
public static extern void DrawConvex(ref d.Vector3 pos, ref d.Matrix3 R, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons);
|
||||
|
||||
[DllImport("drawstuff", EntryPoint = "dsSetColor")]
|
||||
public static extern void SetColor(float red, float green, float blue);
|
||||
|
||||
[DllImport("drawstuff", EntryPoint = "dsSetTexture")]
|
||||
public static extern void SetTexture(Texture texture);
|
||||
|
||||
[DllImport("drawstuff", EntryPoint = "dsSetViewpoint")]
|
||||
public static extern void SetViewpoint(ref d.Vector3 xyz, ref d.Vector3 hpr);
|
||||
|
||||
[DllImport("drawstuff", EntryPoint = "dsSimulationLoop")]
|
||||
public static extern void SimulationLoop(int argc, string[] argv, int window_width, int window_height, ref Functions fn);
|
||||
}
|
||||
}
|
||||
@@ -1205,7 +1205,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
|
||||
public override float APIDDamping{ set { return; } }
|
||||
|
||||
|
||||
public override void SubscribeEvents(int ms)
|
||||
{
|
||||
m_requestedUpdateFrequency = ms;
|
||||
|
||||
@@ -2824,7 +2824,7 @@ Console.WriteLine(" JointCreateFixed");
|
||||
}
|
||||
public override bool PIDActive { set { m_usePID = value; } }
|
||||
public override float PIDTau { set { m_PIDTau = value; } }
|
||||
|
||||
|
||||
public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } }
|
||||
public override bool PIDHoverActive { set { m_useHoverPID = value; } }
|
||||
public override PIDHoverType PIDHoverType { set { m_PIDHoverType = value; } }
|
||||
|
||||
@@ -299,7 +299,7 @@ namespace OpenSim.Region.Physics.POSPlugin
|
||||
{
|
||||
set { return; }
|
||||
}
|
||||
|
||||
|
||||
public override Quaternion APIDTarget
|
||||
{
|
||||
set { return; }
|
||||
|
||||
@@ -88,89 +88,7 @@ namespace OpenSim.Region.RegionCombinerModule
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
if (enabledYN)
|
||||
{
|
||||
RegionLoadedDoWork(scene);
|
||||
|
||||
scene.EventManager.OnNewPresence += NewPresence;
|
||||
}
|
||||
}
|
||||
|
||||
private void NewPresence(ScenePresence presence)
|
||||
{
|
||||
if (presence.IsChildAgent)
|
||||
{
|
||||
byte[] throttleData;
|
||||
|
||||
try
|
||||
{
|
||||
throttleData = presence.ControllingClient.GetThrottlesPacked(1);
|
||||
}
|
||||
catch (NotImplementedException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (throttleData == null)
|
||||
return;
|
||||
|
||||
if (throttleData.Length == 0)
|
||||
return;
|
||||
|
||||
if (throttleData.Length != 28)
|
||||
return;
|
||||
|
||||
byte[] adjData;
|
||||
int pos = 0;
|
||||
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
byte[] newData = new byte[7 * 4];
|
||||
Buffer.BlockCopy(throttleData, 0, newData, 0, 7 * 4);
|
||||
|
||||
for (int i = 0; i < 7; i++)
|
||||
Array.Reverse(newData, i * 4, 4);
|
||||
|
||||
adjData = newData;
|
||||
}
|
||||
else
|
||||
{
|
||||
adjData = throttleData;
|
||||
}
|
||||
|
||||
// 0.125f converts from bits to bytes
|
||||
int resend = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
|
||||
int land = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
|
||||
int wind = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
|
||||
int cloud = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
|
||||
int task = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
|
||||
int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
|
||||
int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
|
||||
// State is a subcategory of task that we allocate a percentage to
|
||||
|
||||
|
||||
//int total = resend + land + wind + cloud + task + texture + asset;
|
||||
|
||||
byte[] data = new byte[7 * 4];
|
||||
int ii = 0;
|
||||
|
||||
Buffer.BlockCopy(Utils.FloatToBytes(resend), 0, data, ii, 4); ii += 4;
|
||||
Buffer.BlockCopy(Utils.FloatToBytes(land * 50), 0, data, ii, 4); ii += 4;
|
||||
Buffer.BlockCopy(Utils.FloatToBytes(wind), 0, data, ii, 4); ii += 4;
|
||||
Buffer.BlockCopy(Utils.FloatToBytes(cloud), 0, data, ii, 4); ii += 4;
|
||||
Buffer.BlockCopy(Utils.FloatToBytes(task), 0, data, ii, 4); ii += 4;
|
||||
Buffer.BlockCopy(Utils.FloatToBytes(texture), 0, data, ii, 4); ii += 4;
|
||||
Buffer.BlockCopy(Utils.FloatToBytes(asset), 0, data, ii, 4);
|
||||
|
||||
try
|
||||
{
|
||||
presence.ControllingClient.SetChildAgentThrottle(data);
|
||||
}
|
||||
catch (NotImplementedException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void RegionLoadedDoWork(Scene scene)
|
||||
|
||||
473
OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
Normal file
473
OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
Normal file
@@ -0,0 +1,473 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Remoting.Lifetime;
|
||||
using OpenMetaverse;
|
||||
using Nini.Config;
|
||||
using OpenSim;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.CoreModules.World.Meta7Windlight;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.ScriptEngine.Shared;
|
||||
using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
|
||||
using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
|
||||
using OpenSim.Region.ScriptEngine.Interfaces;
|
||||
using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
|
||||
|
||||
using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
|
||||
using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
|
||||
using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
|
||||
using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
|
||||
using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
|
||||
using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
|
||||
using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
|
||||
|
||||
namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
{
|
||||
[Serializable]
|
||||
public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
|
||||
{
|
||||
internal IScriptEngine m_ScriptEngine;
|
||||
internal SceneObjectPart m_host;
|
||||
internal uint m_localID;
|
||||
internal UUID m_itemID;
|
||||
internal bool m_CMFunctionsEnabled = false;
|
||||
internal IScriptModuleComms m_comms = null;
|
||||
|
||||
public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
|
||||
{
|
||||
m_ScriptEngine = ScriptEngine;
|
||||
m_host = host;
|
||||
m_localID = localID;
|
||||
m_itemID = itemID;
|
||||
|
||||
if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
|
||||
m_CMFunctionsEnabled = true;
|
||||
|
||||
m_comms = m_ScriptEngine.World.RequestModuleInterface<IScriptModuleComms>();
|
||||
if (m_comms == null)
|
||||
m_CMFunctionsEnabled = false;
|
||||
}
|
||||
|
||||
public override Object InitializeLifetimeService()
|
||||
{
|
||||
ILease lease = (ILease)base.InitializeLifetimeService();
|
||||
|
||||
if (lease.CurrentState == LeaseState.Initial)
|
||||
{
|
||||
lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
|
||||
// lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
|
||||
// lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
|
||||
}
|
||||
return lease;
|
||||
}
|
||||
|
||||
public Scene World
|
||||
{
|
||||
get { return m_ScriptEngine.World; }
|
||||
}
|
||||
|
||||
//
|
||||
//Dumps an error message on the debug console.
|
||||
//
|
||||
|
||||
internal void CMShoutError(string message)
|
||||
{
|
||||
if (message.Length > 1023)
|
||||
message = message.Substring(0, 1023);
|
||||
|
||||
World.SimChat(Utils.StringToBytes(message),
|
||||
ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, true);
|
||||
|
||||
IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
|
||||
wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the current Windlight scene
|
||||
/// </summary>
|
||||
/// <returns>List of windlight parameters</returns>
|
||||
public LSL_List cmGetWindlightScene(LSL_List rules)
|
||||
{
|
||||
if (!m_CMFunctionsEnabled)
|
||||
{
|
||||
CMShoutError("Careminster functions are not enabled.");
|
||||
return new LSL_List();
|
||||
}
|
||||
m_host.AddScriptLPS(1);
|
||||
RegionMeta7WindlightData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings;
|
||||
|
||||
LSL_List values = new LSL_List();
|
||||
int idx = 0;
|
||||
while (idx < rules.Length)
|
||||
{
|
||||
uint rule = (uint)rules.GetLSLIntegerItem(idx);
|
||||
LSL_List toadd = new LSL_List();
|
||||
|
||||
switch (rule)
|
||||
{
|
||||
case (int)ScriptBaseClass.WL_AMBIENT:
|
||||
toadd.Add(new LSL_Rotation(wl.ambient.X, wl.ambient.Y, wl.ambient.Z, wl.ambient.W));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION:
|
||||
toadd.Add(new LSL_Vector(wl.bigWaveDirection.X, wl.bigWaveDirection.Y, 0.0f));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_BLUE_DENSITY:
|
||||
toadd.Add(new LSL_Rotation(wl.blueDensity.X, wl.blueDensity.Y, wl.blueDensity.Z, wl.blueDensity.W));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER:
|
||||
toadd.Add(new LSL_Float(wl.blurMultiplier));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_CLOUD_COLOR:
|
||||
toadd.Add(new LSL_Rotation(wl.cloudColor.X, wl.cloudColor.Y, wl.cloudColor.Z, wl.cloudColor.W));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_CLOUD_COVERAGE:
|
||||
toadd.Add(new LSL_Float(wl.cloudCoverage));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY:
|
||||
toadd.Add(new LSL_Vector(wl.cloudDetailXYDensity.X, wl.cloudDetailXYDensity.Y, wl.cloudDetailXYDensity.Z));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_CLOUD_SCALE:
|
||||
toadd.Add(new LSL_Float(wl.cloudScale));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X:
|
||||
toadd.Add(new LSL_Float(wl.cloudScrollX));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK:
|
||||
toadd.Add(new LSL_Integer(wl.cloudScrollXLock ? 1 : 0));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y:
|
||||
toadd.Add(new LSL_Float(wl.cloudScrollY));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK:
|
||||
toadd.Add(new LSL_Integer(wl.cloudScrollYLock ? 1 : 0));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY:
|
||||
toadd.Add(new LSL_Vector(wl.cloudXYDensity.X, wl.cloudXYDensity.Y, wl.cloudXYDensity.Z));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER:
|
||||
toadd.Add(new LSL_Float(wl.densityMultiplier));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER:
|
||||
toadd.Add(new LSL_Float(wl.distanceMultiplier));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS:
|
||||
toadd.Add(new LSL_Integer(wl.drawClassicClouds ? 1 : 0));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_EAST_ANGLE:
|
||||
toadd.Add(new LSL_Float(wl.eastAngle));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_FRESNEL_OFFSET:
|
||||
toadd.Add(new LSL_Float(wl.fresnelOffset));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_FRESNEL_SCALE:
|
||||
toadd.Add(new LSL_Float(wl.fresnelScale));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_HAZE_DENSITY:
|
||||
toadd.Add(new LSL_Float(wl.hazeDensity));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_HAZE_HORIZON:
|
||||
toadd.Add(new LSL_Float(wl.hazeHorizon));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_HORIZON:
|
||||
toadd.Add(new LSL_Rotation(wl.horizon.X, wl.horizon.Y, wl.horizon.Z, wl.horizon.W));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION:
|
||||
toadd.Add(new LSL_Vector(wl.littleWaveDirection.X, wl.littleWaveDirection.Y, 0.0f));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_MAX_ALTITUDE:
|
||||
toadd.Add(new LSL_Integer(wl.maxAltitude));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE:
|
||||
toadd.Add(new LSL_Key(wl.normalMapTexture.ToString()));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE:
|
||||
toadd.Add(new LSL_Vector(wl.reflectionWaveletScale.X, wl.reflectionWaveletScale.Y, wl.reflectionWaveletScale.Z));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE:
|
||||
toadd.Add(new LSL_Float(wl.refractScaleAbove));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW:
|
||||
toadd.Add(new LSL_Float(wl.refractScaleBelow));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_SCENE_GAMMA:
|
||||
toadd.Add(new LSL_Float(wl.sceneGamma));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS:
|
||||
toadd.Add(new LSL_Float(wl.starBrightness));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS:
|
||||
toadd.Add(new LSL_Float(wl.sunGlowFocus));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE:
|
||||
toadd.Add(new LSL_Float(wl.sunGlowSize));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_SUN_MOON_COLOR:
|
||||
toadd.Add(new LSL_Rotation(wl.sunMoonColor.X, wl.sunMoonColor.Y, wl.sunMoonColor.Z, wl.sunMoonColor.W));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER:
|
||||
toadd.Add(new LSL_Float(wl.underwaterFogModifier));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_WATER_COLOR:
|
||||
toadd.Add(new LSL_Vector(wl.waterColor.X, wl.waterColor.Y, wl.waterColor.Z));
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT:
|
||||
toadd.Add(new LSL_Float(wl.waterFogDensityExponent));
|
||||
break;
|
||||
}
|
||||
|
||||
if (toadd.Length > 0)
|
||||
{
|
||||
values.Add(rule);
|
||||
values.Add(toadd.Data[0]);
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
|
||||
|
||||
return values;
|
||||
|
||||
}
|
||||
|
||||
private RegionMeta7WindlightData getWindlightProfileFromRules(LSL_List rules)
|
||||
{
|
||||
RegionMeta7WindlightData wl = (RegionMeta7WindlightData)m_host.ParentGroup.Scene.RegionInfo.WindlightSettings.Clone();
|
||||
|
||||
LSL_List values = new LSL_List();
|
||||
int idx = 0;
|
||||
while (idx < rules.Length)
|
||||
{
|
||||
uint rule = (uint)rules.GetLSLIntegerItem(idx);
|
||||
LSL_Types.Quaternion iQ;
|
||||
LSL_Types.Vector3 iV;
|
||||
switch (rule)
|
||||
{
|
||||
case (int)ScriptBaseClass.WL_AMBIENT:
|
||||
idx++;
|
||||
iQ = rules.GetQuaternionItem(idx);
|
||||
wl.ambient = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION:
|
||||
idx++;
|
||||
iV = rules.GetVector3Item(idx);
|
||||
wl.bigWaveDirection = new Vector2((float)iV.x, (float)iV.y);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_BLUE_DENSITY:
|
||||
idx++;
|
||||
iQ = rules.GetQuaternionItem(idx);
|
||||
wl.blueDensity = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER:
|
||||
idx++;
|
||||
wl.blurMultiplier = (float)rules.GetLSLFloatItem(idx);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_CLOUD_COLOR:
|
||||
idx++;
|
||||
iQ = rules.GetQuaternionItem(idx);
|
||||
wl.cloudColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_CLOUD_COVERAGE:
|
||||
idx++;
|
||||
wl.cloudCoverage = (float)rules.GetLSLFloatItem(idx);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY:
|
||||
idx++;
|
||||
iV = rules.GetVector3Item(idx);
|
||||
wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_CLOUD_SCALE:
|
||||
idx++;
|
||||
wl.cloudScale = (float)rules.GetLSLFloatItem(idx);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X:
|
||||
idx++;
|
||||
wl.cloudScrollX = (float)rules.GetLSLFloatItem(idx);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK:
|
||||
idx++;
|
||||
wl.cloudScrollXLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false;
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y:
|
||||
idx++;
|
||||
wl.cloudScrollY = (float)rules.GetLSLFloatItem(idx);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK:
|
||||
idx++;
|
||||
wl.cloudScrollYLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false;
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY:
|
||||
idx++;
|
||||
iV = rules.GetVector3Item(idx);
|
||||
wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER:
|
||||
idx++;
|
||||
wl.densityMultiplier = (float)rules.GetLSLFloatItem(idx);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER:
|
||||
idx++;
|
||||
wl.distanceMultiplier = (float)rules.GetLSLFloatItem(idx);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS:
|
||||
idx++;
|
||||
wl.drawClassicClouds = rules.GetLSLIntegerItem(idx).value == 1 ? true : false;
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_EAST_ANGLE:
|
||||
idx++;
|
||||
wl.eastAngle = (float)rules.GetLSLFloatItem(idx);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_FRESNEL_OFFSET:
|
||||
idx++;
|
||||
wl.fresnelOffset = (float)rules.GetLSLFloatItem(idx);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_FRESNEL_SCALE:
|
||||
idx++;
|
||||
wl.fresnelScale = (float)rules.GetLSLFloatItem(idx);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_HAZE_DENSITY:
|
||||
idx++;
|
||||
wl.hazeDensity = (float)rules.GetLSLFloatItem(idx);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_HAZE_HORIZON:
|
||||
idx++;
|
||||
wl.hazeHorizon = (float)rules.GetLSLFloatItem(idx);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_HORIZON:
|
||||
idx++;
|
||||
iQ = rules.GetQuaternionItem(idx);
|
||||
wl.horizon = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION:
|
||||
idx++;
|
||||
iV = rules.GetVector3Item(idx);
|
||||
wl.littleWaveDirection = new Vector2((float)iV.x, (float)iV.y);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_MAX_ALTITUDE:
|
||||
idx++;
|
||||
wl.maxAltitude = (ushort)rules.GetLSLIntegerItem(idx).value;
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE:
|
||||
idx++;
|
||||
wl.normalMapTexture = new UUID(rules.GetLSLStringItem(idx).m_string);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE:
|
||||
idx++;
|
||||
iV = rules.GetVector3Item(idx);
|
||||
wl.reflectionWaveletScale = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE:
|
||||
idx++;
|
||||
wl.refractScaleAbove = (float)rules.GetLSLFloatItem(idx);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW:
|
||||
idx++;
|
||||
wl.refractScaleBelow = (float)rules.GetLSLFloatItem(idx);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_SCENE_GAMMA:
|
||||
idx++;
|
||||
wl.sceneGamma = (float)rules.GetLSLFloatItem(idx);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS:
|
||||
idx++;
|
||||
wl.starBrightness = (float)rules.GetLSLFloatItem(idx);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS:
|
||||
idx++;
|
||||
wl.sunGlowFocus = (float)rules.GetLSLFloatItem(idx);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE:
|
||||
idx++;
|
||||
wl.sunGlowSize = (float)rules.GetLSLFloatItem(idx);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_SUN_MOON_COLOR:
|
||||
idx++;
|
||||
iQ = rules.GetQuaternionItem(idx);
|
||||
wl.sunMoonColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER:
|
||||
idx++;
|
||||
wl.underwaterFogModifier = (float)rules.GetLSLFloatItem(idx);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_WATER_COLOR:
|
||||
idx++;
|
||||
iV = rules.GetVector3Item(idx);
|
||||
wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT:
|
||||
idx++;
|
||||
wl.waterFogDensityExponent = (float)rules.GetLSLFloatItem(idx);
|
||||
break;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
return wl;
|
||||
}
|
||||
/// <summary>
|
||||
/// Set the current Windlight scene
|
||||
/// </summary>
|
||||
/// <param name="rules"></param>
|
||||
/// <returns>success: true or false</returns>
|
||||
public int cmSetWindlightScene(LSL_List rules)
|
||||
{
|
||||
if (!m_CMFunctionsEnabled)
|
||||
{
|
||||
CMShoutError("Careminster functions are not enabled.");
|
||||
return 0;
|
||||
}
|
||||
if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200)
|
||||
{
|
||||
CMShoutError("cmSetWindlightScene can only be used by estate managers or owners.");
|
||||
return 0;
|
||||
}
|
||||
int success = 0;
|
||||
m_host.AddScriptLPS(1);
|
||||
if (Meta7WindlightModule.EnableWindlight)
|
||||
{
|
||||
RegionMeta7WindlightData wl = getWindlightProfileFromRules(rules);
|
||||
m_host.ParentGroup.Scene.StoreWindlightProfile(wl);
|
||||
success = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CMShoutError("Windlight module is disabled");
|
||||
return 0;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
/// <summary>
|
||||
/// Set the current Windlight scene to a target avatar
|
||||
/// </summary>
|
||||
/// <param name="rules"></param>
|
||||
/// <returns>success: true or false</returns>
|
||||
public int cmSetWindlightSceneTargeted(LSL_List rules, LSL_Key target)
|
||||
{
|
||||
if (!m_CMFunctionsEnabled)
|
||||
{
|
||||
CMShoutError("Careminster functions are not enabled.");
|
||||
return 0;
|
||||
}
|
||||
if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200)
|
||||
{
|
||||
CMShoutError("cmSetWindlightSceneTargeted can only be used by estate managers or owners.");
|
||||
return 0;
|
||||
}
|
||||
int success = 0;
|
||||
m_host.AddScriptLPS(1);
|
||||
if (Meta7WindlightModule.EnableWindlight)
|
||||
{
|
||||
RegionMeta7WindlightData wl = getWindlightProfileFromRules(rules);
|
||||
World.EventManager.TriggerOnSendNewWindlightProfileTargeted(wl, new UUID(target.m_string));
|
||||
success = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CMShoutError("Windlight module is disabled");
|
||||
return 0;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -728,18 +728,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
if (target != null)
|
||||
{
|
||||
UUID animID=UUID.Zero;
|
||||
lock (m_host.TaskInventory)
|
||||
m_host.TaskInventory.LockItemsForRead(true);
|
||||
foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
|
||||
{
|
||||
foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
|
||||
if (inv.Value.Name == animation)
|
||||
{
|
||||
if (inv.Value.Name == animation)
|
||||
{
|
||||
if (inv.Value.Type == (int)AssetType.Animation)
|
||||
animID = inv.Value.AssetID;
|
||||
continue;
|
||||
}
|
||||
if (inv.Value.Type == (int)AssetType.Animation)
|
||||
animID = inv.Value.AssetID;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
m_host.TaskInventory.LockItemsForRead(false);
|
||||
if (animID == UUID.Zero)
|
||||
target.Animator.AddAnimation(animation, m_host.UUID);
|
||||
else
|
||||
@@ -761,18 +760,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
if (target != null)
|
||||
{
|
||||
UUID animID=UUID.Zero;
|
||||
lock (m_host.TaskInventory)
|
||||
m_host.TaskInventory.LockItemsForRead(true);
|
||||
foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
|
||||
{
|
||||
foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
|
||||
if (inv.Value.Name == animation)
|
||||
{
|
||||
if (inv.Value.Name == animation)
|
||||
{
|
||||
if (inv.Value.Type == (int)AssetType.Animation)
|
||||
animID = inv.Value.AssetID;
|
||||
continue;
|
||||
}
|
||||
if (inv.Value.Type == (int)AssetType.Animation)
|
||||
animID = inv.Value.AssetID;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
m_host.TaskInventory.LockItemsForRead(false);
|
||||
|
||||
if (animID == UUID.Zero)
|
||||
target.Animator.RemoveAnimation(animation);
|
||||
@@ -1541,6 +1539,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
|
||||
if (!UUID.TryParse(name, out assetID))
|
||||
{
|
||||
m_host.TaskInventory.LockItemsForRead(true);
|
||||
foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
|
||||
{
|
||||
if (item.Type == 7 && item.Name == name)
|
||||
@@ -1548,6 +1547,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
assetID = item.AssetID;
|
||||
}
|
||||
}
|
||||
m_host.TaskInventory.LockItemsForRead(false);
|
||||
}
|
||||
|
||||
if (assetID == UUID.Zero)
|
||||
@@ -1594,6 +1594,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
|
||||
if (!UUID.TryParse(name, out assetID))
|
||||
{
|
||||
m_host.TaskInventory.LockItemsForRead(true);
|
||||
foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
|
||||
{
|
||||
if (item.Type == 7 && item.Name == name)
|
||||
@@ -1601,6 +1602,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
assetID = item.AssetID;
|
||||
}
|
||||
}
|
||||
m_host.TaskInventory.LockItemsForRead(false);
|
||||
}
|
||||
|
||||
if (assetID == UUID.Zero)
|
||||
@@ -1651,6 +1653,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
|
||||
if (!UUID.TryParse(name, out assetID))
|
||||
{
|
||||
m_host.TaskInventory.LockItemsForRead(true);
|
||||
foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
|
||||
{
|
||||
if (item.Type == 7 && item.Name == name)
|
||||
@@ -1658,6 +1661,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
assetID = item.AssetID;
|
||||
}
|
||||
}
|
||||
m_host.TaskInventory.LockItemsForRead(false);
|
||||
}
|
||||
|
||||
if (assetID == UUID.Zero)
|
||||
|
||||
@@ -109,25 +109,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
|
||||
if (Timers.Count == 0)
|
||||
return;
|
||||
|
||||
Dictionary<string, TimerClass>.ValueCollection tvals;
|
||||
lock (TimerListLock)
|
||||
{
|
||||
// Go through all timers
|
||||
Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values;
|
||||
foreach (TimerClass ts in tvals)
|
||||
{
|
||||
// Time has passed?
|
||||
if (ts.next < DateTime.Now.Ticks)
|
||||
{
|
||||
//m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
|
||||
// Add it to queue
|
||||
m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
|
||||
new EventParams("timer", new Object[0],
|
||||
new DetectParams[0]));
|
||||
// set next interval
|
||||
tvals = Timers.Values;
|
||||
}
|
||||
|
||||
//ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
|
||||
ts.next = DateTime.Now.Ticks + ts.interval;
|
||||
}
|
||||
foreach (TimerClass ts in tvals)
|
||||
{
|
||||
// Time has passed?
|
||||
if (ts.next < DateTime.Now.Ticks)
|
||||
{
|
||||
//m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
|
||||
// Add it to queue
|
||||
m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
|
||||
new EventParams("timer", new Object[0],
|
||||
new DetectParams[0]));
|
||||
// set next interval
|
||||
|
||||
//ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
|
||||
ts.next = DateTime.Now.Ticks + ts.interval;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
21
OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
Normal file
21
OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System.Collections;
|
||||
using OpenSim.Region.ScriptEngine.Interfaces;
|
||||
|
||||
using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
|
||||
using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
|
||||
using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
|
||||
using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
|
||||
using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
|
||||
using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
|
||||
using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
|
||||
|
||||
namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
||||
{
|
||||
public interface ICM_Api
|
||||
{
|
||||
// Windlight Functions
|
||||
LSL_List cmGetWindlightScene(LSL_List rules);
|
||||
int cmSetWindlightScene(LSL_List rules);
|
||||
int cmSetWindlightSceneTargeted(LSL_List rules, key target);
|
||||
}
|
||||
}
|
||||
@@ -80,7 +80,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
||||
// Avatar Info Commands
|
||||
string osGetAgentIP(string agent);
|
||||
LSL_List osGetAgents();
|
||||
|
||||
|
||||
// Teleport commands
|
||||
void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
|
||||
void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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 vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
|
||||
using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
|
||||
using LSLInteger = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
|
||||
|
||||
namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||
{
|
||||
public partial class ScriptBaseClass
|
||||
{
|
||||
// Constants for cmWindlight*
|
||||
public const int WL_WATER_COLOR = 0;
|
||||
public const int WL_WATER_FOG_DENSITY_EXPONENT = 1;
|
||||
public const int WL_UNDERWATER_FOG_MODIFIER = 2;
|
||||
public const int WL_REFLECTION_WAVELET_SCALE = 3;
|
||||
public const int WL_FRESNEL_SCALE = 4;
|
||||
public const int WL_FRESNEL_OFFSET = 5;
|
||||
public const int WL_REFRACT_SCALE_ABOVE = 6;
|
||||
public const int WL_REFRACT_SCALE_BELOW = 7;
|
||||
public const int WL_BLUR_MULTIPLIER = 8;
|
||||
public const int WL_BIG_WAVE_DIRECTION = 9;
|
||||
public const int WL_LITTLE_WAVE_DIRECTION = 10;
|
||||
public const int WL_NORMAL_MAP_TEXTURE = 11;
|
||||
public const int WL_HORIZON = 12;
|
||||
public const int WL_HAZE_HORIZON = 13;
|
||||
public const int WL_BLUE_DENSITY = 14;
|
||||
public const int WL_HAZE_DENSITY = 15;
|
||||
public const int WL_DENSITY_MULTIPLIER = 16;
|
||||
public const int WL_DISTANCE_MULTIPLIER = 17;
|
||||
public const int WL_MAX_ALTITUDE = 18;
|
||||
public const int WL_SUN_MOON_COLOR = 19;
|
||||
public const int WL_AMBIENT = 20;
|
||||
public const int WL_EAST_ANGLE = 21;
|
||||
public const int WL_SUN_GLOW_FOCUS = 22;
|
||||
public const int WL_SUN_GLOW_SIZE = 23;
|
||||
public const int WL_SCENE_GAMMA = 24;
|
||||
public const int WL_STAR_BRIGHTNESS = 25;
|
||||
public const int WL_CLOUD_COLOR = 26;
|
||||
public const int WL_CLOUD_XY_DENSITY = 27;
|
||||
public const int WL_CLOUD_COVERAGE = 28;
|
||||
public const int WL_CLOUD_SCALE = 29;
|
||||
public const int WL_CLOUD_DETAIL_XY_DENSITY = 30;
|
||||
public const int WL_CLOUD_SCROLL_X = 31;
|
||||
public const int WL_CLOUD_SCROLL_Y = 32;
|
||||
public const int WL_CLOUD_SCROLL_Y_LOCK = 33;
|
||||
public const int WL_CLOUD_SCROLL_X_LOCK = 34;
|
||||
public const int WL_DRAW_CLASSIC_CLOUDS = 35;
|
||||
|
||||
}
|
||||
}
|
||||
76
OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
Normal file
76
OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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.Runtime.Remoting.Lifetime;
|
||||
using System.Threading;
|
||||
using System.Reflection;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.ScriptEngine.Interfaces;
|
||||
using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
|
||||
using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
|
||||
using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
|
||||
using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
|
||||
using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
|
||||
using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
|
||||
using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
|
||||
using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
|
||||
using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
|
||||
|
||||
namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||
{
|
||||
public partial class ScriptBaseClass : MarshalByRefObject
|
||||
{
|
||||
public ICM_Api m_CM_Functions;
|
||||
|
||||
public void ApiTypeCM(IScriptApi api)
|
||||
{
|
||||
if (!(api is ICM_Api))
|
||||
return;
|
||||
|
||||
m_CM_Functions = (ICM_Api)api;
|
||||
}
|
||||
|
||||
public LSL_List cmGetWindlightScene(LSL_List rules)
|
||||
{
|
||||
return m_CM_Functions.cmGetWindlightScene(rules);
|
||||
}
|
||||
|
||||
public int cmSetWindlightScene(LSL_List rules)
|
||||
{
|
||||
return m_CM_Functions.cmSetWindlightScene(rules);
|
||||
}
|
||||
|
||||
public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
|
||||
{
|
||||
return m_CM_Functions.cmSetWindlightSceneTargeted(rules, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics; //for [DebuggerNonUserCode]
|
||||
using System.Reflection;
|
||||
using System.Runtime.Remoting.Lifetime;
|
||||
using OpenSim.Region.ScriptEngine.Shared;
|
||||
@@ -132,6 +133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||
return (eventFlags);
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
public void ExecuteEvent(string state, string FunctionName, object[] args)
|
||||
{
|
||||
// IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
<excludeFiles />
|
||||
</DeploymentInformation>
|
||||
<Contents>
|
||||
<File name="./CM_Constants.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||
<File name="./CM_Stub.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||
<File name="./Executor.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||
<File name="./LSL_Constants.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||
<File name="./LSL_Stub.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||
|
||||
@@ -33,6 +33,7 @@ using System.Threading;
|
||||
using System.Reflection;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics; //for [DebuggerNonUserCode]
|
||||
using OpenSim.Region.ScriptEngine.Interfaces;
|
||||
using OpenSim.Region.ScriptEngine.Shared;
|
||||
using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
|
||||
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||
return (int)m_Executor.GetStateEventFlags(state);
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
public void ExecuteEvent(string state, string FunctionName, object[] args)
|
||||
{
|
||||
m_Executor.ExecuteEvent(state, FunctionName, args);
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics; //for [DebuggerNonUserCode]
|
||||
using System.Runtime.Remoting;
|
||||
using System.Runtime.Remoting.Lifetime;
|
||||
using System.Threading;
|
||||
@@ -237,13 +238,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||
|
||||
if (part != null)
|
||||
{
|
||||
lock (part.TaskInventory)
|
||||
part.TaskInventory.LockItemsForRead(true);
|
||||
if (part.TaskInventory.ContainsKey(m_ItemID))
|
||||
{
|
||||
if (part.TaskInventory.ContainsKey(m_ItemID))
|
||||
{
|
||||
m_thisScriptTask = part.TaskInventory[m_ItemID];
|
||||
}
|
||||
m_thisScriptTask = part.TaskInventory[m_ItemID];
|
||||
}
|
||||
part.TaskInventory.LockItemsForRead(false);
|
||||
}
|
||||
|
||||
ApiManager am = new ApiManager();
|
||||
@@ -428,14 +428,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||
{
|
||||
int permsMask;
|
||||
UUID permsGranter;
|
||||
lock (part.TaskInventory)
|
||||
part.TaskInventory.LockItemsForRead(true);
|
||||
if (!part.TaskInventory.ContainsKey(m_ItemID))
|
||||
{
|
||||
if (!part.TaskInventory.ContainsKey(m_ItemID))
|
||||
return;
|
||||
|
||||
permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
|
||||
permsMask = part.TaskInventory[m_ItemID].PermsMask;
|
||||
part.TaskInventory.LockItemsForRead(false);
|
||||
return;
|
||||
}
|
||||
permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
|
||||
permsMask = part.TaskInventory[m_ItemID].PermsMask;
|
||||
part.TaskInventory.LockItemsForRead(false);
|
||||
|
||||
if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
|
||||
{
|
||||
@@ -544,6 +545,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||
return true;
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode] //Prevents the debugger from farting in this function
|
||||
public void SetState(string state)
|
||||
{
|
||||
if (state == State)
|
||||
@@ -555,7 +557,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||
new DetectParams[0]));
|
||||
PostEvent(new EventParams("state_entry", new Object[0],
|
||||
new DetectParams[0]));
|
||||
|
||||
|
||||
throw new EventAbortException();
|
||||
}
|
||||
|
||||
@@ -637,140 +639,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public object EventProcessor()
|
||||
{
|
||||
|
||||
EventParams data = null;
|
||||
|
||||
lock (m_EventQueue)
|
||||
{
|
||||
lock (m_Script)
|
||||
{
|
||||
EventParams data = null;
|
||||
|
||||
lock (m_EventQueue)
|
||||
{
|
||||
data = (EventParams) m_EventQueue.Dequeue();
|
||||
if (data == null) // Shouldn't happen
|
||||
{
|
||||
if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
|
||||
{
|
||||
m_CurrentResult = m_Engine.QueueEventHandler(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CurrentResult = null;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (data.EventName == "timer")
|
||||
m_TimerQueued = false;
|
||||
if (data.EventName == "control")
|
||||
{
|
||||
if (m_ControlEventsInQueue > 0)
|
||||
m_ControlEventsInQueue--;
|
||||
}
|
||||
if (data.EventName == "collision")
|
||||
m_CollisionInQueue = false;
|
||||
}
|
||||
|
||||
//m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this);
|
||||
|
||||
m_DetectParams = data.DetectParams;
|
||||
|
||||
if (data.EventName == "state") // Hardcoded state change
|
||||
{
|
||||
// m_log.DebugFormat("[Script] Script {0}.{1} state set to {2}",
|
||||
// m_PrimName, m_ScriptName, data.Params[0].ToString());
|
||||
m_State=data.Params[0].ToString();
|
||||
AsyncCommandManager.RemoveScript(m_Engine,
|
||||
m_LocalID, m_ItemID);
|
||||
|
||||
SceneObjectPart part = m_Engine.World.GetSceneObjectPart(
|
||||
m_LocalID);
|
||||
if (part != null)
|
||||
{
|
||||
part.SetScriptEvents(m_ItemID,
|
||||
(int)m_Script.GetStateEventFlags(State));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_Engine.World.PipeEventsForScript(m_LocalID) ||
|
||||
data.EventName == "control") // Don't freeze avies!
|
||||
{
|
||||
SceneObjectPart part = m_Engine.World.GetSceneObjectPart(
|
||||
m_LocalID);
|
||||
// m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}",
|
||||
// m_PrimName, m_ScriptName, data.EventName, m_State);
|
||||
|
||||
try
|
||||
{
|
||||
m_CurrentEvent = data.EventName;
|
||||
m_EventStart = DateTime.Now;
|
||||
m_InEvent = true;
|
||||
|
||||
m_Script.ExecuteEvent(State, data.EventName, data.Params);
|
||||
|
||||
m_InEvent = false;
|
||||
m_CurrentEvent = String.Empty;
|
||||
|
||||
if (m_SaveState)
|
||||
{
|
||||
// This will be the very first event we deliver
|
||||
// (state_entry) in default state
|
||||
//
|
||||
|
||||
SaveState(m_Assembly);
|
||||
|
||||
m_SaveState = false;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// m_log.DebugFormat("[SCRIPT] Exception: {0}", e.Message);
|
||||
m_InEvent = false;
|
||||
m_CurrentEvent = String.Empty;
|
||||
|
||||
if ((!(e is TargetInvocationException) || (!(e.InnerException is SelfDeleteException) && !(e.InnerException is ScriptDeleteException))) && !(e is ThreadAbortException))
|
||||
{
|
||||
try
|
||||
{
|
||||
// DISPLAY ERROR INWORLD
|
||||
string text = FormatException(e);
|
||||
|
||||
if (text.Length > 1000)
|
||||
text = text.Substring(0, 1000);
|
||||
m_Engine.World.SimChat(Utils.StringToBytes(text),
|
||||
ChatTypeEnum.DebugChannel, 2147483647,
|
||||
part.AbsolutePosition,
|
||||
part.Name, part.UUID, false);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
// catch (Exception e2) // LEGIT: User Scripting
|
||||
// {
|
||||
// m_log.Error("[SCRIPT]: "+
|
||||
// "Error displaying error in-world: " +
|
||||
// e2.ToString());
|
||||
// m_log.Error("[SCRIPT]: " +
|
||||
// "Errormessage: Error compiling script:\r\n" +
|
||||
// e.ToString());
|
||||
// }
|
||||
}
|
||||
else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException))
|
||||
{
|
||||
m_InSelfDelete = true;
|
||||
if (part != null && part.ParentGroup != null)
|
||||
m_Engine.World.DeleteSceneObject(part.ParentGroup, false);
|
||||
}
|
||||
else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException))
|
||||
{
|
||||
m_InSelfDelete = true;
|
||||
if (part != null && part.ParentGroup != null)
|
||||
part.Inventory.RemoveInventoryItem(m_ItemID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lock (m_EventQueue)
|
||||
data = (EventParams) m_EventQueue.Dequeue();
|
||||
if (data == null) // Shouldn't happen
|
||||
{
|
||||
if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
|
||||
{
|
||||
@@ -780,13 +658,141 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||
{
|
||||
m_CurrentResult = null;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_DetectParams = null;
|
||||
|
||||
return 0;
|
||||
if (data.EventName == "timer")
|
||||
m_TimerQueued = false;
|
||||
if (data.EventName == "control")
|
||||
{
|
||||
if (m_ControlEventsInQueue > 0)
|
||||
m_ControlEventsInQueue--;
|
||||
}
|
||||
if (data.EventName == "collision")
|
||||
m_CollisionInQueue = false;
|
||||
}
|
||||
}
|
||||
lock(m_Script)
|
||||
{
|
||||
|
||||
//m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this);
|
||||
|
||||
m_DetectParams = data.DetectParams;
|
||||
|
||||
if (data.EventName == "state") // Hardcoded state change
|
||||
{
|
||||
// m_log.DebugFormat("[Script] Script {0}.{1} state set to {2}",
|
||||
// m_PrimName, m_ScriptName, data.Params[0].ToString());
|
||||
m_State=data.Params[0].ToString();
|
||||
AsyncCommandManager.RemoveScript(m_Engine,
|
||||
m_LocalID, m_ItemID);
|
||||
|
||||
SceneObjectPart part = m_Engine.World.GetSceneObjectPart(
|
||||
m_LocalID);
|
||||
if (part != null)
|
||||
{
|
||||
part.SetScriptEvents(m_ItemID,
|
||||
(int)m_Script.GetStateEventFlags(State));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_Engine.World.PipeEventsForScript(m_LocalID) ||
|
||||
data.EventName == "control") // Don't freeze avies!
|
||||
{
|
||||
SceneObjectPart part = m_Engine.World.GetSceneObjectPart(
|
||||
m_LocalID);
|
||||
// m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}",
|
||||
// m_PrimName, m_ScriptName, data.EventName, m_State);
|
||||
|
||||
try
|
||||
{
|
||||
m_CurrentEvent = data.EventName;
|
||||
m_EventStart = DateTime.Now;
|
||||
m_InEvent = true;
|
||||
|
||||
m_Script.ExecuteEvent(State, data.EventName, data.Params);
|
||||
|
||||
m_InEvent = false;
|
||||
m_CurrentEvent = String.Empty;
|
||||
|
||||
if (m_SaveState)
|
||||
{
|
||||
// This will be the very first event we deliver
|
||||
// (state_entry) in default state
|
||||
//
|
||||
|
||||
SaveState(m_Assembly);
|
||||
|
||||
m_SaveState = false;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// m_log.DebugFormat("[SCRIPT] Exception: {0}", e.Message);
|
||||
m_InEvent = false;
|
||||
m_CurrentEvent = String.Empty;
|
||||
|
||||
if ((!(e is TargetInvocationException) || (!(e.InnerException is SelfDeleteException) && !(e.InnerException is ScriptDeleteException))) && !(e is ThreadAbortException))
|
||||
{
|
||||
try
|
||||
{
|
||||
// DISPLAY ERROR INWORLD
|
||||
string text = FormatException(e);
|
||||
|
||||
if (text.Length > 1000)
|
||||
text = text.Substring(0, 1000);
|
||||
m_Engine.World.SimChat(Utils.StringToBytes(text),
|
||||
ChatTypeEnum.DebugChannel, 2147483647,
|
||||
part.AbsolutePosition,
|
||||
part.Name, part.UUID, false);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
// catch (Exception e2) // LEGIT: User Scripting
|
||||
// {
|
||||
// m_log.Error("[SCRIPT]: "+
|
||||
// "Error displaying error in-world: " +
|
||||
// e2.ToString());
|
||||
// m_log.Error("[SCRIPT]: " +
|
||||
// "Errormessage: Error compiling script:\r\n" +
|
||||
// e.ToString());
|
||||
// }
|
||||
}
|
||||
else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException))
|
||||
{
|
||||
m_InSelfDelete = true;
|
||||
if (part != null && part.ParentGroup != null)
|
||||
m_Engine.World.DeleteSceneObject(part.ParentGroup, false);
|
||||
}
|
||||
else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException))
|
||||
{
|
||||
m_InSelfDelete = true;
|
||||
if (part != null && part.ParentGroup != null)
|
||||
part.Inventory.RemoveInventoryItem(m_ItemID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lock (m_EventQueue)
|
||||
{
|
||||
if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
|
||||
{
|
||||
m_CurrentResult = m_Engine.QueueEventHandler(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CurrentResult = null;
|
||||
}
|
||||
}
|
||||
|
||||
m_DetectParams = null;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int EventTime()
|
||||
{
|
||||
@@ -824,6 +830,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||
new Object[0], new DetectParams[0]));
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode] //Stops the VS debugger from farting in this function
|
||||
public void ApiResetScript()
|
||||
{
|
||||
// bool running = Running;
|
||||
|
||||
@@ -30,6 +30,7 @@ using System.IO;
|
||||
using System.Threading;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics; //for [DebuggerNonUserCode]
|
||||
using System.Security;
|
||||
using System.Security.Policy;
|
||||
using System.Reflection;
|
||||
@@ -102,6 +103,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||
private Dictionary<UUID, IScriptInstance> m_Scripts =
|
||||
new Dictionary<UUID, IScriptInstance>();
|
||||
|
||||
private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
|
||||
|
||||
// Maps the asset ID to the assembly
|
||||
|
||||
private Dictionary<UUID, string> m_Assemblies =
|
||||
@@ -123,6 +126,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||
private ScriptCompileQueue m_CompileQueue = new ScriptCompileQueue();
|
||||
IWorkItemResult m_CurrentCompile = null;
|
||||
|
||||
private void lockScriptsForRead(bool locked)
|
||||
{
|
||||
if (locked)
|
||||
{
|
||||
if (m_scriptsLock.RecursiveReadCount > 0)
|
||||
{
|
||||
m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
|
||||
m_scriptsLock.ExitReadLock();
|
||||
}
|
||||
if (m_scriptsLock.RecursiveWriteCount > 0)
|
||||
{
|
||||
m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
|
||||
m_scriptsLock.ExitWriteLock();
|
||||
}
|
||||
|
||||
while (!m_scriptsLock.TryEnterReadLock(60000))
|
||||
{
|
||||
m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire READ lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
|
||||
if (m_scriptsLock.IsWriteLockHeld)
|
||||
{
|
||||
m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_scriptsLock.RecursiveReadCount > 0)
|
||||
{
|
||||
m_scriptsLock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
private void lockScriptsForWrite(bool locked)
|
||||
{
|
||||
if (locked)
|
||||
{
|
||||
if (m_scriptsLock.RecursiveReadCount > 0)
|
||||
{
|
||||
m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
|
||||
m_scriptsLock.ExitReadLock();
|
||||
}
|
||||
if (m_scriptsLock.RecursiveWriteCount > 0)
|
||||
{
|
||||
m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
|
||||
m_scriptsLock.ExitWriteLock();
|
||||
}
|
||||
|
||||
while (!m_scriptsLock.TryEnterWriteLock(60000))
|
||||
{
|
||||
m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
|
||||
if (m_scriptsLock.IsWriteLockHeld)
|
||||
{
|
||||
m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_scriptsLock.RecursiveWriteCount > 0)
|
||||
{
|
||||
m_scriptsLock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string ScriptEngineName
|
||||
{
|
||||
get { return "XEngine"; }
|
||||
@@ -262,43 +330,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
lock (m_Scripts)
|
||||
lockScriptsForRead(true);
|
||||
foreach (IScriptInstance instance in m_Scripts.Values)
|
||||
{
|
||||
foreach (IScriptInstance instance in m_Scripts.Values)
|
||||
// Force a final state save
|
||||
//
|
||||
if (m_Assemblies.ContainsKey(instance.AssetID))
|
||||
{
|
||||
// Force a final state save
|
||||
//
|
||||
if (m_Assemblies.ContainsKey(instance.AssetID))
|
||||
{
|
||||
string assembly = m_Assemblies[instance.AssetID];
|
||||
instance.SaveState(assembly);
|
||||
}
|
||||
|
||||
// Clear the event queue and abort the instance thread
|
||||
//
|
||||
instance.ClearQueue();
|
||||
instance.Stop(0);
|
||||
|
||||
// Release events, timer, etc
|
||||
//
|
||||
instance.DestroyScriptInstance();
|
||||
|
||||
// Unload scripts and app domains
|
||||
// Must be done explicitly because they have infinite
|
||||
// lifetime
|
||||
//
|
||||
m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
|
||||
if (m_DomainScripts[instance.AppDomain].Count == 0)
|
||||
{
|
||||
m_DomainScripts.Remove(instance.AppDomain);
|
||||
UnloadAppDomain(instance.AppDomain);
|
||||
}
|
||||
string assembly = m_Assemblies[instance.AssetID];
|
||||
instance.SaveState(assembly);
|
||||
}
|
||||
|
||||
// Clear the event queue and abort the instance thread
|
||||
//
|
||||
instance.ClearQueue();
|
||||
instance.Stop(0);
|
||||
|
||||
// Release events, timer, etc
|
||||
//
|
||||
instance.DestroyScriptInstance();
|
||||
|
||||
// Unload scripts and app domains
|
||||
// Must be done explicitly because they have infinite
|
||||
// lifetime
|
||||
//
|
||||
m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
|
||||
if (m_DomainScripts[instance.AppDomain].Count == 0)
|
||||
{
|
||||
m_DomainScripts.Remove(instance.AppDomain);
|
||||
UnloadAppDomain(instance.AppDomain);
|
||||
}
|
||||
m_Scripts.Clear();
|
||||
m_PrimObjects.Clear();
|
||||
m_Assemblies.Clear();
|
||||
m_DomainScripts.Clear();
|
||||
}
|
||||
lockScriptsForRead(false);
|
||||
lockScriptsForWrite(true);
|
||||
m_Scripts.Clear();
|
||||
lockScriptsForWrite(false);
|
||||
m_PrimObjects.Clear();
|
||||
m_Assemblies.Clear();
|
||||
m_DomainScripts.Clear();
|
||||
|
||||
lock (m_ScriptEngines)
|
||||
{
|
||||
m_ScriptEngines.Remove(this);
|
||||
@@ -357,22 +427,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||
|
||||
List<IScriptInstance> instances = new List<IScriptInstance>();
|
||||
|
||||
lock (m_Scripts)
|
||||
{
|
||||
foreach (IScriptInstance instance in m_Scripts.Values)
|
||||
lockScriptsForRead(true);
|
||||
foreach (IScriptInstance instance in m_Scripts.Values)
|
||||
instances.Add(instance);
|
||||
}
|
||||
lockScriptsForRead(false);
|
||||
|
||||
foreach (IScriptInstance i in instances)
|
||||
{
|
||||
string assembly = String.Empty;
|
||||
|
||||
lock (m_Scripts)
|
||||
{
|
||||
|
||||
if (!m_Assemblies.ContainsKey(i.AssetID))
|
||||
continue;
|
||||
assembly = m_Assemblies[i.AssetID];
|
||||
}
|
||||
|
||||
|
||||
i.SaveState(assembly);
|
||||
}
|
||||
@@ -684,173 +752,184 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||
}
|
||||
}
|
||||
|
||||
lock (m_Scripts)
|
||||
|
||||
|
||||
ScriptInstance instance = null;
|
||||
// Create the object record
|
||||
lockScriptsForRead(true);
|
||||
if ((!m_Scripts.ContainsKey(itemID)) ||
|
||||
(m_Scripts[itemID].AssetID != assetID))
|
||||
{
|
||||
ScriptInstance instance = null;
|
||||
// Create the object record
|
||||
lockScriptsForRead(false);
|
||||
|
||||
if ((!m_Scripts.ContainsKey(itemID)) ||
|
||||
(m_Scripts[itemID].AssetID != assetID))
|
||||
UUID appDomain = assetID;
|
||||
|
||||
if (part.ParentGroup.IsAttachment)
|
||||
appDomain = part.ParentGroup.RootPart.UUID;
|
||||
|
||||
if (!m_AppDomains.ContainsKey(appDomain))
|
||||
{
|
||||
UUID appDomain = assetID;
|
||||
|
||||
if (part.ParentGroup.IsAttachment)
|
||||
appDomain = part.ParentGroup.RootPart.UUID;
|
||||
|
||||
if (!m_AppDomains.ContainsKey(appDomain))
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
AppDomainSetup appSetup = new AppDomainSetup();
|
||||
// appSetup.ApplicationBase = Path.Combine(
|
||||
// "ScriptEngines",
|
||||
// m_Scene.RegionInfo.RegionID.ToString());
|
||||
AppDomainSetup appSetup = new AppDomainSetup();
|
||||
// appSetup.ApplicationBase = Path.Combine(
|
||||
// "ScriptEngines",
|
||||
// m_Scene.RegionInfo.RegionID.ToString());
|
||||
|
||||
Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
|
||||
Evidence evidence = new Evidence(baseEvidence);
|
||||
Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
|
||||
Evidence evidence = new Evidence(baseEvidence);
|
||||
|
||||
AppDomain sandbox;
|
||||
if (m_AppDomainLoading)
|
||||
sandbox = AppDomain.CreateDomain(
|
||||
m_Scene.RegionInfo.RegionID.ToString(),
|
||||
evidence, appSetup);
|
||||
else
|
||||
sandbox = AppDomain.CurrentDomain;
|
||||
|
||||
//PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
|
||||
//AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
|
||||
//PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
|
||||
//PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
|
||||
//CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
|
||||
//sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
|
||||
//sandbox.SetAppDomainPolicy(sandboxPolicy);
|
||||
|
||||
m_AppDomains[appDomain] = sandbox;
|
||||
AppDomain sandbox;
|
||||
if (m_AppDomainLoading)
|
||||
sandbox = AppDomain.CreateDomain(
|
||||
m_Scene.RegionInfo.RegionID.ToString(),
|
||||
evidence, appSetup);
|
||||
else
|
||||
sandbox = AppDomain.CurrentDomain;
|
||||
|
||||
m_AppDomains[appDomain].AssemblyResolve +=
|
||||
new ResolveEventHandler(
|
||||
AssemblyResolver.OnAssemblyResolve);
|
||||
m_DomainScripts[appDomain] = new List<UUID>();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
|
||||
m_ScriptErrorMessage += "Exception creating app domain:\n";
|
||||
m_ScriptFailCount++;
|
||||
lock (m_AddingAssemblies)
|
||||
{
|
||||
m_AddingAssemblies[assembly]--;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
|
||||
//AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
|
||||
//PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
|
||||
//PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
|
||||
//CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
|
||||
//sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
|
||||
//sandbox.SetAppDomainPolicy(sandboxPolicy);
|
||||
|
||||
m_AppDomains[appDomain] = sandbox;
|
||||
|
||||
m_AppDomains[appDomain].AssemblyResolve +=
|
||||
new ResolveEventHandler(
|
||||
AssemblyResolver.OnAssemblyResolve);
|
||||
m_DomainScripts[appDomain] = new List<UUID>();
|
||||
}
|
||||
m_DomainScripts[appDomain].Add(itemID);
|
||||
|
||||
instance = new ScriptInstance(this, part,
|
||||
itemID, assetID, assembly,
|
||||
m_AppDomains[appDomain],
|
||||
part.ParentGroup.RootPart.Name,
|
||||
item.Name, startParam, postOnRez,
|
||||
stateSource, m_MaxScriptQueue);
|
||||
|
||||
m_log.DebugFormat("[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}",
|
||||
part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, part.ParentGroup.RootPart.AbsolutePosition.ToString());
|
||||
|
||||
if (presence != null)
|
||||
catch (Exception e)
|
||||
{
|
||||
ShowScriptSaveResponse(item.OwnerID,
|
||||
assetID, "Compile successful", true);
|
||||
m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
|
||||
m_ScriptErrorMessage += "Exception creating app domain:\n";
|
||||
m_ScriptFailCount++;
|
||||
lock (m_AddingAssemblies)
|
||||
{
|
||||
m_AddingAssemblies[assembly]--;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
instance.AppDomain = appDomain;
|
||||
instance.LineMap = linemap;
|
||||
|
||||
m_Scripts[itemID] = instance;
|
||||
}
|
||||
m_DomainScripts[appDomain].Add(itemID);
|
||||
|
||||
lock (m_PrimObjects)
|
||||
instance = new ScriptInstance(this, part,
|
||||
itemID, assetID, assembly,
|
||||
m_AppDomains[appDomain],
|
||||
part.ParentGroup.RootPart.Name,
|
||||
item.Name, startParam, postOnRez,
|
||||
stateSource, m_MaxScriptQueue);
|
||||
|
||||
m_log.DebugFormat("[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}",
|
||||
part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, part.ParentGroup.RootPart.AbsolutePosition.ToString());
|
||||
|
||||
if (presence != null)
|
||||
{
|
||||
if (!m_PrimObjects.ContainsKey(localID))
|
||||
m_PrimObjects[localID] = new List<UUID>();
|
||||
|
||||
if (!m_PrimObjects[localID].Contains(itemID))
|
||||
m_PrimObjects[localID].Add(itemID);
|
||||
|
||||
ShowScriptSaveResponse(item.OwnerID,
|
||||
assetID, "Compile successful", true);
|
||||
}
|
||||
|
||||
if (!m_Assemblies.ContainsKey(assetID))
|
||||
m_Assemblies[assetID] = assembly;
|
||||
|
||||
lock (m_AddingAssemblies)
|
||||
{
|
||||
m_AddingAssemblies[assembly]--;
|
||||
}
|
||||
|
||||
if (instance!=null)
|
||||
instance.Init();
|
||||
instance.AppDomain = appDomain;
|
||||
instance.LineMap = linemap;
|
||||
lockScriptsForWrite(true);
|
||||
m_Scripts[itemID] = instance;
|
||||
lockScriptsForWrite(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
lockScriptsForRead(false);
|
||||
}
|
||||
lock (m_PrimObjects)
|
||||
{
|
||||
if (!m_PrimObjects.ContainsKey(localID))
|
||||
m_PrimObjects[localID] = new List<UUID>();
|
||||
|
||||
if (!m_PrimObjects[localID].Contains(itemID))
|
||||
m_PrimObjects[localID].Add(itemID);
|
||||
|
||||
}
|
||||
|
||||
if (!m_Assemblies.ContainsKey(assetID))
|
||||
m_Assemblies[assetID] = assembly;
|
||||
|
||||
lock (m_AddingAssemblies)
|
||||
{
|
||||
m_AddingAssemblies[assembly]--;
|
||||
}
|
||||
|
||||
if (instance!=null)
|
||||
instance.Init();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void OnRemoveScript(uint localID, UUID itemID)
|
||||
{
|
||||
lock (m_Scripts)
|
||||
lockScriptsForRead(true);
|
||||
// Do we even have it?
|
||||
if (!m_Scripts.ContainsKey(itemID))
|
||||
{
|
||||
// Do we even have it?
|
||||
if (!m_Scripts.ContainsKey(itemID))
|
||||
return;
|
||||
lockScriptsForRead(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
IScriptInstance instance=m_Scripts[itemID];
|
||||
m_Scripts.Remove(itemID);
|
||||
IScriptInstance instance=m_Scripts[itemID];
|
||||
lockScriptsForRead(false);
|
||||
lockScriptsForWrite(true);
|
||||
m_Scripts.Remove(itemID);
|
||||
lockScriptsForWrite(false);
|
||||
instance.ClearQueue();
|
||||
instance.Stop(0);
|
||||
|
||||
instance.ClearQueue();
|
||||
instance.Stop(0);
|
||||
SceneObjectPart part =
|
||||
m_Scene.GetSceneObjectPart(localID);
|
||||
|
||||
SceneObjectPart part =
|
||||
m_Scene.GetSceneObjectPart(localID);
|
||||
|
||||
if (part != null)
|
||||
part.RemoveScriptEvents(itemID);
|
||||
if (part != null)
|
||||
part.RemoveScriptEvents(itemID);
|
||||
|
||||
// bool objectRemoved = false;
|
||||
|
||||
lock (m_PrimObjects)
|
||||
lock (m_PrimObjects)
|
||||
{
|
||||
// Remove the script from it's prim
|
||||
if (m_PrimObjects.ContainsKey(localID))
|
||||
{
|
||||
// Remove the script from it's prim
|
||||
if (m_PrimObjects.ContainsKey(localID))
|
||||
{
|
||||
// Remove inventory item record
|
||||
if (m_PrimObjects[localID].Contains(itemID))
|
||||
m_PrimObjects[localID].Remove(itemID);
|
||||
// Remove inventory item record
|
||||
if (m_PrimObjects[localID].Contains(itemID))
|
||||
m_PrimObjects[localID].Remove(itemID);
|
||||
|
||||
// If there are no more scripts, remove prim
|
||||
if (m_PrimObjects[localID].Count == 0)
|
||||
{
|
||||
m_PrimObjects.Remove(localID);
|
||||
// If there are no more scripts, remove prim
|
||||
if (m_PrimObjects[localID].Count == 0)
|
||||
{
|
||||
m_PrimObjects.Remove(localID);
|
||||
// objectRemoved = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
instance.RemoveState();
|
||||
instance.DestroyScriptInstance();
|
||||
|
||||
m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
|
||||
if (m_DomainScripts[instance.AppDomain].Count == 0)
|
||||
{
|
||||
m_DomainScripts.Remove(instance.AppDomain);
|
||||
UnloadAppDomain(instance.AppDomain);
|
||||
}
|
||||
|
||||
instance = null;
|
||||
|
||||
ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
|
||||
if (handlerObjectRemoved != null)
|
||||
handlerObjectRemoved(part.UUID);
|
||||
|
||||
CleanAssemblies();
|
||||
}
|
||||
|
||||
instance.RemoveState();
|
||||
instance.DestroyScriptInstance();
|
||||
|
||||
m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
|
||||
if (m_DomainScripts[instance.AppDomain].Count == 0)
|
||||
{
|
||||
m_DomainScripts.Remove(instance.AppDomain);
|
||||
UnloadAppDomain(instance.AppDomain);
|
||||
}
|
||||
|
||||
instance = null;
|
||||
|
||||
ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
|
||||
if (handlerObjectRemoved != null)
|
||||
handlerObjectRemoved(part.UUID);
|
||||
|
||||
CleanAssemblies();
|
||||
|
||||
|
||||
ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
|
||||
if (handlerScriptRemoved != null)
|
||||
handlerScriptRemoved(itemID);
|
||||
@@ -1102,12 +1181,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||
private IScriptInstance GetInstance(UUID itemID)
|
||||
{
|
||||
IScriptInstance instance;
|
||||
lock (m_Scripts)
|
||||
lockScriptsForRead(true);
|
||||
if (!m_Scripts.ContainsKey(itemID))
|
||||
{
|
||||
if (!m_Scripts.ContainsKey(itemID))
|
||||
return null;
|
||||
instance = m_Scripts[itemID];
|
||||
lockScriptsForRead(false);
|
||||
return null;
|
||||
}
|
||||
instance = m_Scripts[itemID];
|
||||
lockScriptsForRead(false);
|
||||
return instance;
|
||||
}
|
||||
|
||||
@@ -1131,6 +1212,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||
return false;
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
public void ApiResetScript(UUID itemID)
|
||||
{
|
||||
IScriptInstance instance = GetInstance(itemID);
|
||||
@@ -1182,6 +1264,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||
return UUID.Zero;
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
public void SetState(UUID itemID, string newState)
|
||||
{
|
||||
IScriptInstance instance = GetInstance(itemID);
|
||||
@@ -1202,11 +1285,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||
{
|
||||
List<IScriptInstance> instances = new List<IScriptInstance>();
|
||||
|
||||
lock (m_Scripts)
|
||||
{
|
||||
foreach (IScriptInstance instance in m_Scripts.Values)
|
||||
lockScriptsForRead(true);
|
||||
foreach (IScriptInstance instance in m_Scripts.Values)
|
||||
instances.Add(instance);
|
||||
}
|
||||
lockScriptsForRead(false);
|
||||
|
||||
foreach (IScriptInstance i in instances)
|
||||
{
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace OpenSim.Server.Handlers.Asset
|
||||
|
||||
if (p.Length > 0)
|
||||
{
|
||||
result = m_AssetService.Delete(p[0]);
|
||||
// result = m_AssetService.Delete(p[0]);
|
||||
}
|
||||
|
||||
XmlSerializer xs = new XmlSerializer(typeof(bool));
|
||||
|
||||
@@ -511,7 +511,7 @@ namespace OpenSim.Tests.Common.Mock
|
||||
|
||||
}
|
||||
|
||||
public void SendGenericMessage(string method, List<string> message)
|
||||
public void SendGenericMessage(string method, List<byte[]> message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -482,6 +482,9 @@
|
||||
|
||||
; Distance in meters that shouts should travel. Default is 100m
|
||||
shout_distance = 100
|
||||
|
||||
; Append a prefix to the god avatar names appearing in chat whilst in god mode
|
||||
; admin_prefix = "@"
|
||||
|
||||
|
||||
[Messaging]
|
||||
@@ -853,6 +856,12 @@
|
||||
; default is 1000
|
||||
cloud_update_rate = 1000
|
||||
|
||||
[Meta7Windlight]
|
||||
|
||||
; This enables the transmission of Windlight scenes to supporting clients, such as the Meta7 viewer.
|
||||
; It has no ill effect on viewers which do not support server-side windlight settings.
|
||||
; Currently we only have support for MySQL databases.
|
||||
enable_windlight = false;
|
||||
|
||||
[Trees]
|
||||
; Enable this to allow the tree module to manage your sim trees, including growing, reproducing and dying
|
||||
@@ -1007,6 +1016,9 @@
|
||||
|
||||
; Allow the use of os* functions (some are dangerous)
|
||||
AllowOSFunctions = false
|
||||
|
||||
; Allow the user of Careminster functions
|
||||
AllowCareminsterFunctions = false
|
||||
|
||||
; Threat level to allow, one of None, VeryLow, Low, Moderate, High, VeryHigh, Severe
|
||||
OSFunctionThreatLevel = VeryLow
|
||||
@@ -1339,6 +1351,9 @@
|
||||
; For example- http://127.0.0.1:9000/SStats/
|
||||
; enabled=false
|
||||
|
||||
[LandManagement]
|
||||
; DefaultAdministratorGroupUUID = "";
|
||||
; DefaultAdministratorParcelName = "";
|
||||
|
||||
;;
|
||||
;; These are defaults that are overwritten below in [Architecture].
|
||||
|
||||
30
prebuild.xml
30
prebuild.xml
@@ -543,6 +543,36 @@
|
||||
</Files>
|
||||
</Project>
|
||||
|
||||
<Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.ChOdePlugin" path="OpenSim/Region/Physics/ChOdePlugin" type="Library">
|
||||
<Configuration name="Debug">
|
||||
<Options>
|
||||
<OutputPath>../../../../bin/Physics/</OutputPath>
|
||||
</Options>
|
||||
</Configuration>
|
||||
<Configuration name="Release">
|
||||
<Options>
|
||||
<OutputPath>../../../../bin/Physics/</OutputPath>
|
||||
</Options>
|
||||
</Configuration>
|
||||
|
||||
<ReferencePath>../../../../bin/</ReferencePath>
|
||||
<Reference name="System"/>
|
||||
<Reference name="System.Core"/>
|
||||
<Reference name="OpenMetaverseTypes.dll"/>
|
||||
<Reference name="Nini.dll" />
|
||||
<Reference name="OpenSim.Framework"/>
|
||||
<Reference name="OpenSim.Framework.Console"/>
|
||||
<Reference name="OpenSim.Region.Physics.Manager"/>
|
||||
<Reference name="Ode.NET.dll" />
|
||||
<Reference name="log4net.dll"/>
|
||||
|
||||
<Files>
|
||||
<Match pattern="*.cs" recurse="true">
|
||||
<Exclude name="Tests" pattern="Tests"/>
|
||||
</Match>
|
||||
</Files>
|
||||
</Project>
|
||||
|
||||
<Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.BulletXPlugin" path="OpenSim/Region/Physics/BulletXPlugin" type="Library">
|
||||
<Configuration name="Debug">
|
||||
<Options>
|
||||
|
||||
Reference in New Issue
Block a user