Merge branch 'master' into careminster
Conflicts: OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.csavinationmerge
commit
12971e73d4
|
@ -363,12 +363,13 @@ namespace OpenSim.Region.CoreModules.Asset
|
||||||
/// Try to get an asset from the file cache.
|
/// Try to get an asset from the file cache.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="id"></param>
|
/// <param name="id"></param>
|
||||||
/// <returns></returns>
|
/// <returns>An asset retrieved from the file cache. null if there was a problem retrieving an asset.</returns>
|
||||||
private AssetBase GetFromFileCache(string id)
|
private AssetBase GetFromFileCache(string id)
|
||||||
{
|
{
|
||||||
AssetBase asset = null;
|
AssetBase asset = null;
|
||||||
|
|
||||||
string filename = GetFileName(id);
|
string filename = GetFileName(id);
|
||||||
|
|
||||||
if (File.Exists(filename))
|
if (File.Exists(filename))
|
||||||
{
|
{
|
||||||
FileStream stream = null;
|
FileStream stream = null;
|
||||||
|
@ -383,7 +384,7 @@ namespace OpenSim.Region.CoreModules.Asset
|
||||||
}
|
}
|
||||||
catch (System.Runtime.Serialization.SerializationException e)
|
catch (System.Runtime.Serialization.SerializationException e)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat(
|
m_log.WarnFormat(
|
||||||
"[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
|
"[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
|
||||||
filename, id, e.Message, e.StackTrace);
|
filename, id, e.Message, e.StackTrace);
|
||||||
|
|
||||||
|
@ -395,7 +396,7 @@ namespace OpenSim.Region.CoreModules.Asset
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat(
|
m_log.WarnFormat(
|
||||||
"[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
|
"[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
|
||||||
filename, id, e.Message, e.StackTrace);
|
filename, id, e.Message, e.StackTrace);
|
||||||
}
|
}
|
||||||
|
@ -552,7 +553,7 @@ namespace OpenSim.Region.CoreModules.Asset
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat(
|
m_log.WarnFormat(
|
||||||
"[FLOTSAM ASSET CACHE]: Failed to expire cached file {0}. Exception {1} {2}",
|
"[FLOTSAM ASSET CACHE]: Failed to expire cached file {0}. Exception {1} {2}",
|
||||||
id, e.Message, e.StackTrace);
|
id, e.Message, e.StackTrace);
|
||||||
}
|
}
|
||||||
|
@ -603,29 +604,39 @@ namespace OpenSim.Region.CoreModules.Asset
|
||||||
/// <param name="purgeLine"></param>
|
/// <param name="purgeLine"></param>
|
||||||
private void CleanExpiredFiles(string dir, DateTime purgeLine)
|
private void CleanExpiredFiles(string dir, DateTime purgeLine)
|
||||||
{
|
{
|
||||||
foreach (string file in Directory.GetFiles(dir))
|
try
|
||||||
{
|
{
|
||||||
if (File.GetLastAccessTime(file) < purgeLine)
|
foreach (string file in Directory.GetFiles(dir))
|
||||||
{
|
{
|
||||||
File.Delete(file);
|
if (File.GetLastAccessTime(file) < purgeLine)
|
||||||
|
{
|
||||||
|
File.Delete(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recurse into lower tiers
|
||||||
|
foreach (string subdir in Directory.GetDirectories(dir))
|
||||||
|
{
|
||||||
|
CleanExpiredFiles(subdir, purgeLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if a tier directory is empty, if so, delete it
|
||||||
|
int dirSize = Directory.GetFiles(dir).Length + Directory.GetDirectories(dir).Length;
|
||||||
|
if (dirSize == 0)
|
||||||
|
{
|
||||||
|
Directory.Delete(dir);
|
||||||
|
}
|
||||||
|
else if (dirSize >= m_CacheWarnAt)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[FLOTSAM ASSET CACHE]: Cache folder exceeded CacheWarnAt limit {0} {1}. Suggest increasing tiers, tier length, or reducing cache expiration",
|
||||||
|
dir, dirSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
// Recurse into lower tiers
|
|
||||||
foreach (string subdir in Directory.GetDirectories(dir))
|
|
||||||
{
|
{
|
||||||
CleanExpiredFiles(subdir, purgeLine);
|
m_log.Warn(
|
||||||
}
|
string.Format("[FLOTSAM ASSET CACHE]: Could not complete clean of expired files in {0}, exception ", dir), e);
|
||||||
|
|
||||||
// Check if a tier directory is empty, if so, delete it
|
|
||||||
int dirSize = Directory.GetFiles(dir).Length + Directory.GetDirectories(dir).Length;
|
|
||||||
if (dirSize == 0)
|
|
||||||
{
|
|
||||||
Directory.Delete(dir);
|
|
||||||
}
|
|
||||||
else if (dirSize >= m_CacheWarnAt)
|
|
||||||
{
|
|
||||||
m_log.WarnFormat("[FLOTSAM ASSET CACHE]: Cache folder exceeded CacheWarnAt limit {0} {1}. Suggest increasing tiers, tier length, or reducing cache expiration", dir, dirSize);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -684,7 +695,7 @@ namespace OpenSim.Region.CoreModules.Asset
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat(
|
m_log.WarnFormat(
|
||||||
"[FLOTSAM ASSET CACHE]: Failed to write asset {0} to temporary location {1} (final {2}) on cache in {3}. Exception {4} {5}.",
|
"[FLOTSAM ASSET CACHE]: Failed to write asset {0} to temporary location {1} (final {2}) on cache in {3}. Exception {4} {5}.",
|
||||||
asset.ID, tempname, filename, directory, e.Message, e.StackTrace);
|
asset.ID, tempname, filename, directory, e.Message, e.StackTrace);
|
||||||
|
|
||||||
|
@ -763,17 +774,31 @@ namespace OpenSim.Region.CoreModules.Asset
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This notes the last time the Region had a deep asset scan performed on it.
|
/// This notes the last time the Region had a deep asset scan performed on it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="RegionID"></param>
|
/// <param name="regionID"></param>
|
||||||
private void StampRegionStatusFile(UUID RegionID)
|
private void StampRegionStatusFile(UUID regionID)
|
||||||
{
|
{
|
||||||
string RegionCacheStatusFile = Path.Combine(m_CacheDirectory, "RegionStatus_" + RegionID.ToString() + ".fac");
|
string RegionCacheStatusFile = Path.Combine(m_CacheDirectory, "RegionStatus_" + regionID.ToString() + ".fac");
|
||||||
if (File.Exists(RegionCacheStatusFile))
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
File.SetLastWriteTime(RegionCacheStatusFile, DateTime.Now);
|
if (File.Exists(RegionCacheStatusFile))
|
||||||
|
{
|
||||||
|
File.SetLastWriteTime(RegionCacheStatusFile, DateTime.Now);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
File.WriteAllText(
|
||||||
|
RegionCacheStatusFile,
|
||||||
|
"Please do not delete this file unless you are manually clearing your Flotsam Asset Cache.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
File.WriteAllText(RegionCacheStatusFile, "Please do not delete this file unless you are manually clearing your Flotsam Asset Cache.");
|
m_log.Warn(
|
||||||
|
string.Format(
|
||||||
|
"[FLOTSAM ASSET CACHE]: Could not stamp region status file for region {0}. Exception ",
|
||||||
|
regionID),
|
||||||
|
e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -842,7 +867,7 @@ namespace OpenSim.Region.CoreModules.Asset
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat(
|
m_log.WarnFormat(
|
||||||
"[FLOTSAM ASSET CACHE]: Couldn't clear asset cache directory {0} from {1}. Exception {2} {3}",
|
"[FLOTSAM ASSET CACHE]: Couldn't clear asset cache directory {0} from {1}. Exception {2} {3}",
|
||||||
dir, m_CacheDirectory, e.Message, e.StackTrace);
|
dir, m_CacheDirectory, e.Message, e.StackTrace);
|
||||||
}
|
}
|
||||||
|
@ -856,7 +881,7 @@ namespace OpenSim.Region.CoreModules.Asset
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat(
|
m_log.WarnFormat(
|
||||||
"[FLOTSAM ASSET CACHE]: Couldn't clear asset cache file {0} from {1}. Exception {1} {2}",
|
"[FLOTSAM ASSET CACHE]: Couldn't clear asset cache file {0} from {1}. Exception {1} {2}",
|
||||||
file, m_CacheDirectory, e.Message, e.StackTrace);
|
file, m_CacheDirectory, e.Message, e.StackTrace);
|
||||||
}
|
}
|
||||||
|
|
|
@ -487,6 +487,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[INVENTORY ARCHIVER]: Loaded coalescence {0} has {1} objects", assetId, coa.Count);
|
// "[INVENTORY ARCHIVER]: Loaded coalescence {0} has {1} objects", assetId, coa.Count);
|
||||||
|
|
||||||
|
if (coa.Objects.Count == 0)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[INVENTORY ARCHIVE READ REQUEST]: Aborting load of coalesced object from asset {0} as it has zero loaded components",
|
||||||
|
assetId);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
sceneObjects.AddRange(coa.Objects);
|
sceneObjects.AddRange(coa.Objects);
|
||||||
}
|
}
|
||||||
|
@ -495,7 +503,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
SceneObjectGroup deserializedObject = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
|
SceneObjectGroup deserializedObject = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
|
||||||
|
|
||||||
if (deserializedObject != null)
|
if (deserializedObject != null)
|
||||||
|
{
|
||||||
sceneObjects.Add(deserializedObject);
|
sceneObjects.Add(deserializedObject);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[INVENTORY ARCHIVE READ REQUEST]: Aborting load of object from asset {0} as deserialization failed",
|
||||||
|
assetId);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (SceneObjectGroup sog in sceneObjects)
|
foreach (SceneObjectGroup sog in sceneObjects)
|
||||||
|
|
|
@ -42,9 +42,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Serialize and deserialize coalesced scene objects.
|
/// Serialize and deserialize coalesced scene objects.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
|
||||||
/// Deserialization not yet here.
|
|
||||||
/// </remarks>
|
|
||||||
public class CoalescedSceneObjectsSerializer
|
public class CoalescedSceneObjectsSerializer
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
@ -128,6 +125,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||||
// m_log.DebugFormat("[COALESCED SCENE OBJECTS SERIALIZER]: TryFromXml() deserializing {0}", xml);
|
// m_log.DebugFormat("[COALESCED SCENE OBJECTS SERIALIZER]: TryFromXml() deserializing {0}", xml);
|
||||||
|
|
||||||
coa = null;
|
coa = null;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
using (StringReader sr = new StringReader(xml))
|
using (StringReader sr = new StringReader(xml))
|
||||||
{
|
{
|
||||||
|
@ -153,7 +151,23 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||||
if (reader.Name == "SceneObjectGroup")
|
if (reader.Name == "SceneObjectGroup")
|
||||||
{
|
{
|
||||||
string soXml = reader.ReadOuterXml();
|
string soXml = reader.ReadOuterXml();
|
||||||
coa.Add(SceneObjectSerializer.FromOriginalXmlFormat(soXml));
|
|
||||||
|
SceneObjectGroup so = SceneObjectSerializer.FromOriginalXmlFormat(soXml);
|
||||||
|
|
||||||
|
if (so != null)
|
||||||
|
{
|
||||||
|
coa.Add(so);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// XXX: Possibly we should fail outright here rather than continuing if a particular component of the
|
||||||
|
// coalesced object fails to load.
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[COALESCED SCENE OBJECTS SERIALIZER]: Deserialization of xml for component {0} failed. Continuing.",
|
||||||
|
i);
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,15 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
// extract the internals of a has reference
|
// extract the internals of a has reference
|
||||||
protected static Regex m_HashPattern = new Regex("{([^}]+)}");
|
protected static Regex m_HashPattern = new Regex("{([^}]+)}");
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
/// <summary>
|
||||||
|
/// This is a simple estimator for the size of the stored data, it
|
||||||
|
/// is not precise, but should be close enough to implement reasonable
|
||||||
|
/// limits on the storage space used
|
||||||
|
/// </summary>
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
public int StringSpace { get; set; }
|
||||||
|
|
||||||
// -----------------------------------------------------------------
|
// -----------------------------------------------------------------
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
@ -110,6 +119,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
// -----------------------------------------------------------------
|
// -----------------------------------------------------------------
|
||||||
public JsonStore()
|
public JsonStore()
|
||||||
{
|
{
|
||||||
|
StringSpace = 0;
|
||||||
m_TakeStore = new List<TakeValueCallbackClass>();
|
m_TakeStore = new List<TakeValueCallbackClass>();
|
||||||
m_ReadStore = new List<TakeValueCallbackClass>();
|
m_ReadStore = new List<TakeValueCallbackClass>();
|
||||||
}
|
}
|
||||||
|
@ -247,9 +257,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
if (path.Count == 0)
|
if (path.Count == 0)
|
||||||
{
|
{
|
||||||
ValueStore = ovalue;
|
ValueStore = ovalue;
|
||||||
|
StringSpace = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pkey will be the final element in the path, we pull it out here to make sure
|
||||||
|
// that the assignment works correctly
|
||||||
string pkey = path.Pop();
|
string pkey = path.Pop();
|
||||||
string pexpr = PathExpressionToKey(path);
|
string pexpr = PathExpressionToKey(path);
|
||||||
if (pexpr != "")
|
if (pexpr != "")
|
||||||
|
@ -259,7 +272,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
if (result == null)
|
if (result == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Check for and extract array references
|
// Check pkey, the last element in the path, for and extract array references
|
||||||
MatchCollection amatches = m_ArrayPattern.Matches(pkey,0);
|
MatchCollection amatches = m_ArrayPattern.Matches(pkey,0);
|
||||||
if (amatches.Count > 0)
|
if (amatches.Count > 0)
|
||||||
{
|
{
|
||||||
|
@ -276,8 +289,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
{
|
{
|
||||||
string npkey = String.Format("[{0}]",amap.Count);
|
string npkey = String.Format("[{0}]",amap.Count);
|
||||||
|
|
||||||
amap.Add(ovalue);
|
if (ovalue != null)
|
||||||
InvokeNextCallback(pexpr + npkey);
|
{
|
||||||
|
StringSpace += ComputeSizeOf(ovalue);
|
||||||
|
|
||||||
|
amap.Add(ovalue);
|
||||||
|
InvokeNextCallback(pexpr + npkey);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,9 +303,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
if (0 <= aval && aval < amap.Count)
|
if (0 <= aval && aval < amap.Count)
|
||||||
{
|
{
|
||||||
if (ovalue == null)
|
if (ovalue == null)
|
||||||
|
{
|
||||||
|
StringSpace -= ComputeSizeOf(amap[aval]);
|
||||||
amap.RemoveAt(aval);
|
amap.RemoveAt(aval);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
StringSpace -= ComputeSizeOf(amap[aval]);
|
||||||
|
StringSpace += ComputeSizeOf(ovalue);
|
||||||
amap[aval] = ovalue;
|
amap[aval] = ovalue;
|
||||||
InvokeNextCallback(pexpr + pkey);
|
InvokeNextCallback(pexpr + pkey);
|
||||||
}
|
}
|
||||||
|
@ -307,16 +330,27 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
|
|
||||||
if (result is OSDMap)
|
if (result is OSDMap)
|
||||||
{
|
{
|
||||||
|
// this is the assignment case
|
||||||
OSDMap hmap = result as OSDMap;
|
OSDMap hmap = result as OSDMap;
|
||||||
if (ovalue != null)
|
if (ovalue != null)
|
||||||
{
|
{
|
||||||
|
StringSpace -= ComputeSizeOf(hmap[hkey]);
|
||||||
|
StringSpace += ComputeSizeOf(ovalue);
|
||||||
|
|
||||||
hmap[hkey] = ovalue;
|
hmap[hkey] = ovalue;
|
||||||
InvokeNextCallback(pexpr + pkey);
|
InvokeNextCallback(pexpr + pkey);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else if (hmap.ContainsKey(hkey))
|
|
||||||
|
// this is the remove case
|
||||||
|
if (hmap.ContainsKey(hkey))
|
||||||
|
{
|
||||||
|
StringSpace -= ComputeSizeOf(hmap[hkey]);
|
||||||
hmap.Remove(hkey);
|
hmap.Remove(hkey);
|
||||||
|
return true;
|
||||||
return true;
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -522,8 +556,27 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
|
|
||||||
return pkey;
|
return pkey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
protected static int ComputeSizeOf(OSD value)
|
||||||
|
{
|
||||||
|
string sval;
|
||||||
|
|
||||||
|
if (ConvertOutputValue(value,out sval,true))
|
||||||
|
return sval.Length;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
/// <summary>
|
||||||
|
/// </summary>
|
||||||
|
// -----------------------------------------------------------------
|
||||||
public class JsonObjectStore : JsonStore
|
public class JsonObjectStore : JsonStore
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log =
|
private static readonly ILog m_log =
|
||||||
|
@ -557,6 +610,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
{
|
{
|
||||||
m_scene = scene;
|
m_scene = scene;
|
||||||
m_objectID = oid;
|
m_objectID = oid;
|
||||||
|
|
||||||
|
// the size limit is imposed on whatever is already in the store
|
||||||
|
StringSpace = ComputeSizeOf(ValueStore);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
|
|
||||||
private IConfig m_config = null;
|
private IConfig m_config = null;
|
||||||
private bool m_enabled = false;
|
private bool m_enabled = false;
|
||||||
|
private bool m_enableObjectStore = false;
|
||||||
|
private int m_maxStringSpace = Int32.MaxValue;
|
||||||
|
|
||||||
private Scene m_scene = null;
|
private Scene m_scene = null;
|
||||||
|
|
||||||
private Dictionary<UUID,JsonStore> m_JsonValueStore;
|
private Dictionary<UUID,JsonStore> m_JsonValueStore;
|
||||||
|
@ -90,6 +93,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
}
|
}
|
||||||
|
|
||||||
m_enabled = m_config.GetBoolean("Enabled", m_enabled);
|
m_enabled = m_config.GetBoolean("Enabled", m_enabled);
|
||||||
|
m_enableObjectStore = m_config.GetBoolean("EnableObjectStore", m_enableObjectStore);
|
||||||
|
m_maxStringSpace = m_config.GetInt("MaxStringSpace", m_maxStringSpace);
|
||||||
|
if (m_maxStringSpace == 0)
|
||||||
|
m_maxStringSpace = Int32.MaxValue;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -178,6 +185,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
public bool AttachObjectStore(UUID objectID)
|
public bool AttachObjectStore(UUID objectID)
|
||||||
{
|
{
|
||||||
if (! m_enabled) return false;
|
if (! m_enabled) return false;
|
||||||
|
if (! m_enableObjectStore) return false;
|
||||||
|
|
||||||
SceneObjectPart sop = m_scene.GetSceneObjectPart(objectID);
|
SceneObjectPart sop = m_scene.GetSceneObjectPart(objectID);
|
||||||
if (sop == null)
|
if (sop == null)
|
||||||
|
@ -239,7 +247,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
if (! m_enabled) return false;
|
if (! m_enabled) return false;
|
||||||
|
|
||||||
lock (m_JsonValueStore)
|
lock (m_JsonValueStore)
|
||||||
m_JsonValueStore.Remove(storeID);
|
return m_JsonValueStore.Remove(storeID);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -311,8 +319,16 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
lock (map)
|
lock (map)
|
||||||
if (map.SetValue(path,value,useJson))
|
{
|
||||||
return true;
|
if (map.StringSpace > m_maxStringSpace)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[JsonStore] {0} exceeded string size; {1} bytes used of {2} limit",
|
||||||
|
storeID,map.StringSpace,m_maxStringSpace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return map.SetValue(path,value,useJson);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -344,8 +360,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
lock (map)
|
lock (map)
|
||||||
if (map.RemoveValue(path))
|
return map.RemoveValue(path);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -504,7 +504,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
{
|
{
|
||||||
string jsondata = SLUtil.ParseNotecardToString(Encoding.UTF8.GetString(a.Data));
|
string jsondata = SLUtil.ParseNotecardToString(Encoding.UTF8.GetString(a.Data));
|
||||||
int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0;
|
int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0;
|
||||||
m_comms.DispatchReply(scriptID,result, "", reqID.ToString());
|
m_comms.DispatchReply(scriptID, result, "", reqID.ToString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|
|
@ -283,7 +283,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
|
||||||
string notecardName = "nc1";
|
string notecardName = "nc1";
|
||||||
|
|
||||||
// Write notecard
|
// Write notecard
|
||||||
UUID writeNotecardRequestId = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "/", notecardName);
|
UUID writeNotecardRequestId = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "", notecardName);
|
||||||
Assert.That(writeNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
|
Assert.That(writeNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
|
||||||
|
|
||||||
TaskInventoryItem nc1Item = so.RootPart.Inventory.GetInventoryItem(notecardName);
|
TaskInventoryItem nc1Item = so.RootPart.Inventory.GetInventoryItem(notecardName);
|
||||||
|
@ -292,8 +292,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
|
||||||
// TODO: Should independently check the contents.
|
// TODO: Should independently check the contents.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Write partial test
|
||||||
|
|
||||||
{
|
{
|
||||||
// Try to write notecard against bad path
|
// Try to write notecard for a bad path
|
||||||
// In this case we do get a request id but no notecard is written.
|
// In this case we do get a request id but no notecard is written.
|
||||||
string badPathNotecardName = "badPathNotecardName";
|
string badPathNotecardName = "badPathNotecardName";
|
||||||
|
|
||||||
|
@ -312,7 +314,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
|
||||||
|
|
||||||
UUID fakeStoreId = TestHelpers.ParseTail(0x500);
|
UUID fakeStoreId = TestHelpers.ParseTail(0x500);
|
||||||
UUID fakeStoreWriteNotecardValue
|
UUID fakeStoreWriteNotecardValue
|
||||||
= (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, fakeStoreId, "/", fakeStoreNotecardName);
|
= (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, fakeStoreId, "", fakeStoreNotecardName);
|
||||||
Assert.That(fakeStoreWriteNotecardValue, Is.Not.EqualTo(UUID.Zero));
|
Assert.That(fakeStoreWriteNotecardValue, Is.Not.EqualTo(UUID.Zero));
|
||||||
|
|
||||||
TaskInventoryItem fakeStoreItem = so.RootPart.Inventory.GetInventoryItem(fakeStoreNotecardName);
|
TaskInventoryItem fakeStoreItem = so.RootPart.Inventory.GetInventoryItem(fakeStoreNotecardName);
|
||||||
|
@ -321,7 +323,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Test for reading and writing json to a notecard
|
/// Test for reading json from a notecard
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// TODO: Really needs to test correct receipt of the link_message event. Could do this by directly fetching
|
/// TODO: Really needs to test correct receipt of the link_message event. Could do this by directly fetching
|
||||||
|
@ -338,20 +340,73 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
|
||||||
SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1));
|
SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1));
|
||||||
m_scene.AddSceneObject(so);
|
m_scene.AddSceneObject(so);
|
||||||
|
|
||||||
UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }");
|
UUID creatingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }");
|
||||||
|
|
||||||
// Write notecard
|
// Write notecard
|
||||||
InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "/", notecardName);
|
InvokeOpOnHost("JsonWriteNotecard", so.UUID, creatingStoreId, "", notecardName);
|
||||||
|
|
||||||
// Read notecard
|
{
|
||||||
UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ }");
|
// Read notecard
|
||||||
UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "/", notecardName);
|
UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}");
|
||||||
Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
|
UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "", notecardName);
|
||||||
|
Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
|
||||||
|
|
||||||
string value = (string)InvokeOp("JsonGetValue", storeId, "Hello");
|
string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
|
||||||
Assert.That(value, Is.EqualTo("World"));
|
Assert.That(value, Is.EqualTo("World"));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Read notecard to new single component path
|
||||||
|
UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}");
|
||||||
|
UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make", notecardName);
|
||||||
|
Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
|
||||||
|
|
||||||
|
// These don't behave as I expect yet - reading to a path still seems to place the notecard contents at the root.
|
||||||
|
string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
|
||||||
|
Assert.That(value, Is.EqualTo(""));
|
||||||
|
|
||||||
|
value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.Hello");
|
||||||
|
Assert.That(value, Is.EqualTo("World"));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Read notecard to new multi-component path
|
||||||
|
UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}");
|
||||||
|
UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make.it", notecardName);
|
||||||
|
Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
|
||||||
|
|
||||||
|
// These don't behave as I expect yet - reading to a path still seems to place the notecard contents at the root.
|
||||||
|
string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
|
||||||
|
Assert.That(value, Is.EqualTo(""));
|
||||||
|
|
||||||
|
// TODO: Check that we are not expecting reading to a new path to work.
|
||||||
|
value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.it.Hello");
|
||||||
|
Assert.That(value, Is.EqualTo(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Read notecard to existing multi-component path
|
||||||
|
UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'make' : { 'it' : 'so' } }");
|
||||||
|
UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make.it", notecardName);
|
||||||
|
Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero));
|
||||||
|
|
||||||
|
// These don't behave as I expect yet - reading to a path still seems to place the notecard contents at the root.
|
||||||
|
string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello");
|
||||||
|
Assert.That(value, Is.EqualTo(""));
|
||||||
|
|
||||||
|
value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.it.Hello");
|
||||||
|
Assert.That(value, Is.EqualTo("World"));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Try read notecard to fake store.
|
||||||
|
UUID fakeStoreId = TestHelpers.ParseTail(0x500);
|
||||||
|
UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, fakeStoreId, "", notecardName);
|
||||||
|
Assert.That(fakeStoreId, Is.Not.EqualTo(UUID.Zero));
|
||||||
|
|
||||||
|
string value = (string)InvokeOp("JsonGetValue", fakeStoreId, "Hello");
|
||||||
|
Assert.That(value, Is.EqualTo(""));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public object DummyTestMethod(object o1, object o2, object o3, object o4, object o5) { return null; }
|
public object DummyTestMethod(object o1, object o2, object o3, object o4, object o5) { return null; }
|
||||||
|
|
|
@ -749,9 +749,10 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
_buoyancy = value;
|
_buoyancy = value;
|
||||||
DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
|
DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
|
||||||
// Buoyancy is faked by changing the gravity applied to the object
|
// Buoyancy is faked by changing the gravity applied to the object
|
||||||
float grav = PhysicsScene.Params.gravity * (1f - _buoyancy);
|
float grav = BSParam.Gravity * (1f - _buoyancy);
|
||||||
|
Gravity = new OMV.Vector3(0f, 0f, grav);
|
||||||
if (PhysBody.HasPhysicalBody)
|
if (PhysBody.HasPhysicalBody)
|
||||||
PhysicsScene.PE.SetGravity(PhysBody, new OMV.Vector3(0f, 0f, grav));
|
PhysicsScene.PE.SetGravity(PhysBody, Gravity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,10 @@ public abstract class BSPhysObject : PhysicsActor
|
||||||
Name = name; // PhysicsActor also has the name of the object. Someday consolidate.
|
Name = name; // PhysicsActor also has the name of the object. Someday consolidate.
|
||||||
TypeName = typeName;
|
TypeName = typeName;
|
||||||
|
|
||||||
|
// Initialize variables kept in base.
|
||||||
|
GravModifier = 1.0f;
|
||||||
|
Gravity = new OMV.Vector3(0f, 0f, BSParam.Gravity);
|
||||||
|
|
||||||
// We don't have any physical representation yet.
|
// We don't have any physical representation yet.
|
||||||
PhysBody = new BulletBody(localID);
|
PhysBody = new BulletBody(localID);
|
||||||
PhysShape = new BulletShape();
|
PhysShape = new BulletShape();
|
||||||
|
@ -88,8 +92,8 @@ public abstract class BSPhysObject : PhysicsActor
|
||||||
|
|
||||||
LastAssetBuildFailed = false;
|
LastAssetBuildFailed = false;
|
||||||
|
|
||||||
// Default material type
|
// Default material type. Also sets Friction, Restitution and Density.
|
||||||
Material = MaterialAttributes.Material.Wood;
|
SetMaterial((int)MaterialAttributes.Material.Wood);
|
||||||
|
|
||||||
CollisionCollection = new CollisionEventUpdate();
|
CollisionCollection = new CollisionEventUpdate();
|
||||||
CollisionsLastTick = CollisionCollection;
|
CollisionsLastTick = CollisionCollection;
|
||||||
|
@ -122,6 +126,8 @@ public abstract class BSPhysObject : PhysicsActor
|
||||||
// 'inWorld' true if the object has already been added to the dynamic world.
|
// 'inWorld' true if the object has already been added to the dynamic world.
|
||||||
public abstract void UpdatePhysicalMassProperties(float mass, bool inWorld);
|
public abstract void UpdatePhysicalMassProperties(float mass, bool inWorld);
|
||||||
|
|
||||||
|
// The gravity being applied to the object. A function of default grav, GravityModifier and Buoyancy.
|
||||||
|
public virtual OMV.Vector3 Gravity { get; set; }
|
||||||
// The last value calculated for the prim's inertia
|
// The last value calculated for the prim's inertia
|
||||||
public OMV.Vector3 Inertia { get; set; }
|
public OMV.Vector3 Inertia { get; set; }
|
||||||
|
|
||||||
|
@ -164,15 +170,18 @@ public abstract class BSPhysObject : PhysicsActor
|
||||||
public override void SetMaterial(int material)
|
public override void SetMaterial(int material)
|
||||||
{
|
{
|
||||||
Material = (MaterialAttributes.Material)material;
|
Material = (MaterialAttributes.Material)material;
|
||||||
|
|
||||||
|
// Setting the material sets the material attributes also.
|
||||||
|
MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false);
|
||||||
|
Friction = matAttrib.friction;
|
||||||
|
Restitution = matAttrib.restitution;
|
||||||
|
Density = matAttrib.density;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop all physical motion.
|
// Stop all physical motion.
|
||||||
public abstract void ZeroMotion(bool inTaintTime);
|
public abstract void ZeroMotion(bool inTaintTime);
|
||||||
public abstract void ZeroAngularMotion(bool inTaintTime);
|
public abstract void ZeroAngularMotion(bool inTaintTime);
|
||||||
|
|
||||||
// Step the vehicle simulation for this object. A NOOP if the vehicle was not configured.
|
|
||||||
public virtual void StepVehicle(float timeStep) { }
|
|
||||||
|
|
||||||
// Update the physical location and motion of the object. Called with data from Bullet.
|
// Update the physical location and motion of the object. Called with data from Bullet.
|
||||||
public abstract void UpdateProperties(EntityProperties entprop);
|
public abstract void UpdateProperties(EntityProperties entprop);
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,6 @@ public sealed class BSPrim : BSPhysObject
|
||||||
private OMV.Vector3 _position;
|
private OMV.Vector3 _position;
|
||||||
|
|
||||||
private float _mass; // the mass of this object
|
private float _mass; // the mass of this object
|
||||||
private float _density;
|
|
||||||
private OMV.Vector3 _force;
|
private OMV.Vector3 _force;
|
||||||
private OMV.Vector3 _velocity;
|
private OMV.Vector3 _velocity;
|
||||||
private OMV.Vector3 _torque;
|
private OMV.Vector3 _torque;
|
||||||
|
@ -64,8 +63,6 @@ public sealed class BSPrim : BSPhysObject
|
||||||
private int _physicsActorType;
|
private int _physicsActorType;
|
||||||
private bool _isPhysical;
|
private bool _isPhysical;
|
||||||
private bool _flying;
|
private bool _flying;
|
||||||
private float _friction;
|
|
||||||
private float _restitution;
|
|
||||||
private bool _setAlwaysRun;
|
private bool _setAlwaysRun;
|
||||||
private bool _throttleUpdates;
|
private bool _throttleUpdates;
|
||||||
private bool _floatOnWater;
|
private bool _floatOnWater;
|
||||||
|
@ -101,12 +98,6 @@ public sealed class BSPrim : BSPhysObject
|
||||||
_isPhysical = pisPhysical;
|
_isPhysical = pisPhysical;
|
||||||
_isVolumeDetect = false;
|
_isVolumeDetect = false;
|
||||||
|
|
||||||
// Someday set default attributes based on the material but, for now, we don't know the prim material yet.
|
|
||||||
// MaterialAttributes primMat = BSMaterials.GetAttributes(Material, pisPhysical);
|
|
||||||
_density = PhysicsScene.Params.defaultDensity;
|
|
||||||
_friction = PhysicsScene.Params.defaultFriction;
|
|
||||||
_restitution = PhysicsScene.Params.defaultRestitution;
|
|
||||||
|
|
||||||
VehicleController = new BSDynamics(PhysicsScene, this); // add vehicleness
|
VehicleController = new BSDynamics(PhysicsScene, this); // add vehicleness
|
||||||
|
|
||||||
_mass = CalculateMass();
|
_mass = CalculateMass();
|
||||||
|
@ -432,8 +423,6 @@ public sealed class BSPrim : BSPhysObject
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OMV.Vector3 grav = ComputeGravity(Buoyancy);
|
|
||||||
|
|
||||||
if (inWorld)
|
if (inWorld)
|
||||||
{
|
{
|
||||||
// Changing interesting properties doesn't change proxy and collision cache
|
// Changing interesting properties doesn't change proxy and collision cache
|
||||||
|
@ -443,25 +432,20 @@ public sealed class BSPrim : BSPhysObject
|
||||||
}
|
}
|
||||||
|
|
||||||
// The computation of mass props requires gravity to be set on the object.
|
// The computation of mass props requires gravity to be set on the object.
|
||||||
PhysicsScene.PE.SetGravity(PhysBody, grav);
|
Gravity = ComputeGravity(Buoyancy);
|
||||||
|
PhysicsScene.PE.SetGravity(PhysBody, Gravity);
|
||||||
|
|
||||||
Inertia = PhysicsScene.PE.CalculateLocalInertia(PhysShape, physMass);
|
Inertia = PhysicsScene.PE.CalculateLocalInertia(PhysShape, physMass);
|
||||||
PhysicsScene.PE.SetMassProps(PhysBody, physMass, Inertia);
|
PhysicsScene.PE.SetMassProps(PhysBody, physMass, Inertia);
|
||||||
PhysicsScene.PE.UpdateInertiaTensor(PhysBody);
|
PhysicsScene.PE.UpdateInertiaTensor(PhysBody);
|
||||||
|
|
||||||
// center of mass is at the zero of the object
|
DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2},grav={3},inWorld={4}",
|
||||||
// DEBUG DEBUG PhysicsScene.PE.SetCenterOfMassByPosRot(PhysBody, ForcePosition, ForceOrientation);
|
LocalID, physMass, Inertia, Gravity, inWorld);
|
||||||
DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2},grav={3},inWorld={4}", LocalID, physMass, Inertia, grav, inWorld);
|
|
||||||
|
|
||||||
if (inWorld)
|
if (inWorld)
|
||||||
{
|
{
|
||||||
AddObjectToPhysicalWorld();
|
AddObjectToPhysicalWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Must set gravity after it has been added to the world because, for unknown reasons,
|
|
||||||
// adding the object resets the object's gravity to world gravity
|
|
||||||
PhysicsScene.PE.SetGravity(PhysBody, grav);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -472,7 +456,10 @@ public sealed class BSPrim : BSPhysObject
|
||||||
OMV.Vector3 ret = PhysicsScene.DefaultGravity;
|
OMV.Vector3 ret = PhysicsScene.DefaultGravity;
|
||||||
|
|
||||||
if (!IsStatic)
|
if (!IsStatic)
|
||||||
|
{
|
||||||
ret *= (1f - buoyancy);
|
ret *= (1f - buoyancy);
|
||||||
|
ret *= GravModifier;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -596,6 +583,74 @@ public sealed class BSPrim : BSPhysObject
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
public override void SetMaterial(int material)
|
||||||
|
{
|
||||||
|
base.SetMaterial(material);
|
||||||
|
PhysicsScene.TaintedObject("BSPrim.SetMaterial", delegate()
|
||||||
|
{
|
||||||
|
UpdatePhysicalParameters();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public override float Friction
|
||||||
|
{
|
||||||
|
get { return base.Friction; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (base.Friction != value)
|
||||||
|
{
|
||||||
|
base.Friction = value;
|
||||||
|
PhysicsScene.TaintedObject("BSPrim.setFriction", delegate()
|
||||||
|
{
|
||||||
|
UpdatePhysicalParameters();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public override float Restitution
|
||||||
|
{
|
||||||
|
get { return base.Restitution; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (base.Restitution != value)
|
||||||
|
{
|
||||||
|
base.Restitution = value;
|
||||||
|
PhysicsScene.TaintedObject("BSPrim.setRestitution", delegate()
|
||||||
|
{
|
||||||
|
UpdatePhysicalParameters();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public override float Density
|
||||||
|
{
|
||||||
|
get { return base.Density; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (base.Density != value)
|
||||||
|
{
|
||||||
|
base.Density = value;
|
||||||
|
PhysicsScene.TaintedObject("BSPrim.setDensity", delegate()
|
||||||
|
{
|
||||||
|
UpdatePhysicalParameters();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public override float GravModifier
|
||||||
|
{
|
||||||
|
get { return base.GravModifier; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (base.GravModifier != value)
|
||||||
|
{
|
||||||
|
base.GravModifier = value;
|
||||||
|
PhysicsScene.TaintedObject("BSPrim.setGravityModifier", delegate()
|
||||||
|
{
|
||||||
|
UpdatePhysicalParameters();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
public override OMV.Vector3 RawVelocity
|
public override OMV.Vector3 RawVelocity
|
||||||
{
|
{
|
||||||
get { return _velocity; }
|
get { return _velocity; }
|
||||||
|
@ -761,7 +816,12 @@ public sealed class BSPrim : BSPhysObject
|
||||||
// collisionEvents: whether this object returns collision events
|
// collisionEvents: whether this object returns collision events
|
||||||
public void UpdatePhysicalParameters()
|
public void UpdatePhysicalParameters()
|
||||||
{
|
{
|
||||||
// DetailLog("{0},BSPrim.UpdatePhysicalParameters,entry,body={1},shape={2}", LocalID, BSBody, BSShape);
|
if (!PhysBody.HasPhysicalBody)
|
||||||
|
{
|
||||||
|
// This would only happen if updates are called for during initialization when the body is not set up yet.
|
||||||
|
DetailLog("{0},BSPrim.UpdatePhysicalParameters,taint,calledWithNoPhysBody", LocalID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Mangling all the physical properties requires the object not be in the physical world.
|
// Mangling all the physical properties requires the object not be in the physical world.
|
||||||
// This is a NOOP if the object is not in the world (BulletSim and Bullet ignore objects not found).
|
// This is a NOOP if the object is not in the world (BulletSim and Bullet ignore objects not found).
|
||||||
|
@ -810,8 +870,8 @@ public sealed class BSPrim : BSPhysObject
|
||||||
|
|
||||||
// Set various physical properties so other object interact properly
|
// Set various physical properties so other object interact properly
|
||||||
MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false);
|
MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false);
|
||||||
PhysicsScene.PE.SetFriction(PhysBody, matAttrib.friction);
|
PhysicsScene.PE.SetFriction(PhysBody, Friction);
|
||||||
PhysicsScene.PE.SetRestitution(PhysBody, matAttrib.restitution);
|
PhysicsScene.PE.SetRestitution(PhysBody, Restitution);
|
||||||
|
|
||||||
// Mass is zero which disables a bunch of physics stuff in Bullet
|
// Mass is zero which disables a bunch of physics stuff in Bullet
|
||||||
UpdatePhysicalMassProperties(0f, false);
|
UpdatePhysicalMassProperties(0f, false);
|
||||||
|
@ -839,9 +899,9 @@ public sealed class BSPrim : BSPhysObject
|
||||||
CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.CF_STATIC_OBJECT);
|
CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.CF_STATIC_OBJECT);
|
||||||
|
|
||||||
// Set various physical properties so other object interact properly
|
// Set various physical properties so other object interact properly
|
||||||
MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, true);
|
PhysicsScene.PE.SetFriction(PhysBody, Friction);
|
||||||
PhysicsScene.PE.SetFriction(PhysBody, matAttrib.friction);
|
PhysicsScene.PE.SetRestitution(PhysBody, Restitution);
|
||||||
PhysicsScene.PE.SetRestitution(PhysBody, matAttrib.restitution);
|
// DetailLog("{0},BSPrim.MakeDynamic,frict={1},rest={2}", LocalID, Friction, Restitution);
|
||||||
|
|
||||||
// per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382
|
// per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382
|
||||||
// Since this can be called multiple times, only zero forces when becoming physical
|
// Since this can be called multiple times, only zero forces when becoming physical
|
||||||
|
@ -944,7 +1004,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("{0} Attempt to add physical object without body. id={1}", LogHeader, LocalID);
|
m_log.ErrorFormat("{0} Attempt to add physical object without body. id={1}", LogHeader, LocalID);
|
||||||
DetailLog("{0},BSPrim.UpdatePhysicalParameters,addObjectWithoutBody,cType={1}", LocalID, PhysBody.collisionType);
|
DetailLog("{0},BSPrim.AddObjectToPhysicalWorld,addObjectWithoutBody,cType={1}", LocalID, PhysBody.collisionType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1581,7 +1641,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
profileEnd = 1.0f - (float)BaseShape.ProfileEnd * 2.0e-5f;
|
profileEnd = 1.0f - (float)BaseShape.ProfileEnd * 2.0e-5f;
|
||||||
volume *= (profileEnd - profileBegin);
|
volume *= (profileEnd - profileBegin);
|
||||||
|
|
||||||
returnMass = _density * volume;
|
returnMass = Density * volume;
|
||||||
|
|
||||||
/* Comment out code that computes the mass of the linkset. That is done in the Linkset class.
|
/* Comment out code that computes the mass of the linkset. That is done in the Linkset class.
|
||||||
if (IsRootOfLinkset)
|
if (IsRootOfLinkset)
|
||||||
|
|
|
@ -274,7 +274,7 @@ namespace OpenSim.Region.Physics.Manager
|
||||||
public virtual float Density { get; set; }
|
public virtual float Density { get; set; }
|
||||||
public virtual float GravModifier { get; set; }
|
public virtual float GravModifier { get; set; }
|
||||||
public virtual float Friction { get; set; }
|
public virtual float Friction { get; set; }
|
||||||
public virtual float Bounce { get; set; }
|
public virtual float Restitution { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Position of this actor.
|
/// Position of this actor.
|
||||||
|
|
Binary file not shown.
|
@ -1648,6 +1648,10 @@
|
||||||
[JsonStore]
|
[JsonStore]
|
||||||
Enabled = False
|
Enabled = False
|
||||||
|
|
||||||
|
;; Enable direct access to the SOP dynamic attributes
|
||||||
|
EnableObjectStore = False
|
||||||
|
MaxStringSpace = 0
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; These are defaults that are overwritten below in [Architecture].
|
;; These are defaults that are overwritten below in [Architecture].
|
||||||
;; These defaults allow OpenSim to work out of the box with
|
;; These defaults allow OpenSim to work out of the box with
|
||||||
|
|
Loading…
Reference in New Issue