Compare commits
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d0a6d82a23 | ||
|
|
ba2792bd1f | ||
|
|
3f8c09e006 | ||
|
|
8f39268761 | ||
|
|
cd8c8d78a9 | ||
|
|
980678846d | ||
|
|
9a92d8d57e | ||
|
|
b155c601d7 | ||
|
|
536f2c085a | ||
|
|
2602d4f16e | ||
|
|
174addc426 | ||
|
|
849053681e | ||
|
|
a8d8ea7990 | ||
|
|
10e6493f9f | ||
|
|
8c4f911935 | ||
|
|
62bc85b5c7 | ||
|
|
76eba917f9 | ||
|
|
84a046eaf5 | ||
|
|
8d1d314f49 | ||
|
|
9395f12584 | ||
|
|
b97f58d597 | ||
|
|
30c36a3960 | ||
|
|
206eccc2b6 | ||
|
|
2358a623e3 | ||
|
|
87850bd6dc | ||
|
|
d80eda202f | ||
|
|
3edfa585ec | ||
|
|
fa13a6a8da | ||
|
|
9d5e7c89d9 | ||
|
|
590bf0bcc0 | ||
|
|
b199a2dea3 | ||
|
|
f1d4b8d83e | ||
|
|
0088661356 | ||
|
|
1a7e3cabc0 | ||
|
|
132d701b3e | ||
|
|
3b97241716 | ||
|
|
f82d090df3 | ||
|
|
7399d3e953 | ||
|
|
cab546ecee | ||
|
|
7dc1c7d841 | ||
|
|
fbff51f387 | ||
|
|
b714fb0c39 | ||
|
|
f37038013d | ||
|
|
5e98e2b7c7 | ||
|
|
35f8f3ff79 | ||
|
|
7ec8e7e025 | ||
|
|
c6efebdd8c | ||
|
|
760047abc5 |
@@ -92,7 +92,6 @@ what it is today.
|
||||
* Flyte Xevious
|
||||
* Garmin Kawaguichi
|
||||
* Gryc Ueusp
|
||||
* Hiro Lecker
|
||||
* Imaze Rhiano
|
||||
* Intimidated
|
||||
* Jeremy Bongio (IBM)
|
||||
|
||||
@@ -2202,18 +2202,5 @@ VALUES
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveExtra(UUID regionID, string name, string value)
|
||||
{
|
||||
}
|
||||
|
||||
public void RemoveExtra(UUID regionID, string name)
|
||||
{
|
||||
}
|
||||
|
||||
public Dictionary<string, string> GetExtra(UUID regionID)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -719,99 +719,95 @@ namespace OpenSim.Data.MySQL
|
||||
RegionLightShareData nWP = new RegionLightShareData();
|
||||
nWP.OnSave += StoreRegionWindlightSettings;
|
||||
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
dbcon.Open();
|
||||
|
||||
string command = "select * from `regionwindlight` where region_id = ?regionID";
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand(command))
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
string command = "select * from `regionwindlight` where region_id = ?regionID";
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand(command))
|
||||
cmd.Connection = dbcon;
|
||||
|
||||
cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString());
|
||||
|
||||
IDataReader result = ExecuteReader(cmd);
|
||||
if (!result.Read())
|
||||
{
|
||||
cmd.Connection = dbcon;
|
||||
|
||||
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
|
||||
{
|
||||
nWP.regionID = DBGuid.FromDB(result["region_id"]);
|
||||
nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]);
|
||||
nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]);
|
||||
nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]);
|
||||
nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]);
|
||||
nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]);
|
||||
nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]);
|
||||
nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]);
|
||||
nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]);
|
||||
nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]);
|
||||
nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]);
|
||||
nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]);
|
||||
nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]);
|
||||
nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]);
|
||||
nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]);
|
||||
nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]);
|
||||
nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]);
|
||||
nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]);
|
||||
UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture);
|
||||
nWP.horizon.X = Convert.ToSingle(result["horizon_r"]);
|
||||
nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]);
|
||||
nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]);
|
||||
nWP.horizon.W = Convert.ToSingle(result["horizon_i"]);
|
||||
nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]);
|
||||
nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]);
|
||||
nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]);
|
||||
nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]);
|
||||
nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]);
|
||||
nWP.hazeDensity = Convert.ToSingle(result["haze_density"]);
|
||||
nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]);
|
||||
nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]);
|
||||
nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]);
|
||||
nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]);
|
||||
nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]);
|
||||
nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]);
|
||||
nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]);
|
||||
nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]);
|
||||
nWP.ambient.X = Convert.ToSingle(result["ambient_r"]);
|
||||
nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]);
|
||||
nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]);
|
||||
nWP.ambient.W = Convert.ToSingle(result["ambient_i"]);
|
||||
nWP.eastAngle = Convert.ToSingle(result["east_angle"]);
|
||||
nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]);
|
||||
nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]);
|
||||
nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]);
|
||||
nWP.starBrightness = Convert.ToSingle(result["star_brightness"]);
|
||||
nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]);
|
||||
nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]);
|
||||
nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]);
|
||||
nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]);
|
||||
nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]);
|
||||
nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]);
|
||||
nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]);
|
||||
nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]);
|
||||
nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]);
|
||||
nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]);
|
||||
nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]);
|
||||
nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]);
|
||||
nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]);
|
||||
nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]);
|
||||
nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]);
|
||||
nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]);
|
||||
nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]);
|
||||
nWP.valid = true;
|
||||
}
|
||||
//No result, so store our default windlight profile and return it
|
||||
nWP.regionID = regionUUID;
|
||||
StoreRegionWindlightSettings(nWP);
|
||||
return nWP;
|
||||
}
|
||||
else
|
||||
{
|
||||
nWP.regionID = DBGuid.FromDB(result["region_id"]);
|
||||
nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]);
|
||||
nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]);
|
||||
nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]);
|
||||
nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]);
|
||||
nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]);
|
||||
nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]);
|
||||
nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]);
|
||||
nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]);
|
||||
nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]);
|
||||
nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]);
|
||||
nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]);
|
||||
nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]);
|
||||
nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]);
|
||||
nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]);
|
||||
nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]);
|
||||
nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]);
|
||||
nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]);
|
||||
UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture);
|
||||
nWP.horizon.X = Convert.ToSingle(result["horizon_r"]);
|
||||
nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]);
|
||||
nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]);
|
||||
nWP.horizon.W = Convert.ToSingle(result["horizon_i"]);
|
||||
nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]);
|
||||
nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]);
|
||||
nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]);
|
||||
nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]);
|
||||
nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]);
|
||||
nWP.hazeDensity = Convert.ToSingle(result["haze_density"]);
|
||||
nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]);
|
||||
nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]);
|
||||
nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]);
|
||||
nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]);
|
||||
nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]);
|
||||
nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]);
|
||||
nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]);
|
||||
nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]);
|
||||
nWP.ambient.X = Convert.ToSingle(result["ambient_r"]);
|
||||
nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]);
|
||||
nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]);
|
||||
nWP.ambient.W = Convert.ToSingle(result["ambient_i"]);
|
||||
nWP.eastAngle = Convert.ToSingle(result["east_angle"]);
|
||||
nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]);
|
||||
nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]);
|
||||
nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]);
|
||||
nWP.starBrightness = Convert.ToSingle(result["star_brightness"]);
|
||||
nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]);
|
||||
nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]);
|
||||
nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]);
|
||||
nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]);
|
||||
nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]);
|
||||
nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]);
|
||||
nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]);
|
||||
nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]);
|
||||
nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]);
|
||||
nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]);
|
||||
nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]);
|
||||
nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]);
|
||||
nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]);
|
||||
nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]);
|
||||
nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]);
|
||||
nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]);
|
||||
nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]);
|
||||
nWP.valid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nWP;
|
||||
}
|
||||
|
||||
@@ -982,29 +978,26 @@ namespace OpenSim.Data.MySQL
|
||||
#region RegionEnvironmentSettings
|
||||
public string LoadRegionEnvironmentSettings(UUID regionUUID)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
dbcon.Open();
|
||||
|
||||
string command = "select * from `regionenvironment` where region_id = ?region_id";
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand(command))
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
string command = "select * from `regionenvironment` where region_id = ?region_id";
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand(command))
|
||||
cmd.Connection = dbcon;
|
||||
|
||||
cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
|
||||
|
||||
IDataReader result = ExecuteReader(cmd);
|
||||
if (!result.Read())
|
||||
{
|
||||
cmd.Connection = dbcon;
|
||||
|
||||
cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
|
||||
|
||||
IDataReader result = ExecuteReader(cmd);
|
||||
if (!result.Read())
|
||||
{
|
||||
return String.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Convert.ToString(result["llsd_settings"]);
|
||||
}
|
||||
return String.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Convert.ToString(result["llsd_settings"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1012,39 +1005,33 @@ namespace OpenSim.Data.MySQL
|
||||
|
||||
public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "REPLACE INTO `regionenvironment` (`region_id`, `llsd_settings`) VALUES (?region_id, ?llsd_settings)";
|
||||
|
||||
cmd.Parameters.AddWithValue("region_id", regionUUID);
|
||||
cmd.Parameters.AddWithValue("llsd_settings", settings);
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
cmd.CommandText = "REPLACE INTO `regionenvironment` (`region_id`, `llsd_settings`) VALUES (?region_id, ?llsd_settings)";
|
||||
|
||||
cmd.Parameters.AddWithValue("region_id", regionUUID);
|
||||
cmd.Parameters.AddWithValue("llsd_settings", settings);
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveRegionEnvironmentSettings(UUID regionUUID)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "delete from `regionenvironment` where region_id = ?region_id";
|
||||
cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
cmd.CommandText = "delete from `regionenvironment` where region_id = ?region_id";
|
||||
cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1985,74 +1972,5 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveExtra(UUID regionID, string name, string val)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "replace into regionextra values (?RegionID, ?Name, ?value)";
|
||||
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
||||
cmd.Parameters.AddWithValue("?Name", name);
|
||||
cmd.Parameters.AddWithValue("?value", val);
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveExtra(UUID regionID, string name)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "delete from regionextra where RegionID=?RegionID and Name=?Name";
|
||||
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
||||
cmd.Parameters.AddWithValue("?Name", name);
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Dictionary<string, string> GetExtra(UUID regionID)
|
||||
{
|
||||
Dictionary<string, string> ret = new Dictionary<string, string>();
|
||||
|
||||
lock (m_dbLock)
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "select * from regionextra where RegionID=?RegionID";
|
||||
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
||||
using (IDataReader r = cmd.ExecuteReader())
|
||||
{
|
||||
while (r.Read())
|
||||
{
|
||||
ret[r["Name"].ToString()] = r["value"].ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -895,10 +895,3 @@ CREATE TABLE `regionenvironment` (
|
||||
|
||||
COMMIT;
|
||||
|
||||
:VERSION 45
|
||||
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE `regionextra` (`RegionID` char(36) not null, `Name` varchar(32) not null, `value` text, primary key(`RegionID`, `Name`));
|
||||
|
||||
COMMIT;
|
||||
|
||||
@@ -151,18 +151,5 @@ namespace OpenSim.Data.Null
|
||||
public void Shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
public void SaveExtra(UUID regionID, string name, string value)
|
||||
{
|
||||
}
|
||||
|
||||
public void RemoveExtra(UUID regionID, string name)
|
||||
{
|
||||
}
|
||||
|
||||
public Dictionary<string, string> GetExtra(UUID regionID)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2890,17 +2890,5 @@ namespace OpenSim.Data.SQLite
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveExtra(UUID regionID, string name, string value)
|
||||
{
|
||||
}
|
||||
|
||||
public void RemoveExtra(UUID regionID, string name)
|
||||
{
|
||||
}
|
||||
|
||||
public Dictionary<string, string> GetExtra(UUID regionID)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -678,8 +678,6 @@ namespace OpenSim.Framework.Console
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public event OnOutputDelegate OnOutput;
|
||||
|
||||
public ICommands Commands { get; private set; }
|
||||
|
||||
public CommandConsole(string defaultPrompt) : base(defaultPrompt)
|
||||
@@ -699,13 +697,6 @@ namespace OpenSim.Framework.Console
|
||||
Output(s);
|
||||
}
|
||||
|
||||
protected void FireOnOutput(string text)
|
||||
{
|
||||
OnOutputDelegate onOutput = OnOutput;
|
||||
if (onOutput != null)
|
||||
onOutput(text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Display a command prompt on the console and wait for user input
|
||||
/// </summary>
|
||||
|
||||
@@ -319,8 +319,6 @@ namespace OpenSim.Framework.Console
|
||||
|
||||
public override void Output(string text, string level)
|
||||
{
|
||||
FireOnOutput(text);
|
||||
|
||||
lock (m_commandLine)
|
||||
{
|
||||
if (m_cursorYPosition == -1)
|
||||
@@ -511,4 +509,4 @@ namespace OpenSim.Framework.Console
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,8 +40,6 @@ namespace OpenSim.Framework.Console
|
||||
/// </summary>
|
||||
public class MockConsole : ICommandConsole
|
||||
{
|
||||
public event OnOutputDelegate OnOutput;
|
||||
|
||||
private MockCommands m_commands = new MockCommands();
|
||||
|
||||
public ICommands Commands { get { return m_commands; } }
|
||||
@@ -78,4 +76,4 @@ namespace OpenSim.Framework.Console
|
||||
public string[] Resolve(string[] cmd) { return null; }
|
||||
public XmlElement GetXml(XmlDocument doc) { return null; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -100,7 +100,6 @@ namespace OpenSim.Framework.Console
|
||||
m_LineNumber++;
|
||||
m_Scrollback.Add(String.Format("{0}", m_LineNumber)+":"+level+":"+text);
|
||||
}
|
||||
FireOnOutput(text.Trim());
|
||||
System.Console.WriteLine(text.Trim());
|
||||
}
|
||||
|
||||
|
||||
@@ -74,12 +74,8 @@ namespace OpenSim.Framework
|
||||
XmlElement GetXml(XmlDocument doc);
|
||||
}
|
||||
|
||||
public delegate void OnOutputDelegate(string message);
|
||||
|
||||
public interface ICommandConsole : IConsole
|
||||
{
|
||||
event OnOutputDelegate OnOutput;
|
||||
|
||||
ICommands Commands { get; }
|
||||
|
||||
/// <summary>
|
||||
@@ -91,4 +87,4 @@ namespace OpenSim.Framework
|
||||
|
||||
string ReadLine(string p, bool isCommand, bool e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,9 +120,7 @@ namespace OpenSim.Framework
|
||||
public UUID lastMapUUID = UUID.Zero;
|
||||
public string lastMapRefresh = "0";
|
||||
|
||||
private float m_nonphysPrimMin = 0;
|
||||
private int m_nonphysPrimMax = 0;
|
||||
private float m_physPrimMin = 0;
|
||||
private int m_physPrimMax = 0;
|
||||
private bool m_clampPrimSize = false;
|
||||
private int m_objectCapacity = 0;
|
||||
@@ -287,21 +285,11 @@ namespace OpenSim.Framework
|
||||
set { m_windlight = value; }
|
||||
}
|
||||
|
||||
public float NonphysPrimMin
|
||||
{
|
||||
get { return m_nonphysPrimMin; }
|
||||
}
|
||||
|
||||
public int NonphysPrimMax
|
||||
{
|
||||
get { return m_nonphysPrimMax; }
|
||||
}
|
||||
|
||||
public float PhysPrimMin
|
||||
{
|
||||
get { return m_physPrimMin; }
|
||||
}
|
||||
|
||||
public int PhysPrimMax
|
||||
{
|
||||
get { return m_physPrimMax; }
|
||||
@@ -635,28 +623,16 @@ namespace OpenSim.Framework
|
||||
m_regionType = config.GetString("RegionType", String.Empty);
|
||||
allKeys.Remove("RegionType");
|
||||
|
||||
#region Prim stuff
|
||||
|
||||
m_nonphysPrimMin = config.GetFloat("NonphysicalPrimMin", 0);
|
||||
allKeys.Remove("NonphysicalPrimMin");
|
||||
|
||||
// Prim stuff
|
||||
//
|
||||
m_nonphysPrimMax = config.GetInt("NonphysicalPrimMax", 0);
|
||||
allKeys.Remove("NonphysicalPrimMax");
|
||||
|
||||
m_physPrimMin = config.GetFloat("PhysicalPrimMin", 0);
|
||||
allKeys.Remove("PhysicalPrimMin");
|
||||
|
||||
m_physPrimMax = config.GetInt("PhysicalPrimMax", 0);
|
||||
allKeys.Remove("PhysicalPrimMax");
|
||||
|
||||
m_clampPrimSize = config.GetBoolean("ClampPrimSize", false);
|
||||
allKeys.Remove("ClampPrimSize");
|
||||
|
||||
m_objectCapacity = config.GetInt("MaxPrims", 15000);
|
||||
allKeys.Remove("MaxPrims");
|
||||
|
||||
#endregion
|
||||
|
||||
m_agentCapacity = config.GetInt("MaxAgents", 100);
|
||||
allKeys.Remove("MaxAgents");
|
||||
|
||||
@@ -692,18 +668,10 @@ namespace OpenSim.Framework
|
||||
|
||||
config.Set("ExternalHostName", m_externalHostName);
|
||||
|
||||
if (m_nonphysPrimMin != 0)
|
||||
config.Set("NonphysicalPrimMax", m_nonphysPrimMin);
|
||||
|
||||
if (m_nonphysPrimMax != 0)
|
||||
config.Set("NonphysicalPrimMax", m_nonphysPrimMax);
|
||||
|
||||
if (m_physPrimMin != 0)
|
||||
config.Set("PhysicalPrimMax", m_physPrimMin);
|
||||
|
||||
if (m_physPrimMax != 0)
|
||||
config.Set("PhysicalPrimMax", m_physPrimMax);
|
||||
|
||||
config.Set("ClampPrimSize", m_clampPrimSize.ToString());
|
||||
|
||||
if (m_objectCapacity != 0)
|
||||
@@ -786,15 +754,9 @@ namespace OpenSim.Framework
|
||||
configMember.addConfigurationOption("lastmap_refresh", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
|
||||
"Last Map Refresh", Util.UnixTimeSinceEpoch().ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("nonphysical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT,
|
||||
"Minimum size for nonphysical prims", m_nonphysPrimMin.ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("nonphysical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Maximum size for nonphysical prims", m_nonphysPrimMax.ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("physical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT,
|
||||
"Minimum size for nonphysical prims", m_physPrimMin.ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("physical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Maximum size for physical prims", m_physPrimMax.ToString(), true);
|
||||
|
||||
|
||||
@@ -29,8 +29,8 @@ namespace OpenSim
|
||||
{
|
||||
public class VersionInfo
|
||||
{
|
||||
private const string VERSION_NUMBER = "0.7.5";
|
||||
private const Flavour VERSION_FLAVOUR = Flavour.Dev;
|
||||
private const string VERSION_NUMBER = "0.7.4";
|
||||
private const Flavour VERSION_FLAVOUR = Flavour.Extended;
|
||||
|
||||
public enum Flavour
|
||||
{
|
||||
|
||||
@@ -420,7 +420,6 @@ namespace OpenSim
|
||||
{
|
||||
RunCommandScript(m_shutdownCommandsFile);
|
||||
}
|
||||
|
||||
base.ShutdownSpecific();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,234 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using Mono.Addins;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenMetaverse.Imaging;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Console;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||
using OpenSim.Capabilities.Handlers;
|
||||
|
||||
namespace OpenSim.Region.ClientStack.Linden
|
||||
{
|
||||
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RegionConsoleModule")]
|
||||
public class RegionConsoleModule : INonSharedRegionModule, IRegionConsole
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Scene m_scene;
|
||||
private IEventQueue m_eventQueue;
|
||||
private Commands m_commands = new Commands();
|
||||
public ICommands Commands { get { return m_commands; } }
|
||||
|
||||
public void Initialise(IConfigSource source)
|
||||
{
|
||||
m_commands.AddCommand( "Help", false, "help", "help [<item>]", "Display help on a particular command or on a list of commands in a category", Help);
|
||||
}
|
||||
|
||||
public void AddRegion(Scene s)
|
||||
{
|
||||
m_scene = s;
|
||||
m_scene.RegisterModuleInterface<IRegionConsole>(this);
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene s)
|
||||
{
|
||||
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
|
||||
m_scene = null;
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene s)
|
||||
{
|
||||
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
|
||||
m_eventQueue = m_scene.RequestModuleInterface<IEventQueue>();
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close() { }
|
||||
|
||||
public string Name { get { return "RegionConsoleModule"; } }
|
||||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public void RegisterCaps(UUID agentID, Caps caps)
|
||||
{
|
||||
if (!m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(agentID))
|
||||
return;
|
||||
|
||||
UUID capID = UUID.Random();
|
||||
|
||||
m_log.DebugFormat("[REGION CONSOLE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
|
||||
caps.RegisterHandler(
|
||||
"SimConsoleAsync",
|
||||
new ConsoleHandler("/CAPS/" + capID + "/", "SimConsoleAsync", agentID, this, m_scene));
|
||||
}
|
||||
|
||||
public void SendConsoleOutput(UUID agentID, string message)
|
||||
{
|
||||
OSD osd = OSD.FromString(message);
|
||||
|
||||
m_eventQueue.Enqueue(EventQueueHelper.BuildEvent("SimConsoleResponse", osd), agentID);
|
||||
}
|
||||
|
||||
public bool RunCommand(string command, UUID invokerID)
|
||||
{
|
||||
string[] parts = Parser.Parse(command);
|
||||
Array.Resize(ref parts, parts.Length + 1);
|
||||
parts[parts.Length - 1] = invokerID.ToString();
|
||||
|
||||
if (m_commands.Resolve(parts).Length == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void Help(string module, string[] cmd)
|
||||
{
|
||||
UUID agentID = new UUID(cmd[cmd.Length - 1]);
|
||||
Array.Resize(ref cmd, cmd.Length - 1);
|
||||
|
||||
List<string> help = Commands.GetHelp(cmd);
|
||||
|
||||
string reply = String.Empty;
|
||||
|
||||
foreach (string s in help)
|
||||
{
|
||||
reply += s + "\n";
|
||||
}
|
||||
|
||||
SendConsoleOutput(agentID, reply);
|
||||
}
|
||||
|
||||
public void AddCommand(string module, bool shared, string command, string help, string longhelp, CommandDelegate fn)
|
||||
{
|
||||
m_commands.AddCommand(module, shared, command, help, longhelp, fn);
|
||||
}
|
||||
}
|
||||
|
||||
public class ConsoleHandler : BaseStreamHandler
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private RegionConsoleModule m_consoleModule;
|
||||
private UUID m_agentID;
|
||||
private bool m_isGod;
|
||||
private Scene m_scene;
|
||||
private bool m_consoleIsOn = false;
|
||||
|
||||
public ConsoleHandler(string path, string name, UUID agentID, RegionConsoleModule module, Scene scene)
|
||||
:base("POST", path, name, agentID.ToString())
|
||||
{
|
||||
m_agentID = agentID;
|
||||
m_consoleModule = module;
|
||||
m_scene = scene;
|
||||
|
||||
m_isGod = m_scene.Permissions.IsGod(agentID);
|
||||
}
|
||||
|
||||
public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
StreamReader reader = new StreamReader(request);
|
||||
string message = reader.ReadToEnd();
|
||||
|
||||
OSD osd = OSDParser.DeserializeLLSDXml(message);
|
||||
|
||||
string cmd = osd.AsString();
|
||||
if (cmd == "set console on")
|
||||
{
|
||||
if (m_isGod)
|
||||
{
|
||||
MainConsole.Instance.OnOutput += ConsoleSender;
|
||||
m_consoleIsOn = true;
|
||||
m_consoleModule.SendConsoleOutput(m_agentID, "Console is now on");
|
||||
}
|
||||
return new byte[0];
|
||||
}
|
||||
else if (cmd == "set console off")
|
||||
{
|
||||
MainConsole.Instance.OnOutput -= ConsoleSender;
|
||||
m_consoleIsOn = false;
|
||||
m_consoleModule.SendConsoleOutput(m_agentID, "Console is now off");
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
if (m_consoleIsOn == false && m_consoleModule.RunCommand(osd.AsString().Trim(), m_agentID))
|
||||
return new byte[0];
|
||||
|
||||
if (m_isGod && m_consoleIsOn)
|
||||
{
|
||||
MainConsole.Instance.RunCommand(osd.AsString().Trim());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_consoleModule.SendConsoleOutput(m_agentID, "Unknown command");
|
||||
}
|
||||
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
private void ConsoleSender(string text)
|
||||
{
|
||||
m_consoleModule.SendConsoleOutput(m_agentID, text);
|
||||
}
|
||||
|
||||
private void OnMakeChildAgent(ScenePresence presence)
|
||||
{
|
||||
if (presence.UUID == m_agentID)
|
||||
{
|
||||
MainConsole.Instance.OnOutput -= ConsoleSender;
|
||||
m_consoleIsOn = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -239,7 +239,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
sp.ClearAttachments();
|
||||
}
|
||||
|
||||
public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp)
|
||||
public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent)
|
||||
{
|
||||
lock (sp.AttachmentsSyncLock)
|
||||
{
|
||||
@@ -298,7 +298,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
group.AbsolutePosition = attachPos;
|
||||
|
||||
if (sp.PresenceType != PresenceType.Npc)
|
||||
UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp);
|
||||
UpdateUserInventoryWithAttachment(sp, group, attachmentPt);
|
||||
|
||||
AttachToAgent(sp, group, attachmentPt, attachPos, silent);
|
||||
}
|
||||
@@ -306,7 +306,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
return true;
|
||||
}
|
||||
|
||||
private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp)
|
||||
private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt)
|
||||
{
|
||||
// Remove any previous attachments
|
||||
List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
|
||||
@@ -316,22 +316,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
{
|
||||
if (attachments[0].FromItemID != UUID.Zero)
|
||||
DetachSingleAttachmentToInvInternal(sp, attachments[0]);
|
||||
// Error logging commented because UUID.Zero now means temp attachment
|
||||
// else
|
||||
// m_log.WarnFormat(
|
||||
// "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!",
|
||||
// attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name);
|
||||
else
|
||||
m_log.WarnFormat(
|
||||
"[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!",
|
||||
attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name);
|
||||
}
|
||||
|
||||
// Add the new attachment to inventory if we don't already have it.
|
||||
if (!temp)
|
||||
{
|
||||
UUID newAttachmentItemID = group.FromItemID;
|
||||
if (newAttachmentItemID == UUID.Zero)
|
||||
newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
|
||||
UUID newAttachmentItemID = group.FromItemID;
|
||||
if (newAttachmentItemID == UUID.Zero)
|
||||
newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
|
||||
|
||||
ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group);
|
||||
}
|
||||
ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group);
|
||||
}
|
||||
|
||||
public SceneObjectGroup RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt)
|
||||
@@ -410,10 +406,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
|
||||
UUID inventoryID = so.FromItemID;
|
||||
|
||||
// As per Linden spec, drop is disabled for temp attachs
|
||||
if (inventoryID == UUID.Zero)
|
||||
return;
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}",
|
||||
// so.Name, so.LocalId, inventoryID);
|
||||
@@ -424,9 +416,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
so.PrimCount, sp.UUID, sp.AbsolutePosition))
|
||||
return;
|
||||
|
||||
bool changed = false;
|
||||
if (inventoryID != UUID.Zero)
|
||||
changed = sp.Appearance.DetachAttachment(inventoryID);
|
||||
bool changed = sp.Appearance.DetachAttachment(inventoryID);
|
||||
if (changed && m_scene.AvatarFactory != null)
|
||||
m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
|
||||
|
||||
@@ -531,13 +521,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
/// <param name="saveAllScripted"></param>
|
||||
private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp, string scriptedState)
|
||||
{
|
||||
if (grp.FromItemID == UUID.Zero)
|
||||
{
|
||||
// We can't save temp attachments
|
||||
grp.HasGroupChanged = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Saving attachments for NPCs messes them up for the real owner!
|
||||
INPCModule module = m_scene.RequestModuleInterface<INPCModule>();
|
||||
if (module != null)
|
||||
@@ -794,7 +777,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
// This will throw if the attachment fails
|
||||
try
|
||||
{
|
||||
AttachObject(sp, objatt, attachmentPt, false, false);
|
||||
AttachObject(sp, objatt, attachmentPt, false);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -948,7 +931,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
AttachmentPt &= 0x7f;
|
||||
|
||||
// Calls attach with a Zero position
|
||||
if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, false))
|
||||
if (AttachObject(sp, part.ParentGroup, AttachmentPt, false))
|
||||
{
|
||||
// m_log.Debug(
|
||||
// "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
|
||||
@@ -972,7 +955,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
|
||||
SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID);
|
||||
|
||||
if (sp != null && group != null && group.FromItemID != UUID.Zero)
|
||||
if (sp != null && group != null)
|
||||
DetachSingleAttachmentToInv(sp, group);
|
||||
}
|
||||
|
||||
@@ -990,7 +973,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
|
||||
foreach (SceneObjectGroup group in attachments)
|
||||
{
|
||||
if (group.FromItemID == itemID && group.FromItemID != UUID.Zero)
|
||||
if (group.FromItemID == itemID)
|
||||
{
|
||||
DetachSingleAttachmentToInv(sp, group);
|
||||
return;
|
||||
|
||||
@@ -189,7 +189,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
|
||||
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID);
|
||||
|
||||
scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false);
|
||||
scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false);
|
||||
|
||||
// Check status on scene presence
|
||||
Assert.That(sp.HasAttachments(), Is.True);
|
||||
@@ -243,7 +243,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
sp2.AbsolutePosition = new Vector3(0, 0, 0);
|
||||
sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero);
|
||||
|
||||
scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false);
|
||||
scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false);
|
||||
|
||||
Assert.That(sp.HasAttachments(), Is.False);
|
||||
Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
|
||||
|
||||
@@ -84,7 +84,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||
public string body;
|
||||
public int responseCode;
|
||||
public string responseBody;
|
||||
public string responseType = "text/plain";
|
||||
//public ManualResetEvent ev;
|
||||
public bool requestDone;
|
||||
public int startTime;
|
||||
@@ -303,22 +302,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||
}
|
||||
}
|
||||
|
||||
public void HttpContentType(UUID request, string type)
|
||||
{
|
||||
lock (m_UrlMap)
|
||||
{
|
||||
if (m_RequestMap.ContainsKey(request))
|
||||
{
|
||||
UrlData urlData = m_RequestMap[request];
|
||||
urlData.requests[request].responseType = type;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Info("[HttpRequestHandler] There is no http-in request with id " + request.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void HttpResponse(UUID request, int status, string body)
|
||||
{
|
||||
lock (m_UrlMap)
|
||||
@@ -521,8 +504,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||
//put response
|
||||
response["int_response_code"] = requestData.responseCode;
|
||||
response["str_response_string"] = requestData.responseBody;
|
||||
response["content_type"] = requestData.responseType;
|
||||
// response["content_type"] = "text/plain";
|
||||
response["content_type"] = "text/plain";
|
||||
response["keepalive"] = false;
|
||||
response["reusecontext"] = false;
|
||||
|
||||
|
||||
@@ -97,13 +97,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to cache lookups for valid groups.
|
||||
/// </summary>
|
||||
private IDictionary<UUID, bool> m_validGroupUuids = new Dictionary<UUID, bool>();
|
||||
|
||||
private IGroupsModule m_groupsModule;
|
||||
|
||||
public ArchiveReadRequest(Scene scene, string loadPath, bool merge, bool skipAssets, Guid requestId)
|
||||
{
|
||||
m_scene = scene;
|
||||
@@ -127,8 +120,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||
|
||||
// Zero can never be a valid user id
|
||||
m_validUserUuids[UUID.Zero] = false;
|
||||
|
||||
m_groupsModule = m_scene.RequestModuleInterface<IGroupsModule>();
|
||||
}
|
||||
|
||||
public ArchiveReadRequest(Scene scene, Stream loadStream, bool merge, bool skipAssets, Guid requestId)
|
||||
@@ -141,8 +132,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||
|
||||
// Zero can never be a valid user id
|
||||
m_validUserUuids[UUID.Zero] = false;
|
||||
|
||||
m_groupsModule = m_scene.RequestModuleInterface<IGroupsModule>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -313,9 +302,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||
if (!ResolveUserUuid(part.LastOwnerID))
|
||||
part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
|
||||
|
||||
if (!ResolveGroupUuid(part.GroupID))
|
||||
part.GroupID = UUID.Zero;
|
||||
|
||||
// And zap any troublesome sit target information
|
||||
// part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
|
||||
// part.SitTargetPosition = new Vector3(0, 0, 0);
|
||||
@@ -332,18 +318,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||
{
|
||||
kvp.Value.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
|
||||
}
|
||||
|
||||
if (kvp.Value.CreatorData == null || kvp.Value.CreatorData == string.Empty)
|
||||
{
|
||||
if (!ResolveUserUuid(kvp.Value.CreatorID))
|
||||
kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner;
|
||||
}
|
||||
|
||||
if (UserManager != null)
|
||||
UserManager.AddUser(kvp.Value.CreatorID, kvp.Value.CreatorData);
|
||||
|
||||
if (!ResolveGroupUuid(kvp.Value.GroupID))
|
||||
kvp.Value.GroupID = UUID.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -383,27 +364,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||
foreach (string serialisedParcel in serialisedParcels)
|
||||
{
|
||||
LandData parcel = LandDataSerializer.Deserialize(serialisedParcel);
|
||||
|
||||
// Validate User and Group UUID's
|
||||
|
||||
if (!ResolveUserUuid(parcel.OwnerID))
|
||||
parcel.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
|
||||
|
||||
if (!ResolveGroupUuid(parcel.GroupID))
|
||||
{
|
||||
parcel.GroupID = UUID.Zero;
|
||||
parcel.IsGroupOwned = false;
|
||||
}
|
||||
|
||||
List<LandAccessEntry> accessList = new List<LandAccessEntry>();
|
||||
foreach (LandAccessEntry entry in parcel.ParcelAccessList)
|
||||
{
|
||||
if (ResolveUserUuid(entry.AgentID))
|
||||
accessList.Add(entry);
|
||||
// else, drop this access rule
|
||||
}
|
||||
parcel.ParcelAccessList = accessList;
|
||||
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[ARCHIVER]: Adding parcel {0}, local id {1}, area {2}",
|
||||
// parcel.Name, parcel.LocalID, parcel.Area);
|
||||
@@ -438,30 +401,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Look up the given group id to check whether it's one that is valid for this grid.
|
||||
/// </summary>
|
||||
/// <param name="uuid"></param>
|
||||
/// <returns></returns>
|
||||
private bool ResolveGroupUuid(UUID uuid)
|
||||
{
|
||||
if (uuid == UUID.Zero)
|
||||
return true; // this means the object has no group
|
||||
|
||||
if (!m_validGroupUuids.ContainsKey(uuid))
|
||||
{
|
||||
bool exists;
|
||||
|
||||
if (m_groupsModule == null)
|
||||
exists = false;
|
||||
else
|
||||
exists = (m_groupsModule.GetGroupRecord(uuid) != null);
|
||||
|
||||
m_validGroupUuids.Add(uuid, exists);
|
||||
}
|
||||
|
||||
return m_validGroupUuids[uuid];
|
||||
}
|
||||
|
||||
/// Load an asset
|
||||
/// </summary>
|
||||
/// <param name="assetFilename"></param>
|
||||
|
||||
@@ -414,7 +414,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
private void LoadPlugins()
|
||||
{
|
||||
m_plugineffects = new Dictionary<string, ITerrainEffect>();
|
||||
LoadPlugins(Assembly.GetCallingAssembly());
|
||||
string plugineffectsPath = "Terrain";
|
||||
|
||||
// Load the files in the Terrain/ dir
|
||||
@@ -428,7 +427,32 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
try
|
||||
{
|
||||
Assembly library = Assembly.LoadFrom(file);
|
||||
LoadPlugins(library);
|
||||
foreach (Type pluginType in library.GetTypes())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (pluginType.IsAbstract || pluginType.IsNotPublic)
|
||||
continue;
|
||||
|
||||
string typeName = pluginType.Name;
|
||||
|
||||
if (pluginType.GetInterface("ITerrainEffect", false) != null)
|
||||
{
|
||||
ITerrainEffect terEffect = (ITerrainEffect) Activator.CreateInstance(library.GetType(pluginType.ToString()));
|
||||
|
||||
InstallPlugin(typeName, terEffect);
|
||||
}
|
||||
else if (pluginType.GetInterface("ITerrainLoader", false) != null)
|
||||
{
|
||||
ITerrainLoader terLoader = (ITerrainLoader) Activator.CreateInstance(library.GetType(pluginType.ToString()));
|
||||
m_loaders[terLoader.FileExtension] = terLoader;
|
||||
m_log.Info("L ... " + typeName);
|
||||
}
|
||||
}
|
||||
catch (AmbiguousMatchException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (BadImageFormatException)
|
||||
{
|
||||
@@ -436,36 +460,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadPlugins(Assembly library)
|
||||
{
|
||||
foreach (Type pluginType in library.GetTypes())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (pluginType.IsAbstract || pluginType.IsNotPublic)
|
||||
continue;
|
||||
|
||||
string typeName = pluginType.Name;
|
||||
|
||||
if (pluginType.GetInterface("ITerrainEffect", false) != null)
|
||||
{
|
||||
ITerrainEffect terEffect = (ITerrainEffect)Activator.CreateInstance(library.GetType(pluginType.ToString()));
|
||||
|
||||
InstallPlugin(typeName, terEffect);
|
||||
}
|
||||
else if (pluginType.GetInterface("ITerrainLoader", false) != null)
|
||||
{
|
||||
ITerrainLoader terLoader = (ITerrainLoader)Activator.CreateInstance(library.GetType(pluginType.ToString()));
|
||||
m_loaders[terLoader.FileExtension] = terLoader;
|
||||
m_log.Info("L ... " + typeName);
|
||||
}
|
||||
}
|
||||
catch (AmbiguousMatchException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void InstallPlugin(string pluginName, ITerrainEffect effect)
|
||||
{
|
||||
lock (m_plugineffects)
|
||||
@@ -1182,8 +1176,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
|
||||
private void InterfaceRunPluginEffect(Object[] args)
|
||||
{
|
||||
string firstArg = (string)args[0];
|
||||
if (firstArg == "list")
|
||||
if ((string) args[0] == "list")
|
||||
{
|
||||
m_log.Info("List of loaded plugins");
|
||||
foreach (KeyValuePair<string, ITerrainEffect> kvp in m_plugineffects)
|
||||
@@ -1192,14 +1185,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (firstArg == "reload")
|
||||
if ((string) args[0] == "reload")
|
||||
{
|
||||
LoadPlugins();
|
||||
return;
|
||||
}
|
||||
if (m_plugineffects.ContainsKey(firstArg))
|
||||
if (m_plugineffects.ContainsKey((string) args[0]))
|
||||
{
|
||||
m_plugineffects[firstArg].RunEffect(m_channel);
|
||||
m_plugineffects[(string) args[0]].RunEffect(m_channel);
|
||||
CheckForTerrainUpdates();
|
||||
}
|
||||
else
|
||||
|
||||
@@ -208,9 +208,6 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||
bitmap = ImageUtils.ResizeImage(origBitmap, viewport.Width, viewport.Height);
|
||||
}
|
||||
|
||||
GC.Collect();
|
||||
m_log.Debug("[WARP 3D IMAGE MODULE]: GC.Collect()");
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
@@ -676,4 +673,4 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -83,7 +83,7 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
/// <param name="AttachmentPt"></param>
|
||||
/// <param name="silent"></param>
|
||||
/// <returns>true if the object was successfully attached, false otherwise</returns>
|
||||
bool AttachObject(IScenePresence sp, SceneObjectGroup grp, uint AttachmentPt, bool silent, bool temp);
|
||||
bool AttachObject(IScenePresence sp, SceneObjectGroup grp, uint AttachmentPt, bool silent);
|
||||
|
||||
/// <summary>
|
||||
/// Rez an attachment from user inventory and change inventory status to match.
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
|
||||
namespace OpenSim.Region.Framework.Interfaces
|
||||
{
|
||||
public interface IRegionConsole
|
||||
{
|
||||
bool RunCommand(string command, UUID invokerID);
|
||||
void SendConsoleOutput(UUID agentID, string message);
|
||||
void AddCommand(string module, bool shared, string command, string help, string longhelp, CommandDelegate fn);
|
||||
}
|
||||
}
|
||||
@@ -46,38 +46,9 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
/// </summary>
|
||||
event ScriptCommand OnScriptCommand;
|
||||
|
||||
/// <summary>
|
||||
/// Register an instance method as a script call by method name
|
||||
/// </summary>
|
||||
/// <param name="target"></param>
|
||||
/// <param name="method"></param>
|
||||
void RegisterScriptInvocation(object target, string method);
|
||||
|
||||
/// <summary>
|
||||
/// Register a static or instance method as a script call by method info
|
||||
/// </summary>
|
||||
/// <param name="target">If target is a Type object, will assume method is static.</param>
|
||||
/// <param name="method"></param>
|
||||
void RegisterScriptInvocation(object target, MethodInfo method);
|
||||
|
||||
/// <summary>
|
||||
/// Register one or more instance methods as script calls by method name
|
||||
/// </summary>
|
||||
/// <param name="target"></param>
|
||||
/// <param name="methods"></param>
|
||||
void RegisterScriptInvocation(object target, string[] methods);
|
||||
|
||||
/// <summary>
|
||||
/// Register one or more static methods as script calls by method name
|
||||
/// </summary>
|
||||
/// <param name="target"></param>
|
||||
/// <param name="methods"></param>
|
||||
void RegisterScriptInvocation(Type target, string[] methods);
|
||||
|
||||
/// <summary>
|
||||
/// Returns an array of all registered script calls
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Delegate[] GetScriptInvocationList();
|
||||
|
||||
Delegate LookupScriptInvocation(string fname);
|
||||
|
||||
@@ -116,10 +116,5 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
/// <param name="regionUUID">the region UUID</param>
|
||||
void RemoveRegionEnvironmentSettings(UUID regionUUID);
|
||||
|
||||
void SaveExtra(UUID regionID, string name, string value);
|
||||
|
||||
void RemoveExtra(UUID regionID, string name);
|
||||
|
||||
Dictionary<string, string> GetExtra(UUID regionID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,12 +127,6 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
/// <param name="regionUUID">the region UUID</param>
|
||||
void RemoveRegionEnvironmentSettings(UUID regionUUID);
|
||||
|
||||
void SaveExtra(UUID regionID, string name, string val);
|
||||
|
||||
void RemoveExtra(UUID regionID, string name);
|
||||
|
||||
Dictionary<string, string> GetExtra(UUID regionID);
|
||||
|
||||
void Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,8 +39,6 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
UUID RequestSecureURL(IScriptModule engine, SceneObjectPart host, UUID itemID);
|
||||
void ReleaseURL(string url);
|
||||
void HttpResponse(UUID request, int status, string body);
|
||||
void HttpContentType(UUID request, string type);
|
||||
|
||||
string GetHttpHeader(UUID request, string header);
|
||||
int GetFreeUrls();
|
||||
|
||||
|
||||
@@ -213,9 +213,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </remarks>
|
||||
public event NewScript OnNewScript;
|
||||
|
||||
public delegate void ExtraSettingChangedDelegate(Scene scene, string name, string value);
|
||||
public event ExtraSettingChangedDelegate OnExtraSettingChanged;
|
||||
|
||||
public virtual void TriggerNewScript(UUID clientID, SceneObjectPart part, UUID itemID)
|
||||
{
|
||||
NewScript handlerNewScript = OnNewScript;
|
||||
@@ -2594,25 +2591,5 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
public void TriggerExtraSettingChanged(Scene scene, string name, string val)
|
||||
{
|
||||
ExtraSettingChangedDelegate handler = OnExtraSettingChanged;
|
||||
|
||||
if (handler != null)
|
||||
{
|
||||
foreach (ExtraSettingChangedDelegate d in handler.GetInvocationList())
|
||||
{
|
||||
try
|
||||
{
|
||||
d(scene, name, val);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[EVENT MANAGER]: Delegate for ExtraSettingChanged failed - continuing {0} - {1}",
|
||||
e.Message, e.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1943,9 +1943,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
deleteIDs.Add(localID);
|
||||
deleteGroups.Add(grp);
|
||||
|
||||
// If child prims have invalid perms, fix them
|
||||
grp.AdjustChildPrimPermissions();
|
||||
|
||||
if (remoteClient == null)
|
||||
{
|
||||
// Autoreturn has a null client. Nothing else does. So
|
||||
|
||||
@@ -103,26 +103,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </summary>
|
||||
public bool CollidablePrims { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Minimum value of the size of a non-physical prim in each axis
|
||||
/// </summary>
|
||||
public float m_minNonphys = 0.01f;
|
||||
|
||||
/// <summary>
|
||||
/// Maximum value of the size of a non-physical prim in each axis
|
||||
/// </summary>
|
||||
public float m_maxNonphys = 256;
|
||||
|
||||
/// <summary>
|
||||
/// Minimum value of the size of a physical prim in each axis
|
||||
/// </summary>
|
||||
public float m_minPhys = 0.01f;
|
||||
|
||||
/// <summary>
|
||||
/// Maximum value of the size of a physical prim in each axis
|
||||
/// </summary>
|
||||
public float m_maxPhys = 10;
|
||||
|
||||
public bool m_clampPrimSize;
|
||||
public bool m_trustBinaries;
|
||||
public bool m_allowScriptCrossings;
|
||||
@@ -192,8 +174,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
protected ICapabilitiesModule m_capsModule;
|
||||
protected IGroupsModule m_groupsModule;
|
||||
|
||||
private Dictionary<string, string> m_extraSettings;
|
||||
|
||||
/// <summary>
|
||||
/// Current scene frame number
|
||||
/// </summary>
|
||||
@@ -655,8 +635,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// FIXME: It shouldn't be up to the database plugins to create this data - we should do it when a new
|
||||
// region is set up and avoid these gyrations.
|
||||
RegionSettings rs = simDataService.LoadRegionSettings(RegionInfo.RegionID);
|
||||
m_extraSettings = simDataService.GetExtra(RegionInfo.RegionID);
|
||||
|
||||
bool updatedTerrainTextures = false;
|
||||
if (rs.TerrainTexture1 == UUID.Zero)
|
||||
{
|
||||
@@ -739,25 +717,14 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
PhysicalPrims = startupConfig.GetBoolean("physical_prim", PhysicalPrims);
|
||||
CollidablePrims = startupConfig.GetBoolean("collidable_prim", CollidablePrims);
|
||||
|
||||
m_minNonphys = startupConfig.GetFloat("NonphysicalPrimMin", m_minNonphys);
|
||||
if (RegionInfo.NonphysPrimMin > 0)
|
||||
{
|
||||
m_minNonphys = RegionInfo.NonphysPrimMin;
|
||||
}
|
||||
|
||||
m_maxNonphys = startupConfig.GetFloat("NonphysicalPrimMax", m_maxNonphys);
|
||||
if (RegionInfo.NonphysPrimMax > 0)
|
||||
{
|
||||
m_maxNonphys = RegionInfo.NonphysPrimMax;
|
||||
}
|
||||
|
||||
m_minPhys = startupConfig.GetFloat("PhysicalPrimMin", m_minPhys);
|
||||
if (RegionInfo.PhysPrimMin > 0)
|
||||
{
|
||||
m_minPhys = RegionInfo.PhysPrimMin;
|
||||
}
|
||||
|
||||
m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys);
|
||||
|
||||
if (RegionInfo.PhysPrimMax > 0)
|
||||
{
|
||||
m_maxPhys = RegionInfo.PhysPrimMax;
|
||||
@@ -2661,7 +2628,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
|
||||
|
||||
if (AttachmentsModule != null)
|
||||
AttachmentsModule.AttachObject(sp, grp, 0, false, false);
|
||||
AttachmentsModule.AttachObject(sp, grp, 0, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -5479,44 +5446,5 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
callback(asset);
|
||||
}
|
||||
|
||||
public string GetExtraSetting(string name)
|
||||
{
|
||||
string val;
|
||||
|
||||
if (!m_extraSettings.TryGetValue(name, out val))
|
||||
return String.Empty;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
public void StoreExtraSetting(string name, string val)
|
||||
{
|
||||
string oldVal;
|
||||
|
||||
if (m_extraSettings.TryGetValue(name, out oldVal))
|
||||
{
|
||||
if (oldVal == val)
|
||||
return;
|
||||
}
|
||||
|
||||
m_extraSettings[name] = val;
|
||||
|
||||
m_SimulationDataService.SaveExtra(RegionInfo.RegionID, name, val);
|
||||
|
||||
m_eventManager.TriggerExtraSettingChanged(this, name, val);
|
||||
}
|
||||
|
||||
public void RemoveExtraSetting(string name)
|
||||
{
|
||||
if (!m_extraSettings.ContainsKey(name))
|
||||
return;
|
||||
|
||||
m_extraSettings.Remove(name);
|
||||
|
||||
m_SimulationDataService.RemoveExtra(RegionInfo.RegionID, name);
|
||||
|
||||
m_eventManager.TriggerExtraSettingChanged(this, name, String.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -375,9 +375,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
Vector3 scale = part.Shape.Scale;
|
||||
|
||||
scale.X = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.X));
|
||||
scale.Y = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Y));
|
||||
scale.Z = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Z));
|
||||
if (scale.X > m_parentScene.m_maxNonphys)
|
||||
scale.X = m_parentScene.m_maxNonphys;
|
||||
if (scale.Y > m_parentScene.m_maxNonphys)
|
||||
scale.Y = m_parentScene.m_maxNonphys;
|
||||
if (scale.Z > m_parentScene.m_maxNonphys)
|
||||
scale.Z = m_parentScene.m_maxNonphys;
|
||||
|
||||
part.Shape.Scale = scale;
|
||||
}
|
||||
|
||||
@@ -2131,9 +2131,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// Can't do this yet since backup still makes use of the root part without any synchronization
|
||||
// objectGroup.m_rootPart = null;
|
||||
|
||||
// If linking prims with different permissions, fix them
|
||||
AdjustChildPrimPermissions();
|
||||
|
||||
AttachToBackup();
|
||||
|
||||
// Here's the deal, this is ABSOLUTELY CRITICAL so the physics scene gets the update about the
|
||||
@@ -2625,21 +2622,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
public void AdjustChildPrimPermissions()
|
||||
{
|
||||
ForEachPart(part =>
|
||||
{
|
||||
if (part != RootPart)
|
||||
part.ClonePermissions(RootPart);
|
||||
});
|
||||
}
|
||||
|
||||
public void UpdatePermissions(UUID AgentID, byte field, uint localID,
|
||||
uint mask, byte addRemTF)
|
||||
{
|
||||
RootPart.UpdatePermissions(AgentID, field, localID, mask, addRemTF);
|
||||
|
||||
AdjustChildPrimPermissions();
|
||||
SceneObjectPart[] parts = m_parts.GetArray();
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
parts[i].UpdatePermissions(AgentID, field, localID, mask, addRemTF);
|
||||
|
||||
HasGroupChanged = true;
|
||||
|
||||
@@ -2686,17 +2674,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
RootPart.StoreUndoState(true);
|
||||
|
||||
scale.X = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.X));
|
||||
scale.Y = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Y));
|
||||
scale.Z = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Z));
|
||||
scale.X = Math.Min(scale.X, Scene.m_maxNonphys);
|
||||
scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys);
|
||||
scale.Z = Math.Min(scale.Z, Scene.m_maxNonphys);
|
||||
|
||||
PhysicsActor pa = m_rootPart.PhysActor;
|
||||
|
||||
if (pa != null && pa.IsPhysical)
|
||||
{
|
||||
scale.X = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.X));
|
||||
scale.Y = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Y));
|
||||
scale.Z = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Z));
|
||||
scale.X = Math.Min(scale.X, Scene.m_maxPhys);
|
||||
scale.Y = Math.Min(scale.Y, Scene.m_maxPhys);
|
||||
scale.Z = Math.Min(scale.Z, Scene.m_maxPhys);
|
||||
}
|
||||
|
||||
float x = (scale.X / RootPart.Scale.X);
|
||||
@@ -2728,14 +2716,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
y *= a;
|
||||
z *= a;
|
||||
}
|
||||
else if (oldSize.X * x < m_scene.m_minPhys)
|
||||
{
|
||||
f = m_scene.m_minPhys / oldSize.X;
|
||||
a = f / x;
|
||||
x *= a;
|
||||
y *= a;
|
||||
z *= a;
|
||||
}
|
||||
|
||||
if (oldSize.Y * y > m_scene.m_maxPhys)
|
||||
{
|
||||
@@ -2745,14 +2725,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
y *= a;
|
||||
z *= a;
|
||||
}
|
||||
else if (oldSize.Y * y < m_scene.m_minPhys)
|
||||
{
|
||||
f = m_scene.m_minPhys / oldSize.Y;
|
||||
a = f / y;
|
||||
x *= a;
|
||||
y *= a;
|
||||
z *= a;
|
||||
}
|
||||
|
||||
if (oldSize.Z * z > m_scene.m_maxPhys)
|
||||
{
|
||||
@@ -2762,14 +2734,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
y *= a;
|
||||
z *= a;
|
||||
}
|
||||
else if (oldSize.Z * z < m_scene.m_minPhys)
|
||||
{
|
||||
f = m_scene.m_minPhys / oldSize.Z;
|
||||
a = f / z;
|
||||
x *= a;
|
||||
y *= a;
|
||||
z *= a;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2781,14 +2745,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
y *= a;
|
||||
z *= a;
|
||||
}
|
||||
else if (oldSize.X * x < m_scene.m_minNonphys)
|
||||
{
|
||||
f = m_scene.m_minNonphys / oldSize.X;
|
||||
a = f / x;
|
||||
x *= a;
|
||||
y *= a;
|
||||
z *= a;
|
||||
}
|
||||
|
||||
if (oldSize.Y * y > m_scene.m_maxNonphys)
|
||||
{
|
||||
@@ -2798,14 +2754,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
y *= a;
|
||||
z *= a;
|
||||
}
|
||||
else if (oldSize.Y * y < m_scene.m_minNonphys)
|
||||
{
|
||||
f = m_scene.m_minNonphys / oldSize.Y;
|
||||
a = f / y;
|
||||
x *= a;
|
||||
y *= a;
|
||||
z *= a;
|
||||
}
|
||||
|
||||
if (oldSize.Z * z > m_scene.m_maxNonphys)
|
||||
{
|
||||
@@ -2815,14 +2763,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
y *= a;
|
||||
z *= a;
|
||||
}
|
||||
else if (oldSize.Z * z < m_scene.m_minNonphys)
|
||||
{
|
||||
f = m_scene.m_minNonphys / oldSize.Z;
|
||||
a = f / z;
|
||||
x *= a;
|
||||
y *= a;
|
||||
z *= a;
|
||||
}
|
||||
}
|
||||
|
||||
// obPart.IgnoreUndoUpdate = false;
|
||||
|
||||
@@ -2368,16 +2368,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <param name="scale"></param>
|
||||
public void Resize(Vector3 scale)
|
||||
{
|
||||
scale.X = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.X));
|
||||
scale.Y = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Y));
|
||||
scale.Z = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Z));
|
||||
scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxNonphys);
|
||||
scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxNonphys);
|
||||
scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxNonphys);
|
||||
|
||||
PhysicsActor pa = PhysActor;
|
||||
|
||||
if (pa != null && pa.IsPhysical)
|
||||
{
|
||||
scale.X = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.X));
|
||||
scale.Y = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Y));
|
||||
scale.Z = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Z));
|
||||
scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxPhys);
|
||||
scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxPhys);
|
||||
scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxPhys);
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale);
|
||||
@@ -2851,32 +2852,23 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the color & alpha of prim faces
|
||||
/// Set the color of prim faces
|
||||
/// </summary>
|
||||
/// <param name="face"></param>
|
||||
/// <param name="color"></param>
|
||||
/// <param name="alpha"></param>
|
||||
public void SetFaceColorAlpha(int face, Vector3 color, double ?alpha)
|
||||
/// <param name="face"></param>
|
||||
public void SetFaceColor(Vector3 color, int face)
|
||||
{
|
||||
Vector3 clippedColor = Util.Clip(color, 0.0f, 1.0f);
|
||||
float clippedAlpha = alpha.HasValue ?
|
||||
Util.Clip((float)alpha.Value, 0.0f, 1.0f) : 0;
|
||||
|
||||
// The only way to get a deep copy/ If we don't do this, we can
|
||||
// never detect color changes further down.
|
||||
// mever detect color changes further down.
|
||||
Byte[] buf = Shape.Textures.GetBytes();
|
||||
Primitive.TextureEntry tex = new Primitive.TextureEntry(buf, 0, buf.Length);
|
||||
Color4 texcolor;
|
||||
if (face >= 0 && face < GetNumberOfSides())
|
||||
{
|
||||
texcolor = tex.CreateFace((uint)face).RGBA;
|
||||
texcolor.R = clippedColor.X;
|
||||
texcolor.G = clippedColor.Y;
|
||||
texcolor.B = clippedColor.Z;
|
||||
if (alpha.HasValue)
|
||||
{
|
||||
texcolor.A = clippedAlpha;
|
||||
}
|
||||
texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f);
|
||||
texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f);
|
||||
texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f);
|
||||
tex.FaceTextures[face].RGBA = texcolor;
|
||||
UpdateTextureEntry(tex.GetBytes());
|
||||
return;
|
||||
@@ -2888,23 +2880,15 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
if (tex.FaceTextures[i] != null)
|
||||
{
|
||||
texcolor = tex.FaceTextures[i].RGBA;
|
||||
texcolor.R = clippedColor.X;
|
||||
texcolor.G = clippedColor.Y;
|
||||
texcolor.B = clippedColor.Z;
|
||||
if (alpha.HasValue)
|
||||
{
|
||||
texcolor.A = clippedAlpha;
|
||||
}
|
||||
texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f);
|
||||
texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f);
|
||||
texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f);
|
||||
tex.FaceTextures[i].RGBA = texcolor;
|
||||
}
|
||||
texcolor = tex.DefaultTexture.RGBA;
|
||||
texcolor.R = clippedColor.X;
|
||||
texcolor.G = clippedColor.Y;
|
||||
texcolor.B = clippedColor.Z;
|
||||
if (alpha.HasValue)
|
||||
{
|
||||
texcolor.A = clippedAlpha;
|
||||
}
|
||||
texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f);
|
||||
texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f);
|
||||
texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f);
|
||||
tex.DefaultTexture.RGBA = texcolor;
|
||||
}
|
||||
UpdateTextureEntry(tex.GetBytes());
|
||||
@@ -3890,27 +3874,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
public void ClonePermissions(SceneObjectPart source)
|
||||
{
|
||||
bool update = false;
|
||||
|
||||
if (BaseMask != source.BaseMask ||
|
||||
OwnerMask != source.OwnerMask ||
|
||||
GroupMask != source.GroupMask ||
|
||||
EveryoneMask != source.EveryoneMask ||
|
||||
NextOwnerMask != source.NextOwnerMask)
|
||||
update = true;
|
||||
|
||||
BaseMask = source.BaseMask;
|
||||
OwnerMask = source.OwnerMask;
|
||||
GroupMask = source.GroupMask;
|
||||
EveryoneMask = source.EveryoneMask;
|
||||
NextOwnerMask = source.NextOwnerMask;
|
||||
|
||||
if (update)
|
||||
SendFullUpdateToAllClients();
|
||||
}
|
||||
|
||||
public bool IsHingeJoint()
|
||||
{
|
||||
// For now, we use the NINJA naming scheme for identifying joints.
|
||||
@@ -4274,57 +4237,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
ScheduleFullUpdate();
|
||||
}
|
||||
|
||||
public void UpdateSlice(float begin, float end)
|
||||
{
|
||||
if (end < begin)
|
||||
{
|
||||
float temp = begin;
|
||||
begin = end;
|
||||
end = temp;
|
||||
}
|
||||
end = Math.Min(1f, Math.Max(0f, end));
|
||||
begin = Math.Min(Math.Min(1f, Math.Max(0f, begin)), end - 0.02f);
|
||||
if (begin < 0.02f && end < 0.02f)
|
||||
{
|
||||
begin = 0f;
|
||||
end = 0.02f;
|
||||
}
|
||||
|
||||
ushort uBegin = (ushort)(50000.0 * begin);
|
||||
ushort uEnd = (ushort)(50000.0 * (1f - end));
|
||||
bool updatePossiblyNeeded = false;
|
||||
PrimType primType = GetPrimType();
|
||||
if (primType == PrimType.SPHERE || primType == PrimType.TORUS || primType == PrimType.TUBE || primType == PrimType.RING)
|
||||
{
|
||||
if (m_shape.ProfileBegin != uBegin || m_shape.ProfileEnd != uEnd)
|
||||
{
|
||||
m_shape.ProfileBegin = uBegin;
|
||||
m_shape.ProfileEnd = uEnd;
|
||||
updatePossiblyNeeded = true;
|
||||
}
|
||||
}
|
||||
else if (m_shape.PathBegin != uBegin || m_shape.PathEnd != uEnd)
|
||||
{
|
||||
m_shape.PathBegin = uBegin;
|
||||
m_shape.PathEnd = uEnd;
|
||||
updatePossiblyNeeded = true;
|
||||
}
|
||||
|
||||
if (updatePossiblyNeeded && ParentGroup != null)
|
||||
{
|
||||
ParentGroup.HasGroupChanged = true;
|
||||
}
|
||||
if (updatePossiblyNeeded && PhysActor != null)
|
||||
{
|
||||
PhysActor.Shape = m_shape;
|
||||
ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
|
||||
}
|
||||
if (updatePossiblyNeeded)
|
||||
{
|
||||
ScheduleFullUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the part is a sculpt/mesh, retrieve the mesh data and reinsert it into the shape so that the physics
|
||||
/// engine can use it.
|
||||
|
||||
@@ -1387,22 +1387,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
bool DCFlagKeyPressed = false;
|
||||
Vector3 agent_control_v3 = Vector3.Zero;
|
||||
|
||||
bool newFlying = actor.Flying;
|
||||
bool oldflying = Flying;
|
||||
|
||||
if (ForceFly)
|
||||
newFlying = true;
|
||||
actor.Flying = true;
|
||||
else if (FlyDisabled)
|
||||
newFlying = false;
|
||||
actor.Flying = false;
|
||||
else
|
||||
newFlying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
|
||||
actor.Flying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
|
||||
|
||||
if (actor.Flying != newFlying)
|
||||
{
|
||||
// Note: ScenePresence.Flying is actually fetched from the physical actor
|
||||
// so setting PhysActor.Flying here also sets the ScenePresence's value.
|
||||
actor.Flying = newFlying;
|
||||
if (actor.Flying != oldflying)
|
||||
update_movementflag = true;
|
||||
}
|
||||
|
||||
if (ParentID == 0)
|
||||
{
|
||||
@@ -3418,16 +3413,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
public List<SceneObjectGroup> GetAttachments(uint attachmentPoint)
|
||||
{
|
||||
List<SceneObjectGroup> attachments = new List<SceneObjectGroup>();
|
||||
|
||||
if (attachmentPoint >= 0)
|
||||
|
||||
lock (m_attachments)
|
||||
{
|
||||
lock (m_attachments)
|
||||
foreach (SceneObjectGroup so in m_attachments)
|
||||
{
|
||||
foreach (SceneObjectGroup so in m_attachments)
|
||||
{
|
||||
if (attachmentPoint == so.AttachmentPoint)
|
||||
attachments.Add(so);
|
||||
}
|
||||
if (attachmentPoint == so.AttachmentPoint)
|
||||
attachments.Add(so);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,189 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using log4net;
|
||||
using Mono.Addins;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Console;
|
||||
using OpenSim.Framework.Monitoring;
|
||||
using OpenSim.Region.ClientStack.LindenUDP;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
|
||||
namespace OpenSim.Region.OptionalModules.Avatar.Attachments
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "TempAttachmentsModule")]
|
||||
public class TempAttachmentsModule : INonSharedRegionModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Scene m_scene;
|
||||
private IRegionConsole m_console;
|
||||
|
||||
public void Initialise(IConfigSource configSource)
|
||||
{
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
m_scene = scene;
|
||||
|
||||
IScriptModuleComms comms = scene.RequestModuleInterface<IScriptModuleComms>();
|
||||
if (comms != null)
|
||||
{
|
||||
comms.RegisterScriptInvocation( this, "llAttachToAvatarTemp");
|
||||
m_log.DebugFormat("[TEMP ATTACHS]: Registered script functions");
|
||||
m_console = scene.RequestModuleInterface<IRegionConsole>();
|
||||
|
||||
if (m_console != null)
|
||||
{
|
||||
m_console.AddCommand("TempATtachModule", false, "set auto_grant_attach_perms", "set auto_grant_attach_perms true|false", "Allow objects owned by the region owner os estate managers to obtain attach permissions without asking the user", SetAutoGrantAttachPerms);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.ErrorFormat("[TEMP ATTACHS]: Failed to register script functions");
|
||||
}
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "TempAttachmentsModule"; }
|
||||
}
|
||||
|
||||
private void SendConsoleOutput(UUID agentID, string text)
|
||||
{
|
||||
if (m_console == null)
|
||||
return;
|
||||
|
||||
m_console.SendConsoleOutput(agentID, text);
|
||||
}
|
||||
|
||||
private void SetAutoGrantAttachPerms(string module, string[] parms)
|
||||
{
|
||||
UUID agentID = new UUID(parms[parms.Length - 1]);
|
||||
Array.Resize(ref parms, parms.Length - 1);
|
||||
|
||||
if (parms.Length != 3)
|
||||
{
|
||||
SendConsoleOutput(agentID, "Command parameter error");
|
||||
return;
|
||||
}
|
||||
|
||||
string val = parms[2];
|
||||
if (val != "true" && val != "false")
|
||||
{
|
||||
SendConsoleOutput(agentID, "Command parameter error");
|
||||
return;
|
||||
}
|
||||
|
||||
m_scene.StoreExtraSetting("auto_grant_attach_perms", val);
|
||||
|
||||
SendConsoleOutput(agentID, String.Format("auto_grant_attach_perms set to {0}", val));
|
||||
}
|
||||
|
||||
private void llAttachToAvatarTemp(UUID host, UUID script, int attachmentPoint)
|
||||
{
|
||||
SceneObjectPart hostPart = m_scene.GetSceneObjectPart(host);
|
||||
|
||||
if (hostPart == null)
|
||||
return;
|
||||
|
||||
if (hostPart.ParentGroup.IsAttachment)
|
||||
return;
|
||||
|
||||
IAttachmentsModule attachmentsModule = m_scene.RequestModuleInterface<IAttachmentsModule>();
|
||||
if (attachmentsModule == null)
|
||||
return;
|
||||
|
||||
TaskInventoryItem item = hostPart.Inventory.GetInventoryItem(script);
|
||||
if (item == null)
|
||||
return;
|
||||
|
||||
if ((item.PermsMask & 32) == 0) // PERMISSION_ATTACH
|
||||
return;
|
||||
|
||||
ScenePresence target;
|
||||
if (!m_scene.TryGetScenePresence(item.PermsGranter, out target))
|
||||
return;
|
||||
|
||||
if (target.UUID != hostPart.ParentGroup.OwnerID)
|
||||
{
|
||||
uint effectivePerms = hostPart.ParentGroup.GetEffectivePermissions();
|
||||
|
||||
if ((effectivePerms & (uint)PermissionMask.Transfer) == 0)
|
||||
return;
|
||||
|
||||
hostPart.ParentGroup.SetOwnerId(target.UUID);
|
||||
hostPart.ParentGroup.SetRootPartOwner(hostPart.ParentGroup.RootPart, target.UUID, target.ControllingClient.ActiveGroupId);
|
||||
|
||||
if (m_scene.Permissions.PropagatePermissions())
|
||||
{
|
||||
foreach (SceneObjectPart child in hostPart.ParentGroup.Parts)
|
||||
{
|
||||
child.Inventory.ChangeInventoryOwner(target.UUID);
|
||||
child.TriggerScriptChangedEvent(Changed.OWNER);
|
||||
child.ApplyNextOwnerPermissions();
|
||||
}
|
||||
}
|
||||
|
||||
hostPart.ParentGroup.RootPart.ObjectSaleType = 0;
|
||||
hostPart.ParentGroup.RootPart.SalePrice = 10;
|
||||
|
||||
hostPart.ParentGroup.HasGroupChanged = true;
|
||||
hostPart.ParentGroup.RootPart.SendPropertiesToClient(target.ControllingClient);
|
||||
hostPart.ParentGroup.RootPart.ScheduleFullUpdate();
|
||||
}
|
||||
|
||||
attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -130,25 +130,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms
|
||||
m_scriptModule.PostScriptEvent(script, "link_message", args);
|
||||
}
|
||||
|
||||
private static MethodInfo GetMethodInfoFromType(Type target, string meth, bool searchInstanceMethods)
|
||||
{
|
||||
BindingFlags getMethodFlags =
|
||||
BindingFlags.NonPublic | BindingFlags.Public;
|
||||
|
||||
if (searchInstanceMethods)
|
||||
getMethodFlags |= BindingFlags.Instance;
|
||||
else
|
||||
getMethodFlags |= BindingFlags.Static;
|
||||
|
||||
return target.GetMethod(meth, getMethodFlags);
|
||||
}
|
||||
|
||||
public void RegisterScriptInvocation(object target, string meth)
|
||||
{
|
||||
MethodInfo mi = GetMethodInfoFromType(target.GetType(), meth, true);
|
||||
MethodInfo mi = target.GetType().GetMethod(meth,
|
||||
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
|
||||
if (mi == null)
|
||||
{
|
||||
m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}", meth);
|
||||
m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}",meth);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -163,54 +151,38 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms
|
||||
|
||||
public void RegisterScriptInvocation(object target, MethodInfo mi)
|
||||
{
|
||||
m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, (target is Type) ? ((Type)target).Name : target.GetType().Name);
|
||||
m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, target.GetType().Name);
|
||||
|
||||
Type delegateType;
|
||||
List<Type> typeArgs = mi.GetParameters()
|
||||
var typeArgs = mi.GetParameters()
|
||||
.Select(p => p.ParameterType)
|
||||
.ToList();
|
||||
|
||||
if (mi.ReturnType == typeof(void))
|
||||
{
|
||||
delegateType = Expression.GetActionType(typeArgs.ToArray());
|
||||
delegateType = Expression.GetActionType(typeArgs.ToArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
typeArgs.Add(mi.ReturnType);
|
||||
delegateType = Expression.GetFuncType(typeArgs.ToArray());
|
||||
typeArgs.Add(mi.ReturnType);
|
||||
delegateType = Expression.GetFuncType(typeArgs.ToArray());
|
||||
}
|
||||
|
||||
Delegate fcall;
|
||||
if (!(target is Type))
|
||||
fcall = Delegate.CreateDelegate(delegateType, target, mi);
|
||||
else
|
||||
fcall = Delegate.CreateDelegate(delegateType, (Type)target, mi.Name);
|
||||
Delegate fcall = Delegate.CreateDelegate(delegateType, target, mi);
|
||||
|
||||
lock (m_scriptInvocation)
|
||||
{
|
||||
ParameterInfo[] parameters = fcall.Method.GetParameters();
|
||||
ParameterInfo[] parameters = fcall.Method.GetParameters ();
|
||||
if (parameters.Length < 2) // Must have two UUID params
|
||||
return;
|
||||
|
||||
// Hide the first two parameters
|
||||
Type[] parmTypes = new Type[parameters.Length - 2];
|
||||
for (int i = 2; i < parameters.Length; i++)
|
||||
for (int i = 2 ; i < parameters.Length ; i++)
|
||||
parmTypes[i - 2] = parameters[i].ParameterType;
|
||||
m_scriptInvocation[fcall.Method.Name] = new ScriptInvocationData(fcall.Method.Name, fcall, parmTypes, fcall.Method.ReturnType);
|
||||
}
|
||||
}
|
||||
|
||||
public void RegisterScriptInvocation(Type target, string[] methods)
|
||||
{
|
||||
foreach (string method in methods)
|
||||
{
|
||||
MethodInfo mi = GetMethodInfoFromType(target, method, false);
|
||||
if (mi == null)
|
||||
m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}", method);
|
||||
else
|
||||
RegisterScriptInvocation(target, mi);
|
||||
}
|
||||
}
|
||||
|
||||
public Delegate[] GetScriptInvocationList()
|
||||
{
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyrightD
|
||||
* 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.Text;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
|
||||
public class BS6DofConstraint : BSConstraint
|
||||
{
|
||||
// Create a btGeneric6DofConstraint
|
||||
public BS6DofConstraint(BulletSim world, BulletBody obj1, BulletBody obj2,
|
||||
Vector3 frame1, Quaternion frame1rot,
|
||||
Vector3 frame2, Quaternion frame2rot,
|
||||
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)
|
||||
{
|
||||
m_world = world;
|
||||
m_body1 = obj1;
|
||||
m_body2 = obj2;
|
||||
m_constraint = new BulletConstraint(
|
||||
BulletSimAPI.Create6DofConstraint2(m_world.Ptr, m_body1.Ptr, m_body2.Ptr,
|
||||
frame1, frame1rot,
|
||||
frame2, frame2rot,
|
||||
useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies));
|
||||
m_enabled = true;
|
||||
}
|
||||
|
||||
public BS6DofConstraint(BulletSim world, BulletBody obj1, BulletBody obj2,
|
||||
Vector3 joinPoint,
|
||||
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)
|
||||
{
|
||||
m_world = world;
|
||||
m_body1 = obj1;
|
||||
m_body2 = obj2;
|
||||
m_constraint = new BulletConstraint(
|
||||
BulletSimAPI.Create6DofConstraintToPoint2(m_world.Ptr, m_body1.Ptr, m_body2.Ptr,
|
||||
joinPoint,
|
||||
useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies));
|
||||
m_enabled = true;
|
||||
}
|
||||
|
||||
public bool SetFrames(Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot)
|
||||
{
|
||||
bool ret = false;
|
||||
if (m_enabled)
|
||||
{
|
||||
BulletSimAPI.SetFrames2(m_constraint.Ptr, frameA, frameArot, frameB, frameBrot);
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public bool SetCFMAndERP(float cfm, float erp)
|
||||
{
|
||||
bool ret = false;
|
||||
if (m_enabled)
|
||||
{
|
||||
BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL);
|
||||
BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_STOP_ERP, erp, ConstraintParamAxis.AXIS_ALL);
|
||||
BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_CFM, cfm, ConstraintParamAxis.AXIS_ALL);
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public bool UseFrameOffset(bool useOffset)
|
||||
{
|
||||
bool ret = false;
|
||||
float onOff = useOffset ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse;
|
||||
if (m_enabled)
|
||||
ret = BulletSimAPI.UseFrameOffset2(m_constraint.Ptr, onOff);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public bool TranslationalLimitMotor(bool enable, float targetVelocity, float maxMotorForce)
|
||||
{
|
||||
bool ret = false;
|
||||
float onOff = enable ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse;
|
||||
if (m_enabled)
|
||||
ret = BulletSimAPI.TranslationalLimitMotor2(m_constraint.Ptr, onOff, targetVelocity, maxMotorForce);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public bool SetBreakingImpulseThreshold(float threshold)
|
||||
{
|
||||
bool ret = false;
|
||||
if (m_enabled)
|
||||
ret = BulletSimAPI.SetBreakingImpulseThreshold2(m_constraint.Ptr, threshold);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,12 +34,13 @@ using OpenSim.Region.Physics.Manager;
|
||||
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
public class BSCharacter : BSPhysObject
|
||||
public class BSCharacter : PhysicsActor
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static readonly string LogHeader = "[BULLETS CHAR]";
|
||||
|
||||
public BSScene Scene { get; private set; }
|
||||
private BSScene _scene;
|
||||
public BSScene Scene { get { return _scene; } }
|
||||
private String _avName;
|
||||
// private bool _stopped;
|
||||
private Vector3 _size;
|
||||
@@ -73,8 +74,11 @@ public class BSCharacter : BSPhysObject
|
||||
private bool _kinematic;
|
||||
private float _buoyancy;
|
||||
|
||||
public override BulletBody Body { get; set; }
|
||||
public override BSLinkset Linkset { get; set; }
|
||||
private BulletBody m_body;
|
||||
public BulletBody Body {
|
||||
get { return m_body; }
|
||||
set { m_body = value; }
|
||||
}
|
||||
|
||||
private int _subscribedEventsMs = 0;
|
||||
private int _nextCollisionOkTime = 0;
|
||||
@@ -91,21 +95,17 @@ public class BSCharacter : BSPhysObject
|
||||
{
|
||||
_localID = localID;
|
||||
_avName = avName;
|
||||
Scene = parent_scene;
|
||||
_scene = parent_scene;
|
||||
_position = pos;
|
||||
_size = size;
|
||||
_flying = isFlying;
|
||||
_orientation = Quaternion.Identity;
|
||||
_velocity = Vector3.Zero;
|
||||
_buoyancy = ComputeBuoyancyFromFlying(isFlying);
|
||||
// The dimensions of the avatar capsule are kept in the scale.
|
||||
// Physics creates a unit capsule which is scaled by the physics engine.
|
||||
_scale = new Vector3(Scene.Params.avatarCapsuleRadius, Scene.Params.avatarCapsuleRadius, size.Z);
|
||||
_density = Scene.Params.avatarDensity;
|
||||
_scale = new Vector3(1f, 1f, 1f);
|
||||
_density = _scene.Params.avatarDensity;
|
||||
ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale
|
||||
|
||||
Linkset = new BSLinkset(Scene, this);
|
||||
|
||||
ShapeData shapeData = new ShapeData();
|
||||
shapeData.ID = _localID;
|
||||
shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR;
|
||||
@@ -116,20 +116,16 @@ public class BSCharacter : BSPhysObject
|
||||
shapeData.Mass = _mass;
|
||||
shapeData.Buoyancy = _buoyancy;
|
||||
shapeData.Static = ShapeData.numericFalse;
|
||||
shapeData.Friction = Scene.Params.avatarFriction;
|
||||
shapeData.Restitution = Scene.Params.avatarRestitution;
|
||||
shapeData.Friction = _scene.Params.avatarFriction;
|
||||
shapeData.Restitution = _scene.Params.avatarRestitution;
|
||||
|
||||
// do actual create at taint time
|
||||
Scene.TaintedObject("BSCharacter.create", delegate()
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
DetailLog("{0},BSCharacter.create", _localID);
|
||||
BulletSimAPI.CreateObject(Scene.WorldID, shapeData);
|
||||
BulletSimAPI.CreateObject(parent_scene.WorldID, shapeData);
|
||||
|
||||
// Set the buoyancy for flying. This will be refactored when all the settings happen in C#
|
||||
BulletSimAPI.SetObjectBuoyancy(Scene.WorldID, LocalID, _buoyancy);
|
||||
|
||||
Body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(Scene.World.Ptr, LocalID));
|
||||
// avatars get all collisions no matter what (makes walking on ground and such work)
|
||||
m_body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
|
||||
// avatars get all collisions no matter what
|
||||
BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||
});
|
||||
|
||||
@@ -137,12 +133,12 @@ public class BSCharacter : BSPhysObject
|
||||
}
|
||||
|
||||
// called when this character is being destroyed and the resources should be released
|
||||
public override void Destroy()
|
||||
public void Destroy()
|
||||
{
|
||||
DetailLog("{0},BSCharacter.Destroy", LocalID);
|
||||
Scene.TaintedObject("BSCharacter.destroy", delegate()
|
||||
// DetailLog("{0},Destroy", LocalID);
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
BulletSimAPI.DestroyObject(Scene.WorldID, _localID);
|
||||
BulletSimAPI.DestroyObject(_scene.WorldID, _localID);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -154,28 +150,9 @@ public class BSCharacter : BSPhysObject
|
||||
public override bool Stopped {
|
||||
get { return false; }
|
||||
}
|
||||
public override Vector3 Size {
|
||||
get
|
||||
{
|
||||
// Avatar capsule size is kept in the scale parameter.
|
||||
return new Vector3(_scale.X * 2, _scale.Y * 2, _scale.Z);
|
||||
}
|
||||
|
||||
set {
|
||||
// When an avatar's size is set, only the height is changed
|
||||
// and that really only depends on the radius.
|
||||
_size = value;
|
||||
_scale.Z = (_size.Z * 1.15f) - (_scale.X + _scale.Y);
|
||||
|
||||
// TODO: something has to be done with the avatar's vertical position
|
||||
|
||||
ComputeAvatarVolumeAndMass();
|
||||
|
||||
Scene.TaintedObject("BSCharacter.setSize", delegate()
|
||||
{
|
||||
BulletSimAPI.SetObjectScaleMass(Scene.WorldID, LocalID, _scale, _mass, true);
|
||||
});
|
||||
|
||||
public override Vector3 Size {
|
||||
get { return _size; }
|
||||
set { _size = value;
|
||||
}
|
||||
}
|
||||
public override PrimitiveBaseShape Shape {
|
||||
@@ -202,78 +179,31 @@ public class BSCharacter : BSPhysObject
|
||||
|
||||
public override Vector3 Position {
|
||||
get {
|
||||
// _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID);
|
||||
// _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
|
||||
return _position;
|
||||
}
|
||||
set {
|
||||
_position = value;
|
||||
PositionSanityCheck();
|
||||
|
||||
Scene.TaintedObject("BSCharacter.setPosition", delegate()
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||
BulletSimAPI.SetObjectTranslation(Scene.WorldID, _localID, _position, _orientation);
|
||||
DetailLog("{0},SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||
BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the current position is sane and, if not, modify the position to make it so.
|
||||
// Check for being below terrain and being out of bounds.
|
||||
// Returns 'true' of the position was made sane by some action.
|
||||
private bool PositionSanityCheck()
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
// If below the ground, move the avatar up
|
||||
float terrainHeight = Scene.TerrainManager.GetTerrainHeightAtXYZ(_position);
|
||||
if (Position.Z < terrainHeight)
|
||||
{
|
||||
DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight);
|
||||
_position.Z = terrainHeight + 2.0f;
|
||||
ret = true;
|
||||
}
|
||||
|
||||
// TODO: check for out of bounds
|
||||
return ret;
|
||||
}
|
||||
|
||||
// A version of the sanity check that also makes sure a new position value is
|
||||
// pushed back to the physics engine. This routine would be used by anyone
|
||||
// who is not already pushing the value.
|
||||
private bool PositionSanityCheck2()
|
||||
{
|
||||
bool ret = false;
|
||||
if (PositionSanityCheck())
|
||||
{
|
||||
// The new position value must be pushed into the physics engine but we can't
|
||||
// just assign to "Position" because of potential call loops.
|
||||
Scene.TaintedObject("BSCharacter.PositionSanityCheck", delegate()
|
||||
{
|
||||
DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||
BulletSimAPI.SetObjectTranslation(Scene.WorldID, _localID, _position, _orientation);
|
||||
});
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public override float Mass {
|
||||
get {
|
||||
return _mass;
|
||||
}
|
||||
}
|
||||
|
||||
// used when we only want this prim's mass and not the linkset thing
|
||||
public override float MassRaw { get {return _mass; } }
|
||||
|
||||
public override Vector3 Force {
|
||||
get { return _force; }
|
||||
set {
|
||||
_force = value;
|
||||
// m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force);
|
||||
Scene.TaintedObject("BSCharacter.SetForce", delegate()
|
||||
Scene.TaintedObject(delegate()
|
||||
{
|
||||
DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force);
|
||||
DetailLog("{0},setForce,taint,force={1}", LocalID, _force);
|
||||
BulletSimAPI.SetObjectForce(Scene.WorldID, LocalID, _force);
|
||||
});
|
||||
}
|
||||
@@ -298,10 +228,10 @@ public class BSCharacter : BSPhysObject
|
||||
set {
|
||||
_velocity = value;
|
||||
// m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity);
|
||||
Scene.TaintedObject("BSCharacter.setVelocity", delegate()
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity);
|
||||
BulletSimAPI.SetObjectVelocity(Scene.WorldID, _localID, _velocity);
|
||||
DetailLog("{0},setVelocity,taint,vel={1}", LocalID, _velocity);
|
||||
BulletSimAPI.SetObjectVelocity(_scene.WorldID, _localID, _velocity);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -324,10 +254,10 @@ public class BSCharacter : BSPhysObject
|
||||
set {
|
||||
_orientation = value;
|
||||
// m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation);
|
||||
Scene.TaintedObject("BSCharacter.setOrientation", delegate()
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
// _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID);
|
||||
BulletSimAPI.SetObjectTranslation(Scene.WorldID, _localID, _position, _orientation);
|
||||
// _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
|
||||
BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -349,8 +279,6 @@ public class BSCharacter : BSPhysObject
|
||||
this.Buoyancy = ComputeBuoyancyFromFlying(_flying);
|
||||
}
|
||||
}
|
||||
// Flying is implimented by changing the avatar's buoyancy.
|
||||
// Would this be done better with a vehicle type?
|
||||
private float ComputeBuoyancyFromFlying(bool ifFlying) {
|
||||
return ifFlying ? 1f : 0f;
|
||||
}
|
||||
@@ -364,11 +292,11 @@ public class BSCharacter : BSPhysObject
|
||||
set { _throttleUpdates = value; }
|
||||
}
|
||||
public override bool IsColliding {
|
||||
get { return (_collidingStep == Scene.SimulationStep); }
|
||||
get { return (_collidingStep == _scene.SimulationStep); }
|
||||
set { _isColliding = value; }
|
||||
}
|
||||
public override bool CollidingGround {
|
||||
get { return (_collidingGroundStep == Scene.SimulationStep); }
|
||||
get { return (_collidingGroundStep == _scene.SimulationStep); }
|
||||
set { _collidingGround = value; }
|
||||
}
|
||||
public override bool CollidingObj {
|
||||
@@ -390,10 +318,10 @@ public class BSCharacter : BSPhysObject
|
||||
public override float Buoyancy {
|
||||
get { return _buoyancy; }
|
||||
set { _buoyancy = value;
|
||||
Scene.TaintedObject("BSCharacter.setBuoyancy", delegate()
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
|
||||
BulletSimAPI.SetObjectBuoyancy(Scene.WorldID, LocalID, _buoyancy);
|
||||
DetailLog("{0},setBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
|
||||
BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -437,9 +365,9 @@ public class BSCharacter : BSPhysObject
|
||||
_force.Y += force.Y;
|
||||
_force.Z += force.Z;
|
||||
// m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force);
|
||||
Scene.TaintedObject("BSCharacter.AddForce", delegate()
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force);
|
||||
DetailLog("{0},setAddForce,taint,addedForce={1}", LocalID, _force);
|
||||
BulletSimAPI.AddObjectForce2(Body.Ptr, _force);
|
||||
});
|
||||
}
|
||||
@@ -463,23 +391,17 @@ public class BSCharacter : BSPhysObject
|
||||
// make sure first collision happens
|
||||
_nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs;
|
||||
|
||||
Scene.TaintedObject("BSCharacter.SubscribeEvents", delegate()
|
||||
Scene.TaintedObject(delegate()
|
||||
{
|
||||
BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public override void ZeroMotion()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Stop collision events
|
||||
public override void UnSubscribeEvents() {
|
||||
_subscribedEventsMs = 0;
|
||||
// Avatars get all their collision events
|
||||
// Scene.TaintedObject("BSCharacter.UnSubscribeEvents", delegate()
|
||||
// Scene.TaintedObject(delegate()
|
||||
// {
|
||||
// BulletSimAPI.RemoveFromCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||
// });
|
||||
@@ -494,57 +416,73 @@ public class BSCharacter : BSPhysObject
|
||||
{
|
||||
_avatarVolume = (float)(
|
||||
Math.PI
|
||||
* _scale.X
|
||||
* _scale.Y // the area of capsule cylinder
|
||||
* _scale.Z // times height of capsule cylinder
|
||||
+ 1.33333333f
|
||||
* Math.PI
|
||||
* _scale.X
|
||||
* Math.Min(_scale.X, _scale.Y)
|
||||
* _scale.Y // plus the volume of the capsule end caps
|
||||
);
|
||||
* _scene.Params.avatarCapsuleRadius * _scale.X
|
||||
* _scene.Params.avatarCapsuleRadius * _scale.Y
|
||||
* _scene.Params.avatarCapsuleHeight * _scale.Z);
|
||||
_mass = _density * _avatarVolume;
|
||||
}
|
||||
|
||||
// The physics engine says that properties have updated. Update same and inform
|
||||
// the world that things have changed.
|
||||
public override void UpdateProperties(EntityProperties entprop)
|
||||
public void UpdateProperties(EntityProperties entprop)
|
||||
{
|
||||
/*
|
||||
bool changed = false;
|
||||
// we assign to the local variables so the normal set action does not happen
|
||||
if (_position != entprop.Position) {
|
||||
_position = entprop.Position;
|
||||
changed = true;
|
||||
}
|
||||
if (_orientation != entprop.Rotation) {
|
||||
_orientation = entprop.Rotation;
|
||||
changed = true;
|
||||
}
|
||||
if (_velocity != entprop.Velocity) {
|
||||
_velocity = entprop.Velocity;
|
||||
changed = true;
|
||||
}
|
||||
if (_acceleration != entprop.Acceleration) {
|
||||
_acceleration = entprop.Acceleration;
|
||||
changed = true;
|
||||
}
|
||||
if (_rotationalVelocity != entprop.RotationalVelocity) {
|
||||
_rotationalVelocity = entprop.RotationalVelocity;
|
||||
changed = true;
|
||||
}
|
||||
if (changed) {
|
||||
// m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation);
|
||||
// Avatar movement is not done by generating this event. There is code in the heartbeat
|
||||
// loop that updates avatars.
|
||||
// base.RequestPhysicsterseUpdate();
|
||||
}
|
||||
*/
|
||||
_position = entprop.Position;
|
||||
_orientation = entprop.Rotation;
|
||||
_velocity = entprop.Velocity;
|
||||
_acceleration = entprop.Acceleration;
|
||||
_rotationalVelocity = entprop.RotationalVelocity;
|
||||
// Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
|
||||
// Avatars don't report theirr changes the usual way. Changes are checked for in the heartbeat loop.
|
||||
// base.RequestPhysicsterseUpdate();
|
||||
|
||||
// Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
|
||||
PositionSanityCheck2();
|
||||
|
||||
float heightHere = Scene.TerrainManager.GetTerrainHeightAtXYZ(_position); // only for debug
|
||||
DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5},terrain={6}",
|
||||
LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity, heightHere);
|
||||
}
|
||||
|
||||
// Called by the scene when a collision with this object is reported
|
||||
// The collision, if it should be reported to the character, is placed in a collection
|
||||
// that will later be sent to the simulator when SendCollisions() is called.
|
||||
CollisionEventUpdate collisionCollection = null;
|
||||
public override void Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth)
|
||||
public void Collide(uint collidingWith, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth)
|
||||
{
|
||||
// m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);
|
||||
|
||||
// The following makes IsColliding() and IsCollidingGround() work
|
||||
_collidingStep = Scene.SimulationStep;
|
||||
_collidingStep = _scene.SimulationStep;
|
||||
if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID)
|
||||
{
|
||||
_collidingGroundStep = Scene.SimulationStep;
|
||||
_collidingGroundStep = _scene.SimulationStep;
|
||||
}
|
||||
// DetailLog("{0},BSCharacter.Collison,call,with={1}", LocalID, collidingWith);
|
||||
|
||||
// throttle collisions to the rate specified in the subscription
|
||||
if (_subscribedEventsMs != 0) {
|
||||
int nowTime = Scene.SimulationNowTime;
|
||||
int nowTime = _scene.SimulationNowTime;
|
||||
if (nowTime >= _nextCollisionOkTime) {
|
||||
_nextCollisionOkTime = nowTime + _subscribedEventsMs;
|
||||
|
||||
@@ -555,7 +493,7 @@ public class BSCharacter : BSPhysObject
|
||||
}
|
||||
}
|
||||
|
||||
public override void SendCollisions()
|
||||
public void SendCollisions()
|
||||
{
|
||||
/*
|
||||
if (collisionCollection != null && collisionCollection.Count > 0)
|
||||
@@ -569,10 +507,7 @@ public class BSCharacter : BSPhysObject
|
||||
if (collisionCollection == null)
|
||||
collisionCollection = new CollisionEventUpdate();
|
||||
base.SendCollisionUpdate(collisionCollection);
|
||||
// If there were any collisions in the collection, make sure we don't use the
|
||||
// same instance next time.
|
||||
if (collisionCollection.Count > 0)
|
||||
collisionCollection = null;
|
||||
collisionCollection.Clear();
|
||||
// End kludge
|
||||
}
|
||||
|
||||
|
||||
@@ -32,33 +32,43 @@ using OpenMetaverse;
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
|
||||
public abstract class BSConstraint : IDisposable
|
||||
public class BSConstraint : IDisposable
|
||||
{
|
||||
protected BulletSim m_world;
|
||||
protected BulletBody m_body1;
|
||||
protected BulletBody m_body2;
|
||||
protected BulletConstraint m_constraint;
|
||||
protected bool m_enabled = false;
|
||||
private BulletSim m_world;
|
||||
private BulletBody m_body1;
|
||||
private BulletBody m_body2;
|
||||
private BulletConstraint m_constraint;
|
||||
private bool m_enabled = false;
|
||||
|
||||
public BSConstraint()
|
||||
public BSConstraint(BulletSim world, BulletBody obj1, BulletBody obj2,
|
||||
Vector3 frame1, Quaternion frame1rot,
|
||||
Vector3 frame2, Quaternion frame2rot
|
||||
)
|
||||
{
|
||||
m_world = world;
|
||||
m_body1 = obj1;
|
||||
m_body2 = obj2;
|
||||
m_constraint = new BulletConstraint(BulletSimAPI.CreateConstraint2(m_world.Ptr, m_body1.Ptr, m_body2.Ptr,
|
||||
frame1, frame1rot,
|
||||
frame2, frame2rot,
|
||||
true /*useLinearReferenceFrameA*/, true /*disableCollisionsBetweenLinkedBodies*/));
|
||||
m_enabled = true;
|
||||
}
|
||||
|
||||
public virtual void Dispose()
|
||||
public void Dispose()
|
||||
{
|
||||
if (m_enabled)
|
||||
{
|
||||
// BulletSimAPI.RemoveConstraint(m_world.ID, m_body1.ID, m_body2.ID);
|
||||
BulletSimAPI.DestroyConstraint2(m_world.Ptr, m_constraint.Ptr);
|
||||
m_enabled = false;
|
||||
bool success = BulletSimAPI.DestroyConstraint2(m_world.Ptr, m_constraint.Ptr);
|
||||
m_world.scene.DetailLog("{0},BSConstraint.Dispose,taint,body1={1},body2={2},success={3}", BSScene.DetailLogZero, m_body1.ID, m_body2.ID, success);
|
||||
m_constraint.Ptr = System.IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
public BulletBody Body1 { get { return m_body1; } }
|
||||
public BulletBody Body2 { get { return m_body2; } }
|
||||
|
||||
public virtual bool SetLinearLimits(Vector3 low, Vector3 high)
|
||||
public bool SetLinearLimits(Vector3 low, Vector3 high)
|
||||
{
|
||||
bool ret = false;
|
||||
if (m_enabled)
|
||||
@@ -66,7 +76,7 @@ public abstract class BSConstraint : IDisposable
|
||||
return ret;
|
||||
}
|
||||
|
||||
public virtual bool SetAngularLimits(Vector3 low, Vector3 high)
|
||||
public bool SetAngularLimits(Vector3 low, Vector3 high)
|
||||
{
|
||||
bool ret = false;
|
||||
if (m_enabled)
|
||||
@@ -74,38 +84,42 @@ public abstract class BSConstraint : IDisposable
|
||||
return ret;
|
||||
}
|
||||
|
||||
public virtual bool CalculateTransforms()
|
||||
public bool SetCFMAndERP(float cfm, float erp)
|
||||
{
|
||||
bool ret = true;
|
||||
BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL);
|
||||
BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_STOP_ERP, erp, ConstraintParamAxis.AXIS_ALL);
|
||||
BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_CFM, cfm, ConstraintParamAxis.AXIS_ALL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public bool UseFrameOffset(bool useOffset)
|
||||
{
|
||||
bool ret = false;
|
||||
float onOff = useOffset ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse;
|
||||
if (m_enabled)
|
||||
ret = BulletSimAPI.UseFrameOffset2(m_constraint.Ptr, onOff);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public bool TranslationalLimitMotor(bool enable, float targetVelocity, float maxMotorForce)
|
||||
{
|
||||
bool ret = false;
|
||||
float onOff = enable ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse;
|
||||
if (m_enabled)
|
||||
ret = BulletSimAPI.TranslationalLimitMotor2(m_constraint.Ptr, onOff, targetVelocity, maxMotorForce);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public bool CalculateTransforms()
|
||||
{
|
||||
bool ret = false;
|
||||
if (m_enabled)
|
||||
{
|
||||
// Recompute the internal transforms
|
||||
BulletSimAPI.CalculateTransforms2(m_constraint.Ptr);
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Reset this constraint making sure it has all its internal structures
|
||||
// recomputed and is enabled and ready to go.
|
||||
public virtual bool RecomputeConstraintVariables(float mass)
|
||||
{
|
||||
bool ret = false;
|
||||
if (m_enabled)
|
||||
{
|
||||
ret = CalculateTransforms();
|
||||
if (ret)
|
||||
{
|
||||
// m_world.scene.PhysicsLogging.Write("{0},BSConstraint.RecomputeConstraintVariables,taint,enabling,A={1},B={2}",
|
||||
// BSScene.DetailLogZero, Body1.ID, Body2.ID);
|
||||
BulletSimAPI.SetConstraintEnable2(m_constraint.Ptr, m_world.scene.NumericBool(true));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_world.scene.Logger.ErrorFormat("[BULLETSIM CONSTRAINT] CalculateTransforms failed. A={0}, B={1}", Body1.ID, Body2.ID);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,25 +56,29 @@ public class BSConstraintCollection : IDisposable
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
lock (m_constraints)
|
||||
foreach (BSConstraint cons in m_constraints)
|
||||
{
|
||||
foreach (BSConstraint cons in m_constraints)
|
||||
{
|
||||
cons.Dispose();
|
||||
}
|
||||
m_constraints.Clear();
|
||||
cons.Dispose();
|
||||
}
|
||||
m_constraints.Clear();
|
||||
}
|
||||
|
||||
public BSConstraint CreateConstraint(BulletSim world, BulletBody obj1, BulletBody obj2,
|
||||
Vector3 frame1, Quaternion frame1rot,
|
||||
Vector3 frame2, Quaternion frame2rot)
|
||||
{
|
||||
BSConstraint constrain = new BSConstraint(world, obj1, obj2, frame1, frame1rot, frame2, frame2rot);
|
||||
|
||||
this.AddConstraint(constrain);
|
||||
return constrain;
|
||||
}
|
||||
|
||||
public bool AddConstraint(BSConstraint cons)
|
||||
{
|
||||
lock (m_constraints)
|
||||
{
|
||||
// There is only one constraint between any bodies. Remove any old just to make sure.
|
||||
RemoveAndDestroyConstraint(cons.Body1, cons.Body2);
|
||||
// There is only one constraint between any bodies. Remove any old just to make sure.
|
||||
RemoveAndDestroyConstraint(cons.Body1, cons.Body2);
|
||||
|
||||
m_constraints.Add(cons);
|
||||
}
|
||||
m_constraints.Add(cons);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -88,19 +92,16 @@ public class BSConstraintCollection : IDisposable
|
||||
|
||||
uint lookingID1 = body1.ID;
|
||||
uint lookingID2 = body2.ID;
|
||||
lock (m_constraints)
|
||||
ForEachConstraint(delegate(BSConstraint constrain)
|
||||
{
|
||||
foreach (BSConstraint constrain in m_constraints)
|
||||
if ((constrain.Body1.ID == lookingID1 && constrain.Body2.ID == lookingID2)
|
||||
|| (constrain.Body1.ID == lookingID2 && constrain.Body2.ID == lookingID1))
|
||||
{
|
||||
if ((constrain.Body1.ID == lookingID1 && constrain.Body2.ID == lookingID2)
|
||||
|| (constrain.Body1.ID == lookingID2 && constrain.Body2.ID == lookingID1))
|
||||
{
|
||||
foundConstraint = constrain;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
foundConstraint = constrain;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
});
|
||||
returnConstraint = foundConstraint;
|
||||
return found;
|
||||
}
|
||||
@@ -110,33 +111,22 @@ public class BSConstraintCollection : IDisposable
|
||||
// Return 'true' if a constraint was found and destroyed.
|
||||
public bool RemoveAndDestroyConstraint(BulletBody body1, BulletBody body2)
|
||||
{
|
||||
// return BulletSimAPI.RemoveConstraint(m_world.ID, obj1.ID, obj2.ID);
|
||||
|
||||
bool ret = false;
|
||||
lock (m_constraints)
|
||||
{
|
||||
BSConstraint constrain;
|
||||
if (this.TryGetConstraint(body1, body2, out constrain))
|
||||
{
|
||||
// remove the constraint from our collection
|
||||
RemoveAndDestroyConstraint(constrain);
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
BSConstraint constrain;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// The constraint MUST exist in the collection
|
||||
public bool RemoveAndDestroyConstraint(BSConstraint constrain)
|
||||
{
|
||||
lock (m_constraints)
|
||||
if (this.TryGetConstraint(body1, body2, out constrain))
|
||||
{
|
||||
// remove the constraint from our collection
|
||||
m_constraints.Remove(constrain);
|
||||
// tell the engine that all its structures need to be freed
|
||||
constrain.Dispose();
|
||||
// we destroyed something
|
||||
ret = true;
|
||||
}
|
||||
// tell the engine that all its structures need to be freed
|
||||
constrain.Dispose();
|
||||
// we destroyed something
|
||||
return true;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Remove all constraints that reference the passed body.
|
||||
@@ -147,15 +137,16 @@ public class BSConstraintCollection : IDisposable
|
||||
|
||||
List<BSConstraint> toRemove = new List<BSConstraint>();
|
||||
uint lookingID = body1.ID;
|
||||
ForEachConstraint(delegate(BSConstraint constrain)
|
||||
{
|
||||
if (constrain.Body1.ID == lookingID || constrain.Body2.ID == lookingID)
|
||||
{
|
||||
toRemove.Add(constrain);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
lock (m_constraints)
|
||||
{
|
||||
foreach (BSConstraint constrain in m_constraints)
|
||||
{
|
||||
if (constrain.Body1.ID == lookingID || constrain.Body2.ID == lookingID)
|
||||
{
|
||||
toRemove.Add(constrain);
|
||||
}
|
||||
}
|
||||
foreach (BSConstraint constrain in toRemove)
|
||||
{
|
||||
m_constraints.Remove(constrain);
|
||||
@@ -167,16 +158,27 @@ public class BSConstraintCollection : IDisposable
|
||||
|
||||
public bool RecalculateAllConstraints()
|
||||
{
|
||||
bool ret = false;
|
||||
foreach (BSConstraint constrain in m_constraints)
|
||||
{
|
||||
constrain.CalculateTransforms();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Lock the constraint list and loop through it.
|
||||
// The constraint action returns 'true' if it wants the loop aborted.
|
||||
private void ForEachConstraint(ConstraintAction action)
|
||||
{
|
||||
lock (m_constraints)
|
||||
{
|
||||
foreach (BSConstraint constrain in m_constraints)
|
||||
{
|
||||
constrain.CalculateTransforms();
|
||||
ret = true;
|
||||
if (action(constrain))
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
private int frcount = 0; // Used to limit dynamics debug output to
|
||||
// every 100th frame
|
||||
|
||||
private BSScene m_physicsScene;
|
||||
private BSPrim m_prim; // the prim this dynamic controller belongs to
|
||||
|
||||
// Vehicle properties
|
||||
@@ -75,6 +74,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
// HOVER_UP_ONLY
|
||||
// LIMIT_MOTOR_UP
|
||||
// LIMIT_ROLL_ONLY
|
||||
private VehicleFlag m_Hoverflags = (VehicleFlag)0;
|
||||
private Vector3 m_BlockingEndPoint = Vector3.Zero;
|
||||
private Quaternion m_RollreferenceFrame = Quaternion.Identity;
|
||||
// Linear properties
|
||||
@@ -124,16 +124,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
private float m_verticalAttractionEfficiency = 1.0f; // damped
|
||||
private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor.
|
||||
|
||||
public BSDynamics(BSScene myScene, BSPrim myPrim)
|
||||
public BSDynamics(BSPrim myPrim)
|
||||
{
|
||||
m_physicsScene = myScene;
|
||||
m_prim = myPrim;
|
||||
m_type = Vehicle.TYPE_NONE;
|
||||
}
|
||||
|
||||
internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue, float timestep)
|
||||
{
|
||||
VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
|
||||
DetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
|
||||
switch (pParam)
|
||||
{
|
||||
case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
|
||||
@@ -232,7 +231,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
|
||||
internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue, float timestep)
|
||||
{
|
||||
VDetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
|
||||
DetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
|
||||
switch (pParam)
|
||||
{
|
||||
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||
@@ -267,7 +266,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
|
||||
internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
|
||||
{
|
||||
VDetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
|
||||
DetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
|
||||
switch (pParam)
|
||||
{
|
||||
case Vehicle.REFERENCE_FRAME:
|
||||
@@ -281,27 +280,164 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
|
||||
internal void ProcessVehicleFlags(int pParam, bool remove)
|
||||
{
|
||||
VDetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", m_prim.LocalID, pParam, remove);
|
||||
VehicleFlag parm = (VehicleFlag)pParam;
|
||||
DetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", m_prim.LocalID, pParam, remove);
|
||||
if (remove)
|
||||
{
|
||||
if (pParam == -1)
|
||||
{
|
||||
m_flags = (VehicleFlag)0;
|
||||
m_Hoverflags = (VehicleFlag)0;
|
||||
return;
|
||||
}
|
||||
else
|
||||
if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT)
|
||||
{
|
||||
m_flags &= ~parm;
|
||||
if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != (VehicleFlag)0)
|
||||
m_Hoverflags &= ~(VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY)
|
||||
{
|
||||
if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != (VehicleFlag)0)
|
||||
m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY)
|
||||
{
|
||||
if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != (VehicleFlag)0)
|
||||
m_Hoverflags &= ~(VehicleFlag.HOVER_UP_ONLY);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY)
|
||||
{
|
||||
if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != (VehicleFlag)0)
|
||||
m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP)
|
||||
{
|
||||
if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != (VehicleFlag)0)
|
||||
m_flags &= ~(VehicleFlag.LIMIT_MOTOR_UP);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.LIMIT_ROLL_ONLY) == (int)VehicleFlag.LIMIT_ROLL_ONLY)
|
||||
{
|
||||
if ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) != (VehicleFlag)0)
|
||||
m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK)
|
||||
{
|
||||
if ((m_flags & VehicleFlag.MOUSELOOK_BANK) != (VehicleFlag)0)
|
||||
m_flags &= ~(VehicleFlag.MOUSELOOK_BANK);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER)
|
||||
{
|
||||
if ((m_flags & VehicleFlag.MOUSELOOK_STEER) != (VehicleFlag)0)
|
||||
m_flags &= ~(VehicleFlag.MOUSELOOK_STEER);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP)
|
||||
{
|
||||
if ((m_flags & VehicleFlag.NO_DEFLECTION_UP) != (VehicleFlag)0)
|
||||
m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED)
|
||||
{
|
||||
if ((m_flags & VehicleFlag.CAMERA_DECOUPLED) != (VehicleFlag)0)
|
||||
m_flags &= ~(VehicleFlag.CAMERA_DECOUPLED);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X)
|
||||
{
|
||||
if ((m_flags & VehicleFlag.NO_X) != (VehicleFlag)0)
|
||||
m_flags &= ~(VehicleFlag.NO_X);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y)
|
||||
{
|
||||
if ((m_flags & VehicleFlag.NO_Y) != (VehicleFlag)0)
|
||||
m_flags &= ~(VehicleFlag.NO_Y);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z)
|
||||
{
|
||||
if ((m_flags & VehicleFlag.NO_Z) != (VehicleFlag)0)
|
||||
m_flags &= ~(VehicleFlag.NO_Z);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT)
|
||||
{
|
||||
if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != (VehicleFlag)0)
|
||||
m_Hoverflags &= ~(VehicleFlag.LOCK_HOVER_HEIGHT);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION)
|
||||
{
|
||||
if ((m_flags & VehicleFlag.NO_DEFLECTION) != (VehicleFlag)0)
|
||||
m_flags &= ~(VehicleFlag.NO_DEFLECTION);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION)
|
||||
{
|
||||
if ((m_flags & VehicleFlag.LOCK_ROTATION) != (VehicleFlag)0)
|
||||
m_flags &= ~(VehicleFlag.LOCK_ROTATION);
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_flags |= parm;
|
||||
else
|
||||
{
|
||||
if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT)
|
||||
{
|
||||
m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT | m_flags);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY)
|
||||
{
|
||||
m_Hoverflags |= (VehicleFlag.HOVER_TERRAIN_ONLY | m_flags);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY)
|
||||
{
|
||||
m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY | m_flags);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY)
|
||||
{
|
||||
m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY | m_flags);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP)
|
||||
{
|
||||
m_flags |= (VehicleFlag.LIMIT_MOTOR_UP | m_flags);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK)
|
||||
{
|
||||
m_flags |= (VehicleFlag.MOUSELOOK_BANK | m_flags);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER)
|
||||
{
|
||||
m_flags |= (VehicleFlag.MOUSELOOK_STEER | m_flags);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP)
|
||||
{
|
||||
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | m_flags);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED)
|
||||
{
|
||||
m_flags |= (VehicleFlag.CAMERA_DECOUPLED | m_flags);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X)
|
||||
{
|
||||
m_flags |= (VehicleFlag.NO_X);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y)
|
||||
{
|
||||
m_flags |= (VehicleFlag.NO_Y);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z)
|
||||
{
|
||||
m_flags |= (VehicleFlag.NO_Z);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT)
|
||||
{
|
||||
m_Hoverflags |= (VehicleFlag.LOCK_HOVER_HEIGHT);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION)
|
||||
{
|
||||
m_flags |= (VehicleFlag.NO_DEFLECTION);
|
||||
}
|
||||
if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION)
|
||||
{
|
||||
m_flags |= (VehicleFlag.LOCK_ROTATION);
|
||||
}
|
||||
}
|
||||
}//end ProcessVehicleFlags
|
||||
|
||||
internal void ProcessTypeChange(Vehicle pType, float stepSize)
|
||||
internal void ProcessTypeChange(Vehicle pType)
|
||||
{
|
||||
VDetailLog("{0},ProcessTypeChange,type={1}", m_prim.LocalID, pType);
|
||||
DetailLog("{0},ProcessTypeChange,type={1}", m_prim.LocalID, pType);
|
||||
// Set Defaults For Type
|
||||
m_type = pType;
|
||||
switch (pType)
|
||||
@@ -342,10 +478,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
// m_bankingMix = 1;
|
||||
// m_bankingTimescale = 10;
|
||||
// m_referenceFrame = Quaternion.Identity;
|
||||
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
||||
m_flags &=
|
||||
m_Hoverflags &=
|
||||
~(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);
|
||||
@@ -370,10 +506,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
// m_bankingMix = 1;
|
||||
// m_bankingTimescale = 1;
|
||||
// m_referenceFrame = Quaternion.Identity;
|
||||
m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY |
|
||||
VehicleFlag.LIMIT_MOTOR_UP);
|
||||
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||
m_flags |= (VehicleFlag.HOVER_UP_ONLY);
|
||||
m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY);
|
||||
break;
|
||||
case Vehicle.TYPE_BOAT:
|
||||
m_linearFrictionTimescale = new Vector3(10, 3, 2);
|
||||
@@ -398,12 +534,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
// m_bankingMix = 0.8f;
|
||||
// m_bankingTimescale = 1;
|
||||
// m_referenceFrame = Quaternion.Identity;
|
||||
m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
|
||||
m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY);
|
||||
m_flags |= (VehicleFlag.NO_DEFLECTION_UP |
|
||||
VehicleFlag.LIMIT_MOTOR_UP);
|
||||
m_flags |= (VehicleFlag.HOVER_WATER_ONLY);
|
||||
m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY);
|
||||
break;
|
||||
case Vehicle.TYPE_AIRPLANE:
|
||||
m_linearFrictionTimescale = new Vector3(200, 10, 5);
|
||||
@@ -428,7 +564,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
// m_bankingMix = 0.7f;
|
||||
// m_bankingTimescale = 2;
|
||||
// m_referenceFrame = Quaternion.Identity;
|
||||
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
|
||||
m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP);
|
||||
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
|
||||
@@ -456,16 +592,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
// m_bankingMix = 0.7f;
|
||||
// m_bankingTimescale = 5;
|
||||
// m_referenceFrame = Quaternion.Identity;
|
||||
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
VehicleFlag.HOVER_UP_ONLY);
|
||||
m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP);
|
||||
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
|
||||
m_flags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||
m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||
break;
|
||||
}
|
||||
}//end SetDefaultsForType
|
||||
|
||||
// One step of the vehicle properties for the next 'pTimestep' seconds.
|
||||
internal void Step(float pTimestep)
|
||||
{
|
||||
if (m_type == Vehicle.TYPE_NONE) return;
|
||||
@@ -478,7 +613,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
MoveAngular(pTimestep);
|
||||
LimitRotation(pTimestep);
|
||||
|
||||
VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",
|
||||
DetailLog("{0},Dynamics,done,pos={1},force={2},velocity={3},angvel={4}",
|
||||
m_prim.LocalID, m_prim.Position, m_prim.Force, m_prim.Velocity, m_prim.RotationalVelocity);
|
||||
}// end Step
|
||||
|
||||
@@ -522,7 +657,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
|
||||
*/
|
||||
|
||||
VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},decay={4},dir={5},vel={6}",
|
||||
DetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},decay={4},dir={5},vel={6}",
|
||||
m_prim.LocalID, origDir, origVel, addAmount, decayfraction, m_linearMotorDirection, m_lastLinearVelocityVector);
|
||||
}
|
||||
else
|
||||
@@ -534,7 +669,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
m_lastLinearVelocityVector = Vector3.Zero;
|
||||
}
|
||||
|
||||
// convert requested object velocity to object relative vector
|
||||
// convert requested object velocity to world-referenced vector
|
||||
Quaternion rotq = m_prim.Orientation;
|
||||
m_dir = m_lastLinearVelocityVector * rotq;
|
||||
|
||||
@@ -587,42 +722,42 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
if (changed)
|
||||
{
|
||||
m_prim.Position = pos;
|
||||
VDetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}",
|
||||
DetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}",
|
||||
m_prim.LocalID, m_BlockingEndPoint, posChange, pos);
|
||||
}
|
||||
}
|
||||
|
||||
// If below the terrain, move us above the ground a little.
|
||||
if (pos.Z < m_prim.Scene.TerrainManager.GetTerrainHeightAtXYZ(pos))
|
||||
if (pos.Z < m_prim.Scene.GetTerrainHeightAtXYZ(pos))
|
||||
{
|
||||
pos.Z = m_prim.Scene.TerrainManager.GetTerrainHeightAtXYZ(pos) + 2;
|
||||
pos.Z = m_prim.Scene.GetTerrainHeightAtXYZ(pos) + 2;
|
||||
m_prim.Position = pos;
|
||||
VDetailLog("{0},MoveLinear,terrainHeight,pos={1}", m_prim.LocalID, pos);
|
||||
DetailLog("{0},MoveLinear,terrainHeight,pos={1}", m_prim.LocalID, pos);
|
||||
}
|
||||
|
||||
// Check if hovering
|
||||
if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
|
||||
if ((m_Hoverflags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
|
||||
{
|
||||
// We should hover, get the target height
|
||||
if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0)
|
||||
if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != 0)
|
||||
{
|
||||
m_VhoverTargetHeight = m_prim.Scene.GetWaterLevel() + m_VhoverHeight;
|
||||
}
|
||||
if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
|
||||
if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
|
||||
{
|
||||
m_VhoverTargetHeight = m_prim.Scene.TerrainManager.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight;
|
||||
m_VhoverTargetHeight = m_prim.Scene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight;
|
||||
}
|
||||
if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0)
|
||||
if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0)
|
||||
{
|
||||
m_VhoverTargetHeight = m_VhoverHeight;
|
||||
}
|
||||
|
||||
if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0)
|
||||
if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != 0)
|
||||
{
|
||||
// If body is aready heigher, use its height as target height
|
||||
if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z;
|
||||
}
|
||||
if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
|
||||
if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
|
||||
{
|
||||
if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2)
|
||||
{
|
||||
@@ -644,7 +779,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
}
|
||||
}
|
||||
|
||||
VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_dir, m_VhoverHeight, m_VhoverTargetHeight);
|
||||
DetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_dir, m_VhoverHeight, m_VhoverTargetHeight);
|
||||
|
||||
// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped
|
||||
// m_VhoverTimescale = 0f; // time to acheive height
|
||||
@@ -674,13 +809,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
grav.Z = (float)(grav.Z * 1.125);
|
||||
}
|
||||
float terraintemp = m_prim.Scene.TerrainManager.GetTerrainHeightAtXYZ(pos);
|
||||
float terraintemp = m_prim.Scene.GetTerrainHeightAtXYZ(pos);
|
||||
float postemp = (pos.Z - terraintemp);
|
||||
if (postemp > 2.5f)
|
||||
{
|
||||
grav.Z = (float)(grav.Z * 1.037125);
|
||||
}
|
||||
VDetailLog("{0},MoveLinear,limitMotorUp,grav={1}", m_prim.LocalID, grav);
|
||||
DetailLog("{0},MoveLinear,limitMotorUp,grav={1}", m_prim.LocalID, grav);
|
||||
//End Experimental Values
|
||||
}
|
||||
if ((m_flags & (VehicleFlag.NO_X)) != 0)
|
||||
@@ -709,7 +844,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep);
|
||||
m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount;
|
||||
|
||||
VDetailLog("{0},MoveLinear,done,pos={1},vel={2},force={3},decay={4}",
|
||||
DetailLog("{0},MoveLinear,done,pos={1},vel={2},force={3},decay={4}",
|
||||
m_prim.LocalID, m_lastPositionVector, m_dir, grav, decayamount);
|
||||
|
||||
} // end MoveLinear()
|
||||
@@ -735,13 +870,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
// There are m_angularMotorApply steps.
|
||||
Vector3 origAngularVelocity = m_angularMotorVelocity;
|
||||
// ramp up to new value
|
||||
// current velocity += error / (time to get there / step interval)
|
||||
// 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);
|
||||
|
||||
VDetailLog("{0},MoveAngular,angularMotorApply,apply={1},origvel={2},dir={3},vel={4}",
|
||||
DetailLog("{0},MoveAngular,angularMotorApply,apply={1},origvel={2},dir={3},vel={4}",
|
||||
m_prim.LocalID,m_angularMotorApply,origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity);
|
||||
|
||||
m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected
|
||||
@@ -752,8 +887,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
// No motor recently applied, keep the body velocity
|
||||
// and decay the velocity
|
||||
m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep);
|
||||
if (m_angularMotorVelocity.LengthSquared() < 0.00001)
|
||||
m_angularMotorVelocity = Vector3.Zero;
|
||||
} // end motor section
|
||||
|
||||
// Vertical attractor section
|
||||
@@ -791,7 +924,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
vertattr.X += bounce * angularVelocity.X;
|
||||
vertattr.Y += bounce * angularVelocity.Y;
|
||||
|
||||
VDetailLog("{0},MoveAngular,verticalAttraction,verterr={1},bounce={2},vertattr={3}",
|
||||
DetailLog("{0},MoveAngular,verticalAttraction,verterr={1},bounce={2},vertattr={3}",
|
||||
m_prim.LocalID, verterr, bounce, vertattr);
|
||||
|
||||
} // else vertical attractor is off
|
||||
@@ -809,13 +942,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
m_lastAngularVelocity.X = 0;
|
||||
m_lastAngularVelocity.Y = 0;
|
||||
VDetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity);
|
||||
DetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity);
|
||||
}
|
||||
|
||||
if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
|
||||
{
|
||||
m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero.
|
||||
VDetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity);
|
||||
DetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity);
|
||||
}
|
||||
|
||||
// apply friction
|
||||
@@ -825,7 +958,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
// Apply to the body
|
||||
m_prim.RotationalVelocity = m_lastAngularVelocity;
|
||||
|
||||
VDetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", m_prim.LocalID, decayamount, m_lastAngularVelocity);
|
||||
DetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", m_prim.LocalID, decayamount, m_lastAngularVelocity);
|
||||
} //end MoveAngular
|
||||
|
||||
internal void LimitRotation(float timestep)
|
||||
@@ -872,11 +1005,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
if (changed)
|
||||
m_prim.Orientation = m_rot;
|
||||
|
||||
VDetailLog("{0},LimitRotation,done,changed={1},orig={2},new={3}", m_prim.LocalID, changed, rotq, m_rot);
|
||||
DetailLog("{0},LimitRotation,done,changed={1},orig={2},new={3}", m_prim.LocalID, changed, rotq, m_rot);
|
||||
}
|
||||
|
||||
// Invoke the detailed logger and output something if it's enabled.
|
||||
private void VDetailLog(string msg, params Object[] args)
|
||||
private void DetailLog(string msg, params Object[] args)
|
||||
{
|
||||
if (m_prim.Scene.VehicleLoggingEnabled)
|
||||
m_prim.Scene.PhysicsLogging.Write(msg, args);
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyrightD
|
||||
* 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.Text;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
|
||||
class BSHingeConstraint : BSConstraint
|
||||
{
|
||||
public BSHingeConstraint(BulletSim world, BulletBody obj1, BulletBody obj2,
|
||||
Vector3 pivotInA, Vector3 pivotInB,
|
||||
Vector3 axisInA, Vector3 axisInB,
|
||||
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)
|
||||
{
|
||||
m_world = world;
|
||||
m_body1 = obj1;
|
||||
m_body2 = obj2;
|
||||
m_constraint = new BulletConstraint(
|
||||
BulletSimAPI.CreateHingeConstraint2(m_world.Ptr, m_body1.Ptr, m_body2.Ptr,
|
||||
pivotInA, pivotInB,
|
||||
axisInA, axisInB,
|
||||
useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies));
|
||||
m_enabled = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -36,17 +36,12 @@ public class BSLinkset
|
||||
{
|
||||
private static string LogHeader = "[BULLETSIM LINKSET]";
|
||||
|
||||
private BSPhysObject m_linksetRoot;
|
||||
public BSPhysObject LinksetRoot { get { return m_linksetRoot; } }
|
||||
private BSPrim m_linksetRoot;
|
||||
public BSPrim Root { get { return m_linksetRoot; } }
|
||||
|
||||
private BSScene m_physicsScene;
|
||||
public BSScene PhysicsScene { get { return m_physicsScene; } }
|
||||
private BSScene m_scene;
|
||||
|
||||
static int m_nextLinksetID = 1;
|
||||
public int LinksetID { get; private set; }
|
||||
|
||||
// The children under the root in this linkset
|
||||
private List<BSPhysObject> m_children;
|
||||
private List<BSPrim> m_children;
|
||||
|
||||
// We lock the diddling of linkset classes to prevent any badness.
|
||||
// This locks the modification of the instances of this class. Changes
|
||||
@@ -74,35 +69,28 @@ public class BSLinkset
|
||||
get { return ComputeLinksetGeometricCenter(); }
|
||||
}
|
||||
|
||||
public BSLinkset(BSScene scene, BSPhysObject parent)
|
||||
public BSLinkset(BSScene scene, BSPrim parent)
|
||||
{
|
||||
// A simple linkset of one (no children)
|
||||
LinksetID = m_nextLinksetID++;
|
||||
// We create LOTS of linksets.
|
||||
if (m_nextLinksetID < 0)
|
||||
m_nextLinksetID = 1;
|
||||
m_physicsScene = scene;
|
||||
m_scene = scene;
|
||||
m_linksetRoot = parent;
|
||||
m_children = new List<BSPhysObject>();
|
||||
m_children = new List<BSPrim>();
|
||||
m_mass = parent.MassRaw;
|
||||
}
|
||||
|
||||
// Link to a linkset where the child knows the parent.
|
||||
// Parent changing should not happen so do some sanity checking.
|
||||
// We return the parent's linkset so the child can track its membership.
|
||||
public BSLinkset AddMeToLinkset(BSPhysObject child)
|
||||
// We return the parent's linkset so the child can track it's membership.
|
||||
public BSLinkset AddMeToLinkset(BSPrim child, BSPrim parent)
|
||||
{
|
||||
lock (m_linksetActivityLock)
|
||||
{
|
||||
AddChildToLinkset(child);
|
||||
parent.Linkset.AddChildToLinkset(child);
|
||||
}
|
||||
return this;
|
||||
return parent.Linkset;
|
||||
}
|
||||
|
||||
// Remove a child from a linkset.
|
||||
// Returns a new linkset for the child which is a linkset of one (just the
|
||||
// orphened child).
|
||||
public BSLinkset RemoveMeFromLinkset(BSPhysObject child)
|
||||
public BSLinkset RemoveMeFromLinkset(BSPrim child)
|
||||
{
|
||||
lock (m_linksetActivityLock)
|
||||
{
|
||||
@@ -113,7 +101,7 @@ public class BSLinkset
|
||||
{
|
||||
// Note that we don't do a foreach because the remove routine
|
||||
// takes it out of the list.
|
||||
RemoveChildFromOtherLinkset(m_children[0]);
|
||||
RemoveChildFromLinkset(m_children[0]);
|
||||
}
|
||||
m_children.Clear(); // just to make sure
|
||||
}
|
||||
@@ -125,33 +113,76 @@ public class BSLinkset
|
||||
}
|
||||
|
||||
// The child is down to a linkset of just itself
|
||||
return new BSLinkset(PhysicsScene, child);
|
||||
return new BSLinkset(m_scene, child);
|
||||
}
|
||||
|
||||
// An existing linkset had one of its members rebuilt or something.
|
||||
// Go through the linkset and rebuild the pointers to the bodies of the linkset members.
|
||||
public BSLinkset RefreshLinkset(BSPrim requestor)
|
||||
{
|
||||
BSLinkset ret = requestor.Linkset;
|
||||
|
||||
lock (m_linksetActivityLock)
|
||||
{
|
||||
System.IntPtr aPtr = BulletSimAPI.GetBodyHandle2(m_scene.World.Ptr, m_linksetRoot.LocalID);
|
||||
if (aPtr == System.IntPtr.Zero)
|
||||
{
|
||||
// That's odd. We can't find the root of the linkset.
|
||||
// The linkset is somehow dead. The requestor is now a member of a linkset of one.
|
||||
DetailLog("{0},RefreshLinkset.RemoveRoot,child={1}", m_linksetRoot.LocalID, m_linksetRoot.LocalID);
|
||||
ret = RemoveMeFromLinkset(m_linksetRoot);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reconstruct the pointer to the body of the linkset root.
|
||||
DetailLog("{0},RefreshLinkset.RebuildRoot,rootID={1},ptr={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, aPtr);
|
||||
m_linksetRoot.Body = new BulletBody(m_linksetRoot.LocalID, aPtr);
|
||||
|
||||
List<BSPrim> toRemove = new List<BSPrim>();
|
||||
foreach (BSPrim bsp in m_children)
|
||||
{
|
||||
aPtr = BulletSimAPI.GetBodyHandle2(m_scene.World.Ptr, bsp.LocalID);
|
||||
if (aPtr == System.IntPtr.Zero)
|
||||
{
|
||||
toRemove.Add(bsp);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reconstruct the pointer to the body of the linkset root.
|
||||
DetailLog("{0},RefreshLinkset.RebuildChild,rootID={1},ptr={2}", bsp.LocalID, m_linksetRoot.LocalID, aPtr);
|
||||
bsp.Body = new BulletBody(bsp.LocalID, aPtr);
|
||||
}
|
||||
}
|
||||
foreach (BSPrim bsp in toRemove)
|
||||
{
|
||||
RemoveChildFromLinkset(bsp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// Return 'true' if the passed object is the root object of this linkset
|
||||
public bool IsRoot(BSPhysObject requestor)
|
||||
public bool IsRoot(BSPrim requestor)
|
||||
{
|
||||
return (requestor.LocalID == m_linksetRoot.LocalID);
|
||||
}
|
||||
|
||||
public int NumberOfChildren { get { return m_children.Count; } }
|
||||
|
||||
// Return 'true' if this linkset has any children (more than the root member)
|
||||
public bool HasAnyChildren { get { return (m_children.Count > 0); } }
|
||||
|
||||
// Return 'true' if this child is in this linkset
|
||||
public bool HasChild(BSPhysObject child)
|
||||
public bool HasChild(BSPrim child)
|
||||
{
|
||||
bool ret = false;
|
||||
lock (m_linksetActivityLock)
|
||||
foreach (BSPrim bp in m_children)
|
||||
{
|
||||
foreach (BSPhysObject bp in m_children)
|
||||
if (child.LocalID == bp.LocalID)
|
||||
{
|
||||
if (child.LocalID == bp.LocalID)
|
||||
{
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@@ -160,7 +191,7 @@ public class BSLinkset
|
||||
private float ComputeLinksetMass()
|
||||
{
|
||||
float mass = m_linksetRoot.MassRaw;
|
||||
foreach (BSPhysObject bp in m_children)
|
||||
foreach (BSPrim bp in m_children)
|
||||
{
|
||||
mass += bp.MassRaw;
|
||||
}
|
||||
@@ -172,16 +203,12 @@ public class BSLinkset
|
||||
OMV.Vector3 com = m_linksetRoot.Position * m_linksetRoot.MassRaw;
|
||||
float totalMass = m_linksetRoot.MassRaw;
|
||||
|
||||
lock (m_linksetActivityLock)
|
||||
foreach (BSPrim bp in m_children)
|
||||
{
|
||||
foreach (BSPhysObject bp in m_children)
|
||||
{
|
||||
com += bp.Position * bp.MassRaw;
|
||||
totalMass += bp.MassRaw;
|
||||
}
|
||||
if (totalMass != 0f)
|
||||
com /= totalMass;
|
||||
com += bp.Position * bp.MassRaw;
|
||||
totalMass += bp.MassRaw;
|
||||
}
|
||||
com /= totalMass;
|
||||
|
||||
return com;
|
||||
}
|
||||
@@ -190,223 +217,135 @@ public class BSLinkset
|
||||
{
|
||||
OMV.Vector3 com = m_linksetRoot.Position;
|
||||
|
||||
lock (m_linksetActivityLock)
|
||||
foreach (BSPrim bp in m_children)
|
||||
{
|
||||
foreach (BSPhysObject bp in m_children)
|
||||
{
|
||||
com += bp.Position * bp.MassRaw;
|
||||
}
|
||||
com /= (m_children.Count + 1);
|
||||
com += bp.Position * bp.MassRaw;
|
||||
}
|
||||
com /= m_children.Count + 1;
|
||||
|
||||
return com;
|
||||
}
|
||||
|
||||
// When physical properties are changed the linkset needs to recalculate
|
||||
// its internal properties.
|
||||
public void Refresh(BSPhysObject requestor)
|
||||
{
|
||||
// If there are no children, there aren't any constraints to recompute
|
||||
if (!HasAnyChildren)
|
||||
return;
|
||||
|
||||
// Only the root does the recomputation
|
||||
if (IsRoot(requestor))
|
||||
{
|
||||
PhysicsScene.TaintedObject("BSLinkSet.Refresh", delegate()
|
||||
{
|
||||
RecomputeLinksetConstraintVariables();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Call each of the constraints that make up this linkset and recompute the
|
||||
// various transforms and variables. Used when objects are added or removed
|
||||
// from a linkset to make sure the constraints know about the new mass and
|
||||
// geometry.
|
||||
// Must only be called at taint time!!
|
||||
private bool RecomputeLinksetConstraintVariables()
|
||||
{
|
||||
float linksetMass = LinksetMass;
|
||||
lock (m_linksetActivityLock)
|
||||
{
|
||||
foreach (BSPhysObject child in m_children)
|
||||
{
|
||||
BSConstraint constrain;
|
||||
if (m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.Body, child.Body, out constrain))
|
||||
{
|
||||
// DetailLog("{0},BSLinkset.RecomputeLinksetConstraintVariables,taint,child={1},mass={2},A={3},B={4}",
|
||||
// LinksetRoot.LocalID, child.LocalID, linksetMass, constrain.Body1.ID, constrain.Body2.ID);
|
||||
constrain.RecomputeConstraintVariables(linksetMass);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non-fatal error that can happen when children are being added to the linkset but
|
||||
// their constraints have not been created yet.
|
||||
// Caused by the fact that m_children is built at run time but building constraints
|
||||
// happens at taint time.
|
||||
// m_physicsScene.Logger.ErrorFormat("[BULLETSIM LINKSET] RecomputeLinksetConstraintVariables: constraint not found for root={0}, child={1}",
|
||||
// m_linksetRoot.Body.ID, child.Body.ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// I am the root of a linkset and a new child is being added
|
||||
// Called while LinkActivity is locked.
|
||||
private void AddChildToLinkset(BSPhysObject child)
|
||||
public void AddChildToLinkset(BSPrim pchild)
|
||||
{
|
||||
BSPrim child = pchild;
|
||||
if (!HasChild(child))
|
||||
{
|
||||
m_children.Add(child);
|
||||
|
||||
BSPhysObject rootx = LinksetRoot; // capture the root as of now
|
||||
BSPhysObject childx = child;
|
||||
m_physicsScene.TaintedObject("AddChildToLinkset", delegate()
|
||||
m_scene.TaintedObject(delegate()
|
||||
{
|
||||
DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
|
||||
PhysicallyLinkAChildToRoot(rootx, childx); // build the physical binding between me and the child
|
||||
DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, m_linksetRoot.LocalID);
|
||||
DetailLog("{0},AddChildToLinkset,child={1}", m_linksetRoot.LocalID, pchild.LocalID);
|
||||
PhysicallyLinkAChildToRoot(pchild); // build the physical binding between me and the child
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Forcefully removing a child from a linkset.
|
||||
// This is not being called by the child so we have to make sure the child doesn't think
|
||||
// it's still connected to the linkset.
|
||||
// Normal OpenSimulator operation will never do this because other SceneObjectPart information
|
||||
// has to be updated also (like pointer to prim's parent).
|
||||
private void RemoveChildFromOtherLinkset(BSPhysObject pchild)
|
||||
{
|
||||
pchild.Linkset = new BSLinkset(m_physicsScene, pchild);
|
||||
RemoveChildFromLinkset(pchild);
|
||||
}
|
||||
|
||||
// I am the root of a linkset and one of my children is being removed.
|
||||
// Safe to call even if the child is not really in my linkset.
|
||||
private void RemoveChildFromLinkset(BSPhysObject child)
|
||||
public void RemoveChildFromLinkset(BSPrim pchild)
|
||||
{
|
||||
BSPrim child = pchild;
|
||||
|
||||
if (m_children.Remove(child))
|
||||
{
|
||||
BSPhysObject rootx = LinksetRoot; // capture the root as of now
|
||||
BSPhysObject childx = child;
|
||||
m_physicsScene.TaintedObject("RemoveChildFromLinkset", delegate()
|
||||
m_scene.TaintedObject(delegate()
|
||||
{
|
||||
DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
|
||||
DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID);
|
||||
DetailLog("{0},RemoveChildFromLinkset,child={1}", m_linksetRoot.LocalID, pchild.LocalID);
|
||||
|
||||
PhysicallyUnlinkAChildFromRoot(rootx, childx);
|
||||
if (m_children.Count == 0)
|
||||
{
|
||||
// if the linkset is empty, make sure all linkages have been removed
|
||||
PhysicallyUnlinkAllChildrenFromRoot();
|
||||
}
|
||||
else
|
||||
{
|
||||
PhysicallyUnlinkAChildFromRoot(pchild);
|
||||
}
|
||||
});
|
||||
|
||||
RecomputeLinksetConstraintVariables();
|
||||
}
|
||||
else
|
||||
{
|
||||
// This will happen if we remove the root of the linkset first. Non-fatal occurance.
|
||||
// PhysicsScene.Logger.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset", LogHeader);
|
||||
// m_scene.Logger.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset", LogHeader);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a constraint between me (root of linkset) and the passed prim (the child).
|
||||
// Called at taint time!
|
||||
private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BSPhysObject childPrim)
|
||||
private void PhysicallyLinkAChildToRoot(BSPrim childPrim)
|
||||
{
|
||||
// Zero motion for children so they don't interpolate
|
||||
childPrim.ZeroMotion();
|
||||
|
||||
// Relative position normalized to the root prim
|
||||
// Essentually a vector pointing from center of rootPrim to center of childPrim
|
||||
OMV.Vector3 childRelativePosition = childPrim.Position - rootPrim.Position;
|
||||
|
||||
// real world coordinate of midpoint between the two objects
|
||||
OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2);
|
||||
|
||||
// create a constraint that allows no freedom of movement between the two objects
|
||||
// http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
|
||||
DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2},rLoc={3},cLoc={4},midLoc={5}",
|
||||
rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID, rootPrim.Position, childPrim.Position, midPoint);
|
||||
BS6DofConstraint constrain = new BS6DofConstraint(
|
||||
m_physicsScene.World, rootPrim.Body, childPrim.Body,
|
||||
midPoint,
|
||||
true,
|
||||
true
|
||||
);
|
||||
/* NOTE: below is an attempt to build constraint with full frame computation, etc.
|
||||
* Using the midpoint is easier since it lets the Bullet code use the transforms
|
||||
* of the objects.
|
||||
* Code left as a warning to future programmers.
|
||||
// ==================================================================================
|
||||
// relative position normalized to the root prim
|
||||
OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation);
|
||||
OMV.Vector3 childRelativePosition = (childPrim.Position - rootPrim.Position) * invThisOrientation;
|
||||
OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(m_linksetRoot.Orientation);
|
||||
OMV.Vector3 childRelativePosition = (childPrim.Position - m_linksetRoot.Position) * invThisOrientation;
|
||||
|
||||
// relative rotation of the child to the parent
|
||||
OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation;
|
||||
OMV.Quaternion inverseChildRelativeRotation = OMV.Quaternion.Inverse(childRelativeRotation);
|
||||
|
||||
// create a constraint that allows no freedom of movement between the two objects
|
||||
// http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
|
||||
DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
|
||||
BS6DofConstraint constrain = new BS6DofConstraint(
|
||||
PhysicsScene.World, rootPrim.Body, childPrim.Body,
|
||||
OMV.Vector3.Zero,
|
||||
OMV.Quaternion.Inverse(rootPrim.Orientation),
|
||||
OMV.Vector3.Zero,
|
||||
OMV.Quaternion.Inverse(childPrim.Orientation),
|
||||
// A point half way between the parent and child
|
||||
// childRelativePosition/2,
|
||||
// DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID);
|
||||
DetailLog("{0},LinkAChildToMe,taint,root={1},child={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, childPrim.LocalID);
|
||||
BSConstraint constrain = m_scene.Constraints.CreateConstraint(
|
||||
m_scene.World, m_linksetRoot.Body, childPrim.Body,
|
||||
// childRelativePosition,
|
||||
// childRelativeRotation,
|
||||
// childRelativePosition/2,
|
||||
// inverseChildRelativeRotation,
|
||||
true,
|
||||
true
|
||||
OMV.Vector3.Zero,
|
||||
OMV.Quaternion.Identity,
|
||||
OMV.Vector3.Zero,
|
||||
OMV.Quaternion.Identity
|
||||
);
|
||||
// ==================================================================================
|
||||
*/
|
||||
|
||||
m_physicsScene.Constraints.AddConstraint(constrain);
|
||||
|
||||
// zero linear and angular limits makes the objects unable to move in relation to each other
|
||||
constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
|
||||
constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
|
||||
|
||||
// tweek the constraint to increase stability
|
||||
constrain.UseFrameOffset(PhysicsScene.BoolNumeric(PhysicsScene.Params.linkConstraintUseFrameOffset));
|
||||
constrain.TranslationalLimitMotor(PhysicsScene.BoolNumeric(PhysicsScene.Params.linkConstraintEnableTransMotor),
|
||||
PhysicsScene.Params.linkConstraintTransMotorMaxVel,
|
||||
PhysicsScene.Params.linkConstraintTransMotorMaxForce);
|
||||
constrain.SetCFMAndERP(PhysicsScene.Params.linkConstraintCFM, PhysicsScene.Params.linkConstraintERP);
|
||||
constrain.UseFrameOffset(m_scene.BoolNumeric(m_scene.Params.linkConstraintUseFrameOffset));
|
||||
constrain.TranslationalLimitMotor(m_scene.BoolNumeric(m_scene.Params.linkConstraintEnableTransMotor),
|
||||
m_scene.Params.linkConstraintTransMotorMaxVel,
|
||||
m_scene.Params.linkConstraintTransMotorMaxForce);
|
||||
constrain.SetCFMAndERP(m_scene.Params.linkConstraintCFM, m_scene.Params.linkConstraintERP);
|
||||
|
||||
RecomputeLinksetConstraintVariables();
|
||||
}
|
||||
|
||||
// Remove linkage between myself and a particular child
|
||||
// Called at taint time!
|
||||
private void PhysicallyUnlinkAChildFromRoot(BSPhysObject rootPrim, BSPhysObject childPrim)
|
||||
private void PhysicallyUnlinkAChildFromRoot(BSPrim childPrim)
|
||||
{
|
||||
DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
|
||||
|
||||
// Find the constraint for this link and get rid of it from the overall collection and from my list
|
||||
m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body, childPrim.Body);
|
||||
|
||||
// Make the child refresh its location
|
||||
BulletSimAPI.PushUpdate2(childPrim.Body.Ptr);
|
||||
DebugLog("{0}: PhysicallyUnlinkAChildFromRoot: RemoveConstraint between root prim {1} and child prim {2}",
|
||||
LogHeader, m_linksetRoot.LocalID, childPrim.LocalID);
|
||||
DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, childPrim.LocalID);
|
||||
// BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, childPrim.LocalID);
|
||||
m_scene.Constraints.RemoveAndDestroyConstraint(m_linksetRoot.Body, childPrim.Body);
|
||||
}
|
||||
|
||||
// Remove linkage between myself and any possible children I might have
|
||||
// Called at taint time!
|
||||
private void PhysicallyUnlinkAllChildrenFromRoot(BSPhysObject rootPrim)
|
||||
private void PhysicallyUnlinkAllChildrenFromRoot()
|
||||
{
|
||||
DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID);
|
||||
// DebugLog("{0}: PhysicallyUnlinkAllChildren:", LogHeader);
|
||||
DetailLog("{0},PhysicallyUnlinkAllChildren,taint", m_linksetRoot.LocalID);
|
||||
m_scene.Constraints.RemoveAndDestroyConstraint(m_linksetRoot.Body);
|
||||
// BulletSimAPI.RemoveConstraintByID(_scene.WorldID, LocalID);
|
||||
}
|
||||
|
||||
m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body);
|
||||
// Invoke the detailed logger and output something if it's enabled.
|
||||
private void DebugLog(string msg, params Object[] args)
|
||||
{
|
||||
m_scene.Logger.DebugFormat(msg, args);
|
||||
}
|
||||
|
||||
// Invoke the detailed logger and output something if it's enabled.
|
||||
private void DetailLog(string msg, params Object[] args)
|
||||
{
|
||||
m_physicsScene.PhysicsLogging.Write(msg, args);
|
||||
m_scene.PhysicsLogging.Write(msg, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyrightD
|
||||
* 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.Text;
|
||||
|
||||
using OMV = OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
// Class to wrap all objects.
|
||||
// The rest of BulletSim doesn't need to keep checking for avatars or prims
|
||||
// unless the difference is significant.
|
||||
public abstract class BSPhysObject : PhysicsActor
|
||||
{
|
||||
public abstract BSLinkset Linkset { get; set; }
|
||||
|
||||
public abstract void Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type,
|
||||
OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth);
|
||||
public abstract void SendCollisions();
|
||||
|
||||
// Return the object mass without calculating it or side effects
|
||||
public abstract float MassRaw { get; }
|
||||
|
||||
public abstract BulletBody Body { get; set; }
|
||||
public abstract void ZeroMotion();
|
||||
|
||||
public virtual void StepVehicle(float timeStep) { }
|
||||
|
||||
public abstract void UpdateProperties(EntityProperties entprop);
|
||||
|
||||
public abstract void Destroy();
|
||||
}
|
||||
}
|
||||
@@ -37,11 +37,13 @@ using OpenSim.Region.Physics.ConvexDecompositionDotNet;
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
[Serializable]
|
||||
public sealed class BSPrim : BSPhysObject
|
||||
public sealed class BSPrim : PhysicsActor
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static readonly string LogHeader = "[BULLETS PRIM]";
|
||||
|
||||
private void DebugLog(string mm, params Object[] xx) { if (_scene.shouldDebugLog) m_log.DebugFormat(mm, xx); }
|
||||
|
||||
private IMesh _mesh;
|
||||
private PrimitiveBaseShape _pbs;
|
||||
private ShapeData.PhysicsShapeType _shapeType;
|
||||
@@ -88,14 +90,23 @@ public sealed class BSPrim : BSPhysObject
|
||||
private float _buoyancy;
|
||||
|
||||
// Membership in a linkset is controlled by this class.
|
||||
public override BSLinkset Linkset { get; set; }
|
||||
private BSLinkset _linkset;
|
||||
public BSLinkset Linkset
|
||||
{
|
||||
get { return _linkset; }
|
||||
set { _linkset = value; }
|
||||
}
|
||||
|
||||
private int _subscribedEventsMs = 0;
|
||||
private int _nextCollisionOkTime = 0;
|
||||
long _collidingStep;
|
||||
long _collidingGroundStep;
|
||||
|
||||
public override BulletBody Body { get; set; }
|
||||
private BulletBody m_body;
|
||||
public BulletBody Body {
|
||||
get { return m_body; }
|
||||
set { m_body = value; }
|
||||
}
|
||||
|
||||
private BSDynamics _vehicle;
|
||||
|
||||
@@ -127,45 +138,39 @@ public sealed class BSPrim : BSPhysObject
|
||||
_isPhysical = pisPhysical;
|
||||
_isVolumeDetect = false;
|
||||
_subscribedEventsMs = 0;
|
||||
_friction = _scene.Params.defaultFriction; // TODO: compute based on object material
|
||||
_density = _scene.Params.defaultDensity; // TODO: compute based on object material
|
||||
_friction = _scene.Params.defaultFriction; // TODO: compute based on object material
|
||||
_density = _scene.Params.defaultDensity; // TODO: compute based on object material
|
||||
_restitution = _scene.Params.defaultRestitution;
|
||||
Linkset = new BSLinkset(Scene, this); // a linkset of one
|
||||
_vehicle = new BSDynamics(Scene, this); // add vehicleness
|
||||
_linkset = new BSLinkset(_scene, this); // a linkset of one
|
||||
_vehicle = new BSDynamics(this); // add vehicleness
|
||||
_mass = CalculateMass();
|
||||
// do the actual object creation at taint time
|
||||
DetailLog("{0},BSPrim.constructor,call", LocalID);
|
||||
_scene.TaintedObject("BSPrim.create", delegate()
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
RecreateGeomAndObject();
|
||||
|
||||
// Get the pointer to the physical body for this object.
|
||||
// At the moment, we're still letting BulletSim manage the creation and destruction
|
||||
// of the object. Someday we'll move that into the C# code.
|
||||
Body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
|
||||
m_body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
|
||||
});
|
||||
}
|
||||
|
||||
// called when this prim is being destroyed and we should free all the resources
|
||||
public override void Destroy()
|
||||
public void Destroy()
|
||||
{
|
||||
// m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID);
|
||||
|
||||
// Undo any links between me and any other object
|
||||
BSPhysObject parentBefore = Linkset.LinksetRoot;
|
||||
int childrenBefore = Linkset.NumberOfChildren;
|
||||
|
||||
Linkset = Linkset.RemoveMeFromLinkset(this);
|
||||
|
||||
DetailLog("{0},BSPrim.Destroy,call,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}",
|
||||
LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
|
||||
// DetailLog("{0},Destroy", LocalID);
|
||||
|
||||
// Undo any vehicle properties
|
||||
this.VehicleType = (int)Vehicle.TYPE_NONE;
|
||||
_vehicle.ProcessTypeChange(Vehicle.TYPE_NONE);
|
||||
_scene.RemoveVehiclePrim(this); // just to make sure
|
||||
|
||||
_scene.TaintedObject("BSPrim.destroy", delegate()
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
DetailLog("{0},BSPrim.Destroy,taint,", LocalID);
|
||||
// Undo any links between me and any other object
|
||||
_linkset = _linkset.RemoveMeFromLinkset(this);
|
||||
|
||||
// everything in the C# world will get garbage collected. Tell the C++ world to free stuff.
|
||||
BulletSimAPI.DestroyObject(_scene.WorldID, LocalID);
|
||||
});
|
||||
@@ -178,11 +183,11 @@ public sealed class BSPrim : BSPhysObject
|
||||
get { return _size; }
|
||||
set {
|
||||
_size = value;
|
||||
_scene.TaintedObject("BSPrim.setSize", delegate()
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
_mass = CalculateMass(); // changing size changes the mass
|
||||
BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical);
|
||||
DetailLog("{0}: BSPrim.setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical);
|
||||
// DetailLog("{0}: setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical);
|
||||
RecreateGeomAndObject();
|
||||
});
|
||||
}
|
||||
@@ -190,7 +195,7 @@ public sealed class BSPrim : BSPhysObject
|
||||
public override PrimitiveBaseShape Shape {
|
||||
set {
|
||||
_pbs = value;
|
||||
_scene.TaintedObject("BSPrim.setShape", delegate()
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
_mass = CalculateMass(); // changing the shape changes the mass
|
||||
RecreateGeomAndObject();
|
||||
@@ -208,7 +213,7 @@ public sealed class BSPrim : BSPhysObject
|
||||
public override bool Selected {
|
||||
set {
|
||||
_isSelected = value;
|
||||
_scene.TaintedObject("BSPrim.setSelected", delegate()
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
SetObjectDynamic();
|
||||
});
|
||||
@@ -219,16 +224,10 @@ public sealed class BSPrim : BSPhysObject
|
||||
// link me to the specified parent
|
||||
public override void link(PhysicsActor obj) {
|
||||
BSPrim parent = obj as BSPrim;
|
||||
if (parent != null)
|
||||
{
|
||||
BSPhysObject parentBefore = Linkset.LinksetRoot;
|
||||
int childrenBefore = Linkset.NumberOfChildren;
|
||||
DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID);
|
||||
DetailLog("{0},link,parent={1}", LocalID, obj.LocalID);
|
||||
|
||||
Linkset = parent.Linkset.AddMeToLinkset(this);
|
||||
|
||||
DetailLog("{0},BSPrim.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}",
|
||||
LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
|
||||
}
|
||||
_linkset = _linkset.AddMeToLinkset(this, parent);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -236,14 +235,11 @@ public sealed class BSPrim : BSPhysObject
|
||||
public override void delink() {
|
||||
// TODO: decide if this parent checking needs to happen at taint time
|
||||
// Race condition here: if link() and delink() in same simulation tick, the delink will not happen
|
||||
DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID,
|
||||
_linkset.Root._avName+"/"+_linkset.Root.LocalID.ToString());
|
||||
DetailLog("{0},delink,parent={1}", LocalID, _linkset.Root.LocalID.ToString());
|
||||
|
||||
BSPhysObject parentBefore = Linkset.LinksetRoot;
|
||||
int childrenBefore = Linkset.NumberOfChildren;
|
||||
|
||||
Linkset = Linkset.RemoveMeFromLinkset(this);
|
||||
|
||||
DetailLog("{0},BSPrim.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ",
|
||||
LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
|
||||
_linkset.RemoveMeFromLinkset(this);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -251,7 +247,7 @@ public sealed class BSPrim : BSPhysObject
|
||||
// Do it to the properties so the values get set in the physics engine.
|
||||
// Push the setting of the values to the viewer.
|
||||
// Called at taint time!
|
||||
public override void ZeroMotion()
|
||||
public void ZeroMotion()
|
||||
{
|
||||
_velocity = OMV.Vector3.Zero;
|
||||
_acceleration = OMV.Vector3.Zero;
|
||||
@@ -266,13 +262,13 @@ public sealed class BSPrim : BSPhysObject
|
||||
|
||||
public override void LockAngularMotion(OMV.Vector3 axis)
|
||||
{
|
||||
DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis);
|
||||
DetailLog("{0},LockAngularMotion,call,axis={1}", LocalID, axis);
|
||||
return;
|
||||
}
|
||||
|
||||
public override OMV.Vector3 Position {
|
||||
get {
|
||||
if (!Linkset.IsRoot(this))
|
||||
if (!_linkset.IsRoot(this))
|
||||
// child prims move around based on their parent. Need to get the latest location
|
||||
_position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
|
||||
|
||||
@@ -283,9 +279,9 @@ public sealed class BSPrim : BSPhysObject
|
||||
set {
|
||||
_position = value;
|
||||
// TODO: what does it mean to set the position of a child prim?? Rebuild the constraint?
|
||||
_scene.TaintedObject("BSPrim.setPosition", delegate()
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||
DetailLog("{0},SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||
BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
|
||||
});
|
||||
}
|
||||
@@ -297,32 +293,32 @@ public sealed class BSPrim : BSPhysObject
|
||||
{
|
||||
get
|
||||
{
|
||||
return Linkset.LinksetMass;
|
||||
return _linkset.LinksetMass;
|
||||
}
|
||||
}
|
||||
|
||||
// used when we only want this prim's mass and not the linkset thing
|
||||
public override float MassRaw { get { return _mass; } }
|
||||
public float MassRaw { get { return _mass; } }
|
||||
|
||||
// Is this used?
|
||||
public override OMV.Vector3 CenterOfMass
|
||||
{
|
||||
get { return Linkset.CenterOfMass; }
|
||||
get { return _linkset.CenterOfMass; }
|
||||
}
|
||||
|
||||
// Is this used?
|
||||
public override OMV.Vector3 GeometricCenter
|
||||
{
|
||||
get { return Linkset.GeometricCenter; }
|
||||
get { return _linkset.GeometricCenter; }
|
||||
}
|
||||
|
||||
public override OMV.Vector3 Force {
|
||||
get { return _force; }
|
||||
set {
|
||||
_force = value;
|
||||
_scene.TaintedObject("BSPrim.setForce", delegate()
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force);
|
||||
DetailLog("{0},setForce,taint,force={1}", LocalID, _force);
|
||||
// BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
|
||||
BulletSimAPI.SetObjectForce2(Body.Ptr, _force);
|
||||
});
|
||||
@@ -335,41 +331,53 @@ public sealed class BSPrim : BSPhysObject
|
||||
}
|
||||
set {
|
||||
Vehicle type = (Vehicle)value;
|
||||
BSPrim vehiclePrim = this;
|
||||
_scene.TaintedObject("setVehicleType", delegate()
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
// Done at taint time so we're sure the physics engine is not using the variables
|
||||
// Vehicle code changes the parameters for this vehicle type.
|
||||
_vehicle.ProcessTypeChange(type, Scene.LastSimulatedTimestep);
|
||||
// Tell the scene about the vehicle so it will get processing each frame.
|
||||
_scene.VehicleInSceneTypeChanged(this, type);
|
||||
DetailLog("{0},SetVehicleType,taint,type={1}", LocalID, type);
|
||||
_vehicle.ProcessTypeChange(type);
|
||||
if (type == Vehicle.TYPE_NONE)
|
||||
{
|
||||
_scene.RemoveVehiclePrim(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
// Tell the physics engine to clear state
|
||||
BulletSimAPI.ClearForces2(this.Body.Ptr);
|
||||
});
|
||||
|
||||
// make it so the scene will call us each tick to do vehicle things
|
||||
_scene.AddVehiclePrim(this);
|
||||
}
|
||||
return;
|
||||
});
|
||||
}
|
||||
}
|
||||
public override void VehicleFloatParam(int param, float value)
|
||||
{
|
||||
_scene.TaintedObject("BSPrim.VehicleFloatParam", delegate()
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
_vehicle.ProcessFloatVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep);
|
||||
});
|
||||
}
|
||||
public override void VehicleVectorParam(int param, OMV.Vector3 value)
|
||||
{
|
||||
_scene.TaintedObject("BSPrim.VehicleVectorParam", delegate()
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
_vehicle.ProcessVectorVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep);
|
||||
});
|
||||
}
|
||||
public override void VehicleRotationParam(int param, OMV.Quaternion rotation)
|
||||
{
|
||||
_scene.TaintedObject("BSPrim.VehicleRotationParam", delegate()
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
_vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
|
||||
});
|
||||
}
|
||||
public override void VehicleFlags(int param, bool remove)
|
||||
{
|
||||
_scene.TaintedObject("BSPrim.VehicleFlags", delegate()
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
_vehicle.ProcessVehicleFlags(param, remove);
|
||||
});
|
||||
@@ -377,7 +385,7 @@ public sealed class BSPrim : BSPhysObject
|
||||
|
||||
// Called each simulation step to advance vehicle characteristics.
|
||||
// Called from Scene when doing simulation step so we're in taint processing time.
|
||||
public override void StepVehicle(float timeStep)
|
||||
public void StepVehicle(float timeStep)
|
||||
{
|
||||
if (IsPhysical)
|
||||
_vehicle.Step(timeStep);
|
||||
@@ -387,7 +395,7 @@ public sealed class BSPrim : BSPhysObject
|
||||
public override void SetVolumeDetect(int param) {
|
||||
bool newValue = (param != 0);
|
||||
_isVolumeDetect = newValue;
|
||||
_scene.TaintedObject("BSPrim.SetVolumeDetect", delegate()
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
SetObjectDynamic();
|
||||
});
|
||||
@@ -398,9 +406,9 @@ public sealed class BSPrim : BSPhysObject
|
||||
get { return _velocity; }
|
||||
set {
|
||||
_velocity = value;
|
||||
_scene.TaintedObject("BSPrim.setVelocity", delegate()
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity);
|
||||
DetailLog("{0},SetVelocity,taint,vel={1}", LocalID, _velocity);
|
||||
BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity);
|
||||
});
|
||||
}
|
||||
@@ -408,7 +416,7 @@ public sealed class BSPrim : BSPhysObject
|
||||
public override OMV.Vector3 Torque {
|
||||
get { return _torque; }
|
||||
set { _torque = value;
|
||||
DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque);
|
||||
DetailLog("{0},SetTorque,call,torque={1}", LocalID, _torque);
|
||||
}
|
||||
}
|
||||
public override float CollisionScore {
|
||||
@@ -422,7 +430,7 @@ public sealed class BSPrim : BSPhysObject
|
||||
}
|
||||
public override OMV.Quaternion Orientation {
|
||||
get {
|
||||
if (!Linkset.IsRoot(this))
|
||||
if (!_linkset.IsRoot(this))
|
||||
{
|
||||
// Children move around because tied to parent. Get a fresh value.
|
||||
_orientation = BulletSimAPI.GetObjectOrientation(_scene.WorldID, LocalID);
|
||||
@@ -432,10 +440,10 @@ public sealed class BSPrim : BSPhysObject
|
||||
set {
|
||||
_orientation = value;
|
||||
// TODO: what does it mean if a child in a linkset changes its orientation? Rebuild the constraint?
|
||||
_scene.TaintedObject("BSPrim.setOrientation", delegate()
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
// _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
|
||||
DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||
DetailLog("{0},setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||
BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
|
||||
});
|
||||
}
|
||||
@@ -449,7 +457,7 @@ public sealed class BSPrim : BSPhysObject
|
||||
get { return _isPhysical; }
|
||||
set {
|
||||
_isPhysical = value;
|
||||
_scene.TaintedObject("BSPrim.setIsPhysical", delegate()
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
SetObjectDynamic();
|
||||
});
|
||||
@@ -470,29 +478,26 @@ public sealed class BSPrim : BSPhysObject
|
||||
|
||||
// Make gravity work if the object is physical and not selected
|
||||
// No locking here because only called when it is safe
|
||||
// Only called at taint time so it is save to call into Bullet.
|
||||
private void SetObjectDynamic()
|
||||
{
|
||||
// If it's becoming dynamic, it will need hullness
|
||||
VerifyCorrectPhysicalShape();
|
||||
// RA: remove this for the moment.
|
||||
// The problem is that dynamic objects are hulls so if we are becoming physical
|
||||
// the shape has to be checked and possibly built.
|
||||
// Maybe a VerifyCorrectPhysicalShape() routine?
|
||||
// RecreateGeomAndObject();
|
||||
|
||||
// Bullet wants static objects to have a mass of zero
|
||||
float mass = IsStatic ? 0f : _mass;
|
||||
|
||||
DetailLog("{0},SetObjectDynamic,taint,static={1},solid={2},mass={3}", LocalID, IsStatic, IsSolid, mass);
|
||||
BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass);
|
||||
|
||||
// recompute any linkset parameters
|
||||
Linkset.Refresh(this);
|
||||
|
||||
CollisionFlags cf = BulletSimAPI.GetCollisionFlags2(Body.Ptr);
|
||||
DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, cf);
|
||||
}
|
||||
|
||||
// prims don't fly
|
||||
public override bool Flying {
|
||||
get { return _flying; }
|
||||
set {
|
||||
_flying = value;
|
||||
}
|
||||
set { _flying = value; }
|
||||
}
|
||||
public override bool SetAlwaysRun {
|
||||
get { return _setAlwaysRun; }
|
||||
@@ -541,9 +546,9 @@ public sealed class BSPrim : BSPhysObject
|
||||
set {
|
||||
_rotationalVelocity = value;
|
||||
// m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
|
||||
_scene.TaintedObject("BSPrim.setRotationalVelocity", delegate()
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
|
||||
DetailLog("{0},SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
|
||||
BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity);
|
||||
});
|
||||
}
|
||||
@@ -558,9 +563,9 @@ public sealed class BSPrim : BSPhysObject
|
||||
get { return _buoyancy; }
|
||||
set {
|
||||
_buoyancy = value;
|
||||
_scene.TaintedObject("BSPrim.setBuoyancy", delegate()
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
|
||||
DetailLog("{0},SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
|
||||
BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy);
|
||||
});
|
||||
}
|
||||
@@ -612,7 +617,7 @@ public sealed class BSPrim : BSPhysObject
|
||||
m_log.WarnFormat("{0}: Got a NaN force applied to a Character", LogHeader);
|
||||
return;
|
||||
}
|
||||
_scene.TaintedObject("BSPrim.AddForce", delegate()
|
||||
_scene.TaintedObject(delegate()
|
||||
{
|
||||
OMV.Vector3 fSum = OMV.Vector3.Zero;
|
||||
lock (m_accumulatedForces)
|
||||
@@ -623,17 +628,17 @@ public sealed class BSPrim : BSPhysObject
|
||||
}
|
||||
m_accumulatedForces.Clear();
|
||||
}
|
||||
DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, _force);
|
||||
DetailLog("{0},AddObjectForce,taint,force={1}", LocalID, _force);
|
||||
BulletSimAPI.AddObjectForce2(Body.Ptr, fSum);
|
||||
});
|
||||
}
|
||||
|
||||
public override void AddAngularForce(OMV.Vector3 force, bool pushforce) {
|
||||
DetailLog("{0},BSPrim.AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce);
|
||||
DetailLog("{0},AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce);
|
||||
// m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce);
|
||||
}
|
||||
public override void SetMomentum(OMV.Vector3 momentum) {
|
||||
DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum);
|
||||
DetailLog("{0},SetMomentum,call,mom={1}", LocalID, momentum);
|
||||
}
|
||||
public override void SubscribeEvents(int ms) {
|
||||
_subscribedEventsMs = ms;
|
||||
@@ -642,7 +647,7 @@ public sealed class BSPrim : BSPhysObject
|
||||
// make sure first collision happens
|
||||
_nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs;
|
||||
|
||||
Scene.TaintedObject("BSPrim.SubscribeEvents", delegate()
|
||||
Scene.TaintedObject(delegate()
|
||||
{
|
||||
BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||
});
|
||||
@@ -650,7 +655,7 @@ public sealed class BSPrim : BSPhysObject
|
||||
}
|
||||
public override void UnSubscribeEvents() {
|
||||
_subscribedEventsMs = 0;
|
||||
Scene.TaintedObject("BSPrim.UnSubscribeEvents", delegate()
|
||||
Scene.TaintedObject(delegate()
|
||||
{
|
||||
BulletSimAPI.RemoveFromCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||
});
|
||||
@@ -972,26 +977,26 @@ public sealed class BSPrim : BSPhysObject
|
||||
{
|
||||
if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
|
||||
{
|
||||
// if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
|
||||
// {
|
||||
if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
|
||||
{
|
||||
// m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size);
|
||||
if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE))
|
||||
{
|
||||
DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild);
|
||||
DetailLog("{0},CreateGeom,sphere", LocalID);
|
||||
_shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE;
|
||||
// Bullet native objects are scaled by the Bullet engine so pass the size in
|
||||
_scale = _size;
|
||||
// TODO: do we need to check for and destroy a mesh or hull that might have been left from before?
|
||||
ret = true;
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size);
|
||||
if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX))
|
||||
{
|
||||
DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild);
|
||||
DetailLog("{0},CreateGeom,box", LocalID);
|
||||
_shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX;
|
||||
_scale = _size;
|
||||
// TODO: do we need to check for and destroy a mesh or hull that might have been left from before?
|
||||
@@ -1027,26 +1032,19 @@ public sealed class BSPrim : BSPhysObject
|
||||
// No locking here because this is done when we know physics is not simulating
|
||||
private void CreateGeomMesh()
|
||||
{
|
||||
// level of detail based on size and type of the object
|
||||
float lod = _scene.MeshLOD;
|
||||
if (_pbs.SculptEntry)
|
||||
lod = _scene.SculptLOD;
|
||||
float maxAxis = Math.Max(_size.X, Math.Max(_size.Y, _size.Z));
|
||||
if (maxAxis > _scene.MeshMegaPrimThreshold)
|
||||
lod = _scene.MeshMegaPrimLOD;
|
||||
|
||||
float lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD;
|
||||
ulong newMeshKey = (ulong)_pbs.GetMeshKey(_size, lod);
|
||||
// m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey);
|
||||
|
||||
// if this new shape is the same as last time, don't recreate the mesh
|
||||
if (_meshKey == newMeshKey) return;
|
||||
|
||||
DetailLog("{0},BSPrim.CreateGeomMesh,create,key={1}", LocalID, newMeshKey);
|
||||
DetailLog("{0},CreateGeomMesh,create,key={1}", LocalID, _meshKey);
|
||||
// Since we're recreating new, get rid of any previously generated shape
|
||||
if (_meshKey != 0)
|
||||
{
|
||||
// m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey);
|
||||
DetailLog("{0},BSPrim.CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey);
|
||||
DetailLog("{0},CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey);
|
||||
BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey);
|
||||
_mesh = null;
|
||||
_meshKey = 0;
|
||||
@@ -1076,7 +1074,7 @@ public sealed class BSPrim : BSPhysObject
|
||||
_shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH;
|
||||
// meshes are already scaled by the meshmerizer
|
||||
_scale = new OMV.Vector3(1f, 1f, 1f);
|
||||
DetailLog("{0},BSPrim.CreateGeomMesh,done", LocalID);
|
||||
DetailLog("{0},CreateGeomMesh,done", LocalID);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1090,21 +1088,28 @@ public sealed class BSPrim : BSPhysObject
|
||||
// if the hull hasn't changed, don't rebuild it
|
||||
if (newHullKey == _hullKey) return;
|
||||
|
||||
DetailLog("{0},BSPrim.CreateGeomHull,create,oldKey={1},newKey={2}", LocalID, _hullKey, newHullKey);
|
||||
DetailLog("{0},CreateGeomHull,create,key={1}", LocalID, _meshKey);
|
||||
|
||||
// Since we're recreating new, get rid of any previously generated shape
|
||||
if (_hullKey != 0)
|
||||
{
|
||||
// m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey);
|
||||
DetailLog("{0},BSPrim.CreateGeomHull,deleteOldHull,key={1}", LocalID, _hullKey);
|
||||
DetailLog("{0},CreateGeomHull,deleteOldHull,key={1}", LocalID, _meshKey);
|
||||
BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey);
|
||||
_hullKey = 0;
|
||||
_hulls.Clear();
|
||||
DetailLog("{0},CreateGeomHull,deleteOldMesh,key={1}", LocalID, _meshKey);
|
||||
BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey);
|
||||
_mesh = null; // the mesh cannot match either
|
||||
_meshKey = 0;
|
||||
}
|
||||
|
||||
_hullKey = newHullKey;
|
||||
|
||||
// Make sure the underlying mesh exists and is correct
|
||||
CreateGeomMesh();
|
||||
if (_meshKey != _hullKey)
|
||||
{
|
||||
// if the underlying mesh has changed, rebuild it
|
||||
CreateGeomMesh();
|
||||
}
|
||||
|
||||
int[] indices = _mesh.getIndexListAsInt();
|
||||
List<OMV.Vector3> vertices = _mesh.getVertexList();
|
||||
@@ -1130,7 +1135,7 @@ public sealed class BSPrim : BSPhysObject
|
||||
// create the hull into the _hulls variable
|
||||
convexBuilder.process(dcomp);
|
||||
|
||||
// Convert the vertices and indices for passing to unmanaged.
|
||||
// Convert the vertices and indices for passing to unmanaged
|
||||
// The hull information is passed as a large floating point array.
|
||||
// The format is:
|
||||
// convHulls[0] = number of hulls
|
||||
@@ -1190,7 +1195,7 @@ public sealed class BSPrim : BSPhysObject
|
||||
_shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL;
|
||||
// meshes are already scaled by the meshmerizer
|
||||
_scale = new OMV.Vector3(1f, 1f, 1f);
|
||||
DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID);
|
||||
DetailLog("{0},CreateGeomHull,done", LocalID);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1202,27 +1207,6 @@ public sealed class BSPrim : BSPhysObject
|
||||
return;
|
||||
}
|
||||
|
||||
private void VerifyCorrectPhysicalShape()
|
||||
{
|
||||
if (IsStatic)
|
||||
{
|
||||
// if static, we don't need a hull so, if there is one, rebuild without it
|
||||
if (_hullKey != 0)
|
||||
{
|
||||
RecreateGeomAndObject();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if not static, it will need a hull to efficiently collide with things
|
||||
if (_hullKey == 0)
|
||||
{
|
||||
RecreateGeomAndObject();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Create an object in Bullet if it has not already been created
|
||||
// No locking here because this is done when the physics engine is not simulating
|
||||
// Returns 'true' if an object was actually created.
|
||||
@@ -1237,7 +1221,7 @@ public sealed class BSPrim : BSPhysObject
|
||||
bool ret = BulletSimAPI.CreateObject(_scene.WorldID, shape);
|
||||
|
||||
// the CreateObject() may have recreated the rigid body. Make sure we have the latest.
|
||||
Body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
|
||||
m_body.Ptr = BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1290,7 +1274,7 @@ public sealed class BSPrim : BSPhysObject
|
||||
const float ACCELERATION_TOLERANCE = 0.01f;
|
||||
const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f;
|
||||
|
||||
public override void UpdateProperties(EntityProperties entprop)
|
||||
public void UpdateProperties(EntityProperties entprop)
|
||||
{
|
||||
/*
|
||||
UpdatedProperties changed = 0;
|
||||
@@ -1338,7 +1322,7 @@ public sealed class BSPrim : BSPhysObject
|
||||
// Don't check for damping here -- it's done in BulletSim and SceneObjectPart.
|
||||
|
||||
// Updates only for individual prims and for the root object of a linkset.
|
||||
if (Linkset.IsRoot(this))
|
||||
if (_linkset.IsRoot(this))
|
||||
{
|
||||
// Assign to the local variables so the normal set action does not happen
|
||||
_position = entprop.Position;
|
||||
@@ -1347,7 +1331,9 @@ public sealed class BSPrim : BSPhysObject
|
||||
_acceleration = entprop.Acceleration;
|
||||
_rotationalVelocity = entprop.RotationalVelocity;
|
||||
|
||||
DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
|
||||
// m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}, vel={5}, acc={6}, rvel={7}",
|
||||
// LogHeader, LocalID, changed, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
|
||||
DetailLog("{0},UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
|
||||
LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
|
||||
|
||||
base.RequestPhysicsterseUpdate();
|
||||
@@ -1356,7 +1342,7 @@ public sealed class BSPrim : BSPhysObject
|
||||
else
|
||||
{
|
||||
// For debugging, we also report the movement of children
|
||||
DetailLog("{0},BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
|
||||
DetailLog("{0},UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
|
||||
LocalID, entprop.Position, entprop.Rotation, entprop.Velocity,
|
||||
entprop.Acceleration, entprop.RotationalVelocity);
|
||||
}
|
||||
@@ -1364,9 +1350,8 @@ public sealed class BSPrim : BSPhysObject
|
||||
}
|
||||
|
||||
// I've collided with something
|
||||
// Called at taint time from within the Step() function
|
||||
CollisionEventUpdate collisionCollection;
|
||||
public override void Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
|
||||
CollisionEventUpdate collisionCollection = null;
|
||||
public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
|
||||
{
|
||||
// m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);
|
||||
|
||||
@@ -1377,16 +1362,8 @@ public sealed class BSPrim : BSPhysObject
|
||||
_collidingGroundStep = _scene.SimulationStep;
|
||||
}
|
||||
|
||||
// DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith);
|
||||
|
||||
// prims in the same linkset cannot collide with each other
|
||||
if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// if someone has subscribed for collision events....
|
||||
if (SubscribedEvents()) {
|
||||
// if someone is subscribed to collision events....
|
||||
if (_subscribedEventsMs != 0) {
|
||||
// throttle the collisions to the number of milliseconds specified in the subscription
|
||||
int nowTime = _scene.SimulationNowTime;
|
||||
if (nowTime >= _nextCollisionOkTime) {
|
||||
@@ -1400,14 +1377,12 @@ public sealed class BSPrim : BSPhysObject
|
||||
}
|
||||
|
||||
// The scene is telling us it's time to pass our collected collisions into the simulator
|
||||
public override void SendCollisions()
|
||||
public void SendCollisions()
|
||||
{
|
||||
if (collisionCollection != null && collisionCollection.Count > 0)
|
||||
{
|
||||
base.SendCollisionUpdate(collisionCollection);
|
||||
// The collisionCollection structure is passed around in the simulator.
|
||||
// Make sure we don't have a handle to that one and that a new one is used next time.
|
||||
collisionCollection = null;
|
||||
collisionCollection.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@ using log4net;
|
||||
using OpenMetaverse;
|
||||
|
||||
// TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim)
|
||||
// Debug linkset
|
||||
// Test with multiple regions in one simulator
|
||||
// Adjust character capsule size when height is adjusted (ScenePresence.SetHeight)
|
||||
// Test sculpties
|
||||
// Compute physics FPS reasonably
|
||||
@@ -52,8 +54,10 @@ using OpenMetaverse;
|
||||
// Use collision masks for collision with terrain and phantom objects
|
||||
// Check out llVolumeDetect. Must do something for that.
|
||||
// Should prim.link() and prim.delink() membership checking happen at taint time?
|
||||
// changing the position and orientation of a linked prim must rebuild the constraint with the root.
|
||||
// Mesh sharing. Use meshHash to tell if we already have a hull of that shape and only create once
|
||||
// Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect
|
||||
// Implement the genCollisions feature in BulletSim::SetObjectProperties (don't pass up unneeded collisions)
|
||||
// Implement LockAngularMotion
|
||||
// Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation)
|
||||
// Does NeedsMeshing() really need to exclude all the different shapes?
|
||||
@@ -69,61 +73,62 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static readonly string LogHeader = "[BULLETS SCENE]";
|
||||
|
||||
// The name of the region we're working for.
|
||||
public string RegionName { get; private set; }
|
||||
public void DebugLog(string mm, params Object[] xx) { if (shouldDebugLog) m_log.DebugFormat(mm, xx); }
|
||||
|
||||
public string BulletSimVersion = "?";
|
||||
|
||||
public Dictionary<uint, BSPhysObject> PhysObjects = new Dictionary<uint, BSPhysObject>();
|
||||
|
||||
private HashSet<BSPhysObject> m_objectsWithCollisions = new HashSet<BSPhysObject>();
|
||||
// Following is a kludge and can be removed when avatar animation updating is
|
||||
// moved to a better place.
|
||||
private Dictionary<uint, BSCharacter> m_avatars = new Dictionary<uint, BSCharacter>();
|
||||
private Dictionary<uint, BSPrim> m_prims = new Dictionary<uint, BSPrim>();
|
||||
private HashSet<BSCharacter> m_avatarsWithCollisions = new HashSet<BSCharacter>();
|
||||
|
||||
// List of all the objects that have vehicle properties and should be called
|
||||
// to update each physics step.
|
||||
private List<BSPhysObject> m_vehicles = new List<BSPhysObject>();
|
||||
private HashSet<BSPrim> m_primsWithCollisions = new HashSet<BSPrim>();
|
||||
private List<BSPrim> m_vehicles = new List<BSPrim>();
|
||||
private float[] m_heightMap;
|
||||
private float m_waterLevel;
|
||||
private uint m_worldID;
|
||||
public uint WorldID { get { return m_worldID; } }
|
||||
|
||||
// let my minuions use my logger
|
||||
public ILog Logger { get { return m_log; } }
|
||||
|
||||
// If non-zero, the number of simulation steps between calls to the physics
|
||||
// engine to output detailed physics stats. Debug logging level must be on also.
|
||||
private bool m_initialized = false;
|
||||
|
||||
private int m_detailedStatsStep = 0;
|
||||
|
||||
public IMesher mesher;
|
||||
// Level of Detail values kept as float because that's what the Meshmerizer wants
|
||||
public float MeshLOD { get; private set; }
|
||||
public float MeshMegaPrimLOD { get; private set; }
|
||||
public float MeshMegaPrimThreshold { get; private set; }
|
||||
public float SculptLOD { get; private set; }
|
||||
private float m_meshLOD;
|
||||
public float MeshLOD
|
||||
{
|
||||
get { return m_meshLOD; }
|
||||
}
|
||||
private float m_sculptLOD;
|
||||
public float SculptLOD
|
||||
{
|
||||
get { return m_sculptLOD; }
|
||||
}
|
||||
|
||||
public uint WorldID { get; private set; }
|
||||
public BulletSim World { get; private set; }
|
||||
private BulletSim m_worldSim;
|
||||
public BulletSim World
|
||||
{
|
||||
get { return m_worldSim; }
|
||||
}
|
||||
private BSConstraintCollection m_constraintCollection;
|
||||
public BSConstraintCollection Constraints
|
||||
{
|
||||
get { return m_constraintCollection; }
|
||||
}
|
||||
|
||||
// All the constraints that have been allocated in this instance.
|
||||
public BSConstraintCollection Constraints { get; private set; }
|
||||
|
||||
// Simulation parameters
|
||||
private int m_maxSubSteps;
|
||||
private float m_fixedTimeStep;
|
||||
private long m_simulationStep = 0;
|
||||
public long SimulationStep { get { return m_simulationStep; } }
|
||||
|
||||
// The length of the last timestep we were asked to simulate.
|
||||
// This is used by the vehicle code. Since the vehicle code is called
|
||||
// once per simulation step, its constants need to be scaled by this.
|
||||
public float LastSimulatedTimestep { get; private set; }
|
||||
|
||||
// A value of the time now so all the collision and update routines do not have to get their own
|
||||
// Set to 'now' just before all the prims and actors are called for collisions and updates
|
||||
public int SimulationNowTime { get; private set; }
|
||||
private int m_simulationNowTime;
|
||||
public int SimulationNowTime { get { return m_simulationNowTime; } }
|
||||
|
||||
// True if initialized and ready to do simulation steps
|
||||
private bool m_initialized = false;
|
||||
|
||||
// Pinned memory used to pass step information between managed and unmanaged
|
||||
private int m_maxCollisionsPerFrame;
|
||||
private CollisionDesc[] m_collisionArray;
|
||||
private GCHandle m_collisionArrayPinnedHandle;
|
||||
@@ -140,10 +145,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
|
||||
public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero
|
||||
public const uint GROUNDPLANE_ID = 1;
|
||||
public const uint CHILDTERRAIN_ID = 2; // Terrain allocated based on our mega-prim childre start here
|
||||
|
||||
private float m_waterLevel;
|
||||
public BSTerrainManager TerrainManager { get; private set; }
|
||||
|
||||
public ConfigurationParameters Params
|
||||
{
|
||||
@@ -154,34 +155,22 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
get { return new Vector3(0f, 0f, Params.gravity); }
|
||||
}
|
||||
|
||||
public float MaximumObjectMass { get; private set; }
|
||||
|
||||
// When functions in the unmanaged code must be called, it is only
|
||||
// done at a known time just before the simulation step. The taint
|
||||
// system saves all these function calls and executes them in
|
||||
// order before the simulation.
|
||||
public delegate void TaintCallback();
|
||||
private struct TaintCallbackEntry
|
||||
private float m_maximumObjectMass;
|
||||
public float MaximumObjectMass
|
||||
{
|
||||
public String ident;
|
||||
public TaintCallback callback;
|
||||
public TaintCallbackEntry(string i, TaintCallback c)
|
||||
{
|
||||
ident = i;
|
||||
callback = c;
|
||||
}
|
||||
get { return m_maximumObjectMass; }
|
||||
}
|
||||
private List<TaintCallbackEntry> _taintedObjects;
|
||||
|
||||
public delegate void TaintCallback();
|
||||
private List<TaintCallback> _taintedObjects;
|
||||
private Object _taintLock = new Object();
|
||||
|
||||
// A pointer to an instance if this structure is passed to the C++ code
|
||||
// Used to pass basic configuration values to the unmanaged code.
|
||||
ConfigurationParameters[] m_params;
|
||||
GCHandle m_paramsHandle;
|
||||
|
||||
// Handle to the callback used by the unmanaged code to call into the managed code.
|
||||
// Used for debug logging.
|
||||
// Need to store the handle in a persistant variable so it won't be freed.
|
||||
public bool shouldDebugLog { get; private set; }
|
||||
|
||||
private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle;
|
||||
|
||||
// Sometimes you just have to log everything.
|
||||
@@ -190,15 +179,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
private string m_physicsLoggingDir;
|
||||
private string m_physicsLoggingPrefix;
|
||||
private int m_physicsLoggingFileMinutes;
|
||||
// 'true' of the vehicle code is to log lots of details
|
||||
public bool VehicleLoggingEnabled { get; private set; }
|
||||
|
||||
#region Construction and Initialization
|
||||
private bool m_vehicleLoggingEnabled;
|
||||
public bool VehicleLoggingEnabled { get { return m_vehicleLoggingEnabled; } }
|
||||
|
||||
public BSScene(string identifier)
|
||||
{
|
||||
m_initialized = false;
|
||||
// we are passed the name of the region we're working for.
|
||||
RegionName = identifier;
|
||||
}
|
||||
|
||||
public override void Initialise(IMesher meshmerizer, IConfigSource config)
|
||||
@@ -216,9 +203,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
m_updateArray = new EntityProperties[m_maxUpdatesPerFrame];
|
||||
m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned);
|
||||
|
||||
mesher = meshmerizer;
|
||||
_taintedObjects = new List<TaintCallbackEntry>();
|
||||
|
||||
// Enable very detailed logging.
|
||||
// By creating an empty logger when not logging, the log message invocation code
|
||||
// can be left in and every call doesn't have to check for null.
|
||||
@@ -231,43 +215,38 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
PhysicsLogging = new Logging.LogWriter();
|
||||
}
|
||||
|
||||
// If Debug logging level, enable logging from the unmanaged code
|
||||
m_DebugLogCallbackHandle = null;
|
||||
if (m_log.IsDebugEnabled || PhysicsLogging.Enabled)
|
||||
{
|
||||
m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader);
|
||||
if (PhysicsLogging.Enabled)
|
||||
// The handle is saved in a variable to make sure it doesn't get freed after this call
|
||||
m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLoggerPhysLog);
|
||||
else
|
||||
m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger);
|
||||
}
|
||||
|
||||
// Get the version of the DLL
|
||||
// TODO: this doesn't work yet. Something wrong with marshaling the returned string.
|
||||
// BulletSimVersion = BulletSimAPI.GetVersion();
|
||||
// m_log.WarnFormat("{0}: BulletSim.dll version='{1}'", LogHeader, BulletSimVersion);
|
||||
|
||||
// The bounding box for the simulated world. The origin is 0,0,0 unless we're
|
||||
// a child in a mega-region.
|
||||
// Turns out that Bullet really doesn't care about the extents of the simulated
|
||||
// area. It tracks active objects no matter where they are.
|
||||
// if Debug, enable logging from the unmanaged code
|
||||
if (m_log.IsDebugEnabled || PhysicsLogging.Enabled)
|
||||
{
|
||||
m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader);
|
||||
if (PhysicsLogging.Enabled)
|
||||
m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLoggerPhysLog);
|
||||
else
|
||||
m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger);
|
||||
// the handle is saved in a variable to make sure it doesn't get freed after this call
|
||||
BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle);
|
||||
}
|
||||
|
||||
_taintedObjects = new List<TaintCallback>();
|
||||
|
||||
mesher = meshmerizer;
|
||||
// The bounding box for the simulated world
|
||||
Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 8192f);
|
||||
|
||||
// m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader);
|
||||
WorldID = BulletSimAPI.Initialize(worldExtent, m_paramsHandle.AddrOfPinnedObject(),
|
||||
m_worldID = BulletSimAPI.Initialize(worldExtent, m_paramsHandle.AddrOfPinnedObject(),
|
||||
m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(),
|
||||
m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject(),
|
||||
m_DebugLogCallbackHandle);
|
||||
m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject());
|
||||
|
||||
// Initialization to support the transition to a new API which puts most of the logic
|
||||
// into the C# code so it is easier to modify and add to.
|
||||
World = new BulletSim(WorldID, this, BulletSimAPI.GetSimHandle2(WorldID));
|
||||
|
||||
Constraints = new BSConstraintCollection(World);
|
||||
|
||||
TerrainManager = new BSTerrainManager(this);
|
||||
TerrainManager.CreateInitialGroundPlaneAndTerrain();
|
||||
m_worldSim = new BulletSim(m_worldID, BulletSimAPI.GetSimHandle2(m_worldID));
|
||||
m_constraintCollection = new BSConstraintCollection(World);
|
||||
|
||||
m_initialized = true;
|
||||
}
|
||||
@@ -292,13 +271,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
// Very detailed logging for physics debugging
|
||||
m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false);
|
||||
m_physicsLoggingDir = pConfig.GetString("PhysicsLoggingDir", ".");
|
||||
m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-%REGIONNAME%-");
|
||||
m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-");
|
||||
m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5);
|
||||
// Very detailed logging for vehicle debugging
|
||||
VehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false);
|
||||
|
||||
// Do any replacements in the parameters
|
||||
m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName);
|
||||
m_vehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -330,38 +306,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
PhysicsLogging.Write("[BULLETS UNMANAGED]:" + msg);
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
// m_log.DebugFormat("{0}: Dispose()", LogHeader);
|
||||
|
||||
// make sure no stepping happens while we're deleting stuff
|
||||
m_initialized = false;
|
||||
|
||||
TerrainManager.ReleaseGroundPlaneAndTerrain();
|
||||
|
||||
foreach (KeyValuePair<uint, BSPhysObject> kvp in PhysObjects)
|
||||
{
|
||||
kvp.Value.Destroy();
|
||||
}
|
||||
PhysObjects.Clear();
|
||||
|
||||
// Now that the prims are all cleaned up, there should be no constraints left
|
||||
if (Constraints != null)
|
||||
{
|
||||
Constraints.Dispose();
|
||||
Constraints = null;
|
||||
}
|
||||
|
||||
// Anything left in the unmanaged code should be cleaned out
|
||||
BulletSimAPI.Shutdown(WorldID);
|
||||
|
||||
// Not logging any more
|
||||
PhysicsLogging.Close();
|
||||
}
|
||||
#endregion // Construction and Initialization
|
||||
|
||||
#region Prim and Avatar addition and removal
|
||||
|
||||
public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying)
|
||||
{
|
||||
m_log.ErrorFormat("{0}: CALL TO AddAvatar in BSScene. NOT IMPLEMENTED", LogHeader);
|
||||
@@ -375,13 +319,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
if (!m_initialized) return null;
|
||||
|
||||
BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying);
|
||||
lock (PhysObjects) PhysObjects.Add(localID, actor);
|
||||
|
||||
// TODO: Remove kludge someday.
|
||||
// We must generate a collision for avatars whether they collide or not.
|
||||
// This is required by OpenSim to update avatar animations, etc.
|
||||
lock (m_avatarsWithCollisions) m_avatarsWithCollisions.Add(actor);
|
||||
|
||||
lock (m_avatars) m_avatars.Add(localID, actor);
|
||||
return actor;
|
||||
}
|
||||
|
||||
@@ -396,9 +334,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (PhysObjects) PhysObjects.Remove(actor.LocalID);
|
||||
// Remove kludge someday
|
||||
lock (m_avatarsWithCollisions) m_avatarsWithCollisions.Remove(bsactor);
|
||||
lock (m_avatars) m_avatars.Remove(actor.LocalID);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -416,11 +352,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
BSPrim bsprim = prim as BSPrim;
|
||||
if (bsprim != null)
|
||||
{
|
||||
DetailLog("{0},RemovePrim,call", bsprim.LocalID);
|
||||
// m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID);
|
||||
m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID);
|
||||
try
|
||||
{
|
||||
lock (PhysObjects) PhysObjects.Remove(bsprim.LocalID);
|
||||
lock (m_prims) m_prims.Remove(bsprim.LocalID);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -442,10 +377,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
|
||||
if (!m_initialized) return null;
|
||||
|
||||
DetailLog("{0},AddPrimShape,call", localID);
|
||||
|
||||
BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical);
|
||||
lock (PhysObjects) PhysObjects.Add(localID, prim);
|
||||
lock (m_prims) m_prims.Add(localID, prim);
|
||||
return prim;
|
||||
}
|
||||
|
||||
@@ -454,9 +387,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
// information call is not needed.
|
||||
public override void AddPhysicsActorTaint(PhysicsActor prim) { }
|
||||
|
||||
#endregion // Prim and Avatar addition and removal
|
||||
|
||||
#region Simulation
|
||||
// Simulate one timestep
|
||||
public override float Simulate(float timeStep)
|
||||
{
|
||||
@@ -470,10 +400,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
// prevent simulation until we've been initialized
|
||||
if (!m_initialized) return 10.0f;
|
||||
|
||||
int simulateStartTime = Util.EnvironmentTickCount();
|
||||
long simulateStartTime = Util.EnvironmentTickCount();
|
||||
|
||||
// update the prim states while we know the physics engine is not busy
|
||||
int numTaints = _taintedObjects.Count;
|
||||
ProcessTaints();
|
||||
|
||||
// Some of the prims operate with special vehicle properties
|
||||
@@ -485,18 +414,15 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
int numSubSteps = 0;
|
||||
try
|
||||
{
|
||||
numSubSteps = BulletSimAPI.PhysicsStep(WorldID, timeStep, m_maxSubSteps, m_fixedTimeStep,
|
||||
numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep,
|
||||
out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr);
|
||||
DetailLog("{0},Simulate,call, nTaints= {1}, substeps={2}, updates={3}, colliders={4}",
|
||||
DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount);
|
||||
DetailLog("{0},Simulate,call, substeps={1}, updates={2}, colliders={3}", "0000000000", numSubSteps, updatedEntityCount, collidersCount);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.WarnFormat("{0},PhysicsStep Exception: nTaints={1}, substeps={2}, updates={3}, colliders={4}, e={5}",
|
||||
LogHeader, numTaints, numSubSteps, updatedEntityCount, collidersCount, e);
|
||||
DetailLog("{0},PhysicsStepException,call, nTaints={1}, substeps={2}, updates={3}, colliders={4}",
|
||||
DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount);
|
||||
updatedEntityCount = 0;
|
||||
m_log.WarnFormat("{0},PhysicsStep Exception: substeps={1}, updates={2}, colliders={3}, e={4}", LogHeader, numSubSteps, updatedEntityCount, collidersCount, e);
|
||||
DetailLog("{0},PhysicsStepException,call, substeps={1}, updates={2}, colliders={3}", "0000000000", numSubSteps, updatedEntityCount, collidersCount);
|
||||
// updatedEntityCount = 0;
|
||||
collidersCount = 0;
|
||||
}
|
||||
|
||||
@@ -504,7 +430,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
// Don't have to use the pointers passed back since we know it is the same pinned memory we passed in
|
||||
|
||||
// Get a value for 'now' so all the collision and update routines don't have to get their own
|
||||
SimulationNowTime = Util.EnvironmentTickCount();
|
||||
m_simulationNowTime = Util.EnvironmentTickCount();
|
||||
|
||||
// If there were collisions, process them by sending the event to the prim.
|
||||
// Collisions must be processed before updates.
|
||||
@@ -523,16 +449,19 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
|
||||
// The above SendCollision's batch up the collisions on the objects.
|
||||
// Now push the collisions into the simulator.
|
||||
foreach (BSPhysObject bsp in m_objectsWithCollisions)
|
||||
foreach (BSPrim bsp in m_primsWithCollisions)
|
||||
bsp.SendCollisions();
|
||||
m_objectsWithCollisions.Clear();
|
||||
m_primsWithCollisions.Clear();
|
||||
|
||||
// This is a kludge to get avatar movement updated.
|
||||
// Don't send collisions only if there were collisions -- send everytime.
|
||||
// ODE sends collisions even if there are none and this is used to update
|
||||
// avatar animations and stuff.
|
||||
foreach (BSPhysObject bpo in m_avatarsWithCollisions)
|
||||
bpo.SendCollisions();
|
||||
// m_avatarsWithCollisions.Clear();
|
||||
// foreach (BSCharacter bsc in m_avatarsWithCollisions)
|
||||
// bsc.SendCollisions();
|
||||
foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars)
|
||||
kvp.Value.SendCollisions();
|
||||
m_avatarsWithCollisions.Clear();
|
||||
|
||||
// If any of the objects had updated properties, tell the object it has been changed by the physics engine
|
||||
if (updatedEntityCount > 0)
|
||||
@@ -540,10 +469,16 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
for (int ii = 0; ii < updatedEntityCount; ii++)
|
||||
{
|
||||
EntityProperties entprop = m_updateArray[ii];
|
||||
BSPhysObject pobj;
|
||||
if (PhysObjects.TryGetValue(entprop.ID, out pobj))
|
||||
BSPrim prim;
|
||||
if (m_prims.TryGetValue(entprop.ID, out prim))
|
||||
{
|
||||
pobj.UpdateProperties(entprop);
|
||||
prim.UpdateProperties(entprop);
|
||||
continue;
|
||||
}
|
||||
BSCharacter actor;
|
||||
if (m_avatars.TryGetValue(entprop.ID, out actor))
|
||||
{
|
||||
actor.UpdateProperties(entprop);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -563,57 +498,61 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
// long simulateTotalTime = Util.EnvironmentTickCountSubtract(simulateStartTime);
|
||||
// return (timeStep * (float)simulateTotalTime);
|
||||
|
||||
// TODO: FIX THIS: fps calculation possibly wrong.
|
||||
// This calculation says 1/timeStep is the ideal frame rate. Any time added to
|
||||
// that by the physics simulation gives a slower frame rate.
|
||||
long totalSimulationTime = Util.EnvironmentTickCountSubtract(simulateStartTime);
|
||||
if (totalSimulationTime >= timeStep)
|
||||
return 0;
|
||||
return 1f / (timeStep + totalSimulationTime);
|
||||
// TODO: FIX THIS: fps calculation wrong. This calculation always returns about 1 in normal operation.
|
||||
return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f;
|
||||
}
|
||||
|
||||
// Something has collided
|
||||
private void SendCollision(uint localID, uint collidingWith, Vector3 collidePoint, Vector3 collideNormal, float penetration)
|
||||
private void SendCollision(uint localID, uint collidingWith, Vector3 collidePoint, Vector3 collideNormal, float penitration)
|
||||
{
|
||||
if (localID <= TerrainManager.HighestTerrainID)
|
||||
if (localID == TERRAIN_ID || localID == GROUNDPLANE_ID)
|
||||
{
|
||||
return; // don't send collisions to the terrain
|
||||
}
|
||||
|
||||
BSPhysObject collider = PhysObjects[localID];
|
||||
// TODO: as of this code, terrain was not in the physical object list.
|
||||
// When BSTerrain is created and it will be in the list, we can remove
|
||||
// the possibility that it's not there and just fetch the collidee.
|
||||
BSPhysObject collidee = null;
|
||||
|
||||
ActorTypes type = ActorTypes.Prim;
|
||||
if (collidingWith <= TerrainManager.HighestTerrainID)
|
||||
{
|
||||
if (collidingWith == TERRAIN_ID || collidingWith == GROUNDPLANE_ID)
|
||||
type = ActorTypes.Ground;
|
||||
else if (m_avatars.ContainsKey(collidingWith))
|
||||
type = ActorTypes.Agent;
|
||||
|
||||
BSPrim prim;
|
||||
if (m_prims.TryGetValue(localID, out prim)) {
|
||||
prim.Collide(collidingWith, type, collidePoint, collideNormal, penitration);
|
||||
m_primsWithCollisions.Add(prim);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
collidee = PhysObjects[collidingWith];
|
||||
if (collidee is BSCharacter)
|
||||
type = ActorTypes.Agent;
|
||||
BSCharacter actor;
|
||||
if (m_avatars.TryGetValue(localID, out actor)) {
|
||||
actor.Collide(collidingWith, type, collidePoint, collideNormal, penitration);
|
||||
m_avatarsWithCollisions.Add(actor);
|
||||
return;
|
||||
}
|
||||
|
||||
// DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith);
|
||||
|
||||
collider.Collide(collidingWith, collidee, type, collidePoint, collideNormal, penetration);
|
||||
m_objectsWithCollisions.Add(collider);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#endregion // Simulation
|
||||
|
||||
public override void GetResults() { }
|
||||
|
||||
#region Terrain
|
||||
|
||||
public override void SetTerrain(float[] heightMap) {
|
||||
TerrainManager.SetTerrain(heightMap);
|
||||
m_heightMap = heightMap;
|
||||
this.TaintedObject(delegate()
|
||||
{
|
||||
BulletSimAPI.SetHeightmap(m_worldID, m_heightMap);
|
||||
});
|
||||
}
|
||||
|
||||
// Someday we will have complex terrain with caves and tunnels
|
||||
// For the moment, it's flat and convex
|
||||
public float GetTerrainHeightAtXYZ(Vector3 loc)
|
||||
{
|
||||
return GetTerrainHeightAtXY(loc.X, loc.Y);
|
||||
}
|
||||
|
||||
public float GetTerrainHeightAtXY(float tX, float tY)
|
||||
{
|
||||
if (tX < 0 || tX >= Constants.RegionSize || tY < 0 || tY >= Constants.RegionSize)
|
||||
return 30;
|
||||
return m_heightMap[((int)tX) * Constants.RegionSize + ((int)tY)];
|
||||
}
|
||||
|
||||
public override void SetWaterLevel(float baseheight)
|
||||
@@ -631,26 +570,37 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
// m_log.DebugFormat("{0}: DeleteTerrain()", LogHeader);
|
||||
}
|
||||
|
||||
// Although no one seems to check this, I do support combining.
|
||||
public override bool SupportsCombining()
|
||||
public override void Dispose()
|
||||
{
|
||||
return TerrainManager.SupportsCombining();
|
||||
}
|
||||
// This call says I am a child to region zero in a mega-region. 'pScene' is that
|
||||
// of region zero, 'offset' is my offset from regions zero's origin, and
|
||||
// 'extents' is the largest XY that is handled in my region.
|
||||
public override void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents)
|
||||
{
|
||||
TerrainManager.Combine(pScene, offset, extents);
|
||||
}
|
||||
// m_log.DebugFormat("{0}: Dispose()", LogHeader);
|
||||
|
||||
// Unhook all the combining that I know about.
|
||||
public override void UnCombine(PhysicsScene pScene)
|
||||
{
|
||||
TerrainManager.UnCombine(pScene);
|
||||
}
|
||||
// make sure no stepping happens while we're deleting stuff
|
||||
m_initialized = false;
|
||||
|
||||
#endregion // Terrain
|
||||
if (m_constraintCollection != null)
|
||||
{
|
||||
m_constraintCollection.Dispose();
|
||||
m_constraintCollection = null;
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars)
|
||||
{
|
||||
kvp.Value.Destroy();
|
||||
}
|
||||
m_avatars.Clear();
|
||||
|
||||
foreach (KeyValuePair<uint, BSPrim> kvp in m_prims)
|
||||
{
|
||||
kvp.Value.Destroy();
|
||||
}
|
||||
m_prims.Clear();
|
||||
|
||||
// Anything left in the unmanaged code should be cleaned out
|
||||
BulletSimAPI.Shutdown(WorldID);
|
||||
|
||||
// Not logging any more
|
||||
PhysicsLogging.Close();
|
||||
}
|
||||
|
||||
public override Dictionary<uint, float> GetTopColliders()
|
||||
{
|
||||
@@ -777,12 +727,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
// Calls to the PhysicsActors can't directly call into the physics engine
|
||||
// because it might be busy. We delay changes to a known time.
|
||||
// We rely on C#'s closure to save and restore the context for the delegate.
|
||||
public void TaintedObject(String ident, TaintCallback callback)
|
||||
public void TaintedObject(TaintCallback callback)
|
||||
{
|
||||
if (!m_initialized) return;
|
||||
|
||||
lock (_taintLock)
|
||||
_taintedObjects.Add(new TaintCallbackEntry(ident, callback));
|
||||
_taintedObjects.Add(callback);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -794,22 +744,22 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
if (_taintedObjects.Count > 0) // save allocating new list if there is nothing to process
|
||||
{
|
||||
// swizzle a new list into the list location so we can process what's there
|
||||
List<TaintCallbackEntry> oldList;
|
||||
List<TaintCallback> oldList;
|
||||
lock (_taintLock)
|
||||
{
|
||||
oldList = _taintedObjects;
|
||||
_taintedObjects = new List<TaintCallbackEntry>();
|
||||
_taintedObjects = new List<TaintCallback>();
|
||||
}
|
||||
|
||||
foreach (TaintCallbackEntry tcbe in oldList)
|
||||
foreach (TaintCallback callback in oldList)
|
||||
{
|
||||
try
|
||||
{
|
||||
tcbe.callback();
|
||||
callback();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("{0}: ProcessTaints: {1}: Exception: {2}", LogHeader, tcbe.ident, e);
|
||||
m_log.ErrorFormat("{0}: ProcessTaints: Exception: {1}", LogHeader, e);
|
||||
}
|
||||
}
|
||||
oldList.Clear();
|
||||
@@ -817,20 +767,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
}
|
||||
|
||||
#region Vehicles
|
||||
|
||||
public void VehicleInSceneTypeChanged(BSPrim vehic, Vehicle newType)
|
||||
{
|
||||
if (newType == Vehicle.TYPE_NONE)
|
||||
{
|
||||
RemoveVehiclePrim(vehic);
|
||||
}
|
||||
else
|
||||
{
|
||||
// make it so the scene will call us each tick to do vehicle things
|
||||
AddVehiclePrim(vehic);
|
||||
}
|
||||
}
|
||||
|
||||
// Make so the scene will call this prim for vehicle actions each tick.
|
||||
// Safe to call if prim is already in the vehicle list.
|
||||
public void AddVehiclePrim(BSPrim vehicle)
|
||||
@@ -861,14 +797,14 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
// no locking because only called when physics engine is not busy
|
||||
private void ProcessVehicles(float timeStep)
|
||||
{
|
||||
foreach (BSPhysObject pobj in m_vehicles)
|
||||
foreach (BSPrim prim in m_vehicles)
|
||||
{
|
||||
pobj.StepVehicle(timeStep);
|
||||
prim.StepVehicle(timeStep);
|
||||
}
|
||||
}
|
||||
#endregion Vehicles
|
||||
|
||||
#region INI and command line parameter processing
|
||||
#region Parameters
|
||||
|
||||
delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val);
|
||||
delegate float ParamGet(BSScene scene);
|
||||
@@ -876,12 +812,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
|
||||
private struct ParameterDefn
|
||||
{
|
||||
public string name; // string name of the parameter
|
||||
public string desc; // a short description of what the parameter means
|
||||
public float defaultValue; // default value if not specified anywhere else
|
||||
public ParamUser userParam; // get the value from the configuration file
|
||||
public ParamGet getter; // return the current value stored for this parameter
|
||||
public ParamSet setter; // set the current value for this parameter
|
||||
public string name;
|
||||
public string desc;
|
||||
public float defaultValue;
|
||||
public ParamUser userParam;
|
||||
public ParamGet getter;
|
||||
public ParamSet setter;
|
||||
public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s)
|
||||
{
|
||||
name = n;
|
||||
@@ -898,7 +834,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
// To add a new externally referencable/settable parameter, add the paramter storage
|
||||
// location somewhere in the program and make an entry in this table with the
|
||||
// getters and setters.
|
||||
// It is easiest to find an existing definition and copy it.
|
||||
// To add a new variable, it is easiest to find an existing definition and copy it.
|
||||
// Parameter values are floats. Booleans are converted to a floating value.
|
||||
//
|
||||
// A ParameterDefn() takes the following parameters:
|
||||
@@ -928,26 +864,16 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
(s) => { return s.NumericBool(s._forceSimplePrimMeshing); },
|
||||
(s,p,l,v) => { s._forceSimplePrimMeshing = s.BoolNumeric(v); } ),
|
||||
|
||||
new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)",
|
||||
new ParameterDefn("MeshLOD", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)",
|
||||
8f,
|
||||
(s,cf,p,v) => { s.MeshLOD = (float)cf.GetInt(p, (int)v); },
|
||||
(s) => { return s.MeshLOD; },
|
||||
(s,p,l,v) => { s.MeshLOD = v; } ),
|
||||
new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters",
|
||||
16f,
|
||||
(s,cf,p,v) => { s.MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); },
|
||||
(s) => { return s.MeshMegaPrimLOD; },
|
||||
(s,p,l,v) => { s.MeshMegaPrimLOD = v; } ),
|
||||
new ParameterDefn("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD",
|
||||
10f,
|
||||
(s,cf,p,v) => { s.MeshMegaPrimThreshold = (float)cf.GetInt(p, (int)v); },
|
||||
(s) => { return s.MeshMegaPrimThreshold; },
|
||||
(s,p,l,v) => { s.MeshMegaPrimThreshold = v; } ),
|
||||
new ParameterDefn("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)",
|
||||
32f,
|
||||
(s,cf,p,v) => { s.SculptLOD = (float)cf.GetInt(p, (int)v); },
|
||||
(s) => { return s.SculptLOD; },
|
||||
(s,p,l,v) => { s.SculptLOD = v; } ),
|
||||
(s,cf,p,v) => { s.m_meshLOD = cf.GetInt(p, (int)v); },
|
||||
(s) => { return (float)s.m_meshLOD; },
|
||||
(s,p,l,v) => { s.m_meshLOD = (int)v; } ),
|
||||
new ParameterDefn("SculptLOD", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)",
|
||||
32,
|
||||
(s,cf,p,v) => { s.m_sculptLOD = cf.GetInt(p, (int)v); },
|
||||
(s) => { return (float)s.m_sculptLOD; },
|
||||
(s,p,l,v) => { s.m_sculptLOD = (int)v; } ),
|
||||
|
||||
new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps",
|
||||
10f,
|
||||
@@ -971,9 +897,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
(s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ),
|
||||
new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)",
|
||||
10000.01f,
|
||||
(s,cf,p,v) => { s.MaximumObjectMass = cf.GetFloat(p, v); },
|
||||
(s) => { return (float)s.MaximumObjectMass; },
|
||||
(s,p,l,v) => { s.MaximumObjectMass = v; } ),
|
||||
(s,cf,p,v) => { s.m_maximumObjectMass = cf.GetFloat(p, v); },
|
||||
(s) => { return (float)s.m_maximumObjectMass; },
|
||||
(s,p,l,v) => { s.m_maximumObjectMass = v; } ),
|
||||
|
||||
new ParameterDefn("PID_D", "Derivitive factor for motion smoothing",
|
||||
2200f,
|
||||
@@ -1017,42 +943,42 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
0f,
|
||||
(s,cf,p,v) => { s.m_params[0].linearDamping = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].linearDamping; },
|
||||
(s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearDamping, p, l, v); } ),
|
||||
(s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].linearDamping, p, l, v); } ),
|
||||
new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)",
|
||||
0f,
|
||||
(s,cf,p,v) => { s.m_params[0].angularDamping = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].angularDamping; },
|
||||
(s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularDamping, p, l, v); } ),
|
||||
(s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].angularDamping, p, l, v); } ),
|
||||
new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static",
|
||||
0.2f,
|
||||
(s,cf,p,v) => { s.m_params[0].deactivationTime = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].deactivationTime; },
|
||||
(s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].deactivationTime, p, l, v); } ),
|
||||
(s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].deactivationTime, p, l, v); } ),
|
||||
new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static",
|
||||
0.8f,
|
||||
(s,cf,p,v) => { s.m_params[0].linearSleepingThreshold = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].linearSleepingThreshold; },
|
||||
(s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearSleepingThreshold, p, l, v); } ),
|
||||
(s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].linearSleepingThreshold, p, l, v); } ),
|
||||
new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static",
|
||||
1.0f,
|
||||
(s,cf,p,v) => { s.m_params[0].angularSleepingThreshold = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].angularSleepingThreshold; },
|
||||
(s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularSleepingThreshold, p, l, v); } ),
|
||||
(s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].angularSleepingThreshold, p, l, v); } ),
|
||||
new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" ,
|
||||
0f, // set to zero to disable
|
||||
(s,cf,p,v) => { s.m_params[0].ccdMotionThreshold = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].ccdMotionThreshold; },
|
||||
(s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdMotionThreshold, p, l, v); } ),
|
||||
(s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].ccdMotionThreshold, p, l, v); } ),
|
||||
new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" ,
|
||||
0f,
|
||||
(s,cf,p,v) => { s.m_params[0].ccdSweptSphereRadius = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].ccdSweptSphereRadius; },
|
||||
(s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdSweptSphereRadius, p, l, v); } ),
|
||||
(s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].ccdSweptSphereRadius, p, l, v); } ),
|
||||
new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" ,
|
||||
0.1f,
|
||||
(s,cf,p,v) => { s.m_params[0].contactProcessingThreshold = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].contactProcessingThreshold; },
|
||||
(s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].contactProcessingThreshold, p, l, v); } ),
|
||||
(s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].contactProcessingThreshold, p, l, v); } ),
|
||||
|
||||
new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" ,
|
||||
0.5f,
|
||||
@@ -1070,50 +996,45 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
(s) => { return s.m_params[0].terrainRestitution; },
|
||||
(s,p,l,v) => { s.m_params[0].terrainRestitution = v; s.TaintedUpdateParameter(p,l,v); } ),
|
||||
new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.",
|
||||
0.2f,
|
||||
0.5f,
|
||||
(s,cf,p,v) => { s.m_params[0].avatarFriction = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].avatarFriction; },
|
||||
(s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarFriction, p, l, v); } ),
|
||||
(s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarFriction, p, l, v); } ),
|
||||
new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.",
|
||||
60f,
|
||||
(s,cf,p,v) => { s.m_params[0].avatarDensity = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].avatarDensity; },
|
||||
(s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarDensity, p, l, v); } ),
|
||||
(s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarDensity, p, l, v); } ),
|
||||
new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.",
|
||||
0f,
|
||||
(s,cf,p,v) => { s.m_params[0].avatarRestitution = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].avatarRestitution; },
|
||||
(s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarRestitution, p, l, v); } ),
|
||||
(s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarRestitution, p, l, v); } ),
|
||||
new ParameterDefn("AvatarCapsuleRadius", "Radius of space around an avatar",
|
||||
0.37f,
|
||||
(s,cf,p,v) => { s.m_params[0].avatarCapsuleRadius = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].avatarCapsuleRadius; },
|
||||
(s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleRadius, p, l, v); } ),
|
||||
(s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarCapsuleRadius, p, l, v); } ),
|
||||
new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar",
|
||||
1.5f,
|
||||
(s,cf,p,v) => { s.m_params[0].avatarCapsuleHeight = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].avatarCapsuleHeight; },
|
||||
(s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleHeight, p, l, v); } ),
|
||||
(s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarCapsuleHeight, p, l, v); } ),
|
||||
new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions",
|
||||
0.1f,
|
||||
(s,cf,p,v) => { s.m_params[0].avatarContactProcessingThreshold = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].avatarContactProcessingThreshold; },
|
||||
(s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ),
|
||||
(s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ),
|
||||
|
||||
|
||||
new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)",
|
||||
new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default)",
|
||||
0f, // zero to disable
|
||||
(s,cf,p,v) => { s.m_params[0].maxPersistantManifoldPoolSize = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].maxPersistantManifoldPoolSize; },
|
||||
(s,p,l,v) => { s.m_params[0].maxPersistantManifoldPoolSize = v; } ),
|
||||
new ParameterDefn("MaxCollisionAlgorithmPoolSize", "Number of collisions pooled (0 means default of 4096)",
|
||||
0f, // zero to disable
|
||||
(s,cf,p,v) => { s.m_params[0].maxCollisionAlgorithmPoolSize = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].maxCollisionAlgorithmPoolSize; },
|
||||
(s,p,l,v) => { s.m_params[0].maxCollisionAlgorithmPoolSize = v; } ),
|
||||
new ParameterDefn("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count",
|
||||
ConfigurationParameters.numericFalse,
|
||||
(s,cf,p,v) => { s.m_params[0].shouldDisableContactPoolDynamicAllocation = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
|
||||
ConfigurationParameters.numericTrue,
|
||||
(s,cf,p,v) => { s.m_params[0].maxPersistantManifoldPoolSize = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
|
||||
(s) => { return s.m_params[0].shouldDisableContactPoolDynamicAllocation; },
|
||||
(s,p,l,v) => { s.m_params[0].shouldDisableContactPoolDynamicAllocation = v; } ),
|
||||
new ParameterDefn("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step",
|
||||
@@ -1178,6 +1099,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
(s,cf,p,v) => { s.m_detailedStatsStep = cf.GetInt(p, (int)v); },
|
||||
(s) => { return (float)s.m_detailedStatsStep; },
|
||||
(s,p,l,v) => { s.m_detailedStatsStep = (int)v; } ),
|
||||
new ParameterDefn("ShouldDebugLog", "Enables detailed DEBUG log statements",
|
||||
ConfigurationParameters.numericFalse,
|
||||
(s,cf,p,v) => { s.shouldDebugLog = cf.GetBoolean(p, s.BoolNumeric(v)); },
|
||||
(s) => { return s.NumericBool(s.shouldDebugLog); },
|
||||
(s,p,l,v) => { s.shouldDebugLog = s.BoolNumeric(v); } ),
|
||||
|
||||
};
|
||||
|
||||
// Convert a boolean to our numeric true and false values
|
||||
@@ -1235,8 +1162,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
|
||||
private PhysParameterEntry[] SettableParameters = new PhysParameterEntry[1];
|
||||
|
||||
// This creates an array in the correct format for returning the list of
|
||||
// parameters. This is used by the 'list' option of the 'physics' command.
|
||||
private void BuildParameterTable()
|
||||
{
|
||||
if (SettableParameters.Length < ParameterDefinitions.Length)
|
||||
@@ -1287,10 +1212,18 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
}
|
||||
|
||||
// check to see if we are updating a parameter for a particular or all of the prims
|
||||
protected void UpdateParameterObject(ref float loc, string parm, uint localID, float val)
|
||||
protected void UpdateParameterPrims(ref float loc, string parm, uint localID, float val)
|
||||
{
|
||||
List<uint> operateOn;
|
||||
lock (PhysObjects) operateOn = new List<uint>(PhysObjects.Keys);
|
||||
lock (m_prims) operateOn = new List<uint>(m_prims.Keys);
|
||||
UpdateParameterSet(operateOn, ref loc, parm, localID, val);
|
||||
}
|
||||
|
||||
// check to see if we are updating a parameter for a particular or all of the avatars
|
||||
protected void UpdateParameterAvatars(ref float loc, string parm, uint localID, float val)
|
||||
{
|
||||
List<uint> operateOn;
|
||||
lock (m_avatars) operateOn = new List<uint>(m_avatars.Keys);
|
||||
UpdateParameterSet(operateOn, ref loc, parm, localID, val);
|
||||
}
|
||||
|
||||
@@ -1310,10 +1243,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
List<uint> objectIDs = lIDs;
|
||||
string xparm = parm.ToLower();
|
||||
float xval = val;
|
||||
TaintedObject("BSScene.UpdateParameterSet", delegate() {
|
||||
TaintedObject(delegate() {
|
||||
foreach (uint lID in objectIDs)
|
||||
{
|
||||
BulletSimAPI.UpdateParameter(WorldID, lID, xparm, xval);
|
||||
BulletSimAPI.UpdateParameter(m_worldID, lID, xparm, xval);
|
||||
}
|
||||
});
|
||||
break;
|
||||
@@ -1330,8 +1263,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
uint xlocalID = localID;
|
||||
string xparm = parm.ToLower();
|
||||
float xval = val;
|
||||
TaintedObject("BSScene.TaintedUpdateParameter", delegate() {
|
||||
BulletSimAPI.UpdateParameter(WorldID, xlocalID, xparm, xval);
|
||||
TaintedObject(delegate() {
|
||||
BulletSimAPI.UpdateParameter(m_worldID, xlocalID, xparm, xval);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1356,12 +1289,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
#endregion Runtime settable parameters
|
||||
|
||||
// Invoke the detailed logger and output something if it's enabled.
|
||||
public void DetailLog(string msg, params Object[] args)
|
||||
private void DetailLog(string msg, params Object[] args)
|
||||
{
|
||||
PhysicsLogging.Write(msg, args);
|
||||
}
|
||||
// used to fill in the LocalID when there isn't one
|
||||
public const string DetailLogZero = "0000000000";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,464 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyrightD
|
||||
* 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.Text;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework;
|
||||
using OpenSim.Region.CoreModules;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
|
||||
using Nini.Config;
|
||||
using log4net;
|
||||
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
public class BSTerrainManager
|
||||
{
|
||||
static string LogHeader = "[BULLETSIM TERRAIN MANAGER]";
|
||||
|
||||
// These height values are fractional so the odd values will be
|
||||
// noticable when debugging.
|
||||
public const float HEIGHT_INITIALIZATION = 24.987f;
|
||||
public const float HEIGHT_INITIAL_LASTHEIGHT = 24.876f;
|
||||
public const float HEIGHT_GETHEIGHT_RET = 24.765f;
|
||||
|
||||
// If the min and max height are equal, we reduce the min by this
|
||||
// amount to make sure that a bounding box is built for the terrain.
|
||||
public const float HEIGHT_EQUAL_FUDGE = 0.2f;
|
||||
|
||||
public const float TERRAIN_COLLISION_MARGIN = 0.0f;
|
||||
|
||||
// Until the whole simulator is changed to pass us the region size, we rely on constants.
|
||||
public Vector3 DefaultRegionSize = new Vector3(Constants.RegionSize, Constants.RegionSize, 0f);
|
||||
|
||||
// The scene that I am part of
|
||||
private BSScene m_physicsScene;
|
||||
|
||||
// The ground plane created to keep thing from falling to infinity.
|
||||
private BulletBody m_groundPlane;
|
||||
|
||||
// If doing mega-regions, if we're region zero we will be managing multiple
|
||||
// region terrains since region zero does the physics for the whole mega-region.
|
||||
private Dictionary<Vector2, BulletHeightMapInfo> m_heightMaps;
|
||||
|
||||
// True of the terrain has been modified.
|
||||
// Used to force recalculation of terrain height after terrain has been modified
|
||||
private bool m_terrainModified;
|
||||
|
||||
// If we are doing mega-regions, terrains are added from TERRAIN_ID to m_terrainCount.
|
||||
// This is incremented before assigning to new region so it is the last ID allocated.
|
||||
private uint m_terrainCount = BSScene.CHILDTERRAIN_ID - 1;
|
||||
public uint HighestTerrainID { get {return m_terrainCount; } }
|
||||
|
||||
// If doing mega-regions, this holds our offset from region zero of
|
||||
// the mega-regions. "parentScene" points to the PhysicsScene of region zero.
|
||||
private Vector3 m_worldOffset;
|
||||
// If the parent region (region 0), this is the extent of the combined regions
|
||||
// relative to the origin of region zero
|
||||
private Vector3 m_worldMax;
|
||||
private PhysicsScene m_parentScene;
|
||||
|
||||
public BSTerrainManager(BSScene physicsScene)
|
||||
{
|
||||
m_physicsScene = physicsScene;
|
||||
m_heightMaps = new Dictionary<Vector2,BulletHeightMapInfo>();
|
||||
m_terrainModified = false;
|
||||
|
||||
// Assume one region of default size
|
||||
m_worldOffset = Vector3.Zero;
|
||||
m_worldMax = new Vector3(DefaultRegionSize.X, DefaultRegionSize.Y, 4096f);
|
||||
m_parentScene = null;
|
||||
}
|
||||
|
||||
// Create the initial instance of terrain and the underlying ground plane.
|
||||
// The objects are allocated in the unmanaged space and the pointers are tracked
|
||||
// by the managed code.
|
||||
// The terrains and the groundPlane are not added to the list of PhysObjects.
|
||||
// This is called from the initialization routine so we presume it is
|
||||
// safe to call Bullet in real time. We hope no one is moving prims around yet.
|
||||
public void CreateInitialGroundPlaneAndTerrain()
|
||||
{
|
||||
// The ground plane is here to catch things that are trying to drop to negative infinity
|
||||
BulletShape groundPlaneShape = new BulletShape(BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, TERRAIN_COLLISION_MARGIN));
|
||||
m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID,
|
||||
BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.Ptr, Vector3.Zero, Quaternion.Identity));
|
||||
BulletSimAPI.AddObjectToWorld2(m_physicsScene.World.Ptr, m_groundPlane.Ptr);
|
||||
|
||||
Vector3 minTerrainCoords = new Vector3(0f, 0f, HEIGHT_INITIALIZATION - HEIGHT_EQUAL_FUDGE);
|
||||
Vector3 maxTerrainCoords = new Vector3(DefaultRegionSize.X, DefaultRegionSize.Y, HEIGHT_INITIALIZATION);
|
||||
int totalHeights = (int)maxTerrainCoords.X * (int)maxTerrainCoords.Y;
|
||||
float[] initialMap = new float[totalHeights];
|
||||
for (int ii = 0; ii < totalHeights; ii++)
|
||||
{
|
||||
initialMap[ii] = HEIGHT_INITIALIZATION;
|
||||
}
|
||||
UpdateOrCreateTerrain(BSScene.TERRAIN_ID, initialMap, minTerrainCoords, maxTerrainCoords, true);
|
||||
}
|
||||
|
||||
// Release all the terrain structures we might have allocated
|
||||
public void ReleaseGroundPlaneAndTerrain()
|
||||
{
|
||||
if (m_groundPlane.Ptr != IntPtr.Zero)
|
||||
{
|
||||
if (BulletSimAPI.RemoveObjectFromWorld2(m_physicsScene.World.Ptr, m_groundPlane.Ptr))
|
||||
{
|
||||
BulletSimAPI.DestroyObject2(m_physicsScene.World.Ptr, m_groundPlane.Ptr);
|
||||
}
|
||||
m_groundPlane.Ptr = IntPtr.Zero;
|
||||
}
|
||||
|
||||
ReleaseTerrain();
|
||||
}
|
||||
|
||||
// Release all the terrain we have allocated
|
||||
public void ReleaseTerrain()
|
||||
{
|
||||
foreach (KeyValuePair<Vector2, BulletHeightMapInfo> kvp in m_heightMaps)
|
||||
{
|
||||
if (BulletSimAPI.RemoveObjectFromWorld2(m_physicsScene.World.Ptr, kvp.Value.terrainBody.Ptr))
|
||||
{
|
||||
BulletSimAPI.DestroyObject2(m_physicsScene.World.Ptr, kvp.Value.terrainBody.Ptr);
|
||||
BulletSimAPI.ReleaseHeightMapInfo2(kvp.Value.Ptr);
|
||||
}
|
||||
}
|
||||
m_heightMaps.Clear();
|
||||
}
|
||||
|
||||
// The simulator wants to set a new heightmap for the terrain.
|
||||
public void SetTerrain(float[] heightMap) {
|
||||
if (m_worldOffset != Vector3.Zero && m_parentScene != null)
|
||||
{
|
||||
// If a child of a mega-region, we shouldn't have any terrain allocated for us
|
||||
ReleaseGroundPlaneAndTerrain();
|
||||
// If doing the mega-prim stuff and we are the child of the zero region,
|
||||
// the terrain is added to our parent
|
||||
if (m_parentScene is BSScene)
|
||||
{
|
||||
DetailLog("{0},SetTerrain.ToParent,offset={1},worldMax={2}",
|
||||
BSScene.DetailLogZero, m_worldOffset, m_worldMax);
|
||||
((BSScene)m_parentScene).TerrainManager.UpdateOrCreateTerrain(BSScene.CHILDTERRAIN_ID,
|
||||
heightMap, m_worldOffset, m_worldOffset+DefaultRegionSize, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If not doing the mega-prim thing, just change the terrain
|
||||
DetailLog("{0},SetTerrain.Existing", BSScene.DetailLogZero);
|
||||
|
||||
UpdateOrCreateTerrain(BSScene.TERRAIN_ID, heightMap, m_worldOffset, m_worldOffset+DefaultRegionSize, false);
|
||||
}
|
||||
}
|
||||
|
||||
// If called with no mapInfo for the terrain, this will create a new mapInfo and terrain
|
||||
// based on the passed information. The 'id' should be either the terrain id or
|
||||
// BSScene.CHILDTERRAIN_ID. If the latter, a new child terrain ID will be allocated and used.
|
||||
// The latter feature is for creating child terrains for mega-regions.
|
||||
// If called with a mapInfo in m_heightMaps but the terrain has no body yet (mapInfo.terrainBody.Ptr == 0)
|
||||
// then a new body and shape is created and the mapInfo is filled.
|
||||
// This call is used for doing the initial terrain creation.
|
||||
// If called with a mapInfo in m_heightMaps and there is an existing terrain body, a new
|
||||
// terrain shape is created and added to the body.
|
||||
// This call is most often used to update the heightMap and parameters of the terrain.
|
||||
// The 'doNow' boolean says whether to do all the unmanaged activities right now (like when
|
||||
// calling this routine from initialization or taint-time routines) or whether to delay
|
||||
// all the unmanaged activities to taint-time.
|
||||
private void UpdateOrCreateTerrain(uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords, bool doNow)
|
||||
{
|
||||
DetailLog("{0},BSTerrainManager.UpdateOrCreateTerrain,call,minC={1},maxC={2},doNow={3}",
|
||||
BSScene.DetailLogZero, minCoords, maxCoords, doNow);
|
||||
|
||||
float minZ = float.MaxValue;
|
||||
float maxZ = float.MinValue;
|
||||
Vector2 terrainRegionBase = new Vector2(minCoords.X, minCoords.Y);
|
||||
|
||||
int heightMapSize = heightMap.Length;
|
||||
for (int ii = 0; ii < heightMapSize; ii++)
|
||||
{
|
||||
float height = heightMap[ii];
|
||||
if (height < minZ) minZ = height;
|
||||
if (height > maxZ) maxZ = height;
|
||||
}
|
||||
|
||||
// The shape of the terrain is from its base to its extents.
|
||||
minCoords.Z = minZ;
|
||||
maxCoords.Z = maxZ;
|
||||
|
||||
BulletHeightMapInfo mapInfo;
|
||||
if (m_heightMaps.TryGetValue(terrainRegionBase, out mapInfo))
|
||||
{
|
||||
// If this is terrain we know about, it's easy to update
|
||||
|
||||
mapInfo.heightMap = heightMap;
|
||||
mapInfo.minCoords = minCoords;
|
||||
mapInfo.maxCoords = maxCoords;
|
||||
mapInfo.minZ = minZ;
|
||||
mapInfo.maxZ = maxZ;
|
||||
mapInfo.sizeX = maxCoords.X - minCoords.X;
|
||||
mapInfo.sizeY = maxCoords.Y - minCoords.Y;
|
||||
DetailLog("{0},UpdateOrCreateTerrain:UpdateExisting,call,terrainBase={1},minC={2}, maxC={3}, szX={4}, szY={5}",
|
||||
BSScene.DetailLogZero, terrainRegionBase, mapInfo.minCoords, mapInfo.maxCoords, mapInfo.sizeX, mapInfo.sizeY);
|
||||
|
||||
BSScene.TaintCallback rebuildOperation = delegate()
|
||||
{
|
||||
if (m_parentScene != null)
|
||||
{
|
||||
// It's possible that Combine() was called after this code was queued.
|
||||
// If we are a child of combined regions, we don't create any terrain for us.
|
||||
DetailLog("{0},UpdateOrCreateTerrain:AmACombineChild,taint", BSScene.DetailLogZero);
|
||||
|
||||
// Get rid of any terrain that may have been allocated for us.
|
||||
ReleaseGroundPlaneAndTerrain();
|
||||
|
||||
// I hate doing this, but just bail
|
||||
return;
|
||||
}
|
||||
|
||||
if (mapInfo.terrainBody.Ptr != IntPtr.Zero)
|
||||
{
|
||||
// Updating an existing terrain.
|
||||
DetailLog("{0},UpdateOrCreateTerrain:UpdateExisting,taint,terrainBase={1},minC={2}, maxC={3}, szX={4}, szY={5}",
|
||||
BSScene.DetailLogZero, terrainRegionBase, mapInfo.minCoords, mapInfo.maxCoords, mapInfo.sizeX, mapInfo.sizeY);
|
||||
|
||||
// Remove from the dynamics world because we're going to mangle this object
|
||||
BulletSimAPI.RemoveObjectFromWorld2(m_physicsScene.World.Ptr, mapInfo.terrainBody.Ptr);
|
||||
|
||||
// Get rid of the old terrain
|
||||
BulletSimAPI.DestroyObject2(m_physicsScene.World.Ptr, mapInfo.terrainBody.Ptr);
|
||||
BulletSimAPI.ReleaseHeightMapInfo2(mapInfo.Ptr);
|
||||
mapInfo.Ptr = IntPtr.Zero;
|
||||
|
||||
/*
|
||||
// NOTE: This routine is half here because I can't get the terrain shape replacement
|
||||
// to work. In the short term, the above three lines completely delete the old
|
||||
// terrain and the code below recreates one from scratch.
|
||||
// Hopefully the Bullet community will help me out on this one.
|
||||
|
||||
// First, release the old collision shape (there is only one terrain)
|
||||
BulletSimAPI.DeleteCollisionShape2(m_physicsScene.World.Ptr, mapInfo.terrainShape.Ptr);
|
||||
|
||||
// Fill the existing height map info with the new location and size information
|
||||
BulletSimAPI.FillHeightMapInfo2(m_physicsScene.World.Ptr, mapInfo.Ptr, mapInfo.ID,
|
||||
mapInfo.minCoords, mapInfo.maxCoords, mapInfo.heightMap, TERRAIN_COLLISION_MARGIN);
|
||||
|
||||
// Create a terrain shape based on the new info
|
||||
mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(mapInfo.Ptr));
|
||||
|
||||
// Stuff the shape into the existing terrain body
|
||||
BulletSimAPI.SetBodyShape2(m_physicsScene.World.Ptr, mapInfo.terrainBody.Ptr, mapInfo.terrainShape.Ptr);
|
||||
*/
|
||||
}
|
||||
// else
|
||||
{
|
||||
// Creating a new terrain.
|
||||
DetailLog("{0},UpdateOrCreateTerrain:CreateNewTerrain,taint,baseX={1},baseY={2},minZ={3},maxZ={4}",
|
||||
BSScene.DetailLogZero, mapInfo.minCoords.X, mapInfo.minCoords.Y, minZ, maxZ);
|
||||
|
||||
mapInfo.ID = id;
|
||||
mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(m_physicsScene.World.Ptr, mapInfo.ID,
|
||||
mapInfo.minCoords, mapInfo.maxCoords, mapInfo.heightMap, TERRAIN_COLLISION_MARGIN);
|
||||
|
||||
// The terrain object initial position is at the center of the object
|
||||
Vector3 centerPos;
|
||||
centerPos.X = minCoords.X + (mapInfo.sizeX / 2f);
|
||||
centerPos.Y = minCoords.Y + (mapInfo.sizeY / 2f);
|
||||
centerPos.Z = minZ + ((maxZ - minZ) / 2f);
|
||||
|
||||
// Create the terrain shape from the mapInfo
|
||||
mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(mapInfo.Ptr));
|
||||
|
||||
mapInfo.terrainBody = new BulletBody(mapInfo.ID,
|
||||
BulletSimAPI.CreateBodyWithDefaultMotionState2(mapInfo.terrainShape.Ptr,
|
||||
centerPos, Quaternion.Identity));
|
||||
}
|
||||
|
||||
// Make sure the entry is in the heightmap table
|
||||
m_heightMaps[terrainRegionBase] = mapInfo;
|
||||
|
||||
// Set current terrain attributes
|
||||
BulletSimAPI.SetFriction2(mapInfo.terrainBody.Ptr, m_physicsScene.Params.terrainFriction);
|
||||
BulletSimAPI.SetHitFraction2(mapInfo.terrainBody.Ptr, m_physicsScene.Params.terrainHitFraction);
|
||||
BulletSimAPI.SetRestitution2(mapInfo.terrainBody.Ptr, m_physicsScene.Params.terrainRestitution);
|
||||
BulletSimAPI.SetCollisionFlags2(mapInfo.terrainBody.Ptr, CollisionFlags.CF_STATIC_OBJECT);
|
||||
|
||||
BulletSimAPI.SetMassProps2(mapInfo.terrainBody.Ptr, 0f, Vector3.Zero);
|
||||
BulletSimAPI.UpdateInertiaTensor2(mapInfo.terrainBody.Ptr);
|
||||
|
||||
// Return the new terrain to the world of physical objects
|
||||
BulletSimAPI.AddObjectToWorld2(m_physicsScene.World.Ptr, mapInfo.terrainBody.Ptr);
|
||||
|
||||
// redo its bounding box now that it is in the world
|
||||
BulletSimAPI.UpdateSingleAabb2(m_physicsScene.World.Ptr, mapInfo.terrainBody.Ptr);
|
||||
|
||||
// Make sure the new shape is processed.
|
||||
BulletSimAPI.Activate2(mapInfo.terrainBody.Ptr, true);
|
||||
};
|
||||
|
||||
// There is the option to do the changes now (we're already in 'taint time'), or
|
||||
// to do the Bullet operations later.
|
||||
if (doNow)
|
||||
rebuildOperation();
|
||||
else
|
||||
m_physicsScene.TaintedObject("BSScene.UpdateOrCreateTerrain:UpdateExisting", rebuildOperation);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We don't know about this terrain so either we are creating a new terrain or
|
||||
// our mega-prim child is giving us a new terrain to add to the phys world
|
||||
|
||||
// if this is a child terrain, calculate a unique terrain id
|
||||
uint newTerrainID = id;
|
||||
if (newTerrainID >= BSScene.CHILDTERRAIN_ID)
|
||||
newTerrainID = ++m_terrainCount;
|
||||
|
||||
float[] heightMapX = heightMap;
|
||||
Vector3 minCoordsX = minCoords;
|
||||
Vector3 maxCoordsX = maxCoords;
|
||||
|
||||
DetailLog("{0},UpdateOrCreateTerrain:NewTerrain,call,id={1}, minC={2}, maxC={3}",
|
||||
BSScene.DetailLogZero, newTerrainID, minCoords, minCoords);
|
||||
|
||||
// Code that must happen at taint-time
|
||||
BSScene.TaintCallback createOperation = delegate()
|
||||
{
|
||||
DetailLog("{0},UpdateOrCreateTerrain:NewTerrain,taint,baseX={1},baseY={2}", BSScene.DetailLogZero, minCoords.X, minCoords.Y);
|
||||
// Create a new mapInfo that will be filled with the new info
|
||||
mapInfo = new BulletHeightMapInfo(id, heightMapX,
|
||||
BulletSimAPI.CreateHeightMapInfo2(m_physicsScene.World.Ptr, newTerrainID,
|
||||
minCoordsX, maxCoordsX, heightMapX, TERRAIN_COLLISION_MARGIN));
|
||||
// Put the unfilled heightmap info into the collection of same
|
||||
m_heightMaps.Add(terrainRegionBase, mapInfo);
|
||||
// Build the terrain
|
||||
UpdateOrCreateTerrain(newTerrainID, heightMap, minCoords, maxCoords, true);
|
||||
};
|
||||
|
||||
// If already in taint-time, just call Bullet. Otherwise queue the operations for the safe time.
|
||||
if (doNow)
|
||||
createOperation();
|
||||
else
|
||||
m_physicsScene.TaintedObject("BSScene.UpdateOrCreateTerrain:NewTerrain", createOperation);
|
||||
}
|
||||
}
|
||||
|
||||
// Someday we will have complex terrain with caves and tunnels
|
||||
public float GetTerrainHeightAtXYZ(Vector3 loc)
|
||||
{
|
||||
// For the moment, it's flat and convex
|
||||
return GetTerrainHeightAtXY(loc.X, loc.Y);
|
||||
}
|
||||
|
||||
// Given an X and Y, find the height of the terrain.
|
||||
// Since we could be handling multiple terrains for a mega-region,
|
||||
// the base of the region is calcuated assuming all regions are
|
||||
// the same size and that is the default.
|
||||
// Once the heightMapInfo is found, we have all the information to
|
||||
// compute the offset into the array.
|
||||
private float lastHeightTX = 999999f;
|
||||
private float lastHeightTY = 999999f;
|
||||
private float lastHeight = HEIGHT_INITIAL_LASTHEIGHT;
|
||||
public float GetTerrainHeightAtXY(float tX, float tY)
|
||||
{
|
||||
// You'd be surprized at the number of times this routine is called
|
||||
// with the same parameters as last time.
|
||||
if (!m_terrainModified && lastHeightTX == tX && lastHeightTY == tY)
|
||||
return lastHeight;
|
||||
|
||||
lastHeightTX = tX;
|
||||
lastHeightTY = tY;
|
||||
float ret = HEIGHT_GETHEIGHT_RET;
|
||||
|
||||
int offsetX = ((int)(tX / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X;
|
||||
int offsetY = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y;
|
||||
Vector2 terrainBaseXY = new Vector2(offsetX, offsetY);
|
||||
|
||||
BulletHeightMapInfo mapInfo;
|
||||
if (m_heightMaps.TryGetValue(terrainBaseXY, out mapInfo))
|
||||
{
|
||||
float regionX = tX - offsetX;
|
||||
float regionY = tY - offsetY;
|
||||
if (regionX > mapInfo.sizeX) regionX = 0;
|
||||
if (regionY > mapInfo.sizeY) regionY = 0;
|
||||
int mapIndex = (int)regionY * (int)mapInfo.sizeY + (int)regionX;
|
||||
ret = mapInfo.heightMap[mapIndex];
|
||||
m_terrainModified = false;
|
||||
DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXY,bX={1},baseY={2},szX={3},szY={4},regX={5},regY={6},index={7},ht={8}",
|
||||
BSScene.DetailLogZero, offsetX, offsetY, mapInfo.sizeX, mapInfo.sizeY, regionX, regionY, mapIndex, ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_physicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}",
|
||||
LogHeader, m_physicsScene.RegionName, tX, tY);
|
||||
}
|
||||
lastHeight = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Although no one seems to check this, I do support combining.
|
||||
public bool SupportsCombining()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// This routine is called two ways:
|
||||
// One with 'offset' and 'pScene' zero and null but 'extents' giving the maximum
|
||||
// extent of the combined regions. This is to inform the parent of the size
|
||||
// of the combined regions.
|
||||
// and one with 'offset' as the offset of the child region to the base region,
|
||||
// 'pScene' pointing to the parent and 'extents' of zero. This informs the
|
||||
// child of its relative base and new parent.
|
||||
public void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents)
|
||||
{
|
||||
m_worldOffset = offset;
|
||||
m_worldMax = extents;
|
||||
m_parentScene = pScene;
|
||||
if (pScene != null)
|
||||
{
|
||||
// We are a child.
|
||||
// We want m_worldMax to be the highest coordinate of our piece of terrain.
|
||||
m_worldMax = offset + DefaultRegionSize;
|
||||
}
|
||||
DetailLog("{0},BSTerrainManager.Combine,offset={1},extents={2},wOffset={3},wMax={4}",
|
||||
BSScene.DetailLogZero, offset, extents, m_worldOffset, m_worldMax);
|
||||
}
|
||||
|
||||
// Unhook all the combining that I know about.
|
||||
public void UnCombine(PhysicsScene pScene)
|
||||
{
|
||||
// Just like ODE, for the moment a NOP
|
||||
DetailLog("{0},BSTerrainManager.UnCombine", BSScene.DetailLogZero);
|
||||
}
|
||||
|
||||
|
||||
private void DetailLog(string msg, params Object[] args)
|
||||
{
|
||||
m_physicsScene.PhysicsLogging.Write(msg, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,25 +33,13 @@ using OpenMetaverse;
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin {
|
||||
|
||||
// Classes to allow some type checking for the API
|
||||
// These hold pointers to allocated objects in the unmanaged space.
|
||||
|
||||
// The physics engine controller class created at initialization
|
||||
public struct BulletSim
|
||||
{
|
||||
public BulletSim(uint worldId, BSScene bss, IntPtr xx) { worldID = worldId; scene = bss; Ptr = xx; }
|
||||
public uint worldID;
|
||||
// The scene is only in here so very low level routines have a handle to print debug/error messages
|
||||
public BSScene scene;
|
||||
public BulletSim(uint id, IntPtr xx) { ID = id; Ptr = xx; }
|
||||
public IntPtr Ptr;
|
||||
public uint ID;
|
||||
}
|
||||
|
||||
public struct BulletShape
|
||||
{
|
||||
public BulletShape(IntPtr xx) { Ptr = xx; }
|
||||
public IntPtr Ptr;
|
||||
}
|
||||
|
||||
// An allocated Bullet btRigidBody
|
||||
public struct BulletBody
|
||||
{
|
||||
public BulletBody(uint id, IntPtr xx) { ID = id; Ptr = xx; }
|
||||
@@ -59,41 +47,12 @@ public struct BulletBody
|
||||
public uint ID;
|
||||
}
|
||||
|
||||
// An allocated Bullet btConstraint
|
||||
public struct BulletConstraint
|
||||
{
|
||||
public BulletConstraint(IntPtr xx) { Ptr = xx; }
|
||||
public IntPtr Ptr;
|
||||
}
|
||||
|
||||
// An allocated HeightMapThing which hold various heightmap info
|
||||
// Made a class rather than a struct so there would be only one
|
||||
// instance of this and C# will pass around pointers rather
|
||||
// than making copies.
|
||||
public class BulletHeightMapInfo
|
||||
{
|
||||
public BulletHeightMapInfo(uint id, float[] hm, IntPtr xx) {
|
||||
ID = id;
|
||||
Ptr = xx;
|
||||
heightMap = hm;
|
||||
terrainRegionBase = new Vector2(0f, 0f);
|
||||
minCoords = new Vector3(100f, 100f, 25f);
|
||||
maxCoords = new Vector3(101f, 101f, 26f);
|
||||
minZ = maxZ = 0f;
|
||||
sizeX = sizeY = 256f;
|
||||
}
|
||||
public uint ID;
|
||||
public IntPtr Ptr;
|
||||
public float[] heightMap;
|
||||
public Vector2 terrainRegionBase;
|
||||
public Vector3 minCoords;
|
||||
public Vector3 maxCoords;
|
||||
public float sizeX, sizeY;
|
||||
public float minZ, maxZ;
|
||||
public BulletShape terrainShape;
|
||||
public BulletBody terrainBody;
|
||||
}
|
||||
|
||||
// ===============================================================================
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct ConvexHull
|
||||
@@ -199,7 +158,6 @@ public struct ConfigurationParameters
|
||||
public float avatarContactProcessingThreshold;
|
||||
|
||||
public float maxPersistantManifoldPoolSize;
|
||||
public float maxCollisionAlgorithmPoolSize;
|
||||
public float shouldDisableContactPoolDynamicAllocation;
|
||||
public float shouldForceUpdateAllAabbs;
|
||||
public float shouldRandomizeSolverOrder;
|
||||
@@ -260,10 +218,6 @@ public enum ConstraintParamAxis : int
|
||||
// ===============================================================================
|
||||
static class BulletSimAPI {
|
||||
|
||||
// Link back to the managed code for outputting log messages
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
[return: MarshalAs(UnmanagedType.LPStr)]
|
||||
public static extern string GetVersion();
|
||||
@@ -271,11 +225,7 @@ public static extern string GetVersion();
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern uint Initialize(Vector3 maxPosition, IntPtr parms,
|
||||
int maxCollisions, IntPtr collisionArray,
|
||||
int maxUpdates, IntPtr updateArray,
|
||||
DebugLogCallback logRoutine);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void CreateInitialGroundPlaneAndTerrain(uint worldID);
|
||||
int maxUpdates, IntPtr updateArray);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void SetHeightmap(uint worldID, [MarshalAs(UnmanagedType.LPArray)] float[] heightMap);
|
||||
@@ -389,6 +339,8 @@ public static extern Vector3 RecoverFromPenetration(uint worldID, uint id);
|
||||
public static extern void DumpBulletStatistics();
|
||||
|
||||
// Log a debug message
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg);
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void SetDebugLogCallback(DebugLogCallback callback);
|
||||
|
||||
@@ -410,7 +362,7 @@ public static extern IntPtr GetSimHandle2(uint worldID);
|
||||
public static extern IntPtr GetBodyHandleWorldID2(uint worldID, uint id);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr GetBodyHandle2(IntPtr world, uint id);
|
||||
public static extern IntPtr GetBodyHandle2(IntPtr sim, uint id);
|
||||
|
||||
// ===============================================================================
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
@@ -419,98 +371,44 @@ public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms,
|
||||
int maxUpdates, IntPtr updateArray);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool UpdateParameter2(IntPtr world, uint localID, String parm, float value);
|
||||
public static extern bool UpdateParameter2(IntPtr sim, uint localID, String parm, float value);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void SetHeightMap2(IntPtr world, float[] heightmap);
|
||||
public static extern void SetHeightmap2(IntPtr sim, float[] heightmap);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void Shutdown2(IntPtr sim);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern int PhysicsStep2(IntPtr world, float timeStep, int maxSubSteps, float fixedTimeStep,
|
||||
public static extern int PhysicsStep2(IntPtr sim, float timeStep, int maxSubSteps, float fixedTimeStep,
|
||||
out int updatedEntityCount,
|
||||
out IntPtr updatedEntitiesPtr,
|
||||
out int collidersCount,
|
||||
out IntPtr collidersPtr);
|
||||
|
||||
/*
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool PushUpdate2(IntPtr obj);
|
||||
|
||||
// =====================================================================================
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateMeshShape2(IntPtr world,
|
||||
int indicesCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices,
|
||||
int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices );
|
||||
public static extern IntPtr CreateMesh2(IntPtr sim, int indicesCount, int* indices, int verticesCount, float* vertices );
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateHullShape2(IntPtr world,
|
||||
int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls);
|
||||
public static extern bool BuildHull2(IntPtr sim, IntPtr mesh);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr BuildHullShape2(IntPtr world, IntPtr meshShape);
|
||||
public static extern bool ReleaseHull2(IntPtr sim, IntPtr mesh);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr BuildNativeShape2(IntPtr world,
|
||||
float shapeType, float collisionMargin, Vector3 scale);
|
||||
public static extern bool DestroyMesh2(IntPtr sim, IntPtr mesh);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool DeleteCollisionShape2(IntPtr world, IntPtr shape);
|
||||
public static extern IntPtr CreateObject2(IntPtr sim, ShapeData shapeData);
|
||||
*/
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateBodyFromShape2(IntPtr sim, IntPtr shape, Vector3 pos, Quaternion rot);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateBodyWithDefaultMotionState2(IntPtr shape, Vector3 pos, Quaternion rot);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool SetBodyShape2(IntPtr sim, IntPtr obj, IntPtr shape);
|
||||
// =====================================================================================
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateHeightMapInfo2(IntPtr sim, uint id, Vector3 minCoords, Vector3 maxCoords,
|
||||
[MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr FillHeightMapInfo2(IntPtr sim, IntPtr mapInfo, uint id, Vector3 minCoords, Vector3 maxCoords,
|
||||
[MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool ReleaseHeightMapInfo2(IntPtr heightMapInfo);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateGroundPlaneShape2(uint id, float height, float collisionMargin);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateTerrainShape2(IntPtr mapInfo);
|
||||
|
||||
// =====================================================================================
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr Create6DofConstraint2(IntPtr world, IntPtr obj1, IntPtr obj2,
|
||||
public static extern IntPtr CreateConstraint2(IntPtr sim, IntPtr obj1, IntPtr obj2,
|
||||
Vector3 frame1loc, Quaternion frame1rot,
|
||||
Vector3 frame2loc, Quaternion frame2rot,
|
||||
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr Create6DofConstraintToPoint2(IntPtr world, IntPtr obj1, IntPtr obj2,
|
||||
Vector3 joinPoint,
|
||||
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateHingeConstraint2(IntPtr world, IntPtr obj1, IntPtr obj2,
|
||||
Vector3 pivotinA, Vector3 pivotinB,
|
||||
Vector3 axisInA, Vector3 axisInB,
|
||||
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void SetConstraintEnable2(IntPtr constrain, float numericTrueFalse);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void SetConstraintNumSolverIterations2(IntPtr constrain, float iterations);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool SetFrames2(IntPtr constrain,
|
||||
Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool SetLinearLimits2(IntPtr constrain, Vector3 low, Vector3 hi);
|
||||
|
||||
@@ -523,9 +421,6 @@ public static extern bool UseFrameOffset2(IntPtr constrain, float enable);
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool TranslationalLimitMotor2(IntPtr constrain, float enable, float targetVel, float maxMotorForce);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool SetBreakingImpulseThreshold2(IntPtr constrain, float threshold);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool CalculateTransforms2(IntPtr constrain);
|
||||
|
||||
@@ -533,18 +428,7 @@ public static extern bool CalculateTransforms2(IntPtr constrain);
|
||||
public static extern bool SetConstraintParam2(IntPtr constrain, ConstraintParams paramIndex, float value, ConstraintParamAxis axis);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool DestroyConstraint2(IntPtr world, IntPtr constrain);
|
||||
|
||||
// =====================================================================================
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool AddObjectToWorld2(IntPtr world, IntPtr obj);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool RemoveObjectFromWorld2(IntPtr world, IntPtr obj);
|
||||
|
||||
// =====================================================================================
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void Activate2(IntPtr obj, bool forceActivation);
|
||||
public static extern bool DestroyConstraint2(IntPtr sim, IntPtr constrain);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern Vector3 GetPosition2(IntPtr obj);
|
||||
@@ -588,9 +472,6 @@ public static extern bool SetContactProcessingThreshold2(IntPtr obj, float val);
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool SetFriction2(IntPtr obj, float val);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool SetHitFraction2(IntPtr obj, float val);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool SetRestitution2(IntPtr obj, float val);
|
||||
|
||||
@@ -600,9 +481,6 @@ public static extern bool SetLinearVelocity2(IntPtr obj, Vector3 val);
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool SetInterpolation2(IntPtr obj, Vector3 lin, Vector3 ang);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern CollisionFlags GetCollisionFlags2(IntPtr obj);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr SetCollisionFlags2(IntPtr obj, CollisionFlags flags);
|
||||
|
||||
@@ -624,9 +502,6 @@ public static extern bool SetGravity2(IntPtr obj, Vector3 val);
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr ClearForces2(IntPtr obj);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr ClearAllForces2(IntPtr obj);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool SetMargin2(IntPtr obj, float val);
|
||||
|
||||
@@ -634,7 +509,13 @@ public static extern bool SetMargin2(IntPtr obj, float val);
|
||||
public static extern bool UpdateSingleAabb2(IntPtr world, IntPtr obj);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool DestroyObject2(IntPtr world, IntPtr obj);
|
||||
public static extern bool AddObjectToWorld2(IntPtr world, IntPtr obj);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool RemoveObjectFromWorld2(IntPtr world, IntPtr obj);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool DestroyObject2(IntPtr world, uint id);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void DumpPhysicsStatistics2(IntPtr sim);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -304,7 +304,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY:
|
||||
idx++;
|
||||
iV = rules.GetVector3Item(idx);
|
||||
wl.cloudDetailXYDensity = iV;
|
||||
wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_CLOUD_SCALE:
|
||||
idx++;
|
||||
@@ -329,7 +329,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY:
|
||||
idx++;
|
||||
iV = rules.GetVector3Item(idx);
|
||||
wl.cloudXYDensity = iV;
|
||||
wl.cloudXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER:
|
||||
idx++;
|
||||
@@ -384,7 +384,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE:
|
||||
idx++;
|
||||
iV = rules.GetVector3Item(idx);
|
||||
wl.reflectionWaveletScale = iV;
|
||||
wl.reflectionWaveletScale = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE:
|
||||
idx++;
|
||||
@@ -422,7 +422,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
case (int)ScriptBaseClass.WL_WATER_COLOR:
|
||||
idx++;
|
||||
iV = rules.GetVector3Item(idx);
|
||||
wl.waterColor = iV;
|
||||
wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
|
||||
break;
|
||||
case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT:
|
||||
idx++;
|
||||
|
||||
@@ -310,7 +310,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
// ---------- Integer ----------
|
||||
else if (lslparm is LSL_Integer)
|
||||
{
|
||||
if (type == typeof(int) || type == typeof(float))
|
||||
if (type == typeof(int))
|
||||
return (int)(LSL_Integer)lslparm;
|
||||
}
|
||||
|
||||
@@ -333,7 +333,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
{
|
||||
if (type == typeof(OpenMetaverse.Quaternion))
|
||||
{
|
||||
return (OpenMetaverse.Quaternion)((LSL_Rotation)lslparm);
|
||||
LSL_Rotation rot = (LSL_Rotation)lslparm;
|
||||
return new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,7 +343,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
{
|
||||
if (type == typeof(OpenMetaverse.Vector3))
|
||||
{
|
||||
return (OpenMetaverse.Vector3)((LSL_Vector)lslparm);
|
||||
LSL_Vector vect = (LSL_Vector)lslparm;
|
||||
return new OpenMetaverse.Vector3((float)vect.x,(float)vect.y,(float)vect.z);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,13 +367,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
result[i] = new UUID((LSL_Key)plist[i]);
|
||||
else if (plist[i] is LSL_Rotation)
|
||||
{
|
||||
result[i] = (OpenMetaverse.Quaternion)(
|
||||
(LSL_Rotation)plist[i]);
|
||||
LSL_Rotation rot = (LSL_Rotation)plist[i];
|
||||
result[i] = new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s);
|
||||
}
|
||||
else if (plist[i] is LSL_Vector)
|
||||
{
|
||||
result[i] = (OpenMetaverse.Vector3)(
|
||||
(LSL_Vector)plist[i]);
|
||||
LSL_Vector vect = (LSL_Vector)plist[i];
|
||||
result[i] = new OpenMetaverse.Vector3((float)vect.x,(float)vect.y,(float)vect.z);
|
||||
}
|
||||
else
|
||||
MODError("unknown LSL list element type");
|
||||
|
||||
@@ -140,16 +140,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
internal float m_ScriptDistanceFactor = 1.0f;
|
||||
internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
|
||||
|
||||
protected IUrlModule m_UrlModule = null;
|
||||
|
||||
public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
|
||||
{
|
||||
m_ScriptEngine = ScriptEngine;
|
||||
m_host = host;
|
||||
m_item = item;
|
||||
|
||||
m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
|
||||
|
||||
if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
|
||||
m_OSFunctionsEnabled = true;
|
||||
|
||||
@@ -777,9 +773,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
|
||||
// We will launch the teleport on a new thread so that when the script threads are terminated
|
||||
// before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
|
||||
Util.FireAndForget(o => World.RequestTeleportLocation(
|
||||
presence.ControllingClient, regionName, position,
|
||||
lookat, (uint)TPFlags.ViaLocation));
|
||||
Util.FireAndForget(
|
||||
o => World.RequestTeleportLocation(presence.ControllingClient, regionName,
|
||||
new Vector3((float)position.x, (float)position.y, (float)position.z),
|
||||
new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation));
|
||||
|
||||
ScriptSleep(5000);
|
||||
|
||||
@@ -822,9 +819,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
|
||||
// We will launch the teleport on a new thread so that when the script threads are terminated
|
||||
// before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
|
||||
Util.FireAndForget(o => World.RequestTeleportLocation(
|
||||
presence.ControllingClient, regionHandle,
|
||||
position, lookat, (uint)TPFlags.ViaLocation));
|
||||
Util.FireAndForget(
|
||||
o => World.RequestTeleportLocation(presence.ControllingClient, regionHandle,
|
||||
new Vector3((float)position.x, (float)position.y, (float)position.z),
|
||||
new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation));
|
||||
|
||||
ScriptSleep(5000);
|
||||
|
||||
@@ -1673,11 +1671,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
return;
|
||||
}
|
||||
|
||||
MessageObject(objUUID, message);
|
||||
}
|
||||
|
||||
private void MessageObject(UUID objUUID, string message)
|
||||
{
|
||||
object[] resobj = new object[] { new LSL_Types.LSLString(m_host.UUID.ToString()), new LSL_Types.LSLString(message) };
|
||||
|
||||
SceneObjectPart sceneOP = World.GetSceneObjectPart(objUUID);
|
||||
@@ -2255,25 +2248,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
CheckThreatLevel(ThreatLevel.High, "osGetLinkPrimitiveParams");
|
||||
m_host.AddScriptLPS(1);
|
||||
InitLSL();
|
||||
// One needs to cast m_LSL_Api because we're using functions not
|
||||
// on the ILSL_Api interface.
|
||||
LSL_Api LSL_Api = (LSL_Api)m_LSL_Api;
|
||||
LSL_List retVal = new LSL_List();
|
||||
LSL_List remaining = null;
|
||||
List<SceneObjectPart> parts = LSL_Api.GetLinkParts(linknumber);
|
||||
List<SceneObjectPart> parts = ((LSL_Api)m_LSL_Api).GetLinkParts(linknumber);
|
||||
foreach (SceneObjectPart part in parts)
|
||||
{
|
||||
remaining = LSL_Api.GetPrimParams(part, rules, ref retVal);
|
||||
}
|
||||
|
||||
while (remaining != null && remaining.Length > 2)
|
||||
{
|
||||
linknumber = remaining.GetLSLIntegerItem(0);
|
||||
rules = remaining.GetSublist(1, -1);
|
||||
parts = LSL_Api.GetLinkParts(linknumber);
|
||||
|
||||
foreach (SceneObjectPart part in parts)
|
||||
remaining = LSL_Api.GetPrimParams(part, rules, ref retVal);
|
||||
retVal += ((LSL_Api)m_LSL_Api).GetLinkPrimitiveParams(part, rules);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
@@ -2350,7 +2329,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
ownerID = m_host.OwnerID;
|
||||
UUID x = module.CreateNPC(firstname,
|
||||
lastname,
|
||||
position,
|
||||
new Vector3((float) position.x, (float) position.y, (float) position.z),
|
||||
ownerID,
|
||||
senseAsAgent,
|
||||
World,
|
||||
@@ -2467,7 +2446,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
return new LSL_Vector(0, 0, 0);
|
||||
}
|
||||
|
||||
public void osNpcMoveTo(LSL_Key npc, LSL_Vector pos)
|
||||
public void osNpcMoveTo(LSL_Key npc, LSL_Vector position)
|
||||
{
|
||||
CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo");
|
||||
m_host.AddScriptLPS(1);
|
||||
@@ -2482,6 +2461,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
if (!module.CheckPermissions(npcId, m_host.OwnerID))
|
||||
return;
|
||||
|
||||
Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z);
|
||||
module.MoveToTarget(npcId, World, pos, false, true, false);
|
||||
}
|
||||
}
|
||||
@@ -2501,10 +2481,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
if (!module.CheckPermissions(npcId, m_host.OwnerID))
|
||||
return;
|
||||
|
||||
Vector3 pos = new Vector3((float)target.x, (float)target.y, (float)target.z);
|
||||
module.MoveToTarget(
|
||||
new UUID(npc.m_string),
|
||||
World,
|
||||
target,
|
||||
pos,
|
||||
(options & ScriptBaseClass.OS_NPC_NO_FLY) != 0,
|
||||
(options & ScriptBaseClass.OS_NPC_LAND_AT_TARGET) != 0,
|
||||
(options & ScriptBaseClass.OS_NPC_RUNNING) != 0);
|
||||
@@ -2556,7 +2537,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
ScenePresence sp = World.GetScenePresence(npcId);
|
||||
|
||||
if (sp != null)
|
||||
sp.Rotation = rotation;
|
||||
sp.Rotation = LSL_Api.Rot2Quaternion(rotation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2918,17 +2899,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public LSL_Float osGetHealth(string avatar)
|
||||
{
|
||||
CheckThreatLevel(ThreatLevel.None, "osGetHealth");
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
LSL_Float health = new LSL_Float(-1);
|
||||
ScenePresence presence = World.GetScenePresence(new UUID(avatar));
|
||||
if (presence != null) health = presence.Health;
|
||||
return health;
|
||||
}
|
||||
|
||||
public void osCauseDamage(string avatar, double damage)
|
||||
{
|
||||
@@ -2988,7 +2958,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
m_host.AddScriptLPS(1);
|
||||
InitLSL();
|
||||
|
||||
return m_LSL_Api.GetPrimitiveParamsEx(prim, rules);
|
||||
return m_LSL_Api.GetLinkPrimitiveParamsEx(prim, rules);
|
||||
}
|
||||
|
||||
public void osSetPrimitiveParams(LSL_Key prim, LSL_List rules)
|
||||
@@ -2997,7 +2967,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
m_host.AddScriptLPS(1);
|
||||
InitLSL();
|
||||
|
||||
m_LSL_Api.SetPrimitiveParamsEx(prim, rules, "osSetPrimitiveParams");
|
||||
m_LSL_Api.SetPrimitiveParamsEx(prim, rules);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -3229,8 +3199,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
}
|
||||
}
|
||||
|
||||
#region Attachment commands
|
||||
|
||||
public void osForceAttachToAvatar(int attachmentPoint)
|
||||
{
|
||||
CheckThreatLevel(ThreatLevel.High, "osForceAttachToAvatar");
|
||||
@@ -3320,175 +3288,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
((LSL_Api)m_LSL_Api).DetachFromAvatar();
|
||||
}
|
||||
|
||||
public LSL_List osGetNumberOfAttachments(LSL_Key avatar, LSL_List attachmentPoints)
|
||||
{
|
||||
CheckThreatLevel(ThreatLevel.Moderate, "osGetNumberOfAttachments");
|
||||
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
UUID targetUUID;
|
||||
ScenePresence target;
|
||||
LSL_List resp = new LSL_List();
|
||||
|
||||
if (attachmentPoints.Length >= 1 && UUID.TryParse(avatar.ToString(), out targetUUID) && World.TryGetScenePresence(targetUUID, out target))
|
||||
{
|
||||
foreach (object point in attachmentPoints.Data)
|
||||
{
|
||||
LSL_Integer ipoint = new LSL_Integer(
|
||||
(point is LSL_Integer || point is int || point is uint) ?
|
||||
(int)point :
|
||||
0
|
||||
);
|
||||
resp.Add(ipoint);
|
||||
if (ipoint == 0)
|
||||
{
|
||||
// indicates zero attachments
|
||||
resp.Add(new LSL_Integer(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
// gets the number of attachments on the attachment point
|
||||
resp.Add(new LSL_Integer(target.GetAttachments((uint)ipoint).Count));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
public void osMessageAttachments(LSL_Key avatar, string message, LSL_List attachmentPoints, int options)
|
||||
{
|
||||
CheckThreatLevel(ThreatLevel.Moderate, "osMessageAttachments");
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
UUID targetUUID;
|
||||
ScenePresence target;
|
||||
|
||||
if (attachmentPoints.Length >= 1 && UUID.TryParse(avatar.ToString(), out targetUUID) && World.TryGetScenePresence(targetUUID, out target))
|
||||
{
|
||||
List<int> aps = new List<int>();
|
||||
foreach (object point in attachmentPoints.Data)
|
||||
{
|
||||
int ipoint;
|
||||
if (int.TryParse(point.ToString(), out ipoint))
|
||||
{
|
||||
aps.Add(ipoint);
|
||||
}
|
||||
}
|
||||
|
||||
List<SceneObjectGroup> attachments = new List<SceneObjectGroup>();
|
||||
|
||||
bool msgAll = aps.Contains(ScriptBaseClass.OS_ATTACH_MSG_ALL);
|
||||
bool invertPoints = (options & ScriptBaseClass.OS_ATTACH_MSG_INVERT_POINTS) != 0;
|
||||
|
||||
if (msgAll && invertPoints)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (msgAll || invertPoints)
|
||||
{
|
||||
attachments = target.GetAttachments();
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (int point in aps)
|
||||
{
|
||||
if (point > 0)
|
||||
{
|
||||
attachments.AddRange(target.GetAttachments((uint)point));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we have no attachments at this point, exit now
|
||||
if (attachments.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<SceneObjectGroup> ignoreThese = new List<SceneObjectGroup>();
|
||||
|
||||
if (invertPoints)
|
||||
{
|
||||
foreach (SceneObjectGroup attachment in attachments)
|
||||
{
|
||||
if (aps.Contains((int)attachment.AttachmentPoint))
|
||||
{
|
||||
ignoreThese.Add(attachment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (SceneObjectGroup attachment in ignoreThese)
|
||||
{
|
||||
attachments.Remove(attachment);
|
||||
}
|
||||
ignoreThese.Clear();
|
||||
|
||||
// if inverting removed all attachments to check, exit now
|
||||
if (attachments.Count < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((options & ScriptBaseClass.OS_ATTACH_MSG_OBJECT_CREATOR) != 0)
|
||||
{
|
||||
foreach (SceneObjectGroup attachment in attachments)
|
||||
{
|
||||
if (attachment.RootPart.CreatorID != m_host.CreatorID)
|
||||
{
|
||||
ignoreThese.Add(attachment);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (SceneObjectGroup attachment in ignoreThese)
|
||||
{
|
||||
attachments.Remove(attachment);
|
||||
}
|
||||
ignoreThese.Clear();
|
||||
|
||||
// if filtering by same object creator removed all
|
||||
// attachments to check, exit now
|
||||
if (attachments.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ((options & ScriptBaseClass.OS_ATTACH_MSG_SCRIPT_CREATOR) != 0)
|
||||
{
|
||||
foreach (SceneObjectGroup attachment in attachments)
|
||||
{
|
||||
if (attachment.RootPart.CreatorID != m_item.CreatorID)
|
||||
{
|
||||
ignoreThese.Add(attachment);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (SceneObjectGroup attachment in ignoreThese)
|
||||
{
|
||||
attachments.Remove(attachment);
|
||||
}
|
||||
ignoreThese.Clear();
|
||||
|
||||
// if filtering by object creator must match originating
|
||||
// script creator removed all attachments to check,
|
||||
// exit now
|
||||
if (attachments.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (SceneObjectGroup attachment in attachments)
|
||||
{
|
||||
MessageObject(attachment.RootPart.UUID, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Checks if thing is a UUID.
|
||||
/// </summary>
|
||||
@@ -3538,17 +3337,5 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
|
||||
return new LSL_Key(m_host.ParentGroup.FromPartID.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the response type for an HTTP request/response
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public void osSetContentType(LSL_Key id, string type)
|
||||
{
|
||||
CheckThreatLevel(ThreatLevel.High,"osSetResponseType");
|
||||
if (m_UrlModule != null)
|
||||
m_UrlModule.HttpContentType(new UUID(id),type);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -351,7 +351,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
|
||||
q = avatar.Rotation * q;
|
||||
}
|
||||
|
||||
LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
|
||||
LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
|
||||
LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
|
||||
double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
|
||||
|
||||
@@ -428,8 +428,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
|
||||
try
|
||||
{
|
||||
Vector3 diff = toRegionPos - fromRegionPos;
|
||||
double dot = LSL_Types.Vector3.Dot(forward_dir, diff);
|
||||
double mag_obj = LSL_Types.Vector3.Mag(diff);
|
||||
LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(diff.X, diff.Y, diff.Z);
|
||||
double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir);
|
||||
double mag_obj = LSL_Types.Vector3.Mag(obj_dir);
|
||||
ang_obj = Math.Acos(dot / (mag_fwd * mag_obj));
|
||||
}
|
||||
catch
|
||||
@@ -478,7 +479,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
|
||||
q = avatar.Rotation * q;
|
||||
}
|
||||
|
||||
LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
|
||||
LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
|
||||
LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
|
||||
double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
|
||||
bool attached = (SensePoint.ParentGroup.AttachmentPoint != 0);
|
||||
@@ -559,8 +560,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
|
||||
double ang_obj = 0;
|
||||
try
|
||||
{
|
||||
LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(
|
||||
toRegionPos - fromRegionPos);
|
||||
Vector3 diff = toRegionPos - fromRegionPos;
|
||||
LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(diff.X, diff.Y, diff.Z);
|
||||
double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir);
|
||||
double mag_obj = LSL_Types.Vector3.Mag(obj_dir);
|
||||
ang_obj = Math.Acos(dot / (mag_fwd * mag_obj));
|
||||
|
||||
@@ -424,7 +424,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
||||
LSL_String llXorBase64StringsCorrect(string str1, string str2);
|
||||
void print(string str);
|
||||
|
||||
void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc);
|
||||
LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
|
||||
void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
|
||||
LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
||||
void osAvatarPlayAnimation(string avatar, string animation);
|
||||
void osAvatarStopAnimation(string avatar, string animation);
|
||||
|
||||
#region Attachment commands
|
||||
// Attachment commands
|
||||
|
||||
/// <summary>
|
||||
/// Attach the object containing this script to the avatar that owns it without asking for PERMISSION_ATTACH
|
||||
@@ -192,29 +192,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
||||
/// <remarks>Nothing happens if the object is not attached.</remarks>
|
||||
void osForceDetachFromAvatar();
|
||||
|
||||
/// <summary>
|
||||
/// Returns a strided list of the specified attachment points and the number of attachments on those points.
|
||||
/// </summary>
|
||||
/// <param name="avatar">avatar UUID</param>
|
||||
/// <param name="attachmentPoints">list of ATTACH_* constants</param>
|
||||
/// <returns></returns>
|
||||
LSL_List osGetNumberOfAttachments(LSL_Key avatar, LSL_List attachmentPoints);
|
||||
|
||||
/// <summary>
|
||||
/// Sends a specified message to the specified avatar's attachments on
|
||||
/// the specified attachment points.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Behaves as osMessageObject(), without the sending script needing to know the attachment keys in advance.
|
||||
/// </remarks>
|
||||
/// <param name="avatar">avatar UUID</param>
|
||||
/// <param name="message">message string</param>
|
||||
/// <param name="attachmentPoints">list of ATTACH_* constants, or -1 for all attachments. If -1 is specified and OS_ATTACH_MSG_INVERT_POINTS is present in flags, no action is taken.</param>
|
||||
/// <param name="flags">flags further constraining the attachments to deliver the message to.</param>
|
||||
void osMessageAttachments(LSL_Key avatar, string message, LSL_List attachmentPoints, int flags);
|
||||
|
||||
#endregion
|
||||
|
||||
//texture draw functions
|
||||
string osMovePen(string drawList, int x, int y);
|
||||
string osDrawLine(string drawList, int startX, int startY, int endX, int endY);
|
||||
@@ -340,7 +317,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
||||
int osGetSimulatorMemory();
|
||||
void osKickAvatar(string FirstName,string SurName,string alert);
|
||||
void osSetSpeed(string UUID, LSL_Float SpeedModifier);
|
||||
LSL_Float osGetHealth(string avatar);
|
||||
void osCauseHealing(string avatar, double healing);
|
||||
void osCauseDamage(string avatar, double damage);
|
||||
LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules);
|
||||
@@ -388,11 +364,5 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
||||
/// </summary>
|
||||
/// <returns>Rezzing object key or NULL_KEY if rezzed by agent or otherwise unknown.</returns>
|
||||
LSL_Key osGetRezzingObject();
|
||||
|
||||
/// <summary>
|
||||
/// Sets the response type for an HTTP request/response
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
void osSetContentType(LSL_Key id, string type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,58 +237,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||
public const int ATTACH_HUD_BOTTOM = 37;
|
||||
public const int ATTACH_HUD_BOTTOM_RIGHT = 38;
|
||||
|
||||
#region osMessageAttachments constants
|
||||
|
||||
/// <summary>
|
||||
/// Instructs osMessageAttachements to send the message to attachments
|
||||
/// on every point.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// One might expect this to be named OS_ATTACH_ALL, but then one might
|
||||
/// also expect functions designed to attach or detach or get
|
||||
/// attachments to work with it too. Attaching a no-copy item to
|
||||
/// many attachments could be dangerous.
|
||||
/// when combined with OS_ATTACH_MSG_INVERT_POINTS, will prevent the
|
||||
/// message from being sent.
|
||||
/// if combined with OS_ATTACH_MSG_OBJECT_CREATOR or
|
||||
/// OS_ATTACH_MSG_SCRIPT_CREATOR, could result in no message being
|
||||
/// sent- this is expected behaviour.
|
||||
/// </remarks>
|
||||
public const int OS_ATTACH_MSG_ALL = -65535;
|
||||
|
||||
/// <summary>
|
||||
/// Instructs osMessageAttachements to invert how the attachment points
|
||||
/// list should be treated (e.g. go from inclusive operation to
|
||||
/// exclusive operation).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This might be used if you want to deliver a message to one set of
|
||||
/// attachments and a different message to everything else. With
|
||||
/// this flag, you only need to build one explicit list for both calls.
|
||||
/// </remarks>
|
||||
public const int OS_ATTACH_MSG_INVERT_POINTS = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Instructs osMessageAttachments to only send the message to
|
||||
/// attachments with a CreatorID that matches the host object CreatorID
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This would be used if distributed in an object vendor/updater server.
|
||||
/// </remarks>
|
||||
public const int OS_ATTACH_MSG_OBJECT_CREATOR = 2;
|
||||
|
||||
/// <summary>
|
||||
/// Instructs osMessageAttachments to only send the message to
|
||||
/// attachments with a CreatorID that matches the sending script CreatorID
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This might be used if the script is distributed independently of a
|
||||
/// containing object.
|
||||
/// </remarks>
|
||||
public const int OS_ATTACH_MSG_SCRIPT_CREATOR = 4;
|
||||
|
||||
#endregion
|
||||
|
||||
public const int LAND_LEVEL = 0;
|
||||
public const int LAND_RAISE = 1;
|
||||
public const int LAND_LOWER = 2;
|
||||
@@ -380,7 +328,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||
public const int PRIM_OMEGA = 32;
|
||||
public const int PRIM_POS_LOCAL = 33;
|
||||
public const int PRIM_LINK_TARGET = 34;
|
||||
public const int PRIM_SLICE = 35;
|
||||
public const int PRIM_TEXGEN_DEFAULT = 0;
|
||||
public const int PRIM_TEXGEN_PLANAR = 1;
|
||||
|
||||
|
||||
@@ -289,7 +289,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||
m_OSSL_Functions.osAvatarStopAnimation(avatar, animation);
|
||||
}
|
||||
|
||||
#region Attachment commands
|
||||
// Avatar functions
|
||||
|
||||
public void osForceAttachToAvatar(int attachmentPoint)
|
||||
{
|
||||
@@ -311,18 +311,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||
m_OSSL_Functions.osForceDetachFromAvatar();
|
||||
}
|
||||
|
||||
public LSL_List osGetNumberOfAttachments(LSL_Key avatar, LSL_List attachmentPoints)
|
||||
{
|
||||
return m_OSSL_Functions.osGetNumberOfAttachments(avatar, attachmentPoints);
|
||||
}
|
||||
|
||||
public void osMessageAttachments(LSL_Key avatar, string message, LSL_List attachmentPoints, int flags)
|
||||
{
|
||||
m_OSSL_Functions.osMessageAttachments(avatar, message, attachmentPoints, flags);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// Texture Draw functions
|
||||
|
||||
public string osMovePen(string drawList, int x, int y)
|
||||
@@ -877,12 +865,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||
{
|
||||
m_OSSL_Functions.osSetSpeed(UUID, SpeedModifier);
|
||||
}
|
||||
|
||||
public LSL_Float osGetHealth(string avatar)
|
||||
{
|
||||
return m_OSSL_Functions.osGetHealth(avatar);
|
||||
}
|
||||
|
||||
|
||||
public void osCauseDamage(string avatar, double damage)
|
||||
{
|
||||
m_OSSL_Functions.osCauseDamage(avatar, damage);
|
||||
@@ -967,10 +950,5 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||
{
|
||||
return m_OSSL_Functions.osGetRezzingObject();
|
||||
}
|
||||
|
||||
public void osSetContentType(LSL_Key id, string type)
|
||||
{
|
||||
m_OSSL_Functions.osSetContentType(id,type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -546,8 +546,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
|
||||
"OpenSim.Region.ScriptEngine.Shared.dll"));
|
||||
parameters.ReferencedAssemblies.Add(Path.Combine(rootPath,
|
||||
"OpenSim.Region.ScriptEngine.Shared.Api.Runtime.dll"));
|
||||
parameters.ReferencedAssemblies.Add(Path.Combine(rootPath,
|
||||
"OpenMetaverseTypes.dll"));
|
||||
|
||||
if (lang == enumCompileType.yp)
|
||||
{
|
||||
|
||||
@@ -160,11 +160,11 @@ namespace OpenSim.Region.ScriptEngine.Shared
|
||||
else
|
||||
{
|
||||
// Set the values from the touch data provided by the client
|
||||
touchST = new LSL_Types.Vector3(value.STCoord);
|
||||
touchUV = new LSL_Types.Vector3(value.UVCoord);
|
||||
touchNormal = new LSL_Types.Vector3(value.Normal);
|
||||
touchBinormal = new LSL_Types.Vector3(value.Binormal);
|
||||
touchPos = new LSL_Types.Vector3(value.Position);
|
||||
touchST = new LSL_Types.Vector3(value.STCoord.X, value.STCoord.Y, value.STCoord.Z);
|
||||
touchUV = new LSL_Types.Vector3(value.UVCoord.X, value.UVCoord.Y, value.UVCoord.Z);
|
||||
touchNormal = new LSL_Types.Vector3(value.Normal.X, value.Normal.Y, value.Normal.Z);
|
||||
touchBinormal = new LSL_Types.Vector3(value.Binormal.X, value.Binormal.Y, value.Binormal.Z);
|
||||
touchPos = new LSL_Types.Vector3(value.Position.X, value.Position.Y, value.Position.Z);
|
||||
touchFace = value.FaceIndex;
|
||||
}
|
||||
}
|
||||
@@ -181,13 +181,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
|
||||
|
||||
Name = presence.Firstname + " " + presence.Lastname;
|
||||
Owner = Key;
|
||||
Position = new LSL_Types.Vector3(presence.AbsolutePosition);
|
||||
Position = new LSL_Types.Vector3(
|
||||
presence.AbsolutePosition.X,
|
||||
presence.AbsolutePosition.Y,
|
||||
presence.AbsolutePosition.Z);
|
||||
Rotation = new LSL_Types.Quaternion(
|
||||
presence.Rotation.X,
|
||||
presence.Rotation.Y,
|
||||
presence.Rotation.Z,
|
||||
presence.Rotation.W);
|
||||
Velocity = new LSL_Types.Vector3(presence.Velocity);
|
||||
Velocity = new LSL_Types.Vector3(
|
||||
presence.Velocity.X,
|
||||
presence.Velocity.Y,
|
||||
presence.Velocity.Z);
|
||||
|
||||
if (presence.PresenceType != PresenceType.Npc)
|
||||
{
|
||||
@@ -235,12 +241,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
|
||||
}
|
||||
}
|
||||
|
||||
Position = new LSL_Types.Vector3(part.AbsolutePosition);
|
||||
Position = new LSL_Types.Vector3(part.AbsolutePosition.X,
|
||||
part.AbsolutePosition.Y,
|
||||
part.AbsolutePosition.Z);
|
||||
|
||||
Quaternion wr = part.ParentGroup.GroupRotation;
|
||||
Rotation = new LSL_Types.Quaternion(wr.X, wr.Y, wr.Z, wr.W);
|
||||
|
||||
Velocity = new LSL_Types.Vector3(part.Velocity);
|
||||
Velocity = new LSL_Types.Vector3(part.Velocity.X,
|
||||
part.Velocity.Y,
|
||||
part.Velocity.Z);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,11 +31,6 @@ using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
using OpenSim.Framework;
|
||||
|
||||
using OpenMetaverse;
|
||||
using OMV_Vector3 = OpenMetaverse.Vector3;
|
||||
using OMV_Vector3d = OpenMetaverse.Vector3d;
|
||||
using OMV_Quaternion = OpenMetaverse.Quaternion;
|
||||
|
||||
namespace OpenSim.Region.ScriptEngine.Shared
|
||||
{
|
||||
[Serializable]
|
||||
@@ -59,20 +54,6 @@ namespace OpenSim.Region.ScriptEngine.Shared
|
||||
z = (float)vector.z;
|
||||
}
|
||||
|
||||
public Vector3(OMV_Vector3 vector)
|
||||
{
|
||||
x = vector.X;
|
||||
y = vector.Y;
|
||||
z = vector.Z;
|
||||
}
|
||||
|
||||
public Vector3(OMV_Vector3d vector)
|
||||
{
|
||||
x = vector.X;
|
||||
y = vector.Y;
|
||||
z = vector.Z;
|
||||
}
|
||||
|
||||
public Vector3(double X, double Y, double Z)
|
||||
{
|
||||
x = X;
|
||||
@@ -128,26 +109,6 @@ namespace OpenSim.Region.ScriptEngine.Shared
|
||||
return new list(new object[] { vec });
|
||||
}
|
||||
|
||||
public static implicit operator OMV_Vector3(Vector3 vec)
|
||||
{
|
||||
return new OMV_Vector3((float)vec.x, (float)vec.y, (float)vec.z);
|
||||
}
|
||||
|
||||
public static implicit operator Vector3(OMV_Vector3 vec)
|
||||
{
|
||||
return new Vector3(vec);
|
||||
}
|
||||
|
||||
public static implicit operator OMV_Vector3d(Vector3 vec)
|
||||
{
|
||||
return new OMV_Vector3d(vec.x, vec.y, vec.z);
|
||||
}
|
||||
|
||||
public static implicit operator Vector3(OMV_Vector3d vec)
|
||||
{
|
||||
return new Vector3(vec);
|
||||
}
|
||||
|
||||
public static bool operator ==(Vector3 lhs, Vector3 rhs)
|
||||
{
|
||||
return (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z);
|
||||
@@ -361,14 +322,6 @@ namespace OpenSim.Region.ScriptEngine.Shared
|
||||
s = 1;
|
||||
}
|
||||
|
||||
public Quaternion(OMV_Quaternion rot)
|
||||
{
|
||||
x = rot.X;
|
||||
y = rot.Y;
|
||||
z = rot.Z;
|
||||
s = rot.W;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Overriders
|
||||
@@ -415,21 +368,6 @@ namespace OpenSim.Region.ScriptEngine.Shared
|
||||
return new list(new object[] { r });
|
||||
}
|
||||
|
||||
public static implicit operator OMV_Quaternion(Quaternion rot)
|
||||
{
|
||||
// LSL quaternions can normalize to 0, normal Quaternions can't.
|
||||
if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
|
||||
rot.z = 1; // ZERO_ROTATION = 0,0,0,1
|
||||
OMV_Quaternion omvrot = new OMV_Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
|
||||
omvrot.Normalize();
|
||||
return omvrot;
|
||||
}
|
||||
|
||||
public static implicit operator Quaternion(OMV_Quaternion rot)
|
||||
{
|
||||
return new Quaternion(rot);
|
||||
}
|
||||
|
||||
public static bool operator ==(Quaternion lhs, Quaternion rhs)
|
||||
{
|
||||
// Return true if the fields match:
|
||||
@@ -622,23 +560,12 @@ namespace OpenSim.Region.ScriptEngine.Shared
|
||||
else if (m_data[itemIndex] is LSL_Types.LSLString)
|
||||
return new LSLInteger(m_data[itemIndex].ToString());
|
||||
else
|
||||
throw new InvalidCastException(string.Format(
|
||||
"{0} expected but {1} given",
|
||||
typeof(LSL_Types.LSLInteger).Name,
|
||||
m_data[itemIndex] != null ?
|
||||
m_data[itemIndex].GetType().Name : "null"));
|
||||
throw new InvalidCastException();
|
||||
}
|
||||
|
||||
public LSL_Types.Vector3 GetVector3Item(int itemIndex)
|
||||
{
|
||||
if(m_data[itemIndex] is LSL_Types.Vector3)
|
||||
return (LSL_Types.Vector3)m_data[itemIndex];
|
||||
else
|
||||
throw new InvalidCastException(string.Format(
|
||||
"{0} expected but {1} given",
|
||||
typeof(LSL_Types.Vector3).Name,
|
||||
m_data[itemIndex] != null ?
|
||||
m_data[itemIndex].GetType().Name : "null"));
|
||||
return (LSL_Types.Vector3)m_data[itemIndex];
|
||||
}
|
||||
|
||||
public LSL_Types.Quaternion GetQuaternionItem(int itemIndex)
|
||||
|
||||
@@ -152,7 +152,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||
det[0] = new DetectParams();
|
||||
det[0].Key = remoteClient.AgentId;
|
||||
det[0].Populate(myScriptEngine.World);
|
||||
det[0].OffsetPos = offsetPos;
|
||||
det[0].OffsetPos = new LSL_Types.Vector3(offsetPos.X,
|
||||
offsetPos.Y,
|
||||
offsetPos.Z);
|
||||
|
||||
if (originalID == 0)
|
||||
{
|
||||
@@ -296,7 +298,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||
foreach (DetectedObject detobj in col.Colliders)
|
||||
{
|
||||
DetectParams d = new DetectParams();
|
||||
d.Position = detobj.posVector;
|
||||
d.Position = new LSL_Types.Vector3(detobj.posVector.X,
|
||||
detobj.posVector.Y,
|
||||
detobj.posVector.Z);
|
||||
d.Populate(myScriptEngine.World);
|
||||
det.Add(d);
|
||||
myScriptEngine.PostObjectEvent(localID, new EventParams(
|
||||
@@ -314,7 +318,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||
foreach (DetectedObject detobj in col.Colliders)
|
||||
{
|
||||
DetectParams d = new DetectParams();
|
||||
d.Position = detobj.posVector;
|
||||
d.Position = new LSL_Types.Vector3(detobj.posVector.X,
|
||||
detobj.posVector.Y,
|
||||
detobj.posVector.Z);
|
||||
d.Populate(myScriptEngine.World);
|
||||
det.Add(d);
|
||||
myScriptEngine.PostObjectEvent(localID, new EventParams(
|
||||
@@ -331,7 +337,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||
foreach (DetectedObject detobj in col.Colliders)
|
||||
{
|
||||
DetectParams d = new DetectParams();
|
||||
d.Position = detobj.posVector;
|
||||
d.Position = new LSL_Types.Vector3(detobj.posVector.X,
|
||||
detobj.posVector.Y,
|
||||
detobj.posVector.Z);
|
||||
d.Populate(myScriptEngine.World);
|
||||
det.Add(d);
|
||||
myScriptEngine.PostObjectEvent(localID, new EventParams(
|
||||
@@ -373,8 +381,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||
myScriptEngine.PostObjectEvent(localID, new EventParams(
|
||||
"at_target", new object[] {
|
||||
new LSL_Types.LSLInteger(handle),
|
||||
new LSL_Types.Vector3(targetpos),
|
||||
new LSL_Types.Vector3(atpos) },
|
||||
new LSL_Types.Vector3(targetpos.X,targetpos.Y,targetpos.Z),
|
||||
new LSL_Types.Vector3(atpos.X,atpos.Y,atpos.Z) },
|
||||
new DetectParams[0]));
|
||||
}
|
||||
|
||||
@@ -391,8 +399,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||
myScriptEngine.PostObjectEvent(localID, new EventParams(
|
||||
"at_rot_target", new object[] {
|
||||
new LSL_Types.LSLInteger(handle),
|
||||
new LSL_Types.Quaternion(targetrot),
|
||||
new LSL_Types.Quaternion(atrot) },
|
||||
new LSL_Types.Quaternion(targetrot.X,targetrot.Y,targetrot.Z,targetrot.W),
|
||||
new LSL_Types.Quaternion(atrot.X,atrot.Y,atrot.Z,atrot.W) },
|
||||
new DetectParams[0]));
|
||||
}
|
||||
|
||||
|
||||
@@ -1492,9 +1492,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||
else if (p[i] is string)
|
||||
lsl_p[i] = new LSL_Types.LSLString((string)p[i]);
|
||||
else if (p[i] is Vector3)
|
||||
lsl_p[i] = new LSL_Types.Vector3((Vector3)p[i]);
|
||||
lsl_p[i] = new LSL_Types.Vector3(((Vector3)p[i]).X, ((Vector3)p[i]).Y, ((Vector3)p[i]).Z);
|
||||
else if (p[i] is Quaternion)
|
||||
lsl_p[i] = new LSL_Types.Quaternion((Quaternion)p[i]);
|
||||
lsl_p[i] = new LSL_Types.Quaternion(((Quaternion)p[i]).X, ((Quaternion)p[i]).Y, ((Quaternion)p[i]).Z, ((Quaternion)p[i]).W);
|
||||
else if (p[i] is float)
|
||||
lsl_p[i] = new LSL_Types.LSLFloat((float)p[i]);
|
||||
else
|
||||
@@ -1518,9 +1518,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||
else if (p[i] is string)
|
||||
lsl_p[i] = new LSL_Types.LSLString((string)p[i]);
|
||||
else if (p[i] is Vector3)
|
||||
lsl_p[i] = new LSL_Types.Vector3((Vector3)p[i]);
|
||||
lsl_p[i] = new LSL_Types.Vector3(((Vector3)p[i]).X, ((Vector3)p[i]).Y, ((Vector3)p[i]).Z);
|
||||
else if (p[i] is Quaternion)
|
||||
lsl_p[i] = new LSL_Types.Quaternion((Quaternion)p[i]);
|
||||
lsl_p[i] = new LSL_Types.Quaternion(((Quaternion)p[i]).X, ((Quaternion)p[i]).Y, ((Quaternion)p[i]).Z, ((Quaternion)p[i]).W);
|
||||
else if (p[i] is float)
|
||||
lsl_p[i] = new LSL_Types.LSLFloat((float)p[i]);
|
||||
else
|
||||
|
||||
@@ -164,19 +164,5 @@ namespace OpenSim.Services.Connectors
|
||||
m_database.RemoveRegionEnvironmentSettings(regionUUID);
|
||||
}
|
||||
|
||||
public void SaveExtra(UUID regionID, string name, string val)
|
||||
{
|
||||
m_database.SaveExtra(regionID, name, val);
|
||||
}
|
||||
|
||||
public void RemoveExtra(UUID regionID, string name)
|
||||
{
|
||||
m_database.RemoveExtra(regionID, name);
|
||||
}
|
||||
|
||||
public Dictionary<string, string> GetExtra(UUID regionID)
|
||||
{
|
||||
return m_database.GetExtra(regionID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,14 +137,9 @@ namespace OpenSim.Services.GridService
|
||||
if (regionInfos.RegionID == UUID.Zero)
|
||||
return "Invalid RegionID - cannot be zero UUID";
|
||||
|
||||
// This needs better sanity testing. What if regionInfo is registering in
|
||||
// overlapping coords?
|
||||
RegionData region = m_Database.Get(regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID);
|
||||
if ((region != null) && (region.RegionID != regionInfos.RegionID))
|
||||
{
|
||||
m_log.WarnFormat("[GRID SERVICE]: Region {0} tried to register in coordinates {1}, {2} which are already in use in scope {3}.",
|
||||
regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID);
|
||||
return "Region overlaps another region";
|
||||
}
|
||||
|
||||
if (region != null)
|
||||
{
|
||||
// There is a preexisting record
|
||||
@@ -181,7 +176,32 @@ namespace OpenSim.Services.GridService
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here, the destination is clear. Now for the real check.
|
||||
if ((region != null) && (region.RegionID != regionInfos.RegionID))
|
||||
{
|
||||
m_log.WarnFormat("[GRID SERVICE]: Region {0} tried to register in coordinates {1}, {2} which are already in use in scope {3}.",
|
||||
regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID);
|
||||
return "Region overlaps another region";
|
||||
}
|
||||
|
||||
if ((region != null) && (region.RegionID == regionInfos.RegionID) &&
|
||||
((region.posX != regionInfos.RegionLocX) || (region.posY != regionInfos.RegionLocY)))
|
||||
{
|
||||
if ((Convert.ToInt32(region.Data["flags"]) & (int)OpenSim.Data.RegionFlags.NoMove) != 0)
|
||||
return "Can't move this region";
|
||||
|
||||
// Region reregistering in other coordinates. Delete the old entry
|
||||
m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) was previously registered at {2}-{3}. Deleting old entry.",
|
||||
regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY);
|
||||
|
||||
try
|
||||
{
|
||||
m_Database.Delete(regionInfos.RegionID);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_AllowDuplicateNames)
|
||||
{
|
||||
@@ -200,31 +220,6 @@ namespace OpenSim.Services.GridService
|
||||
}
|
||||
}
|
||||
|
||||
// If there is an old record for us, delete it if it is elsewhere.
|
||||
region = m_Database.Get(regionInfos.RegionID, scopeID);
|
||||
if ((region != null) && (region.RegionID == regionInfos.RegionID) &&
|
||||
((region.posX != regionInfos.RegionLocX) || (region.posY != regionInfos.RegionLocY)))
|
||||
{
|
||||
if ((Convert.ToInt32(region.Data["flags"]) & (int)OpenSim.Data.RegionFlags.NoMove) != 0)
|
||||
return "Can't move this region";
|
||||
|
||||
if ((Convert.ToInt32(region.Data["flags"]) & (int)OpenSim.Data.RegionFlags.LockedOut) != 0)
|
||||
return "Region locked out";
|
||||
|
||||
// Region reregistering in other coordinates. Delete the old entry
|
||||
m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) was previously registered at {2}-{3}. Deleting old entry.",
|
||||
regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY);
|
||||
|
||||
try
|
||||
{
|
||||
m_Database.Delete(regionInfos.RegionID);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Everything is ok, let's register
|
||||
RegionData rdata = RegionInfo2RegionData(regionInfos);
|
||||
rdata.ScopeID = scopeID;
|
||||
@@ -232,6 +227,8 @@ namespace OpenSim.Services.GridService
|
||||
if (region != null)
|
||||
{
|
||||
int oldFlags = Convert.ToInt32(region.Data["flags"]);
|
||||
if ((oldFlags & (int)OpenSim.Data.RegionFlags.LockedOut) != 0)
|
||||
return "Region locked out";
|
||||
|
||||
oldFlags &= ~(int)OpenSim.Data.RegionFlags.Reservation;
|
||||
|
||||
|
||||
@@ -176,8 +176,7 @@ namespace OpenSim.Services.Interfaces
|
||||
List<AvatarAttachment> attachments = appearance.GetAttachments();
|
||||
foreach (AvatarAttachment attach in attachments)
|
||||
{
|
||||
if (attach.ItemID != UUID.Zero)
|
||||
Data["_ap_" + attach.AttachPoint] = attach.ItemID.ToString();
|
||||
Data["_ap_" + attach.AttachPoint] = attach.ItemID.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -127,19 +127,6 @@ namespace OpenSim.Data.Null
|
||||
{
|
||||
m_store.RemoveRegionEnvironmentSettings(regionUUID);
|
||||
}
|
||||
|
||||
public void SaveExtra(UUID regionID, string name, string value)
|
||||
{
|
||||
}
|
||||
|
||||
public void RemoveExtra(UUID regionID, string name)
|
||||
{
|
||||
}
|
||||
|
||||
public Dictionary<string, string> GetExtra(UUID regionID)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -331,18 +318,5 @@ namespace OpenSim.Data.Null
|
||||
public void Shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
public void SaveExtra(UUID regionID, string name, string value)
|
||||
{
|
||||
}
|
||||
|
||||
public void RemoveExtra(UUID regionID, string name)
|
||||
{
|
||||
}
|
||||
|
||||
public Dictionary<string, string> GetExtra(UUID regionID)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
23
ThirdPartyLicenses/Newtonsoft-JsonDotNet.txt
Normal file
23
ThirdPartyLicenses/Newtonsoft-JsonDotNet.txt
Normal file
@@ -0,0 +1,23 @@
|
||||
Json.NET
|
||||
License: The MIT License
|
||||
Copyright (c) 2007 James Newton-King
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
BIN
bin/Newtonsoft.Json.Net20.dll
Executable file
BIN
bin/Newtonsoft.Json.Net20.dll
Executable file
Binary file not shown.
5827
bin/Newtonsoft.Json.XML
Normal file
5827
bin/Newtonsoft.Json.XML
Normal file
File diff suppressed because it is too large
Load Diff
BIN
bin/Newtonsoft.Json.pdb
Normal file
BIN
bin/Newtonsoft.Json.pdb
Normal file
Binary file not shown.
@@ -87,18 +87,10 @@
|
||||
;; from the selected region_info_source.
|
||||
; allow_regionless = false
|
||||
|
||||
;# {NonPhysicalPrimMin} {} {Minimum size of nonphysical prims?} {} 0.01
|
||||
;; Minimum size for non-physical prims. Affects resizing of existing prims. This can be overriden in the region config file (as NonphysicalPrimMin!).
|
||||
; NonphysicalPrimMin = 0.01
|
||||
|
||||
;# {NonPhysicalPrimMax} {} {Maximum size of nonphysical prims?} {} 256
|
||||
;; Maximum size for non-physical prims. Affects resizing of existing prims. This can be overriden in the region config file (as NonphysicalPrimMax!).
|
||||
; NonphysicalPrimMax = 256
|
||||
|
||||
;# {PhysicalPrimMin} {} {Minimum size of physical prims?} {} 10
|
||||
;; Maximum size where a prim can be physical. Affects resizing of existing prims. This can be overriden in the region config file.
|
||||
; PhysicalPrimMin = 0.01
|
||||
|
||||
;# {PhysicalPrimMax} {} {Maximum size of physical prims?} {} 10
|
||||
;; Maximum size where a prim can be physical. Affects resizing of existing prims. This can be overriden in the region config file.
|
||||
; PhysicalPrimMax = 10
|
||||
|
||||
@@ -905,7 +905,7 @@
|
||||
AvatarDensity = 60.0
|
||||
AvatarCapsuleRadius = 0.37
|
||||
AvatarCapsuleHeight = 1.5
|
||||
AvatarContactProcessingThreshold = 0.1
|
||||
AvatarContactProcessingThreshold = 0.1;
|
||||
|
||||
MaxObjectMass = 10000.01
|
||||
|
||||
@@ -919,19 +919,19 @@
|
||||
CcdSweptSphereRadius = 0.0
|
||||
ContactProcessingThreshold = 0.1
|
||||
; If setting a pool size, also disable dynamic allocation (default pool size is 4096 with dynamic alloc)
|
||||
MaxPersistantManifoldPoolSize = 0
|
||||
ShouldDisableContactPoolDynamicAllocation = False
|
||||
ShouldForceUpdateAllAabbs = False
|
||||
ShouldRandomizeSolverOrder = False
|
||||
ShouldSplitSimulationIslands = False
|
||||
ShouldEnableFrictionCaching = False
|
||||
MaxPersistantManifoldPoolSize = 0;
|
||||
ShouldDisableContactPoolDynamicAllocation = False;
|
||||
ShouldForceUpdateAllAabbs = False;
|
||||
ShouldRandomizeSolverOrder = False;
|
||||
ShouldSplitSimulationIslands = False;
|
||||
ShouldEnableFrictionCaching = False;
|
||||
NumberOfSolverIterations = 0;
|
||||
|
||||
; Linkset constraint parameters
|
||||
LinkConstraintUseFrameOffset = False
|
||||
LinkConstraintEnableTransMotor = True
|
||||
LinkConstraintTransMotorMaxVel = 5.0
|
||||
LinkConstraintTransMotorMaxForce = 0.1
|
||||
LinkConstraintUseFrameOffset = False;
|
||||
LinkConstraintEnableTransMotor = True;
|
||||
LinkConstraintTransMotorMaxVel = 5.0;
|
||||
LinkConstraintTransMotorMaxForce = 0.1;
|
||||
|
||||
|
||||
; Whether to mesh sculpties
|
||||
@@ -942,23 +942,15 @@
|
||||
|
||||
; level of detail for physical meshes. 32,16,8 or 4 with 32 being full detail
|
||||
MeshLevelOfDetail = 8
|
||||
; if mesh size is > threshold meters, we need to add more detail because people will notice
|
||||
MeshLevelOfDetailMegaPrimThreshold = 10
|
||||
MeshLevelOfDetailMegaPrim = 16
|
||||
; number^2 non-physical level of detail of the sculpt texture. 32x32 - 1024 verticies
|
||||
SculptLevelOfDetail = 32
|
||||
|
||||
; Bullet step parameters
|
||||
MaxSubSteps = 10
|
||||
MaxSubSteps = 10;
|
||||
FixedTimeStep = .01667
|
||||
|
||||
MaxCollisionsPerFrame = 2048
|
||||
MaxUpdatesPerFrame = 8192
|
||||
|
||||
; Detailed physics debug logging
|
||||
PhysicsLoggingEnabled = False
|
||||
PhysicsLoggingDir = "."
|
||||
VehicleLoggingEnabled = False
|
||||
MaxUpdatesPerFrame = 2048
|
||||
|
||||
[RemoteAdmin]
|
||||
enabled = false
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -3264,7 +3264,6 @@
|
||||
|
||||
<ReferencePath>../../../bin/</ReferencePath>
|
||||
<Reference name="System"/>
|
||||
<Reference name="System.Core"/>
|
||||
<Reference name="System.Xml"/>
|
||||
<Reference name="System.Data"/>
|
||||
<Reference name="log4net" path="../../../bin/"/>
|
||||
|
||||
Reference in New Issue
Block a user