diff options
Diffstat (limited to 'OpenSim')
11 files changed, 348 insertions, 95 deletions
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index 730643d..96e8f35 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | |||
@@ -363,12 +363,13 @@ namespace OpenSim.Region.CoreModules.Asset | |||
363 | /// Try to get an asset from the file cache. | 363 | /// Try to get an asset from the file cache. |
364 | /// </summary> | 364 | /// </summary> |
365 | /// <param name="id"></param> | 365 | /// <param name="id"></param> |
366 | /// <returns></returns> | 366 | /// <returns>An asset retrieved from the file cache. null if there was a problem retrieving an asset.</returns> |
367 | private AssetBase GetFromFileCache(string id) | 367 | private AssetBase GetFromFileCache(string id) |
368 | { | 368 | { |
369 | AssetBase asset = null; | 369 | AssetBase asset = null; |
370 | 370 | ||
371 | string filename = GetFileName(id); | 371 | string filename = GetFileName(id); |
372 | |||
372 | if (File.Exists(filename)) | 373 | if (File.Exists(filename)) |
373 | { | 374 | { |
374 | FileStream stream = null; | 375 | FileStream stream = null; |
@@ -383,7 +384,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
383 | } | 384 | } |
384 | catch (System.Runtime.Serialization.SerializationException e) | 385 | catch (System.Runtime.Serialization.SerializationException e) |
385 | { | 386 | { |
386 | m_log.ErrorFormat( | 387 | m_log.WarnFormat( |
387 | "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", | 388 | "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", |
388 | filename, id, e.Message, e.StackTrace); | 389 | filename, id, e.Message, e.StackTrace); |
389 | 390 | ||
@@ -395,7 +396,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
395 | } | 396 | } |
396 | catch (Exception e) | 397 | catch (Exception e) |
397 | { | 398 | { |
398 | m_log.ErrorFormat( | 399 | m_log.WarnFormat( |
399 | "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", | 400 | "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", |
400 | filename, id, e.Message, e.StackTrace); | 401 | filename, id, e.Message, e.StackTrace); |
401 | } | 402 | } |
@@ -552,7 +553,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
552 | } | 553 | } |
553 | catch (Exception e) | 554 | catch (Exception e) |
554 | { | 555 | { |
555 | m_log.ErrorFormat( | 556 | m_log.WarnFormat( |
556 | "[FLOTSAM ASSET CACHE]: Failed to expire cached file {0}. Exception {1} {2}", | 557 | "[FLOTSAM ASSET CACHE]: Failed to expire cached file {0}. Exception {1} {2}", |
557 | id, e.Message, e.StackTrace); | 558 | id, e.Message, e.StackTrace); |
558 | } | 559 | } |
@@ -603,29 +604,39 @@ namespace OpenSim.Region.CoreModules.Asset | |||
603 | /// <param name="purgeLine"></param> | 604 | /// <param name="purgeLine"></param> |
604 | private void CleanExpiredFiles(string dir, DateTime purgeLine) | 605 | private void CleanExpiredFiles(string dir, DateTime purgeLine) |
605 | { | 606 | { |
606 | foreach (string file in Directory.GetFiles(dir)) | 607 | try |
607 | { | 608 | { |
608 | if (File.GetLastAccessTime(file) < purgeLine) | 609 | foreach (string file in Directory.GetFiles(dir)) |
609 | { | 610 | { |
610 | File.Delete(file); | 611 | if (File.GetLastAccessTime(file) < purgeLine) |
612 | { | ||
613 | File.Delete(file); | ||
614 | } | ||
611 | } | 615 | } |
612 | } | ||
613 | 616 | ||
614 | // Recurse into lower tiers | 617 | // Recurse into lower tiers |
615 | foreach (string subdir in Directory.GetDirectories(dir)) | 618 | foreach (string subdir in Directory.GetDirectories(dir)) |
616 | { | 619 | { |
617 | CleanExpiredFiles(subdir, purgeLine); | 620 | CleanExpiredFiles(subdir, purgeLine); |
618 | } | 621 | } |
619 | 622 | ||
620 | // Check if a tier directory is empty, if so, delete it | 623 | // Check if a tier directory is empty, if so, delete it |
621 | int dirSize = Directory.GetFiles(dir).Length + Directory.GetDirectories(dir).Length; | 624 | int dirSize = Directory.GetFiles(dir).Length + Directory.GetDirectories(dir).Length; |
622 | if (dirSize == 0) | 625 | if (dirSize == 0) |
623 | { | 626 | { |
624 | Directory.Delete(dir); | 627 | Directory.Delete(dir); |
628 | } | ||
629 | else if (dirSize >= m_CacheWarnAt) | ||
630 | { | ||
631 | m_log.WarnFormat( | ||
632 | "[FLOTSAM ASSET CACHE]: Cache folder exceeded CacheWarnAt limit {0} {1}. Suggest increasing tiers, tier length, or reducing cache expiration", | ||
633 | dir, dirSize); | ||
634 | } | ||
625 | } | 635 | } |
626 | else if (dirSize >= m_CacheWarnAt) | 636 | catch (Exception e) |
627 | { | 637 | { |
628 | m_log.WarnFormat("[FLOTSAM ASSET CACHE]: Cache folder exceeded CacheWarnAt limit {0} {1}. Suggest increasing tiers, tier length, or reducing cache expiration", dir, dirSize); | 638 | m_log.Warn( |
639 | string.Format("[FLOTSAM ASSET CACHE]: Could not complete clean of expired files in {0}, exception ", dir), e); | ||
629 | } | 640 | } |
630 | } | 641 | } |
631 | 642 | ||
@@ -684,7 +695,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
684 | } | 695 | } |
685 | catch (IOException e) | 696 | catch (IOException e) |
686 | { | 697 | { |
687 | m_log.ErrorFormat( | 698 | m_log.WarnFormat( |
688 | "[FLOTSAM ASSET CACHE]: Failed to write asset {0} to temporary location {1} (final {2}) on cache in {3}. Exception {4} {5}.", | 699 | "[FLOTSAM ASSET CACHE]: Failed to write asset {0} to temporary location {1} (final {2}) on cache in {3}. Exception {4} {5}.", |
689 | asset.ID, tempname, filename, directory, e.Message, e.StackTrace); | 700 | asset.ID, tempname, filename, directory, e.Message, e.StackTrace); |
690 | 701 | ||
@@ -763,17 +774,31 @@ namespace OpenSim.Region.CoreModules.Asset | |||
763 | /// <summary> | 774 | /// <summary> |
764 | /// This notes the last time the Region had a deep asset scan performed on it. | 775 | /// This notes the last time the Region had a deep asset scan performed on it. |
765 | /// </summary> | 776 | /// </summary> |
766 | /// <param name="RegionID"></param> | 777 | /// <param name="regionID"></param> |
767 | private void StampRegionStatusFile(UUID RegionID) | 778 | private void StampRegionStatusFile(UUID regionID) |
768 | { | 779 | { |
769 | string RegionCacheStatusFile = Path.Combine(m_CacheDirectory, "RegionStatus_" + RegionID.ToString() + ".fac"); | 780 | string RegionCacheStatusFile = Path.Combine(m_CacheDirectory, "RegionStatus_" + regionID.ToString() + ".fac"); |
770 | if (File.Exists(RegionCacheStatusFile)) | 781 | |
782 | try | ||
771 | { | 783 | { |
772 | File.SetLastWriteTime(RegionCacheStatusFile, DateTime.Now); | 784 | if (File.Exists(RegionCacheStatusFile)) |
785 | { | ||
786 | File.SetLastWriteTime(RegionCacheStatusFile, DateTime.Now); | ||
787 | } | ||
788 | else | ||
789 | { | ||
790 | File.WriteAllText( | ||
791 | RegionCacheStatusFile, | ||
792 | "Please do not delete this file unless you are manually clearing your Flotsam Asset Cache."); | ||
793 | } | ||
773 | } | 794 | } |
774 | else | 795 | catch (Exception e) |
775 | { | 796 | { |
776 | File.WriteAllText(RegionCacheStatusFile, "Please do not delete this file unless you are manually clearing your Flotsam Asset Cache."); | 797 | m_log.Warn( |
798 | string.Format( | ||
799 | "[FLOTSAM ASSET CACHE]: Could not stamp region status file for region {0}. Exception ", | ||
800 | regionID), | ||
801 | e); | ||
777 | } | 802 | } |
778 | } | 803 | } |
779 | 804 | ||
@@ -842,7 +867,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
842 | } | 867 | } |
843 | catch (Exception e) | 868 | catch (Exception e) |
844 | { | 869 | { |
845 | m_log.ErrorFormat( | 870 | m_log.WarnFormat( |
846 | "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache directory {0} from {1}. Exception {2} {3}", | 871 | "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache directory {0} from {1}. Exception {2} {3}", |
847 | dir, m_CacheDirectory, e.Message, e.StackTrace); | 872 | dir, m_CacheDirectory, e.Message, e.StackTrace); |
848 | } | 873 | } |
@@ -856,7 +881,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
856 | } | 881 | } |
857 | catch (Exception e) | 882 | catch (Exception e) |
858 | { | 883 | { |
859 | m_log.ErrorFormat( | 884 | m_log.WarnFormat( |
860 | "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache file {0} from {1}. Exception {1} {2}", | 885 | "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache file {0} from {1}. Exception {1} {2}", |
861 | file, m_CacheDirectory, e.Message, e.StackTrace); | 886 | file, m_CacheDirectory, e.Message, e.StackTrace); |
862 | } | 887 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs index dc2b0e0..6c3ac0c 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs | |||
@@ -487,6 +487,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
487 | { | 487 | { |
488 | // m_log.DebugFormat( | 488 | // m_log.DebugFormat( |
489 | // "[INVENTORY ARCHIVER]: Loaded coalescence {0} has {1} objects", assetId, coa.Count); | 489 | // "[INVENTORY ARCHIVER]: Loaded coalescence {0} has {1} objects", assetId, coa.Count); |
490 | |||
491 | if (coa.Objects.Count == 0) | ||
492 | { | ||
493 | m_log.WarnFormat( | ||
494 | "[INVENTORY ARCHIVE READ REQUEST]: Aborting load of coalesced object from asset {0} as it has zero loaded components", | ||
495 | assetId); | ||
496 | return false; | ||
497 | } | ||
490 | 498 | ||
491 | sceneObjects.AddRange(coa.Objects); | 499 | sceneObjects.AddRange(coa.Objects); |
492 | } | 500 | } |
@@ -495,7 +503,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
495 | SceneObjectGroup deserializedObject = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | 503 | SceneObjectGroup deserializedObject = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); |
496 | 504 | ||
497 | if (deserializedObject != null) | 505 | if (deserializedObject != null) |
506 | { | ||
498 | sceneObjects.Add(deserializedObject); | 507 | sceneObjects.Add(deserializedObject); |
508 | } | ||
509 | else | ||
510 | { | ||
511 | m_log.WarnFormat( | ||
512 | "[INVENTORY ARCHIVE READ REQUEST]: Aborting load of object from asset {0} as deserialization failed", | ||
513 | assetId); | ||
514 | |||
515 | return false; | ||
516 | } | ||
499 | } | 517 | } |
500 | 518 | ||
501 | foreach (SceneObjectGroup sog in sceneObjects) | 519 | foreach (SceneObjectGroup sog in sceneObjects) |
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs index a4f730d..5cb271d 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs | |||
@@ -42,9 +42,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization | |||
42 | /// <summary> | 42 | /// <summary> |
43 | /// Serialize and deserialize coalesced scene objects. | 43 | /// Serialize and deserialize coalesced scene objects. |
44 | /// </summary> | 44 | /// </summary> |
45 | /// <remarks> | ||
46 | /// Deserialization not yet here. | ||
47 | /// </remarks> | ||
48 | public class CoalescedSceneObjectsSerializer | 45 | public class CoalescedSceneObjectsSerializer |
49 | { | 46 | { |
50 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
@@ -128,6 +125,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization | |||
128 | // m_log.DebugFormat("[COALESCED SCENE OBJECTS SERIALIZER]: TryFromXml() deserializing {0}", xml); | 125 | // m_log.DebugFormat("[COALESCED SCENE OBJECTS SERIALIZER]: TryFromXml() deserializing {0}", xml); |
129 | 126 | ||
130 | coa = null; | 127 | coa = null; |
128 | int i = 0; | ||
131 | 129 | ||
132 | using (StringReader sr = new StringReader(xml)) | 130 | using (StringReader sr = new StringReader(xml)) |
133 | { | 131 | { |
@@ -153,7 +151,23 @@ namespace OpenSim.Region.Framework.Scenes.Serialization | |||
153 | if (reader.Name == "SceneObjectGroup") | 151 | if (reader.Name == "SceneObjectGroup") |
154 | { | 152 | { |
155 | string soXml = reader.ReadOuterXml(); | 153 | string soXml = reader.ReadOuterXml(); |
156 | coa.Add(SceneObjectSerializer.FromOriginalXmlFormat(soXml)); | 154 | |
155 | SceneObjectGroup so = SceneObjectSerializer.FromOriginalXmlFormat(soXml); | ||
156 | |||
157 | if (so != null) | ||
158 | { | ||
159 | coa.Add(so); | ||
160 | } | ||
161 | else | ||
162 | { | ||
163 | // XXX: Possibly we should fail outright here rather than continuing if a particular component of the | ||
164 | // coalesced object fails to load. | ||
165 | m_log.WarnFormat( | ||
166 | "[COALESCED SCENE OBJECTS SERIALIZER]: Deserialization of xml for component {0} failed. Continuing.", | ||
167 | i); | ||
168 | } | ||
169 | |||
170 | i++; | ||
157 | } | 171 | } |
158 | } | 172 | } |
159 | 173 | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs index 5808d46..088d0cd 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs | |||
@@ -95,6 +95,15 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
95 | 95 | ||
96 | // ----------------------------------------------------------------- | 96 | // ----------------------------------------------------------------- |
97 | /// <summary> | 97 | /// <summary> |
98 | /// This is a simple estimator for the size of the stored data, it | ||
99 | /// is not precise, but should be close enough to implement reasonable | ||
100 | /// limits on the storage space used | ||
101 | /// </summary> | ||
102 | // ----------------------------------------------------------------- | ||
103 | public int StringSpace { get; set; } | ||
104 | |||
105 | // ----------------------------------------------------------------- | ||
106 | /// <summary> | ||
98 | /// | 107 | /// |
99 | /// </summary> | 108 | /// </summary> |
100 | // ----------------------------------------------------------------- | 109 | // ----------------------------------------------------------------- |
@@ -110,6 +119,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
110 | // ----------------------------------------------------------------- | 119 | // ----------------------------------------------------------------- |
111 | public JsonStore() | 120 | public JsonStore() |
112 | { | 121 | { |
122 | StringSpace = 0; | ||
113 | m_TakeStore = new List<TakeValueCallbackClass>(); | 123 | m_TakeStore = new List<TakeValueCallbackClass>(); |
114 | m_ReadStore = new List<TakeValueCallbackClass>(); | 124 | m_ReadStore = new List<TakeValueCallbackClass>(); |
115 | } | 125 | } |
@@ -247,9 +257,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
247 | if (path.Count == 0) | 257 | if (path.Count == 0) |
248 | { | 258 | { |
249 | ValueStore = ovalue; | 259 | ValueStore = ovalue; |
260 | StringSpace = 0; | ||
250 | return true; | 261 | return true; |
251 | } | 262 | } |
252 | 263 | ||
264 | // pkey will be the final element in the path, we pull it out here to make sure | ||
265 | // that the assignment works correctly | ||
253 | string pkey = path.Pop(); | 266 | string pkey = path.Pop(); |
254 | string pexpr = PathExpressionToKey(path); | 267 | string pexpr = PathExpressionToKey(path); |
255 | if (pexpr != "") | 268 | if (pexpr != "") |
@@ -259,7 +272,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
259 | if (result == null) | 272 | if (result == null) |
260 | return false; | 273 | return false; |
261 | 274 | ||
262 | // Check for and extract array references | 275 | // Check pkey, the last element in the path, for and extract array references |
263 | MatchCollection amatches = m_ArrayPattern.Matches(pkey,0); | 276 | MatchCollection amatches = m_ArrayPattern.Matches(pkey,0); |
264 | if (amatches.Count > 0) | 277 | if (amatches.Count > 0) |
265 | { | 278 | { |
@@ -276,8 +289,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
276 | { | 289 | { |
277 | string npkey = String.Format("[{0}]",amap.Count); | 290 | string npkey = String.Format("[{0}]",amap.Count); |
278 | 291 | ||
279 | amap.Add(ovalue); | 292 | if (ovalue != null) |
280 | InvokeNextCallback(pexpr + npkey); | 293 | { |
294 | StringSpace += ComputeSizeOf(ovalue); | ||
295 | |||
296 | amap.Add(ovalue); | ||
297 | InvokeNextCallback(pexpr + npkey); | ||
298 | } | ||
281 | return true; | 299 | return true; |
282 | } | 300 | } |
283 | 301 | ||
@@ -285,9 +303,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
285 | if (0 <= aval && aval < amap.Count) | 303 | if (0 <= aval && aval < amap.Count) |
286 | { | 304 | { |
287 | if (ovalue == null) | 305 | if (ovalue == null) |
306 | { | ||
307 | StringSpace -= ComputeSizeOf(amap[aval]); | ||
288 | amap.RemoveAt(aval); | 308 | amap.RemoveAt(aval); |
309 | } | ||
289 | else | 310 | else |
290 | { | 311 | { |
312 | StringSpace -= ComputeSizeOf(amap[aval]); | ||
313 | StringSpace += ComputeSizeOf(ovalue); | ||
291 | amap[aval] = ovalue; | 314 | amap[aval] = ovalue; |
292 | InvokeNextCallback(pexpr + pkey); | 315 | InvokeNextCallback(pexpr + pkey); |
293 | } | 316 | } |
@@ -307,16 +330,27 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
307 | 330 | ||
308 | if (result is OSDMap) | 331 | if (result is OSDMap) |
309 | { | 332 | { |
333 | // this is the assignment case | ||
310 | OSDMap hmap = result as OSDMap; | 334 | OSDMap hmap = result as OSDMap; |
311 | if (ovalue != null) | 335 | if (ovalue != null) |
312 | { | 336 | { |
337 | StringSpace -= ComputeSizeOf(hmap[hkey]); | ||
338 | StringSpace += ComputeSizeOf(ovalue); | ||
339 | |||
313 | hmap[hkey] = ovalue; | 340 | hmap[hkey] = ovalue; |
314 | InvokeNextCallback(pexpr + pkey); | 341 | InvokeNextCallback(pexpr + pkey); |
342 | return true; | ||
315 | } | 343 | } |
316 | else if (hmap.ContainsKey(hkey)) | 344 | |
345 | // this is the remove case | ||
346 | if (hmap.ContainsKey(hkey)) | ||
347 | { | ||
348 | StringSpace -= ComputeSizeOf(hmap[hkey]); | ||
317 | hmap.Remove(hkey); | 349 | hmap.Remove(hkey); |
318 | 350 | return true; | |
319 | return true; | 351 | } |
352 | |||
353 | return false; | ||
320 | } | 354 | } |
321 | 355 | ||
322 | return false; | 356 | return false; |
@@ -522,8 +556,27 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
522 | 556 | ||
523 | return pkey; | 557 | return pkey; |
524 | } | 558 | } |
559 | |||
560 | // ----------------------------------------------------------------- | ||
561 | /// <summary> | ||
562 | /// | ||
563 | /// </summary> | ||
564 | // ----------------------------------------------------------------- | ||
565 | protected static int ComputeSizeOf(OSD value) | ||
566 | { | ||
567 | string sval; | ||
568 | |||
569 | if (ConvertOutputValue(value,out sval,true)) | ||
570 | return sval.Length; | ||
571 | |||
572 | return 0; | ||
573 | } | ||
525 | } | 574 | } |
526 | 575 | ||
576 | // ----------------------------------------------------------------- | ||
577 | /// <summary> | ||
578 | /// </summary> | ||
579 | // ----------------------------------------------------------------- | ||
527 | public class JsonObjectStore : JsonStore | 580 | public class JsonObjectStore : JsonStore |
528 | { | 581 | { |
529 | private static readonly ILog m_log = | 582 | private static readonly ILog m_log = |
@@ -557,6 +610,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
557 | { | 610 | { |
558 | m_scene = scene; | 611 | m_scene = scene; |
559 | m_objectID = oid; | 612 | m_objectID = oid; |
613 | |||
614 | // the size limit is imposed on whatever is already in the store | ||
615 | StringSpace = ComputeSizeOf(ValueStore); | ||
560 | } | 616 | } |
561 | } | 617 | } |
562 | 618 | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs index 3b52e44..f1ce856 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs | |||
@@ -54,6 +54,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
54 | 54 | ||
55 | private IConfig m_config = null; | 55 | private IConfig m_config = null; |
56 | private bool m_enabled = false; | 56 | private bool m_enabled = false; |
57 | private bool m_enableObjectStore = false; | ||
58 | private int m_maxStringSpace = Int32.MaxValue; | ||
59 | |||
57 | private Scene m_scene = null; | 60 | private Scene m_scene = null; |
58 | 61 | ||
59 | private Dictionary<UUID,JsonStore> m_JsonValueStore; | 62 | private Dictionary<UUID,JsonStore> m_JsonValueStore; |
@@ -90,6 +93,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
90 | } | 93 | } |
91 | 94 | ||
92 | m_enabled = m_config.GetBoolean("Enabled", m_enabled); | 95 | m_enabled = m_config.GetBoolean("Enabled", m_enabled); |
96 | m_enableObjectStore = m_config.GetBoolean("EnableObjectStore", m_enableObjectStore); | ||
97 | m_maxStringSpace = m_config.GetInt("MaxStringSpace", m_maxStringSpace); | ||
98 | if (m_maxStringSpace == 0) | ||
99 | m_maxStringSpace = Int32.MaxValue; | ||
93 | } | 100 | } |
94 | catch (Exception e) | 101 | catch (Exception e) |
95 | { | 102 | { |
@@ -178,6 +185,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
178 | public bool AttachObjectStore(UUID objectID) | 185 | public bool AttachObjectStore(UUID objectID) |
179 | { | 186 | { |
180 | if (! m_enabled) return false; | 187 | if (! m_enabled) return false; |
188 | if (! m_enableObjectStore) return false; | ||
181 | 189 | ||
182 | SceneObjectPart sop = m_scene.GetSceneObjectPart(objectID); | 190 | SceneObjectPart sop = m_scene.GetSceneObjectPart(objectID); |
183 | if (sop == null) | 191 | if (sop == null) |
@@ -239,7 +247,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
239 | if (! m_enabled) return false; | 247 | if (! m_enabled) return false; |
240 | 248 | ||
241 | lock (m_JsonValueStore) | 249 | lock (m_JsonValueStore) |
242 | m_JsonValueStore.Remove(storeID); | 250 | return m_JsonValueStore.Remove(storeID); |
243 | 251 | ||
244 | return true; | 252 | return true; |
245 | } | 253 | } |
@@ -311,8 +319,16 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
311 | try | 319 | try |
312 | { | 320 | { |
313 | lock (map) | 321 | lock (map) |
314 | if (map.SetValue(path,value,useJson)) | 322 | { |
315 | return true; | 323 | if (map.StringSpace > m_maxStringSpace) |
324 | { | ||
325 | m_log.WarnFormat("[JsonStore] {0} exceeded string size; {1} bytes used of {2} limit", | ||
326 | storeID,map.StringSpace,m_maxStringSpace); | ||
327 | return false; | ||
328 | } | ||
329 | |||
330 | return map.SetValue(path,value,useJson); | ||
331 | } | ||
316 | } | 332 | } |
317 | catch (Exception e) | 333 | catch (Exception e) |
318 | { | 334 | { |
@@ -344,8 +360,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
344 | try | 360 | try |
345 | { | 361 | { |
346 | lock (map) | 362 | lock (map) |
347 | if (map.RemoveValue(path)) | 363 | return map.RemoveValue(path); |
348 | return true; | ||
349 | } | 364 | } |
350 | catch (Exception e) | 365 | catch (Exception e) |
351 | { | 366 | { |
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index 48b4a9f..d75cd32 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs | |||
@@ -504,7 +504,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
504 | { | 504 | { |
505 | string jsondata = SLUtil.ParseNotecardToString(Encoding.UTF8.GetString(a.Data)); | 505 | string jsondata = SLUtil.ParseNotecardToString(Encoding.UTF8.GetString(a.Data)); |
506 | int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0; | 506 | int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0; |
507 | m_comms.DispatchReply(scriptID,result, "", reqID.ToString()); | 507 | m_comms.DispatchReply(scriptID, result, "", reqID.ToString()); |
508 | return; | 508 | return; |
509 | } | 509 | } |
510 | catch (Exception e) | 510 | catch (Exception e) |
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 6658e1e..ca88d1a 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs | |||
@@ -283,7 +283,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests | |||
283 | string notecardName = "nc1"; | 283 | string notecardName = "nc1"; |
284 | 284 | ||
285 | // Write notecard | 285 | // Write notecard |
286 | UUID writeNotecardRequestId = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "/", notecardName); | 286 | UUID writeNotecardRequestId = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "", notecardName); |
287 | Assert.That(writeNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); | 287 | Assert.That(writeNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); |
288 | 288 | ||
289 | TaskInventoryItem nc1Item = so.RootPart.Inventory.GetInventoryItem(notecardName); | 289 | TaskInventoryItem nc1Item = so.RootPart.Inventory.GetInventoryItem(notecardName); |
@@ -292,8 +292,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests | |||
292 | // TODO: Should independently check the contents. | 292 | // TODO: Should independently check the contents. |
293 | } | 293 | } |
294 | 294 | ||
295 | // TODO: Write partial test | ||
296 | |||
295 | { | 297 | { |
296 | // Try to write notecard against bad path | 298 | // Try to write notecard for a bad path |
297 | // In this case we do get a request id but no notecard is written. | 299 | // In this case we do get a request id but no notecard is written. |
298 | string badPathNotecardName = "badPathNotecardName"; | 300 | string badPathNotecardName = "badPathNotecardName"; |
299 | 301 | ||
@@ -312,7 +314,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests | |||
312 | 314 | ||
313 | UUID fakeStoreId = TestHelpers.ParseTail(0x500); | 315 | UUID fakeStoreId = TestHelpers.ParseTail(0x500); |
314 | UUID fakeStoreWriteNotecardValue | 316 | UUID fakeStoreWriteNotecardValue |
315 | = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, fakeStoreId, "/", fakeStoreNotecardName); | 317 | = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, fakeStoreId, "", fakeStoreNotecardName); |
316 | Assert.That(fakeStoreWriteNotecardValue, Is.Not.EqualTo(UUID.Zero)); | 318 | Assert.That(fakeStoreWriteNotecardValue, Is.Not.EqualTo(UUID.Zero)); |
317 | 319 | ||
318 | TaskInventoryItem fakeStoreItem = so.RootPart.Inventory.GetInventoryItem(fakeStoreNotecardName); | 320 | TaskInventoryItem fakeStoreItem = so.RootPart.Inventory.GetInventoryItem(fakeStoreNotecardName); |
@@ -321,7 +323,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests | |||
321 | } | 323 | } |
322 | 324 | ||
323 | /// <summary> | 325 | /// <summary> |
324 | /// Test for reading and writing json to a notecard | 326 | /// Test for reading json from a notecard |
325 | /// </summary> | 327 | /// </summary> |
326 | /// <remarks> | 328 | /// <remarks> |
327 | /// TODO: Really needs to test correct receipt of the link_message event. Could do this by directly fetching | 329 | /// 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 | |||
338 | SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1)); | 340 | SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1)); |
339 | m_scene.AddSceneObject(so); | 341 | m_scene.AddSceneObject(so); |
340 | 342 | ||
341 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }"); | 343 | UUID creatingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }"); |
342 | 344 | ||
343 | // Write notecard | 345 | // Write notecard |
344 | InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "/", notecardName); | 346 | InvokeOpOnHost("JsonWriteNotecard", so.UUID, creatingStoreId, "", notecardName); |
345 | 347 | ||
346 | // Read notecard | 348 | { |
347 | UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ }"); | 349 | // Read notecard |
348 | UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "/", notecardName); | 350 | UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}"); |
349 | Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); | 351 | UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "", notecardName); |
352 | Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); | ||
350 | 353 | ||
351 | string value = (string)InvokeOp("JsonGetValue", storeId, "Hello"); | 354 | string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); |
352 | Assert.That(value, Is.EqualTo("World")); | 355 | Assert.That(value, Is.EqualTo("World")); |
356 | } | ||
357 | |||
358 | { | ||
359 | // Read notecard to new single component path | ||
360 | UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
361 | UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make", notecardName); | ||
362 | Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); | ||
363 | |||
364 | // These don't behave as I expect yet - reading to a path still seems to place the notecard contents at the root. | ||
365 | string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); | ||
366 | Assert.That(value, Is.EqualTo("")); | ||
367 | |||
368 | value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.Hello"); | ||
369 | Assert.That(value, Is.EqualTo("World")); | ||
370 | } | ||
353 | 371 | ||
372 | { | ||
373 | // Read notecard to new multi-component path | ||
374 | UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
375 | UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make.it", notecardName); | ||
376 | Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); | ||
377 | |||
378 | // These don't behave as I expect yet - reading to a path still seems to place the notecard contents at the root. | ||
379 | string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); | ||
380 | Assert.That(value, Is.EqualTo("")); | ||
381 | |||
382 | // TODO: Check that we are not expecting reading to a new path to work. | ||
383 | value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.it.Hello"); | ||
384 | Assert.That(value, Is.EqualTo("")); | ||
385 | } | ||
386 | |||
387 | { | ||
388 | // Read notecard to existing multi-component path | ||
389 | UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'make' : { 'it' : 'so' } }"); | ||
390 | UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make.it", notecardName); | ||
391 | Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); | ||
392 | |||
393 | // These don't behave as I expect yet - reading to a path still seems to place the notecard contents at the root. | ||
394 | string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); | ||
395 | Assert.That(value, Is.EqualTo("")); | ||
354 | 396 | ||
397 | value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.it.Hello"); | ||
398 | Assert.That(value, Is.EqualTo("World")); | ||
399 | } | ||
400 | |||
401 | { | ||
402 | // Try read notecard to fake store. | ||
403 | UUID fakeStoreId = TestHelpers.ParseTail(0x500); | ||
404 | UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, fakeStoreId, "", notecardName); | ||
405 | Assert.That(fakeStoreId, Is.Not.EqualTo(UUID.Zero)); | ||
406 | |||
407 | string value = (string)InvokeOp("JsonGetValue", fakeStoreId, "Hello"); | ||
408 | Assert.That(value, Is.EqualTo("")); | ||
409 | } | ||
355 | } | 410 | } |
356 | 411 | ||
357 | public object DummyTestMethod(object o1, object o2, object o3, object o4, object o5) { return null; } | 412 | public object DummyTestMethod(object o1, object o2, object o3, object o4, object o5) { return null; } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 192bcb5..d694a6a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | |||
@@ -749,9 +749,10 @@ public sealed class BSCharacter : BSPhysObject | |||
749 | _buoyancy = value; | 749 | _buoyancy = value; |
750 | DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); | 750 | DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); |
751 | // Buoyancy is faked by changing the gravity applied to the object | 751 | // Buoyancy is faked by changing the gravity applied to the object |
752 | float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); | 752 | float grav = BSParam.Gravity * (1f - _buoyancy); |
753 | Gravity = new OMV.Vector3(0f, 0f, grav); | ||
753 | if (PhysBody.HasPhysicalBody) | 754 | if (PhysBody.HasPhysicalBody) |
754 | PhysicsScene.PE.SetGravity(PhysBody, new OMV.Vector3(0f, 0f, grav)); | 755 | PhysicsScene.PE.SetGravity(PhysBody, Gravity); |
755 | } | 756 | } |
756 | } | 757 | } |
757 | 758 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index ec25aa9..0d8bb03 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | |||
@@ -78,6 +78,10 @@ public abstract class BSPhysObject : PhysicsActor | |||
78 | Name = name; // PhysicsActor also has the name of the object. Someday consolidate. | 78 | Name = name; // PhysicsActor also has the name of the object. Someday consolidate. |
79 | TypeName = typeName; | 79 | TypeName = typeName; |
80 | 80 | ||
81 | // Initialize variables kept in base. | ||
82 | GravModifier = 1.0f; | ||
83 | Gravity = new OMV.Vector3(0f, 0f, BSParam.Gravity); | ||
84 | |||
81 | // We don't have any physical representation yet. | 85 | // We don't have any physical representation yet. |
82 | PhysBody = new BulletBody(localID); | 86 | PhysBody = new BulletBody(localID); |
83 | PhysShape = new BulletShape(); | 87 | PhysShape = new BulletShape(); |
@@ -88,8 +92,8 @@ public abstract class BSPhysObject : PhysicsActor | |||
88 | 92 | ||
89 | LastAssetBuildFailed = false; | 93 | LastAssetBuildFailed = false; |
90 | 94 | ||
91 | // Default material type | 95 | // Default material type. Also sets Friction, Restitution and Density. |
92 | Material = MaterialAttributes.Material.Wood; | 96 | SetMaterial((int)MaterialAttributes.Material.Wood); |
93 | 97 | ||
94 | CollisionCollection = new CollisionEventUpdate(); | 98 | CollisionCollection = new CollisionEventUpdate(); |
95 | CollisionsLastTick = CollisionCollection; | 99 | CollisionsLastTick = CollisionCollection; |
@@ -122,6 +126,8 @@ public abstract class BSPhysObject : PhysicsActor | |||
122 | // 'inWorld' true if the object has already been added to the dynamic world. | 126 | // 'inWorld' true if the object has already been added to the dynamic world. |
123 | public abstract void UpdatePhysicalMassProperties(float mass, bool inWorld); | 127 | public abstract void UpdatePhysicalMassProperties(float mass, bool inWorld); |
124 | 128 | ||
129 | // The gravity being applied to the object. A function of default grav, GravityModifier and Buoyancy. | ||
130 | public virtual OMV.Vector3 Gravity { get; set; } | ||
125 | // The last value calculated for the prim's inertia | 131 | // The last value calculated for the prim's inertia |
126 | public OMV.Vector3 Inertia { get; set; } | 132 | public OMV.Vector3 Inertia { get; set; } |
127 | 133 | ||
@@ -164,15 +170,18 @@ public abstract class BSPhysObject : PhysicsActor | |||
164 | public override void SetMaterial(int material) | 170 | public override void SetMaterial(int material) |
165 | { | 171 | { |
166 | Material = (MaterialAttributes.Material)material; | 172 | Material = (MaterialAttributes.Material)material; |
173 | |||
174 | // Setting the material sets the material attributes also. | ||
175 | MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false); | ||
176 | Friction = matAttrib.friction; | ||
177 | Restitution = matAttrib.restitution; | ||
178 | Density = matAttrib.density; | ||
167 | } | 179 | } |
168 | 180 | ||
169 | // Stop all physical motion. | 181 | // Stop all physical motion. |
170 | public abstract void ZeroMotion(bool inTaintTime); | 182 | public abstract void ZeroMotion(bool inTaintTime); |
171 | public abstract void ZeroAngularMotion(bool inTaintTime); | 183 | public abstract void ZeroAngularMotion(bool inTaintTime); |
172 | 184 | ||
173 | // Step the vehicle simulation for this object. A NOOP if the vehicle was not configured. | ||
174 | public virtual void StepVehicle(float timeStep) { } | ||
175 | |||
176 | // Update the physical location and motion of the object. Called with data from Bullet. | 185 | // Update the physical location and motion of the object. Called with data from Bullet. |
177 | public abstract void UpdateProperties(EntityProperties entprop); | 186 | public abstract void UpdateProperties(EntityProperties entprop); |
178 | 187 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 54bf063..85c2627 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -55,7 +55,6 @@ public sealed class BSPrim : BSPhysObject | |||
55 | private OMV.Vector3 _position; | 55 | private OMV.Vector3 _position; |
56 | 56 | ||
57 | private float _mass; // the mass of this object | 57 | private float _mass; // the mass of this object |
58 | private float _density; | ||
59 | private OMV.Vector3 _force; | 58 | private OMV.Vector3 _force; |
60 | private OMV.Vector3 _velocity; | 59 | private OMV.Vector3 _velocity; |
61 | private OMV.Vector3 _torque; | 60 | private OMV.Vector3 _torque; |
@@ -64,8 +63,6 @@ public sealed class BSPrim : BSPhysObject | |||
64 | private int _physicsActorType; | 63 | private int _physicsActorType; |
65 | private bool _isPhysical; | 64 | private bool _isPhysical; |
66 | private bool _flying; | 65 | private bool _flying; |
67 | private float _friction; | ||
68 | private float _restitution; | ||
69 | private bool _setAlwaysRun; | 66 | private bool _setAlwaysRun; |
70 | private bool _throttleUpdates; | 67 | private bool _throttleUpdates; |
71 | private bool _floatOnWater; | 68 | private bool _floatOnWater; |
@@ -101,12 +98,6 @@ public sealed class BSPrim : BSPhysObject | |||
101 | _isPhysical = pisPhysical; | 98 | _isPhysical = pisPhysical; |
102 | _isVolumeDetect = false; | 99 | _isVolumeDetect = false; |
103 | 100 | ||
104 | // Someday set default attributes based on the material but, for now, we don't know the prim material yet. | ||
105 | // MaterialAttributes primMat = BSMaterials.GetAttributes(Material, pisPhysical); | ||
106 | _density = PhysicsScene.Params.defaultDensity; | ||
107 | _friction = PhysicsScene.Params.defaultFriction; | ||
108 | _restitution = PhysicsScene.Params.defaultRestitution; | ||
109 | |||
110 | VehicleController = new BSDynamics(PhysicsScene, this); // add vehicleness | 101 | VehicleController = new BSDynamics(PhysicsScene, this); // add vehicleness |
111 | 102 | ||
112 | _mass = CalculateMass(); | 103 | _mass = CalculateMass(); |
@@ -432,8 +423,6 @@ public sealed class BSPrim : BSPhysObject | |||
432 | } | 423 | } |
433 | else | 424 | else |
434 | { | 425 | { |
435 | OMV.Vector3 grav = ComputeGravity(Buoyancy); | ||
436 | |||
437 | if (inWorld) | 426 | if (inWorld) |
438 | { | 427 | { |
439 | // Changing interesting properties doesn't change proxy and collision cache | 428 | // Changing interesting properties doesn't change proxy and collision cache |
@@ -443,25 +432,20 @@ public sealed class BSPrim : BSPhysObject | |||
443 | } | 432 | } |
444 | 433 | ||
445 | // The computation of mass props requires gravity to be set on the object. | 434 | // The computation of mass props requires gravity to be set on the object. |
446 | PhysicsScene.PE.SetGravity(PhysBody, grav); | 435 | Gravity = ComputeGravity(Buoyancy); |
436 | PhysicsScene.PE.SetGravity(PhysBody, Gravity); | ||
447 | 437 | ||
448 | Inertia = PhysicsScene.PE.CalculateLocalInertia(PhysShape, physMass); | 438 | Inertia = PhysicsScene.PE.CalculateLocalInertia(PhysShape, physMass); |
449 | PhysicsScene.PE.SetMassProps(PhysBody, physMass, Inertia); | 439 | PhysicsScene.PE.SetMassProps(PhysBody, physMass, Inertia); |
450 | PhysicsScene.PE.UpdateInertiaTensor(PhysBody); | 440 | PhysicsScene.PE.UpdateInertiaTensor(PhysBody); |
451 | 441 | ||
452 | // center of mass is at the zero of the object | 442 | DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2},grav={3},inWorld={4}", |
453 | // DEBUG DEBUG PhysicsScene.PE.SetCenterOfMassByPosRot(PhysBody, ForcePosition, ForceOrientation); | 443 | LocalID, physMass, Inertia, Gravity, inWorld); |
454 | DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2},grav={3},inWorld={4}", LocalID, physMass, Inertia, grav, inWorld); | ||
455 | 444 | ||
456 | if (inWorld) | 445 | if (inWorld) |
457 | { | 446 | { |
458 | AddObjectToPhysicalWorld(); | 447 | AddObjectToPhysicalWorld(); |
459 | } | 448 | } |
460 | |||
461 | // Must set gravity after it has been added to the world because, for unknown reasons, | ||
462 | // adding the object resets the object's gravity to world gravity | ||
463 | PhysicsScene.PE.SetGravity(PhysBody, grav); | ||
464 | |||
465 | } | 449 | } |
466 | } | 450 | } |
467 | } | 451 | } |
@@ -472,7 +456,10 @@ public sealed class BSPrim : BSPhysObject | |||
472 | OMV.Vector3 ret = PhysicsScene.DefaultGravity; | 456 | OMV.Vector3 ret = PhysicsScene.DefaultGravity; |
473 | 457 | ||
474 | if (!IsStatic) | 458 | if (!IsStatic) |
459 | { | ||
475 | ret *= (1f - buoyancy); | 460 | ret *= (1f - buoyancy); |
461 | ret *= GravModifier; | ||
462 | } | ||
476 | 463 | ||
477 | return ret; | 464 | return ret; |
478 | } | 465 | } |
@@ -596,6 +583,74 @@ public sealed class BSPrim : BSPhysObject | |||
596 | } | 583 | } |
597 | return; | 584 | return; |
598 | } | 585 | } |
586 | public override void SetMaterial(int material) | ||
587 | { | ||
588 | base.SetMaterial(material); | ||
589 | PhysicsScene.TaintedObject("BSPrim.SetMaterial", delegate() | ||
590 | { | ||
591 | UpdatePhysicalParameters(); | ||
592 | }); | ||
593 | } | ||
594 | public override float Friction | ||
595 | { | ||
596 | get { return base.Friction; } | ||
597 | set | ||
598 | { | ||
599 | if (base.Friction != value) | ||
600 | { | ||
601 | base.Friction = value; | ||
602 | PhysicsScene.TaintedObject("BSPrim.setFriction", delegate() | ||
603 | { | ||
604 | UpdatePhysicalParameters(); | ||
605 | }); | ||
606 | } | ||
607 | } | ||
608 | } | ||
609 | public override float Restitution | ||
610 | { | ||
611 | get { return base.Restitution; } | ||
612 | set | ||
613 | { | ||
614 | if (base.Restitution != value) | ||
615 | { | ||
616 | base.Restitution = value; | ||
617 | PhysicsScene.TaintedObject("BSPrim.setRestitution", delegate() | ||
618 | { | ||
619 | UpdatePhysicalParameters(); | ||
620 | }); | ||
621 | } | ||
622 | } | ||
623 | } | ||
624 | public override float Density | ||
625 | { | ||
626 | get { return base.Density; } | ||
627 | set | ||
628 | { | ||
629 | if (base.Density != value) | ||
630 | { | ||
631 | base.Density = value; | ||
632 | PhysicsScene.TaintedObject("BSPrim.setDensity", delegate() | ||
633 | { | ||
634 | UpdatePhysicalParameters(); | ||
635 | }); | ||
636 | } | ||
637 | } | ||
638 | } | ||
639 | public override float GravModifier | ||
640 | { | ||
641 | get { return base.GravModifier; } | ||
642 | set | ||
643 | { | ||
644 | if (base.GravModifier != value) | ||
645 | { | ||
646 | base.GravModifier = value; | ||
647 | PhysicsScene.TaintedObject("BSPrim.setGravityModifier", delegate() | ||
648 | { | ||
649 | UpdatePhysicalParameters(); | ||
650 | }); | ||
651 | } | ||
652 | } | ||
653 | } | ||
599 | public override OMV.Vector3 RawVelocity | 654 | public override OMV.Vector3 RawVelocity |
600 | { | 655 | { |
601 | get { return _velocity; } | 656 | get { return _velocity; } |
@@ -761,7 +816,12 @@ public sealed class BSPrim : BSPhysObject | |||
761 | // collisionEvents: whether this object returns collision events | 816 | // collisionEvents: whether this object returns collision events |
762 | public void UpdatePhysicalParameters() | 817 | public void UpdatePhysicalParameters() |
763 | { | 818 | { |
764 | // DetailLog("{0},BSPrim.UpdatePhysicalParameters,entry,body={1},shape={2}", LocalID, BSBody, BSShape); | 819 | if (!PhysBody.HasPhysicalBody) |
820 | { | ||
821 | // This would only happen if updates are called for during initialization when the body is not set up yet. | ||
822 | DetailLog("{0},BSPrim.UpdatePhysicalParameters,taint,calledWithNoPhysBody", LocalID); | ||
823 | return; | ||
824 | } | ||
765 | 825 | ||
766 | // Mangling all the physical properties requires the object not be in the physical world. | 826 | // Mangling all the physical properties requires the object not be in the physical world. |
767 | // This is a NOOP if the object is not in the world (BulletSim and Bullet ignore objects not found). | 827 | // 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 | |||
810 | 870 | ||
811 | // Set various physical properties so other object interact properly | 871 | // Set various physical properties so other object interact properly |
812 | MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false); | 872 | MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false); |
813 | PhysicsScene.PE.SetFriction(PhysBody, matAttrib.friction); | 873 | PhysicsScene.PE.SetFriction(PhysBody, Friction); |
814 | PhysicsScene.PE.SetRestitution(PhysBody, matAttrib.restitution); | 874 | PhysicsScene.PE.SetRestitution(PhysBody, Restitution); |
815 | 875 | ||
816 | // Mass is zero which disables a bunch of physics stuff in Bullet | 876 | // Mass is zero which disables a bunch of physics stuff in Bullet |
817 | UpdatePhysicalMassProperties(0f, false); | 877 | UpdatePhysicalMassProperties(0f, false); |
@@ -839,9 +899,9 @@ public sealed class BSPrim : BSPhysObject | |||
839 | CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.CF_STATIC_OBJECT); | 899 | CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.CF_STATIC_OBJECT); |
840 | 900 | ||
841 | // Set various physical properties so other object interact properly | 901 | // Set various physical properties so other object interact properly |
842 | MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, true); | 902 | PhysicsScene.PE.SetFriction(PhysBody, Friction); |
843 | PhysicsScene.PE.SetFriction(PhysBody, matAttrib.friction); | 903 | PhysicsScene.PE.SetRestitution(PhysBody, Restitution); |
844 | PhysicsScene.PE.SetRestitution(PhysBody, matAttrib.restitution); | 904 | // DetailLog("{0},BSPrim.MakeDynamic,frict={1},rest={2}", LocalID, Friction, Restitution); |
845 | 905 | ||
846 | // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382 | 906 | // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382 |
847 | // Since this can be called multiple times, only zero forces when becoming physical | 907 | // Since this can be called multiple times, only zero forces when becoming physical |
@@ -944,7 +1004,7 @@ public sealed class BSPrim : BSPhysObject | |||
944 | else | 1004 | else |
945 | { | 1005 | { |
946 | m_log.ErrorFormat("{0} Attempt to add physical object without body. id={1}", LogHeader, LocalID); | 1006 | m_log.ErrorFormat("{0} Attempt to add physical object without body. id={1}", LogHeader, LocalID); |
947 | DetailLog("{0},BSPrim.UpdatePhysicalParameters,addObjectWithoutBody,cType={1}", LocalID, PhysBody.collisionType); | 1007 | DetailLog("{0},BSPrim.AddObjectToPhysicalWorld,addObjectWithoutBody,cType={1}", LocalID, PhysBody.collisionType); |
948 | } | 1008 | } |
949 | } | 1009 | } |
950 | 1010 | ||
@@ -1581,7 +1641,7 @@ public sealed class BSPrim : BSPhysObject | |||
1581 | profileEnd = 1.0f - (float)BaseShape.ProfileEnd * 2.0e-5f; | 1641 | profileEnd = 1.0f - (float)BaseShape.ProfileEnd * 2.0e-5f; |
1582 | volume *= (profileEnd - profileBegin); | 1642 | volume *= (profileEnd - profileBegin); |
1583 | 1643 | ||
1584 | returnMass = _density * volume; | 1644 | returnMass = Density * volume; |
1585 | 1645 | ||
1586 | /* Comment out code that computes the mass of the linkset. That is done in the Linkset class. | 1646 | /* Comment out code that computes the mass of the linkset. That is done in the Linkset class. |
1587 | if (IsRootOfLinkset) | 1647 | if (IsRootOfLinkset) |
diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index e2789d6..7cd364b 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs | |||
@@ -274,7 +274,7 @@ namespace OpenSim.Region.Physics.Manager | |||
274 | public virtual float Density { get; set; } | 274 | public virtual float Density { get; set; } |
275 | public virtual float GravModifier { get; set; } | 275 | public virtual float GravModifier { get; set; } |
276 | public virtual float Friction { get; set; } | 276 | public virtual float Friction { get; set; } |
277 | public virtual float Bounce { get; set; } | 277 | public virtual float Restitution { get; set; } |
278 | 278 | ||
279 | /// <summary> | 279 | /// <summary> |
280 | /// Position of this actor. | 280 | /// Position of this actor. |