From f473252fa8022f95f60e219b24ffa342966f8c13 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 23 Nov 2012 03:56:53 +0000 Subject: Add AllowRegionRestartFromClient setting to [EstateManagement] section of OpenSim.ini. Setting this to false will block all restart requests from the viewer even if they are otherwise legitimate. One use is to block region restarts if necessary whilst restart functionality remains buggy or triggers bugs in modules, though these should be fixed as soon as practicable. Default is true, as has been the case historically. --- .../World/Estate/EstateManagementModule.cs | 103 +++++++++++++-------- 1 file changed, 63 insertions(+), 40 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index f974a63..eb06fcc 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -53,6 +53,11 @@ namespace OpenSim.Region.CoreModules.World.Estate protected EstateManagementCommands m_commands; + /// + /// If false, region restart requests from the client are blocked even if they are otherwise legitimate. + /// + public bool AllowRegionRestartFromClient { get; set; } + private EstateTerrainXferHandler TerrainUploader; public TelehubManager m_Telehub; @@ -60,6 +65,53 @@ namespace OpenSim.Region.CoreModules.World.Estate public event ChangeDelegate OnEstateInfoChange; public event MessageDelegate OnEstateMessage; + #region Region Module interface + + public string Name { get { return "EstateManagementModule"; } } + + public Type ReplaceableInterface { get { return null; } } + + public void Initialise(IConfigSource source) + { + AllowRegionRestartFromClient = true; + + IConfig config = source.Configs["EstateManagement"]; + + if (config != null) + AllowRegionRestartFromClient = config.GetBoolean("AllowRegionRestartFromClient", true); + } + + public void AddRegion(Scene scene) + { + Scene = scene; + Scene.RegisterModuleInterface(this); + Scene.EventManager.OnNewClient += EventManager_OnNewClient; + Scene.EventManager.OnRequestChangeWaterHeight += changeWaterHeight; + + m_Telehub = new TelehubManager(scene); + + m_commands = new EstateManagementCommands(this); + m_commands.Initialise(); + } + + public void RemoveRegion(Scene scene) {} + + public void RegionLoaded(Scene scene) + { + // Sets up the sun module based no the saved Estate and Region Settings + // DO NOT REMOVE or the sun will stop working + scene.TriggerEstateSunUpdate(); + + UserManager = scene.RequestModuleInterface(); + } + + public void Close() + { + m_commands.Close(); + } + + #endregion + #region Packet Data Responders private void sendDetailedEstateData(IClientAPI remote_client, UUID invoice) @@ -184,6 +236,7 @@ namespace OpenSim.Region.CoreModules.World.Estate Scene.RegionInfo.RegionSettings.TerrainTexture4 = texture; break; } + Scene.RegionInfo.RegionSettings.Save(); TriggerRegionInfoChange(); sendRegionInfoPacketToAll(); @@ -215,6 +268,7 @@ namespace OpenSim.Region.CoreModules.World.Estate Scene.RegionInfo.RegionSettings.Elevation2NE = highValue; break; } + Scene.RegionInfo.RegionSettings.Save(); TriggerRegionInfoChange(); sendRegionHandshakeToAll(); @@ -255,6 +309,12 @@ namespace OpenSim.Region.CoreModules.World.Estate private void handleEstateRestartSimRequest(IClientAPI remoteClient, int timeInSeconds) { + if (!AllowRegionRestartFromClient) + { + remoteClient.SendAlertMessage("Region restart has been disabled on this simulator."); + return; + } + IRestartModule restartModule = Scene.RequestModuleInterface(); if (restartModule != null) { @@ -329,6 +389,7 @@ namespace OpenSim.Region.CoreModules.World.Estate } } + if ((estateAccessType & 8) != 0) // User remove { if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true)) @@ -360,6 +421,7 @@ namespace OpenSim.Region.CoreModules.World.Estate remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); } } + if ((estateAccessType & 16) != 0) // Group add { if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true)) @@ -623,7 +685,7 @@ namespace OpenSim.Region.CoreModules.World.Estate } } - public void handleOnEstateManageTelehub (IClientAPI client, UUID invoice, UUID senderID, string cmd, uint param1) + public void handleOnEstateManageTelehub(IClientAPI client, UUID invoice, UUID senderID, string cmd, uint param1) { SceneObjectPart part; @@ -1081,45 +1143,6 @@ namespace OpenSim.Region.CoreModules.World.Estate #endregion - #region Region Module interface - - public string Name { get { return "EstateManagementModule"; } } - - public Type ReplaceableInterface { get { return null; } } - - public void Initialise(IConfigSource source) {} - - public void AddRegion(Scene scene) - { - Scene = scene; - Scene.RegisterModuleInterface(this); - Scene.EventManager.OnNewClient += EventManager_OnNewClient; - Scene.EventManager.OnRequestChangeWaterHeight += changeWaterHeight; - - m_Telehub = new TelehubManager(scene); - - m_commands = new EstateManagementCommands(this); - m_commands.Initialise(); - } - - public void RemoveRegion(Scene scene) {} - - public void RegionLoaded(Scene scene) - { - // Sets up the sun module based no the saved Estate and Region Settings - // DO NOT REMOVE or the sun will stop working - scene.TriggerEstateSunUpdate(); - - UserManager = scene.RequestModuleInterface(); - } - - public void Close() - { - m_commands.Close(); - } - - #endregion - #region Other Functions public void changeWaterHeight(float height) -- cgit v1.1 From 1f336579c87b6b9e3152175c8b6724bff2777b65 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 23 Nov 2012 04:06:48 +0000 Subject: minor: Make note in log if scene was restarted due to an unrecoverable physics error --- OpenSim/Region/Framework/Scenes/Scene.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 8ef22bd..1ad5edd 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -740,7 +740,12 @@ namespace OpenSim.Region.Framework.Scenes // // Out of memory // Operating system has killed the plugin - m_sceneGraph.UnRecoverableError += RestartNow; + m_sceneGraph.UnRecoverableError + += () => + { + m_log.ErrorFormat("[SCENE]: Restarting region {0} due to unrecoverable physics crash", Name); + RestartNow(); + }; RegisterDefaultSceneEvents(); -- cgit v1.1 From acc1810af2d4527d9cb0e3e7aaaf43c2f54ffb43 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 23 Nov 2012 04:08:17 +0000 Subject: minor: remove some mono compiler warnings --- OpenSim/Region/CoreModules/World/Sound/SoundModule.cs | 4 ++-- OpenSim/Region/CoreModules/World/Wind/WindModule.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs index 513a8f5..089fcda 100644 --- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs +++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs @@ -43,8 +43,8 @@ namespace OpenSim.Region.CoreModules.World.Sound [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SoundModule")] public class SoundModule : INonSharedRegionModule, ISoundModule { - private static readonly ILog m_log = LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger( +// MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene; diff --git a/OpenSim/Region/CoreModules/World/Wind/WindModule.cs b/OpenSim/Region/CoreModules/World/Wind/WindModule.cs index fd8e2b4..9de588c 100644 --- a/OpenSim/Region/CoreModules/World/Wind/WindModule.cs +++ b/OpenSim/Region/CoreModules/World/Wind/WindModule.cs @@ -66,7 +66,7 @@ namespace OpenSim.Region.CoreModules public void Initialise(IConfigSource config) { m_windConfig = config.Configs["Wind"]; - string desiredWindPlugin = m_dWindPluginName; +// string desiredWindPlugin = m_dWindPluginName; if (m_windConfig != null) { -- cgit v1.1 From cda531bc3ce5e4a73eca33d6284197bbd59c9252 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 23 Nov 2012 05:43:51 +0000 Subject: minor: Add some currently commented out debug log lines for investigating issues resolving group IDs for land parcels on OAR loading where groups do not exist --- OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index ea806ec..60bbf9b 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs @@ -557,9 +557,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver if (!ResolveGroupUuid(parcel.GroupID)) { +// m_log.DebugFormat("[ARCHIVE READ REQUEST]: Could not find group {0}", parcel.GroupID); parcel.GroupID = UUID.Zero; parcel.IsGroupOwned = false; } +// else +// { +// m_log.DebugFormat("[ARCHIVE READ REQUEST]: Found group {0}", parcel.GroupID); +// } List accessList = new List(); foreach (LandAccessEntry entry in parcel.ParcelAccessList) -- cgit v1.1 From 82690e138448ebac6456ab03dcca4b0a8a1cc57a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 24 Nov 2012 02:43:31 +0000 Subject: Fix bug where loading an OAR with a deeded parcel would always set the parcel owner ID to the estate owner even if the group UUID was present. Aims to address http://opensimulator.org/mantis/view.php?id=6355 As part of this work, an incomplete IXGroupsData was added which currently only allows store/fetch/delete of group records (i.e. no membership data etc) This is subject to change and currently only an in-memory storage implementation exists for regression test purposes. --- .../World/Archiver/ArchiveReadRequest.cs | 30 +- .../World/Archiver/ArchiveWriteRequest.cs | 11 +- .../World/Archiver/Tests/ArchiverTests.cs | 312 +++++++++++++-------- .../CoreModules/World/Land/LandManagementModule.cs | 5 +- .../Region/CoreModules/World/Land/LandObject.cs | 13 +- .../XmlRpcGroups/IGroupsServicesConnector.cs | 15 + .../XmlRpcGroupsServicesConnectorModule.cs | 127 ++++----- 7 files changed, 300 insertions(+), 213 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index 60bbf9b..c810242 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs @@ -552,19 +552,23 @@ namespace OpenSim.Region.CoreModules.World.Archiver // Validate User and Group UUID's - if (!ResolveUserUuid(scene, parcel.OwnerID)) - parcel.OwnerID = m_rootScene.RegionInfo.EstateSettings.EstateOwner; - - if (!ResolveGroupUuid(parcel.GroupID)) + if (parcel.IsGroupOwned) { -// m_log.DebugFormat("[ARCHIVE READ REQUEST]: Could not find group {0}", parcel.GroupID); - parcel.GroupID = UUID.Zero; - parcel.IsGroupOwned = false; + if (!ResolveGroupUuid(parcel.GroupID)) + { + parcel.OwnerID = m_rootScene.RegionInfo.EstateSettings.EstateOwner; + parcel.GroupID = UUID.Zero; + parcel.IsGroupOwned = false; + } + } + else + { + if (!ResolveUserUuid(scene, parcel.OwnerID)) + parcel.OwnerID = m_rootScene.RegionInfo.EstateSettings.EstateOwner; + + if (!ResolveGroupUuid(parcel.GroupID)) + parcel.GroupID = UUID.Zero; } -// else -// { -// m_log.DebugFormat("[ARCHIVE READ REQUEST]: Found group {0}", parcel.GroupID); -// } List accessList = new List(); foreach (LandAccessEntry entry in parcel.ParcelAccessList) @@ -576,8 +580,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver parcel.ParcelAccessList = accessList; // m_log.DebugFormat( -// "[ARCHIVER]: Adding parcel {0}, local id {1}, area {2}", -// parcel.Name, parcel.LocalID, parcel.Area); +// "[ARCHIVER]: Adding parcel {0}, local id {1}, owner {2}, group {3}, isGroupOwned {4}, area {5}", +// parcel.Name, parcel.LocalID, parcel.OwnerID, parcel.GroupID, parcel.IsGroupOwned, parcel.Area); landData.Add(parcel); } diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs index d751b1c..7bdd65c 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs @@ -167,7 +167,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver } scenesGroup.CalcSceneLocations(); - m_archiveWriter = new TarArchiveWriter(m_saveStream); try @@ -216,7 +215,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver } } - private void ArchiveOneRegion(Scene scene, string regionDir, Dictionary assetUuids) { m_log.InfoFormat("[ARCHIVER]: Writing region {0}", scene.RegionInfo.RegionName); @@ -540,7 +538,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver xtw.WriteElementString("size_in_meters", string.Format("{0},{1}", size.X, size.Y)); } - protected void Save(Scene scene, List sceneObjects, string regionDir) { if (regionDir != string.Empty) @@ -560,8 +557,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver foreach (ILandObject lo in landObjects) { LandData landData = lo.LandData; - string landDataPath = String.Format("{0}{1}{2}.xml", - regionDir, ArchiveConstants.LANDDATA_PATH, landData.GlobalID.ToString()); + string landDataPath + = String.Format("{0}{1}", regionDir, ArchiveConstants.CreateOarLandDataPath(landData)); m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData, m_options)); } @@ -604,7 +601,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver CloseArchive(String.Empty); } - /// /// Closes the archive and notifies that we're done. @@ -629,6 +625,5 @@ namespace OpenSim.Region.CoreModules.World.Archiver m_rootScene.EventManager.TriggerOarFileSaved(m_requestId, errorMessage); } - } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs index 82f49b0..7cc3519 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs @@ -31,16 +31,19 @@ using System.IO; using System.Reflection; using System.Threading; using log4net.Config; +using Nini.Config; using NUnit.Framework; using OpenMetaverse; using OpenMetaverse.Assets; using OpenSim.Framework; using OpenSim.Framework.Serialization; using OpenSim.Framework.Serialization.External; +using OpenSim.Region.CoreModules.World.Land; using OpenSim.Region.CoreModules.World.Serialiser; using OpenSim.Region.CoreModules.World.Terrain; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes.Serialization; +using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups; using OpenSim.Tests.Common; using OpenSim.Tests.Common.Mock; using ArchiveConstants = OpenSim.Framework.Serialization.ArchiveConstants; @@ -127,6 +130,53 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests return new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, offsetPosition) { Name = partName }; } + + private void CreateTestObjects(Scene scene, out SceneObjectGroup sog1, out SceneObjectGroup sog2, out UUID ncAssetUuid) + { + SceneObjectPart part1 = CreateSceneObjectPart1(); + sog1 = new SceneObjectGroup(part1); + scene.AddNewSceneObject(sog1, false); + + AssetNotecard nc = new AssetNotecard(); + nc.BodyText = "Hello World!"; + nc.Encode(); + ncAssetUuid = UUID.Random(); + UUID ncItemUuid = UUID.Random(); + AssetBase ncAsset + = AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero); + m_scene.AssetService.Store(ncAsset); + + TaskInventoryItem ncItem + = new TaskInventoryItem { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid }; + SceneObjectPart part2 = CreateSceneObjectPart2(); + sog2 = new SceneObjectGroup(part2); + part2.Inventory.AddInventoryItem(ncItem, true); + + scene.AddNewSceneObject(sog2, false); + } + + private static void CreateSoundAsset(TarArchiveWriter tar, Assembly assembly, string soundDataResourceName, out byte[] soundData, out UUID soundUuid) + { + using (Stream resource = assembly.GetManifestResourceStream(soundDataResourceName)) + { + using (BinaryReader br = new BinaryReader(resource)) + { + // FIXME: Use the inspector instead + soundData = br.ReadBytes(99999999); + soundUuid = UUID.Parse("00000000-0000-0000-0000-000000000001"); + string soundAssetFileName + = ArchiveConstants.ASSETS_PATH + soundUuid + + ArchiveConstants.ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.SoundWAV]; + tar.WriteFile(soundAssetFileName, soundData); + + /* + AssetBase soundAsset = AssetHelpers.CreateAsset(soundUuid, soundData); + scene.AssetService.Store(soundAsset); + asset1FileName = ArchiveConstants.ASSETS_PATH + soundUuid + ".wav"; + */ + } + } + } /// /// Test saving an OpenSim Region Archive. @@ -204,30 +254,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests // TODO: Test presence of more files and contents of files. } - private void CreateTestObjects(Scene scene, out SceneObjectGroup sog1, out SceneObjectGroup sog2, out UUID ncAssetUuid) - { - SceneObjectPart part1 = CreateSceneObjectPart1(); - sog1 = new SceneObjectGroup(part1); - scene.AddNewSceneObject(sog1, false); - - AssetNotecard nc = new AssetNotecard(); - nc.BodyText = "Hello World!"; - nc.Encode(); - ncAssetUuid = UUID.Random(); - UUID ncItemUuid = UUID.Random(); - AssetBase ncAsset - = AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero); - m_scene.AssetService.Store(ncAsset); - - TaskInventoryItem ncItem - = new TaskInventoryItem { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid }; - SceneObjectPart part2 = CreateSceneObjectPart2(); - sog2 = new SceneObjectGroup(part2); - part2.Inventory.AddInventoryItem(ncItem, true); - - scene.AddNewSceneObject(sog2, false); - } - /// /// Test saving an OpenSim Region Archive with the no assets option /// @@ -309,59 +335,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests } /// - /// Test loading an OpenSim Region Archive where the scene object parts are not ordered by link number (e.g. - /// 2 can come after 3). - /// - [Test] - public void TestLoadOarUnorderedParts() - { - TestHelpers.InMethod(); - - UUID ownerId = TestHelpers.ParseTail(0xaaaa); - - MemoryStream archiveWriteStream = new MemoryStream(); - TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream); - - tar.WriteFile( - ArchiveConstants.CONTROL_FILE_PATH, - new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup())); - - SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ownerId, "obj1-", 0x11); - SceneObjectPart sop2 - = SceneHelpers.CreateSceneObjectPart("obj1-Part2", TestHelpers.ParseTail(0x12), ownerId); - SceneObjectPart sop3 - = SceneHelpers.CreateSceneObjectPart("obj1-Part3", TestHelpers.ParseTail(0x13), ownerId); - - // Add the parts so they will be written out in reverse order to the oar - sog1.AddPart(sop3); - sop3.LinkNum = 3; - sog1.AddPart(sop2); - sop2.LinkNum = 2; - - tar.WriteFile( - ArchiveConstants.CreateOarObjectPath(sog1.Name, sog1.UUID, sog1.AbsolutePosition), - SceneObjectSerializer.ToXml2Format(sog1)); - - tar.Close(); - - MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); - - lock (this) - { - m_scene.EventManager.OnOarFileLoaded += LoadCompleted; - m_archiverModule.DearchiveRegion(archiveReadStream); - } - - Assert.That(m_lastErrorMessage, Is.Null); - - SceneObjectPart part2 = m_scene.GetSceneObjectPart("obj1-Part2"); - Assert.That(part2.LinkNum, Is.EqualTo(2)); - - SceneObjectPart part3 = m_scene.GetSceneObjectPart("obj1-Part3"); - Assert.That(part3.LinkNum, Is.EqualTo(3)); - } - - /// /// Test loading an OpenSim Region Archive. /// [Test] @@ -435,50 +408,57 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests TestLoadedRegion(part1, soundItemName, soundData); } - private static void CreateSoundAsset(TarArchiveWriter tar, Assembly assembly, string soundDataResourceName, out byte[] soundData, out UUID soundUuid) + /// + /// Test loading an OpenSim Region Archive where the scene object parts are not ordered by link number (e.g. + /// 2 can come after 3). + /// + [Test] + public void TestLoadOarUnorderedParts() { - using (Stream resource = assembly.GetManifestResourceStream(soundDataResourceName)) - { - using (BinaryReader br = new BinaryReader(resource)) - { - // FIXME: Use the inspector instead - soundData = br.ReadBytes(99999999); - soundUuid = UUID.Parse("00000000-0000-0000-0000-000000000001"); - string soundAssetFileName - = ArchiveConstants.ASSETS_PATH + soundUuid - + ArchiveConstants.ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.SoundWAV]; - tar.WriteFile(soundAssetFileName, soundData); + TestHelpers.InMethod(); - /* - AssetBase soundAsset = AssetHelpers.CreateAsset(soundUuid, soundData); - scene.AssetService.Store(soundAsset); - asset1FileName = ArchiveConstants.ASSETS_PATH + soundUuid + ".wav"; - */ - } - } - } + UUID ownerId = TestHelpers.ParseTail(0xaaaa); - private void TestLoadedRegion(SceneObjectPart part1, string soundItemName, byte[] soundData) - { - SceneObjectPart object1PartLoaded = m_scene.GetSceneObjectPart(part1.Name); + MemoryStream archiveWriteStream = new MemoryStream(); + TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream); - Assert.That(object1PartLoaded, Is.Not.Null, "object1 was not loaded"); - Assert.That(object1PartLoaded.Name, Is.EqualTo(part1.Name), "object1 names not identical"); - Assert.That(object1PartLoaded.GroupPosition, Is.EqualTo(part1.GroupPosition), "object1 group position not equal"); - Assert.That( - object1PartLoaded.RotationOffset, Is.EqualTo(part1.RotationOffset), "object1 rotation offset not equal"); - Assert.That( - object1PartLoaded.OffsetPosition, Is.EqualTo(part1.OffsetPosition), "object1 offset position not equal"); - Assert.That(object1PartLoaded.SitTargetOrientation, Is.EqualTo(part1.SitTargetOrientation)); - Assert.That(object1PartLoaded.SitTargetPosition, Is.EqualTo(part1.SitTargetPosition)); + tar.WriteFile( + ArchiveConstants.CONTROL_FILE_PATH, + new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup())); - TaskInventoryItem loadedSoundItem = object1PartLoaded.Inventory.GetInventoryItems(soundItemName)[0]; - Assert.That(loadedSoundItem, Is.Not.Null, "loaded sound item was null"); - AssetBase loadedSoundAsset = m_scene.AssetService.Get(loadedSoundItem.AssetID.ToString()); - Assert.That(loadedSoundAsset, Is.Not.Null, "loaded sound asset was null"); - Assert.That(loadedSoundAsset.Data, Is.EqualTo(soundData), "saved and loaded sound data do not match"); + SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ownerId, "obj1-", 0x11); + SceneObjectPart sop2 + = SceneHelpers.CreateSceneObjectPart("obj1-Part2", TestHelpers.ParseTail(0x12), ownerId); + SceneObjectPart sop3 + = SceneHelpers.CreateSceneObjectPart("obj1-Part3", TestHelpers.ParseTail(0x13), ownerId); - Assert.Greater(m_scene.LandChannel.AllParcels().Count, 0, "incorrect number of parcels"); + // Add the parts so they will be written out in reverse order to the oar + sog1.AddPart(sop3); + sop3.LinkNum = 3; + sog1.AddPart(sop2); + sop2.LinkNum = 2; + + tar.WriteFile( + ArchiveConstants.CreateOarObjectPath(sog1.Name, sog1.UUID, sog1.AbsolutePosition), + SceneObjectSerializer.ToXml2Format(sog1)); + + tar.Close(); + + MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); + + lock (this) + { + m_scene.EventManager.OnOarFileLoaded += LoadCompleted; + m_archiverModule.DearchiveRegion(archiveReadStream); + } + + Assert.That(m_lastErrorMessage, Is.Null); + + SceneObjectPart part2 = m_scene.GetSceneObjectPart("obj1-Part2"); + Assert.That(part2.LinkNum, Is.EqualTo(2)); + + SceneObjectPart part3 = m_scene.GetSceneObjectPart("obj1-Part3"); + Assert.That(part3.LinkNum, Is.EqualTo(3)); } /// @@ -563,6 +543,81 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests } /// + /// Test OAR loading where the land parcel is group deeded. + /// + /// + /// In this situation, the owner ID is set to the group ID. + /// + [Test] + public void TestLoadOarDeededLand() + { + TestHelpers.InMethod(); + TestHelpers.EnableLogging(); + + UUID landID = TestHelpers.ParseTail(0x10); + + MockGroupsServicesConnector groupsService = new MockGroupsServicesConnector(); + + IConfigSource configSource = new IniConfigSource(); + IConfig config = configSource.AddConfig("Groups"); + config.Set("Enabled", true); + config.Set("Module", "GroupsModule"); + config.Set("DebugEnabled", true); + SceneHelpers.SetupSceneModules( + m_scene, configSource, new object[] { new GroupsModule(), groupsService, new LandManagementModule() }); + + // Create group in scene for loading + // FIXME: For now we'll put up with the issue that we'll get a group ID that varies across tests. + UUID groupID + = groupsService.CreateGroup(UUID.Zero, "group1", "", true, UUID.Zero, 3, true, true, true, UUID.Zero); + + // Construct OAR + MemoryStream oarStream = new MemoryStream(); + TarArchiveWriter tar = new TarArchiveWriter(oarStream); + + tar.WriteDir(ArchiveConstants.LANDDATA_PATH); + tar.WriteFile( + ArchiveConstants.CONTROL_FILE_PATH, + new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup())); + + LandObject lo = new LandObject(groupID, true, null); + + // FIXME: We set directly rather than call SetLandBitmap in order not to do an AABB value update, which + // requests the terrain heightmap from an active scene. This is confusing and not a long-term solution. + //lo.LandBitmap = lo.BasicFullRegionLandBitmap(); + lo.SetLandBitmap(lo.BasicFullRegionLandBitmap()); + + // FIXME: We have to make a separate call to update the LandData's copy of the land bitmap, even though this is + // identical to the LandObject copy. This should be changed so there's only one copy of the data if at all + // possible + //lo.UpdateLandBitmapByteArray(); + + LandData ld = lo.LandData; + ld.GlobalID = landID; + + string ldPath = ArchiveConstants.CreateOarLandDataPath(ld); + tar.WriteFile(ldPath, LandDataSerializer.Serialize(ld, null)); + tar.Close(); + + oarStream = new MemoryStream(oarStream.ToArray()); + + // Load OAR + lock (this) + { + m_scene.EventManager.OnOarFileLoaded += LoadCompleted; + m_archiverModule.DearchiveRegion(oarStream); + } + + ILandObject rLo = m_scene.LandChannel.GetLandObject(16, 16); + LandData rLd = rLo.LandData; + + Assert.That(rLd.GlobalID, Is.EqualTo(landID)); + Assert.That(rLd.OwnerID, Is.EqualTo(groupID)); + Assert.That(rLd.GroupID, Is.EqualTo(groupID)); + Assert.That(rLd.IsGroupOwned, Is.EqualTo(true)); + } + + /// /// Test loading the region settings of an OpenSim Region Archive. /// [Test] @@ -781,9 +836,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests } } - // Save OAR - MemoryStream archiveWriteStream = new MemoryStream(); m_scene.EventManager.OnOarFileSaved += SaveCompleted; @@ -800,7 +853,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests // Check that the OAR contains the expected data - Assert.That(m_lastRequestId, Is.EqualTo(requestId)); byte[] archive = archiveWriteStream.ToArray(); @@ -976,5 +1028,27 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests TestLoadedRegion(part1, soundItemName, soundData); } + private void TestLoadedRegion(SceneObjectPart part1, string soundItemName, byte[] soundData) + { + SceneObjectPart object1PartLoaded = m_scene.GetSceneObjectPart(part1.Name); + + Assert.That(object1PartLoaded, Is.Not.Null, "object1 was not loaded"); + Assert.That(object1PartLoaded.Name, Is.EqualTo(part1.Name), "object1 names not identical"); + Assert.That(object1PartLoaded.GroupPosition, Is.EqualTo(part1.GroupPosition), "object1 group position not equal"); + Assert.That( + object1PartLoaded.RotationOffset, Is.EqualTo(part1.RotationOffset), "object1 rotation offset not equal"); + Assert.That( + object1PartLoaded.OffsetPosition, Is.EqualTo(part1.OffsetPosition), "object1 offset position not equal"); + Assert.That(object1PartLoaded.SitTargetOrientation, Is.EqualTo(part1.SitTargetOrientation)); + Assert.That(object1PartLoaded.SitTargetPosition, Is.EqualTo(part1.SitTargetPosition)); + + TaskInventoryItem loadedSoundItem = object1PartLoaded.Inventory.GetInventoryItems(soundItemName)[0]; + Assert.That(loadedSoundItem, Is.Not.Null, "loaded sound item was null"); + AssetBase loadedSoundAsset = m_scene.AssetService.Get(loadedSoundItem.AssetID.ToString()); + Assert.That(loadedSoundAsset, Is.Not.Null, "loaded sound asset was null"); + Assert.That(loadedSoundAsset.Data, Is.EqualTo(soundData), "saved and loaded sound data do not match"); + + Assert.Greater(m_scene.LandChannel.AllParcels().Count, 0, "incorrect number of parcels"); + } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 8682798..7149aad 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -1378,10 +1378,11 @@ namespace OpenSim.Region.CoreModules.World.Land public void EventManagerOnIncomingLandDataFromStorage(List data) { +// m_log.DebugFormat( +// "[LAND MANAGMENT MODULE]: Processing {0} incoming parcels on {1}", data.Count, m_scene.Name); + for (int i = 0; i < data.Count; i++) - { IncomingLandObjectFromStorage(data[i]); - } } public void IncomingLandObjectFromStorage(LandData data) diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 8829f27..5969d45 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -727,9 +727,10 @@ namespace OpenSim.Region.CoreModules.World.Land int ty = min_y * 4; if (ty > ((int)Constants.RegionSize - 1)) ty = ((int)Constants.RegionSize - 1); + LandData.AABBMin = - new Vector3((float) (min_x * 4), (float) (min_y * 4), - (float) m_scene.Heightmap[tx, ty]); + new Vector3( + (float)(min_x * 4), (float)(min_y * 4), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0); tx = max_x * 4; if (tx > ((int)Constants.RegionSize - 1)) @@ -737,9 +738,11 @@ namespace OpenSim.Region.CoreModules.World.Land ty = max_y * 4; if (ty > ((int)Constants.RegionSize - 1)) ty = ((int)Constants.RegionSize - 1); - LandData.AABBMax = - new Vector3((float) (max_x * 4), (float) (max_y * 4), - (float) m_scene.Heightmap[tx, ty]); + + LandData.AABBMax + = new Vector3( + (float)(max_x * 4), (float)(max_y * 4), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0); + LandData.Area = tempArea; } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs index 6d26075..6b5b40a 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs @@ -36,7 +36,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID); void UpdateGroup(UUID RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish); + + /// + /// Get the group record. + /// + /// + /// The UUID of the user making the request. + /// + /// The ID of the record to retrieve. + /// GroupName may be specified instead, in which case this parameter will be UUID.Zero + /// + /// + /// The name of the group to retrieve. + /// GroupID may be specified instead, in which case this parmeter will be null. + /// GroupRecord GetGroupRecord(UUID RequestingAgentID, UUID GroupID, string GroupName); + List FindGroups(UUID RequestingAgentID, string search); List GetGroupMembers(UUID RequestingAgentID, UUID GroupID); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index d0c3ea5..1101851 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -54,13 +54,62 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private bool m_debugEnabled = false; - public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | - GroupPowers.Accountable | - GroupPowers.JoinChat | - GroupPowers.AllowVoiceChat | - GroupPowers.ReceiveNotices | - GroupPowers.StartProposal | - GroupPowers.VoteOnProposal; + public const GroupPowers DefaultEveryonePowers + = GroupPowers.AllowSetHome + | GroupPowers.Accountable + | GroupPowers.JoinChat + | GroupPowers.AllowVoiceChat + | GroupPowers.ReceiveNotices + | GroupPowers.StartProposal + | GroupPowers.VoteOnProposal; + + // Would this be cleaner as (GroupPowers)ulong.MaxValue? + public const GroupPowers DefaultOwnerPowers + = GroupPowers.Accountable + | GroupPowers.AllowEditLand + | GroupPowers.AllowFly + | GroupPowers.AllowLandmark + | GroupPowers.AllowRez + | GroupPowers.AllowSetHome + | GroupPowers.AllowVoiceChat + | GroupPowers.AssignMember + | GroupPowers.AssignMemberLimited + | GroupPowers.ChangeActions + | GroupPowers.ChangeIdentity + | GroupPowers.ChangeMedia + | GroupPowers.ChangeOptions + | GroupPowers.CreateRole + | GroupPowers.DeedObject + | GroupPowers.DeleteRole + | GroupPowers.Eject + | GroupPowers.FindPlaces + | GroupPowers.Invite + | GroupPowers.JoinChat + | GroupPowers.LandChangeIdentity + | GroupPowers.LandDeed + | GroupPowers.LandDivideJoin + | GroupPowers.LandEdit + | GroupPowers.LandEjectAndFreeze + | GroupPowers.LandGardening + | GroupPowers.LandManageAllowed + | GroupPowers.LandManageBanned + | GroupPowers.LandManagePasses + | GroupPowers.LandOptions + | GroupPowers.LandRelease + | GroupPowers.LandSetSale + | GroupPowers.ModerateChat + | GroupPowers.ObjectManipulate + | GroupPowers.ObjectSetForSale + | GroupPowers.ReceiveNotices + | GroupPowers.RemoveMember + | GroupPowers.ReturnGroupOwned + | GroupPowers.ReturnGroupSet + | GroupPowers.ReturnNonGroup + | GroupPowers.RoleProperties + | GroupPowers.SendNotices + | GroupPowers.SetLandingPoint + | GroupPowers.StartProposal + | GroupPowers.VoteOnProposal; private bool m_connectorEnabled = false; @@ -219,59 +268,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["AllowPublish"] = allowPublish == true ? 1 : 0; param["MaturePublish"] = maturePublish == true ? 1 : 0; param["FounderID"] = founderID.ToString(); - param["EveryonePowers"] = ((ulong)m_DefaultEveryonePowers).ToString(); + param["EveryonePowers"] = ((ulong)DefaultEveryonePowers).ToString(); param["OwnerRoleID"] = OwnerRoleID.ToString(); - - // Would this be cleaner as (GroupPowers)ulong.MaxValue; - GroupPowers OwnerPowers = GroupPowers.Accountable - | GroupPowers.AllowEditLand - | GroupPowers.AllowFly - | GroupPowers.AllowLandmark - | GroupPowers.AllowRez - | GroupPowers.AllowSetHome - | GroupPowers.AllowVoiceChat - | GroupPowers.AssignMember - | GroupPowers.AssignMemberLimited - | GroupPowers.ChangeActions - | GroupPowers.ChangeIdentity - | GroupPowers.ChangeMedia - | GroupPowers.ChangeOptions - | GroupPowers.CreateRole - | GroupPowers.DeedObject - | GroupPowers.DeleteRole - | GroupPowers.Eject - | GroupPowers.FindPlaces - | GroupPowers.Invite - | GroupPowers.JoinChat - | GroupPowers.LandChangeIdentity - | GroupPowers.LandDeed - | GroupPowers.LandDivideJoin - | GroupPowers.LandEdit - | GroupPowers.LandEjectAndFreeze - | GroupPowers.LandGardening - | GroupPowers.LandManageAllowed - | GroupPowers.LandManageBanned - | GroupPowers.LandManagePasses - | GroupPowers.LandOptions - | GroupPowers.LandRelease - | GroupPowers.LandSetSale - | GroupPowers.ModerateChat - | GroupPowers.ObjectManipulate - | GroupPowers.ObjectSetForSale - | GroupPowers.ReceiveNotices - | GroupPowers.RemoveMember - | GroupPowers.ReturnGroupOwned - | GroupPowers.ReturnGroupSet - | GroupPowers.ReturnNonGroup - | GroupPowers.RoleProperties - | GroupPowers.SendNotices - | GroupPowers.SetLandingPoint - | GroupPowers.StartProposal - | GroupPowers.VoteOnProposal; - param["OwnersPowers"] = ((ulong)OwnerPowers).ToString(); - - - + param["OwnersPowers"] = ((ulong)DefaultOwnerPowers).ToString(); Hashtable respData = XmlRpcCall(requestingAgentID, "groups.createGroup", param); @@ -612,8 +611,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } return Roles; - - } public List GetGroupRoles(UUID requestingAgentID, UUID GroupID) @@ -676,7 +673,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } return members; - } public List GetGroupRoleMembers(UUID requestingAgentID, UUID GroupID) @@ -727,9 +723,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups values.Add(data); } } - return values; + return values; } + public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID) { Hashtable param = new Hashtable(); @@ -737,7 +734,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupNotice", param); - if (respData.Contains("error")) { return null; @@ -761,6 +757,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return data; } + public void AddGroupNotice(UUID requestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) { string binBucket = OpenMetaverse.Utils.BytesToHexString(binaryBucket, ""); @@ -777,8 +774,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups XmlRpcCall(requestingAgentID, "groups.addGroupNotice", param); } - - #endregion #region GroupSessionTracking -- cgit v1.1 From e9be85442f31d0a8655df8c8f640b9a502ad8774 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 24 Nov 2012 02:57:43 +0000 Subject: In ArchiverTests, use the local instantiated SceneManager rather than potentially cross-contaminating tests by relying on the static SceneManager.Instance --- .../World/Archiver/Tests/ArchiverTests.cs | 27 ++++++---------------- 1 file changed, 7 insertions(+), 20 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs index 7cc3519..eec1cec 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs @@ -72,9 +72,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests { base.SetUp(); - // FIXME: Do something about this - relying on statics in unit tests causes trouble sooner or later - new SceneManager(); - m_archiverModule = new ArchiverModule(); m_serialiserModule = new SerialiserModule(); TerrainModule terrainModule = new TerrainModule(); @@ -518,8 +515,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests SerialiserModule serialiserModule = new SerialiserModule(); TerrainModule terrainModule = new TerrainModule(); - m_sceneHelpers = new SceneHelpers(); - TestScene scene2 = m_sceneHelpers.SetupScene(); + SceneHelpers m_sceneHelpers2 = new SceneHelpers(); + TestScene scene2 = m_sceneHelpers2.SetupScene(); SceneHelpers.SetupSceneModules(scene2, archiverModule, serialiserModule, terrainModule); // Make sure there's a valid owner for the owner we saved (this should have been wiped if the code is @@ -552,7 +549,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests public void TestLoadOarDeededLand() { TestHelpers.InMethod(); - TestHelpers.EnableLogging(); +// TestHelpers.EnableLogging(); UUID landID = TestHelpers.ParseTail(0x10); @@ -581,17 +578,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup())); LandObject lo = new LandObject(groupID, true, null); - - // FIXME: We set directly rather than call SetLandBitmap in order not to do an AABB value update, which - // requests the terrain heightmap from an active scene. This is confusing and not a long-term solution. - //lo.LandBitmap = lo.BasicFullRegionLandBitmap(); lo.SetLandBitmap(lo.BasicFullRegionLandBitmap()); - - // FIXME: We have to make a separate call to update the LandData's copy of the land bitmap, even though this is - // identical to the LandObject copy. This should be changed so there's only one copy of the data if at all - // possible - //lo.UpdateLandBitmapByteArray(); - LandData ld = lo.LandData; ld.GlobalID = landID; @@ -944,7 +931,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests } ArchiveScenesGroup scenesGroup = new ArchiveScenesGroup(); - SceneManager.Instance.ForEachScene(delegate(Scene scene) + m_sceneHelpers.SceneManager.ForEachScene(delegate(Scene scene) { scenesGroup.AddScene(scene); }); @@ -1002,13 +989,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests // Delete the current objects, to test that they're loaded from the OAR and didn't // just remain in the scene. - SceneManager.Instance.ForEachScene(delegate(Scene scene) + m_sceneHelpers.SceneManager.ForEachScene(delegate(Scene scene) { scene.DeleteAllSceneObjects(); }); // Create a "hole", to test that that the corresponding region isn't loaded from the OAR - SceneManager.Instance.CloseScene(SceneManager.Instance.Scenes[1]); + m_sceneHelpers.SceneManager.CloseScene(SceneManager.Instance.Scenes[1]); // Check thay the OAR file contains the expected data @@ -1023,7 +1010,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests Assert.That(m_lastErrorMessage, Is.Null); - Assert.AreEqual(3, SceneManager.Instance.Scenes.Count); + Assert.AreEqual(3, m_sceneHelpers.SceneManager.Scenes.Count); TestLoadedRegion(part1, soundItemName, soundData); } -- cgit v1.1 From 22d4c52ffc374e167cb674e0e20815615d8a6927 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 24 Nov 2012 03:15:24 +0000 Subject: Consistenly make NUnit test cases inherit from OpenSimTestCase which automatically turns off any logging enabled between tests --- .../Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs | 2 +- OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs | 2 +- OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs | 2 +- OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs | 2 +- .../CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs | 2 +- OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs | 2 +- .../Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs | 2 +- .../ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs | 3 +-- OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs | 2 +- OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs | 2 +- OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs | 2 +- OpenSim/Region/CoreModules/World/Terrain/Tests/TerrainTest.cs | 3 ++- OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs | 2 +- OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs | 2 +- OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs | 2 +- OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs | 2 +- OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs | 2 +- OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs | 2 +- OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs | 2 +- OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs | 2 +- OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs | 2 +- OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs | 2 +- OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs | 2 +- OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs | 2 +- OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs | 2 +- OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs | 2 +- OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs | 2 +- OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs | 2 +- OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs | 2 +- .../OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs | 2 +- OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs | 2 +- OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs | 3 ++- .../Region/ScriptEngine/Shared/CodeTools/Tests/CSCodeGeneratorTest.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLFloat.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLInteger.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLString.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestList.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestVector3.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs | 2 +- OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs | 2 +- 44 files changed, 46 insertions(+), 45 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs index d604cf6..ed8ec16 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs @@ -44,7 +44,7 @@ using OpenSim.Tests.Common.Mock; namespace OpenSim.Region.ClientStack.Linden.Tests { [TestFixture] - public class EventQueueTests + public class EventQueueTests : OpenSimTestCase { private TestScene m_scene; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs index 5fcf376..7d9f581 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs @@ -43,7 +43,7 @@ using OpenSim.Tests.Common.Mock; namespace OpenSim.Region.ClientStack.LindenUDP.Tests { [TestFixture] - public class LLImageManagerTests + public class LLImageManagerTests : OpenSimTestCase { private AssetBase m_testImageAsset; private Scene scene; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs index 0f88ec6..5f73a94 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs @@ -39,7 +39,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests /// Tests for the LL packet handler /// [TestFixture] - public class PacketHandlerTests + public class PacketHandlerTests : OpenSimTestCase { // [Test] // /// diff --git a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs index 1c2bfd0..0872cc8 100644 --- a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs +++ b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs @@ -47,7 +47,7 @@ namespace OpenSim.Region.CoreModules.Asset.Tests /// At the moment we're only test the in-memory part of the FlotsamAssetCache. This is a considerable weakness. /// [TestFixture] - public class FlotsamAssetCacheTests + public class FlotsamAssetCacheTests : OpenSimTestCase { protected TestScene m_scene; protected FlotsamAssetCache m_cache; diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs index 848b3bf..1830d41 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs @@ -39,7 +39,7 @@ using OpenSim.Tests.Common.Mock; namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory { [TestFixture] - public class AvatarFactoryModuleTests + public class AvatarFactoryModuleTests : OpenSimTestCase { /// /// Only partial right now since we don't yet test that it's ended up in the avatar appearance service. diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs index 7a197f7..961117e 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs @@ -40,7 +40,7 @@ using OpenSim.Tests.Common.Mock; namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests { [TestFixture] - public class FriendsModuleTests + public class FriendsModuleTests : OpenSimTestCase { private FriendsModule m_fm; private TestScene m_scene; diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs index 21d8bd7..b768257 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs @@ -49,7 +49,7 @@ using OpenSim.Tests.Common.Mock; namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests { [TestFixture] - public class InventoryAccessModuleTests + public class InventoryAccessModuleTests : OpenSimTestCase { protected TestScene m_scene; protected BasicInventoryAccessModule m_iam; diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs index 32e47f9..7e365ca 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs @@ -35,7 +35,6 @@ using NUnit.Framework; using OpenMetaverse; using OpenSim.Framework; using Nini.Config; - using OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence; using OpenSim.Region.Framework.Scenes; using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; @@ -44,7 +43,7 @@ using OpenSim.Tests.Common; namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence.Tests { [TestFixture] - public class PresenceConnectorsTests + public class PresenceConnectorsTests : OpenSimTestCase { LocalPresenceServicesConnector m_LocalConnector; private void SetUp() diff --git a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs index b5ee4d2..14eca42 100644 --- a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs +++ b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs @@ -41,7 +41,7 @@ using OpenSim.Tests.Common.Mock; namespace OpenSim.Region.CoreModules.World.Land.Tests { [TestFixture] - public class PrimCountModuleTests + public class PrimCountModuleTests : OpenSimTestCase { protected UUID m_userId = new UUID("00000000-0000-0000-0000-100000000000"); protected UUID m_groupId = new UUID("00000000-0000-0000-8888-000000000000"); diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs index 396095a..ba4b041 100644 --- a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs +++ b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs @@ -44,7 +44,7 @@ using OpenSim.Tests.Common.Mock; namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests { [TestFixture] - public class MoapTests + public class MoapTests : OpenSimTestCase { protected TestScene m_scene; protected MoapModule m_module; diff --git a/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs b/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs index 7825e3e..bcb8e2f 100644 --- a/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs +++ b/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs @@ -39,7 +39,7 @@ using OpenSim.Tests.Common; namespace OpenSim.Region.CoreModules.World.Serialiser.Tests { [TestFixture] - public class SerialiserTests + public class SerialiserTests : OpenSimTestCase { private string xml = @" diff --git a/OpenSim/Region/CoreModules/World/Terrain/Tests/TerrainTest.cs b/OpenSim/Region/CoreModules/World/Terrain/Tests/TerrainTest.cs index 3d4f762..be719ea 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/Tests/TerrainTest.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/Tests/TerrainTest.cs @@ -30,11 +30,12 @@ using NUnit.Framework; using OpenSim.Framework; using OpenSim.Region.CoreModules.World.Terrain.PaintBrushes; using OpenSim.Region.Framework.Scenes; +using OpenSim.Tests.Common; namespace OpenSim.Region.CoreModules.World.Terrain.Tests { [TestFixture] - public class TerrainTest + public class TerrainTest : OpenSimTestCase { [Test] public void BrushTest() diff --git a/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs b/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs index 4a21dc9..e209221 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs @@ -37,7 +37,7 @@ using OpenSim.Tests.Common; namespace OpenSim.Region.Framework.Scenes.Tests { [TestFixture] - public class BorderTests + public class BorderTests : OpenSimTestCase { [Test] public void TestCross() diff --git a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs index ea9fc93..766ce83 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs @@ -41,7 +41,7 @@ using OpenSim.Tests.Common; namespace OpenSim.Region.Framework.Scenes.Tests { [TestFixture, LongRunning] - public class EntityManagerTests + public class EntityManagerTests : OpenSimTestCase { static public Random random; SceneObjectGroup found; diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs index d23c965..575a081 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs @@ -40,7 +40,7 @@ using OpenSim.Tests.Common.Mock; namespace OpenSim.Region.Framework.Scenes.Tests { [TestFixture] - public class SceneGraphTests + public class SceneGraphTests : OpenSimTestCase { [Test] public void TestDuplicateObject() diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs index ab56f4e..2d831fa 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs @@ -41,7 +41,7 @@ using OpenSim.Tests.Common.Mock; namespace OpenSim.Region.Framework.Scenes.Tests { [TestFixture] - public class SceneManagerTests + public class SceneManagerTests : OpenSimTestCase { [Test] public void TestClose() diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs index 0076f41..4f15791 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs @@ -48,7 +48,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests /// TODO: These tests are very incomplete - they only test for a few conditions. /// [TestFixture] - public class SceneObjectDeRezTests + public class SceneObjectDeRezTests : OpenSimTestCase { /// /// Test deleting an object from a scene. diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs index 0e525c9..9378e20 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs @@ -40,7 +40,7 @@ using log4net; namespace OpenSim.Region.Framework.Scenes.Tests { [TestFixture] - public class SceneObjectLinkingTests + public class SceneObjectLinkingTests : OpenSimTestCase { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs index 89647d6..c264433 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs @@ -41,7 +41,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests /// Basic scene object resize tests /// [TestFixture] - public class SceneObjectResizeTests + public class SceneObjectResizeTests : OpenSimTestCase { /// /// Test resizing an object diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs index d2361f8..a58e735 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs @@ -40,7 +40,7 @@ using OpenSim.Tests.Common.Mock; namespace OpenSim.Region.Framework.Scenes.Tests { [TestFixture] - public class SceneObjectScriptTests + public class SceneObjectScriptTests : OpenSimTestCase { [Test] public void TestAddScript() diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs index 6d255aa..5cf62c2 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs @@ -42,7 +42,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests /// Spatial scene object tests (will eventually cover root and child part position, rotation properties, etc.) /// [TestFixture] - public class SceneObjectSpatialTests + public class SceneObjectSpatialTests : OpenSimTestCase { TestScene m_scene; UUID m_ownerId = TestHelpers.ParseTail(0x1); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs index 742c769..093cbd2 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs @@ -42,7 +42,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests /// Basic scene object status tests /// [TestFixture] - public class SceneObjectStatusTests + public class SceneObjectStatusTests : OpenSimTestCase { private TestScene m_scene; private UUID m_ownerId = TestHelpers.ParseTail(0x1); diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs index 646e5fa..1cd8ae9 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs @@ -51,7 +51,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests /// Scene presence animation tests /// [TestFixture] - public class ScenePresenceAnimationTests + public class ScenePresenceAnimationTests : OpenSimTestCase { [Test] public void TestFlyingAnimation() diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs index 1d1ff88..d80afd3 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs @@ -42,7 +42,7 @@ using OpenSim.Tests.Common.Mock; namespace OpenSim.Region.Framework.Scenes.Tests { [TestFixture] - public class ScenePresenceAutopilotTests + public class ScenePresenceAutopilotTests : OpenSimTestCase { private TestScene m_scene; diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs index 493ab70..acaeb90 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs @@ -43,7 +43,7 @@ using System.Threading; namespace OpenSim.Region.Framework.Scenes.Tests { [TestFixture] - public class ScenePresenceSitTests + public class ScenePresenceSitTests : OpenSimTestCase { private TestScene m_scene; private ScenePresence m_sp; diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs index 37b5184..8dd1f3d 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs @@ -49,7 +49,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests /// Teleport tests in a standalone OpenSim /// [TestFixture] - public class ScenePresenceTeleportTests + public class ScenePresenceTeleportTests : OpenSimTestCase { [TestFixtureSetUp] public void FixtureInit() diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs index ac3da1e..9d8eb0b 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs @@ -50,7 +50,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests /// Scene presence tests /// [TestFixture] - public class SceneTests + public class SceneTests : OpenSimTestCase { /// /// Very basic scene update test. Should become more elaborate with time. diff --git a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs index a51e4e3..0b461f5 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs @@ -50,7 +50,7 @@ using OpenSim.Tests.Common.Mock; namespace OpenSim.Region.Framework.Tests { [TestFixture] - public class TaskInventoryTests + public class TaskInventoryTests : OpenSimTestCase { [Test] public void TestAddTaskInventoryItem() diff --git a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs index 198e487..dd27294 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs @@ -38,7 +38,7 @@ using OpenSim.Tests.Common.Mock; namespace OpenSim.Region.Framework.Scenes.Tests { [TestFixture] - public class UuidGathererTests + public class UuidGathererTests : OpenSimTestCase { protected IAssetService m_assetService; protected UuidGatherer m_uuidGatherer; diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs index ac638f1..c1bdacb 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs @@ -42,7 +42,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests /// Basic groups module tests /// [TestFixture] - public class GroupsModuleTests + public class GroupsModuleTests : OpenSimTestCase { [Test] public void TestBasic() diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index 52ed846..a522277 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -48,7 +48,7 @@ using OpenSim.Tests.Common.Mock; namespace OpenSim.Region.OptionalModules.World.NPC.Tests { [TestFixture] - public class NPCModuleTests + public class NPCModuleTests : OpenSimTestCase { private TestScene m_scene; private AvatarFactoryModule m_afMod; diff --git a/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs b/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs index cbc6b95..16404c6 100644 --- a/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs +++ b/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs @@ -32,13 +32,14 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Physics.Manager; using OpenSim.Region.Physics.OdePlugin; +using OpenSim.Tests.Common; using log4net; using System.Reflection; namespace OpenSim.Region.Physics.OdePlugin.Tests { [TestFixture] - public class ODETestClass + public class ODETestClass : OpenSimTestCase { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CSCodeGeneratorTest.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CSCodeGeneratorTest.cs index 7763619..77e087c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CSCodeGeneratorTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CSCodeGeneratorTest.cs @@ -39,7 +39,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests /// The generated C# code is compared against the expected C# code. /// [TestFixture] - public class CSCodeGeneratorTest + public class CSCodeGeneratorTest : OpenSimTestCase { [Test] public void TestDefaultState() diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs index 1fa6954..05a8756 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs @@ -41,7 +41,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests /// the LSL source. /// [TestFixture] - public class CompilerTest + public class CompilerTest : OpenSimTestCase { private string m_testDir; private CSharpCodeProvider m_CSCodeProvider; diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs index c73e22f..2c9d9e8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs @@ -51,7 +51,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests /// Tests for inventory functions in LSL /// [TestFixture] - public class LSL_ApiInventoryTests + public class LSL_ApiInventoryTests : OpenSimTestCase { protected Scene m_scene; protected XEngine.XEngine m_engine; diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs index 2565ae7..57f19b9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs @@ -56,7 +56,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests /// OpenSim.Region.Framework.Scenes.Tests.SceneObjectLinkingTests. /// [TestFixture] - public class LSL_ApiLinkingTests + public class LSL_ApiLinkingTests : OpenSimTestCase { protected Scene m_scene; protected XEngine.XEngine m_engine; diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs index dd23be8..182b07b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs @@ -46,7 +46,7 @@ using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; namespace OpenSim.Region.ScriptEngine.Shared.Tests { [TestFixture] - public class LSL_ApiListTests + public class LSL_ApiListTests : OpenSimTestCase { private LSL_Api m_lslApi; diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLFloat.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLFloat.cs index 3ed2562..c8c7f82 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLFloat.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLFloat.cs @@ -33,7 +33,7 @@ using OpenSim.Region.ScriptEngine.Shared; namespace OpenSim.Region.ScriptEngine.Shared.Tests { [TestFixture] - public class LSL_TypesTestLSLFloat + public class LSL_TypesTestLSLFloat : OpenSimTestCase { // Used for testing equality of two floats. private double _lowPrecisionTolerance = 0.000001; diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLInteger.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLInteger.cs index 8d1169a..c664108 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLInteger.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLInteger.cs @@ -33,7 +33,7 @@ using OpenSim.Region.ScriptEngine.Shared; namespace OpenSim.Region.ScriptEngine.Shared.Tests { [TestFixture] - public class LSL_TypesTestLSLInteger + public class LSL_TypesTestLSLInteger : OpenSimTestCase { private Dictionary m_doubleIntSet; private Dictionary m_stringIntSet; diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLString.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLString.cs index c4ca1a8..8550f2d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLString.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLString.cs @@ -33,7 +33,7 @@ using OpenSim.Region.ScriptEngine.Shared; namespace OpenSim.Region.ScriptEngine.Shared.Tests { [TestFixture] - public class LSL_TypesTestLSLString + public class LSL_TypesTestLSLString : OpenSimTestCase { private Dictionary m_doubleStringSet; diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestList.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestList.cs index b81225f..71b88bc 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestList.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestList.cs @@ -36,7 +36,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests /// Tests the LSL_Types.list class. /// [TestFixture] - public class LSL_TypesTestList + public class LSL_TypesTestList : OpenSimTestCase { /// /// Tests concatenating a string to a list. diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestVector3.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestVector3.cs index ebf8001..0c838af 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestVector3.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestVector3.cs @@ -36,7 +36,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests /// Tests for Vector3 /// [TestFixture] - public class LSL_TypesTestVector3 + public class LSL_TypesTestVector3 : OpenSimTestCase { [Test] public void TestDotProduct() diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs index c401794..213f33f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs @@ -51,7 +51,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests /// Tests for OSSL_Api /// [TestFixture] - public class OSSL_ApiAppearanceTest + public class OSSL_ApiAppearanceTest : OpenSimTestCase { protected Scene m_scene; protected XEngine.XEngine m_engine; diff --git a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs index f331658..5abfe9a 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs @@ -44,7 +44,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine.Tests /// XEngine tests. /// [TestFixture] - public class XEngineTest + public class XEngineTest : OpenSimTestCase { private TestScene m_scene; private XEngine m_xEngine; -- cgit v1.1 From a4ce63d0cd5dacdd33c6563bbc1af29ef5d36755 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 24 Nov 2012 03:38:15 +0000 Subject: Fix regression TestDeleteSceneObjectAsyncToUserInventory by adding a BasicInventoryAccessModule() and re-enable in test suite. --- .../Framework/Scenes/Tests/SceneObjectBasicTests.cs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs index 5b334c6..373094b 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs @@ -29,10 +29,12 @@ using System; using System.Collections.Generic; using System.Reflection; using System.Threading; +using Nini.Config; using NUnit.Framework; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Communications; +using OpenSim.Region.CoreModules.Framework.InventoryAccess; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; using OpenSim.Tests.Common; @@ -239,28 +241,31 @@ namespace OpenSim.Region.Framework.Scenes.Tests /// /// Test deleting an object asynchronously to user inventory. /// -// [Test] + [Test] public void TestDeleteSceneObjectAsyncToUserInventory() { TestHelpers.InMethod(); - TestHelpers.EnableLogging(); +// TestHelpers.EnableLogging(); UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000001"); string myObjectName = "Fred"; TestScene scene = new SceneHelpers().SetupScene(); + IConfigSource configSource = new IniConfigSource(); + IConfig config = configSource.AddConfig("Modules"); + config.Set("InventoryAccessModule", "BasicInventoryAccessModule"); + SceneHelpers.SetupSceneModules( + scene, configSource, new object[] { new BasicInventoryAccessModule() }); + + SceneHelpers.SetupSceneModules(scene, new object[] { }); + // Turn off the timer on the async sog deleter - we'll crank it by hand for this test. AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter; sogd.Enabled = false; SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, myObjectName, agentId); -// Assert.That( -// scene.CommsManager.UserAdminService.AddUser( -// "Bob", "Hoskins", "test", "test@test.com", 1000, 1000, agentId), -// Is.EqualTo(agentId)); - UserAccount ua = UserAccountHelpers.CreateUserWithInventory(scene, agentId); InventoryFolderBase folder1 = UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, ua.PrincipalID, "folder1"); -- cgit v1.1 From 02db8b9adbfd69d117bc54288473f5240de46918 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 24 Nov 2012 03:49:23 +0000 Subject: Combine TestDeleteSceneObjectAsync() with TestDeRezSceneObject() as they are functionally identical. Move TestDeleteSceneObjectAsync() and TestDeleteSceneObjectAsyncToUserInventory() from SceneObjectBasicTests -> SceneObjectDeRezTests --- .../Scenes/Tests/SceneObjectBasicTests.cs | 104 +-------------------- .../Scenes/Tests/SceneObjectDeRezTests.cs | 81 ++++++++++++++-- .../Scenes/Tests/SceneObjectSpatialTests.cs | 4 +- 3 files changed, 83 insertions(+), 106 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs index 373094b..a07d64c 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs @@ -34,7 +34,6 @@ using NUnit.Framework; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Communications; -using OpenSim.Region.CoreModules.Framework.InventoryAccess; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; using OpenSim.Tests.Common; @@ -184,6 +183,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests /// /// Test deleting an object from a scene. /// + /// + /// This is the most basic form of delete. For all more sophisticated forms of derez (done asynchrnously + /// and where object can be taken to user inventory, etc.), see SceneObjectDeRezTests. + /// [Test] public void TestDeleteSceneObject() { @@ -203,103 +206,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests } /// - /// Test deleting an object asynchronously - /// - [Test] - public void TestDeleteSceneObjectAsync() - { - TestHelpers.InMethod(); - //log4net.Config.XmlConfigurator.Configure(); - - UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000001"); - - TestScene scene = new SceneHelpers().SetupScene(); - - // Turn off the timer on the async sog deleter - we'll crank it by hand for this test. - AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter; - sogd.Enabled = false; - - SceneObjectGroup so = SceneHelpers.AddSceneObject(scene); - - IClientAPI client = SceneHelpers.AddScenePresence(scene, agentId).ControllingClient; - scene.DeRezObjects(client, new System.Collections.Generic.List() { so.LocalId }, UUID.Zero, DeRezAction.Delete, UUID.Zero); - - SceneObjectPart retrievedPart = scene.GetSceneObjectPart(so.LocalId); - - Assert.That(retrievedPart, Is.Not.Null); - - Assert.That(so.IsDeleted, Is.False); - - sogd.InventoryDeQueueAndDelete(); - - Assert.That(so.IsDeleted, Is.True); - - SceneObjectPart retrievedPart2 = scene.GetSceneObjectPart(so.LocalId); - Assert.That(retrievedPart2, Is.Null); - } - - /// - /// Test deleting an object asynchronously to user inventory. - /// - [Test] - public void TestDeleteSceneObjectAsyncToUserInventory() - { - TestHelpers.InMethod(); -// TestHelpers.EnableLogging(); - - UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000001"); - string myObjectName = "Fred"; - - TestScene scene = new SceneHelpers().SetupScene(); - - IConfigSource configSource = new IniConfigSource(); - IConfig config = configSource.AddConfig("Modules"); - config.Set("InventoryAccessModule", "BasicInventoryAccessModule"); - SceneHelpers.SetupSceneModules( - scene, configSource, new object[] { new BasicInventoryAccessModule() }); - - SceneHelpers.SetupSceneModules(scene, new object[] { }); - - // Turn off the timer on the async sog deleter - we'll crank it by hand for this test. - AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter; - sogd.Enabled = false; - - SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, myObjectName, agentId); - - UserAccount ua = UserAccountHelpers.CreateUserWithInventory(scene, agentId); - InventoryFolderBase folder1 - = UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, ua.PrincipalID, "folder1"); - - IClientAPI client = SceneHelpers.AddScenePresence(scene, agentId).ControllingClient; - scene.DeRezObjects(client, new List() { so.LocalId }, UUID.Zero, DeRezAction.Take, folder1.ID); - - SceneObjectPart retrievedPart = scene.GetSceneObjectPart(so.LocalId); - - Assert.That(retrievedPart, Is.Not.Null); - Assert.That(so.IsDeleted, Is.False); - - sogd.InventoryDeQueueAndDelete(); - - Assert.That(so.IsDeleted, Is.True); - - SceneObjectPart retrievedPart2 = scene.GetSceneObjectPart(so.LocalId); - Assert.That(retrievedPart2, Is.Null); - -// SceneSetupHelpers.DeleteSceneObjectAsync(scene, part, DeRezAction.Take, userInfo.RootFolder.ID, client); - - InventoryItemBase retrievedItem - = UserInventoryHelpers.GetInventoryItem( - scene.InventoryService, ua.PrincipalID, "folder1/" + myObjectName); - - // Check that we now have the taken part in our inventory - Assert.That(retrievedItem, Is.Not.Null); - - // Check that the taken part has actually disappeared -// SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); -// Assert.That(retrievedPart, Is.Null); - } - - /// /// Changing a scene object uuid changes the root part uuid. This is a valid operation if the object is not /// in a scene and is useful if one wants to supply a UUID directly rather than use the one generated by /// OpenSim. @@ -334,4 +240,4 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(sog.Parts.Length, Is.EqualTo(2)); } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs index 4f15791..c1522e7 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs @@ -33,19 +33,21 @@ using NUnit.Framework; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Communications; +using OpenSim.Region.CoreModules.Framework.InventoryAccess; using OpenSim.Region.CoreModules.World.Permissions; using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; using OpenSim.Tests.Common; using OpenSim.Tests.Common.Mock; namespace OpenSim.Region.Framework.Scenes.Tests { /// - /// Tests derez of scene objects by users. + /// Tests derez of scene objects. /// /// /// This is at a level above the SceneObjectBasicTests, which act on the scene directly. - /// TODO: These tests are very incomplete - they only test for a few conditions. + /// TODO: These tests are incomplete - need to test more kinds of derez (e.g. return object). /// [TestFixture] public class SceneObjectDeRezTests : OpenSimTestCase @@ -76,14 +78,20 @@ namespace OpenSim.Region.Framework.Scenes.Tests = new SceneObjectPart(userId, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero); part.Name = "obj1"; scene.AddNewSceneObject(new SceneObjectGroup(part), false); + List localIds = new List(); localIds.Add(part.LocalId); - scene.DeRezObjects(client, localIds, UUID.Zero, DeRezAction.Delete, UUID.Zero); + + // Check that object isn't deleted until we crank the sogd handle. + SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); + Assert.That(retrievedPart, Is.Not.Null); + Assert.That(retrievedPart.ParentGroup.IsDeleted, Is.False); + sogd.InventoryDeQueueAndDelete(); - SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); - Assert.That(retrievedPart, Is.Null); + SceneObjectPart retrievedPart2 = scene.GetSceneObjectPart(part.LocalId); + Assert.That(retrievedPart2, Is.Null); } /// @@ -124,6 +132,67 @@ namespace OpenSim.Region.Framework.Scenes.Tests // Object should still be in the scene. SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); Assert.That(retrievedPart.UUID, Is.EqualTo(part.UUID)); - } + } + + /// + /// Test deleting an object asynchronously to user inventory. + /// + [Test] + public void TestDeleteSceneObjectAsyncToUserInventory() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000001"); + string myObjectName = "Fred"; + + TestScene scene = new SceneHelpers().SetupScene(); + + IConfigSource configSource = new IniConfigSource(); + IConfig config = configSource.AddConfig("Modules"); + config.Set("InventoryAccessModule", "BasicInventoryAccessModule"); + SceneHelpers.SetupSceneModules( + scene, configSource, new object[] { new BasicInventoryAccessModule() }); + + SceneHelpers.SetupSceneModules(scene, new object[] { }); + + // Turn off the timer on the async sog deleter - we'll crank it by hand for this test. + AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter; + sogd.Enabled = false; + + SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, myObjectName, agentId); + + UserAccount ua = UserAccountHelpers.CreateUserWithInventory(scene, agentId); + InventoryFolderBase folder1 + = UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, ua.PrincipalID, "folder1"); + + IClientAPI client = SceneHelpers.AddScenePresence(scene, agentId).ControllingClient; + scene.DeRezObjects(client, new List() { so.LocalId }, UUID.Zero, DeRezAction.Take, folder1.ID); + + SceneObjectPart retrievedPart = scene.GetSceneObjectPart(so.LocalId); + + Assert.That(retrievedPart, Is.Not.Null); + Assert.That(so.IsDeleted, Is.False); + + sogd.InventoryDeQueueAndDelete(); + + Assert.That(so.IsDeleted, Is.True); + + SceneObjectPart retrievedPart2 = scene.GetSceneObjectPart(so.LocalId); + Assert.That(retrievedPart2, Is.Null); + +// SceneSetupHelpers.DeleteSceneObjectAsync(scene, part, DeRezAction.Take, userInfo.RootFolder.ID, client); + + InventoryItemBase retrievedItem + = UserInventoryHelpers.GetInventoryItem( + scene.InventoryService, ua.PrincipalID, "folder1/" + myObjectName); + + // Check that we now have the taken part in our inventory + Assert.That(retrievedItem, Is.Not.Null); + + // Check that the taken part has actually disappeared +// SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); +// Assert.That(retrievedPart, Is.Null); + } } } \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs index 5cf62c2..abaa1d1 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs @@ -48,8 +48,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests UUID m_ownerId = TestHelpers.ParseTail(0x1); [SetUp] - public void SetUp() + public override void SetUp() { + base.SetUp(); + m_scene = new SceneHelpers().SetupScene(); } -- cgit v1.1 From 4ae30873ad1c0d48b7e03047eafe5cd690bbe61c Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 22 Nov 2012 12:01:56 -0800 Subject: BulletSim: Add tables and initialization for different attributes for different materials. For the moment, the per material tables are not used. --- .../Region/Physics/BulletSPlugin/BSMaterials.cs | 191 +++++++++++++++++++++ OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 7 + 2 files changed, 198 insertions(+) create mode 100755 OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs new file mode 100755 index 0000000..663b6f4 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs @@ -0,0 +1,191 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using System.Reflection; +using Nini.Config; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ + +public struct MaterialAttributes +{ + // Material type values that correspond with definitions for LSL + public enum Material : int + { + Stone = 0, + Metal, + Glass, + Wood, + Flesh, + Plastic, + Rubber, + Light, + // Hereafter are BulletSim additions + Avatar, + NumberOfTypes // the count of types in the enum. + } + // Names must be in the order of the above enum. + public static string[] MaterialNames = { "Stone", "Metal", "Glass", "Wood", + "Flesh", "Plastic", "Rubber", "Light", "Avatar" }; + public static string[] MaterialAttribs = { "Density", "Friction", "Restitution", + "ccdMotionThreshold", "ccdSweptSphereRadius" }; + + public MaterialAttributes(string t, float d, float f, float r, float ccdM, float ccdS) + { + type = t; + density = d; + friction = f; + restitution = r; + ccdMotionThreshold = ccdM; + ccdSweptSphereRadius = ccdS; + } + public string type; + public float density; + public float friction; + public float restitution; + public float ccdMotionThreshold; + public float ccdSweptSphereRadius; +} + +public static class BSMaterials +{ + public static MaterialAttributes[] Attributes; + + static BSMaterials() + { + // Attribute sets for both the non-physical and physical instances of materials. + Attributes = new MaterialAttributes[(int)MaterialAttributes.Material.NumberOfTypes * 2]; + } + + // This is where all the default material attributes are defined. + public static void InitializeFromDefaults(ConfigurationParameters parms) + { + // public static string[] MaterialNames = { "Stone", "Metal", "Glass", "Wood", + // "Flesh", "Plastic", "Rubber", "Light", "Avatar" }; + float dFriction = parms.defaultFriction; + float dRestitution = parms.defaultRestitution; + float dDensity = parms.defaultDensity; + float dCcdM = parms.ccdMotionThreshold; + float dCcdS = parms.ccdSweptSphereRadius; + Attributes[(int)MaterialAttributes.Material.Stone] = + new MaterialAttributes("stone",dDensity,dFriction,dRestitution, dCcdM, dCcdS); + Attributes[(int)MaterialAttributes.Material.Metal] = + new MaterialAttributes("metal",dDensity,dFriction,dRestitution, dCcdM, dCcdS); + Attributes[(int)MaterialAttributes.Material.Glass] = + new MaterialAttributes("glass",dDensity,dFriction,dRestitution, dCcdM, dCcdS); + Attributes[(int)MaterialAttributes.Material.Wood] = + new MaterialAttributes("wood",dDensity,dFriction,dRestitution, dCcdM, dCcdS); + Attributes[(int)MaterialAttributes.Material.Flesh] = + new MaterialAttributes("flesh",dDensity,dFriction,dRestitution, dCcdM, dCcdS); + Attributes[(int)MaterialAttributes.Material.Plastic] = + new MaterialAttributes("plastic",dDensity,dFriction,dRestitution, dCcdM, dCcdS); + Attributes[(int)MaterialAttributes.Material.Rubber] = + new MaterialAttributes("rubber",dDensity,dFriction,dRestitution, dCcdM, dCcdS); + Attributes[(int)MaterialAttributes.Material.Light] = + new MaterialAttributes("light",dDensity,dFriction,dRestitution, dCcdM, dCcdS); + Attributes[(int)MaterialAttributes.Material.Avatar] = + new MaterialAttributes("avatar",dDensity,dFriction,dRestitution, dCcdM, dCcdS); + + Attributes[(int)MaterialAttributes.Material.Stone + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("stonePhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); + Attributes[(int)MaterialAttributes.Material.Metal + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("metalPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); + Attributes[(int)MaterialAttributes.Material.Glass + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("glassPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); + Attributes[(int)MaterialAttributes.Material.Wood + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("woodPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); + Attributes[(int)MaterialAttributes.Material.Flesh + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("fleshPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); + Attributes[(int)MaterialAttributes.Material.Plastic + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("plasticPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); + Attributes[(int)MaterialAttributes.Material.Rubber + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("rubberPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); + Attributes[(int)MaterialAttributes.Material.Light + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("lightPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); + Attributes[(int)MaterialAttributes.Material.Avatar + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("avatarPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); + } + + // Under the [BulletSim] section, one can change the individual material + // attribute values. The format of the configuration parameter is: + // ["Physical"] = floatValue + // For instance: + // [BulletSim] + // StoneFriction = 0.2 + // FleshRestitutionPhysical = 0.8 + // Materials can have different parameters for their static and + // physical instantiations. When setting the non-physical value, + // both values are changed. Setting the physical value only changes + // the physical value. + public static void InitializefromParameters(IConfig pConfig) + { + int matType = 0; + foreach (string matName in MaterialAttributes.MaterialNames) + { + foreach (string attribName in MaterialAttributes.MaterialAttribs) + { + string paramName = matName + attribName; + if (pConfig.Contains(paramName)) + { + float paramValue = pConfig.GetFloat(paramName); + SetAttributeValue(matType, attribName, paramValue); + // set the physical value also + SetAttributeValue(matType + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue); + } + paramName += "Physical"; + if (pConfig.Contains(paramName)) + { + float paramValue = pConfig.GetFloat(paramName); + SetAttributeValue(matType + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue); + } + } + matType++; + } + } + + private static void SetAttributeValue(int matType, string attribName, float val) + { + MaterialAttributes thisAttrib = Attributes[matType]; + FieldInfo fieldInfo = thisAttrib.GetType().GetField(attribName); + if (fieldInfo != null) + { + fieldInfo.SetValue(thisAttrib, val); + Attributes[matType] = thisAttrib; + } + } + + public static MaterialAttributes GetAttributes(MaterialAttributes.Material type, bool isPhysical) + { + int ind = (int)type; + if (isPhysical) ind += (int)MaterialAttributes.Material.NumberOfTypes; + return Attributes[ind]; + } + +} +} diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 27a78d1..37bdb84 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -308,6 +308,13 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // Do any replacements in the parameters m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName); } + + // The material characteristics. + BSMaterials.InitializeFromDefaults(Params); + if (pConfig != null) + { + BSMaterials.InitializefromParameters(pConfig); + } } } -- cgit v1.1 From c3f30fef96674e9f43a277399c987a85cec9a7d3 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 24 Nov 2012 19:57:11 -0800 Subject: BulletSim: add parameter for terrain collision margin. Add locking around unlikely but possible race conditions on terrain list. --- .../Physics/BulletSPlugin/BSTerrainHeightmap.cs | 2 +- .../Physics/BulletSPlugin/BSTerrainManager.cs | 93 ++++++++++------------ .../Region/Physics/BulletSPlugin/BSTerrainMesh.cs | 4 - 3 files changed, 45 insertions(+), 54 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs index 3ca756c..1450f66 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs @@ -93,7 +93,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys { m_mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, m_mapInfo.ID, m_mapInfo.minCoords, m_mapInfo.maxCoords, - m_mapInfo.heightMap, BSTerrainManager.TERRAIN_COLLISION_MARGIN); + m_mapInfo.heightMap, PhysicsScene.Params.terrainCollisionMargin); // Create the terrain shape from the mapInfo m_mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(m_mapInfo.Ptr), diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index 23fcfd3..cd623f1 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -80,8 +80,6 @@ public sealed class BSTerrainManager // amount to make sure that a bounding box is built for the terrain. public const float HEIGHT_EQUAL_FUDGE = 0.2f; - public const float TERRAIN_COLLISION_MARGIN = 0.0f; - // Until the whole simulator is changed to pass us the region size, we rely on constants. public Vector3 DefaultRegionSize = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); @@ -129,7 +127,8 @@ public sealed class BSTerrainManager { // The ground plane is here to catch things that are trying to drop to negative infinity BulletShape groundPlaneShape = new BulletShape( - BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, TERRAIN_COLLISION_MARGIN), + BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, + PhysicsScene.Params.terrainCollisionMargin), BSPhysicsShapeType.SHAPE_GROUNDPLANE); m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID, BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID, @@ -165,17 +164,22 @@ public sealed class BSTerrainManager // Release all the terrain we have allocated public void ReleaseTerrain() { - foreach (KeyValuePair kvp in m_terrains) + lock (m_terrains) { - kvp.Value.Dispose(); + foreach (KeyValuePair kvp in m_terrains) + { + kvp.Value.Dispose(); + } + m_terrains.Clear(); } - m_terrains.Clear(); } // The simulator wants to set a new heightmap for the terrain. public void SetTerrain(float[] heightMap) { float[] localHeightMap = heightMap; - PhysicsScene.TaintedObject("TerrainManager.SetTerrain", delegate() + // If there are multiple requests for changes to the same terrain between ticks, + // only do that last one. + PhysicsScene.PostTaintObject("TerrainManager.SetTerrain-"+ m_worldOffset.ToString(), 0, delegate() { if (m_worldOffset != Vector3.Zero && MegaRegionParentPhysicsScene != null) { @@ -211,6 +215,7 @@ public sealed class BSTerrainManager // terrain shape is created and added to the body. // This call is most often used to update the heightMap and parameters of the terrain. // (The above does suggest that some simplification/refactoring is in order.) + // Called during taint-time. private void UpdateTerrain(uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords, bool inTaintTime) { @@ -220,7 +225,7 @@ public sealed class BSTerrainManager // Find high and low points of passed heightmap. // The min and max passed in is usually the area objects can be in (maximum // object height, for instance). The terrain wants the bounding box for the - // terrain so we replace passed min and max Z with the actual terrain min/max Z. + // terrain so replace passed min and max Z with the actual terrain min/max Z. float minZ = float.MaxValue; float maxZ = float.MinValue; foreach (float height in heightMap) @@ -238,15 +243,15 @@ public sealed class BSTerrainManager Vector3 terrainRegionBase = new Vector3(minCoords.X, minCoords.Y, 0f); - BSTerrainPhys terrainPhys; - if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys)) + lock (m_terrains) { - // There is already a terrain in this spot. Free the old and build the new. - DetailLog("{0},UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}", - BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords); - - PhysicsScene.TaintedObject(inTaintTime, "BSScene.UpdateTerrain:UpdateExisting", delegate() + BSTerrainPhys terrainPhys; + if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys)) { + // There is already a terrain in this spot. Free the old and build the new. + DetailLog("{0},UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}", + BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords); + // Remove old terrain from the collection m_terrains.Remove(terrainRegionBase); // Release any physical memory it may be using. @@ -271,35 +276,24 @@ public sealed class BSTerrainManager // I hate doing this, but just bail return; } - }); - } - else - { - // We don't know about this terrain so either we are creating a new terrain or - // our mega-prim child is giving us a new terrain to add to the phys world - - // if this is a child terrain, calculate a unique terrain id - uint newTerrainID = id; - if (newTerrainID >= BSScene.CHILDTERRAIN_ID) - newTerrainID = ++m_terrainCount; - - float[] heightMapX = heightMap; - Vector3 minCoordsX = minCoords; - Vector3 maxCoordsX = maxCoords; + } + else + { + // We don't know about this terrain so either we are creating a new terrain or + // our mega-prim child is giving us a new terrain to add to the phys world - DetailLog("{0},UpdateTerrain:NewTerrain,call,id={1}, minC={2}, maxC={3}", - BSScene.DetailLogZero, newTerrainID, minCoords, minCoords); + // if this is a child terrain, calculate a unique terrain id + uint newTerrainID = id; + if (newTerrainID >= BSScene.CHILDTERRAIN_ID) + newTerrainID = ++m_terrainCount; - // Code that must happen at taint-time - PhysicsScene.TaintedObject(inTaintTime, "BSScene.UpdateTerrain:NewTerrain", delegate() - { - DetailLog("{0},UpdateTerrain:NewTerrain,taint,baseX={1},baseY={2}", - BSScene.DetailLogZero, minCoordsX.X, minCoordsX.Y); + DetailLog("{0},UpdateTerrain:NewTerrain,taint,newID={1},minCoord={2},maxCoord={3}", + BSScene.DetailLogZero, newTerrainID, minCoords, minCoords); BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords); m_terrains.Add(terrainRegionBase, newTerrainPhys); m_terrainModified = true; - }); + } } } @@ -349,6 +343,7 @@ public sealed class BSTerrainManager // with the same parameters as last time. if (!m_terrainModified && lastHeightTX == tX && lastHeightTY == tY) return lastHeight; + m_terrainModified = false; lastHeightTX = tX; lastHeightTY = tY; @@ -358,19 +353,19 @@ public sealed class BSTerrainManager int offsetY = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y; Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f); - BSTerrainPhys physTerrain; - if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain)) + lock (m_terrains) { - ret = physTerrain.GetHeightAtXYZ(loc - terrainBaseXYZ); - DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXYZ,loc={1},base={2},height={3}", - BSScene.DetailLogZero, loc, terrainBaseXYZ, ret); - } - else - { - PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}", - LogHeader, PhysicsScene.RegionName, tX, tY); + BSTerrainPhys physTerrain; + if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain)) + { + ret = physTerrain.GetHeightAtXYZ(loc - terrainBaseXYZ); + } + else + { + PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}", + LogHeader, PhysicsScene.RegionName, tX, tY); + } } - m_terrainModified = false; lastHeight = ret; return ret; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index dca7150..d7afdeb 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs @@ -217,8 +217,6 @@ public sealed class BSTerrainMesh : BSTerrainPhys } } verticesCount = verticesCount / 3; - physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeVerts,verCount={1}", - BSScene.DetailLogZero, verticesCount); for (int yy = 0; yy < sizeY; yy++) { @@ -235,8 +233,6 @@ public sealed class BSTerrainMesh : BSTerrainPhys indicesCount += 6; } } - physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeIndices,indCount={1}", // DEEBUG DEBUG DEBUG - LogHeader, indicesCount); // DEBUG ret = true; } catch (Exception e) -- cgit v1.1 From d1480ac7ee3f4a7386feac261a9a2618f946adb3 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 24 Nov 2012 19:58:52 -0800 Subject: BulletSim: add terrain collision margin and vehicle angular damping parameters to the parameter block. New API call for setting collision margin. --- OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index e60a760..12baee9 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -287,6 +287,8 @@ public struct ConfigurationParameters public float terrainFriction; public float terrainHitFraction; public float terrainRestitution; + public float terrainCollisionMargin; + public float avatarFriction; public float avatarStandingFriction; public float avatarDensity; @@ -296,6 +298,8 @@ public struct ConfigurationParameters public float avatarCapsuleHeight; public float avatarContactProcessingThreshold; + public float vehicleAngularDamping; + public float maxPersistantManifoldPoolSize; public float maxCollisionAlgorithmPoolSize; public float shouldDisableContactPoolDynamicAllocation; @@ -482,6 +486,9 @@ public static extern IntPtr BuildNativeShape2(IntPtr world, ShapeData shapeData) public static extern bool IsNativeShape2(IntPtr shape); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetShapeCollisionMargin(IntPtr shape, float margin); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern IntPtr BuildCapsuleShape2(IntPtr world, float radius, float height, Vector3 scale); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -- cgit v1.1 From 22d5bf8ff9942707c3e189aa31e1e253dc20603b Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 24 Nov 2012 20:01:34 -0800 Subject: BulletSim: complete vector motor. Correct line endings. --- OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 233 +++++++++++++---------- 1 file changed, 129 insertions(+), 104 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index bc6e4c4..b8bdd87 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -1,104 +1,129 @@ -using System; -using System.Collections.Generic; -using System.Text; -using OpenMetaverse; - -namespace OpenSim.Region.Physics.BulletSPlugin -{ -public abstract class BSMotor -{ - public virtual void Reset() { } - public virtual void Zero() { } -} -// Can all the incremental stepping be replaced with motor classes? -public class BSVMotor : BSMotor -{ - public Vector3 FrameOfReference { get; set; } - public Vector3 Offset { get; set; } - - public float TimeScale { get; set; } - public float TargetValueDecayTimeScale { get; set; } - public Vector3 CurrentValueReductionTimescale { get; set; } - public float Efficiency { get; set; } - - public Vector3 TargetValue { get; private set; } - public Vector3 CurrentValue { get; private set; } - - - - BSVMotor(float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency) - { - TimeScale = timeScale; - TargetValueDecayTimeScale = decayTimeScale; - CurrentValueReductionTimescale = frictionTimeScale; - Efficiency = efficiency; - } - public void SetCurrent(Vector3 current) - { - CurrentValue = current; - } - public void SetTarget(Vector3 target) - { - TargetValue = target; - } - public Vector3 Step(float timeStep) - { - if (CurrentValue.LengthSquared() > 0.001f) - { - // Vector3 origDir = Target; // DEBUG - // Vector3 origVel = CurrentValue; // DEBUG - - // Add (desiredVelocity - currentAppliedVelocity) / howLongItShouldTakeToComplete - Vector3 addAmount = (TargetValue - CurrentValue)/(TargetValue) * timeStep; - CurrentValue += addAmount; - - float decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep; - TargetValue *= (1f - decayFactor); - - Vector3 frictionFactor = (Vector3.One / CurrentValueReductionTimescale) * timeStep; - CurrentValue *= (Vector3.One - frictionFactor); - } - else - { - // if what remains of direction is very small, zero it. - TargetValue = Vector3.Zero; - CurrentValue = Vector3.Zero; - - // VDetailLog("{0},MoveLinear,zeroed", Prim.LocalID); - } - return CurrentValue; - } -} - -public class BSFMotor : BSMotor -{ - public float TimeScale { get; set; } - public float DecayTimeScale { get; set; } - public float Friction { get; set; } - public float Efficiency { get; set; } - - public float Target { get; private set; } - public float CurrentValue { get; private set; } - - BSFMotor(float timeScale, float decayTimescale, float friction, float efficiency) - { - } - public void SetCurrent(float target) - { - } - public void SetTarget(float target) - { - } - public float Step(float timeStep) - { - return 0f; - } -} -public class BSPIDMotor : BSMotor -{ - // TODO: write and use this one - BSPIDMotor() - { - } -} -} +using System; +using System.Collections.Generic; +using System.Text; +using OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ +public abstract class BSMotor +{ + public BSMotor() + { + PhysicsScene = null; + } + public virtual void Reset() { } + public virtual void Zero() { } + + // Used only for outputting debug information. Might not be set so check for null. + public BSScene PhysicsScene { get; set; } + protected void MDetailLog(string msg, params Object[] parms) + { + if (PhysicsScene != null) + { + if (PhysicsScene.VehicleLoggingEnabled) + { + PhysicsScene.DetailLog(msg, parms); + } + } + } +} +// Can all the incremental stepping be replaced with motor classes? +public class BSVMotor : BSMotor +{ + public Vector3 FrameOfReference { get; set; } + public Vector3 Offset { get; set; } + + public float TimeScale { get; set; } + public float TargetValueDecayTimeScale { get; set; } + public Vector3 CurrentValueReductionTimescale { get; set; } + public float Efficiency { get; set; } + + public Vector3 TargetValue { get; private set; } + public Vector3 CurrentValue { get; private set; } + + BSVMotor(float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency) : base() + { + TimeScale = timeScale; + TargetValueDecayTimeScale = decayTimeScale; + CurrentValueReductionTimescale = frictionTimeScale; + Efficiency = efficiency; + CurrentValue = TargetValue = Vector3.Zero; + } + public void SetCurrent(Vector3 current) + { + CurrentValue = current; + } + public void SetTarget(Vector3 target) + { + TargetValue = target; + } + public Vector3 Step(float timeStep) + { + Vector3 returnCurrent = Vector3.Zero; + if (CurrentValue.LengthSquared() > 0.001f) + { + // Vector3 origDir = Target; // DEBUG + // Vector3 origVel = CurrentValue; // DEBUG + + // Add (desiredVector - currentAppliedVector) / howLongItShouldTakeToComplete + Vector3 addAmount = (TargetValue - CurrentValue)/TimeScale * timeStep; + CurrentValue += addAmount; + returnCurrent = CurrentValue; + + // The desired value reduces to zero when also reduces the difference with current. + float decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep; + TargetValue *= (1f - decayFactor); + + Vector3 frictionFactor = (Vector3.One / CurrentValueReductionTimescale) * timeStep; + CurrentValue *= (Vector3.One - frictionFactor); + + MDetailLog("{0},BSVMotor.Step,nonZero,curr={1},target={2},add={3},decay={4},frict={5},ret={6}", + BSScene.DetailLogZero, TargetValue, CurrentValue, + addAmount, decayFactor, frictionFactor, returnCurrent); + } + else + { + // Difference between what we have and target is small. Motor is done. + CurrentValue = Vector3.Zero; + TargetValue = Vector3.Zero; + + MDetailLog("{0},BSVMotor.Step,zero,curr={1},target={2},ret={3}", + BSScene.DetailLogZero, TargetValue, CurrentValue, returnCurrent); + + } + return returnCurrent; + } +} + +public class BSFMotor : BSMotor +{ + public float TimeScale { get; set; } + public float DecayTimeScale { get; set; } + public float Friction { get; set; } + public float Efficiency { get; set; } + + public float Target { get; private set; } + public float CurrentValue { get; private set; } + + BSFMotor(float timeScale, float decayTimescale, float friction, float efficiency) : base() + { + } + public void SetCurrent(float target) + { + } + public void SetTarget(float target) + { + } + public float Step(float timeStep) + { + return 0f; + } +} +public class BSPIDMotor : BSMotor +{ + // TODO: write and use this one + BSPIDMotor() : base() + { + } +} +} -- cgit v1.1 From 9a424059446fadb80c2700ece273905ebe5a2b5a Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 24 Nov 2012 20:11:38 -0800 Subject: BulletSim: small change to add position correction force with AddForce rather than just storing it in the variable --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 29 ++++++++++++++-------- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 9 +++---- 2 files changed, 22 insertions(+), 16 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index dbc9039..a121c3d 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -518,13 +518,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin { if (IsActive) { + VDetailLog("{0},BSDynamics.Refresh", Prim.LocalID); + m_vehicleMass = Prim.Linkset.LinksetMass; + // Friction effects are handled by this vehicle code BulletSimAPI.SetFriction2(Prim.PhysBody.ptr, 0f); BulletSimAPI.SetHitFraction2(Prim.PhysBody.ptr, 0f); - // BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, 0.8f); + BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, 0.8f); + + BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, new Vector3(1f, 1f, 1f)); + - VDetailLog("{0},BSDynamics.Refresh,zeroingFriction and adding damping", Prim.LocalID); } } @@ -560,8 +565,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin // m_lastLinearVelocityVector = Prim.ForceVelocity * Quaternion.Inverse(Prim.ForceOrientation); // DEBUG: // END DEBUG - m_vehicleMass = Prim.Linkset.LinksetMass; - MoveLinear(pTimestep); // Commented out for debug MoveAngular(pTimestep); @@ -650,6 +653,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // if (rotatedSize.Z < terrainHeight) if (pos.Z < terrainHeight) { + // TODO: correct position by applying force rather than forcing position. pos.Z = terrainHeight + 2; Prim.ForcePosition = pos; VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, terrainHeight, pos); @@ -810,9 +814,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin private void MoveAngular(float pTimestep) { // m_angularMotorDirection // angular velocity requested by LSL motor - // m_angularMotorApply // application frame counter // m_angularMotorVelocity // current angular motor velocity (ramps up and down) - // m_angularMotorTimescale // motor angular velocity ramp up rate + // m_angularMotorTimescale // motor angular velocity ramp up time // m_angularMotorDecayTimescale // motor angular velocity decay rate // m_angularFrictionTimescale // body angular velocity decay rate // m_lastAngularVelocity // what was last applied to body @@ -847,7 +850,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { float VAservo = pTimestep * 0.2f / m_verticalAttractionTimescale; if (Prim.IsColliding) - VAservo = pTimestep * 0.05f / (m_verticalAttractionTimescale); + VAservo = pTimestep * 0.05f / m_verticalAttractionTimescale; VAservo *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); @@ -925,6 +928,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin float mix = Math.Abs(m_bankingMix); if (m_angularMotorVelocity.X == 0) { + // The vehicle is stopped /*if (!parent.Orientation.ApproxEquals(this.m_referenceFrame, 0.25f)) { Vector3 axisAngle; @@ -938,9 +942,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin }*/ } else - banking.Z += (effSquared*(mult*mix))*(m_angularMotorVelocity.X) * 4; + { + banking.Z += (effSquared * (mult * mix)) * (m_angularMotorVelocity.X) * 4; + } + + //If they are colliding, we probably shouldn't shove the prim around... probably if (!Prim.IsColliding && Math.Abs(m_angularMotorVelocity.X) > mix) - //If they are colliding, we probably shouldn't shove the prim around... probably { float angVelZ = m_angularMotorVelocity.X*-1; /*if(angVelZ > mix) @@ -957,8 +964,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin banking += bankingRot; } m_angularMotorVelocity.X *= m_bankingEfficiency == 1 ? 0.0f : 1 - m_bankingEfficiency; - VDetailLog("{0},MoveAngular,Banking,bEff={1},angMotVel={2},banking={3}", - Prim.LocalID, m_bankingEfficiency, m_angularMotorVelocity, banking); + VDetailLog("{0},MoveAngular,Banking,bEff={1},angMotVel={2},effSq={3},mult={4},mix={5},banking={6}", + Prim.LocalID, m_bankingEfficiency, m_angularMotorVelocity, effSquared, mult, mix, banking); } #endregion diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 2b3fa25..caa6c46 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -342,13 +342,12 @@ public sealed class BSPrim : BSPhysObject // TODO: check for out of bounds // The above code computes a force to apply to correct any out-of-bounds problems. Apply same. + // TODO: This should be intergrated with a geneal physics action mechanism. + // TODO: This should be moderated with PID'ness. if (ret) { - PhysicsScene.TaintedObject(inTaintTime, "BSPrim.PositionSanityCheck:belowTerrain", delegate() - { - // Apply upforce and overcome gravity. - ForceVelocity = ForceVelocity + upForce - PhysicsScene.DefaultGravity; - }); + // Apply upforce and overcome gravity. + AddForce(upForce - PhysicsScene.DefaultGravity, false, inTaintTime); } return ret; } -- cgit v1.1 From 980edabc2e9c3563a27f76bc6d8dcc88a59568a1 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 24 Nov 2012 20:15:07 -0800 Subject: BulletSim: clean up TODO list. It is kept somewhere wlse that should be more public. Add error logging for the detail log writer so a message is output when it cannot write to the specified logging directory. Modify friction defaults to be closer to ODE's values. Add new collision margin and vehicle angular damping parameters. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 33 +++++++++++----------- 2 files changed, 17 insertions(+), 18 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index a121c3d..7fd7b82 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -525,7 +525,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin BulletSimAPI.SetFriction2(Prim.PhysBody.ptr, 0f); BulletSimAPI.SetHitFraction2(Prim.PhysBody.ptr, 0f); - BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, 0.8f); + BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, PhysicsScene.Params.vehicleAngularDamping); BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, new Vector3(1f, 1f, 1f)); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 37bdb84..333247f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -39,23 +39,10 @@ using log4net; using OpenMetaverse; // TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim) -// Test sculpties (verified that they don't work) -// Compute physics FPS reasonably // Based on material, set density and friction -// Don't use constraints in linksets of non-physical objects. Means having to move children manually. -// Four states of prim: Physical, regular, phantom and selected. Are we modeling these correctly? -// In SL one can set both physical and phantom (gravity, does not effect others, makes collisions with ground) -// At the moment, physical and phantom causes object to drop through the terrain -// Physical phantom objects and related typing (collision options ) -// Check out llVolumeDetect. Must do something for that. -// Use collision masks for collision with terrain and phantom objects // More efficient memory usage when passing hull information from BSPrim to BulletSim -// Should prim.link() and prim.delink() membership checking happen at taint time? -// Mesh sharing. Use meshHash to tell if we already have a hull of that shape and only create once. // Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect // Implement LockAngularMotion -// Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation) -// Remove mesh and Hull stuff. Use mesh passed to bullet and use convexdecom from bullet. // Add PID movement operations. What does ScenePresence.MoveToTarget do? // Check terrain size. 128 or 127? // Raycast @@ -234,6 +221,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters if (m_physicsLoggingEnabled) { PhysicsLogging = new Logging.LogWriter(m_physicsLoggingDir, m_physicsLoggingPrefix, m_physicsLoggingFileMinutes); + PhysicsLogging.ErrorLogger = m_log; // for DEBUG. Let's the logger output error messages. } else { @@ -1076,7 +1064,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters (s,p,l,v) => { s.PID_P = v; } ), new ParameterDefn("DefaultFriction", "Friction factor used on new objects", - 0.5f, + 0.2f, (s,cf,p,v) => { s.m_params[0].defaultFriction = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].defaultFriction; }, (s,p,l,v) => { s.m_params[0].defaultFriction = v; } ), @@ -1091,7 +1079,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters (s) => { return s.m_params[0].defaultRestitution; }, (s,p,l,v) => { s.m_params[0].defaultRestitution = v; } ), new ParameterDefn("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!)", - 0f, + 0.04f, (s,cf,p,v) => { s.m_params[0].collisionMargin = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].collisionMargin; }, (s,p,l,v) => { s.m_params[0].collisionMargin = v; } ), @@ -1158,7 +1146,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters (s) => { return s.m_params[0].terrainImplementation; }, (s,p,l,v) => { s.m_params[0].terrainImplementation = v; } ), new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" , - 0.5f, + 0.3f, (s,cf,p,v) => { s.m_params[0].terrainFriction = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].terrainFriction; }, (s,p,l,v) => { s.m_params[0].terrainFriction = v; /* TODO: set on real terrain */} ), @@ -1172,13 +1160,19 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters (s,cf,p,v) => { s.m_params[0].terrainRestitution = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].terrainRestitution; }, (s,p,l,v) => { s.m_params[0].terrainRestitution = v; /* TODO: set on real terrain */ } ), + new ParameterDefn("TerrainCollisionMargin", "Margin where collision checking starts" , + 0.04f, + (s,cf,p,v) => { s.m_params[0].terrainCollisionMargin = cf.GetFloat(p, v); }, + (s) => { return s.m_params[0].terrainCollisionMargin; }, + (s,p,l,v) => { s.m_params[0].terrainCollisionMargin = v; /* TODO: set on real terrain */ } ), + new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.", 0.2f, (s,cf,p,v) => { s.m_params[0].avatarFriction = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].avatarFriction; }, (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarFriction, p, l, v); } ), new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", - 10f, + 0.99f, (s,cf,p,v) => { s.m_params[0].avatarStandingFriction = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].avatarStandingFriction; }, (s,p,l,v) => { s.m_params[0].avatarStandingFriction = v; } ), @@ -1213,6 +1207,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters (s) => { return s.m_params[0].avatarContactProcessingThreshold; }, (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ), + new ParameterDefn("vehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", + 0.8f, + (s,cf,p,v) => { s.m_params[0].vehicleAngularDamping = cf.GetFloat(p, v); }, + (s) => { return s.m_params[0].vehicleAngularDamping; }, + (s,p,l,v) => { s.m_params[0].vehicleAngularDamping = v; } ), new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", 0f, -- cgit v1.1 From 319ec3235c69bb207fe04415feb8bc9f90601f37 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 25 Nov 2012 17:41:15 -0800 Subject: BulletSim: add BSVMotor as BSDynamics linear motor. Properly limit *_MOTOR_DECAY_TIMESCALE to 120 as per specs. Invode BSDynamics.Refresh() when vehicle type is changed. Previously the vehicle properties weren't getting set because the physical properties were set before the vehicle type was set. Add a "use name" to BSMotors for identification while debugging. Correct current and target confusion in BSVMotor design. Rename CurrentValueReductionTimescale to FrictionTimescale. Event more detailed logging. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 55 +++++++++++++++++----- OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 46 ++++++++++++------ 2 files changed, 74 insertions(+), 27 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 7fd7b82..bf8a004 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -80,6 +80,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin private Quaternion m_referenceFrame = Quaternion.Identity; // Linear properties + private BSVMotor m_linearMotor = new BSVMotor("LinearMotor"); private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time private Vector3 m_linearMotorOffset = Vector3.Zero; // the point of force can be offset from the center private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL @@ -152,7 +153,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_angularDeflectionTimescale = Math.Max(pValue, 0.01f); break; case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE: - m_angularMotorDecayTimescale = Math.Max(pValue, 0.01f); + m_angularMotorDecayTimescale = Math.Max(0.01f, Math.Min(pValue,120)); break; case Vehicle.ANGULAR_MOTOR_TIMESCALE: m_angularMotorTimescale = Math.Max(pValue, 0.01f); @@ -185,10 +186,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_linearDeflectionTimescale = Math.Max(pValue, 0.01f); break; case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE: - m_linearMotorDecayTimescale = Math.Max(pValue, 0.01f); + m_linearMotorDecayTimescale = Math.Max(0.01f, Math.Min(pValue,120)); + m_linearMotor.TargetValueDecayTimeScale = m_linearMotorDecayTimescale; break; case Vehicle.LINEAR_MOTOR_TIMESCALE: m_linearMotorTimescale = Math.Max(pValue, 0.01f); + m_linearMotor.TimeScale = m_linearMotorTimescale; break; case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: m_verticalAttractionEfficiency = Math.Max(0.1f, Math.Min(pValue, 1f)); @@ -208,10 +211,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin break; case Vehicle.LINEAR_FRICTION_TIMESCALE: m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue); + m_linearMotor.FrictionTimescale = m_linearFrictionTimescale; break; case Vehicle.LINEAR_MOTOR_DIRECTION: m_linearMotorDirection = new Vector3(pValue, pValue, pValue); m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue); + m_linearMotor.SetTarget(m_linearMotorDirection); break; case Vehicle.LINEAR_MOTOR_OFFSET: m_linearMotorOffset = new Vector3(pValue, pValue, pValue); @@ -238,10 +243,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin break; case Vehicle.LINEAR_FRICTION_TIMESCALE: m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); + m_linearMotor.FrictionTimescale = m_linearFrictionTimescale; break; case Vehicle.LINEAR_MOTOR_DIRECTION: m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z); + m_linearMotor.SetTarget(m_linearMotorDirection); break; case Vehicle.LINEAR_MOTOR_OFFSET: m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); @@ -319,6 +326,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_referenceFrame = Quaternion.Identity; m_flags = (VehicleFlag)0; + break; case Vehicle.TYPE_SLED: @@ -510,6 +518,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin | VehicleFlag.HOVER_GLOBAL_HEIGHT); break; } + + // Update any physical parameters based on this type. + Refresh(); + + m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale, m_linearMotorDecayTimescale, m_linearFrictionTimescale, 1f); + m_linearMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) } // Some of the properties of this prim may have changed. @@ -518,18 +532,25 @@ namespace OpenSim.Region.Physics.BulletSPlugin { if (IsActive) { - VDetailLog("{0},BSDynamics.Refresh", Prim.LocalID); m_vehicleMass = Prim.Linkset.LinksetMass; // Friction effects are handled by this vehicle code - BulletSimAPI.SetFriction2(Prim.PhysBody.ptr, 0f); - BulletSimAPI.SetHitFraction2(Prim.PhysBody.ptr, 0f); - - BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, PhysicsScene.Params.vehicleAngularDamping); - - BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, new Vector3(1f, 1f, 1f)); - - + float friction = 0f; + BulletSimAPI.SetFriction2(Prim.PhysBody.ptr, friction); + + // Moderate angular movement introduced by Bullet. + // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle. + // Maybe compute linear and angular factor and damping from params. + float angularDamping = PhysicsScene.Params.vehicleAngularDamping; + BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, angularDamping); + + // DEBUG DEBUG DEBUG: use uniform inertia to smooth movement added by Bullet + // Vector3 localInertia = new Vector3(1f, 1f, 1f); + Vector3 localInertia = new Vector3(m_vehicleMass, m_vehicleMass, m_vehicleMass); + BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia); + + VDetailLog("{0},BSDynamics.Refresh,frict={1},inert={2},aDamp={3}", + Prim.LocalID, friction, localInertia, angularDamping); } } @@ -591,6 +612,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Also does hover and float. private void MoveLinear(float pTimestep) { + /* // m_linearMotorDirection is the target direction we are moving relative to the vehicle coordinates // m_lastLinearVelocityVector is the current speed we are moving in that direction if (m_linearMotorDirection.LengthSquared() > 0.001f) @@ -627,6 +649,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin VDetailLog("{0},MoveLinear,zeroed", Prim.LocalID); } + */ + + m_newVelocity = m_linearMotor.Step(pTimestep); + + // Rotate new object velocity from vehicle relative to world coordinates + m_newVelocity *= Prim.ForceOrientation; // m_newVelocity is velocity computed from linear motor in world coordinates @@ -785,12 +813,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_newVelocity.Z = 0; // Clamp REALLY high or low velocities - if (m_newVelocity.LengthSquared() > 1e6f) + float newVelocityLengthSq = m_newVelocity.LengthSquared(); + if (newVelocityLengthSq > 1e6f) { m_newVelocity /= m_newVelocity.Length(); m_newVelocity *= 1000f; } - else if (m_newVelocity.LengthSquared() < 1e-6f) + else if (newVelocityLengthSq < 1e-6f) m_newVelocity = Vector3.Zero; // Stuff new linear velocity into the vehicle diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index b8bdd87..68eec2d 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -7,13 +7,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin { public abstract class BSMotor { - public BSMotor() + public BSMotor(string useName) { + UseName = useName; PhysicsScene = null; } public virtual void Reset() { } public virtual void Zero() { } + public string UseName { get; private set; } // Used only for outputting debug information. Might not be set so check for null. public BSScene PhysicsScene { get; set; } protected void MDetailLog(string msg, params Object[] parms) @@ -35,17 +37,25 @@ public class BSVMotor : BSMotor public float TimeScale { get; set; } public float TargetValueDecayTimeScale { get; set; } - public Vector3 CurrentValueReductionTimescale { get; set; } + public Vector3 FrictionTimescale { get; set; } public float Efficiency { get; set; } public Vector3 TargetValue { get; private set; } public Vector3 CurrentValue { get; private set; } - BSVMotor(float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency) : base() + public BSVMotor(string useName) + : base(useName) + { + TimeScale = TargetValueDecayTimeScale = Efficiency = 1f; + FrictionTimescale = Vector3.Zero; + CurrentValue = TargetValue = Vector3.Zero; + } + public BSVMotor(string useName, float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency) + : this(useName) { TimeScale = timeScale; TargetValueDecayTimeScale = decayTimeScale; - CurrentValueReductionTimescale = frictionTimeScale; + FrictionTimescale = frictionTimeScale; Efficiency = efficiency; CurrentValue = TargetValue = Vector3.Zero; } @@ -60,10 +70,10 @@ public class BSVMotor : BSMotor public Vector3 Step(float timeStep) { Vector3 returnCurrent = Vector3.Zero; - if (CurrentValue.LengthSquared() > 0.001f) + if (!CurrentValue.ApproxEquals(TargetValue, 0.01f)) { - // Vector3 origDir = Target; // DEBUG - // Vector3 origVel = CurrentValue; // DEBUG + Vector3 origTarget = TargetValue; // DEBUG + Vector3 origCurrVal = CurrentValue; // DEBUG // Add (desiredVector - currentAppliedVector) / howLongItShouldTakeToComplete Vector3 addAmount = (TargetValue - CurrentValue)/TimeScale * timeStep; @@ -74,11 +84,17 @@ public class BSVMotor : BSMotor float decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep; TargetValue *= (1f - decayFactor); - Vector3 frictionFactor = (Vector3.One / CurrentValueReductionTimescale) * timeStep; + Vector3 frictionFactor = Vector3.Zero; + frictionFactor = (Vector3.One / FrictionTimescale) * timeStep; CurrentValue *= (Vector3.One - frictionFactor); - MDetailLog("{0},BSVMotor.Step,nonZero,curr={1},target={2},add={3},decay={4},frict={5},ret={6}", - BSScene.DetailLogZero, TargetValue, CurrentValue, + MDetailLog("{0},BSVMotor.Step,nonZero,{1},origTarget={2},origCurr={3},timeStep={4},timeScale={5},addAmnt={6},targetDecay={7},decayFact={8},fricTS={9},frictFact={10}", + BSScene.DetailLogZero, UseName, origTarget, origCurrVal, + timeStep, TimeScale, addAmount, + TargetValueDecayTimeScale, decayFactor, + FrictionTimescale, frictionFactor); + MDetailLog("{0},BSVMotor.Step,nonZero,{1},curr={2},target={3},add={4},decay={5},frict={6},ret={7}", + BSScene.DetailLogZero, UseName, TargetValue, CurrentValue, addAmount, decayFactor, frictionFactor, returnCurrent); } else @@ -87,8 +103,8 @@ public class BSVMotor : BSMotor CurrentValue = Vector3.Zero; TargetValue = Vector3.Zero; - MDetailLog("{0},BSVMotor.Step,zero,curr={1},target={2},ret={3}", - BSScene.DetailLogZero, TargetValue, CurrentValue, returnCurrent); + MDetailLog("{0},BSVMotor.Step,zero,{1},curr={2},target={3},ret={4}", + BSScene.DetailLogZero, UseName, TargetValue, CurrentValue, returnCurrent); } return returnCurrent; @@ -105,7 +121,8 @@ public class BSFMotor : BSMotor public float Target { get; private set; } public float CurrentValue { get; private set; } - BSFMotor(float timeScale, float decayTimescale, float friction, float efficiency) : base() + public BSFMotor(string useName, float timeScale, float decayTimescale, float friction, float efficiency) + : base(useName) { } public void SetCurrent(float target) @@ -122,7 +139,8 @@ public class BSFMotor : BSMotor public class BSPIDMotor : BSMotor { // TODO: write and use this one - BSPIDMotor() : base() + public BSPIDMotor(string useName) + : base(useName) { } } -- cgit v1.1 From f977131fe084b9bd431a24c27e61b59ebe88ec84 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 25 Nov 2012 19:05:42 -0800 Subject: BulletSim: add ToString override to BSVMotor. --- OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index 68eec2d..480da2c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -75,7 +75,7 @@ public class BSVMotor : BSMotor Vector3 origTarget = TargetValue; // DEBUG Vector3 origCurrVal = CurrentValue; // DEBUG - // Add (desiredVector - currentAppliedVector) / howLongItShouldTakeToComplete + // Addition = (desiredVector - currentAppliedVector) / secondsItShouldTakeToComplete Vector3 addAmount = (TargetValue - CurrentValue)/TimeScale * timeStep; CurrentValue += addAmount; returnCurrent = CurrentValue; @@ -109,6 +109,11 @@ public class BSVMotor : BSMotor } return returnCurrent; } + public override string ToString() + { + return String.Format("<{0},curr={1},targ={2},decayTS={3},frictTS={4}>", + UseName, CurrentValue, TargetValue, TargetValueDecayTimeScale, FrictionTimescale); + } } public class BSFMotor : BSMotor -- cgit v1.1 From 4c077a06947fe879fb02849f7ed7c4ec5358366f Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 25 Nov 2012 19:06:53 -0800 Subject: BulletSim: organize MoveLinear code for understandability. Make LIMIT_MOTOR_UP contribution a velocity and not a force. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 129 +++++++-------------- 1 file changed, 40 insertions(+), 89 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index bf8a004..7757584 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -84,7 +84,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time private Vector3 m_linearMotorOffset = Vector3.Zero; // the point of force can be offset from the center private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL - private Vector3 m_newVelocity = Vector3.Zero; // velocity computed to be applied to body private Vector3 m_linearFrictionTimescale = Vector3.Zero; private float m_linearMotorDecayTimescale = 0; private float m_linearMotorTimescale = 0; @@ -577,15 +576,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin { if (!IsActive) return; - // DEBUG - // Because Bullet does apply forces to the vehicle, our last computed - // linear and angular velocities are not what is happening now. - // Vector3 externalAngularVelocity = Prim.ForceRotationalVelocity - m_lastAngularVelocity; - // m_lastAngularVelocity += (externalAngularVelocity * 0.5f) * pTimestep; - // m_lastAngularVelocity = Prim.ForceRotationalVelocity; // DEBUG: account for what Bullet did last time - // m_lastLinearVelocityVector = Prim.ForceVelocity * Quaternion.Inverse(Prim.ForceOrientation); // DEBUG: - // END DEBUG - MoveLinear(pTimestep); // Commented out for debug MoveAngular(pTimestep); @@ -612,67 +602,22 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Also does hover and float. private void MoveLinear(float pTimestep) { - /* - // m_linearMotorDirection is the target direction we are moving relative to the vehicle coordinates - // m_lastLinearVelocityVector is the current speed we are moving in that direction - if (m_linearMotorDirection.LengthSquared() > 0.001f) - { - Vector3 origDir = m_linearMotorDirection; // DEBUG - Vector3 origVel = m_lastLinearVelocityVector; // DEBUG - // DEBUG: the vehicle velocity rotated to be relative to vehicle coordinates for comparison - Vector3 vehicleVelocity = Prim.ForceVelocity * Quaternion.Inverse(Prim.ForceOrientation); // DEBUG - - // Add (desiredVelocity - lastAppliedVelocity) / howLongItShouldTakeToComplete - Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/(m_linearMotorTimescale) * pTimestep; - m_lastLinearVelocityVector += addAmount; - - float decayFactor = (1.0f / m_linearMotorDecayTimescale) * pTimestep; - m_linearMotorDirection *= (1f - decayFactor); - - // Rotate new object velocity from vehicle relative to world coordinates - m_newVelocity = m_lastLinearVelocityVector * Prim.ForceOrientation; - - // Apply friction for next time - Vector3 frictionFactor = (Vector3.One / m_linearFrictionTimescale) * pTimestep; - m_lastLinearVelocityVector *= (Vector3.One - frictionFactor); - - VDetailLog("{0},MoveLinear,nonZero,origlmDir={1},origlvVel={2},vehVel={3},add={4},decay={5},frict={6},lmDir={7},lvVec={8},newVel={9}", - Prim.LocalID, origDir, origVel, vehicleVelocity, addAmount, decayFactor, frictionFactor, - m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity); - } - else - { - // if what remains of direction is very small, zero it. - m_linearMotorDirection = Vector3.Zero; - m_lastLinearVelocityVector = Vector3.Zero; - m_newVelocity = Vector3.Zero; - - VDetailLog("{0},MoveLinear,zeroed", Prim.LocalID); - } - */ - - m_newVelocity = m_linearMotor.Step(pTimestep); + Vector3 linearMotorContribution = m_linearMotor.Step(pTimestep); // Rotate new object velocity from vehicle relative to world coordinates - m_newVelocity *= Prim.ForceOrientation; - - // m_newVelocity is velocity computed from linear motor in world coordinates + linearMotorContribution *= Prim.ForceOrientation; + // ================================================================== // Gravity and Buoyancy // There is some gravity, make a gravity force vector that is applied after object velocity. // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy); - /* - * RA: Not sure why one would do this unless we are hoping external forces are doing gravity, ... - // Preserve the current Z velocity - Vector3 vel_now = m_prim.Velocity; - m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity - */ - + // Current vehicle position Vector3 pos = Prim.ForcePosition; -// Vector3 accel = new Vector3(-(m_dir.X - m_lastLinearVelocityVector.X / 0.1f), -(m_dir.Y - m_lastLinearVelocityVector.Y / 0.1f), m_dir.Z - m_lastLinearVelocityVector.Z / 0.1f); + // ================================================================== + Vector3 terrainHeightContribution = Vector3.Zero; // If below the terrain, move us above the ground a little. float terrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); // Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset. @@ -687,6 +632,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, terrainHeight, pos); } + // ================================================================== + Vector3 hoverContribution = Vector3.Zero; // Check if hovering // m_VhoverEfficiency: 0=bouncy, 1=totally damped // m_VhoverTimescale: time to achieve height @@ -726,24 +673,22 @@ namespace OpenSim.Region.Physics.BulletSPlugin // RA: where does the 50 come from? float verticalCorrectionVelocity = pTimestep * ((verticalError * 50.0f) / m_VhoverTimescale); // Replace Vertical speed with correction figure if significant - if (Math.Abs(verticalError) > 0.01f) + if (verticalError > 0.01f) { - m_newVelocity.Z += verticalCorrectionVelocity; + hoverContribution = new Vector3(0f, 0f, verticalCorrectionVelocity); //KF: m_VhoverEfficiency is not yet implemented } else if (verticalError < -0.01) { - m_newVelocity.Z -= verticalCorrectionVelocity; - } - else - { - m_newVelocity.Z = 0f; + hoverContribution = new Vector3(0f, 0f, -verticalCorrectionVelocity); } } - VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", Prim.LocalID, pos, m_newVelocity, m_VhoverHeight, m_VhoverTargetHeight); + VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", + Prim.LocalID, pos, hoverContribution, m_VhoverHeight, m_VhoverTargetHeight); } + // ================================================================== Vector3 posChange = pos - m_lastPositionVector; if (m_BlockingEndPoint != Vector3.Zero) { @@ -781,60 +726,66 @@ namespace OpenSim.Region.Physics.BulletSPlugin } } - #region downForce - Vector3 downForce = Vector3.Zero; - + // ================================================================== + Vector3 limitMotorUpContribution = Vector3.Zero; if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) { // If the vehicle is motoring into the sky, get it going back down. - // Is this an angular force or both linear and angular?? float distanceAboveGround = pos.Z - terrainHeight; - if (distanceAboveGround > 2f) + if (distanceAboveGround > 1f) { // downForce = new Vector3(0, 0, (-distanceAboveGround / m_bankingTimescale) * pTimestep); // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); - downForce = new Vector3(0, 0, -distanceAboveGround); + limitMotorUpContribution = new Vector3(0, 0, -distanceAboveGround); } // TODO: this calculation is all wrong. From the description at // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce // has a decay factor. This says this force should // be computed with a motor. VDetailLog("{0},MoveLinear,limitMotorUp,distAbove={1},downForce={2}", - Prim.LocalID, distanceAboveGround, downForce); + Prim.LocalID, distanceAboveGround, limitMotorUpContribution); } - #endregion // downForce + + // ================================================================== + Vector3 newVelocity = linearMotorContribution + + terrainHeightContribution + + hoverContribution + + limitMotorUpContribution; // If not changing some axis, reduce out velocity if ((m_flags & (VehicleFlag.NO_X)) != 0) - m_newVelocity.X = 0; + newVelocity.X = 0; if ((m_flags & (VehicleFlag.NO_Y)) != 0) - m_newVelocity.Y = 0; + newVelocity.Y = 0; if ((m_flags & (VehicleFlag.NO_Z)) != 0) - m_newVelocity.Z = 0; + newVelocity.Z = 0; + // ================================================================== // Clamp REALLY high or low velocities - float newVelocityLengthSq = m_newVelocity.LengthSquared(); + float newVelocityLengthSq = newVelocity.LengthSquared(); if (newVelocityLengthSq > 1e6f) { - m_newVelocity /= m_newVelocity.Length(); - m_newVelocity *= 1000f; + newVelocity /= newVelocity.Length(); + newVelocity *= 1000f; } else if (newVelocityLengthSq < 1e-6f) - m_newVelocity = Vector3.Zero; + newVelocity = Vector3.Zero; + // ================================================================== // Stuff new linear velocity into the vehicle - Prim.ForceVelocity = m_newVelocity; + Prim.ForceVelocity = newVelocity; // Prim.ApplyForceImpulse((m_newVelocity - Prim.Velocity) * m_vehicleMass, false); // DEBUG DEBUG - Vector3 totalDownForce = downForce + grav; + // Other linear forces are applied as forces. + Vector3 totalDownForce = grav * m_vehicleMass; if (totalDownForce != Vector3.Zero) { - Prim.AddForce(totalDownForce * m_vehicleMass, false); - // Prim.ApplyForceImpulse(totalDownForce * m_vehicleMass, false); + Prim.AddForce(totalDownForce, false); } VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},primVel={4},totalDown={5}", - Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity, Prim.Velocity, totalDownForce); + Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, + newVelocity, Prim.Velocity, totalDownForce); } // end MoveLinear() -- cgit v1.1 From d7126a14e15958b00f8ea33b34253f88b1c341c5 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 25 Nov 2012 20:02:19 -0800 Subject: BulletSim: up the vehicle angular damping to 0.95. Still trying to overcome the movement added by Bullet. --- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 333247f..805e670 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -1207,8 +1207,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters (s) => { return s.m_params[0].avatarContactProcessingThreshold; }, (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ), - new ParameterDefn("vehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", - 0.8f, + new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", + 0.95f, (s,cf,p,v) => { s.m_params[0].vehicleAngularDamping = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].vehicleAngularDamping; }, (s,p,l,v) => { s.m_params[0].vehicleAngularDamping = v; } ), -- cgit v1.1 From 084e3926ca4c344279935f1bce3173c8f6e8258a Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 25 Nov 2012 20:03:36 -0800 Subject: BulletSim: use m_angularMotor to do the basic movement. Add the setting of same. Rename the angular forces and add comments to match MoveAngular to the form of MoveLinear. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 124 +++++++++++---------- 1 file changed, 64 insertions(+), 60 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 7757584..95a4134 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -93,6 +93,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // private Vector3 m_linearMotorOffset = Vector3.Zero; //Angular properties + private BSVMotor m_angularMotor = new BSVMotor("AngularMotor"); private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor // private int m_angularMotorApply = 0; // application frame counter private Vector3 m_angularMotorVelocity = Vector3.Zero; // current angular motor velocity @@ -153,9 +154,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin break; case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE: m_angularMotorDecayTimescale = Math.Max(0.01f, Math.Min(pValue,120)); + m_angularMotor.TargetValueDecayTimeScale = m_angularMotorDecayTimescale; break; case Vehicle.ANGULAR_MOTOR_TIMESCALE: m_angularMotorTimescale = Math.Max(pValue, 0.01f); + m_angularMotor.TimeScale = m_angularMotorTimescale; break; case Vehicle.BANKING_EFFICIENCY: m_bankingEfficiency = Math.Max(-1f, Math.Min(pValue, 1f)); @@ -203,10 +206,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin // set all of the components to the same value case Vehicle.ANGULAR_FRICTION_TIMESCALE: m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue); + m_angularMotor.FrictionTimescale = m_angularFrictionTimescale; break; case Vehicle.ANGULAR_MOTOR_DIRECTION: m_angularMotorDirection = new Vector3(pValue, pValue, pValue); - // m_angularMotorApply = 100; + m_angularMotor.SetTarget(m_angularMotorDirection); break; case Vehicle.LINEAR_FRICTION_TIMESCALE: m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue); @@ -231,6 +235,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { case Vehicle.ANGULAR_FRICTION_TIMESCALE: m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); + m_angularMotor.FrictionTimescale = m_angularFrictionTimescale; break; case Vehicle.ANGULAR_MOTOR_DIRECTION: // Limit requested angular speed to 2 rps= 4 pi rads/sec @@ -238,7 +243,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin pValue.Y = Math.Max(-12.56f, Math.Min(pValue.Y, 12.56f)); pValue.Z = Math.Max(-12.56f, Math.Min(pValue.Z, 12.56f)); m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); - // m_angularMotorApply = 100; + m_angularMotor.SetTarget(m_angularMotorDirection); break; case Vehicle.LINEAR_FRICTION_TIMESCALE: m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); @@ -358,10 +363,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingMix = 1; m_referenceFrame = Quaternion.Identity; - m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP); - m_flags &= - ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | - VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); + m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY + | VehicleFlag.HOVER_TERRAIN_ONLY + | VehicleFlag.HOVER_GLOBAL_HEIGHT + | VehicleFlag.HOVER_UP_ONLY); + m_flags |= (VehicleFlag.NO_DEFLECTION_UP + | VehicleFlag.LIMIT_ROLL_ONLY + | VehicleFlag.LIMIT_MOTOR_UP); break; case Vehicle.TYPE_CAR: m_linearMotorDirection = Vector3.Zero; @@ -521,8 +529,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Update any physical parameters based on this type. Refresh(); - m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale, m_linearMotorDecayTimescale, m_linearFrictionTimescale, 1f); + m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale, + m_linearMotorDecayTimescale, m_linearFrictionTimescale, 1f); m_linearMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) + m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale, + m_angularMotorDecayTimescale, m_angularFrictionTimescale, 1f); + m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) + + // m_bankingMotor = new BSVMotor("BankingMotor", ...); } // Some of the properties of this prim may have changed. @@ -577,26 +591,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (!IsActive) return; MoveLinear(pTimestep); - // Commented out for debug MoveAngular(pTimestep); - // Prim.ApplyTorqueImpulse(-Prim.RotationalVelocity * m_vehicleMass, false); // DEBUG DEBUG - // Prim.ForceRotationalVelocity = -Prim.RotationalVelocity; // DEBUG DEBUG LimitRotation(pTimestep); // remember the position so next step we can limit absolute movement effects m_lastPositionVector = Prim.ForcePosition; - VDetailLog("{0},BSDynamics.Step,frict={1},grav={2},inertia={3},mass={4}", // DEBUG DEBUG - Prim.LocalID, - BulletSimAPI.GetFriction2(Prim.PhysBody.ptr), - BulletSimAPI.GetGravity2(Prim.PhysBody.ptr), - Prim.Inertia, - m_vehicleMass - ); VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", Prim.LocalID, Prim.ForcePosition, Prim.Force, Prim.ForceVelocity, Prim.RotationalVelocity); - }// end Step + } // Apply the effect of the linear motor. // Also does hover and float. @@ -790,6 +794,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin } // end MoveLinear() // ======================================================================= + // ======================================================================= // Apply the effect of the angular motor. private void MoveAngular(float pTimestep) { @@ -819,12 +824,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_angularMotorVelocity = Vector3.Zero; } - #region Vertical attactor - - Vector3 vertattr = Vector3.Zero; - Vector3 deflection = Vector3.Zero; - Vector3 banking = Vector3.Zero; + Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); + // ================================================================== + Vector3 verticalAttractionContribution = Vector3.Zero; // If vertical attaction timescale is reasonable and we applied an angular force last time... if (m_verticalAttractionTimescale < 300 && m_lastAngularVelocity != Vector3.Zero) { @@ -854,24 +857,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin // As the body rotates around the X axis, then verticalError.Y increases; Rotated around Y // then .X increases, so change Body angular velocity X based on Y, and Y based on X. // Z is not changed. - vertattr.X = verticalError.Y; - vertattr.Y = - verticalError.X; - vertattr.Z = 0f; + verticalAttractionContribution.X = verticalError.Y; + verticalAttractionContribution.Y = - verticalError.X; + verticalAttractionContribution.Z = 0f; // scaling appears better usingsquare-law Vector3 angularVelocity = Prim.ForceRotationalVelocity; float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); - vertattr.X += bounce * angularVelocity.X; - vertattr.Y += bounce * angularVelocity.Y; + verticalAttractionContribution.X += bounce * angularVelocity.X; + verticalAttractionContribution.Y += bounce * angularVelocity.Y; VDetailLog("{0},MoveAngular,verticalAttraction,VAservo={1},effic={2},verticalError={3},bounce={4},vertattr={5}", - Prim.LocalID, VAservo, m_verticalAttractionEfficiency, verticalError, bounce, vertattr); + Prim.LocalID, VAservo, m_verticalAttractionEfficiency, verticalError, bounce, verticalAttractionContribution); } - #endregion // Vertical attactor - - #region Deflection + // ================================================================== + Vector3 deflectionContribution = Vector3.Zero; if (m_angularDeflectionEfficiency != 0) { // Compute a scaled vector that points in the preferred axis (X direction) @@ -882,18 +884,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 preferredAxisOfMotion = scaledDefaultDirection * Quaternion.Add(Prim.ForceOrientation, m_referenceFrame); // Scale by efficiency and timescale - deflection = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep; + deflectionContribution = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep; VDetailLog("{0},MoveAngular,Deflection,perfAxis={1},deflection={2}", - Prim.LocalID, preferredAxisOfMotion, deflection); + Prim.LocalID, preferredAxisOfMotion, deflectionContribution); // This deflection computation is not correct. - deflection = Vector3.Zero; + deflectionContribution = Vector3.Zero; } - #endregion - - #region Banking - + // ================================================================== + Vector3 bankingContribution = Vector3.Zero; if (m_bankingEfficiency != 0) { Vector3 dir = Vector3.One * Prim.ForceOrientation; @@ -923,7 +923,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin } else { - banking.Z += (effSquared * (mult * mix)) * (m_angularMotorVelocity.X) * 4; + bankingContribution.Z += (effSquared * (mult * mix)) * (m_angularMotorVelocity.X) * 4; } //If they are colliding, we probably shouldn't shove the prim around... probably @@ -941,22 +941,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin else if (bankingRot.X < -3) bankingRot.X = -3; bankingRot *= Prim.ForceOrientation; - banking += bankingRot; + bankingContribution += bankingRot; } m_angularMotorVelocity.X *= m_bankingEfficiency == 1 ? 0.0f : 1 - m_bankingEfficiency; VDetailLog("{0},MoveAngular,Banking,bEff={1},angMotVel={2},effSq={3},mult={4},mix={5},banking={6}", - Prim.LocalID, m_bankingEfficiency, m_angularMotorVelocity, effSquared, mult, mix, banking); + Prim.LocalID, m_bankingEfficiency, m_angularMotorVelocity, effSquared, mult, mix, bankingContribution); } - #endregion - - m_lastVertAttractor = vertattr; + // ================================================================== + m_lastVertAttractor = verticalAttractionContribution; // Sum velocities - m_lastAngularVelocity = m_angularMotorVelocity + vertattr + banking + deflection; - - #region Linear Motor Offset + m_lastAngularVelocity = angularMotorContribution + + verticalAttractionContribution + + bankingContribution + + deflectionContribution; + // ================================================================== //Offset section if (m_linearMotorOffset != Vector3.Zero) { @@ -972,8 +973,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin // // The torque created is the linear velocity crossed with the offset - // NOTE: this computation does should be in the linear section - // because there we know the impulse being applied. + // TODO: this computation should be in the linear section + // because that is where we know the impulse being applied. Vector3 torqueFromOffset = Vector3.Zero; // torqueFromOffset = Vector3.Cross(m_linearMotorOffset, appliedImpulse); if (float.IsNaN(torqueFromOffset.X)) @@ -987,8 +988,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin VDetailLog("{0},BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset); } - #endregion - + // ================================================================== + // NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) { m_lastAngularVelocity.X = 0; @@ -996,6 +997,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin VDetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); } + // ================================================================== if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) { m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. @@ -1008,18 +1010,20 @@ namespace OpenSim.Region.Physics.BulletSPlugin // The above calculates the absolute angular velocity needed. Angular velocity is massless. // Since we are stuffing the angular velocity directly into the object, the computed // velocity needs to be scaled by the timestep. - Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep) - Prim.ForceRotationalVelocity); + // Also remove any motion that is on the object so added motion is only from vehicle. + Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep) + - Prim.ForceRotationalVelocity); Prim.ForceRotationalVelocity = applyAngularForce; - // Decay the angular movement for next time - Vector3 decayamount = (Vector3.One / m_angularFrictionTimescale) * pTimestep; - m_lastAngularVelocity *= Vector3.One - decayamount; - - VDetailLog("{0},MoveAngular,done,newRotVel={1},decay={2},lastAngular={3}", - Prim.LocalID, applyAngularForce, decayamount, m_lastAngularVelocity); + VDetailLog("{0},MoveAngular,done,newRotVel={1},lastAngular={2}", + Prim.LocalID, applyAngularForce, m_lastAngularVelocity); } - } //end MoveAngular + } + // This is from previous instantiations of XXXDynamics.cs. + // Applies roll reference frame. + // TODO: is this the right way to separate the code to do this operation? + // Should this be in MoveAngular()? internal void LimitRotation(float timestep) { Quaternion rotq = Prim.ForceOrientation; -- cgit v1.1 From 5685b33071c683c41643fcb78d6f8a28d98db468 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 26 Nov 2012 10:47:34 -0800 Subject: BulletSim: increase vehicle stability by suppressing Bullet's update to angular velocity. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 21 +++++---- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 50 +++------------------- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 12 +++--- .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 2 +- 4 files changed, 26 insertions(+), 59 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 95a4134..6ff8a48 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -805,6 +805,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // m_angularFrictionTimescale // body angular velocity decay rate // m_lastAngularVelocity // what was last applied to body + /* if (m_angularMotorDirection.LengthSquared() > 0.0001) { Vector3 origVel = m_angularMotorVelocity; @@ -823,6 +824,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { m_angularMotorVelocity = Vector3.Zero; } + */ Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); @@ -842,15 +844,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin // verticalError.X and .Y are the World error amounts. They are 0 when there is no // error (Vehicle Body is 'vertical'), and .Z will be 1. As the body leans to its // side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall - // and .Z will go // negative. Similar for tilt and |.Y|. .X and .Y must be + // and .Z will go negative. Similar for tilt and |.Y|. .X and .Y must be // modulated to prevent a stable inverted body. // Error is 0 (no error) to +/- 2 (max error) - if (verticalError.Z < 0.0f) - { - verticalError.X = 2.0f - verticalError.X; - verticalError.Y = 2.0f - verticalError.Y; - } + verticalError.X = Math.Max(-2f, Math.Min(verticalError.X, 2f)); + verticalError.Y = Math.Max(-2f, Math.Min(verticalError.Y, 2f)); + // scale it by VAservo (timestep and timescale) verticalError = verticalError * VAservo; @@ -1013,10 +1013,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Also remove any motion that is on the object so added motion is only from vehicle. Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep) - Prim.ForceRotationalVelocity); + // Unscale the force by the angular factor so it overwhelmes the Bullet additions. Prim.ForceRotationalVelocity = applyAngularForce; - VDetailLog("{0},MoveAngular,done,newRotVel={1},lastAngular={2}", - Prim.LocalID, applyAngularForce, m_lastAngularVelocity); + VDetailLog("{0},MoveAngular,done,angMotor={1},vertAttr={2},bank={3},deflect={4},newAngForce={5},lastAngular={6}", + Prim.LocalID, + angularMotorContribution, verticalAttractionContribution, + bankingContribution, deflectionContribution, + applyAngularForce, m_lastAngularVelocity + ); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index caa6c46..c62c79a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -1380,54 +1380,16 @@ public sealed class BSPrim : BSPhysObject public override void UpdateProperties(EntityProperties entprop) { - /* - UpdatedProperties changed = 0; - // assign to the local variables so the normal set action does not happen - // if (_position != entprop.Position) - if (!_position.ApproxEquals(entprop.Position, POSITION_TOLERANCE)) - { - _position = entprop.Position; - changed |= UpdatedProperties.Position; - } - // if (_orientation != entprop.Rotation) - if (!_orientation.ApproxEquals(entprop.Rotation, ROTATION_TOLERANCE)) - { - _orientation = entprop.Rotation; - changed |= UpdatedProperties.Rotation; - } - // if (_velocity != entprop.Velocity) - if (!_velocity.ApproxEquals(entprop.Velocity, VELOCITY_TOLERANCE)) - { - _velocity = entprop.Velocity; - changed |= UpdatedProperties.Velocity; - } - // if (_acceleration != entprop.Acceleration) - if (!_acceleration.ApproxEquals(entprop.Acceleration, ACCELERATION_TOLERANCE)) - { - _acceleration = entprop.Acceleration; - changed |= UpdatedProperties.Acceleration; - } - // if (_rotationalVelocity != entprop.RotationalVelocity) - if (!_rotationalVelocity.ApproxEquals(entprop.RotationalVelocity, ROTATIONAL_VELOCITY_TOLERANCE)) - { - _rotationalVelocity = entprop.RotationalVelocity; - changed |= UpdatedProperties.RotationalVel; - } - if (changed != 0) + // Updates only for individual prims and for the root object of a linkset. + if (Linkset.IsRoot(this)) { - // Only update the position of single objects and linkset roots - if (Linkset.IsRoot(this)) + // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet + // TODO: handle physics introduced by Bullet with computed vehicle physics. + if (_vehicle.IsActive) { - base.RequestPhysicsterseUpdate(); + entprop.RotationalVelocity = OMV.Vector3.Zero; } - } - */ - - // Don't check for damping here -- it's done in BulletSim and SceneObjectPart. - // Updates only for individual prims and for the root object of a linkset. - if (Linkset.IsRoot(this)) - { // Assign directly to the local variables so the normal set action does not happen _position = entprop.Position; _orientation = entprop.Rotation; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 805e670..09b1423 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -515,9 +515,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters collidersCount = 0; } - // Don't have to use the pointers passed back since we know it is the same pinned memory we passed in + // Don't have to use the pointers passed back since we know it is the same pinned memory we passed in. - // Get a value for 'now' so all the collision and update routines don't have to get their own + // Get a value for 'now' so all the collision and update routines don't have to get their own. SimulationNowTime = Util.EnvironmentTickCount(); // If there were collisions, process them by sending the event to the prim. @@ -563,6 +563,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters ObjectsWithCollisions.Remove(po); ObjectsWithNoMoreCollisions.Clear(); } + // Done with collisions. // If any of the objects had updated properties, tell the object it has been changed by the physics engine if (updatedEntityCount > 0) @@ -586,9 +587,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // The physics engine returns the number of milliseconds it simulated this call. // These are summed and normalized to one second and divided by 1000 to give the reported physics FPS. - // We multiply by 55 to give a recognizable running rate (55 or less). - return numSubSteps * m_fixedTimeStep * 1000 * 55; - // return timeStep * 1000 * 55; + // Multiply by 55 to give a nominal frame rate of 55. + return (float)numSubSteps * m_fixedTimeStep * 1000f * 55f; } // Something has collided @@ -1172,7 +1172,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters (s) => { return s.m_params[0].avatarFriction; }, (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarFriction, p, l, v); } ), new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", - 0.99f, + 10.0f, (s,cf,p,v) => { s.m_params[0].avatarStandingFriction = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].avatarStandingFriction; }, (s,p,l,v) => { s.m_params[0].avatarStandingFriction = v; } ), diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 12baee9..1e003e6 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -357,7 +357,7 @@ public enum CollisionFlags : uint CF_CHARACTER_OBJECT = 1 << 4, CF_DISABLE_VISUALIZE_OBJECT = 1 << 5, CF_DISABLE_SPU_COLLISION_PROCESS = 1 << 6, - // Following used by BulletSim to control collisions + // Following used by BulletSim to control collisions and updates BS_SUBSCRIBE_COLLISION_EVENTS = 1 << 10, BS_FLOATS_ON_WATER = 1 << 11, BS_NONE = 0, -- cgit v1.1 From 9e0db36c82da303a0d9c709b84b1c35879a39e86 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 27 Nov 2012 05:23:50 -0800 Subject: BulletSim: add 'infinite' timescale that does not reduce motor target or friction. --- OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 37 +++++++++++++++++------- 1 file changed, 27 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index 480da2c..e91bfa8 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -7,6 +7,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin { public abstract class BSMotor { + // Timescales and other things can be turned off by setting them to 'infinite'. + public const float Infinite = 10000f; + public readonly static Vector3 InfiniteVector = new Vector3(BSMotor.Infinite, BSMotor.Infinite, BSMotor.Infinite); + public BSMotor(string useName) { UseName = useName; @@ -46,8 +50,9 @@ public class BSVMotor : BSMotor public BSVMotor(string useName) : base(useName) { - TimeScale = TargetValueDecayTimeScale = Efficiency = 1f; - FrictionTimescale = Vector3.Zero; + TimeScale = TargetValueDecayTimeScale = BSMotor.Infinite; + Efficiency = 1f; + FrictionTimescale = BSMotor.InfiniteVector; CurrentValue = TargetValue = Vector3.Zero; } public BSVMotor(string useName, float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency) @@ -78,23 +83,35 @@ public class BSVMotor : BSMotor // Addition = (desiredVector - currentAppliedVector) / secondsItShouldTakeToComplete Vector3 addAmount = (TargetValue - CurrentValue)/TimeScale * timeStep; CurrentValue += addAmount; + returnCurrent = CurrentValue; - // The desired value reduces to zero when also reduces the difference with current. - float decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep; - TargetValue *= (1f - decayFactor); + // The desired value reduces to zero which also reduces the difference with current. + // If the decay time is infinite, don't decay at all. + float decayFactor = 0f; + if (TargetValueDecayTimeScale != BSMotor.Infinite) + { + decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep; + TargetValue *= (1f - decayFactor); + } Vector3 frictionFactor = Vector3.Zero; - frictionFactor = (Vector3.One / FrictionTimescale) * timeStep; - CurrentValue *= (Vector3.One - frictionFactor); + if (FrictionTimescale != BSMotor.InfiniteVector) + { + // frictionFactor = (Vector3.One / FrictionTimescale) * timeStep; + frictionFactor.X = FrictionTimescale.X == BSMotor.Infinite ? 0f : (1f / FrictionTimescale.X) * timeStep; + frictionFactor.Y = FrictionTimescale.Y == BSMotor.Infinite ? 0f : (1f / FrictionTimescale.Y) * timeStep; + frictionFactor.Z = FrictionTimescale.Z == BSMotor.Infinite ? 0f : (1f / FrictionTimescale.Z) * timeStep; + CurrentValue *= (Vector3.One - frictionFactor); + } - MDetailLog("{0},BSVMotor.Step,nonZero,{1},origTarget={2},origCurr={3},timeStep={4},timeScale={5},addAmnt={6},targetDecay={7},decayFact={8},fricTS={9},frictFact={10}", - BSScene.DetailLogZero, UseName, origTarget, origCurrVal, + MDetailLog("{0},BSVMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},timeScale={5},addAmnt={6},targetDecay={7},decayFact={8},fricTS={9},frictFact={10}", + BSScene.DetailLogZero, UseName, origCurrVal, origTarget, timeStep, TimeScale, addAmount, TargetValueDecayTimeScale, decayFactor, FrictionTimescale, frictionFactor); MDetailLog("{0},BSVMotor.Step,nonZero,{1},curr={2},target={3},add={4},decay={5},frict={6},ret={7}", - BSScene.DetailLogZero, UseName, TargetValue, CurrentValue, + BSScene.DetailLogZero, UseName, CurrentValue, TargetValue, addAmount, decayFactor, frictionFactor, returnCurrent); } else -- cgit v1.1 From 59554758b155c7965dc414a16e8b35c115ad3f64 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 27 Nov 2012 05:24:29 -0800 Subject: BulletSim: implementation of vertical attraction motor. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 103 +++++++++++++-------- 1 file changed, 62 insertions(+), 41 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 6ff8a48..d94abf4 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -125,6 +125,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity. //Attractor properties + private BSVMotor m_verticalAttractionMotor = new BSVMotor("VerticalAttraction"); private float m_verticalAttractionEfficiency = 1.0f; // damped private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. @@ -197,9 +198,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin break; case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: m_verticalAttractionEfficiency = Math.Max(0.1f, Math.Min(pValue, 1f)); + m_verticalAttractionMotor.Efficiency = m_verticalAttractionEfficiency; break; case Vehicle.VERTICAL_ATTRACTION_TIMESCALE: m_verticalAttractionTimescale = Math.Max(pValue, 0.01f); + m_verticalAttractionMotor.TimeScale = m_verticalAttractionTimescale; break; // These are vector properties but the engine lets you use a single float value to @@ -530,12 +533,22 @@ namespace OpenSim.Region.Physics.BulletSPlugin Refresh(); m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale, - m_linearMotorDecayTimescale, m_linearFrictionTimescale, 1f); + m_linearMotorDecayTimescale, m_linearFrictionTimescale, + 1f); m_linearMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) + m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale, - m_angularMotorDecayTimescale, m_angularFrictionTimescale, 1f); + m_angularMotorDecayTimescale, m_angularFrictionTimescale, + 1f); m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) + m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale, + BSMotor.Infinite, BSMotor.InfiniteVector, + m_verticalAttractionEfficiency); + // Z goes away and we keep X and Y + m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f); + m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) + // m_bankingMotor = new BSVMotor("BankingMotor", ...); } @@ -829,46 +842,63 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); // ================================================================== + // NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement + if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) + { + angularMotorContribution.X = 0f; + angularMotorContribution.Y = 0f; + VDetailLog("{0},MoveAngular,noDeflectionUp,angularMotorContrib={1}", Prim.LocalID, angularMotorContribution); + } + + // ================================================================== Vector3 verticalAttractionContribution = Vector3.Zero; // If vertical attaction timescale is reasonable and we applied an angular force last time... - if (m_verticalAttractionTimescale < 300 && m_lastAngularVelocity != Vector3.Zero) + if (m_verticalAttractionTimescale < 500) { - float VAservo = pTimestep * 0.2f / m_verticalAttractionTimescale; - if (Prim.IsColliding) - VAservo = pTimestep * 0.05f / m_verticalAttractionTimescale; + Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; + verticalError.Normalize(); + m_verticalAttractionMotor.SetCurrent(verticalError); + m_verticalAttractionMotor.SetTarget(Vector3.UnitZ); + verticalAttractionContribution = m_verticalAttractionMotor.Step(pTimestep); + /* + // Take a vector pointing up and convert it from world to vehicle relative coords. + Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; + verticalError.Normalize(); - VAservo *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); + // If vertical attraction correction is needed, the vector that was pointing up (UnitZ) + // is now leaning to one side (rotated around the X axis) and the Y value will + // go from zero (nearly straight up) to one (completely to the side) or leaning + // front-to-back (rotated around the Y axis) and the value of X will be between + // zero and one. + // The value of Z is how far the rotation is off with 1 meaning none and 0 being 90 degrees. - // Create a vector of the vehicle "up" in world coordinates - Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; - // verticalError.X and .Y are the World error amounts. They are 0 when there is no - // error (Vehicle Body is 'vertical'), and .Z will be 1. As the body leans to its - // side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall - // and .Z will go negative. Similar for tilt and |.Y|. .X and .Y must be - // modulated to prevent a stable inverted body. - - // Error is 0 (no error) to +/- 2 (max error) - verticalError.X = Math.Max(-2f, Math.Min(verticalError.X, 2f)); - verticalError.Y = Math.Max(-2f, Math.Min(verticalError.Y, 2f)); - - // scale it by VAservo (timestep and timescale) - verticalError = verticalError * VAservo; - - // As the body rotates around the X axis, then verticalError.Y increases; Rotated around Y - // then .X increases, so change Body angular velocity X based on Y, and Y based on X. - // Z is not changed. + // If verticalError.Z is negative, the vehicle is upside down. Add additional push. + if (verticalError.Z < 0f) + { + verticalError.X = 2f - verticalError.X; + verticalError.Y = 2f - verticalError.Y; + } + + // Y error means needed rotation around X axis and visa versa. verticalAttractionContribution.X = verticalError.Y; verticalAttractionContribution.Y = - verticalError.X; verticalAttractionContribution.Z = 0f; - // scaling appears better usingsquare-law - Vector3 angularVelocity = Prim.ForceRotationalVelocity; - float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); - verticalAttractionContribution.X += bounce * angularVelocity.X; - verticalAttractionContribution.Y += bounce * angularVelocity.Y; + // scale by the time scale and timestep + Vector3 unscaledContrib = verticalAttractionContribution; + verticalAttractionContribution /= m_verticalAttractionTimescale; + verticalAttractionContribution *= pTimestep; - VDetailLog("{0},MoveAngular,verticalAttraction,VAservo={1},effic={2},verticalError={3},bounce={4},vertattr={5}", - Prim.LocalID, VAservo, m_verticalAttractionEfficiency, verticalError, bounce, verticalAttractionContribution); + // apply efficiency + Vector3 preEfficiencyContrib = verticalAttractionContribution; + float efficencySquared = m_verticalAttractionEfficiency * m_verticalAttractionEfficiency; + verticalAttractionContribution *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); + + VDetailLog("{0},MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},preEff={3},eff={4},effSq={5},vertAttr={6}", + Prim.LocalID, verticalError, unscaledContrib, preEfficiencyContrib, + m_verticalAttractionEfficiency, efficencySquared, + verticalAttractionContribution); + */ } @@ -989,15 +1019,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin } // ================================================================== - // NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement - if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) - { - m_lastAngularVelocity.X = 0; - m_lastAngularVelocity.Y = 0; - VDetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); - } - - // ================================================================== if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) { m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. -- cgit v1.1 From 68fe7dff20fb38480a1c760f1347dafac43899c5 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 27 Nov 2012 05:37:06 -0800 Subject: BulletSim: reorganize angular movement routine into separate subroutines enabling external calibration routines and unit testing. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 209 +++++++++++---------- 1 file changed, 114 insertions(+), 95 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index d94abf4..eb4d06a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -317,7 +317,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_VhoverEfficiency = 0; m_VhoverTimescale = 0; m_VehicleBuoyancy = 0; - + m_linearDeflectionEfficiency = 1; m_linearDeflectionTimescale = 1; @@ -366,8 +366,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingMix = 1; m_referenceFrame = Quaternion.Identity; - m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY - | VehicleFlag.HOVER_TERRAIN_ONLY + m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY + | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); m_flags |= (VehicleFlag.NO_DEFLECTION_UP @@ -575,7 +575,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 localInertia = new Vector3(m_vehicleMass, m_vehicleMass, m_vehicleMass); BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia); - VDetailLog("{0},BSDynamics.Refresh,frict={1},inert={2},aDamp={3}", + VDetailLog("{0},BSDynamics.Refresh,frict={1},inert={2},aDamp={3}", Prim.LocalID, friction, localInertia, angularDamping); } } @@ -759,13 +759,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce // has a decay factor. This says this force should // be computed with a motor. - VDetailLog("{0},MoveLinear,limitMotorUp,distAbove={1},downForce={2}", + VDetailLog("{0},MoveLinear,limitMotorUp,distAbove={1},downForce={2}", Prim.LocalID, distanceAboveGround, limitMotorUpContribution); } // ================================================================== - Vector3 newVelocity = linearMotorContribution - + terrainHeightContribution + Vector3 newVelocity = linearMotorContribution + + terrainHeightContribution + hoverContribution + limitMotorUpContribution; @@ -801,7 +801,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin } VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},primVel={4},totalDown={5}", - Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, + Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, newVelocity, Prim.Velocity, totalDownForce); } // end MoveLinear() @@ -850,8 +850,84 @@ namespace OpenSim.Region.Physics.BulletSPlugin VDetailLog("{0},MoveAngular,noDeflectionUp,angularMotorContrib={1}", Prim.LocalID, angularMotorContribution); } + Vector3 verticalAttractionContribution = ComputeAngularVerticalAttraction(pTimestep); + + Vector3 deflectionContribution = ComputeAngularDeflection(pTimestep); + + Vector3 bankingContribution = ComputeAngularBanking(pTimestep); + + // ================================================================== + m_lastVertAttractor = verticalAttractionContribution; + + // Sum velocities + m_lastAngularVelocity = angularMotorContribution + + verticalAttractionContribution + + bankingContribution + + deflectionContribution; + + // ================================================================== + //Offset section + if (m_linearMotorOffset != Vector3.Zero) + { + //Offset of linear velocity doesn't change the linear velocity, + // but causes a torque to be applied, for example... + // + // IIIII >>> IIIII + // IIIII >>> IIIII + // IIIII >>> IIIII + // ^ + // | Applying a force at the arrow will cause the object to move forward, but also rotate + // + // + // The torque created is the linear velocity crossed with the offset + + // TODO: this computation should be in the linear section + // because that is where we know the impulse being applied. + Vector3 torqueFromOffset = Vector3.Zero; + // torqueFromOffset = Vector3.Cross(m_linearMotorOffset, appliedImpulse); + if (float.IsNaN(torqueFromOffset.X)) + torqueFromOffset.X = 0; + if (float.IsNaN(torqueFromOffset.Y)) + torqueFromOffset.Y = 0; + if (float.IsNaN(torqueFromOffset.Z)) + torqueFromOffset.Z = 0; + torqueFromOffset *= m_vehicleMass; + Prim.ApplyTorqueImpulse(torqueFromOffset, true); + VDetailLog("{0},BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset); + } + // ================================================================== - Vector3 verticalAttractionContribution = Vector3.Zero; + if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) + { + m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. + Prim.ZeroAngularMotion(true); + VDetailLog("{0},MoveAngular,zeroAngularMotion,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); + } + else + { + // Apply to the body. + // The above calculates the absolute angular velocity needed. Angular velocity is massless. + // Since we are stuffing the angular velocity directly into the object, the computed + // velocity needs to be scaled by the timestep. + // Also remove any motion that is on the object so added motion is only from vehicle. + Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep) + - Prim.ForceRotationalVelocity); + // Unscale the force by the angular factor so it overwhelmes the Bullet additions. + Prim.ForceRotationalVelocity = applyAngularForce; + + VDetailLog("{0},MoveAngular,done,angMotor={1},vertAttr={2},bank={3},deflect={4},newAngForce={5},lastAngular={6}", + Prim.LocalID, + angularMotorContribution, verticalAttractionContribution, + bankingContribution, deflectionContribution, + applyAngularForce, m_lastAngularVelocity + ); + } + } + + public Vector3 ComputeAngularVerticalAttraction(float pTimestep) + { + Vector3 ret = Vector3.Zero; + // If vertical attaction timescale is reasonable and we applied an angular force last time... if (m_verticalAttractionTimescale < 500) { @@ -859,7 +935,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin verticalError.Normalize(); m_verticalAttractionMotor.SetCurrent(verticalError); m_verticalAttractionMotor.SetTarget(Vector3.UnitZ); - verticalAttractionContribution = m_verticalAttractionMotor.Step(pTimestep); + ret = m_verticalAttractionMotor.Step(pTimestep); /* // Take a vector pointing up and convert it from world to vehicle relative coords. Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; @@ -895,15 +971,19 @@ namespace OpenSim.Region.Physics.BulletSPlugin verticalAttractionContribution *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); VDetailLog("{0},MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},preEff={3},eff={4},effSq={5},vertAttr={6}", - Prim.LocalID, verticalError, unscaledContrib, preEfficiencyContrib, + Prim.LocalID, verticalError, unscaledContrib, preEfficiencyContrib, m_verticalAttractionEfficiency, efficencySquared, verticalAttractionContribution); */ } + return ret; + } + + public Vector3 ComputeAngularDeflection(float pTimestep) + { + Vector3 ret = Vector3.Zero; - // ================================================================== - Vector3 deflectionContribution = Vector3.Zero; if (m_angularDeflectionEfficiency != 0) { // Compute a scaled vector that points in the preferred axis (X direction) @@ -914,24 +994,28 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 preferredAxisOfMotion = scaledDefaultDirection * Quaternion.Add(Prim.ForceOrientation, m_referenceFrame); // Scale by efficiency and timescale - deflectionContribution = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep; + ret = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep; + + VDetailLog("{0},MoveAngular,Deflection,perfAxis={1},deflection={2}", Prim.LocalID, preferredAxisOfMotion, ret); - VDetailLog("{0},MoveAngular,Deflection,perfAxis={1},deflection={2}", - Prim.LocalID, preferredAxisOfMotion, deflectionContribution); // This deflection computation is not correct. - deflectionContribution = Vector3.Zero; + ret = Vector3.Zero; } + return ret; + } + + public Vector3 ComputeAngularBanking(float pTimestep) + { + Vector3 ret = Vector3.Zero; - // ================================================================== - Vector3 bankingContribution = Vector3.Zero; if (m_bankingEfficiency != 0) { Vector3 dir = Vector3.One * Prim.ForceOrientation; - float mult = (m_bankingMix*m_bankingMix)*-1*(m_bankingMix < 0 ? -1 : 1); - //Changes which way it banks in and out of turns + float mult = (m_bankingMix * m_bankingMix) * -1 * (m_bankingMix < 0 ? -1 : 1); + //Changes which way it banks in and out of turns //Use the square of the efficiency, as it looks much more how SL banking works - float effSquared = (m_bankingEfficiency*m_bankingEfficiency); + float effSquared = (m_bankingEfficiency * m_bankingEfficiency); if (m_bankingEfficiency < 0) effSquared *= -1; //Keep the negative! @@ -953,99 +1037,34 @@ namespace OpenSim.Region.Physics.BulletSPlugin } else { - bankingContribution.Z += (effSquared * (mult * mix)) * (m_angularMotorVelocity.X) * 4; + ret.Z += (effSquared * (mult * mix)) * (m_angularMotorVelocity.X) * 4; } //If they are colliding, we probably shouldn't shove the prim around... probably if (!Prim.IsColliding && Math.Abs(m_angularMotorVelocity.X) > mix) { - float angVelZ = m_angularMotorVelocity.X*-1; + float angVelZ = m_angularMotorVelocity.X * -1; /*if(angVelZ > mix) angVelZ = mix; else if(angVelZ < -mix) angVelZ = -mix;*/ //This controls how fast and how far the banking occurs - Vector3 bankingRot = new Vector3(angVelZ*(effSquared*mult), 0, 0); + Vector3 bankingRot = new Vector3(angVelZ * (effSquared * mult), 0, 0); if (bankingRot.X > 3) bankingRot.X = 3; else if (bankingRot.X < -3) bankingRot.X = -3; bankingRot *= Prim.ForceOrientation; - bankingContribution += bankingRot; + ret += bankingRot; } m_angularMotorVelocity.X *= m_bankingEfficiency == 1 ? 0.0f : 1 - m_bankingEfficiency; - VDetailLog("{0},MoveAngular,Banking,bEff={1},angMotVel={2},effSq={3},mult={4},mix={5},banking={6}", - Prim.LocalID, m_bankingEfficiency, m_angularMotorVelocity, effSquared, mult, mix, bankingContribution); - } - - // ================================================================== - m_lastVertAttractor = verticalAttractionContribution; - - // Sum velocities - m_lastAngularVelocity = angularMotorContribution - + verticalAttractionContribution - + bankingContribution - + deflectionContribution; - - // ================================================================== - //Offset section - if (m_linearMotorOffset != Vector3.Zero) - { - //Offset of linear velocity doesn't change the linear velocity, - // but causes a torque to be applied, for example... - // - // IIIII >>> IIIII - // IIIII >>> IIIII - // IIIII >>> IIIII - // ^ - // | Applying a force at the arrow will cause the object to move forward, but also rotate - // - // - // The torque created is the linear velocity crossed with the offset - - // TODO: this computation should be in the linear section - // because that is where we know the impulse being applied. - Vector3 torqueFromOffset = Vector3.Zero; - // torqueFromOffset = Vector3.Cross(m_linearMotorOffset, appliedImpulse); - if (float.IsNaN(torqueFromOffset.X)) - torqueFromOffset.X = 0; - if (float.IsNaN(torqueFromOffset.Y)) - torqueFromOffset.Y = 0; - if (float.IsNaN(torqueFromOffset.Z)) - torqueFromOffset.Z = 0; - torqueFromOffset *= m_vehicleMass; - Prim.ApplyTorqueImpulse(torqueFromOffset, true); - VDetailLog("{0},BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset); - } - - // ================================================================== - if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) - { - m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. - Prim.ZeroAngularMotion(true); - VDetailLog("{0},MoveAngular,zeroAngularMotion,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); - } - else - { - // Apply to the body. - // The above calculates the absolute angular velocity needed. Angular velocity is massless. - // Since we are stuffing the angular velocity directly into the object, the computed - // velocity needs to be scaled by the timestep. - // Also remove any motion that is on the object so added motion is only from vehicle. - Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep) - - Prim.ForceRotationalVelocity); - // Unscale the force by the angular factor so it overwhelmes the Bullet additions. - Prim.ForceRotationalVelocity = applyAngularForce; - - VDetailLog("{0},MoveAngular,done,angMotor={1},vertAttr={2},bank={3},deflect={4},newAngForce={5},lastAngular={6}", - Prim.LocalID, - angularMotorContribution, verticalAttractionContribution, - bankingContribution, deflectionContribution, - applyAngularForce, m_lastAngularVelocity - ); + VDetailLog("{0},MoveAngular,Banking,bEff={1},angMotVel={2},effSq={3},mult={4},mix={5},banking={6}", + Prim.LocalID, m_bankingEfficiency, m_angularMotorVelocity, effSquared, mult, mix, ret); } + return ret; } + // This is from previous instantiations of XXXDynamics.cs. // Applies roll reference frame. // TODO: is this the right way to separate the code to do this operation? -- cgit v1.1 From a5100cafee7e1e79f911c1e33fb1742075ca7283 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 27 Nov 2012 10:01:25 -0800 Subject: BulletSim: fix terrain mesh generation for problem with regions that have unequal edge heights. Thanks UBit. --- .../Region/Physics/BulletSPlugin/BSTerrainMesh.cs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index d7afdeb..5f6675d 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs @@ -88,9 +88,11 @@ public sealed class BSTerrainMesh : BSTerrainPhys // Something is very messed up and a crash is in our future. return; } + PhysicsScene.DetailLog("{0},BSTerrainMesh.create,meshed,indices={1},indSz={2},vertices={3},vertSz={4}", + ID, indicesCount, indices.Length, verticesCount, vertices.Length); m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, - indicesCount, indices, verticesCount, vertices), + indicesCount, indices, verticesCount, vertices), BSPhysicsShapeType.SHAPE_MESH); if (m_terrainShape.ptr == IntPtr.Zero) { @@ -122,10 +124,10 @@ public sealed class BSTerrainMesh : BSTerrainPhys // Static objects are not very massive. BulletSimAPI.SetMassProps2(m_terrainBody.ptr, 0f, Vector3.Zero); - // Return the new terrain to the world of physical objects + // Put the new terrain to the world of physical objects BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr); - // redo its bounding box now that it is in the world + // Redo its bounding box now that it is in the world BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr); BulletSimAPI.SetCollisionFilterMask2(m_terrainBody.ptr, @@ -188,6 +190,11 @@ public sealed class BSTerrainMesh : BSTerrainPhys // Simple mesh creation which assumes magnification == 1. // TODO: do a more general solution that scales, adds new vertices and smoothes the result. + // Create an array of vertices that is sizeX+1 by sizeY+1 (note the loop + // from zero to <= sizeX). The triangle indices are then generated as two triangles + // per heightmap point. There are sizeX by sizeY of these squares. The extra row and + // column of vertices are used to complete the triangles of the last row and column + // of the heightmap. try { // One vertice per heightmap value plus the vertices off the top and bottom edge. @@ -200,16 +207,18 @@ public sealed class BSTerrainMesh : BSTerrainPhys float magY = (float)sizeY / extentY; physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2},extentBase={3},magX={4},magY={5}", BSScene.DetailLogZero, totalVertices, totalIndices, extentBase, magX, magY); + float minHeight = float.MaxValue; // Note that sizeX+1 vertices are created since there is land between this and the next region. for (int yy = 0; yy <= sizeY; yy++) { - for (int xx = 0; xx <= sizeX; xx++) // Hint: the "<=" means we got through sizeX + 1 times + for (int xx = 0; xx <= sizeX; xx++) // Hint: the "<=" means we go around sizeX + 1 times { int offset = yy * sizeX + xx; - // Extend the height from the height from the last row or column + // Extend the height with the height from the last row or column if (yy == sizeY) offset -= sizeX; if (xx == sizeX) offset -= 1; float height = heightMap[offset]; + minHeight = Math.Min(minHeight, height); vertices[verticesCount + 0] = (float)xx * magX + extentBase.X; vertices[verticesCount + 1] = (float)yy * magY + extentBase.Y; vertices[verticesCount + 2] = height + extentBase.Z; @@ -222,7 +231,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys { for (int xx = 0; xx < sizeX; xx++) { - int offset = yy * sizeX + xx; + int offset = yy * (sizeX + 1) + xx; // Each vertices is presumed to be the upper left corner of a box of two triangles indices[indicesCount + 0] = offset; indices[indicesCount + 1] = offset + 1; @@ -233,6 +242,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys indicesCount += 6; } } + ret = true; } catch (Exception e) -- cgit v1.1 From 8e459a03467ffa45145f90ea764854deaf2615ed Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 27 Nov 2012 10:02:29 -0800 Subject: BulletSim: reorganize linear movement routine into separate subroutines enabling external calibration routines and unit tests. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 137 ++++++++++++--------- 1 file changed, 79 insertions(+), 58 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index eb4d06a..74eb9ab 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -630,13 +630,64 @@ namespace OpenSim.Region.Physics.BulletSPlugin // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy); - // Current vehicle position Vector3 pos = Prim.ForcePosition; + float terrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); + + Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(pTimestep, ref pos, terrainHeight); + + Vector3 hoverContribution = ComputeLinearHover(pTimestep, ref pos, terrainHeight); + + ComputeLinearBlockingEndPoint(pTimestep, ref pos); + + Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pTimestep, pos, terrainHeight); + + // ================================================================== + Vector3 newVelocity = linearMotorContribution + + terrainHeightContribution + + hoverContribution + + limitMotorUpContribution; + + // If not changing some axis, reduce out velocity + if ((m_flags & (VehicleFlag.NO_X)) != 0) + newVelocity.X = 0; + if ((m_flags & (VehicleFlag.NO_Y)) != 0) + newVelocity.Y = 0; + if ((m_flags & (VehicleFlag.NO_Z)) != 0) + newVelocity.Z = 0; + + // ================================================================== + // Clamp REALLY high or low velocities + float newVelocityLengthSq = newVelocity.LengthSquared(); + if (newVelocityLengthSq > 1e6f) + { + newVelocity /= newVelocity.Length(); + newVelocity *= 1000f; + } + else if (newVelocityLengthSq < 1e-6f) + newVelocity = Vector3.Zero; // ================================================================== - Vector3 terrainHeightContribution = Vector3.Zero; + // Stuff new linear velocity into the vehicle + Prim.ForceVelocity = newVelocity; + // Prim.ApplyForceImpulse((m_newVelocity - Prim.Velocity) * m_vehicleMass, false); // DEBUG DEBUG + + // Other linear forces are applied as forces. + Vector3 totalDownForce = grav * m_vehicleMass; + if (totalDownForce != Vector3.Zero) + { + Prim.AddForce(totalDownForce, false); + } + + VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},primVel={4},totalDown={5}", + Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, + newVelocity, Prim.Velocity, totalDownForce); + + } // end MoveLinear() + + public Vector3 ComputeLinearTerrainHeightCorrection(float pTimestep, ref Vector3 pos, float terrainHeight) + { + Vector3 ret = Vector3.Zero; // If below the terrain, move us above the ground a little. - float terrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); // Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset. // TODO: Add a m_prim.LinkSet.Size similar to m_prim.LinkSet.Mass. // Vector3 rotatedSize = m_prim.Size * m_prim.ForceOrientation; @@ -648,10 +699,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin Prim.ForcePosition = pos; VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, terrainHeight, pos); } + return ret; + } + + public Vector3 ComputeLinearHover(float pTimestep, ref Vector3 pos, float terrainHeight) + { + Vector3 ret = Vector3.Zero; - // ================================================================== - Vector3 hoverContribution = Vector3.Zero; - // Check if hovering // m_VhoverEfficiency: 0=bouncy, 1=totally damped // m_VhoverTimescale: time to achieve height if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) @@ -692,24 +746,29 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Replace Vertical speed with correction figure if significant if (verticalError > 0.01f) { - hoverContribution = new Vector3(0f, 0f, verticalCorrectionVelocity); + ret = new Vector3(0f, 0f, verticalCorrectionVelocity); //KF: m_VhoverEfficiency is not yet implemented } else if (verticalError < -0.01) { - hoverContribution = new Vector3(0f, 0f, -verticalCorrectionVelocity); + ret = new Vector3(0f, 0f, -verticalCorrectionVelocity); } } VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", - Prim.LocalID, pos, hoverContribution, m_VhoverHeight, m_VhoverTargetHeight); + Prim.LocalID, pos, ret, m_VhoverHeight, m_VhoverTargetHeight); } - // ================================================================== + return ret; + } + + public bool ComputeLinearBlockingEndPoint(float pTimestep, ref Vector3 pos) + { + bool changed = false; + Vector3 posChange = pos - m_lastPositionVector; if (m_BlockingEndPoint != Vector3.Zero) { - bool changed = false; if (pos.X >= (m_BlockingEndPoint.X - (float)1)) { pos.X -= posChange.X + 1; @@ -742,9 +801,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin Prim.LocalID, m_BlockingEndPoint, posChange, pos); } } + return changed; + } - // ================================================================== - Vector3 limitMotorUpContribution = Vector3.Zero; + public Vector3 ComputeLinearMotorUp(float pTimestep, Vector3 pos, float terrainHeight) + { + Vector3 ret = Vector3.Zero; if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) { // If the vehicle is motoring into the sky, get it going back down. @@ -753,58 +815,17 @@ namespace OpenSim.Region.Physics.BulletSPlugin { // downForce = new Vector3(0, 0, (-distanceAboveGround / m_bankingTimescale) * pTimestep); // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); - limitMotorUpContribution = new Vector3(0, 0, -distanceAboveGround); + ret = new Vector3(0, 0, -distanceAboveGround); } // TODO: this calculation is all wrong. From the description at // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce // has a decay factor. This says this force should // be computed with a motor. VDetailLog("{0},MoveLinear,limitMotorUp,distAbove={1},downForce={2}", - Prim.LocalID, distanceAboveGround, limitMotorUpContribution); + Prim.LocalID, distanceAboveGround, ret); } - - // ================================================================== - Vector3 newVelocity = linearMotorContribution - + terrainHeightContribution - + hoverContribution - + limitMotorUpContribution; - - // If not changing some axis, reduce out velocity - if ((m_flags & (VehicleFlag.NO_X)) != 0) - newVelocity.X = 0; - if ((m_flags & (VehicleFlag.NO_Y)) != 0) - newVelocity.Y = 0; - if ((m_flags & (VehicleFlag.NO_Z)) != 0) - newVelocity.Z = 0; - - // ================================================================== - // Clamp REALLY high or low velocities - float newVelocityLengthSq = newVelocity.LengthSquared(); - if (newVelocityLengthSq > 1e6f) - { - newVelocity /= newVelocity.Length(); - newVelocity *= 1000f; - } - else if (newVelocityLengthSq < 1e-6f) - newVelocity = Vector3.Zero; - - // ================================================================== - // Stuff new linear velocity into the vehicle - Prim.ForceVelocity = newVelocity; - // Prim.ApplyForceImpulse((m_newVelocity - Prim.Velocity) * m_vehicleMass, false); // DEBUG DEBUG - - // Other linear forces are applied as forces. - Vector3 totalDownForce = grav * m_vehicleMass; - if (totalDownForce != Vector3.Zero) - { - Prim.AddForce(totalDownForce, false); - } - - VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},primVel={4},totalDown={5}", - Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, - newVelocity, Prim.Velocity, totalDownForce); - - } // end MoveLinear() + return ret; + } // ======================================================================= // ======================================================================= -- cgit v1.1 From 2cd88787af52213e1f0b2d863b75e35ca83e8032 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 27 Nov 2012 14:42:28 -0800 Subject: Prevent the core Groups module from being enabled when its name doesn't match the "default" ini choice --- OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs b/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs index af54c1a..b735c61 100644 --- a/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs @@ -81,7 +81,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups } if (groupsConfig.GetString("Module", "Default") != "Default") + { + m_Enabled = false; return; + } } } -- cgit v1.1 From c17ea2049b3027abb5bc5446a8c5b0d4985953b9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 28 Nov 2012 01:42:58 +0000 Subject: Show many more primitive properties on console command "show part name/id/pos" --- .../World/Objects/Commands/ObjectCommandsModule.cs | 60 ++++++++++++++++++++-- 1 file changed, 57 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs index ab8f143..7b235ae 100644 --- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs @@ -365,7 +365,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands if (mainParams.Count < 4) { - m_console.OutputFormat("Usage: show part id [--full] "); + //m_console.OutputFormat("Usage: show part id [--full] "); + m_console.OutputFormat("Usage: show part id "); return; } @@ -405,6 +406,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands if (mainParams.Count < 5) { + //m_console.OutputFormat("Usage: show part pos to "); m_console.OutputFormat("Usage: show part pos [--full] to "); return; } @@ -445,7 +447,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands if (mainParams.Count < 4) { - m_console.OutputFormat("Usage: show part name [--full] [--regex] "); + m_console.OutputFormat("Usage: show part name [--regex] "); + //m_console.OutputFormat("Usage: show part name [--full] [--regex] "); return; } @@ -577,6 +580,58 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands cdl.AddRow("Link number", sop.LinkNum); cdl.AddRow("Flags", sop.Flags); + if (showFull) + { + PrimitiveBaseShape s = sop.Shape; + cdl.AddRow("FlexiDrag", s.FlexiDrag); + cdl.AddRow("FlexiEntry", s.FlexiEntry); + cdl.AddRow("FlexiForce", string.Format("<{0},{1},{2}>", s.FlexiForceX, s.FlexiForceY, s.FlexiForceZ)); + cdl.AddRow("FlexiGravity", s.FlexiGravity); + cdl.AddRow("FlexiSoftness", s.FlexiSoftness); + cdl.AddRow("HollowShape", s.HollowShape); + cdl.AddRow( + "LightColor", + string.Format("<{0},{1},{2},{3}>", s.LightColorR, s.LightColorB, s.LightColorG, s.LightColorA)); + cdl.AddRow("FlexiDrag", s.LightCutoff); + cdl.AddRow("FlexiDrag", s.LightEntry); + cdl.AddRow("FlexiDrag", s.LightFalloff); + cdl.AddRow("FlexiDrag", s.LightIntensity); + cdl.AddRow("FlexiDrag", s.LightRadius); + cdl.AddRow("Media", string.Format("{0} entries", s.Media != null ? s.Media.Count.ToString() : "n/a")); + cdl.AddRow("PathBegin", s.PathBegin); + cdl.AddRow("PathEnd", s.PathEnd); + cdl.AddRow("PathCurve", s.PathCurve); + cdl.AddRow("PathRadiusOffset", s.PathRadiusOffset); + cdl.AddRow("PathRevolutions", s.PathRevolutions); + cdl.AddRow("PathScale", string.Format("<{0},{1}>", s.PathScaleX, s.PathScaleY)); + cdl.AddRow("PathSkew", string.Format("<{0},{1}>", s.PathShearX, s.PathShearY)); + cdl.AddRow("FlexiDrag", s.PathSkew); + cdl.AddRow("PathTaper", string.Format("<{0},{1}>", s.PathTaperX, s.PathTaperY)); + cdl.AddRow("PathTwist", s.PathTwist); + cdl.AddRow("PathTwistBegin", s.PathTwistBegin); + cdl.AddRow("PCode", s.PCode); + cdl.AddRow("ProfileBegin", s.ProfileBegin); + cdl.AddRow("ProfileEnd", s.ProfileEnd); + cdl.AddRow("ProfileHollow", s.ProfileHollow); + cdl.AddRow("ProfileShape", s.ProfileShape); + cdl.AddRow("ProjectionAmbiance", s.ProjectionAmbiance); + cdl.AddRow("ProjectionEntry", s.ProjectionEntry); + cdl.AddRow("ProjectionFocus", s.ProjectionFocus); + cdl.AddRow("ProjectionFOV", s.ProjectionFOV); + cdl.AddRow("ProjectionTextureUUID", s.ProjectionTextureUUID); + cdl.AddRow("Scale", s.Scale); + cdl.AddRow( + "SculptData", + string.Format("{0} bytes", s.SculptData != null ? s.SculptData.Length.ToString() : "n/a")); + cdl.AddRow("SculptEntry", s.SculptEntry); + cdl.AddRow("SculptTexture", s.SculptTexture); + cdl.AddRow("SculptType", s.SculptType); + cdl.AddRow("State", s.State); + + // TODO, unpack and display texture entries + //cdl.AddRow("Textures", string.Format("{0} entries", s.Textures. + } + object itemsOutput; if (showFull) { @@ -588,7 +643,6 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands itemsOutput = sop.Inventory.Count; } - cdl.AddRow("Items", itemsOutput); return sb.Append(cdl.ToString()); -- cgit v1.1 From aae76f7be4f62db230bf4750496b913b6d013eb8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 28 Nov 2012 02:01:04 +0000 Subject: Stop logging spurious asset data for {0} is zero length error for sculpts/mesh ODEPrim, for instance, always hits this code path twice at the moment Firstly before any sculpt data has been loaded (hence the spurious message) Secondly when any sculpt data has been loaded or failed to load (when the message would be valid). Hence comment this out and rely on the message in ODEPrim.MeshAssetReceived() instead (though this is not ideal since it requires all physics plugins to copy/paste similar code). --- OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 5 ++++- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 3bd15ce..6fa91ab 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -321,7 +321,10 @@ namespace OpenSim.Region.Physics.Meshing if (primShape.SculptData.Length <= 0) { - m_log.ErrorFormat("[MESH]: asset data for {0} is zero length", primName); + // XXX: At the moment we can not log here since ODEPrim, for instance, ends up triggering this + // method twice - once before it has loaded sculpt data from the asset service and once afterwards. + // The first time will always call with unloaded SculptData if this needs to be uploaded. +// m_log.ErrorFormat("[MESH]: asset data for {0} is zero length", primName); return false; } diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 5a0b8d1..0d66496 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -3361,6 +3361,11 @@ Console.WriteLine(" JointCreateFixed"); _pbs.SculptData = new byte[asset.Data.Length]; asset.Data.CopyTo(_pbs.SculptData, 0); // m_assetFailed = false; + +// m_log.DebugFormat( +// "[ODE PRIM]: Received mesh/sculpt data asset {0} with {1} bytes for {2} at {3} in {4}", +// _pbs.SculptTexture, _pbs.SculptData.Length, Name, _position, _parent_scene.Name); + m_taintshape = true; _parent_scene.AddPhysicsActorTaint(this); } -- cgit v1.1 From 92a766e8cb38ed0cf2f778d95e192275cd4e3100 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 27 Nov 2012 21:10:58 -0800 Subject: Bug fix in Offline IM for inventory transfers. The items were being placed twice in the receiver's inventory. --- .../Avatar/InstantMessage/OfflineMessageModule.cs | 26 +++++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs index 4aaf1fe..41364d7 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs @@ -186,17 +186,21 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage foreach (GridInstantMessage im in msglist) { - // client.SendInstantMessage(im); - - // Send through scene event manager so all modules get a chance - // to look at this message before it gets delivered. - // - // Needed for proper state management for stored group - // invitations - // - Scene s = FindScene(client.AgentId); - if (s != null) - s.EventManager.TriggerIncomingInstantMessage(im); + if (im.dialog == (byte)InstantMessageDialog.InventoryOffered) + // send it directly or else the item will be given twice + client.SendInstantMessage(im); + else + { + // Send through scene event manager so all modules get a chance + // to look at this message before it gets delivered. + // + // Needed for proper state management for stored group + // invitations + // + Scene s = FindScene(client.AgentId); + if (s != null) + s.EventManager.TriggerIncomingInstantMessage(im); + } } } } -- cgit v1.1 From 0a66317fa6414dff9a7a4ab5bae10802e1e6693f Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 28 Nov 2012 08:05:01 -0800 Subject: BulletSim: move GetWaterLevelAtXYZ from BSScene to BSPhysTerrain. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 10 ++++--- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 7 +++-- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 17 +++++------ .../Physics/BulletSPlugin/BSTerrainHeightmap.cs | 8 +++++- .../Physics/BulletSPlugin/BSTerrainManager.cs | 33 ++++++++++++++++++++-- .../Region/Physics/BulletSPlugin/BSTerrainMesh.cs | 8 +++++- 7 files changed, 63 insertions(+), 22 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 4c195e1..1dfc420 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -307,7 +307,7 @@ public sealed class BSCharacter : BSPhysObject } if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) { - float waterHeight = PhysicsScene.GetWaterLevelAtXYZ(_position); + float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(_position); if (Position.Z < waterHeight) { _position.Z = waterHeight; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 74eb9ab..b6e3594 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -713,7 +713,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // We should hover, get the target height if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0) { - m_VhoverTargetHeight = Prim.PhysicsScene.GetWaterLevelAtXYZ(pos) + m_VhoverHeight; + m_VhoverTargetHeight = Prim.PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(pos) + m_VhoverHeight; } if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) { @@ -730,6 +730,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z; } + if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) { if (Math.Abs(pos.Z - m_VhoverTargetHeight) > 0.2f) @@ -883,8 +884,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Sum velocities m_lastAngularVelocity = angularMotorContribution + verticalAttractionContribution - + bankingContribution - + deflectionContribution; + + deflectionContribution + + bankingContribution; // ================================================================== //Offset section @@ -921,8 +922,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) { m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. - Prim.ZeroAngularMotion(true); + // TODO: zeroing is good but it also sets values in unmanaged code. Remove the stores when idle. VDetailLog("{0},MoveAngular,zeroAngularMotion,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); + Prim.ZeroAngularMotion(true); } else { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index c62c79a..3fb0300 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -253,8 +253,9 @@ public sealed class BSPrim : BSPhysObject // Zero some other properties in the physics engine PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate() { - BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero); - BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero); + // DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity); + BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, _rotationalVelocity); + BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity); }); } @@ -329,7 +330,7 @@ public sealed class BSPrim : BSPhysObject if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) { - float waterHeight = PhysicsScene.GetWaterLevelAtXYZ(_position); + float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(_position); // TODO: a floating motor so object will bob in the water if (Math.Abs(Position.Z - waterHeight) > 0.1f) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 09b1423..0c80611 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -127,7 +127,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public const uint GROUNDPLANE_ID = 1; public const uint CHILDTERRAIN_ID = 2; // Terrain allocated based on our mega-prim childre start here - private float m_waterLevel; + public float SimpleWaterLevel { get; set; } public BSTerrainManager TerrainManager { get; private set; } public ConfigurationParameters Params @@ -182,6 +182,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters private string m_physicsLoggingDir; private string m_physicsLoggingPrefix; private int m_physicsLoggingFileMinutes; + private bool m_physicsLoggingDoFlush; // 'true' of the vehicle code is to log lots of details public bool VehicleLoggingEnabled { get; private set; } @@ -290,6 +291,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters m_physicsLoggingDir = pConfig.GetString("PhysicsLoggingDir", "."); m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-%REGIONNAME%-"); m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5); + m_physicsLoggingDoFlush = pConfig.GetBoolean("PhysicsLoggingDoFlush", false); // Very detailed logging for vehicle debugging VehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false); @@ -494,7 +496,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters try { - if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG + // if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount(); numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep, @@ -503,7 +505,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime); DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}", DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount); - if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG + // if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG } catch (Exception e) { @@ -634,12 +636,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public override void SetWaterLevel(float baseheight) { - m_waterLevel = baseheight; - } - // Someday.... - public float GetWaterLevelAtXYZ(Vector3 loc) - { - return m_waterLevel; + SimpleWaterLevel = baseheight; } public override void DeleteTerrain() @@ -1493,7 +1490,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters { PhysicsLogging.Write(msg, args); // Add the Flush() if debugging crashes. Gets all the messages written out. - // PhysicsLogging.Flush(); + if (m_physicsLoggingDoFlush) PhysicsLogging.Flush(); } // Used to fill in the LocalID when there isn't one. It's the correct number of characters. public const string DetailLogZero = "0000000000"; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs index 1450f66..0cb151e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs @@ -148,7 +148,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys } // The passed position is relative to the base of the region. - public override float GetHeightAtXYZ(Vector3 pos) + public override float GetTerrainHeightAtXYZ(Vector3 pos) { float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; @@ -166,5 +166,11 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys } return ret; } + + // The passed position is relative to the base of the region. + public override float GetWaterLevelAtXYZ(Vector3 pos) + { + return PhysicsScene.SimpleWaterLevel; + } } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index cd623f1..17d9536 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -62,7 +62,8 @@ public abstract class BSTerrainPhys : IDisposable ID = id; } public abstract void Dispose(); - public abstract float GetHeightAtXYZ(Vector3 pos); + public abstract float GetTerrainHeightAtXYZ(Vector3 pos); + public abstract float GetWaterLevelAtXYZ(Vector3 pos); } // ========================================================================================== @@ -75,6 +76,7 @@ public sealed class BSTerrainManager public const float HEIGHT_INITIALIZATION = 24.987f; public const float HEIGHT_INITIAL_LASTHEIGHT = 24.876f; public const float HEIGHT_GETHEIGHT_RET = 24.765f; + public const float WATER_HEIGHT_GETHEIGHT_RET = 19.998f; // If the min and max height are equal, we reduce the min by this // amount to make sure that a bounding box is built for the terrain. @@ -358,7 +360,7 @@ public sealed class BSTerrainManager BSTerrainPhys physTerrain; if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain)) { - ret = physTerrain.GetHeightAtXYZ(loc - terrainBaseXYZ); + ret = physTerrain.GetTerrainHeightAtXYZ(loc - terrainBaseXYZ); } else { @@ -370,6 +372,33 @@ public sealed class BSTerrainManager return ret; } + public float GetWaterLevelAtXYZ(Vector3 pos) + { + float ret = WATER_HEIGHT_GETHEIGHT_RET; + + float tX = pos.X; + float tY = pos.Y; + + Vector3 terrainBaseXYZ = Vector3.Zero; + terrainBaseXYZ.X = ((int)(tX / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X; + terrainBaseXYZ.Y = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y; + + lock (m_terrains) + { + BSTerrainPhys physTerrain; + if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain)) + { + ret = physTerrain.GetWaterLevelAtXYZ(pos); + } + else + { + PhysicsScene.Logger.ErrorFormat("{0} GetWaterHeightAtXY: terrain not found: region={1}, x={2}, y={3}", + LogHeader, PhysicsScene.RegionName, tX, tY); + } + } + return ret; + } + // Although no one seems to check this, I do support combining. public bool SupportsCombining() { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index 5f6675d..7e93ab4 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs @@ -148,7 +148,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys } } - public override float GetHeightAtXYZ(Vector3 pos) + public override float GetTerrainHeightAtXYZ(Vector3 pos) { // For the moment use the saved heightmap to get the terrain height. // TODO: raycast downward to find the true terrain below the position. @@ -169,6 +169,12 @@ public sealed class BSTerrainMesh : BSTerrainPhys return ret; } + // The passed position is relative to the base of the region. + public override float GetWaterLevelAtXYZ(Vector3 pos) + { + return PhysicsScene.SimpleWaterLevel; + } + // Convert the passed heightmap to mesh information suitable for CreateMeshShape2(). // Return 'true' if successfully created. public static bool ConvertHeightmapToMesh( -- cgit v1.1 From 2ccd4c130234ff16a6c31845958476c759f72245 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 28 Nov 2012 09:46:05 -0800 Subject: BulletSim: fix boats floating low by removing LIMIT_MOTOR_UP flag from TYPE_BOAT definition. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index b6e3594..3a73fba 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -445,9 +445,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.LIMIT_ROLL_ONLY + | VehicleFlag.LIMIT_MOTOR_UP | VehicleFlag.HOVER_UP_ONLY); m_flags |= (VehicleFlag.NO_DEFLECTION_UP - | VehicleFlag.LIMIT_MOTOR_UP | VehicleFlag.HOVER_WATER_ONLY); break; case Vehicle.TYPE_AIRPLANE: @@ -805,6 +805,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin return changed; } + // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags : + // Prevent ground vehicles from motoring into the sky.This flag has a subtle effect when + // used with conjunction with banking: the strength of the banking will decay when the + // vehicle no longer experiences collisions. The decay timescale is the same as + // VEHICLE_BANKING_TIMESCALE. This is to help prevent ground vehicles from steering + // when they are in mid jump. + // TODO: this code is wrong. Also, what should it do for boats? public Vector3 ComputeLinearMotorUp(float pTimestep, Vector3 pos, float terrainHeight) { Vector3 ret = Vector3.Zero; @@ -818,10 +825,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); ret = new Vector3(0, 0, -distanceAboveGround); } - // TODO: this calculation is all wrong. From the description at + // TODO: this calculation is wrong. From the description at // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce // has a decay factor. This says this force should // be computed with a motor. + // TODO: add interaction with banking. VDetailLog("{0},MoveLinear,limitMotorUp,distAbove={1},downForce={2}", Prim.LocalID, distanceAboveGround, ret); } @@ -864,7 +872,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); // ================================================================== - // NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement + // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags : + // This flag prevents linear deflection parallel to world z-axis. This is useful + // for preventing ground vehicles with large linear deflection, like bumper cars, + // from climbing their linear deflection into the sky. + // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) { angularMotorContribution.X = 0f; -- cgit v1.1 From b8a7cbb9e916f0fe47e56a35a1bf3a6001ed02d0 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 29 Nov 2012 08:03:30 -0800 Subject: BulletSim: reverse direction of hover correction. Removes problem with vehicles being orbited. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 3a73fba..a398b74 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -742,22 +742,22 @@ namespace OpenSim.Region.Physics.BulletSPlugin else { float verticalError = pos.Z - m_VhoverTargetHeight; - // RA: where does the 50 come from? - float verticalCorrectionVelocity = pTimestep * ((verticalError * 50.0f) / m_VhoverTimescale); - // Replace Vertical speed with correction figure if significant + float verticalCorrectionVelocity = pTimestep * (verticalError / m_VhoverTimescale); + + // TODO: implement m_VhoverEfficiency if (verticalError > 0.01f) { - ret = new Vector3(0f, 0f, verticalCorrectionVelocity); - //KF: m_VhoverEfficiency is not yet implemented + // If error is positive (we're above the target height), push down + ret = new Vector3(0f, 0f, -verticalCorrectionVelocity); } else if (verticalError < -0.01) { - ret = new Vector3(0f, 0f, -verticalCorrectionVelocity); + ret = new Vector3(0f, 0f, verticalCorrectionVelocity); } } - VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", - Prim.LocalID, pos, ret, m_VhoverHeight, m_VhoverTargetHeight); + VDetailLog("{0},MoveLinear,hover,pos={1},ret={2},hoverTS={3},height={4},target={5}", + Prim.LocalID, pos, ret, m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight); } return ret; -- cgit v1.1 From 0cd99c74a70ddfd42c3e8325716f56bf35d4474c Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 29 Nov 2012 09:24:53 -0800 Subject: BulletSim: add expanded call to IMesher/Meshmerizer which enables/disables mesh caching. Since BulletSim caches and tracks the unmanaged memory version of meshes, the Meshmerizer itself does not need to cache built meshes once BulletSim has made the physical proxy mesh. --- .../Physics/BulletSPlugin/BSShapeCollection.cs | 7 +++---- OpenSim/Region/Physics/Manager/IMesher.cs | 1 + OpenSim/Region/Physics/Manager/ZeroMesher.cs | 7 ++++++- OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 21 ++++++++++++++++----- 4 files changed, 26 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 892c34b..b94dcf6 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -620,8 +620,7 @@ public sealed class BSShapeCollection : IDisposable } else { - // Pass false for physicalness as this creates some sort of bounding box which we don't need - meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, false); + meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false); if (meshData != null) { @@ -694,8 +693,8 @@ public sealed class BSShapeCollection : IDisposable else { // Build a new hull in the physical world - // Pass false for physicalness as this creates some sort of bounding box which we don't need - IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, false); + // Pass true for physicalness as this creates some sort of bounding box which we don't need + IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false); if (meshData != null) { diff --git a/OpenSim/Region/Physics/Manager/IMesher.cs b/OpenSim/Region/Physics/Manager/IMesher.cs index 3a9ca1b..10c4bd3 100644 --- a/OpenSim/Region/Physics/Manager/IMesher.cs +++ b/OpenSim/Region/Physics/Manager/IMesher.cs @@ -36,6 +36,7 @@ namespace OpenSim.Region.Physics.Manager { IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod); IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical); + IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache); } // Values for level of detail to be passed to the mesher. diff --git a/OpenSim/Region/Physics/Manager/ZeroMesher.cs b/OpenSim/Region/Physics/Manager/ZeroMesher.cs index ba19db6..270d2ec 100644 --- a/OpenSim/Region/Physics/Manager/ZeroMesher.cs +++ b/OpenSim/Region/Physics/Manager/ZeroMesher.cs @@ -64,11 +64,16 @@ namespace OpenSim.Region.Physics.Manager { public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) { - return CreateMesh(primName, primShape, size, lod, false); + return CreateMesh(primName, primShape, size, lod, false, false); } public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical) { + return CreateMesh(primName, primShape, size, lod, false, false); + } + + public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache) + { // Remove the reference to the encoded JPEG2000 data so it can be GCed primShape.SculptData = OpenMetaverse.Utils.EmptyBytes; diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 6fa91ab..8145d61 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -702,11 +702,16 @@ namespace OpenSim.Region.Physics.Meshing public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) { - return CreateMesh(primName, primShape, size, lod, false); + return CreateMesh(primName, primShape, size, lod, false, true); } public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical) { + return CreateMesh(primName, primShape, size, lod, isPhysical, true); + } + + public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache) + { #if SPAM m_log.DebugFormat("[MESH]: Creating mesh for {0}", primName); #endif @@ -716,9 +721,12 @@ namespace OpenSim.Region.Physics.Meshing // If this mesh has been created already, return it instead of creating another copy // For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory - key = primShape.GetMeshKey(size, lod); - if (m_uniqueMeshes.TryGetValue(key, out mesh)) - return mesh; + if (shouldCache) + { + key = primShape.GetMeshKey(size, lod); + if (m_uniqueMeshes.TryGetValue(key, out mesh)) + return mesh; + } if (size.X < 0.01f) size.X = 0.01f; if (size.Y < 0.01f) size.Y = 0.01f; @@ -741,7 +749,10 @@ namespace OpenSim.Region.Physics.Meshing // trim the vertex and triangle lists to free up memory mesh.TrimExcess(); - m_uniqueMeshes.Add(key, mesh); + if (shouldCache) + { + m_uniqueMeshes.Add(key, mesh); + } } return mesh; -- cgit v1.1 From 0bda35e18fdba53998d752b7ce7ef5b0580a642e Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 29 Nov 2012 09:53:59 -0800 Subject: BulletSim: add copyright header where it is missing. Remove some unnecessary 'using' requirements so testing framework is less complicated. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 2 -- OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 32 +++++++++++++++++++++- 2 files changed, 31 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index a398b74..fcee1de 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -45,9 +45,7 @@ using System; using System.Collections.Generic; using System.Reflection; using System.Runtime.InteropServices; -using log4net; using OpenMetaverse; -using OpenSim.Framework; using OpenSim.Region.Physics.Manager; namespace OpenSim.Region.Physics.BulletSPlugin diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index e91bfa8..eca1452 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -1,3 +1,30 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ using System; using System.Collections.Generic; using System.Text; @@ -8,7 +35,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin public abstract class BSMotor { // Timescales and other things can be turned off by setting them to 'infinite'. - public const float Infinite = 10000f; + public const float Infinite = 12345f; public readonly static Vector3 InfiniteVector = new Vector3(BSMotor.Infinite, BSMotor.Infinite, BSMotor.Infinite); public BSMotor(string useName) @@ -19,7 +46,9 @@ public abstract class BSMotor public virtual void Reset() { } public virtual void Zero() { } + // A name passed at motor creation for easily identifyable debugging messages. public string UseName { get; private set; } + // Used only for outputting debug information. Might not be set so check for null. public BSScene PhysicsScene { get; set; } protected void MDetailLog(string msg, params Object[] parms) @@ -99,6 +128,7 @@ public class BSVMotor : BSMotor if (FrictionTimescale != BSMotor.InfiniteVector) { // frictionFactor = (Vector3.One / FrictionTimescale) * timeStep; + // Individual friction components can be 'infinite' so compute each separately. frictionFactor.X = FrictionTimescale.X == BSMotor.Infinite ? 0f : (1f / FrictionTimescale.X) * timeStep; frictionFactor.Y = FrictionTimescale.Y == BSMotor.Infinite ? 0f : (1f / FrictionTimescale.Y) * timeStep; frictionFactor.Z = FrictionTimescale.Z == BSMotor.Infinite ? 0f : (1f / FrictionTimescale.Z) * timeStep; -- cgit v1.1 From ec63e4ff29f9983b65d76232018156605762ccc0 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 29 Nov 2012 22:21:45 -0800 Subject: BulletSim: remove time scaling of computed vehicle absolute velocity since Bullet will scale the movement by the time slice. Restore LIMIT_MOTOR_UP to definitition of BOAT simce some vehicle engines use it even for land vehicles. Push vehicle parameter updates through the regular property update to solve vehicles floating off when they should be stopped. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 98 ++++++++++++++-------- OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 8 ++ OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 15 +--- 3 files changed, 73 insertions(+), 48 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index fcee1de..fcc1224 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -127,6 +127,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin private float m_verticalAttractionEfficiency = 1.0f; // damped private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. + // Local + private float m_knownTerrainHeight; + private float m_knownWaterLevel; + public BSDynamics(BSScene myScene, BSPrim myPrim) { PhysicsScene = myScene; @@ -443,9 +447,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.LIMIT_ROLL_ONLY - | VehicleFlag.LIMIT_MOTOR_UP | VehicleFlag.HOVER_UP_ONLY); m_flags |= (VehicleFlag.NO_DEFLECTION_UP + | VehicleFlag.LIMIT_MOTOR_UP | VehicleFlag.HOVER_WATER_ONLY); break; case Vehicle.TYPE_AIRPLANE: @@ -596,11 +600,32 @@ namespace OpenSim.Region.Physics.BulletSPlugin Refresh(); } + // Since the computation of terrain height can be a little involved, this routine + // is used ot fetch the height only once for each vehicle simulation step. + private float GetTerrainHeight(Vector3 pos) + { + if (m_knownTerrainHeight == float.MinValue) + m_knownTerrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); + return m_knownTerrainHeight; + } + + // Since the computation of water level can be a little involved, this routine + // is used ot fetch the level only once for each vehicle simulation step. + private float GetWaterLevel(Vector3 pos) + { + if (m_knownWaterLevel == float.MinValue) + m_knownWaterLevel = Prim.PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(pos); + return m_knownWaterLevel; + } + // One step of the vehicle properties for the next 'pTimestep' seconds. internal void Step(float pTimestep) { if (!IsActive) return; + // zap values so they will be fetched when needed + m_knownTerrainHeight = m_knownWaterLevel = float.MinValue; + MoveLinear(pTimestep); MoveAngular(pTimestep); @@ -609,6 +634,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin // remember the position so next step we can limit absolute movement effects m_lastPositionVector = Prim.ForcePosition; + // Force the physics engine to decide whether values have updated. + // TODO: this is only necessary if pos, velocity, ... were updated. Is it quicker + // to check for changes here or just push the update? + BulletSimAPI.PushUpdate2(Prim.PhysBody.ptr); + VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", Prim.LocalID, Prim.ForcePosition, Prim.Force, Prim.ForceVelocity, Prim.RotationalVelocity); } @@ -629,15 +659,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy); Vector3 pos = Prim.ForcePosition; - float terrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); - Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(pTimestep, ref pos, terrainHeight); + Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(ref pos); - Vector3 hoverContribution = ComputeLinearHover(pTimestep, ref pos, terrainHeight); + Vector3 hoverContribution = ComputeLinearHover(ref pos); - ComputeLinearBlockingEndPoint(pTimestep, ref pos); + ComputeLinearBlockingEndPoint(ref pos); - Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pTimestep, pos, terrainHeight); + Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pos); // ================================================================== Vector3 newVelocity = linearMotorContribution @@ -665,42 +694,40 @@ namespace OpenSim.Region.Physics.BulletSPlugin newVelocity = Vector3.Zero; // ================================================================== - // Stuff new linear velocity into the vehicle + // Stuff new linear velocity into the vehicle. + // Since the velocity is just being set, it is not scaled by pTimeStep. Bullet will do that for us. Prim.ForceVelocity = newVelocity; - // Prim.ApplyForceImpulse((m_newVelocity - Prim.Velocity) * m_vehicleMass, false); // DEBUG DEBUG // Other linear forces are applied as forces. - Vector3 totalDownForce = grav * m_vehicleMass; + Vector3 totalDownForce = grav * m_vehicleMass * pTimestep; if (totalDownForce != Vector3.Zero) { Prim.AddForce(totalDownForce, false); } - VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},primVel={4},totalDown={5}", - Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, - newVelocity, Prim.Velocity, totalDownForce); + VDetailLog("{0},MoveLinear,done,newVel={1},totDown={2},linContrib={3},terrContrib={4},hoverContrib={5},limitContrib={6}", + Prim.LocalID, newVelocity, totalDownForce, + linearMotorContribution, terrainHeightContribution, hoverContribution, limitMotorUpContribution + ); } // end MoveLinear() - public Vector3 ComputeLinearTerrainHeightCorrection(float pTimestep, ref Vector3 pos, float terrainHeight) + public Vector3 ComputeLinearTerrainHeightCorrection(ref Vector3 pos) { Vector3 ret = Vector3.Zero; // If below the terrain, move us above the ground a little. - // Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset. - // TODO: Add a m_prim.LinkSet.Size similar to m_prim.LinkSet.Mass. - // Vector3 rotatedSize = m_prim.Size * m_prim.ForceOrientation; - // if (rotatedSize.Z < terrainHeight) - if (pos.Z < terrainHeight) + // TODO: Consider taking the rotated size of the object or possibly casting a ray. + if (pos.Z < GetTerrainHeight(pos)) { // TODO: correct position by applying force rather than forcing position. - pos.Z = terrainHeight + 2; + pos.Z = GetTerrainHeight(pos) + 2; Prim.ForcePosition = pos; - VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, terrainHeight, pos); + VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, GetTerrainHeight(pos), pos); } return ret; } - public Vector3 ComputeLinearHover(float pTimestep, ref Vector3 pos, float terrainHeight) + public Vector3 ComputeLinearHover(ref Vector3 pos) { Vector3 ret = Vector3.Zero; @@ -711,11 +738,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin // We should hover, get the target height if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0) { - m_VhoverTargetHeight = Prim.PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(pos) + m_VhoverHeight; + m_VhoverTargetHeight = GetWaterLevel(pos) + m_VhoverHeight; } if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) { - m_VhoverTargetHeight = terrainHeight + m_VhoverHeight; + m_VhoverTargetHeight = GetTerrainHeight(pos) + m_VhoverHeight; } if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0) { @@ -739,16 +766,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin } else { - float verticalError = pos.Z - m_VhoverTargetHeight; - float verticalCorrectionVelocity = pTimestep * (verticalError / m_VhoverTimescale); + // Error is positive if below the target and negative if above. + float verticalError = m_VhoverTargetHeight - pos.Z; + float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; - // TODO: implement m_VhoverEfficiency - if (verticalError > 0.01f) - { - // If error is positive (we're above the target height), push down - ret = new Vector3(0f, 0f, -verticalCorrectionVelocity); - } - else if (verticalError < -0.01) + // TODO: implement m_VhoverEfficiency correctly + if (Math.Abs(verticalError) > m_VhoverEfficiency) { ret = new Vector3(0f, 0f, verticalCorrectionVelocity); } @@ -761,7 +784,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin return ret; } - public bool ComputeLinearBlockingEndPoint(float pTimestep, ref Vector3 pos) + public bool ComputeLinearBlockingEndPoint(ref Vector3 pos) { bool changed = false; @@ -810,13 +833,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin // VEHICLE_BANKING_TIMESCALE. This is to help prevent ground vehicles from steering // when they are in mid jump. // TODO: this code is wrong. Also, what should it do for boats? - public Vector3 ComputeLinearMotorUp(float pTimestep, Vector3 pos, float terrainHeight) + public Vector3 ComputeLinearMotorUp(Vector3 pos) { Vector3 ret = Vector3.Zero; if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) { // If the vehicle is motoring into the sky, get it going back down. - float distanceAboveGround = pos.Z - terrainHeight; + // float distanceAboveGround = pos.Z - Math.Max(GetTerrainHeight(pos), GetWaterLevel(pos)); + float distanceAboveGround = pos.Z - GetTerrainHeight(pos); if (distanceAboveGround > 1f) { // downForce = new Vector3(0, 0, (-distanceAboveGround / m_bankingTimescale) * pTimestep); @@ -933,7 +957,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. // TODO: zeroing is good but it also sets values in unmanaged code. Remove the stores when idle. - VDetailLog("{0},MoveAngular,zeroAngularMotion,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); + VDetailLog("{0},MoveAngular,done,zero,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); Prim.ZeroAngularMotion(true); } else @@ -948,7 +972,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Unscale the force by the angular factor so it overwhelmes the Bullet additions. Prim.ForceRotationalVelocity = applyAngularForce; - VDetailLog("{0},MoveAngular,done,angMotor={1},vertAttr={2},bank={3},deflect={4},newAngForce={5},lastAngular={6}", + VDetailLog("{0},MoveAngular,done,nonZero,angMotor={1},vertAttr={2},bank={3},deflect={4},newAngForce={5},lastAngular={6}", Prim.LocalID, angularMotorContribution, verticalAttractionContribution, bankingContribution, deflectionContribution, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index eca1452..b256887 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -101,6 +101,14 @@ public class BSVMotor : BSMotor { TargetValue = target; } + + // A form of stepping that does not take the time quantum into account. + // The caller must do the right thing later. + public Vector3 Step() + { + return Step(1f); + } + public Vector3 Step(float timeStep) { Vector3 returnCurrent = Vector3.Zero; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 3fb0300..54b4167 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -348,7 +348,9 @@ public sealed class BSPrim : BSPhysObject if (ret) { // Apply upforce and overcome gravity. - AddForce(upForce - PhysicsScene.DefaultGravity, false, inTaintTime); + OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity; + DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce); + AddForce(correctionForce, false, inTaintTime); } return ret; } @@ -839,15 +841,6 @@ public sealed class BSPrim : BSPhysObject } public override OMV.Vector3 RotationalVelocity { get { - /* - OMV.Vector3 pv = OMV.Vector3.Zero; - // if close to zero, report zero - // This is copied from ODE but I'm not sure why it returns zero but doesn't - // zero the property in the physics engine. - if (_rotationalVelocity.ApproxEquals(pv, 0.2f)) - return pv; - */ - return _rotationalVelocity; } set { @@ -1409,7 +1402,7 @@ public sealed class BSPrim : BSPhysObject LastEntityProperties = CurrentEntityProperties; CurrentEntityProperties = entprop; - OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; + OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}", LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity); -- cgit v1.1 From b124aae05e6aeca02f692a7a5d96569b804612bd Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 1 Dec 2012 15:39:13 -0800 Subject: BulletSim: Add DumpActivationInfo2 function. Change static objects from DISABLE_SIMULATION to ISLAND_SLEEPING. Update DLLs and SOs to add DumpActivationInfo2 function. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 12 ++++++------ OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 4 ++-- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 2 ++ OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs | 7 +++++-- 4 files changed, 15 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index fcc1224..15a40fe 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -623,7 +623,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { if (!IsActive) return; - // zap values so they will be fetched when needed + // Zap values so they will be fetched if needed m_knownTerrainHeight = m_knownWaterLevel = float.MinValue; MoveLinear(pTimestep); @@ -634,8 +634,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin // remember the position so next step we can limit absolute movement effects m_lastPositionVector = Prim.ForcePosition; - // Force the physics engine to decide whether values have updated. - // TODO: this is only necessary if pos, velocity, ... were updated. Is it quicker + // Force the physics engine to decide whether values were updated. + // TODO: this is only necessary if pos, velocity, etc were updated. Is it quicker // to check for changes here or just push the update? BulletSimAPI.PushUpdate2(Prim.PhysBody.ptr); @@ -643,13 +643,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin Prim.LocalID, Prim.ForcePosition, Prim.Force, Prim.ForceVelocity, Prim.RotationalVelocity); } - // Apply the effect of the linear motor. - // Also does hover and float. + // Apply the effect of the linear motor and other linear motions (like hover and float). private void MoveLinear(float pTimestep) { Vector3 linearMotorContribution = m_linearMotor.Step(pTimestep); - // Rotate new object velocity from vehicle relative to world coordinates + // The movement computed in the linear motor is relative to the vehicle + // coordinates. Rotate the movement to world coordinates. linearMotorContribution *= Prim.ForceOrientation; // ================================================================== diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 54b4167..42a362f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -687,9 +687,9 @@ public sealed class BSPrim : BSPhysObject // There can be special things needed for implementing linksets Linkset.MakeStatic(this); // The activation state is 'disabled' so Bullet will not try to act on it. - BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.DISABLE_SIMULATION); + // BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.DISABLE_SIMULATION); // Start it out sleeping and physical actions could wake it up. - // BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.ISLAND_SLEEPING); + BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ISLAND_SLEEPING); PhysBody.collisionFilter = CollisionFilterGroups.StaticObjectFilter; PhysBody.collisionMask = CollisionFilterGroups.StaticObjectMask; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 0c80611..5e70a23 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -971,6 +971,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // Should handle fetching the right type from the ini file and converting it. // -- a delegate for getting the value as a float // -- a delegate for setting the value from a float + // -- an optional delegate to update the value in the world. Most often used to + // push the new value to an in-world object. // // The single letter parameters for the delegates are: // s = BSScene diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 1e003e6..21bc6a3 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -1007,13 +1007,16 @@ public static extern void DumpRigidBody2(IntPtr sim, IntPtr collisionObject); public static extern void DumpCollisionShape2(IntPtr sim, IntPtr collisionShape); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void DumpMapInfo2(IntPtr sim, IntPtr manInfo); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern void DumpConstraint2(IntPtr sim, IntPtr constrain); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void DumpAllInfo2(IntPtr sim); +public static extern void DumpActivationInfo2(IntPtr sim); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void DumpMapInfo2(IntPtr sim, IntPtr manInfo); +public static extern void DumpAllInfo2(IntPtr sim); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern void DumpPhysicsStatistics2(IntPtr sim); -- cgit v1.1 From 20c3ec7d9277997d9510f5d08df6a0523faaa31e Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 1 Dec 2012 18:03:32 -0800 Subject: BulletSim: localize vehicle property setting so the vehicle prim is only updated at the end of the vehicle simulation step and the push of the physics property update event only happens if the properties are actually changed. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 161 ++++++++++++++++----- 1 file changed, 128 insertions(+), 33 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 15a40fe..9749429 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -127,10 +127,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin private float m_verticalAttractionEfficiency = 1.0f; // damped private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. - // Local - private float m_knownTerrainHeight; - private float m_knownWaterLevel; - public BSDynamics(BSScene myScene, BSPrim myPrim) { PhysicsScene = myScene; @@ -560,9 +556,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin { if (IsActive) { + // Remember the mass so we don't have to fetch it every step m_vehicleMass = Prim.Linkset.LinksetMass; - // Friction effects are handled by this vehicle code + // Friction affects are handled by this vehicle code float friction = 0f; BulletSimAPI.SetFriction2(Prim.PhysBody.ptr, friction); @@ -600,31 +597,130 @@ namespace OpenSim.Region.Physics.BulletSPlugin Refresh(); } + #region Known vehicle value functions + private int m_knownChanged; + private float? m_knownTerrainHeight; + private float? m_knownWaterLevel; + + private Vector3? m_knownPosition; + private Vector3? m_knownVelocity; + private Quaternion? m_knownOrientation; + private Vector3? m_knownRotationalVelocity; + + private const int m_knownChangedPosition = 1 << 0; + private const int m_knownChangedVelocity = 1 << 1; + private const int m_knownChangedOrientation = 1 << 2; + private const int m_knownChangedRotationalVelocity = 1 << 3; + + private void ForgetKnownVehicleProperties() + { + m_knownTerrainHeight = null; + m_knownWaterLevel = null; + m_knownPosition = null; + m_knownVelocity = null; + m_knownOrientation = null; + m_knownRotationalVelocity = null; + m_knownChanged = 0; + } + private void PushKnownChanged() + { + if (m_knownChanged != 0) + { + if ((m_knownChanged & m_knownChangedPosition) != 0) Prim.ForcePosition = VehiclePosition; + if ((m_knownChanged & m_knownChangedOrientation) != 0) Prim.ForceOrientation = VehicleOrientation; + if ((m_knownChanged & m_knownChangedVelocity) != 0) Prim.ForceVelocity = VehicleVelocity; + if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) Prim.ForceRotationalVelocity = VehicleRotationalVelocity; + // If we set one of the values (ie, the physics engine doesn't do it) we must make sure there + // is an UpdateProperties event to send the changes up to the simulator. + BulletSimAPI.PushUpdate2(Prim.PhysBody.ptr); + } + } + // Since the computation of terrain height can be a little involved, this routine // is used ot fetch the height only once for each vehicle simulation step. private float GetTerrainHeight(Vector3 pos) { - if (m_knownTerrainHeight == float.MinValue) + if (m_knownTerrainHeight == null) m_knownTerrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); - return m_knownTerrainHeight; + return (float)m_knownTerrainHeight; } // Since the computation of water level can be a little involved, this routine // is used ot fetch the level only once for each vehicle simulation step. private float GetWaterLevel(Vector3 pos) { - if (m_knownWaterLevel == float.MinValue) + if (m_knownWaterLevel == null) m_knownWaterLevel = Prim.PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(pos); - return m_knownWaterLevel; + return (float)m_knownWaterLevel; + } + + private Vector3 VehiclePosition + { + get + { + if (m_knownPosition == null) + m_knownPosition = Prim.ForcePosition; + return (Vector3)m_knownPosition; + } + set + { + m_knownPosition = value; + m_knownChanged |= m_knownChangedPosition; + } + } + + private Quaternion VehicleOrientation + { + get + { + if (m_knownOrientation == null) + m_knownOrientation = Prim.ForceOrientation; + return (Quaternion)m_knownOrientation; + } + set + { + m_knownOrientation = value; + m_knownChanged |= m_knownChangedOrientation; + } + } + + private Vector3 VehicleVelocity + { + get + { + if (m_knownVelocity == null) + m_knownVelocity = Prim.ForceVelocity; + return (Vector3)m_knownVelocity; + } + set + { + m_knownVelocity = value; + m_knownChanged |= m_knownChangedVelocity; + } + } + + private Vector3 VehicleRotationalVelocity + { + get + { + if (m_knownRotationalVelocity == null) + m_knownRotationalVelocity = Prim.ForceRotationalVelocity; + return (Vector3)m_knownRotationalVelocity; + } + set + { + m_knownRotationalVelocity = value; + m_knownChanged |= m_knownChangedRotationalVelocity; + } } + #endregion // Known vehicle value functions // One step of the vehicle properties for the next 'pTimestep' seconds. internal void Step(float pTimestep) { if (!IsActive) return; - // Zap values so they will be fetched if needed - m_knownTerrainHeight = m_knownWaterLevel = float.MinValue; + ForgetKnownVehicleProperties(); MoveLinear(pTimestep); MoveAngular(pTimestep); @@ -632,15 +728,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin LimitRotation(pTimestep); // remember the position so next step we can limit absolute movement effects - m_lastPositionVector = Prim.ForcePosition; + m_lastPositionVector = VehiclePosition; - // Force the physics engine to decide whether values were updated. - // TODO: this is only necessary if pos, velocity, etc were updated. Is it quicker - // to check for changes here or just push the update? - BulletSimAPI.PushUpdate2(Prim.PhysBody.ptr); + // If we forced the changing of some vehicle parameters, update the values and + // for the physics engine to note the changes so an UpdateProperties event will happen. + PushKnownChanged(); VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", - Prim.LocalID, Prim.ForcePosition, Prim.Force, Prim.ForceVelocity, Prim.RotationalVelocity); + Prim.LocalID, VehiclePosition, Prim.Force, VehicleVelocity, VehicleRotationalVelocity); } // Apply the effect of the linear motor and other linear motions (like hover and float). @@ -650,7 +745,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // The movement computed in the linear motor is relative to the vehicle // coordinates. Rotate the movement to world coordinates. - linearMotorContribution *= Prim.ForceOrientation; + linearMotorContribution *= VehicleOrientation; // ================================================================== // Gravity and Buoyancy @@ -658,7 +753,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy); - Vector3 pos = Prim.ForcePosition; + Vector3 pos = VehiclePosition; Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(ref pos); @@ -696,7 +791,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ================================================================== // Stuff new linear velocity into the vehicle. // Since the velocity is just being set, it is not scaled by pTimeStep. Bullet will do that for us. - Prim.ForceVelocity = newVelocity; + VehicleVelocity = newVelocity; // Other linear forces are applied as forces. Vector3 totalDownForce = grav * m_vehicleMass * pTimestep; @@ -721,7 +816,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { // TODO: correct position by applying force rather than forcing position. pos.Z = GetTerrainHeight(pos) + 2; - Prim.ForcePosition = pos; + VehiclePosition = pos; VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, GetTerrainHeight(pos), pos); } return ret; @@ -761,7 +856,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (Math.Abs(pos.Z - m_VhoverTargetHeight) > 0.2f) { pos.Z = m_VhoverTargetHeight; - Prim.ForcePosition = pos; + VehiclePosition = pos; } } else @@ -818,7 +913,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin } if (changed) { - Prim.ForcePosition = pos; + VehiclePosition = pos; VDetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}", Prim.LocalID, m_BlockingEndPoint, posChange, pos); } @@ -958,6 +1053,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. // TODO: zeroing is good but it also sets values in unmanaged code. Remove the stores when idle. VDetailLog("{0},MoveAngular,done,zero,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); + VehicleRotationalVelocity = Vector3.Zero; Prim.ZeroAngularMotion(true); } else @@ -967,10 +1063,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Since we are stuffing the angular velocity directly into the object, the computed // velocity needs to be scaled by the timestep. // Also remove any motion that is on the object so added motion is only from vehicle. - Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep) - - Prim.ForceRotationalVelocity); + Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep) - VehicleRotationalVelocity); // Unscale the force by the angular factor so it overwhelmes the Bullet additions. - Prim.ForceRotationalVelocity = applyAngularForce; + VehicleRotationalVelocity = applyAngularForce; VDetailLog("{0},MoveAngular,done,nonZero,angMotor={1},vertAttr={2},bank={3},deflect={4},newAngForce={5},lastAngular={6}", Prim.LocalID, @@ -988,14 +1083,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin // If vertical attaction timescale is reasonable and we applied an angular force last time... if (m_verticalAttractionTimescale < 500) { - Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; + Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; verticalError.Normalize(); m_verticalAttractionMotor.SetCurrent(verticalError); m_verticalAttractionMotor.SetTarget(Vector3.UnitZ); ret = m_verticalAttractionMotor.Step(pTimestep); /* // Take a vector pointing up and convert it from world to vehicle relative coords. - Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; + Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; verticalError.Normalize(); // If vertical attraction correction is needed, the vector that was pointing up (UnitZ) @@ -1048,7 +1143,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin new Vector3((pTimestep * 10 * (m_angularDeflectionEfficiency / m_angularDeflectionTimescale)), 0, 0); // Adding the current vehicle orientation and reference frame displaces the orientation to the frame. // Rotate the scaled default axix relative to the actual vehicle direction giving where it should point. - Vector3 preferredAxisOfMotion = scaledDefaultDirection * Quaternion.Add(Prim.ForceOrientation, m_referenceFrame); + Vector3 preferredAxisOfMotion = scaledDefaultDirection * Quaternion.Add(VehicleOrientation, m_referenceFrame); // Scale by efficiency and timescale ret = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep; @@ -1067,7 +1162,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (m_bankingEfficiency != 0) { - Vector3 dir = Vector3.One * Prim.ForceOrientation; + Vector3 dir = Vector3.One * VehicleOrientation; float mult = (m_bankingMix * m_bankingMix) * -1 * (m_bankingMix < 0 ? -1 : 1); //Changes which way it banks in and out of turns @@ -1111,7 +1206,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin bankingRot.X = 3; else if (bankingRot.X < -3) bankingRot.X = -3; - bankingRot *= Prim.ForceOrientation; + bankingRot *= VehicleOrientation; ret += bankingRot; } m_angularMotorVelocity.X *= m_bankingEfficiency == 1 ? 0.0f : 1 - m_bankingEfficiency; @@ -1128,7 +1223,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Should this be in MoveAngular()? internal void LimitRotation(float timestep) { - Quaternion rotq = Prim.ForceOrientation; + Quaternion rotq = VehicleOrientation; Quaternion m_rot = rotq; if (m_RollreferenceFrame != Quaternion.Identity) { @@ -1156,7 +1251,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin } if (rotq != m_rot) { - Prim.ForceOrientation = m_rot; + VehicleOrientation = m_rot; VDetailLog("{0},LimitRotation,done,orig={1},new={2}", Prim.LocalID, rotq, m_rot); } -- cgit v1.1 From f9fed421fed75d2494fe55c6b153f59232e2c796 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 1 Dec 2012 18:06:39 -0800 Subject: BulletSim: format vehicle detail logging messages so vehicle changs are grouped better in the log output. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 28 +++++++++++----------- OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 6 ++--- 2 files changed, 17 insertions(+), 17 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 9749429..cbad3bf 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -800,7 +800,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin Prim.AddForce(totalDownForce, false); } - VDetailLog("{0},MoveLinear,done,newVel={1},totDown={2},linContrib={3},terrContrib={4},hoverContrib={5},limitContrib={6}", + VDetailLog("{0}, MoveLinear,done,newVel={1},totDown={2},linContrib={3},terrContrib={4},hoverContrib={5},limitContrib={6}", Prim.LocalID, newVelocity, totalDownForce, linearMotorContribution, terrainHeightContribution, hoverContribution, limitMotorUpContribution ); @@ -817,7 +817,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // TODO: correct position by applying force rather than forcing position. pos.Z = GetTerrainHeight(pos) + 2; VehiclePosition = pos; - VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, GetTerrainHeight(pos), pos); + VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, GetTerrainHeight(pos), pos); } return ret; } @@ -872,7 +872,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin } } - VDetailLog("{0},MoveLinear,hover,pos={1},ret={2},hoverTS={3},height={4},target={5}", + VDetailLog("{0}, MoveLinear,hover,pos={1},ret={2},hoverTS={3},height={4},target={5}", Prim.LocalID, pos, ret, m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight); } @@ -914,7 +914,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (changed) { VehiclePosition = pos; - VDetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}", + VDetailLog("{0}, MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}", Prim.LocalID, m_BlockingEndPoint, posChange, pos); } } @@ -947,7 +947,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // has a decay factor. This says this force should // be computed with a motor. // TODO: add interaction with banking. - VDetailLog("{0},MoveLinear,limitMotorUp,distAbove={1},downForce={2}", + VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},downForce={2}", Prim.LocalID, distanceAboveGround, ret); } return ret; @@ -977,7 +977,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // decay requested direction m_angularMotorDirection *= (1.0f - (pTimestep * 1.0f/m_angularMotorDecayTimescale)); - VDetailLog("{0},MoveAngular,angularMotorApply,angTScale={1},timeStep={2},origvel={3},origDir={4},vel={5}", + VDetailLog("{0}, MoveAngular,angularMotorApply,angTScale={1},timeStep={2},origvel={3},origDir={4},vel={5}", Prim.LocalID, m_angularMotorTimescale, pTimestep, origVel, origDir, m_angularMotorVelocity); } else @@ -998,7 +998,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { angularMotorContribution.X = 0f; angularMotorContribution.Y = 0f; - VDetailLog("{0},MoveAngular,noDeflectionUp,angularMotorContrib={1}", Prim.LocalID, angularMotorContribution); + VDetailLog("{0}, MoveAngular,noDeflectionUp,angularMotorContrib={1}", Prim.LocalID, angularMotorContribution); } Vector3 verticalAttractionContribution = ComputeAngularVerticalAttraction(pTimestep); @@ -1044,7 +1044,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin torqueFromOffset.Z = 0; torqueFromOffset *= m_vehicleMass; Prim.ApplyTorqueImpulse(torqueFromOffset, true); - VDetailLog("{0},BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset); + VDetailLog("{0}, BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset); } // ================================================================== @@ -1052,7 +1052,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. // TODO: zeroing is good but it also sets values in unmanaged code. Remove the stores when idle. - VDetailLog("{0},MoveAngular,done,zero,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); + VDetailLog("{0}, MoveAngular,done,zero,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); VehicleRotationalVelocity = Vector3.Zero; Prim.ZeroAngularMotion(true); } @@ -1067,7 +1067,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Unscale the force by the angular factor so it overwhelmes the Bullet additions. VehicleRotationalVelocity = applyAngularForce; - VDetailLog("{0},MoveAngular,done,nonZero,angMotor={1},vertAttr={2},bank={3},deflect={4},newAngForce={5},lastAngular={6}", + VDetailLog("{0}, MoveAngular,done,nonZero,angMotor={1},vertAttr={2},bank={3},deflect={4},newAngForce={5},lastAngular={6}", Prim.LocalID, angularMotorContribution, verticalAttractionContribution, bankingContribution, deflectionContribution, @@ -1122,7 +1122,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin float efficencySquared = m_verticalAttractionEfficiency * m_verticalAttractionEfficiency; verticalAttractionContribution *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); - VDetailLog("{0},MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},preEff={3},eff={4},effSq={5},vertAttr={6}", + VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},preEff={3},eff={4},effSq={5},vertAttr={6}", Prim.LocalID, verticalError, unscaledContrib, preEfficiencyContrib, m_verticalAttractionEfficiency, efficencySquared, verticalAttractionContribution); @@ -1148,7 +1148,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Scale by efficiency and timescale ret = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep; - VDetailLog("{0},MoveAngular,Deflection,perfAxis={1},deflection={2}", Prim.LocalID, preferredAxisOfMotion, ret); + VDetailLog("{0}, MoveAngular,Deflection,perfAxis={1},deflection={2}", Prim.LocalID, preferredAxisOfMotion, ret); // This deflection computation is not correct. ret = Vector3.Zero; @@ -1210,7 +1210,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin ret += bankingRot; } m_angularMotorVelocity.X *= m_bankingEfficiency == 1 ? 0.0f : 1 - m_bankingEfficiency; - VDetailLog("{0},MoveAngular,Banking,bEff={1},angMotVel={2},effSq={3},mult={4},mix={5},banking={6}", + VDetailLog("{0}, MoveAngular,Banking,bEff={1},angMotVel={2},effSq={3},mult={4},mix={5},banking={6}", Prim.LocalID, m_bankingEfficiency, m_angularMotorVelocity, effSquared, mult, mix, ret); } return ret; @@ -1252,7 +1252,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (rotq != m_rot) { VehicleOrientation = m_rot; - VDetailLog("{0},LimitRotation,done,orig={1},new={2}", Prim.LocalID, rotq, m_rot); + VDetailLog("{0}, LimitRotation,done,orig={1},new={2}", Prim.LocalID, rotq, m_rot); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index b256887..e9f1549 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -143,12 +143,12 @@ public class BSVMotor : BSMotor CurrentValue *= (Vector3.One - frictionFactor); } - MDetailLog("{0},BSVMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},timeScale={5},addAmnt={6},targetDecay={7},decayFact={8},fricTS={9},frictFact={10}", + MDetailLog("{0}, BSVMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},timeScale={5},addAmnt={6},targetDecay={7},decayFact={8},fricTS={9},frictFact={10}", BSScene.DetailLogZero, UseName, origCurrVal, origTarget, timeStep, TimeScale, addAmount, TargetValueDecayTimeScale, decayFactor, FrictionTimescale, frictionFactor); - MDetailLog("{0},BSVMotor.Step,nonZero,{1},curr={2},target={3},add={4},decay={5},frict={6},ret={7}", + MDetailLog("{0}, BSVMotor.Step,nonZero,{1},curr={2},target={3},add={4},decay={5},frict={6},ret={7}", BSScene.DetailLogZero, UseName, CurrentValue, TargetValue, addAmount, decayFactor, frictionFactor, returnCurrent); } @@ -158,7 +158,7 @@ public class BSVMotor : BSMotor CurrentValue = Vector3.Zero; TargetValue = Vector3.Zero; - MDetailLog("{0},BSVMotor.Step,zero,{1},curr={2},target={3},ret={4}", + MDetailLog("{0}, BSVMotor.Step,zero,{1},curr={2},target={3},ret={4}", BSScene.DetailLogZero, UseName, TargetValue, CurrentValue, returnCurrent); } -- cgit v1.1 From 10fcc70b36aa1b38cd92e9c4d9c441e4c0eeb5f6 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 2 Dec 2012 20:07:05 -0800 Subject: BulletSim: revert angular vertical attraction from motor to code. The motor code did not return the restoring difference but the current value. Remove unused commented out code. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 66 +++++++--------------- 1 file changed, 19 insertions(+), 47 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index cbad3bf..4d067cf 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -125,7 +125,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin //Attractor properties private BSVMotor m_verticalAttractionMotor = new BSVMotor("VerticalAttraction"); private float m_verticalAttractionEfficiency = 1.0f; // damped - private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. + private float m_verticalAttractionTimescale = 600f; // Timescale > 500 means no vert attractor. public BSDynamics(BSScene myScene, BSPrim myPrim) { @@ -573,6 +573,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Vector3 localInertia = new Vector3(1f, 1f, 1f); Vector3 localInertia = new Vector3(m_vehicleMass, m_vehicleMass, m_vehicleMass); BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia); + BulletSimAPI.UpdateInertiaTensor2(Prim.PhysBody.ptr); VDetailLog("{0},BSDynamics.Refresh,frict={1},inert={2},aDamp={3}", Prim.LocalID, friction, localInertia, angularDamping); @@ -958,34 +959,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Apply the effect of the angular motor. private void MoveAngular(float pTimestep) { - // m_angularMotorDirection // angular velocity requested by LSL motor - // m_angularMotorVelocity // current angular motor velocity (ramps up and down) - // m_angularMotorTimescale // motor angular velocity ramp up time - // m_angularMotorDecayTimescale // motor angular velocity decay rate - // m_angularFrictionTimescale // body angular velocity decay rate - // m_lastAngularVelocity // what was last applied to body - - /* - if (m_angularMotorDirection.LengthSquared() > 0.0001) - { - Vector3 origVel = m_angularMotorVelocity; - Vector3 origDir = m_angularMotorDirection; - - // new velocity += error / ( time to get there / step interval) - // requested direction - current vehicle direction - m_angularMotorVelocity += (m_angularMotorDirection - m_angularMotorVelocity) / (m_angularMotorTimescale / pTimestep); - // decay requested direction - m_angularMotorDirection *= (1.0f - (pTimestep * 1.0f/m_angularMotorDecayTimescale)); - - VDetailLog("{0}, MoveAngular,angularMotorApply,angTScale={1},timeStep={2},origvel={3},origDir={4},vel={5}", - Prim.LocalID, m_angularMotorTimescale, pTimestep, origVel, origDir, m_angularMotorVelocity); - } - else - { - m_angularMotorVelocity = Vector3.Zero; - } - */ - Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); // ================================================================== @@ -1050,9 +1023,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ================================================================== if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) { - m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. // TODO: zeroing is good but it also sets values in unmanaged code. Remove the stores when idle. - VDetailLog("{0}, MoveAngular,done,zero,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); + VDetailLog("{0}, MoveAngular,done,zero", Prim.LocalID); VehicleRotationalVelocity = Vector3.Zero; Prim.ZeroAngularMotion(true); } @@ -1063,15 +1035,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Since we are stuffing the angular velocity directly into the object, the computed // velocity needs to be scaled by the timestep. // Also remove any motion that is on the object so added motion is only from vehicle. - Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep) - VehicleRotationalVelocity); - // Unscale the force by the angular factor so it overwhelmes the Bullet additions. - VehicleRotationalVelocity = applyAngularForce; + Vector3 setAngularVelocity = ((m_lastAngularVelocity * pTimestep) - VehicleRotationalVelocity); + VehicleRotationalVelocity = setAngularVelocity; - VDetailLog("{0}, MoveAngular,done,nonZero,angMotor={1},vertAttr={2},bank={3},deflect={4},newAngForce={5},lastAngular={6}", + VDetailLog("{0}, MoveAngular,done,nonZero,angMotorContrib={1},vertAttrContrib={2},bankContrib={3},deflectContrib={4},totalContrib={5},setAngVelocity={6}", Prim.LocalID, angularMotorContribution, verticalAttractionContribution, bankingContribution, deflectionContribution, - applyAngularForce, m_lastAngularVelocity + m_lastAngularVelocity, setAngularVelocity ); } } @@ -1083,12 +1054,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin // If vertical attaction timescale is reasonable and we applied an angular force last time... if (m_verticalAttractionTimescale < 500) { + /* Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; verticalError.Normalize(); m_verticalAttractionMotor.SetCurrent(verticalError); m_verticalAttractionMotor.SetTarget(Vector3.UnitZ); ret = m_verticalAttractionMotor.Step(pTimestep); - /* + */ // Take a vector pointing up and convert it from world to vehicle relative coords. Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; verticalError.Normalize(); @@ -1108,25 +1080,25 @@ namespace OpenSim.Region.Physics.BulletSPlugin } // Y error means needed rotation around X axis and visa versa. - verticalAttractionContribution.X = verticalError.Y; - verticalAttractionContribution.Y = - verticalError.X; - verticalAttractionContribution.Z = 0f; + ret.X = verticalError.Y; + ret.Y = - verticalError.X; + ret.Z = 0f; // scale by the time scale and timestep - Vector3 unscaledContrib = verticalAttractionContribution; - verticalAttractionContribution /= m_verticalAttractionTimescale; - verticalAttractionContribution *= pTimestep; + Vector3 unscaledContrib = ret; + ret /= m_verticalAttractionTimescale; + ret *= pTimestep; // apply efficiency - Vector3 preEfficiencyContrib = verticalAttractionContribution; + Vector3 preEfficiencyContrib = ret; + // Effenciency squared seems to give a more realistic effect float efficencySquared = m_verticalAttractionEfficiency * m_verticalAttractionEfficiency; - verticalAttractionContribution *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); + ret *= efficencySquared; VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},preEff={3},eff={4},effSq={5},vertAttr={6}", Prim.LocalID, verticalError, unscaledContrib, preEfficiencyContrib, m_verticalAttractionEfficiency, efficencySquared, - verticalAttractionContribution); - */ + ret); } return ret; -- cgit v1.1 From dc0497c1b831b3bb8fe021d48520bbff7305ce2e Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 2 Dec 2012 20:08:11 -0800 Subject: BulletSim: begin tracking a TODO list. There just are so many things to remember to do. --- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 112 +++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100755 OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt new file mode 100755 index 0000000..cf112fb --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -0,0 +1,112 @@ +CRASHES +================================================= +20121129.1411: editting/moving phys object across region boundries causes crash + getPos-> btRigidBody::upcast -> getBodyType -> BOOM +20121128.1600: mesh object not rezzing (no physics mesh). + Causes many errors. Doesn't stop after first error with box shape. + Eventually crashes when deleting the object. + +BULLETSIM TODO LIST: +================================================= +Neb car jiggling left and right +Vehicles (Move smoothly) +Light cycle falling over when driving +Light cycle not banking +Do single prim vehicles don't seem to properly vehiclize. +Gun sending shooter flying +Collision margin (gap between physical objects lying on each other) +Boundry checking (crashes related to crossing boundry) + Add check for border edge position for avatars and objects. + Verify the events are created for border crossings. +Avatar rotation (check out changes to ScenePresence for physical rotation) +Avatar running (what does phys engine need to do?) +Small physical objects do not interact correctly + Create chain of .5x.5x.1 torui and make all but top physical so to hang. + The chain will fall apart and pairs will dance around on ground + Chains of 1x1x.2 will stay connected but will dance. + Chains above 2x2x.4 are move stable and get stablier as torui get larger. +Add material type linkage and input all the material property definitions. + Skeleton classes and table are in the sources but are not filled or used. + +After getting off a vehicle, the root prim is phantom (can be walked through) + Need to force a position update for the root prim after compound shape destruction +Find/remove avatar collision with ID=0. +Test avatar walking up stairs. How does compare with SL. + Radius of the capsule affects ability to climb edges. +Tune terrain/object friction to be closer to SL. +Debounce avatar contact so legs don't keep folding up when standing. +Implement LSL physics controls. Like STATUS_ROTATE_X. +Add border extensions to terrain to help region crossings and objects leaving region. +Linkset explosion after three "rides" on Nebadon lite vehicle (LinksetConstraint) + +Speed up creation of large physical linksets + For instance, sitting in Neb's car (130 prims) takes several seconds to become physical +Performance test with lots of avatars. Can BulletSim support a thousand? +Optimize collisions in C++: only send up to the object subscribed to collisions. + Use collision subscription and remove the collsion(A,B) and collision(B,A) +Check wheter SimMotionState needs large if statement (see TODO). + +Implement 'top colliders' info. +Avatar jump +Implement meshes or just verify that they work. +Do prim hash codes work for sculpties and meshes? +Performance measurement and changes to make quicker. +Implement detailed physics stats (GetStats()). + +Eliminate collisions between objects in a linkset. (LinksetConstraint) + Have UserPointer point to struct with localID and linksetID? + Objects in original linkset still collide with each other? + +Measure performance improvement from hulls +Test not using ghost objects for volume detect implementation. +Performance of closures and delegates for taint processing + Are there faster ways? + Is any slowdown introduced by the existing implementation significant? +Is there are more efficient method of implementing pre and post step actions? + See http://www.codeproject.com/Articles/29922/Weak-Events-in-C + +Package Bullet source mods for Bullet internal stats output + +Physics Arena central pyramid: why is one side permiable? + +INTERNAL IMPROVEMENT/CLEANUP +================================================= +Remove unused fields from ShapeData (not used in API2) +Breakout code for mesh/hull/compound/native into separate BSShape* classes + Standardize access to building and reference code. + The skeleton classes are in the sources but are not complete or linked in. +Generalize Dynamics and PID with standardized motors. +Generalize Linkset and vehicles into PropertyManagers + Methods for Refresh, RemoveBodyDependencies, RestoreBodyDependencies + Possibly generalized a 'per step action' registration. +Implement linkset by setting position of children when root updated. (LinksetManual) +LinkablePrim class? Would that simplify/centralize the linkset logic? +Linkset implementation using manual prim movement. +Linkset implementation using compound shapes. + Compound shapes will need the LocalID in the shapes and collision + processing to get it from there. +BSScene.UpdateParameterSet() is broken. How to set params on objects? +Remove HeightmapInfo from terrain specification. + Since C++ code does not need terrain height, this structure et al are not needed. +Add floating motor for BS_FLOATS_ON_WATER so prim and avatar will + bob at the water level. BSPrim.PositionSanityCheck(). + +DONE DONE DONE DONE +================================================= +Cleanup code in BSDynamics by using motors. +Consider implementing terrain with a mesh rather than heightmap. + Would have better and adjustable resolution. +NOTDONE: Build terrain mesh so heighmap is height of the center of the square meter. + SL and ODE define meter square as being at one corner with one diagional. +Terrain as mesh. +How are static linksets seen by the physics engine? + A: they are not linked in physics. When moved, all the children are repositioned. +Remember to remove BSScene.DetailLog Refresh call. +Convert BSCharacter to use all API2 +Avatar pushing difficult (too heavy?) +Use asset service passed to BulletSim to get sculptie bodies, etc. +Vehicles (fix bouncing on terrain) +Remove old code in DLL (all non-API2 stuff). +Measurements of mega-physical prim performance (with graph) +Debug Bullet internal stats output (why is timing all wrong?) + Bullet stats logging only works with a single instance of Bullet (one region). \ No newline at end of file -- cgit v1.1 From 2586bab2dde141c4d01c81c54291394ba07b1ee7 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 2 Dec 2012 20:45:46 -0800 Subject: BulletSim: add stubs for generalization of preStep actions. Will eventually replace the specialized vehicle processing with preStep event processing. Add TODO comments about this feature. Redo line endings in TODO file to be all Linux. --- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 19 +++++++++++++++++-- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 6 +++++- 2 files changed, 22 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 5e70a23..17cc7b4 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -96,6 +96,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public long SimulationStep { get { return m_simulationStep; } } private int m_taintsToProcessPerStep; + public delegate void PreStepAction(float timeStep); + public event PreStepAction BeforeStep; + // A value of the time now so all the collision and update routines do not have to get their own // Set to 'now' just before all the prims and actors are called for collisions and updates public int SimulationNowTime { get; private set; } @@ -487,8 +490,10 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters ProcessTaints(); // Some of the prims operate with special vehicle properties - ProcessVehicles(timeStep); - ProcessTaints(); // the vehicles might have added taints + DoPreStepActions(timeStep); + + // the prestep actions might have added taints + ProcessTaints(); // step the physical world one interval m_simulationStep++; @@ -907,6 +912,16 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters } } + private void DoPreStepActions(float timeStep) + { + ProcessVehicles(timeStep); + + PreStepAction actions = BeforeStep; + if (actions != null) + actions(timeStep); + + } + // Some prims have extra vehicle actions // Called at taint time! private void ProcessVehicles(float timeStep) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index cf112fb..ca71313 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -27,6 +27,7 @@ Small physical objects do not interact correctly Chains above 2x2x.4 are move stable and get stablier as torui get larger. Add material type linkage and input all the material property definitions. Skeleton classes and table are in the sources but are not filled or used. +Add PID motor for avatar movement (slow to stop, ...) After getting off a vehicle, the root prim is phantom (can be walked through) Need to force a position update for the root prim after compound shape destruction @@ -78,7 +79,10 @@ Breakout code for mesh/hull/compound/native into separate BSShape* classes Generalize Dynamics and PID with standardized motors. Generalize Linkset and vehicles into PropertyManagers Methods for Refresh, RemoveBodyDependencies, RestoreBodyDependencies - Possibly generalized a 'per step action' registration. + Possibly generalized a 'pre step action' registration. +Complete implemention of preStepActions + Replace vehicle step call with prestep event. + Is there a need for postStepActions? postStepTaints? Implement linkset by setting position of children when root updated. (LinksetManual) LinkablePrim class? Would that simplify/centralize the linkset logic? Linkset implementation using manual prim movement. -- cgit v1.1 From 41f1c5b7f712ed9c093ce421b39460c7711aece4 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 2 Dec 2012 23:39:17 -0800 Subject: BulletSim: rework angular corrections to remove any hybrid code and compute absolute collections. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 204 ++++++++++----------- OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 17 +- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 4 +- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 1 + 4 files changed, 115 insertions(+), 111 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 4d067cf..525aac4 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -98,7 +98,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate - private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body + private Vector3 m_lastAngularCorrection = Vector3.Zero; private Vector3 m_lastVertAttractor = Vector3.Zero; // what VA was last applied to body //Deflection properties @@ -111,6 +111,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin private float m_bankingEfficiency = 0; private float m_bankingMix = 0; private float m_bankingTimescale = 0; + private Vector3 m_lastBanking = Vector3.Zero; //Hover and Buoyancy properties private float m_VhoverHeight = 0f; @@ -152,7 +153,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_angularDeflectionTimescale = Math.Max(pValue, 0.01f); break; case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE: - m_angularMotorDecayTimescale = Math.Max(0.01f, Math.Min(pValue,120)); + m_angularMotorDecayTimescale = ClampInRange(0.01f, pValue, 120); m_angularMotor.TargetValueDecayTimeScale = m_angularMotorDecayTimescale; break; case Vehicle.ANGULAR_MOTOR_TIMESCALE: @@ -240,9 +241,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin break; case Vehicle.ANGULAR_MOTOR_DIRECTION: // Limit requested angular speed to 2 rps= 4 pi rads/sec - pValue.X = Math.Max(-12.56f, Math.Min(pValue.X, 12.56f)); - pValue.Y = Math.Max(-12.56f, Math.Min(pValue.Y, 12.56f)); - pValue.Z = Math.Max(-12.56f, Math.Min(pValue.Z, 12.56f)); + pValue.X = ClampInRange(-12.56f, pValue.X, 12.56f); + pValue.Y = ClampInRange(-12.56f, pValue.Y, 12.56f); + pValue.Z = ClampInRange(-12.56f, pValue.Z, 12.56f); m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); m_angularMotor.SetTarget(m_angularMotorDirection); break; @@ -328,6 +329,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingEfficiency = 0; m_bankingTimescale = 1000; m_bankingMix = 1; + m_lastBanking = Vector3.Zero; m_referenceFrame = Quaternion.Identity; m_flags = (VehicleFlag)0; @@ -362,6 +364,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingEfficiency = 0; m_bankingTimescale = 10; m_bankingMix = 1; + m_lastBanking = Vector3.Zero; m_referenceFrame = Quaternion.Identity; m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY @@ -400,6 +403,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingEfficiency = -0.2f; m_bankingMix = 1; m_bankingTimescale = 1; + m_lastBanking = Vector3.Zero; m_referenceFrame = Quaternion.Identity; m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY @@ -438,6 +442,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingEfficiency = -0.3f; m_bankingMix = 0.8f; m_bankingTimescale = 1; + m_lastBanking = Vector3.Zero; m_referenceFrame = Quaternion.Identity; m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY @@ -476,6 +481,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingEfficiency = 1; m_bankingMix = 0.7f; m_bankingTimescale = 2; + m_lastBanking = Vector3.Zero; m_referenceFrame = Quaternion.Identity; m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY @@ -514,6 +520,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingEfficiency = 0; m_bankingMix = 0.7f; m_bankingTimescale = 5; + m_lastBanking = Vector3.Zero; + m_referenceFrame = Quaternion.Identity; m_referenceFrame = Quaternion.Identity; @@ -627,12 +635,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin { if (m_knownChanged != 0) { - if ((m_knownChanged & m_knownChangedPosition) != 0) Prim.ForcePosition = VehiclePosition; - if ((m_knownChanged & m_knownChangedOrientation) != 0) Prim.ForceOrientation = VehicleOrientation; - if ((m_knownChanged & m_knownChangedVelocity) != 0) Prim.ForceVelocity = VehicleVelocity; - if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) Prim.ForceRotationalVelocity = VehicleRotationalVelocity; - // If we set one of the values (ie, the physics engine doesn't do it) we must make sure there - // is an UpdateProperties event to send the changes up to the simulator. + if ((m_knownChanged & m_knownChangedPosition) != 0) + Prim.ForcePosition = VehiclePosition; + if ((m_knownChanged & m_knownChangedOrientation) != 0) + Prim.ForceOrientation = VehicleOrientation; + if ((m_knownChanged & m_knownChangedVelocity) != 0) + Prim.ForceVelocity = VehicleVelocity; + if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) + Prim.ForceRotationalVelocity = VehicleRotationalVelocity; + // If we set one of the values (ie, the physics engine didn't do it) we must force + // an UpdateProperties event to send the changes up to the simulator. BulletSimAPI.PushUpdate2(Prim.PhysBody.ptr); } } @@ -957,9 +969,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ======================================================================= // ======================================================================= // Apply the effect of the angular motor. + // The 'contribution' is how much angular correction each function wants. + // All the contributions are added together and the orientation of the vehicle + // is changed by all the contributed corrections. private void MoveAngular(float pTimestep) { - Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); + Vector3 angularMotorContribution = m_angularMotor.Step(); // ================================================================== // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags : @@ -974,22 +989,41 @@ namespace OpenSim.Region.Physics.BulletSPlugin VDetailLog("{0}, MoveAngular,noDeflectionUp,angularMotorContrib={1}", Prim.LocalID, angularMotorContribution); } - Vector3 verticalAttractionContribution = ComputeAngularVerticalAttraction(pTimestep); + Vector3 verticalAttractionContribution = ComputeAngularVerticalAttraction(); - Vector3 deflectionContribution = ComputeAngularDeflection(pTimestep); + Vector3 deflectionContribution = ComputeAngularDeflection(); - Vector3 bankingContribution = ComputeAngularBanking(pTimestep); + Vector3 bankingContribution = ComputeAngularBanking(angularMotorContribution.Z); // ================================================================== m_lastVertAttractor = verticalAttractionContribution; - // Sum velocities - m_lastAngularVelocity = angularMotorContribution + // Sum corrections + m_lastAngularCorrection = angularMotorContribution + verticalAttractionContribution + deflectionContribution + bankingContribution; // ================================================================== + // The correction is applied to the current orientation. + // Any angular velocity on the vehicle is not us so zero the current value. + VehicleRotationalVelocity = Vector3.Zero; + if (!m_lastAngularCorrection.ApproxEquals(Vector3.Zero, 0.01f)) + { + Vector3 scaledCorrection = m_lastAngularCorrection * pTimestep; + Quaternion quatCorrection = Quaternion.CreateFromEulers(scaledCorrection); + + VehicleOrientation = Quaternion.Add(VehicleOrientation, quatCorrection); + + VDetailLog("{0}, MoveAngular,done,nonZero,angMotorContrib={1},vertAttrContrib={2},bankContrib={3},deflectContrib={4},totalContrib={5},scaledCorr={6}", + Prim.LocalID, + angularMotorContribution, verticalAttractionContribution, + bankingContribution, deflectionContribution, + m_lastAngularCorrection, scaledCorrection + ); + } + + // ================================================================== //Offset section if (m_linearMotorOffset != Vector3.Zero) { @@ -1020,50 +1054,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin VDetailLog("{0}, BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset); } - // ================================================================== - if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) - { - // TODO: zeroing is good but it also sets values in unmanaged code. Remove the stores when idle. - VDetailLog("{0}, MoveAngular,done,zero", Prim.LocalID); - VehicleRotationalVelocity = Vector3.Zero; - Prim.ZeroAngularMotion(true); - } - else - { - // Apply to the body. - // The above calculates the absolute angular velocity needed. Angular velocity is massless. - // Since we are stuffing the angular velocity directly into the object, the computed - // velocity needs to be scaled by the timestep. - // Also remove any motion that is on the object so added motion is only from vehicle. - Vector3 setAngularVelocity = ((m_lastAngularVelocity * pTimestep) - VehicleRotationalVelocity); - VehicleRotationalVelocity = setAngularVelocity; - - VDetailLog("{0}, MoveAngular,done,nonZero,angMotorContrib={1},vertAttrContrib={2},bankContrib={3},deflectContrib={4},totalContrib={5},setAngVelocity={6}", - Prim.LocalID, - angularMotorContribution, verticalAttractionContribution, - bankingContribution, deflectionContribution, - m_lastAngularVelocity, setAngularVelocity - ); - } } - public Vector3 ComputeAngularVerticalAttraction(float pTimestep) + public Vector3 ComputeAngularVerticalAttraction() { Vector3 ret = Vector3.Zero; // If vertical attaction timescale is reasonable and we applied an angular force last time... if (m_verticalAttractionTimescale < 500) { - /* - Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; - verticalError.Normalize(); - m_verticalAttractionMotor.SetCurrent(verticalError); - m_verticalAttractionMotor.SetTarget(Vector3.UnitZ); - ret = m_verticalAttractionMotor.Step(pTimestep); - */ // Take a vector pointing up and convert it from world to vehicle relative coords. Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; - verticalError.Normalize(); + // verticalError.Normalize(); // If vertical attraction correction is needed, the vector that was pointing up (UnitZ) // is now leaning to one side (rotated around the X axis) and the Y value will @@ -1087,56 +1089,63 @@ namespace OpenSim.Region.Physics.BulletSPlugin // scale by the time scale and timestep Vector3 unscaledContrib = ret; ret /= m_verticalAttractionTimescale; - ret *= pTimestep; + // This returns the angular correction desired. Timestep is added later. + // ret *= pTimestep; // apply efficiency Vector3 preEfficiencyContrib = ret; + // TODO: implement efficiency. // Effenciency squared seems to give a more realistic effect float efficencySquared = m_verticalAttractionEfficiency * m_verticalAttractionEfficiency; - ret *= efficencySquared; + // ret *= efficencySquared; VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},preEff={3},eff={4},effSq={5},vertAttr={6}", Prim.LocalID, verticalError, unscaledContrib, preEfficiencyContrib, m_verticalAttractionEfficiency, efficencySquared, ret); - } return ret; } - public Vector3 ComputeAngularDeflection(float pTimestep) + // Return the angular correction to correct the direction the vehicle is pointing to be + // the direction is should want to be pointing. + public Vector3 ComputeAngularDeflection() { Vector3 ret = Vector3.Zero; if (m_angularDeflectionEfficiency != 0) { - // Compute a scaled vector that points in the preferred axis (X direction) - Vector3 scaledDefaultDirection = - new Vector3((pTimestep * 10 * (m_angularDeflectionEfficiency / m_angularDeflectionTimescale)), 0, 0); - // Adding the current vehicle orientation and reference frame displaces the orientation to the frame. - // Rotate the scaled default axix relative to the actual vehicle direction giving where it should point. - Vector3 preferredAxisOfMotion = scaledDefaultDirection * Quaternion.Add(VehicleOrientation, m_referenceFrame); + // Where the vehicle should want to point relative to the vehicle + Vector3 preferredDirection = Vector3.UnitX * m_referenceFrame; + + // Where the vehicle is pointing relative to the vehicle. + Vector3 currentDirection = Vector3.UnitX * Quaternion.Add(VehicleOrientation, m_referenceFrame); - // Scale by efficiency and timescale - ret = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep; + // Difference between where vehicle is pointing and where it should wish to point + Vector3 directionCorrection = preferredDirection - currentDirection; - VDetailLog("{0}, MoveAngular,Deflection,perfAxis={1},deflection={2}", Prim.LocalID, preferredAxisOfMotion, ret); + // Scale the correction by recovery timescale and efficiency + ret = directionCorrection * m_angularDeflectionEfficiency / m_angularDeflectionTimescale; - // This deflection computation is not correct. - ret = Vector3.Zero; + VDetailLog("{0}, MoveAngular,Deflection,perfDir={1},currentDir={2},dirCorrection={3},ret={4}", + Prim.LocalID, preferredDirection, currentDirection, directionCorrection, ret); } return ret; } - public Vector3 ComputeAngularBanking(float pTimestep) + // Return an angular change to tip the vehicle (around X axis) when turning (turned around Z). + // Remembers the last banking value calculated and returns the difference needed this tick. + // TurningFactor is rate going left or right (pos=left, neg=right, scale=0..1). + public Vector3 ComputeAngularBanking(float turningFactor) { Vector3 ret = Vector3.Zero; + Vector3 computedBanking = Vector3.Zero; if (m_bankingEfficiency != 0) { - Vector3 dir = Vector3.One * VehicleOrientation; + Vector3 currentDirection = Vector3.UnitX * VehicleOrientation; + float mult = (m_bankingMix * m_bankingMix) * -1 * (m_bankingMix < 0 ? -1 : 1); - //Changes which way it banks in and out of turns //Use the square of the efficiency, as it looks much more how SL banking works float effSquared = (m_bankingEfficiency * m_bankingEfficiency); @@ -1144,51 +1153,27 @@ namespace OpenSim.Region.Physics.BulletSPlugin effSquared *= -1; //Keep the negative! float mix = Math.Abs(m_bankingMix); - if (m_angularMotorVelocity.X == 0) - { - // The vehicle is stopped - /*if (!parent.Orientation.ApproxEquals(this.m_referenceFrame, 0.25f)) - { - Vector3 axisAngle; - float angle; - parent.Orientation.GetAxisAngle(out axisAngle, out angle); - Vector3 rotatedVel = parent.Velocity * parent.Orientation; - if ((rotatedVel.X < 0 && axisAngle.Y > 0) || (rotatedVel.X > 0 && axisAngle.Y < 0)) - m_angularMotorVelocity.X += (effSquared * (mult * mix)) * (1f) * 10; - else - m_angularMotorVelocity.X += (effSquared * (mult * mix)) * (-1f) * 10; - }*/ - } - else - { - ret.Z += (effSquared * (mult * mix)) * (m_angularMotorVelocity.X) * 4; - } + // TODO: Must include reference frame. + float forwardSpeed = VehicleVelocity.X; - //If they are colliding, we probably shouldn't shove the prim around... probably - if (!Prim.IsColliding && Math.Abs(m_angularMotorVelocity.X) > mix) + if (!Prim.IsColliding && forwardSpeed > mix) { - float angVelZ = m_angularMotorVelocity.X * -1; - /*if(angVelZ > mix) - angVelZ = mix; - else if(angVelZ < -mix) - angVelZ = -mix;*/ - //This controls how fast and how far the banking occurs - Vector3 bankingRot = new Vector3(angVelZ * (effSquared * mult), 0, 0); - if (bankingRot.X > 3) - bankingRot.X = 3; - else if (bankingRot.X < -3) - bankingRot.X = -3; - bankingRot *= VehicleOrientation; - ret += bankingRot; + computedBanking.X = ClampInRange(-3f, turningFactor * (effSquared * mult), 3f); } - m_angularMotorVelocity.X *= m_bankingEfficiency == 1 ? 0.0f : 1 - m_bankingEfficiency; - VDetailLog("{0}, MoveAngular,Banking,bEff={1},angMotVel={2},effSq={3},mult={4},mix={5},banking={6}", - Prim.LocalID, m_bankingEfficiency, m_angularMotorVelocity, effSquared, mult, mix, ret); + + // 'computedBanking' is now how much banking that should be happening. + ret = computedBanking - m_lastBanking; + + // Scale the correction by timescale and efficiency + ret /= m_bankingTimescale * m_bankingEfficiency; + + VDetailLog("{0}, MoveAngular,Banking,computedB={1},lastB={2},bEff={3},effSq={4},mult={5},mix={6},banking={7}", + Prim.LocalID, computedBanking, m_lastBanking, m_bankingEfficiency, effSquared, mult, mix, ret); } + m_lastBanking = computedBanking; return ret; } - // This is from previous instantiations of XXXDynamics.cs. // Applies roll reference frame. // TODO: is this the right way to separate the code to do this operation? @@ -1229,6 +1214,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin } + private float ClampInRange(float low, float val, float high) + { + return Math.Max(low, Math.Min(val, high)); + } + // Invoke the detailed logger and output something if it's enabled. private void VDetailLog(string msg, params Object[] args) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index e9f1549..851d508 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -63,10 +63,23 @@ public abstract class BSMotor } } // Can all the incremental stepping be replaced with motor classes? + +// Motor which moves CurrentValue to TargetValue over TimeScale seconds. +// The TargetValue is decays in TargetValueDecayTimeScale and +// the CurrentValue will be held back by FrictionTimeScale. +// TimeScale and TargetDelayTimeScale may be 'infinite' which means go decay. + +// For instance, if something is moving at speed X and the desired speed is Y, +// CurrentValue is X and TargetValue is Y. As the motor is stepped, new +// values of CurrentValue are returned that approach the TargetValue. +// The feature of decaying TargetValue is so vehicles will eventually +// come to a stop rather than run forever. This can be disabled by +// setting TargetValueDecayTimescale to 'infinite'. +// The change from CurrentValue to TargetValue is linear over TimeScale seconds. public class BSVMotor : BSMotor { - public Vector3 FrameOfReference { get; set; } - public Vector3 Offset { get; set; } + // public Vector3 FrameOfReference { get; set; } + // public Vector3 Offset { get; set; } public float TimeScale { get; set; } public float TargetValueDecayTimeScale { get; set; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 17cc7b4..f72bd74 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -501,7 +501,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters try { - // if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG + if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount(); numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep, @@ -510,7 +510,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime); DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}", DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount); - // if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG + if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG } catch (Exception e) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index ca71313..68f25fc 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -28,6 +28,7 @@ Small physical objects do not interact correctly Add material type linkage and input all the material property definitions. Skeleton classes and table are in the sources but are not filled or used. Add PID motor for avatar movement (slow to stop, ...) +Implement function efficiency for lineaar and angular motion. After getting off a vehicle, the root prim is phantom (can be walked through) Need to force a position update for the root prim after compound shape destruction -- cgit v1.1 From 787636b97ac242c3a903664a2fe1f26ea8c0130a Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 3 Dec 2012 16:25:51 -0800 Subject: BulletSim: Reduce idle region physics overhead where there are MANY static objects by more restrictive selection of objects that collide with static objects. Rename collision mask fuctions from 'filter' to 'group' so it is clear what is being set. Rename BulletSimAPI.SetCollisionFilterMask() to SetCollisionGroupMask to match above. Restore passing of time step to linear and angular motion component routines. Use buffering vehicle physical parameter get/set routines consistantly. Make range enforcement clearer by using ClampInRange() function for parameter setting. Remove commented out experimental vehicle calculations. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 4 +- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 81 ++++++++++++---------- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 14 ++-- .../Physics/BulletSPlugin/BSTerrainHeightmap.cs | 4 +- .../Physics/BulletSPlugin/BSTerrainManager.cs | 4 +- .../Region/Physics/BulletSPlugin/BSTerrainMesh.cs | 4 +- .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 64 ++++++++--------- 7 files changed, 95 insertions(+), 80 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 1dfc420..21aa9be 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -165,8 +165,8 @@ public sealed class BSCharacter : BSPhysObject BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); // Do this after the object has been added to the world - BulletSimAPI.SetCollisionFilterMask2(PhysBody.ptr, - (uint)CollisionFilterGroups.AvatarFilter, + BulletSimAPI.SetCollisionGroupMask2(PhysBody.ptr, + (uint)CollisionFilterGroups.AvatarGroup, (uint)CollisionFilterGroups.AvatarMask); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 525aac4..be8a502 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -161,7 +161,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_angularMotor.TimeScale = m_angularMotorTimescale; break; case Vehicle.BANKING_EFFICIENCY: - m_bankingEfficiency = Math.Max(-1f, Math.Min(pValue, 1f)); + m_bankingEfficiency = ClampInRange(-1f, pValue, 1f); break; case Vehicle.BANKING_MIX: m_bankingMix = Math.Max(pValue, 0.01f); @@ -170,10 +170,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingTimescale = Math.Max(pValue, 0.01f); break; case Vehicle.BUOYANCY: - m_VehicleBuoyancy = Math.Max(-1f, Math.Min(pValue, 1f)); + m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f); break; case Vehicle.HOVER_EFFICIENCY: - m_VhoverEfficiency = Math.Max(0f, Math.Min(pValue, 1f)); + m_VhoverEfficiency = ClampInRange(0f, pValue, 1f); break; case Vehicle.HOVER_HEIGHT: m_VhoverHeight = pValue; @@ -188,7 +188,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_linearDeflectionTimescale = Math.Max(pValue, 0.01f); break; case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE: - m_linearMotorDecayTimescale = Math.Max(0.01f, Math.Min(pValue,120)); + m_linearMotorDecayTimescale = ClampInRange(0.01f, pValue, 120); m_linearMotor.TargetValueDecayTimeScale = m_linearMotorDecayTimescale; break; case Vehicle.LINEAR_MOTOR_TIMESCALE: @@ -196,7 +196,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_linearMotor.TimeScale = m_linearMotorTimescale; break; case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: - m_verticalAttractionEfficiency = Math.Max(0.1f, Math.Min(pValue, 1f)); + m_verticalAttractionEfficiency = ClampInRange(0.1f, pValue, 1f); m_verticalAttractionMotor.Efficiency = m_verticalAttractionEfficiency; break; case Vehicle.VERTICAL_ATTRACTION_TIMESCALE: @@ -607,10 +607,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin } #region Known vehicle value functions + // Vehicle physical parameters that we buffer from constant getting and setting. + // The "m_known*" variables are initialized to 'null', fetched only if referenced + // and stored back into the physics engine only if updated. + // This does two things: 1) saves continuious calls into unmanaged code, and + // 2) signals when a physics property update must happen back to the simulator + // to update values modified for the vehicle. private int m_knownChanged; private float? m_knownTerrainHeight; private float? m_knownWaterLevel; - private Vector3? m_knownPosition; private Vector3? m_knownVelocity; private Quaternion? m_knownOrientation; @@ -642,7 +647,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin if ((m_knownChanged & m_knownChangedVelocity) != 0) Prim.ForceVelocity = VehicleVelocity; if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) + { Prim.ForceRotationalVelocity = VehicleRotationalVelocity; + BulletSimAPI.SetInterpolationAngularVelocity2(Prim.PhysBody.ptr, VehicleRotationalVelocity); + } // If we set one of the values (ie, the physics engine didn't do it) we must force // an UpdateProperties event to send the changes up to the simulator. BulletSimAPI.PushUpdate2(Prim.PhysBody.ptr); @@ -766,15 +774,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy); - Vector3 pos = VehiclePosition; - - Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(ref pos); + Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(pTimestep); - Vector3 hoverContribution = ComputeLinearHover(ref pos); + Vector3 hoverContribution = ComputeLinearHover(pTimestep); - ComputeLinearBlockingEndPoint(ref pos); + ComputeLinearBlockingEndPoint(pTimestep); - Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pos); + Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pTimestep); // ================================================================== Vector3 newVelocity = linearMotorContribution @@ -820,22 +826,21 @@ namespace OpenSim.Region.Physics.BulletSPlugin } // end MoveLinear() - public Vector3 ComputeLinearTerrainHeightCorrection(ref Vector3 pos) + public Vector3 ComputeLinearTerrainHeightCorrection(float pTimestep) { Vector3 ret = Vector3.Zero; // If below the terrain, move us above the ground a little. // TODO: Consider taking the rotated size of the object or possibly casting a ray. - if (pos.Z < GetTerrainHeight(pos)) + if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition)) { // TODO: correct position by applying force rather than forcing position. - pos.Z = GetTerrainHeight(pos) + 2; - VehiclePosition = pos; - VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, GetTerrainHeight(pos), pos); + VehiclePosition += new Vector3(0f, 0f, GetTerrainHeight(VehiclePosition) + 2f); + VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition); } return ret; } - public Vector3 ComputeLinearHover(ref Vector3 pos) + public Vector3 ComputeLinearHover(float pTimestep) { Vector3 ret = Vector3.Zero; @@ -846,11 +851,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin // We should hover, get the target height if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0) { - m_VhoverTargetHeight = GetWaterLevel(pos) + m_VhoverHeight; + m_VhoverTargetHeight = GetWaterLevel(VehiclePosition) + m_VhoverHeight; } if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) { - m_VhoverTargetHeight = GetTerrainHeight(pos) + m_VhoverHeight; + m_VhoverTargetHeight = GetTerrainHeight(VehiclePosition) + m_VhoverHeight; } if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0) { @@ -860,14 +865,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0) { // If body is already heigher, use its height as target height - if (pos.Z > m_VhoverTargetHeight) - m_VhoverTargetHeight = pos.Z; + if (VehiclePosition.Z > m_VhoverTargetHeight) + m_VhoverTargetHeight = VehiclePosition.Z; } if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) { - if (Math.Abs(pos.Z - m_VhoverTargetHeight) > 0.2f) + if (Math.Abs(VehiclePosition.Z - m_VhoverTargetHeight) > 0.2f) { + Vector3 pos = VehiclePosition; pos.Z = m_VhoverTargetHeight; VehiclePosition = pos; } @@ -875,7 +881,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin else { // Error is positive if below the target and negative if above. - float verticalError = m_VhoverTargetHeight - pos.Z; + float verticalError = m_VhoverTargetHeight - VehiclePosition.Z; float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; // TODO: implement m_VhoverEfficiency correctly @@ -886,16 +892,17 @@ namespace OpenSim.Region.Physics.BulletSPlugin } VDetailLog("{0}, MoveLinear,hover,pos={1},ret={2},hoverTS={3},height={4},target={5}", - Prim.LocalID, pos, ret, m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight); + Prim.LocalID, VehiclePosition, ret, m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight); } return ret; } - public bool ComputeLinearBlockingEndPoint(ref Vector3 pos) + public bool ComputeLinearBlockingEndPoint(float pTimestep) { bool changed = false; + Vector3 pos = VehiclePosition; Vector3 posChange = pos - m_lastPositionVector; if (m_BlockingEndPoint != Vector3.Zero) { @@ -941,14 +948,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin // VEHICLE_BANKING_TIMESCALE. This is to help prevent ground vehicles from steering // when they are in mid jump. // TODO: this code is wrong. Also, what should it do for boats? - public Vector3 ComputeLinearMotorUp(Vector3 pos) + public Vector3 ComputeLinearMotorUp(float pTimestep) { Vector3 ret = Vector3.Zero; if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) { // If the vehicle is motoring into the sky, get it going back down. // float distanceAboveGround = pos.Z - Math.Max(GetTerrainHeight(pos), GetWaterLevel(pos)); - float distanceAboveGround = pos.Z - GetTerrainHeight(pos); + float distanceAboveGround = VehiclePosition.Z - GetTerrainHeight(VehiclePosition); if (distanceAboveGround > 1f) { // downForce = new Vector3(0, 0, (-distanceAboveGround / m_bankingTimescale) * pTimestep); @@ -969,12 +976,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ======================================================================= // ======================================================================= // Apply the effect of the angular motor. - // The 'contribution' is how much angular correction each function wants. + // The 'contribution' is how much angular correction velocity each function wants. // All the contributions are added together and the orientation of the vehicle // is changed by all the contributed corrections. private void MoveAngular(float pTimestep) { - Vector3 angularMotorContribution = m_angularMotor.Step(); + // The user wants how many radians per second angular change? + Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); // ================================================================== // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags : @@ -1006,14 +1014,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ================================================================== // The correction is applied to the current orientation. - // Any angular velocity on the vehicle is not us so zero the current value. - VehicleRotationalVelocity = Vector3.Zero; if (!m_lastAngularCorrection.ApproxEquals(Vector3.Zero, 0.01f)) { Vector3 scaledCorrection = m_lastAngularCorrection * pTimestep; - Quaternion quatCorrection = Quaternion.CreateFromEulers(scaledCorrection); - VehicleOrientation = Quaternion.Add(VehicleOrientation, quatCorrection); + VehicleRotationalVelocity = scaledCorrection; VDetailLog("{0}, MoveAngular,done,nonZero,angMotorContrib={1},vertAttrContrib={2},bankContrib={3},deflectContrib={4},totalContrib={5},scaledCorr={6}", Prim.LocalID, @@ -1022,6 +1027,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_lastAngularCorrection, scaledCorrection ); } + else + { + // The vehicle is not adding anything velocity wise. + VehicleRotationalVelocity = Vector3.Zero; + VDetailLog("{0}, MoveAngular,done,zero", Prim.LocalID); + } // ================================================================== //Offset section @@ -1065,7 +1076,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { // Take a vector pointing up and convert it from world to vehicle relative coords. Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; - // verticalError.Normalize(); + verticalError.Normalize(); // If vertical attraction correction is needed, the vector that was pointing up (UnitZ) // is now leaning to one side (rotated around the X axis) and the Y value will diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 42a362f..ea1f71a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -646,9 +646,13 @@ public sealed class BSPrim : BSPhysObject BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); // Collision filter can be set only when the object is in the world - if (PhysBody.collisionFilter != 0 || PhysBody.collisionMask != 0) + if (PhysBody.collisionGroup != 0 || PhysBody.collisionMask != 0) { - BulletSimAPI.SetCollisionFilterMask2(PhysBody.ptr, (uint)PhysBody.collisionFilter, (uint)PhysBody.collisionMask); + if (!BulletSimAPI.SetCollisionGroupMask2(PhysBody.ptr, (uint)PhysBody.collisionGroup, (uint)PhysBody.collisionMask)) + { + PhysicsScene.Logger.ErrorFormat("{0} Failure setting prim collision mask. localID={1}, grp={2:X}, mask={3:X}", + LogHeader, LocalID, PhysBody.collisionGroup, PhysBody.collisionMask); + } } // Recompute any linkset parameters. @@ -691,7 +695,7 @@ public sealed class BSPrim : BSPhysObject // Start it out sleeping and physical actions could wake it up. BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ISLAND_SLEEPING); - PhysBody.collisionFilter = CollisionFilterGroups.StaticObjectFilter; + PhysBody.collisionGroup = CollisionFilterGroups.StaticObjectGroup; PhysBody.collisionMask = CollisionFilterGroups.StaticObjectMask; } else @@ -737,7 +741,7 @@ public sealed class BSPrim : BSPhysObject BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ACTIVE_TAG); // BulletSimAPI.Activate2(BSBody.ptr, true); - PhysBody.collisionFilter = CollisionFilterGroups.ObjectFilter; + PhysBody.collisionGroup = CollisionFilterGroups.ObjectGroup; PhysBody.collisionMask = CollisionFilterGroups.ObjectMask; } } @@ -765,7 +769,7 @@ public sealed class BSPrim : BSPhysObject m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for non-solidness. id={1}, type={2}", LogHeader, LocalID, bodyType); } CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); - PhysBody.collisionFilter = CollisionFilterGroups.VolumeDetectFilter; + PhysBody.collisionGroup = CollisionFilterGroups.VolumeDetectGroup; PhysBody.collisionMask = CollisionFilterGroups.VolumeDetectMask; } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs index 0cb151e..83b9c37 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs @@ -121,8 +121,8 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys // redo its bounding box now that it is in the world BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); - BulletSimAPI.SetCollisionFilterMask2(m_mapInfo.terrainBody.ptr, - (uint)CollisionFilterGroups.TerrainFilter, + BulletSimAPI.SetCollisionGroupMask2(m_mapInfo.terrainBody.ptr, + (uint)CollisionFilterGroups.TerrainGroup, (uint)CollisionFilterGroups.TerrainMask); // Make it so the terrain will not move or be considered for movement. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index 17d9536..83df360 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -140,8 +140,8 @@ public sealed class BSTerrainManager // Ground plane does not move BulletSimAPI.ForceActivationState2(m_groundPlane.ptr, ActivationState.DISABLE_SIMULATION); // Everything collides with the ground plane. - BulletSimAPI.SetCollisionFilterMask2(m_groundPlane.ptr, - (uint)CollisionFilterGroups.GroundPlaneFilter, (uint)CollisionFilterGroups.GroundPlaneMask); + BulletSimAPI.SetCollisionGroupMask2(m_groundPlane.ptr, + (uint)CollisionFilterGroups.GroundPlaneGroup, (uint)CollisionFilterGroups.GroundPlaneMask); // Build an initial terrain and put it in the world. This quickly gets replaced by the real region terrain. BSTerrainPhys initialTerrain = new BSTerrainHeightmap(PhysicsScene, Vector3.Zero, BSScene.TERRAIN_ID, DefaultRegionSize); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index 7e93ab4..6ce767d 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs @@ -130,8 +130,8 @@ public sealed class BSTerrainMesh : BSTerrainPhys // Redo its bounding box now that it is in the world BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr); - BulletSimAPI.SetCollisionFilterMask2(m_terrainBody.ptr, - (uint)CollisionFilterGroups.TerrainFilter, + BulletSimAPI.SetCollisionGroupMask2(m_terrainBody.ptr, + (uint)CollisionFilterGroups.TerrainGroup, (uint)CollisionFilterGroups.TerrainMask); // Make it so the terrain will not move or be considered for movement. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 21bc6a3..a5acfd1 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -57,12 +57,12 @@ public struct BulletBody { ID = id; ptr = xx; - collisionFilter = 0; + collisionGroup = 0; collisionMask = 0; } public IntPtr ptr; public uint ID; - public CollisionFilterGroups collisionFilter; + public CollisionFilterGroups collisionGroup; public CollisionFilterGroups collisionMask; public override string ToString() { @@ -71,10 +71,10 @@ public struct BulletBody buff.Append(ID.ToString()); buff.Append(",p="); buff.Append(ptr.ToString("X")); - if (collisionFilter != 0 || collisionMask != 0) + if (collisionGroup != 0 || collisionMask != 0) { - buff.Append(",f="); - buff.Append(collisionFilter.ToString("X")); + buff.Append(",g="); + buff.Append(collisionGroup.ToString("X")); buff.Append(",m="); buff.Append(collisionMask.ToString("X")); } @@ -376,36 +376,36 @@ public enum CollisionFilterGroups : uint // Don't use the bit definitions!! Define the use in a // filter/mask definition below. This way collision interactions // are more easily debugged. - BNoneFilter = 0, - BDefaultFilter = 1 << 0, - BStaticFilter = 1 << 1, - BKinematicFilter = 1 << 2, - BDebrisFilter = 1 << 3, - BSensorTrigger = 1 << 4, - BCharacterFilter = 1 << 5, - BAllFilter = 0xFFFFFFFF, + BNoneGroup = 0, + BDefaultGroup = 1 << 0, + BStaticGroup = 1 << 1, + BKinematicGroup = 1 << 2, + BDebrisGroup = 1 << 3, + BSensorTrigger = 1 << 4, + BCharacterGroup = 1 << 5, + BAllGroup = 0xFFFFFFFF, // Filter groups defined by BulletSim - BGroundPlaneFilter = 1 << 10, - BTerrainFilter = 1 << 11, - BRaycastFilter = 1 << 12, - BSolidFilter = 1 << 13, - BLinksetFilter = 1 << 14, + BGroundPlaneGroup = 1 << 10, + BTerrainGroup = 1 << 11, + BRaycastGroup = 1 << 12, + BSolidGroup = 1 << 13, + BLinksetGroup = 1 << 14, // The collsion filters and masked are defined in one place -- don't want them scattered - AvatarFilter = BCharacterFilter, - AvatarMask = BAllFilter, - ObjectFilter = BSolidFilter, - ObjectMask = BAllFilter, - StaticObjectFilter = BStaticFilter, - StaticObjectMask = BAllFilter & ~BStaticFilter, // static objects don't collide with each other - LinksetFilter = BLinksetFilter, - LinksetMask = BAllFilter & ~BLinksetFilter, // linkset objects don't collide with each other - VolumeDetectFilter = BSensorTrigger, + AvatarGroup = BCharacterGroup, + AvatarMask = BAllGroup, + ObjectGroup = BSolidGroup, + ObjectMask = BAllGroup, + StaticObjectGroup = BStaticGroup, + StaticObjectMask = AvatarGroup | ObjectGroup, // static things don't interact with much + LinksetGroup = BLinksetGroup, + LinksetMask = BAllGroup & ~BLinksetGroup, // linkset objects don't collide with each other + VolumeDetectGroup = BSensorTrigger, VolumeDetectMask = ~BSensorTrigger, - TerrainFilter = BTerrainFilter, - TerrainMask = BAllFilter & ~BStaticFilter, // static objects on the ground don't collide - GroundPlaneFilter = BGroundPlaneFilter, - GroundPlaneMask = BAllFilter + TerrainGroup = BTerrainGroup, + TerrainMask = BAllGroup & ~BStaticGroup, // static objects on the ground don't collide + GroundPlaneGroup = BGroundPlaneGroup, + GroundPlaneMask = BAllGroup }; @@ -945,7 +945,7 @@ public static extern IntPtr GetConstraintRef2(IntPtr obj, int index); public static extern int GetNumConstraintRefs2(IntPtr obj); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetCollisionFilterMask2(IntPtr body, uint filter, uint mask); +public static extern bool SetCollisionGroupMask2(IntPtr body, uint filter, uint mask); // ===================================================================================== // btCollisionShape entries -- cgit v1.1 From ac65085cc36bb4820482bf769b4be44e1c8d58ce Mon Sep 17 00:00:00 2001 From: BlueWall Date: Mon, 3 Dec 2012 20:09:54 -0500 Subject: XmlRpcGridRouter Flesh out XmlRpcGridRouter to reap unused channels from gateway when scripts or objects are removed, or when the llCloseRemoteDataChannel is called. See: http://http://forge.opensimulator.org/gf/project/xmlrpcrouter/ or https://github.com/BlueWall/XmlRpcRouter for php gateway and test code. --- .../Region/Framework/Interfaces/IXmlRpcRouter.cs | 1 + .../XmlRpcRouterModule/XmlRpcGridRouterModule.cs | 82 +++++++++++++++++----- .../XmlRpcRouterModule/XmlRpcRouterModule.cs | 6 ++ .../Shared/Api/Implementation/LSL_Api.cs | 7 ++ 4 files changed, 77 insertions(+), 19 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Interfaces/IXmlRpcRouter.cs b/OpenSim/Region/Framework/Interfaces/IXmlRpcRouter.cs index 6db6674..093d3f0 100644 --- a/OpenSim/Region/Framework/Interfaces/IXmlRpcRouter.cs +++ b/OpenSim/Region/Framework/Interfaces/IXmlRpcRouter.cs @@ -34,5 +34,6 @@ namespace OpenSim.Region.Framework.Interfaces void RegisterNewReceiver(IScriptModule scriptEngine, UUID channelID, UUID objectID, UUID itemID, string url); void ScriptRemoved(UUID itemID); void ObjectRemoved(UUID objectID); + void UnRegisterReceiver(string channelID, UUID itemID); } } diff --git a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs index 6120a81..709d389 100644 --- a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs @@ -46,6 +46,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule { public class XmlRpcInfo { + public UUID item; public UUID channel; public string uri; } @@ -88,6 +89,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule return; scene.RegisterModuleInterface(this); + + IScriptModule scriptEngine = scene.RequestModuleInterface(); + if ( scriptEngine != null ) + { + scriptEngine.OnScriptRemoved += this.ScriptRemoved; + scriptEngine.OnObjectRemoved += this.ObjectRemoved; + + } } public void RegionLoaded(Scene scene) @@ -120,22 +129,36 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule public void RegisterNewReceiver(IScriptModule scriptEngine, UUID channel, UUID objectID, UUID itemID, string uri) { - if (!m_Channels.ContainsKey(itemID)) - { - XmlRpcInfo info = new XmlRpcInfo(); - info.channel = channel; - info.uri = uri; + if (!m_Enabled) + return; - bool success = SynchronousRestObjectRequester.MakeRequest( - "POST", m_ServerURI+"/RegisterChannel/", info); + m_log.InfoFormat("[XMLRPC GRID ROUTER]: New receiver Obj: {0} Ch: {1} ID: {2} URI: {3}", + objectID.ToString(), channel.ToString(), itemID.ToString(), uri); - if (!success) - { - m_log.Error("[XMLRPC GRID ROUTER] Error contacting server"); - } + XmlRpcInfo info = new XmlRpcInfo(); + info.channel = channel; + info.uri = uri; + info.item = itemID; + + bool success = SynchronousRestObjectRequester.MakeRequest( + "POST", m_ServerURI+"/RegisterChannel/", info); - m_Channels[itemID] = channel; + if (!success) + { + m_log.Error("[XMLRPC GRID ROUTER] Error contacting server"); } + + m_Channels[itemID] = channel; + + } + + public void UnRegisterReceiver(string channelID, UUID itemID) + { + if (!m_Enabled) + return; + + RemoveChannel(itemID); + } public void ScriptRemoved(UUID itemID) @@ -143,10 +166,33 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule if (!m_Enabled) return; - if (m_Channels.ContainsKey(itemID)) + RemoveChannel(itemID); + + } + + public void ObjectRemoved(UUID objectID) + { + // m_log.InfoFormat("[XMLRPC GRID ROUTER]: Object Removed {0}",objectID.ToString()); + } + + private bool RemoveChannel(UUID itemID) + { + if(!m_Channels.ContainsKey(itemID)) + { + m_log.InfoFormat("[XMLRPC GRID ROUTER]: Attempted to unregister non-existing Item: {0}", itemID.ToString()); + return false; + } + + XmlRpcInfo info = new XmlRpcInfo(); + + info.channel = m_Channels[itemID]; + info.item = itemID; + info.uri = "http://0.0.0.0:00"; + + if (info != null) { - bool success = SynchronousRestObjectRequester.MakeRequest( - "POST", m_ServerURI+"/RemoveChannel/", m_Channels[itemID]); + bool success = SynchronousRestObjectRequester.MakeRequest( + "POST", m_ServerURI+"/RemoveChannel/", info); if (!success) { @@ -154,11 +200,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule } m_Channels.Remove(itemID); + return true; } - } - - public void ObjectRemoved(UUID objectID) - { + return false; } } } diff --git a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs index 4783f4c..ad0b83d 100644 --- a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs @@ -101,12 +101,18 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcRouterModule scriptEngine.PostScriptEvent(itemID, "xmlrpc_uri", new Object[] {uri}); } + public void UnRegisterReceiver(string channelID, UUID itemID) + { + } + public void ScriptRemoved(UUID itemID) { + System.Console.WriteLine("TEST Script Removed!"); } public void ObjectRemoved(UUID objectID) { + System.Console.WriteLine("TEST Obj Removed!"); } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index acf4d8c..4108588 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -6856,6 +6856,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llCloseRemoteDataChannel(string channel) { m_host.AddScriptLPS(1); + + IXmlRpcRouter xmlRpcRouter = m_ScriptEngine.World.RequestModuleInterface(); + if (xmlRpcRouter != null) + { + xmlRpcRouter.UnRegisterReceiver(channel, m_item.ItemID); + } + IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface(); xmlrpcMod.CloseXMLRPCChannel((UUID)channel); ScriptSleep(1000); -- cgit v1.1 From 583e44103c8eb552c437468cba84771c94592ae9 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 4 Dec 2012 08:36:54 -0800 Subject: Bug fix in OfflineMessageModule. Mantis #6446 --- .../Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs index 41364d7..7d763fa 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs @@ -219,7 +219,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage if (!m_ForwardOfflineGroupMessages) { if (im.dialog == (byte)InstantMessageDialog.GroupNotice || - im.dialog != (byte)InstantMessageDialog.GroupInvitation) + im.dialog == (byte)InstantMessageDialog.GroupInvitation) return; } -- cgit v1.1 From fb26d32a5c1320e97c9288326ebe402658a0a1c7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 4 Dec 2012 22:33:25 +0000 Subject: minor: Put Scene.PhysicsRequestAsset() into standard C# xml format. --- OpenSim/Region/Framework/Scenes/Scene.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 1ad5edd..cca295c 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -5638,10 +5638,17 @@ namespace OpenSim.Region.Framework.Scenes return m_SpawnPoint - 1; } - // Wrappers to get physics modules retrieve assets. Has to be done this way - // because we can't assign the asset service to physics directly - at the - // time physics are instantiated it's not registered but it will be by - // the time the first prim exists. + /// + /// Wrappers to get physics modules retrieve assets. + /// + /// + /// Has to be done this way + /// because we can't assign the asset service to physics directly - at the + /// time physics are instantiated it's not registered but it will be by + /// the time the first prim exists. + /// + /// + /// public void PhysicsRequestAsset(UUID assetID, AssetReceivedDelegate callback) { AssetService.Get(assetID.ToString(), callback, PhysicsAssetReceived); -- cgit v1.1 From 0d4047e641bac2d7fa554097ad23cec930082e33 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 4 Dec 2012 23:06:02 +0000 Subject: minor: Comment out "Delivering IM to..." messages for now. --- .../CoreModules/Avatar/InstantMessage/MessageTransferModule.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs index 3983369..a169748 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs @@ -146,7 +146,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage if (sp != null && !sp.IsChildAgent) { // Local message - m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", sp.Name, toAgentID); +// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", sp.Name, toAgentID); sp.ControllingClient.SendInstantMessage(im); @@ -166,7 +166,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage if (sp != null) { // Local message - m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", sp.Name, toAgentID); +// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", sp.Name, toAgentID); sp.ControllingClient.SendInstantMessage(im); @@ -176,7 +176,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage } } - m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID); +// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID); SendGridInstantMessageViaXMLRPC(im, result); } -- cgit v1.1 From 1b5f21f761ae12be34d80a41d23c5b97cc10f4a9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 4 Dec 2012 23:07:26 +0000 Subject: minor: also comment out the debug log message which reports searching for child agents in simulator scenes for now. --- .../Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs index a169748..fa935cd 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs @@ -159,8 +159,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage // try child avatar second foreach (Scene scene in m_Scenes) { - m_log.DebugFormat( - "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName); +// m_log.DebugFormat( +// "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName); ScenePresence sp = scene.GetScenePresence(toAgentID); if (sp != null) -- cgit v1.1 From d97440c7cf307ec701cc5351a0075239ece44727 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 5 Dec 2012 21:37:41 +0000 Subject: On XEngine.ProcessEventHandler(), instead of creating a new CultureInfo on every call use the single one set by Culture.SetCurrentCulture() This is slightly different in that SetCurrentCulture() does not use overridden settings if the system culture matches en-US but some settings there have been changed. This is what we want - we do not want to use any system overriden settings. --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 0460f22..1dab51e 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1415,8 +1415,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine /// private object ProcessEventHandler(object parms) { - CultureInfo USCulture = new CultureInfo("en-US"); - Thread.CurrentThread.CurrentCulture = USCulture; + Culture.SetCurrentCulture(); IScriptInstance instance = (ScriptInstance) parms; -- cgit v1.1 From ea786414c283ed04a32905b177afd342c88a7471 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 5 Dec 2012 21:51:08 +0000 Subject: In XEngine.DoOnRezScript() use Culture.SetCurrentCulture() instead of constructing a new CultureInfo separately --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 1dab51e..d9d4494 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1018,8 +1018,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine string assembly = ""; - CultureInfo USCulture = new CultureInfo("en-US"); - Thread.CurrentThread.CurrentCulture = USCulture; + Culture.SetCurrentCulture(); Dictionary, KeyValuePair> linemap; -- cgit v1.1 From e8df0f1b4c3194c7f5c1a354b5d5d2f67d6a250c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 5 Dec 2012 22:33:28 +0000 Subject: Add IScriptInstance.EventsProcessed stat so that we can record this information and display in "show scripts" for debug purposes --- OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs | 5 +++++ OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 4 ++++ OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 1 + 3 files changed, 10 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index b04f6b6..f3abd96 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs @@ -114,6 +114,11 @@ namespace OpenSim.Region.ScriptEngine.Interfaces UUID AssetID { get; } Queue EventQueue { get; } + /// + /// Number of events processed by this script instance. + /// + long EventsProcessed { get; } + void ClearQueue(); int StartParam { get; set; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 5793cc9..5bfe97a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -173,6 +173,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance public Queue EventQueue { get; private set; } + public long EventsProcessed { get; private set; } + public int StartParam { get; set; } public TaskInventoryItem ScriptTask { get; private set; } @@ -808,6 +810,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance // script engine to run the next event. lock (EventQueue) { + EventsProcessed++; + if (EventQueue.Count > 0 && Running && !ShuttingDown) { m_CurrentWorkItem = Engine.QueueEventHandler(this); diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index d9d4494..2136fe8 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -512,6 +512,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine lock (eq) sb.AppendFormat("Queued events : {0}\n", eq.Count); + sb.AppendFormat("Processed events : {0}\n", instance.EventsProcessed); sb.AppendFormat("Item UUID : {0}\n", instance.ItemID); sb.AppendFormat("Containing part name: {0}\n", instance.PrimName); sb.AppendFormat("Containing part UUID: {0}\n", instance.ObjectID); -- cgit v1.1 From 652f4bcb425646aab2096da99aa00016dfe639fd Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 5 Dec 2012 23:27:50 +0000 Subject: For now, sort "show scripts" output in descending order sorted by events processed. For debug purposes - should later add options to allow different sorting or show only highest 10, etc. --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 2136fe8..394826e 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -30,6 +30,7 @@ using System.Collections; using System.Collections.Generic; using System.Globalization; using System.IO; +using System.Linq; using System.Reflection; using System.Security; using System.Security.Policy; @@ -377,9 +378,21 @@ namespace OpenSim.Region.ScriptEngine.XEngine /// /// /// - /// true if we're okay to proceed, false if not. + /// Basis on which to sort output. Can be null if no sort needs to take place private void HandleScriptsAction(string[] cmdparams, Action action) { + HandleScriptsAction(cmdparams, action, null); + } + + /// + /// Parse the raw item id into a script instance from the command params if it's present. + /// + /// + /// + /// Basis on which to sort output. Can be null if no sort needs to take place + private void HandleScriptsAction( + string[] cmdparams, Action action, Func keySelector) + { if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene)) return; @@ -390,7 +403,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine if (cmdparams.Length == 2) { - foreach (IScriptInstance instance in m_Scripts.Values) + IEnumerable scripts = m_Scripts.Values; + + if (keySelector != null) + scripts = scripts.OrderBy(keySelector); + + foreach (IScriptInstance instance in scripts) action(instance); return; @@ -478,7 +496,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine } } - HandleScriptsAction(cmdparams, HandleShowScript); + HandleScriptsAction(cmdparams, HandleShowScript, si => si.EventsProcessed); } private void HandleShowScript(IScriptInstance instance) -- cgit v1.1 From 5ba99cbf554d965a6b11114a602c5317ca8f5ebd Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 5 Dec 2012 23:33:48 +0000 Subject: Add IScriptInstance.EventsQueued to match EventsProcessed instead of asking callers to lock and directly inspect the EventQueue --- OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs | 5 +++++ OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 9 +++++++++ OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 5 +---- 3 files changed, 15 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index f3abd96..0cef550 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs @@ -115,6 +115,11 @@ namespace OpenSim.Region.ScriptEngine.Interfaces Queue EventQueue { get; } /// + /// Number of events queued for processing. + /// + long EventsQueued { get; } + + /// /// Number of events processed by this script instance. /// long EventsProcessed { get; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 5bfe97a..8e81e9f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -173,6 +173,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance public Queue EventQueue { get; private set; } + public long EventsQueued + { + get + { + lock (EventQueue) + return EventQueue.Count; + } + } + public long EventsProcessed { get; private set; } public int StartParam { get; set; } diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 394826e..aeb807c 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -526,10 +526,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine sb.AppendFormat("Script name : {0}\n", instance.ScriptName); sb.AppendFormat("Status : {0}\n", status); - - lock (eq) - sb.AppendFormat("Queued events : {0}\n", eq.Count); - + sb.AppendFormat("Queued events : {0}\n", instance.EventsQueued); sb.AppendFormat("Processed events : {0}\n", instance.EventsProcessed); sb.AppendFormat("Item UUID : {0}\n", instance.ItemID); sb.AppendFormat("Containing part name: {0}\n", instance.PrimName); -- cgit v1.1 From 66982c8a599eeeaf63f9e3c5bfdae743deab5528 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 5 Dec 2012 23:36:15 +0000 Subject: Remove some mono warnings in script tests, chiefly where SetUp() wasn't properly calling to OpenSimTestCase.SetUp() --- OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs | 4 +++- OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs | 4 +++- OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs | 4 +++- OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs | 4 +++- OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs | 4 +--- 5 files changed, 13 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs index 2c9d9e8..cb7291a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs @@ -57,8 +57,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests protected XEngine.XEngine m_engine; [SetUp] - public void SetUp() + public override void SetUp() { + base.SetUp(); + IConfigSource initConfigSource = new IniConfigSource(); IConfig config = initConfigSource.AddConfig("XEngine"); config.Set("Enabled", "true"); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs index 57f19b9..d9b17d7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs @@ -62,8 +62,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests protected XEngine.XEngine m_engine; [SetUp] - public void SetUp() + public override void SetUp() { + base.SetUp(); + IConfigSource initConfigSource = new IniConfigSource(); IConfig config = initConfigSource.AddConfig("XEngine"); config.Set("Enabled", "true"); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs index 182b07b..98017d8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs @@ -51,8 +51,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests private LSL_Api m_lslApi; [SetUp] - public void SetUp() + public override void SetUp() { + base.SetUp(); + IConfigSource initConfigSource = new IniConfigSource(); IConfig config = initConfigSource.AddConfig("XEngine"); config.Set("Enabled", "true"); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs index 213f33f..1381d2b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs @@ -57,8 +57,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests protected XEngine.XEngine m_engine; [SetUp] - public void SetUp() + public override void SetUp() { + base.SetUp(); + IConfigSource initConfigSource = new IniConfigSource(); IConfig config = initConfigSource.AddConfig("XEngine"); config.Set("Enabled", "true"); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs index b49bcc2..d6c82f1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs @@ -127,12 +127,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests OSSL_Api osslApi = new OSSL_Api(); osslApi.Initialize(m_engine, so.RootPart, null); - string npcRaw; bool gotExpectedException = false; try { - npcRaw - = osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), "not existing notecard name"); + osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), "not existing notecard name"); } catch (ScriptException) { -- cgit v1.1 From ec765de7e55893c24792c95c1356bfad67e02034 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 5 Dec 2012 23:41:50 +0000 Subject: Add engine-wide events queued and events processed numbers to output of "xengine status" console command. For debugging purposes. --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index aeb807c..965101a 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -455,9 +455,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine StringBuilder sb = new StringBuilder(); sb.AppendFormat("Status of XEngine instance for {0}\n", m_Scene.RegionInfo.RegionName); + long scriptsLoaded, eventsQueued = 0, eventsProcessed = 0; + lock (m_Scripts) - sb.AppendFormat("Scripts loaded : {0}\n", m_Scripts.Count); + { + scriptsLoaded = m_Scripts.Count; + + foreach (IScriptInstance si in m_Scripts.Values) + { + eventsQueued += si.EventsQueued; + eventsProcessed += si.EventsProcessed; + } + } + sb.AppendFormat("Scripts loaded : {0}\n", scriptsLoaded); sb.AppendFormat("Unique scripts : {0}\n", m_uniqueScripts.Count); sb.AppendFormat("Scripts waiting for load : {0}\n", m_CompileQueue.Count); sb.AppendFormat("Max threads : {0}\n", m_ThreadPool.MaxThreads); @@ -466,6 +477,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine sb.AppendFormat("In use threads : {0}\n", m_ThreadPool.InUseThreads); sb.AppendFormat("Work items waiting : {0}\n", m_ThreadPool.WaitingCallbacks); // sb.AppendFormat("Assemblies loaded : {0}\n", m_Assemblies.Count); + sb.AppendFormat("Events queued : {0}\n", eventsQueued); + sb.AppendFormat("Events processed : {0}\n", eventsProcessed); SensorRepeat sr = AsyncCommandManager.GetSensorRepeatPlugin(this); sb.AppendFormat("Sensors : {0}\n", sr != null ? sr.SensorsCount : 0); -- cgit v1.1 From e60fe958df1709d1443abaa44faa4736f515f977 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 5 Dec 2012 23:44:12 +0000 Subject: minor: Fix more compiler warnings in CoreModules tests by properly overriding OpenSimTestCase.SetUp() --- OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs | 4 +++- .../Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs | 4 +++- .../ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs | 5 ++++- OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs | 4 +++- OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs | 4 +++- 5 files changed, 16 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs index 0872cc8..fd02b08 100644 --- a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs +++ b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs @@ -53,8 +53,10 @@ namespace OpenSim.Region.CoreModules.Asset.Tests protected FlotsamAssetCache m_cache; [SetUp] - public void SetUp() + public override void SetUp() { + base.SetUp(); + IConfigSource config = new IniConfigSource(); config.AddConfig("Modules"); diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs index b768257..ac25a93 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs @@ -57,8 +57,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests protected TestClient m_tc; [SetUp] - public void SetUp() + public override void SetUp() { + base.SetUp(); + m_iam = new BasicInventoryAccessModule(); IConfigSource config = new IniConfigSource(); diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs index 7e365ca..69bac82 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs @@ -46,8 +46,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence.Tests public class PresenceConnectorsTests : OpenSimTestCase { LocalPresenceServicesConnector m_LocalConnector; - private void SetUp() + + public override void SetUp() { + base.SetUp(); + IConfigSource config = new IniConfigSource(); config.AddConfig("Modules"); config.AddConfig("PresenceService"); diff --git a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs index 14eca42..0945b43 100644 --- a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs +++ b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs @@ -60,8 +60,10 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests protected ILandObject m_lo2; [SetUp] - public void SetUp() + public override void SetUp() { + base.SetUp(); + m_pcm = new PrimCountModule(); LandManagementModule lmm = new LandManagementModule(); m_scene = new SceneHelpers().SetupScene(); diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs index ba4b041..03a96a4 100644 --- a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs +++ b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs @@ -50,8 +50,10 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests protected MoapModule m_module; [SetUp] - public void SetUp() + public override void SetUp() { + base.SetUp(); + m_module = new MoapModule(); m_scene = new SceneHelpers().SetupScene(); SceneHelpers.SetupSceneModules(m_scene, m_module); -- cgit v1.1 From 1c9ecc55d3ae52548f974c4c19cc1f8ed6fb7d88 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 6 Dec 2012 00:22:52 +0000 Subject: Instead of printing script errors out to console, put to debug log so that we also get timestamps. This commit also adds script name, part name, uuid, etc. for later identification. This information has been sent to console since 2009 but may be turned down if it proves too noisy. However, I still currently need it to investigate some region problems probably triggered by scripting. --- .../Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 8e81e9f..5ad6eeb 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -785,6 +785,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance ChatTypeEnum.DebugChannel, 2147483647, part.AbsolutePosition, part.Name, part.UUID, false); + + + m_log.DebugFormat( + "[SCRIPT INSTANCE]: Runtime error in script {0}, part {1} {2} at {3} in {4}, displayed error {5}, actual exception {6}", + ScriptName, + PrimName, + part.UUID, + part.AbsolutePosition, + part.ParentGroup.Scene.Name, + text.Replace("\n", "\\n"), + e.InnerException); } catch (Exception) { @@ -1026,7 +1037,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance "({0}): {1}", scriptLine - 1, e.InnerException.Message); - System.Console.WriteLine(e.ToString()+"\n"); return message; } } -- cgit v1.1 From e599a8b2421ab51860c65e49bdfd38fa064fa9b8 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 5 Dec 2012 09:27:38 -0800 Subject: BulletSim: Vehicle angular vertical attraction works. Other vehicle angular forces commented out for the moment for debugging. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 55 ++++++++++++++-------- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 3 ++ 2 files changed, 38 insertions(+), 20 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index be8a502..a83d966 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -620,11 +620,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin private Vector3? m_knownVelocity; private Quaternion? m_knownOrientation; private Vector3? m_knownRotationalVelocity; + private Vector3? m_knownRotationalForce; private const int m_knownChangedPosition = 1 << 0; private const int m_knownChangedVelocity = 1 << 1; private const int m_knownChangedOrientation = 1 << 2; private const int m_knownChangedRotationalVelocity = 1 << 3; + private const int m_knownChangedRotationalForce = 1 << 4; private void ForgetKnownVehicleProperties() { @@ -634,6 +636,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_knownVelocity = null; m_knownOrientation = null; m_knownRotationalVelocity = null; + m_knownRotationalForce = null; m_knownChanged = 0; } private void PushKnownChanged() @@ -645,12 +648,19 @@ namespace OpenSim.Region.Physics.BulletSPlugin if ((m_knownChanged & m_knownChangedOrientation) != 0) Prim.ForceOrientation = VehicleOrientation; if ((m_knownChanged & m_knownChangedVelocity) != 0) + { Prim.ForceVelocity = VehicleVelocity; + BulletSimAPI.SetInterpolationLinearVelocity2(Prim.PhysBody.ptr, VehicleVelocity); + } if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) { Prim.ForceRotationalVelocity = VehicleRotationalVelocity; + // Fake out Bullet by making it think the velocity is the same as last time. BulletSimAPI.SetInterpolationAngularVelocity2(Prim.PhysBody.ptr, VehicleRotationalVelocity); } + if ((m_knownChanged & m_knownChangedRotationalForce) != 0) + Prim.AddAngularForce((Vector3)m_knownRotationalForce, false, true); + // If we set one of the values (ie, the physics engine didn't do it) we must force // an UpdateProperties event to send the changes up to the simulator. BulletSimAPI.PushUpdate2(Prim.PhysBody.ptr); @@ -734,6 +744,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_knownChanged |= m_knownChangedRotationalVelocity; } } + private void VehicleAddAngularForce(Vector3 aForce) + { + m_knownRotationalForce += aForce; + m_knownChanged |= m_knownChangedRotationalForce; + } #endregion // Known vehicle value functions // One step of the vehicle properties for the next 'pTimestep' seconds. @@ -1013,11 +1028,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin + bankingContribution; // ================================================================== - // The correction is applied to the current orientation. + // Apply the correction velocity. + // TODO: Should this be applied as an angular force (torque)? if (!m_lastAngularCorrection.ApproxEquals(Vector3.Zero, 0.01f)) { Vector3 scaledCorrection = m_lastAngularCorrection * pTimestep; - VehicleRotationalVelocity = scaledCorrection; VDetailLog("{0}, MoveAngular,done,nonZero,angMotorContrib={1},vertAttrContrib={2},bankContrib={3},deflectContrib={4},totalContrib={5},scaledCorr={6}", @@ -1029,7 +1044,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin } else { - // The vehicle is not adding anything velocity wise. + // The vehicle is not adding anything angular wise. VehicleRotationalVelocity = Vector3.Zero; VDetailLog("{0}, MoveAngular,done,zero", Prim.LocalID); } @@ -1060,8 +1075,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin torqueFromOffset.Y = 0; if (float.IsNaN(torqueFromOffset.Z)) torqueFromOffset.Z = 0; - torqueFromOffset *= m_vehicleMass; - Prim.ApplyTorqueImpulse(torqueFromOffset, true); + + VehicleAddAngularForce(torqueFromOffset * m_vehicleMass); VDetailLog("{0}, BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset); } @@ -1097,23 +1112,21 @@ namespace OpenSim.Region.Physics.BulletSPlugin ret.Y = - verticalError.X; ret.Z = 0f; - // scale by the time scale and timestep + // Scale the correction force by how far we're off from vertical. + // Z error of one says little error. As Z gets smaller, the vehicle is leaning farther over. + // float clampedZError = ClampInRange(0.1f, Math.Abs(verticalError.Z), 1f); + float clampedSqrZError = ClampInRange(0.01f, verticalError.Z * verticalError.Z, 1f); + // float vertForce = 1f / clampedSqrZError * m_verticalAttractionEfficiency; + float vertForce = 1f / clampedSqrZError; + + ret *= vertForce; + + // Correction happens over a number of seconds. Vector3 unscaledContrib = ret; ret /= m_verticalAttractionTimescale; - // This returns the angular correction desired. Timestep is added later. - // ret *= pTimestep; - - // apply efficiency - Vector3 preEfficiencyContrib = ret; - // TODO: implement efficiency. - // Effenciency squared seems to give a more realistic effect - float efficencySquared = m_verticalAttractionEfficiency * m_verticalAttractionEfficiency; - // ret *= efficencySquared; - - VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},preEff={3},eff={4},effSq={5},vertAttr={6}", - Prim.LocalID, verticalError, unscaledContrib, preEfficiencyContrib, - m_verticalAttractionEfficiency, efficencySquared, - ret); + + VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},vertForce={3},eff={4},vertAttr={5}", + Prim.LocalID, verticalError, unscaledContrib, vertForce, m_verticalAttractionEfficiency, ret); } return ret; } @@ -1123,6 +1136,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin public Vector3 ComputeAngularDeflection() { Vector3 ret = Vector3.Zero; + return ret; // DEBUG DEBUG DEBUG debug the other contributors first if (m_angularDeflectionEfficiency != 0) { @@ -1151,6 +1165,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { Vector3 ret = Vector3.Zero; Vector3 computedBanking = Vector3.Zero; + return ret; // DEBUG DEBUG DEBUG debug the other contributors first if (m_bankingEfficiency != 0) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index ea1f71a..e392078 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -1010,6 +1010,9 @@ public sealed class BSPrim : BSPhysObject }); } // A torque impulse. + // ApplyTorqueImpulse adds torque directly to the angularVelocity. + // AddAngularForce accumulates the force and applied it to the angular velocity all at once. + // Computed as: angularVelocity += impulse * inertia; public void ApplyTorqueImpulse(OMV.Vector3 impulse, bool inTaintTime) { OMV.Vector3 applyImpulse = impulse; -- cgit v1.1 From 6d7f66f78192c686f2f9666bbb4c4517310c30a7 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 5 Dec 2012 09:45:33 -0800 Subject: BulletSim: Don't add gravity to down force -- let Bullet do that. Add VehicleAddForce to set of managed vehicle prim properties. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 42 ++++++++++++++-------- 1 file changed, 28 insertions(+), 14 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index a83d966..09aee17 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -618,15 +618,17 @@ namespace OpenSim.Region.Physics.BulletSPlugin private float? m_knownWaterLevel; private Vector3? m_knownPosition; private Vector3? m_knownVelocity; + private Vector3? m_knownForce; private Quaternion? m_knownOrientation; private Vector3? m_knownRotationalVelocity; private Vector3? m_knownRotationalForce; private const int m_knownChangedPosition = 1 << 0; private const int m_knownChangedVelocity = 1 << 1; - private const int m_knownChangedOrientation = 1 << 2; - private const int m_knownChangedRotationalVelocity = 1 << 3; - private const int m_knownChangedRotationalForce = 1 << 4; + private const int m_knownChangedForce = 1 << 2; + private const int m_knownChangedOrientation = 1 << 3; + private const int m_knownChangedRotationalVelocity = 1 << 4; + private const int m_knownChangedRotationalForce = 1 << 5; private void ForgetKnownVehicleProperties() { @@ -634,6 +636,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_knownWaterLevel = null; m_knownPosition = null; m_knownVelocity = null; + m_knownForce = null; m_knownOrientation = null; m_knownRotationalVelocity = null; m_knownRotationalForce = null; @@ -652,6 +655,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin Prim.ForceVelocity = VehicleVelocity; BulletSimAPI.SetInterpolationLinearVelocity2(Prim.PhysBody.ptr, VehicleVelocity); } + if ((m_knownChanged & m_knownChangedForce) != 0) + Prim.AddForce((Vector3)m_knownForce, false, true); + if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) { Prim.ForceRotationalVelocity = VehicleRotationalVelocity; @@ -730,6 +736,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin } } + private void VehicleAddForce(Vector3 aForce) + { + m_knownForce += aForce; + m_knownChanged |= m_knownChangedForce; + } + private Vector3 VehicleRotationalVelocity { get @@ -784,10 +796,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin linearMotorContribution *= VehicleOrientation; // ================================================================== - // Gravity and Buoyancy - // There is some gravity, make a gravity force vector that is applied after object velocity. + // Buoyancy: force to overcome gravity. // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; - Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy); + Vector3 buoyancyContribution = Prim.PhysicsScene.DefaultGravity * (m_VehicleBuoyancy - 1f); Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(pTimestep); @@ -812,14 +823,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin newVelocity.Z = 0; // ================================================================== - // Clamp REALLY high or low velocities + // Clamp high or low velocities float newVelocityLengthSq = newVelocity.LengthSquared(); - if (newVelocityLengthSq > 1e6f) + // if (newVelocityLengthSq > 1e6f) + if (newVelocityLengthSq > 1000f) { newVelocity /= newVelocity.Length(); newVelocity *= 1000f; } - else if (newVelocityLengthSq < 1e-6f) + // else if (newVelocityLengthSq < 1e-6f) + else if (newVelocityLengthSq < 0.001f) newVelocity = Vector3.Zero; // ================================================================== @@ -828,15 +841,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin VehicleVelocity = newVelocity; // Other linear forces are applied as forces. - Vector3 totalDownForce = grav * m_vehicleMass * pTimestep; - if (totalDownForce != Vector3.Zero) + Vector3 totalDownForce = buoyancyContribution * m_vehicleMass; + if (!totalDownForce.ApproxEquals(Vector3.Zero, 0.01f)) { - Prim.AddForce(totalDownForce, false); + VehicleAddForce(totalDownForce); } - VDetailLog("{0}, MoveLinear,done,newVel={1},totDown={2},linContrib={3},terrContrib={4},hoverContrib={5},limitContrib={6}", + VDetailLog("{0}, MoveLinear,done,newVel={1},totDown={2},linContrib={3},terrContrib={4},hoverContrib={5},limitContrib={6},buoyContrib={7}", Prim.LocalID, newVelocity, totalDownForce, - linearMotorContribution, terrainHeightContribution, hoverContribution, limitMotorUpContribution + linearMotorContribution, terrainHeightContribution, hoverContribution, + limitMotorUpContribution, buoyancyContribution ); } // end MoveLinear() -- cgit v1.1 From 2ecd8e6720ebc9668aa30a8276c8b15a8650b8fe Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 6 Dec 2012 06:45:51 -0800 Subject: BulletSim: add values for material friction and restitution. Fix line endings in material definition file. --- .../Region/Physics/BulletSPlugin/BSMaterials.cs | 376 ++++++++++----------- 1 file changed, 185 insertions(+), 191 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs index 663b6f4..390c2f9 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs @@ -1,191 +1,185 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Text; -using System.Reflection; -using Nini.Config; - -namespace OpenSim.Region.Physics.BulletSPlugin -{ - -public struct MaterialAttributes -{ - // Material type values that correspond with definitions for LSL - public enum Material : int - { - Stone = 0, - Metal, - Glass, - Wood, - Flesh, - Plastic, - Rubber, - Light, - // Hereafter are BulletSim additions - Avatar, - NumberOfTypes // the count of types in the enum. - } - // Names must be in the order of the above enum. - public static string[] MaterialNames = { "Stone", "Metal", "Glass", "Wood", - "Flesh", "Plastic", "Rubber", "Light", "Avatar" }; - public static string[] MaterialAttribs = { "Density", "Friction", "Restitution", - "ccdMotionThreshold", "ccdSweptSphereRadius" }; - - public MaterialAttributes(string t, float d, float f, float r, float ccdM, float ccdS) - { - type = t; - density = d; - friction = f; - restitution = r; - ccdMotionThreshold = ccdM; - ccdSweptSphereRadius = ccdS; - } - public string type; - public float density; - public float friction; - public float restitution; - public float ccdMotionThreshold; - public float ccdSweptSphereRadius; -} - -public static class BSMaterials -{ - public static MaterialAttributes[] Attributes; - - static BSMaterials() - { - // Attribute sets for both the non-physical and physical instances of materials. - Attributes = new MaterialAttributes[(int)MaterialAttributes.Material.NumberOfTypes * 2]; - } - - // This is where all the default material attributes are defined. - public static void InitializeFromDefaults(ConfigurationParameters parms) - { - // public static string[] MaterialNames = { "Stone", "Metal", "Glass", "Wood", - // "Flesh", "Plastic", "Rubber", "Light", "Avatar" }; - float dFriction = parms.defaultFriction; - float dRestitution = parms.defaultRestitution; - float dDensity = parms.defaultDensity; - float dCcdM = parms.ccdMotionThreshold; - float dCcdS = parms.ccdSweptSphereRadius; - Attributes[(int)MaterialAttributes.Material.Stone] = - new MaterialAttributes("stone",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Metal] = - new MaterialAttributes("metal",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Glass] = - new MaterialAttributes("glass",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Wood] = - new MaterialAttributes("wood",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Flesh] = - new MaterialAttributes("flesh",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Plastic] = - new MaterialAttributes("plastic",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Rubber] = - new MaterialAttributes("rubber",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Light] = - new MaterialAttributes("light",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Avatar] = - new MaterialAttributes("avatar",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - - Attributes[(int)MaterialAttributes.Material.Stone + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("stonePhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Metal + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("metalPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Glass + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("glassPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Wood + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("woodPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Flesh + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("fleshPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Plastic + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("plasticPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Rubber + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("rubberPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Light + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("lightPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - Attributes[(int)MaterialAttributes.Material.Avatar + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("avatarPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); - } - - // Under the [BulletSim] section, one can change the individual material - // attribute values. The format of the configuration parameter is: - // ["Physical"] = floatValue - // For instance: - // [BulletSim] - // StoneFriction = 0.2 - // FleshRestitutionPhysical = 0.8 - // Materials can have different parameters for their static and - // physical instantiations. When setting the non-physical value, - // both values are changed. Setting the physical value only changes - // the physical value. - public static void InitializefromParameters(IConfig pConfig) - { - int matType = 0; - foreach (string matName in MaterialAttributes.MaterialNames) - { - foreach (string attribName in MaterialAttributes.MaterialAttribs) - { - string paramName = matName + attribName; - if (pConfig.Contains(paramName)) - { - float paramValue = pConfig.GetFloat(paramName); - SetAttributeValue(matType, attribName, paramValue); - // set the physical value also - SetAttributeValue(matType + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue); - } - paramName += "Physical"; - if (pConfig.Contains(paramName)) - { - float paramValue = pConfig.GetFloat(paramName); - SetAttributeValue(matType + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue); - } - } - matType++; - } - } - - private static void SetAttributeValue(int matType, string attribName, float val) - { - MaterialAttributes thisAttrib = Attributes[matType]; - FieldInfo fieldInfo = thisAttrib.GetType().GetField(attribName); - if (fieldInfo != null) - { - fieldInfo.SetValue(thisAttrib, val); - Attributes[matType] = thisAttrib; - } - } - - public static MaterialAttributes GetAttributes(MaterialAttributes.Material type, bool isPhysical) - { - int ind = (int)type; - if (isPhysical) ind += (int)MaterialAttributes.Material.NumberOfTypes; - return Attributes[ind]; - } - -} -} +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using System.Reflection; +using Nini.Config; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ + +public struct MaterialAttributes +{ + // Material type values that correspond with definitions for LSL + public enum Material : int + { + Stone = 0, + Metal, + Glass, + Wood, + Flesh, + Plastic, + Rubber, + Light, + // Hereafter are BulletSim additions + Avatar, + NumberOfTypes // the count of types in the enum. + } + // Names must be in the order of the above enum. + public static string[] MaterialNames = { "Stone", "Metal", "Glass", "Wood", + "Flesh", "Plastic", "Rubber", "Light", "Avatar" }; + public static string[] MaterialAttribs = { "Density", "Friction", "Restitution"}; + + public MaterialAttributes(string t, float d, float f, float r) + { + type = t; + density = d; + friction = f; + restitution = r; + } + public string type; + public float density; + public float friction; + public float restitution; +} + +public static class BSMaterials +{ + public static MaterialAttributes[] Attributes; + + static BSMaterials() + { + // Attribute sets for both the non-physical and physical instances of materials. + Attributes = new MaterialAttributes[(int)MaterialAttributes.Material.NumberOfTypes * 2]; + } + + // This is where all the default material attributes are defined. + public static void InitializeFromDefaults(ConfigurationParameters parms) + { + // Values from http://wiki.secondlife.com/wiki/PRIM_MATERIAL + // public static string[] MaterialNames = { "Stone", "Metal", "Glass", "Wood", + // "Flesh", "Plastic", "Rubber", "Light", "Avatar" }; + float dFriction = parms.defaultFriction; + float dRestitution = parms.defaultRestitution; + float dDensity = parms.defaultDensity; + Attributes[(int)MaterialAttributes.Material.Stone] = + new MaterialAttributes("stone",dDensity, 0.8f, 0.4f); + Attributes[(int)MaterialAttributes.Material.Metal] = + new MaterialAttributes("metal",dDensity, 0.3f, 0.4f); + Attributes[(int)MaterialAttributes.Material.Glass] = + new MaterialAttributes("glass",dDensity, 0.2f, 0.7f); + Attributes[(int)MaterialAttributes.Material.Wood] = + new MaterialAttributes("wood",dDensity, 0.6f, 0.5f); + Attributes[(int)MaterialAttributes.Material.Flesh] = + new MaterialAttributes("flesh",dDensity, 0.9f, 0.3f); + Attributes[(int)MaterialAttributes.Material.Plastic] = + new MaterialAttributes("plastic",dDensity, 0.4f, 0.7f); + Attributes[(int)MaterialAttributes.Material.Rubber] = + new MaterialAttributes("rubber",dDensity, 0.9f, 0.9f); + Attributes[(int)MaterialAttributes.Material.Light] = + new MaterialAttributes("light",dDensity, dFriction, dRestitution); + Attributes[(int)MaterialAttributes.Material.Avatar] = + new MaterialAttributes("avatar",60f, 0.2f, 0f); + + Attributes[(int)MaterialAttributes.Material.Stone + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("stonePhysical",dDensity, 0.8f, 0.4f); + Attributes[(int)MaterialAttributes.Material.Metal + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("metalPhysical",dDensity, 0.8f, 0.4f); + Attributes[(int)MaterialAttributes.Material.Glass + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("glassPhysical",dDensity, 0.8f, 0.7f); + Attributes[(int)MaterialAttributes.Material.Wood + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("woodPhysical",dDensity, 0.8f, 0.5f); + Attributes[(int)MaterialAttributes.Material.Flesh + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("fleshPhysical",dDensity, 0.8f, 0.3f); + Attributes[(int)MaterialAttributes.Material.Plastic + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("plasticPhysical",dDensity, 0.8f, 0.7f); + Attributes[(int)MaterialAttributes.Material.Rubber + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("rubberPhysical",dDensity, 0.8f, 0.9f); + Attributes[(int)MaterialAttributes.Material.Light + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("lightPhysical",dDensity, dFriction, dRestitution); + Attributes[(int)MaterialAttributes.Material.Avatar + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("avatarPhysical",60f, 0.2f, 0f); + } + + // Under the [BulletSim] section, one can change the individual material + // attribute values. The format of the configuration parameter is: + // ["Physical"] = floatValue + // For instance: + // [BulletSim] + // StoneFriction = 0.2 + // FleshRestitutionPhysical = 0.8 + // Materials can have different parameters for their static and + // physical instantiations. When setting the non-physical value, + // both values are changed. Setting the physical value only changes + // the physical value. + public static void InitializefromParameters(IConfig pConfig) + { + int matType = 0; + foreach (string matName in MaterialAttributes.MaterialNames) + { + foreach (string attribName in MaterialAttributes.MaterialAttribs) + { + string paramName = matName + attribName; + if (pConfig.Contains(paramName)) + { + float paramValue = pConfig.GetFloat(paramName); + SetAttributeValue(matType, attribName, paramValue); + // set the physical value also + SetAttributeValue(matType + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue); + } + paramName += "Physical"; + if (pConfig.Contains(paramName)) + { + float paramValue = pConfig.GetFloat(paramName); + SetAttributeValue(matType + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue); + } + } + matType++; + } + } + + private static void SetAttributeValue(int matType, string attribName, float val) + { + MaterialAttributes thisAttrib = Attributes[matType]; + FieldInfo fieldInfo = thisAttrib.GetType().GetField(attribName); + if (fieldInfo != null) + { + fieldInfo.SetValue(thisAttrib, val); + Attributes[matType] = thisAttrib; + } + } + + public static MaterialAttributes GetAttributes(MaterialAttributes.Material type, bool isPhysical) + { + int ind = (int)type; + if (isPhysical) ind += (int)MaterialAttributes.Material.NumberOfTypes; + return Attributes[ind]; + } + +} +} -- cgit v1.1 From cc59e3cbdf2d660422bc8707816d7d30d7c72b92 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 6 Dec 2012 09:21:04 -0800 Subject: BulletSim: only check position sanity if the prim is physical -- the user can do anything dumb they wish. --- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index e392078..62aaf80 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -1399,7 +1399,7 @@ public sealed class BSPrim : BSPhysObject _rotationalVelocity = entprop.RotationalVelocity; // The sanity check can change the velocity and/or position. - if (PositionSanityCheck(true)) + if (IsPhysical && PositionSanityCheck(true)) { entprop.Position = _position; entprop.Velocity = _velocity; @@ -1413,8 +1413,6 @@ public sealed class BSPrim : BSPhysObject DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}", LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity); - // BulletSimAPI.DumpRigidBody2(PhysicsScene.World.ptr, BSBody.ptr); // DEBUG DEBUG DEBUG - base.RequestPhysicsterseUpdate(); } /* -- cgit v1.1 From 18fe35906dd07ecfe8f8b439f5648982262aa17f Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 6 Dec 2012 09:22:29 -0800 Subject: BulletSim: add detail logging detail flag so I don't have to comment and uncomment the detail logging when changing the depth of logged info. --- .../Physics/BulletSPlugin/BSShapeCollection.cs | 61 ++++++++++++---------- 1 file changed, 34 insertions(+), 27 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index b94dcf6..e77b6ba 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -65,9 +65,16 @@ public sealed class BSShapeCollection : IDisposable private Dictionary Meshes = new Dictionary(); private Dictionary Hulls = new Dictionary(); + private bool DDetail = false; + public BSShapeCollection(BSScene physScene) { PhysicsScene = physScene; + // Set the next to 'true' for very detailed shape update detailed logging (detailed details?) + // While detailed debugging is still active, this is better than commenting out all the + // DetailLog statements. When debugging slows down, this and the protected logging + // statements can be commented/removed. + DDetail = true; } public void Dispose() @@ -126,13 +133,13 @@ public sealed class BSShapeCollection : IDisposable { lock (m_collectionActivityLock) { - DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,body={1}", body.ID, body); + if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,body={1}", body.ID, body); PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.ReferenceBody", delegate() { if (!BulletSimAPI.IsInWorld2(body.ptr)) { BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, body.ptr); - DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", body.ID, body); + if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", body.ID, body); } }); } @@ -149,7 +156,7 @@ public sealed class BSShapeCollection : IDisposable { PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceBody", delegate() { - DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1},inTaintTime={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1},inTaintTime={2}", body.ID, body, inTaintTime); // If the caller needs to know the old body is going away, pass the event up. if (bodyCallback != null) bodyCallback(body); @@ -157,7 +164,7 @@ public sealed class BSShapeCollection : IDisposable if (BulletSimAPI.IsInWorld2(body.ptr)) { BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr); - DetailLog("{0},BSShapeCollection.DereferenceBody,removingFromWorld. Body={1}", body.ID, body); + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,removingFromWorld. Body={1}", body.ID, body); } // Zero any reference to the shape so it is not freed when the body is deleted. @@ -184,7 +191,7 @@ public sealed class BSShapeCollection : IDisposable { // There is an existing instance of this mesh. meshDesc.referenceCount++; - DetailLog("{0},BSShapeCollection.ReferenceShape,existingMesh,key={1},cnt={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,existingMesh,key={1},cnt={2}", BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount); } else @@ -194,7 +201,7 @@ public sealed class BSShapeCollection : IDisposable meshDesc.shapeKey = shape.shapeKey; // We keep a reference to the underlying IMesh data so a hull can be built meshDesc.referenceCount = 1; - DetailLog("{0},BSShapeCollection.ReferenceShape,newMesh,key={1},cnt={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,newMesh,key={1},cnt={2}", BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount); ret = true; } @@ -207,7 +214,7 @@ public sealed class BSShapeCollection : IDisposable { // There is an existing instance of this hull. hullDesc.referenceCount++; - DetailLog("{0},BSShapeCollection.ReferenceShape,existingHull,key={1},cnt={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,existingHull,key={1},cnt={2}", BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount); } else @@ -216,7 +223,7 @@ public sealed class BSShapeCollection : IDisposable hullDesc.ptr = shape.ptr; hullDesc.shapeKey = shape.shapeKey; hullDesc.referenceCount = 1; - DetailLog("{0},BSShapeCollection.ReferenceShape,newHull,key={1},cnt={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,newHull,key={1},cnt={2}", BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount); ret = true; @@ -246,7 +253,7 @@ public sealed class BSShapeCollection : IDisposable if (shape.isNativeShape) { // Native shapes are not tracked and are released immediately - DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}", BSScene.DetailLogZero, shape.ptr.ToString("X"), inTaintTime); if (shapeCallback != null) shapeCallback(shape); BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr); @@ -286,7 +293,7 @@ public sealed class BSShapeCollection : IDisposable if (shapeCallback != null) shapeCallback(shape); meshDesc.lastReferenced = System.DateTime.Now; Meshes[shape.shapeKey] = meshDesc; - DetailLog("{0},BSShapeCollection.DereferenceMesh,shape={1},refCnt={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceMesh,shape={1},refCnt={2}", BSScene.DetailLogZero, shape, meshDesc.referenceCount); } @@ -307,7 +314,7 @@ public sealed class BSShapeCollection : IDisposable hullDesc.lastReferenced = System.DateTime.Now; Hulls[shape.shapeKey] = hullDesc; - DetailLog("{0},BSShapeCollection.DereferenceHull,shape={1},refCnt={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceHull,shape={1},refCnt={2}", BSScene.DetailLogZero, shape, hullDesc.referenceCount); } } @@ -325,13 +332,13 @@ public sealed class BSShapeCollection : IDisposable // Failed the sanity check!! PhysicsScene.Logger.ErrorFormat("{0} Attempt to free a compound shape that is not compound!! type={1}, ptr={2}", LogHeader, shape.type, shape.ptr.ToString("X")); - DetailLog("{0},BSShapeCollection.DereferenceCompound,notACompoundShape,type={1},ptr={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceCompound,notACompoundShape,type={1},ptr={2}", BSScene.DetailLogZero, shape.type, shape.ptr.ToString("X")); return; } int numChildren = BulletSimAPI.GetNumberOfCompoundChildren2(shape.ptr); - DetailLog("{0},BSShapeCollection.DereferenceCompound,shape={1},children={2}", BSScene.DetailLogZero, shape, numChildren); + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceCompound,shape={1},children={2}", BSScene.DetailLogZero, shape, numChildren); for (int ii = numChildren - 1; ii >= 0; ii--) { @@ -379,7 +386,7 @@ public sealed class BSShapeCollection : IDisposable } } - DetailLog("{0},BSShapeCollection.DereferenceAnonCollisionShape,shape={1}", BSScene.DetailLogZero, shapeInfo); + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceAnonCollisionShape,shape={1}", BSScene.DetailLogZero, shapeInfo); if (shapeInfo.type != BSPhysicsShapeType.SHAPE_UNKNOWN) { @@ -410,7 +417,7 @@ public sealed class BSShapeCollection : IDisposable // an avatar capsule is close to a native shape (it is not shared) ret = GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_CAPSULE, FixedShapeKey.KEY_CAPSULE, shapeCallback); - DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape); + if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape); ret = true; haveShape = true; } @@ -420,7 +427,7 @@ public sealed class BSShapeCollection : IDisposable if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND) { ret = GetReferenceToCompoundShape(prim, shapeCallback); - DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, prim.PhysShape); + if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, prim.PhysShape); haveShape = true; } @@ -465,7 +472,7 @@ public sealed class BSShapeCollection : IDisposable { ret = GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_SPHERE, FixedShapeKey.KEY_SPHERE, shapeCallback); - DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}", prim.LocalID, forceRebuild, prim.PhysShape); } } @@ -479,7 +486,7 @@ public sealed class BSShapeCollection : IDisposable { ret = GetReferenceToNativeShape( prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX, shapeCallback); - DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}", prim.LocalID, forceRebuild, prim.PhysShape); } } @@ -504,13 +511,13 @@ public sealed class BSShapeCollection : IDisposable { // Update prim.BSShape to reference a hull of this shape. ret = GetReferenceToHull(prim,shapeCallback); - DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); } else { ret = GetReferenceToMesh(prim, shapeCallback); - DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}", prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); } return ret; @@ -528,7 +535,7 @@ public sealed class BSShapeCollection : IDisposable BulletShape newShape = BuildPhysicalNativeShape(prim, shapeType, shapeKey); // Don't need to do a 'ReferenceShape()' here because native shapes are not shared. - DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1},scale={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1},scale={2}", prim.LocalID, newShape, prim.Scale); prim.PhysShape = newShape; @@ -554,7 +561,7 @@ public sealed class BSShapeCollection : IDisposable newShape = new BulletShape( BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale) , shapeType); - DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); + if (DDetail) DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); } else { @@ -589,7 +596,7 @@ public sealed class BSShapeCollection : IDisposable if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_MESH) return false; - DetailLog("{0},BSShapeCollection.GetReferenceToMesh,create,oldKey={1},newKey={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToMesh,create,oldKey={1},newKey={2}", prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X")); // Since we're recreating new, get rid of the reference to the previous shape @@ -662,7 +669,7 @@ public sealed class BSShapeCollection : IDisposable if (newHullKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_HULL) return false; - DetailLog("{0},BSShapeCollection.GetReferenceToHull,create,oldKey={1},newKey={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToHull,create,oldKey={1},newKey={2}", prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newHullKey.ToString("X")); // Remove usage of the previous shape. @@ -808,7 +815,7 @@ public sealed class BSShapeCollection : IDisposable // Create the shape for the root prim and add it to the compound shape. Cannot be a native shape. CreateGeomMeshOrHull(prim, shapeCallback); BulletSimAPI.AddChildShapeToCompoundShape2(cShape.ptr, prim.PhysShape.ptr, OMV.Vector3.Zero, OMV.Quaternion.Identity); - DetailLog("{0},BSShapeCollection.GetReferenceToCompoundShape,addRootPrim,compShape={1},rootShape={2}", + if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToCompoundShape,addRootPrim,compShape={1},rootShape={2}", prim.LocalID, cShape, prim.PhysShape); prim.PhysShape = cShape; @@ -935,13 +942,13 @@ public sealed class BSShapeCollection : IDisposable { bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr, prim.LocalID, prim.RawPosition, prim.RawOrientation); - DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); + if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); } else { bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr, prim.LocalID, prim.RawPosition, prim.RawOrientation); - DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); + if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); } aBody = new BulletBody(prim.LocalID, bodyPtr); -- cgit v1.1 From edd1b353a5b683b7d9b22e80d97e15e05f34611c Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 6 Dec 2012 09:23:20 -0800 Subject: BulletSim: update and add to the TODO list. --- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 87 ++++++++++++++-------- 1 file changed, 56 insertions(+), 31 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 68f25fc..d51003c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -6,14 +6,34 @@ CRASHES Causes many errors. Doesn't stop after first error with box shape. Eventually crashes when deleting the object. -BULLETSIM TODO LIST: +VEHICLES TODO LIST: ================================================= Neb car jiggling left and right + Happens on terrain and any other mesh object. Flat cubes are much smoother. Vehicles (Move smoothly) -Light cycle falling over when driving -Light cycle not banking -Do single prim vehicles don't seem to properly vehiclize. -Gun sending shooter flying +Add vehicle collisions so IsColliding is properly reported. + Needed for banking, limitMotorUp, movementLimiting, ... +Some vehicles should not be able to turn if no speed or off ground. +For limitMotorUp, use raycast down to find if vehicle is in the air. +Implement function efficiency for lineaar and angular motion. +Should vehicle angular/linear movement friction happen after all the components + or does it only apply to the basic movement? +After getting off a vehicle, the root prim is phantom (can be walked through) + Need to force a position update for the root prim after compound shape destruction +Linkset explosion after three "rides" on Nebadon lite vehicle (LinksetConstraint) +Implement referenceFrame for all the motion routines. +Cannot edit/move a vehicle being ridden: it jumps back to the origional position. + +BULLETSIM TODO LIST: +================================================= +Disable activity of passive linkset children. + Since the linkset is a compound object, the old prims are left lying + around and need to be phantomized so they don't collide, ... +Scenes with hundred of thousands of static objects take a lot of physics CPU time. +BSPrim.Force should set a continious force on the prim. The force should be + applied each tick. Some limits? +Single prim vehicles don't seem to properly vehiclize. +Gun sending shooter flying. Collision margin (gap between physical objects lying on each other) Boundry checking (crashes related to crossing boundry) Add check for border edge position for avatars and objects. @@ -28,10 +48,11 @@ Small physical objects do not interact correctly Add material type linkage and input all the material property definitions. Skeleton classes and table are in the sources but are not filled or used. Add PID motor for avatar movement (slow to stop, ...) -Implement function efficiency for lineaar and angular motion. +setForce should set a constant force. Different than AddImpulse. +Implement raycast. +Implement ShapeCollection.Dispose() +Implement water as a plain so raycasting and collisions can happen with same. -After getting off a vehicle, the root prim is phantom (can be walked through) - Need to force a position update for the root prim after compound shape destruction Find/remove avatar collision with ID=0. Test avatar walking up stairs. How does compare with SL. Radius of the capsule affects ability to climb edges. @@ -39,19 +60,16 @@ Tune terrain/object friction to be closer to SL. Debounce avatar contact so legs don't keep folding up when standing. Implement LSL physics controls. Like STATUS_ROTATE_X. Add border extensions to terrain to help region crossings and objects leaving region. -Linkset explosion after three "rides" on Nebadon lite vehicle (LinksetConstraint) Speed up creation of large physical linksets For instance, sitting in Neb's car (130 prims) takes several seconds to become physical Performance test with lots of avatars. Can BulletSim support a thousand? Optimize collisions in C++: only send up to the object subscribed to collisions. Use collision subscription and remove the collsion(A,B) and collision(B,A) -Check wheter SimMotionState needs large if statement (see TODO). +Check whether SimMotionState needs large if statement (see TODO). Implement 'top colliders' info. Avatar jump -Implement meshes or just verify that they work. -Do prim hash codes work for sculpties and meshes? Performance measurement and changes to make quicker. Implement detailed physics stats (GetStats()). @@ -67,8 +85,6 @@ Performance of closures and delegates for taint processing Is there are more efficient method of implementing pre and post step actions? See http://www.codeproject.com/Articles/29922/Weak-Events-in-C -Package Bullet source mods for Bullet internal stats output - Physics Arena central pyramid: why is one side permiable? INTERNAL IMPROVEMENT/CLEANUP @@ -85,33 +101,42 @@ Complete implemention of preStepActions Replace vehicle step call with prestep event. Is there a need for postStepActions? postStepTaints? Implement linkset by setting position of children when root updated. (LinksetManual) + Linkset implementation using manual prim movement. LinkablePrim class? Would that simplify/centralize the linkset logic? -Linkset implementation using manual prim movement. -Linkset implementation using compound shapes. - Compound shapes will need the LocalID in the shapes and collision - processing to get it from there. BSScene.UpdateParameterSet() is broken. How to set params on objects? Remove HeightmapInfo from terrain specification. Since C++ code does not need terrain height, this structure et al are not needed. Add floating motor for BS_FLOATS_ON_WATER so prim and avatar will bob at the water level. BSPrim.PositionSanityCheck(). +THREADING +================================================= +Do taint action immediately if not actually executing Bullet. + Add lock around Bullet execution and just do taint actions if simulation is not happening. + DONE DONE DONE DONE ================================================= -Cleanup code in BSDynamics by using motors. -Consider implementing terrain with a mesh rather than heightmap. +Cleanup code in BSDynamics by using motors. (Resolution: started) +Consider implementing terrain with a mesh rather than heightmap. (Resolution: done) Would have better and adjustable resolution. -NOTDONE: Build terrain mesh so heighmap is height of the center of the square meter. - SL and ODE define meter square as being at one corner with one diagional. -Terrain as mesh. +Build terrain mesh so heighmap is height of the center of the square meter. + Resolution: NOT DONE: SL and ODE define meter square as being at one corner with one diagional. +Terrain as mesh. (Resolution: done) How are static linksets seen by the physics engine? - A: they are not linked in physics. When moved, all the children are repositioned. -Remember to remove BSScene.DetailLog Refresh call. -Convert BSCharacter to use all API2 + Resolution: they are not linked in physics. When moved, all the children are repositioned. +Convert BSCharacter to use all API2 (Resolution: done) Avatar pushing difficult (too heavy?) -Use asset service passed to BulletSim to get sculptie bodies, etc. -Vehicles (fix bouncing on terrain) -Remove old code in DLL (all non-API2 stuff). -Measurements of mega-physical prim performance (with graph) +Use asset service passed to BulletSim to get sculptie bodies, etc. (Resolution: done) +Remove old code in DLL (all non-API2 stuff). (Resolution: done) +Measurements of mega-physical prim performance (with graph) (Resolution: done, email) Debug Bullet internal stats output (why is timing all wrong?) - Bullet stats logging only works with a single instance of Bullet (one region). \ No newline at end of file + Resolution: Bullet stats logging only works with a single instance of Bullet (one region). +Implement meshes or just verify that they work. (Resolution: they do!) +Do prim hash codes work for sculpties and meshes? (Resolution: yes) +Linkset implementation using compound shapes. (Resolution: implemented LinksetCompound) + Compound shapes will need the LocalID in the shapes and collision + processing to get it from there. +Light cycle falling over when driving (Resolution: implemented VerticalAttractor) +Light cycle not banking (Resolution: It doesn't. Banking is roll adding yaw.) +Package Bullet source mods for Bullet internal stats output + (Resolution: move code into WorldData.h rather than relying on patches) \ No newline at end of file -- cgit v1.1 From 7fd8202ae3fbe5627396f34dfc03e3571f4f9fe4 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 6 Dec 2012 09:24:24 -0800 Subject: BulletSim: rewrite and improve vehicle angularDeflection, verticalAttraction, linearMotorUp and related vehicle forces. Fixed problems with downward vehicle position correction forces being too large. Add vehicle collision flag so can sense whether vehicle is on the ground. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 212 +++++++++++++-------- .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 1 + 2 files changed, 130 insertions(+), 83 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 09aee17..fa3110c 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -24,21 +24,10 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - -/* RA: June 14, 2011. Copied from ODEDynamics.cs and converted to - * call the BulletSim system. - */ -/* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces - * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised: - * ODEPrim.cs contains methods dealing with Prim editing, Prim - * characteristics and Kinetic motion. - * ODEDynamics.cs contains methods dealing with Prim Physical motion - * (dynamics) and the associated settings. Old Linear and angular - * motors for dynamic motion have been replace with MoveLinear() - * and MoveAngular(); 'Physical' is used only to switch ODE dynamic - * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_ is to - * switch between 'VEHICLE' parameter use and general dynamics - * settings use. + * The quotations from http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial + * are Copyright (c) 2009 Linden Research, Inc and are used under their license + * of Creative Commons Attribution-Share Alike 3.0 + * (http://creativecommons.org/licenses/by-sa/3.0/). */ using System; @@ -111,7 +100,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin private float m_bankingEfficiency = 0; private float m_bankingMix = 0; private float m_bankingTimescale = 0; - private Vector3 m_lastBanking = Vector3.Zero; //Hover and Buoyancy properties private float m_VhoverHeight = 0f; @@ -125,8 +113,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin //Attractor properties private BSVMotor m_verticalAttractionMotor = new BSVMotor("VerticalAttraction"); - private float m_verticalAttractionEfficiency = 1.0f; // damped - private float m_verticalAttractionTimescale = 600f; // Timescale > 500 means no vert attractor. + private float m_verticalAttractionEfficiency = 1.0f; // damped + private float m_verticalAttractionCutoff = 500f; // per the documentation + // Timescale > cutoff means no vert attractor. + private float m_verticalAttractionTimescale = 510f; public BSDynamics(BSScene myScene, BSPrim myPrim) { @@ -329,7 +319,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingEfficiency = 0; m_bankingTimescale = 1000; m_bankingMix = 1; - m_lastBanking = Vector3.Zero; m_referenceFrame = Quaternion.Identity; m_flags = (VehicleFlag)0; @@ -364,7 +353,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingEfficiency = 0; m_bankingTimescale = 10; m_bankingMix = 1; - m_lastBanking = Vector3.Zero; m_referenceFrame = Quaternion.Identity; m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY @@ -374,6 +362,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP); + break; case Vehicle.TYPE_CAR: m_linearMotorDirection = Vector3.Zero; @@ -403,7 +392,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingEfficiency = -0.2f; m_bankingMix = 1; m_bankingTimescale = 1; - m_lastBanking = Vector3.Zero; m_referenceFrame = Quaternion.Identity; m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY @@ -442,7 +430,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingEfficiency = -0.3f; m_bankingMix = 0.8f; m_bankingTimescale = 1; - m_lastBanking = Vector3.Zero; m_referenceFrame = Quaternion.Identity; m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY @@ -481,7 +468,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingEfficiency = 1; m_bankingMix = 0.7f; m_bankingTimescale = 2; - m_lastBanking = Vector3.Zero; m_referenceFrame = Quaternion.Identity; m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY @@ -520,7 +506,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingEfficiency = 0; m_bankingMix = 0.7f; m_bankingTimescale = 5; - m_lastBanking = Vector3.Zero; m_referenceFrame = Quaternion.Identity; @@ -554,8 +539,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Z goes away and we keep X and Y m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f); m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) - - // m_bankingMotor = new BSVMotor("BankingMotor", ...); } // Some of the properties of this prim may have changed. @@ -577,15 +560,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin float angularDamping = PhysicsScene.Params.vehicleAngularDamping; BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, angularDamping); + // Vehicles report collision events so we know when it's on the ground + BulletSimAPI.AddToCollisionFlags2(Prim.PhysBody.ptr, CollisionFlags.BS_VEHICLE_COLLISIONS); + // DEBUG DEBUG DEBUG: use uniform inertia to smooth movement added by Bullet // Vector3 localInertia = new Vector3(1f, 1f, 1f); - Vector3 localInertia = new Vector3(m_vehicleMass, m_vehicleMass, m_vehicleMass); + // Vector3 localInertia = new Vector3(m_vehicleMass, m_vehicleMass, m_vehicleMass); + Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(Prim.PhysShape.ptr, m_vehicleMass); BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia); BulletSimAPI.UpdateInertiaTensor2(Prim.PhysBody.ptr); VDetailLog("{0},BSDynamics.Refresh,frict={1},inert={2},aDamp={3}", Prim.LocalID, friction, localInertia, angularDamping); } + else + { + BulletSimAPI.RemoveFromCollisionFlags2(Prim.PhysBody.ptr, CollisionFlags.BS_VEHICLE_COLLISIONS); + } } public bool RemoveBodyDependencies(BSPhysObject prim) @@ -618,10 +609,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin private float? m_knownWaterLevel; private Vector3? m_knownPosition; private Vector3? m_knownVelocity; - private Vector3? m_knownForce; + private Vector3 m_knownForce; private Quaternion? m_knownOrientation; private Vector3? m_knownRotationalVelocity; - private Vector3? m_knownRotationalForce; + private Vector3 m_knownRotationalForce; + private float? m_knownForwardSpeed; private const int m_knownChangedPosition = 1 << 0; private const int m_knownChangedVelocity = 1 << 1; @@ -636,10 +628,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_knownWaterLevel = null; m_knownPosition = null; m_knownVelocity = null; - m_knownForce = null; + m_knownForce = Vector3.Zero; m_knownOrientation = null; m_knownRotationalVelocity = null; - m_knownRotationalForce = null; + m_knownRotationalForce = Vector3.Zero; + m_knownForwardSpeed = null; m_knownChanged = 0; } private void PushKnownChanged() @@ -761,6 +754,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_knownRotationalForce += aForce; m_knownChanged |= m_knownChangedRotationalForce; } + private float VehicleForwardSpeed + { + get + { + if (m_knownForwardSpeed == null) + m_knownForwardSpeed = (VehicleVelocity * Quaternion.Inverse(VehicleOrientation)).X; + return (float)m_knownForwardSpeed; + } + } + #endregion // Known vehicle value functions // One step of the vehicle properties for the next 'pTimestep' seconds. @@ -798,7 +801,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ================================================================== // Buoyancy: force to overcome gravity. // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; - Vector3 buoyancyContribution = Prim.PhysicsScene.DefaultGravity * (m_VehicleBuoyancy - 1f); + // So, if zero, don't change anything (let gravity happen). If one, negate the effect of gravity. + Vector3 buoyancyContribution = Prim.PhysicsScene.DefaultGravity * m_VehicleBuoyancy; Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(pTimestep); @@ -847,8 +851,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin VehicleAddForce(totalDownForce); } - VDetailLog("{0}, MoveLinear,done,newVel={1},totDown={2},linContrib={3},terrContrib={4},hoverContrib={5},limitContrib={6},buoyContrib={7}", - Prim.LocalID, newVelocity, totalDownForce, + VDetailLog("{0}, MoveLinear,done,newVel={1},totDown={2},IsColliding={3}", + Prim.LocalID, newVelocity, totalDownForce, Prim.IsColliding); + VDetailLog("{0}, MoveLinear,done,linContrib={1},terrContrib={2},hoverContrib={3},limitContrib={4},buoyContrib={5}", + Prim.LocalID, linearMotorContribution, terrainHeightContribution, hoverContribution, limitMotorUpContribution, buoyancyContribution ); @@ -971,21 +977,24 @@ namespace OpenSim.Region.Physics.BulletSPlugin } // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags : - // Prevent ground vehicles from motoring into the sky.This flag has a subtle effect when + // Prevent ground vehicles from motoring into the sky. This flag has a subtle effect when // used with conjunction with banking: the strength of the banking will decay when the // vehicle no longer experiences collisions. The decay timescale is the same as // VEHICLE_BANKING_TIMESCALE. This is to help prevent ground vehicles from steering // when they are in mid jump. - // TODO: this code is wrong. Also, what should it do for boats? + // TODO: this code is wrong. Also, what should it do for boats (height from water)? + // This is just using the ground and a general collision check. Should really be using + // a downward raycast to find what is below. public Vector3 ComputeLinearMotorUp(float pTimestep) { Vector3 ret = Vector3.Zero; + if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) { // If the vehicle is motoring into the sky, get it going back down. - // float distanceAboveGround = pos.Z - Math.Max(GetTerrainHeight(pos), GetWaterLevel(pos)); float distanceAboveGround = VehiclePosition.Z - GetTerrainHeight(VehiclePosition); - if (distanceAboveGround > 1f) + // Not colliding if the vehicle is off the ground + if (!Prim.IsColliding) { // downForce = new Vector3(0, 0, (-distanceAboveGround / m_bankingTimescale) * pTimestep); // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); @@ -1006,8 +1015,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ======================================================================= // Apply the effect of the angular motor. // The 'contribution' is how much angular correction velocity each function wants. - // All the contributions are added together and the orientation of the vehicle - // is changed by all the contributed corrections. + // All the contributions are added together and the resulting velocity is + // set directly on the vehicle. private void MoveAngular(float pTimestep) { // The user wants how many radians per second angular change? @@ -1030,7 +1039,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 deflectionContribution = ComputeAngularDeflection(); - Vector3 bankingContribution = ComputeAngularBanking(angularMotorContribution.Z); + Vector3 bankingContribution = ComputeAngularBanking(); // ================================================================== m_lastVertAttractor = verticalAttractionContribution; @@ -1095,13 +1104,20 @@ namespace OpenSim.Region.Physics.BulletSPlugin } } - + // From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial: + // Some vehicles, like boats, should always keep their up-side up. This can be done by + // enabling the "vertical attractor" behavior that springs the vehicle's local z-axis to + // the world z-axis (a.k.a. "up"). To take advantage of this feature you would set the + // VEHICLE_VERTICAL_ATTRACTION_TIMESCALE to control the period of the spring frequency, + // and then set the VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY to control the damping. An + // efficiency of 0.0 will cause the spring to wobble around its equilibrium, while an + // efficiency of 1.0 will cause the spring to reach its equilibrium with exponential decay. public Vector3 ComputeAngularVerticalAttraction() { Vector3 ret = Vector3.Zero; // If vertical attaction timescale is reasonable and we applied an angular force last time... - if (m_verticalAttractionTimescale < 500) + if (m_verticalAttractionTimescale < m_verticalAttractionCutoff) { // Take a vector pointing up and convert it from world to vehicle relative coords. Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; @@ -1128,9 +1144,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Scale the correction force by how far we're off from vertical. // Z error of one says little error. As Z gets smaller, the vehicle is leaning farther over. - // float clampedZError = ClampInRange(0.1f, Math.Abs(verticalError.Z), 1f); float clampedSqrZError = ClampInRange(0.01f, verticalError.Z * verticalError.Z, 1f); - // float vertForce = 1f / clampedSqrZError * m_verticalAttractionEfficiency; float vertForce = 1f / clampedSqrZError; ret *= vertForce; @@ -1147,70 +1161,102 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Return the angular correction to correct the direction the vehicle is pointing to be // the direction is should want to be pointing. + // The vehicle is moving in some direction and correct its orientation to it is pointing + // in that direction. + // TODO: implement reference frame. public Vector3 ComputeAngularDeflection() { Vector3 ret = Vector3.Zero; - return ret; // DEBUG DEBUG DEBUG debug the other contributors first + return ret; // DEBUG DEBUG DEBUG debug one force at a time if (m_angularDeflectionEfficiency != 0) { - // Where the vehicle should want to point relative to the vehicle - Vector3 preferredDirection = Vector3.UnitX * m_referenceFrame; + // The direction the vehicle is moving + Vector3 movingDirection = VehicleVelocity; + movingDirection.Normalize(); - // Where the vehicle is pointing relative to the vehicle. - Vector3 currentDirection = Vector3.UnitX * Quaternion.Add(VehicleOrientation, m_referenceFrame); + // The direction the vehicle is pointing + Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation; + pointingDirection.Normalize(); - // Difference between where vehicle is pointing and where it should wish to point - Vector3 directionCorrection = preferredDirection - currentDirection; + // The difference between what is and what should be + Vector3 deflectionError = movingDirection - pointingDirection; // Scale the correction by recovery timescale and efficiency - ret = directionCorrection * m_angularDeflectionEfficiency / m_angularDeflectionTimescale; + ret = (-deflectionError * VehicleForwardSpeed) * m_angularDeflectionEfficiency; + ret /= m_angularDeflectionTimescale; - VDetailLog("{0}, MoveAngular,Deflection,perfDir={1},currentDir={2},dirCorrection={3},ret={4}", - Prim.LocalID, preferredDirection, currentDirection, directionCorrection, ret); + VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}", + Prim.LocalID, movingDirection, pointingDirection, deflectionError, ret); } return ret; } - // Return an angular change to tip the vehicle (around X axis) when turning (turned around Z). - // Remembers the last banking value calculated and returns the difference needed this tick. - // TurningFactor is rate going left or right (pos=left, neg=right, scale=0..1). - public Vector3 ComputeAngularBanking(float turningFactor) + // Return an angular change to rotate the vehicle around the Z axis when the vehicle + // is tipped around the X axis. + // From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial: + // The vertical attractor feature must be enabled in order for the banking behavior to + // function. The way banking works is this: a rotation around the vehicle's roll-axis will + // produce a angular velocity around the yaw-axis, causing the vehicle to turn. The magnitude + // of the yaw effect will be proportional to the + // VEHICLE_BANKING_EFFICIENCY, the angle of the roll rotation, and sometimes the vehicle's + // velocity along its preferred axis of motion. + // The VEHICLE_BANKING_EFFICIENCY can vary between -1 and +1. When it is positive then any + // positive rotation (by the right-hand rule) about the roll-axis will effect a + // (negative) torque around the yaw-axis, making it turn to the right--that is the + // vehicle will lean into the turn, which is how real airplanes and motorcycle's work. + // Negating the banking coefficient will make it so that the vehicle leans to the + // outside of the turn (not very "physical" but might allow interesting vehicles so why not?). + // The VEHICLE_BANKING_MIX is a fake (i.e. non-physical) parameter that is useful for making + // banking vehicles do what you want rather than what the laws of physics allow. + // For example, consider a real motorcycle...it must be moving forward in order for + // it to turn while banking, however video-game motorcycles are often configured + // to turn in place when at a dead stop--because they are often easier to control + // that way using the limited interface of the keyboard or game controller. The + // VEHICLE_BANKING_MIX enables combinations of both realistic and non-realistic + // banking by functioning as a slider between a banking that is correspondingly + // totally static (0.0) and totally dynamic (1.0). By "static" we mean that the + // banking effect depends only on the vehicle's rotation about its roll-axis compared + // to "dynamic" where the banking is also proportional to its velocity along its + // roll-axis. Finding the best value of the "mixture" will probably require trial and error. + // The time it takes for the banking behavior to defeat a preexisting angular velocity about the + // world z-axis is determined by the VEHICLE_BANKING_TIMESCALE. So if you want the vehicle to + // bank quickly then give it a banking timescale of about a second or less, otherwise you can + // make a sluggish vehicle by giving it a timescale of several seconds. + public Vector3 ComputeAngularBanking() { Vector3 ret = Vector3.Zero; - Vector3 computedBanking = Vector3.Zero; - return ret; // DEBUG DEBUG DEBUG debug the other contributors first - if (m_bankingEfficiency != 0) + if (m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) { - Vector3 currentDirection = Vector3.UnitX * VehicleOrientation; - - float mult = (m_bankingMix * m_bankingMix) * -1 * (m_bankingMix < 0 ? -1 : 1); + // This works by rotating a unit vector to the orientation of the vehicle. The + // roll (tilt) will be Y component of a tilting Z vector (zero for no tilt + // up to one for full over). + Vector3 rollComponents = Vector3.UnitZ * VehicleOrientation; - //Use the square of the efficiency, as it looks much more how SL banking works - float effSquared = (m_bankingEfficiency * m_bankingEfficiency); - if (m_bankingEfficiency < 0) - effSquared *= -1; //Keep the negative! + // Figure out the yaw value for this much roll. + float turnComponent = rollComponents.Y * rollComponents.Y * m_bankingEfficiency; + // Keep the sign + if (rollComponents.Y < 0f) + turnComponent = -turnComponent; - float mix = Math.Abs(m_bankingMix); - // TODO: Must include reference frame. - float forwardSpeed = VehicleVelocity.X; + // TODO: there must be a better computation of the banking force. + float bankingTurnForce = turnComponent; - if (!Prim.IsColliding && forwardSpeed > mix) - { - computedBanking.X = ClampInRange(-3f, turningFactor * (effSquared * mult), 3f); - } + // actual error = static turn error + dynamic turn error + float mixedBankingError = bankingTurnForce * (1f - m_bankingMix) + bankingTurnForce * m_bankingMix * VehicleForwardSpeed; + // TODO: the banking effect should not go to infinity but what to limit it to? + mixedBankingError = ClampInRange(-20f, mixedBankingError, 20f); - // 'computedBanking' is now how much banking that should be happening. - ret = computedBanking - m_lastBanking; + // Build the force vector to change rotation from what it is to what it should be + ret.Z = -mixedBankingError; - // Scale the correction by timescale and efficiency - ret /= m_bankingTimescale * m_bankingEfficiency; + // Don't do it all at once. + ret /= m_bankingTimescale; - VDetailLog("{0}, MoveAngular,Banking,computedB={1},lastB={2},bEff={3},effSq={4},mult={5},mix={6},banking={7}", - Prim.LocalID, computedBanking, m_lastBanking, m_bankingEfficiency, effSquared, mult, mix, ret); + VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},turnComp={3},bankErr={4},mixedBankErr={5},ret={6}", + Prim.LocalID, rollComponents, VehicleForwardSpeed, turnComponent, bankingTurnForce, mixedBankingError, ret); } - m_lastBanking = computedBanking; return ret; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index a5acfd1..2671995 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -360,6 +360,7 @@ public enum CollisionFlags : uint // Following used by BulletSim to control collisions and updates BS_SUBSCRIBE_COLLISION_EVENTS = 1 << 10, BS_FLOATS_ON_WATER = 1 << 11, + BS_VEHICLE_COLLISIONS = 1 << 12, BS_NONE = 0, BS_ALL = 0xFFFFFFFF, -- cgit v1.1 From 0568c76a8801408665730702c97717d3c05cfe4d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 7 Dec 2012 00:47:04 +0000 Subject: Use a thread abort safe version of OpenMetaverse.DoubleDictionary with the aim of avoiding OpenSimulator problems due to script thread aborts. When an object is removed, its scripts are stopped and then the thread running them is aborted if stop takes too long. However, it appears that aborting a thread at just the wrong moment when it is obtaining a ReaderWriterLockSlim lock can leave this lock in an inconsistent state. One symptom of this is that mono leaps to 100% cpu and a vm thread dump reveals lots of threads waiting for a ReaderWriterLockSlim lock without any thread actually holding it. This is probably the same problem as encountered originally in commit 12cebb12 This commit looks to plaster this problem by putting lock obtaining methods inside finally blocks which should be uninterruptible by thread aborts. --- OpenSim/Region/Framework/Scenes/EntityManager.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/EntityManager.cs b/OpenSim/Region/Framework/Scenes/EntityManager.cs index b788a3c..7181313 100644 --- a/OpenSim/Region/Framework/Scenes/EntityManager.cs +++ b/OpenSim/Region/Framework/Scenes/EntityManager.cs @@ -31,6 +31,7 @@ using System.Collections.Generic; using System.Reflection; using log4net; using OpenMetaverse; +using OpenSim.Framework; namespace OpenSim.Region.Framework.Scenes { @@ -38,7 +39,8 @@ namespace OpenSim.Region.Framework.Scenes { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private readonly DoubleDictionary m_entities = new DoubleDictionary(); + private readonly DoubleDictionaryThreadAbortSafe m_entities + = new DoubleDictionaryThreadAbortSafe(); public int Count { -- cgit v1.1 From 63cff49bceab2a8edc889d1abaae840512bf60e6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 8 Dec 2012 01:29:58 +0000 Subject: Re-enable code disabled in f605a62 to allow a TaskInventoryAccepted message to nominate a non-root destination folder. This is in relation to http://opensimulator.org/mantis/view.php?id=6311 This is after further analysis which shows the viewer expects the server to move the folder for #RLV give but then should be renaming the folder itself. For some reason this is not happening, possibly because we are not sending BulkUpdates or because we are not using transaction IDs properly. This needs to be fixed in the future. However, moving the folder even if the rename isn't correctly triggered in the viewer seems preferable to disabling this code altogether. --- .../Inventory/Transfer/InventoryTransferModule.cs | 138 ++++++++++----------- 1 file changed, 68 insertions(+), 70 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs index 582aac4..bcb7f42 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs @@ -300,76 +300,74 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer } } - // Disabled for now as it looks like http://opensimulator.org/mantis/view.php?id=6311 was fixed by fixes - // to inventory folder versioning allowing the viewer to move the received folder itself as happens on the - // LL grid. Doing it again server-side then wrongly does a second create and move -// // XXX: This code was placed here to try and accomdate RLV which moves given folders named #RLV/~ -// // to a folder called name in #RLV. However, this approach may not be ultimately correct - from analysis -// // of Firestorm 4.2.2 on sending an InventoryOffered instead of TaskInventoryOffered (as was previously -// // done), the viewer itself would appear to move and rename the folder, rather than the simulator doing it here. -// else if (im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted) -// { -// UUID destinationFolderID = UUID.Zero; -// -// if (im.binaryBucket != null && im.binaryBucket.Length >= 16) -// { -// destinationFolderID = new UUID(im.binaryBucket, 0); -// } -// -// if (destinationFolderID != UUID.Zero) -// { -// InventoryFolderBase destinationFolder = new InventoryFolderBase(destinationFolderID, client.AgentId); -// if (destinationFolder == null) -// { -// m_log.WarnFormat( -// "[INVENTORY TRANSFER]: TaskInventoryAccepted message from {0} in {1} specified folder {2} which does not exist", -// client.Name, scene.Name, destinationFolderID); -// -// return; -// } -// -// IInventoryService invService = scene.InventoryService; -// -// UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip -// -// InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId); -// item = invService.GetItem(item); -// InventoryFolderBase folder = null; -// UUID? previousParentFolderID = null; -// -// if (item != null) // It's an item -// { -// previousParentFolderID = item.Folder; -// item.Folder = destinationFolderID; -// -// invService.DeleteItems(item.Owner, new List() { item.ID }); -// scene.AddInventoryItem(client, item); -// } -// else -// { -// folder = new InventoryFolderBase(inventoryID, client.AgentId); -// folder = invService.GetFolder(folder); -// -// if (folder != null) // It's a folder -// { -// previousParentFolderID = folder.ParentID; -// folder.ParentID = destinationFolderID; -// invService.MoveFolder(folder); -// } -// } -// -// // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code). -// if (previousParentFolderID != null) -// { -// InventoryFolderBase previousParentFolder -// = new InventoryFolderBase((UUID)previousParentFolderID, client.AgentId); -// previousParentFolder = invService.GetFolder(previousParentFolder); -// scene.SendInventoryUpdate(client, previousParentFolder, true, true); -// -// scene.SendInventoryUpdate(client, destinationFolder, true, true); -// } -// } -// } + // XXX: This code was placed here to try and accomodate RLV which moves given folders named #RLV/~ + // to the requested folder, which in this case is #RLV. However, it is the viewer that appears to be + // response from renaming the #RLV/~example folder to ~example. For some reason this is not yet + // happening, possibly because we are not sending the correct inventory update messages with the correct + // transaction IDs + else if (im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted) + { + UUID destinationFolderID = UUID.Zero; + + if (im.binaryBucket != null && im.binaryBucket.Length >= 16) + { + destinationFolderID = new UUID(im.binaryBucket, 0); + } + + if (destinationFolderID != UUID.Zero) + { + InventoryFolderBase destinationFolder = new InventoryFolderBase(destinationFolderID, client.AgentId); + if (destinationFolder == null) + { + m_log.WarnFormat( + "[INVENTORY TRANSFER]: TaskInventoryAccepted message from {0} in {1} specified folder {2} which does not exist", + client.Name, scene.Name, destinationFolderID); + + return; + } + + IInventoryService invService = scene.InventoryService; + + UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip + + InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId); + item = invService.GetItem(item); + InventoryFolderBase folder = null; + UUID? previousParentFolderID = null; + + if (item != null) // It's an item + { + previousParentFolderID = item.Folder; + item.Folder = destinationFolderID; + + invService.DeleteItems(item.Owner, new List() { item.ID }); + scene.AddInventoryItem(client, item); + } + else + { + folder = new InventoryFolderBase(inventoryID, client.AgentId); + folder = invService.GetFolder(folder); + + if (folder != null) // It's a folder + { + previousParentFolderID = folder.ParentID; + folder.ParentID = destinationFolderID; + invService.MoveFolder(folder); + } + } + + // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code). + if (previousParentFolderID != null) + { + InventoryFolderBase previousParentFolder + = new InventoryFolderBase((UUID)previousParentFolderID, client.AgentId); + previousParentFolder = invService.GetFolder(previousParentFolder); + scene.SendInventoryUpdate(client, previousParentFolder, true, true); + + scene.SendInventoryUpdate(client, destinationFolder, true, true); + } + } + } else if ( im.dialog == (byte)InstantMessageDialog.InventoryDeclined || im.dialog == (byte)InstantMessageDialog.TaskInventoryDeclined) -- cgit v1.1 From addb791f3df481560d36cbeea6824bfe48d0d971 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 6 Dec 2012 13:00:52 -0800 Subject: BulletSim: update comments and add more to TODO list. --- OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | 6 +++--- OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | 8 +++++++- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index b9c2cf9..492c7b1 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -59,7 +59,7 @@ public sealed class BSLinksetCompound : BSLinkset // refresh will happen once after all the other taints are applied. public override void Refresh(BSPhysObject requestor) { - // External request for Refresh (from BSPrim) is not necessary + // External request for Refresh (from BSPrim) doesn't need to do anything // InternalRefresh(requestor); } @@ -86,7 +86,7 @@ public sealed class BSLinksetCompound : BSLinkset DetailLog("{0},BSLinksetCompound.MakeDynamic,call,IsRoot={1}", child.LocalID, IsRoot(child)); if (!IsRoot(child)) { - // Physical children are removed from the world as the shape ofthe root compound + // The origional prims are removed from the world as the shape of the root compound // shape takes over. BulletSimAPI.AddToCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); BulletSimAPI.ForceActivationState2(child.PhysBody.ptr, ActivationState.DISABLE_SIMULATION); @@ -118,7 +118,7 @@ public sealed class BSLinksetCompound : BSLinkset // Called at taint-time!! public override void UpdateProperties(BSPhysObject updated) { - // Nothing to do for constraints on property updates + // Nothing to do for compound linksets on property updates } // The children move around in relationship to the root. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index d51003c..a2161c3 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -5,6 +5,9 @@ CRASHES 20121128.1600: mesh object not rezzing (no physics mesh). Causes many errors. Doesn't stop after first error with box shape. Eventually crashes when deleting the object. +20121206.1434: rez Sam-pan into OSGrid BulletSim11 region + Immediate simulator crash. Mono does not output any stacktrace and + log just stops after reporting taint-time linking of the linkset. VEHICLES TODO LIST: ================================================= @@ -23,9 +26,12 @@ After getting off a vehicle, the root prim is phantom (can be walked through) Linkset explosion after three "rides" on Nebadon lite vehicle (LinksetConstraint) Implement referenceFrame for all the motion routines. Cannot edit/move a vehicle being ridden: it jumps back to the origional position. +Border crossing with linked vehicle causes crash BULLETSIM TODO LIST: ================================================= +Duplicating a physical prim causes old prim to jump away + Dup a phys prim and the original become unselected and thus interacts w/ selected prim. Disable activity of passive linkset children. Since the linkset is a compound object, the old prims are left lying around and need to be phantomized so they don't collide, ... @@ -96,7 +102,7 @@ Breakout code for mesh/hull/compound/native into separate BSShape* classes Generalize Dynamics and PID with standardized motors. Generalize Linkset and vehicles into PropertyManagers Methods for Refresh, RemoveBodyDependencies, RestoreBodyDependencies - Possibly generalized a 'pre step action' registration. + Potentially add events for shape destruction, etc. Complete implemention of preStepActions Replace vehicle step call with prestep event. Is there a need for postStepActions? postStepTaints? -- cgit v1.1 From 216c121935537f707e6334176e590225fdc988d8 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 8 Dec 2012 08:59:53 -0800 Subject: BulletSim: fix small problem with setting size/scale of native shapes which caused the native shapes to be rebuilt when not necessary. --- OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index e77b6ba..933f573 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -415,7 +415,7 @@ public sealed class BSShapeCollection : IDisposable if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_CAPSULE) { // an avatar capsule is close to a native shape (it is not shared) - ret = GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_CAPSULE, + GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_CAPSULE, FixedShapeKey.KEY_CAPSULE, shapeCallback); if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape); ret = true; @@ -423,7 +423,7 @@ public sealed class BSShapeCollection : IDisposable } // Compound shapes are handled special as they are rebuilt from scratch. - // This isn't too great a hardship since most of the child shapes will already been created. + // This isn't too great a hardship since most of the child shapes will have already been created. if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND) { ret = GetReferenceToCompoundShape(prim, shapeCallback); @@ -460,6 +460,9 @@ public sealed class BSShapeCollection : IDisposable && pbs.PathScaleX == 100 && pbs.PathScaleY == 100 && pbs.PathShearX == 0 && pbs.PathShearY == 0) ) ) { + if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,maybeNative,force={1},primScale={2},primSize={3},primShape={4}", + prim.LocalID, forceRebuild, prim.Scale, prim.Size, prim.PhysShape.type); + // It doesn't look like Bullet scales spheres so make sure the scales are all equal if ((pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1) && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z) @@ -538,6 +541,8 @@ public sealed class BSShapeCollection : IDisposable if (DDetail) DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1},scale={2}", prim.LocalID, newShape, prim.Scale); + // native shapes are scaled by Bullet + prim.Scale = prim.Size; prim.PhysShape = newShape; return true; } @@ -550,8 +555,8 @@ public sealed class BSShapeCollection : IDisposable ShapeData nativeShapeData = new ShapeData(); nativeShapeData.Type = shapeType; nativeShapeData.ID = prim.LocalID; - nativeShapeData.Scale = prim.Scale; - nativeShapeData.Size = prim.Scale; // unneeded, I think. + nativeShapeData.Scale = prim.Size; + nativeShapeData.Size = prim.Size; // unneeded, I think. nativeShapeData.MeshKey = (ulong)shapeKey; nativeShapeData.HullKey = (ulong)shapeKey; @@ -566,8 +571,6 @@ public sealed class BSShapeCollection : IDisposable else { // Native shapes are scaled in Bullet so set the scaling to the size - prim.Scale = prim.Size; - nativeShapeData.Scale = prim.Scale; newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, nativeShapeData), shapeType); } if (newShape.ptr == IntPtr.Zero) -- cgit v1.1 From 04e64d73dfddf9ef3e3716f6c43752c6f63438cb Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 8 Dec 2012 09:12:45 -0800 Subject: BulletSim: set material properties for static objects. Move Linkset.MakeStatic() after call to ForceActivationState2() since linkset might change activation state. Make BSPrim.CreateGeomAndObject public as linkset rebuilding might need access to it. Only rebuild prim if selection state is actually changes -- OpenSimulator calls PhysObject.Selected() multiple times whenever a prim is selected or deselected. --- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 5 ++++ OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 30 ++++++++++++++-------- 2 files changed, 24 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 492c7b1..1f7c398 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -257,6 +257,11 @@ public sealed class BSLinksetCompound : BSLinkset BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, cPrim.PhysShape.ptr, displacementPos, displacementRot); } } + + // TODO: need to phantomize the child prims left behind. + // Maybe just destroy the children bodies and shapes and have them rebuild on unlink. + // Selection/deselection might cause way too many build/destructions esp. for LARGE linksets. + return false; // 'false' says to move onto the next child in the list }); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 62aaf80..4d203ff 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -190,12 +190,15 @@ public sealed class BSPrim : BSPhysObject } public override bool Selected { set { - _isSelected = value; - PhysicsScene.TaintedObject("BSPrim.setSelected", delegate() + if (value != _isSelected) { - DetailLog("{0},BSPrim.selected,taint,selected={1}", LocalID, _isSelected); - SetObjectDynamic(false); - }); + _isSelected = value; + PhysicsScene.TaintedObject("BSPrim.setSelected", delegate() + { + DetailLog("{0},BSPrim.selected,taint,selected={1}", LocalID, _isSelected); + SetObjectDynamic(false); + }); + } } } public override void CrossingFailure() { return; } @@ -678,8 +681,11 @@ public sealed class BSPrim : BSPhysObject CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT); // Stop all movement ZeroMotion(true); - // Center of mass is at the center of the object - // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.PhysBody.ptr, _position, _orientation); + + // Set various physical properties so other object interact properly + BulletSimAPI.SetFriction2(PhysBody.ptr, PhysicsScene.Params.defaultFriction); + BulletSimAPI.SetRestitution2(PhysBody.ptr, PhysicsScene.Params.defaultRestitution); + // Mass is zero which disables a bunch of physics stuff in Bullet UpdatePhysicalMassProperties(0f); // Set collision detection parameters @@ -688,13 +694,15 @@ public sealed class BSPrim : BSPhysObject BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, PhysicsScene.Params.ccdMotionThreshold); BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); } - // There can be special things needed for implementing linksets - Linkset.MakeStatic(this); + // The activation state is 'disabled' so Bullet will not try to act on it. // BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.DISABLE_SIMULATION); // Start it out sleeping and physical actions could wake it up. BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ISLAND_SLEEPING); + // There can be special things needed for implementing linksets + Linkset.MakeStatic(this); + PhysBody.collisionGroup = CollisionFilterGroups.StaticObjectGroup; PhysBody.collisionMask = CollisionFilterGroups.StaticObjectMask; } @@ -1326,7 +1334,7 @@ public sealed class BSPrim : BSPhysObject // Rebuild the geometry and object. // This is called when the shape changes so we need to recreate the mesh/hull. // Called at taint-time!!! - private void CreateGeomAndObject(bool forceRebuild) + public void CreateGeomAndObject(bool forceRebuild) { // If this prim is part of a linkset, we must remove and restore the physical // links if the body is rebuilt. @@ -1341,7 +1349,7 @@ public sealed class BSPrim : BSPhysObject { // Called if the current prim body is about to be destroyed. // Remove all the physical dependencies on the old body. - // (Maybe someday make the changing of BSShape an event handled by BSLinkset.) + // (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...) needToRestoreLinkset = Linkset.RemoveBodyDependencies(this); needToRestoreVehicle = _vehicle.RemoveBodyDependencies(this); }); -- cgit v1.1 From cb80d8a29c0af24421a51087ddb56ad35a5c49b8 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 9 Dec 2012 15:31:11 -0800 Subject: UserManagementModule: search the local cache for names too. Inventory transfers: don't do async on asset transfers or now. --- .../Framework/UserManagement/UserManagementModule.cs | 10 ++++++++++ OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index 86e7004..77e8b00 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -181,6 +181,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement m_log.DebugFormat("[USER MANAGEMENT MODULE]: HandleAvatarPickerRequest for {0}", query); + // searhc the user accounts service List accs = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, query); List users = new List(); @@ -196,6 +197,12 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement } } + // search the local cache + foreach (UserData data in m_UserCache.Values) + if (users.Find(delegate(UserData d) { return d.Id == data.Id; }) == null && + (data.FirstName.StartsWith(query) || data.LastName.StartsWith(query))) + users.Add(data); + AddAdditionalUsers(avatarID, query, users); AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply); @@ -433,6 +440,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement public void AddUser(UUID uuid, string first, string last, string homeURL) { //m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, first {1}, last {2}, url {3}", uuid, first, last, homeURL); + if (homeURL == string.Empty) + return; + AddUser(uuid, homeURL + ";" + first + " " + last); } diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index ad40d6b..e0f3c99 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -692,7 +692,7 @@ namespace OpenSim.Region.Framework.Scenes { IInventoryAccessModule invAccess = RequestModuleInterface(); if (invAccess != null) - Util.FireAndForget(delegate { invAccess.TransferInventoryAssets(itemCopy, senderId, recipient); }); + invAccess.TransferInventoryAssets(itemCopy, senderId, recipient); } if (!Permissions.BypassPermissions()) -- cgit v1.1 From b8178f5a509caf897dac0660db47ea9a5224194a Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 9 Dec 2012 22:03:21 -0800 Subject: Switched the order by which foreign inventory and foreign assets are brought in, to avoid race conditions on the client. --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index e0f3c99..5c8b097 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -688,12 +688,10 @@ namespace OpenSim.Region.Framework.Scenes itemCopy.SalePrice = item.SalePrice; itemCopy.SaleType = item.SaleType; - if (AddInventoryItem(itemCopy)) - { - IInventoryAccessModule invAccess = RequestModuleInterface(); - if (invAccess != null) - invAccess.TransferInventoryAssets(itemCopy, senderId, recipient); - } + IInventoryAccessModule invAccess = RequestModuleInterface(); + if (invAccess != null) + invAccess.TransferInventoryAssets(itemCopy, senderId, recipient); + AddInventoryItem(itemCopy); if (!Permissions.BypassPermissions()) { -- cgit v1.1 From af8d53657d581404e4719a4f2e75eff3c56f524a Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 9 Dec 2012 22:05:12 -0800 Subject: HGAssetMapper: Get wasn't really working. It's true that some assets are copied in the process of being gathered their UUID, but not all. Specifically, terminal assets like textures aren't copied. We have to go one more time through the ids. --- .../Framework/InventoryAccess/HGAssetMapper.cs | 38 ++++++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs index f8ec6de..7871eda 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs @@ -71,7 +71,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess #region Internal functions - public AssetMetadata FetchMetadata(string url, UUID assetID) + private AssetMetadata FetchMetadata(string url, UUID assetID) { if (!url.EndsWith("/") && !url.EndsWith("=")) url = url + "/"; @@ -86,6 +86,27 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess return meta; } + private AssetBase FetchAsset(string url, UUID assetID) + { + // Test if it's already here + AssetBase asset = m_scene.AssetService.Get(assetID.ToString()); + if (asset == null) + { + if (!url.EndsWith("/") && !url.EndsWith("=")) + url = url + "/"; + + asset = m_scene.AssetService.Get(url + assetID.ToString()); + + //if (asset != null) + // m_log.DebugFormat("[HG ASSET MAPPER]: Fetched asset {0} of type {1} from {2} ", assetID, asset.Metadata.Type, url); + //else + // m_log.DebugFormat("[HG ASSET MAPPER]: Unable to fetch asset {0} from {1} ", assetID, url); + + } + + return asset; + } + public bool PostAsset(string url, AssetBase asset) { if (asset != null) @@ -228,11 +249,22 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess if (meta == null) return; - // The act of gathering UUIDs downloads the assets from the remote server + // The act of gathering UUIDs downloads some assets from the remote server + // but not all... Dictionary ids = new Dictionary(); HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, userAssetURL); uuidGatherer.GatherAssetUuids(assetID, (AssetType)meta.Type, ids); - + m_log.DebugFormat("[HG ASSET MAPPER]: Preparing to get {0} assets", ids.Count); + bool success = true; + foreach (UUID uuid in ids.Keys) + if (FetchAsset(userAssetURL, uuid) == null) + success = false; + + // maybe all pieces got here... + if (!success) + m_log.DebugFormat("[HG ASSET MAPPER]: Problems getting item {0} from asset server {1}", assetID, userAssetURL); + else + m_log.DebugFormat("[HG ASSET MAPPER]: Successfully got item {0} from asset server {1}", assetID, userAssetURL); } -- cgit v1.1 From ce5083a504a82712149f5e3dab622d42e260bba3 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 9 Dec 2012 22:10:32 -0800 Subject: BulletSim: adjust friction and restitution based on material type. --- OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | 10 ++++++++++ OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 12 +++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index f6a890e..b05d4ee 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -60,6 +60,9 @@ public abstract class BSPhysObject : PhysicsActor Linkset = BSLinkset.Factory(PhysicsScene, this); LastAssetBuildFailed = false; + // Default material type + Material = MaterialAttributes.Material.Wood; + CollisionCollection = new CollisionEventUpdate(); SubscribedEventsMs = 0; CollidingStep = 0; @@ -109,6 +112,13 @@ public abstract class BSPhysObject : PhysicsActor public abstract bool IsSolid { get; } public abstract bool IsStatic { get; } + // Materialness + public MaterialAttributes.Material Material { get; private set; } + public override void SetMaterial(int material) + { + Material = (MaterialAttributes.Material)material; + } + // Stop all physical motion. public abstract void ZeroMotion(bool inTaintTime); public abstract void ZeroAngularMotion(bool inTaintTime); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 4d203ff..627393a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -683,8 +683,9 @@ public sealed class BSPrim : BSPhysObject ZeroMotion(true); // Set various physical properties so other object interact properly - BulletSimAPI.SetFriction2(PhysBody.ptr, PhysicsScene.Params.defaultFriction); - BulletSimAPI.SetRestitution2(PhysBody.ptr, PhysicsScene.Params.defaultRestitution); + MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false); + BulletSimAPI.SetFriction2(PhysBody.ptr, matAttrib.friction); + BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution); // Mass is zero which disables a bunch of physics stuff in Bullet UpdatePhysicalMassProperties(0f); @@ -711,9 +712,10 @@ public sealed class BSPrim : BSPhysObject // Not a Bullet static object CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT); - // Set various physical properties so internal dynamic properties will get computed correctly as they are set - BulletSimAPI.SetFriction2(PhysBody.ptr, PhysicsScene.Params.defaultFriction); - BulletSimAPI.SetRestitution2(PhysBody.ptr, PhysicsScene.Params.defaultRestitution); + // Set various physical properties so other object interact properly + MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, true); + BulletSimAPI.SetFriction2(PhysBody.ptr, matAttrib.friction); + BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution); // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382 // Since this can be called multiple times, only zero forces when becoming physical -- cgit v1.1 From a19896cc569c037436ad8e65f044224f169d63d4 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 9 Dec 2012 22:32:13 -0800 Subject: BulletSim: some comments about rebuilding linksets (having to recompute and restore a child's position in the world based on its position in the moved linkset). --- OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 1f7c398..bc9f9be 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -192,6 +192,8 @@ public sealed class BSLinksetCompound : BSLinkset child.LocalID, child.PhysBody.ptr.ToString("X")); // Cause the child's body to be rebuilt and thus restored to normal operation + // TODO: position and rotation must be restored because the child could have moved + // based on the linkset. child.ForceBodyShapeRebuild(false); if (!HasAnyChildren) @@ -236,9 +238,10 @@ public sealed class BSLinksetCompound : BSLinkset if (cPrim.PhysShape.isNativeShape) { - // Native shapes are not shared so we need to create a new one. - // A mesh or hull is created because scale is not available on a native shape. - // (TODO: Bullet does have a btScaledCollisionShape. Can that be used?) + // A native shape is turning into a null collision shape because native + // shapes are not shared so we have to hullify it so it will be tracked + // and freed at the correct time. This also solves the scaling problem + // (native shapes scaled but hull/meshes are assumed to not be). BulletShape saveShape = cPrim.PhysShape; cPrim.PhysShape.ptr = IntPtr.Zero; // Don't let the create free the child's shape PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); -- cgit v1.1 From 9df85eadf4b3719a898fda8769313ae023962c25 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 10 Dec 2012 15:35:53 -0800 Subject: BulletSim: Fix crash on the destruction of physical linksets. While fixing the above, add methods to physical body and shape pointer wrapper so routines won't have to know that IntPtr.Zero means no physical instance. Fix problem with physical linksets failing after a few sits and unsits by properly restoring child prom positions for compound linksets after multiple selection and deselections. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 2 + .../Region/Physics/BulletSPlugin/BSConstraint.cs | 4 +- .../Physics/BulletSPlugin/BSConstraint6Dof.cs | 4 +- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 8 ++ .../Physics/BulletSPlugin/BSLinksetCompound.cs | 113 +++++++++++++++++---- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 5 +- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 6 +- .../Physics/BulletSPlugin/BSShapeCollection.cs | 16 +-- .../Physics/BulletSPlugin/BSTerrainHeightmap.cs | 2 +- .../Physics/BulletSPlugin/BSTerrainManager.cs | 4 +- .../Region/Physics/BulletSPlugin/BSTerrainMesh.cs | 6 +- .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 23 +++++ 12 files changed, 155 insertions(+), 38 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 21aa9be..88460cc 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -124,7 +124,9 @@ public sealed class BSCharacter : BSPhysObject PhysicsScene.TaintedObject("BSCharacter.destroy", delegate() { PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null); + PhysBody.Clear(); PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null); + PhysShape.Clear(); }); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs index 65fac00..6b1e304 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs @@ -57,7 +57,7 @@ public abstract class BSConstraint : IDisposable if (m_enabled) { m_enabled = false; - if (m_constraint.ptr != IntPtr.Zero) + if (m_constraint.HasPhysicalConstraint) { bool success = BulletSimAPI.DestroyConstraint2(m_world.ptr, m_constraint.ptr); m_world.physicsScene.DetailLog("{0},BSConstraint.Dispose,taint,id1={1},body1={2},id2={3},body2={4},success={5}", @@ -65,7 +65,7 @@ public abstract class BSConstraint : IDisposable m_body1.ID, m_body1.ptr.ToString("X"), m_body2.ID, m_body2.ptr.ToString("X"), success); - m_constraint.ptr = System.IntPtr.Zero; + m_constraint.Clear(); } } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs index 23ef052..b073555 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs @@ -65,7 +65,7 @@ public sealed class BSConstraint6Dof : BSConstraint m_world = world; m_body1 = obj1; m_body2 = obj2; - if (obj1.ptr == IntPtr.Zero || obj2.ptr == IntPtr.Zero) + if (!obj1.HasPhysicalBody || !obj2.HasPhysicalBody) { world.physicsScene.DetailLog("{0},BS6DOFConstraint,badBodyPtr,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}", BSScene.DetailLogZero, world.worldID, @@ -83,7 +83,7 @@ public sealed class BSConstraint6Dof : BSConstraint world.physicsScene.DetailLog("{0},BS6DofConstraint,createMidPoint,wID={1}, csrt={2}, rID={3}, rBody={4}, cID={5}, cBody={6}", BSScene.DetailLogZero, world.worldID, m_constraint.ptr.ToString("X"), obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X")); - if (m_constraint.ptr == IntPtr.Zero) + if (!m_constraint.HasPhysicalConstraint) { world.physicsScene.Logger.ErrorFormat("{0} Failed creation of 6Dof constraint. rootID={1}, childID={2}", LogHeader, obj1.ID, obj2.ID); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 0df4310..777c5cb 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -32,6 +32,14 @@ using OMV = OpenMetaverse; namespace OpenSim.Region.Physics.BulletSPlugin { + +// A BSPrim can get individual information about its linkedness attached +// to it through an instance of a subclass of LinksetInfo. +// Each type of linkset will define the information needed for its type. +public abstract class BSLinksetInfo +{ +} + public abstract class BSLinkset { // private static string LogHeader = "[BULLETSIM LINKSET]"; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index bc9f9be..fe5b5e3 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -32,6 +32,31 @@ using OMV = OpenMetaverse; namespace OpenSim.Region.Physics.BulletSPlugin { + +// When a child is linked, the relationship position of the child to the parent +// is remembered so the child's world position can be recomputed when it is +// removed from the linkset. +sealed class BSLinksetCompoundInfo : BSLinksetInfo +{ + public OMV.Vector3 OffsetPos; + public OMV.Quaternion OffsetRot; + public BSLinksetCompoundInfo(OMV.Vector3 p, OMV.Quaternion r) + { + OffsetPos = p; + OffsetRot = r; + } + public override string ToString() + { + StringBuilder buff = new StringBuilder(); + buff.Append(""); + return buff.ToString(); + } +}; + public sealed class BSLinksetCompound : BSLinkset { private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]"; @@ -44,6 +69,7 @@ public sealed class BSLinksetCompound : BSLinkset // For compound implimented linksets, if there are children, use compound shape for the root. public override BSPhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor) { + // Returning 'unknown' means we don't have a preference. BSPhysicsShapeType ret = BSPhysicsShapeType.SHAPE_UNKNOWN; if (IsRoot(requestor) && HasAnyChildren) { @@ -63,10 +89,10 @@ public sealed class BSLinksetCompound : BSLinkset // InternalRefresh(requestor); } + // Schedule a refresh to happen after all the other taint processing. private void InternalRefresh(BSPhysObject requestor) { DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,requestor={1}", LinksetRoot.LocalID, requestor.LocalID); - // Queue to happen after all the other taint processing PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", requestor.LocalID, delegate() { if (IsRoot(requestor) && HasAnyChildren) @@ -108,7 +134,7 @@ public sealed class BSLinksetCompound : BSLinkset { // The non-physical children can come back to life. BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); - // Don't force activation so setting of DISABLE_SIMULATION can stay. + // Don't force activation so setting of DISABLE_SIMULATION can stay if used. BulletSimAPI.Activate2(child.PhysBody.ptr, false); ret = true; } @@ -146,6 +172,10 @@ public sealed class BSLinksetCompound : BSLinkset if (!IsRoot(child)) { + // Because it is a convenient time, recompute child world position and rotation based on + // its position in the linkset. + RecomputeChildWorldPosition(child, true); + // Cause the current shape to be freed and the new one to be built. InternalRefresh(LinksetRoot); ret = true; @@ -154,6 +184,42 @@ public sealed class BSLinksetCompound : BSLinkset return ret; } + // When the linkset is built, the child shape is added + // to the compound shape relative to the root shape. The linkset then moves around but + // this does not move the actual child prim. The child prim's location must be recomputed + // based on the location of the root shape. + private void RecomputeChildWorldPosition(BSPhysObject child, bool inTaintTime) + { + BSLinksetCompoundInfo lci = child.LinksetInfo as BSLinksetCompoundInfo; + if (lci != null) + { + if (inTaintTime) + { + OMV.Vector3 oldPos = child.RawPosition; + child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetPos; + child.ForceOrientation = LinksetRoot.RawOrientation * lci.OffsetRot; + DetailLog("{0},BSLinksetCompound.RecomputeChildWorldPosition,oldPos={1},lci={2},newPos={3}", + child.LocalID, oldPos, lci, child.RawPosition); + } + else + { + // TaintedObject is not used here so the raw position is set now and not at taint-time. + child.Position = LinksetRoot.RawPosition + lci.OffsetPos; + child.Orientation = LinksetRoot.RawOrientation * lci.OffsetRot; + } + } + else + { + // This happens when children have been added to the linkset but the linkset + // has not been constructed yet. So like, at taint time, adding children to a linkset + // and then changing properties of the children (makePhysical, for instance) + // but the post-print action of actually rebuilding the linkset has not yet happened. + // PhysicsScene.Logger.WarnFormat("{0} Restoring linkset child position failed because of no relative position computed. ID={1}", + // LogHeader, child.LocalID); + DetailLog("{0},BSLinksetCompound.recomputeChildWorldPosition,noRelativePositonInfo", child.LocalID); + } + } + // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true', // this routine will restore the removed constraints. // Called at taint-time!! @@ -192,8 +258,7 @@ public sealed class BSLinksetCompound : BSLinkset child.LocalID, child.PhysBody.ptr.ToString("X")); // Cause the child's body to be rebuilt and thus restored to normal operation - // TODO: position and rotation must be restored because the child could have moved - // based on the linkset. + RecomputeChildWorldPosition(child, false); child.ForceBodyShapeRebuild(false); if (!HasAnyChildren) @@ -228,43 +293,57 @@ public sealed class BSLinksetCompound : BSLinkset { if (!IsRoot(cPrim)) { - // Each child position and rotation is given relative to the root. - OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); - OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; - OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; + // Compute the displacement of the child from the root of the linkset. + // This info is saved in the child prim so the relationship does not + // change over time and the new child position can be computed + // when the linkset is being disassembled (the linkset may have moved). + BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; + if (lci == null) + { + // Each child position and rotation is given relative to the root. + OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); + OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; + OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; + + // Save relative position for recomputing child's world position after moving linkset. + lci = new BSLinksetCompoundInfo(displacementPos, displacementRot); + cPrim.LinksetInfo = lci; + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); + } DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}", - LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, displacementPos, displacementRot); + LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); if (cPrim.PhysShape.isNativeShape) { - // A native shape is turning into a null collision shape because native + // A native shape is turning into a hull collision shape because native // shapes are not shared so we have to hullify it so it will be tracked // and freed at the correct time. This also solves the scaling problem // (native shapes scaled but hull/meshes are assumed to not be). + // TODO: decide of the native shape can just be used in the compound shape. + // Use call to CreateGeomNonSpecial(). BulletShape saveShape = cPrim.PhysShape; - cPrim.PhysShape.ptr = IntPtr.Zero; // Don't let the create free the child's shape + cPrim.PhysShape.Clear(); // Don't let the create free the child's shape + // PhysicsScene.Shapes.CreateGeomNonSpecial(true, cPrim, null); PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); BulletShape newShape = cPrim.PhysShape; cPrim.PhysShape = saveShape; - BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, newShape.ptr, displacementPos, displacementRot); + BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, newShape.ptr, lci.OffsetPos , lci.OffsetRot); } else { // For the shared shapes (meshes and hulls), just use the shape in the child. + // The reference count added here will be decremented when the compound shape + // is destroyed in BSShapeCollection (the child shapes are looped over and dereferenced). if (PhysicsScene.Shapes.ReferenceShape(cPrim.PhysShape)) { PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); } - BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, cPrim.PhysShape.ptr, displacementPos, displacementRot); + BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, cPrim.PhysShape.ptr, lci.OffsetPos , lci.OffsetRot); } } - // TODO: need to phantomize the child prims left behind. - // Maybe just destroy the children bodies and shapes and have them rebuild on unlink. - // Selection/deselection might cause way too many build/destructions esp. for LARGE linksets. - return false; // 'false' says to move onto the next child in the list }); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index b05d4ee..d2fc15c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -75,6 +75,7 @@ public abstract class BSPhysObject : PhysicsActor public string TypeName { get; protected set; } public BSLinkset Linkset { get; set; } + public BSLinksetInfo LinksetInfo { get; set; } // Return the object mass without calculating it or having side effects public abstract float RawMass { get; } @@ -253,7 +254,9 @@ public abstract class BSPhysObject : PhysicsActor SubscribedEventsMs = 0; PhysicsScene.TaintedObject(TypeName+".UnSubscribeEvents", delegate() { - CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + // Make sure there is a body there because sometimes destruction happens in an un-ideal order. + if (PhysBody.HasPhysicalBody) + CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); }); } // Return 'true' if the simulator wants collision events diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 627393a..d1d100d 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -108,8 +108,8 @@ public sealed class BSPrim : BSPhysObject _mass = CalculateMass(); // No body or shape yet - PhysBody = new BulletBody(LocalID, IntPtr.Zero); - PhysShape = new BulletShape(IntPtr.Zero); + PhysBody = new BulletBody(LocalID); + PhysShape = new BulletShape(); DetailLog("{0},BSPrim.constructor,call", LocalID); // do the actual object creation at taint time @@ -143,7 +143,9 @@ public sealed class BSPrim : BSPhysObject DetailLog("{0},BSPrim.Destroy,taint,", LocalID); // If there are physical body and shape, release my use of same. PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null); + PhysBody.Clear(); PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null); + PhysShape.Clear(); }); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 933f573..74b4371 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -149,7 +149,7 @@ public sealed class BSShapeCollection : IDisposable // Called when releasing use of a BSBody. BSShape is handled separately. public void DereferenceBody(BulletBody body, bool inTaintTime, BodyDestructionCallback bodyCallback ) { - if (body.ptr == IntPtr.Zero) + if (!body.HasPhysicalBody) return; lock (m_collectionActivityLock) @@ -243,12 +243,12 @@ public sealed class BSShapeCollection : IDisposable // Release the usage of a shape. public void DereferenceShape(BulletShape shape, bool inTaintTime, ShapeDestructionCallback shapeCallback) { - if (shape.ptr == IntPtr.Zero) + if (!shape.HasPhysicalShape) return; PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceShape", delegate() { - if (shape.ptr != IntPtr.Zero) + if (shape.HasPhysicalShape) { if (shape.isNativeShape) { @@ -440,7 +440,7 @@ public sealed class BSShapeCollection : IDisposable } // Create a mesh/hull shape or a native shape if 'nativeShapePossible' is 'true'. - private bool CreateGeomNonSpecial(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback) + public bool CreateGeomNonSpecial(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback) { bool ret = false; bool haveShape = false; @@ -573,7 +573,7 @@ public sealed class BSShapeCollection : IDisposable // Native shapes are scaled in Bullet so set the scaling to the size newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, nativeShapeData), shapeType); } - if (newShape.ptr == IntPtr.Zero) + if (!newShape.HasPhysicalShape) { PhysicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}", LogHeader, prim.LocalID, shapeType); @@ -590,7 +590,7 @@ public sealed class BSShapeCollection : IDisposable // Called at taint-time! private bool GetReferenceToMesh(BSPhysObject prim, ShapeDestructionCallback shapeCallback) { - BulletShape newShape = new BulletShape(IntPtr.Zero); + BulletShape newShape = new BulletShape(); float lod; System.UInt64 newMeshKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod); @@ -860,7 +860,7 @@ public sealed class BSShapeCollection : IDisposable private BulletShape VerifyMeshCreated(BulletShape newShape, BSPhysObject prim) { // If the shape was successfully created, nothing more to do - if (newShape.ptr != IntPtr.Zero) + if (newShape.HasPhysicalShape) return newShape; // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset @@ -919,7 +919,7 @@ public sealed class BSShapeCollection : IDisposable bool ret = false; // the mesh, hull or native shape must have already been created in Bullet - bool mustRebuild = (prim.PhysBody.ptr == IntPtr.Zero); + bool mustRebuild = !prim.PhysBody.HasPhysicalBody; // If there is an existing body, verify it's of an acceptable type. // If not a solid object, body is a GhostObject. Otherwise a RigidBody. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs index 83b9c37..2d379bb 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs @@ -136,7 +136,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys { if (m_mapInfo != null) { - if (m_mapInfo.terrainBody.ptr != IntPtr.Zero) + if (m_mapInfo.terrainBody.HasPhysicalBody) { BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); // Frees both the body and the shape. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index 83df360..c28d69d 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -151,13 +151,13 @@ public sealed class BSTerrainManager // Release all the terrain structures we might have allocated public void ReleaseGroundPlaneAndTerrain() { - if (m_groundPlane.ptr != IntPtr.Zero) + if (m_groundPlane.HasPhysicalBody) { if (BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr)) { BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_groundPlane.ptr); } - m_groundPlane.ptr = IntPtr.Zero; + m_groundPlane.Clear(); } ReleaseTerrain(); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index 6ce767d..3473006 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs @@ -94,7 +94,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, indicesCount, indices, verticesCount, vertices), BSPhysicsShapeType.SHAPE_MESH); - if (m_terrainShape.ptr == IntPtr.Zero) + if (!m_terrainShape.HasPhysicalShape) { // DISASTER!! PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape", ID); @@ -107,7 +107,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys Quaternion rot = Quaternion.Identity; m_terrainBody = new BulletBody(id, BulletSimAPI.CreateBodyWithDefaultMotionState2( m_terrainShape.ptr, ID, pos, rot)); - if (m_terrainBody.ptr == IntPtr.Zero) + if (!m_terrainBody.HasPhysicalBody) { // DISASTER!! physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain body! base={1}", LogHeader, TerrainBase); @@ -140,7 +140,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys public override void Dispose() { - if (m_terrainBody.ptr != IntPtr.Zero) + if (m_terrainBody.HasPhysicalBody) { BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr); // Frees both the body and the shape. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 2671995..1559025 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -53,6 +53,9 @@ public struct BulletSim // An allocated Bullet btRigidBody public struct BulletBody { + public BulletBody(uint id) : this(id, IntPtr.Zero) + { + } public BulletBody(uint id, IntPtr xx) { ID = id; @@ -64,6 +67,13 @@ public struct BulletBody public uint ID; public CollisionFilterGroups collisionGroup; public CollisionFilterGroups collisionMask; + + public void Clear() + { + ptr = IntPtr.Zero; + } + public bool HasPhysicalBody { get { return ptr != IntPtr.Zero; } } + public override string ToString() { StringBuilder buff = new StringBuilder(); @@ -103,6 +113,13 @@ public struct BulletShape public BSPhysicsShapeType type; public System.UInt64 shapeKey; public bool isNativeShape; + + public void Clear() + { + ptr = IntPtr.Zero; + } + public bool HasPhysicalShape { get { return ptr != IntPtr.Zero; } } + public override string ToString() { StringBuilder buff = new StringBuilder(); @@ -140,6 +157,12 @@ public struct BulletConstraint ptr = xx; } public IntPtr ptr; + + public void Clear() + { + ptr = IntPtr.Zero; + } + public bool HasPhysicalConstraint { get { return ptr != IntPtr.Zero; } } } // An allocated HeightMapThing which holds various heightmap info. -- cgit v1.1 From 93393fb975f3886c448b6f945705304552fe8875 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 10 Dec 2012 16:46:12 -0800 Subject: BulletSim: comment out some chatty debug logging. Rearrange some code in BSDynamics to make velocity vs force calculation clearer. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 8 +++++--- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index fa3110c..cb84456 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -818,6 +818,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin + hoverContribution + limitMotorUpContribution; + Vector3 newForce = buoyancyContribution; + // If not changing some axis, reduce out velocity if ((m_flags & (VehicleFlag.NO_X)) != 0) newVelocity.X = 0; @@ -845,7 +847,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin VehicleVelocity = newVelocity; // Other linear forces are applied as forces. - Vector3 totalDownForce = buoyancyContribution * m_vehicleMass; + Vector3 totalDownForce = newForce * m_vehicleMass; if (!totalDownForce.ApproxEquals(Vector3.Zero, 0.01f)) { VehicleAddForce(totalDownForce); @@ -1005,8 +1007,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin // has a decay factor. This says this force should // be computed with a motor. // TODO: add interaction with banking. - VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},downForce={2}", - Prim.LocalID, distanceAboveGround, ret); + VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},colliding={2},ret={3}", + Prim.LocalID, distanceAboveGround, Prim.IsColliding, ret); } return ret; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index f72bd74..17cc7b4 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -501,7 +501,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters try { - if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG + // if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount(); numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep, @@ -510,7 +510,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime); DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}", DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount); - if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG + // if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG } catch (Exception e) { -- cgit v1.1 From ebf30e7ba66446d7018346c12111d65a030d2786 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 11 Dec 2012 00:02:20 -0800 Subject: BulletSim: set mass for single prim linksets when going physical. This fixes single prim vehicles not working (the surf board now zooms). --- OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index fe5b5e3..d2abdb4 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -110,12 +110,19 @@ public sealed class BSLinksetCompound : BSLinkset { bool ret = false; DetailLog("{0},BSLinksetCompound.MakeDynamic,call,IsRoot={1}", child.LocalID, IsRoot(child)); - if (!IsRoot(child)) + if (IsRoot(child)) + { + // The root is going dynamic. Make sure mass is properly set. + m_mass = ComputeLinksetMass(); + } + else { // The origional prims are removed from the world as the shape of the root compound // shape takes over. BulletSimAPI.AddToCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); BulletSimAPI.ForceActivationState2(child.PhysBody.ptr, ActivationState.DISABLE_SIMULATION); + // We don't want collisions from the old linkset children. + BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); ret = true; } return ret; -- cgit v1.1 From 8b861e880ad128edc0267b8e2d5931cfc8a142bc Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 11 Dec 2012 00:13:13 -0800 Subject: BulletSim: add ini file and command line parameters to control dumping of physical vehicle parameters (out of Bullet) on each simulation step and to optionally scale vehicle angular velocity by the time step. The latter looks to be part of a difference between angular parameters for ODE and BulletSim. SL docs say angular velocity is measured in radians/timeScale. Not sure if this is different than what ODE does. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 9 ++++++--- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 12 ++++++++++-- OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | 7 +++++-- 4 files changed, 22 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index cb84456..acddc09 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -570,8 +570,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia); BulletSimAPI.UpdateInertiaTensor2(Prim.PhysBody.ptr); - VDetailLog("{0},BSDynamics.Refresh,frict={1},inert={2},aDamp={3}", - Prim.LocalID, friction, localInertia, angularDamping); + VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4}", + Prim.LocalID, m_vehicleMass, friction, localInertia, angularDamping); } else { @@ -1057,7 +1057,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin // TODO: Should this be applied as an angular force (torque)? if (!m_lastAngularCorrection.ApproxEquals(Vector3.Zero, 0.01f)) { - Vector3 scaledCorrection = m_lastAngularCorrection * pTimestep; + // DEBUG DEBUG DEBUG: optionally scale the angular velocity. Debugging SL vs ODE turning functions. + Vector3 scaledCorrection = m_lastAngularCorrection; + if (PhysicsScene.VehicleScaleAngularVelocityByTimestep) + scaledCorrection *= pTimestep; VehicleRotationalVelocity = scaledCorrection; VDetailLog("{0}, MoveAngular,done,nonZero,angMotorContrib={1},vertAttrContrib={2},bankContrib={3},deflectContrib={4},totalContrib={5},scaledCorr={6}", diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 17cc7b4..f4f2801 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -188,6 +188,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters private bool m_physicsLoggingDoFlush; // 'true' of the vehicle code is to log lots of details public bool VehicleLoggingEnabled { get; private set; } + public bool VehiclePhysicalLoggingEnabled { get; private set; } + public bool VehicleScaleAngularVelocityByTimestep { get; private set; } #region Construction and Initialization public BSScene(string identifier) @@ -297,6 +299,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters m_physicsLoggingDoFlush = pConfig.GetBoolean("PhysicsLoggingDoFlush", false); // Very detailed logging for vehicle debugging VehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false); + VehiclePhysicalLoggingEnabled = pConfig.GetBoolean("VehiclePhysicalLoggingEnabled", false); // Do any replacements in the parameters m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName); @@ -501,7 +504,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters try { - // if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG + if (VehiclePhysicalLoggingEnabled) DumpVehicles(); // DEBUG if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount(); numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep, @@ -510,7 +513,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime); DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}", DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount); - // if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG + if (VehiclePhysicalLoggingEnabled) DumpVehicles(); // DEBUG } catch (Exception e) { @@ -1226,6 +1229,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters (s,cf,p,v) => { s.m_params[0].vehicleAngularDamping = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].vehicleAngularDamping; }, (s,p,l,v) => { s.m_params[0].vehicleAngularDamping = v; } ), + new ParameterDefn("VehicleScaleAngularVelocityByTimestep", "If true, scale angular turning by timestep", + ConfigurationParameters.numericFalse, + (s,cf,p,v) => { s.VehicleScaleAngularVelocityByTimestep = cf.GetBoolean(p, s.BoolNumeric(v)); }, + (s) => { return s.NumericBool(s.VehicleScaleAngularVelocityByTimestep); }, + (s,p,l,v) => { s.VehicleScaleAngularVelocityByTimestep = s.BoolNumeric(v); } ), new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", 0f, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 74b4371..4ab9a99 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -793,7 +793,7 @@ public sealed class BSShapeCollection : IDisposable BulletShape newShape = new BulletShape(hullPtr, BSPhysicsShapeType.SHAPE_HULL); newShape.shapeKey = newHullKey; - return newShape; // 'true' means a new shape has been added to this prim + return newShape; } // Callback from convex hull creater with a newly created hull. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index a2161c3..4b6e9a4 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -38,7 +38,8 @@ Disable activity of passive linkset children. Scenes with hundred of thousands of static objects take a lot of physics CPU time. BSPrim.Force should set a continious force on the prim. The force should be applied each tick. Some limits? -Single prim vehicles don't seem to properly vehiclize. +Linksets should allow collisions to individual children + Add LocalID to children shapes in LinksetCompound and create events for individuals Gun sending shooter flying. Collision margin (gap between physical objects lying on each other) Boundry checking (crashes related to crossing boundry) @@ -145,4 +146,6 @@ Linkset implementation using compound shapes. (Resolution: implemented LinksetCo Light cycle falling over when driving (Resolution: implemented VerticalAttractor) Light cycle not banking (Resolution: It doesn't. Banking is roll adding yaw.) Package Bullet source mods for Bullet internal stats output - (Resolution: move code into WorldData.h rather than relying on patches) \ No newline at end of file + (Resolution: move code into WorldData.h rather than relying on patches) +Single prim vehicles don't seem to properly vehiclize. + (Resolution: mass was not getting set properly for single prim linksets) -- cgit v1.1 From 905d7c43ad34869df03b21fcd24eb8ea8c6beeae Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 11 Dec 2012 00:35:16 -0800 Subject: BulletSim: modify LIMIT_MOTOR_UP to limit BOAT types to be at water rather than ground level. This makes boats float at water level better but not perfectly. There probably needs to be some interaction between HOVER and LIMIT_MOTOR_UP. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index acddc09..82e829e 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -993,8 +993,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) { - // If the vehicle is motoring into the sky, get it going back down. - float distanceAboveGround = VehiclePosition.Z - GetTerrainHeight(VehiclePosition); + float targetHeight = Type == Vehicle.TYPE_BOAT ? GetWaterLevel(VehiclePosition) : GetTerrainHeight(VehiclePosition); + float distanceAboveGround = VehiclePosition.Z - targetHeight; // Not colliding if the vehicle is off the ground if (!Prim.IsColliding) { -- cgit v1.1 From 63099184dbd2c1c5bcee2c3c87802f78444e7008 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 11 Dec 2012 13:42:23 -0800 Subject: BulletSim: protect prim property setting to remove crash from taints setting properties after the destroy object taint has happened. --- OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 54 +++++++++++++++------- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 9 +++- 3 files changed, 45 insertions(+), 20 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index 851d508..cf0a9dc 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -65,7 +65,7 @@ public abstract class BSMotor // Can all the incremental stepping be replaced with motor classes? // Motor which moves CurrentValue to TargetValue over TimeScale seconds. -// The TargetValue is decays in TargetValueDecayTimeScale and +// The TargetValue decays in TargetValueDecayTimeScale and // the CurrentValue will be held back by FrictionTimeScale. // TimeScale and TargetDelayTimeScale may be 'infinite' which means go decay. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index d1d100d..1280c25 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -249,7 +249,8 @@ public sealed class BSPrim : BSPhysObject // Zero some other properties in the physics engine PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate() { - BulletSimAPI.ClearAllForces2(PhysBody.ptr); + if (PhysBody.HasPhysicalBody) + BulletSimAPI.ClearAllForces2(PhysBody.ptr); }); } public override void ZeroAngularMotion(bool inTaintTime) @@ -259,8 +260,11 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate() { // DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity); - BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, _rotationalVelocity); - BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity); + if (PhysBody.HasPhysicalBody) + { + BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, _rotationalVelocity); + BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity); + } }); } @@ -297,8 +301,11 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject("BSPrim.setPosition", delegate() { // DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); - ActivateIfPhysical(false); + if (PhysBody.HasPhysicalBody) + { + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + ActivateIfPhysical(false); + } }); } } @@ -415,7 +422,8 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject("BSPrim.setForce", delegate() { // DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force); - BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force); + if (PhysBody.HasPhysicalBody) + BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force); }); } } @@ -509,7 +517,8 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject("BSPrim.setVelocity", delegate() { // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); - BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); + if (PhysBody.HasPhysicalBody) + BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); }); } } @@ -558,9 +567,12 @@ public sealed class BSPrim : BSPhysObject // TODO: what does it mean if a child in a linkset changes its orientation? Rebuild the constraint? PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate() { - // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr); - // DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + if (PhysBody.HasPhysicalBody) + { + // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr); + // DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + } }); } } @@ -865,7 +877,8 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject("BSPrim.setRotationalVelocity", delegate() { DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); - BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity); + if (PhysBody.HasPhysicalBody) + BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity); }); } } @@ -900,8 +913,11 @@ public sealed class BSPrim : BSPhysObject _buoyancy = value; // DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); // Buoyancy is faked by changing the gravity applied to the object - float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); - BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav)); + if (PhysBody.HasPhysicalBody) + { + float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); + BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav)); + } } } @@ -969,7 +985,8 @@ public sealed class BSPrim : BSPhysObject } DetailLog("{0},BSPrim.AddForce,taint,force={1}", LocalID, fSum); if (fSum != OMV.Vector3.Zero) - BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, fSum); + if (PhysBody.HasPhysicalBody) + BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, fSum); }); } @@ -980,7 +997,8 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ApplyForceImpulse", delegate() { DetailLog("{0},BSPrim.ApplyForceImpulse,taint,tImpulse={1}", LocalID, applyImpulse); - BulletSimAPI.ApplyCentralImpulse2(PhysBody.ptr, applyImpulse); + if (PhysBody.HasPhysicalBody) + BulletSimAPI.ApplyCentralImpulse2(PhysBody.ptr, applyImpulse); }); } @@ -1016,7 +1034,8 @@ public sealed class BSPrim : BSPhysObject DetailLog("{0},BSPrim.AddAngularForce,taint,aForce={1}", LocalID, fSum); if (fSum != OMV.Vector3.Zero) { - BulletSimAPI.ApplyTorque2(PhysBody.ptr, fSum); + if (PhysBody.HasPhysicalBody) + BulletSimAPI.ApplyTorque2(PhysBody.ptr, fSum); _torque = fSum; } }); @@ -1030,7 +1049,8 @@ public sealed class BSPrim : BSPhysObject OMV.Vector3 applyImpulse = impulse; PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ApplyTorqueImpulse", delegate() { - BulletSimAPI.ApplyTorqueImpulse2(PhysBody.ptr, applyImpulse); + if (PhysBody.HasPhysicalBody) + BulletSimAPI.ApplyTorqueImpulse2(PhysBody.ptr, applyImpulse); }); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 4b6e9a4..1c7b577 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -11,12 +11,14 @@ CRASHES VEHICLES TODO LIST: ================================================= -Neb car jiggling left and right - Happens on terrain and any other mesh object. Flat cubes are much smoother. +Neb vehicle taking > 25ms of physics time!! Vehicles (Move smoothly) Add vehicle collisions so IsColliding is properly reported. Needed for banking, limitMotorUp, movementLimiting, ... Some vehicles should not be able to turn if no speed or off ground. +Neb car jiggling left and right + Happens on terrain and any other mesh object. Flat cubes are much smoother. + This has been reduced but not eliminated. For limitMotorUp, use raycast down to find if vehicle is in the air. Implement function efficiency for lineaar and angular motion. Should vehicle angular/linear movement friction happen after all the components @@ -30,6 +32,9 @@ Border crossing with linked vehicle causes crash BULLETSIM TODO LIST: ================================================= +Avatar height off after unsitting (float off ground) + Editting appearance then moving restores. + Must not be initializing height when recreating capsule after unsit. Duplicating a physical prim causes old prim to jump away Dup a phys prim and the original become unselected and thus interacts w/ selected prim. Disable activity of passive linkset children. -- cgit v1.1 From d4e0e98c001c3501ac17849ab78e7ac5a59a5c26 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 11 Dec 2012 13:54:26 -0800 Subject: BulletSim: protect character property setting to remove crash from taints setting properties after the destroy character taint. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 60 ++++++++++++++-------- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 3 +- 2 files changed, 42 insertions(+), 21 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 88460cc..83c78f6 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -196,8 +196,11 @@ public sealed class BSCharacter : BSPhysObject PhysicsScene.TaintedObject("BSCharacter.setSize", delegate() { - BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale); - UpdatePhysicalMassProperties(RawMass); + if (PhysShape.HasPhysicalShape) + { + BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale); + UpdatePhysicalMassProperties(RawMass); + } }); } @@ -238,7 +241,8 @@ public sealed class BSCharacter : BSPhysObject // Zero some other properties directly into the physics engine PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate() { - BulletSimAPI.ClearAllForces2(PhysBody.ptr); + if (PhysBody.HasPhysicalBody) + BulletSimAPI.ClearAllForces2(PhysBody.ptr); }); } public override void ZeroAngularMotion(bool inTaintTime) @@ -247,10 +251,13 @@ public sealed class BSCharacter : BSPhysObject PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate() { - BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero); - BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero); - // The next also get rid of applied linear force but the linear velocity is untouched. - BulletSimAPI.ClearForces2(PhysBody.ptr); + if (PhysBody.HasPhysicalBody) + { + BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero); + BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero); + // The next also get rid of applied linear force but the linear velocity is untouched. + BulletSimAPI.ClearForces2(PhysBody.ptr); + } }); } @@ -275,7 +282,8 @@ public sealed class BSCharacter : BSPhysObject PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate() { DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + if (PhysBody.HasPhysicalBody) + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); }); } } @@ -334,7 +342,8 @@ public sealed class BSCharacter : BSPhysObject PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.PositionSanityCheck", delegate() { DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + if (PhysBody.HasPhysicalBody) + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); }); ret = true; } @@ -361,7 +370,8 @@ public sealed class BSCharacter : BSPhysObject PhysicsScene.TaintedObject("BSCharacter.SetForce", delegate() { DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force); - BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force); + if (PhysBody.HasPhysicalBody) + BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force); }); } } @@ -400,7 +410,8 @@ public sealed class BSCharacter : BSPhysObject if (_currentFriction != PhysicsScene.Params.avatarStandingFriction) { _currentFriction = PhysicsScene.Params.avatarStandingFriction; - BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction); + if (PhysBody.HasPhysicalBody) + BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction); } } else @@ -408,7 +419,8 @@ public sealed class BSCharacter : BSPhysObject if (_currentFriction != PhysicsScene.Params.avatarFriction) { _currentFriction = PhysicsScene.Params.avatarFriction; - BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction); + if (PhysBody.HasPhysicalBody) + BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction); } } _velocity = value; @@ -445,8 +457,11 @@ public sealed class BSCharacter : BSPhysObject // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation); PhysicsScene.TaintedObject("BSCharacter.setOrientation", delegate() { - // _position = BulletSimAPI.GetPosition2(BSBody.ptr); - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + if (PhysBody.HasPhysicalBody) + { + // _position = BulletSimAPI.GetPosition2(BSBody.ptr); + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + } }); } } @@ -519,10 +534,13 @@ public sealed class BSCharacter : BSPhysObject _floatOnWater = value; PhysicsScene.TaintedObject("BSCharacter.setFloatOnWater", delegate() { - if (_floatOnWater) - CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); - else - CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); + if (PhysBody.HasPhysicalBody) + { + if (_floatOnWater) + CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); + else + CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); + } }); } } @@ -555,7 +573,8 @@ public sealed class BSCharacter : BSPhysObject DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); // Buoyancy is faked by changing the gravity applied to the object float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); - BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav)); + if (PhysBody.HasPhysicalBody) + BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav)); } } @@ -601,7 +620,8 @@ public sealed class BSCharacter : BSPhysObject PhysicsScene.TaintedObject("BSCharacter.AddForce", delegate() { DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force); - BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force); + if (PhysBody.HasPhysicalBody) + BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force); }); } else diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 1280c25..446e44c 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -191,7 +191,8 @@ public sealed class BSPrim : BSPhysObject } } public override bool Selected { - set { + set + { if (value != _isSelected) { _isSelected = value; -- cgit v1.1 From a082ce9da78ffb50454834fde4e3dd19e3b5bc74 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 11 Dec 2012 14:27:09 -0800 Subject: BulletSim: fix crash caused by the creation of a linkset child that is under the terrain. Users can sure find some interesting corner conditions. --- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 446e44c..35d22c0 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -332,12 +332,12 @@ public sealed class BSPrim : BSPhysObject float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); OMV.Vector3 upForce = OMV.Vector3.Zero; - if (Position.Z < terrainHeight) + if (RawPosition.Z < terrainHeight) { DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); float targetHeight = terrainHeight + (Size.Z / 2f); // Upforce proportional to the distance away from the terrain. Correct the error in 1 sec. - upForce.Z = (terrainHeight - Position.Z) * 1f; + upForce.Z = (terrainHeight - RawPosition.Z) * 1f; ret = true; } @@ -345,10 +345,10 @@ public sealed class BSPrim : BSPhysObject { float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(_position); // TODO: a floating motor so object will bob in the water - if (Math.Abs(Position.Z - waterHeight) > 0.1f) + if (Math.Abs(RawPosition.Z - waterHeight) > 0.1f) { // Upforce proportional to the distance away from the water. Correct the error in 1 sec. - upForce.Z = (waterHeight - Position.Z) * 1f; + upForce.Z = (waterHeight - RawPosition.Z) * 1f; ret = true; } } -- cgit v1.1 From bb6eeb54296246e26594bc06edc3a42c0e5824e9 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 12 Dec 2012 11:01:36 -0800 Subject: BulletSim: do not return the current velocity for targetVelocity. --- OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index d2fc15c..f3b6993 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -139,6 +139,17 @@ public abstract class BSPhysObject : PhysicsActor public abstract OMV.Quaternion RawOrientation { get; set; } public abstract OMV.Quaternion ForceOrientation { get; set; } + // The system is telling us the velocity it wants to move at. + protected OMV.Vector3 m_targetVelocity; + public override OMV.Vector3 TargetVelocity + { + get { return m_targetVelocity; } + set + { + m_targetVelocity = value; + Velocity = value; + } + } public abstract OMV.Vector3 ForceVelocity { get; set; } public abstract OMV.Vector3 ForceRotationalVelocity { get; set; } -- cgit v1.1 From 418c0cb01d72a48bb1cd708d25a3e9159e711661 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 12 Dec 2012 22:06:09 +0000 Subject: Add asset id to "show script" and "show scripts" command output to make it easier to extract and inspect the script's asset via "dump asset" --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 965101a..986f658 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -542,6 +542,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine sb.AppendFormat("Queued events : {0}\n", instance.EventsQueued); sb.AppendFormat("Processed events : {0}\n", instance.EventsProcessed); sb.AppendFormat("Item UUID : {0}\n", instance.ItemID); + sb.AppendFormat("Asset UUID : {0}\n", instance.AssetID); sb.AppendFormat("Containing part name: {0}\n", instance.PrimName); sb.AppendFormat("Containing part UUID: {0}\n", instance.ObjectID); sb.AppendFormat("Position : {0}\n", sop.AbsolutePosition); -- cgit v1.1 From 047270bdc83d029486215a418fada27b225dbab0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 12 Dec 2012 23:13:34 +0000 Subject: Add "debug script log" command to allow setting a numeric debug level on individual IScriptInstances for debugging purposes. Current, state changes and event fires can be logged for individual scripts. See command help for more details. --- .../ScriptEngine/Interfaces/IScriptInstance.cs | 12 +++++ .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 37 +++++++++++---- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 53 ++++++++++++++++++++-- 3 files changed, 89 insertions(+), 13 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index 0cef550..00a99c3 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs @@ -59,6 +59,18 @@ namespace OpenSim.Region.ScriptEngine.Interfaces public interface IScriptInstance { /// + /// Debug level for this script instance. + /// + /// + /// Level == 0, no extra data is logged. + /// Level >= 1, state changes are logged. + /// Level >= 2, event firing is logged. + /// + /// The debug level. + /// + int DebugLevel { get; set; } + + /// /// Is the script currently running? /// bool Running { get; set; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 5ad6eeb..435e9dc 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -93,6 +93,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance private UUID m_CurrentStateHash; private UUID m_RegionID; + public int DebugLevel { get; set; } + public Dictionary, KeyValuePair> LineMap { get; set; } private Dictionary m_Apis = new Dictionary(); @@ -703,21 +705,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance if (data.EventName == "collision") m_CollisionInQueue = false; } - -// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); + + SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); + + if (DebugLevel >= 2) + m_log.DebugFormat( + "[SCRIPT INSTANCE]: Processing event {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", + data.EventName, + ScriptName, + part.Name, + part.LocalId, + part.ParentGroup.Name, + part.ParentGroup.UUID, + part.AbsolutePosition, + part.ParentGroup.Scene.Name); m_DetectParams = data.DetectParams; if (data.EventName == "state") // Hardcoded state change { - // m_log.DebugFormat("[Script] Script {0}.{1} state set to {2}", - // PrimName, ScriptName, data.Params[0].ToString()); State = data.Params[0].ToString(); + + if (DebugLevel >= 1) + m_log.DebugFormat( + "[SCRIPT INSTANCE]: Changing state to {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", + State, + ScriptName, + part.Name, + part.LocalId, + part.ParentGroup.Name, + part.ParentGroup.UUID, + part.AbsolutePosition, + part.ParentGroup.Scene.Name); + AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); - SceneObjectPart part = Engine.World.GetSceneObjectPart( - LocalID); if (part != null) { part.SetScriptEvents(ItemID, @@ -729,8 +752,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance if (Engine.World.PipeEventsForScript(LocalID) || data.EventName == "control") // Don't freeze avies! { - SceneObjectPart part = Engine.World.GetSceneObjectPart( - LocalID); // m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}", // PrimName, ScriptName, data.EventName, State); diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 986f658..828f2fb 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -304,7 +304,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine MainConsole.Instance.Commands.AddCommand( "Scripts", false, "scripts show", "scripts show []", "Show script information", - "Show information on all scripts known to the script engine." + "Show information on all scripts known to the script engine.\n" + "If a is given then only information on that script will be shown.", HandleShowScripts); @@ -323,22 +323,30 @@ namespace OpenSim.Region.ScriptEngine.XEngine MainConsole.Instance.Commands.AddCommand( "Scripts", false, "scripts resume", "scripts resume []", "Resumes all suspended scripts", "Resumes all currently suspended scripts.\n" - + "Resumed scripts will process all events accumulated whilst suspended." + + "Resumed scripts will process all events accumulated whilst suspended.\n" + "If a is given then only that script will be resumed. Otherwise, all suitable scripts are resumed.", (module, cmdparams) => HandleScriptsAction(cmdparams, HandleResumeScript)); MainConsole.Instance.Commands.AddCommand( "Scripts", false, "scripts stop", "scripts stop []", "Stops all running scripts", - "Stops all running scripts." + "Stops all running scripts.\n" + "If a is given then only that script will be stopped. Otherwise, all suitable scripts are stopped.", (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStopScript)); MainConsole.Instance.Commands.AddCommand( "Scripts", false, "scripts start", "scripts start []", "Starts all stopped scripts", - "Starts all stopped scripts." + "Starts all stopped scripts.\n" + "If a is given then only that script will be started. Otherwise, all suitable scripts are started.", (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStartScript)); + MainConsole.Instance.Commands.AddCommand( + "Scripts", false, "debug script log", "debug scripts log ", "Extra debug logging for a script", + "Activates or deactivates extra debug logging for the given script.\n" + + "Level == 0, deactivate extra debug logging.\n" + + "Level >= 1, log state changes.\n" + + "Level >= 2, log event invocations.\n", + HandleDebugScriptLogCommand); + // MainConsole.Instance.Commands.AddCommand( // "Debug", false, "debug xengine", "debug xengine []", // "Turn on detailed xengine debugging.", @@ -347,6 +355,41 @@ namespace OpenSim.Region.ScriptEngine.XEngine // HandleDebugLevelCommand); } + private void HandleDebugScriptLogCommand(string module, string[] args) + { + if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene)) + return; + + if (args.Length != 5) + { + MainConsole.Instance.Output("Usage: debug script log "); + return; + } + + UUID itemId; + + if (!ConsoleUtil.TryParseConsoleUuid(MainConsole.Instance, args[3], out itemId)) + return; + + int newLevel; + + if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out newLevel)) + return; + + IScriptInstance si; + + lock (m_Scripts) + { + // XXX: We can't give the user feedback on a bad item id because this may apply to a different script + // engine + if (!m_Scripts.TryGetValue(itemId, out si)) + return; + } + + si.DebugLevel = newLevel; + MainConsole.Instance.OutputFormat("Set debug level of {0} {1} to {2}", si.ScriptName, si.ItemID, newLevel); + } + /// /// Change debug level /// @@ -418,7 +461,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine if (!UUID.TryParse(rawItemId, out itemId)) { - MainConsole.Instance.OutputFormat("Error - {0} is not a valid UUID", rawItemId); + MainConsole.Instance.OutputFormat("ERROR: {0} is not a valid UUID", rawItemId); return; } -- cgit v1.1 From 512e4c931379877a1fd8c35f41111431f0a85ff5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 12 Dec 2012 23:30:26 +0000 Subject: Log situations where workitem event threads are aborted on stop request because they failed to complete event processing within the given timeout. This is for bug hunting purposes where thread aborts may be causing dangling lock issues and subsequent vm crashes on mono (with ReaderWriterLockSlim, etc.) --- OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 435e9dc..dfe8386 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -550,9 +550,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance // forcibly abort the work item (this aborts the underlying thread). if (!m_InSelfDelete) { -// m_log.ErrorFormat( -// "[SCRIPT INSTANCE]: Aborting script {0} {1} in prim {2} {3} {4} {5}", -// ScriptName, ItemID, PrimName, ObjectID, m_InSelfDelete, DateTime.Now.Ticks); + m_log.DebugFormat( + "[SCRIPT INSTANCE]: Aborting unstopped script {0} {1} in prim {2}, localID {3}, timeout was {4} ms", + ScriptName, ItemID, PrimName, LocalID, timeout); workItem.Abort(); } -- cgit v1.1 From 7bb5613dc665a788e1b151278c20d415f708242a Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 11 Dec 2012 16:46:43 -0800 Subject: BulletSim: updates and rearrangement of the TODO list. --- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 47 +++++++++++++++------- 1 file changed, 33 insertions(+), 14 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 1c7b577..11c1387 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -20,6 +20,10 @@ Neb car jiggling left and right Happens on terrain and any other mesh object. Flat cubes are much smoother. This has been reduced but not eliminated. For limitMotorUp, use raycast down to find if vehicle is in the air. +Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE. + Verify that angular motion specified around Z moves in the vehicle coordinates. +Verify llGetVel() is returning a smooth and good value for vehicle movement. +llGetVel() should return the root's velocity if requested in a child prim. Implement function efficiency for lineaar and angular motion. Should vehicle angular/linear movement friction happen after all the components or does it only apply to the basic movement? @@ -32,19 +36,14 @@ Border crossing with linked vehicle causes crash BULLETSIM TODO LIST: ================================================= -Avatar height off after unsitting (float off ground) +Avatar height off after unsitting (floats off ground) Editting appearance then moving restores. Must not be initializing height when recreating capsule after unsit. Duplicating a physical prim causes old prim to jump away Dup a phys prim and the original become unselected and thus interacts w/ selected prim. -Disable activity of passive linkset children. - Since the linkset is a compound object, the old prims are left lying - around and need to be phantomized so they don't collide, ... Scenes with hundred of thousands of static objects take a lot of physics CPU time. BSPrim.Force should set a continious force on the prim. The force should be applied each tick. Some limits? -Linksets should allow collisions to individual children - Add LocalID to children shapes in LinksetCompound and create events for individuals Gun sending shooter flying. Collision margin (gap between physical objects lying on each other) Boundry checking (crashes related to crossing boundry) @@ -57,14 +56,34 @@ Small physical objects do not interact correctly The chain will fall apart and pairs will dance around on ground Chains of 1x1x.2 will stay connected but will dance. Chains above 2x2x.4 are move stable and get stablier as torui get larger. -Add material type linkage and input all the material property definitions. - Skeleton classes and table are in the sources but are not filled or used. Add PID motor for avatar movement (slow to stop, ...) setForce should set a constant force. Different than AddImpulse. Implement raycast. Implement ShapeCollection.Dispose() Implement water as a plain so raycasting and collisions can happen with same. +Add osGetPhysicsEngineName() so scripters can tell whether BulletSim or ODE + Also osGetPhysicsEngineVerion() maybe. + +LINKSETS +====================================================== +Linksets should allow collisions to individual children + Add LocalID to children shapes in LinksetCompound and create events for individuals +Verify/think through scripts in children of linksets. What do they reference + and return when getting position, velocity, ... +Confirm constraint linksets still work after making all the changes for compound linksets. +Add 'changed' flag or similar to reduce the number of times a linkset is rebuilt. + For compound linksets, add ability to remove or reposition individual child shapes. +Disable activity of passive linkset children. + Since the linkset is a compound object, the old prims are left lying + around and need to be phantomized so they don't collide, ... +Speed up creation of large physical linksets + For instance, sitting in Neb's car (130 prims) takes several seconds to become physical +Eliminate collisions between objects in a linkset. (LinksetConstraint) + Have UserPointer point to struct with localID and linksetID? + Objects in original linkset still collide with each other? +MORE +====================================================== Find/remove avatar collision with ID=0. Test avatar walking up stairs. How does compare with SL. Radius of the capsule affects ability to climb edges. @@ -73,8 +92,6 @@ Debounce avatar contact so legs don't keep folding up when standing. Implement LSL physics controls. Like STATUS_ROTATE_X. Add border extensions to terrain to help region crossings and objects leaving region. -Speed up creation of large physical linksets - For instance, sitting in Neb's car (130 prims) takes several seconds to become physical Performance test with lots of avatars. Can BulletSim support a thousand? Optimize collisions in C++: only send up to the object subscribed to collisions. Use collision subscription and remove the collsion(A,B) and collision(B,A) @@ -85,10 +102,6 @@ Avatar jump Performance measurement and changes to make quicker. Implement detailed physics stats (GetStats()). -Eliminate collisions between objects in a linkset. (LinksetConstraint) - Have UserPointer point to struct with localID and linksetID? - Objects in original linkset still collide with each other? - Measure performance improvement from hulls Test not using ghost objects for volume detect implementation. Performance of closures and delegates for taint processing @@ -101,6 +114,9 @@ Physics Arena central pyramid: why is one side permiable? INTERNAL IMPROVEMENT/CLEANUP ================================================= +Consider moving prim/character body and shape destruction in destroy() + to postTimeTime rather than protecting all the potential sets that + might have been queued up. Remove unused fields from ShapeData (not used in API2) Breakout code for mesh/hull/compound/native into separate BSShape* classes Standardize access to building and reference code. @@ -154,3 +170,6 @@ Package Bullet source mods for Bullet internal stats output (Resolution: move code into WorldData.h rather than relying on patches) Single prim vehicles don't seem to properly vehiclize. (Resolution: mass was not getting set properly for single prim linksets) +Add material type linkage and input all the material property definitions. + Skeleton classes and table are in the sources but are not filled or used. + (Resolution: -- cgit v1.1 From 6f1f7f02065520d061745afff9b1ed1bd672d87b Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 12 Dec 2012 15:07:17 -0800 Subject: BulletSim: non-functional commenting and reorganization of material attribute specifications. --- .../Region/Physics/BulletSPlugin/BSMaterials.cs | 81 +++++++++++++--------- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 1 + 2 files changed, 49 insertions(+), 33 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs index 390c2f9..c113a43 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs @@ -50,10 +50,11 @@ public struct MaterialAttributes Avatar, NumberOfTypes // the count of types in the enum. } + // Names must be in the order of the above enum. - public static string[] MaterialNames = { "Stone", "Metal", "Glass", "Wood", - "Flesh", "Plastic", "Rubber", "Light", "Avatar" }; - public static string[] MaterialAttribs = { "Density", "Friction", "Restitution"}; + // These names must coorespond to the lower case field names in the MaterialAttributes + // structure as reflection is used to select the field to put the value in. + public static readonly string[] MaterialAttribs = { "Density", "Friction", "Restitution"}; public MaterialAttributes(string t, float d, float f, float r) { @@ -70,60 +71,74 @@ public struct MaterialAttributes public static class BSMaterials { - public static MaterialAttributes[] Attributes; + // Attributes for each material type + private static readonly MaterialAttributes[] Attributes; + + // Map of material name to material type code + public static readonly Dictionary MaterialMap; static BSMaterials() { // Attribute sets for both the non-physical and physical instances of materials. Attributes = new MaterialAttributes[(int)MaterialAttributes.Material.NumberOfTypes * 2]; + + // Map of name to type code. + MaterialMap = new Dictionary(); + MaterialMap.Add("Stone", MaterialAttributes.Material.Stone); + MaterialMap.Add("Metal", MaterialAttributes.Material.Metal); + MaterialMap.Add("Glass", MaterialAttributes.Material.Glass); + MaterialMap.Add("Wood", MaterialAttributes.Material.Wood); + MaterialMap.Add("Flesh", MaterialAttributes.Material.Flesh); + MaterialMap.Add("Plastic", MaterialAttributes.Material.Plastic); + MaterialMap.Add("Rubber", MaterialAttributes.Material.Rubber); + MaterialMap.Add("Light", MaterialAttributes.Material.Light); + MaterialMap.Add("Avatar", MaterialAttributes.Material.Avatar); } // This is where all the default material attributes are defined. public static void InitializeFromDefaults(ConfigurationParameters parms) { // Values from http://wiki.secondlife.com/wiki/PRIM_MATERIAL - // public static string[] MaterialNames = { "Stone", "Metal", "Glass", "Wood", - // "Flesh", "Plastic", "Rubber", "Light", "Avatar" }; + float dDensity = parms.defaultDensity; float dFriction = parms.defaultFriction; float dRestitution = parms.defaultRestitution; - float dDensity = parms.defaultDensity; Attributes[(int)MaterialAttributes.Material.Stone] = - new MaterialAttributes("stone",dDensity, 0.8f, 0.4f); + new MaterialAttributes("stone",dDensity, 0.8f, 0.4f); Attributes[(int)MaterialAttributes.Material.Metal] = - new MaterialAttributes("metal",dDensity, 0.3f, 0.4f); + new MaterialAttributes("metal",dDensity, 0.3f, 0.4f); Attributes[(int)MaterialAttributes.Material.Glass] = - new MaterialAttributes("glass",dDensity, 0.2f, 0.7f); + new MaterialAttributes("glass",dDensity, 0.2f, 0.7f); Attributes[(int)MaterialAttributes.Material.Wood] = - new MaterialAttributes("wood",dDensity, 0.6f, 0.5f); + new MaterialAttributes("wood",dDensity, 0.6f, 0.5f); Attributes[(int)MaterialAttributes.Material.Flesh] = - new MaterialAttributes("flesh",dDensity, 0.9f, 0.3f); + new MaterialAttributes("flesh",dDensity, 0.9f, 0.3f); Attributes[(int)MaterialAttributes.Material.Plastic] = - new MaterialAttributes("plastic",dDensity, 0.4f, 0.7f); + new MaterialAttributes("plastic",dDensity, 0.4f, 0.7f); Attributes[(int)MaterialAttributes.Material.Rubber] = - new MaterialAttributes("rubber",dDensity, 0.9f, 0.9f); + new MaterialAttributes("rubber",dDensity, 0.9f, 0.9f); Attributes[(int)MaterialAttributes.Material.Light] = - new MaterialAttributes("light",dDensity, dFriction, dRestitution); + new MaterialAttributes("light",dDensity, dFriction, dRestitution); Attributes[(int)MaterialAttributes.Material.Avatar] = - new MaterialAttributes("avatar",60f, 0.2f, 0f); + new MaterialAttributes("avatar",60f, 0.2f, 0f); Attributes[(int)MaterialAttributes.Material.Stone + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("stonePhysical",dDensity, 0.8f, 0.4f); + new MaterialAttributes("stonePhysical",dDensity, 0.8f, 0.4f); Attributes[(int)MaterialAttributes.Material.Metal + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("metalPhysical",dDensity, 0.8f, 0.4f); + new MaterialAttributes("metalPhysical",dDensity, 0.8f, 0.4f); Attributes[(int)MaterialAttributes.Material.Glass + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("glassPhysical",dDensity, 0.8f, 0.7f); + new MaterialAttributes("glassPhysical",dDensity, 0.8f, 0.7f); Attributes[(int)MaterialAttributes.Material.Wood + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("woodPhysical",dDensity, 0.8f, 0.5f); + new MaterialAttributes("woodPhysical",dDensity, 0.8f, 0.5f); Attributes[(int)MaterialAttributes.Material.Flesh + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("fleshPhysical",dDensity, 0.8f, 0.3f); + new MaterialAttributes("fleshPhysical",dDensity, 0.8f, 0.3f); Attributes[(int)MaterialAttributes.Material.Plastic + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("plasticPhysical",dDensity, 0.8f, 0.7f); + new MaterialAttributes("plasticPhysical",dDensity, 0.8f, 0.7f); Attributes[(int)MaterialAttributes.Material.Rubber + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("rubberPhysical",dDensity, 0.8f, 0.9f); + new MaterialAttributes("rubberPhysical",dDensity, 0.8f, 0.9f); Attributes[(int)MaterialAttributes.Material.Light + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("lightPhysical",dDensity, dFriction, dRestitution); + new MaterialAttributes("lightPhysical",dDensity, dFriction, dRestitution); Attributes[(int)MaterialAttributes.Material.Avatar + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("avatarPhysical",60f, 0.2f, 0f); + new MaterialAttributes("avatarPhysical",60f, 0.2f, 0f); } // Under the [BulletSim] section, one can change the individual material @@ -139,34 +154,34 @@ public static class BSMaterials // the physical value. public static void InitializefromParameters(IConfig pConfig) { - int matType = 0; - foreach (string matName in MaterialAttributes.MaterialNames) + foreach (KeyValuePair kvp in MaterialMap) { + string matName = kvp.Key; foreach (string attribName in MaterialAttributes.MaterialAttribs) { string paramName = matName + attribName; if (pConfig.Contains(paramName)) { float paramValue = pConfig.GetFloat(paramName); - SetAttributeValue(matType, attribName, paramValue); + SetAttributeValue((int)kvp.Value, attribName, paramValue); // set the physical value also - SetAttributeValue(matType + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue); + SetAttributeValue((int)kvp.Value + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue); } paramName += "Physical"; if (pConfig.Contains(paramName)) { float paramValue = pConfig.GetFloat(paramName); - SetAttributeValue(matType + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue); + SetAttributeValue((int)kvp.Value + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue); } } - matType++; } } + // Use reflection to set the value in the attribute structure. private static void SetAttributeValue(int matType, string attribName, float val) { MaterialAttributes thisAttrib = Attributes[matType]; - FieldInfo fieldInfo = thisAttrib.GetType().GetField(attribName); + FieldInfo fieldInfo = thisAttrib.GetType().GetField(attribName.ToLower()); if (fieldInfo != null) { fieldInfo.SetValue(thisAttrib, val); @@ -174,12 +189,12 @@ public static class BSMaterials } } + // Given a material type, return a structure of attributes. public static MaterialAttributes GetAttributes(MaterialAttributes.Material type, bool isPhysical) { int ind = (int)type; if (isPhysical) ind += (int)MaterialAttributes.Material.NumberOfTypes; return Attributes[ind]; } - } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index f4f2801..cf5bb57 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -309,6 +309,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters BSMaterials.InitializeFromDefaults(Params); if (pConfig != null) { + // Let the user add new and interesting material property values. BSMaterials.InitializefromParameters(pConfig); } } -- cgit v1.1 From e1814aa827c2d0af21d087bd34e3c7f4f7cf25bd Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 12 Dec 2012 16:29:03 -0800 Subject: BulletSim: fix problem of avatar's floating off the ground after unsitting. Reworked size/scale logic so physical scale is kept in Bullet and physObject scale is the preferred size -- usually same as size but avatars are computed differently. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 18 +++++++++-------- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 8 ++------ .../Physics/BulletSPlugin/BSShapeCollection.cs | 23 +++++++++++++--------- 4 files changed, 27 insertions(+), 24 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 83c78f6..c8aad8d 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -105,12 +105,12 @@ public sealed class BSCharacter : BSPhysObject DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}", LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass); - // do actual create at taint time + // do actual creation in taint time PhysicsScene.TaintedObject("BSCharacter.create", delegate() { DetailLog("{0},BSCharacter.create,taint", LocalID); // New body and shape into PhysBody and PhysShape - PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this, null, null); + PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this); SetPhysicalProperties(); }); @@ -189,6 +189,11 @@ public sealed class BSCharacter : BSPhysObject set { // When an avatar's size is set, only the height is changed. _size = value; + // Old versions of ScenePresence passed only the height. If width and/or depth are zero, + // replace with the default values. + if (_size.X == 0f) _size.X = PhysicsScene.Params.avatarCapsuleDepth; + if (_size.Y == 0f) _size.Y = PhysicsScene.Params.avatarCapsuleWidth; + ComputeAvatarScale(_size); ComputeAvatarVolumeAndMass(); DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}", @@ -196,18 +201,18 @@ public sealed class BSCharacter : BSPhysObject PhysicsScene.TaintedObject("BSCharacter.setSize", delegate() { - if (PhysShape.HasPhysicalShape) + if (PhysBody.HasPhysicalBody && PhysShape.HasPhysicalShape) { BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale); UpdatePhysicalMassProperties(RawMass); + // Make sure this change appears as a property update event + BulletSimAPI.PushUpdate2(PhysBody.ptr); } }); } } - public override OMV.Vector3 Scale { get; set; } - public override PrimitiveBaseShape Shape { set { BaseShape = value; } @@ -638,9 +643,6 @@ public sealed class BSCharacter : BSPhysObject private void ComputeAvatarScale(OMV.Vector3 size) { - // The 'size' given by the simulator is the mid-point of the avatar - // and X and Y are unspecified. - OMV.Vector3 newScale = size; // newScale.X = PhysicsScene.Params.avatarCapsuleWidth; // newScale.Y = PhysicsScene.Params.avatarCapsuleDepth; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index f3b6993..6539b43 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -109,7 +109,7 @@ public abstract class BSPhysObject : PhysicsActor public EntityProperties CurrentEntityProperties { get; set; } public EntityProperties LastEntityProperties { get; set; } - public abstract OMV.Vector3 Scale { get; set; } + public virtual OMV.Vector3 Scale { get; set; } public abstract bool IsSolid { get; } public abstract bool IsStatic { get; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 35d22c0..19c29cc 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -45,7 +45,6 @@ public sealed class BSPrim : BSPhysObject private static readonly string LogHeader = "[BULLETS PRIM]"; // _size is what the user passed. Scale is what we pass to the physics engine with the mesh. - // Often Scale is unity because the meshmerizer will apply _size when creating the mesh. private OMV.Vector3 _size; // the multiplier for each mesh dimension as passed by the user private bool _grabbed; @@ -93,7 +92,7 @@ public sealed class BSPrim : BSPhysObject _physicsActorType = (int)ActorTypes.Prim; _position = pos; _size = size; - Scale = size; // the scale will be set by CreateGeom depending on object type + Scale = size; // prims are the size the user wants them to be (different for BSCharactes). _orientation = rotation; _buoyancy = 1f; _velocity = OMV.Vector3.Zero; @@ -159,12 +158,10 @@ public sealed class BSPrim : BSPhysObject // We presume the scale and size are the same. If scale must be changed for // the physical shape, that is done when the geometry is built. _size = value; + Scale = _size; ForceBodyShapeRebuild(false); } } - // Scale is what we set in the physics engine. It is different than 'size' in that - // 'size' can be encorporated into the mesh. In that case, the scale is <1,1,1>. - public override OMV.Vector3 Scale { get; set; } public override PrimitiveBaseShape Shape { set { @@ -1369,7 +1366,6 @@ public sealed class BSPrim : BSPhysObject // Create the correct physical representation for this type of object. // Updates PhysBody and PhysShape with the new information. // Ignore 'forceRebuild'. This routine makes the right choices and changes of necessary. - // Returns 'true' if either the body or the shape was changed. PhysicsScene.Shapes.GetBodyAndShape(false, PhysicsScene.World, this, null, delegate(BulletBody dBody) { // Called if the current prim body is about to be destroyed. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 4ab9a99..ea996ae 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -126,6 +126,11 @@ public sealed class BSShapeCollection : IDisposable return ret; } + public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim) + { + return GetBodyAndShape(forceRebuild, sim, prim, null, null); + } + // Track another user of a body. // We presume the caller has allocated the body. // Bodies only have one user so the body is just put into the world if not already there. @@ -460,6 +465,11 @@ public sealed class BSShapeCollection : IDisposable && pbs.PathScaleX == 100 && pbs.PathScaleY == 100 && pbs.PathShearX == 0 && pbs.PathShearY == 0) ) ) { + // Get the scale of any existing shape so we can see if the new shape is same native type and same size. + OMV.Vector3 scaleOfExistingShape = OMV.Vector3.Zero; + if (prim.PhysShape.HasPhysicalShape) + scaleOfExistingShape = BulletSimAPI.GetLocalScaling2(prim.PhysShape.ptr); + if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,maybeNative,force={1},primScale={2},primSize={3},primShape={4}", prim.LocalID, forceRebuild, prim.Scale, prim.Size, prim.PhysShape.type); @@ -469,7 +479,7 @@ public sealed class BSShapeCollection : IDisposable { haveShape = true; if (forceRebuild - || prim.Scale != prim.Size + || prim.Scale != scaleOfExistingShape || prim.PhysShape.type != BSPhysicsShapeType.SHAPE_SPHERE ) { @@ -483,7 +493,7 @@ public sealed class BSShapeCollection : IDisposable { haveShape = true; if (forceRebuild - || prim.Scale != prim.Size + || prim.Scale != scaleOfExistingShape || prim.PhysShape.type != BSPhysicsShapeType.SHAPE_BOX ) { @@ -542,7 +552,6 @@ public sealed class BSShapeCollection : IDisposable prim.LocalID, newShape, prim.Scale); // native shapes are scaled by Bullet - prim.Scale = prim.Size; prim.PhysShape = newShape; return true; } @@ -555,8 +564,8 @@ public sealed class BSShapeCollection : IDisposable ShapeData nativeShapeData = new ShapeData(); nativeShapeData.Type = shapeType; nativeShapeData.ID = prim.LocalID; - nativeShapeData.Scale = prim.Size; - nativeShapeData.Size = prim.Size; // unneeded, I think. + nativeShapeData.Scale = prim.Scale; + nativeShapeData.Size = prim.Scale; // unneeded, I think. nativeShapeData.MeshKey = (ulong)shapeKey; nativeShapeData.HullKey = (ulong)shapeKey; @@ -611,8 +620,6 @@ public sealed class BSShapeCollection : IDisposable ReferenceShape(newShape); - // meshes are already scaled by the meshmerizer - prim.Scale = new OMV.Vector3(1f, 1f, 1f); prim.PhysShape = newShape; return true; // 'true' means a new shape has been added to this prim @@ -683,8 +690,6 @@ public sealed class BSShapeCollection : IDisposable ReferenceShape(newShape); - // hulls are already scaled by the meshmerizer - prim.Scale = new OMV.Vector3(1f, 1f, 1f); prim.PhysShape = newShape; return true; // 'true' means a new shape has been added to this prim } -- cgit v1.1 From 6fca93f0b1343bad8582d10634a4ae4dc161e401 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 13 Dec 2012 01:03:35 +0000 Subject: Fix sounds so that they play from inventory after teleport rather than only on initial login region. Regression from commit ed162a10 (Fri Oct 5 13:50:12 2012) We had started listening for the client login event for attaching the sound trigger event rather than OnNewClient Addresses http://opensimulator.org/mantis/view.php?id=6453 Many thanks to danbanner for identifying the exact commit where this went wrong, which made identifying the fix easy. --- OpenSim/Region/CoreModules/World/Sound/SoundModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs index 089fcda..883045a 100644 --- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs +++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs @@ -76,7 +76,7 @@ namespace OpenSim.Region.CoreModules.World.Sound public void RemoveRegion(Scene scene) { - m_scene.EventManager.OnClientLogin -= OnNewClient; + m_scene.EventManager.OnNewClient -= OnNewClient; } public void RegionLoaded(Scene scene) @@ -85,7 +85,7 @@ namespace OpenSim.Region.CoreModules.World.Sound return; m_scene = scene; - m_scene.EventManager.OnClientLogin += OnNewClient; + m_scene.EventManager.OnNewClient += OnNewClient; m_scene.RegisterModuleInterface(this); } -- cgit v1.1 From 88b094cbf76e9775163ebfdfa23ddb052b62b460 Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Thu, 13 Dec 2012 13:05:28 -0800 Subject: Simplify sit code a bit by determining correct animation in HandleSit instead of HandleSitRequest. This eliminates m_nextSitAnimation, an unneeded state-saving variable in ScenePresence --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 36 ++++-------------------- 1 file changed, 6 insertions(+), 30 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 6f36c0b..58721b0 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -212,8 +212,6 @@ namespace OpenSim.Region.Framework.Scenes private Quaternion m_headrotation = Quaternion.Identity; - private string m_nextSitAnimation = String.Empty; - //PauPaw:Proper PID Controler for autopilot************ public bool MovingToTarget { get; private set; } public Vector3 MoveToPositionTarget { get; private set; } @@ -1955,25 +1953,10 @@ namespace OpenSim.Region.Framework.Scenes StandUp(); } -// if (!String.IsNullOrEmpty(sitAnimation)) -// { -// m_nextSitAnimation = sitAnimation; -// } -// else -// { - m_nextSitAnimation = "SIT"; -// } - - //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); SceneObjectPart part = FindNextAvailableSitTarget(targetID); if (part != null) { - if (!String.IsNullOrEmpty(part.SitAnimation)) - { - m_nextSitAnimation = part.SitAnimation; - } - m_requestedSitTargetID = part.LocalId; m_requestedSitTargetUUID = targetID; @@ -2188,18 +2171,6 @@ namespace OpenSim.Region.Framework.Scenes public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) { - if (!String.IsNullOrEmpty(m_nextSitAnimation)) - { - HandleAgentSit(remoteClient, agentID, m_nextSitAnimation); - } - else - { - HandleAgentSit(remoteClient, agentID, "SIT"); - } - } - - public void HandleAgentSit(IClientAPI remoteClient, UUID agentID, string sitAnimation) - { SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); if (part != null) @@ -2246,7 +2217,12 @@ namespace OpenSim.Region.Framework.Scenes Velocity = Vector3.Zero; RemoveFromPhysicalScene(); - + + String sitAnimation = "SIT"; + if (!String.IsNullOrEmpty(part.SitAnimation)) + { + sitAnimation = part.SitAnimation; + } Animator.TrySetMovementAnimation(sitAnimation); SendAvatarDataToAllAgents(); } -- cgit v1.1 From 523213060b315c677bf3142b5d2925460a49c9ed Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 13 Dec 2012 21:02:55 +0000 Subject: Add WaitForEventCompletionOnScriptStop [XEngine] config param to OpenSimDefaults.ini to allow change of the wait time for an event to complete on script removal before aborting its thread Default is 1000, as has previously been the case. This parameter exists for further debug work concerning mono 2.10 crashes that may be related to locks not being removed on Thread.Abort --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 34 ++++++++++++++++++-------- 1 file changed, 24 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 828f2fb..1dd50c7 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -107,6 +107,24 @@ namespace OpenSim.Region.ScriptEngine.XEngine private IXmlRpcRouter m_XmlRpcRouter; private int m_EventLimit; private bool m_KillTimedOutScripts; + + /// + /// Number of milliseconds we will wait for a script event to complete on script stop before we forcibly abort + /// its thread. + /// + /// + /// It appears that if a script thread is aborted whilst it is holding ReaderWriterLockSlim (possibly the write + /// lock) then the lock is not properly released. This causes mono 2.6, 2.10 and possibly + /// later to crash, sometimes with symptoms such as a leap to 100% script usage and a vm thead dump showing + /// all threads waiting on release of ReaderWriterLockSlim write thread which none of the threads listed + /// actually hold. + /// + /// Pausing for event completion reduces the risk of this happening. However, it may be that aborting threads + /// is not a mono issue per se but rather a risky activity in itself in an AppDomain that is not immediately + /// shutting down. + /// + private int m_WaitForEventCompletionOnScriptStop = 1000; + private string m_ScriptEnginesPath = null; private ExpiringCache m_runFlags = new ExpiringCache(); @@ -249,6 +267,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_EventLimit = m_ScriptConfig.GetInt("EventLimit", 30); m_KillTimedOutScripts = m_ScriptConfig.GetBoolean("KillTimedOutScripts", false); m_SaveTime = m_ScriptConfig.GetInt("SaveInterval", 120) * 1000; + m_WaitForEventCompletionOnScriptStop + = m_ScriptConfig.GetInt("WaitForEventCompletionOnScriptStop", m_WaitForEventCompletionOnScriptStop); + m_ScriptEnginesPath = m_ScriptConfig.GetString("ScriptEnginesPath", "ScriptEngines"); m_Prio = ThreadPriority.BelowNormal; @@ -1335,9 +1356,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine instance.ClearQueue(); - // Give the script some time to finish processing its last event. Simply aborting the script thread can - // cause issues on mono 2.6, 2.10 and possibly later where locks are not released properly on abort. - instance.Stop(1000); + instance.Stop(m_WaitForEventCompletionOnScriptStop); // bool objectRemoved = false; @@ -1687,16 +1706,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine public void StopScript(UUID itemID) { IScriptInstance instance = GetInstance(itemID); + if (instance != null) - { - // Give the script some time to finish processing its last event. Simply aborting the script thread can - // cause issues on mono 2.6, 2.10 and possibly later where locks are not released properly on abort. - instance.Stop(1000); - } + instance.Stop(m_WaitForEventCompletionOnScriptStop); else - { m_runFlags.AddOrUpdate(itemID, false, 240); - } } public DetectParams GetDetectParams(UUID itemID, int idx) -- cgit v1.1 From 0b93a68030cb498896c296654004d3dc2270bc4b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 13 Dec 2012 23:32:28 +0000 Subject: minor: add some more detail to the logging if an LLClientView fails to process a packet --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 4fd81fa..504df40 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -11864,11 +11864,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (logPacket) m_log.DebugFormat( "[CLIENT]: PACKET IN from {0} ({1}) in {2} - {3}", - Name, SceneAgent.IsChildAgent ? "child" : "root ", m_scene.RegionInfo.RegionName, packet.Type); + Name, SceneAgent.IsChildAgent ? "child" : "root ", Scene.Name, packet.Type); } if (!ProcessPacketMethod(packet)) - m_log.Warn("[CLIENT]: unhandled packet " + packet.Type); + m_log.WarnFormat( + "[CLIENT]: Unhandled packet {0} from {1} ({2}) in {3}. Ignoring.", + packet.Type, Name, SceneAgent.IsChildAgent ? "child" : "root ", Scene.Name); } private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket) -- cgit v1.1 From 9e0dd9952b76fdda337e518932a1ef57f8215986 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 13 Dec 2012 12:42:09 -0800 Subject: BulletSim: remove extra linkset rebuilds. --- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 54 ++++++++++++++-------- 1 file changed, 36 insertions(+), 18 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index d2abdb4..6cabe3a 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -114,6 +114,12 @@ public sealed class BSLinksetCompound : BSLinkset { // The root is going dynamic. Make sure mass is properly set. m_mass = ComputeLinksetMass(); + if (HasAnyChildren) + { + // Schedule a rebuilding as this will construct the complete compound shape + // and set all the properties correctly. + InternalRefresh(LinksetRoot); + } } else { @@ -123,6 +129,9 @@ public sealed class BSLinksetCompound : BSLinkset BulletSimAPI.ForceActivationState2(child.PhysBody.ptr, ActivationState.DISABLE_SIMULATION); // We don't want collisions from the old linkset children. BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + + child.PhysBody.collisionType = CollisionType.LinksetChild; + ret = true; } return ret; @@ -137,10 +146,21 @@ public sealed class BSLinksetCompound : BSLinkset { bool ret = false; DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child)); - if (!IsRoot(child)) + if (IsRoot(child)) + { + if (HasAnyChildren) + { + // Schedule a rebuilding as this will construct the complete compound shape + // and set all the properties correctly. + InternalRefresh(LinksetRoot); + } + } + else { // The non-physical children can come back to life. BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); + child.PhysBody.collisionType = CollisionType.LinksetChild; + // Don't force activation so setting of DISABLE_SIMULATION can stay if used. BulletSimAPI.Activate2(child.PhysBody.ptr, false); ret = true; @@ -182,19 +202,25 @@ public sealed class BSLinksetCompound : BSLinkset // Because it is a convenient time, recompute child world position and rotation based on // its position in the linkset. RecomputeChildWorldPosition(child, true); - - // Cause the current shape to be freed and the new one to be built. - InternalRefresh(LinksetRoot); - ret = true; } + // Cannot schedule a refresh/rebuild here because this routine is called when + // the linkset is being rebuilt. + // InternalRefresh(LinksetRoot); + return ret; } - // When the linkset is built, the child shape is added - // to the compound shape relative to the root shape. The linkset then moves around but - // this does not move the actual child prim. The child prim's location must be recomputed - // based on the location of the root shape. + // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true', + // this routine will restore the removed constraints. + // Called at taint-time!! + public override void RestoreBodyDependencies(BSPrim child) + { + } + + // When the linkset is built, the child shape is added to the compound shape relative to the + // root shape. The linkset then moves around but this does not move the actual child + // prim. The child prim's location must be recomputed based on the location of the root shape. private void RecomputeChildWorldPosition(BSPhysObject child, bool inTaintTime) { BSLinksetCompoundInfo lci = child.LinksetInfo as BSLinksetCompoundInfo; @@ -227,14 +253,6 @@ public sealed class BSLinksetCompound : BSLinkset } } - // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true', - // this routine will restore the removed constraints. - // Called at taint-time!! - public override void RestoreBodyDependencies(BSPrim child) - { - // The Refresh operation queued by RemoveBodyDependencies() will build any missing constraints. - } - // ================================================================ // Add a new child to the linkset. @@ -254,7 +272,7 @@ public sealed class BSLinksetCompound : BSLinkset } // Remove the specified child from the linkset. - // Safe to call even if the child is not really in my linkset. + // Safe to call even if the child is not really in the linkset. protected override void RemoveChildFromLinkset(BSPhysObject child) { if (m_children.Remove(child)) -- cgit v1.1 From 3b2b785a461eba34c26a45be246c2baef2820e39 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 13 Dec 2012 12:42:25 -0800 Subject: BulletSim: Add 'BulletSimData' which separates structures created for the operation of BulletSim and those defintiions/structures defined so they can be used in the unmanaged world. Consolidate setting of collision flags so implementation is not scattered. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 5 +- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 29 +-- .../Physics/BulletSPlugin/BSTerrainHeightmap.cs | 5 +- .../Physics/BulletSPlugin/BSTerrainManager.cs | 4 +- .../Region/Physics/BulletSPlugin/BSTerrainMesh.cs | 5 +- .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 183 +------------ .../Region/Physics/BulletSPlugin/BulletSimData.cs | 282 +++++++++++++++++++++ 7 files changed, 308 insertions(+), 205 deletions(-) create mode 100755 OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index c8aad8d..0defb24 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -167,9 +167,8 @@ public sealed class BSCharacter : BSPhysObject BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); // Do this after the object has been added to the world - BulletSimAPI.SetCollisionGroupMask2(PhysBody.ptr, - (uint)CollisionFilterGroups.AvatarGroup, - (uint)CollisionFilterGroups.AvatarMask); + PhysBody.collisionType = CollisionType.Avatar; + PhysBody.ApplyCollisionMask(); } public override void RequestPhysicsterseUpdate() diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 19c29cc..c9c9c2c 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -661,14 +661,7 @@ public sealed class BSPrim : BSPhysObject BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); // Collision filter can be set only when the object is in the world - if (PhysBody.collisionGroup != 0 || PhysBody.collisionMask != 0) - { - if (!BulletSimAPI.SetCollisionGroupMask2(PhysBody.ptr, (uint)PhysBody.collisionGroup, (uint)PhysBody.collisionMask)) - { - PhysicsScene.Logger.ErrorFormat("{0} Failure setting prim collision mask. localID={1}, grp={2:X}, mask={3:X}", - LogHeader, LocalID, PhysBody.collisionGroup, PhysBody.collisionMask); - } - } + PhysBody.ApplyCollisionMask(); // Recompute any linkset parameters. // When going from non-physical to physical, this re-enables the constraints that @@ -713,11 +706,11 @@ public sealed class BSPrim : BSPhysObject // Start it out sleeping and physical actions could wake it up. BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ISLAND_SLEEPING); + // This collides like a static object + PhysBody.collisionType = CollisionType.Static; + // There can be special things needed for implementing linksets Linkset.MakeStatic(this); - - PhysBody.collisionGroup = CollisionFilterGroups.StaticObjectGroup; - PhysBody.collisionMask = CollisionFilterGroups.StaticObjectMask; } else { @@ -755,16 +748,15 @@ public sealed class BSPrim : BSPhysObject BulletSimAPI.SetSleepingThresholds2(PhysBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold); BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, PhysicsScene.Params.contactProcessingThreshold); - // There might be special things needed for implementing linksets. - Linkset.MakeDynamic(this); + // This collides like an object. + PhysBody.collisionType = CollisionType.Dynamic; // Force activation of the object so Bullet will act on it. // Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects. BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ACTIVE_TAG); - // BulletSimAPI.Activate2(BSBody.ptr, true); - PhysBody.collisionGroup = CollisionFilterGroups.ObjectGroup; - PhysBody.collisionMask = CollisionFilterGroups.ObjectMask; + // There might be special things needed for implementing linksets. + Linkset.MakeDynamic(this); } } @@ -791,8 +783,9 @@ public sealed class BSPrim : BSPhysObject m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for non-solidness. id={1}, type={2}", LogHeader, LocalID, bodyType); } CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); - PhysBody.collisionGroup = CollisionFilterGroups.VolumeDetectGroup; - PhysBody.collisionMask = CollisionFilterGroups.VolumeDetectMask; + + // Change collision info from a static object to a ghosty collision object + PhysBody.collisionType = CollisionType.VolumeDetect; } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs index 2d379bb..2b120d6 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs @@ -121,9 +121,8 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys // redo its bounding box now that it is in the world BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); - BulletSimAPI.SetCollisionGroupMask2(m_mapInfo.terrainBody.ptr, - (uint)CollisionFilterGroups.TerrainGroup, - (uint)CollisionFilterGroups.TerrainMask); + m_mapInfo.terrainBody.collisionType = CollisionType.Terrain; + m_mapInfo.terrainBody.ApplyCollisionMask(); // Make it so the terrain will not move or be considered for movement. BulletSimAPI.ForceActivationState2(m_mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index c28d69d..5dbd8ce 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -140,8 +140,8 @@ public sealed class BSTerrainManager // Ground plane does not move BulletSimAPI.ForceActivationState2(m_groundPlane.ptr, ActivationState.DISABLE_SIMULATION); // Everything collides with the ground plane. - BulletSimAPI.SetCollisionGroupMask2(m_groundPlane.ptr, - (uint)CollisionFilterGroups.GroundPlaneGroup, (uint)CollisionFilterGroups.GroundPlaneMask); + m_groundPlane.collisionType = CollisionType.Groundplane; + m_groundPlane.ApplyCollisionMask(); // Build an initial terrain and put it in the world. This quickly gets replaced by the real region terrain. BSTerrainPhys initialTerrain = new BSTerrainHeightmap(PhysicsScene, Vector3.Zero, BSScene.TERRAIN_ID, DefaultRegionSize); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index 3473006..6dc0d92 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs @@ -130,9 +130,8 @@ public sealed class BSTerrainMesh : BSTerrainPhys // Redo its bounding box now that it is in the world BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr); - BulletSimAPI.SetCollisionGroupMask2(m_terrainBody.ptr, - (uint)CollisionFilterGroups.TerrainGroup, - (uint)CollisionFilterGroups.TerrainMask); + m_terrainBody.collisionType = CollisionType.Terrain; + m_terrainBody.ApplyCollisionMask(); // Make it so the terrain will not move or be considered for movement. BulletSimAPI.ForceActivationState2(m_terrainBody.ptr, ActivationState.DISABLE_SIMULATION); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 1559025..962b540 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -25,6 +25,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ using System; +using System.Collections.Generic; using System.Runtime.InteropServices; using System.Security; using System.Text; @@ -32,110 +33,6 @@ using OpenMetaverse; namespace OpenSim.Region.Physics.BulletSPlugin { -// Classes to allow some type checking for the API -// These hold pointers to allocated objects in the unmanaged space. - -// The physics engine controller class created at initialization -public struct BulletSim -{ - public BulletSim(uint worldId, BSScene bss, IntPtr xx) - { - ptr = xx; - worldID = worldId; - physicsScene = bss; - } - public IntPtr ptr; - public uint worldID; - // The scene is only in here so very low level routines have a handle to print debug/error messages - public BSScene physicsScene; -} - -// An allocated Bullet btRigidBody -public struct BulletBody -{ - public BulletBody(uint id) : this(id, IntPtr.Zero) - { - } - public BulletBody(uint id, IntPtr xx) - { - ID = id; - ptr = xx; - collisionGroup = 0; - collisionMask = 0; - } - public IntPtr ptr; - public uint ID; - public CollisionFilterGroups collisionGroup; - public CollisionFilterGroups collisionMask; - - public void Clear() - { - ptr = IntPtr.Zero; - } - public bool HasPhysicalBody { get { return ptr != IntPtr.Zero; } } - - public override string ToString() - { - StringBuilder buff = new StringBuilder(); - buff.Append(""); - return buff.ToString(); - } -} - -public struct BulletShape -{ - public BulletShape(IntPtr xx) - { - ptr = xx; - type=BSPhysicsShapeType.SHAPE_UNKNOWN; - shapeKey = (System.UInt64)FixedShapeKey.KEY_NONE; - isNativeShape = false; - } - public BulletShape(IntPtr xx, BSPhysicsShapeType typ) - { - ptr = xx; - type = typ; - shapeKey = 0; - isNativeShape = false; - } - public IntPtr ptr; - public BSPhysicsShapeType type; - public System.UInt64 shapeKey; - public bool isNativeShape; - - public void Clear() - { - ptr = IntPtr.Zero; - } - public bool HasPhysicalShape { get { return ptr != IntPtr.Zero; } } - - public override string ToString() - { - StringBuilder buff = new StringBuilder(); - buff.Append(""); - return buff.ToString(); - } -} - // Constraint type values as defined by Bullet public enum ConstraintType : int { @@ -149,50 +46,6 @@ public enum ConstraintType : int MAX_CONSTRAINT_TYPE } -// An allocated Bullet btConstraint -public struct BulletConstraint -{ - public BulletConstraint(IntPtr xx) - { - ptr = xx; - } - public IntPtr ptr; - - public void Clear() - { - ptr = IntPtr.Zero; - } - public bool HasPhysicalConstraint { get { return ptr != IntPtr.Zero; } } -} - -// An allocated HeightMapThing which holds various heightmap info. -// Made a class rather than a struct so there would be only one -// instance of this and C# will pass around pointers rather -// than making copies. -public class BulletHeightMapInfo -{ - public BulletHeightMapInfo(uint id, float[] hm, IntPtr xx) { - ID = id; - Ptr = xx; - heightMap = hm; - terrainRegionBase = Vector3.Zero; - minCoords = new Vector3(100f, 100f, 25f); - maxCoords = new Vector3(101f, 101f, 26f); - minZ = maxZ = 0f; - sizeX = sizeY = 256f; - } - public uint ID; - public IntPtr Ptr; - public float[] heightMap; - public Vector3 terrainRegionBase; - public Vector3 minCoords; - public Vector3 maxCoords; - public float sizeX, sizeY; - public float minZ, maxZ; - public BulletShape terrainShape; - public BulletBody terrainBody; -} - // =============================================================================== [StructLayout(LayoutKind.Sequential)] public struct ConvexHull @@ -385,21 +238,15 @@ public enum CollisionFlags : uint BS_FLOATS_ON_WATER = 1 << 11, BS_VEHICLE_COLLISIONS = 1 << 12, BS_NONE = 0, - BS_ALL = 0xFFFFFFFF, - - // These are the collision flags switched depending on physical state. - // The other flags are used for other things and should not be fooled with. - BS_ACTIVE = CF_STATIC_OBJECT - | CF_KINEMATIC_OBJECT - | CF_NO_CONTACT_RESPONSE + BS_ALL = 0xFFFFFFFF }; -// Values for collisions groups and masks +// Values f collisions groups and masks public enum CollisionFilterGroups : uint { // Don't use the bit definitions!! Define the use in a // filter/mask definition below. This way collision interactions - // are more easily debugged. + // are more easily found and debugged. BNoneGroup = 0, BDefaultGroup = 1 << 0, BStaticGroup = 1 << 1, @@ -413,24 +260,8 @@ public enum CollisionFilterGroups : uint BTerrainGroup = 1 << 11, BRaycastGroup = 1 << 12, BSolidGroup = 1 << 13, - BLinksetGroup = 1 << 14, - - // The collsion filters and masked are defined in one place -- don't want them scattered - AvatarGroup = BCharacterGroup, - AvatarMask = BAllGroup, - ObjectGroup = BSolidGroup, - ObjectMask = BAllGroup, - StaticObjectGroup = BStaticGroup, - StaticObjectMask = AvatarGroup | ObjectGroup, // static things don't interact with much - LinksetGroup = BLinksetGroup, - LinksetMask = BAllGroup & ~BLinksetGroup, // linkset objects don't collide with each other - VolumeDetectGroup = BSensorTrigger, - VolumeDetectMask = ~BSensorTrigger, - TerrainGroup = BTerrainGroup, - TerrainMask = BAllGroup & ~BStaticGroup, // static objects on the ground don't collide - GroundPlaneGroup = BGroundPlaneGroup, - GroundPlaneMask = BAllGroup - + // BLinksetGroup = xx // a linkset proper is either static or dynamic + BLinksetChildGroup = 1 << 14, }; // CFM controls the 'hardness' of the constraint. 0=fixed, 0..1=violatable. Default=0 @@ -457,7 +288,7 @@ public enum ConstraintParamAxis : int // =============================================================================== static class BulletSimAPI { - +// =============================================================================== // Link back to the managed code for outputting log messages [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs new file mode 100755 index 0000000..e5c4777 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs @@ -0,0 +1,282 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using OMV = OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ +// Classes to allow some type checking for the API +// These hold pointers to allocated objects in the unmanaged space. + +// The physics engine controller class created at initialization +public struct BulletSim +{ + public BulletSim(uint worldId, BSScene bss, IntPtr xx) + { + ptr = xx; + worldID = worldId; + physicsScene = bss; + } + public IntPtr ptr; + public uint worldID; + // The scene is only in here so very low level routines have a handle to print debug/error messages + public BSScene physicsScene; +} + +// An allocated Bullet btRigidBody +public struct BulletBody +{ + public BulletBody(uint id) : this(id, IntPtr.Zero) + { + } + public BulletBody(uint id, IntPtr xx) + { + ID = id; + ptr = xx; + collisionType = CollisionType.Static; + } + public IntPtr ptr; + public uint ID; + public CollisionType collisionType; + + public void Clear() + { + ptr = IntPtr.Zero; + } + public bool HasPhysicalBody { get { return ptr != IntPtr.Zero; } } + + // Apply the specificed collision mask into the physical world + public void ApplyCollisionMask() + { + // Should assert the body has been added to the physical world. + // (The collision masks are stored in the collision proxy cache which only exists for + // a collision body that is in the world.) + BulletSimAPI.SetCollisionGroupMask2(ptr, + BulletSimData.CollisionTypeMasks[collisionType].group, + BulletSimData.CollisionTypeMasks[collisionType].mask); + } + + public override string ToString() + { + StringBuilder buff = new StringBuilder(); + buff.Append(""); + return buff.ToString(); + } +} + +public struct BulletShape +{ + public BulletShape(IntPtr xx) + { + ptr = xx; + type=BSPhysicsShapeType.SHAPE_UNKNOWN; + shapeKey = (System.UInt64)FixedShapeKey.KEY_NONE; + isNativeShape = false; + } + public BulletShape(IntPtr xx, BSPhysicsShapeType typ) + { + ptr = xx; + type = typ; + shapeKey = 0; + isNativeShape = false; + } + public IntPtr ptr; + public BSPhysicsShapeType type; + public System.UInt64 shapeKey; + public bool isNativeShape; + + public void Clear() + { + ptr = IntPtr.Zero; + } + public bool HasPhysicalShape { get { return ptr != IntPtr.Zero; } } + + public override string ToString() + { + StringBuilder buff = new StringBuilder(); + buff.Append(""); + return buff.ToString(); + } +} + +// An allocated Bullet btConstraint +public struct BulletConstraint +{ + public BulletConstraint(IntPtr xx) + { + ptr = xx; + } + public IntPtr ptr; + + public void Clear() + { + ptr = IntPtr.Zero; + } + public bool HasPhysicalConstraint { get { return ptr != IntPtr.Zero; } } +} + +// An allocated HeightMapThing which holds various heightmap info. +// Made a class rather than a struct so there would be only one +// instance of this and C# will pass around pointers rather +// than making copies. +public class BulletHeightMapInfo +{ + public BulletHeightMapInfo(uint id, float[] hm, IntPtr xx) { + ID = id; + Ptr = xx; + heightMap = hm; + terrainRegionBase = OMV.Vector3.Zero; + minCoords = new OMV.Vector3(100f, 100f, 25f); + maxCoords = new OMV.Vector3(101f, 101f, 26f); + minZ = maxZ = 0f; + sizeX = sizeY = 256f; + } + public uint ID; + public IntPtr Ptr; + public float[] heightMap; + public OMV.Vector3 terrainRegionBase; + public OMV.Vector3 minCoords; + public OMV.Vector3 maxCoords; + public float sizeX, sizeY; + public float minZ, maxZ; + public BulletShape terrainShape; + public BulletBody terrainBody; +} + +// The general class of collsion object. +public enum CollisionType +{ + Avatar, + Groundplane, + Terrain, + Static, + Dynamic, + VolumeDetect, + // Linkset, // A linkset proper should be either Static or Dynamic + LinksetChild, + Unknown +}; + +// Hold specification of group and mask collision flags for a CollisionType +public struct CollisionTypeFilterGroup +{ + public CollisionTypeFilterGroup(CollisionType t, uint g, uint m) + { + type = t; + group = g; + mask = m; + } + public CollisionType type; + public uint group; + public uint mask; +}; + + /* + // The collsion filters and masked are defined in one place -- don't want them scattered + AvatarGroup = BCharacterGroup, + AvatarMask = BAllGroup, + ObjectGroup = BSolidGroup, + ObjectMask = BAllGroup, + StaticObjectGroup = BStaticGroup, + StaticObjectMask = AvatarGroup | ObjectGroup, // static things don't interact with much + LinksetGroup = BLinksetGroup, + LinksetMask = BAllGroup, + LinksetChildGroup = BLinksetChildGroup, + LinksetChildMask = BNoneGroup, // Linkset children disappear from the world + VolumeDetectGroup = BSensorTrigger, + VolumeDetectMask = ~BSensorTrigger, + TerrainGroup = BTerrainGroup, + TerrainMask = BAllGroup & ~BStaticGroup, // static objects on the ground don't collide + GroundPlaneGroup = BGroundPlaneGroup, + GroundPlaneMask = BAllGroup + */ + +public static class BulletSimData +{ + +// Map of collisionTypes to flags for collision groups and masks. +// As mentioned above, don't use the CollisionFilterGroups definitions directly in the code +// but, instead, user references to this dictionary. This makes finding and debugging +// collision flag usage easier. +public static Dictionary CollisionTypeMasks + = new Dictionary() +{ + { CollisionType.Avatar, + new CollisionTypeFilterGroup(CollisionType.Avatar, + (uint)CollisionFilterGroups.BCharacterGroup, + (uint)CollisionFilterGroups.BAllGroup) + }, + { CollisionType.Groundplane, + new CollisionTypeFilterGroup(CollisionType.Groundplane, + (uint)CollisionFilterGroups.BGroundPlaneGroup, + (uint)CollisionFilterGroups.BAllGroup) + }, + { CollisionType.Terrain, + new CollisionTypeFilterGroup(CollisionType.Terrain, + (uint)CollisionFilterGroups.BTerrainGroup, + (uint)(CollisionFilterGroups.BAllGroup & ~CollisionFilterGroups.BStaticGroup)) + }, + { CollisionType.Static, + new CollisionTypeFilterGroup(CollisionType.Static, + (uint)CollisionFilterGroups.BStaticGroup, + (uint)(CollisionFilterGroups.BCharacterGroup | CollisionFilterGroups.BSolidGroup)) + }, + { CollisionType.Dynamic, + new CollisionTypeFilterGroup(CollisionType.Dynamic, + (uint)CollisionFilterGroups.BSolidGroup, + (uint)(CollisionFilterGroups.BAllGroup)) + }, + { CollisionType.VolumeDetect, + new CollisionTypeFilterGroup(CollisionType.VolumeDetect, + (uint)CollisionFilterGroups.BSensorTrigger, + (uint)(~CollisionFilterGroups.BSensorTrigger)) + }, + { CollisionType.LinksetChild, + new CollisionTypeFilterGroup(CollisionType.LinksetChild, + (uint)CollisionFilterGroups.BTerrainGroup, + (uint)(CollisionFilterGroups.BNoneGroup)) + }, +}; + +} +} -- cgit v1.1 From 60950bfab5657b09c314ffd03aceeac5973be84c Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 13 Dec 2012 16:15:21 -0800 Subject: BulletSim: correct line endings in new BulletSimData.cs file. --- .../Region/Physics/BulletSPlugin/BulletSimData.cs | 564 ++++++++++----------- 1 file changed, 282 insertions(+), 282 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs index e5c4777..524a1d0 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs @@ -1,282 +1,282 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Text; -using OMV = OpenMetaverse; - -namespace OpenSim.Region.Physics.BulletSPlugin -{ -// Classes to allow some type checking for the API -// These hold pointers to allocated objects in the unmanaged space. - -// The physics engine controller class created at initialization -public struct BulletSim -{ - public BulletSim(uint worldId, BSScene bss, IntPtr xx) - { - ptr = xx; - worldID = worldId; - physicsScene = bss; - } - public IntPtr ptr; - public uint worldID; - // The scene is only in here so very low level routines have a handle to print debug/error messages - public BSScene physicsScene; -} - -// An allocated Bullet btRigidBody -public struct BulletBody -{ - public BulletBody(uint id) : this(id, IntPtr.Zero) - { - } - public BulletBody(uint id, IntPtr xx) - { - ID = id; - ptr = xx; - collisionType = CollisionType.Static; - } - public IntPtr ptr; - public uint ID; - public CollisionType collisionType; - - public void Clear() - { - ptr = IntPtr.Zero; - } - public bool HasPhysicalBody { get { return ptr != IntPtr.Zero; } } - - // Apply the specificed collision mask into the physical world - public void ApplyCollisionMask() - { - // Should assert the body has been added to the physical world. - // (The collision masks are stored in the collision proxy cache which only exists for - // a collision body that is in the world.) - BulletSimAPI.SetCollisionGroupMask2(ptr, - BulletSimData.CollisionTypeMasks[collisionType].group, - BulletSimData.CollisionTypeMasks[collisionType].mask); - } - - public override string ToString() - { - StringBuilder buff = new StringBuilder(); - buff.Append(""); - return buff.ToString(); - } -} - -public struct BulletShape -{ - public BulletShape(IntPtr xx) - { - ptr = xx; - type=BSPhysicsShapeType.SHAPE_UNKNOWN; - shapeKey = (System.UInt64)FixedShapeKey.KEY_NONE; - isNativeShape = false; - } - public BulletShape(IntPtr xx, BSPhysicsShapeType typ) - { - ptr = xx; - type = typ; - shapeKey = 0; - isNativeShape = false; - } - public IntPtr ptr; - public BSPhysicsShapeType type; - public System.UInt64 shapeKey; - public bool isNativeShape; - - public void Clear() - { - ptr = IntPtr.Zero; - } - public bool HasPhysicalShape { get { return ptr != IntPtr.Zero; } } - - public override string ToString() - { - StringBuilder buff = new StringBuilder(); - buff.Append(""); - return buff.ToString(); - } -} - -// An allocated Bullet btConstraint -public struct BulletConstraint -{ - public BulletConstraint(IntPtr xx) - { - ptr = xx; - } - public IntPtr ptr; - - public void Clear() - { - ptr = IntPtr.Zero; - } - public bool HasPhysicalConstraint { get { return ptr != IntPtr.Zero; } } -} - -// An allocated HeightMapThing which holds various heightmap info. -// Made a class rather than a struct so there would be only one -// instance of this and C# will pass around pointers rather -// than making copies. -public class BulletHeightMapInfo -{ - public BulletHeightMapInfo(uint id, float[] hm, IntPtr xx) { - ID = id; - Ptr = xx; - heightMap = hm; - terrainRegionBase = OMV.Vector3.Zero; - minCoords = new OMV.Vector3(100f, 100f, 25f); - maxCoords = new OMV.Vector3(101f, 101f, 26f); - minZ = maxZ = 0f; - sizeX = sizeY = 256f; - } - public uint ID; - public IntPtr Ptr; - public float[] heightMap; - public OMV.Vector3 terrainRegionBase; - public OMV.Vector3 minCoords; - public OMV.Vector3 maxCoords; - public float sizeX, sizeY; - public float minZ, maxZ; - public BulletShape terrainShape; - public BulletBody terrainBody; -} - -// The general class of collsion object. -public enum CollisionType -{ - Avatar, - Groundplane, - Terrain, - Static, - Dynamic, - VolumeDetect, - // Linkset, // A linkset proper should be either Static or Dynamic - LinksetChild, - Unknown -}; - -// Hold specification of group and mask collision flags for a CollisionType -public struct CollisionTypeFilterGroup -{ - public CollisionTypeFilterGroup(CollisionType t, uint g, uint m) - { - type = t; - group = g; - mask = m; - } - public CollisionType type; - public uint group; - public uint mask; -}; - - /* - // The collsion filters and masked are defined in one place -- don't want them scattered - AvatarGroup = BCharacterGroup, - AvatarMask = BAllGroup, - ObjectGroup = BSolidGroup, - ObjectMask = BAllGroup, - StaticObjectGroup = BStaticGroup, - StaticObjectMask = AvatarGroup | ObjectGroup, // static things don't interact with much - LinksetGroup = BLinksetGroup, - LinksetMask = BAllGroup, - LinksetChildGroup = BLinksetChildGroup, - LinksetChildMask = BNoneGroup, // Linkset children disappear from the world - VolumeDetectGroup = BSensorTrigger, - VolumeDetectMask = ~BSensorTrigger, - TerrainGroup = BTerrainGroup, - TerrainMask = BAllGroup & ~BStaticGroup, // static objects on the ground don't collide - GroundPlaneGroup = BGroundPlaneGroup, - GroundPlaneMask = BAllGroup - */ - -public static class BulletSimData -{ - -// Map of collisionTypes to flags for collision groups and masks. -// As mentioned above, don't use the CollisionFilterGroups definitions directly in the code -// but, instead, user references to this dictionary. This makes finding and debugging -// collision flag usage easier. -public static Dictionary CollisionTypeMasks - = new Dictionary() -{ - { CollisionType.Avatar, - new CollisionTypeFilterGroup(CollisionType.Avatar, - (uint)CollisionFilterGroups.BCharacterGroup, - (uint)CollisionFilterGroups.BAllGroup) - }, - { CollisionType.Groundplane, - new CollisionTypeFilterGroup(CollisionType.Groundplane, - (uint)CollisionFilterGroups.BGroundPlaneGroup, - (uint)CollisionFilterGroups.BAllGroup) - }, - { CollisionType.Terrain, - new CollisionTypeFilterGroup(CollisionType.Terrain, - (uint)CollisionFilterGroups.BTerrainGroup, - (uint)(CollisionFilterGroups.BAllGroup & ~CollisionFilterGroups.BStaticGroup)) - }, - { CollisionType.Static, - new CollisionTypeFilterGroup(CollisionType.Static, - (uint)CollisionFilterGroups.BStaticGroup, - (uint)(CollisionFilterGroups.BCharacterGroup | CollisionFilterGroups.BSolidGroup)) - }, - { CollisionType.Dynamic, - new CollisionTypeFilterGroup(CollisionType.Dynamic, - (uint)CollisionFilterGroups.BSolidGroup, - (uint)(CollisionFilterGroups.BAllGroup)) - }, - { CollisionType.VolumeDetect, - new CollisionTypeFilterGroup(CollisionType.VolumeDetect, - (uint)CollisionFilterGroups.BSensorTrigger, - (uint)(~CollisionFilterGroups.BSensorTrigger)) - }, - { CollisionType.LinksetChild, - new CollisionTypeFilterGroup(CollisionType.LinksetChild, - (uint)CollisionFilterGroups.BTerrainGroup, - (uint)(CollisionFilterGroups.BNoneGroup)) - }, -}; - -} -} +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using OMV = OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ +// Classes to allow some type checking for the API +// These hold pointers to allocated objects in the unmanaged space. + +// The physics engine controller class created at initialization +public struct BulletSim +{ + public BulletSim(uint worldId, BSScene bss, IntPtr xx) + { + ptr = xx; + worldID = worldId; + physicsScene = bss; + } + public IntPtr ptr; + public uint worldID; + // The scene is only in here so very low level routines have a handle to print debug/error messages + public BSScene physicsScene; +} + +// An allocated Bullet btRigidBody +public struct BulletBody +{ + public BulletBody(uint id) : this(id, IntPtr.Zero) + { + } + public BulletBody(uint id, IntPtr xx) + { + ID = id; + ptr = xx; + collisionType = CollisionType.Static; + } + public IntPtr ptr; + public uint ID; + public CollisionType collisionType; + + public void Clear() + { + ptr = IntPtr.Zero; + } + public bool HasPhysicalBody { get { return ptr != IntPtr.Zero; } } + + // Apply the specificed collision mask into the physical world + public void ApplyCollisionMask() + { + // Should assert the body has been added to the physical world. + // (The collision masks are stored in the collision proxy cache which only exists for + // a collision body that is in the world.) + BulletSimAPI.SetCollisionGroupMask2(ptr, + BulletSimData.CollisionTypeMasks[collisionType].group, + BulletSimData.CollisionTypeMasks[collisionType].mask); + } + + public override string ToString() + { + StringBuilder buff = new StringBuilder(); + buff.Append(""); + return buff.ToString(); + } +} + +public struct BulletShape +{ + public BulletShape(IntPtr xx) + { + ptr = xx; + type=BSPhysicsShapeType.SHAPE_UNKNOWN; + shapeKey = (System.UInt64)FixedShapeKey.KEY_NONE; + isNativeShape = false; + } + public BulletShape(IntPtr xx, BSPhysicsShapeType typ) + { + ptr = xx; + type = typ; + shapeKey = 0; + isNativeShape = false; + } + public IntPtr ptr; + public BSPhysicsShapeType type; + public System.UInt64 shapeKey; + public bool isNativeShape; + + public void Clear() + { + ptr = IntPtr.Zero; + } + public bool HasPhysicalShape { get { return ptr != IntPtr.Zero; } } + + public override string ToString() + { + StringBuilder buff = new StringBuilder(); + buff.Append(""); + return buff.ToString(); + } +} + +// An allocated Bullet btConstraint +public struct BulletConstraint +{ + public BulletConstraint(IntPtr xx) + { + ptr = xx; + } + public IntPtr ptr; + + public void Clear() + { + ptr = IntPtr.Zero; + } + public bool HasPhysicalConstraint { get { return ptr != IntPtr.Zero; } } +} + +// An allocated HeightMapThing which holds various heightmap info. +// Made a class rather than a struct so there would be only one +// instance of this and C# will pass around pointers rather +// than making copies. +public class BulletHeightMapInfo +{ + public BulletHeightMapInfo(uint id, float[] hm, IntPtr xx) { + ID = id; + Ptr = xx; + heightMap = hm; + terrainRegionBase = OMV.Vector3.Zero; + minCoords = new OMV.Vector3(100f, 100f, 25f); + maxCoords = new OMV.Vector3(101f, 101f, 26f); + minZ = maxZ = 0f; + sizeX = sizeY = 256f; + } + public uint ID; + public IntPtr Ptr; + public float[] heightMap; + public OMV.Vector3 terrainRegionBase; + public OMV.Vector3 minCoords; + public OMV.Vector3 maxCoords; + public float sizeX, sizeY; + public float minZ, maxZ; + public BulletShape terrainShape; + public BulletBody terrainBody; +} + +// The general class of collsion object. +public enum CollisionType +{ + Avatar, + Groundplane, + Terrain, + Static, + Dynamic, + VolumeDetect, + // Linkset, // A linkset proper should be either Static or Dynamic + LinksetChild, + Unknown +}; + +// Hold specification of group and mask collision flags for a CollisionType +public struct CollisionTypeFilterGroup +{ + public CollisionTypeFilterGroup(CollisionType t, uint g, uint m) + { + type = t; + group = g; + mask = m; + } + public CollisionType type; + public uint group; + public uint mask; +}; + + /* + // The collsion filters and masked are defined in one place -- don't want them scattered + AvatarGroup = BCharacterGroup, + AvatarMask = BAllGroup, + ObjectGroup = BSolidGroup, + ObjectMask = BAllGroup, + StaticObjectGroup = BStaticGroup, + StaticObjectMask = AvatarGroup | ObjectGroup, // static things don't interact with much + LinksetGroup = BLinksetGroup, + LinksetMask = BAllGroup, + LinksetChildGroup = BLinksetChildGroup, + LinksetChildMask = BNoneGroup, // Linkset children disappear from the world + VolumeDetectGroup = BSensorTrigger, + VolumeDetectMask = ~BSensorTrigger, + TerrainGroup = BTerrainGroup, + TerrainMask = BAllGroup & ~BStaticGroup, // static objects on the ground don't collide + GroundPlaneGroup = BGroundPlaneGroup, + GroundPlaneMask = BAllGroup + */ + +public static class BulletSimData +{ + +// Map of collisionTypes to flags for collision groups and masks. +// As mentioned above, don't use the CollisionFilterGroups definitions directly in the code +// but, instead, use references to this dictionary. Finding and debugging +// collision flag problems will be made easier. +public static Dictionary CollisionTypeMasks + = new Dictionary() +{ + { CollisionType.Avatar, + new CollisionTypeFilterGroup(CollisionType.Avatar, + (uint)CollisionFilterGroups.BCharacterGroup, + (uint)CollisionFilterGroups.BAllGroup) + }, + { CollisionType.Groundplane, + new CollisionTypeFilterGroup(CollisionType.Groundplane, + (uint)CollisionFilterGroups.BGroundPlaneGroup, + (uint)CollisionFilterGroups.BAllGroup) + }, + { CollisionType.Terrain, + new CollisionTypeFilterGroup(CollisionType.Terrain, + (uint)CollisionFilterGroups.BTerrainGroup, + (uint)(CollisionFilterGroups.BAllGroup & ~CollisionFilterGroups.BStaticGroup)) + }, + { CollisionType.Static, + new CollisionTypeFilterGroup(CollisionType.Static, + (uint)CollisionFilterGroups.BStaticGroup, + (uint)(CollisionFilterGroups.BCharacterGroup | CollisionFilterGroups.BSolidGroup)) + }, + { CollisionType.Dynamic, + new CollisionTypeFilterGroup(CollisionType.Dynamic, + (uint)CollisionFilterGroups.BSolidGroup, + (uint)(CollisionFilterGroups.BAllGroup)) + }, + { CollisionType.VolumeDetect, + new CollisionTypeFilterGroup(CollisionType.VolumeDetect, + (uint)CollisionFilterGroups.BSensorTrigger, + (uint)(~CollisionFilterGroups.BSensorTrigger)) + }, + { CollisionType.LinksetChild, + new CollisionTypeFilterGroup(CollisionType.LinksetChild, + (uint)CollisionFilterGroups.BTerrainGroup, + (uint)(CollisionFilterGroups.BNoneGroup)) + }, +}; + +} +} -- cgit v1.1 From 31d3952477b96b669d8a46d0941ea6d1bc1133b5 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 13 Dec 2012 16:23:51 -0800 Subject: BulletSim: fix problem with continuious rebuilding of physical linksets. This caused movement problems and large prim vehicles to take up a LOT of simulation time. --- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 9 +- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 155 +++++++++++---------- .../Physics/BulletSPlugin/BSLinksetConstraints.cs | 3 +- 3 files changed, 88 insertions(+), 79 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 777c5cb..ce0fbe6 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -124,7 +124,7 @@ public abstract class BSLinkset get { return ComputeLinksetGeometricCenter(); } } - protected void Initialize(BSScene scene, BSPhysObject parent) + protected BSLinkset(BSScene scene, BSPhysObject parent) { // A simple linkset of one (no children) LinksetID = m_nextLinksetID++; @@ -135,6 +135,7 @@ public abstract class BSLinkset LinksetRoot = parent; m_children = new HashSet(); m_mass = parent.RawMass; + Rebuilding = false; } // Link to a linkset where the child knows the parent. @@ -227,7 +228,7 @@ public abstract class BSLinkset // I am the root of a linkset and a new child is being added // Called while LinkActivity is locked. protected abstract void AddChildToLinkset(BSPhysObject child); - + // I am the root of a linkset and one of my children is being removed. // Safe to call even if the child is not really in my linkset. protected abstract void RemoveChildFromLinkset(BSPhysObject child); @@ -237,6 +238,10 @@ public abstract class BSLinkset // May be called at runtime or taint-time. public abstract void Refresh(BSPhysObject requestor); + // Flag denoting the linkset is in the process of being rebuilt. + // Used to know not the schedule a rebuild in the middle of a rebuild. + protected bool Rebuilding { get; set; } + // The object is going dynamic (physical). Do any setup necessary // for a dynamic linkset. // Only the state of the passed object can be modified. The rest of the linkset diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 6cabe3a..2189468 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -61,9 +61,8 @@ public sealed class BSLinksetCompound : BSLinkset { private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]"; - public BSLinksetCompound(BSScene scene, BSPhysObject parent) + public BSLinksetCompound(BSScene scene, BSPhysObject parent) : base(scene, parent) { - base.Initialize(scene, parent); } // For compound implimented linksets, if there are children, use compound shape for the root. @@ -81,8 +80,6 @@ public sealed class BSLinksetCompound : BSLinkset // When physical properties are changed the linkset needs to recalculate // its internal properties. - // This is queued in the 'post taint' queue so the - // refresh will happen once after all the other taints are applied. public override void Refresh(BSPhysObject requestor) { // External request for Refresh (from BSPrim) doesn't need to do anything @@ -92,12 +89,18 @@ public sealed class BSLinksetCompound : BSLinkset // Schedule a refresh to happen after all the other taint processing. private void InternalRefresh(BSPhysObject requestor) { - DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,requestor={1}", LinksetRoot.LocalID, requestor.LocalID); - PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", requestor.LocalID, delegate() + DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,requestor={1},rebuilding={2}", + LinksetRoot.LocalID, requestor.LocalID, Rebuilding); + // When rebuilding, it is possible to set properties that would normally require a rebuild. + // If already rebuilding, don't request another rebuild. + if (!Rebuilding) { - if (IsRoot(requestor) && HasAnyChildren) - RecomputeLinksetCompound(); - }); + PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", requestor.LocalID, delegate() + { + if (IsRoot(requestor) && HasAnyChildren) + RecomputeLinksetCompound(); + }); + } } // The object is going dynamic (physical). Do any setup necessary @@ -115,11 +118,7 @@ public sealed class BSLinksetCompound : BSLinkset // The root is going dynamic. Make sure mass is properly set. m_mass = ComputeLinksetMass(); if (HasAnyChildren) - { - // Schedule a rebuilding as this will construct the complete compound shape - // and set all the properties correctly. InternalRefresh(LinksetRoot); - } } else { @@ -149,16 +148,13 @@ public sealed class BSLinksetCompound : BSLinkset if (IsRoot(child)) { if (HasAnyChildren) - { - // Schedule a rebuilding as this will construct the complete compound shape - // and set all the properties correctly. InternalRefresh(LinksetRoot); - } } else { // The non-physical children can come back to life. BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); + child.PhysBody.collisionType = CollisionType.LinksetChild; // Don't force activation so setting of DISABLE_SIMULATION can stay if used. @@ -307,74 +303,83 @@ public sealed class BSLinksetCompound : BSLinkset // Called at taint time!! private void RecomputeLinksetCompound() { - // Cause the root shape to be rebuilt as a compound object with just the root in it - LinksetRoot.ForceBodyShapeRebuild(true); + try + { + // Suppress rebuilding while rebuilding + Rebuilding = true; - DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", - LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); + // Cause the root shape to be rebuilt as a compound object with just the root in it + LinksetRoot.ForceBodyShapeRebuild(true); - // Add a shape for each of the other children in the linkset - ForEachMember(delegate(BSPhysObject cPrim) - { - if (!IsRoot(cPrim)) + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", + LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); + + // Add a shape for each of the other children in the linkset + ForEachMember(delegate(BSPhysObject cPrim) { - // Compute the displacement of the child from the root of the linkset. - // This info is saved in the child prim so the relationship does not - // change over time and the new child position can be computed - // when the linkset is being disassembled (the linkset may have moved). - BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; - if (lci == null) + if (!IsRoot(cPrim)) { - // Each child position and rotation is given relative to the root. - OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); - OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; - OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; - - // Save relative position for recomputing child's world position after moving linkset. - lci = new BSLinksetCompoundInfo(displacementPos, displacementRot); - cPrim.LinksetInfo = lci; - DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); - } + // Compute the displacement of the child from the root of the linkset. + // This info is saved in the child prim so the relationship does not + // change over time and the new child position can be computed + // when the linkset is being disassembled (the linkset may have moved). + BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; + if (lci == null) + { + // Each child position and rotation is given relative to the root. + OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); + OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; + OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; + + // Save relative position for recomputing child's world position after moving linkset. + lci = new BSLinksetCompoundInfo(displacementPos, displacementRot); + cPrim.LinksetInfo = lci; + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); + } - DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}", - LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}", + LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); - if (cPrim.PhysShape.isNativeShape) - { - // A native shape is turning into a hull collision shape because native - // shapes are not shared so we have to hullify it so it will be tracked - // and freed at the correct time. This also solves the scaling problem - // (native shapes scaled but hull/meshes are assumed to not be). - // TODO: decide of the native shape can just be used in the compound shape. - // Use call to CreateGeomNonSpecial(). - BulletShape saveShape = cPrim.PhysShape; - cPrim.PhysShape.Clear(); // Don't let the create free the child's shape - // PhysicsScene.Shapes.CreateGeomNonSpecial(true, cPrim, null); - PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); - BulletShape newShape = cPrim.PhysShape; - cPrim.PhysShape = saveShape; - BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, newShape.ptr, lci.OffsetPos , lci.OffsetRot); - } - else - { - // For the shared shapes (meshes and hulls), just use the shape in the child. - // The reference count added here will be decremented when the compound shape - // is destroyed in BSShapeCollection (the child shapes are looped over and dereferenced). - if (PhysicsScene.Shapes.ReferenceShape(cPrim.PhysShape)) + if (cPrim.PhysShape.isNativeShape) + { + // A native shape is turning into a hull collision shape because native + // shapes are not shared so we have to hullify it so it will be tracked + // and freed at the correct time. This also solves the scaling problem + // (native shapes scaled but hull/meshes are assumed to not be). + // TODO: decide of the native shape can just be used in the compound shape. + // Use call to CreateGeomNonSpecial(). + BulletShape saveShape = cPrim.PhysShape; + cPrim.PhysShape.Clear(); // Don't let the create free the child's shape + // PhysicsScene.Shapes.CreateGeomNonSpecial(true, cPrim, null); + PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); + BulletShape newShape = cPrim.PhysShape; + cPrim.PhysShape = saveShape; + BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, newShape.ptr, lci.OffsetPos, lci.OffsetRot); + } + else { - PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", - LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); + // For the shared shapes (meshes and hulls), just use the shape in the child. + // The reference count added here will be decremented when the compound shape + // is destroyed in BSShapeCollection (the child shapes are looped over and dereferenced). + if (PhysicsScene.Shapes.ReferenceShape(cPrim.PhysShape)) + { + PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", + LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); + } + BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, cPrim.PhysShape.ptr, lci.OffsetPos, lci.OffsetRot); } - BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, cPrim.PhysShape.ptr, lci.OffsetPos , lci.OffsetRot); } - } - - return false; // 'false' says to move onto the next child in the list - }); + return false; // 'false' says to move onto the next child in the list + }); - // With all of the linkset packed into the root prim, it has the mass of everyone. - float linksetMass = LinksetMass; - LinksetRoot.UpdatePhysicalMassProperties(linksetMass); + // With all of the linkset packed into the root prim, it has the mass of everyone. + float linksetMass = LinksetMass; + LinksetRoot.UpdatePhysicalMassProperties(linksetMass); + } + finally + { + Rebuilding = false; + } BulletSimAPI.RecalculateCompoundShapeLocalAabb2(LinksetRoot.PhysShape.ptr); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index c855fda..732c084 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -36,9 +36,8 @@ public sealed class BSLinksetConstraints : BSLinkset { // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]"; - public BSLinksetConstraints(BSScene scene, BSPhysObject parent) + public BSLinksetConstraints(BSScene scene, BSPhysObject parent) : base(scene, parent) { - base.Initialize(scene, parent); } // When physical properties are changed the linkset needs to recalculate -- cgit v1.1 From 469c6c000a85dafc3704b2ff053949e8588506f8 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 13 Dec 2012 16:31:28 -0800 Subject: Return the last set targetVelocity rather than the current velocity as the default action made available in PhysicsActor.TargetVelocity. Doesn't change any physics operation but makes DSG work better as the targetVelocity value does not keep moving around. --- OpenSim/Region/Physics/Manager/PhysicsActor.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index 34413e5..d119791 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs @@ -250,17 +250,20 @@ namespace OpenSim.Region.Physics.Manager public abstract Vector3 CenterOfMass { get; } /// - /// Velocity of this actor. + /// The desired velocity of this actor. /// /// /// Setting this provides a target velocity for physics scene updates. - /// Getting this returns the velocity calculated by physics scene updates, using factors such as target velocity, - /// time to accelerate and collisions. + /// Getting this returns the last set target. Fetch Velocity to get the current velocity. /// + protected Vector3 m_targetVelocity; public virtual Vector3 TargetVelocity { - get { return Velocity; } - set { Velocity = value; } + get { return m_targetVelocity; } + set { + m_targetVelocity = value; + Velocity = m_targetVelocity; + } } public abstract Vector3 Velocity { get; set; } -- cgit v1.1 From 664dad53dded9537e75893ca9fc6a42c93a95ded Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 13 Dec 2012 23:08:01 -0800 Subject: BulletSim: Add more to the TODO list. Clean up and improve some comments. --- OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs | 12 ++++-------- OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | 7 +++++-- 2 files changed, 9 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs index 524a1d0..662177f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs @@ -98,18 +98,14 @@ public struct BulletBody public struct BulletShape { - public BulletShape(IntPtr xx) + public BulletShape(IntPtr xx) : this(xx, BSPhysicsShapeType.SHAPE_UNKNOWN) { - ptr = xx; - type=BSPhysicsShapeType.SHAPE_UNKNOWN; - shapeKey = (System.UInt64)FixedShapeKey.KEY_NONE; - isNativeShape = false; } public BulletShape(IntPtr xx, BSPhysicsShapeType typ) { ptr = xx; type = typ; - shapeKey = 0; + shapeKey = (System.UInt64)FixedShapeKey.KEY_NONE; isNativeShape = false; } public IntPtr ptr; @@ -192,7 +188,7 @@ public enum CollisionType Static, Dynamic, VolumeDetect, - // Linkset, // A linkset proper should be either Static or Dynamic + // Linkset, // A linkset should be either Static or Dynamic LinksetChild, Unknown }; @@ -211,7 +207,7 @@ public struct CollisionTypeFilterGroup public uint mask; }; - /* + /* NOTE: old definitions kept for reference. Delete when things are working. // The collsion filters and masked are defined in one place -- don't want them scattered AvatarGroup = BCharacterGroup, AvatarMask = BAllGroup, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 11c1387..7d6ace8 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -19,6 +19,7 @@ Some vehicles should not be able to turn if no speed or off ground. Neb car jiggling left and right Happens on terrain and any other mesh object. Flat cubes are much smoother. This has been reduced but not eliminated. +Light cycle falling over when driving For limitMotorUp, use raycast down to find if vehicle is in the air. Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE. Verify that angular motion specified around Z moves in the vehicle coordinates. @@ -121,6 +122,9 @@ Remove unused fields from ShapeData (not used in API2) Breakout code for mesh/hull/compound/native into separate BSShape* classes Standardize access to building and reference code. The skeleton classes are in the sources but are not complete or linked in. +Make BSBody and BSShape real classes to centralize creation/changin/destruction + Convert state and parameter calls from BulletSimAPI direct calls to + calls on BSBody and BSShape Generalize Dynamics and PID with standardized motors. Generalize Linkset and vehicles into PropertyManagers Methods for Refresh, RemoveBodyDependencies, RestoreBodyDependencies @@ -132,7 +136,7 @@ Implement linkset by setting position of children when root updated. (LinksetMan Linkset implementation using manual prim movement. LinkablePrim class? Would that simplify/centralize the linkset logic? BSScene.UpdateParameterSet() is broken. How to set params on objects? -Remove HeightmapInfo from terrain specification. +Remove HeightmapInfo from terrain specification Since C++ code does not need terrain height, this structure et al are not needed. Add floating motor for BS_FLOATS_ON_WATER so prim and avatar will bob at the water level. BSPrim.PositionSanityCheck(). @@ -164,7 +168,6 @@ Do prim hash codes work for sculpties and meshes? (Resolution: yes) Linkset implementation using compound shapes. (Resolution: implemented LinksetCompound) Compound shapes will need the LocalID in the shapes and collision processing to get it from there. -Light cycle falling over when driving (Resolution: implemented VerticalAttractor) Light cycle not banking (Resolution: It doesn't. Banking is roll adding yaw.) Package Bullet source mods for Bullet internal stats output (Resolution: move code into WorldData.h rather than relying on patches) -- cgit v1.1 From 750ad2d3afd6fcf32a9e04794d860e117559a78f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 14 Dec 2012 22:15:40 +0000 Subject: Fix issue where calling llVolumeDetect(FALSE) would not remove phantom flag, causing subsequent issues if physics was re-enabled. Added regression tests Addresses http://opensimulator.org/mantis/view.php?id=6365 --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 3 +- .../Scenes/Tests/SceneObjectStatusTests.cs | 41 +++++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index f79ac96..ff67d6d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3993,13 +3993,14 @@ namespace OpenSim.Region.Framework.Scenes VolumeDetectActive = true; } } - else + else if (SetVD != wasVD) { // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like // (mumbles, well, at least if you have infinte CPU powers :-)) if (pa != null) pa.SetVolumeDetect(0); + RemFlag(PrimFlags.Phantom); VolumeDetectActive = false; } diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs index 093cbd2..8eb3191 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs @@ -78,6 +78,26 @@ namespace OpenSim.Region.Framework.Scenes.Tests } [Test] + public void TestSetNonPhysicsVolumeDetectSinglePrim() + { + TestHelpers.InMethod(); + + m_scene.AddSceneObject(m_so1); + + SceneObjectPart rootPart = m_so1.RootPart; + Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); + + m_so1.ScriptSetVolumeDetect(true); + +// Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags); + Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Phantom)); + + m_so1.ScriptSetVolumeDetect(false); + + Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); + } + + [Test] public void TestSetPhysicsSinglePrim() { TestHelpers.InMethod(); @@ -89,13 +109,32 @@ namespace OpenSim.Region.Framework.Scenes.Tests m_so1.ScriptSetPhysicsStatus(true); -// Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags); Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Physics)); m_so1.ScriptSetPhysicsStatus(false); Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); } + + [Test] + public void TestSetPhysicsVolumeDetectSinglePrim() + { + TestHelpers.InMethod(); + + m_scene.AddSceneObject(m_so1); + + SceneObjectPart rootPart = m_so1.RootPart; + Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); + + m_so1.ScriptSetPhysicsStatus(true); + m_so1.ScriptSetVolumeDetect(true); + + Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Phantom | PrimFlags.Physics)); + + m_so1.ScriptSetVolumeDetect(false); + + Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Physics)); + } [Test] public void TestSetPhysicsLinkset() -- cgit v1.1 From 56ec177b3b5b8f5b30d1024cfe6fbf8c59e36c6f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 14 Dec 2012 23:42:23 +0000 Subject: minor: Add commented out log lines to ScenePresenceAnimator for future debug use (such as logging anim pack contents sent to clients) --- .../Framework/Scenes/Animation/ScenePresenceAnimator.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index bb33f07..5b16b67 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -26,9 +26,10 @@ */ using System; -using System.Threading; using System.Collections.Generic; +using System.Linq; using System.Reflection; +using System.Threading; using log4net; using OpenMetaverse; using OpenSim.Framework; @@ -113,6 +114,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation if (m_scenePresence.IsChildAgent) return; +// m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Removing animation {0} for {1}", animID, m_scenePresence.Name); + if (m_animations.Remove(animID)) SendAnimPack(); } @@ -503,6 +506,12 @@ namespace OpenSim.Region.Framework.Scenes.Animation if (m_scenePresence.IsChildAgent) return; +// m_log.DebugFormat( +// "[SCENE PRESENCE ANIMATOR]: Sending anim pack with animations '{0}', sequence '{1}', uuids '{2}'", +// string.Join(",", Array.ConvertAll(animations, a => a.ToString())), +// string.Join(",", Array.ConvertAll(seqs, s => s.ToString())), +// string.Join(",", Array.ConvertAll(objectIDs, o => o.ToString()))); + m_scenePresence.Scene.ForEachClient( delegate(IClientAPI client) { -- cgit v1.1 From 494e6a5f114372ca417607ff6af3c6d5a3aaae9e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 15 Dec 2012 00:30:17 +0000 Subject: minor: If the physics module tells us that an object has gone out of bounds, more helpfully log the name, id, position and region of that object. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index ff67d6d..af7fae3 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2266,11 +2266,14 @@ namespace OpenSim.Region.Framework.Scenes public void PhysicsOutOfBounds(Vector3 pos) { - m_log.Error("[PHYSICS]: Physical Object went out of bounds."); + // Note: This is only being called on the root prim at this time. + + m_log.ErrorFormat( + "[SCENE OBJECT PART]: Physical object {0}, localID {1} went out of bounds at {2} in {3}. Stopping at {4} and making non-physical.", + Name, LocalId, pos, ParentGroup.Scene.Name, AbsolutePosition); RemFlag(PrimFlags.Physics); DoPhysicsPropertyUpdate(false, true); - //ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); } public void PhysicsRequestingTerseUpdate() -- cgit v1.1 From 1a262bdde75ab87867b8cf96f12852d219a1b719 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 15 Dec 2012 00:45:27 +0000 Subject: Make WebStatsModule properly handle scenes added or removed after initial startup. This may have been the cause of the DivByZero in http://opensimulator.org/mantis/view.php?id=6460 --- OpenSim/Region/UserStatistics/WebStatsModule.cs | 45 +++++++++++++++++-------- 1 file changed, 31 insertions(+), 14 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs index b08233c..64cb577 100644 --- a/OpenSim/Region/UserStatistics/WebStatsModule.cs +++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs @@ -94,8 +94,6 @@ namespace OpenSim.Region.UserStatistics if (!enabled) return; - AddEventHandlers(); - if (Util.IsWindows()) Util.LoadArchSpecificWindowsDll("sqlite3.dll"); @@ -143,10 +141,14 @@ namespace OpenSim.Region.UserStatistics lock (m_scenes) { m_scenes.Add(scene); - if (m_simstatsCounters.ContainsKey(scene.RegionInfo.RegionID)) - m_simstatsCounters.Remove(scene.RegionInfo.RegionID); + updateLogMod = m_scenes.Count * 2; m_simstatsCounters.Add(scene.RegionInfo.RegionID, new USimStatsData(scene.RegionInfo.RegionID)); + + scene.EventManager.OnRegisterCaps += OnRegisterCaps; + scene.EventManager.OnDeregisterCaps += OnDeRegisterCaps; + scene.EventManager.OnClientClosed += OnClientClosed; + scene.EventManager.OnMakeRootAgent += OnMakeRootAgent; scene.StatsReporter.OnSendStatsResult += ReceiveClassicSimStatsPacket; } } @@ -157,6 +159,15 @@ namespace OpenSim.Region.UserStatistics public void RemoveRegion(Scene scene) { + if (!enabled) + return; + + lock (m_scenes) + { + m_scenes.Remove(scene); + updateLogMod = m_scenes.Count * 2; + m_simstatsCounters.Remove(scene.RegionInfo.RegionID); + } } public virtual void Close() @@ -187,9 +198,7 @@ namespace OpenSim.Region.UserStatistics private void ReceiveClassicSimStatsPacket(SimStats stats) { if (!enabled) - { return; - } try { @@ -198,17 +207,25 @@ namespace OpenSim.Region.UserStatistics if (concurrencyCounter > 0 || System.Environment.TickCount - lastHit > 30000) return; - if ((updateLogCounter++ % updateLogMod) == 0) + // We will conduct this under lock so that fields such as updateLogCounter do not potentially get + // confused if a scene is removed. + // XXX: Possibly the scope of this lock could be reduced though it's not critical. + lock (m_scenes) { - m_loglines = readLogLines(10); - if (updateLogCounter > 10000) updateLogCounter = 1; - } + if (updateLogMod != 0 && updateLogCounter++ % updateLogMod == 0) + { + m_loglines = readLogLines(10); - USimStatsData ss = m_simstatsCounters[stats.RegionUUID]; + if (updateLogCounter > 10000) + updateLogCounter = 1; + } - if ((++ss.StatsCounter % updateStatsMod) == 0) - { - ss.ConsumeSimStats(stats); + USimStatsData ss = m_simstatsCounters[stats.RegionUUID]; + + if ((++ss.StatsCounter % updateStatsMod) == 0) + { + ss.ConsumeSimStats(stats); + } } } catch (KeyNotFoundException) -- cgit v1.1 From ace1f1e9314d2e5b3cf45426225ca485649bbf96 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 14 Dec 2012 17:03:59 -0800 Subject: BulletSim: rip out old code for linkset child position fetching. BulletSim doesn't need to do that bookkeeping because SOG/SOP already does it. --- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 8 +----- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 24 ++++++++---------- .../Physics/BulletSPlugin/BSLinksetConstraints.cs | 12 --------- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 29 +++++++++++++--------- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 3 +++ 5 files changed, 31 insertions(+), 45 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index ce0fbe6..2486be5 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -38,6 +38,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Each type of linkset will define the information needed for its type. public abstract class BSLinksetInfo { + public virtual void Clear() { } } public abstract class BSLinkset @@ -95,13 +96,6 @@ public abstract class BSLinkset return BSPhysicsShapeType.SHAPE_UNKNOWN; } - // Linksets move around the children so the linkset might need to compute the child position - public virtual OMV.Vector3 Position(BSPhysObject member) - { return member.RawPosition; } - public virtual OMV.Quaternion Orientation(BSPhysObject member) - { return member.RawOrientation; } - // TODO: does this need to be done for Velocity and RotationalVelocityy? - // We keep the prim's mass in the linkset structure since it could be dependent on other prims protected float m_mass; public float LinksetMass diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 2189468..8359607 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -45,6 +45,11 @@ sealed class BSLinksetCompoundInfo : BSLinksetInfo OffsetPos = p; OffsetRot = r; } + public override void Clear() + { + OffsetPos = OMV.Vector3.Zero; + OffsetRot = OMV.Quaternion.Identity; + } public override string ToString() { StringBuilder buff = new StringBuilder(); @@ -82,8 +87,11 @@ public sealed class BSLinksetCompound : BSLinkset // its internal properties. public override void Refresh(BSPhysObject requestor) { - // External request for Refresh (from BSPrim) doesn't need to do anything - // InternalRefresh(requestor); + if (!IsRoot(requestor)) + { + } + // Something changed so do the rebuilding thing + InternalRefresh(requestor); } // Schedule a refresh to happen after all the other taint processing. @@ -170,18 +178,6 @@ public sealed class BSLinksetCompound : BSLinkset // Nothing to do for compound linksets on property updates } - // The children move around in relationship to the root. - // Just grab the current values of wherever it is right now. - public override OMV.Vector3 Position(BSPhysObject member) - { - return BulletSimAPI.GetPosition2(member.PhysBody.ptr); - } - - public override OMV.Quaternion Orientation(BSPhysObject member) - { - return BulletSimAPI.GetOrientation2(member.PhysBody.ptr); - } - // Routine called when rebuilding the body of some member of the linkset. // Since we don't keep in world relationships, do nothing unless it's a child changing. // Returns 'true' of something was actually removed and would need restoring diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index 732c084..7076ab4 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -83,18 +83,6 @@ public sealed class BSLinksetConstraints : BSLinkset // Nothing to do for constraints on property updates } - // The children of the linkset are moved around by the constraints. - // Just grab the current values of wherever it is right now. - public override OMV.Vector3 Position(BSPhysObject member) - { - return BulletSimAPI.GetPosition2(member.PhysBody.ptr); - } - - public override OMV.Quaternion Orientation(BSPhysObject member) - { - return BulletSimAPI.GetOrientation2(member.PhysBody.ptr); - } - // Routine called when rebuilding the body of some member of the linkset. // Destroy all the constraints have have been made to root and set // up to rebuild the constraints before the next simulation step. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index c9c9c2c..53be2e3 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -279,9 +279,12 @@ public sealed class BSPrim : BSPhysObject } public override OMV.Vector3 Position { get { + /* NOTE: this refetch is not necessary. The simulator knows about linkset children + * and does not fetch this position info for children. Thus this is commented out. // child prims move around based on their parent. Need to get the latest location if (!Linkset.IsRoot(this)) - _position = Linkset.Position(this); + _position = Linkset.PositionGet(this); + */ // don't do the GetObjectPosition for root elements because this function is called a zillion times. // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr); @@ -289,21 +292,18 @@ public sealed class BSPrim : BSPhysObject } set { // If the position must be forced into the physics engine, use ForcePosition. + // All positions are given in world positions. if (_position == value) { + DetailLog("{0},BSPrim.setPosition,taint,positionNotChanging,pos={1},orient={2}", LocalID, _position, _orientation); return; } _position = value; - // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint? PositionSanityCheck(false); PhysicsScene.TaintedObject("BSPrim.setPosition", delegate() { - // DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); - if (PhysBody.HasPhysicalBody) - { - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); - ActivateIfPhysical(false); - } + DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); + ForcePosition = _position; }); } } @@ -314,9 +314,11 @@ public sealed class BSPrim : BSPhysObject } set { _position = value; - // PositionSanityCheck(); // Don't do this! Causes a loop and caller should know better. - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); - ActivateIfPhysical(false); + if (PhysBody.HasPhysicalBody) + { + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + ActivateIfPhysical(false); + } } } @@ -551,11 +553,14 @@ public sealed class BSPrim : BSPhysObject } public override OMV.Quaternion Orientation { get { + /* NOTE: this refetch is not necessary. The simulator knows about linkset children + * and does not fetch this position info for children. Thus this is commented out. // Children move around because tied to parent. Get a fresh value. if (!Linkset.IsRoot(this)) { - _orientation = Linkset.Orientation(this); + _orientation = Linkset.OrientationGet(this); } + */ return _orientation; } set { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 7d6ace8..9b89f0b 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -37,6 +37,7 @@ Border crossing with linked vehicle causes crash BULLETSIM TODO LIST: ================================================= +Revisit CollisionMargin. Builders notice the 0.04 spacing between prims. Avatar height off after unsitting (floats off ground) Editting appearance then moving restores. Must not be initializing height when recreating capsule after unsit. @@ -64,6 +65,8 @@ Implement ShapeCollection.Dispose() Implement water as a plain so raycasting and collisions can happen with same. Add osGetPhysicsEngineName() so scripters can tell whether BulletSim or ODE Also osGetPhysicsEngineVerion() maybe. +Linkset.Position and Linkset.Orientation requre rewrite to properly return + child position. LinksetConstraint acts like it's at taint time!! LINKSETS ====================================================== -- cgit v1.1 From f3b1efd889e2e87f89c8e8da6a08089596c878f6 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 15 Dec 2012 11:31:26 -0800 Subject: BulletSim: remove some errors on shutdown by moving terrain destruction until after physical object destruction. TerrainManager also made disposable and that feature used. --- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 9 +++++++-- OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs | 10 +++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index cf5bb57..ac99777 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -349,8 +349,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // make sure no stepping happens while we're deleting stuff m_initialized = false; - TerrainManager.ReleaseGroundPlaneAndTerrain(); - foreach (KeyValuePair kvp in PhysObjects) { kvp.Value.Destroy(); @@ -370,6 +368,13 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters Shapes = null; } + if (TerrainManager != null) + { + TerrainManager.ReleaseGroundPlaneAndTerrain(); + TerrainManager.Dispose(); + TerrainManager = null; + } + // Anything left in the unmanaged code should be cleaned out BulletSimAPI.Shutdown2(World.ptr); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index 5dbd8ce..c68fd69 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -67,7 +67,7 @@ public abstract class BSTerrainPhys : IDisposable } // ========================================================================================== -public sealed class BSTerrainManager +public sealed class BSTerrainManager : IDisposable { static string LogHeader = "[BULLETSIM TERRAIN MANAGER]"; @@ -122,6 +122,11 @@ public sealed class BSTerrainManager MegaRegionParentPhysicsScene = null; } + public void Dispose() + { + ReleaseGroundPlaneAndTerrain(); + } + // Create the initial instance of terrain and the underlying ground plane. // This is called from the initialization routine so we presume it is // safe to call Bullet in real time. We hope no one is moving prims around yet. @@ -366,6 +371,9 @@ public sealed class BSTerrainManager { PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}", LogHeader, PhysicsScene.RegionName, tX, tY); + DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXYZ,terrainNotFound,loc={1},base={2}", + BSScene.DetailLogZero, loc, terrainBaseXYZ); + Util.PrintCallStack(); // DEBUG DEBUG DEBUG } } lastHeight = ret; -- cgit v1.1 From 8a95953bb7c35ec1f2b6d97520c56178778ef729 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 16 Dec 2012 21:12:01 -0800 Subject: BulletSim: experimentally remove unit displacement from prim border crossing test. This seems to cause border crossing to be sensed either a little early or a little late depending on which directin the object is moving. If border crossings become totally borked or someone remembers why this was displacement was done, revert this change. --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 1fa6a75..64a5811 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -430,8 +430,19 @@ namespace OpenSim.Region.Framework.Scenes if (Scene != null) { - if ((Scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) || Scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W) - || Scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) || Scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S)) + if ( + // (Scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) + // || Scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W) + // || Scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) + // || Scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S)) + // Experimental change for better border crossings. + // The commented out original lines above would, it seems, trigger + // a border crossing a little early or late depending on which + // direction the object was moving. + (Scene.TestBorderCross(val, Cardinals.E) + || Scene.TestBorderCross(val, Cardinals.W) + || Scene.TestBorderCross(val, Cardinals.N) + || Scene.TestBorderCross(val, Cardinals.S)) && !IsAttachmentCheckFull() && (!Scene.LoadingPrims)) { m_scene.CrossPrimGroupIntoNewRegion(val, this, true); -- cgit v1.1 From 4cbc5082ffc5aa4818471cedf906c78038a7b0f9 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 16 Dec 2012 21:14:48 -0800 Subject: BulletSim: refactor to combine common terrain height testing code. Add function to test if a position is over known terrain. --- .../Physics/BulletSPlugin/BSTerrainManager.cs | 86 ++++++++++++---------- 1 file changed, 48 insertions(+), 38 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index c68fd69..3428b9c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -332,6 +332,13 @@ public sealed class BSTerrainManager : IDisposable return newTerrainPhys; } + // Return 'true' of this position is somewhere in known physical terrain space + public bool IsWithinKnownTerrain(Vector3 pos) + { + Vector3 terrainBaseXYZ; + BSTerrainPhys physTerrain; + return GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ); + } // Given an X and Y, find the height of the terrain. // Since we could be handling multiple terrains for a mega-region, @@ -342,13 +349,13 @@ public sealed class BSTerrainManager : IDisposable private float lastHeightTX = 999999f; private float lastHeightTY = 999999f; private float lastHeight = HEIGHT_INITIAL_LASTHEIGHT; - public float GetTerrainHeightAtXYZ(Vector3 loc) + public float GetTerrainHeightAtXYZ(Vector3 pos) { - float tX = loc.X; - float tY = loc.Y; + float tX = pos.X; + float tY = pos.Y; // You'd be surprized at the number of times this routine is called // with the same parameters as last time. - if (!m_terrainModified && lastHeightTX == tX && lastHeightTY == tY) + if (!m_terrainModified && (lastHeightTX == tX) && (lastHeightTY == tY)) return lastHeight; m_terrainModified = false; @@ -356,26 +363,20 @@ public sealed class BSTerrainManager : IDisposable lastHeightTY = tY; float ret = HEIGHT_GETHEIGHT_RET; - int offsetX = ((int)(tX / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X; - int offsetY = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y; - Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f); - - lock (m_terrains) + Vector3 terrainBaseXYZ; + BSTerrainPhys physTerrain; + if (GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ)) { - BSTerrainPhys physTerrain; - if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain)) - { - ret = physTerrain.GetTerrainHeightAtXYZ(loc - terrainBaseXYZ); - } - else - { - PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}", - LogHeader, PhysicsScene.RegionName, tX, tY); - DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXYZ,terrainNotFound,loc={1},base={2}", - BSScene.DetailLogZero, loc, terrainBaseXYZ); - Util.PrintCallStack(); // DEBUG DEBUG DEBUG - } + ret = physTerrain.GetTerrainHeightAtXYZ(pos - terrainBaseXYZ); } + else + { + PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}", + LogHeader, PhysicsScene.RegionName, tX, tY); + DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXYZ,terrainNotFound,pos={1},base={2}", + BSScene.DetailLogZero, pos, terrainBaseXYZ); + } + lastHeight = ret; return ret; } @@ -384,27 +385,36 @@ public sealed class BSTerrainManager : IDisposable { float ret = WATER_HEIGHT_GETHEIGHT_RET; - float tX = pos.X; - float tY = pos.Y; + Vector3 terrainBaseXYZ; + BSTerrainPhys physTerrain; + if (GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ)) + { + ret = physTerrain.GetWaterLevelAtXYZ(pos); + } + else + { + PhysicsScene.Logger.ErrorFormat("{0} GetWaterHeightAtXY: terrain not found: pos={1}, terrainBase={2}, height={3}", + LogHeader, PhysicsScene.RegionName, pos, terrainBaseXYZ, ret); + } + return ret; + } - Vector3 terrainBaseXYZ = Vector3.Zero; - terrainBaseXYZ.X = ((int)(tX / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X; - terrainBaseXYZ.Y = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y; + // Given an address, return 'true' of there is a description of that terrain and output + // the descriptor class and the 'base' fo the addresses therein. + private bool GetTerrainPhysicalAtXYZ(Vector3 pos, out BSTerrainPhys outPhysTerrain, out Vector3 outTerrainBase) + { + int offsetX = ((int)(pos.X / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X; + int offsetY = ((int)(pos.Y / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y; + Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f); + BSTerrainPhys physTerrain = null; lock (m_terrains) { - BSTerrainPhys physTerrain; - if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain)) - { - ret = physTerrain.GetWaterLevelAtXYZ(pos); - } - else - { - PhysicsScene.Logger.ErrorFormat("{0} GetWaterHeightAtXY: terrain not found: region={1}, x={2}, y={3}", - LogHeader, PhysicsScene.RegionName, tX, tY); - } + m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain); } - return ret; + outTerrainBase = terrainBaseXYZ; + outPhysTerrain = physTerrain; + return (physTerrain != null); } // Although no one seems to check this, I do support combining. -- cgit v1.1 From 7ed860d3ac8307b2f404fea1c40471ee488cf70e Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 16 Dec 2012 21:15:49 -0800 Subject: BulletSim: add check for border crossing in character position sanity check. --- OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 0defb24..4dd6264 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -311,6 +311,15 @@ public sealed class BSCharacter : BSPhysObject { bool ret = false; + // TODO: check for out of bounds + if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position)) + { + // The character is out of the known/simulated area. + // Upper levels of code will handle the transition to other areas so, for + // the time, we just ignore the position. + return ret; + } + // If below the ground, move the avatar up float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); if (Position.Z < terrainHeight) @@ -329,7 +338,6 @@ public sealed class BSCharacter : BSPhysObject } } - // TODO: check for out of bounds return ret; } @@ -700,7 +708,7 @@ public sealed class BSCharacter : BSPhysObject } // Tell the linkset about value changes - Linkset.UpdateProperties(this); + Linkset.UpdateProperties(this, true); // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. // base.RequestPhysicsterseUpdate(); -- cgit v1.1 From 3f2aaffd4d32ec7569cc2e5faae76c5faa9e9da4 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 16 Dec 2012 21:16:40 -0800 Subject: BulletSim: add even more to the TODO list. --- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 31 +++++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 9b89f0b..31dd790 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -1,3 +1,16 @@ +CURRENT PRIORITIES +================================================= +Eliminate all crashes (DONEish) + Editing/deleting physical linkset (DONE) + Border crossing of physical linkset (DONE) +Enable vehicle border crossings (at least as poorly as ODE) + Avatar created in previous region and not new region when crossing border + Vehicle recreated in new sim at small Z value (offset from root value?) +Calibrate turning radius +limitMotorUp calibration (more down?) +study PID motors (include 'efficiency' implementation + Add to avatar movement + CRASHES ================================================= 20121129.1411: editting/moving phys object across region boundries causes crash @@ -11,16 +24,18 @@ CRASHES VEHICLES TODO LIST: ================================================= +Border crossing with linked vehicle causes crash Neb vehicle taking > 25ms of physics time!! Vehicles (Move smoothly) Add vehicle collisions so IsColliding is properly reported. Needed for banking, limitMotorUp, movementLimiting, ... Some vehicles should not be able to turn if no speed or off ground. +Cannot edit/move a vehicle being ridden: it jumps back to the origional position. Neb car jiggling left and right Happens on terrain and any other mesh object. Flat cubes are much smoother. This has been reduced but not eliminated. Light cycle falling over when driving -For limitMotorUp, use raycast down to find if vehicle is in the air. +Implement referenceFrame for all the motion routines. Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE. Verify that angular motion specified around Z moves in the vehicle coordinates. Verify llGetVel() is returning a smooth and good value for vehicle movement. @@ -31,9 +46,9 @@ Should vehicle angular/linear movement friction happen after all the components After getting off a vehicle, the root prim is phantom (can be walked through) Need to force a position update for the root prim after compound shape destruction Linkset explosion after three "rides" on Nebadon lite vehicle (LinksetConstraint) -Implement referenceFrame for all the motion routines. -Cannot edit/move a vehicle being ridden: it jumps back to the origional position. -Border crossing with linked vehicle causes crash +For limitMotorUp, use raycast down to find if vehicle is in the air. +Remove vehicle angular velocity zeroing in BSPrim.UpdateProperties(). + A kludge that isn't fixing the real problem of Bullet adding extra motion. BULLETSIM TODO LIST: ================================================= @@ -72,6 +87,9 @@ LINKSETS ====================================================== Linksets should allow collisions to individual children Add LocalID to children shapes in LinksetCompound and create events for individuals +LinksetCompound: when one of the children changes orientation (like tires + turning on a vehicle, the whole compound object is rebuilt. Optimize this + so orientation/position of individual children can change without a rebuild. Verify/think through scripts in children of linksets. What do they reference and return when getting position, velocity, ... Confirm constraint linksets still work after making all the changes for compound linksets. @@ -143,6 +161,11 @@ Remove HeightmapInfo from terrain specification Since C++ code does not need terrain height, this structure et al are not needed. Add floating motor for BS_FLOATS_ON_WATER so prim and avatar will bob at the water level. BSPrim.PositionSanityCheck(). +Should taints check for existance or activeness of target? + When destroying linksets/etc, taints can be generated for objects that are + actually gone when the taint happens. Crashes don't happen because the taint closure + keeps the object from being freed, but that is just an accident. + Possibly have and 'active' flag that is checked by the taint processor? THREADING ================================================= -- cgit v1.1 From 2b8efa24dd816fda23fe3aed5822af1d50febf5d Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 16 Dec 2012 21:18:32 -0800 Subject: BulletSim: add parameter to UpdateProperties call into the linkset so changes from the physics engine can be differentiated from changes made by the user. This eliminates a linkset rebuild loop. Also add logic to not rebuild or freak out when the object/linkset crosses a terrain boundry. --- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 3 +- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 48 +++++++++++++--------- .../Physics/BulletSPlugin/BSLinksetConstraints.cs | 2 +- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 9 ++-- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 29 +++++++++---- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 10 +++-- 6 files changed, 65 insertions(+), 36 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 2486be5..2017fa5 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -252,8 +252,9 @@ public abstract class BSLinkset // Called when a parameter update comes from the physics engine for any object // of the linkset is received. + // Passed flag is update came from physics engine (true) or the user (false). // Called at taint-time!! - public abstract void UpdateProperties(BSPhysObject physObject); + public abstract void UpdateProperties(BSPhysObject physObject, bool physicalUpdate); // Routine used when rebuilding the body of the root of the linkset // Destroy all the constraints have have been made to root. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 8359607..4d4f712 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -28,6 +28,8 @@ using System; using System.Collections.Generic; using System.Text; +using OpenSim.Framework; + using OMV = OpenMetaverse; namespace OpenSim.Region.Physics.BulletSPlugin @@ -87,25 +89,22 @@ public sealed class BSLinksetCompound : BSLinkset // its internal properties. public override void Refresh(BSPhysObject requestor) { - if (!IsRoot(requestor)) - { - } // Something changed so do the rebuilding thing - InternalRefresh(requestor); + // ScheduleRebuild(); } // Schedule a refresh to happen after all the other taint processing. - private void InternalRefresh(BSPhysObject requestor) + private void ScheduleRebuild() { - DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,requestor={1},rebuilding={2}", - LinksetRoot.LocalID, requestor.LocalID, Rebuilding); + DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,rebuilding={1}", + LinksetRoot.LocalID, Rebuilding); // When rebuilding, it is possible to set properties that would normally require a rebuild. // If already rebuilding, don't request another rebuild. if (!Rebuilding) { - PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", requestor.LocalID, delegate() + PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", LinksetRoot.LocalID, delegate() { - if (IsRoot(requestor) && HasAnyChildren) + if (HasAnyChildren) RecomputeLinksetCompound(); }); } @@ -125,8 +124,7 @@ public sealed class BSLinksetCompound : BSLinkset { // The root is going dynamic. Make sure mass is properly set. m_mass = ComputeLinksetMass(); - if (HasAnyChildren) - InternalRefresh(LinksetRoot); + ScheduleRebuild(); } else { @@ -155,8 +153,7 @@ public sealed class BSLinksetCompound : BSLinkset DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child)); if (IsRoot(child)) { - if (HasAnyChildren) - InternalRefresh(LinksetRoot); + ScheduleRebuild(); } else { @@ -172,10 +169,21 @@ public sealed class BSLinksetCompound : BSLinkset return ret; } - // Called at taint-time!! - public override void UpdateProperties(BSPhysObject updated) + public override void UpdateProperties(BSPhysObject updated, bool physicalUpdate) { - // Nothing to do for compound linksets on property updates + // The user moving a child around requires the rebuilding of the linkset compound shape + // One problem is this happens when a border is crossed -- the simulator implementation + // is to store the position into the group which causes the move of the object + // but it also means all the child positions get updated. + // What would cause an unnecessary rebuild so we make sure the linkset is in a + // region before bothering to do a rebuild. + if (!IsRoot(updated) + && !physicalUpdate + && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition)) + { + updated.LinksetInfo = null; + ScheduleRebuild(); + } } // Routine called when rebuilding the body of some member of the linkset. @@ -257,8 +265,8 @@ public sealed class BSLinksetCompound : BSLinkset DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); - // Cause constraints and assorted properties to be recomputed before the next simulation step. - InternalRefresh(LinksetRoot); + // Rebuild the compound shape with the new child shape included + ScheduleRebuild(); } return; } @@ -285,8 +293,8 @@ public sealed class BSLinksetCompound : BSLinkset } else { - // Schedule a rebuild of the linkset before the next simulation tick. - InternalRefresh(LinksetRoot); + // Rebuild the compound shape with the child removed + ScheduleRebuild(); } } return; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index 7076ab4..8c36c31 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -78,7 +78,7 @@ public sealed class BSLinksetConstraints : BSLinkset } // Called at taint-time!! - public override void UpdateProperties(BSPhysObject updated) + public override void UpdateProperties(BSPhysObject updated, bool inTaintTime) { // Nothing to do for constraints on property updates } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 6539b43..92a5f2f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -214,7 +214,7 @@ public abstract class BSPhysObject : PhysicsActor { bool ret = true; // If the 'no collision' call, force it to happen right now so quick collision_end - bool force = CollisionCollection.Count == 0; + bool force = (CollisionCollection.Count == 0); // throttle the collisions to the number of milliseconds specified in the subscription if (force || (PhysicsScene.SimulationNowTime >= NextCollisionOkTime)) @@ -232,8 +232,10 @@ public abstract class BSPhysObject : PhysicsActor // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count); base.SendCollisionUpdate(CollisionCollection); - // The collisionCollection structure is passed around in the simulator. + // The CollisionCollection instance is passed around in the simulator. // Make sure we don't have a handle to that one and that a new one is used for next time. + // This fixes an interesting 'gotcha'. If we call CollisionCollection.Clear() here, + // a race condition is created for the other users of this instance. CollisionCollection = new CollisionEventUpdate(); } return ret; @@ -251,7 +253,8 @@ public abstract class BSPhysObject : PhysicsActor PhysicsScene.TaintedObject(TypeName+".SubscribeEvents", delegate() { - CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + if (PhysBody.HasPhysicalBody) + CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); }); } else diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 53be2e3..758d92b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -300,6 +300,10 @@ public sealed class BSPrim : BSPhysObject } _position = value; PositionSanityCheck(false); + + // A linkset might need to know if a component information changed. + Linkset.UpdateProperties(this, false); + PhysicsScene.TaintedObject("BSPrim.setPosition", delegate() { DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); @@ -329,6 +333,14 @@ public sealed class BSPrim : BSPhysObject { bool ret = false; + if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position)) + { + // The physical object is out of the known/simulated area. + // Upper levels of code will handle the transition to other areas so, for + // the time, we just ignore the position. + return ret; + } + float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); OMV.Vector3 upForce = OMV.Vector3.Zero; if (RawPosition.Z < terrainHeight) @@ -352,8 +364,6 @@ public sealed class BSPrim : BSPhysObject } } - // TODO: check for out of bounds - // The above code computes a force to apply to correct any out-of-bounds problems. Apply same. // TODO: This should be intergrated with a geneal physics action mechanism. // TODO: This should be moderated with PID'ness. @@ -567,7 +577,10 @@ public sealed class BSPrim : BSPhysObject if (_orientation == value) return; _orientation = value; - // TODO: what does it mean if a child in a linkset changes its orientation? Rebuild the constraint? + + // A linkset might need to know if a component information changed. + Linkset.UpdateProperties(this, false); + PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate() { if (PhysBody.HasPhysicalBody) @@ -1432,14 +1445,14 @@ public sealed class BSPrim : BSPhysObject entprop.Velocity = _velocity; } - // remember the current and last set values - LastEntityProperties = CurrentEntityProperties; - CurrentEntityProperties = entprop; - OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}", LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity); + // remember the current and last set values + LastEntityProperties = CurrentEntityProperties; + CurrentEntityProperties = entprop; + base.RequestPhysicsterseUpdate(); } /* @@ -1453,7 +1466,7 @@ public sealed class BSPrim : BSPhysObject */ // The linkset implimentation might want to know about this. - Linkset.UpdateProperties(this); + Linkset.UpdateProperties(this, true); } } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index ac99777..7b44574 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -517,8 +517,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime); - DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}", - DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount); + DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}, objWColl={7}", + DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, + updatedEntityCount, collidersCount, ObjectsWithCollisions.Count); if (VehiclePhysicalLoggingEnabled) DumpVehicles(); // DEBUG } catch (Exception e) @@ -573,6 +574,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // Objects that are done colliding are removed from the ObjectsWithCollisions list. // Not done above because it is inside an iteration of ObjectWithCollisions. + // This complex collision processing is required to create an empty collision + // event call after all collisions have happened on an object. This enables + // the simulator to generate the 'collision end' event. if (ObjectsWithNoMoreCollisions.Count > 0) { foreach (BSPhysObject po in ObjectsWithNoMoreCollisions) @@ -597,7 +601,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters ProcessPostStepTaints(); - // This causes the unmanaged code to output ALL the values found in ALL the objects in the world. + // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world. // Only enable this in a limited test world with few objects. // BulletSimAPI.DumpAllInfo2(World.ptr); // DEBUG DEBUG DEBUG -- cgit v1.1 From 021623a17d8371147eefe9290d780048e24812c6 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 16 Dec 2012 22:31:22 -0800 Subject: BulletSim: fix vehicles being shot in the air at border crossings because of mis-application of correction to postion for below groundness. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 82e829e..ef68471 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -871,8 +871,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition)) { // TODO: correct position by applying force rather than forcing position. - VehiclePosition += new Vector3(0f, 0f, GetTerrainHeight(VehiclePosition) + 2f); - VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition); + Vector3 newPosition = VehiclePosition; + newPosition.Z = GetTerrainHeight(VehiclePosition) + 1f; + VehiclePosition = newPosition; + VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}", + Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition); } return ret; } -- cgit v1.1 From 11532a4390ce3054f5a6798b4bf8dcf39d002e77 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 17 Dec 2012 13:22:04 -0800 Subject: BulletSim: fix vehicles going underground when unsat. Problem was that, when doing unsit, the order of operations on the prims and the vehicle is very chaotic and not in a good order so the root prim was being left physical and thus it fell for a bit. Also changed default of velocity scaling to be closer to the movement standard. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 43 ++++++++++++---------- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 14 +++---- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 2 +- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 2 +- 4 files changed, 32 insertions(+), 29 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index ef68471..48ba419 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -87,7 +87,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate - private Vector3 m_lastAngularCorrection = Vector3.Zero; + private Vector3 m_lastAngularVelocity = Vector3.Zero; private Vector3 m_lastVertAttractor = Vector3.Zero; // what VA was last applied to body //Deflection properties @@ -128,7 +128,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Return 'true' if this vehicle is doing vehicle things public bool IsActive { - get { return Type != Vehicle.TYPE_NONE; } + get { return Type != Vehicle.TYPE_NONE && Prim.IsPhysical; } } internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) @@ -664,6 +664,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // an UpdateProperties event to send the changes up to the simulator. BulletSimAPI.PushUpdate2(Prim.PhysBody.ptr); } + m_knownChanged = 0; } // Since the computation of terrain height can be a little involved, this routine @@ -993,11 +994,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin public Vector3 ComputeLinearMotorUp(float pTimestep) { Vector3 ret = Vector3.Zero; + float distanceAboveGround = 0f; if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) { float targetHeight = Type == Vehicle.TYPE_BOAT ? GetWaterLevel(VehiclePosition) : GetTerrainHeight(VehiclePosition); - float distanceAboveGround = VehiclePosition.Z - targetHeight; + distanceAboveGround = VehiclePosition.Z - targetHeight; // Not colliding if the vehicle is off the ground if (!Prim.IsColliding) { @@ -1010,9 +1012,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin // has a decay factor. This says this force should // be computed with a motor. // TODO: add interaction with banking. - VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},colliding={2},ret={3}", - Prim.LocalID, distanceAboveGround, Prim.IsColliding, ret); } + VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},colliding={2},ret={3}", + Prim.LocalID, distanceAboveGround, Prim.IsColliding, ret); return ret; } @@ -1049,8 +1051,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ================================================================== m_lastVertAttractor = verticalAttractionContribution; + // DEBUG DEBUG DEBUG: optionally scale the angular velocity. Debugging SL vs ODE turning functions. + Vector3 originalAngularMotorContrib = angularMotorContribution; + if (PhysicsScene.VehicleScaleAngularVelocityByTimestep) + angularMotorContribution *= pTimestep; + // Sum corrections - m_lastAngularCorrection = angularMotorContribution + m_lastAngularVelocity = angularMotorContribution + verticalAttractionContribution + deflectionContribution + bankingContribution; @@ -1058,19 +1065,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ================================================================== // Apply the correction velocity. // TODO: Should this be applied as an angular force (torque)? - if (!m_lastAngularCorrection.ApproxEquals(Vector3.Zero, 0.01f)) + if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) { - // DEBUG DEBUG DEBUG: optionally scale the angular velocity. Debugging SL vs ODE turning functions. - Vector3 scaledCorrection = m_lastAngularCorrection; - if (PhysicsScene.VehicleScaleAngularVelocityByTimestep) - scaledCorrection *= pTimestep; - VehicleRotationalVelocity = scaledCorrection; + VehicleRotationalVelocity = m_lastAngularVelocity; - VDetailLog("{0}, MoveAngular,done,nonZero,angMotorContrib={1},vertAttrContrib={2},bankContrib={3},deflectContrib={4},totalContrib={5},scaledCorr={6}", + VDetailLog("{0}, MoveAngular,done,nonZero,angMotorContrib={1},vertAttrContrib={2},bankContrib={3},deflectContrib={4},totalContrib={5}", Prim.LocalID, angularMotorContribution, verticalAttractionContribution, bankingContribution, deflectionContribution, - m_lastAngularCorrection, scaledCorrection + m_lastAngularVelocity ); } else @@ -1124,18 +1127,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin { Vector3 ret = Vector3.Zero; - // If vertical attaction timescale is reasonable and we applied an angular force last time... + // If vertical attaction timescale is reasonable if (m_verticalAttractionTimescale < m_verticalAttractionCutoff) { // Take a vector pointing up and convert it from world to vehicle relative coords. Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; - verticalError.Normalize(); // If vertical attraction correction is needed, the vector that was pointing up (UnitZ) - // is now leaning to one side (rotated around the X axis) and the Y value will - // go from zero (nearly straight up) to one (completely to the side) or leaning - // front-to-back (rotated around the Y axis) and the value of X will be between - // zero and one. + // is now: + // leaning to one side: rotated around the X axis with the Y value going + // from zero (nearly straight up) to one (completely to the side)) or + // leaning front-to-back: rotated around the Y axis with the value of X being between + // zero and one. // The value of Z is how far the rotation is off with 1 meaning none and 0 being 90 degrees. // If verticalError.Z is negative, the vehicle is upside down. Add additional push. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 4d4f712..2a7b72c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -94,10 +94,10 @@ public sealed class BSLinksetCompound : BSLinkset } // Schedule a refresh to happen after all the other taint processing. - private void ScheduleRebuild() + private void ScheduleRebuild(BSPhysObject requestor) { DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,rebuilding={1}", - LinksetRoot.LocalID, Rebuilding); + requestor.LocalID, Rebuilding); // When rebuilding, it is possible to set properties that would normally require a rebuild. // If already rebuilding, don't request another rebuild. if (!Rebuilding) @@ -124,7 +124,7 @@ public sealed class BSLinksetCompound : BSLinkset { // The root is going dynamic. Make sure mass is properly set. m_mass = ComputeLinksetMass(); - ScheduleRebuild(); + ScheduleRebuild(LinksetRoot); } else { @@ -153,7 +153,7 @@ public sealed class BSLinksetCompound : BSLinkset DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child)); if (IsRoot(child)) { - ScheduleRebuild(); + ScheduleRebuild(LinksetRoot); } else { @@ -182,7 +182,7 @@ public sealed class BSLinksetCompound : BSLinkset && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition)) { updated.LinksetInfo = null; - ScheduleRebuild(); + ScheduleRebuild(updated); } } @@ -266,7 +266,7 @@ public sealed class BSLinksetCompound : BSLinkset DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); // Rebuild the compound shape with the new child shape included - ScheduleRebuild(); + ScheduleRebuild(child); } return; } @@ -294,7 +294,7 @@ public sealed class BSLinksetCompound : BSLinkset else { // Rebuild the compound shape with the child removed - ScheduleRebuild(); + ScheduleRebuild(child); } } return; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 7b44574..ebaf97e 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -1240,7 +1240,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters (s) => { return s.m_params[0].vehicleAngularDamping; }, (s,p,l,v) => { s.m_params[0].vehicleAngularDamping = v; } ), new ParameterDefn("VehicleScaleAngularVelocityByTimestep", "If true, scale angular turning by timestep", - ConfigurationParameters.numericFalse, + ConfigurationParameters.numericTrue, (s,cf,p,v) => { s.VehicleScaleAngularVelocityByTimestep = cf.GetBoolean(p, s.BoolNumeric(v)); }, (s) => { return s.NumericBool(s.VehicleScaleAngularVelocityByTimestep); }, (s,p,l,v) => { s.VehicleScaleAngularVelocityByTimestep = s.BoolNumeric(v); } ), diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 31dd790..0d9a156 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -5,7 +5,7 @@ Eliminate all crashes (DONEish) Border crossing of physical linkset (DONE) Enable vehicle border crossings (at least as poorly as ODE) Avatar created in previous region and not new region when crossing border - Vehicle recreated in new sim at small Z value (offset from root value?) + Vehicle recreated in new sim at small Z value (offset from root value?) (DONE) Calibrate turning radius limitMotorUp calibration (more down?) study PID motors (include 'efficiency' implementation -- cgit v1.1 From e6fd8365af0b0dc7a4664278c369752cb4e87155 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 17 Dec 2012 21:37:02 +0000 Subject: Extend default 1 second wait for event completion to other thread script reset (as called by llResetOtherScript()). As with script stop (via llDie()) aborting other scripts event threads, llResetOtherScript() can also abort any current event thread on another script. On mono 2.6, 2.10 and possibly later this may cause locking problems in certain code areas. This commit reuses the recently introduced [XEngine] WaitForEventCompletionOnScriptStop to make this a 1 sec timeout, rather than 0 secs. --- .../ScriptEngine/Interfaces/IScriptInstance.cs | 31 +++++++++++++++++++++- .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 4 +-- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 2 +- 3 files changed, 33 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index 00a99c3..2f5b526 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs @@ -147,7 +147,13 @@ namespace OpenSim.Region.ScriptEngine.Interfaces /// /// Stop the script instance. /// + /// + /// This must not be called by a thread that is in the process of handling an event for this script. Otherwise + /// there is a danger that it will self-abort and not complete the reset. + /// /// + /// How many milliseconds we will wait for an existing script event to finish before + /// forcibly aborting that event. /// true if the script was successfully stopped, false otherwise bool Stop(int timeout); @@ -169,8 +175,31 @@ namespace OpenSim.Region.ScriptEngine.Interfaces object EventProcessor(); int EventTime(); - void ResetScript(); + + /// + /// Reset the script. + /// + /// + /// This must not be called by a thread that is in the process of handling an event for this script. Otherwise + /// there is a danger that it will self-abort and not complete the reset. Such a thread must call + /// ApiResetScript() instead. + /// + /// + /// How many milliseconds we will wait for an existing script event to finish before + /// forcibly aborting that event prior to script reset. + /// + void ResetScript(int timeout); + + /// + /// Reset the script. + /// + /// + /// This must not be called by any thread other than the one executing the scripts current event. This is + /// because there is no wait or abort logic if another thread is in the middle of processing a script event. + /// Such an external thread should use ResetScript() instead. + /// void ApiResetScript(); + Dictionary GetVars(); void SetVars(Dictionary vars); DetectParams GetDetectParams(int idx); diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index dfe8386..01a5e34 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -877,7 +877,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance return (DateTime.Now - m_EventStart).Seconds; } - public void ResetScript() + public void ResetScript(int timeout) { if (m_Script == null) return; @@ -887,7 +887,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance RemoveState(); ReleaseControls(); - Stop(0); + Stop(timeout); SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 1dd50c7..f38d17d 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1691,7 +1691,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine { IScriptInstance instance = GetInstance(itemID); if (instance != null) - instance.ResetScript(); + instance.ResetScript(m_WaitForEventCompletionOnScriptStop); } public void StartScript(UUID itemID) -- cgit v1.1 From 8653ea93b2669a180beaedad8765bdeec385d501 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 17 Dec 2012 13:51:39 -0800 Subject: BulletSim: apply friction to linear and angular motion before returning advanced motor value. This seems to be the problem with BulletSim vehicles turning too quickly. Also removed the configuration parameter that controlled the timestep scaling kludge for angular velocity that was added to research the question of quick turning. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 6 ------ OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 4 ++-- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 6 ------ 3 files changed, 2 insertions(+), 14 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 48ba419..5887249 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -1051,12 +1051,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ================================================================== m_lastVertAttractor = verticalAttractionContribution; - // DEBUG DEBUG DEBUG: optionally scale the angular velocity. Debugging SL vs ODE turning functions. - Vector3 originalAngularMotorContrib = angularMotorContribution; - if (PhysicsScene.VehicleScaleAngularVelocityByTimestep) - angularMotorContribution *= pTimestep; - - // Sum corrections m_lastAngularVelocity = angularMotorContribution + verticalAttractionContribution + deflectionContribution diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index cf0a9dc..e0faf4e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -134,8 +134,6 @@ public class BSVMotor : BSMotor Vector3 addAmount = (TargetValue - CurrentValue)/TimeScale * timeStep; CurrentValue += addAmount; - returnCurrent = CurrentValue; - // The desired value reduces to zero which also reduces the difference with current. // If the decay time is infinite, don't decay at all. float decayFactor = 0f; @@ -156,6 +154,8 @@ public class BSVMotor : BSMotor CurrentValue *= (Vector3.One - frictionFactor); } + returnCurrent = CurrentValue; + MDetailLog("{0}, BSVMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},timeScale={5},addAmnt={6},targetDecay={7},decayFact={8},fricTS={9},frictFact={10}", BSScene.DetailLogZero, UseName, origCurrVal, origTarget, timeStep, TimeScale, addAmount, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index ebaf97e..069cb0d 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -189,7 +189,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // 'true' of the vehicle code is to log lots of details public bool VehicleLoggingEnabled { get; private set; } public bool VehiclePhysicalLoggingEnabled { get; private set; } - public bool VehicleScaleAngularVelocityByTimestep { get; private set; } #region Construction and Initialization public BSScene(string identifier) @@ -1239,11 +1238,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters (s,cf,p,v) => { s.m_params[0].vehicleAngularDamping = cf.GetFloat(p, v); }, (s) => { return s.m_params[0].vehicleAngularDamping; }, (s,p,l,v) => { s.m_params[0].vehicleAngularDamping = v; } ), - new ParameterDefn("VehicleScaleAngularVelocityByTimestep", "If true, scale angular turning by timestep", - ConfigurationParameters.numericTrue, - (s,cf,p,v) => { s.VehicleScaleAngularVelocityByTimestep = cf.GetBoolean(p, s.BoolNumeric(v)); }, - (s) => { return s.NumericBool(s.VehicleScaleAngularVelocityByTimestep); }, - (s,p,l,v) => { s.VehicleScaleAngularVelocityByTimestep = s.BoolNumeric(v); } ), new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", 0f, -- cgit v1.1 From 5f71ee57c44f277e9e78392c616509498459c027 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 25 Dec 2012 23:54:10 -0800 Subject: BulletSim: stop avatar from sliding VERY slowly after walking by only zeroing the movement motor in the UpdateProperties routine. --- OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index bf0545a..9f0d5af 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -260,7 +260,6 @@ public sealed class BSCharacter : BSPhysObject public override void ZeroMotion(bool inTaintTime) { _velocity = OMV.Vector3.Zero; - _velocityMotor.Zero(); _acceleration = OMV.Vector3.Zero; _rotationalVelocity = OMV.Vector3.Zero; @@ -772,9 +771,9 @@ public sealed class BSCharacter : BSPhysObject // the motor can be turned off. Set the velocity to zero so the zero motion is sent to the viewer. if (_velocityMotor.TargetValue.ApproxEquals(OMV.Vector3.Zero, 0.01f) && _velocityMotor.ErrorIsZero) { - _velocityMotor.Enabled = false; - stepVelocity = OMV.Vector3.Zero; ZeroMotion(true); + stepVelocity = OMV.Vector3.Zero; + _velocityMotor.Enabled = false; DetailLog("{0},BSCharacter.UpdateProperties,taint,disableVelocityMotor,m={1}", LocalID, _velocityMotor); } -- cgit v1.1 From d1ede1df3a04428c83a9937059a0df00d7f3e281 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 25 Dec 2012 23:55:25 -0800 Subject: BulletSim: make llBuoyancy work. For some reason, Bullet resets an object's individual gravity to the world gravity when the object is added to the physical world. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 3 +++ OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 12 ++++++++---- OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | 3 ++- 3 files changed, 13 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 3fde57b..a8edd23 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -573,6 +573,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia); BulletSimAPI.UpdateInertiaTensor2(Prim.PhysBody.ptr); + Vector3 grav = PhysicsScene.DefaultGravity * (1f - Prim.Buoyancy); + BulletSimAPI.SetGravity2(Prim.PhysBody.ptr, grav); + VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4}", Prim.LocalID, m_vehicleMass, friction, localInertia, angularDamping); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 159f79f..0d13096 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -422,20 +422,24 @@ public sealed class BSPrim : BSPhysObject BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr); } - float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); - BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav)); - Inertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass); BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, Inertia); BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); + // center of mass is at the zero of the object // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(PhysBody.ptr, ForcePosition, ForceOrientation); - DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2}", LocalID, physMass, Inertia); + DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2},inWorld={3}", LocalID, physMass, Inertia, inWorld); if (inWorld) { BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr); } + + // 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 + OMV.Vector3 grav = PhysicsScene.DefaultGravity * (1f - Buoyancy); + BulletSimAPI.SetGravity2(PhysBody.ptr, grav); + } } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 35cb8f3..9d07d72 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -58,7 +58,6 @@ Incorporate inter-relationship of angular corrections. For instance, angularDefl BULLETSIM TODO LIST: ================================================= -In SL, perfect spheres don't seem to have rolling friction. Add special case. Avatar density is WAY off. Compare and calibrate with what's in SL. Revisit CollisionMargin. Builders notice the 0.04 spacing between prims. Duplicating a physical prim causes old prim to jump away @@ -146,6 +145,8 @@ Is there are more efficient method of implementing pre and post step actions? See http://www.codeproject.com/Articles/29922/Weak-Events-in-C Physics Arena central pyramid: why is one side permiable? + +In SL, perfect spheres don't seem to have rolling friction. Add special case. Enforce physical parameter min/max: Gravity: [-1, 28] Friction: [0, 255] -- cgit v1.1 From 225b564573a5ac12ca1b1e592834476feccf8ebb Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 26 Dec 2012 10:25:50 -0800 Subject: BulletSim: scale the force for external AddForce by the simulation step time so it will be applied completely the next step. The internal AddForce routine does not scale the force. --- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 12 +++++++++++- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 4 ++++ OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | 4 ++++ 3 files changed, 19 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 0d13096..9013414 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -1014,7 +1014,9 @@ public sealed class BSPrim : BSPhysObject public override float APIDDamping { set { return; } } public override void AddForce(OMV.Vector3 force, bool pushforce) { - AddForce(force, pushforce, false); + // Since this force is being applied in only one step, make this a force per second. + OMV.Vector3 addForce = force / PhysicsScene.LastTimeStep; + AddForce(addForce, pushforce, false); } // Applying a force just adds this to the total force on the object. // This added force will only last the next simulation tick. @@ -1022,8 +1024,16 @@ public sealed class BSPrim : BSPhysObject // for an object, doesn't matter if force is a pushforce or not if (force.IsFinite()) { + float magnitude = force.Length(); + if (magnitude > 20000f) + { + // Force has a limit + force = force / magnitude * 20000f; + } + OMV.Vector3 addForce = force; DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); + PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() { // Bullet adds this central force to the total force for this tick diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 0022e45..b67c0ed 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -495,6 +495,10 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters InTaintTime = false; // Only used for debugging so locking is not necessary. + // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world. + // Only enable this in a limited test world with few objects. + // BulletSimAPI.DumpAllInfo2(World.ptr); // DEBUG DEBUG DEBUG + // step the physical world one interval m_simulationStep++; int numSubSteps = 0; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 9d07d72..78cc26c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -35,6 +35,8 @@ Border crossing with linked vehicle causes crash Vehicles (Move smoothly) Add vehicle collisions so IsColliding is properly reported. Needed for banking, limitMotorUp, movementLimiting, ... +VehicleAddForce is not scaled by the simulation step but it is only + applied for one step. Should it be scaled? Some vehicles should not be able to turn if no speed or off ground. Cannot edit/move a vehicle being ridden: it jumps back to the origional position. Neb car jiggling left and right @@ -92,6 +94,8 @@ Should the different PID factors have non-equal contributions for different Selecting and deselecting physical objects causes CPU processing time to jump http://www.youtube.com/watch?v=Hjg57fWg8yI&hd=1 put thousand physical objects, select and deselect same. CPU time will be large. +Re-implement buoyancy as a separate force on the object rather than diddling gravity. + Register a pre-step event to add the force. LINKSETS ====================================================== -- cgit v1.1 From 29cdf0f3dd99605192f29fc83bbacdf8ecb0ea8d Mon Sep 17 00:00:00 2001 From: teravus Date: Tue, 18 Dec 2012 15:00:10 -0500 Subject: * Merges BulletSim Updates to BulletSimN(BulletSNPlugin) --- .../Region/Physics/BulletSNPlugin/BSCharacter.cs | 8 +- .../Region/Physics/BulletSNPlugin/BSConstraint.cs | 2 +- .../Physics/BulletSNPlugin/BSConstraint6Dof.cs | 4 +- .../BulletSNPlugin/BSConstraintCollection.cs | 4 +- .../Physics/BulletSNPlugin/BSConstraintHinge.cs | 2 +- .../Region/Physics/BulletSNPlugin/BSDynamics.cs | 3 + OpenSim/Region/Physics/BulletSNPlugin/BSLinkset.cs | 20 ++--- .../Physics/BulletSNPlugin/BSLinksetCompound.cs | 11 +-- .../Physics/BulletSNPlugin/BSLinksetConstraints.cs | 6 +- .../Region/Physics/BulletSNPlugin/BSMaterials.cs | 16 ++-- OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs | 2 +- .../Region/Physics/BulletSNPlugin/BSPhysObject.cs | 3 +- OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs | 87 +++++++++++++++------- OpenSim/Region/Physics/BulletSNPlugin/BSScene.cs | 11 ++- .../Physics/BulletSNPlugin/BSShapeCollection.cs | 6 +- .../Physics/BulletSNPlugin/BSTerrainHeightmap.cs | 2 +- .../Physics/BulletSNPlugin/BSTerrainManager.cs | 3 +- .../Region/Physics/BulletSNPlugin/BulletSimAPI.cs | 1 - .../Region/Physics/BulletSNPlugin/BulletSimData.cs | 4 +- 19 files changed, 116 insertions(+), 79 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSCharacter.cs index 4c4e950..d91c47f 100644 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSCharacter.cs @@ -174,7 +174,7 @@ public sealed class BSCharacter : BSPhysObject BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius); } - UpdatePhysicalMassProperties(RawMass); + UpdatePhysicalMassProperties(RawMass, false); // Make so capsule does not fall over BulletSimAPI.SetAngularFactorV2(PhysBody.ptr, OMV.Vector3.Zero); @@ -224,7 +224,7 @@ public sealed class BSCharacter : BSPhysObject if (PhysBody.HasPhysicalBody && PhysShape.HasPhysicalShape) { BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale); - UpdatePhysicalMassProperties(RawMass); + UpdatePhysicalMassProperties(RawMass, true); // Make sure this change appears as a property update event BulletSimAPI.PushUpdate2(PhysBody.ptr); } @@ -260,7 +260,6 @@ public sealed class BSCharacter : BSPhysObject public override void ZeroMotion(bool inTaintTime) { _velocity = OMV.Vector3.Zero; - _velocityMotor.Zero(); _acceleration = OMV.Vector3.Zero; _rotationalVelocity = OMV.Vector3.Zero; @@ -390,7 +389,7 @@ public sealed class BSCharacter : BSPhysObject public override float RawMass { get {return _mass; } } - public override void UpdatePhysicalMassProperties(float physMass) + public override void UpdatePhysicalMassProperties(float physMass, bool inWorld) { OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass); BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, localInertia); @@ -787,6 +786,7 @@ public sealed class BSCharacter : BSPhysObject // the motor can be turned off. Set the velocity to zero so the zero motion is sent to the viewer. if (_velocityMotor.TargetValue.ApproxEquals(OMV.Vector3.Zero, 0.01f) && _velocityMotor.ErrorIsZero) { + ZeroMotion(true); stepVelocity = OMV.Vector3.Zero; _velocityMotor.Enabled = false; DetailLog("{0},BSCharacter.UpdateProperties,taint,disableVelocityMotor,m={1}", LocalID, _velocityMotor); diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSConstraint.cs index 426bdc2..f1bed39 100644 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSConstraint.cs +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSConstraint.cs @@ -36,7 +36,7 @@ public abstract class BSConstraint : IDisposable { private static string LogHeader = "[BULLETSIM CONSTRAINT]"; - protected BulletSim m_world; + protected BulletWorld m_world; protected BulletBody m_body1; protected BulletBody m_body2; protected BulletConstraint m_constraint; diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSConstraint6Dof.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSConstraint6Dof.cs index 0181d9d..d1e3f55 100644 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSConstraint6Dof.cs +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSConstraint6Dof.cs @@ -39,7 +39,7 @@ public sealed class BSConstraint6Dof : BSConstraint public override ConstraintType Type { get { return ConstraintType.D6_CONSTRAINT_TYPE; } } // Create a btGeneric6DofConstraint - public BSConstraint6Dof(BulletSim world, BulletBody obj1, BulletBody obj2, + public BSConstraint6Dof(BulletWorld world, BulletBody obj1, BulletBody obj2, Vector3 frame1, Quaternion frame1rot, Vector3 frame2, Quaternion frame2rot, bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) @@ -58,7 +58,7 @@ public sealed class BSConstraint6Dof : BSConstraint obj1.ID, obj1.ptr.ToString(), obj2.ID, obj2.ptr.ToString()); } - public BSConstraint6Dof(BulletSim world, BulletBody obj1, BulletBody obj2, + public BSConstraint6Dof(BulletWorld world, BulletBody obj1, BulletBody obj2, Vector3 joinPoint, bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) { diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSConstraintCollection.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSConstraintCollection.cs index 5c00b1a..87d1e44 100644 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSConstraintCollection.cs +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSConstraintCollection.cs @@ -41,9 +41,9 @@ public sealed class BSConstraintCollection : IDisposable delegate bool ConstraintAction(BSConstraint constrain); private List m_constraints; - private BulletSim m_world; + private BulletWorld m_world; - public BSConstraintCollection(BulletSim world) + public BSConstraintCollection(BulletWorld world) { m_world = world; m_constraints = new List(); diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSConstraintHinge.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSConstraintHinge.cs index 7951f06..fbd1bc0 100644 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSConstraintHinge.cs +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSConstraintHinge.cs @@ -36,7 +36,7 @@ public sealed class BSConstraintHinge : BSConstraint { public override ConstraintType Type { get { return ConstraintType.HINGE_CONSTRAINT_TYPE; } } - public BSConstraintHinge(BulletSim world, BulletBody obj1, BulletBody obj2, + public BSConstraintHinge(BulletWorld world, BulletBody obj1, BulletBody obj2, Vector3 pivotInA, Vector3 pivotInB, Vector3 axisInA, Vector3 axisInB, bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSDynamics.cs index 72afacc..415ad4f 100644 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSDynamics.cs @@ -573,6 +573,9 @@ namespace OpenSim.Region.Physics.BulletSNPlugin BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia); BulletSimAPI.UpdateInertiaTensor2(Prim.PhysBody.ptr); + Vector3 grav = PhysicsScene.DefaultGravity * (1f - Prim.Buoyancy); + BulletSimAPI.SetGravity2(Prim.PhysBody.ptr, grav); + VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4}", Prim.LocalID, m_vehicleMass, friction, localInertia, angularDamping); } diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSLinkset.cs index 253128b..845a113 100644 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSLinkset.cs @@ -97,14 +97,7 @@ public abstract class BSLinkset } // We keep the prim's mass in the linkset structure since it could be dependent on other prims - protected float m_mass; - public float LinksetMass - { - get - { - return m_mass; - } - } + public float LinksetMass { get; protected set; } public virtual bool LinksetIsColliding { get { return false; } } @@ -128,7 +121,7 @@ public abstract class BSLinkset PhysicsScene = scene; LinksetRoot = parent; m_children = new HashSet(); - m_mass = parent.RawMass; + LinksetMass = parent.RawMass; Rebuilding = false; } @@ -143,7 +136,7 @@ public abstract class BSLinkset // Don't add the root to its own linkset if (!IsRoot(child)) AddChildToLinkset(child); - m_mass = ComputeLinksetMass(); + LinksetMass = ComputeLinksetMass(); } return this; } @@ -162,7 +155,7 @@ public abstract class BSLinkset return this; } RemoveChildFromLinkset(child); - m_mass = ComputeLinksetMass(); + LinksetMass = ComputeLinksetMass(); } // The child is down to a linkset of just itself @@ -230,7 +223,10 @@ public abstract class BSLinkset // When physical properties are changed the linkset needs to recalculate // its internal properties. // May be called at runtime or taint-time. - public abstract void Refresh(BSPhysObject requestor); + public virtual void Refresh(BSPhysObject requestor) + { + LinksetMass = ComputeLinksetMass(); + } // Flag denoting the linkset is in the process of being rebuilt. // Used to know not the schedule a rebuild in the middle of a rebuild. diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetCompound.cs index 23a0b8b..9a977e6 100644 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetCompound.cs @@ -89,6 +89,8 @@ public sealed class BSLinksetCompound : BSLinkset // its internal properties. public override void Refresh(BSPhysObject requestor) { + base.Refresh(requestor); + // Something changed so do the rebuilding thing // ScheduleRebuild(); } @@ -96,13 +98,13 @@ public sealed class BSLinksetCompound : BSLinkset // Schedule a refresh to happen after all the other taint processing. private void ScheduleRebuild(BSPhysObject requestor) { - DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,rebuilding={1}", + DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1}", requestor.LocalID, Rebuilding); // When rebuilding, it is possible to set properties that would normally require a rebuild. // If already rebuilding, don't request another rebuild. if (!Rebuilding) { - PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", LinksetRoot.LocalID, delegate() + PhysicsScene.PostTaintObject("BSLinksetCompound.ScheduleRebuild", LinksetRoot.LocalID, delegate() { if (HasAnyChildren) RecomputeLinksetCompound(); @@ -123,7 +125,6 @@ public sealed class BSLinksetCompound : BSLinkset if (IsRoot(child)) { // The root is going dynamic. Make sure mass is properly set. - m_mass = ComputeLinksetMass(); ScheduleRebuild(LinksetRoot); } else @@ -377,8 +378,8 @@ public sealed class BSLinksetCompound : BSLinkset }); // With all of the linkset packed into the root prim, it has the mass of everyone. - float linksetMass = LinksetMass; - LinksetRoot.UpdatePhysicalMassProperties(linksetMass); + LinksetMass = LinksetMass; + LinksetRoot.UpdatePhysicalMassProperties(LinksetMass, true); } finally { diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetConstraints.cs index 5757e64..46ff99f 100644 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetConstraints.cs @@ -46,6 +46,8 @@ public sealed class BSLinksetConstraints : BSLinkset // refresh will happen once after all the other taints are applied. public override void Refresh(BSPhysObject requestor) { + base.Refresh(requestor); + // Queue to happen after all the other taint processing PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate() { @@ -279,7 +281,7 @@ public sealed class BSLinksetConstraints : BSLinkset private void RecomputeLinksetConstraints() { float linksetMass = LinksetMass; - LinksetRoot.UpdatePhysicalMassProperties(linksetMass); + LinksetRoot.UpdatePhysicalMassProperties(linksetMass, true); // DEBUG: see of inter-linkset collisions are causing problems // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, @@ -292,7 +294,7 @@ public sealed class BSLinksetConstraints : BSLinkset // A child in the linkset physically shows the mass of the whole linkset. // This allows Bullet to apply enough force on the child to move the whole linkset. // (Also do the mass stuff before recomputing the constraint so mass is not zero.) - child.UpdatePhysicalMassProperties(linksetMass); + child.UpdatePhysicalMassProperties(linksetMass, true); BSConstraint constrain; if (!PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, child.PhysBody, out constrain)) diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSMaterials.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSMaterials.cs index 732191f..d7941b6 100644 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSMaterials.cs +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSMaterials.cs @@ -119,26 +119,26 @@ public static class BSMaterials Attributes[(int)MaterialAttributes.Material.Light] = new MaterialAttributes("light",dDensity, dFriction, dRestitution); Attributes[(int)MaterialAttributes.Material.Avatar] = - new MaterialAttributes("avatar",60f, 0.2f, 0f); + new MaterialAttributes("avatar",3.5f, 0.2f, 0f); Attributes[(int)MaterialAttributes.Material.Stone + (int)MaterialAttributes.Material.NumberOfTypes] = new MaterialAttributes("stonePhysical",dDensity, 0.8f, 0.4f); Attributes[(int)MaterialAttributes.Material.Metal + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("metalPhysical",dDensity, 0.8f, 0.4f); + new MaterialAttributes("metalPhysical",dDensity, 0.3f, 0.4f); Attributes[(int)MaterialAttributes.Material.Glass + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("glassPhysical",dDensity, 0.8f, 0.7f); + new MaterialAttributes("glassPhysical",dDensity, 0.2f, 0.7f); Attributes[(int)MaterialAttributes.Material.Wood + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("woodPhysical",dDensity, 0.8f, 0.5f); + new MaterialAttributes("woodPhysical",dDensity, 0.6f, 0.5f); Attributes[(int)MaterialAttributes.Material.Flesh + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("fleshPhysical",dDensity, 0.8f, 0.3f); + new MaterialAttributes("fleshPhysical",dDensity, 0.9f, 0.3f); Attributes[(int)MaterialAttributes.Material.Plastic + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("plasticPhysical",dDensity, 0.8f, 0.7f); + new MaterialAttributes("plasticPhysical",dDensity, 0.4f, 0.7f); Attributes[(int)MaterialAttributes.Material.Rubber + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("rubberPhysical",dDensity, 0.8f, 0.9f); + new MaterialAttributes("rubberPhysical",dDensity, 0.9f, 0.9f); Attributes[(int)MaterialAttributes.Material.Light + (int)MaterialAttributes.Material.NumberOfTypes] = new MaterialAttributes("lightPhysical",dDensity, dFriction, dRestitution); Attributes[(int)MaterialAttributes.Material.Avatar + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("avatarPhysical",60f, 0.2f, 0f); + new MaterialAttributes("avatarPhysical",3.5f, 0.2f, 0f); } // Under the [BulletSim] section, one can change the individual material diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs index 20c0939..5e93a03 100644 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs @@ -351,7 +351,7 @@ public static class BSParam (s) => { return AvatarStandingFriction; }, (s,p,l,v) => { AvatarStandingFriction = v; } ), new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.", - 60f, + 3.5f, (s,cf,p,v) => { AvatarDensity = cf.GetFloat(p, v); }, (s) => { return AvatarDensity; }, (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarDensity=x;}, p, l, v); } ), diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSPhysObject.cs index 4096ef8..689da7f 100644 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSPhysObject.cs @@ -96,7 +96,8 @@ public abstract class BSPhysObject : PhysicsActor // Return the object mass without calculating it or having side effects public abstract float RawMass { get; } // Set the raw mass but also update physical mass properties (inertia, ...) - public abstract void UpdatePhysicalMassProperties(float mass); + // 'inWorld' true if the object has already been added to the dynamic world. + public abstract void UpdatePhysicalMassProperties(float mass, bool inWorld); // The last value calculated for the prim's inertia public OMV.Vector3 Inertia { get; set; } diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs index a889c24..9c4ba30 100644 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs @@ -115,6 +115,8 @@ public sealed class BSPrim : BSPhysObject PhysBody = new BulletBody(LocalID); PhysShape = new BulletShape(); + Linkset.Refresh(this); + DetailLog("{0},BSPrim.constructor,call", LocalID); // do the actual object creation at taint time PhysicsScene.TaintedObject("BSPrim.create", delegate() @@ -384,13 +386,13 @@ public sealed class BSPrim : BSPhysObject } // Return the effective mass of the object. - // If there are multiple items in the linkset, add them together for the root + // The definition of this call is to return the mass of the prim. + // If the simulator cares about the mass of the linkset, it will sum it itself. public override float Mass { get { - return Linkset.LinksetMass; - // return _mass; + return _mass; } } @@ -400,22 +402,45 @@ public sealed class BSPrim : BSPhysObject } // Set the physical mass to the passed mass. // Note that this does not change _mass! - public override void UpdatePhysicalMassProperties(float physMass) + public override void UpdatePhysicalMassProperties(float physMass, bool inWorld) { - if (IsStatic) + if (PhysBody.HasPhysicalBody) { - Inertia = OMV.Vector3.Zero; - BulletSimAPI.SetMassProps2(PhysBody.ptr, 0f, Inertia); - BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); - } - else - { - Inertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass); - BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, Inertia); - BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); - // center of mass is at the zero of the object - // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(PhysBody.ptr, ForcePosition, ForceOrientation); - DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2}", LocalID, physMass, Inertia); + if (IsStatic) + { + Inertia = OMV.Vector3.Zero; + BulletSimAPI.SetMassProps2(PhysBody.ptr, 0f, Inertia); + BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); + } + else + { + if (inWorld) + { + // Changing interesting properties doesn't change proxy and collision cache + // information. The Bullet solution is to re-add the object to the world + // after parameters are changed. + BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr); + } + + Inertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass); + BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, Inertia); + BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); + + // center of mass is at the zero of the object + // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(PhysBody.ptr, ForcePosition, ForceOrientation); + DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2},inWorld={3}", LocalID, physMass, Inertia, inWorld); + + if (inWorld) + { + BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr,_position,_orientation); + } + + // 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 + OMV.Vector3 grav = PhysicsScene.DefaultGravity * (1f - Buoyancy); + BulletSimAPI.SetGravity2(PhysBody.ptr, grav); + + } } } @@ -714,7 +739,7 @@ public sealed class BSPrim : BSPhysObject Linkset.Refresh(this); DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},body={6},shape={7}", - LocalID, IsStatic, IsSolid, _mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody, PhysShape); + LocalID, IsStatic, IsSolid, Mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody, PhysShape); } // "Making dynamic" means changing to and from static. @@ -737,7 +762,7 @@ public sealed class BSPrim : BSPhysObject BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution); // Mass is zero which disables a bunch of physics stuff in Bullet - UpdatePhysicalMassProperties(0f); + UpdatePhysicalMassProperties(0f, false); // Set collision detection parameters if (BSParam.CcdMotionThreshold > 0f) { @@ -777,7 +802,7 @@ public sealed class BSPrim : BSPhysObject // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.PhysBody.ptr, _position, _orientation); // A dynamic object has mass - UpdatePhysicalMassProperties(RawMass); + UpdatePhysicalMassProperties(RawMass, false); // Set collision detection parameters if (BSParam.CcdMotionThreshold > 0f) @@ -950,13 +975,9 @@ public sealed class BSPrim : BSPhysObject set { _buoyancy = value; // DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); - // Buoyancy is faked by changing the gravity applied to the object - if (PhysBody.HasPhysicalBody) - { - float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); - BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav)); - ActivateIfPhysical(false); - } + // Force the recalculation of the various inertia,etc variables in the object + UpdatePhysicalMassProperties(_mass, true); + ActivateIfPhysical(false); } } @@ -993,7 +1014,9 @@ public sealed class BSPrim : BSPhysObject public override float APIDDamping { set { return; } } public override void AddForce(OMV.Vector3 force, bool pushforce) { - AddForce(force, pushforce, false); + // Since this force is being applied in only one step, make this a force per second. + OMV.Vector3 addForce = force / PhysicsScene.LastTimeStep; + AddForce(addForce, pushforce, false); } // Applying a force just adds this to the total force on the object. // This added force will only last the next simulation tick. @@ -1001,8 +1024,16 @@ public sealed class BSPrim : BSPhysObject // for an object, doesn't matter if force is a pushforce or not if (force.IsFinite()) { + float magnitude = force.Length(); + if (magnitude > 20000f) + { + // Force has a limit + force = force / magnitude * 20000f; + } + OMV.Vector3 addForce = force; DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); + PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() { // Bullet adds this central force to the total force for this tick diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSScene.cs index 6bcea3f..1a7c34b 100644 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSScene.cs @@ -74,7 +74,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public IMesher mesher; public uint WorldID { get; private set; } - public BulletSim World { get; private set; } + public BulletWorld World { get; private set; } // All the constraints that have been allocated in this instance. public BSConstraintCollection Constraints { get; private set; } @@ -244,7 +244,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader); - World = new BulletSim(0, this, BulletSimAPI.Initialize2(worldExtent, UnmanagedParams, + World = new BulletWorld(0, this, BulletSimAPI.Initialize2(worldExtent, UnmanagedParams, m_maxCollisionsPerFrame, ref m_collisionArray, m_maxUpdatesPerFrame,ref m_updateArray, m_DebugLogCallbackHandle)); @@ -497,13 +497,16 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters InTaintTime = false; // Only used for debugging so locking is not necessary. + // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world. + // Only enable this in a limited test world with few objects. + // BulletSimAPI.DumpAllInfo2(World.ptr); // DEBUG DEBUG DEBUG + // step the physical world one interval m_simulationStep++; int numSubSteps = 0; try { - //if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount(); numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep, @@ -833,7 +836,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters { DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom); m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom); - Util.PrintCallStack(); // Prints the stack into the DEBUG log file. + Util.PrintCallStack(DetailLog); } return InTaintTime; } diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSShapeCollection.cs index 398ece0..47fb768 100644 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSShapeCollection.cs @@ -98,7 +98,7 @@ public sealed class BSShapeCollection : IDisposable // higher level dependencies on the shape or body. Mostly used for LinkSets to // remove the physical constraints before the body is destroyed. // Called at taint-time!! - public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim, + public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim, ShapeDestructionCallback shapeCallback, BodyDestructionCallback bodyCallback) { PhysicsScene.AssertInTaintTime("BSShapeCollection.GetBodyAndShape"); @@ -126,7 +126,7 @@ public sealed class BSShapeCollection : IDisposable return ret; } - public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim) + public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim) { return GetBodyAndShape(forceRebuild, sim, prim, null, null); } @@ -918,7 +918,7 @@ public sealed class BSShapeCollection : IDisposable // Updates prim.BSBody with the information about the new body if one is created. // Returns 'true' if an object was actually created. // Called at taint-time. - private bool CreateBody(bool forceRebuild, BSPhysObject prim, BulletSim sim, BulletShape shape, + private bool CreateBody(bool forceRebuild, BSPhysObject prim, BulletWorld sim, BulletShape shape, BodyDestructionCallback bodyCallback) { bool ret = false; diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainHeightmap.cs index 252953b..ba17059 100644 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainHeightmap.cs +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainHeightmap.cs @@ -103,7 +103,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys Vector3 centerPos; centerPos.X = m_mapInfo.minCoords.X + (m_mapInfo.sizeX / 2f); centerPos.Y = m_mapInfo.minCoords.Y + (m_mapInfo.sizeY / 2f); - centerPos.Z = m_mapInfo.minZ + ((m_mapInfo.maxZ - m_mapInfo.minZ) / 2f + 0.5f); + centerPos.Z = m_mapInfo.minZ + ((m_mapInfo.maxZ - m_mapInfo.minZ) / 2f - 0.5f); m_mapInfo.terrainBody = new BulletBody(m_mapInfo.ID, BulletSimAPI.CreateBodyWithDefaultMotionState2(m_mapInfo.terrainShape.ptr, diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainManager.cs index dfad70e..66d62f0 100644 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainManager.cs @@ -140,7 +140,7 @@ public sealed class BSTerrainManager : IDisposable m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID, BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID, Vector3.Zero, Quaternion.Identity)); - BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr); + BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr, Vector3.Zero, Quaternion.Identity); BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_groundPlane.ptr); // Ground plane does not move BulletSimAPI.ForceActivationState2(m_groundPlane.ptr, ActivationState.DISABLE_SIMULATION); @@ -376,6 +376,7 @@ public sealed class BSTerrainManager : IDisposable DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXYZ,terrainNotFound,pos={1},base={2}", BSScene.DetailLogZero, pos, terrainBaseXYZ); } + lastHeight = ret; return ret; } diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSNPlugin/BulletSimAPI.cs index 6af59d6..93643c9 100644 --- a/OpenSim/Region/Physics/BulletSNPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSNPlugin/BulletSimAPI.cs @@ -58,7 +58,6 @@ public enum ConstraintType : int MAX_CONSTRAINT_TYPE } - // =============================================================================== [StructLayout(LayoutKind.Sequential)] public struct ConvexHull diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BulletSimData.cs b/OpenSim/Region/Physics/BulletSNPlugin/BulletSimData.cs index a1ed8d8..f509dc4 100644 --- a/OpenSim/Region/Physics/BulletSNPlugin/BulletSimData.cs +++ b/OpenSim/Region/Physics/BulletSNPlugin/BulletSimData.cs @@ -35,9 +35,9 @@ namespace OpenSim.Region.Physics.BulletSNPlugin // These hold pointers to allocated objects in the unmanaged space. // The physics engine controller class created at initialization -public struct BulletSim +public struct BulletWorld { - public BulletSim(uint worldId, BSScene bss, object xx) + public BulletWorld(uint worldId, BSScene bss, object xx) { ptr = xx; worldID = worldId; -- cgit v1.1 From ae67435146d65e1241c15677952f7d4a05ee794c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 19 Dec 2012 01:51:30 +0000 Subject: Disable UDPPacketBuffer pooling for now to resolve an issue on Windows of interference between incoming packets. On Windows, concurrent multi-threaded processing of inbound UDP somehow allows different data input processing to interfere with each other. Possibly the endpoint reference is being switched, though I don't yet know the mechanism. Not seen on Mono. Also resolveable by setting RecyclePackets = false or RecycleBaseUDPPackets = false in [PacketPool] Or async_packet_handling = false in [ClientStack.LindenUDP] For now, will simply disable this particular pooling though will revisit this issue. In response to http://opensimulator.org/mantis/view.php?id=6468 --- OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index 3f7ca2b..f143c32 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs @@ -208,9 +208,12 @@ namespace OpenMetaverse { UDPPacketBuffer buf; - if (UsePools) - buf = Pool.GetObject(); - else + // FIXME: Disabled for now as this causes issues with reused packet objects interfering with each other + // on Windows with m_asyncPacketHandling = true, though this has not been seen on Linux. + // Possibly some unexpected issue with fetching UDP data concurrently with multiple threads. Requires more investigation. +// if (UsePools) +// buf = Pool.GetObject(); +// else buf = new UDPPacketBuffer(); if (IsRunningInbound) @@ -291,8 +294,8 @@ namespace OpenMetaverse catch (ObjectDisposedException) { } finally { - if (UsePools) - Pool.ReturnObject(buffer); +// if (UsePools) +// Pool.ReturnObject(buffer); // Synchronous mode waits until the packet callback completes // before starting the receive to fetch another packet -- cgit v1.1 From d15bfcf61404914c3d64c965db9e66295655bea5 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 18 Dec 2012 14:59:41 -0800 Subject: Replace axis rotation numeric constants (STATUS_ROTATE_XYZ) with symbols. Also made it so llSetStatus() can individually enable disable rotation axi using the bitmask of flags. --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 9 +++++++++ OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 12 ++++++------ .../Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 7 ++++--- 3 files changed, 19 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 64a5811..35e7c45 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -99,6 +99,15 @@ namespace OpenSim.Region.Framework.Scenes /// public partial class SceneObjectGroup : EntityBase, ISceneObject { + // Axis selection bitmask used by SetAxisRotation() + // Just happen to be the same bits used by llSetStatus() and defined in ScriptBaseClass. + public enum axisSelect : int + { + STATUS_ROTATE_X = 0x002, + STATUS_ROTATE_Y = 0x004, + STATUS_ROTATE_Z = 0x008, + } + // private PrimCountTaintedDelegate handlerPrimCountTainted = null; /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index af7fae3..7a97e5f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1918,11 +1918,11 @@ namespace OpenSim.Region.Framework.Scenes public int GetAxisRotation(int axis) { //Cannot use ScriptBaseClass constants as no referance to it currently. - if (axis == 2)//STATUS_ROTATE_X + if (axis == (int)SceneObjectGroup.axisSelect.STATUS_ROTATE_X) return STATUS_ROTATE_X; - if (axis == 4)//STATUS_ROTATE_Y + if (axis == (int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Y) return STATUS_ROTATE_Y; - if (axis == 8)//STATUS_ROTATE_Z + if (axis == (int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Z) return STATUS_ROTATE_Z; return 0; @@ -2671,13 +2671,13 @@ namespace OpenSim.Region.Framework.Scenes ParentGroup.SetAxisRotation(axis, rotate); //Cannot use ScriptBaseClass constants as no referance to it currently. - if (axis == 2)//STATUS_ROTATE_X + if ((axis & (int)SceneObjectGroup.axisSelect.STATUS_ROTATE_X) != 0) STATUS_ROTATE_X = rotate; - if (axis == 4)//STATUS_ROTATE_Y + if ((axis & (int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Y) != 0) STATUS_ROTATE_Y = rotate; - if (axis == 8)//STATUS_ROTATE_Z + if ((axis & (int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Z) != 0) STATUS_ROTATE_Z = rotate; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 4108588..837779d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1334,19 +1334,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return 0; case ScriptBaseClass.STATUS_ROTATE_X: - if (m_host.GetAxisRotation(2) == 2) + // if (m_host.GetAxisRotation(2) != 0) + if (m_host.GetAxisRotation((int)SceneObjectGroup.axisSelect.STATUS_ROTATE_X) != 0) return 1; else return 0; case ScriptBaseClass.STATUS_ROTATE_Y: - if (m_host.GetAxisRotation(4) == 4) + if (m_host.GetAxisRotation((int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Y) != 0) return 1; else return 0; case ScriptBaseClass.STATUS_ROTATE_Z: - if (m_host.GetAxisRotation(8) == 8) + if (m_host.GetAxisRotation((int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Z) != 0) return 1; else return 0; -- cgit v1.1 From cf89e29ac315cbac74361b8fd85e0fdbf6157f09 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 18 Dec 2012 19:19:58 -0800 Subject: BulletSim: comments and TODO list update --- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 9 +++++++-- OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | 3 ++- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 758d92b..1c6f946 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -100,10 +100,15 @@ public sealed class BSPrim : BSPhysObject BaseShape = pbs; _isPhysical = pisPhysical; _isVolumeDetect = false; - _friction = PhysicsScene.Params.defaultFriction; // TODO: compute based on object material - _density = PhysicsScene.Params.defaultDensity; // TODO: compute based on object material + + // 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; + _vehicle = new BSDynamics(PhysicsScene, this); // add vehicleness + _mass = CalculateMass(); // No body or shape yet diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 0d9a156..ad4e42b 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -6,7 +6,7 @@ Eliminate all crashes (DONEish) Enable vehicle border crossings (at least as poorly as ODE) Avatar created in previous region and not new region when crossing border Vehicle recreated in new sim at small Z value (offset from root value?) (DONE) -Calibrate turning radius +Calibrate turning radius (DONE) limitMotorUp calibration (more down?) study PID motors (include 'efficiency' implementation Add to avatar movement @@ -82,6 +82,7 @@ Add osGetPhysicsEngineName() so scripters can tell whether BulletSim or ODE Also osGetPhysicsEngineVerion() maybe. Linkset.Position and Linkset.Orientation requre rewrite to properly return child position. LinksetConstraint acts like it's at taint time!! +Implement LockAngularMotion -- implements llSetStatus(ROTATE_AXIS_*, T/F) LINKSETS ====================================================== -- cgit v1.1 From 7b84bcfbb8817feca25f33db85bee6c1fc7f0b98 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 18 Dec 2012 22:59:59 -0800 Subject: BulletSim: initial implementation of a PID motor. Not hooked up yet. --- OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 44 ++++++++++++++++++++---- 1 file changed, 38 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index e0faf4e..c718228 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -117,12 +117,12 @@ public class BSVMotor : BSMotor // A form of stepping that does not take the time quantum into account. // The caller must do the right thing later. - public Vector3 Step() + public virtual Vector3 Step() { return Step(1f); } - public Vector3 Step(float timeStep) + public virtual Vector3 Step(float timeStep) { Vector3 returnCurrent = Vector3.Zero; if (!CurrentValue.ApproxEquals(TargetValue, 0.01f)) @@ -204,17 +204,49 @@ public class BSFMotor : BSMotor public void SetTarget(float target) { } - public float Step(float timeStep) + public virtual float Step(float timeStep) { return 0f; } } -public class BSPIDMotor : BSMotor + +// Proportional, Integral, Derivitive Motor +// Good description at http://www.answers.com/topic/pid-controller . Includes processes for choosing p, i and d factors. +public class BSPIDVMotor : BSVMotor { - // TODO: write and use this one - public BSPIDMotor(string useName) + public Vector3 pFactor { get; set; } // Amount of direct correction of an error (sometimes called 'proportional gain') + public Vector3 iFactor { get; set; } // + public Vector3 dFactor { get; set; } + + Vector3 IntegralFactor { get; set; } + Vector3 LastError { get; set; } + + public BSPIDVMotor(string useName) : base(useName) { + // larger makes more overshoot, smaller means converge quicker. Range of 0.1 to 10. + pFactor = new Vector3(1.00f, 1.00f, 1.00f); + iFactor = new Vector3(1.00f, 1.00f, 1.00f); + dFactor = new Vector3(1.00f, 1.00f, 1.00f); + } + + public override Vector3 Step(float timeStep) + { + // How far are we from where we should be + Vector3 error = TargetValue - CurrentValue; + + // Add up the error so we can integrate over the accumulated errors + IntegralFactor += error * timeStep; + + // A simple derivitive is the rate of change from the last error. + Vector3 derivFactor = (error - LastError) * timeStep; + LastError = error; + + // Proportion Integral Derivitive + // Correction = proportionOfPresentError + accumulationOfPastError + rateOfChangeOfError + Vector3 ret = error * pFactor + IntegralFactor * iFactor + derivFactor * dFactor; + + return ret; } } } -- cgit v1.1 From a9b9c0f0351a6749bf55c29b2891fa40928b4c39 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 18 Dec 2012 23:05:59 -0800 Subject: BulletSim: improve angularVerticalAttraction calculation to compute angular correction velocity rather than estimating correction (excuse to use trig functions). --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 33 ++++++++++------------ 1 file changed, 15 insertions(+), 18 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 5887249..912aadd 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -1003,7 +1003,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Not colliding if the vehicle is off the ground if (!Prim.IsColliding) { - // downForce = new Vector3(0, 0, (-distanceAboveGround / m_bankingTimescale) * pTimestep); // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); ret = new Vector3(0, 0, -distanceAboveGround); } @@ -1135,31 +1134,30 @@ namespace OpenSim.Region.Physics.BulletSPlugin // zero and one. // The value of Z is how far the rotation is off with 1 meaning none and 0 being 90 degrees. + // Y error means needed rotation around X axis and visa versa. + // Since the error goes from zero to one, the asin is the corresponding angle. + ret.X = (float)Math.Asin(verticalError.Y); + ret.Y = (float)Math.Asin(verticalError.X); + // If verticalError.Z is negative, the vehicle is upside down. Add additional push. if (verticalError.Z < 0f) { - verticalError.X = 2f - verticalError.X; - verticalError.Y = 2f - verticalError.Y; + ret.X += (float)Math.PI / 4f; + ret.Y += (float)Math.PI / 4f; } - // Y error means needed rotation around X axis and visa versa. - ret.X = verticalError.Y; - ret.Y = - verticalError.X; - ret.Z = 0f; - - // Scale the correction force by how far we're off from vertical. - // Z error of one says little error. As Z gets smaller, the vehicle is leaning farther over. - float clampedSqrZError = ClampInRange(0.01f, verticalError.Z * verticalError.Z, 1f); - float vertForce = 1f / clampedSqrZError; - - ret *= vertForce; + // Put the signs back on so the rotation is in the correct direction. + ret.X *= (float)Math.Sign(verticalError.Y); + // (Tilt forward (positive X) needs to tilt back (rotate negative) around Y axis.) + ret.Y *= -(float)Math.Sign(verticalError.X); - // Correction happens over a number of seconds. + // 'ret' is now the necessary velocity to correct tilt in one second. + // Correction happens over a number of seconds. Vector3 unscaledContrib = ret; ret /= m_verticalAttractionTimescale; - VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},vertForce={3},eff={4},vertAttr={5}", - Prim.LocalID, verticalError, unscaledContrib, vertForce, m_verticalAttractionEfficiency, ret); + VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},eff={3},vertAttr={4}", + Prim.LocalID, verticalError, unscaledContrib, m_verticalAttractionEfficiency, ret); } return ret; } @@ -1172,7 +1170,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin public Vector3 ComputeAngularDeflection() { Vector3 ret = Vector3.Zero; - return ret; // DEBUG DEBUG DEBUG debug one force at a time if (m_angularDeflectionEfficiency != 0) { -- cgit v1.1 From b7ad44e3a687041a5a4761f1d0739a4226a901c2 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 20 Dec 2012 08:35:36 -0800 Subject: BulletSim: reorganize motor step code to separate error computation allowing subclass for PID error correction. --- OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 142 +++++++++++++++-------- 1 file changed, 91 insertions(+), 51 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index c718228..b57d2c8 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -29,13 +29,14 @@ using System; using System.Collections.Generic; using System.Text; using OpenMetaverse; +using OpenSim.Framework; namespace OpenSim.Region.Physics.BulletSPlugin { public abstract class BSMotor { // Timescales and other things can be turned off by setting them to 'infinite'. - public const float Infinite = 12345f; + public const float Infinite = 12345.6f; public readonly static Vector3 InfiniteVector = new Vector3(BSMotor.Infinite, BSMotor.Infinite, BSMotor.Infinite); public BSMotor(string useName) @@ -62,12 +63,16 @@ public abstract class BSMotor } } } -// Can all the incremental stepping be replaced with motor classes? // Motor which moves CurrentValue to TargetValue over TimeScale seconds. // The TargetValue decays in TargetValueDecayTimeScale and // the CurrentValue will be held back by FrictionTimeScale. -// TimeScale and TargetDelayTimeScale may be 'infinite' which means go decay. +// This motor will "zero itself" over time in that the targetValue will +// decay to zero and the currentValue will follow it to that zero. +// The overall effect is for the returned correction value to go from large +// values (the total difference between current and target minus friction) +// to small and eventually zero values. +// TimeScale and TargetDelayTimeScale may be 'infinite' which means no decay. // For instance, if something is moving at speed X and the desired speed is Y, // CurrentValue is X and TargetValue is Y. As the motor is stepped, new @@ -81,13 +86,15 @@ public class BSVMotor : BSMotor // public Vector3 FrameOfReference { get; set; } // public Vector3 Offset { get; set; } - public float TimeScale { get; set; } - public float TargetValueDecayTimeScale { get; set; } - public Vector3 FrictionTimescale { get; set; } - public float Efficiency { get; set; } + public virtual float TimeScale { get; set; } + public virtual float TargetValueDecayTimeScale { get; set; } + public virtual Vector3 FrictionTimescale { get; set; } + public virtual float Efficiency { get; set; } + + public virtual float ErrorZeroThreshold { get; set; } - public Vector3 TargetValue { get; private set; } - public Vector3 CurrentValue { get; private set; } + public virtual Vector3 TargetValue { get; private set; } + public virtual Vector3 CurrentValue { get; private set; } public BSVMotor(string useName) : base(useName) @@ -96,6 +103,7 @@ public class BSVMotor : BSMotor Efficiency = 1f; FrictionTimescale = BSMotor.InfiniteVector; CurrentValue = TargetValue = Vector3.Zero; + ErrorZeroThreshold = 0.01f; } public BSVMotor(string useName, float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency) : this(useName) @@ -115,24 +123,19 @@ public class BSVMotor : BSMotor TargetValue = target; } - // A form of stepping that does not take the time quantum into account. - // The caller must do the right thing later. - public virtual Vector3 Step() - { - return Step(1f); - } - + // Compute the next step and return the new current value public virtual Vector3 Step(float timeStep) { - Vector3 returnCurrent = Vector3.Zero; - if (!CurrentValue.ApproxEquals(TargetValue, 0.01f)) + Vector3 origTarget = TargetValue; // DEBUG + Vector3 origCurrVal = CurrentValue; // DEBUG + + Vector3 correction = Vector3.Zero; + Vector3 error = TargetValue - CurrentValue; + if (!error.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)) { - Vector3 origTarget = TargetValue; // DEBUG - Vector3 origCurrVal = CurrentValue; // DEBUG + correction = Step(timeStep, error); - // Addition = (desiredVector - currentAppliedVector) / secondsItShouldTakeToComplete - Vector3 addAmount = (TargetValue - CurrentValue)/TimeScale * timeStep; - CurrentValue += addAmount; + CurrentValue += correction; // The desired value reduces to zero which also reduces the difference with current. // If the decay time is infinite, don't decay at all. @@ -143,39 +146,50 @@ public class BSVMotor : BSMotor TargetValue *= (1f - decayFactor); } + // The amount we can correct the error is reduced by the friction Vector3 frictionFactor = Vector3.Zero; if (FrictionTimescale != BSMotor.InfiniteVector) { // frictionFactor = (Vector3.One / FrictionTimescale) * timeStep; // Individual friction components can be 'infinite' so compute each separately. - frictionFactor.X = FrictionTimescale.X == BSMotor.Infinite ? 0f : (1f / FrictionTimescale.X) * timeStep; - frictionFactor.Y = FrictionTimescale.Y == BSMotor.Infinite ? 0f : (1f / FrictionTimescale.Y) * timeStep; - frictionFactor.Z = FrictionTimescale.Z == BSMotor.Infinite ? 0f : (1f / FrictionTimescale.Z) * timeStep; + frictionFactor.X = (FrictionTimescale.X == BSMotor.Infinite) ? 0f : (1f / FrictionTimescale.X); + frictionFactor.Y = (FrictionTimescale.Y == BSMotor.Infinite) ? 0f : (1f / FrictionTimescale.Y); + frictionFactor.Z = (FrictionTimescale.Z == BSMotor.Infinite) ? 0f : (1f / FrictionTimescale.Z); + frictionFactor *= timeStep; CurrentValue *= (Vector3.One - frictionFactor); } - returnCurrent = CurrentValue; - - MDetailLog("{0}, BSVMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},timeScale={5},addAmnt={6},targetDecay={7},decayFact={8},fricTS={9},frictFact={10}", + MDetailLog("{0}, BSVMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},error={5},corr={6},targetDecay={6},decayFact={7},frictFac{8},curr={9},target={10},ret={11}", BSScene.DetailLogZero, UseName, origCurrVal, origTarget, - timeStep, TimeScale, addAmount, - TargetValueDecayTimeScale, decayFactor, - FrictionTimescale, frictionFactor); - MDetailLog("{0}, BSVMotor.Step,nonZero,{1},curr={2},target={3},add={4},decay={5},frict={6},ret={7}", - BSScene.DetailLogZero, UseName, CurrentValue, TargetValue, - addAmount, decayFactor, frictionFactor, returnCurrent); + timeStep, error, correction, + TargetValueDecayTimeScale, decayFactor, frictionFactor, + CurrentValue, TargetValue, CurrentValue); } else { // Difference between what we have and target is small. Motor is done. CurrentValue = Vector3.Zero; TargetValue = Vector3.Zero; + MDetailLog("{0}, BSVMotor.Step,zero,{1},ret={2}", + BSScene.DetailLogZero, UseName, CurrentValue); + } - MDetailLog("{0}, BSVMotor.Step,zero,{1},curr={2},target={3},ret={4}", - BSScene.DetailLogZero, UseName, TargetValue, CurrentValue, returnCurrent); + return CurrentValue; + } + public virtual Vector3 Step(float timeStep, Vector3 error) + { + Vector3 returnCorrection = Vector3.Zero; + if (!error.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)) + { + // correction = error / secondsItShouldTakeToCorrect + Vector3 correctionAmount = error / TimeScale * timeStep; + returnCorrection = correctionAmount; + MDetailLog("{0}, BSVMotor.Step,nonZero,{1},timeStep={2},timeScale={3},err={4},corr={5},frictTS={6},ret={7}", + BSScene.DetailLogZero, UseName, timeStep, TimeScale, error, + correctionAmount, FrictionTimescale, returnCorrection); } - return returnCurrent; + return returnCorrection; } public override string ToString() { @@ -214,9 +228,14 @@ public class BSFMotor : BSMotor // Good description at http://www.answers.com/topic/pid-controller . Includes processes for choosing p, i and d factors. public class BSPIDVMotor : BSVMotor { - public Vector3 pFactor { get; set; } // Amount of direct correction of an error (sometimes called 'proportional gain') - public Vector3 iFactor { get; set; } // - public Vector3 dFactor { get; set; } + // Larger makes more overshoot, smaller means converge quicker. Range of 0.1 to 10. + public Vector3 proportionFactor { get; set; } + public Vector3 integralFactor { get; set; } + public Vector3 derivFactor { get; set; } + // Arbritrary factor range. + // EfficiencyHigh means move quickly to the correct number. EfficiencyLow means might over correct. + public float EfficiencyHigh = 0.4f; + public float EfficiencyLow = 4.0f; Vector3 IntegralFactor { get; set; } Vector3 LastError { get; set; } @@ -224,17 +243,39 @@ public class BSPIDVMotor : BSVMotor public BSPIDVMotor(string useName) : base(useName) { - // larger makes more overshoot, smaller means converge quicker. Range of 0.1 to 10. - pFactor = new Vector3(1.00f, 1.00f, 1.00f); - iFactor = new Vector3(1.00f, 1.00f, 1.00f); - dFactor = new Vector3(1.00f, 1.00f, 1.00f); + proportionFactor = new Vector3(1.00f, 1.00f, 1.00f); + integralFactor = new Vector3(1.00f, 1.00f, 1.00f); + derivFactor = new Vector3(1.00f, 1.00f, 1.00f); + IntegralFactor = Vector3.Zero; + LastError = Vector3.Zero; } - public override Vector3 Step(float timeStep) + public override void Zero() { - // How far are we from where we should be - Vector3 error = TargetValue - CurrentValue; + base.Zero(); + } + + public override float Efficiency + { + get { return base.Efficiency; } + set + { + base.Efficiency = Util.Clamp(value, 0f, 1f); + // Compute factors based on efficiency. + // If efficiency is high (1f), use a factor value that moves the error value to zero with little overshoot. + // If efficiency is low (0f), use a factor value that overcorrects. + // TODO: might want to vary contribution of different factor depending on efficiency. + float factor = ((1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow) / 3f; + // float factor = (1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow; + proportionFactor = new Vector3(factor, factor, factor); + integralFactor = new Vector3(factor, factor, factor); + derivFactor = new Vector3(factor, factor, factor); + } + } + // Ignore Current and Target Values and just advance the PID computation on this error. + public Vector3 Step(float timeStep, Vector3 error) + { // Add up the error so we can integrate over the accumulated errors IntegralFactor += error * timeStep; @@ -242,9 +283,8 @@ public class BSPIDVMotor : BSVMotor Vector3 derivFactor = (error - LastError) * timeStep; LastError = error; - // Proportion Integral Derivitive - // Correction = proportionOfPresentError + accumulationOfPastError + rateOfChangeOfError - Vector3 ret = error * pFactor + IntegralFactor * iFactor + derivFactor * dFactor; + // Correction = -(proportionOfPresentError + accumulationOfPastError + rateOfChangeOfError) + Vector3 ret = -(error * proportionFactor + IntegralFactor * integralFactor + derivFactor * derivFactor); return ret; } -- cgit v1.1 From e73dac4debcf79cba83b94255d62fce0815871cb Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 20 Dec 2012 10:19:16 -0800 Subject: BulletSim: angularMotorUp working again (seems a little slow as it takes longer than timescale to correct, but getting better). Disabled angularDeflection (need to resolve interactions between angular corrections). Update TODO list. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 65 +++++++++++++++------- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 33 +++++++---- 2 files changed, 66 insertions(+), 32 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 912aadd..77ec76d 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -91,6 +91,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin private Vector3 m_lastVertAttractor = Vector3.Zero; // what VA was last applied to body //Deflection properties + private BSVMotor m_angularDeflectionMotor = new BSVMotor("AngularDeflection"); private float m_angularDeflectionEfficiency = 0; private float m_angularDeflectionTimescale = 0; private float m_linearDeflectionEfficiency = 0; @@ -102,6 +103,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin private float m_bankingTimescale = 0; //Hover and Buoyancy properties + private BSVMotor m_hoverMotor = new BSVMotor("Hover"); private float m_VhoverHeight = 0f; private float m_VhoverEfficiency = 0f; private float m_VhoverTimescale = 0f; @@ -118,6 +120,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Timescale > cutoff means no vert attractor. private float m_verticalAttractionTimescale = 510f; + // Just some recomputed constants: + static readonly float PIOverFour = ((float)Math.PI) / 4f; + static readonly float PIOverTwo = ((float)Math.PI) / 2f; + public BSDynamics(BSScene myScene, BSPrim myPrim) { PhysicsScene = myScene; @@ -563,9 +569,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Vehicles report collision events so we know when it's on the ground BulletSimAPI.AddToCollisionFlags2(Prim.PhysBody.ptr, CollisionFlags.BS_VEHICLE_COLLISIONS); - // DEBUG DEBUG DEBUG: use uniform inertia to smooth movement added by Bullet - // Vector3 localInertia = new Vector3(1f, 1f, 1f); - // Vector3 localInertia = new Vector3(m_vehicleMass, m_vehicleMass, m_vehicleMass); Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(Prim.PhysShape.ptr, m_vehicleMass); BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia); BulletSimAPI.UpdateInertiaTensor2(Prim.PhysBody.ptr); @@ -613,7 +616,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin private Quaternion? m_knownOrientation; private Vector3? m_knownRotationalVelocity; private Vector3 m_knownRotationalForce; - private float? m_knownForwardSpeed; + private Vector3? m_knownForwardVelocity; // vehicle relative forward speed private const int m_knownChangedPosition = 1 << 0; private const int m_knownChangedVelocity = 1 << 1; @@ -632,7 +635,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_knownOrientation = null; m_knownRotationalVelocity = null; m_knownRotationalForce = Vector3.Zero; - m_knownForwardSpeed = null; + m_knownForwardVelocity = null; m_knownChanged = 0; } private void PushKnownChanged() @@ -755,13 +758,21 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_knownRotationalForce += aForce; m_knownChanged |= m_knownChangedRotationalForce; } + // Vehicle relative forward velocity + private Vector3 VehicleForwardVelocity + { + get + { + if (m_knownForwardVelocity == null) + m_knownForwardVelocity = VehicleVelocity * Quaternion.Inverse(Quaternion.Normalize(VehicleOrientation)); + return (Vector3)m_knownForwardVelocity; + } + } private float VehicleForwardSpeed { get { - if (m_knownForwardSpeed == null) - m_knownForwardSpeed = (VehicleVelocity * Quaternion.Inverse(VehicleOrientation)).X; - return (float)m_knownForwardSpeed; + return VehicleForwardVelocity.X; } } @@ -1025,7 +1036,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // set directly on the vehicle. private void MoveAngular(float pTimestep) { - // The user wants how many radians per second angular change? + // The user wants this many radians per second angular change? Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); // ================================================================== @@ -1137,27 +1148,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Y error means needed rotation around X axis and visa versa. // Since the error goes from zero to one, the asin is the corresponding angle. ret.X = (float)Math.Asin(verticalError.Y); - ret.Y = (float)Math.Asin(verticalError.X); + // (Tilt forward (positive X) needs to tilt back (rotate negative) around Y axis.) + ret.Y = -(float)Math.Asin(verticalError.X); // If verticalError.Z is negative, the vehicle is upside down. Add additional push. if (verticalError.Z < 0f) { - ret.X += (float)Math.PI / 4f; - ret.Y += (float)Math.PI / 4f; + ret.X += PIOverFour; + ret.Y += PIOverFour; } - // Put the signs back on so the rotation is in the correct direction. - ret.X *= (float)Math.Sign(verticalError.Y); - // (Tilt forward (positive X) needs to tilt back (rotate negative) around Y axis.) - ret.Y *= -(float)Math.Sign(verticalError.X); - // 'ret' is now the necessary velocity to correct tilt in one second. // Correction happens over a number of seconds. Vector3 unscaledContrib = ret; ret /= m_verticalAttractionTimescale; - VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},eff={3},vertAttr={4}", - Prim.LocalID, verticalError, unscaledContrib, m_verticalAttractionEfficiency, ret); + VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},eff={3},ts={4},vertAttr={5}", + Prim.LocalID, verticalError, unscaledContrib, m_verticalAttractionEfficiency, m_verticalAttractionTimescale, ret); } return ret; } @@ -1170,6 +1177,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin public Vector3 ComputeAngularDeflection() { Vector3 ret = Vector3.Zero; + return ret; // DEBUG DEBUG DEBUG + // Disable angular deflection for the moment. + // Since angularMotorUp and angularDeflection are computed independently, they will calculate + // approximately the same X or Y correction. When added together (when contributions are combined) + // this creates an over-correction and then wabbling as the target is overshot. + // TODO: rethink how the different correction computations inter-relate. if (m_angularDeflectionEfficiency != 0) { @@ -1181,15 +1194,24 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation; pointingDirection.Normalize(); - // The difference between what is and what should be + // The difference between what is and what should be. Vector3 deflectionError = movingDirection - pointingDirection; + // Don't try to correct very large errors (not our job) + if (Math.Abs(deflectionError.X) > PIOverFour) deflectionError.X = 0f; + if (Math.Abs(deflectionError.Y) > PIOverFour) deflectionError.Y = 0f; + if (Math.Abs(deflectionError.Z) > PIOverFour) deflectionError.Z = 0f; + + // ret = m_angularDeflectionCorrectionMotor(1f, deflectionError); + // Scale the correction by recovery timescale and efficiency - ret = (-deflectionError * VehicleForwardSpeed) * m_angularDeflectionEfficiency; + ret = (-deflectionError) * m_angularDeflectionEfficiency; ret /= m_angularDeflectionTimescale; VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}", Prim.LocalID, movingDirection, pointingDirection, deflectionError, ret); + VDetailLog("{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3}", + Prim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale); } return ret; } @@ -1305,6 +1327,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin private float ClampInRange(float low, float val, float high) { return Math.Max(low, Math.Min(val, high)); + // return Utils.Clamp(val, low, high); } // Invoke the detailed logger and output something if it's enabled. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index ad4e42b..8a9aec9 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -8,9 +8,10 @@ Enable vehicle border crossings (at least as poorly as ODE) Vehicle recreated in new sim at small Z value (offset from root value?) (DONE) Calibrate turning radius (DONE) limitMotorUp calibration (more down?) -study PID motors (include 'efficiency' implementation +study PID motors (include 'efficiency' implementation (DONE) Add to avatar movement + CRASHES ================================================= 20121129.1411: editting/moving phys object across region boundries causes crash @@ -25,7 +26,6 @@ CRASHES VEHICLES TODO LIST: ================================================= Border crossing with linked vehicle causes crash -Neb vehicle taking > 25ms of physics time!! Vehicles (Move smoothly) Add vehicle collisions so IsColliding is properly reported. Needed for banking, limitMotorUp, movementLimiting, ... @@ -34,28 +34,25 @@ Cannot edit/move a vehicle being ridden: it jumps back to the origional position Neb car jiggling left and right Happens on terrain and any other mesh object. Flat cubes are much smoother. This has been reduced but not eliminated. -Light cycle falling over when driving Implement referenceFrame for all the motion routines. Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE. Verify that angular motion specified around Z moves in the vehicle coordinates. Verify llGetVel() is returning a smooth and good value for vehicle movement. llGetVel() should return the root's velocity if requested in a child prim. Implement function efficiency for lineaar and angular motion. -Should vehicle angular/linear movement friction happen after all the components - or does it only apply to the basic movement? After getting off a vehicle, the root prim is phantom (can be walked through) Need to force a position update for the root prim after compound shape destruction Linkset explosion after three "rides" on Nebadon lite vehicle (LinksetConstraint) For limitMotorUp, use raycast down to find if vehicle is in the air. Remove vehicle angular velocity zeroing in BSPrim.UpdateProperties(). A kludge that isn't fixing the real problem of Bullet adding extra motion. +Incorporate inter-relationship of angular corrections. For instance, angularDeflection + and angularMotorUp will compute same X or Y correction. When added together + creates over-correction and over-shoot and wabbling. BULLETSIM TODO LIST: ================================================= Revisit CollisionMargin. Builders notice the 0.04 spacing between prims. -Avatar height off after unsitting (floats off ground) - Editting appearance then moving restores. - Must not be initializing height when recreating capsule after unsit. Duplicating a physical prim causes old prim to jump away Dup a phys prim and the original become unselected and thus interacts w/ selected prim. Scenes with hundred of thousands of static objects take a lot of physics CPU time. @@ -83,6 +80,8 @@ Add osGetPhysicsEngineName() so scripters can tell whether BulletSim or ODE Linkset.Position and Linkset.Orientation requre rewrite to properly return child position. LinksetConstraint acts like it's at taint time!! Implement LockAngularMotion -- implements llSetStatus(ROTATE_AXIS_*, T/F) +Should the different PID factors have non-equal contributions for different + values of Efficiency? LINKSETS ====================================================== @@ -100,17 +99,16 @@ Disable activity of passive linkset children. Since the linkset is a compound object, the old prims are left lying around and need to be phantomized so they don't collide, ... Speed up creation of large physical linksets - For instance, sitting in Neb's car (130 prims) takes several seconds to become physical + For instance, sitting in Neb's car (130 prims) takes several seconds to become physical. + REALLY bad for very large physical linksets (freezes the sim for many seconds). Eliminate collisions between objects in a linkset. (LinksetConstraint) Have UserPointer point to struct with localID and linksetID? Objects in original linkset still collide with each other? MORE ====================================================== -Find/remove avatar collision with ID=0. Test avatar walking up stairs. How does compare with SL. Radius of the capsule affects ability to climb edges. -Tune terrain/object friction to be closer to SL. Debounce avatar contact so legs don't keep folding up when standing. Implement LSL physics controls. Like STATUS_ROTATE_X. Add border extensions to terrain to help region crossings and objects leaving region. @@ -203,3 +201,16 @@ Single prim vehicles don't seem to properly vehiclize. Add material type linkage and input all the material property definitions. Skeleton classes and table are in the sources but are not filled or used. (Resolution: +Neb vehicle taking > 25ms of physics time!! + (Resolution: compound linksets were being rebuild WAY too often) +Avatar height off after unsitting (floats off ground) + Editting appearance then moving restores. + Must not be initializing height when recreating capsule after unsit. + (Resolution: confusion of scale vs size for native objects removed) +Light cycle falling over when driving (Resolution: implemented angularMotorUp) +Should vehicle angular/linear movement friction happen after all the components + or does it only apply to the basic movement? + (Resolution: friction added before returning newly computed motor value. + What is expected by some vehicles (turning up friction to moderate speed)) +Tune terrain/object friction to be closer to SL. + (Resolution: added material type with friction and resolution) -- cgit v1.1 From a5b2539cf92aac65c11a36d4eb41d04f1c55b042 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 20 Dec 2012 10:32:33 -0800 Subject: BulletSim: replace use of funky nullable values for vehicle property update control (m_known* stuff). Bitmaps will be quicker to test and to clear. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 69 ++++++++++++++-------- 1 file changed, 43 insertions(+), 26 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 77ec76d..c3d75ea 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -602,21 +602,22 @@ namespace OpenSim.Region.Physics.BulletSPlugin #region Known vehicle value functions // Vehicle physical parameters that we buffer from constant getting and setting. - // The "m_known*" variables are initialized to 'null', fetched only if referenced - // and stored back into the physics engine only if updated. + // The "m_known*" values are unknown until they are fetched and the m_knownHas flag is set. + // Changing is remembered and the parameter is stored back into the physics engine only if updated. // This does two things: 1) saves continuious calls into unmanaged code, and // 2) signals when a physics property update must happen back to the simulator // to update values modified for the vehicle. private int m_knownChanged; - private float? m_knownTerrainHeight; - private float? m_knownWaterLevel; - private Vector3? m_knownPosition; - private Vector3? m_knownVelocity; + private int m_knownHas; + private float m_knownTerrainHeight; + private float m_knownWaterLevel; + private Vector3 m_knownPosition; + private Vector3 m_knownVelocity; private Vector3 m_knownForce; - private Quaternion? m_knownOrientation; - private Vector3? m_knownRotationalVelocity; + private Quaternion m_knownOrientation; + private Vector3 m_knownRotationalVelocity; private Vector3 m_knownRotationalForce; - private Vector3? m_knownForwardVelocity; // vehicle relative forward speed + private Vector3 m_knownForwardVelocity; // vehicle relative forward speed private const int m_knownChangedPosition = 1 << 0; private const int m_knownChangedVelocity = 1 << 1; @@ -624,18 +625,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin private const int m_knownChangedOrientation = 1 << 3; private const int m_knownChangedRotationalVelocity = 1 << 4; private const int m_knownChangedRotationalForce = 1 << 5; + private const int m_knownChangedTerrainHeight = 1 << 6; + private const int m_knownChangedWaterLevel = 1 << 7; + private const int m_knownChangedForwardVelocity = 1 << 7; private void ForgetKnownVehicleProperties() { - m_knownTerrainHeight = null; - m_knownWaterLevel = null; - m_knownPosition = null; - m_knownVelocity = null; - m_knownForce = Vector3.Zero; - m_knownOrientation = null; - m_knownRotationalVelocity = null; - m_knownRotationalForce = Vector3.Zero; - m_knownForwardVelocity = null; + m_knownHas = 0; m_knownChanged = 0; } private void PushKnownChanged() @@ -674,17 +670,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin // is used ot fetch the height only once for each vehicle simulation step. private float GetTerrainHeight(Vector3 pos) { - if (m_knownTerrainHeight == null) + if ((m_knownHas & m_knownChangedTerrainHeight) == 0) + { m_knownTerrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); - return (float)m_knownTerrainHeight; + m_knownHas |= m_knownChangedTerrainHeight; + } + return m_knownTerrainHeight; } // Since the computation of water level can be a little involved, this routine // is used ot fetch the level only once for each vehicle simulation step. private float GetWaterLevel(Vector3 pos) { - if (m_knownWaterLevel == null) + if ((m_knownHas & m_knownChangedWaterLevel) == 0) + { m_knownWaterLevel = Prim.PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(pos); + m_knownHas |= m_knownChangedWaterLevel; + } return (float)m_knownWaterLevel; } @@ -692,8 +694,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin { get { - if (m_knownPosition == null) + if ((m_knownHas & m_knownChangedPosition) == 0) + { m_knownPosition = Prim.ForcePosition; + m_knownHas |= m_knownChangedPosition; + } return (Vector3)m_knownPosition; } set @@ -707,8 +712,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin { get { - if (m_knownOrientation == null) + if ((m_knownHas & m_knownChangedOrientation) == 0) + { m_knownOrientation = Prim.ForceOrientation; + m_knownHas |= m_knownChangedOrientation; + } return (Quaternion)m_knownOrientation; } set @@ -722,8 +730,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin { get { - if (m_knownVelocity == null) + if ((m_knownHas & m_knownChangedVelocity) == 0) + { m_knownVelocity = Prim.ForceVelocity; + m_knownHas |= m_knownChangedVelocity; + } return (Vector3)m_knownVelocity; } set @@ -743,8 +754,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin { get { - if (m_knownRotationalVelocity == null) + if ((m_knownHas & m_knownChangedRotationalVelocity) == 0) + { m_knownRotationalVelocity = Prim.ForceRotationalVelocity; + m_knownHas |= m_knownChangedRotationalVelocity; + } return (Vector3)m_knownRotationalVelocity; } set @@ -763,8 +777,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin { get { - if (m_knownForwardVelocity == null) + if ((m_knownHas & m_knownChangedForwardVelocity) == 0) + { m_knownForwardVelocity = VehicleVelocity * Quaternion.Inverse(Quaternion.Normalize(VehicleOrientation)); + m_knownHas |= m_knownChangedForwardVelocity; + } return (Vector3)m_knownForwardVelocity; } } -- cgit v1.1 From e522bdb96a86ed1789e1438e4aac1ed522db70b8 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 20 Dec 2012 16:05:33 -0800 Subject: BulletSim: Check for unspecified TimeScale in BSVMotor and don't scale if not specified. Add test dump routine. Don'e zero current and target values when error goes to zero as the values could be used externally to store the actual target values, etc. --- OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 52 ++++++++++++++++++++---- 1 file changed, 43 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index b57d2c8..a6af40d 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -46,6 +46,7 @@ public abstract class BSMotor } public virtual void Reset() { } public virtual void Zero() { } + public virtual void GenerateTestOutput(float timeStep) { } // A name passed at motor creation for easily identifyable debugging messages. public string UseName { get; private set; } @@ -93,8 +94,9 @@ public class BSVMotor : BSMotor public virtual float ErrorZeroThreshold { get; set; } - public virtual Vector3 TargetValue { get; private set; } - public virtual Vector3 CurrentValue { get; private set; } + public virtual Vector3 TargetValue { get; protected set; } + public virtual Vector3 CurrentValue { get; protected set; } + public virtual Vector3 LastError { get; protected set; } public BSVMotor(string useName) : base(useName) @@ -122,6 +124,11 @@ public class BSVMotor : BSMotor { TargetValue = target; } + public override void Zero() + { + base.Zero(); + CurrentValue = TargetValue = Vector3.Zero; + } // Compute the next step and return the new current value public virtual Vector3 Step(float timeStep) @@ -168,21 +175,25 @@ public class BSVMotor : BSMotor else { // Difference between what we have and target is small. Motor is done. - CurrentValue = Vector3.Zero; - TargetValue = Vector3.Zero; - MDetailLog("{0}, BSVMotor.Step,zero,{1},ret={2}", - BSScene.DetailLogZero, UseName, CurrentValue); + CurrentValue = TargetValue; + MDetailLog("{0}, BSVMotor.Step,zero,{1},origTgt={2},origCurr={3},ret={2}", + BSScene.DetailLogZero, UseName, origCurrVal, origTarget, CurrentValue); } return CurrentValue; } public virtual Vector3 Step(float timeStep, Vector3 error) { + LastError = error; Vector3 returnCorrection = Vector3.Zero; if (!error.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)) { // correction = error / secondsItShouldTakeToCorrect - Vector3 correctionAmount = error / TimeScale * timeStep; + Vector3 correctionAmount; + if (TimeScale == 0f || TimeScale == BSMotor.Infinite) + correctionAmount = error * timeStep; + else + correctionAmount = error / TimeScale * timeStep; returnCorrection = correctionAmount; MDetailLog("{0}, BSVMotor.Step,nonZero,{1},timeStep={2},timeScale={3},err={4},corr={5},frictTS={6},ret={7}", @@ -191,6 +202,30 @@ public class BSVMotor : BSMotor } return returnCorrection; } + + // The user sets all the parameters and calls this which outputs values until error is zero. + public override void GenerateTestOutput(float timeStep) + { + // maximum number of outputs to generate. + int maxOutput = 50; + MDetailLog("{0},BSVMotor.Test,{1},===================================== BEGIN Test Output", BSScene.DetailLogZero, UseName); + MDetailLog("{0},BSVMotor.Test,{1},timeScale={2},targDlyTS={3},frictTS={4},eff={5},curr={6},tgt={7}", + BSScene.DetailLogZero, UseName, + TimeScale, TargetValueDecayTimeScale, FrictionTimescale, Efficiency, + CurrentValue, TargetValue); + + LastError = BSMotor.InfiniteVector; + while (maxOutput-- > 0 && !LastError.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)) + { + Vector3 lastStep = Step(timeStep); + MDetailLog("{0},BSVMotor.Test,{1},cur={2},tgt={3},lastError={4},lastStep={5}", + BSScene.DetailLogZero, UseName, CurrentValue, TargetValue, LastError, lastStep); + } + MDetailLog("{0},BSVMotor.Test,{1},===================================== END Test Output", BSScene.DetailLogZero, UseName); + + + } + public override string ToString() { return String.Format("<{0},curr={1},targ={2},decayTS={3},frictTS={4}>", @@ -238,7 +273,6 @@ public class BSPIDVMotor : BSVMotor public float EfficiencyLow = 4.0f; Vector3 IntegralFactor { get; set; } - Vector3 LastError { get; set; } public BSPIDVMotor(string useName) : base(useName) @@ -274,7 +308,7 @@ public class BSPIDVMotor : BSVMotor } // Ignore Current and Target Values and just advance the PID computation on this error. - public Vector3 Step(float timeStep, Vector3 error) + public override Vector3 Step(float timeStep, Vector3 error) { // Add up the error so we can integrate over the accumulated errors IntegralFactor += error * timeStep; -- cgit v1.1 From 9d2f569d600cad688ac7e06fcac7e94023b3600a Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 20 Dec 2012 16:06:52 -0800 Subject: BulletSim: fix incorrectly defined property changed flag. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index c3d75ea..a5acd86 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -627,7 +627,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin private const int m_knownChangedRotationalForce = 1 << 5; private const int m_knownChangedTerrainHeight = 1 << 6; private const int m_knownChangedWaterLevel = 1 << 7; - private const int m_knownChangedForwardVelocity = 1 << 7; + private const int m_knownChangedForwardVelocity = 1 << 8; private void ForgetKnownVehicleProperties() { @@ -860,13 +860,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ================================================================== // Clamp high or low velocities float newVelocityLengthSq = newVelocity.LengthSquared(); - // if (newVelocityLengthSq > 1e6f) if (newVelocityLengthSq > 1000f) { newVelocity /= newVelocity.Length(); newVelocity *= 1000f; } - // else if (newVelocityLengthSq < 1e-6f) else if (newVelocityLengthSq < 0.001f) newVelocity = Vector3.Zero; -- cgit v1.1 From 750492796d3f19028ddd7fdf5f696933f083fd33 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 21 Dec 2012 09:55:20 -0800 Subject: BulletSim: begin movement of parameters from pinned memory block to variables all in managed code. Add note to TODO list to remember to do the rest. Other updates to TODO list. --- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 10 ++++++++++ OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | 16 +++++++++------- 2 files changed, 19 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 069cb0d..2ca4912 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -96,6 +96,16 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public long SimulationStep { get { return m_simulationStep; } } private int m_taintsToProcessPerStep; + // Avatar parameters + public float ParamAvatarFriction { get; private set; } + public float ParamAvatarStandingFriction { get; private set; } + public float ParamAvatarDensity { get; private set; } + public float ParamAvatarRestitution { get; private set; } + public float ParamAvatarCapsuleWidth { get; private set; } + public float ParamAvatarCapsuleDepth { get; private set; } + public float ParamAvatarCapsuleHeight { get; private set; } + public float ParamAvatarContactProcessingThreshold { get; private set; } + public delegate void PreStepAction(float timeStep); public event PreStepAction BeforeStep; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 8a9aec9..c084ab4 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -1,16 +1,16 @@ CURRENT PRIORITIES ================================================= -Eliminate all crashes (DONEish) - Editing/deleting physical linkset (DONE) - Border crossing of physical linkset (DONE) +Smooth avatar movement with motor + Should motor update be all at taint-time? Enable vehicle border crossings (at least as poorly as ODE) + Terrain skirts Avatar created in previous region and not new region when crossing border Vehicle recreated in new sim at small Z value (offset from root value?) (DONE) -Calibrate turning radius (DONE) +Vehicle movement on terrain smoothness +Vehicle script tuning/debugging + Avanti speed script + Weapon shooter script limitMotorUp calibration (more down?) -study PID motors (include 'efficiency' implementation (DONE) - Add to avatar movement - CRASHES ================================================= @@ -139,6 +139,8 @@ Consider moving prim/character body and shape destruction in destroy() to postTimeTime rather than protecting all the potential sets that might have been queued up. Remove unused fields from ShapeData (not used in API2) +Remove unused fields from pinned memory shared parameter block + Create parameter variables in BSScene to replace same. Breakout code for mesh/hull/compound/native into separate BSShape* classes Standardize access to building and reference code. The skeleton classes are in the sources but are not complete or linked in. -- cgit v1.1 From b4f8a05e9a30373942c3a0511e43dcce3df11184 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 21 Dec 2012 09:56:31 -0800 Subject: BulletSim: Better detail logging of VMotor actions. --- OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index a6af40d..34a87c6 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -166,11 +166,13 @@ public class BSVMotor : BSMotor CurrentValue *= (Vector3.One - frictionFactor); } - MDetailLog("{0}, BSVMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},error={5},corr={6},targetDecay={6},decayFact={7},frictFac{8},curr={9},target={10},ret={11}", + MDetailLog("{0}, BSVMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},err={5},corr={6}", BSScene.DetailLogZero, UseName, origCurrVal, origTarget, - timeStep, error, correction, - TargetValueDecayTimeScale, decayFactor, frictionFactor, - CurrentValue, TargetValue, CurrentValue); + timeStep, error, correction); + MDetailLog("{0}, BSVMotor.Step,nonZero,{1},tgtDecayTS={2},decayFact={3},frictTS={4},frictFact={5},tgt={6},curr={7}", + BSScene.DetailLogZero, UseName, + TargetValueDecayTimeScale, decayFactor, FrictionTimescale, frictionFactor, + TargetValue, CurrentValue); } else { @@ -196,9 +198,8 @@ public class BSVMotor : BSMotor correctionAmount = error / TimeScale * timeStep; returnCorrection = correctionAmount; - MDetailLog("{0}, BSVMotor.Step,nonZero,{1},timeStep={2},timeScale={3},err={4},corr={5},frictTS={6},ret={7}", - BSScene.DetailLogZero, UseName, timeStep, TimeScale, error, - correctionAmount, FrictionTimescale, returnCorrection); + MDetailLog("{0}, BSVMotor.Step,nonZero,{1},timeStep={2},timeScale={3},err={4},corr={5}", + BSScene.DetailLogZero, UseName, timeStep, TimeScale, error, correctionAmount); } return returnCorrection; } -- cgit v1.1 From 8c99f63239702bcdb8f1e0efa57efc91c98fc3d7 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 21 Dec 2012 10:00:03 -0800 Subject: BulletSim: avatar movement smoothed with motor that modifies avatar velocity to target velocity. Fails in incorporating physical world effects (gravity) so avatar doesn't fly correctly. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 77 +++++++++++++++++++++- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 8 ++- 2 files changed, 81 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 4dd6264..695896e 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -69,6 +69,8 @@ public sealed class BSCharacter : BSPhysObject private OMV.Vector3 _appliedVelocity; // the last velocity applied to the avatar private float _currentFriction; // the friction currently being used (changed by setVelocity). + private BSVMotor _velocityMotor; + private OMV.Vector3 _PIDTarget; private bool _usePID; private float _PIDTau; @@ -89,6 +91,18 @@ public sealed class BSCharacter : BSPhysObject if (_size.X == 0f) _size.X = PhysicsScene.Params.avatarCapsuleDepth; if (_size.Y == 0f) _size.Y = PhysicsScene.Params.avatarCapsuleWidth; + // A motor to control the acceleration and deceleration of the avatar movement. + // _velocityMotor = new BSVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); + // _velocityMotor = new BSPIDVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); + // Infinite decay and timescale values so motor only changes current to target values. + _velocityMotor = new BSVMotor("BSCharacter.Velocity", + 0.2f, // time scale + BSMotor.Infinite, // decay time scale + BSMotor.InfiniteVector, // friction timescale + 1f // efficiency + ); + _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages. + _flying = isFlying; _orientation = OMV.Quaternion.Identity; _velocity = OMV.Vector3.Zero; @@ -138,6 +152,10 @@ public sealed class BSCharacter : BSPhysObject ForcePosition = _position; // Set the velocity and compute the proper friction ForceVelocity = _velocity; + // Setting the current and target in the motor will cause it to start computing any deceleration. + _velocityMotor.Reset(); + _velocityMotor.SetCurrent(_velocity); + _velocityMotor.SetTarget(_velocity); // This will enable or disable the flying buoyancy of the avatar. // Needs to be reset especially when an avatar is recreated after crossing a region boundry. @@ -239,6 +257,7 @@ public sealed class BSCharacter : BSPhysObject public override void ZeroMotion(bool inTaintTime) { _velocity = OMV.Vector3.Zero; + _velocityMotor.Zero(); _acceleration = OMV.Vector3.Zero; _rotationalVelocity = OMV.Vector3.Zero; @@ -400,10 +419,38 @@ public sealed class BSCharacter : BSPhysObject public override OMV.Vector3 GeometricCenter { get { return OMV.Vector3.Zero; } } public override OMV.Vector3 CenterOfMass { get { return OMV.Vector3.Zero; } } + + // Sets the target in the motor. This starts the changing of the avatar's velocity. + public override OMV.Vector3 TargetVelocity + { + get + { + return _velocityMotor.TargetValue; + } + set + { + DetailLog("{0},BSCharacter.setTargetVelocity,call,vel={1}", LocalID, value); + OMV.Vector3 targetVel = value; + PhysicsScene.TaintedObject("BSCharacter.setTargetVelocity", delegate() + { + float timeStep = 0.089f; // DEBUG DEBUG FIX FIX FIX + _velocityMotor.Reset(); + _velocityMotor.SetTarget(targetVel); + _velocityMotor.SetCurrent(_velocity); + // Compute a velocity value and make sure it gets pushed into the avatar. + // This makes sure the avatar will start from a stop. + ForceVelocity = _velocityMotor.Step(timeStep); + }); + } + } + // Directly setting velocity means this is what the user really wants now. public override OMV.Vector3 Velocity { get { return _velocity; } set { _velocity = value; + _velocityMotor.Reset(); + _velocityMotor.SetCurrent(_velocity); + _velocityMotor.SetTarget(_velocity); // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity); PhysicsScene.TaintedObject("BSCharacter.setVelocity", delegate() { @@ -415,6 +462,8 @@ public sealed class BSCharacter : BSPhysObject public override OMV.Vector3 ForceVelocity { get { return _velocity; } set { + PhysicsScene.AssertInTaintTime("BSCharacter.ForceVelocity"); + // Depending on whether the avatar is moving or not, change the friction // to keep the avatar from slipping around if (_velocity.Length() == 0) @@ -511,6 +560,13 @@ public sealed class BSCharacter : BSPhysObject get { return _flying; } set { _flying = value; + + // Velocity movement is different when flying: flying velocity degrades over time. + if (_flying) + _velocityMotor.TargetValueDecayTimeScale = 1f; + else + _velocityMotor.TargetValueDecayTimeScale = BSMotor.Infinite; + // simulate flying by changing the effect of gravity Buoyancy = ComputeBuoyancyFromFlying(_flying); } @@ -581,7 +637,10 @@ public sealed class BSCharacter : BSPhysObject } public override float ForceBuoyancy { get { return _buoyancy; } - set { _buoyancy = value; + set { + PhysicsScene.AssertInTaintTime("BSCharacter.ForceBuoyancy"); + + _buoyancy = value; DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); // Buoyancy is faked by changing the gravity applied to the object float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); @@ -698,6 +757,21 @@ public sealed class BSCharacter : BSPhysObject LastEntityProperties = CurrentEntityProperties; CurrentEntityProperties = entprop; + // Avatars don't respond to world friction, etc. They only go the speed I tell them too. + // Special kludge here for falling. Even though the target velocity might not have a + // Z component, the avatar could be falling (walked off a ledge, stopped flying, ...) + // and that velocity component must be retained. + float timeStep = 0.089f; // DEBUG DEBUG FIX FIX FIX + OMV.Vector3 stepVelocity = _velocityMotor.Step(timeStep); + stepVelocity.Z += entprop.Velocity.Z; + _velocity = stepVelocity; + BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); + /* + OMV.Vector3 stepVelocity = _velocityMotor.Step(timeStep); + OMV.Vector3 avVel = new OMV.Vector3(stepVelocity.X, stepVelocity.Y, entprop.Velocity.Z); + _velocity = avVel; + BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, avVel); + if (entprop.Velocity != LastEntityProperties.Velocity) { // Changes in the velocity are suppressed in avatars. @@ -706,6 +780,7 @@ public sealed class BSCharacter : BSPhysObject _velocity = avVel; BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, avVel); } + */ // Tell the linkset about value changes Linkset.UpdateProperties(this, true); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 1c6f946..68a0db6 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -532,16 +532,18 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject("BSPrim.setVelocity", delegate() { // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); - if (PhysBody.HasPhysicalBody) - BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); + ForceVelocity = _velocity; }); } } public override OMV.Vector3 ForceVelocity { get { return _velocity; } set { + PhysicsScene.AssertInTaintTime("BSPrim.ForceVelocity"); + _velocity = value; - BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); + if (PhysBody.HasPhysicalBody) + BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); } } public override OMV.Vector3 Torque { -- cgit v1.1 From 2e3e95e84634853366d61fa483b44597f8c53797 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 21 Dec 2012 10:04:12 -0800 Subject: BulletSim: small fix to avatar movement motor use which keeps avatar from flying up forever. This doesn't fix the overall problem but keeps avatar flying from being totally unusable. --- OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 695896e..57c5898 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -763,7 +763,8 @@ public sealed class BSCharacter : BSPhysObject // and that velocity component must be retained. float timeStep = 0.089f; // DEBUG DEBUG FIX FIX FIX OMV.Vector3 stepVelocity = _velocityMotor.Step(timeStep); - stepVelocity.Z += entprop.Velocity.Z; + // Remove next line so avatars don't fly up forever. DEBUG DEBUG this is only temporary. + // stepVelocity.Z += entprop.Velocity.Z; _velocity = stepVelocity; BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); /* -- cgit v1.1 From ae4d932e7f00e781db9c9cdd5c29efc51e2425fb Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 21 Dec 2012 13:35:44 -0800 Subject: BulletSim: Move all the parameter variables, tables and get and fetch logic to a separate, static class for easier addition and to remove all that bulk from the BSScene class. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 30 +- .../Region/Physics/BulletSPlugin/BSConstraint.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 2 +- .../Physics/BulletSPlugin/BSLinksetConstraints.cs | 14 +- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 558 +++++++++++++++++++++ OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 26 +- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 549 ++------------------ .../Physics/BulletSPlugin/BSShapeCollection.cs | 12 +- .../Physics/BulletSPlugin/BSTerrainHeightmap.cs | 8 +- .../Physics/BulletSPlugin/BSTerrainManager.cs | 10 +- .../Region/Physics/BulletSPlugin/BSTerrainMesh.cs | 6 +- .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 68 +-- 13 files changed, 681 insertions(+), 606 deletions(-) create mode 100755 OpenSim/Region/Physics/BulletSPlugin/BSParam.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 57c5898..7bde1c1 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -88,8 +88,8 @@ public sealed class BSCharacter : BSPhysObject // Old versions of ScenePresence passed only the height. If width and/or depth are zero, // replace with the default values. _size = size; - if (_size.X == 0f) _size.X = PhysicsScene.Params.avatarCapsuleDepth; - if (_size.Y == 0f) _size.Y = PhysicsScene.Params.avatarCapsuleWidth; + if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth; + if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth; // A motor to control the acceleration and deceleration of the avatar movement. // _velocityMotor = new BSVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); @@ -108,8 +108,8 @@ public sealed class BSCharacter : BSPhysObject _velocity = OMV.Vector3.Zero; _appliedVelocity = OMV.Vector3.Zero; _buoyancy = ComputeBuoyancyFromFlying(isFlying); - _currentFriction = PhysicsScene.Params.avatarStandingFriction; - _avatarDensity = PhysicsScene.Params.avatarDensity; + _currentFriction = BSParam.AvatarStandingFriction; + _avatarDensity = BSParam.AvatarDensity; // The dimensions of the avatar capsule are kept in the scale. // Physics creates a unit capsule which is scaled by the physics engine. @@ -161,14 +161,14 @@ public sealed class BSCharacter : BSPhysObject // Needs to be reset especially when an avatar is recreated after crossing a region boundry. Flying = _flying; - BulletSimAPI.SetRestitution2(PhysBody.ptr, PhysicsScene.Params.avatarRestitution); + BulletSimAPI.SetRestitution2(PhysBody.ptr, BSParam.AvatarRestitution); BulletSimAPI.SetMargin2(PhysShape.ptr, PhysicsScene.Params.collisionMargin); BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale); - BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, PhysicsScene.Params.contactProcessingThreshold); - if (PhysicsScene.Params.ccdMotionThreshold > 0f) + BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, BSParam.ContactProcessingThreshold); + if (BSParam.CcdMotionThreshold > 0f) { - BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, PhysicsScene.Params.ccdMotionThreshold); - BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); + BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, BSParam.CcdMotionThreshold); + BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius); } UpdatePhysicalMassProperties(RawMass); @@ -208,8 +208,8 @@ public sealed class BSCharacter : BSPhysObject _size = value; // Old versions of ScenePresence passed only the height. If width and/or depth are zero, // replace with the default values. - if (_size.X == 0f) _size.X = PhysicsScene.Params.avatarCapsuleDepth; - if (_size.Y == 0f) _size.Y = PhysicsScene.Params.avatarCapsuleWidth; + if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth; + if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth; ComputeAvatarScale(_size); ComputeAvatarVolumeAndMass(); @@ -468,18 +468,18 @@ public sealed class BSCharacter : BSPhysObject // to keep the avatar from slipping around if (_velocity.Length() == 0) { - if (_currentFriction != PhysicsScene.Params.avatarStandingFriction) + if (_currentFriction != BSParam.AvatarStandingFriction) { - _currentFriction = PhysicsScene.Params.avatarStandingFriction; + _currentFriction = BSParam.AvatarStandingFriction; if (PhysBody.HasPhysicalBody) BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction); } } else { - if (_currentFriction != PhysicsScene.Params.avatarFriction) + if (_currentFriction != BSParam.AvatarFriction) { - _currentFriction = PhysicsScene.Params.avatarFriction; + _currentFriction = BSParam.AvatarFriction; if (PhysBody.HasPhysicalBody) BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs index 6b1e304..e77fb50 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs @@ -122,7 +122,7 @@ public abstract class BSConstraint : IDisposable // Setting an object's mass to zero (making it static like when it's selected) // automatically disables the constraints. // If the link is enabled, be sure to set the constraint itself to enabled. - BulletSimAPI.SetConstraintEnable2(m_constraint.ptr, m_world.physicsScene.NumericBool(true)); + BulletSimAPI.SetConstraintEnable2(m_constraint.ptr, BSParam.NumericBool(true)); } else { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index a5acd86..e59ed8d 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -563,7 +563,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Moderate angular movement introduced by Bullet. // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle. // Maybe compute linear and angular factor and damping from params. - float angularDamping = PhysicsScene.Params.vehicleAngularDamping; + float angularDamping = BSParam.VehicleAngularDamping; BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, angularDamping); // Vehicles report collision events so we know when it's on the ground diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 2017fa5..8580928 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -56,7 +56,7 @@ public abstract class BSLinkset { BSLinkset ret = null; - switch ((int)physScene.Params.linksetImplementation) + switch ((int)BSParam.LinksetImplementation) { case (int)LinksetImplementation.Constraint: ret = new BSLinksetConstraints(physScene, parent); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index 8c36c31..d95f223 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -226,14 +226,14 @@ public sealed class BSLinksetConstraints : BSLinkset constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); // tweek the constraint to increase stability - constrain.UseFrameOffset(PhysicsScene.BoolNumeric(PhysicsScene.Params.linkConstraintUseFrameOffset)); - constrain.TranslationalLimitMotor(PhysicsScene.BoolNumeric(PhysicsScene.Params.linkConstraintEnableTransMotor), - PhysicsScene.Params.linkConstraintTransMotorMaxVel, - PhysicsScene.Params.linkConstraintTransMotorMaxForce); - constrain.SetCFMAndERP(PhysicsScene.Params.linkConstraintCFM, PhysicsScene.Params.linkConstraintERP); - if (PhysicsScene.Params.linkConstraintSolverIterations != 0f) + constrain.UseFrameOffset(BSParam.BoolNumeric(BSParam.LinkConstraintUseFrameOffset)); + constrain.TranslationalLimitMotor(BSParam.BoolNumeric(BSParam.LinkConstraintEnableTransMotor), + BSParam.LinkConstraintTransMotorMaxVel, + BSParam.LinkConstraintTransMotorMaxForce); + constrain.SetCFMAndERP(BSParam.LinkConstraintCFM, BSParam.LinkConstraintERP); + if (BSParam.LinkConstraintSolverIterations != 0f) { - constrain.SetSolverIterations(PhysicsScene.Params.linkConstraintSolverIterations); + constrain.SetSolverIterations(BSParam.LinkConstraintSolverIterations); } return constrain; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs new file mode 100755 index 0000000..1fb4c31 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -0,0 +1,558 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; + +using OpenSim.Region.Physics.Manager; + +using OpenMetaverse; +using Nini.Config; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ +public static class BSParam +{ + // Level of Detail values kept as float because that's what the Meshmerizer wants + public static float MeshLOD { get; private set; } + public static float MeshMegaPrimLOD { get; private set; } + public static float MeshMegaPrimThreshold { get; private set; } + public static float SculptLOD { get; private set; } + + public static float MinimumObjectMass { get; private set; } + public static float MaximumObjectMass { get; private set; } + + public static float LinearDamping { get; private set; } + public static float AngularDamping { get; private set; } + public static float DeactivationTime { get; private set; } + public static float LinearSleepingThreshold { get; private set; } + public static float AngularSleepingThreshold { get; private set; } + public static float CcdMotionThreshold { get; private set; } + public static float CcdSweptSphereRadius { get; private set; } + public static float ContactProcessingThreshold { get; private set; } + + public static bool ShouldMeshSculptedPrim { get; private set; } // cause scuplted prims to get meshed + public static bool ShouldForceSimplePrimMeshing { get; private set; } // if a cube or sphere, let Bullet do internal shapes + public static bool ShouldUseHullsForPhysicalObjects { get; private set; } // 'true' if should create hulls for physical objects + + public static float TerrainImplementation { get; private set; } + public static float TerrainFriction { get; private set; } + public static float TerrainHitFraction { get; private set; } + public static float TerrainRestitution { get; private set; } + public static float TerrainCollisionMargin { get; private set; } + + // Avatar parameters + public static float AvatarFriction { get; private set; } + public static float AvatarStandingFriction { get; private set; } + public static float AvatarDensity { get; private set; } + public static float AvatarRestitution { get; private set; } + public static float AvatarCapsuleWidth { get; private set; } + public static float AvatarCapsuleDepth { get; private set; } + public static float AvatarCapsuleHeight { get; private set; } + public static float AvatarContactProcessingThreshold { get; private set; } + + public static float VehicleAngularDamping { get; private set; } + + public static float LinksetImplementation { get; private set; } + public static float LinkConstraintUseFrameOffset { get; private set; } + public static float LinkConstraintEnableTransMotor { get; private set; } + public static float LinkConstraintTransMotorMaxVel { get; private set; } + public static float LinkConstraintTransMotorMaxForce { get; private set; } + public static float LinkConstraintERP { get; private set; } + public static float LinkConstraintCFM { get; private set; } + public static float LinkConstraintSolverIterations { get; private set; } + + public static float PID_D { get; private set; } // derivative + public static float PID_P { get; private set; } // proportional + + public delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val); + public delegate float ParamGet(BSScene scene); + public delegate void ParamSet(BSScene scene, string paramName, uint localID, float val); + public delegate void SetOnObject(BSScene scene, BSPhysObject obj, float val); + + public struct ParameterDefn + { + public string name; // string name of the parameter + public string desc; // a short description of what the parameter means + public float defaultValue; // default value if not specified anywhere else + public ParamUser userParam; // get the value from the configuration file + public ParamGet getter; // return the current value stored for this parameter + public ParamSet setter; // set the current value for this parameter + public SetOnObject onObject; // set the value on an object in the physical domain + public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s) + { + name = n; + desc = d; + defaultValue = v; + userParam = u; + getter = g; + setter = s; + onObject = null; + } + public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s, SetOnObject o) + { + name = n; + desc = d; + defaultValue = v; + userParam = u; + getter = g; + setter = s; + onObject = o; + } + } + + // List of all of the externally visible parameters. + // For each parameter, this table maps a text name to getter and setters. + // To add a new externally referencable/settable parameter, add the paramter storage + // location somewhere in the program and make an entry in this table with the + // getters and setters. + // It is easiest to find an existing definition and copy it. + // Parameter values are floats. Booleans are converted to a floating value. + // + // A ParameterDefn() takes the following parameters: + // -- the text name of the parameter. This is used for console input and ini file. + // -- a short text description of the parameter. This shows up in the console listing. + // -- a delegate for fetching the parameter from the ini file. + // Should handle fetching the right type from the ini file and converting it. + // -- a delegate for getting the value as a float + // -- a delegate for setting the value from a float + // -- an optional delegate to update the value in the world. Most often used to + // push the new value to an in-world object. + // + // The single letter parameters for the delegates are: + // s = BSScene + // o = BSPhysObject + // p = string parameter name + // l = localID of referenced object + // v = float value + // cf = parameter configuration class (for fetching values from ini file) + private static ParameterDefn[] ParameterDefinitions = + { + new ParameterDefn("MeshSculptedPrim", "Whether to create meshes for sculpties", + ConfigurationParameters.numericTrue, + (s,cf,p,v) => { ShouldMeshSculptedPrim = cf.GetBoolean(p, BSParam.BoolNumeric(v)); }, + (s) => { return BSParam.NumericBool(ShouldMeshSculptedPrim); }, + (s,p,l,v) => { ShouldMeshSculptedPrim = BSParam.BoolNumeric(v); } ), + new ParameterDefn("ForceSimplePrimMeshing", "If true, only use primitive meshes for objects", + ConfigurationParameters.numericFalse, + (s,cf,p,v) => { ShouldForceSimplePrimMeshing = cf.GetBoolean(p, BSParam.BoolNumeric(v)); }, + (s) => { return BSParam.NumericBool(ShouldForceSimplePrimMeshing); }, + (s,p,l,v) => { ShouldForceSimplePrimMeshing = BSParam.BoolNumeric(v); } ), + new ParameterDefn("UseHullsForPhysicalObjects", "If true, create hulls for physical objects", + ConfigurationParameters.numericTrue, + (s,cf,p,v) => { ShouldUseHullsForPhysicalObjects = cf.GetBoolean(p, BSParam.BoolNumeric(v)); }, + (s) => { return BSParam.NumericBool(ShouldUseHullsForPhysicalObjects); }, + (s,p,l,v) => { ShouldUseHullsForPhysicalObjects = BSParam.BoolNumeric(v); } ), + + new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", + 8f, + (s,cf,p,v) => { MeshLOD = (float)cf.GetInt(p, (int)v); }, + (s) => { return MeshLOD; }, + (s,p,l,v) => { MeshLOD = v; } ), + new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters", + 16f, + (s,cf,p,v) => { MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); }, + (s) => { return MeshMegaPrimLOD; }, + (s,p,l,v) => { MeshMegaPrimLOD = v; } ), + new ParameterDefn("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD", + 10f, + (s,cf,p,v) => { MeshMegaPrimThreshold = (float)cf.GetInt(p, (int)v); }, + (s) => { return MeshMegaPrimThreshold; }, + (s,p,l,v) => { MeshMegaPrimThreshold = v; } ), + new ParameterDefn("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)", + 32f, + (s,cf,p,v) => { SculptLOD = (float)cf.GetInt(p, (int)v); }, + (s) => { return SculptLOD; }, + (s,p,l,v) => { SculptLOD = v; } ), + + new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps", + 10f, + (s,cf,p,v) => { s.m_maxSubSteps = cf.GetInt(p, (int)v); }, + (s) => { return (float)s.m_maxSubSteps; }, + (s,p,l,v) => { s.m_maxSubSteps = (int)v; } ), + new ParameterDefn("FixedTimeStep", "In simulation step, seconds of one substep (1/60)", + 1f / 60f, + (s,cf,p,v) => { s.m_fixedTimeStep = cf.GetFloat(p, v); }, + (s) => { return (float)s.m_fixedTimeStep; }, + (s,p,l,v) => { s.m_fixedTimeStep = v; } ), + new ParameterDefn("MaxCollisionsPerFrame", "Max collisions returned at end of each frame", + 2048f, + (s,cf,p,v) => { s.m_maxCollisionsPerFrame = cf.GetInt(p, (int)v); }, + (s) => { return (float)s.m_maxCollisionsPerFrame; }, + (s,p,l,v) => { s.m_maxCollisionsPerFrame = (int)v; } ), + new ParameterDefn("MaxUpdatesPerFrame", "Max updates returned at end of each frame", + 8000f, + (s,cf,p,v) => { s.m_maxUpdatesPerFrame = cf.GetInt(p, (int)v); }, + (s) => { return (float)s.m_maxUpdatesPerFrame; }, + (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ), + new ParameterDefn("MaxTaintsToProcessPerStep", "Number of update taints to process before each simulation step", + 500f, + (s,cf,p,v) => { s.m_taintsToProcessPerStep = cf.GetInt(p, (int)v); }, + (s) => { return (float)s.m_taintsToProcessPerStep; }, + (s,p,l,v) => { s.m_taintsToProcessPerStep = (int)v; } ), + new ParameterDefn("MinObjectMass", "Minimum object mass (0.0001)", + 0.0001f, + (s,cf,p,v) => { MinimumObjectMass = cf.GetFloat(p, v); }, + (s) => { return (float)MinimumObjectMass; }, + (s,p,l,v) => { MinimumObjectMass = v; } ), + new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)", + 10000.01f, + (s,cf,p,v) => { MaximumObjectMass = cf.GetFloat(p, v); }, + (s) => { return (float)MaximumObjectMass; }, + (s,p,l,v) => { MaximumObjectMass = v; } ), + + new ParameterDefn("PID_D", "Derivitive factor for motion smoothing", + 2200f, + (s,cf,p,v) => { PID_D = cf.GetFloat(p, v); }, + (s) => { return (float)PID_D; }, + (s,p,l,v) => { PID_D = v; } ), + new ParameterDefn("PID_P", "Parameteric factor for motion smoothing", + 900f, + (s,cf,p,v) => { PID_P = cf.GetFloat(p, v); }, + (s) => { return (float)PID_P; }, + (s,p,l,v) => { PID_P = v; } ), + + new ParameterDefn("DefaultFriction", "Friction factor used on new objects", + 0.2f, + (s,cf,p,v) => { s.UnmanagedParams[0].defaultFriction = cf.GetFloat(p, v); }, + (s) => { return s.UnmanagedParams[0].defaultFriction; }, + (s,p,l,v) => { s.UnmanagedParams[0].defaultFriction = v; } ), + new ParameterDefn("DefaultDensity", "Density for new objects" , + 10.000006836f, // Aluminum g/cm3 + (s,cf,p,v) => { s.UnmanagedParams[0].defaultDensity = cf.GetFloat(p, v); }, + (s) => { return s.UnmanagedParams[0].defaultDensity; }, + (s,p,l,v) => { s.UnmanagedParams[0].defaultDensity = v; } ), + new ParameterDefn("DefaultRestitution", "Bouncyness of an object" , + 0f, + (s,cf,p,v) => { s.UnmanagedParams[0].defaultRestitution = cf.GetFloat(p, v); }, + (s) => { return s.UnmanagedParams[0].defaultRestitution; }, + (s,p,l,v) => { s.UnmanagedParams[0].defaultRestitution = v; } ), + new ParameterDefn("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!)", + 0.04f, + (s,cf,p,v) => { s.UnmanagedParams[0].collisionMargin = cf.GetFloat(p, v); }, + (s) => { return s.UnmanagedParams[0].collisionMargin; }, + (s,p,l,v) => { s.UnmanagedParams[0].collisionMargin = v; } ), + new ParameterDefn("Gravity", "Vertical force of gravity (negative means down)", + -9.80665f, + (s,cf,p,v) => { s.UnmanagedParams[0].gravity = cf.GetFloat(p, v); }, + (s) => { return s.UnmanagedParams[0].gravity; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{s.UnmanagedParams[0].gravity=x;}, p, PhysParameterEntry.APPLY_TO_NONE, v); }, + (s,o,v) => { BulletSimAPI.SetGravity2(s.World.ptr, new Vector3(0f,0f,v)); } ), + + + new ParameterDefn("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)", + 0f, + (s,cf,p,v) => { LinearDamping = cf.GetFloat(p, v); }, + (s) => { return LinearDamping; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{LinearDamping=x;}, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, v, AngularDamping); } ), + new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)", + 0f, + (s,cf,p,v) => { AngularDamping = cf.GetFloat(p, v); }, + (s) => { return AngularDamping; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularDamping=x;}, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, LinearDamping, v); } ), + new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static", + 0.2f, + (s,cf,p,v) => { DeactivationTime = cf.GetFloat(p, v); }, + (s) => { return DeactivationTime; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{DeactivationTime=x;}, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetDeactivationTime2(o.PhysBody.ptr, v); } ), + new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static", + 0.8f, + (s,cf,p,v) => { LinearSleepingThreshold = cf.GetFloat(p, v); }, + (s) => { return LinearSleepingThreshold; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{LinearSleepingThreshold=x;}, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ), + new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static", + 1.0f, + (s,cf,p,v) => { AngularSleepingThreshold = cf.GetFloat(p, v); }, + (s) => { return AngularSleepingThreshold; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularSleepingThreshold=x;}, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ), + new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" , + 0f, // set to zero to disable + (s,cf,p,v) => { CcdMotionThreshold = cf.GetFloat(p, v); }, + (s) => { return CcdMotionThreshold; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdMotionThreshold=x;}, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetCcdMotionThreshold2(o.PhysBody.ptr, v); } ), + new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" , + 0f, + (s,cf,p,v) => { CcdSweptSphereRadius = cf.GetFloat(p, v); }, + (s) => { return CcdSweptSphereRadius; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdSweptSphereRadius=x;}, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetCcdSweptSphereRadius2(o.PhysBody.ptr, v); } ), + new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" , + 0.1f, + (s,cf,p,v) => { ContactProcessingThreshold = cf.GetFloat(p, v); }, + (s) => { return ContactProcessingThreshold; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{ContactProcessingThreshold=x;}, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetContactProcessingThreshold2(o.PhysBody.ptr, v); } ), + + new ParameterDefn("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)", + (float)BSTerrainPhys.TerrainImplementation.Mesh, + (s,cf,p,v) => { TerrainImplementation = cf.GetFloat(p,v); }, + (s) => { return TerrainImplementation; }, + (s,p,l,v) => { TerrainImplementation = v; } ), + new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" , + 0.3f, + (s,cf,p,v) => { TerrainFriction = cf.GetFloat(p, v); }, + (s) => { return TerrainFriction; }, + (s,p,l,v) => { TerrainFriction = v; /* TODO: set on real terrain */} ), + new ParameterDefn("TerrainHitFraction", "Distance to measure hit collisions" , + 0.8f, + (s,cf,p,v) => { TerrainHitFraction = cf.GetFloat(p, v); }, + (s) => { return TerrainHitFraction; }, + (s,p,l,v) => { TerrainHitFraction = v; /* TODO: set on real terrain */ } ), + new ParameterDefn("TerrainRestitution", "Bouncyness" , + 0f, + (s,cf,p,v) => { TerrainRestitution = cf.GetFloat(p, v); }, + (s) => { return TerrainRestitution; }, + (s,p,l,v) => { TerrainRestitution = v; /* TODO: set on real terrain */ } ), + new ParameterDefn("TerrainCollisionMargin", "Margin where collision checking starts" , + 0.04f, + (s,cf,p,v) => { TerrainCollisionMargin = cf.GetFloat(p, v); }, + (s) => { return TerrainCollisionMargin; }, + (s,p,l,v) => { TerrainCollisionMargin = v; /* TODO: set on real terrain */ } ), + + new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.", + 0.2f, + (s,cf,p,v) => { AvatarFriction = cf.GetFloat(p, v); }, + (s) => { return AvatarFriction; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarFriction=x;}, p, l, v); } ), + new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", + 10.0f, + (s,cf,p,v) => { AvatarStandingFriction = cf.GetFloat(p, v); }, + (s) => { return AvatarStandingFriction; }, + (s,p,l,v) => { AvatarStandingFriction = v; } ), + new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.", + 60f, + (s,cf,p,v) => { AvatarDensity = cf.GetFloat(p, v); }, + (s) => { return AvatarDensity; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarDensity=x;}, p, l, v); } ), + new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.", + 0f, + (s,cf,p,v) => { AvatarRestitution = cf.GetFloat(p, v); }, + (s) => { return AvatarRestitution; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarRestitution=x;}, p, l, v); } ), + new ParameterDefn("AvatarCapsuleWidth", "The distance between the sides of the avatar capsule", + 0.6f, + (s,cf,p,v) => { AvatarCapsuleWidth = cf.GetFloat(p, v); }, + (s) => { return AvatarCapsuleWidth; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleWidth=x;}, p, l, v); } ), + new ParameterDefn("AvatarCapsuleDepth", "The distance between the front and back of the avatar capsule", + 0.45f, + (s,cf,p,v) => { AvatarCapsuleDepth = cf.GetFloat(p, v); }, + (s) => { return AvatarCapsuleDepth; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleDepth=x;}, p, l, v); } ), + new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar", + 1.5f, + (s,cf,p,v) => { AvatarCapsuleHeight = cf.GetFloat(p, v); }, + (s) => { return AvatarCapsuleHeight; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleHeight=x;}, p, l, v); } ), + new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", + 0.1f, + (s,cf,p,v) => { AvatarContactProcessingThreshold = cf.GetFloat(p, v); }, + (s) => { return AvatarContactProcessingThreshold; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarContactProcessingThreshold=x;}, p, l, v); } ), + + new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", + 0.95f, + (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); }, + (s) => { return VehicleAngularDamping; }, + (s,p,l,v) => { VehicleAngularDamping = v; } ), + + new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", + 0f, + (s,cf,p,v) => { s.UnmanagedParams[0].maxPersistantManifoldPoolSize = cf.GetFloat(p, v); }, + (s) => { return s.UnmanagedParams[0].maxPersistantManifoldPoolSize; }, + (s,p,l,v) => { s.UnmanagedParams[0].maxPersistantManifoldPoolSize = v; } ), + new ParameterDefn("MaxCollisionAlgorithmPoolSize", "Number of collisions pooled (0 means default of 4096)", + 0f, + (s,cf,p,v) => { s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = cf.GetFloat(p, v); }, + (s) => { return s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize; }, + (s,p,l,v) => { s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = v; } ), + new ParameterDefn("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count", + ConfigurationParameters.numericFalse, + (s,cf,p,v) => { s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation; }, + (s,p,l,v) => { s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = v; } ), + new ParameterDefn("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step", + ConfigurationParameters.numericFalse, + (s,cf,p,v) => { s.UnmanagedParams[0].shouldForceUpdateAllAabbs = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return s.UnmanagedParams[0].shouldForceUpdateAllAabbs; }, + (s,p,l,v) => { s.UnmanagedParams[0].shouldForceUpdateAllAabbs = v; } ), + new ParameterDefn("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction", + ConfigurationParameters.numericTrue, + (s,cf,p,v) => { s.UnmanagedParams[0].shouldRandomizeSolverOrder = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return s.UnmanagedParams[0].shouldRandomizeSolverOrder; }, + (s,p,l,v) => { s.UnmanagedParams[0].shouldRandomizeSolverOrder = v; } ), + new ParameterDefn("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands", + ConfigurationParameters.numericTrue, + (s,cf,p,v) => { s.UnmanagedParams[0].shouldSplitSimulationIslands = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return s.UnmanagedParams[0].shouldSplitSimulationIslands; }, + (s,p,l,v) => { s.UnmanagedParams[0].shouldSplitSimulationIslands = v; } ), + new ParameterDefn("ShouldEnableFrictionCaching", "Enable friction computation caching", + ConfigurationParameters.numericFalse, + (s,cf,p,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return s.UnmanagedParams[0].shouldEnableFrictionCaching; }, + (s,p,l,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = v; } ), + new ParameterDefn("NumberOfSolverIterations", "Number of internal iterations (0 means default)", + 0f, // zero says use Bullet default + (s,cf,p,v) => { s.UnmanagedParams[0].numberOfSolverIterations = cf.GetFloat(p, v); }, + (s) => { return s.UnmanagedParams[0].numberOfSolverIterations; }, + (s,p,l,v) => { s.UnmanagedParams[0].numberOfSolverIterations = v; } ), + + new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", + (float)BSLinkset.LinksetImplementation.Compound, + (s,cf,p,v) => { LinksetImplementation = cf.GetFloat(p,v); }, + (s) => { return LinksetImplementation; }, + (s,p,l,v) => { LinksetImplementation = v; } ), + new ParameterDefn("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.", + ConfigurationParameters.numericFalse, + (s,cf,p,v) => { LinkConstraintUseFrameOffset = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return LinkConstraintUseFrameOffset; }, + (s,p,l,v) => { LinkConstraintUseFrameOffset = v; } ), + new ParameterDefn("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints", + ConfigurationParameters.numericTrue, + (s,cf,p,v) => { LinkConstraintEnableTransMotor = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return LinkConstraintEnableTransMotor; }, + (s,p,l,v) => { LinkConstraintEnableTransMotor = v; } ), + new ParameterDefn("LinkConstraintTransMotorMaxVel", "Maximum velocity to be applied by translational motor in linkset constraints", + 5.0f, + (s,cf,p,v) => { LinkConstraintTransMotorMaxVel = cf.GetFloat(p, v); }, + (s) => { return LinkConstraintTransMotorMaxVel; }, + (s,p,l,v) => { LinkConstraintTransMotorMaxVel = v; } ), + new ParameterDefn("LinkConstraintTransMotorMaxForce", "Maximum force to be applied by translational motor in linkset constraints", + 0.1f, + (s,cf,p,v) => { LinkConstraintTransMotorMaxForce = cf.GetFloat(p, v); }, + (s) => { return LinkConstraintTransMotorMaxForce; }, + (s,p,l,v) => { LinkConstraintTransMotorMaxForce = v; } ), + new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1", + 0.1f, + (s,cf,p,v) => { LinkConstraintCFM = cf.GetFloat(p, v); }, + (s) => { return LinkConstraintCFM; }, + (s,p,l,v) => { LinkConstraintCFM = v; } ), + new ParameterDefn("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2", + 0.1f, + (s,cf,p,v) => { LinkConstraintERP = cf.GetFloat(p, v); }, + (s) => { return LinkConstraintERP; }, + (s,p,l,v) => { LinkConstraintERP = v; } ), + new ParameterDefn("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)", + 40, + (s,cf,p,v) => { LinkConstraintSolverIterations = cf.GetFloat(p, v); }, + (s) => { return LinkConstraintSolverIterations; }, + (s,p,l,v) => { LinkConstraintSolverIterations = v; } ), + + new ParameterDefn("LogPhysicsStatisticsFrames", "Frames between outputting detailed phys stats. (0 is off)", + 0f, + (s,cf,p,v) => { s.UnmanagedParams[0].physicsLoggingFrames = cf.GetInt(p, (int)v); }, + (s) => { return (float)s.UnmanagedParams[0].physicsLoggingFrames; }, + (s,p,l,v) => { s.UnmanagedParams[0].physicsLoggingFrames = (int)v; } ), + }; + + // Convert a boolean to our numeric true and false values + public static float NumericBool(bool b) + { + return (b ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse); + } + + // Convert numeric true and false values to a boolean + public static bool BoolNumeric(float b) + { + return (b == ConfigurationParameters.numericTrue ? true : false); + } + + // Search through the parameter definitions and return the matching + // ParameterDefn structure. + // Case does not matter as names are compared after converting to lower case. + // Returns 'false' if the parameter is not found. + internal static bool TryGetParameter(string paramName, out ParameterDefn defn) + { + bool ret = false; + ParameterDefn foundDefn = new ParameterDefn(); + string pName = paramName.ToLower(); + + foreach (ParameterDefn parm in ParameterDefinitions) + { + if (pName == parm.name.ToLower()) + { + foundDefn = parm; + ret = true; + break; + } + } + defn = foundDefn; + return ret; + } + + // Pass through the settable parameters and set the default values + internal static void SetParameterDefaultValues(BSScene physicsScene) + { + foreach (ParameterDefn parm in ParameterDefinitions) + { + parm.setter(physicsScene, parm.name, PhysParameterEntry.APPLY_TO_NONE, parm.defaultValue); + } + } + + // Get user set values out of the ini file. + internal static void SetParameterConfigurationValues(BSScene physicsScene, IConfig cfg) + { + foreach (ParameterDefn parm in ParameterDefinitions) + { + parm.userParam(physicsScene, cfg, parm.name, parm.defaultValue); + } + } + + internal static PhysParameterEntry[] SettableParameters = new PhysParameterEntry[1]; + + // This creates an array in the correct format for returning the list of + // parameters. This is used by the 'list' option of the 'physics' command. + internal static void BuildParameterTable() + { + if (SettableParameters.Length < ParameterDefinitions.Length) + { + List entries = new List(); + for (int ii = 0; ii < ParameterDefinitions.Length; ii++) + { + ParameterDefn pd = ParameterDefinitions[ii]; + entries.Add(new PhysParameterEntry(pd.name, pd.desc)); + } + + // make the list in alphabetical order for estetic reasons + entries.Sort(delegate(PhysParameterEntry ppe1, PhysParameterEntry ppe2) + { + return ppe1.name.CompareTo(ppe2.name); + }); + + SettableParameters = entries.ToArray(); + } + } + + +} +} diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 68a0db6..e43bf8e 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -720,10 +720,10 @@ public sealed class BSPrim : BSPhysObject // Mass is zero which disables a bunch of physics stuff in Bullet UpdatePhysicalMassProperties(0f); // Set collision detection parameters - if (PhysicsScene.Params.ccdMotionThreshold > 0f) + if (BSParam.CcdMotionThreshold > 0f) { - BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, PhysicsScene.Params.ccdMotionThreshold); - BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); + BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, BSParam.CcdMotionThreshold); + BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius); } // The activation state is 'disabled' so Bullet will not try to act on it. @@ -761,17 +761,17 @@ public sealed class BSPrim : BSPhysObject UpdatePhysicalMassProperties(RawMass); // Set collision detection parameters - if (PhysicsScene.Params.ccdMotionThreshold > 0f) + if (BSParam.CcdMotionThreshold > 0f) { - BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, PhysicsScene.Params.ccdMotionThreshold); - BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); + BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, BSParam.CcdMotionThreshold); + BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius); } // Various values for simulation limits - BulletSimAPI.SetDamping2(PhysBody.ptr, PhysicsScene.Params.linearDamping, PhysicsScene.Params.angularDamping); - BulletSimAPI.SetDeactivationTime2(PhysBody.ptr, PhysicsScene.Params.deactivationTime); - BulletSimAPI.SetSleepingThresholds2(PhysBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold); - BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, PhysicsScene.Params.contactProcessingThreshold); + BulletSimAPI.SetDamping2(PhysBody.ptr, BSParam.LinearDamping, BSParam.AngularDamping); + BulletSimAPI.SetDeactivationTime2(PhysBody.ptr, BSParam.DeactivationTime); + BulletSimAPI.SetSleepingThresholds2(PhysBody.ptr, BSParam.LinearSleepingThreshold, BSParam.AngularSleepingThreshold); + BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, BSParam.ContactProcessingThreshold); // This collides like an object. PhysBody.collisionType = CollisionType.Dynamic; @@ -1361,11 +1361,7 @@ public sealed class BSPrim : BSPhysObject } */ - if (returnMass <= 0) - returnMass = 0.0001f; - - if (returnMass > PhysicsScene.MaximumObjectMass) - returnMass = PhysicsScene.MaximumObjectMass; + returnMass = Util.Clamp(returnMass, BSParam.MinimumObjectMass, BSParam.MaximumObjectMass); return returnMass; }// end CalculateMass diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 2ca4912..492a255 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -77,12 +77,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public ILog Logger { get { return m_log; } } public IMesher mesher; - // Level of Detail values kept as float because that's what the Meshmerizer wants - public float MeshLOD { get; private set; } - public float MeshMegaPrimLOD { get; private set; } - public float MeshMegaPrimThreshold { get; private set; } - public float SculptLOD { get; private set; } - public uint WorldID { get; private set; } public BulletSim World { get; private set; } @@ -90,21 +84,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public BSConstraintCollection Constraints { get; private set; } // Simulation parameters - private int m_maxSubSteps; - private float m_fixedTimeStep; - private long m_simulationStep = 0; + internal int m_maxSubSteps; + internal float m_fixedTimeStep; + internal long m_simulationStep = 0; public long SimulationStep { get { return m_simulationStep; } } - private int m_taintsToProcessPerStep; - - // Avatar parameters - public float ParamAvatarFriction { get; private set; } - public float ParamAvatarStandingFriction { get; private set; } - public float ParamAvatarDensity { get; private set; } - public float ParamAvatarRestitution { get; private set; } - public float ParamAvatarCapsuleWidth { get; private set; } - public float ParamAvatarCapsuleDepth { get; private set; } - public float ParamAvatarCapsuleHeight { get; private set; } - public float ParamAvatarContactProcessingThreshold { get; private set; } + internal int m_taintsToProcessPerStep; public delegate void PreStepAction(float timeStep); public event PreStepAction BeforeStep; @@ -121,20 +105,13 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public bool InTaintTime { get; private set; } // Pinned memory used to pass step information between managed and unmanaged - private int m_maxCollisionsPerFrame; - private CollisionDesc[] m_collisionArray; - private GCHandle m_collisionArrayPinnedHandle; - - private int m_maxUpdatesPerFrame; - private EntityProperties[] m_updateArray; - private GCHandle m_updateArrayPinnedHandle; + internal int m_maxCollisionsPerFrame; + internal CollisionDesc[] m_collisionArray; + internal GCHandle m_collisionArrayPinnedHandle; - public bool ShouldMeshSculptedPrim { get; private set; } // cause scuplted prims to get meshed - public bool ShouldForceSimplePrimMeshing { get; private set; } // if a cube or sphere, let Bullet do internal shapes - public bool ShouldUseHullsForPhysicalObjects { get; private set; } // 'true' if should create hulls for physical objects - - public float PID_D { get; private set; } // derivative - public float PID_P { get; private set; } // proportional + internal int m_maxUpdatesPerFrame; + internal EntityProperties[] m_updateArray; + internal GCHandle m_updateArrayPinnedHandle; public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero public const uint GROUNDPLANE_ID = 1; @@ -145,7 +122,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public ConfigurationParameters Params { - get { return m_params[0]; } + get { return UnmanagedParams[0]; } } public Vector3 DefaultGravity { @@ -157,8 +134,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters get { return Params.gravity; } } - public float MaximumObjectMass { get; private set; } - // When functions in the unmanaged code must be called, it is only // done at a known time just before the simulation step. The taint // system saves all these function calls and executes them in @@ -181,7 +156,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // A pointer to an instance if this structure is passed to the C++ code // Used to pass basic configuration values to the unmanaged code. - ConfigurationParameters[] m_params; + internal ConfigurationParameters[] UnmanagedParams; GCHandle m_paramsHandle; // Handle to the callback used by the unmanaged code to call into the managed code. @@ -218,8 +193,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters Shapes = new BSShapeCollection(this); // Allocate pinned memory to pass parameters. - m_params = new ConfigurationParameters[1]; - m_paramsHandle = GCHandle.Alloc(m_params, GCHandleType.Pinned); + UnmanagedParams = new ConfigurationParameters[1]; + m_paramsHandle = GCHandle.Alloc(UnmanagedParams, GCHandleType.Pinned); // Set default values for physics parameters plus any overrides from the ini file GetInitialParameterValues(config); @@ -277,7 +252,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters TerrainManager = new BSTerrainManager(this); TerrainManager.CreateInitialGroundPlaneAndTerrain(); - m_log.WarnFormat("{0} Linksets implemented with {1}", LogHeader, (BSLinkset.LinksetImplementation)Params.linksetImplementation); + m_log.WarnFormat("{0} Linksets implemented with {1}", LogHeader, (BSLinkset.LinksetImplementation)BSParam.LinksetImplementation); InTaintTime = false; m_initialized = true; @@ -288,9 +263,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters private void GetInitialParameterValues(IConfigSource config) { ConfigurationParameters parms = new ConfigurationParameters(); - m_params[0] = parms; + UnmanagedParams[0] = parms; - SetParameterDefaultValues(); + BSParam.SetParameterDefaultValues(this); if (config != null) { @@ -298,7 +273,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters IConfig pConfig = config.Configs["BulletSim"]; if (pConfig != null) { - SetParameterConfigurationValues(pConfig); + BSParam.SetParameterConfigurationValues(this, pConfig); // Very detailed logging for physics debugging m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false); @@ -889,7 +864,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters { DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom); m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom); - Util.PrintCallStack(); // Prints the stack into the DEBUG log file. + Util.PrintCallStack(DetailLog); // Prints the stack into the DEBUG log file. } return InTaintTime; } @@ -936,12 +911,15 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters private void DoPreStepActions(float timeStep) { + InTaintTime = true; // Only used for debugging so locking is not necessary. ProcessVehicles(timeStep); PreStepAction actions = BeforeStep; if (actions != null) actions(timeStep); + InTaintTime = false; + } // Some prims have extra vehicle actions @@ -957,472 +935,12 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters #region INI and command line parameter processing - delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val); - delegate float ParamGet(BSScene scene); - delegate void ParamSet(BSScene scene, string paramName, uint localID, float val); - delegate void SetOnObject(BSScene scene, BSPhysObject obj, float val); - - private struct ParameterDefn - { - public string name; // string name of the parameter - public string desc; // a short description of what the parameter means - public float defaultValue; // default value if not specified anywhere else - public ParamUser userParam; // get the value from the configuration file - public ParamGet getter; // return the current value stored for this parameter - public ParamSet setter; // set the current value for this parameter - public SetOnObject onObject; // set the value on an object in the physical domain - public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s) - { - name = n; - desc = d; - defaultValue = v; - userParam = u; - getter = g; - setter = s; - onObject = null; - } - public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s, SetOnObject o) - { - name = n; - desc = d; - defaultValue = v; - userParam = u; - getter = g; - setter = s; - onObject = o; - } - } - - // List of all of the externally visible parameters. - // For each parameter, this table maps a text name to getter and setters. - // To add a new externally referencable/settable parameter, add the paramter storage - // location somewhere in the program and make an entry in this table with the - // getters and setters. - // It is easiest to find an existing definition and copy it. - // Parameter values are floats. Booleans are converted to a floating value. - // - // A ParameterDefn() takes the following parameters: - // -- the text name of the parameter. This is used for console input and ini file. - // -- a short text description of the parameter. This shows up in the console listing. - // -- a delegate for fetching the parameter from the ini file. - // Should handle fetching the right type from the ini file and converting it. - // -- a delegate for getting the value as a float - // -- a delegate for setting the value from a float - // -- an optional delegate to update the value in the world. Most often used to - // push the new value to an in-world object. - // - // The single letter parameters for the delegates are: - // s = BSScene - // o = BSPhysObject - // p = string parameter name - // l = localID of referenced object - // v = float value - // cf = parameter configuration class (for fetching values from ini file) - private ParameterDefn[] ParameterDefinitions = - { - new ParameterDefn("MeshSculptedPrim", "Whether to create meshes for sculpties", - ConfigurationParameters.numericTrue, - (s,cf,p,v) => { s.ShouldMeshSculptedPrim = cf.GetBoolean(p, s.BoolNumeric(v)); }, - (s) => { return s.NumericBool(s.ShouldMeshSculptedPrim); }, - (s,p,l,v) => { s.ShouldMeshSculptedPrim = s.BoolNumeric(v); } ), - new ParameterDefn("ForceSimplePrimMeshing", "If true, only use primitive meshes for objects", - ConfigurationParameters.numericFalse, - (s,cf,p,v) => { s.ShouldForceSimplePrimMeshing = cf.GetBoolean(p, s.BoolNumeric(v)); }, - (s) => { return s.NumericBool(s.ShouldForceSimplePrimMeshing); }, - (s,p,l,v) => { s.ShouldForceSimplePrimMeshing = s.BoolNumeric(v); } ), - new ParameterDefn("UseHullsForPhysicalObjects", "If true, create hulls for physical objects", - ConfigurationParameters.numericTrue, - (s,cf,p,v) => { s.ShouldUseHullsForPhysicalObjects = cf.GetBoolean(p, s.BoolNumeric(v)); }, - (s) => { return s.NumericBool(s.ShouldUseHullsForPhysicalObjects); }, - (s,p,l,v) => { s.ShouldUseHullsForPhysicalObjects = s.BoolNumeric(v); } ), - - new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", - 8f, - (s,cf,p,v) => { s.MeshLOD = (float)cf.GetInt(p, (int)v); }, - (s) => { return s.MeshLOD; }, - (s,p,l,v) => { s.MeshLOD = v; } ), - new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters", - 16f, - (s,cf,p,v) => { s.MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); }, - (s) => { return s.MeshMegaPrimLOD; }, - (s,p,l,v) => { s.MeshMegaPrimLOD = v; } ), - new ParameterDefn("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD", - 10f, - (s,cf,p,v) => { s.MeshMegaPrimThreshold = (float)cf.GetInt(p, (int)v); }, - (s) => { return s.MeshMegaPrimThreshold; }, - (s,p,l,v) => { s.MeshMegaPrimThreshold = v; } ), - new ParameterDefn("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)", - 32f, - (s,cf,p,v) => { s.SculptLOD = (float)cf.GetInt(p, (int)v); }, - (s) => { return s.SculptLOD; }, - (s,p,l,v) => { s.SculptLOD = v; } ), - - new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps", - 10f, - (s,cf,p,v) => { s.m_maxSubSteps = cf.GetInt(p, (int)v); }, - (s) => { return (float)s.m_maxSubSteps; }, - (s,p,l,v) => { s.m_maxSubSteps = (int)v; } ), - new ParameterDefn("FixedTimeStep", "In simulation step, seconds of one substep (1/60)", - 1f / 60f, - (s,cf,p,v) => { s.m_fixedTimeStep = cf.GetFloat(p, v); }, - (s) => { return (float)s.m_fixedTimeStep; }, - (s,p,l,v) => { s.m_fixedTimeStep = v; } ), - new ParameterDefn("MaxCollisionsPerFrame", "Max collisions returned at end of each frame", - 2048f, - (s,cf,p,v) => { s.m_maxCollisionsPerFrame = cf.GetInt(p, (int)v); }, - (s) => { return (float)s.m_maxCollisionsPerFrame; }, - (s,p,l,v) => { s.m_maxCollisionsPerFrame = (int)v; } ), - new ParameterDefn("MaxUpdatesPerFrame", "Max updates returned at end of each frame", - 8000f, - (s,cf,p,v) => { s.m_maxUpdatesPerFrame = cf.GetInt(p, (int)v); }, - (s) => { return (float)s.m_maxUpdatesPerFrame; }, - (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ), - new ParameterDefn("MaxTaintsToProcessPerStep", "Number of update taints to process before each simulation step", - 500f, - (s,cf,p,v) => { s.m_taintsToProcessPerStep = cf.GetInt(p, (int)v); }, - (s) => { return (float)s.m_taintsToProcessPerStep; }, - (s,p,l,v) => { s.m_taintsToProcessPerStep = (int)v; } ), - new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)", - 10000.01f, - (s,cf,p,v) => { s.MaximumObjectMass = cf.GetFloat(p, v); }, - (s) => { return (float)s.MaximumObjectMass; }, - (s,p,l,v) => { s.MaximumObjectMass = v; } ), - - new ParameterDefn("PID_D", "Derivitive factor for motion smoothing", - 2200f, - (s,cf,p,v) => { s.PID_D = cf.GetFloat(p, v); }, - (s) => { return (float)s.PID_D; }, - (s,p,l,v) => { s.PID_D = v; } ), - new ParameterDefn("PID_P", "Parameteric factor for motion smoothing", - 900f, - (s,cf,p,v) => { s.PID_P = cf.GetFloat(p, v); }, - (s) => { return (float)s.PID_P; }, - (s,p,l,v) => { s.PID_P = v; } ), - - new ParameterDefn("DefaultFriction", "Friction factor used on new objects", - 0.2f, - (s,cf,p,v) => { s.m_params[0].defaultFriction = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].defaultFriction; }, - (s,p,l,v) => { s.m_params[0].defaultFriction = v; } ), - new ParameterDefn("DefaultDensity", "Density for new objects" , - 10.000006836f, // Aluminum g/cm3 - (s,cf,p,v) => { s.m_params[0].defaultDensity = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].defaultDensity; }, - (s,p,l,v) => { s.m_params[0].defaultDensity = v; } ), - new ParameterDefn("DefaultRestitution", "Bouncyness of an object" , - 0f, - (s,cf,p,v) => { s.m_params[0].defaultRestitution = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].defaultRestitution; }, - (s,p,l,v) => { s.m_params[0].defaultRestitution = v; } ), - new ParameterDefn("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!)", - 0.04f, - (s,cf,p,v) => { s.m_params[0].collisionMargin = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].collisionMargin; }, - (s,p,l,v) => { s.m_params[0].collisionMargin = v; } ), - new ParameterDefn("Gravity", "Vertical force of gravity (negative means down)", - -9.80665f, - (s,cf,p,v) => { s.m_params[0].gravity = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].gravity; }, - (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].gravity, p, PhysParameterEntry.APPLY_TO_NONE, v); }, - (s,o,v) => { BulletSimAPI.SetGravity2(s.World.ptr, new Vector3(0f,0f,v)); } ), - - - new ParameterDefn("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)", - 0f, - (s,cf,p,v) => { s.m_params[0].linearDamping = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].linearDamping; }, - (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearDamping, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, v, s.m_params[0].angularDamping); } ), - new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)", - 0f, - (s,cf,p,v) => { s.m_params[0].angularDamping = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].angularDamping; }, - (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularDamping, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, s.m_params[0].linearDamping, v); } ), - new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static", - 0.2f, - (s,cf,p,v) => { s.m_params[0].deactivationTime = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].deactivationTime; }, - (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].deactivationTime, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetDeactivationTime2(o.PhysBody.ptr, v); } ), - new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static", - 0.8f, - (s,cf,p,v) => { s.m_params[0].linearSleepingThreshold = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].linearSleepingThreshold; }, - (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearSleepingThreshold, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ), - new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static", - 1.0f, - (s,cf,p,v) => { s.m_params[0].angularSleepingThreshold = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].angularSleepingThreshold; }, - (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularSleepingThreshold, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ), - new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" , - 0f, // set to zero to disable - (s,cf,p,v) => { s.m_params[0].ccdMotionThreshold = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].ccdMotionThreshold; }, - (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdMotionThreshold, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetCcdMotionThreshold2(o.PhysBody.ptr, v); } ), - new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" , - 0f, - (s,cf,p,v) => { s.m_params[0].ccdSweptSphereRadius = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].ccdSweptSphereRadius; }, - (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdSweptSphereRadius, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetCcdSweptSphereRadius2(o.PhysBody.ptr, v); } ), - new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" , - 0.1f, - (s,cf,p,v) => { s.m_params[0].contactProcessingThreshold = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].contactProcessingThreshold; }, - (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].contactProcessingThreshold, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetContactProcessingThreshold2(o.PhysBody.ptr, v); } ), - - new ParameterDefn("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)", - (float)BSTerrainPhys.TerrainImplementation.Mesh, - (s,cf,p,v) => { s.m_params[0].terrainImplementation = cf.GetFloat(p,v); }, - (s) => { return s.m_params[0].terrainImplementation; }, - (s,p,l,v) => { s.m_params[0].terrainImplementation = v; } ), - new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" , - 0.3f, - (s,cf,p,v) => { s.m_params[0].terrainFriction = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].terrainFriction; }, - (s,p,l,v) => { s.m_params[0].terrainFriction = v; /* TODO: set on real terrain */} ), - new ParameterDefn("TerrainHitFraction", "Distance to measure hit collisions" , - 0.8f, - (s,cf,p,v) => { s.m_params[0].terrainHitFraction = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].terrainHitFraction; }, - (s,p,l,v) => { s.m_params[0].terrainHitFraction = v; /* TODO: set on real terrain */ } ), - new ParameterDefn("TerrainRestitution", "Bouncyness" , - 0f, - (s,cf,p,v) => { s.m_params[0].terrainRestitution = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].terrainRestitution; }, - (s,p,l,v) => { s.m_params[0].terrainRestitution = v; /* TODO: set on real terrain */ } ), - new ParameterDefn("TerrainCollisionMargin", "Margin where collision checking starts" , - 0.04f, - (s,cf,p,v) => { s.m_params[0].terrainCollisionMargin = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].terrainCollisionMargin; }, - (s,p,l,v) => { s.m_params[0].terrainCollisionMargin = v; /* TODO: set on real terrain */ } ), - - new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.", - 0.2f, - (s,cf,p,v) => { s.m_params[0].avatarFriction = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].avatarFriction; }, - (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarFriction, p, l, v); } ), - new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", - 10.0f, - (s,cf,p,v) => { s.m_params[0].avatarStandingFriction = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].avatarStandingFriction; }, - (s,p,l,v) => { s.m_params[0].avatarStandingFriction = v; } ), - new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.", - 60f, - (s,cf,p,v) => { s.m_params[0].avatarDensity = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].avatarDensity; }, - (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarDensity, p, l, v); } ), - new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.", - 0f, - (s,cf,p,v) => { s.m_params[0].avatarRestitution = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].avatarRestitution; }, - (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarRestitution, p, l, v); } ), - new ParameterDefn("AvatarCapsuleWidth", "The distance between the sides of the avatar capsule", - 0.6f, - (s,cf,p,v) => { s.m_params[0].avatarCapsuleWidth = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].avatarCapsuleWidth; }, - (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleWidth, p, l, v); } ), - new ParameterDefn("AvatarCapsuleDepth", "The distance between the front and back of the avatar capsule", - 0.45f, - (s,cf,p,v) => { s.m_params[0].avatarCapsuleDepth = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].avatarCapsuleDepth; }, - (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleDepth, p, l, v); } ), - new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar", - 1.5f, - (s,cf,p,v) => { s.m_params[0].avatarCapsuleHeight = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].avatarCapsuleHeight; }, - (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleHeight, p, l, v); } ), - new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", - 0.1f, - (s,cf,p,v) => { s.m_params[0].avatarContactProcessingThreshold = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].avatarContactProcessingThreshold; }, - (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ), - - new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", - 0.95f, - (s,cf,p,v) => { s.m_params[0].vehicleAngularDamping = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].vehicleAngularDamping; }, - (s,p,l,v) => { s.m_params[0].vehicleAngularDamping = v; } ), - - new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", - 0f, - (s,cf,p,v) => { s.m_params[0].maxPersistantManifoldPoolSize = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].maxPersistantManifoldPoolSize; }, - (s,p,l,v) => { s.m_params[0].maxPersistantManifoldPoolSize = v; } ), - new ParameterDefn("MaxCollisionAlgorithmPoolSize", "Number of collisions pooled (0 means default of 4096)", - 0f, - (s,cf,p,v) => { s.m_params[0].maxCollisionAlgorithmPoolSize = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].maxCollisionAlgorithmPoolSize; }, - (s,p,l,v) => { s.m_params[0].maxCollisionAlgorithmPoolSize = v; } ), - new ParameterDefn("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count", - ConfigurationParameters.numericFalse, - (s,cf,p,v) => { s.m_params[0].shouldDisableContactPoolDynamicAllocation = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); }, - (s) => { return s.m_params[0].shouldDisableContactPoolDynamicAllocation; }, - (s,p,l,v) => { s.m_params[0].shouldDisableContactPoolDynamicAllocation = v; } ), - new ParameterDefn("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step", - ConfigurationParameters.numericFalse, - (s,cf,p,v) => { s.m_params[0].shouldForceUpdateAllAabbs = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); }, - (s) => { return s.m_params[0].shouldForceUpdateAllAabbs; }, - (s,p,l,v) => { s.m_params[0].shouldForceUpdateAllAabbs = v; } ), - new ParameterDefn("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction", - ConfigurationParameters.numericTrue, - (s,cf,p,v) => { s.m_params[0].shouldRandomizeSolverOrder = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); }, - (s) => { return s.m_params[0].shouldRandomizeSolverOrder; }, - (s,p,l,v) => { s.m_params[0].shouldRandomizeSolverOrder = v; } ), - new ParameterDefn("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands", - ConfigurationParameters.numericTrue, - (s,cf,p,v) => { s.m_params[0].shouldSplitSimulationIslands = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); }, - (s) => { return s.m_params[0].shouldSplitSimulationIslands; }, - (s,p,l,v) => { s.m_params[0].shouldSplitSimulationIslands = v; } ), - new ParameterDefn("ShouldEnableFrictionCaching", "Enable friction computation caching", - ConfigurationParameters.numericFalse, - (s,cf,p,v) => { s.m_params[0].shouldEnableFrictionCaching = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); }, - (s) => { return s.m_params[0].shouldEnableFrictionCaching; }, - (s,p,l,v) => { s.m_params[0].shouldEnableFrictionCaching = v; } ), - new ParameterDefn("NumberOfSolverIterations", "Number of internal iterations (0 means default)", - 0f, // zero says use Bullet default - (s,cf,p,v) => { s.m_params[0].numberOfSolverIterations = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].numberOfSolverIterations; }, - (s,p,l,v) => { s.m_params[0].numberOfSolverIterations = v; } ), - - new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", - (float)BSLinkset.LinksetImplementation.Compound, - (s,cf,p,v) => { s.m_params[0].linksetImplementation = cf.GetFloat(p,v); }, - (s) => { return s.m_params[0].linksetImplementation; }, - (s,p,l,v) => { s.m_params[0].linksetImplementation = v; } ), - new ParameterDefn("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.", - ConfigurationParameters.numericFalse, - (s,cf,p,v) => { s.m_params[0].linkConstraintUseFrameOffset = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); }, - (s) => { return s.m_params[0].linkConstraintUseFrameOffset; }, - (s,p,l,v) => { s.m_params[0].linkConstraintUseFrameOffset = v; } ), - new ParameterDefn("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints", - ConfigurationParameters.numericTrue, - (s,cf,p,v) => { s.m_params[0].linkConstraintEnableTransMotor = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); }, - (s) => { return s.m_params[0].linkConstraintEnableTransMotor; }, - (s,p,l,v) => { s.m_params[0].linkConstraintEnableTransMotor = v; } ), - new ParameterDefn("LinkConstraintTransMotorMaxVel", "Maximum velocity to be applied by translational motor in linkset constraints", - 5.0f, - (s,cf,p,v) => { s.m_params[0].linkConstraintTransMotorMaxVel = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].linkConstraintTransMotorMaxVel; }, - (s,p,l,v) => { s.m_params[0].linkConstraintTransMotorMaxVel = v; } ), - new ParameterDefn("LinkConstraintTransMotorMaxForce", "Maximum force to be applied by translational motor in linkset constraints", - 0.1f, - (s,cf,p,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].linkConstraintTransMotorMaxForce; }, - (s,p,l,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = v; } ), - new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1", - 0.1f, - (s,cf,p,v) => { s.m_params[0].linkConstraintCFM = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].linkConstraintCFM; }, - (s,p,l,v) => { s.m_params[0].linkConstraintCFM = v; } ), - new ParameterDefn("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2", - 0.1f, - (s,cf,p,v) => { s.m_params[0].linkConstraintERP = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].linkConstraintERP; }, - (s,p,l,v) => { s.m_params[0].linkConstraintERP = v; } ), - new ParameterDefn("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)", - 40, - (s,cf,p,v) => { s.m_params[0].linkConstraintSolverIterations = cf.GetFloat(p, v); }, - (s) => { return s.m_params[0].linkConstraintSolverIterations; }, - (s,p,l,v) => { s.m_params[0].linkConstraintSolverIterations = v; } ), - - new ParameterDefn("LogPhysicsStatisticsFrames", "Frames between outputting detailed phys stats. (0 is off)", - 0f, - (s,cf,p,v) => { s.m_params[0].physicsLoggingFrames = cf.GetInt(p, (int)v); }, - (s) => { return (float)s.m_params[0].physicsLoggingFrames; }, - (s,p,l,v) => { s.m_params[0].physicsLoggingFrames = (int)v; } ), - }; - - // Convert a boolean to our numeric true and false values - public float NumericBool(bool b) - { - return (b ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse); - } - - // Convert numeric true and false values to a boolean - public bool BoolNumeric(float b) - { - return (b == ConfigurationParameters.numericTrue ? true : false); - } - - // Search through the parameter definitions and return the matching - // ParameterDefn structure. - // Case does not matter as names are compared after converting to lower case. - // Returns 'false' if the parameter is not found. - private bool TryGetParameter(string paramName, out ParameterDefn defn) - { - bool ret = false; - ParameterDefn foundDefn = new ParameterDefn(); - string pName = paramName.ToLower(); - - foreach (ParameterDefn parm in ParameterDefinitions) - { - if (pName == parm.name.ToLower()) - { - foundDefn = parm; - ret = true; - break; - } - } - defn = foundDefn; - return ret; - } - - // Pass through the settable parameters and set the default values - private void SetParameterDefaultValues() - { - foreach (ParameterDefn parm in ParameterDefinitions) - { - parm.setter(this, parm.name, PhysParameterEntry.APPLY_TO_NONE, parm.defaultValue); - } - } - - // Get user set values out of the ini file. - private void SetParameterConfigurationValues(IConfig cfg) - { - foreach (ParameterDefn parm in ParameterDefinitions) - { - parm.userParam(this, cfg, parm.name, parm.defaultValue); - } - } - - private PhysParameterEntry[] SettableParameters = new PhysParameterEntry[1]; - - // This creates an array in the correct format for returning the list of - // parameters. This is used by the 'list' option of the 'physics' command. - private void BuildParameterTable() - { - if (SettableParameters.Length < ParameterDefinitions.Length) - { - List entries = new List(); - for (int ii = 0; ii < ParameterDefinitions.Length; ii++) - { - ParameterDefn pd = ParameterDefinitions[ii]; - entries.Add(new PhysParameterEntry(pd.name, pd.desc)); - } - - // make the list in alphabetical order for estetic reasons - entries.Sort(delegate(PhysParameterEntry ppe1, PhysParameterEntry ppe2) - { - return ppe1.name.CompareTo(ppe2.name); - }); - - SettableParameters = entries.ToArray(); - } - } - - #region IPhysicsParameters // Get the list of parameters this physics engine supports public PhysParameterEntry[] GetParameterList() { - BuildParameterTable(); - return SettableParameters; + BSParam.BuildParameterTable(); + return BSParam.SettableParameters; } // Set parameter on a specific or all instances. @@ -1434,8 +952,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public bool SetPhysicsParameter(string parm, float val, uint localID) { bool ret = false; - ParameterDefn theParam; - if (TryGetParameter(parm, out theParam)) + BSParam.ParameterDefn theParam; + if (BSParam.TryGetParameter(parm, out theParam)) { theParam.setter(this, parm, localID, val); ret = true; @@ -1447,19 +965,20 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // If the local ID is APPLY_TO_NONE, just change the default value // If the localID is APPLY_TO_ALL change the default value and apply the new value to all the lIDs // If the localID is a specific object, apply the parameter change to only that object - private void UpdateParameterObject(ref float defaultLoc, string parm, uint localID, float val) + internal delegate void AssignVal(float x); + internal void UpdateParameterObject(AssignVal setDefault, string parm, uint localID, float val) { List objectIDs = new List(); switch (localID) { case PhysParameterEntry.APPLY_TO_NONE: - defaultLoc = val; // setting only the default value + setDefault(val); // setting only the default value // This will cause a call into the physical world if some operation is specified (SetOnObject). objectIDs.Add(TERRAIN_ID); TaintedUpdateParameter(parm, objectIDs, val); break; case PhysParameterEntry.APPLY_TO_ALL: - defaultLoc = val; // setting ALL also sets the default value + setDefault(val); // setting ALL also sets the default value lock (PhysObjects) objectIDs = new List(PhysObjects.Keys); TaintedUpdateParameter(parm, objectIDs, val); break; @@ -1478,8 +997,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters List xlIDs = lIDs; string xparm = parm; TaintedObject("BSScene.UpdateParameterSet", delegate() { - ParameterDefn thisParam; - if (TryGetParameter(xparm, out thisParam)) + BSParam.ParameterDefn thisParam; + if (BSParam.TryGetParameter(xparm, out thisParam)) { if (thisParam.onObject != null) { @@ -1500,8 +1019,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters { float val = 0f; bool ret = false; - ParameterDefn theParam; - if (TryGetParameter(parm, out theParam)) + BSParam.ParameterDefn theParam; + if (BSParam.TryGetParameter(parm, out theParam)) { val = theParam.getter(this); ret = true; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index ea996ae..939d5e9 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -456,7 +456,7 @@ public sealed class BSShapeCollection : IDisposable if (!haveShape && pbs != null && nativeShapePossible - && ((pbs.SculptEntry && !PhysicsScene.ShouldMeshSculptedPrim) + && ((pbs.SculptEntry && !BSParam.ShouldMeshSculptedPrim) || (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0 && pbs.ProfileHollow == 0 && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0 @@ -520,7 +520,7 @@ public sealed class BSShapeCollection : IDisposable bool ret = false; // Note that if it's a native shape, the check for physical/non-physical is not // made. Native shapes work in either case. - if (prim.IsPhysical && PhysicsScene.ShouldUseHullsForPhysicalObjects) + if (prim.IsPhysical && BSParam.ShouldUseHullsForPhysicalObjects) { // Update prim.BSShape to reference a hull of this shape. ret = GetReferenceToHull(prim,shapeCallback); @@ -836,14 +836,14 @@ public sealed class BSShapeCollection : IDisposable private System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs, out float retLod) { // level of detail based on size and type of the object - float lod = PhysicsScene.MeshLOD; + float lod = BSParam.MeshLOD; if (pbs.SculptEntry) - lod = PhysicsScene.SculptLOD; + lod = BSParam.SculptLOD; // Mega prims usually get more detail because one can interact with shape approximations at this size. float maxAxis = Math.Max(size.X, Math.Max(size.Y, size.Z)); - if (maxAxis > PhysicsScene.MeshMegaPrimThreshold) - lod = PhysicsScene.MeshMegaPrimLOD; + if (maxAxis > BSParam.MeshMegaPrimThreshold) + lod = BSParam.MeshMegaPrimLOD; retLod = lod; return pbs.GetMeshKey(size, lod); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs index 2b120d6..07a9fd8 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs @@ -93,7 +93,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys { m_mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, m_mapInfo.ID, m_mapInfo.minCoords, m_mapInfo.maxCoords, - m_mapInfo.heightMap, PhysicsScene.Params.terrainCollisionMargin); + m_mapInfo.heightMap, BSParam.TerrainCollisionMargin); // Create the terrain shape from the mapInfo m_mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(m_mapInfo.Ptr), @@ -110,9 +110,9 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys m_mapInfo.ID, centerPos, Quaternion.Identity)); // Set current terrain attributes - BulletSimAPI.SetFriction2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainFriction); - BulletSimAPI.SetHitFraction2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainHitFraction); - BulletSimAPI.SetRestitution2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainRestitution); + BulletSimAPI.SetFriction2(m_mapInfo.terrainBody.ptr, BSParam.TerrainFriction); + BulletSimAPI.SetHitFraction2(m_mapInfo.terrainBody.ptr, BSParam.TerrainHitFraction); + BulletSimAPI.SetRestitution2(m_mapInfo.terrainBody.ptr, BSParam.TerrainRestitution); BulletSimAPI.SetCollisionFlags2(m_mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); // Return the new terrain to the world of physical objects diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index 3428b9c..86ccfbb 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -135,7 +135,7 @@ public sealed class BSTerrainManager : IDisposable // The ground plane is here to catch things that are trying to drop to negative infinity BulletShape groundPlaneShape = new BulletShape( BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, - PhysicsScene.Params.terrainCollisionMargin), + BSParam.TerrainCollisionMargin), BSPhysicsShapeType.SHAPE_GROUNDPLANE); m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID, BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID, @@ -309,9 +309,9 @@ public sealed class BSTerrainManager : IDisposable { PhysicsScene.Logger.DebugFormat("{0} Terrain for {1}/{2} created with {3}", LogHeader, PhysicsScene.RegionName, terrainRegionBase, - (BSTerrainPhys.TerrainImplementation)PhysicsScene.Params.terrainImplementation); + (BSTerrainPhys.TerrainImplementation)BSParam.TerrainImplementation); BSTerrainPhys newTerrainPhys = null; - switch ((int)PhysicsScene.Params.terrainImplementation) + switch ((int)BSParam.TerrainImplementation) { case (int)BSTerrainPhys.TerrainImplementation.Heightmap: newTerrainPhys = new BSTerrainHeightmap(PhysicsScene, terrainRegionBase, id, @@ -324,8 +324,8 @@ public sealed class BSTerrainManager : IDisposable default: PhysicsScene.Logger.ErrorFormat("{0} Bad terrain implementation specified. Type={1}/{2},Region={3}/{4}", LogHeader, - (int)PhysicsScene.Params.terrainImplementation, - PhysicsScene.Params.terrainImplementation, + (int)BSParam.TerrainImplementation, + BSParam.TerrainImplementation, PhysicsScene.RegionName, terrainRegionBase); break; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index 6dc0d92..061e232 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs @@ -116,9 +116,9 @@ public sealed class BSTerrainMesh : BSTerrainPhys } // Set current terrain attributes - BulletSimAPI.SetFriction2(m_terrainBody.ptr, PhysicsScene.Params.terrainFriction); - BulletSimAPI.SetHitFraction2(m_terrainBody.ptr, PhysicsScene.Params.terrainHitFraction); - BulletSimAPI.SetRestitution2(m_terrainBody.ptr, PhysicsScene.Params.terrainRestitution); + BulletSimAPI.SetFriction2(m_terrainBody.ptr, BSParam.TerrainFriction); + BulletSimAPI.SetHitFraction2(m_terrainBody.ptr, BSParam.TerrainHitFraction); + BulletSimAPI.SetRestitution2(m_terrainBody.ptr, BSParam.TerrainRestitution); BulletSimAPI.SetCollisionFlags2(m_terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); // Static objects are not very massive. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 962b540..7857eaa 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -141,6 +141,8 @@ public struct EntityProperties } // Format of this structure must match the definition in the C++ code +// NOTE: adding the X causes compile breaks if used. These are unused symbols +// that can be removed from both here and the unmanaged definition of this structure. [StructLayout(LayoutKind.Sequential)] public struct ConfigurationParameters { @@ -150,31 +152,31 @@ public struct ConfigurationParameters public float collisionMargin; public float gravity; - public float linearDamping; - public float angularDamping; - public float deactivationTime; - public float linearSleepingThreshold; - public float angularSleepingThreshold; - public float ccdMotionThreshold; - public float ccdSweptSphereRadius; - public float contactProcessingThreshold; - - public float terrainImplementation; - public float terrainFriction; - public float terrainHitFraction; - public float terrainRestitution; - public float terrainCollisionMargin; - - public float avatarFriction; - public float avatarStandingFriction; - public float avatarDensity; - public float avatarRestitution; - public float avatarCapsuleWidth; - public float avatarCapsuleDepth; - public float avatarCapsuleHeight; - public float avatarContactProcessingThreshold; - - public float vehicleAngularDamping; + public float XlinearDamping; + public float XangularDamping; + public float XdeactivationTime; + public float XlinearSleepingThreshold; + public float XangularSleepingThreshold; + public float XccdMotionThreshold; + public float XccdSweptSphereRadius; + public float XcontactProcessingThreshold; + + public float XterrainImplementation; + public float XterrainFriction; + public float XterrainHitFraction; + public float XterrainRestitution; + public float XterrainCollisionMargin; + + public float XavatarFriction; + public float XavatarStandingFriction; + public float XavatarDensity; + public float XavatarRestitution; + public float XavatarCapsuleWidth; + public float XavatarCapsuleDepth; + public float XavatarCapsuleHeight; + public float XavatarContactProcessingThreshold; + + public float XvehicleAngularDamping; public float maxPersistantManifoldPoolSize; public float maxCollisionAlgorithmPoolSize; @@ -185,14 +187,14 @@ public struct ConfigurationParameters public float shouldEnableFrictionCaching; public float numberOfSolverIterations; - public float linksetImplementation; - public float linkConstraintUseFrameOffset; - public float linkConstraintEnableTransMotor; - public float linkConstraintTransMotorMaxVel; - public float linkConstraintTransMotorMaxForce; - public float linkConstraintERP; - public float linkConstraintCFM; - public float linkConstraintSolverIterations; + public float XlinksetImplementation; + public float XlinkConstraintUseFrameOffset; + public float XlinkConstraintEnableTransMotor; + public float XlinkConstraintTransMotorMaxVel; + public float XlinkConstraintTransMotorMaxForce; + public float XlinkConstraintERP; + public float XlinkConstraintCFM; + public float XlinkConstraintSolverIterations; public float physicsLoggingFrames; -- cgit v1.1 From 6dbf9c8ed4ca5646f47043f9937da5acbe124d0e Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 21 Dec 2012 15:21:32 -0800 Subject: BulletSim: repair vehicle problems introduced in previous 'improvements'. Fix line endings in BSParams. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 37 +- OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 14 +- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 1117 ++++++++++---------- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 2 +- 4 files changed, 598 insertions(+), 572 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index e59ed8d..3fde57b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -634,28 +634,33 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_knownHas = 0; m_knownChanged = 0; } + // Push all the changed values back into the physics engine private void PushKnownChanged() { if (m_knownChanged != 0) { if ((m_knownChanged & m_knownChangedPosition) != 0) - Prim.ForcePosition = VehiclePosition; + Prim.ForcePosition = m_knownPosition; + if ((m_knownChanged & m_knownChangedOrientation) != 0) - Prim.ForceOrientation = VehicleOrientation; + Prim.ForceOrientation = m_knownOrientation; + if ((m_knownChanged & m_knownChangedVelocity) != 0) { - Prim.ForceVelocity = VehicleVelocity; + Prim.ForceVelocity = m_knownVelocity; BulletSimAPI.SetInterpolationLinearVelocity2(Prim.PhysBody.ptr, VehicleVelocity); } + if ((m_knownChanged & m_knownChangedForce) != 0) Prim.AddForce((Vector3)m_knownForce, false, true); if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) { - Prim.ForceRotationalVelocity = VehicleRotationalVelocity; + Prim.ForceRotationalVelocity = m_knownRotationalVelocity; // Fake out Bullet by making it think the velocity is the same as last time. - BulletSimAPI.SetInterpolationAngularVelocity2(Prim.PhysBody.ptr, VehicleRotationalVelocity); + BulletSimAPI.SetInterpolationAngularVelocity2(Prim.PhysBody.ptr, m_knownRotationalVelocity); } + if ((m_knownChanged & m_knownChangedRotationalForce) != 0) Prim.AddAngularForce((Vector3)m_knownRotationalForce, false, true); @@ -667,7 +672,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin } // Since the computation of terrain height can be a little involved, this routine - // is used ot fetch the height only once for each vehicle simulation step. + // is used to fetch the height only once for each vehicle simulation step. private float GetTerrainHeight(Vector3 pos) { if ((m_knownHas & m_knownChangedTerrainHeight) == 0) @@ -699,12 +704,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_knownPosition = Prim.ForcePosition; m_knownHas |= m_knownChangedPosition; } - return (Vector3)m_knownPosition; + return m_knownPosition; } set { m_knownPosition = value; m_knownChanged |= m_knownChangedPosition; + m_knownHas |= m_knownChangedPosition; } } @@ -717,12 +723,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_knownOrientation = Prim.ForceOrientation; m_knownHas |= m_knownChangedOrientation; } - return (Quaternion)m_knownOrientation; + return m_knownOrientation; } set { m_knownOrientation = value; m_knownChanged |= m_knownChangedOrientation; + m_knownHas |= m_knownChangedOrientation; } } @@ -741,13 +748,19 @@ namespace OpenSim.Region.Physics.BulletSPlugin { m_knownVelocity = value; m_knownChanged |= m_knownChangedVelocity; + m_knownHas |= m_knownChangedVelocity; } } private void VehicleAddForce(Vector3 aForce) { + if ((m_knownHas & m_knownChangedForce) == 0) + { + m_knownForce = Vector3.Zero; + } m_knownForce += aForce; m_knownChanged |= m_knownChangedForce; + m_knownHas |= m_knownChangedForce; } private Vector3 VehicleRotationalVelocity @@ -765,12 +778,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin { m_knownRotationalVelocity = value; m_knownChanged |= m_knownChangedRotationalVelocity; + m_knownHas |= m_knownChangedRotationalVelocity; } } private void VehicleAddAngularForce(Vector3 aForce) { + if ((m_knownHas & m_knownChangedRotationalForce) == 0) + { + m_knownRotationalForce = Vector3.Zero; + } m_knownRotationalForce += aForce; m_knownChanged |= m_knownChangedRotationalForce; + m_knownHas |= m_knownChangedRotationalForce; } // Vehicle relative forward velocity private Vector3 VehicleForwardVelocity @@ -782,7 +801,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_knownForwardVelocity = VehicleVelocity * Quaternion.Inverse(Quaternion.Normalize(VehicleOrientation)); m_knownHas |= m_knownChangedForwardVelocity; } - return (Vector3)m_knownForwardVelocity; + return m_knownForwardVelocity; } } private float VehicleForwardSpeed diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index 34a87c6..8781fe9 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -268,12 +268,14 @@ public class BSPIDVMotor : BSVMotor public Vector3 proportionFactor { get; set; } public Vector3 integralFactor { get; set; } public Vector3 derivFactor { get; set; } + // Arbritrary factor range. // EfficiencyHigh means move quickly to the correct number. EfficiencyLow means might over correct. public float EfficiencyHigh = 0.4f; public float EfficiencyLow = 4.0f; - Vector3 IntegralFactor { get; set; } + // Running integration of the error + Vector3 RunningIntegration { get; set; } public BSPIDVMotor(string useName) : base(useName) @@ -281,7 +283,7 @@ public class BSPIDVMotor : BSVMotor proportionFactor = new Vector3(1.00f, 1.00f, 1.00f); integralFactor = new Vector3(1.00f, 1.00f, 1.00f); derivFactor = new Vector3(1.00f, 1.00f, 1.00f); - IntegralFactor = Vector3.Zero; + RunningIntegration = Vector3.Zero; LastError = Vector3.Zero; } @@ -312,14 +314,18 @@ public class BSPIDVMotor : BSVMotor public override Vector3 Step(float timeStep, Vector3 error) { // Add up the error so we can integrate over the accumulated errors - IntegralFactor += error * timeStep; + RunningIntegration += error * timeStep; // A simple derivitive is the rate of change from the last error. Vector3 derivFactor = (error - LastError) * timeStep; LastError = error; // Correction = -(proportionOfPresentError + accumulationOfPastError + rateOfChangeOfError) - Vector3 ret = -(error * proportionFactor + IntegralFactor * integralFactor + derivFactor * derivFactor); + Vector3 ret = -( + error * proportionFactor + + RunningIntegration * integralFactor + + derivFactor * derivFactor + ); return ret; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 1fb4c31..5558ad5 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -1,558 +1,559 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Text; - -using OpenSim.Region.Physics.Manager; - -using OpenMetaverse; -using Nini.Config; - -namespace OpenSim.Region.Physics.BulletSPlugin -{ -public static class BSParam -{ - // Level of Detail values kept as float because that's what the Meshmerizer wants - public static float MeshLOD { get; private set; } - public static float MeshMegaPrimLOD { get; private set; } - public static float MeshMegaPrimThreshold { get; private set; } - public static float SculptLOD { get; private set; } - - public static float MinimumObjectMass { get; private set; } - public static float MaximumObjectMass { get; private set; } - - public static float LinearDamping { get; private set; } - public static float AngularDamping { get; private set; } - public static float DeactivationTime { get; private set; } - public static float LinearSleepingThreshold { get; private set; } - public static float AngularSleepingThreshold { get; private set; } - public static float CcdMotionThreshold { get; private set; } - public static float CcdSweptSphereRadius { get; private set; } - public static float ContactProcessingThreshold { get; private set; } - - public static bool ShouldMeshSculptedPrim { get; private set; } // cause scuplted prims to get meshed - public static bool ShouldForceSimplePrimMeshing { get; private set; } // if a cube or sphere, let Bullet do internal shapes - public static bool ShouldUseHullsForPhysicalObjects { get; private set; } // 'true' if should create hulls for physical objects - - public static float TerrainImplementation { get; private set; } - public static float TerrainFriction { get; private set; } - public static float TerrainHitFraction { get; private set; } - public static float TerrainRestitution { get; private set; } - public static float TerrainCollisionMargin { get; private set; } - - // Avatar parameters - public static float AvatarFriction { get; private set; } - public static float AvatarStandingFriction { get; private set; } - public static float AvatarDensity { get; private set; } - public static float AvatarRestitution { get; private set; } - public static float AvatarCapsuleWidth { get; private set; } - public static float AvatarCapsuleDepth { get; private set; } - public static float AvatarCapsuleHeight { get; private set; } - public static float AvatarContactProcessingThreshold { get; private set; } - - public static float VehicleAngularDamping { get; private set; } - - public static float LinksetImplementation { get; private set; } - public static float LinkConstraintUseFrameOffset { get; private set; } - public static float LinkConstraintEnableTransMotor { get; private set; } - public static float LinkConstraintTransMotorMaxVel { get; private set; } - public static float LinkConstraintTransMotorMaxForce { get; private set; } - public static float LinkConstraintERP { get; private set; } - public static float LinkConstraintCFM { get; private set; } - public static float LinkConstraintSolverIterations { get; private set; } - - public static float PID_D { get; private set; } // derivative - public static float PID_P { get; private set; } // proportional - - public delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val); - public delegate float ParamGet(BSScene scene); - public delegate void ParamSet(BSScene scene, string paramName, uint localID, float val); - public delegate void SetOnObject(BSScene scene, BSPhysObject obj, float val); - - public struct ParameterDefn - { - public string name; // string name of the parameter - public string desc; // a short description of what the parameter means - public float defaultValue; // default value if not specified anywhere else - public ParamUser userParam; // get the value from the configuration file - public ParamGet getter; // return the current value stored for this parameter - public ParamSet setter; // set the current value for this parameter - public SetOnObject onObject; // set the value on an object in the physical domain - public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s) - { - name = n; - desc = d; - defaultValue = v; - userParam = u; - getter = g; - setter = s; - onObject = null; - } - public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s, SetOnObject o) - { - name = n; - desc = d; - defaultValue = v; - userParam = u; - getter = g; - setter = s; - onObject = o; - } - } - - // List of all of the externally visible parameters. - // For each parameter, this table maps a text name to getter and setters. - // To add a new externally referencable/settable parameter, add the paramter storage - // location somewhere in the program and make an entry in this table with the - // getters and setters. - // It is easiest to find an existing definition and copy it. - // Parameter values are floats. Booleans are converted to a floating value. - // - // A ParameterDefn() takes the following parameters: - // -- the text name of the parameter. This is used for console input and ini file. - // -- a short text description of the parameter. This shows up in the console listing. - // -- a delegate for fetching the parameter from the ini file. - // Should handle fetching the right type from the ini file and converting it. - // -- a delegate for getting the value as a float - // -- a delegate for setting the value from a float - // -- an optional delegate to update the value in the world. Most often used to - // push the new value to an in-world object. - // - // The single letter parameters for the delegates are: - // s = BSScene - // o = BSPhysObject - // p = string parameter name - // l = localID of referenced object - // v = float value - // cf = parameter configuration class (for fetching values from ini file) - private static ParameterDefn[] ParameterDefinitions = - { - new ParameterDefn("MeshSculptedPrim", "Whether to create meshes for sculpties", - ConfigurationParameters.numericTrue, - (s,cf,p,v) => { ShouldMeshSculptedPrim = cf.GetBoolean(p, BSParam.BoolNumeric(v)); }, - (s) => { return BSParam.NumericBool(ShouldMeshSculptedPrim); }, - (s,p,l,v) => { ShouldMeshSculptedPrim = BSParam.BoolNumeric(v); } ), - new ParameterDefn("ForceSimplePrimMeshing", "If true, only use primitive meshes for objects", - ConfigurationParameters.numericFalse, - (s,cf,p,v) => { ShouldForceSimplePrimMeshing = cf.GetBoolean(p, BSParam.BoolNumeric(v)); }, - (s) => { return BSParam.NumericBool(ShouldForceSimplePrimMeshing); }, - (s,p,l,v) => { ShouldForceSimplePrimMeshing = BSParam.BoolNumeric(v); } ), - new ParameterDefn("UseHullsForPhysicalObjects", "If true, create hulls for physical objects", - ConfigurationParameters.numericTrue, - (s,cf,p,v) => { ShouldUseHullsForPhysicalObjects = cf.GetBoolean(p, BSParam.BoolNumeric(v)); }, - (s) => { return BSParam.NumericBool(ShouldUseHullsForPhysicalObjects); }, - (s,p,l,v) => { ShouldUseHullsForPhysicalObjects = BSParam.BoolNumeric(v); } ), - - new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", - 8f, - (s,cf,p,v) => { MeshLOD = (float)cf.GetInt(p, (int)v); }, - (s) => { return MeshLOD; }, - (s,p,l,v) => { MeshLOD = v; } ), - new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters", - 16f, - (s,cf,p,v) => { MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); }, - (s) => { return MeshMegaPrimLOD; }, - (s,p,l,v) => { MeshMegaPrimLOD = v; } ), - new ParameterDefn("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD", - 10f, - (s,cf,p,v) => { MeshMegaPrimThreshold = (float)cf.GetInt(p, (int)v); }, - (s) => { return MeshMegaPrimThreshold; }, - (s,p,l,v) => { MeshMegaPrimThreshold = v; } ), - new ParameterDefn("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)", - 32f, - (s,cf,p,v) => { SculptLOD = (float)cf.GetInt(p, (int)v); }, - (s) => { return SculptLOD; }, - (s,p,l,v) => { SculptLOD = v; } ), - - new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps", - 10f, - (s,cf,p,v) => { s.m_maxSubSteps = cf.GetInt(p, (int)v); }, - (s) => { return (float)s.m_maxSubSteps; }, - (s,p,l,v) => { s.m_maxSubSteps = (int)v; } ), - new ParameterDefn("FixedTimeStep", "In simulation step, seconds of one substep (1/60)", - 1f / 60f, - (s,cf,p,v) => { s.m_fixedTimeStep = cf.GetFloat(p, v); }, - (s) => { return (float)s.m_fixedTimeStep; }, - (s,p,l,v) => { s.m_fixedTimeStep = v; } ), - new ParameterDefn("MaxCollisionsPerFrame", "Max collisions returned at end of each frame", - 2048f, - (s,cf,p,v) => { s.m_maxCollisionsPerFrame = cf.GetInt(p, (int)v); }, - (s) => { return (float)s.m_maxCollisionsPerFrame; }, - (s,p,l,v) => { s.m_maxCollisionsPerFrame = (int)v; } ), - new ParameterDefn("MaxUpdatesPerFrame", "Max updates returned at end of each frame", - 8000f, - (s,cf,p,v) => { s.m_maxUpdatesPerFrame = cf.GetInt(p, (int)v); }, - (s) => { return (float)s.m_maxUpdatesPerFrame; }, - (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ), - new ParameterDefn("MaxTaintsToProcessPerStep", "Number of update taints to process before each simulation step", - 500f, - (s,cf,p,v) => { s.m_taintsToProcessPerStep = cf.GetInt(p, (int)v); }, - (s) => { return (float)s.m_taintsToProcessPerStep; }, - (s,p,l,v) => { s.m_taintsToProcessPerStep = (int)v; } ), - new ParameterDefn("MinObjectMass", "Minimum object mass (0.0001)", - 0.0001f, - (s,cf,p,v) => { MinimumObjectMass = cf.GetFloat(p, v); }, - (s) => { return (float)MinimumObjectMass; }, - (s,p,l,v) => { MinimumObjectMass = v; } ), - new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)", - 10000.01f, - (s,cf,p,v) => { MaximumObjectMass = cf.GetFloat(p, v); }, - (s) => { return (float)MaximumObjectMass; }, - (s,p,l,v) => { MaximumObjectMass = v; } ), - - new ParameterDefn("PID_D", "Derivitive factor for motion smoothing", - 2200f, - (s,cf,p,v) => { PID_D = cf.GetFloat(p, v); }, - (s) => { return (float)PID_D; }, - (s,p,l,v) => { PID_D = v; } ), - new ParameterDefn("PID_P", "Parameteric factor for motion smoothing", - 900f, - (s,cf,p,v) => { PID_P = cf.GetFloat(p, v); }, - (s) => { return (float)PID_P; }, - (s,p,l,v) => { PID_P = v; } ), - - new ParameterDefn("DefaultFriction", "Friction factor used on new objects", - 0.2f, - (s,cf,p,v) => { s.UnmanagedParams[0].defaultFriction = cf.GetFloat(p, v); }, - (s) => { return s.UnmanagedParams[0].defaultFriction; }, - (s,p,l,v) => { s.UnmanagedParams[0].defaultFriction = v; } ), - new ParameterDefn("DefaultDensity", "Density for new objects" , - 10.000006836f, // Aluminum g/cm3 - (s,cf,p,v) => { s.UnmanagedParams[0].defaultDensity = cf.GetFloat(p, v); }, - (s) => { return s.UnmanagedParams[0].defaultDensity; }, - (s,p,l,v) => { s.UnmanagedParams[0].defaultDensity = v; } ), - new ParameterDefn("DefaultRestitution", "Bouncyness of an object" , - 0f, - (s,cf,p,v) => { s.UnmanagedParams[0].defaultRestitution = cf.GetFloat(p, v); }, - (s) => { return s.UnmanagedParams[0].defaultRestitution; }, - (s,p,l,v) => { s.UnmanagedParams[0].defaultRestitution = v; } ), - new ParameterDefn("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!)", - 0.04f, - (s,cf,p,v) => { s.UnmanagedParams[0].collisionMargin = cf.GetFloat(p, v); }, - (s) => { return s.UnmanagedParams[0].collisionMargin; }, - (s,p,l,v) => { s.UnmanagedParams[0].collisionMargin = v; } ), - new ParameterDefn("Gravity", "Vertical force of gravity (negative means down)", - -9.80665f, - (s,cf,p,v) => { s.UnmanagedParams[0].gravity = cf.GetFloat(p, v); }, - (s) => { return s.UnmanagedParams[0].gravity; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{s.UnmanagedParams[0].gravity=x;}, p, PhysParameterEntry.APPLY_TO_NONE, v); }, - (s,o,v) => { BulletSimAPI.SetGravity2(s.World.ptr, new Vector3(0f,0f,v)); } ), - - - new ParameterDefn("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)", - 0f, - (s,cf,p,v) => { LinearDamping = cf.GetFloat(p, v); }, - (s) => { return LinearDamping; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{LinearDamping=x;}, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, v, AngularDamping); } ), - new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)", - 0f, - (s,cf,p,v) => { AngularDamping = cf.GetFloat(p, v); }, - (s) => { return AngularDamping; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularDamping=x;}, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, LinearDamping, v); } ), - new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static", - 0.2f, - (s,cf,p,v) => { DeactivationTime = cf.GetFloat(p, v); }, - (s) => { return DeactivationTime; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{DeactivationTime=x;}, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetDeactivationTime2(o.PhysBody.ptr, v); } ), - new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static", - 0.8f, - (s,cf,p,v) => { LinearSleepingThreshold = cf.GetFloat(p, v); }, - (s) => { return LinearSleepingThreshold; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{LinearSleepingThreshold=x;}, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ), - new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static", - 1.0f, - (s,cf,p,v) => { AngularSleepingThreshold = cf.GetFloat(p, v); }, - (s) => { return AngularSleepingThreshold; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularSleepingThreshold=x;}, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ), - new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" , - 0f, // set to zero to disable - (s,cf,p,v) => { CcdMotionThreshold = cf.GetFloat(p, v); }, - (s) => { return CcdMotionThreshold; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdMotionThreshold=x;}, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetCcdMotionThreshold2(o.PhysBody.ptr, v); } ), - new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" , - 0f, - (s,cf,p,v) => { CcdSweptSphereRadius = cf.GetFloat(p, v); }, - (s) => { return CcdSweptSphereRadius; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdSweptSphereRadius=x;}, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetCcdSweptSphereRadius2(o.PhysBody.ptr, v); } ), - new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" , - 0.1f, - (s,cf,p,v) => { ContactProcessingThreshold = cf.GetFloat(p, v); }, - (s) => { return ContactProcessingThreshold; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{ContactProcessingThreshold=x;}, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetContactProcessingThreshold2(o.PhysBody.ptr, v); } ), - - new ParameterDefn("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)", - (float)BSTerrainPhys.TerrainImplementation.Mesh, - (s,cf,p,v) => { TerrainImplementation = cf.GetFloat(p,v); }, - (s) => { return TerrainImplementation; }, - (s,p,l,v) => { TerrainImplementation = v; } ), - new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" , - 0.3f, - (s,cf,p,v) => { TerrainFriction = cf.GetFloat(p, v); }, - (s) => { return TerrainFriction; }, - (s,p,l,v) => { TerrainFriction = v; /* TODO: set on real terrain */} ), - new ParameterDefn("TerrainHitFraction", "Distance to measure hit collisions" , - 0.8f, - (s,cf,p,v) => { TerrainHitFraction = cf.GetFloat(p, v); }, - (s) => { return TerrainHitFraction; }, - (s,p,l,v) => { TerrainHitFraction = v; /* TODO: set on real terrain */ } ), - new ParameterDefn("TerrainRestitution", "Bouncyness" , - 0f, - (s,cf,p,v) => { TerrainRestitution = cf.GetFloat(p, v); }, - (s) => { return TerrainRestitution; }, - (s,p,l,v) => { TerrainRestitution = v; /* TODO: set on real terrain */ } ), - new ParameterDefn("TerrainCollisionMargin", "Margin where collision checking starts" , - 0.04f, - (s,cf,p,v) => { TerrainCollisionMargin = cf.GetFloat(p, v); }, - (s) => { return TerrainCollisionMargin; }, - (s,p,l,v) => { TerrainCollisionMargin = v; /* TODO: set on real terrain */ } ), - - new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.", - 0.2f, - (s,cf,p,v) => { AvatarFriction = cf.GetFloat(p, v); }, - (s) => { return AvatarFriction; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarFriction=x;}, p, l, v); } ), - new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", - 10.0f, - (s,cf,p,v) => { AvatarStandingFriction = cf.GetFloat(p, v); }, - (s) => { return AvatarStandingFriction; }, - (s,p,l,v) => { AvatarStandingFriction = v; } ), - new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.", - 60f, - (s,cf,p,v) => { AvatarDensity = cf.GetFloat(p, v); }, - (s) => { return AvatarDensity; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarDensity=x;}, p, l, v); } ), - new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.", - 0f, - (s,cf,p,v) => { AvatarRestitution = cf.GetFloat(p, v); }, - (s) => { return AvatarRestitution; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarRestitution=x;}, p, l, v); } ), - new ParameterDefn("AvatarCapsuleWidth", "The distance between the sides of the avatar capsule", - 0.6f, - (s,cf,p,v) => { AvatarCapsuleWidth = cf.GetFloat(p, v); }, - (s) => { return AvatarCapsuleWidth; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleWidth=x;}, p, l, v); } ), - new ParameterDefn("AvatarCapsuleDepth", "The distance between the front and back of the avatar capsule", - 0.45f, - (s,cf,p,v) => { AvatarCapsuleDepth = cf.GetFloat(p, v); }, - (s) => { return AvatarCapsuleDepth; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleDepth=x;}, p, l, v); } ), - new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar", - 1.5f, - (s,cf,p,v) => { AvatarCapsuleHeight = cf.GetFloat(p, v); }, - (s) => { return AvatarCapsuleHeight; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleHeight=x;}, p, l, v); } ), - new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", - 0.1f, - (s,cf,p,v) => { AvatarContactProcessingThreshold = cf.GetFloat(p, v); }, - (s) => { return AvatarContactProcessingThreshold; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarContactProcessingThreshold=x;}, p, l, v); } ), - - new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", - 0.95f, - (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); }, - (s) => { return VehicleAngularDamping; }, - (s,p,l,v) => { VehicleAngularDamping = v; } ), - - new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", - 0f, - (s,cf,p,v) => { s.UnmanagedParams[0].maxPersistantManifoldPoolSize = cf.GetFloat(p, v); }, - (s) => { return s.UnmanagedParams[0].maxPersistantManifoldPoolSize; }, - (s,p,l,v) => { s.UnmanagedParams[0].maxPersistantManifoldPoolSize = v; } ), - new ParameterDefn("MaxCollisionAlgorithmPoolSize", "Number of collisions pooled (0 means default of 4096)", - 0f, - (s,cf,p,v) => { s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = cf.GetFloat(p, v); }, - (s) => { return s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize; }, - (s,p,l,v) => { s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = v; } ), - new ParameterDefn("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count", - ConfigurationParameters.numericFalse, - (s,cf,p,v) => { s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, - (s) => { return s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation; }, - (s,p,l,v) => { s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = v; } ), - new ParameterDefn("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step", - ConfigurationParameters.numericFalse, - (s,cf,p,v) => { s.UnmanagedParams[0].shouldForceUpdateAllAabbs = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, - (s) => { return s.UnmanagedParams[0].shouldForceUpdateAllAabbs; }, - (s,p,l,v) => { s.UnmanagedParams[0].shouldForceUpdateAllAabbs = v; } ), - new ParameterDefn("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction", - ConfigurationParameters.numericTrue, - (s,cf,p,v) => { s.UnmanagedParams[0].shouldRandomizeSolverOrder = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, - (s) => { return s.UnmanagedParams[0].shouldRandomizeSolverOrder; }, - (s,p,l,v) => { s.UnmanagedParams[0].shouldRandomizeSolverOrder = v; } ), - new ParameterDefn("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands", - ConfigurationParameters.numericTrue, - (s,cf,p,v) => { s.UnmanagedParams[0].shouldSplitSimulationIslands = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, - (s) => { return s.UnmanagedParams[0].shouldSplitSimulationIslands; }, - (s,p,l,v) => { s.UnmanagedParams[0].shouldSplitSimulationIslands = v; } ), - new ParameterDefn("ShouldEnableFrictionCaching", "Enable friction computation caching", - ConfigurationParameters.numericFalse, - (s,cf,p,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, - (s) => { return s.UnmanagedParams[0].shouldEnableFrictionCaching; }, - (s,p,l,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = v; } ), - new ParameterDefn("NumberOfSolverIterations", "Number of internal iterations (0 means default)", - 0f, // zero says use Bullet default - (s,cf,p,v) => { s.UnmanagedParams[0].numberOfSolverIterations = cf.GetFloat(p, v); }, - (s) => { return s.UnmanagedParams[0].numberOfSolverIterations; }, - (s,p,l,v) => { s.UnmanagedParams[0].numberOfSolverIterations = v; } ), - - new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", - (float)BSLinkset.LinksetImplementation.Compound, - (s,cf,p,v) => { LinksetImplementation = cf.GetFloat(p,v); }, - (s) => { return LinksetImplementation; }, - (s,p,l,v) => { LinksetImplementation = v; } ), - new ParameterDefn("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.", - ConfigurationParameters.numericFalse, - (s,cf,p,v) => { LinkConstraintUseFrameOffset = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, - (s) => { return LinkConstraintUseFrameOffset; }, - (s,p,l,v) => { LinkConstraintUseFrameOffset = v; } ), - new ParameterDefn("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints", - ConfigurationParameters.numericTrue, - (s,cf,p,v) => { LinkConstraintEnableTransMotor = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, - (s) => { return LinkConstraintEnableTransMotor; }, - (s,p,l,v) => { LinkConstraintEnableTransMotor = v; } ), - new ParameterDefn("LinkConstraintTransMotorMaxVel", "Maximum velocity to be applied by translational motor in linkset constraints", - 5.0f, - (s,cf,p,v) => { LinkConstraintTransMotorMaxVel = cf.GetFloat(p, v); }, - (s) => { return LinkConstraintTransMotorMaxVel; }, - (s,p,l,v) => { LinkConstraintTransMotorMaxVel = v; } ), - new ParameterDefn("LinkConstraintTransMotorMaxForce", "Maximum force to be applied by translational motor in linkset constraints", - 0.1f, - (s,cf,p,v) => { LinkConstraintTransMotorMaxForce = cf.GetFloat(p, v); }, - (s) => { return LinkConstraintTransMotorMaxForce; }, - (s,p,l,v) => { LinkConstraintTransMotorMaxForce = v; } ), - new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1", - 0.1f, - (s,cf,p,v) => { LinkConstraintCFM = cf.GetFloat(p, v); }, - (s) => { return LinkConstraintCFM; }, - (s,p,l,v) => { LinkConstraintCFM = v; } ), - new ParameterDefn("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2", - 0.1f, - (s,cf,p,v) => { LinkConstraintERP = cf.GetFloat(p, v); }, - (s) => { return LinkConstraintERP; }, - (s,p,l,v) => { LinkConstraintERP = v; } ), - new ParameterDefn("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)", - 40, - (s,cf,p,v) => { LinkConstraintSolverIterations = cf.GetFloat(p, v); }, - (s) => { return LinkConstraintSolverIterations; }, - (s,p,l,v) => { LinkConstraintSolverIterations = v; } ), - - new ParameterDefn("LogPhysicsStatisticsFrames", "Frames between outputting detailed phys stats. (0 is off)", - 0f, - (s,cf,p,v) => { s.UnmanagedParams[0].physicsLoggingFrames = cf.GetInt(p, (int)v); }, - (s) => { return (float)s.UnmanagedParams[0].physicsLoggingFrames; }, - (s,p,l,v) => { s.UnmanagedParams[0].physicsLoggingFrames = (int)v; } ), - }; - - // Convert a boolean to our numeric true and false values - public static float NumericBool(bool b) - { - return (b ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse); - } - - // Convert numeric true and false values to a boolean - public static bool BoolNumeric(float b) - { - return (b == ConfigurationParameters.numericTrue ? true : false); - } - - // Search through the parameter definitions and return the matching - // ParameterDefn structure. - // Case does not matter as names are compared after converting to lower case. - // Returns 'false' if the parameter is not found. - internal static bool TryGetParameter(string paramName, out ParameterDefn defn) - { - bool ret = false; - ParameterDefn foundDefn = new ParameterDefn(); - string pName = paramName.ToLower(); - - foreach (ParameterDefn parm in ParameterDefinitions) - { - if (pName == parm.name.ToLower()) - { - foundDefn = parm; - ret = true; - break; - } - } - defn = foundDefn; - return ret; - } - - // Pass through the settable parameters and set the default values - internal static void SetParameterDefaultValues(BSScene physicsScene) - { - foreach (ParameterDefn parm in ParameterDefinitions) - { - parm.setter(physicsScene, parm.name, PhysParameterEntry.APPLY_TO_NONE, parm.defaultValue); - } - } - - // Get user set values out of the ini file. - internal static void SetParameterConfigurationValues(BSScene physicsScene, IConfig cfg) - { - foreach (ParameterDefn parm in ParameterDefinitions) - { - parm.userParam(physicsScene, cfg, parm.name, parm.defaultValue); - } - } - - internal static PhysParameterEntry[] SettableParameters = new PhysParameterEntry[1]; - - // This creates an array in the correct format for returning the list of - // parameters. This is used by the 'list' option of the 'physics' command. - internal static void BuildParameterTable() - { - if (SettableParameters.Length < ParameterDefinitions.Length) - { - List entries = new List(); - for (int ii = 0; ii < ParameterDefinitions.Length; ii++) - { - ParameterDefn pd = ParameterDefinitions[ii]; - entries.Add(new PhysParameterEntry(pd.name, pd.desc)); - } - - // make the list in alphabetical order for estetic reasons - entries.Sort(delegate(PhysParameterEntry ppe1, PhysParameterEntry ppe2) - { - return ppe1.name.CompareTo(ppe2.name); - }); - - SettableParameters = entries.ToArray(); - } - } - - -} -} +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; + +using OpenSim.Region.Physics.Manager; + +using OpenMetaverse; +using Nini.Config; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ +public static class BSParam +{ + // Level of Detail values kept as float because that's what the Meshmerizer wants + public static float MeshLOD { get; private set; } + public static float MeshMegaPrimLOD { get; private set; } + public static float MeshMegaPrimThreshold { get; private set; } + public static float SculptLOD { get; private set; } + + public static float MinimumObjectMass { get; private set; } + public static float MaximumObjectMass { get; private set; } + + public static float LinearDamping { get; private set; } + public static float AngularDamping { get; private set; } + public static float DeactivationTime { get; private set; } + public static float LinearSleepingThreshold { get; private set; } + public static float AngularSleepingThreshold { get; private set; } + public static float CcdMotionThreshold { get; private set; } + public static float CcdSweptSphereRadius { get; private set; } + public static float ContactProcessingThreshold { get; private set; } + + public static bool ShouldMeshSculptedPrim { get; private set; } // cause scuplted prims to get meshed + public static bool ShouldForceSimplePrimMeshing { get; private set; } // if a cube or sphere, let Bullet do internal shapes + public static bool ShouldUseHullsForPhysicalObjects { get; private set; } // 'true' if should create hulls for physical objects + + public static float TerrainImplementation { get; private set; } + public static float TerrainFriction { get; private set; } + public static float TerrainHitFraction { get; private set; } + public static float TerrainRestitution { get; private set; } + public static float TerrainCollisionMargin { get; private set; } + + // Avatar parameters + public static float AvatarFriction { get; private set; } + public static float AvatarStandingFriction { get; private set; } + public static float AvatarDensity { get; private set; } + public static float AvatarRestitution { get; private set; } + public static float AvatarCapsuleWidth { get; private set; } + public static float AvatarCapsuleDepth { get; private set; } + public static float AvatarCapsuleHeight { get; private set; } + public static float AvatarContactProcessingThreshold { get; private set; } + + public static float VehicleAngularDamping { get; private set; } + + public static float LinksetImplementation { get; private set; } + public static float LinkConstraintUseFrameOffset { get; private set; } + public static float LinkConstraintEnableTransMotor { get; private set; } + public static float LinkConstraintTransMotorMaxVel { get; private set; } + public static float LinkConstraintTransMotorMaxForce { get; private set; } + public static float LinkConstraintERP { get; private set; } + public static float LinkConstraintCFM { get; private set; } + public static float LinkConstraintSolverIterations { get; private set; } + + public static float PID_D { get; private set; } // derivative + public static float PID_P { get; private set; } // proportional + + public delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val); + public delegate float ParamGet(BSScene scene); + public delegate void ParamSet(BSScene scene, string paramName, uint localID, float val); + public delegate void SetOnObject(BSScene scene, BSPhysObject obj, float val); + + public struct ParameterDefn + { + public string name; // string name of the parameter + public string desc; // a short description of what the parameter means + public float defaultValue; // default value if not specified anywhere else + public ParamUser userParam; // get the value from the configuration file + public ParamGet getter; // return the current value stored for this parameter + public ParamSet setter; // set the current value for this parameter + public SetOnObject onObject; // set the value on an object in the physical domain + public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s) + { + name = n; + desc = d; + defaultValue = v; + userParam = u; + getter = g; + setter = s; + onObject = null; + } + public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s, SetOnObject o) + { + name = n; + desc = d; + defaultValue = v; + userParam = u; + getter = g; + setter = s; + onObject = o; + } + } + + // List of all of the externally visible parameters. + // For each parameter, this table maps a text name to getter and setters. + // To add a new externally referencable/settable parameter, add the paramter storage + // location somewhere in the program and make an entry in this table with the + // getters and setters. + // It is easiest to find an existing definition and copy it. + // Parameter values are floats. Booleans are converted to a floating value. + // + // A ParameterDefn() takes the following parameters: + // -- the text name of the parameter. This is used for console input and ini file. + // -- a short text description of the parameter. This shows up in the console listing. + // -- a default value (float) + // -- a delegate for fetching the parameter from the ini file. + // Should handle fetching the right type from the ini file and converting it. + // -- a delegate for getting the value as a float + // -- a delegate for setting the value from a float + // -- an optional delegate to update the value in the world. Most often used to + // push the new value to an in-world object. + // + // The single letter parameters for the delegates are: + // s = BSScene + // o = BSPhysObject + // p = string parameter name + // l = localID of referenced object + // v = value (float) + // cf = parameter configuration class (for fetching values from ini file) + private static ParameterDefn[] ParameterDefinitions = + { + new ParameterDefn("MeshSculptedPrim", "Whether to create meshes for sculpties", + ConfigurationParameters.numericTrue, + (s,cf,p,v) => { ShouldMeshSculptedPrim = cf.GetBoolean(p, BSParam.BoolNumeric(v)); }, + (s) => { return BSParam.NumericBool(ShouldMeshSculptedPrim); }, + (s,p,l,v) => { ShouldMeshSculptedPrim = BSParam.BoolNumeric(v); } ), + new ParameterDefn("ForceSimplePrimMeshing", "If true, only use primitive meshes for objects", + ConfigurationParameters.numericFalse, + (s,cf,p,v) => { ShouldForceSimplePrimMeshing = cf.GetBoolean(p, BSParam.BoolNumeric(v)); }, + (s) => { return BSParam.NumericBool(ShouldForceSimplePrimMeshing); }, + (s,p,l,v) => { ShouldForceSimplePrimMeshing = BSParam.BoolNumeric(v); } ), + new ParameterDefn("UseHullsForPhysicalObjects", "If true, create hulls for physical objects", + ConfigurationParameters.numericTrue, + (s,cf,p,v) => { ShouldUseHullsForPhysicalObjects = cf.GetBoolean(p, BSParam.BoolNumeric(v)); }, + (s) => { return BSParam.NumericBool(ShouldUseHullsForPhysicalObjects); }, + (s,p,l,v) => { ShouldUseHullsForPhysicalObjects = BSParam.BoolNumeric(v); } ), + + new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", + 8f, + (s,cf,p,v) => { MeshLOD = (float)cf.GetInt(p, (int)v); }, + (s) => { return MeshLOD; }, + (s,p,l,v) => { MeshLOD = v; } ), + new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters", + 16f, + (s,cf,p,v) => { MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); }, + (s) => { return MeshMegaPrimLOD; }, + (s,p,l,v) => { MeshMegaPrimLOD = v; } ), + new ParameterDefn("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD", + 10f, + (s,cf,p,v) => { MeshMegaPrimThreshold = (float)cf.GetInt(p, (int)v); }, + (s) => { return MeshMegaPrimThreshold; }, + (s,p,l,v) => { MeshMegaPrimThreshold = v; } ), + new ParameterDefn("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)", + 32f, + (s,cf,p,v) => { SculptLOD = (float)cf.GetInt(p, (int)v); }, + (s) => { return SculptLOD; }, + (s,p,l,v) => { SculptLOD = v; } ), + + new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps", + 10f, + (s,cf,p,v) => { s.m_maxSubSteps = cf.GetInt(p, (int)v); }, + (s) => { return (float)s.m_maxSubSteps; }, + (s,p,l,v) => { s.m_maxSubSteps = (int)v; } ), + new ParameterDefn("FixedTimeStep", "In simulation step, seconds of one substep (1/60)", + 1f / 60f, + (s,cf,p,v) => { s.m_fixedTimeStep = cf.GetFloat(p, v); }, + (s) => { return (float)s.m_fixedTimeStep; }, + (s,p,l,v) => { s.m_fixedTimeStep = v; } ), + new ParameterDefn("MaxCollisionsPerFrame", "Max collisions returned at end of each frame", + 2048f, + (s,cf,p,v) => { s.m_maxCollisionsPerFrame = cf.GetInt(p, (int)v); }, + (s) => { return (float)s.m_maxCollisionsPerFrame; }, + (s,p,l,v) => { s.m_maxCollisionsPerFrame = (int)v; } ), + new ParameterDefn("MaxUpdatesPerFrame", "Max updates returned at end of each frame", + 8000f, + (s,cf,p,v) => { s.m_maxUpdatesPerFrame = cf.GetInt(p, (int)v); }, + (s) => { return (float)s.m_maxUpdatesPerFrame; }, + (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ), + new ParameterDefn("MaxTaintsToProcessPerStep", "Number of update taints to process before each simulation step", + 500f, + (s,cf,p,v) => { s.m_taintsToProcessPerStep = cf.GetInt(p, (int)v); }, + (s) => { return (float)s.m_taintsToProcessPerStep; }, + (s,p,l,v) => { s.m_taintsToProcessPerStep = (int)v; } ), + new ParameterDefn("MinObjectMass", "Minimum object mass (0.0001)", + 0.0001f, + (s,cf,p,v) => { MinimumObjectMass = cf.GetFloat(p, v); }, + (s) => { return (float)MinimumObjectMass; }, + (s,p,l,v) => { MinimumObjectMass = v; } ), + new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)", + 10000.01f, + (s,cf,p,v) => { MaximumObjectMass = cf.GetFloat(p, v); }, + (s) => { return (float)MaximumObjectMass; }, + (s,p,l,v) => { MaximumObjectMass = v; } ), + + new ParameterDefn("PID_D", "Derivitive factor for motion smoothing", + 2200f, + (s,cf,p,v) => { PID_D = cf.GetFloat(p, v); }, + (s) => { return (float)PID_D; }, + (s,p,l,v) => { PID_D = v; } ), + new ParameterDefn("PID_P", "Parameteric factor for motion smoothing", + 900f, + (s,cf,p,v) => { PID_P = cf.GetFloat(p, v); }, + (s) => { return (float)PID_P; }, + (s,p,l,v) => { PID_P = v; } ), + + new ParameterDefn("DefaultFriction", "Friction factor used on new objects", + 0.2f, + (s,cf,p,v) => { s.UnmanagedParams[0].defaultFriction = cf.GetFloat(p, v); }, + (s) => { return s.UnmanagedParams[0].defaultFriction; }, + (s,p,l,v) => { s.UnmanagedParams[0].defaultFriction = v; } ), + new ParameterDefn("DefaultDensity", "Density for new objects" , + 10.000006836f, // Aluminum g/cm3 + (s,cf,p,v) => { s.UnmanagedParams[0].defaultDensity = cf.GetFloat(p, v); }, + (s) => { return s.UnmanagedParams[0].defaultDensity; }, + (s,p,l,v) => { s.UnmanagedParams[0].defaultDensity = v; } ), + new ParameterDefn("DefaultRestitution", "Bouncyness of an object" , + 0f, + (s,cf,p,v) => { s.UnmanagedParams[0].defaultRestitution = cf.GetFloat(p, v); }, + (s) => { return s.UnmanagedParams[0].defaultRestitution; }, + (s,p,l,v) => { s.UnmanagedParams[0].defaultRestitution = v; } ), + new ParameterDefn("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!)", + 0.04f, + (s,cf,p,v) => { s.UnmanagedParams[0].collisionMargin = cf.GetFloat(p, v); }, + (s) => { return s.UnmanagedParams[0].collisionMargin; }, + (s,p,l,v) => { s.UnmanagedParams[0].collisionMargin = v; } ), + new ParameterDefn("Gravity", "Vertical force of gravity (negative means down)", + -9.80665f, + (s,cf,p,v) => { s.UnmanagedParams[0].gravity = cf.GetFloat(p, v); }, + (s) => { return s.UnmanagedParams[0].gravity; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{s.UnmanagedParams[0].gravity=x;}, p, PhysParameterEntry.APPLY_TO_NONE, v); }, + (s,o,v) => { BulletSimAPI.SetGravity2(s.World.ptr, new Vector3(0f,0f,v)); } ), + + + new ParameterDefn("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)", + 0f, + (s,cf,p,v) => { LinearDamping = cf.GetFloat(p, v); }, + (s) => { return LinearDamping; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{LinearDamping=x;}, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, v, AngularDamping); } ), + new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)", + 0f, + (s,cf,p,v) => { AngularDamping = cf.GetFloat(p, v); }, + (s) => { return AngularDamping; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularDamping=x;}, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, LinearDamping, v); } ), + new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static", + 0.2f, + (s,cf,p,v) => { DeactivationTime = cf.GetFloat(p, v); }, + (s) => { return DeactivationTime; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{DeactivationTime=x;}, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetDeactivationTime2(o.PhysBody.ptr, v); } ), + new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static", + 0.8f, + (s,cf,p,v) => { LinearSleepingThreshold = cf.GetFloat(p, v); }, + (s) => { return LinearSleepingThreshold; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{LinearSleepingThreshold=x;}, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ), + new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static", + 1.0f, + (s,cf,p,v) => { AngularSleepingThreshold = cf.GetFloat(p, v); }, + (s) => { return AngularSleepingThreshold; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularSleepingThreshold=x;}, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ), + new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" , + 0f, // set to zero to disable + (s,cf,p,v) => { CcdMotionThreshold = cf.GetFloat(p, v); }, + (s) => { return CcdMotionThreshold; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdMotionThreshold=x;}, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetCcdMotionThreshold2(o.PhysBody.ptr, v); } ), + new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" , + 0f, + (s,cf,p,v) => { CcdSweptSphereRadius = cf.GetFloat(p, v); }, + (s) => { return CcdSweptSphereRadius; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdSweptSphereRadius=x;}, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetCcdSweptSphereRadius2(o.PhysBody.ptr, v); } ), + new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" , + 0.1f, + (s,cf,p,v) => { ContactProcessingThreshold = cf.GetFloat(p, v); }, + (s) => { return ContactProcessingThreshold; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{ContactProcessingThreshold=x;}, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetContactProcessingThreshold2(o.PhysBody.ptr, v); } ), + + new ParameterDefn("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)", + (float)BSTerrainPhys.TerrainImplementation.Mesh, + (s,cf,p,v) => { TerrainImplementation = cf.GetFloat(p,v); }, + (s) => { return TerrainImplementation; }, + (s,p,l,v) => { TerrainImplementation = v; } ), + new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" , + 0.3f, + (s,cf,p,v) => { TerrainFriction = cf.GetFloat(p, v); }, + (s) => { return TerrainFriction; }, + (s,p,l,v) => { TerrainFriction = v; /* TODO: set on real terrain */} ), + new ParameterDefn("TerrainHitFraction", "Distance to measure hit collisions" , + 0.8f, + (s,cf,p,v) => { TerrainHitFraction = cf.GetFloat(p, v); }, + (s) => { return TerrainHitFraction; }, + (s,p,l,v) => { TerrainHitFraction = v; /* TODO: set on real terrain */ } ), + new ParameterDefn("TerrainRestitution", "Bouncyness" , + 0f, + (s,cf,p,v) => { TerrainRestitution = cf.GetFloat(p, v); }, + (s) => { return TerrainRestitution; }, + (s,p,l,v) => { TerrainRestitution = v; /* TODO: set on real terrain */ } ), + new ParameterDefn("TerrainCollisionMargin", "Margin where collision checking starts" , + 0.04f, + (s,cf,p,v) => { TerrainCollisionMargin = cf.GetFloat(p, v); }, + (s) => { return TerrainCollisionMargin; }, + (s,p,l,v) => { TerrainCollisionMargin = v; /* TODO: set on real terrain */ } ), + + new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.", + 0.2f, + (s,cf,p,v) => { AvatarFriction = cf.GetFloat(p, v); }, + (s) => { return AvatarFriction; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarFriction=x;}, p, l, v); } ), + new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", + 10.0f, + (s,cf,p,v) => { AvatarStandingFriction = cf.GetFloat(p, v); }, + (s) => { return AvatarStandingFriction; }, + (s,p,l,v) => { AvatarStandingFriction = v; } ), + new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.", + 60f, + (s,cf,p,v) => { AvatarDensity = cf.GetFloat(p, v); }, + (s) => { return AvatarDensity; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarDensity=x;}, p, l, v); } ), + new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.", + 0f, + (s,cf,p,v) => { AvatarRestitution = cf.GetFloat(p, v); }, + (s) => { return AvatarRestitution; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarRestitution=x;}, p, l, v); } ), + new ParameterDefn("AvatarCapsuleWidth", "The distance between the sides of the avatar capsule", + 0.6f, + (s,cf,p,v) => { AvatarCapsuleWidth = cf.GetFloat(p, v); }, + (s) => { return AvatarCapsuleWidth; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleWidth=x;}, p, l, v); } ), + new ParameterDefn("AvatarCapsuleDepth", "The distance between the front and back of the avatar capsule", + 0.45f, + (s,cf,p,v) => { AvatarCapsuleDepth = cf.GetFloat(p, v); }, + (s) => { return AvatarCapsuleDepth; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleDepth=x;}, p, l, v); } ), + new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar", + 1.5f, + (s,cf,p,v) => { AvatarCapsuleHeight = cf.GetFloat(p, v); }, + (s) => { return AvatarCapsuleHeight; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleHeight=x;}, p, l, v); } ), + new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", + 0.1f, + (s,cf,p,v) => { AvatarContactProcessingThreshold = cf.GetFloat(p, v); }, + (s) => { return AvatarContactProcessingThreshold; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarContactProcessingThreshold=x;}, p, l, v); } ), + + new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", + 0.95f, + (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); }, + (s) => { return VehicleAngularDamping; }, + (s,p,l,v) => { VehicleAngularDamping = v; } ), + + new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", + 0f, + (s,cf,p,v) => { s.UnmanagedParams[0].maxPersistantManifoldPoolSize = cf.GetFloat(p, v); }, + (s) => { return s.UnmanagedParams[0].maxPersistantManifoldPoolSize; }, + (s,p,l,v) => { s.UnmanagedParams[0].maxPersistantManifoldPoolSize = v; } ), + new ParameterDefn("MaxCollisionAlgorithmPoolSize", "Number of collisions pooled (0 means default of 4096)", + 0f, + (s,cf,p,v) => { s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = cf.GetFloat(p, v); }, + (s) => { return s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize; }, + (s,p,l,v) => { s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = v; } ), + new ParameterDefn("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count", + ConfigurationParameters.numericFalse, + (s,cf,p,v) => { s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation; }, + (s,p,l,v) => { s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = v; } ), + new ParameterDefn("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step", + ConfigurationParameters.numericFalse, + (s,cf,p,v) => { s.UnmanagedParams[0].shouldForceUpdateAllAabbs = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return s.UnmanagedParams[0].shouldForceUpdateAllAabbs; }, + (s,p,l,v) => { s.UnmanagedParams[0].shouldForceUpdateAllAabbs = v; } ), + new ParameterDefn("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction", + ConfigurationParameters.numericTrue, + (s,cf,p,v) => { s.UnmanagedParams[0].shouldRandomizeSolverOrder = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return s.UnmanagedParams[0].shouldRandomizeSolverOrder; }, + (s,p,l,v) => { s.UnmanagedParams[0].shouldRandomizeSolverOrder = v; } ), + new ParameterDefn("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands", + ConfigurationParameters.numericTrue, + (s,cf,p,v) => { s.UnmanagedParams[0].shouldSplitSimulationIslands = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return s.UnmanagedParams[0].shouldSplitSimulationIslands; }, + (s,p,l,v) => { s.UnmanagedParams[0].shouldSplitSimulationIslands = v; } ), + new ParameterDefn("ShouldEnableFrictionCaching", "Enable friction computation caching", + ConfigurationParameters.numericFalse, + (s,cf,p,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return s.UnmanagedParams[0].shouldEnableFrictionCaching; }, + (s,p,l,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = v; } ), + new ParameterDefn("NumberOfSolverIterations", "Number of internal iterations (0 means default)", + 0f, // zero says use Bullet default + (s,cf,p,v) => { s.UnmanagedParams[0].numberOfSolverIterations = cf.GetFloat(p, v); }, + (s) => { return s.UnmanagedParams[0].numberOfSolverIterations; }, + (s,p,l,v) => { s.UnmanagedParams[0].numberOfSolverIterations = v; } ), + + new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", + (float)BSLinkset.LinksetImplementation.Compound, + (s,cf,p,v) => { LinksetImplementation = cf.GetFloat(p,v); }, + (s) => { return LinksetImplementation; }, + (s,p,l,v) => { LinksetImplementation = v; } ), + new ParameterDefn("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.", + ConfigurationParameters.numericFalse, + (s,cf,p,v) => { LinkConstraintUseFrameOffset = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return LinkConstraintUseFrameOffset; }, + (s,p,l,v) => { LinkConstraintUseFrameOffset = v; } ), + new ParameterDefn("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints", + ConfigurationParameters.numericTrue, + (s,cf,p,v) => { LinkConstraintEnableTransMotor = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return LinkConstraintEnableTransMotor; }, + (s,p,l,v) => { LinkConstraintEnableTransMotor = v; } ), + new ParameterDefn("LinkConstraintTransMotorMaxVel", "Maximum velocity to be applied by translational motor in linkset constraints", + 5.0f, + (s,cf,p,v) => { LinkConstraintTransMotorMaxVel = cf.GetFloat(p, v); }, + (s) => { return LinkConstraintTransMotorMaxVel; }, + (s,p,l,v) => { LinkConstraintTransMotorMaxVel = v; } ), + new ParameterDefn("LinkConstraintTransMotorMaxForce", "Maximum force to be applied by translational motor in linkset constraints", + 0.1f, + (s,cf,p,v) => { LinkConstraintTransMotorMaxForce = cf.GetFloat(p, v); }, + (s) => { return LinkConstraintTransMotorMaxForce; }, + (s,p,l,v) => { LinkConstraintTransMotorMaxForce = v; } ), + new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1", + 0.1f, + (s,cf,p,v) => { LinkConstraintCFM = cf.GetFloat(p, v); }, + (s) => { return LinkConstraintCFM; }, + (s,p,l,v) => { LinkConstraintCFM = v; } ), + new ParameterDefn("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2", + 0.1f, + (s,cf,p,v) => { LinkConstraintERP = cf.GetFloat(p, v); }, + (s) => { return LinkConstraintERP; }, + (s,p,l,v) => { LinkConstraintERP = v; } ), + new ParameterDefn("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)", + 40, + (s,cf,p,v) => { LinkConstraintSolverIterations = cf.GetFloat(p, v); }, + (s) => { return LinkConstraintSolverIterations; }, + (s,p,l,v) => { LinkConstraintSolverIterations = v; } ), + + new ParameterDefn("LogPhysicsStatisticsFrames", "Frames between outputting detailed phys stats. (0 is off)", + 0f, + (s,cf,p,v) => { s.UnmanagedParams[0].physicsLoggingFrames = cf.GetInt(p, (int)v); }, + (s) => { return (float)s.UnmanagedParams[0].physicsLoggingFrames; }, + (s,p,l,v) => { s.UnmanagedParams[0].physicsLoggingFrames = (int)v; } ), + }; + + // Convert a boolean to our numeric true and false values + public static float NumericBool(bool b) + { + return (b ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse); + } + + // Convert numeric true and false values to a boolean + public static bool BoolNumeric(float b) + { + return (b == ConfigurationParameters.numericTrue ? true : false); + } + + // Search through the parameter definitions and return the matching + // ParameterDefn structure. + // Case does not matter as names are compared after converting to lower case. + // Returns 'false' if the parameter is not found. + internal static bool TryGetParameter(string paramName, out ParameterDefn defn) + { + bool ret = false; + ParameterDefn foundDefn = new ParameterDefn(); + string pName = paramName.ToLower(); + + foreach (ParameterDefn parm in ParameterDefinitions) + { + if (pName == parm.name.ToLower()) + { + foundDefn = parm; + ret = true; + break; + } + } + defn = foundDefn; + return ret; + } + + // Pass through the settable parameters and set the default values + internal static void SetParameterDefaultValues(BSScene physicsScene) + { + foreach (ParameterDefn parm in ParameterDefinitions) + { + parm.setter(physicsScene, parm.name, PhysParameterEntry.APPLY_TO_NONE, parm.defaultValue); + } + } + + // Get user set values out of the ini file. + internal static void SetParameterConfigurationValues(BSScene physicsScene, IConfig cfg) + { + foreach (ParameterDefn parm in ParameterDefinitions) + { + parm.userParam(physicsScene, cfg, parm.name, parm.defaultValue); + } + } + + internal static PhysParameterEntry[] SettableParameters = new PhysParameterEntry[1]; + + // This creates an array in the correct format for returning the list of + // parameters. This is used by the 'list' option of the 'physics' command. + internal static void BuildParameterTable() + { + if (SettableParameters.Length < ParameterDefinitions.Length) + { + List entries = new List(); + for (int ii = 0; ii < ParameterDefinitions.Length; ii++) + { + ParameterDefn pd = ParameterDefinitions[ii]; + entries.Add(new PhysParameterEntry(pd.name, pd.desc)); + } + + // make the list in alphabetical order for estetic reasons + entries.Sort(delegate(PhysParameterEntry ppe1, PhysParameterEntry ppe2) + { + return ppe1.name.CompareTo(ppe2.name); + }); + + SettableParameters = entries.ToArray(); + } + } + + +} +} diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 492a255..eb47178 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -864,7 +864,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters { DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom); m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom); - Util.PrintCallStack(DetailLog); // Prints the stack into the DEBUG log file. + Util.PrintCallStack(DetailLog); } return InTaintTime; } -- cgit v1.1 From 3d659fe97d79c04983dcfa8c78e9dde1623f54f2 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 21 Dec 2012 17:27:53 -0800 Subject: BulletSim: add BSPhysObject code to manage registrations of preStep events. Use same to implement setForce and setTorque so the values are restored at the beginning of each step (since Bullet zeros forces applied last step). Simplify implementation of AddForce and AddTorque by relying on the addition of forces in Bullet. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 2 + .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 56 ++++++++++- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 112 +++++++++------------ 3 files changed, 104 insertions(+), 66 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 7bde1c1..b392d75 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -134,6 +134,8 @@ public sealed class BSCharacter : BSPhysObject // called when this character is being destroyed and the resources should be released public override void Destroy() { + base.Destroy(); + DetailLog("{0},BSCharacter.Destroy", LocalID); PhysicsScene.TaintedObject("BSCharacter.destroy", delegate() { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 92a5f2f..9525a11 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -45,6 +45,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin * ForceVariableName: direct reference (store and fetch) to the value in the physics engine. * The last two (and certainly the last one) should be referenced only in taint-time. */ + +/* + * As of 20121221, the following are the call sequences (going down) for different script physical functions: + * llApplyImpulse llApplyRotImpulse llSetTorque llSetForce + * SOP.ApplyImpulse SOP.ApplyAngularImpulse SOP.SetAngularImpulse SOP.SetForce + * SOG.ApplyImpulse SOG.ApplyAngularImpulse SOG.SetAngularImpulse + * PA.AddForce PA.AddAngularForce PA.Torque = v PA.Force = v + * BS.ApplyCentralForce BS.ApplyTorque + */ + public abstract class BSPhysObject : PhysicsActor { protected BSPhysObject() @@ -69,6 +79,12 @@ public abstract class BSPhysObject : PhysicsActor CollidingGroundStep = 0; } + // Tell the object to clean up. + public virtual void Destroy() + { + UnRegisterAllPreStepActions(); + } + public BSScene PhysicsScene { get; protected set; } // public override uint LocalID { get; set; } // Use the LocalID definition in PhysicsActor public string PhysObjectName { get; protected set; } @@ -130,9 +146,6 @@ public abstract class BSPhysObject : PhysicsActor // Update the physical location and motion of the object. Called with data from Bullet. public abstract void UpdateProperties(EntityProperties entprop); - // Tell the object to clean up. - public abstract void Destroy(); - public abstract OMV.Vector3 RawPosition { get; set; } public abstract OMV.Vector3 ForcePosition { get; set; } @@ -280,11 +293,48 @@ public abstract class BSPhysObject : PhysicsActor #endregion // Collisions + #region Per Simulation Step actions + // There are some actions that must be performed for a physical object before each simulation step. + // These actions are optional so, rather than scanning all the physical objects and asking them + // if they have anything to do, a physical object registers for an event call before the step is performed. + // This bookkeeping makes it easy to add, remove and clean up after all these registrations. + private Dictionary RegisteredActions = new Dictionary(); + protected void RegisterPreStepAction(string op, uint id, BSScene.PreStepAction actn) + { + string identifier = op + "-" + id.ToString(); + RegisteredActions[identifier] = actn; + PhysicsScene.BeforeStep += actn; + } + + // Unregister a pre step action. Safe to call if the action has not been registered. + protected void UnRegisterPreStepAction(string op, uint id) + { + string identifier = op + "-" + id.ToString(); + if (RegisteredActions.ContainsKey(identifier)) + { + PhysicsScene.BeforeStep -= RegisteredActions[identifier]; + RegisteredActions.Remove(identifier); + } + } + + protected void UnRegisterAllPreStepActions() + { + foreach (KeyValuePair kvp in RegisteredActions) + { + PhysicsScene.BeforeStep -= kvp.Value; + } + RegisteredActions.Clear(); + } + + + #endregion // Per Simulation Step actions + // High performance detailed logging routine used by the physical objects. protected void DetailLog(string msg, params Object[] args) { if (PhysicsScene.PhysicsLogging.Enabled) PhysicsScene.DetailLog(msg, args); } + } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index e43bf8e..e6aeebb 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -129,6 +129,7 @@ public sealed class BSPrim : BSPhysObject public override void Destroy() { // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); + base.Destroy(); // Undo any links between me and any other object BSPhysObject parentBefore = Linkset.LinksetRoot; @@ -434,12 +435,22 @@ public sealed class BSPrim : BSPhysObject get { return _force; } set { _force = value; - PhysicsScene.TaintedObject("BSPrim.setForce", delegate() + if (_force != OMV.Vector3.Zero) { - // DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force); - if (PhysBody.HasPhysicalBody) - BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force); - }); + // If the force is non-zero, it must be reapplied each tick because + // Bullet clears the forces applied last frame. + RegisterPreStepAction("BSPrim.setForce", LocalID, + delegate(float timeStep) + { + if (PhysBody.HasPhysicalBody) + BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, _force); + } + ); + } + else + { + UnRegisterPreStepAction("BSPrim.setForce", LocalID); + } } } @@ -550,7 +561,22 @@ public sealed class BSPrim : BSPhysObject get { return _torque; } set { _torque = value; - AddAngularForce(_torque, false, false); + if (_torque != OMV.Vector3.Zero) + { + // If the torque is non-zero, it must be reapplied each tick because + // Bullet clears the forces applied last frame. + RegisterPreStepAction("BSPrim.setTorque", LocalID, + delegate(float timeStep) + { + if (PhysBody.HasPhysicalBody) + AddAngularForce(_torque, false, true); + } + ); + } + else + { + UnRegisterPreStepAction("BSPrim.setTorque", LocalID); + } // DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque); } } @@ -969,56 +995,32 @@ public sealed class BSPrim : BSPhysObject public override float APIDStrength { set { return; } } public override float APIDDamping { set { return; } } - private List m_accumulatedForces = new List(); public override void AddForce(OMV.Vector3 force, bool pushforce) { AddForce(force, pushforce, false); } // Applying a force just adds this to the total force on the object. + // This added force will only last the next simulation tick. public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { // for an object, doesn't matter if force is a pushforce or not if (force.IsFinite()) { - // _force += force; - lock (m_accumulatedForces) - m_accumulatedForces.Add(new OMV.Vector3(force)); + OMV.Vector3 addForce = force; + DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); + PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() + { + // Bullet adds this central force to the total force for this tick + DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce); + if (PhysBody.HasPhysicalBody) + BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, addForce); + }); } else { m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID); return; } - PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() - { - OMV.Vector3 fSum = OMV.Vector3.Zero; - lock (m_accumulatedForces) - { - // Sum the accumulated additional forces for one big force to apply once. - foreach (OMV.Vector3 v in m_accumulatedForces) - { - fSum += v; - } - m_accumulatedForces.Clear(); - } - DetailLog("{0},BSPrim.AddForce,taint,force={1}", LocalID, fSum); - if (fSum != OMV.Vector3.Zero) - if (PhysBody.HasPhysicalBody) - BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, fSum); - }); } - // An impulse force is scaled by the mass of the object. - public void ApplyForceImpulse(OMV.Vector3 impulse, bool inTaintTime) - { - OMV.Vector3 applyImpulse = impulse; - PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ApplyForceImpulse", delegate() - { - DetailLog("{0},BSPrim.ApplyForceImpulse,taint,tImpulse={1}", LocalID, applyImpulse); - if (PhysBody.HasPhysicalBody) - BulletSimAPI.ApplyCentralImpulse2(PhysBody.ptr, applyImpulse); - }); - } - - private List m_accumulatedAngularForces = new List(); public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { AddAngularForce(force, pushforce, false); } @@ -1026,36 +1028,20 @@ public sealed class BSPrim : BSPhysObject { if (force.IsFinite()) { - // _force += force; - lock (m_accumulatedAngularForces) - m_accumulatedAngularForces.Add(new OMV.Vector3(force)); + OMV.Vector3 angForce = force; + PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddAngularForce", delegate() + { + if (PhysBody.HasPhysicalBody) + BulletSimAPI.ApplyTorque2(PhysBody.ptr, angForce); + }); } else { m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID); return; } - PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddAngularForce", delegate() - { - OMV.Vector3 fSum = OMV.Vector3.Zero; - lock (m_accumulatedAngularForces) - { - // Sum the accumulated additional forces for one big force to apply once. - foreach (OMV.Vector3 v in m_accumulatedAngularForces) - { - fSum += v; - } - m_accumulatedAngularForces.Clear(); - } - DetailLog("{0},BSPrim.AddAngularForce,taint,aForce={1}", LocalID, fSum); - if (fSum != OMV.Vector3.Zero) - { - if (PhysBody.HasPhysicalBody) - BulletSimAPI.ApplyTorque2(PhysBody.ptr, fSum); - _torque = fSum; - } - }); } + // A torque impulse. // ApplyTorqueImpulse adds torque directly to the angularVelocity. // AddAngularForce accumulates the force and applied it to the angular velocity all at once. -- cgit v1.1 From 37fb691ba56a72b95eeeacc13fb16c1f03af6006 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 21 Dec 2012 23:03:27 -0800 Subject: BulletSim: Fix llApplyImpulse so it works after the first impulse. The problem was Bullet deactivating the object between the pushes (when, as far as the physics engine is concerned, it isn't moving). --- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 5 ++++ OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 28 ++++++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 9525a11..19de1e5 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -304,17 +304,21 @@ public abstract class BSPhysObject : PhysicsActor string identifier = op + "-" + id.ToString(); RegisteredActions[identifier] = actn; PhysicsScene.BeforeStep += actn; + DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier); } // Unregister a pre step action. Safe to call if the action has not been registered. protected void UnRegisterPreStepAction(string op, uint id) { string identifier = op + "-" + id.ToString(); + bool removed = false; if (RegisteredActions.ContainsKey(identifier)) { PhysicsScene.BeforeStep -= RegisteredActions[identifier]; RegisteredActions.Remove(identifier); + removed = true; } + DetailLog("{0},BSPhysObject.UnRegisterPreStepAction,id={1},removed={2}", LocalID, identifier, removed); } protected void UnRegisterAllPreStepActions() @@ -324,6 +328,7 @@ public abstract class BSPhysObject : PhysicsActor PhysicsScene.BeforeStep -= kvp.Value; } RegisteredActions.Clear(); + DetailLog("{0},BSPhysObject.UnRegisterAllPreStepActions,", LocalID); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index e6aeebb..d137b2a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -442,8 +442,12 @@ public sealed class BSPrim : BSPhysObject RegisterPreStepAction("BSPrim.setForce", LocalID, delegate(float timeStep) { + DetailLog("{0},BSPrim.setForce,preStep,force={1}", LocalID, _force); if (PhysBody.HasPhysicalBody) + { BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, _force); + ActivateIfPhysical(false); + } } ); } @@ -554,7 +558,10 @@ public sealed class BSPrim : BSPhysObject _velocity = value; if (PhysBody.HasPhysicalBody) + { BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); + ActivateIfPhysical(false); + } } } public override OMV.Vector3 Torque { @@ -845,7 +852,7 @@ public sealed class BSPrim : BSPhysObject // Called in taint-time!! private void ActivateIfPhysical(bool forceIt) { - if (IsPhysical) + if (IsPhysical && PhysBody.HasPhysicalBody) BulletSimAPI.Activate2(PhysBody.ptr, forceIt); } @@ -919,8 +926,7 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject("BSPrim.setRotationalVelocity", delegate() { DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); - if (PhysBody.HasPhysicalBody) - BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity); + ForceRotationalVelocity = _rotationalVelocity; }); } } @@ -930,7 +936,11 @@ public sealed class BSPrim : BSPhysObject } set { _rotationalVelocity = value; - BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity); + if (PhysBody.HasPhysicalBody) + { + BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity); + ActivateIfPhysical(false); + } } } public override bool Kinematic { @@ -959,6 +969,7 @@ public sealed class BSPrim : BSPhysObject { float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav)); + ActivateIfPhysical(false); } } } @@ -1011,7 +1022,10 @@ public sealed class BSPrim : BSPhysObject // Bullet adds this central force to the total force for this tick DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce); if (PhysBody.HasPhysicalBody) + { BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, addForce); + ActivateIfPhysical(false); + } }); } else @@ -1032,7 +1046,10 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddAngularForce", delegate() { if (PhysBody.HasPhysicalBody) + { BulletSimAPI.ApplyTorque2(PhysBody.ptr, angForce); + ActivateIfPhysical(false); + } }); } else @@ -1052,7 +1069,10 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ApplyTorqueImpulse", delegate() { if (PhysBody.HasPhysicalBody) + { BulletSimAPI.ApplyTorqueImpulse2(PhysBody.ptr, applyImpulse); + ActivateIfPhysical(false); + } }); } -- cgit v1.1 From a54392d7cc0c81d70d241393da8f50c409e9b895 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 21 Dec 2012 23:05:05 -0800 Subject: BulletSim: remove the movement decay while flying. Made flying slow down over time. --- OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 6 ------ 1 file changed, 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index b392d75..01cd279 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -563,12 +563,6 @@ public sealed class BSCharacter : BSPhysObject set { _flying = value; - // Velocity movement is different when flying: flying velocity degrades over time. - if (_flying) - _velocityMotor.TargetValueDecayTimeScale = 1f; - else - _velocityMotor.TargetValueDecayTimeScale = BSMotor.Infinite; - // simulate flying by changing the effect of gravity Buoyancy = ComputeBuoyancyFromFlying(_flying); } -- cgit v1.1 From 5b2cbc0ae69c041abb34d70fd03e4e1a4b7f4ea4 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 21 Dec 2012 23:24:31 -0800 Subject: BulletSim: remove all special vehicle code from BSScene. Replace per-frame updates for vehicles with per-frame action registration. One fewer special case. --- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 26 ++----- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 95 ++++--------------------- 2 files changed, 20 insertions(+), 101 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index d137b2a..26b8df5 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -465,15 +465,18 @@ public sealed class BSPrim : BSPhysObject set { Vehicle type = (Vehicle)value; - // Tell the scene about the vehicle so it will get processing each frame. - PhysicsScene.VehicleInSceneTypeChanged(this, type); - PhysicsScene.TaintedObject("setVehicleType", delegate() { // Done at taint time so we're sure the physics engine is not using the variables // Vehicle code changes the parameters for this vehicle type. _vehicle.ProcessTypeChange(type); ActivateIfPhysical(false); + + // If an active vehicle, register the vehicle code to be called before each step + if (_vehicle.Type == Vehicle.TYPE_NONE) + UnRegisterPreStepAction("BSPrim.Vehicle", LocalID); + else + RegisterPreStepAction("BSPrim.Vehicle", LocalID, _vehicle.Step); }); } } @@ -509,23 +512,6 @@ public sealed class BSPrim : BSPhysObject }); } - // Called each simulation step to advance vehicle characteristics. - // Called from Scene when doing simulation step so we're in taint processing time. - public override void StepVehicle(float timeStep) - { - if (IsPhysical && _vehicle.IsActive) - { - _vehicle.Step(timeStep); - /* // TEST TEST DEBUG DEBUG -- trying to reduce the extra action of Bullet simulation step - PhysicsScene.PostTaintObject("BSPrim.StepVehicles", LocalID, delegate() - { - // This resets the interpolation values and recomputes the tensor variables - BulletSimAPI.SetCenterOfMassByPosRot2(BSBody.ptr, ForcePosition, ForceOrientation); - }); - */ - } - } - // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more public override void SetVolumeDetect(int param) { bool newValue = (param != 0); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index eb47178..3a129a4 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -69,10 +69,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // every tick so OpenSim will update its animation. private HashSet m_avatars = new HashSet(); - // List of all the objects that have vehicle properties and should be called - // to update each physics step. - private List m_vehicles = new List(); - // let my minuions use my logger public ILog Logger { get { return m_log; } } @@ -480,21 +476,25 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // update the prim states while we know the physics engine is not busy int numTaints = _taintOperations.Count; + + InTaintTime = true; // Only used for debugging so locking is not necessary. + ProcessTaints(); - // Some of the prims operate with special vehicle properties + // Some of the physical objects requre individual, pre-step calls DoPreStepActions(timeStep); // the prestep actions might have added taints ProcessTaints(); + InTaintTime = false; // Only used for debugging so locking is not necessary. + // step the physical world one interval m_simulationStep++; int numSubSteps = 0; try { - if (VehiclePhysicalLoggingEnabled) DumpVehicles(); // DEBUG if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount(); numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep, @@ -504,7 +504,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}, objWColl={7}", DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount, ObjectsWithCollisions.Count); - if (VehiclePhysicalLoggingEnabled) DumpVehicles(); // DEBUG } catch (Exception e) { @@ -701,15 +700,21 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters TaintedObject(ident, callback); } + private void DoPreStepActions(float timeStep) + { + PreStepAction actions = BeforeStep; + if (actions != null) + actions(timeStep); + + } + // When someone tries to change a property on a BSPrim or BSCharacter, the object queues // a callback into itself to do the actual property change. That callback is called // here just before the physics engine is called to step the simulation. public void ProcessTaints() { - InTaintTime = true; // Only used for debugging so locking is not necessary. ProcessRegularTaints(); ProcessPostTaintTaints(); - InTaintTime = false; } private void ProcessRegularTaints() @@ -871,68 +876,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters #endregion // Taints - #region Vehicles - - public void VehicleInSceneTypeChanged(BSPrim vehic, Vehicle newType) - { - RemoveVehiclePrim(vehic); - if (newType != Vehicle.TYPE_NONE) - { - // make it so the scene will call us each tick to do vehicle things - AddVehiclePrim(vehic); - } - } - - // Make so the scene will call this prim for vehicle actions each tick. - // Safe to call if prim is already in the vehicle list. - public void AddVehiclePrim(BSPrim vehicle) - { - lock (m_vehicles) - { - if (!m_vehicles.Contains(vehicle)) - { - m_vehicles.Add(vehicle); - } - } - } - - // Remove a prim from our list of vehicles. - // Safe to call if the prim is not in the vehicle list. - public void RemoveVehiclePrim(BSPrim vehicle) - { - lock (m_vehicles) - { - if (m_vehicles.Contains(vehicle)) - { - m_vehicles.Remove(vehicle); - } - } - } - - private void DoPreStepActions(float timeStep) - { - InTaintTime = true; // Only used for debugging so locking is not necessary. - ProcessVehicles(timeStep); - - PreStepAction actions = BeforeStep; - if (actions != null) - actions(timeStep); - - InTaintTime = false; - - } - - // Some prims have extra vehicle actions - // Called at taint time! - private void ProcessVehicles(float timeStep) - { - foreach (BSPhysObject pobj in m_vehicles) - { - pobj.StepVehicle(timeStep); - } - } - #endregion Vehicles - #region INI and command line parameter processing #region IPhysicsParameters @@ -1033,16 +976,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters #endregion Runtime settable parameters - // Debugging routine for dumping detailed physical information for vehicle prims - private void DumpVehicles() - { - foreach (BSPrim prim in m_vehicles) - { - BulletSimAPI.DumpRigidBody2(World.ptr, prim.PhysBody.ptr); - BulletSimAPI.DumpCollisionShape2(World.ptr, prim.PhysShape.ptr); - } - } - // Invoke the detailed logger and output something if it's enabled. public void DetailLog(string msg, params Object[] args) { -- cgit v1.1 From 16e49035f7420979aa7f77ac63b951a32aa0bd6b Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 22 Dec 2012 17:06:13 -0800 Subject: BulletSim: add Enabled parameter and operation to motors. --- OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index 8781fe9..9e1a9ba 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -43,7 +43,9 @@ public abstract class BSMotor { UseName = useName; PhysicsScene = null; + Enabled = true; } + public virtual bool Enabled { get; set; } public virtual void Reset() { } public virtual void Zero() { } public virtual void GenerateTestOutput(float timeStep) { } @@ -98,6 +100,12 @@ public class BSVMotor : BSMotor public virtual Vector3 CurrentValue { get; protected set; } public virtual Vector3 LastError { get; protected set; } + public virtual bool ErrorIsZero + { get { + return (LastError == Vector3.Zero || LastError.LengthSquared() <= ErrorZeroThreshold); + } + } + public BSVMotor(string useName) : base(useName) { @@ -105,7 +113,7 @@ public class BSVMotor : BSMotor Efficiency = 1f; FrictionTimescale = BSMotor.InfiniteVector; CurrentValue = TargetValue = Vector3.Zero; - ErrorZeroThreshold = 0.01f; + ErrorZeroThreshold = 0.001f; } public BSVMotor(string useName, float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency) : this(useName) @@ -133,6 +141,8 @@ public class BSVMotor : BSMotor // Compute the next step and return the new current value public virtual Vector3 Step(float timeStep) { + if (!Enabled) return TargetValue; + Vector3 origTarget = TargetValue; // DEBUG Vector3 origCurrVal = CurrentValue; // DEBUG @@ -178,7 +188,7 @@ public class BSVMotor : BSMotor { // Difference between what we have and target is small. Motor is done. CurrentValue = TargetValue; - MDetailLog("{0}, BSVMotor.Step,zero,{1},origTgt={2},origCurr={3},ret={2}", + MDetailLog("{0}, BSVMotor.Step,zero,{1},origTgt={2},origCurr={3},ret={4}", BSScene.DetailLogZero, UseName, origCurrVal, origTarget, CurrentValue); } @@ -186,6 +196,8 @@ public class BSVMotor : BSMotor } public virtual Vector3 Step(float timeStep, Vector3 error) { + if (!Enabled) return Vector3.Zero; + LastError = error; Vector3 returnCorrection = Vector3.Zero; if (!error.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)) @@ -313,6 +325,8 @@ public class BSPIDVMotor : BSVMotor // Ignore Current and Target Values and just advance the PID computation on this error. public override Vector3 Step(float timeStep, Vector3 error) { + if (!Enabled) return Vector3.Zero; + // Add up the error so we can integrate over the accumulated errors RunningIntegration += error * timeStep; -- cgit v1.1 From 144322a7c9e78a8df91c2e0026ade499b521e302 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 22 Dec 2012 17:07:52 -0800 Subject: BulletSim: remove post step one-time taints (doesn't make any sense). Rename pre and post step event invocation routines to Trigger* to be consistant. Remove old, unused code. --- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 112 +++++++----------------- 1 file changed, 30 insertions(+), 82 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 3a129a4..e8e0d50 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -85,9 +85,13 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters internal long m_simulationStep = 0; public long SimulationStep { get { return m_simulationStep; } } internal int m_taintsToProcessPerStep; + internal float LastTimeStep { get; private set; } + // Physical objects can register for prestep or poststep events public delegate void PreStepAction(float timeStep); + public delegate void PostStepAction(float timeStep); public event PreStepAction BeforeStep; + public event PreStepAction AfterStep; // A value of the time now so all the collision and update routines do not have to get their own // Set to 'now' just before all the prims and actors are called for collisions and updates @@ -463,6 +467,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // Simulate one timestep public override float Simulate(float timeStep) { + // prevent simulation until we've been initialized + if (!m_initialized) return 5.0f; + + LastTimeStep = timeStep; + int updatedEntityCount = 0; IntPtr updatedEntitiesPtr; int collidersCount = 0; @@ -471,9 +480,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters int beforeTime = 0; int simTime = 0; - // prevent simulation until we've been initialized - if (!m_initialized) return 5.0f; - // update the prim states while we know the physics engine is not busy int numTaints = _taintOperations.Count; @@ -482,7 +488,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters ProcessTaints(); // Some of the physical objects requre individual, pre-step calls - DoPreStepActions(timeStep); + TriggerPreStepEvent(timeStep); // the prestep actions might have added taints ProcessTaints(); @@ -582,7 +588,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters } } - ProcessPostStepTaints(); + TriggerPostStepEvent(timeStep); // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world. // Only enable this in a limited test world with few objects. @@ -674,6 +680,15 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public override bool IsThreaded { get { return false; } } #region Taints + // The simulation execution order is: + // Simulate() + // DoOneTimeTaints + // TriggerPreStepEvent + // DoOneTimeTaints + // Step() + // ProcessAndForwardCollisions + // ProcessAndForwardPropertyUpdates + // TriggerPostStepEvent // Calls to the PhysicsActors can't directly call into the physics engine // because it might be busy. We delay changes to a known time. @@ -700,7 +715,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters TaintedObject(ident, callback); } - private void DoPreStepActions(float timeStep) + private void TriggerPreStepEvent(float timeStep) { PreStepAction actions = BeforeStep; if (actions != null) @@ -708,6 +723,14 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters } + private void TriggerPostStepEvent(float timeStep) + { + PreStepAction actions = AfterStep; + if (actions != null) + actions(timeStep); + + } + // When someone tries to change a property on a BSPrim or BSCharacter, the object queues // a callback into itself to do the actual property change. That callback is called // here just before the physics engine is called to step the simulation. @@ -721,43 +744,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters { if (_taintOperations.Count > 0) // save allocating new list if there is nothing to process { - /* - // Code to limit the number of taints processed per step. Meant to limit step time. - // Unsure if a good idea as code assumes that taints are done before the step. - int taintCount = m_taintsToProcessPerStep; - TaintCallbackEntry oneCallback = new TaintCallbackEntry(); - while (_taintOperations.Count > 0 && taintCount-- > 0) - { - bool gotOne = false; - lock (_taintLock) - { - if (_taintOperations.Count > 0) - { - oneCallback = _taintOperations[0]; - _taintOperations.RemoveAt(0); - gotOne = true; - } - } - if (gotOne) - { - try - { - DetailLog("{0},BSScene.ProcessTaints,doTaint,id={1}", DetailLogZero, oneCallback.ident); - oneCallback.callback(); - } - catch (Exception e) - { - DetailLog("{0},BSScene.ProcessTaints,doTaintException,id={1}", DetailLogZero, oneCallback.ident); // DEBUG DEBUG DEBUG - m_log.ErrorFormat("{0}: ProcessTaints: {1}: Exception: {2}", LogHeader, oneCallback.ident, e); - } - } - } - if (_taintOperations.Count > 0) - { - DetailLog("{0},BSScene.ProcessTaints,leftTaintsOnList,numNotProcessed={1}", DetailLogZero, _taintOperations.Count); - } - */ - // swizzle a new list into the list location so we can process what's there List oldList; lock (_taintLock) @@ -796,6 +782,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters return; } + // Taints that happen after the normal taint processing but before the simulation step. private void ProcessPostTaintTaints() { if (_postTaintOperations.Count > 0) @@ -823,45 +810,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters } } - public void PostStepTaintObject(String ident, TaintCallback callback) - { - if (!m_initialized) return; - - lock (_taintLock) - { - _postStepOperations.Add(new TaintCallbackEntry(ident, callback)); - } - - return; - } - - private void ProcessPostStepTaints() - { - if (_postStepOperations.Count > 0) - { - List oldList; - lock (_taintLock) - { - oldList = _postStepOperations; - _postStepOperations = new List(); - } - - foreach (TaintCallbackEntry tcbe in oldList) - { - try - { - DetailLog("{0},BSScene.ProcessPostStepTaints,doTaint,id={1}", DetailLogZero, tcbe.ident); // DEBUG DEBUG DEBUG - tcbe.callback(); - } - catch (Exception e) - { - m_log.ErrorFormat("{0}: ProcessPostStepTaints: {1}: Exception: {2}", LogHeader, tcbe.ident, e); - } - } - oldList.Clear(); - } - } - // Only used for debugging. Does not change state of anything so locking is not necessary. public bool AssertInTaintTime(string whereFrom) { -- cgit v1.1 From 30807b81cc9f91917fd3b4bf8dc24a1622013afa Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 22 Dec 2012 17:09:40 -0800 Subject: BulletSim: modify avatar motor code to make falling movement better. Clean up some usages. Disable motor when done. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 75 ++++++++++++---------- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 2 +- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 3 + 3 files changed, 45 insertions(+), 35 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 01cd279..8e059ee 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -158,6 +158,7 @@ public sealed class BSCharacter : BSPhysObject _velocityMotor.Reset(); _velocityMotor.SetCurrent(_velocity); _velocityMotor.SetTarget(_velocity); + _velocityMotor.Enabled = false; // This will enable or disable the flying buoyancy of the avatar. // Needs to be reset especially when an avatar is recreated after crossing a region boundry. @@ -435,13 +436,13 @@ public sealed class BSCharacter : BSPhysObject OMV.Vector3 targetVel = value; PhysicsScene.TaintedObject("BSCharacter.setTargetVelocity", delegate() { - float timeStep = 0.089f; // DEBUG DEBUG FIX FIX FIX _velocityMotor.Reset(); _velocityMotor.SetTarget(targetVel); _velocityMotor.SetCurrent(_velocity); - // Compute a velocity value and make sure it gets pushed into the avatar. - // This makes sure the avatar will start from a stop. - ForceVelocity = _velocityMotor.Step(timeStep); + _velocityMotor.Enabled = true; + + // Make sure a property update happens next step so the motor gets incorporated. + BulletSimAPI.PushUpdate2(PhysBody.ptr); }); } } @@ -450,12 +451,15 @@ public sealed class BSCharacter : BSPhysObject get { return _velocity; } set { _velocity = value; - _velocityMotor.Reset(); - _velocityMotor.SetCurrent(_velocity); - _velocityMotor.SetTarget(_velocity); // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity); PhysicsScene.TaintedObject("BSCharacter.setVelocity", delegate() { + _velocityMotor.Reset(); + _velocityMotor.SetCurrent(_velocity); + _velocityMotor.SetTarget(_velocity); + // Even though the motor is initialized, it's not used and the velocity goes straight into the avatar. + _velocityMotor.Enabled = false; + DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity); ForceVelocity = _velocity; }); @@ -466,6 +470,7 @@ public sealed class BSCharacter : BSPhysObject set { PhysicsScene.AssertInTaintTime("BSCharacter.ForceVelocity"); + _velocity = value; // Depending on whether the avatar is moving or not, change the friction // to keep the avatar from slipping around if (_velocity.Length() == 0) @@ -486,7 +491,6 @@ public sealed class BSCharacter : BSPhysObject BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction); } } - _velocity = value; // Remember the set velocity so we can suppress the reduction by friction, ... _appliedVelocity = value; @@ -746,39 +750,42 @@ public sealed class BSCharacter : BSPhysObject _velocity = entprop.Velocity; _acceleration = entprop.Acceleration; _rotationalVelocity = entprop.RotationalVelocity; + // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. PositionSanityCheck(true); + if (_velocityMotor.Enabled) + { + // TODO: Decide if the step parameters should be changed depending on the avatar's + // state (flying, colliding, ...). + + OMV.Vector3 stepVelocity = _velocityMotor.Step(PhysicsScene.LastTimeStep); + + // If falling, we keep the world's downward vector no matter what the other axis specify. + if (!Flying && !IsColliding) + { + stepVelocity.Z = entprop.Velocity.Z; + DetailLog("{0},BSCharacter.UpdateProperties,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity); + } + + // If the user has said stop and we've stopped applying velocity correction, + // the motor can be turned off. Set the velocity to zero so the zero motion is sent to the viewer. + if (_velocityMotor.TargetValue.ApproxEquals(OMV.Vector3.Zero, 0.01f) && _velocityMotor.ErrorIsZero) + { + stepVelocity = OMV.Vector3.Zero; + _velocityMotor.Enabled = false; + DetailLog("{0},BSCharacter.UpdateProperties,taint,disableVelocityMotor,m={1}", LocalID, _velocityMotor); + } + + _velocity = stepVelocity; + entprop.Velocity = _velocity; + BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); + } + // remember the current and last set values LastEntityProperties = CurrentEntityProperties; CurrentEntityProperties = entprop; - // Avatars don't respond to world friction, etc. They only go the speed I tell them too. - // Special kludge here for falling. Even though the target velocity might not have a - // Z component, the avatar could be falling (walked off a ledge, stopped flying, ...) - // and that velocity component must be retained. - float timeStep = 0.089f; // DEBUG DEBUG FIX FIX FIX - OMV.Vector3 stepVelocity = _velocityMotor.Step(timeStep); - // Remove next line so avatars don't fly up forever. DEBUG DEBUG this is only temporary. - // stepVelocity.Z += entprop.Velocity.Z; - _velocity = stepVelocity; - BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); - /* - OMV.Vector3 stepVelocity = _velocityMotor.Step(timeStep); - OMV.Vector3 avVel = new OMV.Vector3(stepVelocity.X, stepVelocity.Y, entprop.Velocity.Z); - _velocity = avVel; - BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, avVel); - - if (entprop.Velocity != LastEntityProperties.Velocity) - { - // Changes in the velocity are suppressed in avatars. - // That's just the way they are defined. - OMV.Vector3 avVel = new OMV.Vector3(_appliedVelocity.X, _appliedVelocity.Y, entprop.Velocity.Z); - _velocity = avVel; - BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, avVel); - } - */ - // Tell the linkset about value changes Linkset.UpdateProperties(this, true); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 19de1e5..c76f869 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -153,7 +153,7 @@ public abstract class BSPhysObject : PhysicsActor public abstract OMV.Quaternion ForceOrientation { get; set; } // The system is telling us the velocity it wants to move at. - protected OMV.Vector3 m_targetVelocity; + // protected OMV.Vector3 m_targetVelocity; // use the definition in PhysicsActor public override OMV.Vector3 TargetVelocity { get { return m_targetVelocity; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index c084ab4..9a7e965 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -112,6 +112,9 @@ Test avatar walking up stairs. How does compare with SL. Debounce avatar contact so legs don't keep folding up when standing. Implement LSL physics controls. Like STATUS_ROTATE_X. Add border extensions to terrain to help region crossings and objects leaving region. +Use a different capsule shape for avatar when sitting + LL uses a pyrimidal shape scaled by the avatar's bounding box + http://wiki.secondlife.com/wiki/File:Avmeshforms.png Performance test with lots of avatars. Can BulletSim support a thousand? Optimize collisions in C++: only send up to the object subscribed to collisions. -- cgit v1.1 From ca30559b05bd44995277c270ec19a92d8170e587 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 23 Dec 2012 18:07:32 +0000 Subject: Whitespace change to trigger ircbot --- OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 8e059ee..9d9532d 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -24,6 +24,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + using System; using System.Collections.Generic; using System.Reflection; -- cgit v1.1 From 6eeb4cb3f745b3180220b0ab465cf4925cbdcddb Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 23 Dec 2012 18:10:34 +0000 Subject: Revert "Whitespace change to trigger ircbot" This reverts commit ca30559b05bd44995277c270ec19a92d8170e587. --- OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 9d9532d..8e059ee 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -24,7 +24,6 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - using System; using System.Collections.Generic; using System.Reflection; -- cgit v1.1 From 92e4f9f412046f8f7926c99c9e56c3a8b6b2edbf Mon Sep 17 00:00:00 2001 From: teravus Date: Sun, 23 Dec 2012 15:21:25 -0500 Subject: * Initial commit of BulletSimN (BulletSNPlugin). Purely C# implementation of BulletSim. This is designed to be /as close as possible/ to the BulletSim plugin while still being entirely in the managed space to make keeping it up to date easy as possible (no thinking work). This implementation is /slower/ then the c++ version just because it's fully managed, so it's not appropriate for huge sims, but it will run small ones OK. At the moment, it supports all known features of BulletSim. Think of it like.. POS but everything works. To use this plugin, set the physics plugin to BulletSimN. --- .../Region/Physics/BulletSNPlugin/BSCharacter.cs | 814 ++++++++++ .../Region/Physics/BulletSNPlugin/BSConstraint.cs | 135 ++ .../Physics/BulletSNPlugin/BSConstraint6Dof.cs | 153 ++ .../BulletSNPlugin/BSConstraintCollection.cs | 180 +++ .../Physics/BulletSNPlugin/BSConstraintHinge.cs | 57 + .../Region/Physics/BulletSNPlugin/BSDynamics.cs | 1374 +++++++++++++++++ OpenSim/Region/Physics/BulletSNPlugin/BSLinkset.cs | 333 ++++ .../Physics/BulletSNPlugin/BSLinksetCompound.cs | 396 +++++ .../Physics/BulletSNPlugin/BSLinksetConstraints.cs | 314 ++++ .../Region/Physics/BulletSNPlugin/BSMaterials.cs | 200 +++ OpenSim/Region/Physics/BulletSNPlugin/BSMotors.cs | 347 +++++ OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs | 559 +++++++ .../Region/Physics/BulletSNPlugin/BSPhysObject.cs | 345 +++++ OpenSim/Region/Physics/BulletSNPlugin/BSPlugin.cs | 81 + OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs | 1467 ++++++++++++++++++ OpenSim/Region/Physics/BulletSNPlugin/BSScene.cs | 954 ++++++++++++ .../Physics/BulletSNPlugin/BSShapeCollection.cs | 1015 +++++++++++++ OpenSim/Region/Physics/BulletSNPlugin/BSShapes.cs | 208 +++ .../Physics/BulletSNPlugin/BSTerrainHeightmap.cs | 175 +++ .../Physics/BulletSNPlugin/BSTerrainManager.cs | 460 ++++++ .../Region/Physics/BulletSNPlugin/BSTerrainMesh.cs | 267 ++++ .../Region/Physics/BulletSNPlugin/BulletSimAPI.cs | 1604 ++++++++++++++++++++ .../Region/Physics/BulletSNPlugin/BulletSimData.cs | 280 ++++ 23 files changed, 11718 insertions(+) create mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSCharacter.cs create mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSConstraint.cs create mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSConstraint6Dof.cs create mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSConstraintCollection.cs create mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSConstraintHinge.cs create mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSDynamics.cs create mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSLinkset.cs create mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSLinksetCompound.cs create mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSLinksetConstraints.cs create mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSMaterials.cs create mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSMotors.cs create mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs create mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSPhysObject.cs create mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSPlugin.cs create mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs create mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSScene.cs create mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSShapeCollection.cs create mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSShapes.cs create mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSTerrainHeightmap.cs create mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSTerrainManager.cs create mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSTerrainMesh.cs create mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BulletSimAPI.cs create mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BulletSimData.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSCharacter.cs new file mode 100644 index 0000000..4c4e950 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSCharacter.cs @@ -0,0 +1,814 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Reflection; +using log4net; +using OMV = OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Physics.Manager; + +namespace OpenSim.Region.Physics.BulletSNPlugin +{ +public sealed class BSCharacter : BSPhysObject +{ + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly string LogHeader = "[BULLETS CHAR]"; + + // private bool _stopped; + private OMV.Vector3 _size; + private bool _grabbed; + private bool _selected; + private OMV.Vector3 _position; + private float _mass; + private float _avatarDensity; + private float _avatarVolume; + private OMV.Vector3 _force; + private OMV.Vector3 _velocity; + private OMV.Vector3 _torque; + private float _collisionScore; + private OMV.Vector3 _acceleration; + private OMV.Quaternion _orientation; + private int _physicsActorType; + private bool _isPhysical; + private bool _flying; + private bool _setAlwaysRun; + private bool _throttleUpdates; + private bool _isColliding; + private bool _collidingObj; + private bool _floatOnWater; + private OMV.Vector3 _rotationalVelocity; + private bool _kinematic; + private float _buoyancy; + + // The friction and velocity of the avatar is modified depending on whether walking or not. + private OMV.Vector3 _appliedVelocity; // the last velocity applied to the avatar + private float _currentFriction; // the friction currently being used (changed by setVelocity). + + private BSVMotor _velocityMotor; + + private OMV.Vector3 _PIDTarget; + private bool _usePID; + private float _PIDTau; + private bool _useHoverPID; + private float _PIDHoverHeight; + private PIDHoverType _PIDHoverType; + private float _PIDHoverTao; + + public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying) + : base(parent_scene, localID, avName, "BSCharacter") + { + _physicsActorType = (int)ActorTypes.Agent; + _position = pos; + + // Old versions of ScenePresence passed only the height. If width and/or depth are zero, + // replace with the default values. + _size = size; + if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth; + if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth; + + // A motor to control the acceleration and deceleration of the avatar movement. + // _velocityMotor = new BSVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); + // _velocityMotor = new BSPIDVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); + // Infinite decay and timescale values so motor only changes current to target values. + _velocityMotor = new BSVMotor("BSCharacter.Velocity", + 0.2f, // time scale + BSMotor.Infinite, // decay time scale + BSMotor.InfiniteVector, // friction timescale + 1f // efficiency + ); + _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages. + + _flying = isFlying; + _orientation = OMV.Quaternion.Identity; + _velocity = OMV.Vector3.Zero; + _appliedVelocity = OMV.Vector3.Zero; + _buoyancy = ComputeBuoyancyFromFlying(isFlying); + _currentFriction = BSParam.AvatarStandingFriction; + _avatarDensity = BSParam.AvatarDensity; + + // The dimensions of the avatar capsule are kept in the scale. + // Physics creates a unit capsule which is scaled by the physics engine. + ComputeAvatarScale(_size); + // set _avatarVolume and _mass based on capsule size, _density and Scale + ComputeAvatarVolumeAndMass(); + DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}", + LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass); + + // do actual creation in taint time + PhysicsScene.TaintedObject("BSCharacter.create", delegate() + { + DetailLog("{0},BSCharacter.create,taint", LocalID); + // New body and shape into PhysBody and PhysShape + PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this); + + SetPhysicalProperties(); + }); + return; + } + + // called when this character is being destroyed and the resources should be released + public override void Destroy() + { + base.Destroy(); + + DetailLog("{0},BSCharacter.Destroy", LocalID); + PhysicsScene.TaintedObject("BSCharacter.destroy", delegate() + { + PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null); + PhysBody.Clear(); + PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null); + PhysShape.Clear(); + }); + } + + private void SetPhysicalProperties() + { + BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr); + + ZeroMotion(true); + ForcePosition = _position; + // Set the velocity and compute the proper friction + ForceVelocity = _velocity; + // Setting the current and target in the motor will cause it to start computing any deceleration. + _velocityMotor.Reset(); + _velocityMotor.SetCurrent(_velocity); + _velocityMotor.SetTarget(_velocity); + _velocityMotor.Enabled = false; + + // This will enable or disable the flying buoyancy of the avatar. + // Needs to be reset especially when an avatar is recreated after crossing a region boundry. + Flying = _flying; + + BulletSimAPI.SetRestitution2(PhysBody.ptr, BSParam.AvatarRestitution); + BulletSimAPI.SetMargin2(PhysShape.ptr, PhysicsScene.Params.collisionMargin); + BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale); + BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, BSParam.ContactProcessingThreshold); + if (BSParam.CcdMotionThreshold > 0f) + { + BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, BSParam.CcdMotionThreshold); + BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius); + } + + UpdatePhysicalMassProperties(RawMass); + + // Make so capsule does not fall over + BulletSimAPI.SetAngularFactorV2(PhysBody.ptr, OMV.Vector3.Zero); + + BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_CHARACTER_OBJECT); + + BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr, _position, _orientation); + + // BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.ACTIVE_TAG); + BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.DISABLE_DEACTIVATION); + BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); + + // Do this after the object has been added to the world + PhysBody.collisionType = CollisionType.Avatar; + PhysBody.ApplyCollisionMask(); + } + + public override void RequestPhysicsterseUpdate() + { + base.RequestPhysicsterseUpdate(); + } + // No one calls this method so I don't know what it could possibly mean + public override bool Stopped { get { return false; } } + + public override OMV.Vector3 Size { + get + { + // Avatar capsule size is kept in the scale parameter. + return _size; + } + + set { + // When an avatar's size is set, only the height is changed. + _size = value; + // Old versions of ScenePresence passed only the height. If width and/or depth are zero, + // replace with the default values. + if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth; + if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth; + + ComputeAvatarScale(_size); + ComputeAvatarVolumeAndMass(); + DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}", + LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass); + + PhysicsScene.TaintedObject("BSCharacter.setSize", delegate() + { + if (PhysBody.HasPhysicalBody && PhysShape.HasPhysicalShape) + { + BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale); + UpdatePhysicalMassProperties(RawMass); + // Make sure this change appears as a property update event + BulletSimAPI.PushUpdate2(PhysBody.ptr); + } + }); + + } + } + + public override PrimitiveBaseShape Shape + { + set { BaseShape = value; } + } + // I want the physics engine to make an avatar capsule + public override BSPhysicsShapeType PreferredPhysicalShape + { + get {return BSPhysicsShapeType.SHAPE_CAPSULE; } + } + + public override bool Grabbed { + set { _grabbed = value; } + } + public override bool Selected { + set { _selected = value; } + } + public override void CrossingFailure() { return; } + public override void link(PhysicsActor obj) { return; } + public override void delink() { return; } + + // Set motion values to zero. + // Do it to the properties so the values get set in the physics engine. + // Push the setting of the values to the viewer. + // Called at taint time! + public override void ZeroMotion(bool inTaintTime) + { + _velocity = OMV.Vector3.Zero; + _velocityMotor.Zero(); + _acceleration = OMV.Vector3.Zero; + _rotationalVelocity = OMV.Vector3.Zero; + + // Zero some other properties directly into the physics engine + PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate() + { + if (PhysBody.HasPhysicalBody) + BulletSimAPI.ClearAllForces2(PhysBody.ptr); + }); + } + public override void ZeroAngularMotion(bool inTaintTime) + { + _rotationalVelocity = OMV.Vector3.Zero; + + PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate() + { + if (PhysBody.HasPhysicalBody) + { + BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero); + BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero); + // The next also get rid of applied linear force but the linear velocity is untouched. + BulletSimAPI.ClearForces2(PhysBody.ptr); + } + }); + } + + + public override void LockAngularMotion(OMV.Vector3 axis) { return; } + + public override OMV.Vector3 RawPosition + { + get { return _position; } + set { _position = value; } + } + public override OMV.Vector3 Position { + get { + // Don't refetch the position because this function is called a zillion times + // _position = BulletSimAPI.GetObjectPosition2(Scene.World.ptr, LocalID); + return _position; + } + set { + _position = value; + PositionSanityCheck(); + + PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate() + { + DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); + if (PhysBody.HasPhysicalBody) + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + }); + } + } + public override OMV.Vector3 ForcePosition { + get { + _position = BulletSimAPI.GetPosition2(PhysBody.ptr); + return _position; + } + set { + _position = value; + PositionSanityCheck(); + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + } + } + + + // Check that the current position is sane and, if not, modify the position to make it so. + // Check for being below terrain or on water. + // Returns 'true' of the position was made sane by some action. + private bool PositionSanityCheck() + { + bool ret = false; + + // TODO: check for out of bounds + if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position)) + { + // The character is out of the known/simulated area. + // Upper levels of code will handle the transition to other areas so, for + // the time, we just ignore the position. + return ret; + } + + // If below the ground, move the avatar up + float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); + if (Position.Z < terrainHeight) + { + DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); + _position.Z = terrainHeight + 2.0f; + ret = true; + } + if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) + { + float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(_position); + if (Position.Z < waterHeight) + { + _position.Z = waterHeight; + ret = true; + } + } + + return ret; + } + + // A version of the sanity check that also makes sure a new position value is + // pushed back to the physics engine. This routine would be used by anyone + // who is not already pushing the value. + private bool PositionSanityCheck(bool inTaintTime) + { + bool ret = false; + if (PositionSanityCheck()) + { + // The new position value must be pushed into the physics engine but we can't + // just assign to "Position" because of potential call loops. + PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.PositionSanityCheck", delegate() + { + DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); + if (PhysBody.HasPhysicalBody) + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + }); + ret = true; + } + return ret; + } + + public override float Mass { get { return _mass; } } + + // used when we only want this prim's mass and not the linkset thing + public override float RawMass { + get {return _mass; } + } + public override void UpdatePhysicalMassProperties(float physMass) + { + OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass); + BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, localInertia); + } + + public override OMV.Vector3 Force { + get { return _force; } + set { + _force = value; + // m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force); + PhysicsScene.TaintedObject("BSCharacter.SetForce", delegate() + { + DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force); + if (PhysBody.HasPhysicalBody) + BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force); + }); + } + } + + public bool TouchingGround() + { + bool ret = BulletSimAPI.RayCastGround(PhysicsScene.World.ptr,_position,_size.Z * 0.55f, PhysBody.ptr); + return ret; + } + // Avatars don't do vehicles + public override int VehicleType { get { return (int)Vehicle.TYPE_NONE; } set { return; } } + public override void VehicleFloatParam(int param, float value) { } + public override void VehicleVectorParam(int param, OMV.Vector3 value) {} + public override void VehicleRotationParam(int param, OMV.Quaternion rotation) { } + public override void VehicleFlags(int param, bool remove) { } + + // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more + public override void SetVolumeDetect(int param) { return; } + + public override OMV.Vector3 GeometricCenter { get { return OMV.Vector3.Zero; } } + public override OMV.Vector3 CenterOfMass { get { return OMV.Vector3.Zero; } } + + // Sets the target in the motor. This starts the changing of the avatar's velocity. + public override OMV.Vector3 TargetVelocity + { + get + { + return _velocityMotor.TargetValue; + } + set + { + DetailLog("{0},BSCharacter.setTargetVelocity,call,vel={1}", LocalID, value); + + if (!_flying) + if ((value.Z >= 0.0001f) || (value.Z <= -0.0001f) || _velocity.Z < -0.0001f) + if (!TouchingGround()) + value.Z = _velocity.Z; + if (_setAlwaysRun) + value *= 1.3f; + + OMV.Vector3 targetVel = value; + + PhysicsScene.TaintedObject("BSCharacter.setTargetVelocity", delegate() + { + + _velocityMotor.Reset(); + _velocityMotor.SetTarget(targetVel); + _velocityMotor.SetCurrent(_velocity); + _velocityMotor.Enabled = true; + + // Make sure a property update happens next step so the motor gets incorporated. + BulletSimAPI.PushUpdate2(PhysBody.ptr); + }); + } + } + // Directly setting velocity means this is what the user really wants now. + public override OMV.Vector3 Velocity { + get { return _velocity; } + set { + _velocity = value; + // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity); + PhysicsScene.TaintedObject("BSCharacter.setVelocity", delegate() + { + _velocityMotor.Reset(); + _velocityMotor.SetCurrent(_velocity); + _velocityMotor.SetTarget(_velocity); + // Even though the motor is initialized, it's not used and the velocity goes straight into the avatar. + _velocityMotor.Enabled = false; + + DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity); + ForceVelocity = _velocity; + }); + } + } + public override OMV.Vector3 ForceVelocity { + get { return _velocity; } + set { + PhysicsScene.AssertInTaintTime("BSCharacter.ForceVelocity"); + + _velocity = value; + // Depending on whether the avatar is moving or not, change the friction + // to keep the avatar from slipping around + if (_velocity.Length() == 0) + { + if (_currentFriction != BSParam.AvatarStandingFriction) + { + _currentFriction = BSParam.AvatarStandingFriction; + if (PhysBody.HasPhysicalBody) + BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction); + } + } + else + { + if (_currentFriction != BSParam.AvatarFriction) + { + _currentFriction = BSParam.AvatarFriction; + if (PhysBody.HasPhysicalBody) + BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction); + } + } + // Remember the set velocity so we can suppress the reduction by friction, ... + _appliedVelocity = value; + + BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); + BulletSimAPI.Activate2(PhysBody.ptr, true); + } + } + public override OMV.Vector3 Torque { + get { return _torque; } + set { _torque = value; + } + } + public override float CollisionScore { + get { return _collisionScore; } + set { _collisionScore = value; + } + } + public override OMV.Vector3 Acceleration { + get { return _acceleration; } + set { _acceleration = value; } + } + public override OMV.Quaternion RawOrientation + { + get { return _orientation; } + set { _orientation = value; } + } + public override OMV.Quaternion Orientation { + get { return _orientation; } + set { + _orientation = value; + // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation); + PhysicsScene.TaintedObject("BSCharacter.setOrientation", delegate() + { + if (PhysBody.HasPhysicalBody) + { + // _position = BulletSimAPI.GetPosition2(BSBody.ptr); + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + } + }); + } + } + // Go directly to Bullet to get/set the value. + public override OMV.Quaternion ForceOrientation + { + get + { + _orientation = BulletSimAPI.GetOrientation2(PhysBody.ptr); + return _orientation; + } + set + { + _orientation = value; + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + } + } + public override int PhysicsActorType { + get { return _physicsActorType; } + set { _physicsActorType = value; + } + } + public override bool IsPhysical { + get { return _isPhysical; } + set { _isPhysical = value; + } + } + public override bool IsSolid { + get { return true; } + } + public override bool IsStatic { + get { return false; } + } + public override bool Flying { + get { return _flying; } + set { + _flying = value; + + // simulate flying by changing the effect of gravity + Buoyancy = ComputeBuoyancyFromFlying(_flying); + } + } + // Flying is implimented by changing the avatar's buoyancy. + // Would this be done better with a vehicle type? + private float ComputeBuoyancyFromFlying(bool ifFlying) { + return ifFlying ? 1f : 0f; + } + public override bool + SetAlwaysRun { + get { return _setAlwaysRun; } + set { _setAlwaysRun = value; } + } + public override bool ThrottleUpdates { + get { return _throttleUpdates; } + set { _throttleUpdates = value; } + } + public override bool IsColliding { + get { return (CollidingStep == PhysicsScene.SimulationStep); } + set { _isColliding = value; } + } + public override bool CollidingGround { + get { return (CollidingGroundStep == PhysicsScene.SimulationStep); } + set { CollidingGround = value; } + } + public override bool CollidingObj { + get { return _collidingObj; } + set { _collidingObj = value; } + } + public override bool FloatOnWater { + set { + _floatOnWater = value; + PhysicsScene.TaintedObject("BSCharacter.setFloatOnWater", delegate() + { + if (PhysBody.HasPhysicalBody) + { + if (_floatOnWater) + CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); + else + CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); + } + }); + } + } + public override OMV.Vector3 RotationalVelocity { + get { return _rotationalVelocity; } + set { _rotationalVelocity = value; } + } + public override OMV.Vector3 ForceRotationalVelocity { + get { return _rotationalVelocity; } + set { _rotationalVelocity = value; } + } + public override bool Kinematic { + get { return _kinematic; } + set { _kinematic = value; } + } + // neg=fall quickly, 0=1g, 1=0g, pos=float up + public override float Buoyancy { + get { return _buoyancy; } + set { _buoyancy = value; + PhysicsScene.TaintedObject("BSCharacter.setBuoyancy", delegate() + { + DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy); + ForceBuoyancy = _buoyancy; + }); + } + } + public override float ForceBuoyancy { + get { return _buoyancy; } + set { + PhysicsScene.AssertInTaintTime("BSCharacter.ForceBuoyancy"); + + _buoyancy = value; + DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); + // Buoyancy is faked by changing the gravity applied to the object + float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); + if (PhysBody.HasPhysicalBody) + BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav)); + } + } + + // Used for MoveTo + public override OMV.Vector3 PIDTarget { + set { _PIDTarget = value; } + } + public override bool PIDActive { + set { _usePID = value; } + } + public override float PIDTau { + set { _PIDTau = value; } + } + + // Used for llSetHoverHeight and maybe vehicle height + // Hover Height will override MoveTo target's Z + public override bool PIDHoverActive { + set { _useHoverPID = value; } + } + public override float PIDHoverHeight { + set { _PIDHoverHeight = value; } + } + public override PIDHoverType PIDHoverType { + set { _PIDHoverType = value; } + } + public override float PIDHoverTau { + set { _PIDHoverTao = value; } + } + + // For RotLookAt + public override OMV.Quaternion APIDTarget { set { return; } } + public override bool APIDActive { set { return; } } + public override float APIDStrength { set { return; } } + public override float APIDDamping { set { return; } } + + public override void AddForce(OMV.Vector3 force, bool pushforce) { + if (force.IsFinite()) + { + _force.X += force.X; + _force.Y += force.Y; + _force.Z += force.Z; + // m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force); + PhysicsScene.TaintedObject("BSCharacter.AddForce", delegate() + { + DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force); + if (PhysBody.HasPhysicalBody) + BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force); + }); + } + else + { + m_log.ErrorFormat("{0}: Got a NaN force applied to a Character", LogHeader); + } + //m_lastUpdateSent = false; + } + + public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { + } + public override void SetMomentum(OMV.Vector3 momentum) { + } + + private void ComputeAvatarScale(OMV.Vector3 size) + { + OMV.Vector3 newScale = size; + // newScale.X = PhysicsScene.Params.avatarCapsuleWidth; + // newScale.Y = PhysicsScene.Params.avatarCapsuleDepth; + + // From the total height, remove the capsule half spheres that are at each end + // The 1.15f came from ODE. Not sure what this factors in. + // newScale.Z = (size.Z * 1.15f) - (newScale.X + newScale.Y); + + // The total scale height is the central cylindar plus the caps on the two ends. + newScale.Z = size.Z + (Math.Min(size.X, size.Y) * 2f); + + // Convert diameters to radii and height to half height -- the way Bullet expects it. + Scale = newScale / 2f; + } + + // set _avatarVolume and _mass based on capsule size, _density and Scale + private void ComputeAvatarVolumeAndMass() + { + _avatarVolume = (float)( + Math.PI + * Scale.X + * Scale.Y // the area of capsule cylinder + * Scale.Z // times height of capsule cylinder + + 1.33333333f + * Math.PI + * Scale.X + * Math.Min(Scale.X, Scale.Y) + * Scale.Y // plus the volume of the capsule end caps + ); + _mass = _avatarDensity * _avatarVolume; + } + + // The physics engine says that properties have updated. Update same and inform + // the world that things have changed. + public override void UpdateProperties(EntityProperties entprop) + { + _position = entprop.Position; + _orientation = entprop.Rotation; + _velocity = entprop.Velocity; + _acceleration = entprop.Acceleration; + _rotationalVelocity = entprop.RotationalVelocity; + + // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. + PositionSanityCheck(true); + + if (_velocityMotor.Enabled) + { + // TODO: Decide if the step parameters should be changed depending on the avatar's + // state (flying, colliding, ...). + + OMV.Vector3 stepVelocity = _velocityMotor.Step(PhysicsScene.LastTimeStep); + + // If falling, we keep the world's downward vector no matter what the other axis specify. + if (!Flying && !IsColliding) + { + stepVelocity.Z = entprop.Velocity.Z; + DetailLog("{0},BSCharacter.UpdateProperties,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity); + } + + // If the user has said stop and we've stopped applying velocity correction, + // the motor can be turned off. Set the velocity to zero so the zero motion is sent to the viewer. + if (_velocityMotor.TargetValue.ApproxEquals(OMV.Vector3.Zero, 0.01f) && _velocityMotor.ErrorIsZero) + { + stepVelocity = OMV.Vector3.Zero; + _velocityMotor.Enabled = false; + DetailLog("{0},BSCharacter.UpdateProperties,taint,disableVelocityMotor,m={1}", LocalID, _velocityMotor); + } + + _velocity = stepVelocity; + entprop.Velocity = _velocity; + BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); + } + + // remember the current and last set values + LastEntityProperties = CurrentEntityProperties; + CurrentEntityProperties = entprop; + + // Tell the linkset about value changes + Linkset.UpdateProperties(this, true); + + // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. + // base.RequestPhysicsterseUpdate(); + + DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", + LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); + } +} +} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSConstraint.cs new file mode 100644 index 0000000..426bdc2 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSConstraint.cs @@ -0,0 +1,135 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSNPlugin +{ + +public abstract class BSConstraint : IDisposable +{ + private static string LogHeader = "[BULLETSIM CONSTRAINT]"; + + protected BulletSim m_world; + protected BulletBody m_body1; + protected BulletBody m_body2; + protected BulletConstraint m_constraint; + protected bool m_enabled = false; + + public BulletBody Body1 { get { return m_body1; } } + public BulletBody Body2 { get { return m_body2; } } + public BulletConstraint Constraint { get { return m_constraint; } } + public abstract ConstraintType Type { get; } + public bool IsEnabled { get { return m_enabled; } } + + public BSConstraint() + { + } + + public virtual void Dispose() + { + if (m_enabled) + { + m_enabled = false; + if (m_constraint.HasPhysicalConstraint) + { + bool success = BulletSimAPI.DestroyConstraint2(m_world.ptr, m_constraint.ptr); + m_world.physicsScene.DetailLog("{0},BSConstraint.Dispose,taint,id1={1},body1={2},id2={3},body2={4},success={5}", + BSScene.DetailLogZero, + m_body1.ID, m_body1.ptr.ToString(), + m_body2.ID, m_body2.ptr.ToString(), + success); + m_constraint.Clear(); + } + } + } + + public virtual bool SetLinearLimits(Vector3 low, Vector3 high) + { + bool ret = false; + if (m_enabled) + ret = BulletSimAPI.SetLinearLimits2(m_constraint.ptr, low, high); + return ret; + } + + public virtual bool SetAngularLimits(Vector3 low, Vector3 high) + { + bool ret = false; + if (m_enabled) + ret = BulletSimAPI.SetAngularLimits2(m_constraint.ptr, low, high); + return ret; + } + + public virtual bool SetSolverIterations(float cnt) + { + bool ret = false; + if (m_enabled) + { + BulletSimAPI.SetConstraintNumSolverIterations2(m_constraint.ptr, cnt); + ret = true; + } + return ret; + } + + public virtual bool CalculateTransforms() + { + bool ret = false; + if (m_enabled) + { + // Recompute the internal transforms + BulletSimAPI.CalculateTransforms2(m_constraint.ptr); + ret = true; + } + return ret; + } + + // Reset this constraint making sure it has all its internal structures + // recomputed and is enabled and ready to go. + public virtual bool RecomputeConstraintVariables(float mass) + { + bool ret = false; + if (m_enabled) + { + ret = CalculateTransforms(); + if (ret) + { + // Setting an object's mass to zero (making it static like when it's selected) + // automatically disables the constraints. + // If the link is enabled, be sure to set the constraint itself to enabled. + BulletSimAPI.SetConstraintEnable2(m_constraint.ptr, BSParam.NumericBool(true)); + } + else + { + m_world.physicsScene.Logger.ErrorFormat("{0} CalculateTransforms failed. A={1}, B={2}", LogHeader, Body1.ID, Body2.ID); + } + } + return ret; + } +} +} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSConstraint6Dof.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSConstraint6Dof.cs new file mode 100644 index 0000000..0181d9d --- /dev/null +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSConstraint6Dof.cs @@ -0,0 +1,153 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSNPlugin +{ + +public sealed class BSConstraint6Dof : BSConstraint +{ + private static string LogHeader = "[BULLETSIM 6DOF CONSTRAINT]"; + + public override ConstraintType Type { get { return ConstraintType.D6_CONSTRAINT_TYPE; } } + + // Create a btGeneric6DofConstraint + public BSConstraint6Dof(BulletSim world, BulletBody obj1, BulletBody obj2, + Vector3 frame1, Quaternion frame1rot, + Vector3 frame2, Quaternion frame2rot, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) + { + m_world = world; + m_body1 = obj1; + m_body2 = obj2; + m_constraint = new BulletConstraint( + BulletSimAPI.Create6DofConstraint2(m_world.ptr, m_body1.ptr, m_body2.ptr, + frame1, frame1rot, + frame2, frame2rot, + useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); + m_enabled = true; + world.physicsScene.DetailLog("{0},BS6DofConstraint,createFrame,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}", + BSScene.DetailLogZero, world.worldID, + obj1.ID, obj1.ptr.ToString(), obj2.ID, obj2.ptr.ToString()); + } + + public BSConstraint6Dof(BulletSim world, BulletBody obj1, BulletBody obj2, + Vector3 joinPoint, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) + { + m_world = world; + m_body1 = obj1; + m_body2 = obj2; + if (!obj1.HasPhysicalBody || !obj2.HasPhysicalBody) + { + world.physicsScene.DetailLog("{0},BS6DOFConstraint,badBodyPtr,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}", + BSScene.DetailLogZero, world.worldID, + obj1.ID, obj1.ptr.ToString(), obj2.ID, obj2.ptr.ToString()); + world.physicsScene.Logger.ErrorFormat("{0} Attempt to build 6DOF constraint with missing bodies: wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}", + LogHeader, world.worldID, obj1.ID, obj1.ptr.ToString(), obj2.ID, obj2.ptr.ToString()); + m_enabled = false; + } + else + { + m_constraint = new BulletConstraint( + BulletSimAPI.Create6DofConstraintToPoint2(m_world.ptr, m_body1.ptr, m_body2.ptr, + joinPoint, + useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); + world.physicsScene.DetailLog("{0},BS6DofConstraint,createMidPoint,wID={1}, csrt={2}, rID={3}, rBody={4}, cID={5}, cBody={6}", + BSScene.DetailLogZero, world.worldID, m_constraint.ptr.ToString(), + obj1.ID, obj1.ptr.ToString(), obj2.ID, obj2.ptr.ToString()); + if (!m_constraint.HasPhysicalConstraint) + { + world.physicsScene.Logger.ErrorFormat("{0} Failed creation of 6Dof constraint. rootID={1}, childID={2}", + LogHeader, obj1.ID, obj2.ID); + m_enabled = false; + } + else + { + m_enabled = true; + } + } + } + + public bool SetFrames(Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot) + { + bool ret = false; + if (m_enabled) + { + BulletSimAPI.SetFrames2(m_constraint.ptr, frameA, frameArot, frameB, frameBrot); + ret = true; + } + return ret; + } + + public bool SetCFMAndERP(float cfm, float erp) + { + bool ret = false; + if (m_enabled) + { + BulletSimAPI.SetConstraintParam2(m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL); + BulletSimAPI.SetConstraintParam2(m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_ERP, erp, ConstraintParamAxis.AXIS_ALL); + BulletSimAPI.SetConstraintParam2(m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_CFM, cfm, ConstraintParamAxis.AXIS_ALL); + ret = true; + } + return ret; + } + + public bool UseFrameOffset(bool useOffset) + { + bool ret = false; + float onOff = useOffset ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse; + if (m_enabled) + ret = BulletSimAPI.UseFrameOffset2(m_constraint.ptr, onOff); + return ret; + } + + public bool TranslationalLimitMotor(bool enable, float targetVelocity, float maxMotorForce) + { + bool ret = false; + float onOff = enable ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse; + if (m_enabled) + { + ret = BulletSimAPI.TranslationalLimitMotor2(m_constraint.ptr, onOff, targetVelocity, maxMotorForce); + m_world.physicsScene.DetailLog("{0},BS6DOFConstraint,TransLimitMotor,enable={1},vel={2},maxForce={3}", + BSScene.DetailLogZero, enable, targetVelocity, maxMotorForce); + } + return ret; + } + + public bool SetBreakingImpulseThreshold(float threshold) + { + bool ret = false; + if (m_enabled) + ret = BulletSimAPI.SetBreakingImpulseThreshold2(m_constraint.ptr, threshold); + return ret; + } +} +} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSConstraintCollection.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSConstraintCollection.cs new file mode 100644 index 0000000..5c00b1a --- /dev/null +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSConstraintCollection.cs @@ -0,0 +1,180 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using log4net; +using OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSNPlugin +{ + +public sealed class BSConstraintCollection : IDisposable +{ + // private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + // private static readonly string LogHeader = "[CONSTRAINT COLLECTION]"; + + delegate bool ConstraintAction(BSConstraint constrain); + + private List m_constraints; + private BulletSim m_world; + + public BSConstraintCollection(BulletSim world) + { + m_world = world; + m_constraints = new List(); + } + + public void Dispose() + { + this.Clear(); + } + + public void Clear() + { + lock (m_constraints) + { + foreach (BSConstraint cons in m_constraints) + { + cons.Dispose(); + } + m_constraints.Clear(); + } + } + + public bool AddConstraint(BSConstraint cons) + { + lock (m_constraints) + { + // There is only one constraint between any bodies. Remove any old just to make sure. + RemoveAndDestroyConstraint(cons.Body1, cons.Body2); + + m_constraints.Add(cons); + } + + return true; + } + + // Get the constraint between two bodies. There can be only one. + // Return 'true' if a constraint was found. + public bool TryGetConstraint(BulletBody body1, BulletBody body2, out BSConstraint returnConstraint) + { + bool found = false; + BSConstraint foundConstraint = null; + + uint lookingID1 = body1.ID; + uint lookingID2 = body2.ID; + lock (m_constraints) + { + foreach (BSConstraint constrain in m_constraints) + { + if ((constrain.Body1.ID == lookingID1 && constrain.Body2.ID == lookingID2) + || (constrain.Body1.ID == lookingID2 && constrain.Body2.ID == lookingID1)) + { + foundConstraint = constrain; + found = true; + break; + } + } + } + returnConstraint = foundConstraint; + return found; + } + + // Remove any constraint between the passed bodies. + // Presumed there is only one such constraint possible. + // Return 'true' if a constraint was found and destroyed. + public bool RemoveAndDestroyConstraint(BulletBody body1, BulletBody body2) + { + bool ret = false; + lock (m_constraints) + { + BSConstraint constrain; + if (this.TryGetConstraint(body1, body2, out constrain)) + { + // remove the constraint from our collection + RemoveAndDestroyConstraint(constrain); + ret = true; + } + } + + return ret; + } + + // The constraint MUST exist in the collection + public bool RemoveAndDestroyConstraint(BSConstraint constrain) + { + lock (m_constraints) + { + // remove the constraint from our collection + m_constraints.Remove(constrain); + } + // tell the engine that all its structures need to be freed + constrain.Dispose(); + // we destroyed something + return true; + } + + // Remove all constraints that reference the passed body. + // Return 'true' if any constraints were destroyed. + public bool RemoveAndDestroyConstraint(BulletBody body1) + { + List toRemove = new List(); + uint lookingID = body1.ID; + lock (m_constraints) + { + foreach (BSConstraint constrain in m_constraints) + { + if (constrain.Body1.ID == lookingID || constrain.Body2.ID == lookingID) + { + toRemove.Add(constrain); + } + } + foreach (BSConstraint constrain in toRemove) + { + m_constraints.Remove(constrain); + constrain.Dispose(); + } + } + return (toRemove.Count > 0); + } + + public bool RecalculateAllConstraints() + { + bool ret = false; + lock (m_constraints) + { + foreach (BSConstraint constrain in m_constraints) + { + constrain.CalculateTransforms(); + ret = true; + } + } + return ret; + } +} +} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSConstraintHinge.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSConstraintHinge.cs new file mode 100644 index 0000000..7951f06 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSConstraintHinge.cs @@ -0,0 +1,57 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSNPlugin +{ + +public sealed class BSConstraintHinge : BSConstraint +{ + public override ConstraintType Type { get { return ConstraintType.HINGE_CONSTRAINT_TYPE; } } + + public BSConstraintHinge(BulletSim world, BulletBody obj1, BulletBody obj2, + Vector3 pivotInA, Vector3 pivotInB, + Vector3 axisInA, Vector3 axisInB, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) + { + m_world = world; + m_body1 = obj1; + m_body2 = obj2; + m_constraint = new BulletConstraint( + BulletSimAPI.CreateHingeConstraint2(m_world.ptr, m_body1.ptr, m_body2.ptr, + pivotInA, pivotInB, + axisInA, axisInB, + useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); + m_enabled = true; + } + +} + +} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSDynamics.cs new file mode 100644 index 0000000..72afacc --- /dev/null +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSDynamics.cs @@ -0,0 +1,1374 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The quotations from http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial + * are Copyright (c) 2009 Linden Research, Inc and are used under their license + * of Creative Commons Attribution-Share Alike 3.0 + * (http://creativecommons.org/licenses/by-sa/3.0/). + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.InteropServices; +using OpenMetaverse; +using OpenSim.Region.Physics.Manager; + +namespace OpenSim.Region.Physics.BulletSNPlugin +{ + public sealed class BSDynamics + { + private static string LogHeader = "[BULLETSIM VEHICLE]"; + + private BSScene PhysicsScene { get; set; } + // the prim this dynamic controller belongs to + private BSPrim Prim { get; set; } + + // mass of the vehicle fetched each time we're calles + private float m_vehicleMass; + + // Vehicle properties + public Vehicle Type { get; set; } + + // private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier + private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings: + // HOVER_TERRAIN_ONLY + // HOVER_GLOBAL_HEIGHT + // NO_DEFLECTION_UP + // HOVER_WATER_ONLY + // HOVER_UP_ONLY + // LIMIT_MOTOR_UP + // LIMIT_ROLL_ONLY + private Vector3 m_BlockingEndPoint = Vector3.Zero; + private Quaternion m_RollreferenceFrame = Quaternion.Identity; + private Quaternion m_referenceFrame = Quaternion.Identity; + + // Linear properties + private BSVMotor m_linearMotor = new BSVMotor("LinearMotor"); + private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time + private Vector3 m_linearMotorOffset = Vector3.Zero; // the point of force can be offset from the center + private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL + private Vector3 m_linearFrictionTimescale = Vector3.Zero; + private float m_linearMotorDecayTimescale = 0; + private float m_linearMotorTimescale = 0; + private Vector3 m_lastLinearVelocityVector = Vector3.Zero; + private Vector3 m_lastPositionVector = Vector3.Zero; + // private bool m_LinearMotorSetLastFrame = false; + // private Vector3 m_linearMotorOffset = Vector3.Zero; + + //Angular properties + private BSVMotor m_angularMotor = new BSVMotor("AngularMotor"); + private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor + // private int m_angularMotorApply = 0; // application frame counter + private Vector3 m_angularMotorVelocity = Vector3.Zero; // current angular motor velocity + private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate + private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate + private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate + private Vector3 m_lastAngularVelocity = Vector3.Zero; + private Vector3 m_lastVertAttractor = Vector3.Zero; // what VA was last applied to body + + //Deflection properties + private BSVMotor m_angularDeflectionMotor = new BSVMotor("AngularDeflection"); + private float m_angularDeflectionEfficiency = 0; + private float m_angularDeflectionTimescale = 0; + private float m_linearDeflectionEfficiency = 0; + private float m_linearDeflectionTimescale = 0; + + //Banking properties + private float m_bankingEfficiency = 0; + private float m_bankingMix = 0; + private float m_bankingTimescale = 0; + + //Hover and Buoyancy properties + private BSVMotor m_hoverMotor = new BSVMotor("Hover"); + private float m_VhoverHeight = 0f; + private float m_VhoverEfficiency = 0f; + private float m_VhoverTimescale = 0f; + private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height + private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle. + // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity) + // KF: So far I have found no good method to combine a script-requested .Z velocity and gravity. + // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity. + + //Attractor properties + private BSVMotor m_verticalAttractionMotor = new BSVMotor("VerticalAttraction"); + private float m_verticalAttractionEfficiency = 1.0f; // damped + private float m_verticalAttractionCutoff = 500f; // per the documentation + // Timescale > cutoff means no vert attractor. + private float m_verticalAttractionTimescale = 510f; + + // Just some recomputed constants: + static readonly float PIOverFour = ((float)Math.PI) / 4f; + static readonly float PIOverTwo = ((float)Math.PI) / 2f; + + public BSDynamics(BSScene myScene, BSPrim myPrim) + { + PhysicsScene = myScene; + Prim = myPrim; + Type = Vehicle.TYPE_NONE; + } + + // Return 'true' if this vehicle is doing vehicle things + public bool IsActive + { + get { return Type != Vehicle.TYPE_NONE && Prim.IsPhysical; } + } + + internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) + { + VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue); + switch (pParam) + { + case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: + m_angularDeflectionEfficiency = Math.Max(pValue, 0.01f); + break; + case Vehicle.ANGULAR_DEFLECTION_TIMESCALE: + m_angularDeflectionTimescale = Math.Max(pValue, 0.01f); + break; + case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE: + m_angularMotorDecayTimescale = ClampInRange(0.01f, pValue, 120); + m_angularMotor.TargetValueDecayTimeScale = m_angularMotorDecayTimescale; + break; + case Vehicle.ANGULAR_MOTOR_TIMESCALE: + m_angularMotorTimescale = Math.Max(pValue, 0.01f); + m_angularMotor.TimeScale = m_angularMotorTimescale; + break; + case Vehicle.BANKING_EFFICIENCY: + m_bankingEfficiency = ClampInRange(-1f, pValue, 1f); + break; + case Vehicle.BANKING_MIX: + m_bankingMix = Math.Max(pValue, 0.01f); + break; + case Vehicle.BANKING_TIMESCALE: + m_bankingTimescale = Math.Max(pValue, 0.01f); + break; + case Vehicle.BUOYANCY: + m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f); + break; + case Vehicle.HOVER_EFFICIENCY: + m_VhoverEfficiency = ClampInRange(0f, pValue, 1f); + break; + case Vehicle.HOVER_HEIGHT: + m_VhoverHeight = pValue; + break; + case Vehicle.HOVER_TIMESCALE: + m_VhoverTimescale = Math.Max(pValue, 0.01f); + break; + case Vehicle.LINEAR_DEFLECTION_EFFICIENCY: + m_linearDeflectionEfficiency = Math.Max(pValue, 0.01f); + break; + case Vehicle.LINEAR_DEFLECTION_TIMESCALE: + m_linearDeflectionTimescale = Math.Max(pValue, 0.01f); + break; + case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE: + m_linearMotorDecayTimescale = ClampInRange(0.01f, pValue, 120); + m_linearMotor.TargetValueDecayTimeScale = m_linearMotorDecayTimescale; + break; + case Vehicle.LINEAR_MOTOR_TIMESCALE: + m_linearMotorTimescale = Math.Max(pValue, 0.01f); + m_linearMotor.TimeScale = m_linearMotorTimescale; + break; + case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: + m_verticalAttractionEfficiency = ClampInRange(0.1f, pValue, 1f); + m_verticalAttractionMotor.Efficiency = m_verticalAttractionEfficiency; + break; + case Vehicle.VERTICAL_ATTRACTION_TIMESCALE: + m_verticalAttractionTimescale = Math.Max(pValue, 0.01f); + m_verticalAttractionMotor.TimeScale = m_verticalAttractionTimescale; + break; + + // These are vector properties but the engine lets you use a single float value to + // set all of the components to the same value + case Vehicle.ANGULAR_FRICTION_TIMESCALE: + m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue); + m_angularMotor.FrictionTimescale = m_angularFrictionTimescale; + break; + case Vehicle.ANGULAR_MOTOR_DIRECTION: + m_angularMotorDirection = new Vector3(pValue, pValue, pValue); + m_angularMotor.SetTarget(m_angularMotorDirection); + break; + case Vehicle.LINEAR_FRICTION_TIMESCALE: + m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue); + m_linearMotor.FrictionTimescale = m_linearFrictionTimescale; + break; + case Vehicle.LINEAR_MOTOR_DIRECTION: + m_linearMotorDirection = new Vector3(pValue, pValue, pValue); + m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue); + m_linearMotor.SetTarget(m_linearMotorDirection); + break; + case Vehicle.LINEAR_MOTOR_OFFSET: + m_linearMotorOffset = new Vector3(pValue, pValue, pValue); + break; + + } + }//end ProcessFloatVehicleParam + + internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue) + { + VDetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue); + switch (pParam) + { + case Vehicle.ANGULAR_FRICTION_TIMESCALE: + m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); + m_angularMotor.FrictionTimescale = m_angularFrictionTimescale; + break; + case Vehicle.ANGULAR_MOTOR_DIRECTION: + // Limit requested angular speed to 2 rps= 4 pi rads/sec + pValue.X = ClampInRange(-12.56f, pValue.X, 12.56f); + pValue.Y = ClampInRange(-12.56f, pValue.Y, 12.56f); + pValue.Z = ClampInRange(-12.56f, pValue.Z, 12.56f); + m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); + m_angularMotor.SetTarget(m_angularMotorDirection); + break; + case Vehicle.LINEAR_FRICTION_TIMESCALE: + m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); + m_linearMotor.FrictionTimescale = m_linearFrictionTimescale; + break; + case Vehicle.LINEAR_MOTOR_DIRECTION: + m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); + m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z); + m_linearMotor.SetTarget(m_linearMotorDirection); + break; + case Vehicle.LINEAR_MOTOR_OFFSET: + m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); + break; + case Vehicle.BLOCK_EXIT: + m_BlockingEndPoint = new Vector3(pValue.X, pValue.Y, pValue.Z); + break; + } + }//end ProcessVectorVehicleParam + + internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) + { + VDetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue); + switch (pParam) + { + case Vehicle.REFERENCE_FRAME: + m_referenceFrame = pValue; + break; + case Vehicle.ROLL_FRAME: + m_RollreferenceFrame = pValue; + break; + } + }//end ProcessRotationVehicleParam + + internal void ProcessVehicleFlags(int pParam, bool remove) + { + VDetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", Prim.LocalID, pParam, remove); + VehicleFlag parm = (VehicleFlag)pParam; + if (pParam == -1) + m_flags = (VehicleFlag)0; + else + { + if (remove) + m_flags &= ~parm; + else + m_flags |= parm; + } + } + + internal void ProcessTypeChange(Vehicle pType) + { + VDetailLog("{0},ProcessTypeChange,type={1}", Prim.LocalID, pType); + // Set Defaults For Type + Type = pType; + switch (pType) + { + case Vehicle.TYPE_NONE: + m_linearMotorDirection = Vector3.Zero; + m_linearMotorTimescale = 0; + m_linearMotorDecayTimescale = 0; + m_linearFrictionTimescale = new Vector3(0, 0, 0); + + m_angularMotorDirection = Vector3.Zero; + m_angularMotorDecayTimescale = 0; + m_angularMotorTimescale = 0; + m_angularFrictionTimescale = new Vector3(0, 0, 0); + + m_VhoverHeight = 0; + m_VhoverEfficiency = 0; + m_VhoverTimescale = 0; + m_VehicleBuoyancy = 0; + + m_linearDeflectionEfficiency = 1; + m_linearDeflectionTimescale = 1; + + m_angularDeflectionEfficiency = 0; + m_angularDeflectionTimescale = 1000; + + m_verticalAttractionEfficiency = 0; + m_verticalAttractionTimescale = 0; + + m_bankingEfficiency = 0; + m_bankingTimescale = 1000; + m_bankingMix = 1; + + m_referenceFrame = Quaternion.Identity; + m_flags = (VehicleFlag)0; + + break; + + case Vehicle.TYPE_SLED: + m_linearMotorDirection = Vector3.Zero; + m_linearMotorTimescale = 1000; + m_linearMotorDecayTimescale = 120; + m_linearFrictionTimescale = new Vector3(30, 1, 1000); + + m_angularMotorDirection = Vector3.Zero; + m_angularMotorTimescale = 1000; + m_angularMotorDecayTimescale = 120; + m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); + + m_VhoverHeight = 0; + m_VhoverEfficiency = 10; // TODO: this looks wrong!! + m_VhoverTimescale = 10; + m_VehicleBuoyancy = 0; + + m_linearDeflectionEfficiency = 1; + m_linearDeflectionTimescale = 1; + + m_angularDeflectionEfficiency = 1; + m_angularDeflectionTimescale = 1000; + + m_verticalAttractionEfficiency = 0; + m_verticalAttractionTimescale = 0; + + m_bankingEfficiency = 0; + m_bankingTimescale = 10; + m_bankingMix = 1; + + m_referenceFrame = Quaternion.Identity; + m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY + | VehicleFlag.HOVER_TERRAIN_ONLY + | VehicleFlag.HOVER_GLOBAL_HEIGHT + | VehicleFlag.HOVER_UP_ONLY); + m_flags |= (VehicleFlag.NO_DEFLECTION_UP + | VehicleFlag.LIMIT_ROLL_ONLY + | VehicleFlag.LIMIT_MOTOR_UP); + + break; + case Vehicle.TYPE_CAR: + m_linearMotorDirection = Vector3.Zero; + m_linearMotorTimescale = 1; + m_linearMotorDecayTimescale = 60; + m_linearFrictionTimescale = new Vector3(100, 2, 1000); + + m_angularMotorDirection = Vector3.Zero; + m_angularMotorTimescale = 1; + m_angularMotorDecayTimescale = 0.8f; + m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); + + m_VhoverHeight = 0; + m_VhoverEfficiency = 0; + m_VhoverTimescale = 1000; + m_VehicleBuoyancy = 0; + + m_linearDeflectionEfficiency = 1; + m_linearDeflectionTimescale = 2; + + m_angularDeflectionEfficiency = 0; + m_angularDeflectionTimescale = 10; + + m_verticalAttractionEfficiency = 1f; + m_verticalAttractionTimescale = 10f; + + m_bankingEfficiency = -0.2f; + m_bankingMix = 1; + m_bankingTimescale = 1; + + m_referenceFrame = Quaternion.Identity; + m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY + | VehicleFlag.HOVER_TERRAIN_ONLY + | VehicleFlag.HOVER_GLOBAL_HEIGHT); + m_flags |= (VehicleFlag.NO_DEFLECTION_UP + | VehicleFlag.LIMIT_ROLL_ONLY + | VehicleFlag.LIMIT_MOTOR_UP + | VehicleFlag.HOVER_UP_ONLY); + break; + case Vehicle.TYPE_BOAT: + m_linearMotorDirection = Vector3.Zero; + m_linearMotorTimescale = 5; + m_linearMotorDecayTimescale = 60; + m_linearFrictionTimescale = new Vector3(10, 3, 2); + + m_angularMotorDirection = Vector3.Zero; + m_angularMotorTimescale = 4; + m_angularMotorDecayTimescale = 4; + m_angularFrictionTimescale = new Vector3(10,10,10); + + m_VhoverHeight = 0; + m_VhoverEfficiency = 0.5f; + m_VhoverTimescale = 2; + m_VehicleBuoyancy = 1; + + m_linearDeflectionEfficiency = 0.5f; + m_linearDeflectionTimescale = 3; + + m_angularDeflectionEfficiency = 0.5f; + m_angularDeflectionTimescale = 5; + + m_verticalAttractionEfficiency = 0.5f; + m_verticalAttractionTimescale = 5f; + + m_bankingEfficiency = -0.3f; + m_bankingMix = 0.8f; + m_bankingTimescale = 1; + + m_referenceFrame = Quaternion.Identity; + m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY + | VehicleFlag.HOVER_GLOBAL_HEIGHT + | VehicleFlag.LIMIT_ROLL_ONLY + | VehicleFlag.HOVER_UP_ONLY); + m_flags |= (VehicleFlag.NO_DEFLECTION_UP + | VehicleFlag.LIMIT_MOTOR_UP + | VehicleFlag.HOVER_WATER_ONLY); + break; + case Vehicle.TYPE_AIRPLANE: + m_linearMotorDirection = Vector3.Zero; + m_linearMotorTimescale = 2; + m_linearMotorDecayTimescale = 60; + m_linearFrictionTimescale = new Vector3(200, 10, 5); + + m_angularMotorDirection = Vector3.Zero; + m_angularMotorTimescale = 4; + m_angularMotorDecayTimescale = 4; + m_angularFrictionTimescale = new Vector3(20, 20, 20); + + m_VhoverHeight = 0; + m_VhoverEfficiency = 0.5f; + m_VhoverTimescale = 1000; + m_VehicleBuoyancy = 0; + + m_linearDeflectionEfficiency = 0.5f; + m_linearDeflectionTimescale = 3; + + m_angularDeflectionEfficiency = 1; + m_angularDeflectionTimescale = 2; + + m_verticalAttractionEfficiency = 0.9f; + m_verticalAttractionTimescale = 2f; + + m_bankingEfficiency = 1; + m_bankingMix = 0.7f; + m_bankingTimescale = 2; + + m_referenceFrame = Quaternion.Identity; + m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY + | VehicleFlag.HOVER_TERRAIN_ONLY + | VehicleFlag.HOVER_GLOBAL_HEIGHT + | VehicleFlag.HOVER_UP_ONLY + | VehicleFlag.NO_DEFLECTION_UP + | VehicleFlag.LIMIT_MOTOR_UP); + m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); + break; + case Vehicle.TYPE_BALLOON: + m_linearMotorDirection = Vector3.Zero; + m_linearMotorTimescale = 5; + m_linearFrictionTimescale = new Vector3(5, 5, 5); + m_linearMotorDecayTimescale = 60; + + m_angularMotorDirection = Vector3.Zero; + m_angularMotorTimescale = 6; + m_angularFrictionTimescale = new Vector3(10, 10, 10); + m_angularMotorDecayTimescale = 10; + + m_VhoverHeight = 5; + m_VhoverEfficiency = 0.8f; + m_VhoverTimescale = 10; + m_VehicleBuoyancy = 1; + + m_linearDeflectionEfficiency = 0; + m_linearDeflectionTimescale = 5; + + m_angularDeflectionEfficiency = 0; + m_angularDeflectionTimescale = 5; + + m_verticalAttractionEfficiency = 1f; + m_verticalAttractionTimescale = 100f; + + m_bankingEfficiency = 0; + m_bankingMix = 0.7f; + m_bankingTimescale = 5; + + m_referenceFrame = Quaternion.Identity; + + m_referenceFrame = Quaternion.Identity; + m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY + | VehicleFlag.HOVER_TERRAIN_ONLY + | VehicleFlag.HOVER_UP_ONLY + | VehicleFlag.NO_DEFLECTION_UP + | VehicleFlag.LIMIT_MOTOR_UP); + m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY + | VehicleFlag.HOVER_GLOBAL_HEIGHT); + break; + } + + // Update any physical parameters based on this type. + Refresh(); + + m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale, + m_linearMotorDecayTimescale, m_linearFrictionTimescale, + 1f); + m_linearMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) + + m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale, + m_angularMotorDecayTimescale, m_angularFrictionTimescale, + 1f); + m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) + + m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale, + BSMotor.Infinite, BSMotor.InfiniteVector, + m_verticalAttractionEfficiency); + // Z goes away and we keep X and Y + m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f); + m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) + } + + // Some of the properties of this prim may have changed. + // Do any updating needed for a vehicle + public void Refresh() + { + if (IsActive) + { + // Remember the mass so we don't have to fetch it every step + m_vehicleMass = Prim.Linkset.LinksetMass; + + // Friction affects are handled by this vehicle code + float friction = 0f; + BulletSimAPI.SetFriction2(Prim.PhysBody.ptr, friction); + + // Moderate angular movement introduced by Bullet. + // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle. + // Maybe compute linear and angular factor and damping from params. + float angularDamping = BSParam.VehicleAngularDamping; + BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, angularDamping); + + // Vehicles report collision events so we know when it's on the ground + BulletSimAPI.AddToCollisionFlags2(Prim.PhysBody.ptr, CollisionFlags.BS_VEHICLE_COLLISIONS); + + Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(Prim.PhysShape.ptr, m_vehicleMass); + BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia); + BulletSimAPI.UpdateInertiaTensor2(Prim.PhysBody.ptr); + + VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4}", + Prim.LocalID, m_vehicleMass, friction, localInertia, angularDamping); + } + else + { + BulletSimAPI.RemoveFromCollisionFlags2(Prim.PhysBody.ptr, CollisionFlags.BS_VEHICLE_COLLISIONS); + } + } + + public bool RemoveBodyDependencies(BSPhysObject prim) + { + // If active, we need to add our properties back when the body is rebuilt. + return IsActive; + } + + public void RestoreBodyDependencies(BSPhysObject prim) + { + if (Prim.LocalID != prim.LocalID) + { + // The call should be on us by our prim. Error if not. + PhysicsScene.Logger.ErrorFormat("{0} RestoreBodyDependencies: called by not my prim. passedLocalID={1}, vehiclePrimLocalID={2}", + LogHeader, prim.LocalID, Prim.LocalID); + return; + } + Refresh(); + } + + #region Known vehicle value functions + // Vehicle physical parameters that we buffer from constant getting and setting. + // The "m_known*" values are unknown until they are fetched and the m_knownHas flag is set. + // Changing is remembered and the parameter is stored back into the physics engine only if updated. + // This does two things: 1) saves continuious calls into unmanaged code, and + // 2) signals when a physics property update must happen back to the simulator + // to update values modified for the vehicle. + private int m_knownChanged; + private int m_knownHas; + private float m_knownTerrainHeight; + private float m_knownWaterLevel; + private Vector3 m_knownPosition; + private Vector3 m_knownVelocity; + private Vector3 m_knownForce; + private Quaternion m_knownOrientation; + private Vector3 m_knownRotationalVelocity; + private Vector3 m_knownRotationalForce; + private Vector3 m_knownForwardVelocity; // vehicle relative forward speed + + private const int m_knownChangedPosition = 1 << 0; + private const int m_knownChangedVelocity = 1 << 1; + private const int m_knownChangedForce = 1 << 2; + private const int m_knownChangedOrientation = 1 << 3; + private const int m_knownChangedRotationalVelocity = 1 << 4; + private const int m_knownChangedRotationalForce = 1 << 5; + private const int m_knownChangedTerrainHeight = 1 << 6; + private const int m_knownChangedWaterLevel = 1 << 7; + private const int m_knownChangedForwardVelocity = 1 << 8; + + private void ForgetKnownVehicleProperties() + { + m_knownHas = 0; + m_knownChanged = 0; + } + // Push all the changed values back into the physics engine + private void PushKnownChanged() + { + if (m_knownChanged != 0) + { + if ((m_knownChanged & m_knownChangedPosition) != 0) + Prim.ForcePosition = m_knownPosition; + + if ((m_knownChanged & m_knownChangedOrientation) != 0) + Prim.ForceOrientation = m_knownOrientation; + + if ((m_knownChanged & m_knownChangedVelocity) != 0) + { + Prim.ForceVelocity = m_knownVelocity; + BulletSimAPI.SetInterpolationLinearVelocity2(Prim.PhysBody.ptr, VehicleVelocity); + } + + if ((m_knownChanged & m_knownChangedForce) != 0) + Prim.AddForce((Vector3)m_knownForce, false, true); + + if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) + { + Prim.ForceRotationalVelocity = m_knownRotationalVelocity; + // Fake out Bullet by making it think the velocity is the same as last time. + BulletSimAPI.SetInterpolationAngularVelocity2(Prim.PhysBody.ptr, m_knownRotationalVelocity); + } + + if ((m_knownChanged & m_knownChangedRotationalForce) != 0) + Prim.AddAngularForce((Vector3)m_knownRotationalForce, false, true); + + // If we set one of the values (ie, the physics engine didn't do it) we must force + // an UpdateProperties event to send the changes up to the simulator. + BulletSimAPI.PushUpdate2(Prim.PhysBody.ptr); + } + m_knownChanged = 0; + } + + // Since the computation of terrain height can be a little involved, this routine + // is used to fetch the height only once for each vehicle simulation step. + private float GetTerrainHeight(Vector3 pos) + { + if ((m_knownHas & m_knownChangedTerrainHeight) == 0) + { + m_knownTerrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); + m_knownHas |= m_knownChangedTerrainHeight; + } + return m_knownTerrainHeight; + } + + // Since the computation of water level can be a little involved, this routine + // is used ot fetch the level only once for each vehicle simulation step. + private float GetWaterLevel(Vector3 pos) + { + if ((m_knownHas & m_knownChangedWaterLevel) == 0) + { + m_knownWaterLevel = Prim.PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(pos); + m_knownHas |= m_knownChangedWaterLevel; + } + return (float)m_knownWaterLevel; + } + + private Vector3 VehiclePosition + { + get + { + if ((m_knownHas & m_knownChangedPosition) == 0) + { + m_knownPosition = Prim.ForcePosition; + m_knownHas |= m_knownChangedPosition; + } + return m_knownPosition; + } + set + { + m_knownPosition = value; + m_knownChanged |= m_knownChangedPosition; + m_knownHas |= m_knownChangedPosition; + } + } + + private Quaternion VehicleOrientation + { + get + { + if ((m_knownHas & m_knownChangedOrientation) == 0) + { + m_knownOrientation = Prim.ForceOrientation; + m_knownHas |= m_knownChangedOrientation; + } + return m_knownOrientation; + } + set + { + m_knownOrientation = value; + m_knownChanged |= m_knownChangedOrientation; + m_knownHas |= m_knownChangedOrientation; + } + } + + private Vector3 VehicleVelocity + { + get + { + if ((m_knownHas & m_knownChangedVelocity) == 0) + { + m_knownVelocity = Prim.ForceVelocity; + m_knownHas |= m_knownChangedVelocity; + } + return (Vector3)m_knownVelocity; + } + set + { + m_knownVelocity = value; + m_knownChanged |= m_knownChangedVelocity; + m_knownHas |= m_knownChangedVelocity; + } + } + + private void VehicleAddForce(Vector3 aForce) + { + if ((m_knownHas & m_knownChangedForce) == 0) + { + m_knownForce = Vector3.Zero; + } + m_knownForce += aForce; + m_knownChanged |= m_knownChangedForce; + m_knownHas |= m_knownChangedForce; + } + + private Vector3 VehicleRotationalVelocity + { + get + { + if ((m_knownHas & m_knownChangedRotationalVelocity) == 0) + { + m_knownRotationalVelocity = Prim.ForceRotationalVelocity; + m_knownHas |= m_knownChangedRotationalVelocity; + } + return (Vector3)m_knownRotationalVelocity; + } + set + { + m_knownRotationalVelocity = value; + m_knownChanged |= m_knownChangedRotationalVelocity; + m_knownHas |= m_knownChangedRotationalVelocity; + } + } + private void VehicleAddAngularForce(Vector3 aForce) + { + if ((m_knownHas & m_knownChangedRotationalForce) == 0) + { + m_knownRotationalForce = Vector3.Zero; + } + m_knownRotationalForce += aForce; + m_knownChanged |= m_knownChangedRotationalForce; + m_knownHas |= m_knownChangedRotationalForce; + } + // Vehicle relative forward velocity + private Vector3 VehicleForwardVelocity + { + get + { + if ((m_knownHas & m_knownChangedForwardVelocity) == 0) + { + m_knownForwardVelocity = VehicleVelocity * Quaternion.Inverse(Quaternion.Normalize(VehicleOrientation)); + m_knownHas |= m_knownChangedForwardVelocity; + } + return m_knownForwardVelocity; + } + } + private float VehicleForwardSpeed + { + get + { + return VehicleForwardVelocity.X; + } + } + + #endregion // Known vehicle value functions + + // One step of the vehicle properties for the next 'pTimestep' seconds. + internal void Step(float pTimestep) + { + if (!IsActive) return; + + ForgetKnownVehicleProperties(); + + MoveLinear(pTimestep); + MoveAngular(pTimestep); + + LimitRotation(pTimestep); + + // remember the position so next step we can limit absolute movement effects + m_lastPositionVector = VehiclePosition; + + // If we forced the changing of some vehicle parameters, update the values and + // for the physics engine to note the changes so an UpdateProperties event will happen. + PushKnownChanged(); + + VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", + Prim.LocalID, VehiclePosition, Prim.Force, VehicleVelocity, VehicleRotationalVelocity); + } + + // Apply the effect of the linear motor and other linear motions (like hover and float). + private void MoveLinear(float pTimestep) + { + Vector3 linearMotorContribution = m_linearMotor.Step(pTimestep); + + // The movement computed in the linear motor is relative to the vehicle + // coordinates. Rotate the movement to world coordinates. + linearMotorContribution *= VehicleOrientation; + + // ================================================================== + // Buoyancy: force to overcome gravity. + // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; + // So, if zero, don't change anything (let gravity happen). If one, negate the effect of gravity. + Vector3 buoyancyContribution = Prim.PhysicsScene.DefaultGravity * m_VehicleBuoyancy; + + Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(pTimestep); + + Vector3 hoverContribution = ComputeLinearHover(pTimestep); + + ComputeLinearBlockingEndPoint(pTimestep); + + Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pTimestep); + + // ================================================================== + Vector3 newVelocity = linearMotorContribution + + terrainHeightContribution + + hoverContribution + + limitMotorUpContribution; + + Vector3 newForce = buoyancyContribution; + + // If not changing some axis, reduce out velocity + if ((m_flags & (VehicleFlag.NO_X)) != 0) + newVelocity.X = 0; + if ((m_flags & (VehicleFlag.NO_Y)) != 0) + newVelocity.Y = 0; + if ((m_flags & (VehicleFlag.NO_Z)) != 0) + newVelocity.Z = 0; + + // ================================================================== + // Clamp high or low velocities + float newVelocityLengthSq = newVelocity.LengthSquared(); + if (newVelocityLengthSq > 1000f) + { + newVelocity /= newVelocity.Length(); + newVelocity *= 1000f; + } + else if (newVelocityLengthSq < 0.001f) + newVelocity = Vector3.Zero; + + // ================================================================== + // Stuff new linear velocity into the vehicle. + // Since the velocity is just being set, it is not scaled by pTimeStep. Bullet will do that for us. + VehicleVelocity = newVelocity; + + // Other linear forces are applied as forces. + Vector3 totalDownForce = newForce * m_vehicleMass; + if (!totalDownForce.ApproxEquals(Vector3.Zero, 0.01f)) + { + VehicleAddForce(totalDownForce); + } + + VDetailLog("{0}, MoveLinear,done,newVel={1},totDown={2},IsColliding={3}", + Prim.LocalID, newVelocity, totalDownForce, Prim.IsColliding); + VDetailLog("{0}, MoveLinear,done,linContrib={1},terrContrib={2},hoverContrib={3},limitContrib={4},buoyContrib={5}", + Prim.LocalID, + linearMotorContribution, terrainHeightContribution, hoverContribution, + limitMotorUpContribution, buoyancyContribution + ); + + } // end MoveLinear() + + public Vector3 ComputeLinearTerrainHeightCorrection(float pTimestep) + { + Vector3 ret = Vector3.Zero; + // If below the terrain, move us above the ground a little. + // TODO: Consider taking the rotated size of the object or possibly casting a ray. + if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition)) + { + // TODO: correct position by applying force rather than forcing position. + Vector3 newPosition = VehiclePosition; + newPosition.Z = GetTerrainHeight(VehiclePosition) + 1f; + VehiclePosition = newPosition; + VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}", + Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition); + } + return ret; + } + + public Vector3 ComputeLinearHover(float pTimestep) + { + Vector3 ret = Vector3.Zero; + + // m_VhoverEfficiency: 0=bouncy, 1=totally damped + // m_VhoverTimescale: time to achieve height + if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) + { + // We should hover, get the target height + if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0) + { + m_VhoverTargetHeight = GetWaterLevel(VehiclePosition) + m_VhoverHeight; + } + if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) + { + m_VhoverTargetHeight = GetTerrainHeight(VehiclePosition) + m_VhoverHeight; + } + if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0) + { + m_VhoverTargetHeight = m_VhoverHeight; + } + + if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0) + { + // If body is already heigher, use its height as target height + if (VehiclePosition.Z > m_VhoverTargetHeight) + m_VhoverTargetHeight = VehiclePosition.Z; + } + + if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) + { + if (Math.Abs(VehiclePosition.Z - m_VhoverTargetHeight) > 0.2f) + { + Vector3 pos = VehiclePosition; + pos.Z = m_VhoverTargetHeight; + VehiclePosition = pos; + } + } + else + { + // Error is positive if below the target and negative if above. + float verticalError = m_VhoverTargetHeight - VehiclePosition.Z; + float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; + + // TODO: implement m_VhoverEfficiency correctly + if (Math.Abs(verticalError) > m_VhoverEfficiency) + { + ret = new Vector3(0f, 0f, verticalCorrectionVelocity); + } + } + + VDetailLog("{0}, MoveLinear,hover,pos={1},ret={2},hoverTS={3},height={4},target={5}", + Prim.LocalID, VehiclePosition, ret, m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight); + } + + return ret; + } + + public bool ComputeLinearBlockingEndPoint(float pTimestep) + { + bool changed = false; + + Vector3 pos = VehiclePosition; + Vector3 posChange = pos - m_lastPositionVector; + if (m_BlockingEndPoint != Vector3.Zero) + { + if (pos.X >= (m_BlockingEndPoint.X - (float)1)) + { + pos.X -= posChange.X + 1; + changed = true; + } + if (pos.Y >= (m_BlockingEndPoint.Y - (float)1)) + { + pos.Y -= posChange.Y + 1; + changed = true; + } + if (pos.Z >= (m_BlockingEndPoint.Z - (float)1)) + { + pos.Z -= posChange.Z + 1; + changed = true; + } + if (pos.X <= 0) + { + pos.X += posChange.X + 1; + changed = true; + } + if (pos.Y <= 0) + { + pos.Y += posChange.Y + 1; + changed = true; + } + if (changed) + { + VehiclePosition = pos; + VDetailLog("{0}, MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}", + Prim.LocalID, m_BlockingEndPoint, posChange, pos); + } + } + return changed; + } + + // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags : + // Prevent ground vehicles from motoring into the sky. This flag has a subtle effect when + // used with conjunction with banking: the strength of the banking will decay when the + // vehicle no longer experiences collisions. The decay timescale is the same as + // VEHICLE_BANKING_TIMESCALE. This is to help prevent ground vehicles from steering + // when they are in mid jump. + // TODO: this code is wrong. Also, what should it do for boats (height from water)? + // This is just using the ground and a general collision check. Should really be using + // a downward raycast to find what is below. + public Vector3 ComputeLinearMotorUp(float pTimestep) + { + Vector3 ret = Vector3.Zero; + float distanceAboveGround = 0f; + + if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) + { + float targetHeight = Type == Vehicle.TYPE_BOAT ? GetWaterLevel(VehiclePosition) : GetTerrainHeight(VehiclePosition); + distanceAboveGround = VehiclePosition.Z - targetHeight; + // Not colliding if the vehicle is off the ground + if (!Prim.IsColliding) + { + // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); + ret = new Vector3(0, 0, -distanceAboveGround); + } + // TODO: this calculation is wrong. From the description at + // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce + // has a decay factor. This says this force should + // be computed with a motor. + // TODO: add interaction with banking. + } + VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},colliding={2},ret={3}", + Prim.LocalID, distanceAboveGround, Prim.IsColliding, ret); + return ret; + } + + // ======================================================================= + // ======================================================================= + // Apply the effect of the angular motor. + // The 'contribution' is how much angular correction velocity each function wants. + // All the contributions are added together and the resulting velocity is + // set directly on the vehicle. + private void MoveAngular(float pTimestep) + { + // The user wants this many radians per second angular change? + Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); + + // ================================================================== + // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags : + // This flag prevents linear deflection parallel to world z-axis. This is useful + // for preventing ground vehicles with large linear deflection, like bumper cars, + // from climbing their linear deflection into the sky. + // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement + if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) + { + angularMotorContribution.X = 0f; + angularMotorContribution.Y = 0f; + VDetailLog("{0}, MoveAngular,noDeflectionUp,angularMotorContrib={1}", Prim.LocalID, angularMotorContribution); + } + + Vector3 verticalAttractionContribution = ComputeAngularVerticalAttraction(); + + Vector3 deflectionContribution = ComputeAngularDeflection(); + + Vector3 bankingContribution = ComputeAngularBanking(); + + // ================================================================== + m_lastVertAttractor = verticalAttractionContribution; + + m_lastAngularVelocity = angularMotorContribution + + verticalAttractionContribution + + deflectionContribution + + bankingContribution; + + // ================================================================== + // Apply the correction velocity. + // TODO: Should this be applied as an angular force (torque)? + if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) + { + VehicleRotationalVelocity = m_lastAngularVelocity; + + VDetailLog("{0}, MoveAngular,done,nonZero,angMotorContrib={1},vertAttrContrib={2},bankContrib={3},deflectContrib={4},totalContrib={5}", + Prim.LocalID, + angularMotorContribution, verticalAttractionContribution, + bankingContribution, deflectionContribution, + m_lastAngularVelocity + ); + } + else + { + // The vehicle is not adding anything angular wise. + VehicleRotationalVelocity = Vector3.Zero; + VDetailLog("{0}, MoveAngular,done,zero", Prim.LocalID); + } + + // ================================================================== + //Offset section + if (m_linearMotorOffset != Vector3.Zero) + { + //Offset of linear velocity doesn't change the linear velocity, + // but causes a torque to be applied, for example... + // + // IIIII >>> IIIII + // IIIII >>> IIIII + // IIIII >>> IIIII + // ^ + // | Applying a force at the arrow will cause the object to move forward, but also rotate + // + // + // The torque created is the linear velocity crossed with the offset + + // TODO: this computation should be in the linear section + // because that is where we know the impulse being applied. + Vector3 torqueFromOffset = Vector3.Zero; + // torqueFromOffset = Vector3.Cross(m_linearMotorOffset, appliedImpulse); + if (float.IsNaN(torqueFromOffset.X)) + torqueFromOffset.X = 0; + if (float.IsNaN(torqueFromOffset.Y)) + torqueFromOffset.Y = 0; + if (float.IsNaN(torqueFromOffset.Z)) + torqueFromOffset.Z = 0; + + VehicleAddAngularForce(torqueFromOffset * m_vehicleMass); + VDetailLog("{0}, BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset); + } + + } + // From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial: + // Some vehicles, like boats, should always keep their up-side up. This can be done by + // enabling the "vertical attractor" behavior that springs the vehicle's local z-axis to + // the world z-axis (a.k.a. "up"). To take advantage of this feature you would set the + // VEHICLE_VERTICAL_ATTRACTION_TIMESCALE to control the period of the spring frequency, + // and then set the VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY to control the damping. An + // efficiency of 0.0 will cause the spring to wobble around its equilibrium, while an + // efficiency of 1.0 will cause the spring to reach its equilibrium with exponential decay. + public Vector3 ComputeAngularVerticalAttraction() + { + Vector3 ret = Vector3.Zero; + + // If vertical attaction timescale is reasonable + if (m_verticalAttractionTimescale < m_verticalAttractionCutoff) + { + // Take a vector pointing up and convert it from world to vehicle relative coords. + Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; + + // If vertical attraction correction is needed, the vector that was pointing up (UnitZ) + // is now: + // leaning to one side: rotated around the X axis with the Y value going + // from zero (nearly straight up) to one (completely to the side)) or + // leaning front-to-back: rotated around the Y axis with the value of X being between + // zero and one. + // The value of Z is how far the rotation is off with 1 meaning none and 0 being 90 degrees. + + // Y error means needed rotation around X axis and visa versa. + // Since the error goes from zero to one, the asin is the corresponding angle. + ret.X = (float)Math.Asin(verticalError.Y); + // (Tilt forward (positive X) needs to tilt back (rotate negative) around Y axis.) + ret.Y = -(float)Math.Asin(verticalError.X); + + // If verticalError.Z is negative, the vehicle is upside down. Add additional push. + if (verticalError.Z < 0f) + { + ret.X += PIOverFour; + ret.Y += PIOverFour; + } + + // 'ret' is now the necessary velocity to correct tilt in one second. + // Correction happens over a number of seconds. + Vector3 unscaledContrib = ret; + ret /= m_verticalAttractionTimescale; + + VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},eff={3},ts={4},vertAttr={5}", + Prim.LocalID, verticalError, unscaledContrib, m_verticalAttractionEfficiency, m_verticalAttractionTimescale, ret); + } + return ret; + } + + // Return the angular correction to correct the direction the vehicle is pointing to be + // the direction is should want to be pointing. + // The vehicle is moving in some direction and correct its orientation to it is pointing + // in that direction. + // TODO: implement reference frame. + public Vector3 ComputeAngularDeflection() + { + Vector3 ret = Vector3.Zero; + return ret; // DEBUG DEBUG DEBUG + // Disable angular deflection for the moment. + // Since angularMotorUp and angularDeflection are computed independently, they will calculate + // approximately the same X or Y correction. When added together (when contributions are combined) + // this creates an over-correction and then wabbling as the target is overshot. + // TODO: rethink how the different correction computations inter-relate. + + if (m_angularDeflectionEfficiency != 0) + { + // The direction the vehicle is moving + Vector3 movingDirection = VehicleVelocity; + movingDirection.Normalize(); + + // The direction the vehicle is pointing + Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation; + pointingDirection.Normalize(); + + // The difference between what is and what should be. + Vector3 deflectionError = movingDirection - pointingDirection; + + // Don't try to correct very large errors (not our job) + if (Math.Abs(deflectionError.X) > PIOverFour) deflectionError.X = 0f; + if (Math.Abs(deflectionError.Y) > PIOverFour) deflectionError.Y = 0f; + if (Math.Abs(deflectionError.Z) > PIOverFour) deflectionError.Z = 0f; + + // ret = m_angularDeflectionCorrectionMotor(1f, deflectionError); + + // Scale the correction by recovery timescale and efficiency + ret = (-deflectionError) * m_angularDeflectionEfficiency; + ret /= m_angularDeflectionTimescale; + + VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}", + Prim.LocalID, movingDirection, pointingDirection, deflectionError, ret); + VDetailLog("{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3}", + Prim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale); + } + return ret; + } + + // Return an angular change to rotate the vehicle around the Z axis when the vehicle + // is tipped around the X axis. + // From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial: + // The vertical attractor feature must be enabled in order for the banking behavior to + // function. The way banking works is this: a rotation around the vehicle's roll-axis will + // produce a angular velocity around the yaw-axis, causing the vehicle to turn. The magnitude + // of the yaw effect will be proportional to the + // VEHICLE_BANKING_EFFICIENCY, the angle of the roll rotation, and sometimes the vehicle's + // velocity along its preferred axis of motion. + // The VEHICLE_BANKING_EFFICIENCY can vary between -1 and +1. When it is positive then any + // positive rotation (by the right-hand rule) about the roll-axis will effect a + // (negative) torque around the yaw-axis, making it turn to the right--that is the + // vehicle will lean into the turn, which is how real airplanes and motorcycle's work. + // Negating the banking coefficient will make it so that the vehicle leans to the + // outside of the turn (not very "physical" but might allow interesting vehicles so why not?). + // The VEHICLE_BANKING_MIX is a fake (i.e. non-physical) parameter that is useful for making + // banking vehicles do what you want rather than what the laws of physics allow. + // For example, consider a real motorcycle...it must be moving forward in order for + // it to turn while banking, however video-game motorcycles are often configured + // to turn in place when at a dead stop--because they are often easier to control + // that way using the limited interface of the keyboard or game controller. The + // VEHICLE_BANKING_MIX enables combinations of both realistic and non-realistic + // banking by functioning as a slider between a banking that is correspondingly + // totally static (0.0) and totally dynamic (1.0). By "static" we mean that the + // banking effect depends only on the vehicle's rotation about its roll-axis compared + // to "dynamic" where the banking is also proportional to its velocity along its + // roll-axis. Finding the best value of the "mixture" will probably require trial and error. + // The time it takes for the banking behavior to defeat a preexisting angular velocity about the + // world z-axis is determined by the VEHICLE_BANKING_TIMESCALE. So if you want the vehicle to + // bank quickly then give it a banking timescale of about a second or less, otherwise you can + // make a sluggish vehicle by giving it a timescale of several seconds. + public Vector3 ComputeAngularBanking() + { + Vector3 ret = Vector3.Zero; + + if (m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) + { + // This works by rotating a unit vector to the orientation of the vehicle. The + // roll (tilt) will be Y component of a tilting Z vector (zero for no tilt + // up to one for full over). + Vector3 rollComponents = Vector3.UnitZ * VehicleOrientation; + + // Figure out the yaw value for this much roll. + float turnComponent = rollComponents.Y * rollComponents.Y * m_bankingEfficiency; + // Keep the sign + if (rollComponents.Y < 0f) + turnComponent = -turnComponent; + + // TODO: there must be a better computation of the banking force. + float bankingTurnForce = turnComponent; + + // actual error = static turn error + dynamic turn error + float mixedBankingError = bankingTurnForce * (1f - m_bankingMix) + bankingTurnForce * m_bankingMix * VehicleForwardSpeed; + // TODO: the banking effect should not go to infinity but what to limit it to? + mixedBankingError = ClampInRange(-20f, mixedBankingError, 20f); + + // Build the force vector to change rotation from what it is to what it should be + ret.Z = -mixedBankingError; + + // Don't do it all at once. + ret /= m_bankingTimescale; + + VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},turnComp={3},bankErr={4},mixedBankErr={5},ret={6}", + Prim.LocalID, rollComponents, VehicleForwardSpeed, turnComponent, bankingTurnForce, mixedBankingError, ret); + } + return ret; + } + + // This is from previous instantiations of XXXDynamics.cs. + // Applies roll reference frame. + // TODO: is this the right way to separate the code to do this operation? + // Should this be in MoveAngular()? + internal void LimitRotation(float timestep) + { + Quaternion rotq = VehicleOrientation; + Quaternion m_rot = rotq; + if (m_RollreferenceFrame != Quaternion.Identity) + { + if (rotq.X >= m_RollreferenceFrame.X) + { + m_rot.X = rotq.X - (m_RollreferenceFrame.X / 2); + } + if (rotq.Y >= m_RollreferenceFrame.Y) + { + m_rot.Y = rotq.Y - (m_RollreferenceFrame.Y / 2); + } + if (rotq.X <= -m_RollreferenceFrame.X) + { + m_rot.X = rotq.X + (m_RollreferenceFrame.X / 2); + } + if (rotq.Y <= -m_RollreferenceFrame.Y) + { + m_rot.Y = rotq.Y + (m_RollreferenceFrame.Y / 2); + } + } + if ((m_flags & VehicleFlag.LOCK_ROTATION) != 0) + { + m_rot.X = 0; + m_rot.Y = 0; + } + if (rotq != m_rot) + { + VehicleOrientation = m_rot; + VDetailLog("{0}, LimitRotation,done,orig={1},new={2}", Prim.LocalID, rotq, m_rot); + } + + } + + private float ClampInRange(float low, float val, float high) + { + return Math.Max(low, Math.Min(val, high)); + // return Utils.Clamp(val, low, high); + } + + // Invoke the detailed logger and output something if it's enabled. + private void VDetailLog(string msg, params Object[] args) + { + if (Prim.PhysicsScene.VehicleLoggingEnabled) + Prim.PhysicsScene.DetailLog(msg, args); + } + } +} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSLinkset.cs new file mode 100644 index 0000000..253128b --- /dev/null +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSLinkset.cs @@ -0,0 +1,333 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; + +using OMV = OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSNPlugin +{ + +// A BSPrim can get individual information about its linkedness attached +// to it through an instance of a subclass of LinksetInfo. +// Each type of linkset will define the information needed for its type. +public abstract class BSLinksetInfo +{ + public virtual void Clear() { } +} + +public abstract class BSLinkset +{ + // private static string LogHeader = "[BULLETSIM LINKSET]"; + + public enum LinksetImplementation + { + Constraint = 0, // linkset tied together with constraints + Compound = 1, // linkset tied together as a compound object + Manual = 2 // linkset tied together manually (code moves all the pieces) + } + // Create the correct type of linkset for this child + public static BSLinkset Factory(BSScene physScene, BSPhysObject parent) + { + BSLinkset ret = null; + + switch ((int)BSParam.LinksetImplementation) + { + case (int)LinksetImplementation.Constraint: + ret = new BSLinksetConstraints(physScene, parent); + break; + case (int)LinksetImplementation.Compound: + ret = new BSLinksetCompound(physScene, parent); + break; + case (int)LinksetImplementation.Manual: + // ret = new BSLinksetManual(physScene, parent); + break; + default: + ret = new BSLinksetCompound(physScene, parent); + break; + } + return ret; + } + + public BSPhysObject LinksetRoot { get; protected set; } + + public BSScene PhysicsScene { get; private set; } + + static int m_nextLinksetID = 1; + public int LinksetID { get; private set; } + + // The children under the root in this linkset. + protected HashSet m_children; + + // We lock the diddling of linkset classes to prevent any badness. + // This locks the modification of the instances of this class. Changes + // to the physical representation is done via the tainting mechenism. + protected object m_linksetActivityLock = new Object(); + + // Some linksets have a preferred physical shape. + // Returns SHAPE_UNKNOWN if there is no preference. Causes the correct shape to be selected. + public virtual BSPhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor) + { + return BSPhysicsShapeType.SHAPE_UNKNOWN; + } + + // We keep the prim's mass in the linkset structure since it could be dependent on other prims + protected float m_mass; + public float LinksetMass + { + get + { + return m_mass; + } + } + + public virtual bool LinksetIsColliding { get { return false; } } + + public OMV.Vector3 CenterOfMass + { + get { return ComputeLinksetCenterOfMass(); } + } + + public OMV.Vector3 GeometricCenter + { + get { return ComputeLinksetGeometricCenter(); } + } + + protected BSLinkset(BSScene scene, BSPhysObject parent) + { + // A simple linkset of one (no children) + LinksetID = m_nextLinksetID++; + // We create LOTS of linksets. + if (m_nextLinksetID <= 0) + m_nextLinksetID = 1; + PhysicsScene = scene; + LinksetRoot = parent; + m_children = new HashSet(); + m_mass = parent.RawMass; + Rebuilding = false; + } + + // Link to a linkset where the child knows the parent. + // Parent changing should not happen so do some sanity checking. + // We return the parent's linkset so the child can track its membership. + // Called at runtime. + public BSLinkset AddMeToLinkset(BSPhysObject child) + { + lock (m_linksetActivityLock) + { + // Don't add the root to its own linkset + if (!IsRoot(child)) + AddChildToLinkset(child); + m_mass = ComputeLinksetMass(); + } + return this; + } + + // Remove a child from a linkset. + // Returns a new linkset for the child which is a linkset of one (just the + // orphened child). + // Called at runtime. + public BSLinkset RemoveMeFromLinkset(BSPhysObject child) + { + lock (m_linksetActivityLock) + { + if (IsRoot(child)) + { + // Cannot remove the root from a linkset. + return this; + } + RemoveChildFromLinkset(child); + m_mass = ComputeLinksetMass(); + } + + // The child is down to a linkset of just itself + return BSLinkset.Factory(PhysicsScene, child); + } + + // Return 'true' if the passed object is the root object of this linkset + public bool IsRoot(BSPhysObject requestor) + { + return (requestor.LocalID == LinksetRoot.LocalID); + } + + public int NumberOfChildren { get { return m_children.Count; } } + + // Return 'true' if this linkset has any children (more than the root member) + public bool HasAnyChildren { get { return (m_children.Count > 0); } } + + // Return 'true' if this child is in this linkset + public bool HasChild(BSPhysObject child) + { + bool ret = false; + lock (m_linksetActivityLock) + { + ret = m_children.Contains(child); + /* Safer version but the above should work + foreach (BSPhysObject bp in m_children) + { + if (child.LocalID == bp.LocalID) + { + ret = true; + break; + } + } + */ + } + return ret; + } + + // Perform an action on each member of the linkset including root prim. + // Depends on the action on whether this should be done at taint time. + public delegate bool ForEachMemberAction(BSPhysObject obj); + public virtual bool ForEachMember(ForEachMemberAction action) + { + bool ret = false; + lock (m_linksetActivityLock) + { + action(LinksetRoot); + foreach (BSPhysObject po in m_children) + { + if (action(po)) + break; + } + } + return ret; + } + + // I am the root of a linkset and a new child is being added + // Called while LinkActivity is locked. + protected abstract void AddChildToLinkset(BSPhysObject child); + + // I am the root of a linkset and one of my children is being removed. + // Safe to call even if the child is not really in my linkset. + protected abstract void RemoveChildFromLinkset(BSPhysObject child); + + // When physical properties are changed the linkset needs to recalculate + // its internal properties. + // May be called at runtime or taint-time. + public abstract void Refresh(BSPhysObject requestor); + + // Flag denoting the linkset is in the process of being rebuilt. + // Used to know not the schedule a rebuild in the middle of a rebuild. + protected bool Rebuilding { get; set; } + + // The object is going dynamic (physical). Do any setup necessary + // for a dynamic linkset. + // Only the state of the passed object can be modified. The rest of the linkset + // has not yet been fully constructed. + // Return 'true' if any properties updated on the passed object. + // Called at taint-time! + public abstract bool MakeDynamic(BSPhysObject child); + + // The object is going static (non-physical). Do any setup necessary + // for a static linkset. + // Return 'true' if any properties updated on the passed object. + // Called at taint-time! + public abstract bool MakeStatic(BSPhysObject child); + + // Called when a parameter update comes from the physics engine for any object + // of the linkset is received. + // Passed flag is update came from physics engine (true) or the user (false). + // Called at taint-time!! + public abstract void UpdateProperties(BSPhysObject physObject, bool physicalUpdate); + + // Routine used when rebuilding the body of the root of the linkset + // Destroy all the constraints have have been made to root. + // This is called when the root body is changing. + // Returns 'true' of something was actually removed and would need restoring + // Called at taint-time!! + public abstract bool RemoveBodyDependencies(BSPrim child); + + // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true', + // this routine will restore the removed constraints. + // Called at taint-time!! + public abstract void RestoreBodyDependencies(BSPrim child); + + // ================================================================ + protected virtual float ComputeLinksetMass() + { + float mass = LinksetRoot.RawMass; + if (HasAnyChildren) + { + lock (m_linksetActivityLock) + { + foreach (BSPhysObject bp in m_children) + { + mass += bp.RawMass; + } + } + } + return mass; + } + + protected virtual OMV.Vector3 ComputeLinksetCenterOfMass() + { + OMV.Vector3 com; + lock (m_linksetActivityLock) + { + com = LinksetRoot.Position * LinksetRoot.RawMass; + float totalMass = LinksetRoot.RawMass; + + foreach (BSPhysObject bp in m_children) + { + com += bp.Position * bp.RawMass; + totalMass += bp.RawMass; + } + if (totalMass != 0f) + com /= totalMass; + } + + return com; + } + + protected virtual OMV.Vector3 ComputeLinksetGeometricCenter() + { + OMV.Vector3 com; + lock (m_linksetActivityLock) + { + com = LinksetRoot.Position; + + foreach (BSPhysObject bp in m_children) + { + com += bp.Position * bp.RawMass; + } + com /= (m_children.Count + 1); + } + + return com; + } + + // Invoke the detailed logger and output something if it's enabled. + protected void DetailLog(string msg, params Object[] args) + { + if (PhysicsScene.PhysicsLogging.Enabled) + PhysicsScene.DetailLog(msg, args); + } + +} +} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetCompound.cs new file mode 100644 index 0000000..23a0b8b --- /dev/null +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetCompound.cs @@ -0,0 +1,396 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; + +using OpenSim.Framework; + +using OMV = OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSNPlugin +{ + +// When a child is linked, the relationship position of the child to the parent +// is remembered so the child's world position can be recomputed when it is +// removed from the linkset. +sealed class BSLinksetCompoundInfo : BSLinksetInfo +{ + public OMV.Vector3 OffsetPos; + public OMV.Quaternion OffsetRot; + public BSLinksetCompoundInfo(OMV.Vector3 p, OMV.Quaternion r) + { + OffsetPos = p; + OffsetRot = r; + } + public override void Clear() + { + OffsetPos = OMV.Vector3.Zero; + OffsetRot = OMV.Quaternion.Identity; + } + public override string ToString() + { + StringBuilder buff = new StringBuilder(); + buff.Append(""); + return buff.ToString(); + } +}; + +public sealed class BSLinksetCompound : BSLinkset +{ + private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]"; + + public BSLinksetCompound(BSScene scene, BSPhysObject parent) : base(scene, parent) + { + } + + // For compound implimented linksets, if there are children, use compound shape for the root. + public override BSPhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor) + { + // Returning 'unknown' means we don't have a preference. + BSPhysicsShapeType ret = BSPhysicsShapeType.SHAPE_UNKNOWN; + if (IsRoot(requestor) && HasAnyChildren) + { + ret = BSPhysicsShapeType.SHAPE_COMPOUND; + } + // DetailLog("{0},BSLinksetCompound.PreferredPhysicalShape,call,shape={1}", LinksetRoot.LocalID, ret); + return ret; + } + + // When physical properties are changed the linkset needs to recalculate + // its internal properties. + public override void Refresh(BSPhysObject requestor) + { + // Something changed so do the rebuilding thing + // ScheduleRebuild(); + } + + // Schedule a refresh to happen after all the other taint processing. + private void ScheduleRebuild(BSPhysObject requestor) + { + DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,rebuilding={1}", + requestor.LocalID, Rebuilding); + // When rebuilding, it is possible to set properties that would normally require a rebuild. + // If already rebuilding, don't request another rebuild. + if (!Rebuilding) + { + PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", LinksetRoot.LocalID, delegate() + { + if (HasAnyChildren) + RecomputeLinksetCompound(); + }); + } + } + + // The object is going dynamic (physical). Do any setup necessary + // for a dynamic linkset. + // Only the state of the passed object can be modified. The rest of the linkset + // has not yet been fully constructed. + // Return 'true' if any properties updated on the passed object. + // Called at taint-time! + public override bool MakeDynamic(BSPhysObject child) + { + bool ret = false; + DetailLog("{0},BSLinksetCompound.MakeDynamic,call,IsRoot={1}", child.LocalID, IsRoot(child)); + if (IsRoot(child)) + { + // The root is going dynamic. Make sure mass is properly set. + m_mass = ComputeLinksetMass(); + ScheduleRebuild(LinksetRoot); + } + else + { + // The origional prims are removed from the world as the shape of the root compound + // shape takes over. + BulletSimAPI.AddToCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); + BulletSimAPI.ForceActivationState2(child.PhysBody.ptr, ActivationState.DISABLE_SIMULATION); + // We don't want collisions from the old linkset children. + BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + + child.PhysBody.collisionType = CollisionType.LinksetChild; + + ret = true; + } + return ret; + } + + // The object is going static (non-physical). Do any setup necessary for a static linkset. + // Return 'true' if any properties updated on the passed object. + // This doesn't normally happen -- OpenSim removes the objects from the physical + // world if it is a static linkset. + // Called at taint-time! + public override bool MakeStatic(BSPhysObject child) + { + bool ret = false; + DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child)); + if (IsRoot(child)) + { + ScheduleRebuild(LinksetRoot); + } + else + { + // The non-physical children can come back to life. + BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); + + child.PhysBody.collisionType = CollisionType.LinksetChild; + + // Don't force activation so setting of DISABLE_SIMULATION can stay if used. + BulletSimAPI.Activate2(child.PhysBody.ptr, false); + ret = true; + } + return ret; + } + + public override void UpdateProperties(BSPhysObject updated, bool physicalUpdate) + { + // The user moving a child around requires the rebuilding of the linkset compound shape + // One problem is this happens when a border is crossed -- the simulator implementation + // is to store the position into the group which causes the move of the object + // but it also means all the child positions get updated. + // What would cause an unnecessary rebuild so we make sure the linkset is in a + // region before bothering to do a rebuild. + if (!IsRoot(updated) + && !physicalUpdate + && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition)) + { + updated.LinksetInfo = null; + ScheduleRebuild(updated); + } + } + + // Routine called when rebuilding the body of some member of the linkset. + // Since we don't keep in world relationships, do nothing unless it's a child changing. + // Returns 'true' of something was actually removed and would need restoring + // Called at taint-time!! + public override bool RemoveBodyDependencies(BSPrim child) + { + bool ret = false; + + DetailLog("{0},BSLinksetCompound.RemoveBodyDependencies,refreshIfChild,rID={1},rBody={2},isRoot={3}", + child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString(), IsRoot(child)); + + if (!IsRoot(child)) + { + // Because it is a convenient time, recompute child world position and rotation based on + // its position in the linkset. + RecomputeChildWorldPosition(child, true); + } + + // Cannot schedule a refresh/rebuild here because this routine is called when + // the linkset is being rebuilt. + // InternalRefresh(LinksetRoot); + + return ret; + } + + // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true', + // this routine will restore the removed constraints. + // Called at taint-time!! + public override void RestoreBodyDependencies(BSPrim child) + { + } + + // When the linkset is built, the child shape is added to the compound shape relative to the + // root shape. The linkset then moves around but this does not move the actual child + // prim. The child prim's location must be recomputed based on the location of the root shape. + private void RecomputeChildWorldPosition(BSPhysObject child, bool inTaintTime) + { + BSLinksetCompoundInfo lci = child.LinksetInfo as BSLinksetCompoundInfo; + if (lci != null) + { + if (inTaintTime) + { + OMV.Vector3 oldPos = child.RawPosition; + child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetPos; + child.ForceOrientation = LinksetRoot.RawOrientation * lci.OffsetRot; + DetailLog("{0},BSLinksetCompound.RecomputeChildWorldPosition,oldPos={1},lci={2},newPos={3}", + child.LocalID, oldPos, lci, child.RawPosition); + } + else + { + // TaintedObject is not used here so the raw position is set now and not at taint-time. + child.Position = LinksetRoot.RawPosition + lci.OffsetPos; + child.Orientation = LinksetRoot.RawOrientation * lci.OffsetRot; + } + } + else + { + // This happens when children have been added to the linkset but the linkset + // has not been constructed yet. So like, at taint time, adding children to a linkset + // and then changing properties of the children (makePhysical, for instance) + // but the post-print action of actually rebuilding the linkset has not yet happened. + // PhysicsScene.Logger.WarnFormat("{0} Restoring linkset child position failed because of no relative position computed. ID={1}", + // LogHeader, child.LocalID); + DetailLog("{0},BSLinksetCompound.recomputeChildWorldPosition,noRelativePositonInfo", child.LocalID); + } + } + + // ================================================================ + + // Add a new child to the linkset. + // Called while LinkActivity is locked. + protected override void AddChildToLinkset(BSPhysObject child) + { + if (!HasChild(child)) + { + m_children.Add(child); + + DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); + + // Rebuild the compound shape with the new child shape included + ScheduleRebuild(child); + } + return; + } + + // Remove the specified child from the linkset. + // Safe to call even if the child is not really in the linkset. + protected override void RemoveChildFromLinkset(BSPhysObject child) + { + if (m_children.Remove(child)) + { + DetailLog("{0},BSLinksetCompound.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}", + child.LocalID, + LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString(), + child.LocalID, child.PhysBody.ptr.ToString()); + + // Cause the child's body to be rebuilt and thus restored to normal operation + RecomputeChildWorldPosition(child, false); + child.ForceBodyShapeRebuild(false); + + if (!HasAnyChildren) + { + // The linkset is now empty. The root needs rebuilding. + LinksetRoot.ForceBodyShapeRebuild(false); + } + else + { + // Rebuild the compound shape with the child removed + ScheduleRebuild(child); + } + } + return; + } + + // Called before the simulation step to make sure the compound based linkset + // is all initialized. + // Constraint linksets are rebuilt every time. + // Note that this works for rebuilding just the root after a linkset is taken apart. + // Called at taint time!! + private void RecomputeLinksetCompound() + { + try + { + // Suppress rebuilding while rebuilding + Rebuilding = true; + + // Cause the root shape to be rebuilt as a compound object with just the root in it + LinksetRoot.ForceBodyShapeRebuild(true); + + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", + LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); + + // Add a shape for each of the other children in the linkset + ForEachMember(delegate(BSPhysObject cPrim) + { + if (!IsRoot(cPrim)) + { + // Compute the displacement of the child from the root of the linkset. + // This info is saved in the child prim so the relationship does not + // change over time and the new child position can be computed + // when the linkset is being disassembled (the linkset may have moved). + BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; + if (lci == null) + { + // Each child position and rotation is given relative to the root. + OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); + OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; + OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; + + // Save relative position for recomputing child's world position after moving linkset. + lci = new BSLinksetCompoundInfo(displacementPos, displacementRot); + cPrim.LinksetInfo = lci; + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); + } + + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}", + LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); + + if (cPrim.PhysShape.isNativeShape) + { + // A native shape is turning into a hull collision shape because native + // shapes are not shared so we have to hullify it so it will be tracked + // and freed at the correct time. This also solves the scaling problem + // (native shapes scaled but hull/meshes are assumed to not be). + // TODO: decide of the native shape can just be used in the compound shape. + // Use call to CreateGeomNonSpecial(). + BulletShape saveShape = cPrim.PhysShape; + cPrim.PhysShape.Clear(); // Don't let the create free the child's shape + // PhysicsScene.Shapes.CreateGeomNonSpecial(true, cPrim, null); + PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); + BulletShape newShape = cPrim.PhysShape; + cPrim.PhysShape = saveShape; + BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, newShape.ptr, lci.OffsetPos, lci.OffsetRot); + } + else + { + // For the shared shapes (meshes and hulls), just use the shape in the child. + // The reference count added here will be decremented when the compound shape + // is destroyed in BSShapeCollection (the child shapes are looped over and dereferenced). + if (PhysicsScene.Shapes.ReferenceShape(cPrim.PhysShape)) + { + PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", + LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); + } + BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, cPrim.PhysShape.ptr, lci.OffsetPos, lci.OffsetRot); + } + } + return false; // 'false' says to move onto the next child in the list + }); + + // With all of the linkset packed into the root prim, it has the mass of everyone. + float linksetMass = LinksetMass; + LinksetRoot.UpdatePhysicalMassProperties(linksetMass); + } + finally + { + Rebuilding = false; + } + + BulletSimAPI.RecalculateCompoundShapeLocalAabb2(LinksetRoot.PhysShape.ptr); + + // DEBUG: see of inter-linkset collisions are causing problems for constraint linksets. + // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, + // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); + + } +} +} \ No newline at end of file diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetConstraints.cs new file mode 100644 index 0000000..5757e64 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetConstraints.cs @@ -0,0 +1,314 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; + +using OMV = OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSNPlugin +{ +public sealed class BSLinksetConstraints : BSLinkset +{ + // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]"; + + public BSLinksetConstraints(BSScene scene, BSPhysObject parent) : base(scene, parent) + { + } + + // When physical properties are changed the linkset needs to recalculate + // its internal properties. + // This is queued in the 'post taint' queue so the + // refresh will happen once after all the other taints are applied. + public override void Refresh(BSPhysObject requestor) + { + // Queue to happen after all the other taint processing + PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate() + { + if (HasAnyChildren && IsRoot(requestor)) + RecomputeLinksetConstraints(); + }); + } + + // The object is going dynamic (physical). Do any setup necessary + // for a dynamic linkset. + // Only the state of the passed object can be modified. The rest of the linkset + // has not yet been fully constructed. + // Return 'true' if any properties updated on the passed object. + // Called at taint-time! + public override bool MakeDynamic(BSPhysObject child) + { + // What is done for each object in BSPrim is what we want. + return false; + } + + // The object is going static (non-physical). Do any setup necessary for a static linkset. + // Return 'true' if any properties updated on the passed object. + // This doesn't normally happen -- OpenSim removes the objects from the physical + // world if it is a static linkset. + // Called at taint-time! + public override bool MakeStatic(BSPhysObject child) + { + // What is done for each object in BSPrim is what we want. + return false; + } + + // Called at taint-time!! + public override void UpdateProperties(BSPhysObject updated, bool inTaintTime) + { + // Nothing to do for constraints on property updates + } + + // Routine called when rebuilding the body of some member of the linkset. + // Destroy all the constraints have have been made to root and set + // up to rebuild the constraints before the next simulation step. + // Returns 'true' of something was actually removed and would need restoring + // Called at taint-time!! + public override bool RemoveBodyDependencies(BSPrim child) + { + bool ret = false; + + DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}", + child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString()); + + lock (m_linksetActivityLock) + { + // Just undo all the constraints for this linkset. Rebuild at the end of the step. + ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot); + // Cause the constraints, et al to be rebuilt before the next simulation step. + Refresh(LinksetRoot); + } + return ret; + } + + // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true', + // this routine will restore the removed constraints. + // Called at taint-time!! + public override void RestoreBodyDependencies(BSPrim child) + { + // The Refresh operation queued by RemoveBodyDependencies() will build any missing constraints. + } + + // ================================================================ + + // Add a new child to the linkset. + // Called while LinkActivity is locked. + protected override void AddChildToLinkset(BSPhysObject child) + { + if (!HasChild(child)) + { + m_children.Add(child); + + DetailLog("{0},BSLinksetConstraints.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); + + // Cause constraints and assorted properties to be recomputed before the next simulation step. + Refresh(LinksetRoot); + } + return; + } + + // Remove the specified child from the linkset. + // Safe to call even if the child is not really in my linkset. + protected override void RemoveChildFromLinkset(BSPhysObject child) + { + if (m_children.Remove(child)) + { + BSPhysObject rootx = LinksetRoot; // capture the root and body as of now + BSPhysObject childx = child; + + DetailLog("{0},BSLinksetConstraints.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}", + childx.LocalID, + rootx.LocalID, rootx.PhysBody.ptr.ToString(), + childx.LocalID, childx.PhysBody.ptr.ToString()); + + PhysicsScene.TaintedObject("BSLinksetConstraints.RemoveChildFromLinkset", delegate() + { + PhysicallyUnlinkAChildFromRoot(rootx, childx); + }); + // See that the linkset parameters are recomputed at the end of the taint time. + Refresh(LinksetRoot); + } + else + { + // Non-fatal occurance. + // PhysicsScene.Logger.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset", LogHeader); + } + return; + } + + // Create a constraint between me (root of linkset) and the passed prim (the child). + // Called at taint time! + private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BSPhysObject childPrim) + { + // Don't build the constraint when asked. Put it off until just before the simulation step. + Refresh(rootPrim); + } + + private BSConstraint BuildConstraint(BSPhysObject rootPrim, BSPhysObject childPrim) + { + // Zero motion for children so they don't interpolate + childPrim.ZeroMotion(true); + + // Relative position normalized to the root prim + // Essentually a vector pointing from center of rootPrim to center of childPrim + OMV.Vector3 childRelativePosition = childPrim.Position - rootPrim.Position; + + // real world coordinate of midpoint between the two objects + OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2); + + DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", + rootPrim.LocalID, + rootPrim.LocalID, rootPrim.PhysBody.ptr.ToString(), + childPrim.LocalID, childPrim.PhysBody.ptr.ToString(), + rootPrim.Position, childPrim.Position, midPoint); + + // create a constraint that allows no freedom of movement between the two objects + // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 + + BSConstraint6Dof constrain = new BSConstraint6Dof( + PhysicsScene.World, rootPrim.PhysBody, childPrim.PhysBody, midPoint, true, true ); + // PhysicsScene.World, childPrim.BSBody, rootPrim.BSBody, midPoint, true, true ); + + /* NOTE: below is an attempt to build constraint with full frame computation, etc. + * Using the midpoint is easier since it lets the Bullet code manipulate the transforms + * of the objects. + * Code left for future programmers. + // ================================================================================== + // relative position normalized to the root prim + OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation); + OMV.Vector3 childRelativePosition = (childPrim.Position - rootPrim.Position) * invThisOrientation; + + // relative rotation of the child to the parent + OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation; + OMV.Quaternion inverseChildRelativeRotation = OMV.Quaternion.Inverse(childRelativeRotation); + + DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); + BS6DofConstraint constrain = new BS6DofConstraint( + PhysicsScene.World, rootPrim.Body, childPrim.Body, + OMV.Vector3.Zero, + OMV.Quaternion.Inverse(rootPrim.Orientation), + OMV.Vector3.Zero, + OMV.Quaternion.Inverse(childPrim.Orientation), + true, + true + ); + // ================================================================================== + */ + + PhysicsScene.Constraints.AddConstraint(constrain); + + // zero linear and angular limits makes the objects unable to move in relation to each other + constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); + constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); + + // tweek the constraint to increase stability + constrain.UseFrameOffset(BSParam.BoolNumeric(BSParam.LinkConstraintUseFrameOffset)); + constrain.TranslationalLimitMotor(BSParam.BoolNumeric(BSParam.LinkConstraintEnableTransMotor), + BSParam.LinkConstraintTransMotorMaxVel, + BSParam.LinkConstraintTransMotorMaxForce); + constrain.SetCFMAndERP(BSParam.LinkConstraintCFM, BSParam.LinkConstraintERP); + if (BSParam.LinkConstraintSolverIterations != 0f) + { + constrain.SetSolverIterations(BSParam.LinkConstraintSolverIterations); + } + return constrain; + } + + // Remove linkage between the linkset root and a particular child + // The root and child bodies are passed in because we need to remove the constraint between + // the bodies that were present at unlink time. + // Called at taint time! + private bool PhysicallyUnlinkAChildFromRoot(BSPhysObject rootPrim, BSPhysObject childPrim) + { + bool ret = false; + DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}", + rootPrim.LocalID, + rootPrim.LocalID, rootPrim.PhysBody.ptr.ToString(), + childPrim.LocalID, childPrim.PhysBody.ptr.ToString()); + + // Find the constraint for this link and get rid of it from the overall collection and from my list + if (PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody, childPrim.PhysBody)) + { + // Make the child refresh its location + BulletSimAPI.PushUpdate2(childPrim.PhysBody.ptr); + ret = true; + } + + return ret; + } + + // Remove linkage between myself and any possible children I might have. + // Returns 'true' of any constraints were destroyed. + // Called at taint time! + private bool PhysicallyUnlinkAllChildrenFromRoot(BSPhysObject rootPrim) + { + DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); + + return PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody); + } + + // Call each of the constraints that make up this linkset and recompute the + // various transforms and variables. Create constraints of not created yet. + // Called before the simulation step to make sure the constraint based linkset + // is all initialized. + // Called at taint time!! + private void RecomputeLinksetConstraints() + { + float linksetMass = LinksetMass; + LinksetRoot.UpdatePhysicalMassProperties(linksetMass); + + // DEBUG: see of inter-linkset collisions are causing problems + // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, + // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); + DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}", + LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString(), linksetMass); + + foreach (BSPhysObject child in m_children) + { + // A child in the linkset physically shows the mass of the whole linkset. + // This allows Bullet to apply enough force on the child to move the whole linkset. + // (Also do the mass stuff before recomputing the constraint so mass is not zero.) + child.UpdatePhysicalMassProperties(linksetMass); + + BSConstraint constrain; + if (!PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, child.PhysBody, out constrain)) + { + // If constraint doesn't exist yet, create it. + constrain = BuildConstraint(LinksetRoot, child); + } + constrain.RecomputeConstraintVariables(linksetMass); + + // DEBUG: see of inter-linkset collisions are causing problems + // BulletSimAPI.SetCollisionFilterMask2(child.BSBody.ptr, + // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); + + // BulletSimAPI.DumpConstraint2(PhysicsScene.World.ptr, constrain.Constraint.ptr); // DEBUG DEBUG + } + + } +} +} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSMaterials.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSMaterials.cs new file mode 100644 index 0000000..732191f --- /dev/null +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSMaterials.cs @@ -0,0 +1,200 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using System.Reflection; +using Nini.Config; + +namespace OpenSim.Region.Physics.BulletSNPlugin +{ + +public struct MaterialAttributes +{ + // Material type values that correspond with definitions for LSL + public enum Material : int + { + Stone = 0, + Metal, + Glass, + Wood, + Flesh, + Plastic, + Rubber, + Light, + // Hereafter are BulletSim additions + Avatar, + NumberOfTypes // the count of types in the enum. + } + + // Names must be in the order of the above enum. + // These names must coorespond to the lower case field names in the MaterialAttributes + // structure as reflection is used to select the field to put the value in. + public static readonly string[] MaterialAttribs = { "Density", "Friction", "Restitution"}; + + public MaterialAttributes(string t, float d, float f, float r) + { + type = t; + density = d; + friction = f; + restitution = r; + } + public string type; + public float density; + public float friction; + public float restitution; +} + +public static class BSMaterials +{ + // Attributes for each material type + private static readonly MaterialAttributes[] Attributes; + + // Map of material name to material type code + public static readonly Dictionary MaterialMap; + + static BSMaterials() + { + // Attribute sets for both the non-physical and physical instances of materials. + Attributes = new MaterialAttributes[(int)MaterialAttributes.Material.NumberOfTypes * 2]; + + // Map of name to type code. + MaterialMap = new Dictionary(); + MaterialMap.Add("Stone", MaterialAttributes.Material.Stone); + MaterialMap.Add("Metal", MaterialAttributes.Material.Metal); + MaterialMap.Add("Glass", MaterialAttributes.Material.Glass); + MaterialMap.Add("Wood", MaterialAttributes.Material.Wood); + MaterialMap.Add("Flesh", MaterialAttributes.Material.Flesh); + MaterialMap.Add("Plastic", MaterialAttributes.Material.Plastic); + MaterialMap.Add("Rubber", MaterialAttributes.Material.Rubber); + MaterialMap.Add("Light", MaterialAttributes.Material.Light); + MaterialMap.Add("Avatar", MaterialAttributes.Material.Avatar); + } + + // This is where all the default material attributes are defined. + public static void InitializeFromDefaults(ConfigurationParameters parms) + { + // Values from http://wiki.secondlife.com/wiki/PRIM_MATERIAL + float dDensity = parms.defaultDensity; + float dFriction = parms.defaultFriction; + float dRestitution = parms.defaultRestitution; + Attributes[(int)MaterialAttributes.Material.Stone] = + new MaterialAttributes("stone",dDensity, 0.8f, 0.4f); + Attributes[(int)MaterialAttributes.Material.Metal] = + new MaterialAttributes("metal",dDensity, 0.3f, 0.4f); + Attributes[(int)MaterialAttributes.Material.Glass] = + new MaterialAttributes("glass",dDensity, 0.2f, 0.7f); + Attributes[(int)MaterialAttributes.Material.Wood] = + new MaterialAttributes("wood",dDensity, 0.6f, 0.5f); + Attributes[(int)MaterialAttributes.Material.Flesh] = + new MaterialAttributes("flesh",dDensity, 0.9f, 0.3f); + Attributes[(int)MaterialAttributes.Material.Plastic] = + new MaterialAttributes("plastic",dDensity, 0.4f, 0.7f); + Attributes[(int)MaterialAttributes.Material.Rubber] = + new MaterialAttributes("rubber",dDensity, 0.9f, 0.9f); + Attributes[(int)MaterialAttributes.Material.Light] = + new MaterialAttributes("light",dDensity, dFriction, dRestitution); + Attributes[(int)MaterialAttributes.Material.Avatar] = + new MaterialAttributes("avatar",60f, 0.2f, 0f); + + Attributes[(int)MaterialAttributes.Material.Stone + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("stonePhysical",dDensity, 0.8f, 0.4f); + Attributes[(int)MaterialAttributes.Material.Metal + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("metalPhysical",dDensity, 0.8f, 0.4f); + Attributes[(int)MaterialAttributes.Material.Glass + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("glassPhysical",dDensity, 0.8f, 0.7f); + Attributes[(int)MaterialAttributes.Material.Wood + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("woodPhysical",dDensity, 0.8f, 0.5f); + Attributes[(int)MaterialAttributes.Material.Flesh + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("fleshPhysical",dDensity, 0.8f, 0.3f); + Attributes[(int)MaterialAttributes.Material.Plastic + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("plasticPhysical",dDensity, 0.8f, 0.7f); + Attributes[(int)MaterialAttributes.Material.Rubber + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("rubberPhysical",dDensity, 0.8f, 0.9f); + Attributes[(int)MaterialAttributes.Material.Light + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("lightPhysical",dDensity, dFriction, dRestitution); + Attributes[(int)MaterialAttributes.Material.Avatar + (int)MaterialAttributes.Material.NumberOfTypes] = + new MaterialAttributes("avatarPhysical",60f, 0.2f, 0f); + } + + // Under the [BulletSim] section, one can change the individual material + // attribute values. The format of the configuration parameter is: + // ["Physical"] = floatValue + // For instance: + // [BulletSim] + // StoneFriction = 0.2 + // FleshRestitutionPhysical = 0.8 + // Materials can have different parameters for their static and + // physical instantiations. When setting the non-physical value, + // both values are changed. Setting the physical value only changes + // the physical value. + public static void InitializefromParameters(IConfig pConfig) + { + foreach (KeyValuePair kvp in MaterialMap) + { + string matName = kvp.Key; + foreach (string attribName in MaterialAttributes.MaterialAttribs) + { + string paramName = matName + attribName; + if (pConfig.Contains(paramName)) + { + float paramValue = pConfig.GetFloat(paramName); + SetAttributeValue((int)kvp.Value, attribName, paramValue); + // set the physical value also + SetAttributeValue((int)kvp.Value + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue); + } + paramName += "Physical"; + if (pConfig.Contains(paramName)) + { + float paramValue = pConfig.GetFloat(paramName); + SetAttributeValue((int)kvp.Value + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue); + } + } + } + } + + // Use reflection to set the value in the attribute structure. + private static void SetAttributeValue(int matType, string attribName, float val) + { + MaterialAttributes thisAttrib = Attributes[matType]; + FieldInfo fieldInfo = thisAttrib.GetType().GetField(attribName.ToLower()); + if (fieldInfo != null) + { + fieldInfo.SetValue(thisAttrib, val); + Attributes[matType] = thisAttrib; + } + } + + // Given a material type, return a structure of attributes. + public static MaterialAttributes GetAttributes(MaterialAttributes.Material type, bool isPhysical) + { + int ind = (int)type; + if (isPhysical) ind += (int)MaterialAttributes.Material.NumberOfTypes; + return Attributes[ind]; + } +} +} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSMotors.cs new file mode 100644 index 0000000..7abc9b2 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSMotors.cs @@ -0,0 +1,347 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +using System; +using System.Collections.Generic; +using System.Text; +using OpenMetaverse; +using OpenSim.Framework; + +namespace OpenSim.Region.Physics.BulletSNPlugin +{ +public abstract class BSMotor +{ + // Timescales and other things can be turned off by setting them to 'infinite'. + public const float Infinite = 12345.6f; + public readonly static Vector3 InfiniteVector = new Vector3(BSMotor.Infinite, BSMotor.Infinite, BSMotor.Infinite); + + public BSMotor(string useName) + { + UseName = useName; + PhysicsScene = null; + Enabled = true; + } + public virtual bool Enabled { get; set; } + public virtual void Reset() { } + public virtual void Zero() { } + public virtual void GenerateTestOutput(float timeStep) { } + + // A name passed at motor creation for easily identifyable debugging messages. + public string UseName { get; private set; } + + // Used only for outputting debug information. Might not be set so check for null. + public BSScene PhysicsScene { get; set; } + protected void MDetailLog(string msg, params Object[] parms) + { + if (PhysicsScene != null) + { + if (PhysicsScene.VehicleLoggingEnabled) + { + PhysicsScene.DetailLog(msg, parms); + } + } + } +} + +// Motor which moves CurrentValue to TargetValue over TimeScale seconds. +// The TargetValue decays in TargetValueDecayTimeScale and +// the CurrentValue will be held back by FrictionTimeScale. +// This motor will "zero itself" over time in that the targetValue will +// decay to zero and the currentValue will follow it to that zero. +// The overall effect is for the returned correction value to go from large +// values (the total difference between current and target minus friction) +// to small and eventually zero values. +// TimeScale and TargetDelayTimeScale may be 'infinite' which means no decay. + +// For instance, if something is moving at speed X and the desired speed is Y, +// CurrentValue is X and TargetValue is Y. As the motor is stepped, new +// values of CurrentValue are returned that approach the TargetValue. +// The feature of decaying TargetValue is so vehicles will eventually +// come to a stop rather than run forever. This can be disabled by +// setting TargetValueDecayTimescale to 'infinite'. +// The change from CurrentValue to TargetValue is linear over TimeScale seconds. +public class BSVMotor : BSMotor +{ + // public Vector3 FrameOfReference { get; set; } + // public Vector3 Offset { get; set; } + + public virtual float TimeScale { get; set; } + public virtual float TargetValueDecayTimeScale { get; set; } + public virtual Vector3 FrictionTimescale { get; set; } + public virtual float Efficiency { get; set; } + + public virtual float ErrorZeroThreshold { get; set; } + + public virtual Vector3 TargetValue { get; protected set; } + public virtual Vector3 CurrentValue { get; protected set; } + public virtual Vector3 LastError { get; protected set; } + + public virtual bool ErrorIsZero + { get { + return (LastError == Vector3.Zero || LastError.LengthSquared() <= ErrorZeroThreshold); + } + } + + public BSVMotor(string useName) + : base(useName) + { + TimeScale = TargetValueDecayTimeScale = BSMotor.Infinite; + Efficiency = 1f; + FrictionTimescale = BSMotor.InfiniteVector; + CurrentValue = TargetValue = Vector3.Zero; + ErrorZeroThreshold = 0.001f; + } + public BSVMotor(string useName, float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency) + : this(useName) + { + TimeScale = timeScale; + TargetValueDecayTimeScale = decayTimeScale; + FrictionTimescale = frictionTimeScale; + Efficiency = efficiency; + CurrentValue = TargetValue = Vector3.Zero; + } + public void SetCurrent(Vector3 current) + { + CurrentValue = current; + } + public void SetTarget(Vector3 target) + { + TargetValue = target; + } + public override void Zero() + { + base.Zero(); + CurrentValue = TargetValue = Vector3.Zero; + } + + // Compute the next step and return the new current value + public virtual Vector3 Step(float timeStep) + { + if (!Enabled) return TargetValue; + + Vector3 origTarget = TargetValue; // DEBUG + Vector3 origCurrVal = CurrentValue; // DEBUG + + Vector3 correction = Vector3.Zero; + Vector3 error = TargetValue - CurrentValue; + if (!error.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)) + { + correction = Step(timeStep, error); + + CurrentValue += correction; + + // The desired value reduces to zero which also reduces the difference with current. + // If the decay time is infinite, don't decay at all. + float decayFactor = 0f; + if (TargetValueDecayTimeScale != BSMotor.Infinite) + { + decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep; + TargetValue *= (1f - decayFactor); + } + + // The amount we can correct the error is reduced by the friction + Vector3 frictionFactor = Vector3.Zero; + if (FrictionTimescale != BSMotor.InfiniteVector) + { + // frictionFactor = (Vector3.One / FrictionTimescale) * timeStep; + // Individual friction components can be 'infinite' so compute each separately. + frictionFactor.X = (FrictionTimescale.X == BSMotor.Infinite) ? 0f : (1f / FrictionTimescale.X); + frictionFactor.Y = (FrictionTimescale.Y == BSMotor.Infinite) ? 0f : (1f / FrictionTimescale.Y); + frictionFactor.Z = (FrictionTimescale.Z == BSMotor.Infinite) ? 0f : (1f / FrictionTimescale.Z); + frictionFactor *= timeStep; + CurrentValue *= (Vector3.One - frictionFactor); + } + + MDetailLog("{0}, BSVMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},err={5},corr={6}", + BSScene.DetailLogZero, UseName, origCurrVal, origTarget, + timeStep, error, correction); + MDetailLog("{0}, BSVMotor.Step,nonZero,{1},tgtDecayTS={2},decayFact={3},frictTS={4},frictFact={5},tgt={6},curr={7}", + BSScene.DetailLogZero, UseName, + TargetValueDecayTimeScale, decayFactor, FrictionTimescale, frictionFactor, + TargetValue, CurrentValue); + } + else + { + // Difference between what we have and target is small. Motor is done. + CurrentValue = TargetValue; + MDetailLog("{0}, BSVMotor.Step,zero,{1},origTgt={2},origCurr={3},ret={4}", + BSScene.DetailLogZero, UseName, origCurrVal, origTarget, CurrentValue); + } + + return CurrentValue; + } + public virtual Vector3 Step(float timeStep, Vector3 error) + { + if (!Enabled) return Vector3.Zero; + + LastError = error; + Vector3 returnCorrection = Vector3.Zero; + if (!error.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)) + { + // correction = error / secondsItShouldTakeToCorrect + Vector3 correctionAmount; + if (TimeScale == 0f || TimeScale == BSMotor.Infinite) + correctionAmount = error * timeStep; + else + correctionAmount = error / TimeScale * timeStep; + + returnCorrection = correctionAmount; + MDetailLog("{0}, BSVMotor.Step,nonZero,{1},timeStep={2},timeScale={3},err={4},corr={5}", + BSScene.DetailLogZero, UseName, timeStep, TimeScale, error, correctionAmount); + } + return returnCorrection; + } + + // The user sets all the parameters and calls this which outputs values until error is zero. + public override void GenerateTestOutput(float timeStep) + { + // maximum number of outputs to generate. + int maxOutput = 50; + MDetailLog("{0},BSVMotor.Test,{1},===================================== BEGIN Test Output", BSScene.DetailLogZero, UseName); + MDetailLog("{0},BSVMotor.Test,{1},timeScale={2},targDlyTS={3},frictTS={4},eff={5},curr={6},tgt={7}", + BSScene.DetailLogZero, UseName, + TimeScale, TargetValueDecayTimeScale, FrictionTimescale, Efficiency, + CurrentValue, TargetValue); + + LastError = BSMotor.InfiniteVector; + while (maxOutput-- > 0 && !LastError.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)) + { + Vector3 lastStep = Step(timeStep); + MDetailLog("{0},BSVMotor.Test,{1},cur={2},tgt={3},lastError={4},lastStep={5}", + BSScene.DetailLogZero, UseName, CurrentValue, TargetValue, LastError, lastStep); + } + MDetailLog("{0},BSVMotor.Test,{1},===================================== END Test Output", BSScene.DetailLogZero, UseName); + + + } + + public override string ToString() + { + return String.Format("<{0},curr={1},targ={2},decayTS={3},frictTS={4}>", + UseName, CurrentValue, TargetValue, TargetValueDecayTimeScale, FrictionTimescale); + } +} + +public class BSFMotor : BSMotor +{ + public float TimeScale { get; set; } + public float DecayTimeScale { get; set; } + public float Friction { get; set; } + public float Efficiency { get; set; } + + public float Target { get; private set; } + public float CurrentValue { get; private set; } + + public BSFMotor(string useName, float timeScale, float decayTimescale, float friction, float efficiency) + : base(useName) + { + } + public void SetCurrent(float target) + { + } + public void SetTarget(float target) + { + } + public virtual float Step(float timeStep) + { + return 0f; + } +} + +// Proportional, Integral, Derivitive Motor +// Good description at http://www.answers.com/topic/pid-controller . Includes processes for choosing p, i and d factors. +public class BSPIDVMotor : BSVMotor +{ + // Larger makes more overshoot, smaller means converge quicker. Range of 0.1 to 10. + public Vector3 proportionFactor { get; set; } + public Vector3 integralFactor { get; set; } + public Vector3 derivFactor { get; set; } + + // Arbritrary factor range. + // EfficiencyHigh means move quickly to the correct number. EfficiencyLow means might over correct. + public float EfficiencyHigh = 0.4f; + public float EfficiencyLow = 4.0f; + + // Running integration of the error + Vector3 RunningIntegration { get; set; } + + public BSPIDVMotor(string useName) + : base(useName) + { + proportionFactor = new Vector3(1.00f, 1.00f, 1.00f); + integralFactor = new Vector3(1.00f, 1.00f, 1.00f); + derivFactor = new Vector3(1.00f, 1.00f, 1.00f); + RunningIntegration = Vector3.Zero; + LastError = Vector3.Zero; + } + + public override void Zero() + { + base.Zero(); + } + + public override float Efficiency + { + get { return base.Efficiency; } + set + { + base.Efficiency = Util.Clamp(value, 0f, 1f); + // Compute factors based on efficiency. + // If efficiency is high (1f), use a factor value that moves the error value to zero with little overshoot. + // If efficiency is low (0f), use a factor value that overcorrects. + // TODO: might want to vary contribution of different factor depending on efficiency. + float factor = ((1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow) / 3f; + // float factor = (1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow; + proportionFactor = new Vector3(factor, factor, factor); + integralFactor = new Vector3(factor, factor, factor); + derivFactor = new Vector3(factor, factor, factor); + } + } + + // Ignore Current and Target Values and just advance the PID computation on this error. + public override Vector3 Step(float timeStep, Vector3 error) + { + if (!Enabled) return Vector3.Zero; + + // Add up the error so we can integrate over the accumulated errors + RunningIntegration += error * timeStep; + + // A simple derivitive is the rate of change from the last error. + Vector3 derivFactor = (error - LastError) * timeStep; + LastError = error; + + // Correction = -(proportionOfPresentError + accumulationOfPastError + rateOfChangeOfError) + Vector3 ret = -( + error * proportionFactor + + RunningIntegration * integralFactor + + derivFactor * derivFactor + ); + + return ret; + } +} +} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs new file mode 100644 index 0000000..0bb1674 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs @@ -0,0 +1,559 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; + +using OpenSim.Region.Physics.Manager; + +using OpenMetaverse; +using Nini.Config; + +namespace OpenSim.Region.Physics.BulletSNPlugin +{ +public static class BSParam +{ + // Level of Detail values kept as float because that's what the Meshmerizer wants + public static float MeshLOD { get; private set; } + public static float MeshMegaPrimLOD { get; private set; } + public static float MeshMegaPrimThreshold { get; private set; } + public static float SculptLOD { get; private set; } + + public static float MinimumObjectMass { get; private set; } + public static float MaximumObjectMass { get; private set; } + + public static float LinearDamping { get; private set; } + public static float AngularDamping { get; private set; } + public static float DeactivationTime { get; private set; } + public static float LinearSleepingThreshold { get; private set; } + public static float AngularSleepingThreshold { get; private set; } + public static float CcdMotionThreshold { get; private set; } + public static float CcdSweptSphereRadius { get; private set; } + public static float ContactProcessingThreshold { get; private set; } + + public static bool ShouldMeshSculptedPrim { get; private set; } // cause scuplted prims to get meshed + public static bool ShouldForceSimplePrimMeshing { get; private set; } // if a cube or sphere, let Bullet do internal shapes + public static bool ShouldUseHullsForPhysicalObjects { get; private set; } // 'true' if should create hulls for physical objects + + public static float TerrainImplementation { get; private set; } + public static float TerrainFriction { get; private set; } + public static float TerrainHitFraction { get; private set; } + public static float TerrainRestitution { get; private set; } + public static float TerrainCollisionMargin { get; private set; } + + // Avatar parameters + public static float AvatarFriction { get; private set; } + public static float AvatarStandingFriction { get; private set; } + public static float AvatarDensity { get; private set; } + public static float AvatarRestitution { get; private set; } + public static float AvatarCapsuleWidth { get; private set; } + public static float AvatarCapsuleDepth { get; private set; } + public static float AvatarCapsuleHeight { get; private set; } + public static float AvatarContactProcessingThreshold { get; private set; } + + public static float VehicleAngularDamping { get; private set; } + + public static float LinksetImplementation { get; private set; } + public static float LinkConstraintUseFrameOffset { get; private set; } + public static float LinkConstraintEnableTransMotor { get; private set; } + public static float LinkConstraintTransMotorMaxVel { get; private set; } + public static float LinkConstraintTransMotorMaxForce { get; private set; } + public static float LinkConstraintERP { get; private set; } + public static float LinkConstraintCFM { get; private set; } + public static float LinkConstraintSolverIterations { get; private set; } + + public static float PID_D { get; private set; } // derivative + public static float PID_P { get; private set; } // proportional + + public delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val); + public delegate float ParamGet(BSScene scene); + public delegate void ParamSet(BSScene scene, string paramName, uint localID, float val); + public delegate void SetOnObject(BSScene scene, BSPhysObject obj, float val); + + public struct ParameterDefn + { + public string name; // string name of the parameter + public string desc; // a short description of what the parameter means + public float defaultValue; // default value if not specified anywhere else + public ParamUser userParam; // get the value from the configuration file + public ParamGet getter; // return the current value stored for this parameter + public ParamSet setter; // set the current value for this parameter + public SetOnObject onObject; // set the value on an object in the physical domain + public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s) + { + name = n; + desc = d; + defaultValue = v; + userParam = u; + getter = g; + setter = s; + onObject = null; + } + public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s, SetOnObject o) + { + name = n; + desc = d; + defaultValue = v; + userParam = u; + getter = g; + setter = s; + onObject = o; + } + } + + // List of all of the externally visible parameters. + // For each parameter, this table maps a text name to getter and setters. + // To add a new externally referencable/settable parameter, add the paramter storage + // location somewhere in the program and make an entry in this table with the + // getters and setters. + // It is easiest to find an existing definition and copy it. + // Parameter values are floats. Booleans are converted to a floating value. + // + // A ParameterDefn() takes the following parameters: + // -- the text name of the parameter. This is used for console input and ini file. + // -- a short text description of the parameter. This shows up in the console listing. + // -- a default value (float) + // -- a delegate for fetching the parameter from the ini file. + // Should handle fetching the right type from the ini file and converting it. + // -- a delegate for getting the value as a float + // -- a delegate for setting the value from a float + // -- an optional delegate to update the value in the world. Most often used to + // push the new value to an in-world object. + // + // The single letter parameters for the delegates are: + // s = BSScene + // o = BSPhysObject + // p = string parameter name + // l = localID of referenced object + // v = value (float) + // cf = parameter configuration class (for fetching values from ini file) + private static ParameterDefn[] ParameterDefinitions = + { + new ParameterDefn("MeshSculptedPrim", "Whether to create meshes for sculpties", + ConfigurationParameters.numericTrue, + (s,cf,p,v) => { ShouldMeshSculptedPrim = cf.GetBoolean(p, BSParam.BoolNumeric(v)); }, + (s) => { return BSParam.NumericBool(ShouldMeshSculptedPrim); }, + (s,p,l,v) => { ShouldMeshSculptedPrim = BSParam.BoolNumeric(v); } ), + new ParameterDefn("ForceSimplePrimMeshing", "If true, only use primitive meshes for objects", + ConfigurationParameters.numericFalse, + (s,cf,p,v) => { ShouldForceSimplePrimMeshing = cf.GetBoolean(p, BSParam.BoolNumeric(v)); }, + (s) => { return BSParam.NumericBool(ShouldForceSimplePrimMeshing); }, + (s,p,l,v) => { ShouldForceSimplePrimMeshing = BSParam.BoolNumeric(v); } ), + new ParameterDefn("UseHullsForPhysicalObjects", "If true, create hulls for physical objects", + ConfigurationParameters.numericTrue, + (s,cf,p,v) => { ShouldUseHullsForPhysicalObjects = cf.GetBoolean(p, BSParam.BoolNumeric(v)); }, + (s) => { return BSParam.NumericBool(ShouldUseHullsForPhysicalObjects); }, + (s,p,l,v) => { ShouldUseHullsForPhysicalObjects = BSParam.BoolNumeric(v); } ), + + new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", + 8f, + (s,cf,p,v) => { MeshLOD = (float)cf.GetInt(p, (int)v); }, + (s) => { return MeshLOD; }, + (s,p,l,v) => { MeshLOD = v; } ), + new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters", + 16f, + (s,cf,p,v) => { MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); }, + (s) => { return MeshMegaPrimLOD; }, + (s,p,l,v) => { MeshMegaPrimLOD = v; } ), + new ParameterDefn("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD", + 10f, + (s,cf,p,v) => { MeshMegaPrimThreshold = (float)cf.GetInt(p, (int)v); }, + (s) => { return MeshMegaPrimThreshold; }, + (s,p,l,v) => { MeshMegaPrimThreshold = v; } ), + new ParameterDefn("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)", + 32f, + (s,cf,p,v) => { SculptLOD = (float)cf.GetInt(p, (int)v); }, + (s) => { return SculptLOD; }, + (s,p,l,v) => { SculptLOD = v; } ), + + new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps", + 10f, + (s,cf,p,v) => { s.m_maxSubSteps = cf.GetInt(p, (int)v); }, + (s) => { return (float)s.m_maxSubSteps; }, + (s,p,l,v) => { s.m_maxSubSteps = (int)v; } ), + new ParameterDefn("FixedTimeStep", "In simulation step, seconds of one substep (1/60)", + 1f / 60f, + (s,cf,p,v) => { s.m_fixedTimeStep = cf.GetFloat(p, v); }, + (s) => { return (float)s.m_fixedTimeStep; }, + (s,p,l,v) => { s.m_fixedTimeStep = v; } ), + new ParameterDefn("MaxCollisionsPerFrame", "Max collisions returned at end of each frame", + 2048f, + (s,cf,p,v) => { s.m_maxCollisionsPerFrame = cf.GetInt(p, (int)v); }, + (s) => { return (float)s.m_maxCollisionsPerFrame; }, + (s,p,l,v) => { s.m_maxCollisionsPerFrame = (int)v; } ), + new ParameterDefn("MaxUpdatesPerFrame", "Max updates returned at end of each frame", + 8000f, + (s,cf,p,v) => { s.m_maxUpdatesPerFrame = cf.GetInt(p, (int)v); }, + (s) => { return (float)s.m_maxUpdatesPerFrame; }, + (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ), + new ParameterDefn("MaxTaintsToProcessPerStep", "Number of update taints to process before each simulation step", + 500f, + (s,cf,p,v) => { s.m_taintsToProcessPerStep = cf.GetInt(p, (int)v); }, + (s) => { return (float)s.m_taintsToProcessPerStep; }, + (s,p,l,v) => { s.m_taintsToProcessPerStep = (int)v; } ), + new ParameterDefn("MinObjectMass", "Minimum object mass (0.0001)", + 0.0001f, + (s,cf,p,v) => { MinimumObjectMass = cf.GetFloat(p, v); }, + (s) => { return (float)MinimumObjectMass; }, + (s,p,l,v) => { MinimumObjectMass = v; } ), + new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)", + 10000.01f, + (s,cf,p,v) => { MaximumObjectMass = cf.GetFloat(p, v); }, + (s) => { return (float)MaximumObjectMass; }, + (s,p,l,v) => { MaximumObjectMass = v; } ), + + new ParameterDefn("PID_D", "Derivitive factor for motion smoothing", + 2200f, + (s,cf,p,v) => { PID_D = cf.GetFloat(p, v); }, + (s) => { return (float)PID_D; }, + (s,p,l,v) => { PID_D = v; } ), + new ParameterDefn("PID_P", "Parameteric factor for motion smoothing", + 900f, + (s,cf,p,v) => { PID_P = cf.GetFloat(p, v); }, + (s) => { return (float)PID_P; }, + (s,p,l,v) => { PID_P = v; } ), + + new ParameterDefn("DefaultFriction", "Friction factor used on new objects", + 0.2f, + (s,cf,p,v) => { s.UnmanagedParams[0].defaultFriction = cf.GetFloat(p, v); }, + (s) => { return s.UnmanagedParams[0].defaultFriction; }, + (s,p,l,v) => { s.UnmanagedParams[0].defaultFriction = v; } ), + new ParameterDefn("DefaultDensity", "Density for new objects" , + 10.000006836f, // Aluminum g/cm3 + (s,cf,p,v) => { s.UnmanagedParams[0].defaultDensity = cf.GetFloat(p, v); }, + (s) => { return s.UnmanagedParams[0].defaultDensity; }, + (s,p,l,v) => { s.UnmanagedParams[0].defaultDensity = v; } ), + new ParameterDefn("DefaultRestitution", "Bouncyness of an object" , + 0f, + (s,cf,p,v) => { s.UnmanagedParams[0].defaultRestitution = cf.GetFloat(p, v); }, + (s) => { return s.UnmanagedParams[0].defaultRestitution; }, + (s,p,l,v) => { s.UnmanagedParams[0].defaultRestitution = v; } ), + new ParameterDefn("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!)", + 0.04f, + (s,cf,p,v) => { s.UnmanagedParams[0].collisionMargin = cf.GetFloat(p, v); }, + (s) => { return s.UnmanagedParams[0].collisionMargin; }, + (s,p,l,v) => { s.UnmanagedParams[0].collisionMargin = v; } ), + new ParameterDefn("Gravity", "Vertical force of gravity (negative means down)", + -9.80665f, + (s,cf,p,v) => { s.UnmanagedParams[0].gravity = cf.GetFloat(p, v); }, + (s) => { return s.UnmanagedParams[0].gravity; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{s.UnmanagedParams[0].gravity=x;}, p, PhysParameterEntry.APPLY_TO_NONE, v); }, + (s,o,v) => { BulletSimAPI.SetGravity2(s.World.ptr, new Vector3(0f,0f,v)); } ), + + + new ParameterDefn("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)", + 0f, + (s,cf,p,v) => { LinearDamping = cf.GetFloat(p, v); }, + (s) => { return LinearDamping; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{LinearDamping=x;}, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, v, AngularDamping); } ), + new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)", + 0f, + (s,cf,p,v) => { AngularDamping = cf.GetFloat(p, v); }, + (s) => { return AngularDamping; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularDamping=x;}, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, LinearDamping, v); } ), + new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static", + 0.2f, + (s,cf,p,v) => { DeactivationTime = cf.GetFloat(p, v); }, + (s) => { return DeactivationTime; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{DeactivationTime=x;}, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetDeactivationTime2(o.PhysBody.ptr, v); } ), + new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static", + 0.8f, + (s,cf,p,v) => { LinearSleepingThreshold = cf.GetFloat(p, v); }, + (s) => { return LinearSleepingThreshold; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{LinearSleepingThreshold=x;}, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ), + new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static", + 1.0f, + (s,cf,p,v) => { AngularSleepingThreshold = cf.GetFloat(p, v); }, + (s) => { return AngularSleepingThreshold; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularSleepingThreshold=x;}, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ), + new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" , + 0f, // set to zero to disable + (s,cf,p,v) => { CcdMotionThreshold = cf.GetFloat(p, v); }, + (s) => { return CcdMotionThreshold; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdMotionThreshold=x;}, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetCcdMotionThreshold2(o.PhysBody.ptr, v); } ), + new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" , + 0f, + (s,cf,p,v) => { CcdSweptSphereRadius = cf.GetFloat(p, v); }, + (s) => { return CcdSweptSphereRadius; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdSweptSphereRadius=x;}, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetCcdSweptSphereRadius2(o.PhysBody.ptr, v); } ), + new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" , + 0.1f, + (s,cf,p,v) => { ContactProcessingThreshold = cf.GetFloat(p, v); }, + (s) => { return ContactProcessingThreshold; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{ContactProcessingThreshold=x;}, p, l, v); }, + (s,o,v) => { BulletSimAPI.SetContactProcessingThreshold2(o.PhysBody.ptr, v); } ), + + new ParameterDefn("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)", + (float)BSTerrainPhys.TerrainImplementation.Mesh, + (s,cf,p,v) => { TerrainImplementation = cf.GetFloat(p,v); }, + (s) => { return TerrainImplementation; }, + (s,p,l,v) => { TerrainImplementation = v; } ), + new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" , + 0.3f, + (s,cf,p,v) => { TerrainFriction = cf.GetFloat(p, v); }, + (s) => { return TerrainFriction; }, + (s,p,l,v) => { TerrainFriction = v; /* TODO: set on real terrain */} ), + new ParameterDefn("TerrainHitFraction", "Distance to measure hit collisions" , + 0.8f, + (s,cf,p,v) => { TerrainHitFraction = cf.GetFloat(p, v); }, + (s) => { return TerrainHitFraction; }, + (s,p,l,v) => { TerrainHitFraction = v; /* TODO: set on real terrain */ } ), + new ParameterDefn("TerrainRestitution", "Bouncyness" , + 0f, + (s,cf,p,v) => { TerrainRestitution = cf.GetFloat(p, v); }, + (s) => { return TerrainRestitution; }, + (s,p,l,v) => { TerrainRestitution = v; /* TODO: set on real terrain */ } ), + new ParameterDefn("TerrainCollisionMargin", "Margin where collision checking starts" , + 0.04f, + (s,cf,p,v) => { TerrainCollisionMargin = cf.GetFloat(p, v); }, + (s) => { return TerrainCollisionMargin; }, + (s,p,l,v) => { TerrainCollisionMargin = v; /* TODO: set on real terrain */ } ), + + new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.", + 0.2f, + (s,cf,p,v) => { AvatarFriction = cf.GetFloat(p, v); }, + (s) => { return AvatarFriction; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarFriction=x;}, p, l, v); } ), + new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", + 10.0f, + (s,cf,p,v) => { AvatarStandingFriction = cf.GetFloat(p, v); }, + (s) => { return AvatarStandingFriction; }, + (s,p,l,v) => { AvatarStandingFriction = v; } ), + new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.", + 60f, + (s,cf,p,v) => { AvatarDensity = cf.GetFloat(p, v); }, + (s) => { return AvatarDensity; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarDensity=x;}, p, l, v); } ), + new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.", + 0f, + (s,cf,p,v) => { AvatarRestitution = cf.GetFloat(p, v); }, + (s) => { return AvatarRestitution; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarRestitution=x;}, p, l, v); } ), + new ParameterDefn("AvatarCapsuleWidth", "The distance between the sides of the avatar capsule", + 0.6f, + (s,cf,p,v) => { AvatarCapsuleWidth = cf.GetFloat(p, v); }, + (s) => { return AvatarCapsuleWidth; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleWidth=x;}, p, l, v); } ), + new ParameterDefn("AvatarCapsuleDepth", "The distance between the front and back of the avatar capsule", + 0.45f, + (s,cf,p,v) => { AvatarCapsuleDepth = cf.GetFloat(p, v); }, + (s) => { return AvatarCapsuleDepth; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleDepth=x;}, p, l, v); } ), + new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar", + 1.5f, + (s,cf,p,v) => { AvatarCapsuleHeight = cf.GetFloat(p, v); }, + (s) => { return AvatarCapsuleHeight; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleHeight=x;}, p, l, v); } ), + new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", + 0.1f, + (s,cf,p,v) => { AvatarContactProcessingThreshold = cf.GetFloat(p, v); }, + (s) => { return AvatarContactProcessingThreshold; }, + (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarContactProcessingThreshold=x;}, p, l, v); } ), + + new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", + 0.95f, + (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); }, + (s) => { return VehicleAngularDamping; }, + (s,p,l,v) => { VehicleAngularDamping = v; } ), + + new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", + 0f, + (s,cf,p,v) => { s.UnmanagedParams[0].maxPersistantManifoldPoolSize = cf.GetFloat(p, v); }, + (s) => { return s.UnmanagedParams[0].maxPersistantManifoldPoolSize; }, + (s,p,l,v) => { s.UnmanagedParams[0].maxPersistantManifoldPoolSize = v; } ), + new ParameterDefn("MaxCollisionAlgorithmPoolSize", "Number of collisions pooled (0 means default of 4096)", + 0f, + (s,cf,p,v) => { s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = cf.GetFloat(p, v); }, + (s) => { return s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize; }, + (s,p,l,v) => { s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = v; } ), + new ParameterDefn("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count", + ConfigurationParameters.numericFalse, + (s,cf,p,v) => { s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation; }, + (s,p,l,v) => { s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = v; } ), + new ParameterDefn("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step", + ConfigurationParameters.numericFalse, + (s,cf,p,v) => { s.UnmanagedParams[0].shouldForceUpdateAllAabbs = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return s.UnmanagedParams[0].shouldForceUpdateAllAabbs; }, + (s,p,l,v) => { s.UnmanagedParams[0].shouldForceUpdateAllAabbs = v; } ), + new ParameterDefn("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction", + ConfigurationParameters.numericTrue, + (s,cf,p,v) => { s.UnmanagedParams[0].shouldRandomizeSolverOrder = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return s.UnmanagedParams[0].shouldRandomizeSolverOrder; }, + (s,p,l,v) => { s.UnmanagedParams[0].shouldRandomizeSolverOrder = v; } ), + new ParameterDefn("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands", + ConfigurationParameters.numericTrue, + (s,cf,p,v) => { s.UnmanagedParams[0].shouldSplitSimulationIslands = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return s.UnmanagedParams[0].shouldSplitSimulationIslands; }, + (s,p,l,v) => { s.UnmanagedParams[0].shouldSplitSimulationIslands = v; } ), + new ParameterDefn("ShouldEnableFrictionCaching", "Enable friction computation caching", + ConfigurationParameters.numericFalse, + (s,cf,p,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return s.UnmanagedParams[0].shouldEnableFrictionCaching; }, + (s,p,l,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = v; } ), + new ParameterDefn("NumberOfSolverIterations", "Number of internal iterations (0 means default)", + 0f, // zero says use Bullet default + (s,cf,p,v) => { s.UnmanagedParams[0].numberOfSolverIterations = cf.GetFloat(p, v); }, + (s) => { return s.UnmanagedParams[0].numberOfSolverIterations; }, + (s,p,l,v) => { s.UnmanagedParams[0].numberOfSolverIterations = v; } ), + + new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", + (float)BSLinkset.LinksetImplementation.Compound, + (s,cf,p,v) => { LinksetImplementation = cf.GetFloat(p,v); }, + (s) => { return LinksetImplementation; }, + (s,p,l,v) => { LinksetImplementation = v; } ), + new ParameterDefn("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.", + ConfigurationParameters.numericFalse, + (s,cf,p,v) => { LinkConstraintUseFrameOffset = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return LinkConstraintUseFrameOffset; }, + (s,p,l,v) => { LinkConstraintUseFrameOffset = v; } ), + new ParameterDefn("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints", + ConfigurationParameters.numericTrue, + (s,cf,p,v) => { LinkConstraintEnableTransMotor = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return LinkConstraintEnableTransMotor; }, + (s,p,l,v) => { LinkConstraintEnableTransMotor = v; } ), + new ParameterDefn("LinkConstraintTransMotorMaxVel", "Maximum velocity to be applied by translational motor in linkset constraints", + 5.0f, + (s,cf,p,v) => { LinkConstraintTransMotorMaxVel = cf.GetFloat(p, v); }, + (s) => { return LinkConstraintTransMotorMaxVel; }, + (s,p,l,v) => { LinkConstraintTransMotorMaxVel = v; } ), + new ParameterDefn("LinkConstraintTransMotorMaxForce", "Maximum force to be applied by translational motor in linkset constraints", + 0.1f, + (s,cf,p,v) => { LinkConstraintTransMotorMaxForce = cf.GetFloat(p, v); }, + (s) => { return LinkConstraintTransMotorMaxForce; }, + (s,p,l,v) => { LinkConstraintTransMotorMaxForce = v; } ), + new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1", + 0.1f, + (s,cf,p,v) => { LinkConstraintCFM = cf.GetFloat(p, v); }, + (s) => { return LinkConstraintCFM; }, + (s,p,l,v) => { LinkConstraintCFM = v; } ), + new ParameterDefn("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2", + 0.1f, + (s,cf,p,v) => { LinkConstraintERP = cf.GetFloat(p, v); }, + (s) => { return LinkConstraintERP; }, + (s,p,l,v) => { LinkConstraintERP = v; } ), + new ParameterDefn("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)", + 40, + (s,cf,p,v) => { LinkConstraintSolverIterations = cf.GetFloat(p, v); }, + (s) => { return LinkConstraintSolverIterations; }, + (s,p,l,v) => { LinkConstraintSolverIterations = v; } ), + + new ParameterDefn("LogPhysicsStatisticsFrames", "Frames between outputting detailed phys stats. (0 is off)", + 0f, + (s,cf,p,v) => { s.UnmanagedParams[0].physicsLoggingFrames = cf.GetInt(p, (int)v); }, + (s) => { return (float)s.UnmanagedParams[0].physicsLoggingFrames; }, + (s,p,l,v) => { s.UnmanagedParams[0].physicsLoggingFrames = (int)v; } ), + }; + + // Convert a boolean to our numeric true and false values + public static float NumericBool(bool b) + { + return (b ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse); + } + + // Convert numeric true and false values to a boolean + public static bool BoolNumeric(float b) + { + return (b == ConfigurationParameters.numericTrue ? true : false); + } + + // Search through the parameter definitions and return the matching + // ParameterDefn structure. + // Case does not matter as names are compared after converting to lower case. + // Returns 'false' if the parameter is not found. + internal static bool TryGetParameter(string paramName, out ParameterDefn defn) + { + bool ret = false; + ParameterDefn foundDefn = new ParameterDefn(); + string pName = paramName.ToLower(); + + foreach (ParameterDefn parm in ParameterDefinitions) + { + if (pName == parm.name.ToLower()) + { + foundDefn = parm; + ret = true; + break; + } + } + defn = foundDefn; + return ret; + } + + // Pass through the settable parameters and set the default values + internal static void SetParameterDefaultValues(BSScene physicsScene) + { + foreach (ParameterDefn parm in ParameterDefinitions) + { + parm.setter(physicsScene, parm.name, PhysParameterEntry.APPLY_TO_NONE, parm.defaultValue); + } + } + + // Get user set values out of the ini file. + internal static void SetParameterConfigurationValues(BSScene physicsScene, IConfig cfg) + { + foreach (ParameterDefn parm in ParameterDefinitions) + { + parm.userParam(physicsScene, cfg, parm.name, parm.defaultValue); + } + } + + internal static PhysParameterEntry[] SettableParameters = new PhysParameterEntry[1]; + + // This creates an array in the correct format for returning the list of + // parameters. This is used by the 'list' option of the 'physics' command. + internal static void BuildParameterTable() + { + if (SettableParameters.Length < ParameterDefinitions.Length) + { + List entries = new List(); + for (int ii = 0; ii < ParameterDefinitions.Length; ii++) + { + ParameterDefn pd = ParameterDefinitions[ii]; + entries.Add(new PhysParameterEntry(pd.name, pd.desc)); + } + + // make the list in alphabetical order for estetic reasons + entries.Sort(delegate(PhysParameterEntry ppe1, PhysParameterEntry ppe2) + { + return ppe1.name.CompareTo(ppe2.name); + }); + + SettableParameters = entries.ToArray(); + } + } + + +} +} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSPhysObject.cs new file mode 100644 index 0000000..4096ef8 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSPhysObject.cs @@ -0,0 +1,345 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; + +using OMV = OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Physics.Manager; + +namespace OpenSim.Region.Physics.BulletSNPlugin +{ +/* + * Class to wrap all objects. + * The rest of BulletSim doesn't need to keep checking for avatars or prims + * unless the difference is significant. + * + * Variables in the physicsl objects are in three forms: + * VariableName: used by the simulator and performs taint operations, etc + * RawVariableName: direct reference to the BulletSim storage for the variable value + * ForceVariableName: direct reference (store and fetch) to the value in the physics engine. + * The last two (and certainly the last one) should be referenced only in taint-time. + */ + +/* + * As of 20121221, the following are the call sequences (going down) for different script physical functions: + * llApplyImpulse llApplyRotImpulse llSetTorque llSetForce + * SOP.ApplyImpulse SOP.ApplyAngularImpulse SOP.SetAngularImpulse SOP.SetForce + * SOG.ApplyImpulse SOG.ApplyAngularImpulse SOG.SetAngularImpulse + * PA.AddForce PA.AddAngularForce PA.Torque = v PA.Force = v + * BS.ApplyCentralForce BS.ApplyTorque + */ + +public abstract class BSPhysObject : PhysicsActor +{ + protected BSPhysObject() + { + } + protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName) + { + PhysicsScene = parentScene; + LocalID = localID; + PhysObjectName = name; + TypeName = typeName; + + Linkset = BSLinkset.Factory(PhysicsScene, this); + LastAssetBuildFailed = false; + + // Default material type + Material = MaterialAttributes.Material.Wood; + + CollisionCollection = new CollisionEventUpdate(); + SubscribedEventsMs = 0; + CollidingStep = 0; + CollidingGroundStep = 0; + } + + // Tell the object to clean up. + public virtual void Destroy() + { + UnRegisterAllPreStepActions(); + } + + public BSScene PhysicsScene { get; protected set; } + // public override uint LocalID { get; set; } // Use the LocalID definition in PhysicsActor + public string PhysObjectName { get; protected set; } + public string TypeName { get; protected set; } + + public BSLinkset Linkset { get; set; } + public BSLinksetInfo LinksetInfo { get; set; } + + // Return the object mass without calculating it or having side effects + public abstract float RawMass { get; } + // Set the raw mass but also update physical mass properties (inertia, ...) + public abstract void UpdatePhysicalMassProperties(float mass); + + // The last value calculated for the prim's inertia + public OMV.Vector3 Inertia { get; set; } + + // Reference to the physical body (btCollisionObject) of this object + public BulletBody PhysBody; + // Reference to the physical shape (btCollisionShape) of this object + public BulletShape PhysShape; + + // 'true' if the mesh's underlying asset failed to build. + // This will keep us from looping after the first time the build failed. + public bool LastAssetBuildFailed { get; set; } + + // The objects base shape information. Null if not a prim type shape. + public PrimitiveBaseShape BaseShape { get; protected set; } + // Some types of objects have preferred physical representations. + // Returns SHAPE_UNKNOWN if there is no preference. + public virtual BSPhysicsShapeType PreferredPhysicalShape + { + get { return BSPhysicsShapeType.SHAPE_UNKNOWN; } + } + + // When the physical properties are updated, an EntityProperty holds the update values. + // Keep the current and last EntityProperties to enable computation of differences + // between the current update and the previous values. + public EntityProperties CurrentEntityProperties { get; set; } + public EntityProperties LastEntityProperties { get; set; } + + public virtual OMV.Vector3 Scale { get; set; } + public abstract bool IsSolid { get; } + public abstract bool IsStatic { get; } + + // Materialness + public MaterialAttributes.Material Material { get; private set; } + public override void SetMaterial(int material) + { + Material = (MaterialAttributes.Material)material; + } + + // Stop all physical motion. + public abstract void ZeroMotion(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. + public abstract void UpdateProperties(EntityProperties entprop); + + public abstract OMV.Vector3 RawPosition { get; set; } + public abstract OMV.Vector3 ForcePosition { get; set; } + + public abstract OMV.Quaternion RawOrientation { get; set; } + public abstract OMV.Quaternion ForceOrientation { get; set; } + + // The system is telling us the velocity it wants to move at. + // protected OMV.Vector3 m_targetVelocity; // use the definition in PhysicsActor + public override OMV.Vector3 TargetVelocity + { + get { return m_targetVelocity; } + set + { + m_targetVelocity = value; + Velocity = value; + } + } + public abstract OMV.Vector3 ForceVelocity { get; set; } + + public abstract OMV.Vector3 ForceRotationalVelocity { get; set; } + + public abstract float ForceBuoyancy { get; set; } + + public virtual bool ForceBodyShapeRebuild(bool inTaintTime) { return false; } + + #region Collisions + + // Requested number of milliseconds between collision events. Zero means disabled. + protected int SubscribedEventsMs { get; set; } + // Given subscription, the time that a collision may be passed up + protected int NextCollisionOkTime { get; set; } + // The simulation step that last had a collision + protected long CollidingStep { get; set; } + // The simulation step that last had a collision with the ground + protected long CollidingGroundStep { get; set; } + // The collision flags we think are set in Bullet + protected CollisionFlags CurrentCollisionFlags { get; set; } + + // The collisions that have been collected this tick + protected CollisionEventUpdate CollisionCollection; + + // The simulation step is telling this object about a collision. + // Return 'true' if a collision was processed and should be sent up. + // Called at taint time from within the Step() function + public virtual bool Collide(uint collidingWith, BSPhysObject collidee, + OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) + { + bool ret = false; + + // The following lines make IsColliding() and IsCollidingGround() work + CollidingStep = PhysicsScene.SimulationStep; + if (collidingWith <= PhysicsScene.TerrainManager.HighestTerrainID) + { + CollidingGroundStep = PhysicsScene.SimulationStep; + } + + // prims in the same linkset cannot collide with each other + if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID)) + { + return ret; + } + + // if someone has subscribed for collision events.... + if (SubscribedEvents()) { + CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); + DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5}", + LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth); + + ret = true; + } + return ret; + } + + // Send the collected collisions into the simulator. + // Called at taint time from within the Step() function thus no locking problems + // with CollisionCollection and ObjectsWithNoMoreCollisions. + // Return 'true' if there were some actual collisions passed up + public virtual bool SendCollisions() + { + bool ret = true; + // If the 'no collision' call, force it to happen right now so quick collision_end + bool force = (CollisionCollection.Count == 0); + + // throttle the collisions to the number of milliseconds specified in the subscription + if (force || (PhysicsScene.SimulationNowTime >= NextCollisionOkTime)) + { + NextCollisionOkTime = PhysicsScene.SimulationNowTime + SubscribedEventsMs; + + // We are called if we previously had collisions. If there are no collisions + // this time, send up one last empty event so OpenSim can sense collision end. + if (CollisionCollection.Count == 0) + { + // If I have no collisions this time, remove me from the list of objects with collisions. + ret = false; + } + + // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count); + base.SendCollisionUpdate(CollisionCollection); + + // The CollisionCollection instance is passed around in the simulator. + // Make sure we don't have a handle to that one and that a new one is used for next time. + // This fixes an interesting 'gotcha'. If we call CollisionCollection.Clear() here, + // a race condition is created for the other users of this instance. + CollisionCollection = new CollisionEventUpdate(); + } + return ret; + } + + // Subscribe for collision events. + // Parameter is the millisecond rate the caller wishes collision events to occur. + public override void SubscribeEvents(int ms) { + // DetailLog("{0},{1}.SubscribeEvents,subscribing,ms={2}", LocalID, TypeName, ms); + SubscribedEventsMs = ms; + if (ms > 0) + { + // make sure first collision happens + NextCollisionOkTime = Util.EnvironmentTickCountSubtract(SubscribedEventsMs); + + PhysicsScene.TaintedObject(TypeName+".SubscribeEvents", delegate() + { + if (PhysBody.HasPhysicalBody) + CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + }); + } + else + { + // Subscribing for zero or less is the same as unsubscribing + UnSubscribeEvents(); + } + } + public override void UnSubscribeEvents() { + // DetailLog("{0},{1}.UnSubscribeEvents,unsubscribing", LocalID, TypeName); + SubscribedEventsMs = 0; + PhysicsScene.TaintedObject(TypeName+".UnSubscribeEvents", delegate() + { + // Make sure there is a body there because sometimes destruction happens in an un-ideal order. + if (PhysBody.HasPhysicalBody) + CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + }); + } + // Return 'true' if the simulator wants collision events + public override bool SubscribedEvents() { + return (SubscribedEventsMs > 0); + } + + #endregion // Collisions + + #region Per Simulation Step actions + // There are some actions that must be performed for a physical object before each simulation step. + // These actions are optional so, rather than scanning all the physical objects and asking them + // if they have anything to do, a physical object registers for an event call before the step is performed. + // This bookkeeping makes it easy to add, remove and clean up after all these registrations. + private Dictionary RegisteredActions = new Dictionary(); + protected void RegisterPreStepAction(string op, uint id, BSScene.PreStepAction actn) + { + string identifier = op + "-" + id.ToString(); + RegisteredActions[identifier] = actn; + PhysicsScene.BeforeStep += actn; + DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier); + } + + // Unregister a pre step action. Safe to call if the action has not been registered. + protected void UnRegisterPreStepAction(string op, uint id) + { + string identifier = op + "-" + id.ToString(); + bool removed = false; + if (RegisteredActions.ContainsKey(identifier)) + { + PhysicsScene.BeforeStep -= RegisteredActions[identifier]; + RegisteredActions.Remove(identifier); + removed = true; + } + DetailLog("{0},BSPhysObject.UnRegisterPreStepAction,id={1},removed={2}", LocalID, identifier, removed); + } + + protected void UnRegisterAllPreStepActions() + { + foreach (KeyValuePair kvp in RegisteredActions) + { + PhysicsScene.BeforeStep -= kvp.Value; + } + RegisteredActions.Clear(); + DetailLog("{0},BSPhysObject.UnRegisterAllPreStepActions,", LocalID); + } + + + #endregion // Per Simulation Step actions + + // High performance detailed logging routine used by the physical objects. + protected void DetailLog(string msg, params Object[] args) + { + if (PhysicsScene.PhysicsLogging.Enabled) + PhysicsScene.DetailLog(msg, args); + } + +} +} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSPlugin.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSPlugin.cs new file mode 100644 index 0000000..75963ee --- /dev/null +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSPlugin.cs @@ -0,0 +1,81 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using OpenSim.Framework; +using OpenSim.Region.Physics.Manager; +using OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSNPlugin +{ + /// + /// Entry for a port of Bullet (http://bulletphysics.org/) to OpenSim. + /// This module interfaces to an unmanaged C++ library which makes the + /// actual calls into the Bullet physics engine. + /// The unmanaged library is found in opensim-libs::trunk/unmanaged/BulletSim/. + /// The unmanaged library is compiled and linked statically with Bullet + /// to create BulletSim.dll and libBulletSim.so (for both 32 and 64 bit). + /// +public class BSPlugin : IPhysicsPlugin +{ + //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private BSScene _mScene; + + public BSPlugin() + { + } + + public bool Init() + { + return true; + } + + public PhysicsScene GetScene(String sceneIdentifier) + { + if (_mScene == null) + { + + // If not Windows, loading is performed by the + // Mono loader as specified in + // "bin/Physics/OpenSim.Region.Physics.BulletSNPlugin.dll.config". + + _mScene = new BSScene(sceneIdentifier); + } + return (_mScene); + } + + public string GetName() + { + return ("BulletSimN"); + } + + public void Dispose() + { + } +} +} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs new file mode 100644 index 0000000..a889c24 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs @@ -0,0 +1,1467 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Reflection; +using System.Collections.Generic; +using System.Xml; +using log4net; +using OMV = OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Physics.Manager; +using OpenSim.Region.Physics.ConvexDecompositionDotNet; + +namespace OpenSim.Region.Physics.BulletSNPlugin +{ + + [Serializable] +public sealed class BSPrim : BSPhysObject +{ + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly string LogHeader = "[BULLETS PRIM]"; + + // _size is what the user passed. Scale is what we pass to the physics engine with the mesh. + private OMV.Vector3 _size; // the multiplier for each mesh dimension as passed by the user + + private bool _grabbed; + private bool _isSelected; + private bool _isVolumeDetect; + private OMV.Vector3 _position; + private float _mass; // the mass of this object + private float _density; + private OMV.Vector3 _force; + private OMV.Vector3 _velocity; + private OMV.Vector3 _torque; + private float _collisionScore; + private OMV.Vector3 _acceleration; + private OMV.Quaternion _orientation; + private int _physicsActorType; + private bool _isPhysical; + private bool _flying; + private float _friction; + private float _restitution; + private bool _setAlwaysRun; + private bool _throttleUpdates; + private bool _isColliding; + private bool _collidingGround; + private bool _collidingObj; + private bool _floatOnWater; + private OMV.Vector3 _rotationalVelocity; + private bool _kinematic; + private float _buoyancy; + + private BSDynamics _vehicle; + + private OMV.Vector3 _PIDTarget; + private bool _usePID; + private float _PIDTau; + private bool _useHoverPID; + private float _PIDHoverHeight; + private PIDHoverType _PIDHoverType; + private float _PIDHoverTao; + + public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, + OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) + : base(parent_scene, localID, primName, "BSPrim") + { + // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID); + _physicsActorType = (int)ActorTypes.Prim; + _position = pos; + _size = size; + Scale = size; // prims are the size the user wants them to be (different for BSCharactes). + _orientation = rotation; + _buoyancy = 1f; + _velocity = OMV.Vector3.Zero; + _rotationalVelocity = OMV.Vector3.Zero; + BaseShape = pbs; + _isPhysical = pisPhysical; + _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; + + _vehicle = new BSDynamics(PhysicsScene, this); // add vehicleness + + _mass = CalculateMass(); + + // No body or shape yet + PhysBody = new BulletBody(LocalID); + PhysShape = new BulletShape(); + + DetailLog("{0},BSPrim.constructor,call", LocalID); + // do the actual object creation at taint time + PhysicsScene.TaintedObject("BSPrim.create", delegate() + { + CreateGeomAndObject(true); + + CurrentCollisionFlags = BulletSimAPI.GetCollisionFlags2(PhysBody.ptr); + }); + } + + // called when this prim is being destroyed and we should free all the resources + public override void Destroy() + { + // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); + base.Destroy(); + + // Undo any links between me and any other object + BSPhysObject parentBefore = Linkset.LinksetRoot; + int childrenBefore = Linkset.NumberOfChildren; + + Linkset = Linkset.RemoveMeFromLinkset(this); + + DetailLog("{0},BSPrim.Destroy,call,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}", + LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren); + + // Undo any vehicle properties + this.VehicleType = (int)Vehicle.TYPE_NONE; + + PhysicsScene.TaintedObject("BSPrim.destroy", delegate() + { + DetailLog("{0},BSPrim.Destroy,taint,", LocalID); + // If there are physical body and shape, release my use of same. + PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null); + PhysBody.Clear(); + PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null); + PhysShape.Clear(); + }); + } + + // No one uses this property. + public override bool Stopped { + get { return false; } + } + public override OMV.Vector3 Size { + get { return _size; } + set { + // We presume the scale and size are the same. If scale must be changed for + // the physical shape, that is done when the geometry is built. + _size = value; + Scale = _size; + ForceBodyShapeRebuild(false); + } + } + + public override PrimitiveBaseShape Shape { + set { + BaseShape = value; + ForceBodyShapeRebuild(false); + } + } + // Whatever the linkset wants is what I want. + public override BSPhysicsShapeType PreferredPhysicalShape + { get { return Linkset.PreferredPhysicalShape(this); } } + + public override bool ForceBodyShapeRebuild(bool inTaintTime) + { + LastAssetBuildFailed = false; + PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ForceBodyShapeRebuild", delegate() + { + _mass = CalculateMass(); // changing the shape changes the mass + CreateGeomAndObject(true); + }); + return true; + } + public override bool Grabbed { + set { _grabbed = value; + } + } + public override bool Selected { + set + { + if (value != _isSelected) + { + _isSelected = value; + PhysicsScene.TaintedObject("BSPrim.setSelected", delegate() + { + DetailLog("{0},BSPrim.selected,taint,selected={1}", LocalID, _isSelected); + SetObjectDynamic(false); + }); + } + } + } + public override void CrossingFailure() { return; } + + // link me to the specified parent + public override void link(PhysicsActor obj) { + BSPrim parent = obj as BSPrim; + if (parent != null) + { + BSPhysObject parentBefore = Linkset.LinksetRoot; + int childrenBefore = Linkset.NumberOfChildren; + + Linkset = parent.Linkset.AddMeToLinkset(this); + + DetailLog("{0},BSPrim.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}", + LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren); + } + return; + } + + // delink me from my linkset + public override void delink() { + // TODO: decide if this parent checking needs to happen at taint time + // Race condition here: if link() and delink() in same simulation tick, the delink will not happen + + BSPhysObject parentBefore = Linkset.LinksetRoot; + int childrenBefore = Linkset.NumberOfChildren; + + Linkset = Linkset.RemoveMeFromLinkset(this); + + DetailLog("{0},BSPrim.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ", + LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren); + return; + } + + // Set motion values to zero. + // Do it to the properties so the values get set in the physics engine. + // Push the setting of the values to the viewer. + // Called at taint time! + public override void ZeroMotion(bool inTaintTime) + { + _velocity = OMV.Vector3.Zero; + _acceleration = OMV.Vector3.Zero; + _rotationalVelocity = OMV.Vector3.Zero; + + // Zero some other properties in the physics engine + PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate() + { + if (PhysBody.HasPhysicalBody) + BulletSimAPI.ClearAllForces2(PhysBody.ptr); + }); + } + public override void ZeroAngularMotion(bool inTaintTime) + { + _rotationalVelocity = OMV.Vector3.Zero; + // Zero some other properties in the physics engine + PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate() + { + // DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity); + if (PhysBody.HasPhysicalBody) + { + BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, _rotationalVelocity); + BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity); + } + }); + } + + public override void LockAngularMotion(OMV.Vector3 axis) + { + DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis); + return; + } + + public override OMV.Vector3 RawPosition + { + get { return _position; } + set { _position = value; } + } + public override OMV.Vector3 Position { + get { + /* NOTE: this refetch is not necessary. The simulator knows about linkset children + * and does not fetch this position info for children. Thus this is commented out. + // child prims move around based on their parent. Need to get the latest location + if (!Linkset.IsRoot(this)) + _position = Linkset.PositionGet(this); + */ + + // don't do the GetObjectPosition for root elements because this function is called a zillion times. + // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr); + return _position; + } + set { + // If the position must be forced into the physics engine, use ForcePosition. + // All positions are given in world positions. + if (_position == value) + { + DetailLog("{0},BSPrim.setPosition,taint,positionNotChanging,pos={1},orient={2}", LocalID, _position, _orientation); + return; + } + _position = value; + PositionSanityCheck(false); + + // A linkset might need to know if a component information changed. + Linkset.UpdateProperties(this, false); + + PhysicsScene.TaintedObject("BSPrim.setPosition", delegate() + { + DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); + ForcePosition = _position; + }); + } + } + public override OMV.Vector3 ForcePosition { + get { + _position = BulletSimAPI.GetPosition2(PhysBody.ptr); + return _position; + } + set { + _position = value; + if (PhysBody.HasPhysicalBody) + { + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + ActivateIfPhysical(false); + } + } + } + + // Check that the current position is sane and, if not, modify the position to make it so. + // Check for being below terrain and being out of bounds. + // Returns 'true' of the position was made sane by some action. + private bool PositionSanityCheck(bool inTaintTime) + { + bool ret = false; + + if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position)) + { + // The physical object is out of the known/simulated area. + // Upper levels of code will handle the transition to other areas so, for + // the time, we just ignore the position. + return ret; + } + + float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); + OMV.Vector3 upForce = OMV.Vector3.Zero; + if (RawPosition.Z < terrainHeight) + { + DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); + float targetHeight = terrainHeight + (Size.Z / 2f); + // Upforce proportional to the distance away from the terrain. Correct the error in 1 sec. + upForce.Z = (terrainHeight - RawPosition.Z) * 1f; + ret = true; + } + + if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) + { + float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(_position); + // TODO: a floating motor so object will bob in the water + if (Math.Abs(RawPosition.Z - waterHeight) > 0.1f) + { + // Upforce proportional to the distance away from the water. Correct the error in 1 sec. + upForce.Z = (waterHeight - RawPosition.Z) * 1f; + ret = true; + } + } + + // The above code computes a force to apply to correct any out-of-bounds problems. Apply same. + // TODO: This should be intergrated with a geneal physics action mechanism. + // TODO: This should be moderated with PID'ness. + if (ret) + { + // Apply upforce and overcome gravity. + OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity; + DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce); + AddForce(correctionForce, false, inTaintTime); + } + return ret; + } + + // Return the effective mass of the object. + // If there are multiple items in the linkset, add them together for the root + public override float Mass + { + get + { + return Linkset.LinksetMass; + // return _mass; + } + } + + // used when we only want this prim's mass and not the linkset thing + public override float RawMass { + get { return _mass; } + } + // Set the physical mass to the passed mass. + // Note that this does not change _mass! + public override void UpdatePhysicalMassProperties(float physMass) + { + if (IsStatic) + { + Inertia = OMV.Vector3.Zero; + BulletSimAPI.SetMassProps2(PhysBody.ptr, 0f, Inertia); + BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); + } + else + { + Inertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass); + BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, Inertia); + BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); + // center of mass is at the zero of the object + // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(PhysBody.ptr, ForcePosition, ForceOrientation); + DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2}", LocalID, physMass, Inertia); + } + } + + // Is this used? + public override OMV.Vector3 CenterOfMass + { + get { return Linkset.CenterOfMass; } + } + + // Is this used? + public override OMV.Vector3 GeometricCenter + { + get { return Linkset.GeometricCenter; } + } + + public override OMV.Vector3 Force { + get { return _force; } + set { + _force = value; + if (_force != OMV.Vector3.Zero) + { + // If the force is non-zero, it must be reapplied each tick because + // Bullet clears the forces applied last frame. + RegisterPreStepAction("BSPrim.setForce", LocalID, + delegate(float timeStep) + { + DetailLog("{0},BSPrim.setForce,preStep,force={1}", LocalID, _force); + if (PhysBody.HasPhysicalBody) + { + BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, _force); + ActivateIfPhysical(false); + } + } + ); + } + else + { + UnRegisterPreStepAction("BSPrim.setForce", LocalID); + } + } + } + + public override int VehicleType { + get { + return (int)_vehicle.Type; // if we are a vehicle, return that type + } + set { + Vehicle type = (Vehicle)value; + + PhysicsScene.TaintedObject("setVehicleType", delegate() + { + // Done at taint time so we're sure the physics engine is not using the variables + // Vehicle code changes the parameters for this vehicle type. + _vehicle.ProcessTypeChange(type); + ActivateIfPhysical(false); + + // If an active vehicle, register the vehicle code to be called before each step + if (_vehicle.Type == Vehicle.TYPE_NONE) + UnRegisterPreStepAction("BSPrim.Vehicle", LocalID); + else + RegisterPreStepAction("BSPrim.Vehicle", LocalID, _vehicle.Step); + }); + } + } + public override void VehicleFloatParam(int param, float value) + { + PhysicsScene.TaintedObject("BSPrim.VehicleFloatParam", delegate() + { + _vehicle.ProcessFloatVehicleParam((Vehicle)param, value); + ActivateIfPhysical(false); + }); + } + public override void VehicleVectorParam(int param, OMV.Vector3 value) + { + PhysicsScene.TaintedObject("BSPrim.VehicleVectorParam", delegate() + { + _vehicle.ProcessVectorVehicleParam((Vehicle)param, value); + ActivateIfPhysical(false); + }); + } + public override void VehicleRotationParam(int param, OMV.Quaternion rotation) + { + PhysicsScene.TaintedObject("BSPrim.VehicleRotationParam", delegate() + { + _vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation); + ActivateIfPhysical(false); + }); + } + public override void VehicleFlags(int param, bool remove) + { + PhysicsScene.TaintedObject("BSPrim.VehicleFlags", delegate() + { + _vehicle.ProcessVehicleFlags(param, remove); + }); + } + + // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more + public override void SetVolumeDetect(int param) { + bool newValue = (param != 0); + if (_isVolumeDetect != newValue) + { + _isVolumeDetect = newValue; + PhysicsScene.TaintedObject("BSPrim.SetVolumeDetect", delegate() + { + // DetailLog("{0},setVolumeDetect,taint,volDetect={1}", LocalID, _isVolumeDetect); + SetObjectDynamic(true); + }); + } + return; + } + public override OMV.Vector3 Velocity { + get { return _velocity; } + set { + _velocity = value; + PhysicsScene.TaintedObject("BSPrim.setVelocity", delegate() + { + // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); + ForceVelocity = _velocity; + }); + } + } + public override OMV.Vector3 ForceVelocity { + get { return _velocity; } + set { + PhysicsScene.AssertInTaintTime("BSPrim.ForceVelocity"); + + _velocity = value; + if (PhysBody.HasPhysicalBody) + { + BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); + ActivateIfPhysical(false); + } + } + } + public override OMV.Vector3 Torque { + get { return _torque; } + set { + _torque = value; + if (_torque != OMV.Vector3.Zero) + { + // If the torque is non-zero, it must be reapplied each tick because + // Bullet clears the forces applied last frame. + RegisterPreStepAction("BSPrim.setTorque", LocalID, + delegate(float timeStep) + { + if (PhysBody.HasPhysicalBody) + AddAngularForce(_torque, false, true); + } + ); + } + else + { + UnRegisterPreStepAction("BSPrim.setTorque", LocalID); + } + // DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque); + } + } + public override float CollisionScore { + get { return _collisionScore; } + set { _collisionScore = value; + } + } + public override OMV.Vector3 Acceleration { + get { return _acceleration; } + set { _acceleration = value; } + } + public override OMV.Quaternion RawOrientation + { + get { return _orientation; } + set { _orientation = value; } + } + public override OMV.Quaternion Orientation { + get { + /* NOTE: this refetch is not necessary. The simulator knows about linkset children + * and does not fetch this position info for children. Thus this is commented out. + // Children move around because tied to parent. Get a fresh value. + if (!Linkset.IsRoot(this)) + { + _orientation = Linkset.OrientationGet(this); + } + */ + return _orientation; + } + set { + if (_orientation == value) + return; + _orientation = value; + + // A linkset might need to know if a component information changed. + Linkset.UpdateProperties(this, false); + + PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate() + { + if (PhysBody.HasPhysicalBody) + { + // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr); + // DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + } + }); + } + } + // Go directly to Bullet to get/set the value. + public override OMV.Quaternion ForceOrientation + { + get + { + _orientation = BulletSimAPI.GetOrientation2(PhysBody.ptr); + return _orientation; + } + set + { + _orientation = value; + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + } + } + public override int PhysicsActorType { + get { return _physicsActorType; } + set { _physicsActorType = value; } + } + public override bool IsPhysical { + get { return _isPhysical; } + set { + if (_isPhysical != value) + { + _isPhysical = value; + PhysicsScene.TaintedObject("BSPrim.setIsPhysical", delegate() + { + // DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical); + SetObjectDynamic(true); + // whether phys-to-static or static-to-phys, the object is not moving. + ZeroMotion(true); + }); + } + } + } + + // An object is static (does not move) if selected or not physical + public override bool IsStatic + { + get { return _isSelected || !IsPhysical; } + } + + // An object is solid if it's not phantom and if it's not doing VolumeDetect + public override bool IsSolid + { + get { return !IsPhantom && !_isVolumeDetect; } + } + + // Make gravity work if the object is physical and not selected + // Called at taint-time!! + private void SetObjectDynamic(bool forceRebuild) + { + // Recreate the physical object if necessary + CreateGeomAndObject(forceRebuild); + } + + // Convert the simulator's physical properties into settings on BulletSim objects. + // There are four flags we're interested in: + // IsStatic: Object does not move, otherwise the object has mass and moves + // isSolid: other objects bounce off of this object + // isVolumeDetect: other objects pass through but can generate collisions + // collisionEvents: whether this object returns collision events + private void UpdatePhysicalParameters() + { + // DetailLog("{0},BSPrim.UpdatePhysicalParameters,entry,body={1},shape={2}", LocalID, BSBody, BSShape); + + // 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). + BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr); + + // Set up the object physicalness (does gravity and collisions move this object) + MakeDynamic(IsStatic); + + // Update vehicle specific parameters (after MakeDynamic() so can change physical parameters) + _vehicle.Refresh(); + + // Arrange for collision events if the simulator wants them + EnableCollisions(SubscribedEvents()); + + // Make solid or not (do things bounce off or pass through this object). + MakeSolid(IsSolid); + + BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr, _position, _orientation); + + // Rebuild its shape + BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); + + // Collision filter can be set only when the object is in the world + PhysBody.ApplyCollisionMask(); + + // Recompute any linkset parameters. + // When going from non-physical to physical, this re-enables the constraints that + // had been automatically disabled when the mass was set to zero. + // For compound based linksets, this enables and disables interactions of the children. + Linkset.Refresh(this); + + DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},body={6},shape={7}", + LocalID, IsStatic, IsSolid, _mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody, PhysShape); + } + + // "Making dynamic" means changing to and from static. + // When static, gravity does not effect the object and it is fixed in space. + // When dynamic, the object can fall and be pushed by others. + // This is independent of its 'solidness' which controls what passes through + // this object and what interacts with it. + private void MakeDynamic(bool makeStatic) + { + if (makeStatic) + { + // Become a Bullet 'static' object type + CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT); + // Stop all movement + ZeroMotion(true); + + // Set various physical properties so other object interact properly + MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false); + BulletSimAPI.SetFriction2(PhysBody.ptr, matAttrib.friction); + BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution); + + // Mass is zero which disables a bunch of physics stuff in Bullet + UpdatePhysicalMassProperties(0f); + // Set collision detection parameters + if (BSParam.CcdMotionThreshold > 0f) + { + BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, BSParam.CcdMotionThreshold); + BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius); + } + + // The activation state is 'disabled' so Bullet will not try to act on it. + // BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.DISABLE_SIMULATION); + // Start it out sleeping and physical actions could wake it up. + BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ISLAND_SLEEPING); + + // This collides like a static object + PhysBody.collisionType = CollisionType.Static; + + // There can be special things needed for implementing linksets + Linkset.MakeStatic(this); + } + else + { + // Not a Bullet static object + CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT); + + // Set various physical properties so other object interact properly + MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, true); + BulletSimAPI.SetFriction2(PhysBody.ptr, matAttrib.friction); + BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution); + + // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382 + // Since this can be called multiple times, only zero forces when becoming physical + // BulletSimAPI.ClearAllForces2(BSBody.ptr); + + // For good measure, make sure the transform is set through to the motion state + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + + // Center of mass is at the center of the object + // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.PhysBody.ptr, _position, _orientation); + + // A dynamic object has mass + UpdatePhysicalMassProperties(RawMass); + + // Set collision detection parameters + if (BSParam.CcdMotionThreshold > 0f) + { + BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, BSParam.CcdMotionThreshold); + BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius); + } + + // Various values for simulation limits + BulletSimAPI.SetDamping2(PhysBody.ptr, BSParam.LinearDamping, BSParam.AngularDamping); + BulletSimAPI.SetDeactivationTime2(PhysBody.ptr, BSParam.DeactivationTime); + BulletSimAPI.SetSleepingThresholds2(PhysBody.ptr, BSParam.LinearSleepingThreshold, BSParam.AngularSleepingThreshold); + BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, BSParam.ContactProcessingThreshold); + + // This collides like an object. + PhysBody.collisionType = CollisionType.Dynamic; + + // Force activation of the object so Bullet will act on it. + // Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects. + BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ACTIVE_TAG); + + // There might be special things needed for implementing linksets. + Linkset.MakeDynamic(this); + } + } + + // "Making solid" means that other object will not pass through this object. + // To make transparent, we create a Bullet ghost object. + // Note: This expects to be called from the UpdatePhysicalParameters() routine as + // the functions after this one set up the state of a possibly newly created collision body. + private void MakeSolid(bool makeSolid) + { + CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(PhysBody.ptr); + if (makeSolid) + { + // Verify the previous code created the correct shape for this type of thing. + if ((bodyType & CollisionObjectTypes.CO_RIGID_BODY) == 0) + { + m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for solidity. id={1}, type={2}", LogHeader, LocalID, bodyType); + } + CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); + } + else + { + if ((bodyType & CollisionObjectTypes.CO_GHOST_OBJECT) == 0) + { + m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for non-solidness. id={1}, type={2}", LogHeader, LocalID, bodyType); + } + CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); + + // Change collision info from a static object to a ghosty collision object + PhysBody.collisionType = CollisionType.VolumeDetect; + } + } + + // Enable physical actions. Bullet will keep sleeping non-moving physical objects so + // they need waking up when parameters are changed. + // Called in taint-time!! + private void ActivateIfPhysical(bool forceIt) + { + if (IsPhysical && PhysBody.HasPhysicalBody) + BulletSimAPI.Activate2(PhysBody.ptr, forceIt); + } + + // Turn on or off the flag controlling whether collision events are returned to the simulator. + private void EnableCollisions(bool wantsCollisionEvents) + { + if (wantsCollisionEvents) + { + CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + } + else + { + CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + } + } + + // prims don't fly + public override bool Flying { + get { return _flying; } + set { + _flying = value; + } + } + public override bool SetAlwaysRun { + get { return _setAlwaysRun; } + set { _setAlwaysRun = value; } + } + public override bool ThrottleUpdates { + get { return _throttleUpdates; } + set { _throttleUpdates = value; } + } + public override bool IsColliding { + get { return (CollidingStep == PhysicsScene.SimulationStep); } + set { _isColliding = value; } + } + public override bool CollidingGround { + get { return (CollidingGroundStep == PhysicsScene.SimulationStep); } + set { _collidingGround = value; } + } + public override bool CollidingObj { + get { return _collidingObj; } + set { _collidingObj = value; } + } + public bool IsPhantom { + get { + // SceneObjectPart removes phantom objects from the physics scene + // so, although we could implement touching and such, we never + // are invoked as a phantom object + return false; + } + } + public override bool FloatOnWater { + set { + _floatOnWater = value; + PhysicsScene.TaintedObject("BSPrim.setFloatOnWater", delegate() + { + if (_floatOnWater) + CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); + else + CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); + }); + } + } + public override OMV.Vector3 RotationalVelocity { + get { + return _rotationalVelocity; + } + set { + _rotationalVelocity = value; + // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); + PhysicsScene.TaintedObject("BSPrim.setRotationalVelocity", delegate() + { + DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); + ForceRotationalVelocity = _rotationalVelocity; + }); + } + } + public override OMV.Vector3 ForceRotationalVelocity { + get { + return _rotationalVelocity; + } + set { + _rotationalVelocity = value; + if (PhysBody.HasPhysicalBody) + { + BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity); + ActivateIfPhysical(false); + } + } + } + public override bool Kinematic { + get { return _kinematic; } + set { _kinematic = value; + // m_log.DebugFormat("{0}: Kinematic={1}", LogHeader, _kinematic); + } + } + public override float Buoyancy { + get { return _buoyancy; } + set { + _buoyancy = value; + PhysicsScene.TaintedObject("BSPrim.setBuoyancy", delegate() + { + ForceBuoyancy = _buoyancy; + }); + } + } + public override float ForceBuoyancy { + get { return _buoyancy; } + set { + _buoyancy = value; + // DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); + // Buoyancy is faked by changing the gravity applied to the object + if (PhysBody.HasPhysicalBody) + { + float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); + BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav)); + ActivateIfPhysical(false); + } + } + } + + // Used for MoveTo + public override OMV.Vector3 PIDTarget { + set { _PIDTarget = value; } + } + public override bool PIDActive { + set { _usePID = value; } + } + public override float PIDTau { + set { _PIDTau = value; } + } + + // Used for llSetHoverHeight and maybe vehicle height + // Hover Height will override MoveTo target's Z + public override bool PIDHoverActive { + set { _useHoverPID = value; } + } + public override float PIDHoverHeight { + set { _PIDHoverHeight = value; } + } + public override PIDHoverType PIDHoverType { + set { _PIDHoverType = value; } + } + public override float PIDHoverTau { + set { _PIDHoverTao = value; } + } + + // For RotLookAt + public override OMV.Quaternion APIDTarget { set { return; } } + public override bool APIDActive { set { return; } } + public override float APIDStrength { set { return; } } + public override float APIDDamping { set { return; } } + + public override void AddForce(OMV.Vector3 force, bool pushforce) { + AddForce(force, pushforce, false); + } + // Applying a force just adds this to the total force on the object. + // This added force will only last the next simulation tick. + public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { + // for an object, doesn't matter if force is a pushforce or not + if (force.IsFinite()) + { + OMV.Vector3 addForce = force; + DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); + PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() + { + // Bullet adds this central force to the total force for this tick + DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce); + if (PhysBody.HasPhysicalBody) + { + BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, addForce); + ActivateIfPhysical(false); + } + }); + } + else + { + m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID); + return; + } + } + + public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { + AddAngularForce(force, pushforce, false); + } + public void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) + { + if (force.IsFinite()) + { + OMV.Vector3 angForce = force; + PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddAngularForce", delegate() + { + if (PhysBody.HasPhysicalBody) + { + BulletSimAPI.ApplyTorque2(PhysBody.ptr, angForce); + ActivateIfPhysical(false); + } + }); + } + else + { + m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID); + return; + } + } + + // A torque impulse. + // ApplyTorqueImpulse adds torque directly to the angularVelocity. + // AddAngularForce accumulates the force and applied it to the angular velocity all at once. + // Computed as: angularVelocity += impulse * inertia; + public void ApplyTorqueImpulse(OMV.Vector3 impulse, bool inTaintTime) + { + OMV.Vector3 applyImpulse = impulse; + PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ApplyTorqueImpulse", delegate() + { + if (PhysBody.HasPhysicalBody) + { + BulletSimAPI.ApplyTorqueImpulse2(PhysBody.ptr, applyImpulse); + ActivateIfPhysical(false); + } + }); + } + + public override void SetMomentum(OMV.Vector3 momentum) { + // DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum); + } + #region Mass Calculation + + private float CalculateMass() + { + float volume = _size.X * _size.Y * _size.Z; // default + float tmp; + + float returnMass = 0; + float hollowAmount = (float)BaseShape.ProfileHollow * 2.0e-5f; + float hollowVolume = hollowAmount * hollowAmount; + + switch (BaseShape.ProfileShape) + { + case ProfileShape.Square: + // default box + + if (BaseShape.PathCurve == (byte)Extrusion.Straight) + { + if (hollowAmount > 0.0) + { + switch (BaseShape.HollowShape) + { + case HollowShape.Square: + case HollowShape.Same: + break; + + case HollowShape.Circle: + + hollowVolume *= 0.78539816339f; + break; + + case HollowShape.Triangle: + + hollowVolume *= (0.5f * .5f); + break; + + default: + hollowVolume = 0; + break; + } + volume *= (1.0f - hollowVolume); + } + } + + else if (BaseShape.PathCurve == (byte)Extrusion.Curve1) + { + //a tube + + volume *= 0.78539816339e-2f * (float)(200 - BaseShape.PathScaleX); + tmp= 1.0f -2.0e-2f * (float)(200 - BaseShape.PathScaleY); + volume -= volume*tmp*tmp; + + if (hollowAmount > 0.0) + { + hollowVolume *= hollowAmount; + + switch (BaseShape.HollowShape) + { + case HollowShape.Square: + case HollowShape.Same: + break; + + case HollowShape.Circle: + hollowVolume *= 0.78539816339f;; + break; + + case HollowShape.Triangle: + hollowVolume *= 0.5f * 0.5f; + break; + default: + hollowVolume = 0; + break; + } + volume *= (1.0f - hollowVolume); + } + } + + break; + + case ProfileShape.Circle: + + if (BaseShape.PathCurve == (byte)Extrusion.Straight) + { + volume *= 0.78539816339f; // elipse base + + if (hollowAmount > 0.0) + { + switch (BaseShape.HollowShape) + { + case HollowShape.Same: + case HollowShape.Circle: + break; + + case HollowShape.Square: + hollowVolume *= 0.5f * 2.5984480504799f; + break; + + case HollowShape.Triangle: + hollowVolume *= .5f * 1.27323954473516f; + break; + + default: + hollowVolume = 0; + break; + } + volume *= (1.0f - hollowVolume); + } + } + + else if (BaseShape.PathCurve == (byte)Extrusion.Curve1) + { + volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - BaseShape.PathScaleX); + tmp = 1.0f - .02f * (float)(200 - BaseShape.PathScaleY); + volume *= (1.0f - tmp * tmp); + + if (hollowAmount > 0.0) + { + + // calculate the hollow volume by it's shape compared to the prim shape + hollowVolume *= hollowAmount; + + switch (BaseShape.HollowShape) + { + case HollowShape.Same: + case HollowShape.Circle: + break; + + case HollowShape.Square: + hollowVolume *= 0.5f * 2.5984480504799f; + break; + + case HollowShape.Triangle: + hollowVolume *= .5f * 1.27323954473516f; + break; + + default: + hollowVolume = 0; + break; + } + volume *= (1.0f - hollowVolume); + } + } + break; + + case ProfileShape.HalfCircle: + if (BaseShape.PathCurve == (byte)Extrusion.Curve1) + { + volume *= 0.52359877559829887307710723054658f; + } + break; + + case ProfileShape.EquilateralTriangle: + + if (BaseShape.PathCurve == (byte)Extrusion.Straight) + { + volume *= 0.32475953f; + + if (hollowAmount > 0.0) + { + + // calculate the hollow volume by it's shape compared to the prim shape + switch (BaseShape.HollowShape) + { + case HollowShape.Same: + case HollowShape.Triangle: + hollowVolume *= .25f; + break; + + case HollowShape.Square: + hollowVolume *= 0.499849f * 3.07920140172638f; + break; + + case HollowShape.Circle: + // Hollow shape is a perfect cyllinder in respect to the cube's scale + // Cyllinder hollow volume calculation + + hollowVolume *= 0.1963495f * 3.07920140172638f; + break; + + default: + hollowVolume = 0; + break; + } + volume *= (1.0f - hollowVolume); + } + } + else if (BaseShape.PathCurve == (byte)Extrusion.Curve1) + { + volume *= 0.32475953f; + volume *= 0.01f * (float)(200 - BaseShape.PathScaleX); + tmp = 1.0f - .02f * (float)(200 - BaseShape.PathScaleY); + volume *= (1.0f - tmp * tmp); + + if (hollowAmount > 0.0) + { + + hollowVolume *= hollowAmount; + + switch (BaseShape.HollowShape) + { + case HollowShape.Same: + case HollowShape.Triangle: + hollowVolume *= .25f; + break; + + case HollowShape.Square: + hollowVolume *= 0.499849f * 3.07920140172638f; + break; + + case HollowShape.Circle: + + hollowVolume *= 0.1963495f * 3.07920140172638f; + break; + + default: + hollowVolume = 0; + break; + } + volume *= (1.0f - hollowVolume); + } + } + break; + + default: + break; + } + + + + float taperX1; + float taperY1; + float taperX; + float taperY; + float pathBegin; + float pathEnd; + float profileBegin; + float profileEnd; + + if (BaseShape.PathCurve == (byte)Extrusion.Straight || BaseShape.PathCurve == (byte)Extrusion.Flexible) + { + taperX1 = BaseShape.PathScaleX * 0.01f; + if (taperX1 > 1.0f) + taperX1 = 2.0f - taperX1; + taperX = 1.0f - taperX1; + + taperY1 = BaseShape.PathScaleY * 0.01f; + if (taperY1 > 1.0f) + taperY1 = 2.0f - taperY1; + taperY = 1.0f - taperY1; + } + else + { + taperX = BaseShape.PathTaperX * 0.01f; + if (taperX < 0.0f) + taperX = -taperX; + taperX1 = 1.0f - taperX; + + taperY = BaseShape.PathTaperY * 0.01f; + if (taperY < 0.0f) + taperY = -taperY; + taperY1 = 1.0f - taperY; + + } + + + volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY); + + pathBegin = (float)BaseShape.PathBegin * 2.0e-5f; + pathEnd = 1.0f - (float)BaseShape.PathEnd * 2.0e-5f; + volume *= (pathEnd - pathBegin); + + // this is crude aproximation + profileBegin = (float)BaseShape.ProfileBegin * 2.0e-5f; + profileEnd = 1.0f - (float)BaseShape.ProfileEnd * 2.0e-5f; + volume *= (profileEnd - profileBegin); + + returnMass = _density * volume; + + /* Comment out code that computes the mass of the linkset. That is done in the Linkset class. + if (IsRootOfLinkset) + { + foreach (BSPrim prim in _childrenPrims) + { + returnMass += prim.CalculateMass(); + } + } + */ + + returnMass = Util.Clamp(returnMass, BSParam.MinimumObjectMass, BSParam.MaximumObjectMass); + + return returnMass; + }// end CalculateMass + #endregion Mass Calculation + + // Rebuild the geometry and object. + // This is called when the shape changes so we need to recreate the mesh/hull. + // Called at taint-time!!! + public void CreateGeomAndObject(bool forceRebuild) + { + // If this prim is part of a linkset, we must remove and restore the physical + // links if the body is rebuilt. + bool needToRestoreLinkset = false; + bool needToRestoreVehicle = false; + + // Create the correct physical representation for this type of object. + // Updates PhysBody and PhysShape with the new information. + // Ignore 'forceRebuild'. This routine makes the right choices and changes of necessary. + PhysicsScene.Shapes.GetBodyAndShape(false, PhysicsScene.World, this, null, delegate(BulletBody dBody) + { + // Called if the current prim body is about to be destroyed. + // Remove all the physical dependencies on the old body. + // (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...) + needToRestoreLinkset = Linkset.RemoveBodyDependencies(this); + needToRestoreVehicle = _vehicle.RemoveBodyDependencies(this); + }); + + if (needToRestoreLinkset) + { + // If physical body dependencies were removed, restore them + Linkset.RestoreBodyDependencies(this); + } + if (needToRestoreVehicle) + { + // If physical body dependencies were removed, restore them + _vehicle.RestoreBodyDependencies(this); + } + + // Make sure the properties are set on the new object + UpdatePhysicalParameters(); + return; + } + + // The physics engine says that properties have updated. Update same and inform + // the world that things have changed. + // TODO: do we really need to check for changed? Maybe just copy values and call RequestPhysicsterseUpdate() + enum UpdatedProperties { + Position = 1 << 0, + Rotation = 1 << 1, + Velocity = 1 << 2, + Acceleration = 1 << 3, + RotationalVel = 1 << 4 + } + + const float ROTATION_TOLERANCE = 0.01f; + const float VELOCITY_TOLERANCE = 0.001f; + const float POSITION_TOLERANCE = 0.05f; + const float ACCELERATION_TOLERANCE = 0.01f; + const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f; + + public override void UpdateProperties(EntityProperties entprop) + { + // Updates only for individual prims and for the root object of a linkset. + if (Linkset.IsRoot(this)) + { + // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet + // TODO: handle physics introduced by Bullet with computed vehicle physics. + if (_vehicle.IsActive) + { + entprop.RotationalVelocity = OMV.Vector3.Zero; + } + + // Assign directly to the local variables so the normal set action does not happen + _position = entprop.Position; + _orientation = entprop.Rotation; + _velocity = entprop.Velocity; + _acceleration = entprop.Acceleration; + _rotationalVelocity = entprop.RotationalVelocity; + + // The sanity check can change the velocity and/or position. + if (IsPhysical && PositionSanityCheck(true)) + { + entprop.Position = _position; + entprop.Velocity = _velocity; + } + + OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG + DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}", + LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity); + + // remember the current and last set values + LastEntityProperties = CurrentEntityProperties; + CurrentEntityProperties = entprop; + + base.RequestPhysicsterseUpdate(); + } + /* + else + { + // For debugging, report the movement of children + DetailLog("{0},BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}", + LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, + entprop.Acceleration, entprop.RotationalVelocity); + } + */ + + // The linkset implimentation might want to know about this. + Linkset.UpdateProperties(this, true); + } +} +} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSScene.cs new file mode 100644 index 0000000..6bcea3f --- /dev/null +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSScene.cs @@ -0,0 +1,954 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; +using OpenSim.Framework; +using OpenSim.Region.Framework; +using OpenSim.Region.CoreModules; +using Logging = OpenSim.Region.CoreModules.Framework.Statistics.Logging; +using OpenSim.Region.Physics.Manager; +using Nini.Config; +using log4net; +using OpenMetaverse; + +// TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim) +// Based on material, set density and friction +// More efficient memory usage when passing hull information from BSPrim to BulletSim +// Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect +// Implement LockAngularMotion +// Add PID movement operations. What does ScenePresence.MoveToTarget do? +// Check terrain size. 128 or 127? +// Raycast +// +namespace OpenSim.Region.Physics.BulletSNPlugin +{ +public sealed class BSScene : PhysicsScene, IPhysicsParameters +{ + private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + private static readonly string LogHeader = "[BULLETS SCENE]"; + + // The name of the region we're working for. + public string RegionName { get; private set; } + + public string BulletSimVersion = "?"; + + public Dictionary PhysObjects; + public BSShapeCollection Shapes; + + // Keeping track of the objects with collisions so we can report begin and end of a collision + public HashSet ObjectsWithCollisions = new HashSet(); + public HashSet ObjectsWithNoMoreCollisions = new HashSet(); + // Keep track of all the avatars so we can send them a collision event + // every tick so OpenSim will update its animation. + private HashSet m_avatars = new HashSet(); + + // let my minuions use my logger + public ILog Logger { get { return m_log; } } + + public IMesher mesher; + public uint WorldID { get; private set; } + public BulletSim World { get; private set; } + + // All the constraints that have been allocated in this instance. + public BSConstraintCollection Constraints { get; private set; } + + // Simulation parameters + internal int m_maxSubSteps; + internal float m_fixedTimeStep; + internal long m_simulationStep = 0; + public long SimulationStep { get { return m_simulationStep; } } + internal int m_taintsToProcessPerStep; + internal float LastTimeStep { get; private set; } + + // Physical objects can register for prestep or poststep events + public delegate void PreStepAction(float timeStep); + public delegate void PostStepAction(float timeStep); + public event PreStepAction BeforeStep; + public event PreStepAction AfterStep; + + // A value of the time now so all the collision and update routines do not have to get their own + // Set to 'now' just before all the prims and actors are called for collisions and updates + public int SimulationNowTime { get; private set; } + + // True if initialized and ready to do simulation steps + private bool m_initialized = false; + + // Flag which is true when processing taints. + // Not guaranteed to be correct all the time (don't depend on this) but good for debugging. + public bool InTaintTime { get; private set; } + + // Pinned memory used to pass step information between managed and unmanaged + internal int m_maxCollisionsPerFrame; + private List m_collisionArray; + //private GCHandle m_collisionArrayPinnedHandle; + + internal int m_maxUpdatesPerFrame; + private List m_updateArray; + //private GCHandle m_updateArrayPinnedHandle; + + + public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero + public const uint GROUNDPLANE_ID = 1; + public const uint CHILDTERRAIN_ID = 2; // Terrain allocated based on our mega-prim childre start here + + public float SimpleWaterLevel { get; set; } + public BSTerrainManager TerrainManager { get; private set; } + + public ConfigurationParameters Params + { + get { return UnmanagedParams[0]; } + } + public Vector3 DefaultGravity + { + get { return new Vector3(0f, 0f, Params.gravity); } + } + // Just the Z value of the gravity + public float DefaultGravityZ + { + get { return Params.gravity; } + } + + // When functions in the unmanaged code must be called, it is only + // done at a known time just before the simulation step. The taint + // system saves all these function calls and executes them in + // order before the simulation. + public delegate void TaintCallback(); + private struct TaintCallbackEntry + { + public String ident; + public TaintCallback callback; + public TaintCallbackEntry(string i, TaintCallback c) + { + ident = i; + callback = c; + } + } + private Object _taintLock = new Object(); // lock for using the next object + private List _taintOperations; + private Dictionary _postTaintOperations; + private List _postStepOperations; + + // A pointer to an instance if this structure is passed to the C++ code + // Used to pass basic configuration values to the unmanaged code. + internal ConfigurationParameters[] UnmanagedParams; + //GCHandle m_paramsHandle; + + // Handle to the callback used by the unmanaged code to call into the managed code. + // Used for debug logging. + // Need to store the handle in a persistant variable so it won't be freed. + private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle; + + // Sometimes you just have to log everything. + public Logging.LogWriter PhysicsLogging; + private bool m_physicsLoggingEnabled; + private string m_physicsLoggingDir; + private string m_physicsLoggingPrefix; + private int m_physicsLoggingFileMinutes; + private bool m_physicsLoggingDoFlush; + // 'true' of the vehicle code is to log lots of details + public bool VehicleLoggingEnabled { get; private set; } + public bool VehiclePhysicalLoggingEnabled { get; private set; } + + #region Construction and Initialization + public BSScene(string identifier) + { + m_initialized = false; + // we are passed the name of the region we're working for. + RegionName = identifier; + } + + public override void Initialise(IMesher meshmerizer, IConfigSource config) + { + mesher = meshmerizer; + _taintOperations = new List(); + _postTaintOperations = new Dictionary(); + _postStepOperations = new List(); + PhysObjects = new Dictionary(); + Shapes = new BSShapeCollection(this); + + // Allocate pinned memory to pass parameters. + UnmanagedParams = new ConfigurationParameters[1]; + //m_paramsHandle = GCHandle.Alloc(UnmanagedParams, GCHandleType.Pinned); + + // Set default values for physics parameters plus any overrides from the ini file + GetInitialParameterValues(config); + + // allocate more pinned memory close to the above in an attempt to get the memory all together + m_collisionArray = new List(); + //m_collisionArrayPinnedHandle = GCHandle.Alloc(m_collisionArray, GCHandleType.Pinned); + m_updateArray = new List(); + //m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned); + + // Enable very detailed logging. + // By creating an empty logger when not logging, the log message invocation code + // can be left in and every call doesn't have to check for null. + if (m_physicsLoggingEnabled) + { + PhysicsLogging = new Logging.LogWriter(m_physicsLoggingDir, m_physicsLoggingPrefix, m_physicsLoggingFileMinutes); + PhysicsLogging.ErrorLogger = m_log; // for DEBUG. Let's the logger output error messages. + } + else + { + PhysicsLogging = new Logging.LogWriter(); + } + + // If Debug logging level, enable logging from the unmanaged code + m_DebugLogCallbackHandle = null; + if (m_log.IsDebugEnabled || PhysicsLogging.Enabled) + { + m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader); + if (PhysicsLogging.Enabled) + // The handle is saved in a variable to make sure it doesn't get freed after this call + m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLoggerPhysLog); + else + m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger); + } + + // Get the version of the DLL + // TODO: this doesn't work yet. Something wrong with marshaling the returned string. + // BulletSimVersion = BulletSimAPI.GetVersion(); + // m_log.WarnFormat("{0}: BulletSim.dll version='{1}'", LogHeader, BulletSimVersion); + + // The bounding box for the simulated world. The origin is 0,0,0 unless we're + // a child in a mega-region. + // Bullet actually doesn't care about the extents of the simulated + // area. It tracks active objects no matter where they are. + Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); + + // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader); + + World = new BulletSim(0, this, BulletSimAPI.Initialize2(worldExtent, UnmanagedParams, + m_maxCollisionsPerFrame, ref m_collisionArray, + m_maxUpdatesPerFrame,ref m_updateArray, + m_DebugLogCallbackHandle)); + + Constraints = new BSConstraintCollection(World); + + TerrainManager = new BSTerrainManager(this); + TerrainManager.CreateInitialGroundPlaneAndTerrain(); + + m_log.WarnFormat("{0} Linksets implemented with {1}", LogHeader, (BSLinkset.LinksetImplementation)BSParam.LinksetImplementation); + + InTaintTime = false; + m_initialized = true; + } + + // All default parameter values are set here. There should be no values set in the + // variable definitions. + private void GetInitialParameterValues(IConfigSource config) + { + ConfigurationParameters parms = new ConfigurationParameters(); + UnmanagedParams[0] = parms; + + BSParam.SetParameterDefaultValues(this); + + if (config != null) + { + // If there are specifications in the ini file, use those values + IConfig pConfig = config.Configs["BulletSim"]; + if (pConfig != null) + { + BSParam.SetParameterConfigurationValues(this, pConfig); + + // Very detailed logging for physics debugging + m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false); + m_physicsLoggingDir = pConfig.GetString("PhysicsLoggingDir", "."); + m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-%REGIONNAME%-"); + m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5); + m_physicsLoggingDoFlush = pConfig.GetBoolean("PhysicsLoggingDoFlush", false); + // Very detailed logging for vehicle debugging + VehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false); + VehiclePhysicalLoggingEnabled = pConfig.GetBoolean("VehiclePhysicalLoggingEnabled", false); + + // Do any replacements in the parameters + m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName); + } + + // The material characteristics. + BSMaterials.InitializeFromDefaults(Params); + if (pConfig != null) + { + // Let the user add new and interesting material property values. + BSMaterials.InitializefromParameters(pConfig); + } + } + } + + // A helper function that handles a true/false parameter and returns the proper float number encoding + float ParamBoolean(IConfig config, string parmName, float deflt) + { + float ret = deflt; + if (config.Contains(parmName)) + { + ret = ConfigurationParameters.numericFalse; + if (config.GetBoolean(parmName, false)) + { + ret = ConfigurationParameters.numericTrue; + } + } + return ret; + } + + // Called directly from unmanaged code so don't do much + private void BulletLogger(string msg) + { + m_log.Debug("[BULLETS UNMANAGED]:" + msg); + } + + // Called directly from unmanaged code so don't do much + private void BulletLoggerPhysLog(string msg) + { + DetailLog("[BULLETS UNMANAGED]:" + msg); + } + + public override void Dispose() + { + // m_log.DebugFormat("{0}: Dispose()", LogHeader); + + // make sure no stepping happens while we're deleting stuff + m_initialized = false; + + foreach (KeyValuePair kvp in PhysObjects) + { + kvp.Value.Destroy(); + } + PhysObjects.Clear(); + + // Now that the prims are all cleaned up, there should be no constraints left + if (Constraints != null) + { + Constraints.Dispose(); + Constraints = null; + } + + if (Shapes != null) + { + Shapes.Dispose(); + Shapes = null; + } + + if (TerrainManager != null) + { + TerrainManager.ReleaseGroundPlaneAndTerrain(); + TerrainManager.Dispose(); + TerrainManager = null; + } + + // Anything left in the unmanaged code should be cleaned out + BulletSimAPI.Shutdown2(World.ptr); + + // Not logging any more + PhysicsLogging.Close(); + } + #endregion // Construction and Initialization + + #region Prim and Avatar addition and removal + + public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying) + { + m_log.ErrorFormat("{0}: CALL TO AddAvatar in BSScene. NOT IMPLEMENTED", LogHeader); + return null; + } + + public override PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, bool isFlying) + { + // m_log.DebugFormat("{0}: AddAvatar: {1}", LogHeader, avName); + + if (!m_initialized) return null; + + BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying); + lock (PhysObjects) PhysObjects.Add(localID, actor); + + // TODO: Remove kludge someday. + // We must generate a collision for avatars whether they collide or not. + // This is required by OpenSim to update avatar animations, etc. + lock (m_avatars) m_avatars.Add(actor); + + return actor; + } + + public override void RemoveAvatar(PhysicsActor actor) + { + // m_log.DebugFormat("{0}: RemoveAvatar", LogHeader); + + if (!m_initialized) return; + + BSCharacter bsactor = actor as BSCharacter; + if (bsactor != null) + { + try + { + lock (PhysObjects) PhysObjects.Remove(actor.LocalID); + // Remove kludge someday + lock (m_avatars) m_avatars.Remove(bsactor); + } + catch (Exception e) + { + m_log.WarnFormat("{0}: Attempt to remove avatar that is not in physics scene: {1}", LogHeader, e); + } + bsactor.Destroy(); + // bsactor.dispose(); + } + } + + public override void RemovePrim(PhysicsActor prim) + { + if (!m_initialized) return; + + BSPrim bsprim = prim as BSPrim; + if (bsprim != null) + { + DetailLog("{0},RemovePrim,call", bsprim.LocalID); + // m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID); + try + { + lock (PhysObjects) PhysObjects.Remove(bsprim.LocalID); + } + catch (Exception e) + { + m_log.ErrorFormat("{0}: Attempt to remove prim that is not in physics scene: {1}", LogHeader, e); + } + bsprim.Destroy(); + // bsprim.dispose(); + } + else + { + m_log.ErrorFormat("{0}: Attempt to remove prim that is not a BSPrim type.", LogHeader); + } + } + + public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, + Vector3 size, Quaternion rotation, bool isPhysical, uint localID) + { + // m_log.DebugFormat("{0}: AddPrimShape2: {1}", LogHeader, primName); + + if (!m_initialized) return null; + + DetailLog("{0},AddPrimShape,call", localID); + + BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical); + lock (PhysObjects) PhysObjects.Add(localID, prim); + return prim; + } + + // This is a call from the simulator saying that some physical property has been updated. + // The BulletSim driver senses the changing of relevant properties so this taint + // information call is not needed. + public override void AddPhysicsActorTaint(PhysicsActor prim) { } + + #endregion // Prim and Avatar addition and removal + + #region Simulation + // Simulate one timestep + public override float Simulate(float timeStep) + { + // prevent simulation until we've been initialized + if (!m_initialized) return 5.0f; + + LastTimeStep = timeStep; + + int updatedEntityCount = 0; + //Object updatedEntitiesPtr; + int collidersCount = 0; + //Object collidersPtr; + + int beforeTime = 0; + int simTime = 0; + + // update the prim states while we know the physics engine is not busy + int numTaints = _taintOperations.Count; + + InTaintTime = true; // Only used for debugging so locking is not necessary. + + ProcessTaints(); + + // Some of the physical objects requre individual, pre-step calls + TriggerPreStepEvent(timeStep); + + // the prestep actions might have added taints + ProcessTaints(); + + InTaintTime = false; // Only used for debugging so locking is not necessary. + + // step the physical world one interval + m_simulationStep++; + int numSubSteps = 0; + + try + { + //if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG + if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount(); + + numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep, + out updatedEntityCount, out m_updateArray, out collidersCount, out m_collisionArray); + + if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime); + DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}, objWColl={7}", + DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, + updatedEntityCount, collidersCount, ObjectsWithCollisions.Count); + } + catch (Exception e) + { + m_log.WarnFormat("{0},PhysicsStep Exception: nTaints={1}, substeps={2}, updates={3}, colliders={4}, e={5}", + LogHeader, numTaints, numSubSteps, updatedEntityCount, collidersCount, e); + DetailLog("{0},PhysicsStepException,call, nTaints={1}, substeps={2}, updates={3}, colliders={4}", + DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount); + updatedEntityCount = 0; + collidersCount = 0; + } + + // Don't have to use the pointers passed back since we know it is the same pinned memory we passed in. + + // Get a value for 'now' so all the collision and update routines don't have to get their own. + SimulationNowTime = Util.EnvironmentTickCount(); + + // If there were collisions, process them by sending the event to the prim. + // Collisions must be processed before updates. + if (collidersCount > 0) + { + for (int ii = 0; ii < collidersCount; ii++) + { + uint cA = m_collisionArray[ii].aID; + uint cB = m_collisionArray[ii].bID; + Vector3 point = new Vector3(m_collisionArray[ii].point.X, m_collisionArray[ii].point.Y, + m_collisionArray[ii].point.Z); + Vector3 normal = new Vector3(m_collisionArray[ii].normal.X, m_collisionArray[ii].normal.Y, + m_collisionArray[ii].normal.Z); + SendCollision(cA, cB, point, normal, 0.01f); + SendCollision(cB, cA, point, -normal, 0.01f); + } + } + + // The above SendCollision's batch up the collisions on the objects. + // Now push the collisions into the simulator. + if (ObjectsWithCollisions.Count > 0) + { + foreach (BSPhysObject bsp in ObjectsWithCollisions) + if (!bsp.SendCollisions()) + { + // If the object is done colliding, see that it's removed from the colliding list + ObjectsWithNoMoreCollisions.Add(bsp); + } + } + + // This is a kludge to get avatar movement updates. + // The simulator expects collisions for avatars even if there are have been no collisions. + // The event updates avatar animations and stuff. + // If you fix avatar animation updates, remove this overhead and let normal collision processing happen. + foreach (BSPhysObject bsp in m_avatars) + if (!ObjectsWithCollisions.Contains(bsp)) // don't call avatars twice + bsp.SendCollisions(); + + // Objects that are done colliding are removed from the ObjectsWithCollisions list. + // Not done above because it is inside an iteration of ObjectWithCollisions. + // This complex collision processing is required to create an empty collision + // event call after all collisions have happened on an object. This enables + // the simulator to generate the 'collision end' event. + if (ObjectsWithNoMoreCollisions.Count > 0) + { + foreach (BSPhysObject po in ObjectsWithNoMoreCollisions) + ObjectsWithCollisions.Remove(po); + ObjectsWithNoMoreCollisions.Clear(); + } + // Done with collisions. + + // If any of the objects had updated properties, tell the object it has been changed by the physics engine + if (updatedEntityCount > 0) + { + for (int ii = 0; ii < updatedEntityCount; ii++) + { + + BulletXNA.EntityProperties entprop = m_updateArray[ii]; + BSPhysObject pobj; + if (PhysObjects.TryGetValue(entprop.ID, out pobj)) + { + EntityProperties prop = new EntityProperties() + { + Acceleration = new Vector3(entprop.Acceleration.X, entprop.Acceleration.Y, entprop.Acceleration.Z), + ID = entprop.ID, + Position = new Vector3(entprop.Position.X,entprop.Position.Y,entprop.Position.Z), + Rotation = new Quaternion(entprop.Rotation.X,entprop.Rotation.Y,entprop.Rotation.Z,entprop.Rotation.W), + RotationalVelocity = new Vector3(entprop.AngularVelocity.X,entprop.AngularVelocity.Y,entprop.AngularVelocity.Z), + Velocity = new Vector3(entprop.Velocity.X,entprop.Velocity.Y,entprop.Velocity.Z) + }; + //m_log.Debug(pobj.Name + ":" + prop.ToString() + "\n"); + pobj.UpdateProperties(prop); + } + } + } + + TriggerPostStepEvent(timeStep); + + // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world. + // Only enable this in a limited test world with few objects. + // BulletSimAPI.DumpAllInfo2(World.ptr); // DEBUG DEBUG DEBUG + + // The physics engine returns the number of milliseconds it simulated this call. + // These are summed and normalized to one second and divided by 1000 to give the reported physics FPS. + // Multiply by 55 to give a nominal frame rate of 55. + return (float)numSubSteps * m_fixedTimeStep * 1000f * 55f; + } + + // Something has collided + private void SendCollision(uint localID, uint collidingWith, Vector3 collidePoint, Vector3 collideNormal, float penetration) + { + if (localID <= TerrainManager.HighestTerrainID) + { + return; // don't send collisions to the terrain + } + + BSPhysObject collider; + if (!PhysObjects.TryGetValue(localID, out collider)) + { + // If the object that is colliding cannot be found, just ignore the collision. + DetailLog("{0},BSScene.SendCollision,colliderNotInObjectList,id={1},with={2}", DetailLogZero, localID, collidingWith); + return; + } + + // The terrain is not in the physical object list so 'collidee' can be null when Collide() is called. + BSPhysObject collidee = null; + PhysObjects.TryGetValue(collidingWith, out collidee); + + // DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith); + + if (collider.Collide(collidingWith, collidee, collidePoint, collideNormal, penetration)) + { + // If a collision was posted, remember to send it to the simulator + ObjectsWithCollisions.Add(collider); + } + + return; + } + + #endregion // Simulation + + public override void GetResults() { } + + #region Terrain + + public override void SetTerrain(float[] heightMap) { + TerrainManager.SetTerrain(heightMap); + } + + public override void SetWaterLevel(float baseheight) + { + SimpleWaterLevel = baseheight; + } + + public override void DeleteTerrain() + { + // m_log.DebugFormat("{0}: DeleteTerrain()", LogHeader); + } + + // Although no one seems to check this, I do support combining. + public override bool SupportsCombining() + { + return TerrainManager.SupportsCombining(); + } + // This call says I am a child to region zero in a mega-region. 'pScene' is that + // of region zero, 'offset' is my offset from regions zero's origin, and + // 'extents' is the largest XY that is handled in my region. + public override void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents) + { + TerrainManager.Combine(pScene, offset, extents); + } + + // Unhook all the combining that I know about. + public override void UnCombine(PhysicsScene pScene) + { + TerrainManager.UnCombine(pScene); + } + + #endregion // Terrain + + public override Dictionary GetTopColliders() + { + return new Dictionary(); + } + + public override bool IsThreaded { get { return false; } } + + #region Taints + // The simulation execution order is: + // Simulate() + // DoOneTimeTaints + // TriggerPreStepEvent + // DoOneTimeTaints + // Step() + // ProcessAndForwardCollisions + // ProcessAndForwardPropertyUpdates + // TriggerPostStepEvent + + // Calls to the PhysicsActors can't directly call into the physics engine + // because it might be busy. We delay changes to a known time. + // We rely on C#'s closure to save and restore the context for the delegate. + public void TaintedObject(String ident, TaintCallback callback) + { + if (!m_initialized) return; + + lock (_taintLock) + { + _taintOperations.Add(new TaintCallbackEntry(ident, callback)); + } + + return; + } + + // Sometimes a potentially tainted operation can be used in and out of taint time. + // This routine executes the command immediately if in taint-time otherwise it is queued. + public void TaintedObject(bool inTaintTime, string ident, TaintCallback callback) + { + if (inTaintTime) + callback(); + else + TaintedObject(ident, callback); + } + + private void TriggerPreStepEvent(float timeStep) + { + PreStepAction actions = BeforeStep; + if (actions != null) + actions(timeStep); + + } + + private void TriggerPostStepEvent(float timeStep) + { + PreStepAction actions = AfterStep; + if (actions != null) + actions(timeStep); + + } + + // When someone tries to change a property on a BSPrim or BSCharacter, the object queues + // a callback into itself to do the actual property change. That callback is called + // here just before the physics engine is called to step the simulation. + public void ProcessTaints() + { + ProcessRegularTaints(); + ProcessPostTaintTaints(); + } + + private void ProcessRegularTaints() + { + if (_taintOperations.Count > 0) // save allocating new list if there is nothing to process + { + // swizzle a new list into the list location so we can process what's there + List oldList; + lock (_taintLock) + { + oldList = _taintOperations; + _taintOperations = new List(); + } + + foreach (TaintCallbackEntry tcbe in oldList) + { + try + { + DetailLog("{0},BSScene.ProcessTaints,doTaint,id={1}", DetailLogZero, tcbe.ident); // DEBUG DEBUG DEBUG + tcbe.callback(); + } + catch (Exception e) + { + m_log.ErrorFormat("{0}: ProcessTaints: {1}: Exception: {2}", LogHeader, tcbe.ident, e); + } + } + oldList.Clear(); + } + } + + // Schedule an update to happen after all the regular taints are processed. + // Note that new requests for the same operation ("ident") for the same object ("ID") + // will replace any previous operation by the same object. + public void PostTaintObject(String ident, uint ID, TaintCallback callback) + { + string uniqueIdent = ident + "-" + ID.ToString(); + lock (_taintLock) + { + _postTaintOperations[uniqueIdent] = new TaintCallbackEntry(uniqueIdent, callback); + } + + return; + } + + // Taints that happen after the normal taint processing but before the simulation step. + private void ProcessPostTaintTaints() + { + if (_postTaintOperations.Count > 0) + { + Dictionary oldList; + lock (_taintLock) + { + oldList = _postTaintOperations; + _postTaintOperations = new Dictionary(); + } + + foreach (KeyValuePair kvp in oldList) + { + try + { + DetailLog("{0},BSScene.ProcessPostTaintTaints,doTaint,id={1}", DetailLogZero, kvp.Key); // DEBUG DEBUG DEBUG + kvp.Value.callback(); + } + catch (Exception e) + { + m_log.ErrorFormat("{0}: ProcessPostTaintTaints: {1}: Exception: {2}", LogHeader, kvp.Key, e); + } + } + oldList.Clear(); + } + } + + // Only used for debugging. Does not change state of anything so locking is not necessary. + public bool AssertInTaintTime(string whereFrom) + { + if (!InTaintTime) + { + DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom); + m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom); + Util.PrintCallStack(); // Prints the stack into the DEBUG log file. + } + return InTaintTime; + } + + #endregion // Taints + + #region INI and command line parameter processing + + #region IPhysicsParameters + // Get the list of parameters this physics engine supports + public PhysParameterEntry[] GetParameterList() + { + BSParam.BuildParameterTable(); + return BSParam.SettableParameters; + } + + // Set parameter on a specific or all instances. + // Return 'false' if not able to set the parameter. + // Setting the value in the m_params block will change the value the physics engine + // will use the next time since it's pinned and shared memory. + // Some of the values require calling into the physics engine to get the new + // value activated ('terrainFriction' for instance). + public bool SetPhysicsParameter(string parm, float val, uint localID) + { + bool ret = false; + BSParam.ParameterDefn theParam; + if (BSParam.TryGetParameter(parm, out theParam)) + { + theParam.setter(this, parm, localID, val); + ret = true; + } + return ret; + } + + // update all the localIDs specified + // If the local ID is APPLY_TO_NONE, just change the default value + // If the localID is APPLY_TO_ALL change the default value and apply the new value to all the lIDs + // If the localID is a specific object, apply the parameter change to only that object + internal delegate void AssignVal(float x); + internal void UpdateParameterObject(AssignVal setDefault, string parm, uint localID, float val) + { + List objectIDs = new List(); + switch (localID) + { + case PhysParameterEntry.APPLY_TO_NONE: + setDefault(val); // setting only the default value + // This will cause a call into the physical world if some operation is specified (SetOnObject). + objectIDs.Add(TERRAIN_ID); + TaintedUpdateParameter(parm, objectIDs, val); + break; + case PhysParameterEntry.APPLY_TO_ALL: + setDefault(val); // setting ALL also sets the default value + lock (PhysObjects) objectIDs = new List(PhysObjects.Keys); + TaintedUpdateParameter(parm, objectIDs, val); + break; + default: + // setting only one localID + objectIDs.Add(localID); + TaintedUpdateParameter(parm, objectIDs, val); + break; + } + } + + // schedule the actual updating of the paramter to when the phys engine is not busy + private void TaintedUpdateParameter(string parm, List lIDs, float val) + { + float xval = val; + List xlIDs = lIDs; + string xparm = parm; + TaintedObject("BSScene.UpdateParameterSet", delegate() { + BSParam.ParameterDefn thisParam; + if (BSParam.TryGetParameter(xparm, out thisParam)) + { + if (thisParam.onObject != null) + { + foreach (uint lID in xlIDs) + { + BSPhysObject theObject = null; + PhysObjects.TryGetValue(lID, out theObject); + thisParam.onObject(this, theObject, xval); + } + } + } + }); + } + + // Get parameter. + // Return 'false' if not able to get the parameter. + public bool GetPhysicsParameter(string parm, out float value) + { + float val = 0f; + bool ret = false; + BSParam.ParameterDefn theParam; + if (BSParam.TryGetParameter(parm, out theParam)) + { + val = theParam.getter(this); + ret = true; + } + value = val; + return ret; + } + + #endregion IPhysicsParameters + + #endregion Runtime settable parameters + + // Invoke the detailed logger and output something if it's enabled. + public void DetailLog(string msg, params Object[] args) + { + PhysicsLogging.Write(msg, args); + // Add the Flush() if debugging crashes. Gets all the messages written out. + if (m_physicsLoggingDoFlush) PhysicsLogging.Flush(); + } + // Used to fill in the LocalID when there isn't one. It's the correct number of characters. + public const string DetailLogZero = "0000000000"; + +} +} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSShapeCollection.cs new file mode 100644 index 0000000..398ece0 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSShapeCollection.cs @@ -0,0 +1,1015 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using OMV = OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Physics.Manager; +using OpenSim.Region.Physics.ConvexDecompositionDotNet; + +namespace OpenSim.Region.Physics.BulletSNPlugin +{ +public sealed class BSShapeCollection : IDisposable +{ + private static string LogHeader = "[BULLETSIM SHAPE COLLECTION]"; + + private BSScene PhysicsScene { get; set; } + + private Object m_collectionActivityLock = new Object(); + + // Description of a Mesh + private struct MeshDesc + { + public Object ptr; + public int referenceCount; + public DateTime lastReferenced; + public UInt64 shapeKey; + } + + // Description of a hull. + // Meshes and hulls have the same shape hash key but we only need hulls for efficient collision calculations. + private struct HullDesc + { + public Object ptr; + public int referenceCount; + public DateTime lastReferenced; + public UInt64 shapeKey; + } + + // The sharable set of meshes and hulls. Indexed by their shape hash. + private Dictionary Meshes = new Dictionary(); + private Dictionary Hulls = new Dictionary(); + + private bool DDetail = false; + + public BSShapeCollection(BSScene physScene) + { + PhysicsScene = physScene; + // Set the next to 'true' for very detailed shape update detailed logging (detailed details?) + // While detailed debugging is still active, this is better than commenting out all the + // DetailLog statements. When debugging slows down, this and the protected logging + // statements can be commented/removed. + DDetail = true; + } + + public void Dispose() + { + // TODO!!!!!!!!! + } + + // Callbacks called just before either the body or shape is destroyed. + // Mostly used for changing bodies out from under Linksets. + // Useful for other cases where parameters need saving. + // Passing 'null' says no callback. + public delegate void ShapeDestructionCallback(BulletShape shape); + public delegate void BodyDestructionCallback(BulletBody body); + + // Called to update/change the body and shape for an object. + // First checks the shape and updates that if necessary then makes + // sure the body is of the right type. + // Return 'true' if either the body or the shape changed. + // 'shapeCallback' and 'bodyCallback' are, if non-null, functions called just before + // the current shape or body is destroyed. This allows the caller to remove any + // higher level dependencies on the shape or body. Mostly used for LinkSets to + // remove the physical constraints before the body is destroyed. + // Called at taint-time!! + public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim, + ShapeDestructionCallback shapeCallback, BodyDestructionCallback bodyCallback) + { + PhysicsScene.AssertInTaintTime("BSShapeCollection.GetBodyAndShape"); + + bool ret = false; + + // This lock could probably be pushed down lower but building shouldn't take long + lock (m_collectionActivityLock) + { + // Do we have the correct geometry for this type of object? + // Updates prim.BSShape with information/pointers to shape. + // Returns 'true' of BSShape is changed to a new shape. + bool newGeom = CreateGeom(forceRebuild, prim, shapeCallback); + // If we had to select a new shape geometry for the object, + // rebuild the body around it. + // Updates prim.BSBody with information/pointers to requested body + // Returns 'true' if BSBody was changed. + bool newBody = CreateBody((newGeom || forceRebuild), prim, PhysicsScene.World, + prim.PhysShape, bodyCallback); + ret = newGeom || newBody; + } + DetailLog("{0},BSShapeCollection.GetBodyAndShape,taintExit,force={1},ret={2},body={3},shape={4}", + prim.LocalID, forceRebuild, ret, prim.PhysBody, prim.PhysShape); + + return ret; + } + + public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim) + { + return GetBodyAndShape(forceRebuild, sim, prim, null, null); + } + + // Track another user of a body. + // We presume the caller has allocated the body. + // Bodies only have one user so the body is just put into the world if not already there. + public void ReferenceBody(BulletBody body, bool inTaintTime) + { + lock (m_collectionActivityLock) + { + if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,body={1}", body.ID, body); + PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.ReferenceBody", delegate() + { + if (!BulletSimAPI.IsInWorld2(PhysicsScene.World.ptr, body.ptr)) + { + BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, body.ptr); + if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", body.ID, body); + } + }); + } + } + + // Release the usage of a body. + // Called when releasing use of a BSBody. BSShape is handled separately. + public void DereferenceBody(BulletBody body, bool inTaintTime, BodyDestructionCallback bodyCallback ) + { + if (!body.HasPhysicalBody) + return; + + lock (m_collectionActivityLock) + { + PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceBody", delegate() + { + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1},inTaintTime={2}", + body.ID, body, inTaintTime); + // If the caller needs to know the old body is going away, pass the event up. + if (bodyCallback != null) bodyCallback(body); + + if (BulletSimAPI.IsInWorld2(PhysicsScene.World.ptr, body.ptr)) + { + BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr); + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,removingFromWorld. Body={1}", body.ID, body); + } + + // Zero any reference to the shape so it is not freed when the body is deleted. + BulletSimAPI.SetCollisionShape2(PhysicsScene.World.ptr, body.ptr, null); + BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, body.ptr); + }); + } + } + + // Track the datastructures and use count for a shape. + // When creating a hull, this is called first to reference the mesh + // and then again to reference the hull. + // Meshes and hulls for the same shape have the same hash key. + // NOTE that native shapes are not added to the mesh list or removed. + // Returns 'true' if this is the initial reference to the shape. Otherwise reused. + public bool ReferenceShape(BulletShape shape) + { + bool ret = false; + switch (shape.type) + { + case BSPhysicsShapeType.SHAPE_MESH: + MeshDesc meshDesc; + if (Meshes.TryGetValue(shape.shapeKey, out meshDesc)) + { + // There is an existing instance of this mesh. + meshDesc.referenceCount++; + if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,existingMesh,key={1},cnt={2}", + BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount); + } + else + { + // This is a new reference to a mesh + meshDesc.ptr = shape.ptr; + meshDesc.shapeKey = shape.shapeKey; + // We keep a reference to the underlying IMesh data so a hull can be built + meshDesc.referenceCount = 1; + if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,newMesh,key={1},cnt={2}", + BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount); + ret = true; + } + meshDesc.lastReferenced = System.DateTime.Now; + Meshes[shape.shapeKey] = meshDesc; + break; + case BSPhysicsShapeType.SHAPE_HULL: + HullDesc hullDesc; + if (Hulls.TryGetValue(shape.shapeKey, out hullDesc)) + { + // There is an existing instance of this hull. + hullDesc.referenceCount++; + if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,existingHull,key={1},cnt={2}", + BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount); + } + else + { + // This is a new reference to a hull + hullDesc.ptr = shape.ptr; + hullDesc.shapeKey = shape.shapeKey; + hullDesc.referenceCount = 1; + if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,newHull,key={1},cnt={2}", + BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount); + ret = true; + + } + hullDesc.lastReferenced = System.DateTime.Now; + Hulls[shape.shapeKey] = hullDesc; + break; + case BSPhysicsShapeType.SHAPE_UNKNOWN: + break; + default: + // Native shapes are not tracked and they don't go into any list + break; + } + return ret; + } + + // Release the usage of a shape. + public void DereferenceShape(BulletShape shape, bool inTaintTime, ShapeDestructionCallback shapeCallback) + { + if (!shape.HasPhysicalShape) + return; + + PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceShape", delegate() + { + if (shape.HasPhysicalShape) + { + if (shape.isNativeShape) + { + // Native shapes are not tracked and are released immediately + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}", + BSScene.DetailLogZero, shape.ptr.ToString(), inTaintTime); + if (shapeCallback != null) shapeCallback(shape); + BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr); + } + else + { + switch (shape.type) + { + case BSPhysicsShapeType.SHAPE_HULL: + DereferenceHull(shape, shapeCallback); + break; + case BSPhysicsShapeType.SHAPE_MESH: + DereferenceMesh(shape, shapeCallback); + break; + case BSPhysicsShapeType.SHAPE_COMPOUND: + DereferenceCompound(shape, shapeCallback); + break; + case BSPhysicsShapeType.SHAPE_UNKNOWN: + break; + default: + break; + } + } + } + }); + } + + // Count down the reference count for a mesh shape + // Called at taint-time. + private void DereferenceMesh(BulletShape shape, ShapeDestructionCallback shapeCallback) + { + MeshDesc meshDesc; + if (Meshes.TryGetValue(shape.shapeKey, out meshDesc)) + { + meshDesc.referenceCount--; + // TODO: release the Bullet storage + if (shapeCallback != null) shapeCallback(shape); + meshDesc.lastReferenced = System.DateTime.Now; + Meshes[shape.shapeKey] = meshDesc; + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceMesh,shape={1},refCnt={2}", + BSScene.DetailLogZero, shape, meshDesc.referenceCount); + + } + } + + // Count down the reference count for a hull shape + // Called at taint-time. + private void DereferenceHull(BulletShape shape, ShapeDestructionCallback shapeCallback) + { + HullDesc hullDesc; + if (Hulls.TryGetValue(shape.shapeKey, out hullDesc)) + { + hullDesc.referenceCount--; + // TODO: release the Bullet storage (aging old entries?) + + // Tell upper layers that, if they have dependencies on this shape, this link is going away + if (shapeCallback != null) shapeCallback(shape); + + hullDesc.lastReferenced = System.DateTime.Now; + Hulls[shape.shapeKey] = hullDesc; + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceHull,shape={1},refCnt={2}", + BSScene.DetailLogZero, shape, hullDesc.referenceCount); + } + } + + // Remove a reference to a compound shape. + // Taking a compound shape apart is a little tricky because if you just delete the + // physical shape, it will free all the underlying children. We can't do that because + // they could be shared. So, this removes each of the children from the compound and + // dereferences them separately before destroying the compound collision object itself. + // Called at taint-time. + private void DereferenceCompound(BulletShape shape, ShapeDestructionCallback shapeCallback) + { + if (!BulletSimAPI.IsCompound2(shape.ptr)) + { + // Failed the sanity check!! + PhysicsScene.Logger.ErrorFormat("{0} Attempt to free a compound shape that is not compound!! type={1}, ptr={2}", + LogHeader, shape.type, shape.ptr.ToString()); + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceCompound,notACompoundShape,type={1},ptr={2}", + BSScene.DetailLogZero, shape.type, shape.ptr.ToString()); + return; + } + + int numChildren = BulletSimAPI.GetNumberOfCompoundChildren2(shape.ptr); + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceCompound,shape={1},children={2}", BSScene.DetailLogZero, shape, numChildren); + + for (int ii = numChildren - 1; ii >= 0; ii--) + { + Object childShape = BulletSimAPI.RemoveChildShapeFromCompoundShapeIndex2(shape.ptr, ii); + DereferenceAnonCollisionShape(childShape); + } + BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr); + } + + // Sometimes we have a pointer to a collision shape but don't know what type it is. + // Figure out type and call the correct dereference routine. + // Called at taint-time. + private void DereferenceAnonCollisionShape(Object cShape) + { + MeshDesc meshDesc; + HullDesc hullDesc; + + BulletShape shapeInfo = new BulletShape(cShape); + if (TryGetMeshByPtr(cShape, out meshDesc)) + { + shapeInfo.type = BSPhysicsShapeType.SHAPE_MESH; + shapeInfo.shapeKey = meshDesc.shapeKey; + } + else + { + if (TryGetHullByPtr(cShape, out hullDesc)) + { + shapeInfo.type = BSPhysicsShapeType.SHAPE_HULL; + shapeInfo.shapeKey = hullDesc.shapeKey; + } + else + { + if (BulletSimAPI.IsCompound2(cShape)) + { + shapeInfo.type = BSPhysicsShapeType.SHAPE_COMPOUND; + } + else + { + if (BulletSimAPI.IsNativeShape2(cShape)) + { + shapeInfo.isNativeShape = true; + shapeInfo.type = BSPhysicsShapeType.SHAPE_BOX; // (technically, type doesn't matter) + } + } + } + } + + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceAnonCollisionShape,shape={1}", BSScene.DetailLogZero, shapeInfo); + + if (shapeInfo.type != BSPhysicsShapeType.SHAPE_UNKNOWN) + { + DereferenceShape(shapeInfo, true, null); + } + else + { + PhysicsScene.Logger.ErrorFormat("{0} Could not decypher shape type. Region={1}, addr={2}", + LogHeader, PhysicsScene.RegionName, cShape.ToString()); + } + } + + // Create the geometry information in Bullet for later use. + // The objects needs a hull if it's physical otherwise a mesh is enough. + // if 'forceRebuild' is true, the geometry is unconditionally rebuilt. For meshes and hulls, + // shared geometries will be used. If the parameters of the existing shape are the same + // as this request, the shape is not rebuilt. + // Info in prim.BSShape is updated to the new shape. + // Returns 'true' if the geometry was rebuilt. + // Called at taint-time! + private bool CreateGeom(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback) + { + bool ret = false; + bool haveShape = false; + + if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_CAPSULE) + { + // an avatar capsule is close to a native shape (it is not shared) + GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_CAPSULE, + FixedShapeKey.KEY_CAPSULE, shapeCallback); + if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape); + ret = true; + haveShape = true; + } + + // Compound shapes are handled special as they are rebuilt from scratch. + // This isn't too great a hardship since most of the child shapes will have already been created. + if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND) + { + ret = GetReferenceToCompoundShape(prim, shapeCallback); + if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, prim.PhysShape); + haveShape = true; + } + + if (!haveShape) + { + ret = CreateGeomNonSpecial(forceRebuild, prim, shapeCallback); + } + + return ret; + } + + // Create a mesh/hull shape or a native shape if 'nativeShapePossible' is 'true'. + public bool CreateGeomNonSpecial(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback) + { + bool ret = false; + bool haveShape = false; + bool nativeShapePossible = true; + PrimitiveBaseShape pbs = prim.BaseShape; + + // If the prim attributes are simple, this could be a simple Bullet native shape + if (!haveShape + && pbs != null + && nativeShapePossible + && ((pbs.SculptEntry && !BSParam.ShouldMeshSculptedPrim) + || (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0 + && pbs.ProfileHollow == 0 + && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0 + && pbs.PathBegin == 0 && pbs.PathEnd == 0 + && pbs.PathTaperX == 0 && pbs.PathTaperY == 0 + && pbs.PathScaleX == 100 && pbs.PathScaleY == 100 + && pbs.PathShearX == 0 && pbs.PathShearY == 0) ) ) + { + // Get the scale of any existing shape so we can see if the new shape is same native type and same size. + OMV.Vector3 scaleOfExistingShape = OMV.Vector3.Zero; + if (prim.PhysShape.HasPhysicalShape) + scaleOfExistingShape = BulletSimAPI.GetLocalScaling2(prim.PhysShape.ptr); + + if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,maybeNative,force={1},primScale={2},primSize={3},primShape={4}", + prim.LocalID, forceRebuild, prim.Scale, prim.Size, prim.PhysShape.type); + + // It doesn't look like Bullet scales spheres so make sure the scales are all equal + if ((pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1) + && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z) + { + haveShape = true; + if (forceRebuild + || prim.Scale != scaleOfExistingShape + || prim.PhysShape.type != BSPhysicsShapeType.SHAPE_SPHERE + ) + { + ret = GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_SPHERE, + FixedShapeKey.KEY_SPHERE, shapeCallback); + if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}", + prim.LocalID, forceRebuild, prim.PhysShape); + } + } + if (!haveShape && pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight) + { + haveShape = true; + if (forceRebuild + || prim.Scale != scaleOfExistingShape + || prim.PhysShape.type != BSPhysicsShapeType.SHAPE_BOX + ) + { + ret = GetReferenceToNativeShape( prim, BSPhysicsShapeType.SHAPE_BOX, + FixedShapeKey.KEY_BOX, shapeCallback); + if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}", + prim.LocalID, forceRebuild, prim.PhysShape); + } + } + } + + // If a simple shape is not happening, create a mesh and possibly a hull. + if (!haveShape && pbs != null) + { + ret = CreateGeomMeshOrHull(prim, shapeCallback); + } + + return ret; + } + + public bool CreateGeomMeshOrHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback) + { + + bool ret = false; + // Note that if it's a native shape, the check for physical/non-physical is not + // made. Native shapes work in either case. + if (prim.IsPhysical && BSParam.ShouldUseHullsForPhysicalObjects) + { + // Update prim.BSShape to reference a hull of this shape. + ret = GetReferenceToHull(prim,shapeCallback); + if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", + prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); + } + else + { + ret = GetReferenceToMesh(prim, shapeCallback); + if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}", + prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); + } + return ret; + } + + // Creates a native shape and assignes it to prim.BSShape. + // "Native" shapes are never shared. they are created here and destroyed in DereferenceShape(). + private bool GetReferenceToNativeShape(BSPhysObject prim, + BSPhysicsShapeType shapeType, FixedShapeKey shapeKey, + ShapeDestructionCallback shapeCallback) + { + // release any previous shape + DereferenceShape(prim.PhysShape, true, shapeCallback); + + BulletShape newShape = BuildPhysicalNativeShape(prim, shapeType, shapeKey); + + // Don't need to do a 'ReferenceShape()' here because native shapes are not shared. + if (DDetail) DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1},scale={2}", + prim.LocalID, newShape, prim.Scale); + + // native shapes are scaled by Bullet + prim.PhysShape = newShape; + return true; + } + + private BulletShape BuildPhysicalNativeShape(BSPhysObject prim, BSPhysicsShapeType shapeType, + FixedShapeKey shapeKey) + { + BulletShape newShape; + // Need to make sure the passed shape information is for the native type. + ShapeData nativeShapeData = new ShapeData(); + nativeShapeData.Type = shapeType; + nativeShapeData.ID = prim.LocalID; + nativeShapeData.Scale = prim.Scale; + nativeShapeData.Size = prim.Scale; // unneeded, I think. + nativeShapeData.MeshKey = (ulong)shapeKey; + nativeShapeData.HullKey = (ulong)shapeKey; + + if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE) + { + // The proper scale has been calculated in the prim. + newShape = new BulletShape( + BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale) + , shapeType); + if (DDetail) DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); + } + else + { + // Native shapes are scaled in Bullet so set the scaling to the size + newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, nativeShapeData), shapeType); + } + if (!newShape.HasPhysicalShape) + { + PhysicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}", + LogHeader, prim.LocalID, shapeType); + } + newShape.shapeKey = (System.UInt64)shapeKey; + newShape.isNativeShape = true; + + return newShape; + } + + // Builds a mesh shape in the physical world and updates prim.BSShape. + // Dereferences previous shape in BSShape and adds a reference for this new shape. + // Returns 'true' of a mesh was actually built. Otherwise . + // Called at taint-time! + private bool GetReferenceToMesh(BSPhysObject prim, ShapeDestructionCallback shapeCallback) + { + BulletShape newShape = new BulletShape(); + + float lod; + System.UInt64 newMeshKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod); + + // if this new shape is the same as last time, don't recreate the mesh + if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_MESH) + return false; + + if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToMesh,create,oldKey={1},newKey={2}", + prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X")); + + // Since we're recreating new, get rid of the reference to the previous shape + DereferenceShape(prim.PhysShape, true, shapeCallback); + + newShape = CreatePhysicalMesh(prim.PhysObjectName, newMeshKey, prim.BaseShape, prim.Size, lod); + // Take evasive action if the mesh was not constructed. + newShape = VerifyMeshCreated(newShape, prim); + + ReferenceShape(newShape); + + prim.PhysShape = newShape; + + return true; // 'true' means a new shape has been added to this prim + } + + private BulletShape CreatePhysicalMesh(string objName, System.UInt64 newMeshKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) + { + IMesh meshData = null; + Object meshPtr = null; + MeshDesc meshDesc; + if (Meshes.TryGetValue(newMeshKey, out meshDesc)) + { + // If the mesh has already been built just use it. + meshPtr = meshDesc.ptr; + } + else + { + meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false); + + if (meshData != null) + { + int[] indices = meshData.getIndexListAsInt(); + List vertices = meshData.getVertexList(); + + float[] verticesAsFloats = new float[vertices.Count * 3]; + int vi = 0; + foreach (OMV.Vector3 vv in vertices) + { + verticesAsFloats[vi++] = vv.X; + verticesAsFloats[vi++] = vv.Y; + verticesAsFloats[vi++] = vv.Z; + } + + // m_log.DebugFormat("{0}: BSShapeCollection.CreatePhysicalMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}", + // LogHeader, prim.LocalID, newMeshKey, indices.Length, vertices.Count); + + meshPtr = BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, + indices.GetLength(0), indices, vertices.Count, verticesAsFloats); + } + } + BulletShape newShape = new BulletShape(meshPtr, BSPhysicsShapeType.SHAPE_MESH); + newShape.shapeKey = newMeshKey; + + return newShape; + } + + // See that hull shape exists in the physical world and update prim.BSShape. + // We could be creating the hull because scale changed or whatever. + private bool GetReferenceToHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback) + { + BulletShape newShape; + + float lod; + System.UInt64 newHullKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod); + + // if the hull hasn't changed, don't rebuild it + if (newHullKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_HULL) + return false; + + if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToHull,create,oldKey={1},newKey={2}", + prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newHullKey.ToString("X")); + + // Remove usage of the previous shape. + DereferenceShape(prim.PhysShape, true, shapeCallback); + + newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, prim.BaseShape, prim.Size, lod); + newShape = VerifyMeshCreated(newShape, prim); + + ReferenceShape(newShape); + + prim.PhysShape = newShape; + return true; // 'true' means a new shape has been added to this prim + } + + List m_hulls; + private BulletShape CreatePhysicalHull(string objName, System.UInt64 newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) + { + + Object hullPtr = null; + HullDesc hullDesc; + if (Hulls.TryGetValue(newHullKey, out hullDesc)) + { + // If the hull shape already is created, just use it. + hullPtr = hullDesc.ptr; + } + else + { + // Build a new hull in the physical world + // Pass true for physicalness as this creates some sort of bounding box which we don't need + IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false); + if (meshData != null) + { + + int[] indices = meshData.getIndexListAsInt(); + List vertices = meshData.getVertexList(); + + //format conversion from IMesh format to DecompDesc format + List convIndices = new List(); + List convVertices = new List(); + for (int ii = 0; ii < indices.GetLength(0); ii++) + { + convIndices.Add(indices[ii]); + } + foreach (OMV.Vector3 vv in vertices) + { + convVertices.Add(new float3(vv.X, vv.Y, vv.Z)); + } + + // setup and do convex hull conversion + m_hulls = new List(); + DecompDesc dcomp = new DecompDesc(); + dcomp.mIndices = convIndices; + dcomp.mVertices = convVertices; + ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn); + // create the hull into the _hulls variable + convexBuilder.process(dcomp); + + // Convert the vertices and indices for passing to unmanaged. + // The hull information is passed as a large floating point array. + // The format is: + // convHulls[0] = number of hulls + // convHulls[1] = number of vertices in first hull + // convHulls[2] = hull centroid X coordinate + // convHulls[3] = hull centroid Y coordinate + // convHulls[4] = hull centroid Z coordinate + // convHulls[5] = first hull vertex X + // convHulls[6] = first hull vertex Y + // convHulls[7] = first hull vertex Z + // convHulls[8] = second hull vertex X + // ... + // convHulls[n] = number of vertices in second hull + // convHulls[n+1] = second hull centroid X coordinate + // ... + // + // TODO: is is very inefficient. Someday change the convex hull generator to return + // data structures that do not need to be converted in order to pass to Bullet. + // And maybe put the values directly into pinned memory rather than marshaling. + int hullCount = m_hulls.Count; + int totalVertices = 1; // include one for the count of the hulls + foreach (ConvexResult cr in m_hulls) + { + totalVertices += 4; // add four for the vertex count and centroid + totalVertices += cr.HullIndices.Count * 3; // we pass just triangles + } + float[] convHulls = new float[totalVertices]; + + convHulls[0] = (float)hullCount; + int jj = 1; + foreach (ConvexResult cr in m_hulls) + { + // copy vertices for index access + float3[] verts = new float3[cr.HullVertices.Count]; + int kk = 0; + foreach (float3 ff in cr.HullVertices) + { + verts[kk++] = ff; + } + + // add to the array one hull's worth of data + convHulls[jj++] = cr.HullIndices.Count; + convHulls[jj++] = 0f; // centroid x,y,z + convHulls[jj++] = 0f; + convHulls[jj++] = 0f; + foreach (int ind in cr.HullIndices) + { + convHulls[jj++] = verts[ind].x; + convHulls[jj++] = verts[ind].y; + convHulls[jj++] = verts[ind].z; + } + } + // create the hull data structure in Bullet + hullPtr = BulletSimAPI.CreateHullShape2(PhysicsScene.World.ptr, hullCount, convHulls); + } + } + + BulletShape newShape = new BulletShape(hullPtr, BSPhysicsShapeType.SHAPE_HULL); + newShape.shapeKey = newHullKey; + + return newShape; + } + + // Callback from convex hull creater with a newly created hull. + // Just add it to our collection of hulls for this shape. + private void HullReturn(ConvexResult result) + { + m_hulls.Add(result); + return; + } + + // Compound shapes are always built from scratch. + // This shouldn't be to bad since most of the parts will be meshes that had been built previously. + private bool GetReferenceToCompoundShape(BSPhysObject prim, ShapeDestructionCallback shapeCallback) + { + // Remove reference to the old shape + // Don't need to do this as the shape is freed when the new root shape is created below. + // DereferenceShape(prim.PhysShape, true, shapeCallback); + + BulletShape cShape = new BulletShape( + BulletSimAPI.CreateCompoundShape2(PhysicsScene.World.ptr, false), BSPhysicsShapeType.SHAPE_COMPOUND); + + // Create the shape for the root prim and add it to the compound shape. Cannot be a native shape. + CreateGeomMeshOrHull(prim, shapeCallback); + BulletSimAPI.AddChildShapeToCompoundShape2(cShape.ptr, prim.PhysShape.ptr, OMV.Vector3.Zero, OMV.Quaternion.Identity); + if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToCompoundShape,addRootPrim,compShape={1},rootShape={2}", + prim.LocalID, cShape, prim.PhysShape); + + prim.PhysShape = cShape; + + return true; + } + + // Create a hash of all the shape parameters to be used as a key + // for this particular shape. + private System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs, out float retLod) + { + // level of detail based on size and type of the object + float lod = BSParam.MeshLOD; + if (pbs.SculptEntry) + lod = BSParam.SculptLOD; + + // Mega prims usually get more detail because one can interact with shape approximations at this size. + float maxAxis = Math.Max(size.X, Math.Max(size.Y, size.Z)); + if (maxAxis > BSParam.MeshMegaPrimThreshold) + lod = BSParam.MeshMegaPrimLOD; + + retLod = lod; + return pbs.GetMeshKey(size, lod); + } + // For those who don't want the LOD + private System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs) + { + float lod; + return ComputeShapeKey(size, pbs, out lod); + } + + // The creation of a mesh or hull can fail if an underlying asset is not available. + // There are two cases: 1) the asset is not in the cache and it needs to be fetched; + // and 2) the asset cannot be converted (like failed decompression of JPEG2000s). + // The first case causes the asset to be fetched. The second case requires + // us to not loop forever. + // Called after creating a physical mesh or hull. If the physical shape was created, + // just return. + private BulletShape VerifyMeshCreated(BulletShape newShape, BSPhysObject prim) + { + // If the shape was successfully created, nothing more to do + if (newShape.HasPhysicalShape) + return newShape; + + // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset + if (prim.BaseShape.SculptEntry && !prim.LastAssetBuildFailed && prim.BaseShape.SculptTexture != OMV.UUID.Zero) + { + prim.LastAssetBuildFailed = true; + BSPhysObject xprim = prim; + DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset,lID={1},lastFailed={2}", + LogHeader, prim.LocalID, prim.LastAssetBuildFailed); + Util.FireAndForget(delegate + { + RequestAssetDelegate assetProvider = PhysicsScene.RequestAssetMethod; + if (assetProvider != null) + { + BSPhysObject yprim = xprim; // probably not necessary, but, just in case. + assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset) + { + if (!yprim.BaseShape.SculptEntry) + return; + if (yprim.BaseShape.SculptTexture.ToString() != asset.ID) + return; + + yprim.BaseShape.SculptData = asset.Data; + // This will cause the prim to see that the filler shape is not the right + // one and try again to build the object. + // No race condition with the normal shape setting since the rebuild is at taint time. + yprim.ForceBodyShapeRebuild(false); + + }); + } + }); + } + else + { + if (prim.LastAssetBuildFailed) + { + PhysicsScene.Logger.ErrorFormat("{0} Mesh failed to fetch asset. lID={1}, texture={2}", + LogHeader, prim.LocalID, prim.BaseShape.SculptTexture); + } + } + + // While we figure out the real problem, stick a simple native shape on the object. + BulletShape fillinShape = + BuildPhysicalNativeShape(prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX); + + return fillinShape; + } + + // Create a body object in Bullet. + // Updates prim.BSBody with the information about the new body if one is created. + // Returns 'true' if an object was actually created. + // Called at taint-time. + private bool CreateBody(bool forceRebuild, BSPhysObject prim, BulletSim sim, BulletShape shape, + BodyDestructionCallback bodyCallback) + { + bool ret = false; + + // the mesh, hull or native shape must have already been created in Bullet + bool mustRebuild = !prim.PhysBody.HasPhysicalBody; + + // If there is an existing body, verify it's of an acceptable type. + // If not a solid object, body is a GhostObject. Otherwise a RigidBody. + if (!mustRebuild) + { + CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(prim.PhysBody.ptr); + if (prim.IsSolid && bodyType != CollisionObjectTypes.CO_RIGID_BODY + || !prim.IsSolid && bodyType != CollisionObjectTypes.CO_GHOST_OBJECT) + { + // If the collisionObject is not the correct type for solidness, rebuild what's there + mustRebuild = true; + } + } + + if (mustRebuild || forceRebuild) + { + // Free any old body + DereferenceBody(prim.PhysBody, true, bodyCallback); + + BulletBody aBody; + Object bodyPtr = null; + if (prim.IsSolid) + { + bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr, + prim.LocalID, prim.RawPosition, prim.RawOrientation); + if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString()); + } + else + { + bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr, + prim.LocalID, prim.RawPosition, prim.RawOrientation); + if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString()); + } + aBody = new BulletBody(prim.LocalID, bodyPtr); + + ReferenceBody(aBody, true); + + prim.PhysBody = aBody; + + ret = true; + } + + return ret; + } + + private bool TryGetMeshByPtr(Object addr, out MeshDesc outDesc) + { + bool ret = false; + MeshDesc foundDesc = new MeshDesc(); + foreach (MeshDesc md in Meshes.Values) + { + if (md.ptr == addr) + { + foundDesc = md; + ret = true; + break; + } + + } + outDesc = foundDesc; + return ret; + } + + private bool TryGetHullByPtr(Object addr, out HullDesc outDesc) + { + bool ret = false; + HullDesc foundDesc = new HullDesc(); + foreach (HullDesc hd in Hulls.Values) + { + if (hd.ptr == addr) + { + foundDesc = hd; + ret = true; + break; + } + + } + outDesc = foundDesc; + return ret; + } + + private void DetailLog(string msg, params Object[] args) + { + if (PhysicsScene.PhysicsLogging.Enabled) + PhysicsScene.DetailLog(msg, args); + } +} +} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSShapes.cs new file mode 100644 index 0000000..8ff0275 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSShapes.cs @@ -0,0 +1,208 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OpenSim.Region.Physics.BulletSNPlugin +{ +public abstract class BSShape +{ + public Object ptr { get; set; } + public BSPhysicsShapeType type { get; set; } + public System.UInt64 key { get; set; } + public int referenceCount { get; set; } + public DateTime lastReferenced { get; set; } + + public BSShape() + { + ptr = null; + type = BSPhysicsShapeType.SHAPE_UNKNOWN; + key = 0; + referenceCount = 0; + lastReferenced = DateTime.Now; + } + + // Get a reference to a physical shape. Create if it doesn't exist + public static BSShape GetShapeReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) + { + BSShape ret = null; + + if (prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_CAPSULE) + { + // an avatar capsule is close to a native shape (it is not shared) + ret = BSShapeNative.GetReference(physicsScene, prim, BSPhysicsShapeType.SHAPE_CAPSULE, + FixedShapeKey.KEY_CAPSULE); + physicsScene.DetailLog("{0},BSShape.GetShapeReference,avatarCapsule,shape={1}", prim.LocalID, ret); + } + + // Compound shapes are handled special as they are rebuilt from scratch. + // This isn't too great a hardship since most of the child shapes will already been created. + if (ret == null && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND) + { + // Getting a reference to a compound shape gets you the compound shape with the root prim shape added + ret = BSShapeCompound.GetReference(prim); + physicsScene.DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, ret); + } + + if (ret == null) + ret = GetShapeReferenceNonSpecial(physicsScene, forceRebuild, prim); + + return ret; + } + public static BSShape GetShapeReferenceNonSpecial(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) + { + return null; + } + public static BSShape GetShapeReferenceNonNative(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) + { + return null; + } + + // Release the use of a physical shape. + public abstract void Dereference(BSScene physicsScene); + + // All shapes have a static call to get a reference to the physical shape + // protected abstract static BSShape GetReference(); + + public override string ToString() + { + StringBuilder buff = new StringBuilder(); + buff.Append(""); + return buff.ToString(); + } +} + +public class BSShapeNull : BSShape +{ + public BSShapeNull() : base() + { + } + public static BSShape GetReference() { return new BSShapeNull(); } + public override void Dereference(BSScene physicsScene) { /* The magic of garbage collection will make this go away */ } +} + +public class BSShapeNative : BSShape +{ + private static string LogHeader = "[BULLETSIM SHAPE NATIVE]"; + public BSShapeNative() : base() + { + } + public static BSShape GetReference(BSScene physicsScene, BSPhysObject prim, + BSPhysicsShapeType shapeType, FixedShapeKey shapeKey) + { + // Native shapes are not shared and are always built anew. + return new BSShapeNative(physicsScene, prim, shapeType, shapeKey); + } + + private BSShapeNative(BSScene physicsScene, BSPhysObject prim, + BSPhysicsShapeType shapeType, FixedShapeKey shapeKey) + { + ShapeData nativeShapeData = new ShapeData(); + nativeShapeData.Type = shapeType; + nativeShapeData.ID = prim.LocalID; + nativeShapeData.Scale = prim.Scale; + nativeShapeData.Size = prim.Scale; + nativeShapeData.MeshKey = (ulong)shapeKey; + nativeShapeData.HullKey = (ulong)shapeKey; + + + if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE) + { + ptr = BulletSimAPI.BuildCapsuleShape2(physicsScene.World.ptr, 1f, 1f, prim.Scale); + physicsScene.DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); + } + else + { + ptr = BulletSimAPI.BuildNativeShape2(physicsScene.World.ptr, nativeShapeData); + } + if (ptr == null) + { + physicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}", + LogHeader, prim.LocalID, shapeType); + } + type = shapeType; + key = (UInt64)shapeKey; + } + // Make this reference to the physical shape go away since native shapes are not shared. + public override void Dereference(BSScene physicsScene) + { + // Native shapes are not tracked and are released immediately + physicsScene.DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,shape={1}", BSScene.DetailLogZero, this); + BulletSimAPI.DeleteCollisionShape2(physicsScene.World.ptr, ptr); + ptr = null; + // Garbage collection will free up this instance. + } +} + +public class BSShapeMesh : BSShape +{ + private static string LogHeader = "[BULLETSIM SHAPE MESH]"; + private static Dictionary Meshes = new Dictionary(); + + public BSShapeMesh() : base() + { + } + public static BSShape GetReference() { return new BSShapeNull(); } + public override void Dereference(BSScene physicsScene) { } +} + +public class BSShapeHull : BSShape +{ + private static string LogHeader = "[BULLETSIM SHAPE HULL]"; + private static Dictionary Hulls = new Dictionary(); + + public BSShapeHull() : base() + { + } + public static BSShape GetReference() { return new BSShapeNull(); } + public override void Dereference(BSScene physicsScene) { } +} + +public class BSShapeCompound : BSShape +{ + private static string LogHeader = "[BULLETSIM SHAPE COMPOUND]"; + public BSShapeCompound() : base() + { + } + public static BSShape GetReference(BSPhysObject prim) + { + return new BSShapeNull(); + } + public override void Dereference(BSScene physicsScene) { } +} +} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainHeightmap.cs new file mode 100644 index 0000000..252953b --- /dev/null +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainHeightmap.cs @@ -0,0 +1,175 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; + +using OpenSim.Framework; +using OpenSim.Region.Framework; +using OpenSim.Region.CoreModules; +using OpenSim.Region.Physics.Manager; + +using Nini.Config; +using log4net; + +using OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSNPlugin +{ +public sealed class BSTerrainHeightmap : BSTerrainPhys +{ + static string LogHeader = "[BULLETSIM TERRAIN HEIGHTMAP]"; + + BulletHeightMapInfo m_mapInfo = null; + + // Constructor to build a default, flat heightmap terrain. + public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize) + : base(physicsScene, regionBase, id) + { + Vector3 minTerrainCoords = new Vector3(0f, 0f, BSTerrainManager.HEIGHT_INITIALIZATION - BSTerrainManager.HEIGHT_EQUAL_FUDGE); + Vector3 maxTerrainCoords = new Vector3(regionSize.X, regionSize.Y, BSTerrainManager.HEIGHT_INITIALIZATION); + int totalHeights = (int)maxTerrainCoords.X * (int)maxTerrainCoords.Y; + float[] initialMap = new float[totalHeights]; + for (int ii = 0; ii < totalHeights; ii++) + { + initialMap[ii] = BSTerrainManager.HEIGHT_INITIALIZATION; + } + m_mapInfo = new BulletHeightMapInfo(id, initialMap, null); + m_mapInfo.minCoords = minTerrainCoords; + m_mapInfo.maxCoords = maxTerrainCoords; + m_mapInfo.terrainRegionBase = TerrainBase; + // Don't have to free any previous since we just got here. + BuildHeightmapTerrain(); + } + + // This minCoords and maxCoords passed in give the size of the terrain (min and max Z + // are the high and low points of the heightmap). + public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap, + Vector3 minCoords, Vector3 maxCoords) + : base(physicsScene, regionBase, id) + { + m_mapInfo = new BulletHeightMapInfo(id, initialMap, null); + m_mapInfo.minCoords = minCoords; + m_mapInfo.maxCoords = maxCoords; + m_mapInfo.minZ = minCoords.Z; + m_mapInfo.maxZ = maxCoords.Z; + m_mapInfo.terrainRegionBase = TerrainBase; + + // Don't have to free any previous since we just got here. + BuildHeightmapTerrain(); + } + + public override void Dispose() + { + ReleaseHeightMapTerrain(); + } + + // Using the information in m_mapInfo, create the physical representation of the heightmap. + private void BuildHeightmapTerrain() + { + m_mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, m_mapInfo.ID, + m_mapInfo.minCoords, m_mapInfo.maxCoords, + m_mapInfo.heightMap, BSParam.TerrainCollisionMargin); + + // Create the terrain shape from the mapInfo + m_mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(m_mapInfo.Ptr), + BSPhysicsShapeType.SHAPE_TERRAIN); + + // The terrain object initial position is at the center of the object + Vector3 centerPos; + centerPos.X = m_mapInfo.minCoords.X + (m_mapInfo.sizeX / 2f); + centerPos.Y = m_mapInfo.minCoords.Y + (m_mapInfo.sizeY / 2f); + centerPos.Z = m_mapInfo.minZ + ((m_mapInfo.maxZ - m_mapInfo.minZ) / 2f + 0.5f); + + m_mapInfo.terrainBody = new BulletBody(m_mapInfo.ID, + BulletSimAPI.CreateBodyWithDefaultMotionState2(m_mapInfo.terrainShape.ptr, + m_mapInfo.ID, centerPos, Quaternion.Identity)); + + // Set current terrain attributes + BulletSimAPI.SetFriction2(m_mapInfo.terrainBody.ptr, BSParam.TerrainFriction); + BulletSimAPI.SetHitFraction2(m_mapInfo.terrainBody.ptr, BSParam.TerrainHitFraction); + BulletSimAPI.SetRestitution2(m_mapInfo.terrainBody.ptr, BSParam.TerrainRestitution); + BulletSimAPI.SetCollisionFlags2(m_mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); + + // Return the new terrain to the world of physical objects + BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr, centerPos, Quaternion.Identity); + + // redo its bounding box now that it is in the world + BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); + + m_mapInfo.terrainBody.collisionType = CollisionType.Terrain; + m_mapInfo.terrainBody.ApplyCollisionMask(); + + // Make it so the terrain will not move or be considered for movement. + BulletSimAPI.ForceActivationState2(m_mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION); + + return; + } + + // If there is information in m_mapInfo pointing to physical structures, release same. + private void ReleaseHeightMapTerrain() + { + if (m_mapInfo != null) + { + if (m_mapInfo.terrainBody.HasPhysicalBody) + { + BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); + // Frees both the body and the shape. + BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); + BulletSimAPI.ReleaseHeightMapInfo2(m_mapInfo.Ptr); + } + } + m_mapInfo = null; + } + + // The passed position is relative to the base of the region. + public override float GetTerrainHeightAtXYZ(Vector3 pos) + { + float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; + + int mapIndex = (int)pos.Y * (int)m_mapInfo.sizeY + (int)pos.X; + try + { + ret = m_mapInfo.heightMap[mapIndex]; + } + catch + { + // Sometimes they give us wonky values of X and Y. Give a warning and return something. + PhysicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, pos={2}", + LogHeader, m_mapInfo.terrainRegionBase, pos); + ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; + } + return ret; + } + + // The passed position is relative to the base of the region. + public override float GetWaterLevelAtXYZ(Vector3 pos) + { + return PhysicsScene.SimpleWaterLevel; + } +} +} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainManager.cs new file mode 100644 index 0000000..dfad70e --- /dev/null +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainManager.cs @@ -0,0 +1,460 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; + +using OpenSim.Framework; +using OpenSim.Region.Framework; +using OpenSim.Region.CoreModules; +using OpenSim.Region.Physics.Manager; + +using Nini.Config; +using log4net; + +using OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSNPlugin +{ + +// The physical implementation of the terrain is wrapped in this class. +public abstract class BSTerrainPhys : IDisposable +{ + public enum TerrainImplementation + { + Heightmap = 0, + Mesh = 1 + } + + public BSScene PhysicsScene { get; private set; } + // Base of the region in world coordinates. Coordinates inside the region are relative to this. + public Vector3 TerrainBase { get; private set; } + public uint ID { get; private set; } + + public BSTerrainPhys(BSScene physicsScene, Vector3 regionBase, uint id) + { + PhysicsScene = physicsScene; + TerrainBase = regionBase; + ID = id; + } + public abstract void Dispose(); + public abstract float GetTerrainHeightAtXYZ(Vector3 pos); + public abstract float GetWaterLevelAtXYZ(Vector3 pos); +} + +// ========================================================================================== +public sealed class BSTerrainManager : IDisposable +{ + static string LogHeader = "[BULLETSIM TERRAIN MANAGER]"; + + // These height values are fractional so the odd values will be + // noticable when debugging. + public const float HEIGHT_INITIALIZATION = 24.987f; + public const float HEIGHT_INITIAL_LASTHEIGHT = 24.876f; + public const float HEIGHT_GETHEIGHT_RET = 24.765f; + public const float WATER_HEIGHT_GETHEIGHT_RET = 19.998f; + + // If the min and max height are equal, we reduce the min by this + // amount to make sure that a bounding box is built for the terrain. + public const float HEIGHT_EQUAL_FUDGE = 0.2f; + + // Until the whole simulator is changed to pass us the region size, we rely on constants. + public Vector3 DefaultRegionSize = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); + + // The scene that I am part of + private BSScene PhysicsScene { get; set; } + + // The ground plane created to keep thing from falling to infinity. + private BulletBody m_groundPlane; + + // If doing mega-regions, if we're region zero we will be managing multiple + // region terrains since region zero does the physics for the whole mega-region. + private Dictionary m_terrains; + + // Flags used to know when to recalculate the height. + private bool m_terrainModified = false; + + // If we are doing mega-regions, terrains are added from TERRAIN_ID to m_terrainCount. + // This is incremented before assigning to new region so it is the last ID allocated. + private uint m_terrainCount = BSScene.CHILDTERRAIN_ID - 1; + public uint HighestTerrainID { get {return m_terrainCount; } } + + // If doing mega-regions, this holds our offset from region zero of + // the mega-regions. "parentScene" points to the PhysicsScene of region zero. + private Vector3 m_worldOffset; + // If the parent region (region 0), this is the extent of the combined regions + // relative to the origin of region zero + private Vector3 m_worldMax; + private PhysicsScene MegaRegionParentPhysicsScene { get; set; } + + public BSTerrainManager(BSScene physicsScene) + { + PhysicsScene = physicsScene; + m_terrains = new Dictionary(); + + // Assume one region of default size + m_worldOffset = Vector3.Zero; + m_worldMax = new Vector3(DefaultRegionSize); + MegaRegionParentPhysicsScene = null; + } + + public void Dispose() + { + ReleaseGroundPlaneAndTerrain(); + } + + // Create the initial instance of terrain and the underlying ground plane. + // This is called from the initialization routine so we presume it is + // safe to call Bullet in real time. We hope no one is moving prims around yet. + public void CreateInitialGroundPlaneAndTerrain() + { + // The ground plane is here to catch things that are trying to drop to negative infinity + BulletShape groundPlaneShape = new BulletShape( + BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, + BSParam.TerrainCollisionMargin), + BSPhysicsShapeType.SHAPE_GROUNDPLANE); + m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID, + BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID, + Vector3.Zero, Quaternion.Identity)); + BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr); + BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_groundPlane.ptr); + // Ground plane does not move + BulletSimAPI.ForceActivationState2(m_groundPlane.ptr, ActivationState.DISABLE_SIMULATION); + // Everything collides with the ground plane. + m_groundPlane.collisionType = CollisionType.Groundplane; + m_groundPlane.ApplyCollisionMask(); + + // Build an initial terrain and put it in the world. This quickly gets replaced by the real region terrain. + BSTerrainPhys initialTerrain = new BSTerrainHeightmap(PhysicsScene, Vector3.Zero, BSScene.TERRAIN_ID, DefaultRegionSize); + m_terrains.Add(Vector3.Zero, initialTerrain); + } + + // Release all the terrain structures we might have allocated + public void ReleaseGroundPlaneAndTerrain() + { + if (m_groundPlane.HasPhysicalBody) + { + if (BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr)) + { + BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_groundPlane.ptr); + } + m_groundPlane.Clear(); + } + + ReleaseTerrain(); + } + + // Release all the terrain we have allocated + public void ReleaseTerrain() + { + lock (m_terrains) + { + foreach (KeyValuePair kvp in m_terrains) + { + kvp.Value.Dispose(); + } + m_terrains.Clear(); + } + } + + // The simulator wants to set a new heightmap for the terrain. + public void SetTerrain(float[] heightMap) { + float[] localHeightMap = heightMap; + // If there are multiple requests for changes to the same terrain between ticks, + // only do that last one. + PhysicsScene.PostTaintObject("TerrainManager.SetTerrain-"+ m_worldOffset.ToString(), 0, delegate() + { + if (m_worldOffset != Vector3.Zero && MegaRegionParentPhysicsScene != null) + { + // If a child of a mega-region, we shouldn't have any terrain allocated for us + ReleaseGroundPlaneAndTerrain(); + // If doing the mega-prim stuff and we are the child of the zero region, + // the terrain is added to our parent + if (MegaRegionParentPhysicsScene is BSScene) + { + DetailLog("{0},SetTerrain.ToParent,offset={1},worldMax={2}", + BSScene.DetailLogZero, m_worldOffset, m_worldMax); + ((BSScene)MegaRegionParentPhysicsScene).TerrainManager.UpdateTerrain( + BSScene.CHILDTERRAIN_ID, localHeightMap, + m_worldOffset, m_worldOffset + DefaultRegionSize, true); + } + } + else + { + // If not doing the mega-prim thing, just change the terrain + DetailLog("{0},SetTerrain.Existing", BSScene.DetailLogZero); + + UpdateTerrain(BSScene.TERRAIN_ID, localHeightMap, + m_worldOffset, m_worldOffset + DefaultRegionSize, true); + } + }); + } + + // If called with no mapInfo for the terrain, this will create a new mapInfo and terrain + // based on the passed information. The 'id' should be either the terrain id or + // BSScene.CHILDTERRAIN_ID. If the latter, a new child terrain ID will be allocated and used. + // The latter feature is for creating child terrains for mega-regions. + // If called with a mapInfo in m_heightMaps and there is an existing terrain body, a new + // terrain shape is created and added to the body. + // This call is most often used to update the heightMap and parameters of the terrain. + // (The above does suggest that some simplification/refactoring is in order.) + // Called during taint-time. + private void UpdateTerrain(uint id, float[] heightMap, + Vector3 minCoords, Vector3 maxCoords, bool inTaintTime) + { + DetailLog("{0},BSTerrainManager.UpdateTerrain,call,minC={1},maxC={2},inTaintTime={3}", + BSScene.DetailLogZero, minCoords, maxCoords, inTaintTime); + + // Find high and low points of passed heightmap. + // The min and max passed in is usually the area objects can be in (maximum + // object height, for instance). The terrain wants the bounding box for the + // terrain so replace passed min and max Z with the actual terrain min/max Z. + float minZ = float.MaxValue; + float maxZ = float.MinValue; + foreach (float height in heightMap) + { + if (height < minZ) minZ = height; + if (height > maxZ) maxZ = height; + } + if (minZ == maxZ) + { + // If min and max are the same, reduce min a little bit so a good bounding box is created. + minZ -= BSTerrainManager.HEIGHT_EQUAL_FUDGE; + } + minCoords.Z = minZ; + maxCoords.Z = maxZ; + + Vector3 terrainRegionBase = new Vector3(minCoords.X, minCoords.Y, 0f); + + lock (m_terrains) + { + BSTerrainPhys terrainPhys; + if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys)) + { + // There is already a terrain in this spot. Free the old and build the new. + DetailLog("{0},UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}", + BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords); + + // Remove old terrain from the collection + m_terrains.Remove(terrainRegionBase); + // Release any physical memory it may be using. + terrainPhys.Dispose(); + + if (MegaRegionParentPhysicsScene == null) + { + BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords); + m_terrains.Add(terrainRegionBase, newTerrainPhys); + + m_terrainModified = true; + } + else + { + // It's possible that Combine() was called after this code was queued. + // If we are a child of combined regions, we don't create any terrain for us. + DetailLog("{0},BSTerrainManager.UpdateTerrain:AmACombineChild,taint", BSScene.DetailLogZero); + + // Get rid of any terrain that may have been allocated for us. + ReleaseGroundPlaneAndTerrain(); + + // I hate doing this, but just bail + return; + } + } + else + { + // We don't know about this terrain so either we are creating a new terrain or + // our mega-prim child is giving us a new terrain to add to the phys world + + // if this is a child terrain, calculate a unique terrain id + uint newTerrainID = id; + if (newTerrainID >= BSScene.CHILDTERRAIN_ID) + newTerrainID = ++m_terrainCount; + + DetailLog("{0},UpdateTerrain:NewTerrain,taint,newID={1},minCoord={2},maxCoord={3}", + BSScene.DetailLogZero, newTerrainID, minCoords, minCoords); + BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords); + m_terrains.Add(terrainRegionBase, newTerrainPhys); + + m_terrainModified = true; + } + } + } + + // TODO: redo terrain implementation selection to allow other base types than heightMap. + private BSTerrainPhys BuildPhysicalTerrain(Vector3 terrainRegionBase, uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords) + { + PhysicsScene.Logger.DebugFormat("{0} Terrain for {1}/{2} created with {3}", + LogHeader, PhysicsScene.RegionName, terrainRegionBase, + (BSTerrainPhys.TerrainImplementation)BSParam.TerrainImplementation); + BSTerrainPhys newTerrainPhys = null; + switch ((int)BSParam.TerrainImplementation) + { + case (int)BSTerrainPhys.TerrainImplementation.Heightmap: + newTerrainPhys = new BSTerrainHeightmap(PhysicsScene, terrainRegionBase, id, + heightMap, minCoords, maxCoords); + break; + case (int)BSTerrainPhys.TerrainImplementation.Mesh: + newTerrainPhys = new BSTerrainMesh(PhysicsScene, terrainRegionBase, id, + heightMap, minCoords, maxCoords); + break; + default: + PhysicsScene.Logger.ErrorFormat("{0} Bad terrain implementation specified. Type={1}/{2},Region={3}/{4}", + LogHeader, + (int)BSParam.TerrainImplementation, + BSParam.TerrainImplementation, + PhysicsScene.RegionName, terrainRegionBase); + break; + } + return newTerrainPhys; + } + + // Return 'true' of this position is somewhere in known physical terrain space + public bool IsWithinKnownTerrain(Vector3 pos) + { + Vector3 terrainBaseXYZ; + BSTerrainPhys physTerrain; + return GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ); + } + + // Given an X and Y, find the height of the terrain. + // Since we could be handling multiple terrains for a mega-region, + // the base of the region is calcuated assuming all regions are + // the same size and that is the default. + // Once the heightMapInfo is found, we have all the information to + // compute the offset into the array. + private float lastHeightTX = 999999f; + private float lastHeightTY = 999999f; + private float lastHeight = HEIGHT_INITIAL_LASTHEIGHT; + public float GetTerrainHeightAtXYZ(Vector3 pos) + { + float tX = pos.X; + float tY = pos.Y; + // You'd be surprized at the number of times this routine is called + // with the same parameters as last time. + if (!m_terrainModified && (lastHeightTX == tX) && (lastHeightTY == tY)) + return lastHeight; + m_terrainModified = false; + + lastHeightTX = tX; + lastHeightTY = tY; + float ret = HEIGHT_GETHEIGHT_RET; + + Vector3 terrainBaseXYZ; + BSTerrainPhys physTerrain; + if (GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ)) + { + ret = physTerrain.GetTerrainHeightAtXYZ(pos - terrainBaseXYZ); + } + else + { + PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}", + LogHeader, PhysicsScene.RegionName, tX, tY); + DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXYZ,terrainNotFound,pos={1},base={2}", + BSScene.DetailLogZero, pos, terrainBaseXYZ); + } + lastHeight = ret; + return ret; + } + + public float GetWaterLevelAtXYZ(Vector3 pos) + { + float ret = WATER_HEIGHT_GETHEIGHT_RET; + + Vector3 terrainBaseXYZ; + BSTerrainPhys physTerrain; + if (GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ)) + { + ret = physTerrain.GetWaterLevelAtXYZ(pos); + } + else + { + PhysicsScene.Logger.ErrorFormat("{0} GetWaterHeightAtXY: terrain not found: pos={1}, terrainBase={2}, height={3}", + LogHeader, PhysicsScene.RegionName, pos, terrainBaseXYZ, ret); + } + return ret; + } + + // Given an address, return 'true' of there is a description of that terrain and output + // the descriptor class and the 'base' fo the addresses therein. + private bool GetTerrainPhysicalAtXYZ(Vector3 pos, out BSTerrainPhys outPhysTerrain, out Vector3 outTerrainBase) + { + int offsetX = ((int)(pos.X / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X; + int offsetY = ((int)(pos.Y / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y; + Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f); + + BSTerrainPhys physTerrain = null; + lock (m_terrains) + { + m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain); + } + outTerrainBase = terrainBaseXYZ; + outPhysTerrain = physTerrain; + return (physTerrain != null); + } + + // Although no one seems to check this, I do support combining. + public bool SupportsCombining() + { + return true; + } + + // This routine is called two ways: + // One with 'offset' and 'pScene' zero and null but 'extents' giving the maximum + // extent of the combined regions. This is to inform the parent of the size + // of the combined regions. + // and one with 'offset' as the offset of the child region to the base region, + // 'pScene' pointing to the parent and 'extents' of zero. This informs the + // child of its relative base and new parent. + public void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents) + { + m_worldOffset = offset; + m_worldMax = extents; + MegaRegionParentPhysicsScene = pScene; + if (pScene != null) + { + // We are a child. + // We want m_worldMax to be the highest coordinate of our piece of terrain. + m_worldMax = offset + DefaultRegionSize; + } + DetailLog("{0},BSTerrainManager.Combine,offset={1},extents={2},wOffset={3},wMax={4}", + BSScene.DetailLogZero, offset, extents, m_worldOffset, m_worldMax); + } + + // Unhook all the combining that I know about. + public void UnCombine(PhysicsScene pScene) + { + // Just like ODE, we don't do anything yet. + DetailLog("{0},BSTerrainManager.UnCombine", BSScene.DetailLogZero); + } + + + private void DetailLog(string msg, params Object[] args) + { + PhysicsScene.PhysicsLogging.Write(msg, args); + } +} +} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainMesh.cs new file mode 100644 index 0000000..6083dd4 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainMesh.cs @@ -0,0 +1,267 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; + +using OpenSim.Framework; +using OpenSim.Region.Framework; +using OpenSim.Region.CoreModules; +using OpenSim.Region.Physics.Manager; + +using Nini.Config; +using log4net; + +using OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSNPlugin +{ +public sealed class BSTerrainMesh : BSTerrainPhys +{ + static string LogHeader = "[BULLETSIM TERRAIN MESH]"; + + private float[] m_savedHeightMap; + int m_sizeX; + int m_sizeY; + + BulletShape m_terrainShape; + BulletBody m_terrainBody; + + public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize) + : base(physicsScene, regionBase, id) + { + } + + public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id /* parameters for making mesh */) + : base(physicsScene, regionBase, id) + { + } + + // Create terrain mesh from a heightmap. + public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap, + Vector3 minCoords, Vector3 maxCoords) + : base(physicsScene, regionBase, id) + { + int indicesCount; + int[] indices; + int verticesCount; + float[] vertices; + + m_savedHeightMap = initialMap; + + m_sizeX = (int)(maxCoords.X - minCoords.X); + m_sizeY = (int)(maxCoords.Y - minCoords.Y); + + if (!BSTerrainMesh.ConvertHeightmapToMesh(PhysicsScene, initialMap, + m_sizeX, m_sizeY, + (float)m_sizeX, (float)m_sizeY, + Vector3.Zero, 1.0f, + out indicesCount, out indices, out verticesCount, out vertices)) + { + // DISASTER!! + PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedConversionOfHeightmap", ID); + PhysicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh! base={1}", LogHeader, TerrainBase); + // Something is very messed up and a crash is in our future. + return; + } + PhysicsScene.DetailLog("{0},BSTerrainMesh.create,meshed,indices={1},indSz={2},vertices={3},vertSz={4}", + ID, indicesCount, indices.Length, verticesCount, vertices.Length); + + m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, + indicesCount, indices, verticesCount, vertices), + BSPhysicsShapeType.SHAPE_MESH); + if (!m_terrainShape.HasPhysicalShape) + { + // DISASTER!! + PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape", ID); + physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain mesh! base={1}", LogHeader, TerrainBase); + // Something is very messed up and a crash is in our future. + return; + } + + Vector3 pos = regionBase; + Quaternion rot = Quaternion.Identity; + + m_terrainBody = new BulletBody(id, BulletSimAPI.CreateBodyWithDefaultMotionState2( m_terrainShape.ptr, ID, pos, rot)); + if (!m_terrainBody.HasPhysicalBody) + { + // DISASTER!! + physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain body! base={1}", LogHeader, TerrainBase); + // Something is very messed up and a crash is in our future. + return; + } + + // Set current terrain attributes + BulletSimAPI.SetFriction2(m_terrainBody.ptr, BSParam.TerrainFriction); + BulletSimAPI.SetHitFraction2(m_terrainBody.ptr, BSParam.TerrainHitFraction); + BulletSimAPI.SetRestitution2(m_terrainBody.ptr, BSParam.TerrainRestitution); + BulletSimAPI.SetCollisionFlags2(m_terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); + + // Static objects are not very massive. + BulletSimAPI.SetMassProps2(m_terrainBody.ptr, 0f, Vector3.Zero); + + // Put the new terrain to the world of physical objects + BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr, pos, rot); + + // Redo its bounding box now that it is in the world + BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr); + + m_terrainBody.collisionType = CollisionType.Terrain; + m_terrainBody.ApplyCollisionMask(); + + // Make it so the terrain will not move or be considered for movement. + BulletSimAPI.ForceActivationState2(m_terrainBody.ptr, ActivationState.DISABLE_SIMULATION); + } + + public override void Dispose() + { + if (m_terrainBody.HasPhysicalBody) + { + BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr); + // Frees both the body and the shape. + BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_terrainBody.ptr); + } + } + + public override float GetTerrainHeightAtXYZ(Vector3 pos) + { + // For the moment use the saved heightmap to get the terrain height. + // TODO: raycast downward to find the true terrain below the position. + float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; + + int mapIndex = (int)pos.Y * m_sizeY + (int)pos.X; + try + { + ret = m_savedHeightMap[mapIndex]; + } + catch + { + // Sometimes they give us wonky values of X and Y. Give a warning and return something. + PhysicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, pos={2}", + LogHeader, TerrainBase, pos); + ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; + } + return ret; + } + + // The passed position is relative to the base of the region. + public override float GetWaterLevelAtXYZ(Vector3 pos) + { + return PhysicsScene.SimpleWaterLevel; + } + + // Convert the passed heightmap to mesh information suitable for CreateMeshShape2(). + // Return 'true' if successfully created. + public static bool ConvertHeightmapToMesh( + BSScene physicsScene, + float[] heightMap, int sizeX, int sizeY, // parameters of incoming heightmap + float extentX, float extentY, // zero based range for output vertices + Vector3 extentBase, // base to be added to all vertices + float magnification, // number of vertices to create between heightMap coords + out int indicesCountO, out int[] indicesO, + out int verticesCountO, out float[] verticesO) + { + bool ret = false; + + int indicesCount = 0; + int verticesCount = 0; + int[] indices = new int[0]; + float[] vertices = new float[0]; + + // Simple mesh creation which assumes magnification == 1. + // TODO: do a more general solution that scales, adds new vertices and smoothes the result. + + // Create an array of vertices that is sizeX+1 by sizeY+1 (note the loop + // from zero to <= sizeX). The triangle indices are then generated as two triangles + // per heightmap point. There are sizeX by sizeY of these squares. The extra row and + // column of vertices are used to complete the triangles of the last row and column + // of the heightmap. + try + { + // One vertice per heightmap value plus the vertices off the top and bottom edge. + int totalVertices = (sizeX + 1) * (sizeY + 1); + vertices = new float[totalVertices * 3]; + int totalIndices = sizeX * sizeY * 6; + indices = new int[totalIndices]; + + float magX = (float)sizeX / extentX; + float magY = (float)sizeY / extentY; + physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2},extentBase={3},magX={4},magY={5}", + BSScene.DetailLogZero, totalVertices, totalIndices, extentBase, magX, magY); + float minHeight = float.MaxValue; + // Note that sizeX+1 vertices are created since there is land between this and the next region. + for (int yy = 0; yy <= sizeY; yy++) + { + for (int xx = 0; xx <= sizeX; xx++) // Hint: the "<=" means we go around sizeX + 1 times + { + int offset = yy * sizeX + xx; + // Extend the height with the height from the last row or column + if (yy == sizeY) offset -= sizeX; + if (xx == sizeX) offset -= 1; + float height = heightMap[offset]; + minHeight = Math.Min(minHeight, height); + vertices[verticesCount + 0] = (float)xx * magX + extentBase.X; + vertices[verticesCount + 1] = (float)yy * magY + extentBase.Y; + vertices[verticesCount + 2] = height + extentBase.Z; + verticesCount += 3; + } + } + verticesCount = verticesCount / 3; + + for (int yy = 0; yy < sizeY; yy++) + { + for (int xx = 0; xx < sizeX; xx++) + { + int offset = yy * (sizeX + 1) + xx; + // Each vertices is presumed to be the upper left corner of a box of two triangles + indices[indicesCount + 0] = offset; + indices[indicesCount + 1] = offset + 1; + indices[indicesCount + 2] = offset + sizeX + 1; // accounting for the extra column + indices[indicesCount + 3] = offset + 1; + indices[indicesCount + 4] = offset + sizeX + 2; + indices[indicesCount + 5] = offset + sizeX + 1; + indicesCount += 6; + } + } + + ret = true; + } + catch (Exception e) + { + physicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh. For={1}/{2}, e={3}", + LogHeader, physicsScene.RegionName, extentBase, e); + } + + indicesCountO = indicesCount; + indicesO = indices; + verticesCountO = verticesCount; + verticesO = vertices; + + return ret; + } +} +} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSNPlugin/BulletSimAPI.cs new file mode 100644 index 0000000..6af59d6 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSNPlugin/BulletSimAPI.cs @@ -0,0 +1,1604 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; +using BulletXNA; +using OpenMetaverse; +using BulletXNA.LinearMath; +using BulletXNA.BulletCollision; +using BulletXNA.BulletDynamics; +using BulletXNA.BulletCollision.CollisionDispatch; +using OpenSim.Framework; + +namespace OpenSim.Region.Physics.BulletSNPlugin { + +// Classes to allow some type checking for the API +// These hold pointers to allocated objects in the unmanaged space. + + + + // Constraint type values as defined by Bullet +public enum ConstraintType : int +{ + POINT2POINT_CONSTRAINT_TYPE = 3, + HINGE_CONSTRAINT_TYPE, + CONETWIST_CONSTRAINT_TYPE, + D6_CONSTRAINT_TYPE, + SLIDER_CONSTRAINT_TYPE, + CONTACT_CONSTRAINT_TYPE, + D6_SPRING_CONSTRAINT_TYPE, + MAX_CONSTRAINT_TYPE +} + + +// =============================================================================== +[StructLayout(LayoutKind.Sequential)] +public struct ConvexHull +{ + Vector3 Offset; + int VertexCount; + Vector3[] Vertices; +} +public enum BSPhysicsShapeType +{ + SHAPE_UNKNOWN = 0, + SHAPE_CAPSULE = 1, + SHAPE_BOX = 2, + SHAPE_CONE = 3, + SHAPE_CYLINDER = 4, + SHAPE_SPHERE = 5, + SHAPE_MESH = 6, + SHAPE_HULL = 7, + // following defined by BulletSim + SHAPE_GROUNDPLANE = 20, + SHAPE_TERRAIN = 21, + SHAPE_COMPOUND = 22, + SHAPE_HEIGHTMAP = 23, +}; + +// The native shapes have predefined shape hash keys +public enum FixedShapeKey : ulong +{ + KEY_NONE = 0, + KEY_BOX = 1, + KEY_SPHERE = 2, + KEY_CONE = 3, + KEY_CYLINDER = 4, + KEY_CAPSULE = 5, +} + +[StructLayout(LayoutKind.Sequential)] +public struct ShapeData +{ + public uint ID; + public BSPhysicsShapeType Type; + public Vector3 Position; + public Quaternion Rotation; + public Vector3 Velocity; + public Vector3 Scale; + public float Mass; + public float Buoyancy; + public System.UInt64 HullKey; + public System.UInt64 MeshKey; + public float Friction; + public float Restitution; + public float Collidable; // true of things bump into this + public float Static; // true if a static object. Otherwise gravity, etc. + public float Solid; // true if object cannot be passed through + public Vector3 Size; + + // note that bools are passed as floats since bool size changes by language and architecture + public const float numericTrue = 1f; + public const float numericFalse = 0f; +} +[StructLayout(LayoutKind.Sequential)] +public struct SweepHit +{ + public uint ID; + public float Fraction; + public Vector3 Normal; + public Vector3 Point; +} +[StructLayout(LayoutKind.Sequential)] +public struct RaycastHit +{ + public uint ID; + public float Fraction; + public Vector3 Normal; +} +[StructLayout(LayoutKind.Sequential)] +public struct CollisionDesc +{ + public uint aID; + public uint bID; + public Vector3 point; + public Vector3 normal; +} +[StructLayout(LayoutKind.Sequential)] +public struct EntityProperties +{ + public uint ID; + public Vector3 Position; + public Quaternion Rotation; + public Vector3 Velocity; + public Vector3 Acceleration; + public Vector3 RotationalVelocity; + public override string ToString() + { + return string.Format("ID:{0}, Pos:<{1:F},{2:F},{3:F}>, Rot:<{4:F},{5:F},{6:F},{7:F}>, LVel:<{8:F},{9:F},{10:F}>, AVel:<{11:F},{12:F},{13:F}>", + ID.ToString(), + Position.X,Position.Y,Position.Z, + Rotation.X,Rotation.Y,Rotation.Z,Rotation.W, + Velocity.X,Velocity.Y,Velocity.Z, + RotationalVelocity.X,RotationalVelocity.Y,RotationalVelocity.Z + ); + } +} + +// Format of this structure must match the definition in the C++ code +// NOTE: adding the X causes compile breaks if used. These are unused symbols +// that can be removed from both here and the unmanaged definition of this structure. +[StructLayout(LayoutKind.Sequential)] +public struct ConfigurationParameters +{ + public float defaultFriction; + public float defaultDensity; + public float defaultRestitution; + public float collisionMargin; + public float gravity; + + public float XlinearDamping; + public float XangularDamping; + public float XdeactivationTime; + public float XlinearSleepingThreshold; + public float XangularSleepingThreshold; + public float XccdMotionThreshold; + public float XccdSweptSphereRadius; + public float XcontactProcessingThreshold; + + public float XterrainImplementation; + public float XterrainFriction; + public float XterrainHitFraction; + public float XterrainRestitution; + public float XterrainCollisionMargin; + + public float XavatarFriction; + public float XavatarStandingFriction; + public float XavatarDensity; + public float XavatarRestitution; + public float XavatarCapsuleWidth; + public float XavatarCapsuleDepth; + public float XavatarCapsuleHeight; + public float XavatarContactProcessingThreshold; + + public float XvehicleAngularDamping; + + public float maxPersistantManifoldPoolSize; + public float maxCollisionAlgorithmPoolSize; + public float shouldDisableContactPoolDynamicAllocation; + public float shouldForceUpdateAllAabbs; + public float shouldRandomizeSolverOrder; + public float shouldSplitSimulationIslands; + public float shouldEnableFrictionCaching; + public float numberOfSolverIterations; + + public float XlinksetImplementation; + public float XlinkConstraintUseFrameOffset; + public float XlinkConstraintEnableTransMotor; + public float XlinkConstraintTransMotorMaxVel; + public float XlinkConstraintTransMotorMaxForce; + public float XlinkConstraintERP; + public float XlinkConstraintCFM; + public float XlinkConstraintSolverIterations; + + public float physicsLoggingFrames; + + public const float numericTrue = 1f; + public const float numericFalse = 0f; +} + + +// The states a bullet collision object can have + +public enum ActivationState : uint +{ + UNDEFINED = 0, + ACTIVE_TAG = 1, + ISLAND_SLEEPING = 2, + WANTS_DEACTIVATION = 3, + DISABLE_DEACTIVATION = 4, + DISABLE_SIMULATION = 5, +} + +public enum CollisionObjectTypes : int +{ + CO_COLLISION_OBJECT = 1 << 0, + CO_RIGID_BODY = 1 << 1, + CO_GHOST_OBJECT = 1 << 2, + CO_SOFT_BODY = 1 << 3, + CO_HF_FLUID = 1 << 4, + CO_USER_TYPE = 1 << 5, +} + +// Values used by Bullet and BulletSim to control object properties. +// Bullet's "CollisionFlags" has more to do with operations on the +// object (if collisions happen, if gravity effects it, ...). + [Flags] +public enum CollisionFlags : uint +{ + CF_STATIC_OBJECT = 1 << 0, + CF_KINEMATIC_OBJECT = 1 << 1, + CF_NO_CONTACT_RESPONSE = 1 << 2, + CF_CUSTOM_MATERIAL_CALLBACK = 1 << 3, + CF_CHARACTER_OBJECT = 1 << 4, + CF_DISABLE_VISUALIZE_OBJECT = 1 << 5, + CF_DISABLE_SPU_COLLISION_PROCESS = 1 << 6, + // Following used by BulletSim to control collisions and updates + BS_SUBSCRIBE_COLLISION_EVENTS = 1 << 10, + BS_FLOATS_ON_WATER = 1 << 11, + BS_VEHICLE_COLLISIONS = 1 << 12, + BS_NONE = 0, + BS_ALL = 0xFFFFFFFF, + + // These are the collision flags switched depending on physical state. + // The other flags are used for other things and should not be fooled with. + BS_ACTIVE = CF_STATIC_OBJECT + | CF_KINEMATIC_OBJECT + | CF_NO_CONTACT_RESPONSE +}; + +// Values for collisions groups and masks +public enum CollisionFilterGroups : uint +{ + // Don't use the bit definitions!! Define the use in a + // filter/mask definition below. This way collision interactions + // are more easily debugged. + BNoneGroup = 0, + BDefaultGroup = 1 << 0, + BStaticGroup = 1 << 1, + BKinematicGroup = 1 << 2, + BDebrisGroup = 1 << 3, + BSensorTrigger = 1 << 4, + BCharacterGroup = 1 << 5, + BAllGroup = 0xFFFFFFFF, + // Filter groups defined by BulletSim + BGroundPlaneGroup = 1 << 10, + BTerrainGroup = 1 << 11, + BRaycastGroup = 1 << 12, + BSolidGroup = 1 << 13, + // BLinksetGroup = xx // a linkset proper is either static or dynamic + BLinksetChildGroup = 1 << 14, + // The collsion filters and masked are defined in one place -- don't want them scattered + AvatarGroup = BCharacterGroup, + AvatarMask = BAllGroup, + ObjectGroup = BSolidGroup, + ObjectMask = BAllGroup, + StaticObjectGroup = BStaticGroup, + StaticObjectMask = AvatarGroup | ObjectGroup, // static things don't interact with much + LinksetGroup = BLinksetChildGroup, + LinksetMask = BAllGroup & ~BLinksetChildGroup, // linkset objects don't collide with each other + VolumeDetectGroup = BSensorTrigger, + VolumeDetectMask = ~BSensorTrigger, + TerrainGroup = BTerrainGroup, + TerrainMask = BAllGroup & ~BStaticGroup, // static objects on the ground don't collide + GroundPlaneGroup = BGroundPlaneGroup, + GroundPlaneMask = BAllGroup + +}; + +// CFM controls the 'hardness' of the constraint. 0=fixed, 0..1=violatable. Default=0 +// ERP controls amount of correction per tick. Usable range=0.1..0.8. Default=0.2. +public enum ConstraintParams : int +{ + BT_CONSTRAINT_ERP = 1, // this one is not used in Bullet as of 20120730 + BT_CONSTRAINT_STOP_ERP, + BT_CONSTRAINT_CFM, + BT_CONSTRAINT_STOP_CFM, +}; +public enum ConstraintParamAxis : int +{ + AXIS_LINEAR_X = 0, + AXIS_LINEAR_Y, + AXIS_LINEAR_Z, + AXIS_ANGULAR_X, + AXIS_ANGULAR_Y, + AXIS_ANGULAR_Z, + AXIS_LINEAR_ALL = 20, // these last three added by BulletSim so we don't have to do zillions of calls + AXIS_ANGULAR_ALL, + AXIS_ALL +}; + +// =============================================================================== +static class BulletSimAPI { + private static int m_collisionsThisFrame; + public delegate void DebugLogCallback(string msg); + /// + /// + /// + /// + /// + internal static bool RemoveObjectFromWorld2(object pWorld, object pBody) + { + DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + RigidBody body = pBody as RigidBody; + world.RemoveRigidBody(body); + return true; + } + + internal static void SetRestitution2(object pBody, float pRestitution) + { + RigidBody body = pBody as RigidBody; + body.SetRestitution(pRestitution); + } + + internal static void SetMargin2(object pShape, float pMargin) + { + CollisionShape shape = pShape as CollisionShape; + shape.SetMargin(pMargin); + } + + internal static void SetLocalScaling2(object pShape, Vector3 pScale) + { + CollisionShape shape = pShape as CollisionShape; + IndexedVector3 vec = new IndexedVector3(pScale.X, pScale.Y, pScale.Z); + shape.SetLocalScaling(ref vec); + + } + + internal static void SetContactProcessingThreshold2(object pBody, float contactprocessingthreshold) + { + RigidBody body = pBody as RigidBody; + body.SetContactProcessingThreshold(contactprocessingthreshold); + } + + internal static void SetCcdMotionThreshold2(object pBody, float pccdMotionThreashold) + { + RigidBody body = pBody as RigidBody; + body.SetCcdMotionThreshold(pccdMotionThreashold); + } + + internal static void SetCcdSweptSphereRadius2(object pBody, float pCcdSweptSphereRadius) + { + RigidBody body = pBody as RigidBody; + body.SetCcdSweptSphereRadius(pCcdSweptSphereRadius); + } + + internal static void SetAngularFactorV2(object pBody, Vector3 pAngularFactor) + { + RigidBody body = pBody as RigidBody; + body.SetAngularFactor(new IndexedVector3(pAngularFactor.X, pAngularFactor.Y, pAngularFactor.Z)); + } + + internal static CollisionFlags AddToCollisionFlags2(object pBody, CollisionFlags pcollisionFlags) + { + CollisionObject body = pBody as CollisionObject; + CollisionFlags existingcollisionFlags = (CollisionFlags)(uint)body.GetCollisionFlags(); + existingcollisionFlags |= pcollisionFlags; + body.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags)(uint)existingcollisionFlags); + return (CollisionFlags) (uint) existingcollisionFlags; + } + + internal static void AddObjectToWorld2(object pWorld, object pBody) + { + RigidBody body = pBody as RigidBody; + DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + //if (!(body.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.STATIC_PLANE_PROXYTYPE && body.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.TERRAIN_SHAPE_PROXYTYPE)) + + world.AddRigidBody(body); + + //if (body.GetBroadphaseHandle() != null) + // world.UpdateSingleAabb(body); + } + + internal static void AddObjectToWorld2(object pWorld, object pBody, Vector3 _position, Quaternion _orientation) + { + RigidBody body = pBody as RigidBody; + DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + //if (!(body.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.STATIC_PLANE_PROXYTYPE && body.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.TERRAIN_SHAPE_PROXYTYPE)) + + world.AddRigidBody(body); + IndexedVector3 vposition = new IndexedVector3(_position.X, _position.Y, _position.Z); + IndexedQuaternion vquaternion = new IndexedQuaternion(_orientation.X, _orientation.Y, _orientation.Z, + _orientation.W); + IndexedMatrix mat = IndexedMatrix.CreateFromQuaternion(vquaternion); + mat._origin = vposition; + body.SetWorldTransform(mat); + //if (body.GetBroadphaseHandle() != null) + // world.UpdateSingleAabb(body); + } + + internal static void ForceActivationState2(object pBody, ActivationState pActivationState) + { + CollisionObject body = pBody as CollisionObject; + body.ForceActivationState((BulletXNA.BulletCollision.ActivationState)(uint)pActivationState); + } + + internal static void UpdateSingleAabb2(object pWorld, object pBody) + { + CollisionObject body = pBody as CollisionObject; + DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + world.UpdateSingleAabb(body); + } + + internal static bool SetCollisionGroupMask2(object pBody, uint pGroup, uint pMask) + { + RigidBody body = pBody as RigidBody; + body.GetBroadphaseHandle().m_collisionFilterGroup = (BulletXNA.BulletCollision.CollisionFilterGroups) pGroup; + body.GetBroadphaseHandle().m_collisionFilterGroup = (BulletXNA.BulletCollision.CollisionFilterGroups) pGroup; + if ((uint) body.GetBroadphaseHandle().m_collisionFilterGroup == 0) + return false; + return true; + } + + internal static void ClearAllForces2(object pBody) + { + CollisionObject body = pBody as CollisionObject; + IndexedVector3 zeroVector = new IndexedVector3(0, 0, 0); + body.SetInterpolationLinearVelocity(ref zeroVector); + body.SetInterpolationAngularVelocity(ref zeroVector); + IndexedMatrix bodytransform = body.GetWorldTransform(); + + body.SetInterpolationWorldTransform(ref bodytransform); + + if (body is RigidBody) + { + RigidBody rigidbody = body as RigidBody; + rigidbody.SetLinearVelocity(zeroVector); + rigidbody.SetAngularVelocity(zeroVector); + rigidbody.ClearForces(); + } + } + + internal static void SetInterpolationAngularVelocity2(object pBody, Vector3 pVector3) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 vec = new IndexedVector3(pVector3.X, pVector3.Y, pVector3.Z); + body.SetInterpolationAngularVelocity(ref vec); + } + + internal static void SetAngularVelocity2(object pBody, Vector3 pVector3) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 vec = new IndexedVector3(pVector3.X, pVector3.Y, pVector3.Z); + body.SetAngularVelocity(ref vec); + } + + internal static void ClearForces2(object pBody) + { + RigidBody body = pBody as RigidBody; + body.ClearForces(); + } + + internal static void SetTranslation2(object pBody, Vector3 _position, Quaternion _orientation) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 vposition = new IndexedVector3(_position.X, _position.Y, _position.Z); + IndexedQuaternion vquaternion = new IndexedQuaternion(_orientation.X, _orientation.Y, _orientation.Z, + _orientation.W); + IndexedMatrix mat = IndexedMatrix.CreateFromQuaternion(vquaternion); + mat._origin = vposition; + body.SetWorldTransform(mat); + + } + + internal static Vector3 GetPosition2(object pBody) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 pos = body.GetInterpolationWorldTransform()._origin; + return new Vector3(pos.X, pos.Y, pos.Z); + } + + internal static Vector3 CalculateLocalInertia2(object pShape, float pphysMass) + { + CollisionShape shape = pShape as CollisionShape; + IndexedVector3 inertia = IndexedVector3.Zero; + shape.CalculateLocalInertia(pphysMass, out inertia); + return new Vector3(inertia.X, inertia.Y, inertia.Z); + } + + internal static void SetMassProps2(object pBody, float pphysMass, Vector3 plocalInertia) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 inertia = new IndexedVector3(plocalInertia.X, plocalInertia.Y, plocalInertia.Z); + body.SetMassProps(pphysMass, inertia); + } + + + internal static void SetObjectForce2(object pBody, Vector3 _force) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 force = new IndexedVector3(_force.X, _force.Y, _force.Z); + body.SetTotalForce(ref force); + } + + internal static void SetFriction2(object pBody, float _currentFriction) + { + RigidBody body = pBody as RigidBody; + body.SetFriction(_currentFriction); + } + + internal static void SetLinearVelocity2(object pBody, Vector3 _velocity) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 velocity = new IndexedVector3(_velocity.X, _velocity.Y, _velocity.Z); + body.SetLinearVelocity(velocity); + } + + internal static void Activate2(object pBody, bool pforceactivation) + { + RigidBody body = pBody as RigidBody; + body.Activate(pforceactivation); + + } + + internal static Quaternion GetOrientation2(object pBody) + { + RigidBody body = pBody as RigidBody; + IndexedQuaternion mat = body.GetInterpolationWorldTransform().GetRotation(); + return new Quaternion(mat.X, mat.Y, mat.Z, mat.W); + } + + internal static CollisionFlags RemoveFromCollisionFlags2(object pBody, CollisionFlags pcollisionFlags) + { + RigidBody body = pBody as RigidBody; + CollisionFlags existingcollisionFlags = (CollisionFlags)(uint)body.GetCollisionFlags(); + existingcollisionFlags &= ~pcollisionFlags; + body.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags)(uint)existingcollisionFlags); + return (CollisionFlags)(uint)existingcollisionFlags; + } + + internal static void SetGravity2(object pBody, Vector3 pGravity) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 gravity = new IndexedVector3(pGravity.X, pGravity.Y, pGravity.Z); + body.SetGravity(gravity); + } + + internal static bool DestroyConstraint2(object pBody, object pConstraint) + { + RigidBody body = pBody as RigidBody; + TypedConstraint constraint = pConstraint as TypedConstraint; + body.RemoveConstraintRef(constraint); + return true; + } + + internal static bool SetLinearLimits2(object pConstraint, Vector3 low, Vector3 high) + { + Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; + IndexedVector3 lowlimit = new IndexedVector3(low.X, low.Y, low.Z); + IndexedVector3 highlimit = new IndexedVector3(high.X, high.Y, high.Z); + constraint.SetLinearLowerLimit(lowlimit); + constraint.SetLinearUpperLimit(highlimit); + return true; + } + + internal static bool SetAngularLimits2(object pConstraint, Vector3 low, Vector3 high) + { + Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; + IndexedVector3 lowlimit = new IndexedVector3(low.X, low.Y, low.Z); + IndexedVector3 highlimit = new IndexedVector3(high.X, high.Y, high.Z); + constraint.SetAngularLowerLimit(lowlimit); + constraint.SetAngularUpperLimit(highlimit); + return true; + } + + internal static void SetConstraintNumSolverIterations2(object pConstraint, float cnt) + { + Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; + constraint.SetOverrideNumSolverIterations((int)cnt); + } + + internal static void CalculateTransforms2(object pConstraint) + { + Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; + constraint.CalculateTransforms(); + } + + internal static void SetConstraintEnable2(object pConstraint, float p_2) + { + Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; + constraint.SetEnabled((p_2 == 0) ? false : true); + } + + + //BulletSimAPI.Create6DofConstraint2(m_world.ptr, m_body1.ptr, m_body2.ptr,frame1, frame1rot,frame2, frame2rot,useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); + internal static object Create6DofConstraint2(object pWorld, object pBody1, object pBody2, Vector3 pframe1, Quaternion pframe1rot, Vector3 pframe2, Quaternion pframe2rot, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies) + + { + DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + RigidBody body1 = pBody1 as RigidBody; + RigidBody body2 = pBody2 as RigidBody; + IndexedVector3 frame1v = new IndexedVector3(pframe1.X, pframe1.Y, pframe1.Z); + IndexedQuaternion frame1rot = new IndexedQuaternion(pframe1rot.X, pframe1rot.Y, pframe1rot.Z, pframe1rot.W); + IndexedMatrix frame1 = IndexedMatrix.CreateFromQuaternion(frame1rot); + frame1._origin = frame1v; + + IndexedVector3 frame2v = new IndexedVector3(pframe2.X, pframe2.Y, pframe2.Z); + IndexedQuaternion frame2rot = new IndexedQuaternion(pframe2rot.X, pframe2rot.Y, pframe2rot.Z, pframe2rot.W); + IndexedMatrix frame2 = IndexedMatrix.CreateFromQuaternion(frame2rot); + frame2._origin = frame1v; + + Generic6DofConstraint consttr = new Generic6DofConstraint(body1, body2, ref frame1, ref frame2, + puseLinearReferenceFrameA); + consttr.CalculateTransforms(); + world.AddConstraint(consttr,pdisableCollisionsBetweenLinkedBodies); + + return consttr; + } + + + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + internal static object Create6DofConstraintToPoint2(object pWorld, object pBody1, object pBody2, Vector3 pjoinPoint, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies) + { + DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + RigidBody body1 = pBody1 as RigidBody; + RigidBody body2 = pBody2 as RigidBody; + IndexedMatrix frame1 = new IndexedMatrix(IndexedBasisMatrix.Identity, new IndexedVector3(0, 0, 0)); + IndexedMatrix frame2 = new IndexedMatrix(IndexedBasisMatrix.Identity, new IndexedVector3(0, 0, 0)); + + IndexedVector3 joinPoint = new IndexedVector3(pjoinPoint.X, pjoinPoint.Y, pjoinPoint.Z); + IndexedMatrix mat = IndexedMatrix.Identity; + mat._origin = new IndexedVector3(pjoinPoint.X, pjoinPoint.Y, pjoinPoint.Z); + frame1._origin = body1.GetWorldTransform().Inverse()*joinPoint; + frame2._origin = body2.GetWorldTransform().Inverse()*joinPoint; + + Generic6DofConstraint consttr = new Generic6DofConstraint(body1, body2, ref frame1, ref frame2, puseLinearReferenceFrameA); + consttr.CalculateTransforms(); + world.AddConstraint(consttr, pdisableCollisionsBetweenLinkedBodies); + + return consttr; + } + //SetFrames2(m_constraint.ptr, frameA, frameArot, frameB, frameBrot); + internal static void SetFrames2(object pConstraint, Vector3 pframe1, Quaternion pframe1rot, Vector3 pframe2, Quaternion pframe2rot) + { + Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; + IndexedVector3 frame1v = new IndexedVector3(pframe1.X, pframe1.Y, pframe1.Z); + IndexedQuaternion frame1rot = new IndexedQuaternion(pframe1rot.X, pframe1rot.Y, pframe1rot.Z, pframe1rot.W); + IndexedMatrix frame1 = IndexedMatrix.CreateFromQuaternion(frame1rot); + frame1._origin = frame1v; + + IndexedVector3 frame2v = new IndexedVector3(pframe2.X, pframe2.Y, pframe2.Z); + IndexedQuaternion frame2rot = new IndexedQuaternion(pframe2rot.X, pframe2rot.Y, pframe2rot.Z, pframe2rot.W); + IndexedMatrix frame2 = IndexedMatrix.CreateFromQuaternion(frame2rot); + frame2._origin = frame1v; + constraint.SetFrames(ref frame1, ref frame2); + } + + + + + internal static bool IsInWorld2(object pWorld, object pShapeObj) + { + DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + CollisionObject shape = pShapeObj as CollisionObject; + return world.IsInWorld(shape); + } + + internal static void SetInterpolationLinearVelocity2(object pBody, Vector3 VehicleVelocity) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 velocity = new IndexedVector3(VehicleVelocity.X, VehicleVelocity.Y, VehicleVelocity.Z); + body.SetInterpolationLinearVelocity(ref velocity); + } + + internal static bool UseFrameOffset2(object pConstraint, float onOff) + { + Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; + constraint.SetUseFrameOffset((onOff == 0) ? false : true); + return true; + } + //SetBreakingImpulseThreshold2(m_constraint.ptr, threshold); + internal static bool SetBreakingImpulseThreshold2(object pConstraint, float threshold) + { + Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; + constraint.SetBreakingImpulseThreshold(threshold); + return true; + } + //BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, angularDamping); + internal static void SetAngularDamping2(object pBody, float angularDamping) + { + RigidBody body = pBody as RigidBody; + float lineardamping = body.GetLinearDamping(); + body.SetDamping(lineardamping, angularDamping); + + } + + internal static void UpdateInertiaTensor2(object pBody) + { + RigidBody body = pBody as RigidBody; + body.UpdateInertiaTensor(); + } + + internal static void RecalculateCompoundShapeLocalAabb2( object pCompoundShape) + { + + CompoundShape shape = pCompoundShape as CompoundShape; + shape.RecalculateLocalAabb(); + } + + //BulletSimAPI.GetCollisionFlags2(PhysBody.ptr) + internal static CollisionFlags GetCollisionFlags2(object pBody) + { + RigidBody body = pBody as RigidBody; + uint flags = (uint)body.GetCollisionFlags(); + return (CollisionFlags) flags; + } + + internal static void SetDamping2(object pBody, float pLinear, float pAngular) + { + RigidBody body = pBody as RigidBody; + body.SetDamping(pLinear, pAngular); + } + //PhysBody.ptr, PhysicsScene.Params.deactivationTime); + internal static void SetDeactivationTime2(object pBody, float pDeactivationTime) + { + RigidBody body = pBody as RigidBody; + body.SetDeactivationTime(pDeactivationTime); + } + //SetSleepingThresholds2(PhysBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold); + internal static void SetSleepingThresholds2(object pBody, float plinearSleepingThreshold, float pangularSleepingThreshold) + { + RigidBody body = pBody as RigidBody; + body.SetSleepingThresholds(plinearSleepingThreshold, pangularSleepingThreshold); + } + + internal static CollisionObjectTypes GetBodyType2(object pBody) + { + RigidBody body = pBody as RigidBody; + return (CollisionObjectTypes)(int) body.GetInternalType(); + } + + //BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, fSum); + internal static void ApplyCentralForce2(object pBody, Vector3 pfSum) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z); + body.ApplyCentralForce(ref fSum); + } + internal static void ApplyCentralImpulse2(object pBody, Vector3 pfSum) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z); + body.ApplyCentralImpulse(ref fSum); + } + internal static void ApplyTorque2(object pBody, Vector3 pfSum) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z); + body.ApplyTorque(ref fSum); + } + internal static void ApplyTorqueImpulse2(object pBody, Vector3 pfSum) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z); + body.ApplyTorqueImpulse(ref fSum); + } + + internal static void DumpRigidBody2(object p, object p_2) + { + //TODO: + } + + internal static void DumpCollisionShape2(object p, object p_2) + { + //TODO: + } + + internal static void DestroyObject2(object p, object p_2) + { + //TODO: + } + + internal static void Shutdown2(object pWorld) + { + DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + world.Cleanup(); + } + + internal static void DeleteCollisionShape2(object p, object p_2) + { + //TODO: + } + //(sim.ptr, shape.ptr, prim.LocalID, prim.RawPosition, prim.RawOrientation); + + internal static object CreateBodyFromShape2(object pWorld, object pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation) + { + CollisionWorld world = pWorld as CollisionWorld; + IndexedMatrix mat = + IndexedMatrix.CreateFromQuaternion(new IndexedQuaternion(pRawOrientation.X, pRawOrientation.Y, + pRawOrientation.Z, pRawOrientation.W)); + mat._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z); + CollisionShape shape = pShape as CollisionShape; + //UpdateSingleAabb2(world, shape); + // TODO: Feed Update array into null + RigidBody body = new RigidBody(0,new SimMotionState(world,pLocalID,mat,null),shape,IndexedVector3.Zero); + + body.SetUserPointer(pLocalID); + return body; + } + + + internal static object CreateBodyWithDefaultMotionState2( object pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation) + { + + IndexedMatrix mat = + IndexedMatrix.CreateFromQuaternion(new IndexedQuaternion(pRawOrientation.X, pRawOrientation.Y, + pRawOrientation.Z, pRawOrientation.W)); + mat._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z); + + CollisionShape shape = pShape as CollisionShape; + + // TODO: Feed Update array into null + RigidBody body = new RigidBody(0, new DefaultMotionState( mat, IndexedMatrix.Identity), shape, IndexedVector3.Zero); + body.SetWorldTransform(mat); + body.SetUserPointer(pLocalID); + return body; + } + //(m_mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); + internal static void SetCollisionFlags2(object pBody, CollisionFlags collisionFlags) + { + RigidBody body = pBody as RigidBody; + body.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags) (uint) collisionFlags); + } + //(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainHitFraction); + internal static void SetHitFraction2(object pBody, float pHitFraction) + { + RigidBody body = pBody as RigidBody; + body.SetHitFraction(pHitFraction); + } + //BuildCapsuleShape2(physicsScene.World.ptr, 1f, 1f, prim.Scale); + internal static object BuildCapsuleShape2(object pWorld, float pRadius, float pHeight, Vector3 pScale) + { + DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + IndexedVector3 scale = new IndexedVector3(pScale.X, pScale.Y, pScale.Z); + CapsuleShapeZ capsuleShapeZ = new CapsuleShapeZ(pRadius, pHeight); + capsuleShapeZ.SetMargin(world.WorldSettings.Params.collisionMargin); + capsuleShapeZ.SetLocalScaling(ref scale); + + return capsuleShapeZ; + } + + public static object Initialize2(Vector3 worldExtent, ConfigurationParameters[] o, int mMaxCollisionsPerFrame, ref List collisionArray, int mMaxUpdatesPerFrame, ref List updateArray, object mDebugLogCallbackHandle) + { + CollisionWorld.WorldData.ParamData p = new CollisionWorld.WorldData.ParamData(); + + p.angularDamping = o[0].XangularDamping; + p.defaultFriction = o[0].defaultFriction; + p.defaultFriction = o[0].defaultFriction; + p.defaultDensity = o[0].defaultDensity; + p.defaultRestitution = o[0].defaultRestitution; + p.collisionMargin = o[0].collisionMargin; + p.gravity = o[0].gravity; + + p.linearDamping = o[0].XlinearDamping; + p.angularDamping = o[0].XangularDamping; + p.deactivationTime = o[0].XdeactivationTime; + p.linearSleepingThreshold = o[0].XlinearSleepingThreshold; + p.angularSleepingThreshold = o[0].XangularSleepingThreshold; + p.ccdMotionThreshold = o[0].XccdMotionThreshold; + p.ccdSweptSphereRadius = o[0].XccdSweptSphereRadius; + p.contactProcessingThreshold = o[0].XcontactProcessingThreshold; + + p.terrainImplementation = o[0].XterrainImplementation; + p.terrainFriction = o[0].XterrainFriction; + + p.terrainHitFraction = o[0].XterrainHitFraction; + p.terrainRestitution = o[0].XterrainRestitution; + p.terrainCollisionMargin = o[0].XterrainCollisionMargin; + + p.avatarFriction = o[0].XavatarFriction; + p.avatarStandingFriction = o[0].XavatarStandingFriction; + p.avatarDensity = o[0].XavatarDensity; + p.avatarRestitution = o[0].XavatarRestitution; + p.avatarCapsuleWidth = o[0].XavatarCapsuleWidth; + p.avatarCapsuleDepth = o[0].XavatarCapsuleDepth; + p.avatarCapsuleHeight = o[0].XavatarCapsuleHeight; + p.avatarContactProcessingThreshold = o[0].XavatarContactProcessingThreshold; + + p.vehicleAngularDamping = o[0].XvehicleAngularDamping; + + p.maxPersistantManifoldPoolSize = o[0].maxPersistantManifoldPoolSize; + p.maxCollisionAlgorithmPoolSize = o[0].maxCollisionAlgorithmPoolSize; + p.shouldDisableContactPoolDynamicAllocation = o[0].shouldDisableContactPoolDynamicAllocation; + p.shouldForceUpdateAllAabbs = o[0].shouldForceUpdateAllAabbs; + p.shouldRandomizeSolverOrder = o[0].shouldRandomizeSolverOrder; + p.shouldSplitSimulationIslands = o[0].shouldSplitSimulationIslands; + p.shouldEnableFrictionCaching = o[0].shouldEnableFrictionCaching; + p.numberOfSolverIterations = o[0].numberOfSolverIterations; + + p.linksetImplementation = o[0].XlinksetImplementation; + p.linkConstraintUseFrameOffset = o[0].XlinkConstraintUseFrameOffset; + p.linkConstraintEnableTransMotor = o[0].XlinkConstraintEnableTransMotor; + p.linkConstraintTransMotorMaxVel = o[0].XlinkConstraintTransMotorMaxVel; + p.linkConstraintTransMotorMaxForce = o[0].XlinkConstraintTransMotorMaxForce; + p.linkConstraintERP = o[0].XlinkConstraintERP; + p.linkConstraintCFM = o[0].XlinkConstraintCFM; + p.linkConstraintSolverIterations = o[0].XlinkConstraintSolverIterations; + p.physicsLoggingFrames = o[0].physicsLoggingFrames; + DefaultCollisionConstructionInfo ccci = new DefaultCollisionConstructionInfo(); + + DefaultCollisionConfiguration cci = new DefaultCollisionConfiguration(); + CollisionDispatcher m_dispatcher = new CollisionDispatcher(cci); + + + if (p.maxPersistantManifoldPoolSize > 0) + cci.m_persistentManifoldPoolSize = (int)p.maxPersistantManifoldPoolSize; + if (p.shouldDisableContactPoolDynamicAllocation !=0) + m_dispatcher.SetDispatcherFlags(DispatcherFlags.CD_DISABLE_CONTACTPOOL_DYNAMIC_ALLOCATION); + //if (p.maxCollisionAlgorithmPoolSize >0 ) + + DbvtBroadphase m_broadphase = new DbvtBroadphase(); + //IndexedVector3 aabbMin = new IndexedVector3(0, 0, 0); + //IndexedVector3 aabbMax = new IndexedVector3(256, 256, 256); + + //AxisSweep3Internal m_broadphase2 = new AxisSweep3Internal(ref aabbMin, ref aabbMax, Convert.ToInt32(0xfffe), 0xffff, ushort.MaxValue/2, null, true); + m_broadphase.GetOverlappingPairCache().SetInternalGhostPairCallback(new GhostPairCallback()); + + SequentialImpulseConstraintSolver m_solver = new SequentialImpulseConstraintSolver(); + + DiscreteDynamicsWorld world = new DiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, cci); + world.UpdatedObjects = updateArray; + world.UpdatedCollisions = collisionArray; + world.WorldSettings.Params = p; + world.SetForceUpdateAllAabbs(p.shouldForceUpdateAllAabbs != 0); + world.GetSolverInfo().m_solverMode = SolverMode.SOLVER_USE_WARMSTARTING | SolverMode.SOLVER_SIMD; + if (p.shouldRandomizeSolverOrder != 0) + world.GetSolverInfo().m_solverMode |= SolverMode.SOLVER_RANDMIZE_ORDER; + + world.GetSimulationIslandManager().SetSplitIslands(p.shouldSplitSimulationIslands != 0); + //world.GetDispatchInfo().m_enableSatConvex Not implemented in C# port + + if (p.shouldEnableFrictionCaching != 0) + world.GetSolverInfo().m_solverMode |= SolverMode.SOLVER_ENABLE_FRICTION_DIRECTION_CACHING; + + if (p.numberOfSolverIterations > 0) + world.GetSolverInfo().m_numIterations = (int) p.numberOfSolverIterations; + + + world.GetSolverInfo().m_damping = world.WorldSettings.Params.linearDamping; + world.GetSolverInfo().m_restitution = world.WorldSettings.Params.defaultRestitution; + world.GetSolverInfo().m_globalCfm = 0.0f; + world.GetSolverInfo().m_tau = 0.6f; + world.GetSolverInfo().m_friction = 0.3f; + world.GetSolverInfo().m_maxErrorReduction = 20f; + world.GetSolverInfo().m_numIterations = 10; + world.GetSolverInfo().m_erp = 0.2f; + world.GetSolverInfo().m_erp2 = 0.1f; + world.GetSolverInfo().m_sor = 1.0f; + world.GetSolverInfo().m_splitImpulse = false; + world.GetSolverInfo().m_splitImpulsePenetrationThreshold = -0.02f; + world.GetSolverInfo().m_linearSlop = 0.0f; + world.GetSolverInfo().m_warmstartingFactor = 0.85f; + world.GetSolverInfo().m_restingContactRestitutionThreshold = 2; + world.SetForceUpdateAllAabbs(true); + + + world.SetGravity(new IndexedVector3(0,0,p.gravity)); + + return world; + } + //m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL + internal static bool SetConstraintParam2(object pConstraint, ConstraintParams paramIndex, float paramvalue, ConstraintParamAxis axis) + { + Generic6DofConstraint constrain = pConstraint as Generic6DofConstraint; + if (axis == ConstraintParamAxis.AXIS_LINEAR_ALL || axis == ConstraintParamAxis.AXIS_ALL) + { + constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams) (int) paramIndex, paramvalue, 0); + constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams) (int) paramIndex, paramvalue, 1); + constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams) (int) paramIndex, paramvalue, 2); + } + if (axis == ConstraintParamAxis.AXIS_ANGULAR_ALL || axis == ConstraintParamAxis.AXIS_ALL) + { + constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams)(int)paramIndex, paramvalue, 3); + constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams)(int)paramIndex, paramvalue, 4); + constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams)(int)paramIndex, paramvalue, 5); + } + if (axis == ConstraintParamAxis.AXIS_LINEAR_ALL) + { + constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams)(int)paramIndex, paramvalue, (int)axis); + } + return true; + } + + internal static bool PushUpdate2(object pCollisionObject) + { + bool ret = false; + RigidBody rb = pCollisionObject as RigidBody; + if (rb != null) + { + SimMotionState sms = rb.GetMotionState() as SimMotionState; + if (sms != null) + { + IndexedMatrix wt = IndexedMatrix.Identity; + sms.GetWorldTransform(out wt); + sms.SetWorldTransform(ref wt, true); + ret = true; + } + } + return ret; + + } + + internal static bool IsCompound2(object pShape) + { + CollisionShape shape = pShape as CollisionShape; + return shape.IsCompound(); + } + internal static bool IsPloyhedral2(object pShape) + { + CollisionShape shape = pShape as CollisionShape; + return shape.IsPolyhedral(); + } + internal static bool IsConvex2d2(object pShape) + { + CollisionShape shape = pShape as CollisionShape; + return shape.IsConvex2d(); + } + internal static bool IsConvex2(object pShape) + { + CollisionShape shape = pShape as CollisionShape; + return shape.IsConvex(); + } + internal static bool IsNonMoving2(object pShape) + { + CollisionShape shape = pShape as CollisionShape; + return shape.IsNonMoving(); + } + internal static bool IsConcave2(object pShape) + { + CollisionShape shape = pShape as CollisionShape; + return shape.IsConcave(); + } + internal static bool IsInfinite2(object pShape) + { + CollisionShape shape = pShape as CollisionShape; + return shape.IsInfinite(); + } + internal static bool IsNativeShape2(object pShape) + { + CollisionShape shape = pShape as CollisionShape; + bool ret; + switch (shape.GetShapeType()) + { + case BroadphaseNativeTypes.BOX_SHAPE_PROXYTYPE: + case BroadphaseNativeTypes.CONE_SHAPE_PROXYTYPE: + case BroadphaseNativeTypes.SPHERE_SHAPE_PROXYTYPE: + case BroadphaseNativeTypes.CYLINDER_SHAPE_PROXYTYPE: + ret = true; + break; + default: + ret = false; + break; + } + return ret; + } + //sim.ptr, shape.ptr,prim.LocalID, prim.RawPosition, prim.RawOrientation + internal static object CreateGhostFromShape2(object pWorld, object pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation) + { + IndexedMatrix bodyTransform = new IndexedMatrix(); + bodyTransform._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z); + bodyTransform.SetRotation(new IndexedQuaternion(pRawOrientation.X,pRawOrientation.Y,pRawOrientation.Z,pRawOrientation.W)); + GhostObject gObj = new PairCachingGhostObject(); + gObj.SetWorldTransform(bodyTransform); + CollisionShape shape = pShape as CollisionShape; + gObj.SetCollisionShape(shape); + gObj.SetUserPointer(pLocalID); + // TODO: Add to Special CollisionObjects! + return gObj; + } + + public static void SetCollisionShape2(object pWorld, object pObj, object pShape) + { + var world = pWorld as DiscreteDynamicsWorld; + var obj = pObj as CollisionObject; + var shape = pShape as CollisionShape; + obj.SetCollisionShape(shape); + + } + //(PhysicsScene.World.ptr, nativeShapeData) + internal static object BuildNativeShape2(object pWorld, ShapeData pShapeData) + { + var world = pWorld as DiscreteDynamicsWorld; + CollisionShape shape = null; + switch (pShapeData.Type) + { + case BSPhysicsShapeType.SHAPE_BOX: + shape = new BoxShape(new IndexedVector3(0.5f,0.5f,0.5f)); + break; + case BSPhysicsShapeType.SHAPE_CONE: + shape = new ConeShapeZ(0.5f, 1.0f); + break; + case BSPhysicsShapeType.SHAPE_CYLINDER: + shape = new CylinderShapeZ(new IndexedVector3(0.5f, 0.5f, 0.5f)); + break; + case BSPhysicsShapeType.SHAPE_SPHERE: + shape = new SphereShape(0.5f); + break; + + } + if (shape != null) + { + IndexedVector3 scaling = new IndexedVector3(pShapeData.Scale.X, pShapeData.Scale.Y, pShapeData.Scale.Z); + shape.SetMargin(world.WorldSettings.Params.collisionMargin); + shape.SetLocalScaling(ref scaling); + + } + return shape; + } + //PhysicsScene.World.ptr, false + internal static object CreateCompoundShape2(object pWorld, bool enableDynamicAabbTree) + { + return new CompoundShape(enableDynamicAabbTree); + } + + internal static int GetNumberOfCompoundChildren2(object pCompoundShape) + { + var compoundshape = pCompoundShape as CompoundShape; + return compoundshape.GetNumChildShapes(); + } + //LinksetRoot.PhysShape.ptr, newShape.ptr, displacementPos, displacementRot + internal static void AddChildShapeToCompoundShape2(object pCShape, object paddShape, Vector3 displacementPos, Quaternion displacementRot) + { + IndexedMatrix relativeTransform = new IndexedMatrix(); + var compoundshape = pCShape as CompoundShape; + var addshape = paddShape as CollisionShape; + + relativeTransform._origin = new IndexedVector3(displacementPos.X, displacementPos.Y, displacementPos.Z); + relativeTransform.SetRotation(new IndexedQuaternion(displacementRot.X,displacementRot.Y,displacementRot.Z,displacementRot.W)); + compoundshape.AddChildShape(ref relativeTransform, addshape); + + } + + internal static object RemoveChildShapeFromCompoundShapeIndex2(object pCShape, int pii) + { + var compoundshape = pCShape as CompoundShape; + CollisionShape ret = null; + ret = compoundshape.GetChildShape(pii); + compoundshape.RemoveChildShapeByIndex(pii); + return ret; + } + + internal static object CreateGroundPlaneShape2(uint pLocalId, float pheight, float pcollisionMargin) + { + StaticPlaneShape m_planeshape = new StaticPlaneShape(new IndexedVector3(0,0,1),(int)pheight ); + m_planeshape.SetMargin(pcollisionMargin); + m_planeshape.SetUserPointer(pLocalId); + return m_planeshape; + } + + internal static object CreateHingeConstraint2(object pWorld, object pBody1, object ppBody2, Vector3 ppivotInA, Vector3 ppivotInB, Vector3 paxisInA, Vector3 paxisInB, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies) + { + HingeConstraint constrain = null; + var rb1 = pBody1 as RigidBody; + var rb2 = ppBody2 as RigidBody; + if (rb1 != null && rb2 != null) + { + IndexedVector3 pivotInA = new IndexedVector3(ppivotInA.X, ppivotInA.Y, ppivotInA.Z); + IndexedVector3 pivotInB = new IndexedVector3(ppivotInB.X, ppivotInB.Y, ppivotInB.Z); + IndexedVector3 axisInA = new IndexedVector3(paxisInA.X, paxisInA.Y, paxisInA.Z); + IndexedVector3 axisInB = new IndexedVector3(paxisInB.X, paxisInB.Y, paxisInB.Z); + var world = pWorld as DiscreteDynamicsWorld; + world.AddConstraint(constrain, pdisableCollisionsBetweenLinkedBodies); + } + return constrain; + } + + internal static bool ReleaseHeightMapInfo2(object pMapInfo) + { + if (pMapInfo != null) + { + BulletHeightMapInfo mapinfo = pMapInfo as BulletHeightMapInfo; + if (mapinfo.heightMap != null) + mapinfo.heightMap = null; + + + } + return true; + } + + internal static object CreateHullShape2(object pWorld, int pHullCount, float[] pConvHulls) + { + CompoundShape compoundshape = new CompoundShape(false); + var world = pWorld as DiscreteDynamicsWorld; + + + compoundshape.SetMargin(world.WorldSettings.Params.collisionMargin); + int ii = 1; + + for (int i = 0; i < pHullCount; i++) + { + int vertexCount = (int) pConvHulls[ii]; + + IndexedVector3 centroid = new IndexedVector3(pConvHulls[ii + 1], pConvHulls[ii + 2], pConvHulls[ii + 3]); + IndexedMatrix childTrans = IndexedMatrix.Identity; + childTrans._origin = centroid; + + List virts = new List(); + int ender = ((ii + 4) + (vertexCount*3)); + for (int iii = ii + 4; iii < ender; iii+=3) + { + + virts.Add(new IndexedVector3(pConvHulls[iii], pConvHulls[iii + 1], pConvHulls[iii +2])); + } + ConvexHullShape convexShape = new ConvexHullShape(virts, vertexCount); + convexShape.SetMargin(world.WorldSettings.Params.collisionMargin); + compoundshape.AddChildShape(ref childTrans, convexShape); + ii += (vertexCount*3 + 4); + } + + + return compoundshape; + } + + internal static object CreateMeshShape2(object pWorld, int pIndicesCount, int[] indices, int pVerticesCount, float[] verticesAsFloats) + { + //DumpRaw(indices,verticesAsFloats,pIndicesCount,pVerticesCount); + + for (int iter = 0; iter < pVerticesCount; iter++) + { + if (verticesAsFloats[iter] > 0 && verticesAsFloats[iter] < 0.0001) verticesAsFloats[iter] = 0; + if (verticesAsFloats[iter] < 0 && verticesAsFloats[iter] > -0.0001) verticesAsFloats[iter] = 0; + } + + ObjectArray indicesarr = new ObjectArray(indices); + ObjectArray vertices = new ObjectArray(verticesAsFloats); + DumpRaw(indicesarr,vertices,pIndicesCount,pVerticesCount); + var world = pWorld as DiscreteDynamicsWorld; + IndexedMesh mesh = new IndexedMesh(); + mesh.m_indexType = PHY_ScalarType.PHY_INTEGER; + mesh.m_numTriangles = pIndicesCount/3; + mesh.m_numVertices = pVerticesCount; + mesh.m_triangleIndexBase = indicesarr; + mesh.m_vertexBase = vertices; + mesh.m_vertexStride = 3; + mesh.m_vertexType = PHY_ScalarType.PHY_FLOAT; + mesh.m_triangleIndexStride = 3; + + TriangleIndexVertexArray tribuilder = new TriangleIndexVertexArray(); + tribuilder.AddIndexedMesh(mesh, PHY_ScalarType.PHY_INTEGER); + BvhTriangleMeshShape meshShape = new BvhTriangleMeshShape(tribuilder, true,true); + meshShape.SetMargin(world.WorldSettings.Params.collisionMargin); + // world.UpdateSingleAabb(meshShape); + return meshShape; + + } + public static void DumpRaw(ObjectArrayindices, ObjectArray vertices, int pIndicesCount,int pVerticesCount ) + { + + String fileName = "objTest3.raw"; + String completePath = System.IO.Path.Combine(Util.configDir(), fileName); + StreamWriter sw = new StreamWriter(completePath); + IndexedMesh mesh = new IndexedMesh(); + + mesh.m_indexType = PHY_ScalarType.PHY_INTEGER; + mesh.m_numTriangles = pIndicesCount / 3; + mesh.m_numVertices = pVerticesCount; + mesh.m_triangleIndexBase = indices; + mesh.m_vertexBase = vertices; + mesh.m_vertexStride = 3; + mesh.m_vertexType = PHY_ScalarType.PHY_FLOAT; + mesh.m_triangleIndexStride = 3; + + TriangleIndexVertexArray tribuilder = new TriangleIndexVertexArray(); + tribuilder.AddIndexedMesh(mesh, PHY_ScalarType.PHY_INTEGER); + + + + for (int i = 0; i < pVerticesCount; i++) + { + + string s = vertices[indices[i * 3]].ToString("0.0000"); + s += " " + vertices[indices[i * 3 + 1]].ToString("0.0000"); + s += " " + vertices[indices[i * 3 + 2]].ToString("0.0000"); + + sw.Write(s + "\n"); + } + + sw.Close(); + } + public static void DumpRaw(int[] indices, float[] vertices, int pIndicesCount, int pVerticesCount) + { + + String fileName = "objTest6.raw"; + String completePath = System.IO.Path.Combine(Util.configDir(), fileName); + StreamWriter sw = new StreamWriter(completePath); + IndexedMesh mesh = new IndexedMesh(); + + mesh.m_indexType = PHY_ScalarType.PHY_INTEGER; + mesh.m_numTriangles = pIndicesCount / 3; + mesh.m_numVertices = pVerticesCount; + mesh.m_triangleIndexBase = indices; + mesh.m_vertexBase = vertices; + mesh.m_vertexStride = 3; + mesh.m_vertexType = PHY_ScalarType.PHY_FLOAT; + mesh.m_triangleIndexStride = 3; + + TriangleIndexVertexArray tribuilder = new TriangleIndexVertexArray(); + tribuilder.AddIndexedMesh(mesh, PHY_ScalarType.PHY_INTEGER); + + + sw.WriteLine("Indices"); + sw.WriteLine(string.Format("int[] indices = new int[{0}];",pIndicesCount)); + for (int iter = 0; iter < indices.Length; iter++) + { + sw.WriteLine(string.Format("indices[{0}]={1};",iter,indices[iter])); + } + sw.WriteLine("VerticesFloats"); + sw.WriteLine(string.Format("float[] vertices = new float[{0}];", pVerticesCount)); + for (int iter = 0; iter < vertices.Length; iter++) + { + sw.WriteLine(string.Format("Vertices[{0}]={1};", iter, vertices[iter].ToString("0.0000"))); + } + + // for (int i = 0; i < pVerticesCount; i++) + // { + // + // string s = vertices[indices[i * 3]].ToString("0.0000"); + // s += " " + vertices[indices[i * 3 + 1]].ToString("0.0000"); + // s += " " + vertices[indices[i * 3 + 2]].ToString("0.0000"); + // + // sw.Write(s + "\n"); + //} + + sw.Close(); + } + //PhysicsScene.World.ptr, m_mapInfo.ID, m_mapInfo.minCoords, m_mapInfo.maxCoords, m_mapInfo.heightMap, PhysicsScene.Params.terrainCollisionMargin + internal static object CreateHeightMapInfo2(object pWorld, uint pId, Vector3 pminCoords, Vector3 pmaxCoords, float[] pheightMap, float pCollisionMargin) + { + BulletHeightMapInfo mapInfo = new BulletHeightMapInfo(pId, pheightMap, null); + mapInfo.heightMap = null; + mapInfo.minCoords = pminCoords; + mapInfo.maxCoords = pmaxCoords; + mapInfo.sizeX = (int) (pmaxCoords.X - pminCoords.X); + mapInfo.sizeY = (int) (pmaxCoords.Y - pminCoords.Y); + mapInfo.ID = pId; + mapInfo.minZ = pminCoords.Z; + mapInfo.maxZ = pmaxCoords.Z; + mapInfo.collisionMargin = pCollisionMargin; + if (mapInfo.minZ == mapInfo.maxZ) + mapInfo.minZ -= 0.2f; + mapInfo.heightMap = pheightMap; + + return mapInfo; + + } + + internal static object CreateTerrainShape2(object pMapInfo) + { + BulletHeightMapInfo mapinfo = pMapInfo as BulletHeightMapInfo; + const int upAxis = 2; + const float scaleFactor = 1.0f; + HeightfieldTerrainShape terrainShape = new HeightfieldTerrainShape((int)mapinfo.sizeX, (int)mapinfo.sizeY, + mapinfo.heightMap, scaleFactor, + mapinfo.minZ, mapinfo.maxZ, upAxis, + false); + terrainShape.SetMargin(mapinfo.collisionMargin + 0.5f); + terrainShape.SetUseDiamondSubdivision(true); + terrainShape.SetUserPointer(mapinfo.ID); + return terrainShape; + } + + internal static bool TranslationalLimitMotor2(object pConstraint, float ponOff, float targetVelocity, float maxMotorForce) + { + TypedConstraint tconstrain = pConstraint as TypedConstraint; + bool onOff = ponOff != 0; + bool ret = false; + + switch (tconstrain.GetConstraintType()) + { + case TypedConstraintType.D6_CONSTRAINT_TYPE: + Generic6DofConstraint constrain = pConstraint as Generic6DofConstraint; + constrain.GetTranslationalLimitMotor().m_enableMotor[0] = onOff; + constrain.GetTranslationalLimitMotor().m_targetVelocity[0] = targetVelocity; + constrain.GetTranslationalLimitMotor().m_maxMotorForce[0] = maxMotorForce; + ret = true; + break; + } + + + return ret; + + } + + internal static int PhysicsStep2(object pWorld, float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount, out List updatedEntities, out int collidersCount, out Listcolliders) + { + int epic = PhysicsStepint2(pWorld, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out updatedEntities, + out collidersCount, out colliders); + return epic; + } + + private static int PhysicsStepint2(object pWorld,float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount, out List updatedEntities, out int collidersCount, out List colliders) + { + int numSimSteps = 0; + + + //if (updatedEntities is null) + // updatedEntities = new List(); + + //if (colliders is null) + // colliders = new List(); + + + if (pWorld is DiscreteDynamicsWorld) + { + DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + + numSimSteps = world.StepSimulation(timeStep, m_maxSubSteps, m_fixedTimeStep); + int updates = 0; + + updatedEntityCount = world.UpdatedObjects.Count; + updatedEntities = new List(world.UpdatedObjects); + updatedEntityCount = updatedEntities.Count; + world.UpdatedObjects.Clear(); + + + collidersCount = world.UpdatedCollisions.Count; + colliders = new List(world.UpdatedCollisions); + + world.UpdatedCollisions.Clear(); + m_collisionsThisFrame = 0; + int numManifolds = world.GetDispatcher().GetNumManifolds(); + for (int j = 0; j < numManifolds; j++) + { + PersistentManifold contactManifold = world.GetDispatcher().GetManifoldByIndexInternal(j); + int numContacts = contactManifold.GetNumContacts(); + if (numContacts == 0) + continue; + + CollisionObject objA = contactManifold.GetBody0() as CollisionObject; + CollisionObject objB = contactManifold.GetBody1() as CollisionObject; + + ManifoldPoint manifoldPoint = contactManifold.GetContactPoint(0); + IndexedVector3 contactPoint = manifoldPoint.GetPositionWorldOnB(); + IndexedVector3 contactNormal = -manifoldPoint.m_normalWorldOnB; // make relative to A + + RecordCollision(world, objA, objB, contactPoint, contactNormal); + m_collisionsThisFrame ++; + if (m_collisionsThisFrame >= 9999999) + break; + + + } + + + } + else + { + //if (updatedEntities is null) + updatedEntities = new List(); + updatedEntityCount = 0; + //if (colliders is null) + colliders = new List(); + collidersCount = 0; + } + return numSimSteps; + } + + private static void RecordCollision(CollisionWorld world,CollisionObject objA, CollisionObject objB, IndexedVector3 contact, IndexedVector3 norm) + { + + IndexedVector3 contactNormal = norm; + if ((objA.GetCollisionFlags() & BulletXNA.BulletCollision.CollisionFlags.BS_WANTS_COLLISIONS) == 0 && + (objB.GetCollisionFlags() & BulletXNA.BulletCollision.CollisionFlags.BS_WANTS_COLLISIONS) == 0) + { + return; + } + uint idA = (uint)objA.GetUserPointer(); + uint idB = (uint)objB.GetUserPointer(); + if (idA > idB) + { + uint temp = idA; + idA = idB; + idB = temp; + contactNormal = -contactNormal; + } + + ulong collisionID = ((ulong) idA << 32) | idB; + + BulletXNA.CollisionDesc cDesc = new BulletXNA.CollisionDesc() + { + aID = idA, + bID = idB, + point = contact, + normal = contactNormal + }; + world.UpdatedCollisions.Add(cDesc); + m_collisionsThisFrame++; + + + } + private static EntityProperties GetDebugProperties(object pWorld, object pBody) + { + EntityProperties ent = new EntityProperties(); + DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + RigidBody body = pBody as RigidBody; + IndexedMatrix transform = body.GetWorldTransform(); + IndexedVector3 LinearVelocity = body.GetInterpolationLinearVelocity(); + IndexedVector3 AngularVelocity = body.GetInterpolationAngularVelocity(); + IndexedQuaternion rotation = transform.GetRotation(); + ent.Acceleration = Vector3.Zero; + ent.ID = (uint)body.GetUserPointer(); + ent.Position = new Vector3(transform._origin.X,transform._origin.Y,transform._origin.Z); + ent.Rotation = new Quaternion(rotation.X,rotation.Y,rotation.Z,rotation.W); + ent.Velocity = new Vector3(LinearVelocity.X, LinearVelocity.Y, LinearVelocity.Z); + ent.RotationalVelocity = new Vector3(AngularVelocity.X, AngularVelocity.Y, AngularVelocity.Z); + return ent; + + + } + + + internal static Vector3 GetLocalScaling2(object pBody) + { + CollisionShape shape = pBody as CollisionShape; + IndexedVector3 scale = shape.GetLocalScaling(); + return new Vector3(scale.X,scale.Y,scale.Z); + } + + internal static bool RayCastGround(object pWorld, Vector3 _RayOrigin, float pRayHeight, object NotMe) + { + DynamicsWorld world = pWorld as DynamicsWorld; + if (world != null) + { + if (NotMe is CollisionObject || NotMe is RigidBody) + { + CollisionObject AvoidBody = NotMe as CollisionObject; + + IndexedVector3 rOrigin = new IndexedVector3(_RayOrigin.X, _RayOrigin.Y, _RayOrigin.Z); + IndexedVector3 rEnd = new IndexedVector3(_RayOrigin.X, _RayOrigin.Y, _RayOrigin.Z - pRayHeight); + using ( + ClosestNotMeRayResultCallback rayCallback = new ClosestNotMeRayResultCallback(rOrigin, + rEnd, AvoidBody) + ) + { + world.RayTest(ref rOrigin, ref rEnd, rayCallback); + if (rayCallback.HasHit()) + { + IndexedVector3 hitLocation = rayCallback.m_hitPointWorld; + + } + return rayCallback.HasHit(); + } + } + } + return false; + } +} +} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BulletSimData.cs b/OpenSim/Region/Physics/BulletSNPlugin/BulletSimData.cs new file mode 100644 index 0000000..a1ed8d8 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSNPlugin/BulletSimData.cs @@ -0,0 +1,280 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using OMV = OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSNPlugin +{ +// Classes to allow some type checking for the API +// These hold pointers to allocated objects in the unmanaged space. + +// The physics engine controller class created at initialization +public struct BulletSim +{ + public BulletSim(uint worldId, BSScene bss, object xx) + { + ptr = xx; + worldID = worldId; + physicsScene = bss; + } + public object ptr; + public uint worldID; + // The scene is only in here so very low level routines have a handle to print debug/error messages + public BSScene physicsScene; +} + +// An allocated Bullet btRigidBody +public struct BulletBody +{ + public BulletBody(uint id) : this(id, null) + { + } + public BulletBody(uint id, object xx) + { + ID = id; + ptr = xx; + collisionType = CollisionType.Static; + } + public object ptr; + public uint ID; + public CollisionType collisionType; + + public void Clear() + { + ptr = null; + } + public bool HasPhysicalBody { get { return ptr != null; } } + + // Apply the specificed collision mask into the physical world + public void ApplyCollisionMask() + { + // Should assert the body has been added to the physical world. + // (The collision masks are stored in the collision proxy cache which only exists for + // a collision body that is in the world.) + BulletSimAPI.SetCollisionGroupMask2(ptr, + BulletSimData.CollisionTypeMasks[collisionType].group, + BulletSimData.CollisionTypeMasks[collisionType].mask); + } + + public override string ToString() + { + StringBuilder buff = new StringBuilder(); + buff.Append(""); + return buff.ToString(); + } +} + +public struct BulletShape +{ + public BulletShape(object xx) : this(xx, BSPhysicsShapeType.SHAPE_UNKNOWN) + { + } + public BulletShape(object xx, BSPhysicsShapeType typ) + { + ptr = xx; + type = typ; + shapeKey = (System.UInt64)FixedShapeKey.KEY_NONE; + isNativeShape = false; + } + public object ptr; + public BSPhysicsShapeType type; + public System.UInt64 shapeKey; + public bool isNativeShape; + + public void Clear() + { + ptr = null; + } + public bool HasPhysicalShape { get { return ptr != null; } } + + public override string ToString() + { + StringBuilder buff = new StringBuilder(); + buff.Append(""); + return buff.ToString(); + } +} + +// An allocated Bullet btConstraint +public struct BulletConstraint +{ + public BulletConstraint(object xx) + { + ptr = xx; + } + public object ptr; + + public void Clear() + { + ptr = null; + } + public bool HasPhysicalConstraint { get { return ptr != null; } } +} + +// An allocated HeightMapThing which holds various heightmap info. +// Made a class rather than a struct so there would be only one +// instance of this and C# will pass around pointers rather +// than making copies. +public class BulletHeightMapInfo +{ + public BulletHeightMapInfo(uint id, float[] hm, object xx) { + ID = id; + Ptr = xx; + heightMap = hm; + terrainRegionBase = OMV.Vector3.Zero; + minCoords = new OMV.Vector3(100f, 100f, 25f); + maxCoords = new OMV.Vector3(101f, 101f, 26f); + minZ = maxZ = 0f; + sizeX = sizeY = 256f; + } + public uint ID; + public object Ptr; + public float[] heightMap; + public OMV.Vector3 terrainRegionBase; + public OMV.Vector3 minCoords; + public OMV.Vector3 maxCoords; + public float sizeX, sizeY; + public float minZ, maxZ; + public BulletShape terrainShape; + public BulletBody terrainBody; + + public float collisionMargin { get; set; } +} + +// The general class of collsion object. +public enum CollisionType +{ + Avatar, + Groundplane, + Terrain, + Static, + Dynamic, + VolumeDetect, + // Linkset, // A linkset should be either Static or Dynamic + LinksetChild, + Unknown +}; + +// Hold specification of group and mask collision flags for a CollisionType +public struct CollisionTypeFilterGroup +{ + public CollisionTypeFilterGroup(CollisionType t, uint g, uint m) + { + type = t; + group = g; + mask = m; + } + public CollisionType type; + public uint group; + public uint mask; +}; + + /* NOTE: old definitions kept for reference. Delete when things are working. + // The collsion filters and masked are defined in one place -- don't want them scattered + AvatarGroup = BCharacterGroup, + AvatarMask = BAllGroup, + ObjectGroup = BSolidGroup, + ObjectMask = BAllGroup, + StaticObjectGroup = BStaticGroup, + StaticObjectMask = AvatarGroup | ObjectGroup, // static things don't interact with much + LinksetGroup = BLinksetGroup, + LinksetMask = BAllGroup, + LinksetChildGroup = BLinksetChildGroup, + LinksetChildMask = BNoneGroup, // Linkset children disappear from the world + VolumeDetectGroup = BSensorTrigger, + VolumeDetectMask = ~BSensorTrigger, + TerrainGroup = BTerrainGroup, + TerrainMask = BAllGroup & ~BStaticGroup, // static objects on the ground don't collide + GroundPlaneGroup = BGroundPlaneGroup, + GroundPlaneMask = BAllGroup + */ + +public static class BulletSimData +{ + +// Map of collisionTypes to flags for collision groups and masks. +// As mentioned above, don't use the CollisionFilterGroups definitions directly in the code +// but, instead, use references to this dictionary. Finding and debugging +// collision flag problems will be made easier. +public static Dictionary CollisionTypeMasks + = new Dictionary() +{ + { CollisionType.Avatar, + new CollisionTypeFilterGroup(CollisionType.Avatar, + (uint)CollisionFilterGroups.BCharacterGroup, + (uint)CollisionFilterGroups.BAllGroup) + }, + { CollisionType.Groundplane, + new CollisionTypeFilterGroup(CollisionType.Groundplane, + (uint)CollisionFilterGroups.BGroundPlaneGroup, + (uint)CollisionFilterGroups.BAllGroup) + }, + { CollisionType.Terrain, + new CollisionTypeFilterGroup(CollisionType.Terrain, + (uint)CollisionFilterGroups.BTerrainGroup, + (uint)(CollisionFilterGroups.BAllGroup & ~CollisionFilterGroups.BStaticGroup)) + }, + { CollisionType.Static, + new CollisionTypeFilterGroup(CollisionType.Static, + (uint)CollisionFilterGroups.BStaticGroup, + (uint)(CollisionFilterGroups.BCharacterGroup | CollisionFilterGroups.BSolidGroup)) + }, + { CollisionType.Dynamic, + new CollisionTypeFilterGroup(CollisionType.Dynamic, + (uint)CollisionFilterGroups.BSolidGroup, + (uint)(CollisionFilterGroups.BAllGroup)) + }, + { CollisionType.VolumeDetect, + new CollisionTypeFilterGroup(CollisionType.VolumeDetect, + (uint)CollisionFilterGroups.BSensorTrigger, + (uint)(~CollisionFilterGroups.BSensorTrigger)) + }, + { CollisionType.LinksetChild, + new CollisionTypeFilterGroup(CollisionType.LinksetChild, + (uint)CollisionFilterGroups.BTerrainGroup, + (uint)(CollisionFilterGroups.BNoneGroup)) + }, +}; + +} +} -- cgit v1.1 From 93188706073fa23aa037456f5ec2d52605257d89 Mon Sep 17 00:00:00 2001 From: teravus Date: Sun, 23 Dec 2012 16:17:18 -0500 Subject: * Update BulletSimN terrain implementation to default to Heightfield, it's less CPU intensive. --- OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs index 0bb1674..20c0939 100644 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs @@ -315,7 +315,7 @@ public static class BSParam (s,o,v) => { BulletSimAPI.SetContactProcessingThreshold2(o.PhysBody.ptr, v); } ), new ParameterDefn("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)", - (float)BSTerrainPhys.TerrainImplementation.Mesh, + (float)BSTerrainPhys.TerrainImplementation.Heightmap, (s,cf,p,v) => { TerrainImplementation = cf.GetFloat(p,v); }, (s) => { return TerrainImplementation; }, (s,p,l,v) => { TerrainImplementation = v; } ), -- cgit v1.1 From 80cee1b85a646045c02e2bb675056d532ce2fe27 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 24 Dec 2012 08:56:02 -0800 Subject: BulletSim: Fix single physical prim reporting its mass as zero. Properly return root mass as mass of just the root prim rather than the mass of the linkset. SOG has the logic to add the masses together to get the linkset mass. Update TODO list. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 9 +-- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 20 +++--- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 13 ++-- .../Physics/BulletSPlugin/BSLinksetConstraints.cs | 6 +- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 3 +- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 71 ++++++++++++++-------- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 15 ++++- 7 files changed, 83 insertions(+), 54 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 8e059ee..bf0545a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -174,7 +174,7 @@ public sealed class BSCharacter : BSPhysObject BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius); } - UpdatePhysicalMassProperties(RawMass); + UpdatePhysicalMassProperties(RawMass, false); // Make so capsule does not fall over BulletSimAPI.SetAngularFactorV2(PhysBody.ptr, OMV.Vector3.Zero); @@ -224,7 +224,7 @@ public sealed class BSCharacter : BSPhysObject if (PhysBody.HasPhysicalBody && PhysShape.HasPhysicalShape) { BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale); - UpdatePhysicalMassProperties(RawMass); + UpdatePhysicalMassProperties(RawMass, true); // Make sure this change appears as a property update event BulletSimAPI.PushUpdate2(PhysBody.ptr); } @@ -390,7 +390,7 @@ public sealed class BSCharacter : BSPhysObject public override float RawMass { get {return _mass; } } - public override void UpdatePhysicalMassProperties(float physMass) + public override void UpdatePhysicalMassProperties(float physMass, bool inWorld) { OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass); BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, localInertia); @@ -772,8 +772,9 @@ public sealed class BSCharacter : BSPhysObject // the motor can be turned off. Set the velocity to zero so the zero motion is sent to the viewer. if (_velocityMotor.TargetValue.ApproxEquals(OMV.Vector3.Zero, 0.01f) && _velocityMotor.ErrorIsZero) { - stepVelocity = OMV.Vector3.Zero; _velocityMotor.Enabled = false; + stepVelocity = OMV.Vector3.Zero; + ZeroMotion(true); DetailLog("{0},BSCharacter.UpdateProperties,taint,disableVelocityMotor,m={1}", LocalID, _velocityMotor); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 8580928..756faed 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -97,14 +97,7 @@ public abstract class BSLinkset } // We keep the prim's mass in the linkset structure since it could be dependent on other prims - protected float m_mass; - public float LinksetMass - { - get - { - return m_mass; - } - } + public float LinksetMass { get; protected set; } public virtual bool LinksetIsColliding { get { return false; } } @@ -128,7 +121,7 @@ public abstract class BSLinkset PhysicsScene = scene; LinksetRoot = parent; m_children = new HashSet(); - m_mass = parent.RawMass; + LinksetMass = parent.RawMass; Rebuilding = false; } @@ -143,7 +136,7 @@ public abstract class BSLinkset // Don't add the root to its own linkset if (!IsRoot(child)) AddChildToLinkset(child); - m_mass = ComputeLinksetMass(); + LinksetMass = ComputeLinksetMass(); } return this; } @@ -162,7 +155,7 @@ public abstract class BSLinkset return this; } RemoveChildFromLinkset(child); - m_mass = ComputeLinksetMass(); + LinksetMass = ComputeLinksetMass(); } // The child is down to a linkset of just itself @@ -230,7 +223,10 @@ public abstract class BSLinkset // When physical properties are changed the linkset needs to recalculate // its internal properties. // May be called at runtime or taint-time. - public abstract void Refresh(BSPhysObject requestor); + public virtual void Refresh(BSPhysObject requestor) + { + LinksetMass = ComputeLinksetMass(); + } // Flag denoting the linkset is in the process of being rebuilt. // Used to know not the schedule a rebuild in the middle of a rebuild. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 2a7b72c..d5cbf5f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -5,7 +5,7 @@ * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclat simer. * * Redistributions in binary form must reproduce the above copyrightD * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. @@ -89,6 +89,8 @@ public sealed class BSLinksetCompound : BSLinkset // its internal properties. public override void Refresh(BSPhysObject requestor) { + base.Refresh(requestor); + // Something changed so do the rebuilding thing // ScheduleRebuild(); } @@ -96,13 +98,13 @@ public sealed class BSLinksetCompound : BSLinkset // Schedule a refresh to happen after all the other taint processing. private void ScheduleRebuild(BSPhysObject requestor) { - DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,rebuilding={1}", + DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1}", requestor.LocalID, Rebuilding); // When rebuilding, it is possible to set properties that would normally require a rebuild. // If already rebuilding, don't request another rebuild. if (!Rebuilding) { - PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", LinksetRoot.LocalID, delegate() + PhysicsScene.PostTaintObject("BSLinksetCompound.ScheduleRebuild", LinksetRoot.LocalID, delegate() { if (HasAnyChildren) RecomputeLinksetCompound(); @@ -123,7 +125,6 @@ public sealed class BSLinksetCompound : BSLinkset if (IsRoot(child)) { // The root is going dynamic. Make sure mass is properly set. - m_mass = ComputeLinksetMass(); ScheduleRebuild(LinksetRoot); } else @@ -377,8 +378,8 @@ public sealed class BSLinksetCompound : BSLinkset }); // With all of the linkset packed into the root prim, it has the mass of everyone. - float linksetMass = LinksetMass; - LinksetRoot.UpdatePhysicalMassProperties(linksetMass); + LinksetMass = LinksetMass; + LinksetRoot.UpdatePhysicalMassProperties(LinksetMass, true); } finally { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index d95f223..6b592e7 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -46,6 +46,8 @@ public sealed class BSLinksetConstraints : BSLinkset // refresh will happen once after all the other taints are applied. public override void Refresh(BSPhysObject requestor) { + base.Refresh(requestor); + // Queue to happen after all the other taint processing PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate() { @@ -279,7 +281,7 @@ public sealed class BSLinksetConstraints : BSLinkset private void RecomputeLinksetConstraints() { float linksetMass = LinksetMass; - LinksetRoot.UpdatePhysicalMassProperties(linksetMass); + LinksetRoot.UpdatePhysicalMassProperties(linksetMass, true); // DEBUG: see of inter-linkset collisions are causing problems // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, @@ -292,7 +294,7 @@ public sealed class BSLinksetConstraints : BSLinkset // A child in the linkset physically shows the mass of the whole linkset. // This allows Bullet to apply enough force on the child to move the whole linkset. // (Also do the mass stuff before recomputing the constraint so mass is not zero.) - child.UpdatePhysicalMassProperties(linksetMass); + child.UpdatePhysicalMassProperties(linksetMass, true); BSConstraint constrain; if (!PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, child.PhysBody, out constrain)) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index c76f869..4bed535 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -96,7 +96,8 @@ public abstract class BSPhysObject : PhysicsActor // Return the object mass without calculating it or having side effects public abstract float RawMass { get; } // Set the raw mass but also update physical mass properties (inertia, ...) - public abstract void UpdatePhysicalMassProperties(float mass); + // 'inWorld' true if the object has already been added to the dynamic world. + public abstract void UpdatePhysicalMassProperties(float mass, bool inWorld); // The last value calculated for the prim's inertia public OMV.Vector3 Inertia { get; set; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 26b8df5..159f79f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -115,6 +115,8 @@ public sealed class BSPrim : BSPhysObject PhysBody = new BulletBody(LocalID); PhysShape = new BulletShape(); + Linkset.Refresh(this); + DetailLog("{0},BSPrim.constructor,call", LocalID); // do the actual object creation at taint time PhysicsScene.TaintedObject("BSPrim.create", delegate() @@ -384,13 +386,13 @@ public sealed class BSPrim : BSPhysObject } // Return the effective mass of the object. - // If there are multiple items in the linkset, add them together for the root + // The definition of this call is to return the mass of the prim. + // If the simulator cares about the mass of the linkset, it will sum it itself. public override float Mass { get { - return Linkset.LinksetMass; - // return _mass; + return _mass; } } @@ -400,22 +402,41 @@ public sealed class BSPrim : BSPhysObject } // Set the physical mass to the passed mass. // Note that this does not change _mass! - public override void UpdatePhysicalMassProperties(float physMass) + public override void UpdatePhysicalMassProperties(float physMass, bool inWorld) { - if (IsStatic) + if (PhysBody.HasPhysicalBody) { - Inertia = OMV.Vector3.Zero; - BulletSimAPI.SetMassProps2(PhysBody.ptr, 0f, Inertia); - BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); - } - else - { - Inertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass); - BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, Inertia); - BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); - // center of mass is at the zero of the object - // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(PhysBody.ptr, ForcePosition, ForceOrientation); - DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2}", LocalID, physMass, Inertia); + if (IsStatic) + { + Inertia = OMV.Vector3.Zero; + BulletSimAPI.SetMassProps2(PhysBody.ptr, 0f, Inertia); + BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); + } + else + { + if (inWorld) + { + // Changing interesting properties doesn't change proxy and collision cache + // information. The Bullet solution is to re-add the object to the world + // after parameters are changed. + BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr); + } + + float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); + BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav)); + + Inertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass); + BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, Inertia); + BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); + // center of mass is at the zero of the object + // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(PhysBody.ptr, ForcePosition, ForceOrientation); + DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2}", LocalID, physMass, Inertia); + + if (inWorld) + { + BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr); + } + } } } @@ -714,7 +735,7 @@ public sealed class BSPrim : BSPhysObject Linkset.Refresh(this); DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},body={6},shape={7}", - LocalID, IsStatic, IsSolid, _mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody, PhysShape); + LocalID, IsStatic, IsSolid, Mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody, PhysShape); } // "Making dynamic" means changing to and from static. @@ -737,7 +758,7 @@ public sealed class BSPrim : BSPhysObject BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution); // Mass is zero which disables a bunch of physics stuff in Bullet - UpdatePhysicalMassProperties(0f); + UpdatePhysicalMassProperties(0f, false); // Set collision detection parameters if (BSParam.CcdMotionThreshold > 0f) { @@ -777,7 +798,7 @@ public sealed class BSPrim : BSPhysObject // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.PhysBody.ptr, _position, _orientation); // A dynamic object has mass - UpdatePhysicalMassProperties(RawMass); + UpdatePhysicalMassProperties(RawMass, false); // Set collision detection parameters if (BSParam.CcdMotionThreshold > 0f) @@ -950,13 +971,9 @@ public sealed class BSPrim : BSPhysObject set { _buoyancy = value; // DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); - // Buoyancy is faked by changing the gravity applied to the object - if (PhysBody.HasPhysicalBody) - { - float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); - BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav)); - ActivateIfPhysical(false); - } + // Force the recalculation of the various inertia,etc variables in the object + UpdatePhysicalMassProperties(_mass, true); + ActivateIfPhysical(false); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 9a7e965..0f27d67 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -1,11 +1,17 @@ CURRENT PRIORITIES ================================================= -Smooth avatar movement with motor - Should motor update be all at taint-time? +Smooth avatar movement with motor (DONE) + Should motor update be all at taint-time? (Yes, DONE) + Fix avatar slowly sliding when standing (zero motion when stopped) +llApplyImpulse() + Compare mass/movement in OS and SL. Calibrate actions. +llSetBuoyancy() +Boats float low in the water Enable vehicle border crossings (at least as poorly as ODE) Terrain skirts Avatar created in previous region and not new region when crossing border Vehicle recreated in new sim at small Z value (offset from root value?) (DONE) +Add material densities to the material types. Vehicle movement on terrain smoothness Vehicle script tuning/debugging Avanti speed script @@ -52,6 +58,8 @@ Incorporate inter-relationship of angular corrections. For instance, angularDefl BULLETSIM TODO LIST: ================================================= +In SL, perfect spheres don't seem to have rolling friction. Add special case. +Avatar density is WAY off. Compare and calibrate with what's in SL. Revisit CollisionMargin. Builders notice the 0.04 spacing between prims. Duplicating a physical prim causes old prim to jump away Dup a phys prim and the original become unselected and thus interacts w/ selected prim. @@ -82,6 +90,9 @@ Linkset.Position and Linkset.Orientation requre rewrite to properly return Implement LockAngularMotion -- implements llSetStatus(ROTATE_AXIS_*, T/F) Should the different PID factors have non-equal contributions for different values of Efficiency? +Selecting and deselecting physical objects causes CPU processing time to jump + http://www.youtube.com/watch?v=Hjg57fWg8yI&hd=1 + put thousand physical objects, select and deselect same. CPU time will be large. LINKSETS ====================================================== -- cgit v1.1 From 4759a8acee97fa175c078ec72d9b8cf0db96121b Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 24 Dec 2012 20:16:10 -0800 Subject: BulletSim: Default avatar density changed to 3.5 which is WAY closer to the SL value. Fixed frictin values for physical materials which were just wrong which caused things that should have slipped to not. --- OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs | 16 ++++++++-------- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs index c113a43..92d62ff 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs @@ -119,26 +119,26 @@ public static class BSMaterials Attributes[(int)MaterialAttributes.Material.Light] = new MaterialAttributes("light",dDensity, dFriction, dRestitution); Attributes[(int)MaterialAttributes.Material.Avatar] = - new MaterialAttributes("avatar",60f, 0.2f, 0f); + new MaterialAttributes("avatar",3.5f, 0.2f, 0f); Attributes[(int)MaterialAttributes.Material.Stone + (int)MaterialAttributes.Material.NumberOfTypes] = new MaterialAttributes("stonePhysical",dDensity, 0.8f, 0.4f); Attributes[(int)MaterialAttributes.Material.Metal + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("metalPhysical",dDensity, 0.8f, 0.4f); + new MaterialAttributes("metalPhysical",dDensity, 0.3f, 0.4f); Attributes[(int)MaterialAttributes.Material.Glass + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("glassPhysical",dDensity, 0.8f, 0.7f); + new MaterialAttributes("glassPhysical",dDensity, 0.2f, 0.7f); Attributes[(int)MaterialAttributes.Material.Wood + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("woodPhysical",dDensity, 0.8f, 0.5f); + new MaterialAttributes("woodPhysical",dDensity, 0.6f, 0.5f); Attributes[(int)MaterialAttributes.Material.Flesh + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("fleshPhysical",dDensity, 0.8f, 0.3f); + new MaterialAttributes("fleshPhysical",dDensity, 0.9f, 0.3f); Attributes[(int)MaterialAttributes.Material.Plastic + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("plasticPhysical",dDensity, 0.8f, 0.7f); + new MaterialAttributes("plasticPhysical",dDensity, 0.4f, 0.7f); Attributes[(int)MaterialAttributes.Material.Rubber + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("rubberPhysical",dDensity, 0.8f, 0.9f); + new MaterialAttributes("rubberPhysical",dDensity, 0.9f, 0.9f); Attributes[(int)MaterialAttributes.Material.Light + (int)MaterialAttributes.Material.NumberOfTypes] = new MaterialAttributes("lightPhysical",dDensity, dFriction, dRestitution); Attributes[(int)MaterialAttributes.Material.Avatar + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("avatarPhysical",60f, 0.2f, 0f); + new MaterialAttributes("avatarPhysical",3.5f, 0.2f, 0f); } // Under the [BulletSim] section, one can change the individual material diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 5558ad5..7454718 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -351,7 +351,7 @@ public static class BSParam (s) => { return AvatarStandingFriction; }, (s,p,l,v) => { AvatarStandingFriction = v; } ), new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.", - 60f, + 3.5f, (s,cf,p,v) => { AvatarDensity = cf.GetFloat(p, v); }, (s) => { return AvatarDensity; }, (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarDensity=x;}, p, l, v); } ), -- cgit v1.1 From bbc5a5089f79a4c5543f4a3f1cd4ffaf1de8c07e Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 24 Dec 2012 20:18:06 -0800 Subject: BulletSim: Rename some of the interface structures (BulletWorld, ...) to get ready for... Start creation of BulletAPITemplate. This defines the abstract interface functions. Following commits will move over to the new interface. This will enable switching between the managed and unmanaged version of Bullet. --- .../Region/Physics/BulletSPlugin/BSConstraint.cs | 2 +- .../Physics/BulletSPlugin/BSConstraint6Dof.cs | 4 +- .../BulletSPlugin/BSConstraintCollection.cs | 4 +- .../Physics/BulletSPlugin/BSConstraintHinge.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 4 +- .../Physics/BulletSPlugin/BSShapeCollection.cs | 6 +- .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 392 +++++++++++++++++++++ .../Region/Physics/BulletSPlugin/BulletSimData.cs | 4 +- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 7 + 9 files changed, 412 insertions(+), 13 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs index e77fb50..59584b2 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs @@ -36,7 +36,7 @@ public abstract class BSConstraint : IDisposable { private static string LogHeader = "[BULLETSIM CONSTRAINT]"; - protected BulletSim m_world; + protected BulletWorld m_world; protected BulletBody m_body1; protected BulletBody m_body2; protected BulletConstraint m_constraint; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs index b073555..b946870 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs @@ -39,7 +39,7 @@ public sealed class BSConstraint6Dof : BSConstraint public override ConstraintType Type { get { return ConstraintType.D6_CONSTRAINT_TYPE; } } // Create a btGeneric6DofConstraint - public BSConstraint6Dof(BulletSim world, BulletBody obj1, BulletBody obj2, + public BSConstraint6Dof(BulletWorld world, BulletBody obj1, BulletBody obj2, Vector3 frame1, Quaternion frame1rot, Vector3 frame2, Quaternion frame2rot, bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) @@ -58,7 +58,7 @@ public sealed class BSConstraint6Dof : BSConstraint obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X")); } - public BSConstraint6Dof(BulletSim world, BulletBody obj1, BulletBody obj2, + public BSConstraint6Dof(BulletWorld world, BulletBody obj1, BulletBody obj2, Vector3 joinPoint, bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs index a9fd826..2aeff25 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs @@ -41,9 +41,9 @@ public sealed class BSConstraintCollection : IDisposable delegate bool ConstraintAction(BSConstraint constrain); private List m_constraints; - private BulletSim m_world; + private BulletWorld m_world; - public BSConstraintCollection(BulletSim world) + public BSConstraintCollection(BulletWorld world) { m_world = world; m_constraints = new List(); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintHinge.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintHinge.cs index ed3ffa7..a5378b9 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintHinge.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintHinge.cs @@ -36,7 +36,7 @@ public sealed class BSConstraintHinge : BSConstraint { public override ConstraintType Type { get { return ConstraintType.HINGE_CONSTRAINT_TYPE; } } - public BSConstraintHinge(BulletSim world, BulletBody obj1, BulletBody obj2, + public BSConstraintHinge(BulletWorld world, BulletBody obj1, BulletBody obj2, Vector3 pivotInA, Vector3 pivotInB, Vector3 axisInA, Vector3 axisInB, bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index e8e0d50..0022e45 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -74,7 +74,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public IMesher mesher; public uint WorldID { get; private set; } - public BulletSim World { get; private set; } + public BulletWorld World { get; private set; } // All the constraints that have been allocated in this instance. public BSConstraintCollection Constraints { get; private set; } @@ -242,7 +242,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader); - World = new BulletSim(0, this, BulletSimAPI.Initialize2(worldExtent, m_paramsHandle.AddrOfPinnedObject(), + World = new BulletWorld(0, this, BulletSimAPI.Initialize2(worldExtent, m_paramsHandle.AddrOfPinnedObject(), m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(), m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject(), m_DebugLogCallbackHandle)); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 939d5e9..65ebcaa 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -98,7 +98,7 @@ public sealed class BSShapeCollection : IDisposable // higher level dependencies on the shape or body. Mostly used for LinkSets to // remove the physical constraints before the body is destroyed. // Called at taint-time!! - public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim, + public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim, ShapeDestructionCallback shapeCallback, BodyDestructionCallback bodyCallback) { PhysicsScene.AssertInTaintTime("BSShapeCollection.GetBodyAndShape"); @@ -126,7 +126,7 @@ public sealed class BSShapeCollection : IDisposable return ret; } - public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim) + public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim) { return GetBodyAndShape(forceRebuild, sim, prim, null, null); } @@ -918,7 +918,7 @@ public sealed class BSShapeCollection : IDisposable // Updates prim.BSBody with the information about the new body if one is created. // Returns 'true' if an object was actually created. // Called at taint-time. - private bool CreateBody(bool forceRebuild, BSPhysObject prim, BulletSim sim, BulletShape shape, + private bool CreateBody(bool forceRebuild, BSPhysObject prim, BulletWorld sim, BulletShape shape, BodyDestructionCallback bodyCallback) { bool ret = false; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 7857eaa..afe5bca 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -288,6 +288,398 @@ public enum ConstraintParamAxis : int AXIS_ALL }; +public abstract class BulletSimAPITemplate +{ +// Initialization and simulation +public abstract BulletWorld Initialize2(Vector3 maxPosition, IntPtr parms, + int maxCollisions, IntPtr collisionArray, + int maxUpdates, IntPtr updateArray + ); + +public abstract bool UpdateParameter2(BulletWorld world, uint localID, String parm, float value); + +public abstract void SetHeightMap2(BulletWorld world, float[] heightmap); + +public abstract void Shutdown2(BulletWorld sim); + +public abstract int PhysicsStep2(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, + out int updatedEntityCount, + out IntPtr updatedEntitiesPtr, + out int collidersCount, + out IntPtr collidersPtr); + +public abstract bool PushUpdate2(BulletBody obj); + +// ===================================================================================== +// Mesh, hull, shape and body creation helper routines +public abstract BulletShape CreateMeshShape2(BulletWorld world, + int indicesCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices, + int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices ); + +public abstract BulletShape CreateHullShape2(BulletWorld world, + int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls); + +public abstract BulletShape BuildHullShapeFromMesh2(BulletWorld world, BulletShape meshShape); + +public abstract BulletShape BuildNativeShape2(BulletWorld world, ShapeData shapeData); + +public abstract bool IsNativeShape2(BulletShape shape); + +public abstract void SetShapeCollisionMargin(BulletShape shape, float margin); + +public abstract BulletShape BuildCapsuleShape2(BulletWorld world, float radius, float height, Vector3 scale); + +public abstract BulletShape CreateCompoundShape2(BulletWorld sim, bool enableDynamicAabbTree); + +public abstract int GetNumberOfCompoundChildren2(BulletShape cShape); + +public abstract void AddChildShapeToCompoundShape2(BulletShape cShape, BulletShape addShape, Vector3 pos, Quaternion rot); + +public abstract BulletShape GetChildShapeFromCompoundShapeIndex2(BulletShape cShape, int indx); + +public abstract BulletShape RemoveChildShapeFromCompoundShapeIndex2(BulletShape cShape, int indx); + +public abstract void RemoveChildShapeFromCompoundShape2(BulletShape cShape, BulletShape removeShape); + +public abstract void RecalculateCompoundShapeLocalAabb2(BulletShape cShape); + +public abstract BulletShape DuplicateCollisionShape2(BulletWorld sim, BulletShape srcShape, uint id); + +public abstract BulletBody CreateBodyFromShapeAndInfo2(BulletWorld sim, BulletShape shape, uint id, IntPtr constructionInfo); + +public abstract bool DeleteCollisionShape2(BulletWorld world, BulletShape shape); + +public abstract int GetBodyType2(BulletBody obj); + +public abstract BulletBody CreateBodyFromShape2(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot); + +public abstract BulletBody CreateBodyWithDefaultMotionState2(BulletShape shape, uint id, Vector3 pos, Quaternion rot); + +public abstract BulletBody CreateGhostFromShape2(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot); + +public abstract IntPtr AllocateBodyInfo2(BulletBody obj); + +public abstract void ReleaseBodyInfo2(IntPtr obj); + +public abstract void DestroyObject2(BulletWorld sim, BulletBody obj); + +// ===================================================================================== +// Terrain creation and helper routines +public abstract IntPtr CreateHeightMapInfo2(BulletWorld sim, uint id, Vector3 minCoords, Vector3 maxCoords, + [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin); + +public abstract IntPtr FillHeightMapInfo2(BulletWorld sim, IntPtr mapInfo, uint id, Vector3 minCoords, Vector3 maxCoords, + [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin); + +public abstract bool ReleaseHeightMapInfo2(IntPtr heightMapInfo); + +public abstract BulletBody CreateGroundPlaneShape2(uint id, float height, float collisionMargin); + +public abstract BulletBody CreateTerrainShape2(IntPtr mapInfo); + +// ===================================================================================== +// Constraint creation and helper routines +public abstract BulletConstraint Create6DofConstraint2(BulletWorld world, BulletBody obj1, BulletBody obj2, + Vector3 frame1loc, Quaternion frame1rot, + Vector3 frame2loc, Quaternion frame2rot, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); + +public abstract BulletConstraint Create6DofConstraintToPoint2(BulletWorld world, BulletBody obj1, BulletBody obj2, + Vector3 joinPoint, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); + +public abstract BulletConstraint CreateHingeConstraint2(BulletWorld world, BulletBody obj1, BulletBody obj2, + Vector3 pivotinA, Vector3 pivotinB, + Vector3 axisInA, Vector3 axisInB, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); + +public abstract void SetConstraintEnable2(BulletConstraint constrain, float numericTrueFalse); + +public abstract void SetConstraintNumSolverIterations2(BulletConstraint constrain, float iterations); + +public abstract bool SetFrames2(BulletConstraint constrain, + Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot); + +public abstract bool SetLinearLimits2(BulletConstraint constrain, Vector3 low, Vector3 hi); + +public abstract bool SetAngularLimits2(BulletConstraint constrain, Vector3 low, Vector3 hi); + +public abstract bool UseFrameOffset2(BulletConstraint constrain, float enable); + +public abstract bool TranslationalLimitMotor2(BulletConstraint constrain, float enable, float targetVel, float maxMotorForce); + +public abstract bool SetBreakingImpulseThreshold2(BulletConstraint constrain, float threshold); + +public abstract bool CalculateTransforms2(BulletConstraint constrain); + +public abstract bool SetConstraintParam2(BulletConstraint constrain, ConstraintParams paramIndex, float value, ConstraintParamAxis axis); + +public abstract bool DestroyConstraint2(BulletWorld world, BulletConstraint constrain); + +// ===================================================================================== +// btCollisionWorld entries +public abstract void UpdateSingleAabb2(BulletWorld world, BulletBody obj); + +public abstract void UpdateAabbs2(BulletWorld world); + +public abstract bool GetForceUpdateAllAabbs2(BulletWorld world); + +public abstract void SetForceUpdateAllAabbs2(BulletWorld world, bool force); + +// ===================================================================================== +// btDynamicsWorld entries +public abstract bool AddObjectToWorld2(BulletWorld world, BulletBody obj); + +public abstract bool RemoveObjectFromWorld2(BulletWorld world, BulletBody obj); + +public abstract bool AddConstraintToWorld2(BulletWorld world, BulletConstraint constrain, bool disableCollisionsBetweenLinkedObjects); + +public abstract bool RemoveConstraintFromWorld2(BulletWorld world, BulletConstraint constrain); +// ===================================================================================== +// btCollisionObject entries +public abstract Vector3 GetAnisotripicFriction2(BulletConstraint constrain); + +public abstract Vector3 SetAnisotripicFriction2(BulletConstraint constrain, Vector3 frict); + +public abstract bool HasAnisotripicFriction2(BulletConstraint constrain); + +public abstract void SetContactProcessingThreshold2(BulletBody obj, float val); + +public abstract float GetContactProcessingThreshold2(BulletBody obj); + +public abstract bool IsStaticObject2(BulletBody obj); + +public abstract bool IsKinematicObject2(BulletBody obj); + +public abstract bool IsStaticOrKinematicObject2(BulletBody obj); + +public abstract bool HasContactResponse2(BulletBody obj); + +public abstract void SetCollisionShape2(BulletWorld sim, BulletBody obj, BulletBody shape); + +public abstract BulletShape GetCollisionShape2(BulletBody obj); + +public abstract int GetActivationState2(BulletBody obj); + +public abstract void SetActivationState2(BulletBody obj, int state); + +public abstract void SetDeactivationTime2(BulletBody obj, float dtime); + +public abstract float GetDeactivationTime2(BulletBody obj); + +public abstract void ForceActivationState2(BulletBody obj, ActivationState state); + +public abstract void Activate2(BulletBody obj, bool forceActivation); + +public abstract bool IsActive2(BulletBody obj); + +public abstract void SetRestitution2(BulletBody obj, float val); + +public abstract float GetRestitution2(BulletBody obj); + +public abstract void SetFriction2(BulletBody obj, float val); + +public abstract float GetFriction2(BulletBody obj); + + /* Haven't defined the type 'Transform' +public abstract Transform GetWorldTransform2(BulletBody obj); + +public abstract void setWorldTransform2(BulletBody obj, Transform trans); + */ + +public abstract Vector3 GetPosition2(BulletBody obj); + +public abstract Quaternion GetOrientation2(BulletBody obj); + +public abstract void SetTranslation2(BulletBody obj, Vector3 position, Quaternion rotation); + +public abstract IntPtr GetBroadphaseHandle2(BulletBody obj); + +public abstract void SetBroadphaseHandle2(BulletBody obj, IntPtr handle); + + /* +public abstract Transform GetInterpolationWorldTransform2(IntPtr obj); + +public abstract void SetInterpolationWorldTransform2(IntPtr obj, Transform trans); + */ + +public abstract void SetInterpolationLinearVelocity2(BulletBody obj, Vector3 vel); + +public abstract void SetInterpolationAngularVelocity2(BulletBody obj, Vector3 vel); + +public abstract void SetInterpolationVelocity2(BulletBody obj, Vector3 linearVel, Vector3 angularVel); + +public abstract float GetHitFraction2(BulletBody obj); + +public abstract void SetHitFraction2(BulletBody obj, float val); + +public abstract CollisionFlags GetCollisionFlags2(BulletBody obj); + +public abstract CollisionFlags SetCollisionFlags2(BulletBody obj, CollisionFlags flags); + +public abstract CollisionFlags AddToCollisionFlags2(BulletBody obj, CollisionFlags flags); + +public abstract CollisionFlags RemoveFromCollisionFlags2(BulletBody obj, CollisionFlags flags); + +public abstract float GetCcdMotionThreshold2(BulletBody obj); + +public abstract void SetCcdMotionThreshold2(BulletBody obj, float val); + +public abstract float GetCcdSweptSphereRadius2(BulletBody obj); + +public abstract void SetCcdSweptSphereRadius2(BulletBody obj, float val); + +public abstract IntPtr GetUserPointer2(BulletBody obj); + +public abstract void SetUserPointer2(BulletBody obj, IntPtr val); + +// ===================================================================================== +// btRigidBody entries +public abstract void ApplyGravity2(BulletBody obj); + +public abstract void SetGravity2(BulletBody obj, Vector3 val); + +public abstract Vector3 GetGravity2(BulletBody obj); + +public abstract void SetDamping2(BulletBody obj, float lin_damping, float ang_damping); + +public abstract void SetLinearDamping2(BulletBody obj, float lin_damping); + +public abstract void SetAngularDamping2(BulletBody obj, float ang_damping); + +public abstract float GetLinearDamping2(BulletBody obj); + +public abstract float GetAngularDamping2(BulletBody obj); + +public abstract float GetLinearSleepingThreshold2(BulletBody obj); + + +public abstract void ApplyDamping2(BulletBody obj, float timeStep); + +public abstract void SetMassProps2(BulletBody obj, float mass, Vector3 inertia); + +public abstract Vector3 GetLinearFactor2(BulletBody obj); + +public abstract void SetLinearFactor2(BulletBody obj, Vector3 factor); + + /* +public abstract void SetCenterOfMassTransform2(BulletBody obj, Transform trans); + */ + +public abstract void SetCenterOfMassByPosRot2(BulletBody obj, Vector3 pos, Quaternion rot); + +// Add a force to the object as if its mass is one. +public abstract void ApplyCentralForce2(BulletBody obj, Vector3 force); + +// Set the force being applied to the object as if its mass is one. +public abstract void SetObjectForce2(BulletBody obj, Vector3 force); + +public abstract Vector3 GetTotalForce2(BulletBody obj); + +public abstract Vector3 GetTotalTorque2(BulletBody obj); + +public abstract Vector3 GetInvInertiaDiagLocal2(BulletBody obj); + +public abstract void SetInvInertiaDiagLocal2(BulletBody obj, Vector3 inert); + +public abstract void SetSleepingThresholds2(BulletBody obj, float lin_threshold, float ang_threshold); + +public abstract void ApplyTorque2(BulletBody obj, Vector3 torque); + +// Apply force at the given point. Will add torque to the object. +public abstract void ApplyForce2(BulletBody obj, Vector3 force, Vector3 pos); + +// Apply impulse to the object. Same as "ApplycentralForce" but force scaled by object's mass. +public abstract void ApplyCentralImpulse2(BulletBody obj, Vector3 imp); + +// Apply impulse to the object's torque. Force is scaled by object's mass. +public abstract void ApplyTorqueImpulse2(BulletBody obj, Vector3 imp); + +// Apply impulse at the point given. For is scaled by object's mass and effects both linear and angular forces. +public abstract void ApplyImpulse2(BulletBody obj, Vector3 imp, Vector3 pos); + +public abstract void ClearForces2(BulletBody obj); + +public abstract void ClearAllForces2(BulletBody obj); + +public abstract void UpdateInertiaTensor2(BulletBody obj); + + + /* +public abstract Transform GetCenterOfMassTransform2(BulletBody obj); + */ + +public abstract Vector3 GetLinearVelocity2(BulletBody obj); + +public abstract Vector3 GetAngularVelocity2(BulletBody obj); + +public abstract void SetLinearVelocity2(BulletBody obj, Vector3 val); + +public abstract void SetAngularVelocity2(BulletBody obj, Vector3 angularVelocity); + +public abstract Vector3 GetVelocityInLocalPoint2(BulletBody obj, Vector3 pos); + +public abstract void Translate2(BulletBody obj, Vector3 trans); + +public abstract void UpdateDeactivation2(BulletBody obj, float timeStep); + +public abstract bool WantsSleeping2(BulletBody obj); + +public abstract void SetAngularFactor2(BulletBody obj, float factor); + +public abstract void SetAngularFactorV2(BulletBody obj, Vector3 factor); + +public abstract Vector3 GetAngularFactor2(BulletBody obj); + +public abstract bool IsInWorld2(BulletBody obj); + +public abstract void AddConstraintRef2(BulletBody obj, BulletConstraint constrain); + +public abstract void RemoveConstraintRef2(BulletBody obj, BulletConstraint constrain); + +public abstract BulletConstraint GetConstraintRef2(BulletBody obj, int index); + +public abstract int GetNumConstraintRefs2(BulletBody obj); + +public abstract bool SetCollisionGroupMask2(BulletBody body, uint filter, uint mask); + +// ===================================================================================== +// btCollisionShape entries + +public abstract float GetAngularMotionDisc2(BulletShape shape); + +public abstract float GetContactBreakingThreshold2(BulletShape shape, float defaultFactor); + +public abstract bool IsPolyhedral2(BulletShape shape); + +public abstract bool IsConvex2d2(BulletShape shape); + +public abstract bool IsConvex2(BulletShape shape); + +public abstract bool IsNonMoving2(BulletShape shape); + +public abstract bool IsConcave2(BulletShape shape); + +public abstract bool IsCompound2(BulletShape shape); + +public abstract bool IsSoftBody2(BulletShape shape); + +public abstract bool IsInfinite2(BulletShape shape); + +public abstract void SetLocalScaling2(BulletShape shape, Vector3 scale); + +public abstract Vector3 GetLocalScaling2(BulletShape shape); + +public abstract Vector3 CalculateLocalInertia2(BulletShape shape, float mass); + +public abstract int GetShapeType2(BulletShape shape); + +public abstract void SetMargin2(BulletShape shape, float val); + +public abstract float GetMargin2(BulletShape shape); + +}; + // =============================================================================== static class BulletSimAPI { // =============================================================================== diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs index 662177f..36d38d4 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs @@ -35,9 +35,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin // These hold pointers to allocated objects in the unmanaged space. // The physics engine controller class created at initialization -public struct BulletSim +public struct BulletWorld { - public BulletSim(uint worldId, BSScene bss, IntPtr xx) + public BulletWorld(uint worldId, BSScene bss, IntPtr xx) { ptr = xx; worldID = worldId; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 0f27d67..35cb8f3 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -146,6 +146,13 @@ Is there are more efficient method of implementing pre and post step actions? See http://www.codeproject.com/Articles/29922/Weak-Events-in-C Physics Arena central pyramid: why is one side permiable? +Enforce physical parameter min/max: + Gravity: [-1, 28] + Friction: [0, 255] + Density: [1, 22587] + Restitution [0, 1] + http://wiki.secondlife.com/wiki/Physics_Material_Settings_test +Avatar attachments have no mass? http://forums-archive.secondlife.com/54/f0/31796/1.html INTERNAL IMPROVEMENT/CLEANUP ================================================= -- cgit v1.1 From e98e223927226602d7a050bbb92ebb2904e81562 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 27 Dec 2012 06:56:36 -0800 Subject: BulletSim: complete applyImpulse function in BSCharacter (like I said I did last time). --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 25 +++++++++++++++------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 9f0d5af..cbc1772 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -683,22 +683,31 @@ public sealed class BSCharacter : BSPhysObject public override void AddForce(OMV.Vector3 force, bool pushforce) { if (force.IsFinite()) { - _force.X += force.X; - _force.Y += force.Y; - _force.Z += force.Z; - // m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force); + float magnitude = force.Length(); + if (magnitude > BSParam.MaxAddForceMagnitude) + { + // Force has a limit + force = force / magnitude * BSParam.MaxAddForceMagnitude; + } + + OMV.Vector3 addForce = force / PhysicsScene.LastTimeStep; + DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce); + PhysicsScene.TaintedObject("BSCharacter.AddForce", delegate() { - DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force); + // Bullet adds this central force to the total force for this tick + DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce); if (PhysBody.HasPhysicalBody) - BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force); + { + BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, addForce); + } }); } else { - m_log.ErrorFormat("{0}: Got a NaN force applied to a Character", LogHeader); + m_log.WarnFormat("{0}: Got a NaN force applied to a character. LocalID={1}", LogHeader, LocalID); + return; } - //m_lastUpdateSent = false; } public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { -- cgit v1.1 From f3baed5827853c5041f042ff36cf394b1e45538f Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 27 Dec 2012 06:58:07 -0800 Subject: BulletSim: add physical parameter min/max constants in BSParam. I just don't like raw numbers scattered around the code. --- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 12 ++++++++++++ OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 4 ++-- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 9 --------- OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | 1 + 4 files changed, 15 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 7454718..8366cef 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -89,6 +89,18 @@ public static class BSParam public static float PID_D { get; private set; } // derivative public static float PID_P { get; private set; } // proportional + // Various constants that come from that other virtual world that shall not be named + public const float MinGravityZ = -1f; + public const float MaxGravityZ = 28f; + public const float MinFriction = 0f; + public const float MaxFriction = 255f; + public const float MinDensity = 0f; + public const float MaxDensity = 22587f; + public const float MinRestitution = 0f; + public const float MaxRestitution = 1f; + public const float MaxAddForceMagnitude = 20000f; + + // =========================================================================== public delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val); public delegate float ParamGet(BSScene scene); public delegate void ParamSet(BSScene scene, string paramName, uint localID, float val); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 9013414..c7a81e0 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -1025,10 +1025,10 @@ public sealed class BSPrim : BSPhysObject if (force.IsFinite()) { float magnitude = force.Length(); - if (magnitude > 20000f) + if (magnitude > BSParam.MaxAddForceMagnitude) { // Force has a limit - force = force / magnitude * 20000f; + force = force / magnitude * BSParam.MaxAddForceMagnitude; } OMV.Vector3 addForce = force; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index b67c0ed..a5fbf10 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -38,15 +38,6 @@ using Nini.Config; using log4net; using OpenMetaverse; -// TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim) -// Based on material, set density and friction -// More efficient memory usage when passing hull information from BSPrim to BulletSim -// Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect -// Implement LockAngularMotion -// Add PID movement operations. What does ScenePresence.MoveToTarget do? -// Check terrain size. 128 or 127? -// Raycast -// namespace OpenSim.Region.Physics.BulletSPlugin { public sealed class BSScene : PhysicsScene, IPhysicsParameters diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 78cc26c..bc6dd7e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -96,6 +96,7 @@ Selecting and deselecting physical objects causes CPU processing time to jump put thousand physical objects, select and deselect same. CPU time will be large. Re-implement buoyancy as a separate force on the object rather than diddling gravity. Register a pre-step event to add the force. +More efficient memory usage when passing hull information from BSPrim to BulletSim LINKSETS ====================================================== -- cgit v1.1 From 723099067976dfa71d18182378000df144d618af Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 27 Dec 2012 10:09:31 -0800 Subject: BulletSim: fix odd code that wasn't really recomputing the mass of a rebuilt linkset. I was burnt by making get/set methods with side effects. I should know better. --- OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index d5cbf5f..4e02904 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -98,11 +98,12 @@ public sealed class BSLinksetCompound : BSLinkset // Schedule a refresh to happen after all the other taint processing. private void ScheduleRebuild(BSPhysObject requestor) { - DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1}", - requestor.LocalID, Rebuilding); + DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1},hasChildren={2}", + requestor.LocalID, Rebuilding, HasAnyChildren); // When rebuilding, it is possible to set properties that would normally require a rebuild. // If already rebuilding, don't request another rebuild. - if (!Rebuilding) + // If a linkset with just a root prim (simple non-linked prim) don't bother rebuilding. + if (!Rebuilding && HasAnyChildren) { PhysicsScene.PostTaintObject("BSLinksetCompound.ScheduleRebuild", LinksetRoot.LocalID, delegate() { @@ -112,8 +113,7 @@ public sealed class BSLinksetCompound : BSLinkset } } - // The object is going dynamic (physical). Do any setup necessary - // for a dynamic linkset. + // The object is going dynamic (physical). Do any setup necessary for a dynamic linkset. // Only the state of the passed object can be modified. The rest of the linkset // has not yet been fully constructed. // Return 'true' if any properties updated on the passed object. @@ -124,7 +124,7 @@ public sealed class BSLinksetCompound : BSLinkset DetailLog("{0},BSLinksetCompound.MakeDynamic,call,IsRoot={1}", child.LocalID, IsRoot(child)); if (IsRoot(child)) { - // The root is going dynamic. Make sure mass is properly set. + // The root is going dynamic. Rebuild the linkset so parts and mass get computed properly. ScheduleRebuild(LinksetRoot); } else @@ -378,7 +378,7 @@ public sealed class BSLinksetCompound : BSLinkset }); // With all of the linkset packed into the root prim, it has the mass of everyone. - LinksetMass = LinksetMass; + LinksetMass = ComputeLinksetMass(); LinksetRoot.UpdatePhysicalMassProperties(LinksetMass, true); } finally -- cgit v1.1 From e57c0e6731bff376186ecba2530e76b697ab5887 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 27 Dec 2012 13:13:35 -0800 Subject: BulletSim: fix buoyancy so it's properly set by a script when an object is selected. Update TODO list. --- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 4 +-- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 29 +++++++++++++++++++--- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 24 ++++++++++++------ 4 files changed, 44 insertions(+), 15 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 4e02904..19ce62b 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -5,7 +5,7 @@ * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclat simer. + * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyrightD * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index 9e1a9ba..817a5f7 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -241,8 +241,8 @@ public class BSVMotor : BSMotor public override string ToString() { - return String.Format("<{0},curr={1},targ={2},decayTS={3},frictTS={4}>", - UseName, CurrentValue, TargetValue, TargetValueDecayTimeScale, FrictionTimescale); + return String.Format("<{0},curr={1},targ={2},lastErr={3},decayTS={4},frictTS={5}>", + UseName, CurrentValue, TargetValue, LastError, TargetValueDecayTimeScale, FrictionTimescale); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index c7a81e0..f804a0f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -94,7 +94,7 @@ public sealed class BSPrim : BSPhysObject _size = size; Scale = size; // prims are the size the user wants them to be (different for BSCharactes). _orientation = rotation; - _buoyancy = 1f; + _buoyancy = 0f; _velocity = OMV.Vector3.Zero; _rotationalVelocity = OMV.Vector3.Zero; BaseShape = pbs; @@ -408,12 +408,15 @@ public sealed class BSPrim : BSPhysObject { if (IsStatic) { + BulletSimAPI.SetGravity2(PhysBody.ptr, PhysicsScene.DefaultGravity); Inertia = OMV.Vector3.Zero; BulletSimAPI.SetMassProps2(PhysBody.ptr, 0f, Inertia); BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); } else { + OMV.Vector3 grav = ComputeGravity(); + if (inWorld) { // Changing interesting properties doesn't change proxy and collision cache @@ -422,13 +425,16 @@ public sealed class BSPrim : BSPhysObject BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr); } + // The computation of mass props requires gravity to be set on the object. + BulletSimAPI.SetGravity2(PhysBody.ptr, grav); + Inertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass); BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, Inertia); BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); // center of mass is at the zero of the object // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(PhysBody.ptr, ForcePosition, ForceOrientation); - DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2},inWorld={3}", LocalID, physMass, Inertia, inWorld); + DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2},grav={3},inWorld={4}", LocalID, physMass, Inertia, grav, inWorld); if (inWorld) { @@ -437,13 +443,23 @@ public sealed class BSPrim : BSPhysObject // 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 - OMV.Vector3 grav = PhysicsScene.DefaultGravity * (1f - Buoyancy); BulletSimAPI.SetGravity2(PhysBody.ptr, grav); } } } + // Return what gravity should be set to this very moment + private OMV.Vector3 ComputeGravity() + { + OMV.Vector3 ret = PhysicsScene.DefaultGravity; + + if (!IsStatic) + ret *= (1f - Buoyancy); + + return ret; + } + // Is this used? public override OMV.Vector3 CenterOfMass { @@ -669,7 +685,7 @@ public sealed class BSPrim : BSPhysObject _isPhysical = value; PhysicsScene.TaintedObject("BSPrim.setIsPhysical", delegate() { - // DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical); + DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical); SetObjectDynamic(true); // whether phys-to-static or static-to-phys, the object is not moving. ZeroMotion(true); @@ -726,6 +742,10 @@ public sealed class BSPrim : BSPhysObject BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr); + // TODO: Fix this. Total kludge because adding object to world resets its gravity to default. + // Replace this when the new AddObjectToWorld function is complete. + BulletSimAPI.SetGravity2(PhysBody.ptr, ComputeGravity()); + // Rebuild its shape BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); @@ -976,6 +996,7 @@ public sealed class BSPrim : BSPhysObject _buoyancy = value; // DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); // Force the recalculation of the various inertia,etc variables in the object + DetailLog("{0},BSPrim.ForceBuoyancy,buoy={1},mass={2}", LocalID, _buoyancy, _mass); UpdatePhysicalMassProperties(_mass, true); ActivateIfPhysical(false); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index bc6dd7e..a66508a 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -1,22 +1,21 @@ CURRENT PRIORITIES ================================================= -Smooth avatar movement with motor (DONE) - Should motor update be all at taint-time? (Yes, DONE) - Fix avatar slowly sliding when standing (zero motion when stopped) -llApplyImpulse() - Compare mass/movement in OS and SL. Calibrate actions. -llSetBuoyancy() -Boats float low in the water +Redo BulletSimAPI to allow native C# implementation of Bullet option. +Avatar movement + flying into a wall doesn't stop avatar who keeps appearing to move through the obsticle + walking up stairs is not calibrated correctly (stairs out of Kepler cabin) + avatar capsule rotation completed Enable vehicle border crossings (at least as poorly as ODE) Terrain skirts Avatar created in previous region and not new region when crossing border Vehicle recreated in new sim at small Z value (offset from root value?) (DONE) -Add material densities to the material types. Vehicle movement on terrain smoothness Vehicle script tuning/debugging Avanti speed script Weapon shooter script limitMotorUp calibration (more down?) +Boats float low in the water +Add material densities to the material types. CRASHES ================================================= @@ -243,3 +242,12 @@ Should vehicle angular/linear movement friction happen after all the components What is expected by some vehicles (turning up friction to moderate speed)) Tune terrain/object friction to be closer to SL. (Resolution: added material type with friction and resolution) +Smooth avatar movement with motor (DONE) + Should motor update be all at taint-time? (Yes, DONE) + Fix avatar slowly sliding when standing (zero motion when stopped) (DONE) + (Resolution: added BSVMotor for avatar starting and stopping) +llApplyImpulse() + Compare mass/movement in OS and SL. Calibrate actions. (DONE) + (Resolution: tested on SL and OS. AddForce scales the force for timestep) +llSetBuoyancy() (DONE) + (Resolution: Bullet resets object gravity when added to world. Moved set gravity) -- cgit v1.1 From 5afab9bcfe9e163219cf6b4317a8914860e3f969 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 27 Dec 2012 16:03:14 -0800 Subject: Add check to always push terse updates for presences that have new velocities of zero. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 58721b0..a60c551 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2335,9 +2335,14 @@ namespace OpenSim.Region.Framework.Scenes // storing a requested force instead of an actual traveling velocity // Throw away duplicate or insignificant updates - if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || - !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || - !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)) + if ( + // If the velocity has become zero, send it no matter what. + (Velocity != m_lastVelocity && Velocity == Vector3.Zero) + // otherwise, if things have changed reasonably, send the update + || (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) + || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) + || !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))) + { SendTerseUpdateToAllClients(); -- cgit v1.1 From 7a5f598399c7373bd146061b478e6d04cb204879 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 27 Dec 2012 16:05:11 -0800 Subject: BulletSim: move logic for IsColliding, CollidingGround and CollidingObj from individual sub-classes and up to parent BSPhysObject class. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 36 ++++++++------------- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 37 +++++++++++++++++++++- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 18 ++--------- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 3 +- 4 files changed, 55 insertions(+), 39 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index cbc1772..3f7b5e1 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -584,18 +584,6 @@ public sealed class BSCharacter : BSPhysObject get { return _throttleUpdates; } set { _throttleUpdates = value; } } - public override bool IsColliding { - get { return (CollidingStep == PhysicsScene.SimulationStep); } - set { _isColliding = value; } - } - public override bool CollidingGround { - get { return (CollidingGroundStep == PhysicsScene.SimulationStep); } - set { CollidingGround = value; } - } - public override bool CollidingObj { - get { return _collidingObj; } - set { _collidingObj = value; } - } public override bool FloatOnWater { set { _floatOnWater = value; @@ -769,22 +757,26 @@ public sealed class BSCharacter : BSPhysObject OMV.Vector3 stepVelocity = _velocityMotor.Step(PhysicsScene.LastTimeStep); - // If falling, we keep the world's downward vector no matter what the other axis specify. - if (!Flying && !IsColliding) - { - stepVelocity.Z = entprop.Velocity.Z; - DetailLog("{0},BSCharacter.UpdateProperties,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity); - } - - // If the user has said stop and we've stopped applying velocity correction, - // the motor can be turned off. Set the velocity to zero so the zero motion is sent to the viewer. - if (_velocityMotor.TargetValue.ApproxEquals(OMV.Vector3.Zero, 0.01f) && _velocityMotor.ErrorIsZero) + // Check for cases to turn off the motor. + if ( + // If the walking motor is all done, turn it off + (_velocityMotor.TargetValue.ApproxEquals(OMV.Vector3.Zero, 0.01f) && _velocityMotor.ErrorIsZero) ) { ZeroMotion(true); stepVelocity = OMV.Vector3.Zero; _velocityMotor.Enabled = false; DetailLog("{0},BSCharacter.UpdateProperties,taint,disableVelocityMotor,m={1}", LocalID, _velocityMotor); } + else + { + // If the motor is not being turned off... + // If falling, we keep the world's downward vector no matter what the other axis specify. + if (!Flying && !IsColliding) + { + stepVelocity.Z = entprop.Velocity.Z; + DetailLog("{0},BSCharacter.UpdateProperties,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity); + } + } _velocity = stepVelocity; entprop.Velocity = _velocity; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 4bed535..73b5764 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -182,9 +182,40 @@ public abstract class BSPhysObject : PhysicsActor protected long CollidingStep { get; set; } // The simulation step that last had a collision with the ground protected long CollidingGroundStep { get; set; } + // The simulation step that last collided with an object + protected long CollidingObjectStep { get; set; } // The collision flags we think are set in Bullet protected CollisionFlags CurrentCollisionFlags { get; set; } + public override bool IsColliding { + get { return (CollidingStep == PhysicsScene.SimulationStep); } + set { + if (value) + CollidingStep = PhysicsScene.SimulationStep; + else + CollidingStep = 0; + } + } + public override bool CollidingGround { + get { return (CollidingGroundStep == PhysicsScene.SimulationStep); } + set + { + if (value) + CollidingGroundStep = PhysicsScene.SimulationStep; + else + CollidingGroundStep = 0; + } + } + public override bool CollidingObj { + get { return (CollidingObjectStep == PhysicsScene.SimulationStep); } + set { + if (value) + CollidingObjectStep = PhysicsScene.SimulationStep; + else + CollidingObjectStep = 0; + } + } + // The collisions that have been collected this tick protected CollisionEventUpdate CollisionCollection; @@ -196,12 +227,16 @@ public abstract class BSPhysObject : PhysicsActor { bool ret = false; - // The following lines make IsColliding() and IsCollidingGround() work + // The following lines make IsColliding(), CollidingGround() and CollidingObj work CollidingStep = PhysicsScene.SimulationStep; if (collidingWith <= PhysicsScene.TerrainManager.HighestTerrainID) { CollidingGroundStep = PhysicsScene.SimulationStep; } + else + { + CollidingObjectStep = PhysicsScene.SimulationStep; + } // prims in the same linkset cannot collide with each other if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID)) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index f804a0f..06e4ada 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -915,18 +915,6 @@ public sealed class BSPrim : BSPhysObject get { return _throttleUpdates; } set { _throttleUpdates = value; } } - public override bool IsColliding { - get { return (CollidingStep == PhysicsScene.SimulationStep); } - set { _isColliding = value; } - } - public override bool CollidingGround { - get { return (CollidingGroundStep == PhysicsScene.SimulationStep); } - set { _collidingGround = value; } - } - public override bool CollidingObj { - get { return _collidingObj; } - set { _collidingObj = value; } - } public bool IsPhantom { get { // SceneObjectPart removes phantom objects from the physics scene @@ -1006,12 +994,12 @@ public sealed class BSPrim : BSPhysObject public override OMV.Vector3 PIDTarget { set { _PIDTarget = value; } } - public override bool PIDActive { - set { _usePID = value; } - } public override float PIDTau { set { _PIDTau = value; } } + public override bool PIDActive { + set { _usePID = value; } + } // Used for llSetHoverHeight and maybe vehicle height // Hover Height will override MoveTo target's Z diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index a66508a..16131cd 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -2,9 +2,10 @@ CURRENT PRIORITIES ================================================= Redo BulletSimAPI to allow native C# implementation of Bullet option. Avatar movement - flying into a wall doesn't stop avatar who keeps appearing to move through the obsticle + flying into a wall doesn't stop avatar who keeps appearing to move through the obstacle walking up stairs is not calibrated correctly (stairs out of Kepler cabin) avatar capsule rotation completed +llMoveToTarget Enable vehicle border crossings (at least as poorly as ODE) Terrain skirts Avatar created in previous region and not new region when crossing border -- cgit v1.1 From c1e7539c77480b839d513dbb7db74aa8f260eba0 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 27 Dec 2012 18:19:25 -0800 Subject: BulletSim: Parameterize nominal frame rate (55) and add parameters to dynamially turn on/off detailed, unmanaged data dumping of prims and vehicles. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 6 ++++++ OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 5 +++++ OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 4 ++-- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 11 ++++++++--- 4 files changed, 21 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index a8edd23..0bdfbe3 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -822,6 +822,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin { if (!IsActive) return; + if (PhysicsScene.VehiclePhysicalLoggingEnabled) + BulletSimAPI.DumpRigidBody2(PhysicsScene.World.ptr, Prim.PhysBody.ptr); + ForgetKnownVehicleProperties(); MoveLinear(pTimestep); @@ -836,6 +839,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin // for the physics engine to note the changes so an UpdateProperties event will happen. PushKnownChanged(); + if (PhysicsScene.VehiclePhysicalLoggingEnabled) + BulletSimAPI.DumpRigidBody2(PhysicsScene.World.ptr, Prim.PhysBody.ptr); + VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", Prim.LocalID, VehiclePosition, Prim.Force, VehicleVelocity, VehicleRotationalVelocity); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 8366cef..f8f24bd 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -212,6 +212,11 @@ public static class BSParam (s,cf,p,v) => { s.m_fixedTimeStep = cf.GetFloat(p, v); }, (s) => { return (float)s.m_fixedTimeStep; }, (s,p,l,v) => { s.m_fixedTimeStep = v; } ), + new ParameterDefn("NominalFrameRate", "The base frame rate we claim", + 55f, + (s,cf,p,v) => { s.NominalFrameRate = cf.GetInt(p, (int)v); }, + (s) => { return (float)s.NominalFrameRate; }, + (s,p,l,v) => { s.NominalFrameRate = (int)v; } ), new ParameterDefn("MaxCollisionsPerFrame", "Max collisions returned at end of each frame", 2048f, (s,cf,p,v) => { s.m_maxCollisionsPerFrame = cf.GetInt(p, (int)v); }, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 06e4ada..2d429c4 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -758,8 +758,8 @@ public sealed class BSPrim : BSPhysObject // For compound based linksets, this enables and disables interactions of the children. Linkset.Refresh(this); - DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},body={6},shape={7}", - LocalID, IsStatic, IsSolid, Mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody, PhysShape); + DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},cType={6},body={7},shape={8}", + LocalID, IsStatic, IsSolid, Mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody.collisionType, PhysBody, PhysShape); } // "Making dynamic" means changing to and from static. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index a5fbf10..8edcd20 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -74,6 +74,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters internal int m_maxSubSteps; internal float m_fixedTimeStep; internal long m_simulationStep = 0; + internal float NominalFrameRate { get; set; } public long SimulationStep { get { return m_simulationStep; } } internal int m_taintsToProcessPerStep; internal float LastTimeStep { get; private set; } @@ -162,6 +163,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters private string m_physicsLoggingPrefix; private int m_physicsLoggingFileMinutes; private bool m_physicsLoggingDoFlush; + private bool m_physicsPhysicalDumpEnabled; // 'true' of the vehicle code is to log lots of details public bool VehicleLoggingEnabled { get; private set; } public bool VehiclePhysicalLoggingEnabled { get; private set; } @@ -272,6 +274,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-%REGIONNAME%-"); m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5); m_physicsLoggingDoFlush = pConfig.GetBoolean("PhysicsLoggingDoFlush", false); + m_physicsPhysicalDumpEnabled = pConfig.GetBoolean("PhysicsPhysicalDumpEnabled", false); // Very detailed logging for vehicle debugging VehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false); VehiclePhysicalLoggingEnabled = pConfig.GetBoolean("VehiclePhysicalLoggingEnabled", false); @@ -488,7 +491,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world. // Only enable this in a limited test world with few objects. - // BulletSimAPI.DumpAllInfo2(World.ptr); // DEBUG DEBUG DEBUG + if (m_physicsPhysicalDumpEnabled) + BulletSimAPI.DumpAllInfo2(World.ptr); // step the physical world one interval m_simulationStep++; @@ -587,12 +591,13 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world. // Only enable this in a limited test world with few objects. - // BulletSimAPI.DumpAllInfo2(World.ptr); // DEBUG DEBUG DEBUG + if (m_physicsPhysicalDumpEnabled) + BulletSimAPI.DumpAllInfo2(World.ptr); // The physics engine returns the number of milliseconds it simulated this call. // These are summed and normalized to one second and divided by 1000 to give the reported physics FPS. // Multiply by 55 to give a nominal frame rate of 55. - return (float)numSubSteps * m_fixedTimeStep * 1000f * 55f; + return (float)numSubSteps * m_fixedTimeStep * 1000f * NominalFrameRate; } // Something has collided -- cgit v1.1 From 422f0fd6ec6e30c5200dbf81875c64223002f9c7 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 27 Dec 2012 22:02:38 -0800 Subject: BulletSim: fix physical object not interacting with static objects. Another instance of the underlying Bullet doing, ah, helpful things when items are added to the world. --- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 33 +++++++++++++++++++------- 1 file changed, 24 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 2d429c4..5f3f0d1 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -438,7 +438,7 @@ public sealed class BSPrim : BSPhysObject if (inWorld) { - BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr); + AddObjectToPhysicalWorld(); } // Must set gravity after it has been added to the world because, for unknown reasons, @@ -740,18 +740,11 @@ public sealed class BSPrim : BSPhysObject // Make solid or not (do things bounce off or pass through this object). MakeSolid(IsSolid); - BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr); - - // TODO: Fix this. Total kludge because adding object to world resets its gravity to default. - // Replace this when the new AddObjectToWorld function is complete. - BulletSimAPI.SetGravity2(PhysBody.ptr, ComputeGravity()); + AddObjectToPhysicalWorld(); // Rebuild its shape BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); - // Collision filter can be set only when the object is in the world - PhysBody.ApplyCollisionMask(); - // Recompute any linkset parameters. // When going from non-physical to physical, this re-enables the constraints that // had been automatically disabled when the mass was set to zero. @@ -900,6 +893,28 @@ public sealed class BSPrim : BSPhysObject } } + // Add me to the physical world. + // Object MUST NOT already be in the world. + // This routine exists because some assorted properties get mangled by adding to the world. + internal void AddObjectToPhysicalWorld() + { + if (PhysBody.HasPhysicalBody) + { + BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr); + + // TODO: Fix this. Total kludge because adding object to world resets its gravity to default. + // Replace this when the new AddObjectToWorld function is complete. + BulletSimAPI.SetGravity2(PhysBody.ptr, ComputeGravity()); + + // Collision filter can be set only when the object is in the world + if (!PhysBody.ApplyCollisionMask()) + { + m_log.ErrorFormat("{0} Failed setting object collision mask: id={1}", LogHeader, LocalID); + DetailLog("{0},BSPrim.UpdatePhysicalParameters,failedSetMaskGroup,cType={1}", LocalID, PhysBody.collisionType); + } + } + } + // prims don't fly public override bool Flying { get { return _flying; } -- cgit v1.1 From 1f6aaad0b587f1589afd7a7ca6feb8d2bbba8641 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 27 Dec 2012 22:04:12 -0800 Subject: BulletSim: correct collision mask definition for linkset children. Remove unused code. Add comments and TODOs. --- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 1 + .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 24 +++++++++---------- .../Region/Physics/BulletSPlugin/BulletSimData.cs | 27 ++++------------------ .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 1 + 4 files changed, 18 insertions(+), 35 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 8edcd20..4133107 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -269,6 +269,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters BSParam.SetParameterConfigurationValues(this, pConfig); // Very detailed logging for physics debugging + // TODO: the boolean values can be moved to the normal parameter processing. m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false); m_physicsLoggingDir = pConfig.GetString("PhysicsLoggingDir", "."); m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-%REGIONNAME%-"); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index afe5bca..eb4d039 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -250,20 +250,20 @@ public enum CollisionFilterGroups : uint // filter/mask definition below. This way collision interactions // are more easily found and debugged. BNoneGroup = 0, - BDefaultGroup = 1 << 0, - BStaticGroup = 1 << 1, - BKinematicGroup = 1 << 2, - BDebrisGroup = 1 << 3, - BSensorTrigger = 1 << 4, - BCharacterGroup = 1 << 5, - BAllGroup = 0xFFFFFFFF, + BDefaultGroup = 1 << 0, // 0001 + BStaticGroup = 1 << 1, // 0002 + BKinematicGroup = 1 << 2, // 0004 + BDebrisGroup = 1 << 3, // 0008 + BSensorTrigger = 1 << 4, // 0010 + BCharacterGroup = 1 << 5, // 0020 + BAllGroup = 0x000FFFFF, // Filter groups defined by BulletSim - BGroundPlaneGroup = 1 << 10, - BTerrainGroup = 1 << 11, - BRaycastGroup = 1 << 12, - BSolidGroup = 1 << 13, + BGroundPlaneGroup = 1 << 10, // 0400 + BTerrainGroup = 1 << 11, // 0800 + BRaycastGroup = 1 << 12, // 1000 + BSolidGroup = 1 << 13, // 2000 // BLinksetGroup = xx // a linkset proper is either static or dynamic - BLinksetChildGroup = 1 << 14, + BLinksetChildGroup = 1 << 14, // 4000 }; // CFM controls the 'hardness' of the constraint. 0=fixed, 0..1=violatable. Default=0 diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs index 36d38d4..5ad6746 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs @@ -72,12 +72,12 @@ public struct BulletBody public bool HasPhysicalBody { get { return ptr != IntPtr.Zero; } } // Apply the specificed collision mask into the physical world - public void ApplyCollisionMask() + public bool ApplyCollisionMask() { // Should assert the body has been added to the physical world. // (The collision masks are stored in the collision proxy cache which only exists for // a collision body that is in the world.) - BulletSimAPI.SetCollisionGroupMask2(ptr, + return BulletSimAPI.SetCollisionGroupMask2(ptr, BulletSimData.CollisionTypeMasks[collisionType].group, BulletSimData.CollisionTypeMasks[collisionType].mask); } @@ -207,26 +207,6 @@ public struct CollisionTypeFilterGroup public uint mask; }; - /* NOTE: old definitions kept for reference. Delete when things are working. - // The collsion filters and masked are defined in one place -- don't want them scattered - AvatarGroup = BCharacterGroup, - AvatarMask = BAllGroup, - ObjectGroup = BSolidGroup, - ObjectMask = BAllGroup, - StaticObjectGroup = BStaticGroup, - StaticObjectMask = AvatarGroup | ObjectGroup, // static things don't interact with much - LinksetGroup = BLinksetGroup, - LinksetMask = BAllGroup, - LinksetChildGroup = BLinksetChildGroup, - LinksetChildMask = BNoneGroup, // Linkset children disappear from the world - VolumeDetectGroup = BSensorTrigger, - VolumeDetectMask = ~BSensorTrigger, - TerrainGroup = BTerrainGroup, - TerrainMask = BAllGroup & ~BStaticGroup, // static objects on the ground don't collide - GroundPlaneGroup = BGroundPlaneGroup, - GroundPlaneMask = BAllGroup - */ - public static class BulletSimData { @@ -269,8 +249,9 @@ public static Dictionary CollisionTypeM }, { CollisionType.LinksetChild, new CollisionTypeFilterGroup(CollisionType.LinksetChild, - (uint)CollisionFilterGroups.BTerrainGroup, + (uint)CollisionFilterGroups.BLinksetChildGroup, (uint)(CollisionFilterGroups.BNoneGroup)) + // (uint)(CollisionFilterGroups.BCharacterGroup | CollisionFilterGroups.BSolidGroup)) }, }; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 16131cd..f805836 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -194,6 +194,7 @@ Should taints check for existance or activeness of target? actually gone when the taint happens. Crashes don't happen because the taint closure keeps the object from being freed, but that is just an accident. Possibly have and 'active' flag that is checked by the taint processor? +Parameters for physics logging should be moved from BSScene to BSParam (at least boolean ones) THREADING ================================================= -- cgit v1.1 From 70e0a86601ed33113a87189ee53a40e12790c609 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 28 Dec 2012 11:56:07 -0800 Subject: BulletSim: fix problem of avatars appearing to walk through walls by moving the movement motor to a pre-step action and out of its questionable previous home in UpdateProperties. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 106 +++++++++++---------- 1 file changed, 55 insertions(+), 51 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 3f7b5e1..90936d0 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -91,17 +91,7 @@ public sealed class BSCharacter : BSPhysObject if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth; if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth; - // A motor to control the acceleration and deceleration of the avatar movement. - // _velocityMotor = new BSVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); - // _velocityMotor = new BSPIDVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); - // Infinite decay and timescale values so motor only changes current to target values. - _velocityMotor = new BSVMotor("BSCharacter.Velocity", - 0.2f, // time scale - BSMotor.Infinite, // decay time scale - BSMotor.InfiniteVector, // friction timescale - 1f // efficiency - ); - _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages. + SetupMovementMotor(); _flying = isFlying; _orientation = OMV.Quaternion.Identity; @@ -152,13 +142,12 @@ public sealed class BSCharacter : BSPhysObject ZeroMotion(true); ForcePosition = _position; + // Set the velocity and compute the proper friction - ForceVelocity = _velocity; - // Setting the current and target in the motor will cause it to start computing any deceleration. _velocityMotor.Reset(); - _velocityMotor.SetCurrent(_velocity); _velocityMotor.SetTarget(_velocity); - _velocityMotor.Enabled = false; + _velocityMotor.SetCurrent(_velocity); + ForceVelocity = _velocity; // This will enable or disable the flying buoyancy of the avatar. // Needs to be reset especially when an avatar is recreated after crossing a region boundry. @@ -192,6 +181,48 @@ public sealed class BSCharacter : BSPhysObject PhysBody.ApplyCollisionMask(); } + // The avatar's movement is controlled by this motor that speeds up and slows down + // the avatar seeking to reach the motor's target speed. + // This motor runs as a prestep action for the avatar so it will keep the avatar + // standing as well as moving. Destruction of the avatar will destroy the pre-step action. + private void SetupMovementMotor() + { + + // Someday, use a PID motor for asymmetric speed up and slow down + // _velocityMotor = new BSPIDVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); + + // Infinite decay and timescale values so motor only changes current to target values. + _velocityMotor = new BSVMotor("BSCharacter.Velocity", + 0.2f, // time scale + BSMotor.Infinite, // decay time scale + BSMotor.InfiniteVector, // friction timescale + 1f // efficiency + ); + // _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages. + + RegisterPreStepAction("BSCharactor.Movement", LocalID, delegate(float timeStep) + { + // TODO: Decide if the step parameters should be changed depending on the avatar's + // state (flying, colliding, ...). There is code in ODE to do this. + + OMV.Vector3 stepVelocity = _velocityMotor.Step(timeStep); + + // If falling, we keep the world's downward vector no matter what the other axis specify. + if (!Flying && !IsColliding) + { + stepVelocity.Z = _velocity.Z; + DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", + LocalID, stepVelocity); + } + + // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force. + OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass / PhysicsScene.LastTimeStep; + DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", + LocalID, stepVelocity, _velocity, Mass, moveForce); + AddForce(moveForce, false, true); + }); + } + public override void RequestPhysicsterseUpdate() { base.RequestPhysicsterseUpdate(); @@ -668,7 +699,13 @@ public sealed class BSCharacter : BSPhysObject public override float APIDStrength { set { return; } } public override float APIDDamping { set { return; } } - public override void AddForce(OMV.Vector3 force, bool pushforce) { + public override void AddForce(OMV.Vector3 force, bool pushforce) + { + // Since this force is being applied in only one step, make this a force per second. + OMV.Vector3 addForce = force / PhysicsScene.LastTimeStep; + AddForce(addForce, pushforce, false); + } + private void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { if (force.IsFinite()) { float magnitude = force.Length(); @@ -678,10 +715,10 @@ public sealed class BSCharacter : BSPhysObject force = force / magnitude * BSParam.MaxAddForceMagnitude; } - OMV.Vector3 addForce = force / PhysicsScene.LastTimeStep; + OMV.Vector3 addForce = force; DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce); - PhysicsScene.TaintedObject("BSCharacter.AddForce", delegate() + PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.AddForce", delegate() { // Bullet adds this central force to the total force for this tick DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce); @@ -750,39 +787,6 @@ public sealed class BSCharacter : BSPhysObject // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. PositionSanityCheck(true); - if (_velocityMotor.Enabled) - { - // TODO: Decide if the step parameters should be changed depending on the avatar's - // state (flying, colliding, ...). - - OMV.Vector3 stepVelocity = _velocityMotor.Step(PhysicsScene.LastTimeStep); - - // Check for cases to turn off the motor. - if ( - // If the walking motor is all done, turn it off - (_velocityMotor.TargetValue.ApproxEquals(OMV.Vector3.Zero, 0.01f) && _velocityMotor.ErrorIsZero) ) - { - ZeroMotion(true); - stepVelocity = OMV.Vector3.Zero; - _velocityMotor.Enabled = false; - DetailLog("{0},BSCharacter.UpdateProperties,taint,disableVelocityMotor,m={1}", LocalID, _velocityMotor); - } - else - { - // If the motor is not being turned off... - // If falling, we keep the world's downward vector no matter what the other axis specify. - if (!Flying && !IsColliding) - { - stepVelocity.Z = entprop.Velocity.Z; - DetailLog("{0},BSCharacter.UpdateProperties,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity); - } - } - - _velocity = stepVelocity; - entprop.Velocity = _velocity; - BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); - } - // remember the current and last set values LastEntityProperties = CurrentEntityProperties; CurrentEntityProperties = entprop; -- cgit v1.1 From 7266eeca6efd10852a062cfc802a50c346b7b119 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 28 Dec 2012 12:01:57 -0800 Subject: BulletSim: add 'AvatarAlwaysRunFactor' parameter and use in setTargetVelocity to implement the 'always run' feature. --- OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 6 +++--- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 90936d0..901f976 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -464,15 +464,15 @@ public sealed class BSCharacter : BSPhysObject { DetailLog("{0},BSCharacter.setTargetVelocity,call,vel={1}", LocalID, value); OMV.Vector3 targetVel = value; + if (_setAlwaysRun) + targetVel *= BSParam.AvatarAlwaysRunFactor; + PhysicsScene.TaintedObject("BSCharacter.setTargetVelocity", delegate() { _velocityMotor.Reset(); _velocityMotor.SetTarget(targetVel); _velocityMotor.SetCurrent(_velocity); _velocityMotor.Enabled = true; - - // Make sure a property update happens next step so the motor gets incorporated. - BulletSimAPI.PushUpdate2(PhysBody.ptr); }); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index f8f24bd..5c8553a 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -68,6 +68,7 @@ public static class BSParam // Avatar parameters public static float AvatarFriction { get; private set; } public static float AvatarStandingFriction { get; private set; } + public static float AvatarAlwaysRunFactor { get; private set; } public static float AvatarDensity { get; private set; } public static float AvatarRestitution { get; private set; } public static float AvatarCapsuleWidth { get; private set; } @@ -367,6 +368,11 @@ public static class BSParam (s,cf,p,v) => { AvatarStandingFriction = cf.GetFloat(p, v); }, (s) => { return AvatarStandingFriction; }, (s,p,l,v) => { AvatarStandingFriction = v; } ), + new ParameterDefn("AvatarAlwaysRunFactor", "Speed multiplier if avatar is set to always run", + 1.3f, + (s,cf,p,v) => { AvatarAlwaysRunFactor = cf.GetFloat(p, v); }, + (s) => { return AvatarAlwaysRunFactor; }, + (s,p,l,v) => { AvatarAlwaysRunFactor = v; } ), new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.", 3.5f, (s,cf,p,v) => { AvatarDensity = cf.GetFloat(p, v); }, -- cgit v1.1 From fdf8732cd712d8a5799a817e61d4c68e204ba9a2 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 28 Dec 2012 16:29:16 -0800 Subject: ScenePresence passes the avatar rotation down to the physics engine. This will be a no-op for ODE but enables asymmetrical avatars for BulletSim. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index a60c551..0219540 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -560,6 +560,10 @@ namespace OpenSim.Region.Framework.Scenes set { m_bodyRot = value; + if (PhysicsActor != null) + { + PhysicsActor.Orientation = m_bodyRot; + } // m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); } } -- cgit v1.1 From db6c0363f05db8b2a180eff04db9138a378d227f Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 29 Dec 2012 08:03:57 -0800 Subject: BulletSim: tweeking avatar capsule code in an attempt to have asymmetrical avatar capsule work now that rotation is being passed from the simulator. Turns out the Bullet capsule is just not very functional: it doesn't scale properly, the implementation only half does asymmetry and, in general, is hard to work with. Avatar shape is about what it was before these changes. Added initial data structures for avatar shape mesh. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 104 ++++++++++++--------- .../Physics/BulletSPlugin/BSShapeCollection.cs | 6 +- OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | 13 +++ .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 4 +- 4 files changed, 81 insertions(+), 46 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 901f976..9659542 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -66,7 +66,6 @@ public sealed class BSCharacter : BSPhysObject private float _buoyancy; // The friction and velocity of the avatar is modified depending on whether walking or not. - private OMV.Vector3 _appliedVelocity; // the last velocity applied to the avatar private float _currentFriction; // the friction currently being used (changed by setVelocity). private BSVMotor _velocityMotor; @@ -85,27 +84,27 @@ public sealed class BSCharacter : BSPhysObject _physicsActorType = (int)ActorTypes.Agent; _position = pos; - // Old versions of ScenePresence passed only the height. If width and/or depth are zero, - // replace with the default values. - _size = size; - if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth; - if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth; - - SetupMovementMotor(); - _flying = isFlying; _orientation = OMV.Quaternion.Identity; _velocity = OMV.Vector3.Zero; - _appliedVelocity = OMV.Vector3.Zero; _buoyancy = ComputeBuoyancyFromFlying(isFlying); _currentFriction = BSParam.AvatarStandingFriction; _avatarDensity = BSParam.AvatarDensity; - // The dimensions of the avatar capsule are kept in the scale. + // Old versions of ScenePresence passed only the height. If width and/or depth are zero, + // replace with the default values. + _size = size; + if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth; + if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth; + + // The dimensions of the physical capsule are kept in the scale. // Physics creates a unit capsule which is scaled by the physics engine. - ComputeAvatarScale(_size); + Scale = ComputeAvatarScale(_size); // set _avatarVolume and _mass based on capsule size, _density and Scale ComputeAvatarVolumeAndMass(); + + SetupMovementMotor(); + DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}", LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass); @@ -217,9 +216,21 @@ public sealed class BSCharacter : BSPhysObject // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force. OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass / PhysicsScene.LastTimeStep; - DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", - LocalID, stepVelocity, _velocity, Mass, moveForce); - AddForce(moveForce, false, true); + + // If moveForce is very small, zero things so we don't keep sending microscopic updates to the user + float moveForceMagnitudeSquared = moveForce.LengthSquared(); + if (moveForceMagnitudeSquared < 0.0001) + { + DetailLog("{0},BSCharacter.MoveMotor,zeroMovement,stepVel={1},vel={2},mass={3},magSq={4},moveForce={5}", + LocalID, stepVelocity, _velocity, Mass, moveForceMagnitudeSquared, moveForce); + ForceVelocity = OMV.Vector3.Zero; + } + else + { + DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", + LocalID, stepVelocity, _velocity, Mass, moveForce); + AddForce(moveForce, false, true); + } }); } @@ -238,14 +249,13 @@ public sealed class BSCharacter : BSPhysObject } set { - // When an avatar's size is set, only the height is changed. _size = value; // Old versions of ScenePresence passed only the height. If width and/or depth are zero, // replace with the default values. if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth; if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth; - ComputeAvatarScale(_size); + Scale = ComputeAvatarScale(_size); ComputeAvatarVolumeAndMass(); DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}", LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass); @@ -521,8 +531,6 @@ public sealed class BSCharacter : BSPhysObject BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction); } } - // Remember the set velocity so we can suppress the reduction by friction, ... - _appliedVelocity = value; BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); BulletSimAPI.Activate2(PhysBody.ptr, true); @@ -554,11 +562,7 @@ public sealed class BSCharacter : BSPhysObject // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation); PhysicsScene.TaintedObject("BSCharacter.setOrientation", delegate() { - if (PhysBody.HasPhysicalBody) - { - // _position = BulletSimAPI.GetPosition2(BSBody.ptr); - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); - } + ForceOrientation = _orientation; }); } } @@ -573,7 +577,11 @@ public sealed class BSCharacter : BSPhysObject set { _orientation = value; - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + if (PhysBody.HasPhysicalBody) + { + // _position = BulletSimAPI.GetPosition2(BSBody.ptr); + BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + } } } public override int PhysicsActorType { @@ -716,7 +724,7 @@ public sealed class BSCharacter : BSPhysObject } OMV.Vector3 addForce = force; - DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce); + // DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce); PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.AddForce", delegate() { @@ -740,21 +748,31 @@ public sealed class BSCharacter : BSPhysObject public override void SetMomentum(OMV.Vector3 momentum) { } - private void ComputeAvatarScale(OMV.Vector3 size) + private OMV.Vector3 ComputeAvatarScale(OMV.Vector3 size) { - OMV.Vector3 newScale = size; - // newScale.X = PhysicsScene.Params.avatarCapsuleWidth; - // newScale.Y = PhysicsScene.Params.avatarCapsuleDepth; - - // From the total height, remove the capsule half spheres that are at each end - // The 1.15f came from ODE. Not sure what this factors in. - // newScale.Z = (size.Z * 1.15f) - (newScale.X + newScale.Y); + OMV.Vector3 newScale; + + // Bullet's capsule total height is the "passed height + radius * 2"; + // The base capsule is 1 diameter and 2 height (passed radius=0.5, passed height = 1) + // The number we pass in for 'scaling' is the multiplier to get that base + // shape to be the size desired. + // So, when creating the scale for the avatar height, we take the passed height + // (size.Z) and remove the caps. + // Another oddity of the Bullet capsule implementation is that it presumes the Y + // dimension is the radius of the capsule. Even though some of the code allows + // for a asymmetrical capsule, other parts of the code presume it is cylindrical. + + // Scale is multiplier of radius with one of "0.5" + newScale.X = size.X / 2f; + newScale.Y = size.Y / 2f; // The total scale height is the central cylindar plus the caps on the two ends. - newScale.Z = size.Z + (Math.Min(size.X, size.Y) * 2f); + newScale.Z = (size.Z + (Math.Min(size.X, size.Y) * 2)) / 2f; + // If smaller than the endcaps, just fake like we're almost that small + if (newScale.Z < 0) + newScale.Z = 0.1f; - // Convert diameters to radii and height to half height -- the way Bullet expects it. - Scale = newScale / 2f; + return newScale; } // set _avatarVolume and _mass based on capsule size, _density and Scale @@ -762,14 +780,14 @@ public sealed class BSCharacter : BSPhysObject { _avatarVolume = (float)( Math.PI - * Scale.X - * Scale.Y // the area of capsule cylinder - * Scale.Z // times height of capsule cylinder + * Size.X / 2f + * Size.Y / 2f // the area of capsule cylinder + * Size.Z // times height of capsule cylinder + 1.33333333f * Math.PI - * Scale.X - * Math.Min(Scale.X, Scale.Y) - * Scale.Y // plus the volume of the capsule end caps + * Size.X / 2f + * Math.Min(Size.X, Size.Y) / 2 + * Size.Y / 2f // plus the volume of the capsule end caps ); _mass = _avatarDensity * _avatarVolume; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 65ebcaa..0cc51b0 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -420,8 +420,7 @@ public sealed class BSShapeCollection : IDisposable if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_CAPSULE) { // an avatar capsule is close to a native shape (it is not shared) - GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_CAPSULE, - FixedShapeKey.KEY_CAPSULE, shapeCallback); + GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_CAPSULE, FixedShapeKey.KEY_CAPSULE, shapeCallback); if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape); ret = true; haveShape = true; @@ -573,6 +572,9 @@ public sealed class BSShapeCollection : IDisposable { // The proper scale has been calculated in the prim. newShape = new BulletShape( + // Bullet's capsule total height is the passed "height + (radius * 2)" so, the base + // capsule is radius of 0.5f (1 diameter) and height of two (1.0f + 0.5f * 2)". + // This must be taken into account when computing the scaling of the capsule. BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale) , shapeType); if (DDetail) DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs index 96cd55e..c7885c6 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs @@ -205,4 +205,17 @@ public class BSShapeCompound : BSShape } public override void Dereference(BSScene physicsScene) { } } + +public class BSShapeAvatar : BSShape +{ + private static string LogHeader = "[BULLETSIM SHAPE AVATAR]"; + public BSShapeAvatar() : base() + { + } + public static BSShape GetReference(BSPhysObject prim) + { + return new BSShapeNull(); + } + public override void Dereference(BSScene physicsScene) { } +} } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index eb4d039..b909b38 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -69,6 +69,7 @@ public enum BSPhysicsShapeType SHAPE_TERRAIN = 21, SHAPE_COMPOUND = 22, SHAPE_HEIGHTMAP = 23, + SHAPE_AVATAR = 24, }; // The native shapes have predefined shape hash keys @@ -79,7 +80,8 @@ public enum FixedShapeKey : ulong KEY_SPHERE = 2, KEY_CONE = 3, KEY_CYLINDER = 4, - KEY_CAPSULE = 5, + KEY_CAPSULE = 5, + KEY_AVATAR = 6, } [StructLayout(LayoutKind.Sequential)] -- cgit v1.1 From 0538096fa3397c52b1171a3ec83dc88489002710 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 29 Dec 2012 08:32:57 -0800 Subject: BulletSim: an 'if' to suppress multiple setting of avatar orientation. Looks like the viewer bombards the server with avatar orientation information (we're talking several hundred a second) when the avatar is being turned or when walking. This change just reduces the number of 'set' calls into unmanaged code. --- OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 9659542..e19b5b3 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -558,12 +558,16 @@ public sealed class BSCharacter : BSPhysObject public override OMV.Quaternion Orientation { get { return _orientation; } set { - _orientation = value; - // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation); - PhysicsScene.TaintedObject("BSCharacter.setOrientation", delegate() + // Orientation is set zillions of times when an avatar is walking. It's like + // the viewer doesn't trust us. + if (_orientation != value) { - ForceOrientation = _orientation; - }); + _orientation = value; + PhysicsScene.TaintedObject("BSCharacter.setOrientation", delegate() + { + ForceOrientation = _orientation; + }); + } } } // Go directly to Bullet to get/set the value. -- cgit v1.1 From 28a8949b9f315e9257a6c51d8872cd99d00fe556 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 29 Dec 2012 10:19:47 -0800 Subject: BulletSim: remove check for small motor movement because, while it did the right thing for stopping (speed reducing to zero), it prevented movement from starting (speed increasing from zero). Will revisit when the generalize PID motor is debugged. --- OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 7 +++++-- OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index e19b5b3..3b77e49 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -217,6 +217,7 @@ public sealed class BSCharacter : BSPhysObject // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force. OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass / PhysicsScene.LastTimeStep; + /* // If moveForce is very small, zero things so we don't keep sending microscopic updates to the user float moveForceMagnitudeSquared = moveForce.LengthSquared(); if (moveForceMagnitudeSquared < 0.0001) @@ -227,10 +228,12 @@ public sealed class BSCharacter : BSPhysObject } else { - DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", - LocalID, stepVelocity, _velocity, Mass, moveForce); AddForce(moveForce, false, true); } + */ + DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", + LocalID, stepVelocity, _velocity, Mass, moveForce); + AddForce(moveForce, false, true); }); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index b909b38..b361498 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -80,7 +80,7 @@ public enum FixedShapeKey : ulong KEY_SPHERE = 2, KEY_CONE = 3, KEY_CYLINDER = 4, - KEY_CAPSULE = 5, + KEY_CAPSULE = 5, KEY_AVATAR = 6, } -- cgit v1.1 From 26f364cc5d935c86d94c9b860757e46fd539085a Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 29 Dec 2012 18:30:53 -0800 Subject: Comment out test messages that go directly to the console. --- .../Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs index ad0b83d..943675e 100644 --- a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs @@ -107,12 +107,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcRouterModule public void ScriptRemoved(UUID itemID) { - System.Console.WriteLine("TEST Script Removed!"); + // System.Console.WriteLine("TEST Script Removed!"); } public void ObjectRemoved(UUID objectID) { - System.Console.WriteLine("TEST Obj Removed!"); + // System.Console.WriteLine("TEST Obj Removed!"); } } } -- cgit v1.1 From 4914d6c0ea02ac0060f2fd7e145119603ecd8e5b Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 29 Dec 2012 18:31:38 -0800 Subject: Resolve Mantis 6480 (http://opensimulator.org/mantis/view.php?id=6480) by reversing the sign on the recoil computation and adding a [XEngine]RecoilScaleFactor parameter which defaults to zero. Testing in SL seems to show that there is not a recoil action there. Or, at least, it is very small. If someone knows how small, the default for the scale factor should be changed. --- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 837779d..f9b90c5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -96,6 +96,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected float m_ScriptDelayFactor = 1.0f; protected float m_ScriptDistanceFactor = 1.0f; protected float m_MinTimerInterval = 0.5f; + protected float m_recoilScaleFactor = 0.0f; protected DateTime m_timer = DateTime.Now; protected bool m_waitingForScriptAnswer = false; @@ -146,6 +147,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // there's an smtp config, so load in the snooze time. EMAIL_PAUSE_TIME = SMTPConfig.GetInt("email_pause_time", EMAIL_PAUSE_TIME); } + // Rezzing an object with a velocity can create recoil. This feature seems to have been + // removed from recent versions of SL. The code computes recoil (vel*mass) and scales + // it by this factor. May be zero to turn off recoil all together. + m_recoilScaleFactor = m_ScriptEngine.Config.GetFloat("RecoilScaleFactor", m_recoilScaleFactor); } public override Object InitializeLifetimeService() @@ -2829,10 +2834,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api PhysicsActor pa = new_group.RootPart.PhysActor; + //Recoil. if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) { - //Recoil. - llApplyImpulse(vel * groupmass, 0); + Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; + if (recoil != Vector3.Zero) + { + llApplyImpulse(recoil, 0); + } } // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) }); -- cgit v1.1 From 203588e3c0374505a6aa564d8f7a655d968653d7 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 29 Dec 2012 18:34:46 -0800 Subject: BulletSim: change physical data structures to classes. Add default instantiations for PhysBody and PhysShape when BSPhysObject is created to account for them being classes and not structures. Update TODO list. --- .../Region/Physics/BulletSPlugin/BSLinksetConstraints.cs | 15 +++++++++------ OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | 5 +++++ OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 5 +---- OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs | 15 ++++++++++----- OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | 4 ++++ 5 files changed, 29 insertions(+), 15 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index 6b592e7..86c29c7 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -48,12 +48,15 @@ public sealed class BSLinksetConstraints : BSLinkset { base.Refresh(requestor); - // Queue to happen after all the other taint processing - PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate() - { - if (HasAnyChildren && IsRoot(requestor)) - RecomputeLinksetConstraints(); - }); + if (HasAnyChildren && IsRoot(requestor)) + { + // Queue to happen after all the other taint processing + PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate() + { + if (HasAnyChildren && IsRoot(requestor)) + RecomputeLinksetConstraints(); + }); + } } // The object is going dynamic (physical). Do any setup necessary diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 73b5764..b093890 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -67,6 +67,11 @@ public abstract class BSPhysObject : PhysicsActor PhysObjectName = name; TypeName = typeName; + // We don't have any physical representation yet. + PhysBody = new BulletBody(localID); + PhysShape = new BulletShape(); + + // A linkset of just me Linkset = BSLinkset.Factory(PhysicsScene, this); LastAssetBuildFailed = false; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 5f3f0d1..2de4717 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -111,10 +111,7 @@ public sealed class BSPrim : BSPhysObject _mass = CalculateMass(); - // No body or shape yet - PhysBody = new BulletBody(LocalID); - PhysShape = new BulletShape(); - + // Cause linkset variables to be initialized (like mass) Linkset.Refresh(this); DetailLog("{0},BSPrim.constructor,call", LocalID); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs index 5ad6746..cd5d170 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs @@ -35,7 +35,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // These hold pointers to allocated objects in the unmanaged space. // The physics engine controller class created at initialization -public struct BulletWorld +public class BulletWorld { public BulletWorld(uint worldId, BSScene bss, IntPtr xx) { @@ -50,7 +50,7 @@ public struct BulletWorld } // An allocated Bullet btRigidBody -public struct BulletBody +public class BulletBody { public BulletBody(uint id) : this(id, IntPtr.Zero) { @@ -96,9 +96,14 @@ public struct BulletBody } } -public struct BulletShape +public class BulletShape { - public BulletShape(IntPtr xx) : this(xx, BSPhysicsShapeType.SHAPE_UNKNOWN) + public BulletShape() + : this(IntPtr.Zero, BSPhysicsShapeType.SHAPE_UNKNOWN) + { + } + public BulletShape(IntPtr xx) + : this(xx, BSPhysicsShapeType.SHAPE_UNKNOWN) { } public BulletShape(IntPtr xx, BSPhysicsShapeType typ) @@ -136,7 +141,7 @@ public struct BulletShape } // An allocated Bullet btConstraint -public struct BulletConstraint +public class BulletConstraint { public BulletConstraint(IntPtr xx) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index f805836..8ec9871 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -97,6 +97,9 @@ Selecting and deselecting physical objects causes CPU processing time to jump Re-implement buoyancy as a separate force on the object rather than diddling gravity. Register a pre-step event to add the force. More efficient memory usage when passing hull information from BSPrim to BulletSim +Avatar movement motor check for zero or small movement. Somehow suppress small movements + when avatar has stopped and is just standing. Simple test for near zero has + the problem of preventing starting up (increase from zero) especially when falling. LINKSETS ====================================================== @@ -195,6 +198,7 @@ Should taints check for existance or activeness of target? keeps the object from being freed, but that is just an accident. Possibly have and 'active' flag that is checked by the taint processor? Parameters for physics logging should be moved from BSScene to BSParam (at least boolean ones) +Can some of the physical wrapper classes (BulletBody, BulletWorld, BulletShape) be 'sealed'? THREADING ================================================= -- cgit v1.1 From 48f718f39fcd61501262878a8bcfbd98efed29d2 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 29 Dec 2012 21:43:43 -0800 Subject: BulletSim: first round of conversion from direct BulletSimAPI interfacing by BulletSim core to using the BulletSimAPITemplate. Physical object creation and destruction first. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 8 +- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 6 +- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 10 +- .../Physics/BulletSPlugin/BSShapeCollection.cs | 63 +- OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | 7 +- .../Physics/BulletSPlugin/BSTerrainHeightmap.cs | 7 +- .../Physics/BulletSPlugin/BSTerrainManager.cs | 8 +- .../Region/Physics/BulletSPlugin/BSTerrainMesh.cs | 8 +- .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 947 ++++----------------- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 7 +- 11 files changed, 234 insertions(+), 839 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 3b77e49..d5ab245 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -210,8 +210,7 @@ public sealed class BSCharacter : BSPhysObject if (!Flying && !IsColliding) { stepVelocity.Z = _velocity.Z; - DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", - LocalID, stepVelocity); + // DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity); } // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force. @@ -231,8 +230,7 @@ public sealed class BSCharacter : BSPhysObject AddForce(moveForce, false, true); } */ - DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", - LocalID, stepVelocity, _velocity, Mass, moveForce); + // DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); AddForce(moveForce, false, true); }); } @@ -736,7 +734,7 @@ public sealed class BSCharacter : BSPhysObject PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.AddForce", delegate() { // Bullet adds this central force to the total force for this tick - DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce); + // DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce); if (PhysBody.HasPhysicalBody) { BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, addForce); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 19ce62b..9bb951c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -359,7 +359,7 @@ public sealed class BSLinksetCompound : BSLinkset PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); BulletShape newShape = cPrim.PhysShape; cPrim.PhysShape = saveShape; - BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, newShape.ptr, lci.OffsetPos, lci.OffsetRot); + PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetPos, lci.OffsetRot); } else { @@ -371,7 +371,7 @@ public sealed class BSLinksetCompound : BSLinkset PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); } - BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, cPrim.PhysShape.ptr, lci.OffsetPos, lci.OffsetRot); + PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); } } return false; // 'false' says to move onto the next child in the list @@ -386,7 +386,7 @@ public sealed class BSLinksetCompound : BSLinkset Rebuilding = false; } - BulletSimAPI.RecalculateCompoundShapeLocalAabb2(LinksetRoot.PhysShape.ptr); + PhysicsScene.PE.RecalculateCompoundShapeLocalAabb(LinksetRoot.PhysShape); // DEBUG: see of inter-linkset collisions are causing problems for constraint linksets. // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 2de4717..cf09be2 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -845,7 +845,7 @@ public sealed class BSPrim : BSPhysObject // the functions after this one set up the state of a possibly newly created collision body. private void MakeSolid(bool makeSolid) { - CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(PhysBody.ptr); + CollisionObjectTypes bodyType = (CollisionObjectTypes)PhysicsScene.PE.GetBodyType(PhysBody); if (makeSolid) { // Verify the previous code created the correct shape for this type of thing. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 4133107..bfc9df2 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -50,6 +50,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public string BulletSimVersion = "?"; + // The handle to the underlying managed or unmanaged version of Bullet being used. + public BulletSimAPITemplate PE; + public Dictionary PhysObjects; public BSShapeCollection Shapes; @@ -187,12 +190,15 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // Allocate pinned memory to pass parameters. UnmanagedParams = new ConfigurationParameters[1]; - m_paramsHandle = GCHandle.Alloc(UnmanagedParams, GCHandleType.Pinned); // Set default values for physics parameters plus any overrides from the ini file GetInitialParameterValues(config); - // allocate more pinned memory close to the above in an attempt to get the memory all together + // For the moment, only one version of the interface + PE = new BSAPIUnman(); + + // Allocate more pinned memory. Do this early to try and get all pinned memory close together. + m_paramsHandle = GCHandle.Alloc(UnmanagedParams, GCHandleType.Pinned); m_collisionArray = new CollisionDesc[m_maxCollisionsPerFrame]; m_collisionArrayPinnedHandle = GCHandle.Alloc(m_collisionArray, GCHandleType.Pinned); m_updateArray = new EntityProperties[m_maxUpdatesPerFrame]; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 0cc51b0..e7d8d14 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -174,7 +174,7 @@ public sealed class BSShapeCollection : IDisposable // Zero any reference to the shape so it is not freed when the body is deleted. BulletSimAPI.SetCollisionShape2(PhysicsScene.World.ptr, body.ptr, IntPtr.Zero); - BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, body.ptr); + PhysicsScene.PE.DestroyObject(PhysicsScene.World, body); }); } } @@ -261,7 +261,7 @@ public sealed class BSShapeCollection : IDisposable if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}", BSScene.DetailLogZero, shape.ptr.ToString("X"), inTaintTime); if (shapeCallback != null) shapeCallback(shape); - BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr); + PhysicsScene.PE.DeleteCollisionShape(PhysicsScene.World, shape); } else { @@ -342,26 +342,26 @@ public sealed class BSShapeCollection : IDisposable return; } - int numChildren = BulletSimAPI.GetNumberOfCompoundChildren2(shape.ptr); + int numChildren = PhysicsScene.PE.GetNumberOfCompoundChildren(shape); if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceCompound,shape={1},children={2}", BSScene.DetailLogZero, shape, numChildren); for (int ii = numChildren - 1; ii >= 0; ii--) { - IntPtr childShape = BulletSimAPI.RemoveChildShapeFromCompoundShapeIndex2(shape.ptr, ii); + BulletShape childShape = PhysicsScene.PE.RemoveChildShapeFromCompoundShapeIndex(shape, ii); DereferenceAnonCollisionShape(childShape); } - BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr); + PhysicsScene.PE.DeleteCollisionShape(PhysicsScene.World, shape); } // Sometimes we have a pointer to a collision shape but don't know what type it is. // Figure out type and call the correct dereference routine. // Called at taint-time. - private void DereferenceAnonCollisionShape(IntPtr cShape) + private void DereferenceAnonCollisionShape(BulletShape shapeInfo) { MeshDesc meshDesc; HullDesc hullDesc; - BulletShape shapeInfo = new BulletShape(cShape); + IntPtr cShape = shapeInfo.ptr; if (TryGetMeshByPtr(cShape, out meshDesc)) { shapeInfo.type = BSPhysicsShapeType.SHAPE_MESH; @@ -382,7 +382,7 @@ public sealed class BSShapeCollection : IDisposable } else { - if (BulletSimAPI.IsNativeShape2(cShape)) + if (PhysicsScene.PE.IsNativeShape(shapeInfo)) { shapeInfo.isNativeShape = true; shapeInfo.type = BSPhysicsShapeType.SHAPE_BOX; // (technically, type doesn't matter) @@ -570,19 +570,15 @@ public sealed class BSShapeCollection : IDisposable if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE) { - // The proper scale has been calculated in the prim. - newShape = new BulletShape( - // Bullet's capsule total height is the passed "height + (radius * 2)" so, the base - // capsule is radius of 0.5f (1 diameter) and height of two (1.0f + 0.5f * 2)". - // This must be taken into account when computing the scaling of the capsule. - BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale) - , shapeType); + + newShape = PhysicsScene.PE.BuildCapsuleShape(PhysicsScene.World, 1f, 1f, prim.Scale); if (DDetail) DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); } else { // Native shapes are scaled in Bullet so set the scaling to the size - newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, nativeShapeData), shapeType); + newShape = PhysicsScene.PE.BuildNativeShape(PhysicsScene.World, nativeShapeData); + } if (!newShape.HasPhysicalShape) { @@ -629,13 +625,14 @@ public sealed class BSShapeCollection : IDisposable private BulletShape CreatePhysicalMesh(string objName, System.UInt64 newMeshKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) { + BulletShape newShape = new BulletShape(); IMesh meshData = null; - IntPtr meshPtr = IntPtr.Zero; + MeshDesc meshDesc; if (Meshes.TryGetValue(newMeshKey, out meshDesc)) { // If the mesh has already been built just use it. - meshPtr = meshDesc.ptr; + newShape = new BulletShape(meshDesc.ptr, BSPhysicsShapeType.SHAPE_MESH); } else { @@ -658,11 +655,10 @@ public sealed class BSShapeCollection : IDisposable // m_log.DebugFormat("{0}: BSShapeCollection.CreatePhysicalMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}", // LogHeader, prim.LocalID, newMeshKey, indices.Length, vertices.Count); - meshPtr = BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, + newShape = PhysicsScene.PE.CreateMeshShape(PhysicsScene.World, indices.GetLength(0), indices, vertices.Count, verticesAsFloats); } } - BulletShape newShape = new BulletShape(meshPtr, BSPhysicsShapeType.SHAPE_MESH); newShape.shapeKey = newMeshKey; return newShape; @@ -700,12 +696,14 @@ public sealed class BSShapeCollection : IDisposable private BulletShape CreatePhysicalHull(string objName, System.UInt64 newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) { + BulletShape newShape = new BulletShape(); IntPtr hullPtr = IntPtr.Zero; + HullDesc hullDesc; if (Hulls.TryGetValue(newHullKey, out hullDesc)) { // If the hull shape already is created, just use it. - hullPtr = hullDesc.ptr; + newShape = new BulletShape(hullDesc.ptr, BSPhysicsShapeType.SHAPE_HULL); } else { @@ -793,11 +791,10 @@ public sealed class BSShapeCollection : IDisposable } } // create the hull data structure in Bullet - hullPtr = BulletSimAPI.CreateHullShape2(PhysicsScene.World.ptr, hullCount, convHulls); + newShape = PhysicsScene.PE.CreateHullShape(PhysicsScene.World, hullCount, convHulls); } } - BulletShape newShape = new BulletShape(hullPtr, BSPhysicsShapeType.SHAPE_HULL); newShape.shapeKey = newHullKey; return newShape; @@ -819,12 +816,12 @@ public sealed class BSShapeCollection : IDisposable // Don't need to do this as the shape is freed when the new root shape is created below. // DereferenceShape(prim.PhysShape, true, shapeCallback); - BulletShape cShape = new BulletShape( - BulletSimAPI.CreateCompoundShape2(PhysicsScene.World.ptr, false), BSPhysicsShapeType.SHAPE_COMPOUND); + + BulletShape cShape = PhysicsScene.PE.CreateCompoundShape(PhysicsScene.World, false); // Create the shape for the root prim and add it to the compound shape. Cannot be a native shape. CreateGeomMeshOrHull(prim, shapeCallback); - BulletSimAPI.AddChildShapeToCompoundShape2(cShape.ptr, prim.PhysShape.ptr, OMV.Vector3.Zero, OMV.Quaternion.Identity); + PhysicsScene.PE.AddChildShapeToCompoundShape(cShape, prim.PhysShape, OMV.Vector3.Zero, OMV.Quaternion.Identity); if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToCompoundShape,addRootPrim,compShape={1},rootShape={2}", prim.LocalID, cShape, prim.PhysShape); @@ -932,7 +929,7 @@ public sealed class BSShapeCollection : IDisposable // If not a solid object, body is a GhostObject. Otherwise a RigidBody. if (!mustRebuild) { - CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(prim.PhysBody.ptr); + CollisionObjectTypes bodyType = (CollisionObjectTypes)PhysicsScene.PE.GetBodyType(prim.PhysBody); if (prim.IsSolid && bodyType != CollisionObjectTypes.CO_RIGID_BODY || !prim.IsSolid && bodyType != CollisionObjectTypes.CO_GHOST_OBJECT) { @@ -947,20 +944,16 @@ public sealed class BSShapeCollection : IDisposable DereferenceBody(prim.PhysBody, true, bodyCallback); BulletBody aBody; - IntPtr bodyPtr = IntPtr.Zero; if (prim.IsSolid) { - bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr, - prim.LocalID, prim.RawPosition, prim.RawOrientation); - if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); + aBody = PhysicsScene.PE.CreateBodyFromShape(sim, shape, prim.LocalID, prim.RawPosition, prim.RawOrientation); + if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,mesh,body={1}", prim.LocalID, aBody); } else { - bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr, - prim.LocalID, prim.RawPosition, prim.RawOrientation); - if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); + aBody = PhysicsScene.PE.CreateGhostFromShape(sim, shape, prim.LocalID, prim.RawPosition, prim.RawOrientation); + if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,ghost,body={1}", prim.LocalID, aBody); } - aBody = new BulletBody(prim.LocalID, bodyPtr); ReferenceBody(aBody, true); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs index c7885c6..cdaa869 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs @@ -126,7 +126,8 @@ public class BSShapeNative : BSShape BSPhysicsShapeType shapeType, FixedShapeKey shapeKey) { // Native shapes are not shared and are always built anew. - return new BSShapeNative(physicsScene, prim, shapeType, shapeKey); + //return new BSShapeNative(physicsScene, prim, shapeType, shapeKey); + return null; } private BSShapeNative(BSScene physicsScene, BSPhysObject prim, @@ -141,6 +142,7 @@ public class BSShapeNative : BSShape nativeShapeData.HullKey = (ulong)shapeKey; + /* if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE) { ptr = BulletSimAPI.BuildCapsuleShape2(physicsScene.World.ptr, 1f, 1f, prim.Scale); @@ -157,15 +159,18 @@ public class BSShapeNative : BSShape } type = shapeType; key = (UInt64)shapeKey; + */ } // Make this reference to the physical shape go away since native shapes are not shared. public override void Dereference(BSScene physicsScene) { + /* // Native shapes are not tracked and are released immediately physicsScene.DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,shape={1}", BSScene.DetailLogZero, this); BulletSimAPI.DeleteCollisionShape2(physicsScene.World.ptr, ptr); ptr = IntPtr.Zero; // Garbage collection will free up this instance. + */ } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs index 07a9fd8..a2c085e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs @@ -105,9 +105,8 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys centerPos.Y = m_mapInfo.minCoords.Y + (m_mapInfo.sizeY / 2f); centerPos.Z = m_mapInfo.minZ + ((m_mapInfo.maxZ - m_mapInfo.minZ) / 2f); - m_mapInfo.terrainBody = new BulletBody(m_mapInfo.ID, - BulletSimAPI.CreateBodyWithDefaultMotionState2(m_mapInfo.terrainShape.ptr, - m_mapInfo.ID, centerPos, Quaternion.Identity)); + m_mapInfo.terrainBody = PhysicsScene.PE.CreateBodyWithDefaultMotionState(m_mapInfo.terrainShape, + m_mapInfo.ID, centerPos, Quaternion.Identity); // Set current terrain attributes BulletSimAPI.SetFriction2(m_mapInfo.terrainBody.ptr, BSParam.TerrainFriction); @@ -139,7 +138,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys { BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); // Frees both the body and the shape. - BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); + PhysicsScene.PE.DestroyObject(PhysicsScene.World, m_mapInfo.terrainBody); BulletSimAPI.ReleaseHeightMapInfo2(m_mapInfo.Ptr); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index 86ccfbb..d99a50f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -137,9 +137,9 @@ public sealed class BSTerrainManager : IDisposable BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, BSParam.TerrainCollisionMargin), BSPhysicsShapeType.SHAPE_GROUNDPLANE); - m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID, - BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID, - Vector3.Zero, Quaternion.Identity)); + m_groundPlane = PhysicsScene.PE.CreateBodyWithDefaultMotionState(groundPlaneShape, + BSScene.GROUNDPLANE_ID, Vector3.Zero, Quaternion.Identity); + BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr); BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_groundPlane.ptr); // Ground plane does not move @@ -160,7 +160,7 @@ public sealed class BSTerrainManager : IDisposable { if (BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr)) { - BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_groundPlane.ptr); + PhysicsScene.PE.DestroyObject(PhysicsScene.World, m_groundPlane); } m_groundPlane.Clear(); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index 061e232..d8c4972 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs @@ -91,9 +91,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys PhysicsScene.DetailLog("{0},BSTerrainMesh.create,meshed,indices={1},indSz={2},vertices={3},vertSz={4}", ID, indicesCount, indices.Length, verticesCount, vertices.Length); - m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, - indicesCount, indices, verticesCount, vertices), - BSPhysicsShapeType.SHAPE_MESH); + m_terrainShape = PhysicsScene.PE.CreateMeshShape(PhysicsScene.World, indicesCount, indices, verticesCount, vertices); if (!m_terrainShape.HasPhysicalShape) { // DISASTER!! @@ -106,7 +104,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys Vector3 pos = regionBase; Quaternion rot = Quaternion.Identity; - m_terrainBody = new BulletBody(id, BulletSimAPI.CreateBodyWithDefaultMotionState2( m_terrainShape.ptr, ID, pos, rot)); + m_terrainBody = PhysicsScene.PE.CreateBodyWithDefaultMotionState(m_terrainShape, ID, pos, rot); if (!m_terrainBody.HasPhysicalBody) { // DISASTER!! @@ -143,7 +141,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys { BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr); // Frees both the body and the shape. - BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_terrainBody.ptr); + PhysicsScene.PE.DestroyObject(PhysicsScene.World, m_terrainBody); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index b361498..6b76151 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -292,985 +292,376 @@ public enum ConstraintParamAxis : int public abstract class BulletSimAPITemplate { + /* // Initialization and simulation -public abstract BulletWorld Initialize2(Vector3 maxPosition, IntPtr parms, +public abstract BulletWorld Initialize(Vector3 maxPosition, IntPtr parms, int maxCollisions, IntPtr collisionArray, int maxUpdates, IntPtr updateArray ); -public abstract bool UpdateParameter2(BulletWorld world, uint localID, String parm, float value); +public abstract bool UpdateParameter(BulletWorld world, uint localID, String parm, float value); -public abstract void SetHeightMap2(BulletWorld world, float[] heightmap); +public abstract void SetHeightMap(BulletWorld world, float[] heightmap); -public abstract void Shutdown2(BulletWorld sim); +public abstract void Shutdown(BulletWorld sim); -public abstract int PhysicsStep2(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, +public abstract int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, out int updatedEntityCount, out IntPtr updatedEntitiesPtr, out int collidersCount, out IntPtr collidersPtr); -public abstract bool PushUpdate2(BulletBody obj); +public abstract bool PushUpdate(BulletBody obj); + */ // ===================================================================================== // Mesh, hull, shape and body creation helper routines -public abstract BulletShape CreateMeshShape2(BulletWorld world, - int indicesCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices, - int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices ); +public abstract BulletShape CreateMeshShape(BulletWorld world, + int indicesCount, int[] indices, + int verticesCount, float[] vertices ); -public abstract BulletShape CreateHullShape2(BulletWorld world, - int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls); +public abstract BulletShape CreateHullShape(BulletWorld world, + int hullCount, float[] hulls); -public abstract BulletShape BuildHullShapeFromMesh2(BulletWorld world, BulletShape meshShape); +public abstract BulletShape BuildHullShapeFromMesh(BulletWorld world, BulletShape meshShape); -public abstract BulletShape BuildNativeShape2(BulletWorld world, ShapeData shapeData); +public abstract BulletShape BuildNativeShape(BulletWorld world, ShapeData shapeData); -public abstract bool IsNativeShape2(BulletShape shape); +public abstract bool IsNativeShape(BulletShape shape); public abstract void SetShapeCollisionMargin(BulletShape shape, float margin); -public abstract BulletShape BuildCapsuleShape2(BulletWorld world, float radius, float height, Vector3 scale); - -public abstract BulletShape CreateCompoundShape2(BulletWorld sim, bool enableDynamicAabbTree); - -public abstract int GetNumberOfCompoundChildren2(BulletShape cShape); - -public abstract void AddChildShapeToCompoundShape2(BulletShape cShape, BulletShape addShape, Vector3 pos, Quaternion rot); - -public abstract BulletShape GetChildShapeFromCompoundShapeIndex2(BulletShape cShape, int indx); - -public abstract BulletShape RemoveChildShapeFromCompoundShapeIndex2(BulletShape cShape, int indx); - -public abstract void RemoveChildShapeFromCompoundShape2(BulletShape cShape, BulletShape removeShape); - -public abstract void RecalculateCompoundShapeLocalAabb2(BulletShape cShape); - -public abstract BulletShape DuplicateCollisionShape2(BulletWorld sim, BulletShape srcShape, uint id); - -public abstract BulletBody CreateBodyFromShapeAndInfo2(BulletWorld sim, BulletShape shape, uint id, IntPtr constructionInfo); - -public abstract bool DeleteCollisionShape2(BulletWorld world, BulletShape shape); - -public abstract int GetBodyType2(BulletBody obj); - -public abstract BulletBody CreateBodyFromShape2(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot); - -public abstract BulletBody CreateBodyWithDefaultMotionState2(BulletShape shape, uint id, Vector3 pos, Quaternion rot); - -public abstract BulletBody CreateGhostFromShape2(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot); - -public abstract IntPtr AllocateBodyInfo2(BulletBody obj); - -public abstract void ReleaseBodyInfo2(IntPtr obj); - -public abstract void DestroyObject2(BulletWorld sim, BulletBody obj); - -// ===================================================================================== -// Terrain creation and helper routines -public abstract IntPtr CreateHeightMapInfo2(BulletWorld sim, uint id, Vector3 minCoords, Vector3 maxCoords, - [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin); - -public abstract IntPtr FillHeightMapInfo2(BulletWorld sim, IntPtr mapInfo, uint id, Vector3 minCoords, Vector3 maxCoords, - [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin); - -public abstract bool ReleaseHeightMapInfo2(IntPtr heightMapInfo); - -public abstract BulletBody CreateGroundPlaneShape2(uint id, float height, float collisionMargin); - -public abstract BulletBody CreateTerrainShape2(IntPtr mapInfo); - -// ===================================================================================== -// Constraint creation and helper routines -public abstract BulletConstraint Create6DofConstraint2(BulletWorld world, BulletBody obj1, BulletBody obj2, - Vector3 frame1loc, Quaternion frame1rot, - Vector3 frame2loc, Quaternion frame2rot, - bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); - -public abstract BulletConstraint Create6DofConstraintToPoint2(BulletWorld world, BulletBody obj1, BulletBody obj2, - Vector3 joinPoint, - bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); - -public abstract BulletConstraint CreateHingeConstraint2(BulletWorld world, BulletBody obj1, BulletBody obj2, - Vector3 pivotinA, Vector3 pivotinB, - Vector3 axisInA, Vector3 axisInB, - bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); - -public abstract void SetConstraintEnable2(BulletConstraint constrain, float numericTrueFalse); - -public abstract void SetConstraintNumSolverIterations2(BulletConstraint constrain, float iterations); - -public abstract bool SetFrames2(BulletConstraint constrain, - Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot); - -public abstract bool SetLinearLimits2(BulletConstraint constrain, Vector3 low, Vector3 hi); - -public abstract bool SetAngularLimits2(BulletConstraint constrain, Vector3 low, Vector3 hi); - -public abstract bool UseFrameOffset2(BulletConstraint constrain, float enable); - -public abstract bool TranslationalLimitMotor2(BulletConstraint constrain, float enable, float targetVel, float maxMotorForce); - -public abstract bool SetBreakingImpulseThreshold2(BulletConstraint constrain, float threshold); - -public abstract bool CalculateTransforms2(BulletConstraint constrain); - -public abstract bool SetConstraintParam2(BulletConstraint constrain, ConstraintParams paramIndex, float value, ConstraintParamAxis axis); - -public abstract bool DestroyConstraint2(BulletWorld world, BulletConstraint constrain); - -// ===================================================================================== -// btCollisionWorld entries -public abstract void UpdateSingleAabb2(BulletWorld world, BulletBody obj); - -public abstract void UpdateAabbs2(BulletWorld world); - -public abstract bool GetForceUpdateAllAabbs2(BulletWorld world); - -public abstract void SetForceUpdateAllAabbs2(BulletWorld world, bool force); - -// ===================================================================================== -// btDynamicsWorld entries -public abstract bool AddObjectToWorld2(BulletWorld world, BulletBody obj); - -public abstract bool RemoveObjectFromWorld2(BulletWorld world, BulletBody obj); - -public abstract bool AddConstraintToWorld2(BulletWorld world, BulletConstraint constrain, bool disableCollisionsBetweenLinkedObjects); - -public abstract bool RemoveConstraintFromWorld2(BulletWorld world, BulletConstraint constrain); -// ===================================================================================== -// btCollisionObject entries -public abstract Vector3 GetAnisotripicFriction2(BulletConstraint constrain); - -public abstract Vector3 SetAnisotripicFriction2(BulletConstraint constrain, Vector3 frict); - -public abstract bool HasAnisotripicFriction2(BulletConstraint constrain); - -public abstract void SetContactProcessingThreshold2(BulletBody obj, float val); - -public abstract float GetContactProcessingThreshold2(BulletBody obj); - -public abstract bool IsStaticObject2(BulletBody obj); - -public abstract bool IsKinematicObject2(BulletBody obj); - -public abstract bool IsStaticOrKinematicObject2(BulletBody obj); - -public abstract bool HasContactResponse2(BulletBody obj); - -public abstract void SetCollisionShape2(BulletWorld sim, BulletBody obj, BulletBody shape); - -public abstract BulletShape GetCollisionShape2(BulletBody obj); - -public abstract int GetActivationState2(BulletBody obj); - -public abstract void SetActivationState2(BulletBody obj, int state); - -public abstract void SetDeactivationTime2(BulletBody obj, float dtime); - -public abstract float GetDeactivationTime2(BulletBody obj); - -public abstract void ForceActivationState2(BulletBody obj, ActivationState state); - -public abstract void Activate2(BulletBody obj, bool forceActivation); - -public abstract bool IsActive2(BulletBody obj); - -public abstract void SetRestitution2(BulletBody obj, float val); - -public abstract float GetRestitution2(BulletBody obj); - -public abstract void SetFriction2(BulletBody obj, float val); - -public abstract float GetFriction2(BulletBody obj); - - /* Haven't defined the type 'Transform' -public abstract Transform GetWorldTransform2(BulletBody obj); - -public abstract void setWorldTransform2(BulletBody obj, Transform trans); - */ - -public abstract Vector3 GetPosition2(BulletBody obj); - -public abstract Quaternion GetOrientation2(BulletBody obj); - -public abstract void SetTranslation2(BulletBody obj, Vector3 position, Quaternion rotation); - -public abstract IntPtr GetBroadphaseHandle2(BulletBody obj); - -public abstract void SetBroadphaseHandle2(BulletBody obj, IntPtr handle); - - /* -public abstract Transform GetInterpolationWorldTransform2(IntPtr obj); - -public abstract void SetInterpolationWorldTransform2(IntPtr obj, Transform trans); - */ - -public abstract void SetInterpolationLinearVelocity2(BulletBody obj, Vector3 vel); - -public abstract void SetInterpolationAngularVelocity2(BulletBody obj, Vector3 vel); - -public abstract void SetInterpolationVelocity2(BulletBody obj, Vector3 linearVel, Vector3 angularVel); - -public abstract float GetHitFraction2(BulletBody obj); - -public abstract void SetHitFraction2(BulletBody obj, float val); - -public abstract CollisionFlags GetCollisionFlags2(BulletBody obj); - -public abstract CollisionFlags SetCollisionFlags2(BulletBody obj, CollisionFlags flags); - -public abstract CollisionFlags AddToCollisionFlags2(BulletBody obj, CollisionFlags flags); - -public abstract CollisionFlags RemoveFromCollisionFlags2(BulletBody obj, CollisionFlags flags); - -public abstract float GetCcdMotionThreshold2(BulletBody obj); - -public abstract void SetCcdMotionThreshold2(BulletBody obj, float val); - -public abstract float GetCcdSweptSphereRadius2(BulletBody obj); - -public abstract void SetCcdSweptSphereRadius2(BulletBody obj, float val); - -public abstract IntPtr GetUserPointer2(BulletBody obj); - -public abstract void SetUserPointer2(BulletBody obj, IntPtr val); - -// ===================================================================================== -// btRigidBody entries -public abstract void ApplyGravity2(BulletBody obj); - -public abstract void SetGravity2(BulletBody obj, Vector3 val); - -public abstract Vector3 GetGravity2(BulletBody obj); - -public abstract void SetDamping2(BulletBody obj, float lin_damping, float ang_damping); - -public abstract void SetLinearDamping2(BulletBody obj, float lin_damping); - -public abstract void SetAngularDamping2(BulletBody obj, float ang_damping); - -public abstract float GetLinearDamping2(BulletBody obj); +public abstract BulletShape BuildCapsuleShape(BulletWorld world, float radius, float height, Vector3 scale); -public abstract float GetAngularDamping2(BulletBody obj); +public abstract BulletShape CreateCompoundShape(BulletWorld sim, bool enableDynamicAabbTree); -public abstract float GetLinearSleepingThreshold2(BulletBody obj); +public abstract int GetNumberOfCompoundChildren(BulletShape cShape); +public abstract void AddChildShapeToCompoundShape(BulletShape cShape, BulletShape addShape, Vector3 pos, Quaternion rot); -public abstract void ApplyDamping2(BulletBody obj, float timeStep); +public abstract BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx); -public abstract void SetMassProps2(BulletBody obj, float mass, Vector3 inertia); +public abstract BulletShape RemoveChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx); -public abstract Vector3 GetLinearFactor2(BulletBody obj); +public abstract void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape); -public abstract void SetLinearFactor2(BulletBody obj, Vector3 factor); +public abstract void RecalculateCompoundShapeLocalAabb(BulletShape cShape); - /* -public abstract void SetCenterOfMassTransform2(BulletBody obj, Transform trans); - */ - -public abstract void SetCenterOfMassByPosRot2(BulletBody obj, Vector3 pos, Quaternion rot); - -// Add a force to the object as if its mass is one. -public abstract void ApplyCentralForce2(BulletBody obj, Vector3 force); - -// Set the force being applied to the object as if its mass is one. -public abstract void SetObjectForce2(BulletBody obj, Vector3 force); - -public abstract Vector3 GetTotalForce2(BulletBody obj); +public abstract BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id); -public abstract Vector3 GetTotalTorque2(BulletBody obj); +public abstract BulletBody CreateBodyFromShapeAndInfo(BulletWorld sim, BulletShape shape, uint id, IntPtr constructionInfo); -public abstract Vector3 GetInvInertiaDiagLocal2(BulletBody obj); +public abstract bool DeleteCollisionShape(BulletWorld world, BulletShape shape); -public abstract void SetInvInertiaDiagLocal2(BulletBody obj, Vector3 inert); +public abstract int GetBodyType(BulletBody obj); -public abstract void SetSleepingThresholds2(BulletBody obj, float lin_threshold, float ang_threshold); +public abstract BulletBody CreateBodyFromShape(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot); -public abstract void ApplyTorque2(BulletBody obj, Vector3 torque); - -// Apply force at the given point. Will add torque to the object. -public abstract void ApplyForce2(BulletBody obj, Vector3 force, Vector3 pos); - -// Apply impulse to the object. Same as "ApplycentralForce" but force scaled by object's mass. -public abstract void ApplyCentralImpulse2(BulletBody obj, Vector3 imp); - -// Apply impulse to the object's torque. Force is scaled by object's mass. -public abstract void ApplyTorqueImpulse2(BulletBody obj, Vector3 imp); - -// Apply impulse at the point given. For is scaled by object's mass and effects both linear and angular forces. -public abstract void ApplyImpulse2(BulletBody obj, Vector3 imp, Vector3 pos); +public abstract BulletBody CreateBodyWithDefaultMotionState(BulletShape shape, uint id, Vector3 pos, Quaternion rot); -public abstract void ClearForces2(BulletBody obj); +public abstract BulletBody CreateGhostFromShape(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot); -public abstract void ClearAllForces2(BulletBody obj); +public abstract IntPtr AllocateBodyInfo(BulletBody obj); -public abstract void UpdateInertiaTensor2(BulletBody obj); +public abstract void ReleaseBodyInfo(IntPtr obj); +public abstract void DestroyObject(BulletWorld sim, BulletBody obj); /* -public abstract Transform GetCenterOfMassTransform2(BulletBody obj); - */ - -public abstract Vector3 GetLinearVelocity2(BulletBody obj); - -public abstract Vector3 GetAngularVelocity2(BulletBody obj); - -public abstract void SetLinearVelocity2(BulletBody obj, Vector3 val); - -public abstract void SetAngularVelocity2(BulletBody obj, Vector3 angularVelocity); - -public abstract Vector3 GetVelocityInLocalPoint2(BulletBody obj, Vector3 pos); - -public abstract void Translate2(BulletBody obj, Vector3 trans); - -public abstract void UpdateDeactivation2(BulletBody obj, float timeStep); - -public abstract bool WantsSleeping2(BulletBody obj); - -public abstract void SetAngularFactor2(BulletBody obj, float factor); - -public abstract void SetAngularFactorV2(BulletBody obj, Vector3 factor); - -public abstract Vector3 GetAngularFactor2(BulletBody obj); - -public abstract bool IsInWorld2(BulletBody obj); - -public abstract void AddConstraintRef2(BulletBody obj, BulletConstraint constrain); - -public abstract void RemoveConstraintRef2(BulletBody obj, BulletConstraint constrain); - -public abstract BulletConstraint GetConstraintRef2(BulletBody obj, int index); - -public abstract int GetNumConstraintRefs2(BulletBody obj); - -public abstract bool SetCollisionGroupMask2(BulletBody body, uint filter, uint mask); - -// ===================================================================================== -// btCollisionShape entries - -public abstract float GetAngularMotionDisc2(BulletShape shape); - -public abstract float GetContactBreakingThreshold2(BulletShape shape, float defaultFactor); - -public abstract bool IsPolyhedral2(BulletShape shape); - -public abstract bool IsConvex2d2(BulletShape shape); - -public abstract bool IsConvex2(BulletShape shape); - -public abstract bool IsNonMoving2(BulletShape shape); - -public abstract bool IsConcave2(BulletShape shape); - -public abstract bool IsCompound2(BulletShape shape); - -public abstract bool IsSoftBody2(BulletShape shape); - -public abstract bool IsInfinite2(BulletShape shape); - -public abstract void SetLocalScaling2(BulletShape shape, Vector3 scale); - -public abstract Vector3 GetLocalScaling2(BulletShape shape); - -public abstract Vector3 CalculateLocalInertia2(BulletShape shape, float mass); - -public abstract int GetShapeType2(BulletShape shape); - -public abstract void SetMargin2(BulletShape shape, float val); - -public abstract float GetMargin2(BulletShape shape); - -}; - -// =============================================================================== -static class BulletSimAPI { -// =============================================================================== -// Link back to the managed code for outputting log messages -[UnmanagedFunctionPointer(CallingConvention.Cdecl)] -public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg); - -// =============================================================================== -// Initialization and simulation -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms, - int maxCollisions, IntPtr collisionArray, - int maxUpdates, IntPtr updateArray, - DebugLogCallback logRoutine); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool UpdateParameter2(IntPtr world, uint localID, String parm, float value); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetHeightMap2(IntPtr world, float[] heightmap); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void Shutdown2(IntPtr sim); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern int PhysicsStep2(IntPtr world, float timeStep, int maxSubSteps, float fixedTimeStep, - out int updatedEntityCount, - out IntPtr updatedEntitiesPtr, - out int collidersCount, - out IntPtr collidersPtr); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool PushUpdate2(IntPtr obj); - -// ===================================================================================== -// Mesh, hull, shape and body creation helper routines -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateMeshShape2(IntPtr world, - int indicesCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices, - int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices ); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateHullShape2(IntPtr world, - int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr BuildHullShapeFromMesh2(IntPtr world, IntPtr meshShape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr BuildNativeShape2(IntPtr world, ShapeData shapeData); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsNativeShape2(IntPtr shape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetShapeCollisionMargin(IntPtr shape, float margin); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr BuildCapsuleShape2(IntPtr world, float radius, float height, Vector3 scale); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateCompoundShape2(IntPtr sim, bool enableDynamicAabbTree); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern int GetNumberOfCompoundChildren2(IntPtr cShape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void AddChildShapeToCompoundShape2(IntPtr cShape, IntPtr addShape, Vector3 pos, Quaternion rot); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr GetChildShapeFromCompoundShapeIndex2(IntPtr cShape, int indx); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr RemoveChildShapeFromCompoundShapeIndex2(IntPtr cShape, int indx); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void RemoveChildShapeFromCompoundShape2(IntPtr cShape, IntPtr removeShape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void RecalculateCompoundShapeLocalAabb2(IntPtr cShape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr DuplicateCollisionShape2(IntPtr sim, IntPtr srcShape, uint id); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateBodyFromShapeAndInfo2(IntPtr sim, IntPtr shape, uint id, IntPtr constructionInfo); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool DeleteCollisionShape2(IntPtr world, IntPtr shape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern int GetBodyType2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateBodyFromShape2(IntPtr sim, IntPtr shape, uint id, Vector3 pos, Quaternion rot); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateBodyWithDefaultMotionState2(IntPtr shape, uint id, Vector3 pos, Quaternion rot); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateGhostFromShape2(IntPtr sim, IntPtr shape, uint id, Vector3 pos, Quaternion rot); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr AllocateBodyInfo2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void ReleaseBodyInfo2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void DestroyObject2(IntPtr sim, IntPtr obj); - // ===================================================================================== // Terrain creation and helper routines -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateHeightMapInfo2(IntPtr sim, uint id, Vector3 minCoords, Vector3 maxCoords, - [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin); +public abstract IntPtr CreateHeightMapInfo(BulletWorld sim, uint id, Vector3 minCoords, Vector3 maxCoords, + float[] heightMap, float collisionMargin); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr FillHeightMapInfo2(IntPtr sim, IntPtr mapInfo, uint id, Vector3 minCoords, Vector3 maxCoords, - [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin); +public abstract IntPtr FillHeightMapInfo(BulletWorld sim, IntPtr mapInfo, uint id, Vector3 minCoords, Vector3 maxCoords, + float[] heightMap, float collisionMargin); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool ReleaseHeightMapInfo2(IntPtr heightMapInfo); +public abstract bool ReleaseHeightMapInfo(IntPtr heightMapInfo); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateGroundPlaneShape2(uint id, float height, float collisionMargin); +public abstract BulletBody CreateGroundPlaneShape(uint id, float height, float collisionMargin); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateTerrainShape2(IntPtr mapInfo); +public abstract BulletBody CreateTerrainShape(IntPtr mapInfo); // ===================================================================================== // Constraint creation and helper routines -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr Create6DofConstraint2(IntPtr world, IntPtr obj1, IntPtr obj2, +public abstract BulletConstraint Create6DofConstraint(BulletWorld world, BulletBody obj1, BulletBody obj2, Vector3 frame1loc, Quaternion frame1rot, Vector3 frame2loc, Quaternion frame2rot, bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr Create6DofConstraintToPoint2(IntPtr world, IntPtr obj1, IntPtr obj2, +public abstract BulletConstraint Create6DofConstraintToPoint(BulletWorld world, BulletBody obj1, BulletBody obj2, Vector3 joinPoint, bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateHingeConstraint2(IntPtr world, IntPtr obj1, IntPtr obj2, +public abstract BulletConstraint CreateHingeConstraint(BulletWorld world, BulletBody obj1, BulletBody obj2, Vector3 pivotinA, Vector3 pivotinB, Vector3 axisInA, Vector3 axisInB, bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetConstraintEnable2(IntPtr constrain, float numericTrueFalse); +public abstract void SetConstraintEnable(BulletConstraint constrain, float numericTrueFalse); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetConstraintNumSolverIterations2(IntPtr constrain, float iterations); +public abstract void SetConstraintNumSolverIterations(BulletConstraint constrain, float iterations); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool SetFrames2(IntPtr constrain, +public abstract bool SetFrames(BulletConstraint constrain, Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool SetLinearLimits2(IntPtr constrain, Vector3 low, Vector3 hi); +public abstract bool SetLinearLimits(BulletConstraint constrain, Vector3 low, Vector3 hi); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool SetAngularLimits2(IntPtr constrain, Vector3 low, Vector3 hi); +public abstract bool SetAngularLimits(BulletConstraint constrain, Vector3 low, Vector3 hi); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool UseFrameOffset2(IntPtr constrain, float enable); +public abstract bool UseFrameOffset(BulletConstraint constrain, float enable); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool TranslationalLimitMotor2(IntPtr constrain, float enable, float targetVel, float maxMotorForce); +public abstract bool TranslationalLimitMotor(BulletConstraint constrain, float enable, float targetVel, float maxMotorForce); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool SetBreakingImpulseThreshold2(IntPtr constrain, float threshold); +public abstract bool SetBreakingImpulseThreshold(BulletConstraint constrain, float threshold); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool CalculateTransforms2(IntPtr constrain); +public abstract bool CalculateTransforms(BulletConstraint constrain); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool SetConstraintParam2(IntPtr constrain, ConstraintParams paramIndex, float value, ConstraintParamAxis axis); +public abstract bool SetConstraintParam(BulletConstraint constrain, ConstraintParams paramIndex, float value, ConstraintParamAxis axis); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool DestroyConstraint2(IntPtr world, IntPtr constrain); +public abstract bool DestroyConstraint(BulletWorld world, BulletConstraint constrain); // ===================================================================================== // btCollisionWorld entries -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void UpdateSingleAabb2(IntPtr world, IntPtr obj); +public abstract void UpdateSingleAabb(BulletWorld world, BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void UpdateAabbs2(IntPtr world); +public abstract void UpdateAabbs(BulletWorld world); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool GetForceUpdateAllAabbs2(IntPtr world); +public abstract bool GetForceUpdateAllAabbs(BulletWorld world); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetForceUpdateAllAabbs2(IntPtr world, bool force); +public abstract void SetForceUpdateAllAabbs(BulletWorld world, bool force); // ===================================================================================== // btDynamicsWorld entries -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool AddObjectToWorld2(IntPtr world, IntPtr obj); +public abstract bool AddObjectToWorld(BulletWorld world, BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool RemoveObjectFromWorld2(IntPtr world, IntPtr obj); +public abstract bool RemoveObjectFromWorld(BulletWorld world, BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool AddConstraintToWorld2(IntPtr world, IntPtr constrain, bool disableCollisionsBetweenLinkedObjects); +public abstract bool AddConstraintToWorld(BulletWorld world, BulletConstraint constrain, bool disableCollisionsBetweenLinkedObjects); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool RemoveConstraintFromWorld2(IntPtr world, IntPtr constrain); +public abstract bool RemoveConstraintFromWorld(BulletWorld world, BulletConstraint constrain); // ===================================================================================== // btCollisionObject entries -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetAnisotripicFriction2(IntPtr constrain); +public abstract Vector3 GetAnisotripicFriction(BulletConstraint constrain); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 SetAnisotripicFriction2(IntPtr constrain, Vector3 frict); +public abstract Vector3 SetAnisotripicFriction(BulletConstraint constrain, Vector3 frict); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool HasAnisotripicFriction2(IntPtr constrain); +public abstract bool HasAnisotripicFriction(BulletConstraint constrain); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetContactProcessingThreshold2(IntPtr obj, float val); +public abstract void SetContactProcessingThreshold(BulletBody obj, float val); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetContactProcessingThreshold2(IntPtr obj); +public abstract float GetContactProcessingThreshold(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsStaticObject2(IntPtr obj); +public abstract bool IsStaticObject(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsKinematicObject2(IntPtr obj); +public abstract bool IsKinematicObject(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsStaticOrKinematicObject2(IntPtr obj); +public abstract bool IsStaticOrKinematicObject(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool HasContactResponse2(IntPtr obj); +public abstract bool HasContactResponse(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetCollisionShape2(IntPtr sim, IntPtr obj, IntPtr shape); +public abstract void SetCollisionShape(BulletWorld sim, BulletBody obj, BulletBody shape); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr GetCollisionShape2(IntPtr obj); +public abstract BulletShape GetCollisionShape(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern int GetActivationState2(IntPtr obj); +public abstract int GetActivationState(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetActivationState2(IntPtr obj, int state); +public abstract void SetActivationState(BulletBody obj, int state); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetDeactivationTime2(IntPtr obj, float dtime); +public abstract void SetDeactivationTime(BulletBody obj, float dtime); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetDeactivationTime2(IntPtr obj); +public abstract float GetDeactivationTime(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void ForceActivationState2(IntPtr obj, ActivationState state); +public abstract void ForceActivationState(BulletBody obj, ActivationState state); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void Activate2(IntPtr obj, bool forceActivation); +public abstract void Activate(BulletBody obj, bool forceActivation); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsActive2(IntPtr obj); +public abstract bool IsActive(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetRestitution2(IntPtr obj, float val); +public abstract void SetRestitution(BulletBody obj, float val); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetRestitution2(IntPtr obj); +public abstract float GetRestitution(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetFriction2(IntPtr obj, float val); +public abstract void SetFriction(BulletBody obj, float val); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetFriction2(IntPtr obj); +public abstract float GetFriction(BulletBody obj); - /* Haven't defined the type 'Transform' -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Transform GetWorldTransform2(IntPtr obj); +public abstract Vector3 GetPosition(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void setWorldTransform2(IntPtr obj, Transform trans); - */ +public abstract Quaternion GetOrientation(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetPosition2(IntPtr obj); +public abstract void SetTranslation(BulletBody obj, Vector3 position, Quaternion rotation); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Quaternion GetOrientation2(IntPtr obj); +public abstract IntPtr GetBroadphaseHandle(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetTranslation2(IntPtr obj, Vector3 position, Quaternion rotation); +public abstract void SetBroadphaseHandle(BulletBody obj, IntPtr handle); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr GetBroadphaseHandle2(IntPtr obj); +public abstract void SetInterpolationLinearVelocity(BulletBody obj, Vector3 vel); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetBroadphaseHandle2(IntPtr obj, IntPtr handle); +public abstract void SetInterpolationAngularVelocity(BulletBody obj, Vector3 vel); - /* -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Transform GetInterpolationWorldTransform2(IntPtr obj); +public abstract void SetInterpolationVelocity(BulletBody obj, Vector3 linearVel, Vector3 angularVel); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetInterpolationWorldTransform2(IntPtr obj, Transform trans); - */ - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetInterpolationLinearVelocity2(IntPtr obj, Vector3 vel); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetInterpolationAngularVelocity2(IntPtr obj, Vector3 vel); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetInterpolationVelocity2(IntPtr obj, Vector3 linearVel, Vector3 angularVel); +public abstract float GetHitFraction(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetHitFraction2(IntPtr obj); +public abstract void SetHitFraction(BulletBody obj, float val); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetHitFraction2(IntPtr obj, float val); +public abstract CollisionFlags GetCollisionFlags(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern CollisionFlags GetCollisionFlags2(IntPtr obj); +public abstract CollisionFlags SetCollisionFlags(BulletBody obj, CollisionFlags flags); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern CollisionFlags SetCollisionFlags2(IntPtr obj, CollisionFlags flags); +public abstract CollisionFlags AddToCollisionFlags(BulletBody obj, CollisionFlags flags); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern CollisionFlags AddToCollisionFlags2(IntPtr obj, CollisionFlags flags); +public abstract CollisionFlags RemoveFromCollisionFlags(BulletBody obj, CollisionFlags flags); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern CollisionFlags RemoveFromCollisionFlags2(IntPtr obj, CollisionFlags flags); +public abstract float GetCcdMotionThreshold(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetCcdMotionThreshold2(IntPtr obj); +public abstract void SetCcdMotionThreshold(BulletBody obj, float val); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetCcdMotionThreshold2(IntPtr obj, float val); +public abstract float GetCcdSweptSphereRadius(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetCcdSweptSphereRadius2(IntPtr obj); +public abstract void SetCcdSweptSphereRadius(BulletBody obj, float val); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetCcdSweptSphereRadius2(IntPtr obj, float val); +public abstract IntPtr GetUserPointer(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr GetUserPointer2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetUserPointer2(IntPtr obj, IntPtr val); +public abstract void SetUserPointer(BulletBody obj, IntPtr val); // ===================================================================================== // btRigidBody entries -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void ApplyGravity2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetGravity2(IntPtr obj, Vector3 val); +public abstract void ApplyGravity(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetGravity2(IntPtr obj); +public abstract void SetGravity(BulletBody obj, Vector3 val); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetDamping2(IntPtr obj, float lin_damping, float ang_damping); +public abstract Vector3 GetGravity(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetLinearDamping2(IntPtr obj, float lin_damping); +public abstract void SetDamping(BulletBody obj, float lin_damping, float ang_damping); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetAngularDamping2(IntPtr obj, float ang_damping); +public abstract void SetLinearDamping(BulletBody obj, float lin_damping); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetLinearDamping2(IntPtr obj); +public abstract void SetAngularDamping(BulletBody obj, float ang_damping); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetAngularDamping2(IntPtr obj); +public abstract float GetLinearDamping(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetLinearSleepingThreshold2(IntPtr obj); +public abstract float GetAngularDamping(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetAngularSleepingThreshold2(IntPtr obj); +public abstract float GetLinearSleepingThreshold(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void ApplyDamping2(IntPtr obj, float timeStep); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetMassProps2(IntPtr obj, float mass, Vector3 inertia); +public abstract void ApplyDamping(BulletBody obj, float timeStep); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetLinearFactor2(IntPtr obj); +public abstract void SetMassProps(BulletBody obj, float mass, Vector3 inertia); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetLinearFactor2(IntPtr obj, Vector3 factor); +public abstract Vector3 GetLinearFactor(BulletBody obj); - /* -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetCenterOfMassTransform2(IntPtr obj, Transform trans); - */ +public abstract void SetLinearFactor(BulletBody obj, Vector3 factor); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetCenterOfMassByPosRot2(IntPtr obj, Vector3 pos, Quaternion rot); +public abstract void SetCenterOfMassByPosRot(BulletBody obj, Vector3 pos, Quaternion rot); // Add a force to the object as if its mass is one. -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void ApplyCentralForce2(IntPtr obj, Vector3 force); +public abstract void ApplyCentralForce(BulletBody obj, Vector3 force); // Set the force being applied to the object as if its mass is one. -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetObjectForce2(IntPtr obj, Vector3 force); +public abstract void SetObjectForce(BulletBody obj, Vector3 force); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetTotalForce2(IntPtr obj); +public abstract Vector3 GetTotalForce(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetTotalTorque2(IntPtr obj); +public abstract Vector3 GetTotalTorque(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetInvInertiaDiagLocal2(IntPtr obj); +public abstract Vector3 GetInvInertiaDiagLocal(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetInvInertiaDiagLocal2(IntPtr obj, Vector3 inert); +public abstract void SetInvInertiaDiagLocal(BulletBody obj, Vector3 inert); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetSleepingThresholds2(IntPtr obj, float lin_threshold, float ang_threshold); +public abstract void SetSleepingThresholds(BulletBody obj, float lin_threshold, float ang_threshold); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void ApplyTorque2(IntPtr obj, Vector3 torque); +public abstract void ApplyTorque(BulletBody obj, Vector3 torque); // Apply force at the given point. Will add torque to the object. -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void ApplyForce2(IntPtr obj, Vector3 force, Vector3 pos); +public abstract void ApplyForce(BulletBody obj, Vector3 force, Vector3 pos); // Apply impulse to the object. Same as "ApplycentralForce" but force scaled by object's mass. -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void ApplyCentralImpulse2(IntPtr obj, Vector3 imp); +public abstract void ApplyCentralImpulse(BulletBody obj, Vector3 imp); // Apply impulse to the object's torque. Force is scaled by object's mass. -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void ApplyTorqueImpulse2(IntPtr obj, Vector3 imp); +public abstract void ApplyTorqueImpulse(BulletBody obj, Vector3 imp); // Apply impulse at the point given. For is scaled by object's mass and effects both linear and angular forces. -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void ApplyImpulse2(IntPtr obj, Vector3 imp, Vector3 pos); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void ClearForces2(IntPtr obj); +public abstract void ApplyImpulse(BulletBody obj, Vector3 imp, Vector3 pos); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void ClearAllForces2(IntPtr obj); +public abstract void ClearForces(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void UpdateInertiaTensor2(IntPtr obj); +public abstract void ClearAllForces(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetCenterOfMassPosition2(IntPtr obj); - - /* -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Transform GetCenterOfMassTransform2(IntPtr obj); - */ +public abstract void UpdateInertiaTensor(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetLinearVelocity2(IntPtr obj); +public abstract Vector3 GetLinearVelocity(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetAngularVelocity2(IntPtr obj); +public abstract Vector3 GetAngularVelocity(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetLinearVelocity2(IntPtr obj, Vector3 val); +public abstract void SetLinearVelocity(BulletBody obj, Vector3 val); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetAngularVelocity2(IntPtr obj, Vector3 angularVelocity); +public abstract void SetAngularVelocity(BulletBody obj, Vector3 angularVelocity); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetVelocityInLocalPoint2(IntPtr obj, Vector3 pos); +public abstract Vector3 GetVelocityInLocalPoint(BulletBody obj, Vector3 pos); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void Translate2(IntPtr obj, Vector3 trans); +public abstract void Translate(BulletBody obj, Vector3 trans); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void UpdateDeactivation2(IntPtr obj, float timeStep); +public abstract void UpdateDeactivation(BulletBody obj, float timeStep); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool WantsSleeping2(IntPtr obj); +public abstract bool WantsSleeping(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetAngularFactor2(IntPtr obj, float factor); +public abstract void SetAngularFactor(BulletBody obj, float factor); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetAngularFactorV2(IntPtr obj, Vector3 factor); +public abstract void SetAngularFactorV(BulletBody obj, Vector3 factor); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetAngularFactor2(IntPtr obj); +public abstract Vector3 GetAngularFactor(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsInWorld2(IntPtr obj); +public abstract bool IsInWorld(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void AddConstraintRef2(IntPtr obj, IntPtr constrain); +public abstract void AddConstraintRef(BulletBody obj, BulletConstraint constrain); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void RemoveConstraintRef2(IntPtr obj, IntPtr constrain); +public abstract void RemoveConstraintRef(BulletBody obj, BulletConstraint constrain); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr GetConstraintRef2(IntPtr obj, int index); +public abstract BulletConstraint GetConstraintRef(BulletBody obj, int index); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern int GetNumConstraintRefs2(IntPtr obj); +public abstract int GetNumConstraintRefs(BulletBody obj); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool SetCollisionGroupMask2(IntPtr body, uint filter, uint mask); +public abstract bool SetCollisionGroupMask(BulletBody body, uint filter, uint mask); // ===================================================================================== // btCollisionShape entries -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetAngularMotionDisc2(IntPtr shape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetContactBreakingThreshold2(IntPtr shape, float defaultFactor); +public abstract float GetAngularMotionDisc(BulletShape shape); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsPolyhedral2(IntPtr shape); +public abstract float GetContactBreakingThreshold(BulletShape shape, float defaultFactor); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsConvex2d2(IntPtr shape); +public abstract bool IsPolyhedral(BulletShape shape); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsConvex2(IntPtr shape); +public abstract bool IsConvex2d(BulletShape shape); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsNonMoving2(IntPtr shape); +public abstract bool IsConvex(BulletShape shape); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsConcave2(IntPtr shape); +public abstract bool IsNonMoving(BulletShape shape); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsCompound2(IntPtr shape); +public abstract bool IsConcave(BulletShape shape); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsSoftBody2(IntPtr shape); +public abstract bool IsCompound(BulletShape shape); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsInfinite2(IntPtr shape); +public abstract bool IsSoftBody(BulletShape shape); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetLocalScaling2(IntPtr shape, Vector3 scale); +public abstract bool IsInfinite(BulletShape shape); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetLocalScaling2(IntPtr shape); +public abstract void SetLocalScaling(BulletShape shape, Vector3 scale); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 CalculateLocalInertia2(IntPtr shape, float mass); +public abstract Vector3 GetLocalScaling(BulletShape shape); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern int GetShapeType2(IntPtr shape); +public abstract Vector3 CalculateLocalInertia(BulletShape shape, float mass); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetMargin2(IntPtr shape, float val); +public abstract int GetShapeType(BulletShape shape); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetMargin2(IntPtr shape); - -// ===================================================================================== -// Debugging -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void DumpRigidBody2(IntPtr sim, IntPtr collisionObject); +public abstract void SetMargin(BulletShape shape, float val); -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void DumpCollisionShape2(IntPtr sim, IntPtr collisionShape); +public abstract float GetMargin(BulletShape shape); + */ -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void DumpMapInfo2(IntPtr sim, IntPtr manInfo); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void DumpConstraint2(IntPtr sim, IntPtr constrain); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void DumpActivationInfo2(IntPtr sim); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void DumpAllInfo2(IntPtr sim); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void DumpPhysicsStatistics2(IntPtr sim); - -} +}; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 8ec9871..4cb8e6d 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -31,6 +31,7 @@ CRASHES VEHICLES TODO LIST: ================================================= +Angular motor direction is global coordinates rather than local coordinates Border crossing with linked vehicle causes crash Vehicles (Move smoothly) Add vehicle collisions so IsColliding is properly reported. @@ -78,7 +79,7 @@ Small physical objects do not interact correctly Create chain of .5x.5x.1 torui and make all but top physical so to hang. The chain will fall apart and pairs will dance around on ground Chains of 1x1x.2 will stay connected but will dance. - Chains above 2x2x.4 are move stable and get stablier as torui get larger. + Chains above 2x2x.4 are more stable and get stablier as torui get larger. Add PID motor for avatar movement (slow to stop, ...) setForce should set a constant force. Different than AddImpulse. Implement raycast. @@ -100,9 +101,13 @@ More efficient memory usage when passing hull information from BSPrim to BulletS Avatar movement motor check for zero or small movement. Somehow suppress small movements when avatar has stopped and is just standing. Simple test for near zero has the problem of preventing starting up (increase from zero) especially when falling. +Physical and phantom will drop through the terrain + LINKSETS ====================================================== +Offset the center of the linkset to be the geometric center of all the prims + Not quite the same as the center-of-gravity Linksets should allow collisions to individual children Add LocalID to children shapes in LinksetCompound and create events for individuals LinksetCompound: when one of the children changes orientation (like tires -- cgit v1.1 From 9fd0e1b0805ccc97b8e4f19727d98b26fb5fa89d Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 29 Dec 2012 21:44:13 -0800 Subject: BulletSim: add the implementation files for the two versions of Bullet: unmanaged (C++) and managed (C#). --- OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | 1107 ++++++++++++++++++++ OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs | 39 + 2 files changed, 1146 insertions(+) create mode 100755 OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs create mode 100755 OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs new file mode 100755 index 0000000..bbfc1f8 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs @@ -0,0 +1,1107 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; + +using OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ +public sealed class BSAPIUnman : BulletSimAPITemplate +{ + /* +// Initialization and simulation +public BulletWorld Initialize(Vector3 maxPosition, IntPtr parms, + int maxCollisions, IntPtr collisionArray, + int maxUpdates, IntPtr updateArray + ); + +public bool UpdateParameter(BulletWorld world, uint localID, String parm, float value); + +public void SetHeightMap(BulletWorld world, float[] heightmap); + +public void Shutdown(BulletWorld sim); + +public int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, + out int updatedEntityCount, + out IntPtr updatedEntitiesPtr, + out int collidersCount, + out IntPtr collidersPtr); + +public bool PushUpdate(BulletBody obj); + */ + +// ===================================================================================== +// Mesh, hull, shape and body creation helper routines +public override BulletShape CreateMeshShape(BulletWorld world, + int indicesCount, int[] indices, + int verticesCount, float[] vertices) +{ + return new BulletShape( + BSAPI.CreateMeshShape2(world.ptr, indicesCount, indices, verticesCount, vertices), + BSPhysicsShapeType.SHAPE_MESH); +} + +public override BulletShape CreateHullShape(BulletWorld world, int hullCount, float[] hulls) +{ + return new BulletShape( + BSAPI.CreateHullShape2(world.ptr, hullCount, hulls), + BSPhysicsShapeType.SHAPE_HULL); +} + +public override BulletShape BuildHullShapeFromMesh(BulletWorld world, BulletShape meshShape) +{ + return new BulletShape( + BSAPI.BuildHullShapeFromMesh2(world.ptr, meshShape.ptr), + BSPhysicsShapeType.SHAPE_HULL); +} + +public override BulletShape BuildNativeShape( BulletWorld world, ShapeData shapeData) +{ + return new BulletShape( + BSAPI.BuildNativeShape2(world.ptr, shapeData), + shapeData.Type); +} + +public override bool IsNativeShape(BulletShape shape) +{ + if (shape.HasPhysicalShape) + return BSAPI.IsNativeShape2(shape.ptr); + return false; +} + +public override void SetShapeCollisionMargin(BulletShape shape, float margin) +{ + if (shape.HasPhysicalShape) + BSAPI.SetShapeCollisionMargin2(shape.ptr, margin); +} + +public override BulletShape BuildCapsuleShape(BulletWorld world, float radius, float height, Vector3 scale) +{ + return new BulletShape( + BSAPI.BuildCapsuleShape2(world.ptr, radius, height, scale), + BSPhysicsShapeType.SHAPE_CAPSULE); +} + +public override BulletShape CreateCompoundShape(BulletWorld sim, bool enableDynamicAabbTree) +{ + return new BulletShape( + BSAPI.CreateCompoundShape2(sim.ptr, enableDynamicAabbTree), + BSPhysicsShapeType.SHAPE_COMPOUND); + +} + +public override int GetNumberOfCompoundChildren(BulletShape shape) +{ + if (shape.HasPhysicalShape) + return BSAPI.GetNumberOfCompoundChildren2(shape.ptr); + return 0; +} + +public override void AddChildShapeToCompoundShape(BulletShape cShape, BulletShape addShape, Vector3 pos, Quaternion rot) +{ + BSAPI.AddChildShapeToCompoundShape2(cShape.ptr, addShape.ptr, pos, rot); +} + +public override BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) +{ + return new BulletShape(BSAPI.GetChildShapeFromCompoundShapeIndex2(cShape.ptr, indx)); +} + +public override BulletShape RemoveChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) +{ + return new BulletShape(BSAPI.RemoveChildShapeFromCompoundShapeIndex2(cShape.ptr, indx)); +} + +public override void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape) +{ + BSAPI.RemoveChildShapeFromCompoundShape2(cShape.ptr, removeShape.ptr); +} + +public override void RecalculateCompoundShapeLocalAabb(BulletShape cShape) +{ + BSAPI.RecalculateCompoundShapeLocalAabb2(cShape.ptr); +} + +public override BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id) +{ + return new BulletShape(BSAPI.DuplicateCollisionShape2(sim.ptr, srcShape.ptr, id), srcShape.type); +} + +public override BulletBody CreateBodyFromShapeAndInfo(BulletWorld sim, BulletShape shape, uint id, IntPtr constructionInfo) +{ + return new BulletBody(id, BSAPI.CreateBodyFromShapeAndInfo2(sim.ptr, shape.ptr, id, constructionInfo)); +} + +public override bool DeleteCollisionShape(BulletWorld world, BulletShape shape) +{ + return BSAPI.DeleteCollisionShape2(world.ptr, shape.ptr); +} + +public override int GetBodyType(BulletBody obj) +{ + return BSAPI.GetBodyType2(obj.ptr); +} + +public override BulletBody CreateBodyFromShape(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot) +{ + return new BulletBody(id, BSAPI.CreateBodyFromShape2(sim.ptr, shape.ptr, id, pos, rot)); +} + +public override BulletBody CreateBodyWithDefaultMotionState(BulletShape shape, uint id, Vector3 pos, Quaternion rot) +{ + return new BulletBody(id, BSAPI.CreateBodyWithDefaultMotionState2(shape.ptr, id, pos, rot)); +} + +public override BulletBody CreateGhostFromShape(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot) +{ + return new BulletBody(id, BSAPI.CreateGhostFromShape2(sim.ptr, shape.ptr, id, pos, rot)); +} + +public override IntPtr AllocateBodyInfo(BulletBody obj) +{ + return BSAPI.AllocateBodyInfo2(obj.ptr); +} + +public override void ReleaseBodyInfo(IntPtr obj) +{ + BSAPI.ReleaseBodyInfo2(obj); +} + +public override void DestroyObject(BulletWorld sim, BulletBody obj) +{ + BSAPI.DestroyObject2(sim.ptr, obj.ptr); +} + + /* +// ===================================================================================== +// Terrain creation and helper routines +public override IntPtr CreateHeightMapInfo(BulletWorld sim, uint id, Vector3 minCoords, Vector3 maxCoords, + [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin); + +public override IntPtr FillHeightMapInfo(BulletWorld sim, IntPtr mapInfo, uint id, Vector3 minCoords, Vector3 maxCoords, + [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin); + +public override bool ReleaseHeightMapInfo(IntPtr heightMapInfo); + +public override BulletBody CreateGroundPlaneShape(uint id, float height, float collisionMargin); + +public override BulletBody CreateTerrainShape(IntPtr mapInfo); + +// ===================================================================================== +// Constraint creation and helper routines +public override BulletConstraint Create6DofConstraint(BulletWorld world, BulletBody obj1, BulletBody obj2, + Vector3 frame1loc, Quaternion frame1rot, + Vector3 frame2loc, Quaternion frame2rot, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); + +public override BulletConstraint Create6DofConstraintToPoint(BulletWorld world, BulletBody obj1, BulletBody obj2, + Vector3 joinPoint, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); + +public override BulletConstraint CreateHingeConstraint(BulletWorld world, BulletBody obj1, BulletBody obj2, + Vector3 pivotinA, Vector3 pivotinB, + Vector3 axisInA, Vector3 axisInB, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); + +public override void SetConstraintEnable(BulletConstraint constrain, float numericTrueFalse); + +public override void SetConstraintNumSolverIterations(BulletConstraint constrain, float iterations); + +public override bool SetFrames(BulletConstraint constrain, + Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot); + +public override bool SetLinearLimits(BulletConstraint constrain, Vector3 low, Vector3 hi); + +public override bool SetAngularLimits(BulletConstraint constrain, Vector3 low, Vector3 hi); + +public override bool UseFrameOffset(BulletConstraint constrain, float enable); + +public override bool TranslationalLimitMotor(BulletConstraint constrain, float enable, float targetVel, float maxMotorForce); + +public override bool SetBreakingImpulseThreshold(BulletConstraint constrain, float threshold); + +public override bool CalculateTransforms(BulletConstraint constrain); + +public override bool SetConstraintParam(BulletConstraint constrain, ConstraintParams paramIndex, float value, ConstraintParamAxis axis); + +public override bool DestroyConstraint(BulletWorld world, BulletConstraint constrain); + +// ===================================================================================== +// btCollisionWorld entries +public override void UpdateSingleAabb(BulletWorld world, BulletBody obj); + +public override void UpdateAabbs(BulletWorld world); + +public override bool GetForceUpdateAllAabbs(BulletWorld world); + +public override void SetForceUpdateAllAabbs(BulletWorld world, bool force); + +// ===================================================================================== +// btDynamicsWorld entries +public override bool AddObjectToWorld(BulletWorld world, BulletBody obj); + +public override bool RemoveObjectFromWorld(BulletWorld world, BulletBody obj); + +public override bool AddConstraintToWorld(BulletWorld world, BulletConstraint constrain, bool disableCollisionsBetweenLinkedObjects); + +public override bool RemoveConstraintFromWorld(BulletWorld world, BulletConstraint constrain); +// ===================================================================================== +// btCollisionObject entries +public override Vector3 GetAnisotripicFriction(BulletConstraint constrain); + +public override Vector3 SetAnisotripicFriction(BulletConstraint constrain, Vector3 frict); + +public override bool HasAnisotripicFriction(BulletConstraint constrain); + +public override void SetContactProcessingThreshold(BulletBody obj, float val); + +public override float GetContactProcessingThreshold(BulletBody obj); + +public override bool IsStaticObject(BulletBody obj); + +public override bool IsKinematicObject(BulletBody obj); + +public override bool IsStaticOrKinematicObject(BulletBody obj); + +public override bool HasContactResponse(BulletBody obj); + +public override void SetCollisionShape(BulletWorld sim, BulletBody obj, BulletBody shape); + +public override BulletShape GetCollisionShape(BulletBody obj); + +public override int GetActivationState(BulletBody obj); + +public override void SetActivationState(BulletBody obj, int state); + +public override void SetDeactivationTime(BulletBody obj, float dtime); + +public override float GetDeactivationTime(BulletBody obj); + +public override void ForceActivationState(BulletBody obj, ActivationState state); + +public override void Activate(BulletBody obj, bool forceActivation); + +public override bool IsActive(BulletBody obj); + +public override void SetRestitution(BulletBody obj, float val); + +public override float GetRestitution(BulletBody obj); + +public override void SetFriction(BulletBody obj, float val); + +public override float GetFriction(BulletBody obj); + +public override Vector3 GetPosition(BulletBody obj); + +public override Quaternion GetOrientation(BulletBody obj); + +public override void SetTranslation(BulletBody obj, Vector3 position, Quaternion rotation); + +public override IntPtr GetBroadphaseHandle(BulletBody obj); + +public override void SetBroadphaseHandle(BulletBody obj, IntPtr handle); + +public override void SetInterpolationLinearVelocity(BulletBody obj, Vector3 vel); + +public override void SetInterpolationAngularVelocity(BulletBody obj, Vector3 vel); + +public override void SetInterpolationVelocity(BulletBody obj, Vector3 linearVel, Vector3 angularVel); + +public override float GetHitFraction(BulletBody obj); + +public override void SetHitFraction(BulletBody obj, float val); + +public override CollisionFlags GetCollisionFlags(BulletBody obj); + +public override CollisionFlags SetCollisionFlags(BulletBody obj, CollisionFlags flags); + +public override CollisionFlags AddToCollisionFlags(BulletBody obj, CollisionFlags flags); + +public override CollisionFlags RemoveFromCollisionFlags(BulletBody obj, CollisionFlags flags); + +public override float GetCcdMotionThreshold(BulletBody obj); + +public override void SetCcdMotionThreshold(BulletBody obj, float val); + +public override float GetCcdSweptSphereRadius(BulletBody obj); + +public override void SetCcdSweptSphereRadius(BulletBody obj, float val); + +public override IntPtr GetUserPointer(BulletBody obj); + +public override void SetUserPointer(BulletBody obj, IntPtr val); + +// ===================================================================================== +// btRigidBody entries +public override void ApplyGravity(BulletBody obj); + +public override void SetGravity(BulletBody obj, Vector3 val); + +public override Vector3 GetGravity(BulletBody obj); + +public override void SetDamping(BulletBody obj, float lin_damping, float ang_damping); + +public override void SetLinearDamping(BulletBody obj, float lin_damping); + +public override void SetAngularDamping(BulletBody obj, float ang_damping); + +public override float GetLinearDamping(BulletBody obj); + +public override float GetAngularDamping(BulletBody obj); + +public override float GetLinearSleepingThreshold(BulletBody obj); + + +public override void ApplyDamping(BulletBody obj, float timeStep); + +public override void SetMassProps(BulletBody obj, float mass, Vector3 inertia); + +public override Vector3 GetLinearFactor(BulletBody obj); + +public override void SetLinearFactor(BulletBody obj, Vector3 factor); + +public override void SetCenterOfMassByPosRot(BulletBody obj, Vector3 pos, Quaternion rot); + +// Add a force to the object as if its mass is one. +public override void ApplyCentralForce(BulletBody obj, Vector3 force); + +// Set the force being applied to the object as if its mass is one. +public override void SetObjectForce(BulletBody obj, Vector3 force); + +public override Vector3 GetTotalForce(BulletBody obj); + +public override Vector3 GetTotalTorque(BulletBody obj); + +public override Vector3 GetInvInertiaDiagLocal(BulletBody obj); + +public override void SetInvInertiaDiagLocal(BulletBody obj, Vector3 inert); + +public override void SetSleepingThresholds(BulletBody obj, float lin_threshold, float ang_threshold); + +public override void ApplyTorque(BulletBody obj, Vector3 torque); + +// Apply force at the given point. Will add torque to the object. +public override void ApplyForce(BulletBody obj, Vector3 force, Vector3 pos); + +// Apply impulse to the object. Same as "ApplycentralForce" but force scaled by object's mass. +public override void ApplyCentralImpulse(BulletBody obj, Vector3 imp); + +// Apply impulse to the object's torque. Force is scaled by object's mass. +public override void ApplyTorqueImpulse(BulletBody obj, Vector3 imp); + +// Apply impulse at the point given. For is scaled by object's mass and effects both linear and angular forces. +public override void ApplyImpulse(BulletBody obj, Vector3 imp, Vector3 pos); + +public override void ClearForces(BulletBody obj); + +public override void ClearAllForces(BulletBody obj); + +public override void UpdateInertiaTensor(BulletBody obj); + +public override Vector3 GetLinearVelocity(BulletBody obj); + +public override Vector3 GetAngularVelocity(BulletBody obj); + +public override void SetLinearVelocity(BulletBody obj, Vector3 val); + +public override void SetAngularVelocity(BulletBody obj, Vector3 angularVelocity); + +public override Vector3 GetVelocityInLocalPoint(BulletBody obj, Vector3 pos); + +public override void Translate(BulletBody obj, Vector3 trans); + +public override void UpdateDeactivation(BulletBody obj, float timeStep); + +public override bool WantsSleeping(BulletBody obj); + +public override void SetAngularFactor(BulletBody obj, float factor); + +public override void SetAngularFactorV(BulletBody obj, Vector3 factor); + +public override Vector3 GetAngularFactor(BulletBody obj); + +public override bool IsInWorld(BulletBody obj); + +public override void AddConstraintRef(BulletBody obj, BulletConstraint constrain); + +public override void RemoveConstraintRef(BulletBody obj, BulletConstraint constrain); + +public override BulletConstraint GetConstraintRef(BulletBody obj, int index); + +public override int GetNumConstraintRefs(BulletBody obj); + +public override bool SetCollisionGroupMask(BulletBody body, uint filter, uint mask); + +// ===================================================================================== +// btCollisionShape entries + +public override float GetAngularMotionDisc(BulletShape shape); + +public override float GetContactBreakingThreshold(BulletShape shape, float defaultFactor); + +public override bool IsPolyhedral(BulletShape shape); + +public override bool IsConvex2d(BulletShape shape); + +public override bool IsConvex(BulletShape shape); + +public override bool IsNonMoving(BulletShape shape); + +public override bool IsConcave(BulletShape shape); + +public override bool IsCompound(BulletShape shape); + +public override bool IsSoftBody(BulletShape shape); + +public override bool IsInfinite(BulletShape shape); + +public override void SetLocalScaling(BulletShape shape, Vector3 scale); + +public override Vector3 GetLocalScaling(BulletShape shape); + +public override Vector3 CalculateLocalInertia(BulletShape shape, float mass); + +public override int GetShapeType(BulletShape shape); + +public override void SetMargin(BulletShape shape, float val); + +public override float GetMargin(BulletShape shape); + */ + +static class BSAPI +{ +// ===================================================================================== +// Mesh, hull, shape and body creation helper routines +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateMeshShape2(IntPtr world, + int indicesCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices, + int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices ); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateHullShape2(IntPtr world, + int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr BuildHullShapeFromMesh2(IntPtr world, IntPtr meshShape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr BuildNativeShape2(IntPtr world, ShapeData shapeData); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsNativeShape2(IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetShapeCollisionMargin2(IntPtr shape, float margin); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr BuildCapsuleShape2(IntPtr world, float radius, float height, Vector3 scale); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateCompoundShape2(IntPtr sim, bool enableDynamicAabbTree); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern int GetNumberOfCompoundChildren2(IntPtr cShape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void AddChildShapeToCompoundShape2(IntPtr cShape, IntPtr addShape, Vector3 pos, Quaternion rot); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr GetChildShapeFromCompoundShapeIndex2(IntPtr cShape, int indx); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr RemoveChildShapeFromCompoundShapeIndex2(IntPtr cShape, int indx); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void RemoveChildShapeFromCompoundShape2(IntPtr cShape, IntPtr removeShape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void RecalculateCompoundShapeLocalAabb2(IntPtr cShape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr DuplicateCollisionShape2(IntPtr sim, IntPtr srcShape, uint id); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateBodyFromShapeAndInfo2(IntPtr sim, IntPtr shape, uint id, IntPtr constructionInfo); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool DeleteCollisionShape2(IntPtr world, IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern int GetBodyType2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateBodyFromShape2(IntPtr sim, IntPtr shape, uint id, Vector3 pos, Quaternion rot); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateBodyWithDefaultMotionState2(IntPtr shape, uint id, Vector3 pos, Quaternion rot); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateGhostFromShape2(IntPtr sim, IntPtr shape, uint id, Vector3 pos, Quaternion rot); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr AllocateBodyInfo2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ReleaseBodyInfo2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void DestroyObject2(IntPtr sim, IntPtr obj); + +} +} + +// =============================================================================== +// =============================================================================== +// =============================================================================== +// =============================================================================== +// =============================================================================== +// =============================================================================== +// =============================================================================== +// =============================================================================== +// =============================================================================== +// =============================================================================== +// =============================================================================== +// =============================================================================== +// =============================================================================== +static class BulletSimAPI { +// =============================================================================== +// Link back to the managed code for outputting log messages +[UnmanagedFunctionPointer(CallingConvention.Cdecl)] +public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg); + +// =============================================================================== +// Initialization and simulation +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms, + int maxCollisions, IntPtr collisionArray, + int maxUpdates, IntPtr updateArray, + DebugLogCallback logRoutine); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool UpdateParameter2(IntPtr world, uint localID, String parm, float value); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetHeightMap2(IntPtr world, float[] heightmap); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void Shutdown2(IntPtr sim); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern int PhysicsStep2(IntPtr world, float timeStep, int maxSubSteps, float fixedTimeStep, + out int updatedEntityCount, + out IntPtr updatedEntitiesPtr, + out int collidersCount, + out IntPtr collidersPtr); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool PushUpdate2(IntPtr obj); + +// ===================================================================================== +// Terrain creation and helper routines +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateHeightMapInfo2(IntPtr sim, uint id, Vector3 minCoords, Vector3 maxCoords, + [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr FillHeightMapInfo2(IntPtr sim, IntPtr mapInfo, uint id, Vector3 minCoords, Vector3 maxCoords, + [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool ReleaseHeightMapInfo2(IntPtr heightMapInfo); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateGroundPlaneShape2(uint id, float height, float collisionMargin); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateTerrainShape2(IntPtr mapInfo); + +// ===================================================================================== +// Constraint creation and helper routines +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr Create6DofConstraint2(IntPtr world, IntPtr obj1, IntPtr obj2, + Vector3 frame1loc, Quaternion frame1rot, + Vector3 frame2loc, Quaternion frame2rot, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr Create6DofConstraintToPoint2(IntPtr world, IntPtr obj1, IntPtr obj2, + Vector3 joinPoint, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateHingeConstraint2(IntPtr world, IntPtr obj1, IntPtr obj2, + Vector3 pivotinA, Vector3 pivotinB, + Vector3 axisInA, Vector3 axisInB, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetConstraintEnable2(IntPtr constrain, float numericTrueFalse); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetConstraintNumSolverIterations2(IntPtr constrain, float iterations); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool SetFrames2(IntPtr constrain, + Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool SetLinearLimits2(IntPtr constrain, Vector3 low, Vector3 hi); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool SetAngularLimits2(IntPtr constrain, Vector3 low, Vector3 hi); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool UseFrameOffset2(IntPtr constrain, float enable); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool TranslationalLimitMotor2(IntPtr constrain, float enable, float targetVel, float maxMotorForce); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool SetBreakingImpulseThreshold2(IntPtr constrain, float threshold); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool CalculateTransforms2(IntPtr constrain); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool SetConstraintParam2(IntPtr constrain, ConstraintParams paramIndex, float value, ConstraintParamAxis axis); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool DestroyConstraint2(IntPtr world, IntPtr constrain); + +// ===================================================================================== +// btCollisionWorld entries +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void UpdateSingleAabb2(IntPtr world, IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void UpdateAabbs2(IntPtr world); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool GetForceUpdateAllAabbs2(IntPtr world); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetForceUpdateAllAabbs2(IntPtr world, bool force); + +// ===================================================================================== +// btDynamicsWorld entries +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool AddObjectToWorld2(IntPtr world, IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool RemoveObjectFromWorld2(IntPtr world, IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool AddConstraintToWorld2(IntPtr world, IntPtr constrain, bool disableCollisionsBetweenLinkedObjects); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool RemoveConstraintFromWorld2(IntPtr world, IntPtr constrain); +// ===================================================================================== +// btCollisionObject entries +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetAnisotripicFriction2(IntPtr constrain); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 SetAnisotripicFriction2(IntPtr constrain, Vector3 frict); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool HasAnisotripicFriction2(IntPtr constrain); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetContactProcessingThreshold2(IntPtr obj, float val); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetContactProcessingThreshold2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsStaticObject2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsKinematicObject2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsStaticOrKinematicObject2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool HasContactResponse2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetCollisionShape2(IntPtr sim, IntPtr obj, IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr GetCollisionShape2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern int GetActivationState2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetActivationState2(IntPtr obj, int state); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetDeactivationTime2(IntPtr obj, float dtime); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetDeactivationTime2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ForceActivationState2(IntPtr obj, ActivationState state); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void Activate2(IntPtr obj, bool forceActivation); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsActive2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetRestitution2(IntPtr obj, float val); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetRestitution2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetFriction2(IntPtr obj, float val); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetFriction2(IntPtr obj); + + /* Haven't defined the type 'Transform' +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Transform GetWorldTransform2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void setWorldTransform2(IntPtr obj, Transform trans); + */ + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetPosition2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Quaternion GetOrientation2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetTranslation2(IntPtr obj, Vector3 position, Quaternion rotation); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr GetBroadphaseHandle2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetBroadphaseHandle2(IntPtr obj, IntPtr handle); + + /* +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Transform GetInterpolationWorldTransform2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetInterpolationWorldTransform2(IntPtr obj, Transform trans); + */ + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetInterpolationLinearVelocity2(IntPtr obj, Vector3 vel); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetInterpolationAngularVelocity2(IntPtr obj, Vector3 vel); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetInterpolationVelocity2(IntPtr obj, Vector3 linearVel, Vector3 angularVel); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetHitFraction2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetHitFraction2(IntPtr obj, float val); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern CollisionFlags GetCollisionFlags2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern CollisionFlags SetCollisionFlags2(IntPtr obj, CollisionFlags flags); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern CollisionFlags AddToCollisionFlags2(IntPtr obj, CollisionFlags flags); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern CollisionFlags RemoveFromCollisionFlags2(IntPtr obj, CollisionFlags flags); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetCcdMotionThreshold2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetCcdMotionThreshold2(IntPtr obj, float val); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetCcdSweptSphereRadius2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetCcdSweptSphereRadius2(IntPtr obj, float val); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr GetUserPointer2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetUserPointer2(IntPtr obj, IntPtr val); + +// ===================================================================================== +// btRigidBody entries +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ApplyGravity2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetGravity2(IntPtr obj, Vector3 val); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetGravity2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetDamping2(IntPtr obj, float lin_damping, float ang_damping); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetLinearDamping2(IntPtr obj, float lin_damping); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetAngularDamping2(IntPtr obj, float ang_damping); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetLinearDamping2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetAngularDamping2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetLinearSleepingThreshold2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetAngularSleepingThreshold2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ApplyDamping2(IntPtr obj, float timeStep); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetMassProps2(IntPtr obj, float mass, Vector3 inertia); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetLinearFactor2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetLinearFactor2(IntPtr obj, Vector3 factor); + + /* +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetCenterOfMassTransform2(IntPtr obj, Transform trans); + */ + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetCenterOfMassByPosRot2(IntPtr obj, Vector3 pos, Quaternion rot); + +// Add a force to the object as if its mass is one. +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ApplyCentralForce2(IntPtr obj, Vector3 force); + +// Set the force being applied to the object as if its mass is one. +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetObjectForce2(IntPtr obj, Vector3 force); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetTotalForce2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetTotalTorque2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetInvInertiaDiagLocal2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetInvInertiaDiagLocal2(IntPtr obj, Vector3 inert); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetSleepingThresholds2(IntPtr obj, float lin_threshold, float ang_threshold); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ApplyTorque2(IntPtr obj, Vector3 torque); + +// Apply force at the given point. Will add torque to the object. +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ApplyForce2(IntPtr obj, Vector3 force, Vector3 pos); + +// Apply impulse to the object. Same as "ApplycentralForce" but force scaled by object's mass. +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ApplyCentralImpulse2(IntPtr obj, Vector3 imp); + +// Apply impulse to the object's torque. Force is scaled by object's mass. +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ApplyTorqueImpulse2(IntPtr obj, Vector3 imp); + +// Apply impulse at the point given. For is scaled by object's mass and effects both linear and angular forces. +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ApplyImpulse2(IntPtr obj, Vector3 imp, Vector3 pos); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ClearForces2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ClearAllForces2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void UpdateInertiaTensor2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetCenterOfMassPosition2(IntPtr obj); + + /* +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Transform GetCenterOfMassTransform2(IntPtr obj); + */ + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetLinearVelocity2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetAngularVelocity2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetLinearVelocity2(IntPtr obj, Vector3 val); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetAngularVelocity2(IntPtr obj, Vector3 angularVelocity); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetVelocityInLocalPoint2(IntPtr obj, Vector3 pos); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void Translate2(IntPtr obj, Vector3 trans); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void UpdateDeactivation2(IntPtr obj, float timeStep); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool WantsSleeping2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetAngularFactor2(IntPtr obj, float factor); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetAngularFactorV2(IntPtr obj, Vector3 factor); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetAngularFactor2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsInWorld2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void AddConstraintRef2(IntPtr obj, IntPtr constrain); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void RemoveConstraintRef2(IntPtr obj, IntPtr constrain); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr GetConstraintRef2(IntPtr obj, int index); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern int GetNumConstraintRefs2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool SetCollisionGroupMask2(IntPtr body, uint filter, uint mask); + +// ===================================================================================== +// btCollisionShape entries + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetAngularMotionDisc2(IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetContactBreakingThreshold2(IntPtr shape, float defaultFactor); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsPolyhedral2(IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsConvex2d2(IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsConvex2(IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsNonMoving2(IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsConcave2(IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsCompound2(IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsSoftBody2(IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsInfinite2(IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetLocalScaling2(IntPtr shape, Vector3 scale); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetLocalScaling2(IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 CalculateLocalInertia2(IntPtr shape, float mass); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern int GetShapeType2(IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetMargin2(IntPtr shape, float val); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetMargin2(IntPtr shape); + +// ===================================================================================== +// Debugging +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void DumpRigidBody2(IntPtr sim, IntPtr collisionObject); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void DumpCollisionShape2(IntPtr sim, IntPtr collisionShape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void DumpMapInfo2(IntPtr sim, IntPtr manInfo); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void DumpConstraint2(IntPtr sim, IntPtr constrain); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void DumpActivationInfo2(IntPtr sim); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void DumpAllInfo2(IntPtr sim); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void DumpPhysicsStatistics2(IntPtr sim); + +} +} diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs new file mode 100755 index 0000000..a56a817 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs @@ -0,0 +1,39 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ + /* +public sealed class BSAPIXNA : BulletSimAPITemplate +{ +} + */ +} -- cgit v1.1 From 9218748321519ed04da5cdffa1f29e69030171b5 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 30 Dec 2012 10:21:47 -0800 Subject: BulletSim: another round of conversion: dynamics world and collision object functions. --- OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | 2425 +++++++++++--------- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 46 +- .../Region/Physics/BulletSPlugin/BSConstraint.cs | 17 +- .../Physics/BulletSPlugin/BSConstraint6Dof.cs | 30 +- .../Physics/BulletSPlugin/BSConstraintHinge.cs | 10 +- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 10 +- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 12 +- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 8 +- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 4 +- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 74 +- .../Physics/BulletSPlugin/BSShapeCollection.cs | 6 +- .../Physics/BulletSPlugin/BSTerrainHeightmap.cs | 23 +- .../Physics/BulletSPlugin/BSTerrainManager.cs | 13 +- .../Region/Physics/BulletSPlugin/BSTerrainMesh.cs | 16 +- .../Region/Physics/BulletSPlugin/BulletSimAPI.cs | 8 +- 15 files changed, 1454 insertions(+), 1248 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs index bbfc1f8..9a8a2e8 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs @@ -1,1107 +1,1318 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Security; -using System.Text; - -using OpenMetaverse; - -namespace OpenSim.Region.Physics.BulletSPlugin -{ -public sealed class BSAPIUnman : BulletSimAPITemplate -{ - /* -// Initialization and simulation -public BulletWorld Initialize(Vector3 maxPosition, IntPtr parms, - int maxCollisions, IntPtr collisionArray, - int maxUpdates, IntPtr updateArray - ); - -public bool UpdateParameter(BulletWorld world, uint localID, String parm, float value); - -public void SetHeightMap(BulletWorld world, float[] heightmap); - -public void Shutdown(BulletWorld sim); - -public int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, - out int updatedEntityCount, - out IntPtr updatedEntitiesPtr, - out int collidersCount, - out IntPtr collidersPtr); - -public bool PushUpdate(BulletBody obj); - */ - -// ===================================================================================== -// Mesh, hull, shape and body creation helper routines -public override BulletShape CreateMeshShape(BulletWorld world, - int indicesCount, int[] indices, - int verticesCount, float[] vertices) -{ - return new BulletShape( - BSAPI.CreateMeshShape2(world.ptr, indicesCount, indices, verticesCount, vertices), - BSPhysicsShapeType.SHAPE_MESH); -} - -public override BulletShape CreateHullShape(BulletWorld world, int hullCount, float[] hulls) -{ - return new BulletShape( - BSAPI.CreateHullShape2(world.ptr, hullCount, hulls), - BSPhysicsShapeType.SHAPE_HULL); -} - -public override BulletShape BuildHullShapeFromMesh(BulletWorld world, BulletShape meshShape) -{ - return new BulletShape( - BSAPI.BuildHullShapeFromMesh2(world.ptr, meshShape.ptr), - BSPhysicsShapeType.SHAPE_HULL); -} - -public override BulletShape BuildNativeShape( BulletWorld world, ShapeData shapeData) -{ - return new BulletShape( - BSAPI.BuildNativeShape2(world.ptr, shapeData), - shapeData.Type); -} - -public override bool IsNativeShape(BulletShape shape) -{ - if (shape.HasPhysicalShape) - return BSAPI.IsNativeShape2(shape.ptr); - return false; -} - -public override void SetShapeCollisionMargin(BulletShape shape, float margin) -{ - if (shape.HasPhysicalShape) - BSAPI.SetShapeCollisionMargin2(shape.ptr, margin); -} - -public override BulletShape BuildCapsuleShape(BulletWorld world, float radius, float height, Vector3 scale) -{ - return new BulletShape( - BSAPI.BuildCapsuleShape2(world.ptr, radius, height, scale), - BSPhysicsShapeType.SHAPE_CAPSULE); -} - -public override BulletShape CreateCompoundShape(BulletWorld sim, bool enableDynamicAabbTree) -{ - return new BulletShape( - BSAPI.CreateCompoundShape2(sim.ptr, enableDynamicAabbTree), - BSPhysicsShapeType.SHAPE_COMPOUND); - -} - -public override int GetNumberOfCompoundChildren(BulletShape shape) -{ - if (shape.HasPhysicalShape) - return BSAPI.GetNumberOfCompoundChildren2(shape.ptr); - return 0; -} - -public override void AddChildShapeToCompoundShape(BulletShape cShape, BulletShape addShape, Vector3 pos, Quaternion rot) -{ - BSAPI.AddChildShapeToCompoundShape2(cShape.ptr, addShape.ptr, pos, rot); -} - -public override BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) -{ - return new BulletShape(BSAPI.GetChildShapeFromCompoundShapeIndex2(cShape.ptr, indx)); -} - -public override BulletShape RemoveChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) -{ - return new BulletShape(BSAPI.RemoveChildShapeFromCompoundShapeIndex2(cShape.ptr, indx)); -} - -public override void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape) -{ - BSAPI.RemoveChildShapeFromCompoundShape2(cShape.ptr, removeShape.ptr); -} - -public override void RecalculateCompoundShapeLocalAabb(BulletShape cShape) -{ - BSAPI.RecalculateCompoundShapeLocalAabb2(cShape.ptr); -} - -public override BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id) -{ - return new BulletShape(BSAPI.DuplicateCollisionShape2(sim.ptr, srcShape.ptr, id), srcShape.type); -} - -public override BulletBody CreateBodyFromShapeAndInfo(BulletWorld sim, BulletShape shape, uint id, IntPtr constructionInfo) -{ - return new BulletBody(id, BSAPI.CreateBodyFromShapeAndInfo2(sim.ptr, shape.ptr, id, constructionInfo)); -} - -public override bool DeleteCollisionShape(BulletWorld world, BulletShape shape) -{ - return BSAPI.DeleteCollisionShape2(world.ptr, shape.ptr); -} - -public override int GetBodyType(BulletBody obj) -{ - return BSAPI.GetBodyType2(obj.ptr); -} - -public override BulletBody CreateBodyFromShape(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot) -{ - return new BulletBody(id, BSAPI.CreateBodyFromShape2(sim.ptr, shape.ptr, id, pos, rot)); -} - -public override BulletBody CreateBodyWithDefaultMotionState(BulletShape shape, uint id, Vector3 pos, Quaternion rot) -{ - return new BulletBody(id, BSAPI.CreateBodyWithDefaultMotionState2(shape.ptr, id, pos, rot)); -} - -public override BulletBody CreateGhostFromShape(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot) -{ - return new BulletBody(id, BSAPI.CreateGhostFromShape2(sim.ptr, shape.ptr, id, pos, rot)); -} - -public override IntPtr AllocateBodyInfo(BulletBody obj) -{ - return BSAPI.AllocateBodyInfo2(obj.ptr); -} - -public override void ReleaseBodyInfo(IntPtr obj) -{ - BSAPI.ReleaseBodyInfo2(obj); -} - -public override void DestroyObject(BulletWorld sim, BulletBody obj) -{ - BSAPI.DestroyObject2(sim.ptr, obj.ptr); -} - - /* -// ===================================================================================== -// Terrain creation and helper routines -public override IntPtr CreateHeightMapInfo(BulletWorld sim, uint id, Vector3 minCoords, Vector3 maxCoords, - [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin); - -public override IntPtr FillHeightMapInfo(BulletWorld sim, IntPtr mapInfo, uint id, Vector3 minCoords, Vector3 maxCoords, - [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin); - -public override bool ReleaseHeightMapInfo(IntPtr heightMapInfo); - -public override BulletBody CreateGroundPlaneShape(uint id, float height, float collisionMargin); - -public override BulletBody CreateTerrainShape(IntPtr mapInfo); - -// ===================================================================================== -// Constraint creation and helper routines -public override BulletConstraint Create6DofConstraint(BulletWorld world, BulletBody obj1, BulletBody obj2, - Vector3 frame1loc, Quaternion frame1rot, - Vector3 frame2loc, Quaternion frame2rot, - bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); - -public override BulletConstraint Create6DofConstraintToPoint(BulletWorld world, BulletBody obj1, BulletBody obj2, - Vector3 joinPoint, - bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); - -public override BulletConstraint CreateHingeConstraint(BulletWorld world, BulletBody obj1, BulletBody obj2, - Vector3 pivotinA, Vector3 pivotinB, - Vector3 axisInA, Vector3 axisInB, - bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); - -public override void SetConstraintEnable(BulletConstraint constrain, float numericTrueFalse); - -public override void SetConstraintNumSolverIterations(BulletConstraint constrain, float iterations); - -public override bool SetFrames(BulletConstraint constrain, - Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot); - -public override bool SetLinearLimits(BulletConstraint constrain, Vector3 low, Vector3 hi); - -public override bool SetAngularLimits(BulletConstraint constrain, Vector3 low, Vector3 hi); - -public override bool UseFrameOffset(BulletConstraint constrain, float enable); - -public override bool TranslationalLimitMotor(BulletConstraint constrain, float enable, float targetVel, float maxMotorForce); - -public override bool SetBreakingImpulseThreshold(BulletConstraint constrain, float threshold); - -public override bool CalculateTransforms(BulletConstraint constrain); - -public override bool SetConstraintParam(BulletConstraint constrain, ConstraintParams paramIndex, float value, ConstraintParamAxis axis); - -public override bool DestroyConstraint(BulletWorld world, BulletConstraint constrain); - -// ===================================================================================== -// btCollisionWorld entries -public override void UpdateSingleAabb(BulletWorld world, BulletBody obj); - -public override void UpdateAabbs(BulletWorld world); - -public override bool GetForceUpdateAllAabbs(BulletWorld world); - -public override void SetForceUpdateAllAabbs(BulletWorld world, bool force); - -// ===================================================================================== -// btDynamicsWorld entries -public override bool AddObjectToWorld(BulletWorld world, BulletBody obj); - -public override bool RemoveObjectFromWorld(BulletWorld world, BulletBody obj); - -public override bool AddConstraintToWorld(BulletWorld world, BulletConstraint constrain, bool disableCollisionsBetweenLinkedObjects); - -public override bool RemoveConstraintFromWorld(BulletWorld world, BulletConstraint constrain); -// ===================================================================================== -// btCollisionObject entries -public override Vector3 GetAnisotripicFriction(BulletConstraint constrain); - -public override Vector3 SetAnisotripicFriction(BulletConstraint constrain, Vector3 frict); - -public override bool HasAnisotripicFriction(BulletConstraint constrain); - -public override void SetContactProcessingThreshold(BulletBody obj, float val); - -public override float GetContactProcessingThreshold(BulletBody obj); - -public override bool IsStaticObject(BulletBody obj); - -public override bool IsKinematicObject(BulletBody obj); - -public override bool IsStaticOrKinematicObject(BulletBody obj); - -public override bool HasContactResponse(BulletBody obj); - -public override void SetCollisionShape(BulletWorld sim, BulletBody obj, BulletBody shape); - -public override BulletShape GetCollisionShape(BulletBody obj); - -public override int GetActivationState(BulletBody obj); - -public override void SetActivationState(BulletBody obj, int state); - -public override void SetDeactivationTime(BulletBody obj, float dtime); - -public override float GetDeactivationTime(BulletBody obj); - -public override void ForceActivationState(BulletBody obj, ActivationState state); - -public override void Activate(BulletBody obj, bool forceActivation); - -public override bool IsActive(BulletBody obj); - -public override void SetRestitution(BulletBody obj, float val); - -public override float GetRestitution(BulletBody obj); - -public override void SetFriction(BulletBody obj, float val); - -public override float GetFriction(BulletBody obj); - -public override Vector3 GetPosition(BulletBody obj); - -public override Quaternion GetOrientation(BulletBody obj); - -public override void SetTranslation(BulletBody obj, Vector3 position, Quaternion rotation); - -public override IntPtr GetBroadphaseHandle(BulletBody obj); - -public override void SetBroadphaseHandle(BulletBody obj, IntPtr handle); - -public override void SetInterpolationLinearVelocity(BulletBody obj, Vector3 vel); - -public override void SetInterpolationAngularVelocity(BulletBody obj, Vector3 vel); - -public override void SetInterpolationVelocity(BulletBody obj, Vector3 linearVel, Vector3 angularVel); - -public override float GetHitFraction(BulletBody obj); - -public override void SetHitFraction(BulletBody obj, float val); - -public override CollisionFlags GetCollisionFlags(BulletBody obj); - -public override CollisionFlags SetCollisionFlags(BulletBody obj, CollisionFlags flags); - -public override CollisionFlags AddToCollisionFlags(BulletBody obj, CollisionFlags flags); - -public override CollisionFlags RemoveFromCollisionFlags(BulletBody obj, CollisionFlags flags); - -public override float GetCcdMotionThreshold(BulletBody obj); - -public override void SetCcdMotionThreshold(BulletBody obj, float val); - -public override float GetCcdSweptSphereRadius(BulletBody obj); - -public override void SetCcdSweptSphereRadius(BulletBody obj, float val); - -public override IntPtr GetUserPointer(BulletBody obj); - -public override void SetUserPointer(BulletBody obj, IntPtr val); - -// ===================================================================================== -// btRigidBody entries -public override void ApplyGravity(BulletBody obj); - -public override void SetGravity(BulletBody obj, Vector3 val); - -public override Vector3 GetGravity(BulletBody obj); - -public override void SetDamping(BulletBody obj, float lin_damping, float ang_damping); - -public override void SetLinearDamping(BulletBody obj, float lin_damping); - -public override void SetAngularDamping(BulletBody obj, float ang_damping); - -public override float GetLinearDamping(BulletBody obj); - -public override float GetAngularDamping(BulletBody obj); - -public override float GetLinearSleepingThreshold(BulletBody obj); - - -public override void ApplyDamping(BulletBody obj, float timeStep); - -public override void SetMassProps(BulletBody obj, float mass, Vector3 inertia); - -public override Vector3 GetLinearFactor(BulletBody obj); - -public override void SetLinearFactor(BulletBody obj, Vector3 factor); - -public override void SetCenterOfMassByPosRot(BulletBody obj, Vector3 pos, Quaternion rot); - -// Add a force to the object as if its mass is one. -public override void ApplyCentralForce(BulletBody obj, Vector3 force); - -// Set the force being applied to the object as if its mass is one. -public override void SetObjectForce(BulletBody obj, Vector3 force); - -public override Vector3 GetTotalForce(BulletBody obj); - -public override Vector3 GetTotalTorque(BulletBody obj); - -public override Vector3 GetInvInertiaDiagLocal(BulletBody obj); - -public override void SetInvInertiaDiagLocal(BulletBody obj, Vector3 inert); - -public override void SetSleepingThresholds(BulletBody obj, float lin_threshold, float ang_threshold); - -public override void ApplyTorque(BulletBody obj, Vector3 torque); - -// Apply force at the given point. Will add torque to the object. -public override void ApplyForce(BulletBody obj, Vector3 force, Vector3 pos); - -// Apply impulse to the object. Same as "ApplycentralForce" but force scaled by object's mass. -public override void ApplyCentralImpulse(BulletBody obj, Vector3 imp); - -// Apply impulse to the object's torque. Force is scaled by object's mass. -public override void ApplyTorqueImpulse(BulletBody obj, Vector3 imp); - -// Apply impulse at the point given. For is scaled by object's mass and effects both linear and angular forces. -public override void ApplyImpulse(BulletBody obj, Vector3 imp, Vector3 pos); - -public override void ClearForces(BulletBody obj); - -public override void ClearAllForces(BulletBody obj); - -public override void UpdateInertiaTensor(BulletBody obj); - -public override Vector3 GetLinearVelocity(BulletBody obj); - -public override Vector3 GetAngularVelocity(BulletBody obj); - -public override void SetLinearVelocity(BulletBody obj, Vector3 val); - -public override void SetAngularVelocity(BulletBody obj, Vector3 angularVelocity); - -public override Vector3 GetVelocityInLocalPoint(BulletBody obj, Vector3 pos); - -public override void Translate(BulletBody obj, Vector3 trans); - -public override void UpdateDeactivation(BulletBody obj, float timeStep); - -public override bool WantsSleeping(BulletBody obj); - -public override void SetAngularFactor(BulletBody obj, float factor); - -public override void SetAngularFactorV(BulletBody obj, Vector3 factor); - -public override Vector3 GetAngularFactor(BulletBody obj); - -public override bool IsInWorld(BulletBody obj); - -public override void AddConstraintRef(BulletBody obj, BulletConstraint constrain); - -public override void RemoveConstraintRef(BulletBody obj, BulletConstraint constrain); - -public override BulletConstraint GetConstraintRef(BulletBody obj, int index); - -public override int GetNumConstraintRefs(BulletBody obj); - -public override bool SetCollisionGroupMask(BulletBody body, uint filter, uint mask); - -// ===================================================================================== -// btCollisionShape entries - -public override float GetAngularMotionDisc(BulletShape shape); - -public override float GetContactBreakingThreshold(BulletShape shape, float defaultFactor); - -public override bool IsPolyhedral(BulletShape shape); - -public override bool IsConvex2d(BulletShape shape); - -public override bool IsConvex(BulletShape shape); - -public override bool IsNonMoving(BulletShape shape); - -public override bool IsConcave(BulletShape shape); - -public override bool IsCompound(BulletShape shape); - -public override bool IsSoftBody(BulletShape shape); - -public override bool IsInfinite(BulletShape shape); - -public override void SetLocalScaling(BulletShape shape, Vector3 scale); - -public override Vector3 GetLocalScaling(BulletShape shape); - -public override Vector3 CalculateLocalInertia(BulletShape shape, float mass); - -public override int GetShapeType(BulletShape shape); - -public override void SetMargin(BulletShape shape, float val); - -public override float GetMargin(BulletShape shape); - */ - -static class BSAPI -{ -// ===================================================================================== -// Mesh, hull, shape and body creation helper routines -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateMeshShape2(IntPtr world, - int indicesCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices, - int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices ); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateHullShape2(IntPtr world, - int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr BuildHullShapeFromMesh2(IntPtr world, IntPtr meshShape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr BuildNativeShape2(IntPtr world, ShapeData shapeData); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsNativeShape2(IntPtr shape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetShapeCollisionMargin2(IntPtr shape, float margin); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr BuildCapsuleShape2(IntPtr world, float radius, float height, Vector3 scale); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateCompoundShape2(IntPtr sim, bool enableDynamicAabbTree); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern int GetNumberOfCompoundChildren2(IntPtr cShape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void AddChildShapeToCompoundShape2(IntPtr cShape, IntPtr addShape, Vector3 pos, Quaternion rot); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr GetChildShapeFromCompoundShapeIndex2(IntPtr cShape, int indx); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr RemoveChildShapeFromCompoundShapeIndex2(IntPtr cShape, int indx); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void RemoveChildShapeFromCompoundShape2(IntPtr cShape, IntPtr removeShape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void RecalculateCompoundShapeLocalAabb2(IntPtr cShape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr DuplicateCollisionShape2(IntPtr sim, IntPtr srcShape, uint id); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateBodyFromShapeAndInfo2(IntPtr sim, IntPtr shape, uint id, IntPtr constructionInfo); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool DeleteCollisionShape2(IntPtr world, IntPtr shape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern int GetBodyType2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateBodyFromShape2(IntPtr sim, IntPtr shape, uint id, Vector3 pos, Quaternion rot); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateBodyWithDefaultMotionState2(IntPtr shape, uint id, Vector3 pos, Quaternion rot); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateGhostFromShape2(IntPtr sim, IntPtr shape, uint id, Vector3 pos, Quaternion rot); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr AllocateBodyInfo2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void ReleaseBodyInfo2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void DestroyObject2(IntPtr sim, IntPtr obj); - -} -} - -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -static class BulletSimAPI { -// =============================================================================== -// Link back to the managed code for outputting log messages -[UnmanagedFunctionPointer(CallingConvention.Cdecl)] -public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg); - -// =============================================================================== -// Initialization and simulation -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms, - int maxCollisions, IntPtr collisionArray, - int maxUpdates, IntPtr updateArray, - DebugLogCallback logRoutine); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool UpdateParameter2(IntPtr world, uint localID, String parm, float value); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetHeightMap2(IntPtr world, float[] heightmap); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void Shutdown2(IntPtr sim); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern int PhysicsStep2(IntPtr world, float timeStep, int maxSubSteps, float fixedTimeStep, - out int updatedEntityCount, - out IntPtr updatedEntitiesPtr, - out int collidersCount, - out IntPtr collidersPtr); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool PushUpdate2(IntPtr obj); - -// ===================================================================================== -// Terrain creation and helper routines -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateHeightMapInfo2(IntPtr sim, uint id, Vector3 minCoords, Vector3 maxCoords, - [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr FillHeightMapInfo2(IntPtr sim, IntPtr mapInfo, uint id, Vector3 minCoords, Vector3 maxCoords, - [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool ReleaseHeightMapInfo2(IntPtr heightMapInfo); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateGroundPlaneShape2(uint id, float height, float collisionMargin); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateTerrainShape2(IntPtr mapInfo); - -// ===================================================================================== -// Constraint creation and helper routines -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr Create6DofConstraint2(IntPtr world, IntPtr obj1, IntPtr obj2, - Vector3 frame1loc, Quaternion frame1rot, - Vector3 frame2loc, Quaternion frame2rot, - bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr Create6DofConstraintToPoint2(IntPtr world, IntPtr obj1, IntPtr obj2, - Vector3 joinPoint, - bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateHingeConstraint2(IntPtr world, IntPtr obj1, IntPtr obj2, - Vector3 pivotinA, Vector3 pivotinB, - Vector3 axisInA, Vector3 axisInB, - bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetConstraintEnable2(IntPtr constrain, float numericTrueFalse); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetConstraintNumSolverIterations2(IntPtr constrain, float iterations); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool SetFrames2(IntPtr constrain, - Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool SetLinearLimits2(IntPtr constrain, Vector3 low, Vector3 hi); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool SetAngularLimits2(IntPtr constrain, Vector3 low, Vector3 hi); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool UseFrameOffset2(IntPtr constrain, float enable); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool TranslationalLimitMotor2(IntPtr constrain, float enable, float targetVel, float maxMotorForce); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool SetBreakingImpulseThreshold2(IntPtr constrain, float threshold); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool CalculateTransforms2(IntPtr constrain); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool SetConstraintParam2(IntPtr constrain, ConstraintParams paramIndex, float value, ConstraintParamAxis axis); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool DestroyConstraint2(IntPtr world, IntPtr constrain); - -// ===================================================================================== -// btCollisionWorld entries -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void UpdateSingleAabb2(IntPtr world, IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void UpdateAabbs2(IntPtr world); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool GetForceUpdateAllAabbs2(IntPtr world); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetForceUpdateAllAabbs2(IntPtr world, bool force); - -// ===================================================================================== -// btDynamicsWorld entries -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool AddObjectToWorld2(IntPtr world, IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool RemoveObjectFromWorld2(IntPtr world, IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool AddConstraintToWorld2(IntPtr world, IntPtr constrain, bool disableCollisionsBetweenLinkedObjects); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool RemoveConstraintFromWorld2(IntPtr world, IntPtr constrain); -// ===================================================================================== -// btCollisionObject entries -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetAnisotripicFriction2(IntPtr constrain); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 SetAnisotripicFriction2(IntPtr constrain, Vector3 frict); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool HasAnisotripicFriction2(IntPtr constrain); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetContactProcessingThreshold2(IntPtr obj, float val); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetContactProcessingThreshold2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsStaticObject2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsKinematicObject2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsStaticOrKinematicObject2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool HasContactResponse2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetCollisionShape2(IntPtr sim, IntPtr obj, IntPtr shape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr GetCollisionShape2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern int GetActivationState2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetActivationState2(IntPtr obj, int state); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetDeactivationTime2(IntPtr obj, float dtime); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetDeactivationTime2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void ForceActivationState2(IntPtr obj, ActivationState state); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void Activate2(IntPtr obj, bool forceActivation); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsActive2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetRestitution2(IntPtr obj, float val); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetRestitution2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetFriction2(IntPtr obj, float val); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetFriction2(IntPtr obj); - - /* Haven't defined the type 'Transform' -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Transform GetWorldTransform2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void setWorldTransform2(IntPtr obj, Transform trans); - */ - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetPosition2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Quaternion GetOrientation2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetTranslation2(IntPtr obj, Vector3 position, Quaternion rotation); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr GetBroadphaseHandle2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetBroadphaseHandle2(IntPtr obj, IntPtr handle); - - /* -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Transform GetInterpolationWorldTransform2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetInterpolationWorldTransform2(IntPtr obj, Transform trans); - */ - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetInterpolationLinearVelocity2(IntPtr obj, Vector3 vel); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetInterpolationAngularVelocity2(IntPtr obj, Vector3 vel); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetInterpolationVelocity2(IntPtr obj, Vector3 linearVel, Vector3 angularVel); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetHitFraction2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetHitFraction2(IntPtr obj, float val); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern CollisionFlags GetCollisionFlags2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern CollisionFlags SetCollisionFlags2(IntPtr obj, CollisionFlags flags); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern CollisionFlags AddToCollisionFlags2(IntPtr obj, CollisionFlags flags); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern CollisionFlags RemoveFromCollisionFlags2(IntPtr obj, CollisionFlags flags); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetCcdMotionThreshold2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetCcdMotionThreshold2(IntPtr obj, float val); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetCcdSweptSphereRadius2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetCcdSweptSphereRadius2(IntPtr obj, float val); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr GetUserPointer2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetUserPointer2(IntPtr obj, IntPtr val); - -// ===================================================================================== -// btRigidBody entries -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void ApplyGravity2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetGravity2(IntPtr obj, Vector3 val); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetGravity2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetDamping2(IntPtr obj, float lin_damping, float ang_damping); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetLinearDamping2(IntPtr obj, float lin_damping); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetAngularDamping2(IntPtr obj, float ang_damping); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetLinearDamping2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetAngularDamping2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetLinearSleepingThreshold2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetAngularSleepingThreshold2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void ApplyDamping2(IntPtr obj, float timeStep); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetMassProps2(IntPtr obj, float mass, Vector3 inertia); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetLinearFactor2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetLinearFactor2(IntPtr obj, Vector3 factor); - - /* -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetCenterOfMassTransform2(IntPtr obj, Transform trans); - */ - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetCenterOfMassByPosRot2(IntPtr obj, Vector3 pos, Quaternion rot); - -// Add a force to the object as if its mass is one. -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void ApplyCentralForce2(IntPtr obj, Vector3 force); - -// Set the force being applied to the object as if its mass is one. -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetObjectForce2(IntPtr obj, Vector3 force); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetTotalForce2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetTotalTorque2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetInvInertiaDiagLocal2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetInvInertiaDiagLocal2(IntPtr obj, Vector3 inert); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetSleepingThresholds2(IntPtr obj, float lin_threshold, float ang_threshold); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void ApplyTorque2(IntPtr obj, Vector3 torque); - -// Apply force at the given point. Will add torque to the object. -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void ApplyForce2(IntPtr obj, Vector3 force, Vector3 pos); - -// Apply impulse to the object. Same as "ApplycentralForce" but force scaled by object's mass. -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void ApplyCentralImpulse2(IntPtr obj, Vector3 imp); - -// Apply impulse to the object's torque. Force is scaled by object's mass. -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void ApplyTorqueImpulse2(IntPtr obj, Vector3 imp); - -// Apply impulse at the point given. For is scaled by object's mass and effects both linear and angular forces. -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void ApplyImpulse2(IntPtr obj, Vector3 imp, Vector3 pos); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void ClearForces2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void ClearAllForces2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void UpdateInertiaTensor2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetCenterOfMassPosition2(IntPtr obj); - - /* -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Transform GetCenterOfMassTransform2(IntPtr obj); - */ - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetLinearVelocity2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetAngularVelocity2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetLinearVelocity2(IntPtr obj, Vector3 val); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetAngularVelocity2(IntPtr obj, Vector3 angularVelocity); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetVelocityInLocalPoint2(IntPtr obj, Vector3 pos); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void Translate2(IntPtr obj, Vector3 trans); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void UpdateDeactivation2(IntPtr obj, float timeStep); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool WantsSleeping2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetAngularFactor2(IntPtr obj, float factor); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetAngularFactorV2(IntPtr obj, Vector3 factor); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetAngularFactor2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsInWorld2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void AddConstraintRef2(IntPtr obj, IntPtr constrain); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void RemoveConstraintRef2(IntPtr obj, IntPtr constrain); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr GetConstraintRef2(IntPtr obj, int index); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern int GetNumConstraintRefs2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool SetCollisionGroupMask2(IntPtr body, uint filter, uint mask); - -// ===================================================================================== -// btCollisionShape entries - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetAngularMotionDisc2(IntPtr shape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetContactBreakingThreshold2(IntPtr shape, float defaultFactor); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsPolyhedral2(IntPtr shape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsConvex2d2(IntPtr shape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsConvex2(IntPtr shape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsNonMoving2(IntPtr shape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsConcave2(IntPtr shape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsCompound2(IntPtr shape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsSoftBody2(IntPtr shape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool IsInfinite2(IntPtr shape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetLocalScaling2(IntPtr shape, Vector3 scale); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 GetLocalScaling2(IntPtr shape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern Vector3 CalculateLocalInertia2(IntPtr shape, float mass); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern int GetShapeType2(IntPtr shape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetMargin2(IntPtr shape, float val); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern float GetMargin2(IntPtr shape); - -// ===================================================================================== -// Debugging -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void DumpRigidBody2(IntPtr sim, IntPtr collisionObject); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void DumpCollisionShape2(IntPtr sim, IntPtr collisionShape); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void DumpMapInfo2(IntPtr sim, IntPtr manInfo); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void DumpConstraint2(IntPtr sim, IntPtr constrain); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void DumpActivationInfo2(IntPtr sim); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void DumpAllInfo2(IntPtr sim); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void DumpPhysicsStatistics2(IntPtr sim); - -} -} +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; + +using OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ +public sealed class BSAPIUnman : BulletSimAPITemplate +{ + /* +// Initialization and simulation +public BulletWorld Initialize(Vector3 maxPosition, IntPtr parms, + int maxCollisions, IntPtr collisionArray, + int maxUpdates, IntPtr updateArray + ); + +public bool UpdateParameter(BulletWorld world, uint localID, String parm, float value); + +public void SetHeightMap(BulletWorld world, float[] heightmap); + +public void Shutdown(BulletWorld sim); + +public int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, + out int updatedEntityCount, + out IntPtr updatedEntitiesPtr, + out int collidersCount, + out IntPtr collidersPtr); + +public bool PushUpdate(BulletBody obj); + */ + +// ===================================================================================== +// Mesh, hull, shape and body creation helper routines +public override BulletShape CreateMeshShape(BulletWorld world, + int indicesCount, int[] indices, + int verticesCount, float[] vertices) +{ + return new BulletShape( + BSAPICPP.CreateMeshShape2(world.ptr, indicesCount, indices, verticesCount, vertices), + BSPhysicsShapeType.SHAPE_MESH); +} + +public override BulletShape CreateHullShape(BulletWorld world, int hullCount, float[] hulls) +{ + return new BulletShape( + BSAPICPP.CreateHullShape2(world.ptr, hullCount, hulls), + BSPhysicsShapeType.SHAPE_HULL); +} + +public override BulletShape BuildHullShapeFromMesh(BulletWorld world, BulletShape meshShape) +{ + return new BulletShape( + BSAPICPP.BuildHullShapeFromMesh2(world.ptr, meshShape.ptr), + BSPhysicsShapeType.SHAPE_HULL); +} + +public override BulletShape BuildNativeShape( BulletWorld world, ShapeData shapeData) +{ + return new BulletShape( + BSAPICPP.BuildNativeShape2(world.ptr, shapeData), + shapeData.Type); +} + +public override bool IsNativeShape(BulletShape shape) +{ + if (shape.HasPhysicalShape) + return BSAPICPP.IsNativeShape2(shape.ptr); + return false; +} + +public override void SetShapeCollisionMargin(BulletShape shape, float margin) +{ + if (shape.HasPhysicalShape) + BSAPICPP.SetShapeCollisionMargin2(shape.ptr, margin); +} + +public override BulletShape BuildCapsuleShape(BulletWorld world, float radius, float height, Vector3 scale) +{ + return new BulletShape( + BSAPICPP.BuildCapsuleShape2(world.ptr, radius, height, scale), + BSPhysicsShapeType.SHAPE_CAPSULE); +} + +public override BulletShape CreateCompoundShape(BulletWorld sim, bool enableDynamicAabbTree) +{ + return new BulletShape( + BSAPICPP.CreateCompoundShape2(sim.ptr, enableDynamicAabbTree), + BSPhysicsShapeType.SHAPE_COMPOUND); + +} + +public override int GetNumberOfCompoundChildren(BulletShape shape) +{ + if (shape.HasPhysicalShape) + return BSAPICPP.GetNumberOfCompoundChildren2(shape.ptr); + return 0; +} + +public override void AddChildShapeToCompoundShape(BulletShape cShape, BulletShape addShape, Vector3 pos, Quaternion rot) +{ + BSAPICPP.AddChildShapeToCompoundShape2(cShape.ptr, addShape.ptr, pos, rot); +} + +public override BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) +{ + return new BulletShape(BSAPICPP.GetChildShapeFromCompoundShapeIndex2(cShape.ptr, indx)); +} + +public override BulletShape RemoveChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) +{ + return new BulletShape(BSAPICPP.RemoveChildShapeFromCompoundShapeIndex2(cShape.ptr, indx)); +} + +public override void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape) +{ + BSAPICPP.RemoveChildShapeFromCompoundShape2(cShape.ptr, removeShape.ptr); +} + +public override void RecalculateCompoundShapeLocalAabb(BulletShape cShape) +{ + BSAPICPP.RecalculateCompoundShapeLocalAabb2(cShape.ptr); +} + +public override BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id) +{ + return new BulletShape(BSAPICPP.DuplicateCollisionShape2(sim.ptr, srcShape.ptr, id), srcShape.type); +} + +public override BulletBody CreateBodyFromShapeAndInfo(BulletWorld sim, BulletShape shape, uint id, IntPtr constructionInfo) +{ + return new BulletBody(id, BSAPICPP.CreateBodyFromShapeAndInfo2(sim.ptr, shape.ptr, id, constructionInfo)); +} + +public override bool DeleteCollisionShape(BulletWorld world, BulletShape shape) +{ + return BSAPICPP.DeleteCollisionShape2(world.ptr, shape.ptr); +} + +public override int GetBodyType(BulletBody obj) +{ + return BSAPICPP.GetBodyType2(obj.ptr); +} + +public override BulletBody CreateBodyFromShape(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot) +{ + return new BulletBody(id, BSAPICPP.CreateBodyFromShape2(sim.ptr, shape.ptr, id, pos, rot)); +} + +public override BulletBody CreateBodyWithDefaultMotionState(BulletShape shape, uint id, Vector3 pos, Quaternion rot) +{ + return new BulletBody(id, BSAPICPP.CreateBodyWithDefaultMotionState2(shape.ptr, id, pos, rot)); +} + +public override BulletBody CreateGhostFromShape(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot) +{ + return new BulletBody(id, BSAPICPP.CreateGhostFromShape2(sim.ptr, shape.ptr, id, pos, rot)); +} + +public override IntPtr AllocateBodyInfo(BulletBody obj) +{ + return BSAPICPP.AllocateBodyInfo2(obj.ptr); +} + +public override void ReleaseBodyInfo(IntPtr obj) +{ + BSAPICPP.ReleaseBodyInfo2(obj); +} + +public override void DestroyObject(BulletWorld sim, BulletBody obj) +{ + BSAPICPP.DestroyObject2(sim.ptr, obj.ptr); +} + +// ===================================================================================== +// Terrain creation and helper routines +public override IntPtr CreateHeightMapInfo(BulletWorld sim, uint id, Vector3 minCoords, Vector3 maxCoords, + float[] heightMap, float collisionMargin) +{ + return BSAPICPP.CreateHeightMapInfo2(sim.ptr, id, minCoords, maxCoords, heightMap, collisionMargin); +} + +public override IntPtr FillHeightMapInfo(BulletWorld sim, IntPtr mapInfo, uint id, Vector3 minCoords, Vector3 maxCoords, + float[] heightMap, float collisionMargin) +{ + return BSAPICPP.FillHeightMapInfo2(sim.ptr, mapInfo, id, minCoords, maxCoords, heightMap, collisionMargin); +} + +public override bool ReleaseHeightMapInfo(IntPtr heightMapInfo) +{ + return BSAPICPP.ReleaseHeightMapInfo2(heightMapInfo); +} + +public override BulletShape CreateGroundPlaneShape(uint id, float height, float collisionMargin) +{ + return new BulletShape(BSAPICPP.CreateGroundPlaneShape2(id, height, collisionMargin), BSPhysicsShapeType.SHAPE_GROUNDPLANE); +} + +public override BulletShape CreateTerrainShape(IntPtr mapInfo) +{ + return new BulletShape(BSAPICPP.CreateTerrainShape2(mapInfo), BSPhysicsShapeType.SHAPE_TERRAIN); +} + +// ===================================================================================== +// Constraint creation and helper routines +public override BulletConstraint Create6DofConstraint(BulletWorld world, BulletBody obj1, BulletBody obj2, + Vector3 frame1loc, Quaternion frame1rot, + Vector3 frame2loc, Quaternion frame2rot, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) +{ + return new BulletConstraint(BSAPICPP.Create6DofConstraint2(world.ptr, obj1.ptr, obj2.ptr, frame1loc, frame1rot, + frame2loc, frame2rot, useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); +} + +public override BulletConstraint Create6DofConstraintToPoint(BulletWorld world, BulletBody obj1, BulletBody obj2, + Vector3 joinPoint, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) +{ + return new BulletConstraint(BSAPICPP.Create6DofConstraintToPoint2(world.ptr, obj1.ptr, obj2.ptr, + joinPoint, useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); +} + +public override BulletConstraint CreateHingeConstraint(BulletWorld world, BulletBody obj1, BulletBody obj2, + Vector3 pivotinA, Vector3 pivotinB, + Vector3 axisInA, Vector3 axisInB, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) +{ + return new BulletConstraint(BSAPICPP.CreateHingeConstraint2(world.ptr, obj1.ptr, obj2.ptr, + pivotinA, pivotinB, axisInA, axisInB, useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); +} + +public override void SetConstraintEnable(BulletConstraint constrain, float numericTrueFalse) +{ + BSAPICPP.SetConstraintEnable2(constrain.ptr, numericTrueFalse); +} + +public override void SetConstraintNumSolverIterations(BulletConstraint constrain, float iterations) +{ + BSAPICPP.SetConstraintNumSolverIterations2(constrain.ptr, iterations); +} + +public override bool SetFrames(BulletConstraint constrain, + Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot) +{ + return BSAPICPP.SetFrames2(constrain.ptr, frameA, frameArot, frameB, frameBrot); +} + +public override bool SetLinearLimits(BulletConstraint constrain, Vector3 low, Vector3 hi) +{ + return BSAPICPP.SetLinearLimits2(constrain.ptr, low, hi); +} + +public override bool SetAngularLimits(BulletConstraint constrain, Vector3 low, Vector3 hi) +{ + return BSAPICPP.SetAngularLimits2(constrain.ptr, low, hi); +} + +public override bool UseFrameOffset(BulletConstraint constrain, float enable) +{ + return BSAPICPP.UseFrameOffset2(constrain.ptr, enable); +} + +public override bool TranslationalLimitMotor(BulletConstraint constrain, float enable, float targetVel, float maxMotorForce) +{ + return BSAPICPP.TranslationalLimitMotor2(constrain.ptr, enable, targetVel, maxMotorForce); +} + +public override bool SetBreakingImpulseThreshold(BulletConstraint constrain, float threshold) +{ + return BSAPICPP.SetBreakingImpulseThreshold2(constrain.ptr, threshold); +} + +public override bool CalculateTransforms(BulletConstraint constrain) +{ + return BSAPICPP.CalculateTransforms2(constrain.ptr); +} + +public override bool SetConstraintParam(BulletConstraint constrain, ConstraintParams paramIndex, float value, ConstraintParamAxis axis) +{ + return BSAPICPP.SetConstraintParam2(constrain.ptr, paramIndex, value, axis); +} + +public override bool DestroyConstraint(BulletWorld world, BulletConstraint constrain) +{ + return BSAPICPP.DestroyConstraint2(world.ptr, constrain.ptr); +} + +// ===================================================================================== +// btCollisionWorld entries +public override void UpdateSingleAabb(BulletWorld world, BulletBody obj) +{ + BSAPICPP.UpdateSingleAabb2(world.ptr, obj.ptr); +} + +public override void UpdateAabbs(BulletWorld world) +{ + BSAPICPP.UpdateAabbs2(world.ptr); +} + +public override bool GetForceUpdateAllAabbs(BulletWorld world) +{ + return BSAPICPP.GetForceUpdateAllAabbs2(world.ptr); +} + +public override void SetForceUpdateAllAabbs(BulletWorld world, bool force) +{ + BSAPICPP.SetForceUpdateAllAabbs2(world.ptr, force); +} + +// ===================================================================================== +// btDynamicsWorld entries +public override bool AddObjectToWorld(BulletWorld world, BulletBody obj) +{ + return BSAPICPP.AddObjectToWorld2(world.ptr, obj.ptr); +} + +public override bool RemoveObjectFromWorld(BulletWorld world, BulletBody obj) +{ + return BSAPICPP.RemoveObjectFromWorld2(world.ptr, obj.ptr); +} + +public override bool AddConstraintToWorld(BulletWorld world, BulletConstraint constrain, bool disableCollisionsBetweenLinkedObjects) +{ + return BSAPICPP.AddConstraintToWorld2(world.ptr, constrain.ptr, disableCollisionsBetweenLinkedObjects); +} + +public override bool RemoveConstraintFromWorld(BulletWorld world, BulletConstraint constrain) +{ + return BSAPICPP.RemoveConstraintFromWorld2(world.ptr, constrain.ptr); +} +// ===================================================================================== +// btCollisionObject entries +public override Vector3 GetAnisotripicFriction(BulletConstraint constrain) +{ + return BSAPICPP.GetAnisotripicFriction2(constrain.ptr); +} + +public override Vector3 SetAnisotripicFriction(BulletConstraint constrain, Vector3 frict) +{ + return BSAPICPP.SetAnisotripicFriction2(constrain.ptr, frict); +} + +public override bool HasAnisotripicFriction(BulletConstraint constrain) +{ + return BSAPICPP.HasAnisotripicFriction2(constrain.ptr); +} + +public override void SetContactProcessingThreshold(BulletBody obj, float val) +{ + BSAPICPP.SetContactProcessingThreshold2(obj.ptr, val); +} + +public override float GetContactProcessingThreshold(BulletBody obj) +{ + return BSAPICPP.GetContactProcessingThreshold2(obj.ptr); +} + +public override bool IsStaticObject(BulletBody obj) +{ + return BSAPICPP.IsStaticObject2(obj.ptr); +} + +public override bool IsKinematicObject(BulletBody obj) +{ + return BSAPICPP.IsKinematicObject2(obj.ptr); +} + +public override bool IsStaticOrKinematicObject(BulletBody obj) +{ + return BSAPICPP.IsStaticOrKinematicObject2(obj.ptr); +} + +public override bool HasContactResponse(BulletBody obj) +{ + return BSAPICPP.HasContactResponse2(obj.ptr); +} + +public override void SetCollisionShape(BulletWorld sim, BulletBody obj, BulletShape shape) +{ + BSAPICPP.SetCollisionShape2(sim.ptr, obj.ptr, shape.ptr); +} + +public override BulletShape GetCollisionShape(BulletBody obj) +{ + return new BulletShape(BSAPICPP.GetCollisionShape2(obj.ptr)); +} + +public override int GetActivationState(BulletBody obj) +{ + return BSAPICPP.GetActivationState2(obj.ptr); +} + +public override void SetActivationState(BulletBody obj, int state) +{ + BSAPICPP.SetActivationState2(obj.ptr, state); +} + +public override void SetDeactivationTime(BulletBody obj, float dtime) +{ + BSAPICPP.SetDeactivationTime2(obj.ptr, dtime); +} + +public override float GetDeactivationTime(BulletBody obj) +{ + return BSAPICPP.GetDeactivationTime2(obj.ptr); +} + +public override void ForceActivationState(BulletBody obj, ActivationState state) +{ + BSAPICPP.ForceActivationState2(obj.ptr, state); +} + +public override void Activate(BulletBody obj, bool forceActivation) +{ + BSAPICPP.Activate2(obj.ptr, forceActivation); +} + +public override bool IsActive(BulletBody obj) +{ + return BSAPICPP.IsActive2(obj.ptr); +} + +public override void SetRestitution(BulletBody obj, float val) +{ + BSAPICPP.SetRestitution2(obj.ptr, val); +} + +public override float GetRestitution(BulletBody obj) +{ + return BSAPICPP.GetRestitution2(obj.ptr); +} + +public override void SetFriction(BulletBody obj, float val) +{ + BSAPICPP.SetFriction2(obj.ptr, val); +} + +public override float GetFriction(BulletBody obj) +{ + return BSAPICPP.GetFriction2(obj.ptr); +} + +public override Vector3 GetPosition(BulletBody obj) +{ + return BSAPICPP.GetPosition2(obj.ptr); +} + +public override Quaternion GetOrientation(BulletBody obj) +{ + return BSAPICPP.GetOrientation2(obj.ptr); +} + +public override void SetTranslation(BulletBody obj, Vector3 position, Quaternion rotation) +{ + BSAPICPP.SetTranslation2(obj.ptr, position, rotation); +} + +public override IntPtr GetBroadphaseHandle(BulletBody obj) +{ + return BSAPICPP.GetBroadphaseHandle2(obj.ptr); +} + +public override void SetBroadphaseHandle(BulletBody obj, IntPtr handle) +{ + BSAPICPP.SetUserPointer2(obj.ptr, handle); +} + +public override void SetInterpolationLinearVelocity(BulletBody obj, Vector3 vel) +{ + BSAPICPP.SetInterpolationLinearVelocity2(obj.ptr, vel); +} + +public override void SetInterpolationAngularVelocity(BulletBody obj, Vector3 vel) +{ + BSAPICPP.SetInterpolationAngularVelocity2(obj.ptr, vel); +} + +public override void SetInterpolationVelocity(BulletBody obj, Vector3 linearVel, Vector3 angularVel) +{ + BSAPICPP.SetInterpolationVelocity2(obj.ptr, linearVel, angularVel); +} + +public override float GetHitFraction(BulletBody obj) +{ + return BSAPICPP.GetHitFraction2(obj.ptr); +} + +public override void SetHitFraction(BulletBody obj, float val) +{ + BSAPICPP.SetHitFraction2(obj.ptr, val); +} + +public override CollisionFlags GetCollisionFlags(BulletBody obj) +{ + return BSAPICPP.GetCollisionFlags2(obj.ptr); +} + +public override CollisionFlags SetCollisionFlags(BulletBody obj, CollisionFlags flags) +{ + return BSAPICPP.SetCollisionFlags2(obj.ptr, flags); +} + +public override CollisionFlags AddToCollisionFlags(BulletBody obj, CollisionFlags flags) +{ + return BSAPICPP.AddToCollisionFlags2(obj.ptr, flags); +} + +public override CollisionFlags RemoveFromCollisionFlags(BulletBody obj, CollisionFlags flags) +{ + return BSAPICPP.RemoveFromCollisionFlags2(obj.ptr, flags); +} + +public override float GetCcdMotionThreshold(BulletBody obj) +{ + return BSAPICPP.GetCcdMotionThreshold2(obj.ptr); +} + + +public override void SetCcdMotionThreshold(BulletBody obj, float val) +{ + BSAPICPP.SetCcdMotionThreshold2(obj.ptr, val); +} + +public override float GetCcdSweptSphereRadius(BulletBody obj) +{ + return BSAPICPP.GetCcdSweptSphereRadius2(obj.ptr); +} + +public override void SetCcdSweptSphereRadius(BulletBody obj, float val) +{ + BSAPICPP.SetCcdSweptSphereRadius2(obj.ptr, val); +} + +public override IntPtr GetUserPointer(BulletBody obj) +{ + return BSAPICPP.GetUserPointer2(obj.ptr); +} + +public override void SetUserPointer(BulletBody obj, IntPtr val) +{ + BSAPICPP.SetUserPointer2(obj.ptr, val); +} + + /* +// ===================================================================================== +// btRigidBody entries +public override void ApplyGravity(BulletBody obj); + +public override void SetGravity(BulletBody obj, Vector3 val); + +public override Vector3 GetGravity(BulletBody obj); + +public override void SetDamping(BulletBody obj, float lin_damping, float ang_damping); + +public override void SetLinearDamping(BulletBody obj, float lin_damping); + +public override void SetAngularDamping(BulletBody obj, float ang_damping); + +public override float GetLinearDamping(BulletBody obj); + +public override float GetAngularDamping(BulletBody obj); + +public override float GetLinearSleepingThreshold(BulletBody obj); + + +public override void ApplyDamping(BulletBody obj, float timeStep); + +public override void SetMassProps(BulletBody obj, float mass, Vector3 inertia); + +public override Vector3 GetLinearFactor(BulletBody obj); + +public override void SetLinearFactor(BulletBody obj, Vector3 factor); + +public override void SetCenterOfMassByPosRot(BulletBody obj, Vector3 pos, Quaternion rot); + +// Add a force to the object as if its mass is one. +public override void ApplyCentralForce(BulletBody obj, Vector3 force); + +// Set the force being applied to the object as if its mass is one. +public override void SetObjectForce(BulletBody obj, Vector3 force); + +public override Vector3 GetTotalForce(BulletBody obj); + +public override Vector3 GetTotalTorque(BulletBody obj); + +public override Vector3 GetInvInertiaDiagLocal(BulletBody obj); + +public override void SetInvInertiaDiagLocal(BulletBody obj, Vector3 inert); + +public override void SetSleepingThresholds(BulletBody obj, float lin_threshold, float ang_threshold); + +public override void ApplyTorque(BulletBody obj, Vector3 torque); + +// Apply force at the given point. Will add torque to the object. +public override void ApplyForce(BulletBody obj, Vector3 force, Vector3 pos); + +// Apply impulse to the object. Same as "ApplycentralForce" but force scaled by object's mass. +public override void ApplyCentralImpulse(BulletBody obj, Vector3 imp); + +// Apply impulse to the object's torque. Force is scaled by object's mass. +public override void ApplyTorqueImpulse(BulletBody obj, Vector3 imp); + +// Apply impulse at the point given. For is scaled by object's mass and effects both linear and angular forces. +public override void ApplyImpulse(BulletBody obj, Vector3 imp, Vector3 pos); + +public override void ClearForces(BulletBody obj); + +public override void ClearAllForces(BulletBody obj); + +public override void UpdateInertiaTensor(BulletBody obj); + +public override Vector3 GetLinearVelocity(BulletBody obj); + +public override Vector3 GetAngularVelocity(BulletBody obj); + +public override void SetLinearVelocity(BulletBody obj, Vector3 val); + +public override void SetAngularVelocity(BulletBody obj, Vector3 angularVelocity); + +public override Vector3 GetVelocityInLocalPoint(BulletBody obj, Vector3 pos); + +public override void Translate(BulletBody obj, Vector3 trans); + +public override void UpdateDeactivation(BulletBody obj, float timeStep); + +public override bool WantsSleeping(BulletBody obj); + +public override void SetAngularFactor(BulletBody obj, float factor); + +public override void SetAngularFactorV(BulletBody obj, Vector3 factor); + +public override Vector3 GetAngularFactor(BulletBody obj); + +public override bool IsInWorld(BulletBody obj); + +public override void AddConstraintRef(BulletBody obj, BulletConstraint constrain); + +public override void RemoveConstraintRef(BulletBody obj, BulletConstraint constrain); + +public override BulletConstraint GetConstraintRef(BulletBody obj, int index); + +public override int GetNumConstraintRefs(BulletBody obj); + +public override bool SetCollisionGroupMask(BulletBody body, uint filter, uint mask); + +// ===================================================================================== +// btCollisionShape entries + +public override float GetAngularMotionDisc(BulletShape shape); + +public override float GetContactBreakingThreshold(BulletShape shape, float defaultFactor); + +public override bool IsPolyhedral(BulletShape shape); + +public override bool IsConvex2d(BulletShape shape); + +public override bool IsConvex(BulletShape shape); + +public override bool IsNonMoving(BulletShape shape); + +public override bool IsConcave(BulletShape shape); + +public override bool IsCompound(BulletShape shape); + +public override bool IsSoftBody(BulletShape shape); + +public override bool IsInfinite(BulletShape shape); + +public override void SetLocalScaling(BulletShape shape, Vector3 scale); + +public override Vector3 GetLocalScaling(BulletShape shape); + +public override Vector3 CalculateLocalInertia(BulletShape shape, float mass); + +public override int GetShapeType(BulletShape shape); + +public override void SetMargin(BulletShape shape, float val); + +public override float GetMargin(BulletShape shape); + */ + +static class BSAPICPP +{ +// ===================================================================================== +// Mesh, hull, shape and body creation helper routines +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateMeshShape2(IntPtr world, + int indicesCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices, + int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices ); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateHullShape2(IntPtr world, + int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr BuildHullShapeFromMesh2(IntPtr world, IntPtr meshShape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr BuildNativeShape2(IntPtr world, ShapeData shapeData); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsNativeShape2(IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetShapeCollisionMargin2(IntPtr shape, float margin); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr BuildCapsuleShape2(IntPtr world, float radius, float height, Vector3 scale); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateCompoundShape2(IntPtr sim, bool enableDynamicAabbTree); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern int GetNumberOfCompoundChildren2(IntPtr cShape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void AddChildShapeToCompoundShape2(IntPtr cShape, IntPtr addShape, Vector3 pos, Quaternion rot); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr GetChildShapeFromCompoundShapeIndex2(IntPtr cShape, int indx); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr RemoveChildShapeFromCompoundShapeIndex2(IntPtr cShape, int indx); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void RemoveChildShapeFromCompoundShape2(IntPtr cShape, IntPtr removeShape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void RecalculateCompoundShapeLocalAabb2(IntPtr cShape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr DuplicateCollisionShape2(IntPtr sim, IntPtr srcShape, uint id); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateBodyFromShapeAndInfo2(IntPtr sim, IntPtr shape, uint id, IntPtr constructionInfo); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool DeleteCollisionShape2(IntPtr world, IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern int GetBodyType2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateBodyFromShape2(IntPtr sim, IntPtr shape, uint id, Vector3 pos, Quaternion rot); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateBodyWithDefaultMotionState2(IntPtr shape, uint id, Vector3 pos, Quaternion rot); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateGhostFromShape2(IntPtr sim, IntPtr shape, uint id, Vector3 pos, Quaternion rot); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr AllocateBodyInfo2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ReleaseBodyInfo2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void DestroyObject2(IntPtr sim, IntPtr obj); + +// ===================================================================================== +// Terrain creation and helper routines +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateHeightMapInfo2(IntPtr sim, uint id, Vector3 minCoords, Vector3 maxCoords, + [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr FillHeightMapInfo2(IntPtr sim, IntPtr mapInfo, uint id, Vector3 minCoords, Vector3 maxCoords, + [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool ReleaseHeightMapInfo2(IntPtr heightMapInfo); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateGroundPlaneShape2(uint id, float height, float collisionMargin); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateTerrainShape2(IntPtr mapInfo); + +// ===================================================================================== +// Constraint creation and helper routines +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr Create6DofConstraint2(IntPtr world, IntPtr obj1, IntPtr obj2, + Vector3 frame1loc, Quaternion frame1rot, + Vector3 frame2loc, Quaternion frame2rot, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr Create6DofConstraintToPoint2(IntPtr world, IntPtr obj1, IntPtr obj2, + Vector3 joinPoint, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateHingeConstraint2(IntPtr world, IntPtr obj1, IntPtr obj2, + Vector3 pivotinA, Vector3 pivotinB, + Vector3 axisInA, Vector3 axisInB, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetConstraintEnable2(IntPtr constrain, float numericTrueFalse); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetConstraintNumSolverIterations2(IntPtr constrain, float iterations); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool SetFrames2(IntPtr constrain, + Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool SetLinearLimits2(IntPtr constrain, Vector3 low, Vector3 hi); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool SetAngularLimits2(IntPtr constrain, Vector3 low, Vector3 hi); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool UseFrameOffset2(IntPtr constrain, float enable); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool TranslationalLimitMotor2(IntPtr constrain, float enable, float targetVel, float maxMotorForce); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool SetBreakingImpulseThreshold2(IntPtr constrain, float threshold); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool CalculateTransforms2(IntPtr constrain); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool SetConstraintParam2(IntPtr constrain, ConstraintParams paramIndex, float value, ConstraintParamAxis axis); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool DestroyConstraint2(IntPtr world, IntPtr constrain); + +// ===================================================================================== +// btCollisionWorld entries +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void UpdateSingleAabb2(IntPtr world, IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void UpdateAabbs2(IntPtr world); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool GetForceUpdateAllAabbs2(IntPtr world); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetForceUpdateAllAabbs2(IntPtr world, bool force); + +// ===================================================================================== +// btDynamicsWorld entries +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool AddObjectToWorld2(IntPtr world, IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool RemoveObjectFromWorld2(IntPtr world, IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool AddConstraintToWorld2(IntPtr world, IntPtr constrain, bool disableCollisionsBetweenLinkedObjects); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool RemoveConstraintFromWorld2(IntPtr world, IntPtr constrain); +// ===================================================================================== +// btCollisionObject entries +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetAnisotripicFriction2(IntPtr constrain); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 SetAnisotripicFriction2(IntPtr constrain, Vector3 frict); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool HasAnisotripicFriction2(IntPtr constrain); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetContactProcessingThreshold2(IntPtr obj, float val); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetContactProcessingThreshold2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsStaticObject2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsKinematicObject2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsStaticOrKinematicObject2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool HasContactResponse2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetCollisionShape2(IntPtr sim, IntPtr obj, IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr GetCollisionShape2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern int GetActivationState2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetActivationState2(IntPtr obj, int state); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetDeactivationTime2(IntPtr obj, float dtime); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetDeactivationTime2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ForceActivationState2(IntPtr obj, ActivationState state); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void Activate2(IntPtr obj, bool forceActivation); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsActive2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetRestitution2(IntPtr obj, float val); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetRestitution2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetFriction2(IntPtr obj, float val); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetFriction2(IntPtr obj); + + /* Haven't defined the type 'Transform' +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Transform GetWorldTransform2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void setWorldTransform2(IntPtr obj, Transform trans); + */ + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetPosition2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Quaternion GetOrientation2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetTranslation2(IntPtr obj, Vector3 position, Quaternion rotation); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr GetBroadphaseHandle2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetBroadphaseHandle2(IntPtr obj, IntPtr handle); + + /* +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Transform GetInterpolationWorldTransform2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetInterpolationWorldTransform2(IntPtr obj, Transform trans); + */ + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetInterpolationLinearVelocity2(IntPtr obj, Vector3 vel); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetInterpolationAngularVelocity2(IntPtr obj, Vector3 vel); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetInterpolationVelocity2(IntPtr obj, Vector3 linearVel, Vector3 angularVel); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetHitFraction2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetHitFraction2(IntPtr obj, float val); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern CollisionFlags GetCollisionFlags2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern CollisionFlags SetCollisionFlags2(IntPtr obj, CollisionFlags flags); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern CollisionFlags AddToCollisionFlags2(IntPtr obj, CollisionFlags flags); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern CollisionFlags RemoveFromCollisionFlags2(IntPtr obj, CollisionFlags flags); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetCcdMotionThreshold2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetCcdMotionThreshold2(IntPtr obj, float val); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetCcdSweptSphereRadius2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetCcdSweptSphereRadius2(IntPtr obj, float val); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr GetUserPointer2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetUserPointer2(IntPtr obj, IntPtr val); + +} +} + +// =============================================================================== +// =============================================================================== +// =============================================================================== +// =============================================================================== +// =============================================================================== +// =============================================================================== +// =============================================================================== +// =============================================================================== +// =============================================================================== +// =============================================================================== +// =============================================================================== +// =============================================================================== +// =============================================================================== +static class BulletSimAPI { +// =============================================================================== +// Link back to the managed code for outputting log messages +[UnmanagedFunctionPointer(CallingConvention.Cdecl)] +public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg); + +// =============================================================================== +// Initialization and simulation +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms, + int maxCollisions, IntPtr collisionArray, + int maxUpdates, IntPtr updateArray, + DebugLogCallback logRoutine); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool UpdateParameter2(IntPtr world, uint localID, String parm, float value); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetHeightMap2(IntPtr world, float[] heightmap); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void Shutdown2(IntPtr sim); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern int PhysicsStep2(IntPtr world, float timeStep, int maxSubSteps, float fixedTimeStep, + out int updatedEntityCount, + out IntPtr updatedEntitiesPtr, + out int collidersCount, + out IntPtr collidersPtr); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool PushUpdate2(IntPtr obj); + +// ===================================================================================== +// btRigidBody entries +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ApplyGravity2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetGravity2(IntPtr obj, Vector3 val); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetGravity2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetDamping2(IntPtr obj, float lin_damping, float ang_damping); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetLinearDamping2(IntPtr obj, float lin_damping); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetAngularDamping2(IntPtr obj, float ang_damping); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetLinearDamping2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetAngularDamping2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetLinearSleepingThreshold2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetAngularSleepingThreshold2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ApplyDamping2(IntPtr obj, float timeStep); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetMassProps2(IntPtr obj, float mass, Vector3 inertia); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetLinearFactor2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetLinearFactor2(IntPtr obj, Vector3 factor); + + /* +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetCenterOfMassTransform2(IntPtr obj, Transform trans); + */ + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetCenterOfMassByPosRot2(IntPtr obj, Vector3 pos, Quaternion rot); + +// Add a force to the object as if its mass is one. +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ApplyCentralForce2(IntPtr obj, Vector3 force); + +// Set the force being applied to the object as if its mass is one. +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetObjectForce2(IntPtr obj, Vector3 force); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetTotalForce2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetTotalTorque2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetInvInertiaDiagLocal2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetInvInertiaDiagLocal2(IntPtr obj, Vector3 inert); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetSleepingThresholds2(IntPtr obj, float lin_threshold, float ang_threshold); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ApplyTorque2(IntPtr obj, Vector3 torque); + +// Apply force at the given point. Will add torque to the object. +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ApplyForce2(IntPtr obj, Vector3 force, Vector3 pos); + +// Apply impulse to the object. Same as "ApplycentralForce" but force scaled by object's mass. +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ApplyCentralImpulse2(IntPtr obj, Vector3 imp); + +// Apply impulse to the object's torque. Force is scaled by object's mass. +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ApplyTorqueImpulse2(IntPtr obj, Vector3 imp); + +// Apply impulse at the point given. For is scaled by object's mass and effects both linear and angular forces. +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ApplyImpulse2(IntPtr obj, Vector3 imp, Vector3 pos); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ClearForces2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ClearAllForces2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void UpdateInertiaTensor2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetCenterOfMassPosition2(IntPtr obj); + + /* +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Transform GetCenterOfMassTransform2(IntPtr obj); + */ + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetLinearVelocity2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetAngularVelocity2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetLinearVelocity2(IntPtr obj, Vector3 val); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetAngularVelocity2(IntPtr obj, Vector3 angularVelocity); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetVelocityInLocalPoint2(IntPtr obj, Vector3 pos); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void Translate2(IntPtr obj, Vector3 trans); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void UpdateDeactivation2(IntPtr obj, float timeStep); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool WantsSleeping2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetAngularFactor2(IntPtr obj, float factor); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetAngularFactorV2(IntPtr obj, Vector3 factor); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetAngularFactor2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsInWorld2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void AddConstraintRef2(IntPtr obj, IntPtr constrain); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void RemoveConstraintRef2(IntPtr obj, IntPtr constrain); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr GetConstraintRef2(IntPtr obj, int index); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern int GetNumConstraintRefs2(IntPtr obj); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool SetCollisionGroupMask2(IntPtr body, uint filter, uint mask); + +// ===================================================================================== +// btCollisionShape entries + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetAngularMotionDisc2(IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetContactBreakingThreshold2(IntPtr shape, float defaultFactor); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsPolyhedral2(IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsConvex2d2(IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsConvex2(IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsNonMoving2(IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsConcave2(IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsCompound2(IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsSoftBody2(IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool IsInfinite2(IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetLocalScaling2(IntPtr shape, Vector3 scale); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 GetLocalScaling2(IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern Vector3 CalculateLocalInertia2(IntPtr shape, float mass); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern int GetShapeType2(IntPtr shape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetMargin2(IntPtr shape, float val); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern float GetMargin2(IntPtr shape); + +// ===================================================================================== +// Debugging +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void DumpRigidBody2(IntPtr sim, IntPtr collisionObject); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void DumpCollisionShape2(IntPtr sim, IntPtr collisionShape); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void DumpMapInfo2(IntPtr sim, IntPtr manInfo); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void DumpConstraint2(IntPtr sim, IntPtr constrain); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void DumpActivationInfo2(IntPtr sim); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void DumpAllInfo2(IntPtr sim); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void DumpPhysicsStatistics2(IntPtr sim); + +} +} diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index d5ab245..328164b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -137,7 +137,7 @@ public sealed class BSCharacter : BSPhysObject private void SetPhysicalProperties() { - BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr); + PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, PhysBody); ZeroMotion(true); ForcePosition = _position; @@ -152,14 +152,14 @@ public sealed class BSCharacter : BSPhysObject // Needs to be reset especially when an avatar is recreated after crossing a region boundry. Flying = _flying; - BulletSimAPI.SetRestitution2(PhysBody.ptr, BSParam.AvatarRestitution); + PhysicsScene.PE.SetRestitution(PhysBody, BSParam.AvatarRestitution); BulletSimAPI.SetMargin2(PhysShape.ptr, PhysicsScene.Params.collisionMargin); BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale); - BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, BSParam.ContactProcessingThreshold); + PhysicsScene.PE.SetContactProcessingThreshold(PhysBody, BSParam.ContactProcessingThreshold); if (BSParam.CcdMotionThreshold > 0f) { - BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, BSParam.CcdMotionThreshold); - BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius); + PhysicsScene.PE.SetCcdMotionThreshold(PhysBody, BSParam.CcdMotionThreshold); + PhysicsScene.PE.SetCcdSweptSphereRadius(PhysBody, BSParam.CcdSweptSphereRadius); } UpdatePhysicalMassProperties(RawMass, false); @@ -167,13 +167,13 @@ public sealed class BSCharacter : BSPhysObject // Make so capsule does not fall over BulletSimAPI.SetAngularFactorV2(PhysBody.ptr, OMV.Vector3.Zero); - BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_CHARACTER_OBJECT); + PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.CF_CHARACTER_OBJECT); - BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr); + PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, PhysBody); - // BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.ACTIVE_TAG); - BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.DISABLE_DEACTIVATION); - BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); + // PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.ACTIVE_TAG); + PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.DISABLE_DEACTIVATION); + PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, PhysBody); // Do this after the object has been added to the world PhysBody.collisionType = CollisionType.Avatar; @@ -320,7 +320,7 @@ public sealed class BSCharacter : BSPhysObject { if (PhysBody.HasPhysicalBody) { - BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero); + PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, OMV.Vector3.Zero); BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero); // The next also get rid of applied linear force but the linear velocity is untouched. BulletSimAPI.ClearForces2(PhysBody.ptr); @@ -350,19 +350,19 @@ public sealed class BSCharacter : BSPhysObject { DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); if (PhysBody.HasPhysicalBody) - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); }); } } public override OMV.Vector3 ForcePosition { get { - _position = BulletSimAPI.GetPosition2(PhysBody.ptr); + _position = PhysicsScene.PE.GetPosition(PhysBody); return _position; } set { _position = value; PositionSanityCheck(); - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); } } @@ -418,7 +418,7 @@ public sealed class BSCharacter : BSPhysObject { DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); if (PhysBody.HasPhysicalBody) - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); }); ret = true; } @@ -520,7 +520,7 @@ public sealed class BSCharacter : BSPhysObject { _currentFriction = BSParam.AvatarStandingFriction; if (PhysBody.HasPhysicalBody) - BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction); + PhysicsScene.PE.SetFriction(PhysBody, _currentFriction); } } else @@ -529,12 +529,12 @@ public sealed class BSCharacter : BSPhysObject { _currentFriction = BSParam.AvatarFriction; if (PhysBody.HasPhysicalBody) - BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction); + PhysicsScene.PE.SetFriction(PhysBody, _currentFriction); } } BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); - BulletSimAPI.Activate2(PhysBody.ptr, true); + PhysicsScene.PE.Activate(PhysBody, true); } } public override OMV.Vector3 Torque { @@ -576,7 +576,7 @@ public sealed class BSCharacter : BSPhysObject { get { - _orientation = BulletSimAPI.GetOrientation2(PhysBody.ptr); + _orientation = PhysicsScene.PE.GetOrientation(PhysBody); return _orientation; } set @@ -584,8 +584,8 @@ public sealed class BSCharacter : BSPhysObject _orientation = value; if (PhysBody.HasPhysicalBody) { - // _position = BulletSimAPI.GetPosition2(BSBody.ptr); - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + // _position = PhysicsScene.PE.GetPosition(BSBody); + PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); } } } @@ -636,9 +636,9 @@ public sealed class BSCharacter : BSPhysObject if (PhysBody.HasPhysicalBody) { if (_floatOnWater) - CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); + CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER); else - CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); + CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER); } }); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs index 59584b2..c9c7c2e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs @@ -37,6 +37,7 @@ public abstract class BSConstraint : IDisposable private static string LogHeader = "[BULLETSIM CONSTRAINT]"; protected BulletWorld m_world; + protected BSScene PhysicsScene; protected BulletBody m_body1; protected BulletBody m_body2; protected BulletConstraint m_constraint; @@ -48,8 +49,10 @@ public abstract class BSConstraint : IDisposable public abstract ConstraintType Type { get; } public bool IsEnabled { get { return m_enabled; } } - public BSConstraint() + public BSConstraint(BulletWorld world) { + m_world = world; + PhysicsScene = m_world.physicsScene; } public virtual void Dispose() @@ -59,7 +62,7 @@ public abstract class BSConstraint : IDisposable m_enabled = false; if (m_constraint.HasPhysicalConstraint) { - bool success = BulletSimAPI.DestroyConstraint2(m_world.ptr, m_constraint.ptr); + bool success = PhysicsScene.PE.DestroyConstraint(m_world, m_constraint); m_world.physicsScene.DetailLog("{0},BSConstraint.Dispose,taint,id1={1},body1={2},id2={3},body2={4},success={5}", BSScene.DetailLogZero, m_body1.ID, m_body1.ptr.ToString("X"), @@ -74,7 +77,7 @@ public abstract class BSConstraint : IDisposable { bool ret = false; if (m_enabled) - ret = BulletSimAPI.SetLinearLimits2(m_constraint.ptr, low, high); + ret = PhysicsScene.PE.SetLinearLimits(m_constraint, low, high); return ret; } @@ -82,7 +85,7 @@ public abstract class BSConstraint : IDisposable { bool ret = false; if (m_enabled) - ret = BulletSimAPI.SetAngularLimits2(m_constraint.ptr, low, high); + ret = PhysicsScene.PE.SetAngularLimits(m_constraint, low, high); return ret; } @@ -91,7 +94,7 @@ public abstract class BSConstraint : IDisposable bool ret = false; if (m_enabled) { - BulletSimAPI.SetConstraintNumSolverIterations2(m_constraint.ptr, cnt); + PhysicsScene.PE.SetConstraintNumSolverIterations(m_constraint, cnt); ret = true; } return ret; @@ -103,7 +106,7 @@ public abstract class BSConstraint : IDisposable if (m_enabled) { // Recompute the internal transforms - BulletSimAPI.CalculateTransforms2(m_constraint.ptr); + PhysicsScene.PE.CalculateTransforms(m_constraint); ret = true; } return ret; @@ -122,7 +125,7 @@ public abstract class BSConstraint : IDisposable // Setting an object's mass to zero (making it static like when it's selected) // automatically disables the constraints. // If the link is enabled, be sure to set the constraint itself to enabled. - BulletSimAPI.SetConstraintEnable2(m_constraint.ptr, BSParam.NumericBool(true)); + PhysicsScene.PE.SetConstraintEnable(m_constraint, BSParam.NumericBool(true)); } else { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs index b946870..aee93c9 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs @@ -43,15 +43,14 @@ public sealed class BSConstraint6Dof : BSConstraint Vector3 frame1, Quaternion frame1rot, Vector3 frame2, Quaternion frame2rot, bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) + : base(world) { - m_world = world; m_body1 = obj1; m_body2 = obj2; - m_constraint = new BulletConstraint( - BulletSimAPI.Create6DofConstraint2(m_world.ptr, m_body1.ptr, m_body2.ptr, + m_constraint = PhysicsScene.PE.Create6DofConstraint(m_world, m_body1, m_body2, frame1, frame1rot, frame2, frame2rot, - useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); + useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies); m_enabled = true; world.physicsScene.DetailLog("{0},BS6DofConstraint,createFrame,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}", BSScene.DetailLogZero, world.worldID, @@ -61,8 +60,8 @@ public sealed class BSConstraint6Dof : BSConstraint public BSConstraint6Dof(BulletWorld world, BulletBody obj1, BulletBody obj2, Vector3 joinPoint, bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) + : base(world) { - m_world = world; m_body1 = obj1; m_body2 = obj2; if (!obj1.HasPhysicalBody || !obj2.HasPhysicalBody) @@ -76,11 +75,10 @@ public sealed class BSConstraint6Dof : BSConstraint } else { - m_constraint = new BulletConstraint( - BulletSimAPI.Create6DofConstraintToPoint2(m_world.ptr, m_body1.ptr, m_body2.ptr, + m_constraint = PhysicsScene.PE.Create6DofConstraintToPoint(m_world, m_body1, m_body2, joinPoint, - useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); - world.physicsScene.DetailLog("{0},BS6DofConstraint,createMidPoint,wID={1}, csrt={2}, rID={3}, rBody={4}, cID={5}, cBody={6}", + useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies); + PhysicsScene.DetailLog("{0},BS6DofConstraint,createMidPoint,wID={1}, csrt={2}, rID={3}, rBody={4}, cID={5}, cBody={6}", BSScene.DetailLogZero, world.worldID, m_constraint.ptr.ToString("X"), obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X")); if (!m_constraint.HasPhysicalConstraint) @@ -101,7 +99,7 @@ public sealed class BSConstraint6Dof : BSConstraint bool ret = false; if (m_enabled) { - BulletSimAPI.SetFrames2(m_constraint.ptr, frameA, frameArot, frameB, frameBrot); + PhysicsScene.PE.SetFrames(m_constraint, frameA, frameArot, frameB, frameBrot); ret = true; } return ret; @@ -112,9 +110,9 @@ public sealed class BSConstraint6Dof : BSConstraint bool ret = false; if (m_enabled) { - BulletSimAPI.SetConstraintParam2(m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL); - BulletSimAPI.SetConstraintParam2(m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_ERP, erp, ConstraintParamAxis.AXIS_ALL); - BulletSimAPI.SetConstraintParam2(m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_CFM, cfm, ConstraintParamAxis.AXIS_ALL); + PhysicsScene.PE.SetConstraintParam(m_constraint, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL); + PhysicsScene.PE.SetConstraintParam(m_constraint, ConstraintParams.BT_CONSTRAINT_STOP_ERP, erp, ConstraintParamAxis.AXIS_ALL); + PhysicsScene.PE.SetConstraintParam(m_constraint, ConstraintParams.BT_CONSTRAINT_CFM, cfm, ConstraintParamAxis.AXIS_ALL); ret = true; } return ret; @@ -125,7 +123,7 @@ public sealed class BSConstraint6Dof : BSConstraint bool ret = false; float onOff = useOffset ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse; if (m_enabled) - ret = BulletSimAPI.UseFrameOffset2(m_constraint.ptr, onOff); + ret = PhysicsScene.PE.UseFrameOffset(m_constraint, onOff); return ret; } @@ -135,7 +133,7 @@ public sealed class BSConstraint6Dof : BSConstraint float onOff = enable ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse; if (m_enabled) { - ret = BulletSimAPI.TranslationalLimitMotor2(m_constraint.ptr, onOff, targetVelocity, maxMotorForce); + ret = PhysicsScene.PE.TranslationalLimitMotor(m_constraint, onOff, targetVelocity, maxMotorForce); m_world.physicsScene.DetailLog("{0},BS6DOFConstraint,TransLimitMotor,enable={1},vel={2},maxForce={3}", BSScene.DetailLogZero, enable, targetVelocity, maxMotorForce); } @@ -146,7 +144,7 @@ public sealed class BSConstraint6Dof : BSConstraint { bool ret = false; if (m_enabled) - ret = BulletSimAPI.SetBreakingImpulseThreshold2(m_constraint.ptr, threshold); + ret = PhysicsScene.PE.SetBreakingImpulseThreshold(m_constraint, threshold); return ret; } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintHinge.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintHinge.cs index a5378b9..7714a03 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintHinge.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintHinge.cs @@ -40,15 +40,13 @@ public sealed class BSConstraintHinge : BSConstraint Vector3 pivotInA, Vector3 pivotInB, Vector3 axisInA, Vector3 axisInB, bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) + : base(world) { - m_world = world; m_body1 = obj1; m_body2 = obj2; - m_constraint = new BulletConstraint( - BulletSimAPI.CreateHingeConstraint2(m_world.ptr, m_body1.ptr, m_body2.ptr, - pivotInA, pivotInB, - axisInA, axisInB, - useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); + m_constraint = PhysicsScene.PE.CreateHingeConstraint(world, obj1, obj2, + pivotInA, pivotInB, axisInA, axisInB, + useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies); m_enabled = true; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 0bdfbe3..5d70ef7 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -558,7 +558,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Friction affects are handled by this vehicle code float friction = 0f; - BulletSimAPI.SetFriction2(Prim.PhysBody.ptr, friction); + PhysicsScene.PE.SetFriction(Prim.PhysBody, friction); // Moderate angular movement introduced by Bullet. // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle. @@ -567,7 +567,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, angularDamping); // Vehicles report collision events so we know when it's on the ground - BulletSimAPI.AddToCollisionFlags2(Prim.PhysBody.ptr, CollisionFlags.BS_VEHICLE_COLLISIONS); + PhysicsScene.PE.AddToCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(Prim.PhysShape.ptr, m_vehicleMass); BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia); @@ -581,7 +581,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin } else { - BulletSimAPI.RemoveFromCollisionFlags2(Prim.PhysBody.ptr, CollisionFlags.BS_VEHICLE_COLLISIONS); + PhysicsScene.PE.RemoveFromCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); } } @@ -651,7 +651,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin if ((m_knownChanged & m_knownChangedVelocity) != 0) { Prim.ForceVelocity = m_knownVelocity; - BulletSimAPI.SetInterpolationLinearVelocity2(Prim.PhysBody.ptr, VehicleVelocity); + PhysicsScene.PE.SetInterpolationLinearVelocity(Prim.PhysBody, VehicleVelocity); } if ((m_knownChanged & m_knownChangedForce) != 0) @@ -661,7 +661,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { Prim.ForceRotationalVelocity = m_knownRotationalVelocity; // Fake out Bullet by making it think the velocity is the same as last time. - BulletSimAPI.SetInterpolationAngularVelocity2(Prim.PhysBody.ptr, m_knownRotationalVelocity); + PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity); } if ((m_knownChanged & m_knownChangedRotationalForce) != 0) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 9bb951c..3c99ca7 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -131,10 +131,10 @@ public sealed class BSLinksetCompound : BSLinkset { // The origional prims are removed from the world as the shape of the root compound // shape takes over. - BulletSimAPI.AddToCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); - BulletSimAPI.ForceActivationState2(child.PhysBody.ptr, ActivationState.DISABLE_SIMULATION); + PhysicsScene.PE.AddToCollisionFlags(child.PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE); + PhysicsScene.PE.ForceActivationState(child.PhysBody, ActivationState.DISABLE_SIMULATION); // We don't want collisions from the old linkset children. - BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + PhysicsScene.PE.RemoveFromCollisionFlags(child.PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); child.PhysBody.collisionType = CollisionType.LinksetChild; @@ -159,12 +159,12 @@ public sealed class BSLinksetCompound : BSLinkset else { // The non-physical children can come back to life. - BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); + PhysicsScene.PE.RemoveFromCollisionFlags(child.PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE); child.PhysBody.collisionType = CollisionType.LinksetChild; // Don't force activation so setting of DISABLE_SIMULATION can stay if used. - BulletSimAPI.Activate2(child.PhysBody.ptr, false); + PhysicsScene.PE.Activate(child.PhysBody, false); ret = true; } return ret; @@ -371,7 +371,7 @@ public sealed class BSLinksetCompound : BSLinkset PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); } - PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); + PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); } } return false; // 'false' says to move onto the next child in the list diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 5c8553a..c6c2946 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -300,7 +300,7 @@ public static class BSParam (s,cf,p,v) => { DeactivationTime = cf.GetFloat(p, v); }, (s) => { return DeactivationTime; }, (s,p,l,v) => { s.UpdateParameterObject((x)=>{DeactivationTime=x;}, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetDeactivationTime2(o.PhysBody.ptr, v); } ), + (s,o,v) => { s.PE.SetDeactivationTime(o.PhysBody, v); } ), new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static", 0.8f, (s,cf,p,v) => { LinearSleepingThreshold = cf.GetFloat(p, v); }, @@ -318,19 +318,19 @@ public static class BSParam (s,cf,p,v) => { CcdMotionThreshold = cf.GetFloat(p, v); }, (s) => { return CcdMotionThreshold; }, (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdMotionThreshold=x;}, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetCcdMotionThreshold2(o.PhysBody.ptr, v); } ), + (s,o,v) => { s.PE.SetCcdMotionThreshold(o.PhysBody, v); } ), new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" , 0f, (s,cf,p,v) => { CcdSweptSphereRadius = cf.GetFloat(p, v); }, (s) => { return CcdSweptSphereRadius; }, (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdSweptSphereRadius=x;}, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetCcdSweptSphereRadius2(o.PhysBody.ptr, v); } ), + (s,o,v) => { s.PE.SetCcdSweptSphereRadius(o.PhysBody, v); } ), new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" , 0.1f, (s,cf,p,v) => { ContactProcessingThreshold = cf.GetFloat(p, v); }, (s) => { return ContactProcessingThreshold; }, (s,p,l,v) => { s.UpdateParameterObject((x)=>{ContactProcessingThreshold=x;}, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetContactProcessingThreshold2(o.PhysBody.ptr, v); } ), + (s,o,v) => { s.PE.SetContactProcessingThreshold(o.PhysBody, v); } ), new ParameterDefn("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)", (float)BSTerrainPhys.TerrainImplementation.Mesh, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index b093890..e7cb3e0 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -308,7 +308,7 @@ public abstract class BSPhysObject : PhysicsActor PhysicsScene.TaintedObject(TypeName+".SubscribeEvents", delegate() { if (PhysBody.HasPhysicalBody) - CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); }); } else @@ -324,7 +324,7 @@ public abstract class BSPhysObject : PhysicsActor { // Make sure there is a body there because sometimes destruction happens in an un-ideal order. if (PhysBody.HasPhysicalBody) - CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); }); } // Return 'true' if the simulator wants collision events diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index cf09be2..613606f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -120,7 +120,7 @@ public sealed class BSPrim : BSPhysObject { CreateGeomAndObject(true); - CurrentCollisionFlags = BulletSimAPI.GetCollisionFlags2(PhysBody.ptr); + CurrentCollisionFlags = PhysicsScene.PE.GetCollisionFlags(PhysBody); }); } @@ -265,7 +265,7 @@ public sealed class BSPrim : BSPhysObject // DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity); if (PhysBody.HasPhysicalBody) { - BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, _rotationalVelocity); + PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, _rotationalVelocity); BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity); } }); @@ -318,14 +318,14 @@ public sealed class BSPrim : BSPhysObject } public override OMV.Vector3 ForcePosition { get { - _position = BulletSimAPI.GetPosition2(PhysBody.ptr); + _position = PhysicsScene.PE.GetPosition(PhysBody); return _position; } set { _position = value; if (PhysBody.HasPhysicalBody) { - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); ActivateIfPhysical(false); } } @@ -419,7 +419,7 @@ public sealed class BSPrim : BSPhysObject // Changing interesting properties doesn't change proxy and collision cache // information. The Bullet solution is to re-add the object to the world // after parameters are changed. - BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr); + PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, PhysBody); } // The computation of mass props requires gravity to be set on the object. @@ -649,9 +649,9 @@ public sealed class BSPrim : BSPhysObject { if (PhysBody.HasPhysicalBody) { - // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr); + // _position = PhysicsScene.PE.GetObjectPosition(PhysicsScene.World, BSBody); // DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); } }); } @@ -661,13 +661,13 @@ public sealed class BSPrim : BSPhysObject { get { - _orientation = BulletSimAPI.GetOrientation2(PhysBody.ptr); + _orientation = PhysicsScene.PE.GetOrientation(PhysBody); return _orientation; } set { _orientation = value; - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); } } public override int PhysicsActorType { @@ -723,7 +723,7 @@ public sealed class BSPrim : BSPhysObject // 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). - BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr); + PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, PhysBody); // Set up the object physicalness (does gravity and collisions move this object) MakeDynamic(IsStatic); @@ -740,7 +740,7 @@ public sealed class BSPrim : BSPhysObject AddObjectToPhysicalWorld(); // Rebuild its shape - BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); + PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, PhysBody); // Recompute any linkset parameters. // When going from non-physical to physical, this re-enables the constraints that @@ -762,28 +762,28 @@ public sealed class BSPrim : BSPhysObject if (makeStatic) { // Become a Bullet 'static' object type - CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT); + CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.CF_STATIC_OBJECT); // Stop all movement ZeroMotion(true); // Set various physical properties so other object interact properly MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false); - BulletSimAPI.SetFriction2(PhysBody.ptr, matAttrib.friction); - BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution); + PhysicsScene.PE.SetFriction(PhysBody, matAttrib.friction); + PhysicsScene.PE.SetRestitution(PhysBody, matAttrib.restitution); // Mass is zero which disables a bunch of physics stuff in Bullet UpdatePhysicalMassProperties(0f, false); // Set collision detection parameters if (BSParam.CcdMotionThreshold > 0f) { - BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, BSParam.CcdMotionThreshold); - BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius); + PhysicsScene.PE.SetCcdMotionThreshold(PhysBody, BSParam.CcdMotionThreshold); + PhysicsScene.PE.SetCcdSweptSphereRadius(PhysBody, BSParam.CcdSweptSphereRadius); } // The activation state is 'disabled' so Bullet will not try to act on it. - // BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.DISABLE_SIMULATION); + // PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.DISABLE_SIMULATION); // Start it out sleeping and physical actions could wake it up. - BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ISLAND_SLEEPING); + PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.ISLAND_SLEEPING); // This collides like a static object PhysBody.collisionType = CollisionType.Static; @@ -794,22 +794,22 @@ public sealed class BSPrim : BSPhysObject else { // Not a Bullet static object - CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT); + CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.CF_STATIC_OBJECT); // Set various physical properties so other object interact properly MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, true); - BulletSimAPI.SetFriction2(PhysBody.ptr, matAttrib.friction); - BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution); + PhysicsScene.PE.SetFriction(PhysBody, matAttrib.friction); + PhysicsScene.PE.SetRestitution(PhysBody, matAttrib.restitution); // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382 // Since this can be called multiple times, only zero forces when becoming physical - // BulletSimAPI.ClearAllForces2(BSBody.ptr); + // PhysicsScene.PE.ClearAllForces(BSBody); // For good measure, make sure the transform is set through to the motion state - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); + PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); // Center of mass is at the center of the object - // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.PhysBody.ptr, _position, _orientation); + // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.PhysBody, _position, _orientation); // A dynamic object has mass UpdatePhysicalMassProperties(RawMass, false); @@ -817,22 +817,22 @@ public sealed class BSPrim : BSPhysObject // Set collision detection parameters if (BSParam.CcdMotionThreshold > 0f) { - BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, BSParam.CcdMotionThreshold); - BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius); + PhysicsScene.PE.SetCcdMotionThreshold(PhysBody, BSParam.CcdMotionThreshold); + PhysicsScene.PE.SetCcdSweptSphereRadius(PhysBody, BSParam.CcdSweptSphereRadius); } // Various values for simulation limits BulletSimAPI.SetDamping2(PhysBody.ptr, BSParam.LinearDamping, BSParam.AngularDamping); - BulletSimAPI.SetDeactivationTime2(PhysBody.ptr, BSParam.DeactivationTime); + PhysicsScene.PE.SetDeactivationTime(PhysBody, BSParam.DeactivationTime); BulletSimAPI.SetSleepingThresholds2(PhysBody.ptr, BSParam.LinearSleepingThreshold, BSParam.AngularSleepingThreshold); - BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, BSParam.ContactProcessingThreshold); + PhysicsScene.PE.SetContactProcessingThreshold(PhysBody, BSParam.ContactProcessingThreshold); // This collides like an object. PhysBody.collisionType = CollisionType.Dynamic; // Force activation of the object so Bullet will act on it. // Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects. - BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ACTIVE_TAG); + PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.ACTIVE_TAG); // There might be special things needed for implementing linksets. Linkset.MakeDynamic(this); @@ -853,7 +853,7 @@ public sealed class BSPrim : BSPhysObject { m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for solidity. id={1}, type={2}", LogHeader, LocalID, bodyType); } - CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); + CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE); } else { @@ -861,7 +861,7 @@ public sealed class BSPrim : BSPhysObject { m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for non-solidness. id={1}, type={2}", LogHeader, LocalID, bodyType); } - CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); + CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE); // Change collision info from a static object to a ghosty collision object PhysBody.collisionType = CollisionType.VolumeDetect; @@ -874,7 +874,7 @@ public sealed class BSPrim : BSPhysObject private void ActivateIfPhysical(bool forceIt) { if (IsPhysical && PhysBody.HasPhysicalBody) - BulletSimAPI.Activate2(PhysBody.ptr, forceIt); + PhysicsScene.PE.Activate(PhysBody, forceIt); } // Turn on or off the flag controlling whether collision events are returned to the simulator. @@ -882,11 +882,11 @@ public sealed class BSPrim : BSPhysObject { if (wantsCollisionEvents) { - CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); } else { - CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); + CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); } } @@ -897,7 +897,7 @@ public sealed class BSPrim : BSPhysObject { if (PhysBody.HasPhysicalBody) { - BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr); + PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, PhysBody); // TODO: Fix this. Total kludge because adding object to world resets its gravity to default. // Replace this when the new AddObjectToWorld function is complete. @@ -941,9 +941,9 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject("BSPrim.setFloatOnWater", delegate() { if (_floatOnWater) - CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); + CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER); else - CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); + CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER); }); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index e7d8d14..6f819d8 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -143,7 +143,7 @@ public sealed class BSShapeCollection : IDisposable { if (!BulletSimAPI.IsInWorld2(body.ptr)) { - BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, body.ptr); + PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, body); if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", body.ID, body); } }); @@ -168,12 +168,12 @@ public sealed class BSShapeCollection : IDisposable if (BulletSimAPI.IsInWorld2(body.ptr)) { - BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr); + PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, body); if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,removingFromWorld. Body={1}", body.ID, body); } // Zero any reference to the shape so it is not freed when the body is deleted. - BulletSimAPI.SetCollisionShape2(PhysicsScene.World.ptr, body.ptr, IntPtr.Zero); + PhysicsScene.PE.SetCollisionShape(PhysicsScene.World, body, new BulletShape()); PhysicsScene.PE.DestroyObject(PhysicsScene.World, body); }); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs index a2c085e..01966c0 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs @@ -91,13 +91,12 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys // Using the information in m_mapInfo, create the physical representation of the heightmap. private void BuildHeightmapTerrain() { - m_mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, m_mapInfo.ID, + m_mapInfo.Ptr = PhysicsScene.PE.CreateHeightMapInfo(PhysicsScene.World, m_mapInfo.ID, m_mapInfo.minCoords, m_mapInfo.maxCoords, m_mapInfo.heightMap, BSParam.TerrainCollisionMargin); // Create the terrain shape from the mapInfo - m_mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(m_mapInfo.Ptr), - BSPhysicsShapeType.SHAPE_TERRAIN); + m_mapInfo.terrainShape = PhysicsScene.PE.CreateTerrainShape(m_mapInfo.Ptr); // The terrain object initial position is at the center of the object Vector3 centerPos; @@ -109,22 +108,22 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys m_mapInfo.ID, centerPos, Quaternion.Identity); // Set current terrain attributes - BulletSimAPI.SetFriction2(m_mapInfo.terrainBody.ptr, BSParam.TerrainFriction); - BulletSimAPI.SetHitFraction2(m_mapInfo.terrainBody.ptr, BSParam.TerrainHitFraction); - BulletSimAPI.SetRestitution2(m_mapInfo.terrainBody.ptr, BSParam.TerrainRestitution); - BulletSimAPI.SetCollisionFlags2(m_mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); + PhysicsScene.PE.SetFriction(m_mapInfo.terrainBody, BSParam.TerrainFriction); + PhysicsScene.PE.SetHitFraction(m_mapInfo.terrainBody, BSParam.TerrainHitFraction); + PhysicsScene.PE.SetRestitution(m_mapInfo.terrainBody, BSParam.TerrainRestitution); + PhysicsScene.PE.SetCollisionFlags(m_mapInfo.terrainBody, CollisionFlags.CF_STATIC_OBJECT); // Return the new terrain to the world of physical objects - BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); + PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, m_mapInfo.terrainBody); // redo its bounding box now that it is in the world - BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); + PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, m_mapInfo.terrainBody); m_mapInfo.terrainBody.collisionType = CollisionType.Terrain; m_mapInfo.terrainBody.ApplyCollisionMask(); // Make it so the terrain will not move or be considered for movement. - BulletSimAPI.ForceActivationState2(m_mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION); + PhysicsScene.PE.ForceActivationState(m_mapInfo.terrainBody, ActivationState.DISABLE_SIMULATION); return; } @@ -136,10 +135,10 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys { if (m_mapInfo.terrainBody.HasPhysicalBody) { - BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); + PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, m_mapInfo.terrainBody); // Frees both the body and the shape. PhysicsScene.PE.DestroyObject(PhysicsScene.World, m_mapInfo.terrainBody); - BulletSimAPI.ReleaseHeightMapInfo2(m_mapInfo.Ptr); + PhysicsScene.PE.ReleaseHeightMapInfo(m_mapInfo.Ptr); } } m_mapInfo = null; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index d99a50f..590c687 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -133,17 +133,14 @@ public sealed class BSTerrainManager : IDisposable public void CreateInitialGroundPlaneAndTerrain() { // The ground plane is here to catch things that are trying to drop to negative infinity - BulletShape groundPlaneShape = new BulletShape( - BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, - BSParam.TerrainCollisionMargin), - BSPhysicsShapeType.SHAPE_GROUNDPLANE); + BulletShape groundPlaneShape = PhysicsScene.PE.CreateGroundPlaneShape(BSScene.GROUNDPLANE_ID, 1f, BSParam.TerrainCollisionMargin); m_groundPlane = PhysicsScene.PE.CreateBodyWithDefaultMotionState(groundPlaneShape, BSScene.GROUNDPLANE_ID, Vector3.Zero, Quaternion.Identity); - BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr); - BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_groundPlane.ptr); + PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, m_groundPlane); + PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, m_groundPlane); // Ground plane does not move - BulletSimAPI.ForceActivationState2(m_groundPlane.ptr, ActivationState.DISABLE_SIMULATION); + PhysicsScene.PE.ForceActivationState(m_groundPlane, ActivationState.DISABLE_SIMULATION); // Everything collides with the ground plane. m_groundPlane.collisionType = CollisionType.Groundplane; m_groundPlane.ApplyCollisionMask(); @@ -158,7 +155,7 @@ public sealed class BSTerrainManager : IDisposable { if (m_groundPlane.HasPhysicalBody) { - if (BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr)) + if (PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, m_groundPlane)) { PhysicsScene.PE.DestroyObject(PhysicsScene.World, m_groundPlane); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index d8c4972..2f55fc3 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs @@ -114,32 +114,32 @@ public sealed class BSTerrainMesh : BSTerrainPhys } // Set current terrain attributes - BulletSimAPI.SetFriction2(m_terrainBody.ptr, BSParam.TerrainFriction); - BulletSimAPI.SetHitFraction2(m_terrainBody.ptr, BSParam.TerrainHitFraction); - BulletSimAPI.SetRestitution2(m_terrainBody.ptr, BSParam.TerrainRestitution); - BulletSimAPI.SetCollisionFlags2(m_terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); + PhysicsScene.PE.SetFriction(m_terrainBody, BSParam.TerrainFriction); + PhysicsScene.PE.SetHitFraction(m_terrainBody, BSParam.TerrainHitFraction); + PhysicsScene.PE.SetRestitution(m_terrainBody, BSParam.TerrainRestitution); + PhysicsScene.PE.SetCollisionFlags(m_terrainBody, CollisionFlags.CF_STATIC_OBJECT); // Static objects are not very massive. BulletSimAPI.SetMassProps2(m_terrainBody.ptr, 0f, Vector3.Zero); // Put the new terrain to the world of physical objects - BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr); + PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, m_terrainBody); // Redo its bounding box now that it is in the world - BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr); + PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, m_terrainBody); m_terrainBody.collisionType = CollisionType.Terrain; m_terrainBody.ApplyCollisionMask(); // Make it so the terrain will not move or be considered for movement. - BulletSimAPI.ForceActivationState2(m_terrainBody.ptr, ActivationState.DISABLE_SIMULATION); + PhysicsScene.PE.ForceActivationState(m_terrainBody, ActivationState.DISABLE_SIMULATION); } public override void Dispose() { if (m_terrainBody.HasPhysicalBody) { - BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr); + PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, m_terrainBody); // Frees both the body and the shape. PhysicsScene.PE.DestroyObject(PhysicsScene.World, m_terrainBody); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 6b76151..b119f22 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs @@ -367,7 +367,6 @@ public abstract void ReleaseBodyInfo(IntPtr obj); public abstract void DestroyObject(BulletWorld sim, BulletBody obj); - /* // ===================================================================================== // Terrain creation and helper routines public abstract IntPtr CreateHeightMapInfo(BulletWorld sim, uint id, Vector3 minCoords, Vector3 maxCoords, @@ -378,9 +377,9 @@ public abstract IntPtr FillHeightMapInfo(BulletWorld sim, IntPtr mapInfo, uint i public abstract bool ReleaseHeightMapInfo(IntPtr heightMapInfo); -public abstract BulletBody CreateGroundPlaneShape(uint id, float height, float collisionMargin); +public abstract BulletShape CreateGroundPlaneShape(uint id, float height, float collisionMargin); -public abstract BulletBody CreateTerrainShape(IntPtr mapInfo); +public abstract BulletShape CreateTerrainShape(IntPtr mapInfo); // ===================================================================================== // Constraint creation and helper routines @@ -460,7 +459,7 @@ public abstract bool IsStaticOrKinematicObject(BulletBody obj); public abstract bool HasContactResponse(BulletBody obj); -public abstract void SetCollisionShape(BulletWorld sim, BulletBody obj, BulletBody shape); +public abstract void SetCollisionShape(BulletWorld sim, BulletBody obj, BulletShape shape); public abstract BulletShape GetCollisionShape(BulletBody obj); @@ -526,6 +525,7 @@ public abstract IntPtr GetUserPointer(BulletBody obj); public abstract void SetUserPointer(BulletBody obj, IntPtr val); + /* // ===================================================================================== // btRigidBody entries public abstract void ApplyGravity(BulletBody obj); -- cgit v1.1 From 5379d6d112a8027c8f0f62ba77303e8b69e24332 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 30 Dec 2012 10:37:37 -0800 Subject: BulletSim: remove all the debug printing of pointer formatting (.ToString(X)) and replace it with a method on BulletBody, BulletShape, ... --- .../Region/Physics/BulletSPlugin/BSConstraint.cs | 4 +-- .../Physics/BulletSPlugin/BSConstraint6Dof.cs | 10 +++---- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 6 ++--- .../Physics/BulletSPlugin/BSLinksetConstraints.cs | 16 +++++------ .../Physics/BulletSPlugin/BSShapeCollection.cs | 8 +++--- OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | 8 +++++- .../Region/Physics/BulletSPlugin/BulletSimData.cs | 31 ++++++++++++++++++++-- 7 files changed, 58 insertions(+), 25 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs index c9c7c2e..b813974 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs @@ -65,8 +65,8 @@ public abstract class BSConstraint : IDisposable bool success = PhysicsScene.PE.DestroyConstraint(m_world, m_constraint); m_world.physicsScene.DetailLog("{0},BSConstraint.Dispose,taint,id1={1},body1={2},id2={3},body2={4},success={5}", BSScene.DetailLogZero, - m_body1.ID, m_body1.ptr.ToString("X"), - m_body2.ID, m_body2.ptr.ToString("X"), + m_body1.ID, m_body1.AddrString, + m_body2.ID, m_body2.AddrString, success); m_constraint.Clear(); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs index aee93c9..ecb1b32 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs @@ -54,7 +54,7 @@ public sealed class BSConstraint6Dof : BSConstraint m_enabled = true; world.physicsScene.DetailLog("{0},BS6DofConstraint,createFrame,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}", BSScene.DetailLogZero, world.worldID, - obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X")); + obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString); } public BSConstraint6Dof(BulletWorld world, BulletBody obj1, BulletBody obj2, @@ -68,9 +68,9 @@ public sealed class BSConstraint6Dof : BSConstraint { world.physicsScene.DetailLog("{0},BS6DOFConstraint,badBodyPtr,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}", BSScene.DetailLogZero, world.worldID, - obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X")); + obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString); world.physicsScene.Logger.ErrorFormat("{0} Attempt to build 6DOF constraint with missing bodies: wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}", - LogHeader, world.worldID, obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X")); + LogHeader, world.worldID, obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString); m_enabled = false; } else @@ -79,8 +79,8 @@ public sealed class BSConstraint6Dof : BSConstraint joinPoint, useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies); PhysicsScene.DetailLog("{0},BS6DofConstraint,createMidPoint,wID={1}, csrt={2}, rID={3}, rBody={4}, cID={5}, cBody={6}", - BSScene.DetailLogZero, world.worldID, m_constraint.ptr.ToString("X"), - obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X")); + BSScene.DetailLogZero, world.worldID, m_constraint.AddrString, + obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString); if (!m_constraint.HasPhysicalConstraint) { world.physicsScene.Logger.ErrorFormat("{0} Failed creation of 6Dof constraint. rootID={1}, childID={2}", diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 3c99ca7..143c60c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -196,7 +196,7 @@ public sealed class BSLinksetCompound : BSLinkset bool ret = false; DetailLog("{0},BSLinksetCompound.RemoveBodyDependencies,refreshIfChild,rID={1},rBody={2},isRoot={3}", - child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), IsRoot(child)); + child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString, IsRoot(child)); if (!IsRoot(child)) { @@ -280,8 +280,8 @@ public sealed class BSLinksetCompound : BSLinkset { DetailLog("{0},BSLinksetCompound.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}", child.LocalID, - LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), - child.LocalID, child.PhysBody.ptr.ToString("X")); + LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString, + child.LocalID, child.PhysBody.AddrString); // Cause the child's body to be rebuilt and thus restored to normal operation RecomputeChildWorldPosition(child, false); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index 86c29c7..629bc72 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -98,7 +98,7 @@ public sealed class BSLinksetConstraints : BSLinkset bool ret = false; DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}", - child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X")); + child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString); lock (m_linksetActivityLock) { @@ -147,8 +147,8 @@ public sealed class BSLinksetConstraints : BSLinkset DetailLog("{0},BSLinksetConstraints.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}", childx.LocalID, - rootx.LocalID, rootx.PhysBody.ptr.ToString("X"), - childx.LocalID, childx.PhysBody.ptr.ToString("X")); + rootx.LocalID, rootx.PhysBody.AddrString, + childx.LocalID, childx.PhysBody.AddrString); PhysicsScene.TaintedObject("BSLinksetConstraints.RemoveChildFromLinkset", delegate() { @@ -187,8 +187,8 @@ public sealed class BSLinksetConstraints : BSLinkset DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", rootPrim.LocalID, - rootPrim.LocalID, rootPrim.PhysBody.ptr.ToString("X"), - childPrim.LocalID, childPrim.PhysBody.ptr.ToString("X"), + rootPrim.LocalID, rootPrim.PhysBody.AddrString, + childPrim.LocalID, childPrim.PhysBody.AddrString, rootPrim.Position, childPrim.Position, midPoint); // create a constraint that allows no freedom of movement between the two objects @@ -252,8 +252,8 @@ public sealed class BSLinksetConstraints : BSLinkset bool ret = false; DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}", rootPrim.LocalID, - rootPrim.LocalID, rootPrim.PhysBody.ptr.ToString("X"), - childPrim.LocalID, childPrim.PhysBody.ptr.ToString("X")); + rootPrim.LocalID, rootPrim.PhysBody.AddrString, + childPrim.LocalID, childPrim.PhysBody.AddrString); // Find the constraint for this link and get rid of it from the overall collection and from my list if (PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody, childPrim.PhysBody)) @@ -290,7 +290,7 @@ public sealed class BSLinksetConstraints : BSLinkset // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}", - LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), linksetMass); + LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString, linksetMass); foreach (BSPhysObject child in m_children) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 6f819d8..d59e455 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -259,7 +259,7 @@ public sealed class BSShapeCollection : IDisposable { // Native shapes are not tracked and are released immediately if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}", - BSScene.DetailLogZero, shape.ptr.ToString("X"), inTaintTime); + BSScene.DetailLogZero, shape.AddrString, inTaintTime); if (shapeCallback != null) shapeCallback(shape); PhysicsScene.PE.DeleteCollisionShape(PhysicsScene.World, shape); } @@ -336,9 +336,9 @@ public sealed class BSShapeCollection : IDisposable { // Failed the sanity check!! PhysicsScene.Logger.ErrorFormat("{0} Attempt to free a compound shape that is not compound!! type={1}, ptr={2}", - LogHeader, shape.type, shape.ptr.ToString("X")); + LogHeader, shape.type, shape.AddrString); if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceCompound,notACompoundShape,type={1},ptr={2}", - BSScene.DetailLogZero, shape.type, shape.ptr.ToString("X")); + BSScene.DetailLogZero, shape.type, shape.AddrString); return; } @@ -400,7 +400,7 @@ public sealed class BSShapeCollection : IDisposable else { PhysicsScene.Logger.ErrorFormat("{0} Could not decypher shape type. Region={1}, addr={2}", - LogHeader, PhysicsScene.RegionName, cShape.ToString("X")); + LogHeader, PhysicsScene.RegionName, shapeInfo.AddrString); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs index cdaa869..423e700 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs @@ -91,11 +91,17 @@ public abstract class BSShape // All shapes have a static call to get a reference to the physical shape // protected abstract static BSShape GetReference(); + // Returns a string for debugging that uniquily identifies the memory used by this instance + public string AddrString + { + get { return ptr.ToString("X"); } + } + public override string ToString() { StringBuilder buff = new StringBuilder(); buff.Append(""); @@ -124,11 +133,20 @@ public class BulletShape } public bool HasPhysicalShape { get { return ptr != IntPtr.Zero; } } + // Used for log messages for a unique display of the memory/object allocated to this instance + public string AddrString + { + get + { + return ptr.ToString("X"); + } + } + public override string ToString() { StringBuilder buff = new StringBuilder(); buff.Append(" 0f) { @@ -165,19 +165,19 @@ public sealed class BSCharacter : BSPhysObject UpdatePhysicalMassProperties(RawMass, false); // Make so capsule does not fall over - BulletSimAPI.SetAngularFactorV2(PhysBody.ptr, OMV.Vector3.Zero); + PhysicsScene.PE.SetAngularFactorV(PhysBody, OMV.Vector3.Zero); PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.CF_CHARACTER_OBJECT); PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, PhysBody); - // PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.ACTIVE_TAG); + // PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.ACTIVE_TAG); PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.DISABLE_DEACTIVATION); PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, PhysBody); // Do this after the object has been added to the world PhysBody.collisionType = CollisionType.Avatar; - PhysBody.ApplyCollisionMask(); + PhysBody.ApplyCollisionMask(PhysicsScene); } // The avatar's movement is controlled by this motor that speeds up and slows down @@ -265,10 +265,10 @@ public sealed class BSCharacter : BSPhysObject { if (PhysBody.HasPhysicalBody && PhysShape.HasPhysicalShape) { - BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale); + PhysicsScene.PE.SetLocalScaling(PhysShape, Scale); UpdatePhysicalMassProperties(RawMass, true); // Make sure this change appears as a property update event - BulletSimAPI.PushUpdate2(PhysBody.ptr); + PhysicsScene.PE.PushUpdate(PhysBody); } }); @@ -309,7 +309,7 @@ public sealed class BSCharacter : BSPhysObject PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate() { if (PhysBody.HasPhysicalBody) - BulletSimAPI.ClearAllForces2(PhysBody.ptr); + PhysicsScene.PE.ClearAllForces(PhysBody); }); } public override void ZeroAngularMotion(bool inTaintTime) @@ -321,9 +321,9 @@ public sealed class BSCharacter : BSPhysObject if (PhysBody.HasPhysicalBody) { PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, OMV.Vector3.Zero); - BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero); + PhysicsScene.PE.SetAngularVelocity(PhysBody, OMV.Vector3.Zero); // The next also get rid of applied linear force but the linear velocity is untouched. - BulletSimAPI.ClearForces2(PhysBody.ptr); + PhysicsScene.PE.ClearForces(PhysBody); } }); } @@ -339,7 +339,7 @@ public sealed class BSCharacter : BSPhysObject public override OMV.Vector3 Position { get { // Don't refetch the position because this function is called a zillion times - // _position = BulletSimAPI.GetObjectPosition2(Scene.World.ptr, LocalID); + // _position = PhysicsScene.PE.GetObjectPosition(Scene.World, LocalID); return _position; } set { @@ -433,8 +433,8 @@ public sealed class BSCharacter : BSPhysObject } public override void UpdatePhysicalMassProperties(float physMass, bool inWorld) { - OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass); - BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, localInertia); + OMV.Vector3 localInertia = PhysicsScene.PE.CalculateLocalInertia(PhysShape, physMass); + PhysicsScene.PE.SetMassProps(PhysBody, physMass, localInertia); } public override OMV.Vector3 Force { @@ -446,7 +446,7 @@ public sealed class BSCharacter : BSPhysObject { DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force); if (PhysBody.HasPhysicalBody) - BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force); + PhysicsScene.PE.SetObjectForce(PhysBody, _force); }); } } @@ -533,7 +533,7 @@ public sealed class BSCharacter : BSPhysObject } } - BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); + PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity); PhysicsScene.PE.Activate(PhysBody, true); } } @@ -676,7 +676,7 @@ public sealed class BSCharacter : BSPhysObject // Buoyancy is faked by changing the gravity applied to the object float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); if (PhysBody.HasPhysicalBody) - BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav)); + PhysicsScene.PE.SetGravity(PhysBody, new OMV.Vector3(0f, 0f, grav)); } } @@ -737,7 +737,7 @@ public sealed class BSCharacter : BSPhysObject // DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce); if (PhysBody.HasPhysicalBody) { - BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, addForce); + PhysicsScene.PE.ApplyCentralForce(PhysBody, addForce); } }); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 5d70ef7..e4e3edc 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -564,17 +564,17 @@ namespace OpenSim.Region.Physics.BulletSPlugin // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle. // Maybe compute linear and angular factor and damping from params. float angularDamping = BSParam.VehicleAngularDamping; - BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, angularDamping); + PhysicsScene.PE.SetAngularDamping(Prim.PhysBody, angularDamping); // Vehicles report collision events so we know when it's on the ground PhysicsScene.PE.AddToCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); - Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(Prim.PhysShape.ptr, m_vehicleMass); - BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia); - BulletSimAPI.UpdateInertiaTensor2(Prim.PhysBody.ptr); + Vector3 localInertia = PhysicsScene.PE.CalculateLocalInertia(Prim.PhysShape, m_vehicleMass); + PhysicsScene.PE.SetMassProps(Prim.PhysBody, m_vehicleMass, localInertia); + PhysicsScene.PE.UpdateInertiaTensor(Prim.PhysBody); Vector3 grav = PhysicsScene.DefaultGravity * (1f - Prim.Buoyancy); - BulletSimAPI.SetGravity2(Prim.PhysBody.ptr, grav); + PhysicsScene.PE.SetGravity(Prim.PhysBody, grav); VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4}", Prim.LocalID, m_vehicleMass, friction, localInertia, angularDamping); @@ -669,7 +669,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // If we set one of the values (ie, the physics engine didn't do it) we must force // an UpdateProperties event to send the changes up to the simulator. - BulletSimAPI.PushUpdate2(Prim.PhysBody.ptr); + PhysicsScene.PE.PushUpdate(Prim.PhysBody); } m_knownChanged = 0; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 143c60c..bd03d31 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -387,11 +387,6 @@ public sealed class BSLinksetCompound : BSLinkset } PhysicsScene.PE.RecalculateCompoundShapeLocalAabb(LinksetRoot.PhysShape); - - // DEBUG: see of inter-linkset collisions are causing problems for constraint linksets. - // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, - // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); - } } } \ No newline at end of file diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index 629bc72..d0b2a56 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -259,7 +259,7 @@ public sealed class BSLinksetConstraints : BSLinkset if (PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody, childPrim.PhysBody)) { // Make the child refresh its location - BulletSimAPI.PushUpdate2(childPrim.PhysBody.ptr); + PhysicsScene.PE.PushUpdate(childPrim.PhysBody); ret = true; } @@ -286,9 +286,6 @@ public sealed class BSLinksetConstraints : BSLinkset float linksetMass = LinksetMass; LinksetRoot.UpdatePhysicalMassProperties(linksetMass, true); - // DEBUG: see of inter-linkset collisions are causing problems - // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, - // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}", LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString, linksetMass); @@ -307,11 +304,7 @@ public sealed class BSLinksetConstraints : BSLinkset } constrain.RecomputeConstraintVariables(linksetMass); - // DEBUG: see of inter-linkset collisions are causing problems - // BulletSimAPI.SetCollisionFilterMask2(child.BSBody.ptr, - // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); - - // BulletSimAPI.DumpConstraint2(PhysicsScene.World.ptr, constrain.Constraint.ptr); // DEBUG DEBUG + // PhysicsScene.PE.DumpConstraint(PhysicsScene.World, constrain.Constraint); // DEBUG DEBUG } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index c6c2946..339722e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -280,7 +280,7 @@ public static class BSParam (s,cf,p,v) => { s.UnmanagedParams[0].gravity = cf.GetFloat(p, v); }, (s) => { return s.UnmanagedParams[0].gravity; }, (s,p,l,v) => { s.UpdateParameterObject((x)=>{s.UnmanagedParams[0].gravity=x;}, p, PhysParameterEntry.APPLY_TO_NONE, v); }, - (s,o,v) => { BulletSimAPI.SetGravity2(s.World.ptr, new Vector3(0f,0f,v)); } ), + (s,o,v) => { s.PE.SetGravity(o.PhysBody, new Vector3(0f,0f,v)); } ), new ParameterDefn("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)", @@ -288,13 +288,13 @@ public static class BSParam (s,cf,p,v) => { LinearDamping = cf.GetFloat(p, v); }, (s) => { return LinearDamping; }, (s,p,l,v) => { s.UpdateParameterObject((x)=>{LinearDamping=x;}, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, v, AngularDamping); } ), + (s,o,v) => { s.PE.SetDamping(o.PhysBody, v, AngularDamping); } ), new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)", 0f, (s,cf,p,v) => { AngularDamping = cf.GetFloat(p, v); }, (s) => { return AngularDamping; }, (s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularDamping=x;}, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, LinearDamping, v); } ), + (s,o,v) => { s.PE.SetDamping(o.PhysBody, LinearDamping, v); } ), new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static", 0.2f, (s,cf,p,v) => { DeactivationTime = cf.GetFloat(p, v); }, @@ -306,13 +306,13 @@ public static class BSParam (s,cf,p,v) => { LinearSleepingThreshold = cf.GetFloat(p, v); }, (s) => { return LinearSleepingThreshold; }, (s,p,l,v) => { s.UpdateParameterObject((x)=>{LinearSleepingThreshold=x;}, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ), + (s,o,v) => { s.PE.SetSleepingThresholds(o.PhysBody, v, v); } ), new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static", 1.0f, (s,cf,p,v) => { AngularSleepingThreshold = cf.GetFloat(p, v); }, (s) => { return AngularSleepingThreshold; }, (s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularSleepingThreshold=x;}, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ), + (s,o,v) => { s.PE.SetSleepingThresholds(o.PhysBody, v, v); } ), new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" , 0f, // set to zero to disable (s,cf,p,v) => { CcdMotionThreshold = cf.GetFloat(p, v); }, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 613606f..064ce3c 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -253,7 +253,7 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate() { if (PhysBody.HasPhysicalBody) - BulletSimAPI.ClearAllForces2(PhysBody.ptr); + PhysicsScene.PE.ClearAllForces(PhysBody); }); } public override void ZeroAngularMotion(bool inTaintTime) @@ -266,7 +266,7 @@ public sealed class BSPrim : BSPhysObject if (PhysBody.HasPhysicalBody) { PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, _rotationalVelocity); - BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity); + PhysicsScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity); } }); } @@ -292,7 +292,7 @@ public sealed class BSPrim : BSPhysObject */ // don't do the GetObjectPosition for root elements because this function is called a zillion times. - // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr); + // _position = PhysicsScene.PE.GetObjectPosition2(PhysicsScene.World, BSBody); return _position; } set { @@ -405,10 +405,10 @@ public sealed class BSPrim : BSPhysObject { if (IsStatic) { - BulletSimAPI.SetGravity2(PhysBody.ptr, PhysicsScene.DefaultGravity); + PhysicsScene.PE.SetGravity(PhysBody, PhysicsScene.DefaultGravity); Inertia = OMV.Vector3.Zero; - BulletSimAPI.SetMassProps2(PhysBody.ptr, 0f, Inertia); - BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); + PhysicsScene.PE.SetMassProps(PhysBody, 0f, Inertia); + PhysicsScene.PE.UpdateInertiaTensor(PhysBody); } else { @@ -423,14 +423,14 @@ public sealed class BSPrim : BSPhysObject } // The computation of mass props requires gravity to be set on the object. - BulletSimAPI.SetGravity2(PhysBody.ptr, grav); + PhysicsScene.PE.SetGravity(PhysBody, grav); - Inertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass); - BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, Inertia); - BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); + Inertia = PhysicsScene.PE.CalculateLocalInertia(PhysShape, physMass); + PhysicsScene.PE.SetMassProps(PhysBody, physMass, Inertia); + PhysicsScene.PE.UpdateInertiaTensor(PhysBody); // center of mass is at the zero of the object - // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(PhysBody.ptr, ForcePosition, ForceOrientation); + // DEBUG DEBUG PhysicsScene.PE.SetCenterOfMassByPosRot(PhysBody, ForcePosition, ForceOrientation); DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2},grav={3},inWorld={4}", LocalID, physMass, Inertia, grav, inWorld); if (inWorld) @@ -440,7 +440,7 @@ public sealed class BSPrim : BSPhysObject // 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 - BulletSimAPI.SetGravity2(PhysBody.ptr, grav); + PhysicsScene.PE.SetGravity(PhysBody, grav); } } @@ -483,7 +483,7 @@ public sealed class BSPrim : BSPhysObject DetailLog("{0},BSPrim.setForce,preStep,force={1}", LocalID, _force); if (PhysBody.HasPhysicalBody) { - BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, _force); + PhysicsScene.PE.ApplyCentralForce(PhysBody, _force); ActivateIfPhysical(false); } } @@ -583,7 +583,7 @@ public sealed class BSPrim : BSPhysObject _velocity = value; if (PhysBody.HasPhysicalBody) { - BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); + PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity); ActivateIfPhysical(false); } } @@ -809,7 +809,7 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); // Center of mass is at the center of the object - // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.PhysBody, _position, _orientation); + // DEBUG DEBUG PhysicsScene.PE.SetCenterOfMassByPosRot(Linkset.LinksetRoot.PhysBody, _position, _orientation); // A dynamic object has mass UpdatePhysicalMassProperties(RawMass, false); @@ -822,9 +822,9 @@ public sealed class BSPrim : BSPhysObject } // Various values for simulation limits - BulletSimAPI.SetDamping2(PhysBody.ptr, BSParam.LinearDamping, BSParam.AngularDamping); + PhysicsScene.PE.SetDamping(PhysBody, BSParam.LinearDamping, BSParam.AngularDamping); PhysicsScene.PE.SetDeactivationTime(PhysBody, BSParam.DeactivationTime); - BulletSimAPI.SetSleepingThresholds2(PhysBody.ptr, BSParam.LinearSleepingThreshold, BSParam.AngularSleepingThreshold); + PhysicsScene.PE.SetSleepingThresholds(PhysBody, BSParam.LinearSleepingThreshold, BSParam.AngularSleepingThreshold); PhysicsScene.PE.SetContactProcessingThreshold(PhysBody, BSParam.ContactProcessingThreshold); // This collides like an object. @@ -901,10 +901,10 @@ public sealed class BSPrim : BSPhysObject // TODO: Fix this. Total kludge because adding object to world resets its gravity to default. // Replace this when the new AddObjectToWorld function is complete. - BulletSimAPI.SetGravity2(PhysBody.ptr, ComputeGravity()); + PhysicsScene.PE.SetGravity(PhysBody, ComputeGravity()); // Collision filter can be set only when the object is in the world - if (!PhysBody.ApplyCollisionMask()) + if (!PhysBody.ApplyCollisionMask(PhysicsScene)) { m_log.ErrorFormat("{0} Failed setting object collision mask: id={1}", LogHeader, LocalID); DetailLog("{0},BSPrim.UpdatePhysicalParameters,failedSetMaskGroup,cType={1}", LocalID, PhysBody.collisionType); @@ -969,7 +969,7 @@ public sealed class BSPrim : BSPhysObject _rotationalVelocity = value; if (PhysBody.HasPhysicalBody) { - BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity); + PhysicsScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity); ActivateIfPhysical(false); } } @@ -1061,7 +1061,7 @@ public sealed class BSPrim : BSPhysObject DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce); if (PhysBody.HasPhysicalBody) { - BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, addForce); + PhysicsScene.PE.ApplyCentralForce(PhysBody, addForce); ActivateIfPhysical(false); } }); @@ -1085,7 +1085,7 @@ public sealed class BSPrim : BSPhysObject { if (PhysBody.HasPhysicalBody) { - BulletSimAPI.ApplyTorque2(PhysBody.ptr, angForce); + PhysicsScene.PE.ApplyTorque(PhysBody, angForce); ActivateIfPhysical(false); } }); @@ -1108,7 +1108,7 @@ public sealed class BSPrim : BSPhysObject { if (PhysBody.HasPhysicalBody) { - BulletSimAPI.ApplyTorqueImpulse2(PhysBody.ptr, applyImpulse); + PhysicsScene.PE.ApplyTorqueImpulse(PhysBody, applyImpulse); ActivateIfPhysical(false); } }); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index bfc9df2..28c6680 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -51,7 +51,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public string BulletSimVersion = "?"; // The handle to the underlying managed or unmanaged version of Bullet being used. - public BulletSimAPITemplate PE; + public BSAPITemplate PE; public Dictionary PhysObjects; public BSShapeCollection Shapes; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index d59e455..cd77581 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -141,7 +141,7 @@ public sealed class BSShapeCollection : IDisposable if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,body={1}", body.ID, body); PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.ReferenceBody", delegate() { - if (!BulletSimAPI.IsInWorld2(body.ptr)) + if (!PhysicsScene.PE.IsInWorld(body)) { PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, body); if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", body.ID, body); @@ -166,7 +166,7 @@ public sealed class BSShapeCollection : IDisposable // If the caller needs to know the old body is going away, pass the event up. if (bodyCallback != null) bodyCallback(body); - if (BulletSimAPI.IsInWorld2(body.ptr)) + if (PhysicsScene.PE.IsInWorld(body)) { PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, body); if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,removingFromWorld. Body={1}", body.ID, body); @@ -332,7 +332,7 @@ public sealed class BSShapeCollection : IDisposable // Called at taint-time. private void DereferenceCompound(BulletShape shape, ShapeDestructionCallback shapeCallback) { - if (!BulletSimAPI.IsCompound2(shape.ptr)) + if (!PhysicsScene.PE.IsCompound(shape)) { // Failed the sanity check!! PhysicsScene.Logger.ErrorFormat("{0} Attempt to free a compound shape that is not compound!! type={1}, ptr={2}", @@ -376,7 +376,7 @@ public sealed class BSShapeCollection : IDisposable } else { - if (BulletSimAPI.IsCompound2(cShape)) + if (PhysicsScene.PE.IsCompound(shapeInfo)) { shapeInfo.type = BSPhysicsShapeType.SHAPE_COMPOUND; } @@ -467,7 +467,7 @@ public sealed class BSShapeCollection : IDisposable // Get the scale of any existing shape so we can see if the new shape is same native type and same size. OMV.Vector3 scaleOfExistingShape = OMV.Vector3.Zero; if (prim.PhysShape.HasPhysicalShape) - scaleOfExistingShape = BulletSimAPI.GetLocalScaling2(prim.PhysShape.ptr); + scaleOfExistingShape = PhysicsScene.PE.GetLocalScaling(prim.PhysShape); if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,maybeNative,force={1},primScale={2},primSize={3},primShape={4}", prim.LocalID, forceRebuild, prim.Scale, prim.Size, prim.PhysShape.type); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs index 423e700..c75eb9b 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs @@ -151,12 +151,12 @@ public class BSShapeNative : BSShape /* if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE) { - ptr = BulletSimAPI.BuildCapsuleShape2(physicsScene.World.ptr, 1f, 1f, prim.Scale); + ptr = PhysicsScene.PE.BuildCapsuleShape(physicsScene.World, 1f, 1f, prim.Scale); physicsScene.DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); } else { - ptr = BulletSimAPI.BuildNativeShape2(physicsScene.World.ptr, nativeShapeData); + ptr = PhysicsScene.PE.BuildNativeShape(physicsScene.World, nativeShapeData); } if (ptr == IntPtr.Zero) { @@ -173,7 +173,7 @@ public class BSShapeNative : BSShape /* // Native shapes are not tracked and are released immediately physicsScene.DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,shape={1}", BSScene.DetailLogZero, this); - BulletSimAPI.DeleteCollisionShape2(physicsScene.World.ptr, ptr); + PhysicsScene.PE.DeleteCollisionShape(physicsScene.World, this); ptr = IntPtr.Zero; // Garbage collection will free up this instance. */ diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs index 01966c0..cc28344 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs @@ -120,7 +120,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, m_mapInfo.terrainBody); m_mapInfo.terrainBody.collisionType = CollisionType.Terrain; - m_mapInfo.terrainBody.ApplyCollisionMask(); + m_mapInfo.terrainBody.ApplyCollisionMask(PhysicsScene); // Make it so the terrain will not move or be considered for movement. PhysicsScene.PE.ForceActivationState(m_mapInfo.terrainBody, ActivationState.DISABLE_SIMULATION); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index 590c687..2e9db39 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -143,7 +143,7 @@ public sealed class BSTerrainManager : IDisposable PhysicsScene.PE.ForceActivationState(m_groundPlane, ActivationState.DISABLE_SIMULATION); // Everything collides with the ground plane. m_groundPlane.collisionType = CollisionType.Groundplane; - m_groundPlane.ApplyCollisionMask(); + m_groundPlane.ApplyCollisionMask(PhysicsScene); // Build an initial terrain and put it in the world. This quickly gets replaced by the real region terrain. BSTerrainPhys initialTerrain = new BSTerrainHeightmap(PhysicsScene, Vector3.Zero, BSScene.TERRAIN_ID, DefaultRegionSize); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index 2f55fc3..1d55ce3 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs @@ -120,7 +120,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys PhysicsScene.PE.SetCollisionFlags(m_terrainBody, CollisionFlags.CF_STATIC_OBJECT); // Static objects are not very massive. - BulletSimAPI.SetMassProps2(m_terrainBody.ptr, 0f, Vector3.Zero); + PhysicsScene.PE.SetMassProps(m_terrainBody, 0f, Vector3.Zero); // Put the new terrain to the world of physical objects PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, m_terrainBody); @@ -129,7 +129,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, m_terrainBody); m_terrainBody.collisionType = CollisionType.Terrain; - m_terrainBody.ApplyCollisionMask(); + m_terrainBody.ApplyCollisionMask(PhysicsScene); // Make it so the terrain will not move or be considered for movement. PhysicsScene.PE.ForceActivationState(m_terrainBody, ActivationState.DISABLE_SIMULATION); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs deleted file mode 100644 index b119f22..0000000 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ /dev/null @@ -1,667 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Security; -using System.Text; -using OpenMetaverse; - -namespace OpenSim.Region.Physics.BulletSPlugin { - - // Constraint type values as defined by Bullet -public enum ConstraintType : int -{ - POINT2POINT_CONSTRAINT_TYPE = 3, - HINGE_CONSTRAINT_TYPE, - CONETWIST_CONSTRAINT_TYPE, - D6_CONSTRAINT_TYPE, - SLIDER_CONSTRAINT_TYPE, - CONTACT_CONSTRAINT_TYPE, - D6_SPRING_CONSTRAINT_TYPE, - MAX_CONSTRAINT_TYPE -} - -// =============================================================================== -[StructLayout(LayoutKind.Sequential)] -public struct ConvexHull -{ - Vector3 Offset; - int VertexCount; - Vector3[] Vertices; -} -public enum BSPhysicsShapeType -{ - SHAPE_UNKNOWN = 0, - SHAPE_CAPSULE = 1, - SHAPE_BOX = 2, - SHAPE_CONE = 3, - SHAPE_CYLINDER = 4, - SHAPE_SPHERE = 5, - SHAPE_MESH = 6, - SHAPE_HULL = 7, - // following defined by BulletSim - SHAPE_GROUNDPLANE = 20, - SHAPE_TERRAIN = 21, - SHAPE_COMPOUND = 22, - SHAPE_HEIGHTMAP = 23, - SHAPE_AVATAR = 24, -}; - -// The native shapes have predefined shape hash keys -public enum FixedShapeKey : ulong -{ - KEY_NONE = 0, - KEY_BOX = 1, - KEY_SPHERE = 2, - KEY_CONE = 3, - KEY_CYLINDER = 4, - KEY_CAPSULE = 5, - KEY_AVATAR = 6, -} - -[StructLayout(LayoutKind.Sequential)] -public struct ShapeData -{ - public uint ID; - public BSPhysicsShapeType Type; - public Vector3 Position; - public Quaternion Rotation; - public Vector3 Velocity; - public Vector3 Scale; - public float Mass; - public float Buoyancy; - public System.UInt64 HullKey; - public System.UInt64 MeshKey; - public float Friction; - public float Restitution; - public float Collidable; // true of things bump into this - public float Static; // true if a static object. Otherwise gravity, etc. - public float Solid; // true if object cannot be passed through - public Vector3 Size; - - // note that bools are passed as floats since bool size changes by language and architecture - public const float numericTrue = 1f; - public const float numericFalse = 0f; -} -[StructLayout(LayoutKind.Sequential)] -public struct SweepHit -{ - public uint ID; - public float Fraction; - public Vector3 Normal; - public Vector3 Point; -} -[StructLayout(LayoutKind.Sequential)] -public struct RaycastHit -{ - public uint ID; - public float Fraction; - public Vector3 Normal; -} -[StructLayout(LayoutKind.Sequential)] -public struct CollisionDesc -{ - public uint aID; - public uint bID; - public Vector3 point; - public Vector3 normal; -} -[StructLayout(LayoutKind.Sequential)] -public struct EntityProperties -{ - public uint ID; - public Vector3 Position; - public Quaternion Rotation; - public Vector3 Velocity; - public Vector3 Acceleration; - public Vector3 RotationalVelocity; -} - -// Format of this structure must match the definition in the C++ code -// NOTE: adding the X causes compile breaks if used. These are unused symbols -// that can be removed from both here and the unmanaged definition of this structure. -[StructLayout(LayoutKind.Sequential)] -public struct ConfigurationParameters -{ - public float defaultFriction; - public float defaultDensity; - public float defaultRestitution; - public float collisionMargin; - public float gravity; - - public float XlinearDamping; - public float XangularDamping; - public float XdeactivationTime; - public float XlinearSleepingThreshold; - public float XangularSleepingThreshold; - public float XccdMotionThreshold; - public float XccdSweptSphereRadius; - public float XcontactProcessingThreshold; - - public float XterrainImplementation; - public float XterrainFriction; - public float XterrainHitFraction; - public float XterrainRestitution; - public float XterrainCollisionMargin; - - public float XavatarFriction; - public float XavatarStandingFriction; - public float XavatarDensity; - public float XavatarRestitution; - public float XavatarCapsuleWidth; - public float XavatarCapsuleDepth; - public float XavatarCapsuleHeight; - public float XavatarContactProcessingThreshold; - - public float XvehicleAngularDamping; - - public float maxPersistantManifoldPoolSize; - public float maxCollisionAlgorithmPoolSize; - public float shouldDisableContactPoolDynamicAllocation; - public float shouldForceUpdateAllAabbs; - public float shouldRandomizeSolverOrder; - public float shouldSplitSimulationIslands; - public float shouldEnableFrictionCaching; - public float numberOfSolverIterations; - - public float XlinksetImplementation; - public float XlinkConstraintUseFrameOffset; - public float XlinkConstraintEnableTransMotor; - public float XlinkConstraintTransMotorMaxVel; - public float XlinkConstraintTransMotorMaxForce; - public float XlinkConstraintERP; - public float XlinkConstraintCFM; - public float XlinkConstraintSolverIterations; - - public float physicsLoggingFrames; - - public const float numericTrue = 1f; - public const float numericFalse = 0f; -} - - -// The states a bullet collision object can have -public enum ActivationState : uint -{ - ACTIVE_TAG = 1, - ISLAND_SLEEPING, - WANTS_DEACTIVATION, - DISABLE_DEACTIVATION, - DISABLE_SIMULATION, -} - -public enum CollisionObjectTypes : int -{ - CO_COLLISION_OBJECT = 1 << 0, - CO_RIGID_BODY = 1 << 1, - CO_GHOST_OBJECT = 1 << 2, - CO_SOFT_BODY = 1 << 3, - CO_HF_FLUID = 1 << 4, - CO_USER_TYPE = 1 << 5, -} - -// Values used by Bullet and BulletSim to control object properties. -// Bullet's "CollisionFlags" has more to do with operations on the -// object (if collisions happen, if gravity effects it, ...). -public enum CollisionFlags : uint -{ - CF_STATIC_OBJECT = 1 << 0, - CF_KINEMATIC_OBJECT = 1 << 1, - CF_NO_CONTACT_RESPONSE = 1 << 2, - CF_CUSTOM_MATERIAL_CALLBACK = 1 << 3, - CF_CHARACTER_OBJECT = 1 << 4, - CF_DISABLE_VISUALIZE_OBJECT = 1 << 5, - CF_DISABLE_SPU_COLLISION_PROCESS = 1 << 6, - // Following used by BulletSim to control collisions and updates - BS_SUBSCRIBE_COLLISION_EVENTS = 1 << 10, - BS_FLOATS_ON_WATER = 1 << 11, - BS_VEHICLE_COLLISIONS = 1 << 12, - BS_NONE = 0, - BS_ALL = 0xFFFFFFFF -}; - -// Values f collisions groups and masks -public enum CollisionFilterGroups : uint -{ - // Don't use the bit definitions!! Define the use in a - // filter/mask definition below. This way collision interactions - // are more easily found and debugged. - BNoneGroup = 0, - BDefaultGroup = 1 << 0, // 0001 - BStaticGroup = 1 << 1, // 0002 - BKinematicGroup = 1 << 2, // 0004 - BDebrisGroup = 1 << 3, // 0008 - BSensorTrigger = 1 << 4, // 0010 - BCharacterGroup = 1 << 5, // 0020 - BAllGroup = 0x000FFFFF, - // Filter groups defined by BulletSim - BGroundPlaneGroup = 1 << 10, // 0400 - BTerrainGroup = 1 << 11, // 0800 - BRaycastGroup = 1 << 12, // 1000 - BSolidGroup = 1 << 13, // 2000 - // BLinksetGroup = xx // a linkset proper is either static or dynamic - BLinksetChildGroup = 1 << 14, // 4000 -}; - -// CFM controls the 'hardness' of the constraint. 0=fixed, 0..1=violatable. Default=0 -// ERP controls amount of correction per tick. Usable range=0.1..0.8. Default=0.2. -public enum ConstraintParams : int -{ - BT_CONSTRAINT_ERP = 1, // this one is not used in Bullet as of 20120730 - BT_CONSTRAINT_STOP_ERP, - BT_CONSTRAINT_CFM, - BT_CONSTRAINT_STOP_CFM, -}; -public enum ConstraintParamAxis : int -{ - AXIS_LINEAR_X = 0, - AXIS_LINEAR_Y, - AXIS_LINEAR_Z, - AXIS_ANGULAR_X, - AXIS_ANGULAR_Y, - AXIS_ANGULAR_Z, - AXIS_LINEAR_ALL = 20, // these last three added by BulletSim so we don't have to do zillions of calls - AXIS_ANGULAR_ALL, - AXIS_ALL -}; - -public abstract class BulletSimAPITemplate -{ - /* -// Initialization and simulation -public abstract BulletWorld Initialize(Vector3 maxPosition, IntPtr parms, - int maxCollisions, IntPtr collisionArray, - int maxUpdates, IntPtr updateArray - ); - -public abstract bool UpdateParameter(BulletWorld world, uint localID, String parm, float value); - -public abstract void SetHeightMap(BulletWorld world, float[] heightmap); - -public abstract void Shutdown(BulletWorld sim); - -public abstract int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, - out int updatedEntityCount, - out IntPtr updatedEntitiesPtr, - out int collidersCount, - out IntPtr collidersPtr); - -public abstract bool PushUpdate(BulletBody obj); - */ - -// ===================================================================================== -// Mesh, hull, shape and body creation helper routines -public abstract BulletShape CreateMeshShape(BulletWorld world, - int indicesCount, int[] indices, - int verticesCount, float[] vertices ); - -public abstract BulletShape CreateHullShape(BulletWorld world, - int hullCount, float[] hulls); - -public abstract BulletShape BuildHullShapeFromMesh(BulletWorld world, BulletShape meshShape); - -public abstract BulletShape BuildNativeShape(BulletWorld world, ShapeData shapeData); - -public abstract bool IsNativeShape(BulletShape shape); - -public abstract void SetShapeCollisionMargin(BulletShape shape, float margin); - -public abstract BulletShape BuildCapsuleShape(BulletWorld world, float radius, float height, Vector3 scale); - -public abstract BulletShape CreateCompoundShape(BulletWorld sim, bool enableDynamicAabbTree); - -public abstract int GetNumberOfCompoundChildren(BulletShape cShape); - -public abstract void AddChildShapeToCompoundShape(BulletShape cShape, BulletShape addShape, Vector3 pos, Quaternion rot); - -public abstract BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx); - -public abstract BulletShape RemoveChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx); - -public abstract void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape); - -public abstract void RecalculateCompoundShapeLocalAabb(BulletShape cShape); - -public abstract BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id); - -public abstract BulletBody CreateBodyFromShapeAndInfo(BulletWorld sim, BulletShape shape, uint id, IntPtr constructionInfo); - -public abstract bool DeleteCollisionShape(BulletWorld world, BulletShape shape); - -public abstract int GetBodyType(BulletBody obj); - -public abstract BulletBody CreateBodyFromShape(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot); - -public abstract BulletBody CreateBodyWithDefaultMotionState(BulletShape shape, uint id, Vector3 pos, Quaternion rot); - -public abstract BulletBody CreateGhostFromShape(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot); - -public abstract IntPtr AllocateBodyInfo(BulletBody obj); - -public abstract void ReleaseBodyInfo(IntPtr obj); - -public abstract void DestroyObject(BulletWorld sim, BulletBody obj); - -// ===================================================================================== -// Terrain creation and helper routines -public abstract IntPtr CreateHeightMapInfo(BulletWorld sim, uint id, Vector3 minCoords, Vector3 maxCoords, - float[] heightMap, float collisionMargin); - -public abstract IntPtr FillHeightMapInfo(BulletWorld sim, IntPtr mapInfo, uint id, Vector3 minCoords, Vector3 maxCoords, - float[] heightMap, float collisionMargin); - -public abstract bool ReleaseHeightMapInfo(IntPtr heightMapInfo); - -public abstract BulletShape CreateGroundPlaneShape(uint id, float height, float collisionMargin); - -public abstract BulletShape CreateTerrainShape(IntPtr mapInfo); - -// ===================================================================================== -// Constraint creation and helper routines -public abstract BulletConstraint Create6DofConstraint(BulletWorld world, BulletBody obj1, BulletBody obj2, - Vector3 frame1loc, Quaternion frame1rot, - Vector3 frame2loc, Quaternion frame2rot, - bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); - -public abstract BulletConstraint Create6DofConstraintToPoint(BulletWorld world, BulletBody obj1, BulletBody obj2, - Vector3 joinPoint, - bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); - -public abstract BulletConstraint CreateHingeConstraint(BulletWorld world, BulletBody obj1, BulletBody obj2, - Vector3 pivotinA, Vector3 pivotinB, - Vector3 axisInA, Vector3 axisInB, - bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); - -public abstract void SetConstraintEnable(BulletConstraint constrain, float numericTrueFalse); - -public abstract void SetConstraintNumSolverIterations(BulletConstraint constrain, float iterations); - -public abstract bool SetFrames(BulletConstraint constrain, - Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot); - -public abstract bool SetLinearLimits(BulletConstraint constrain, Vector3 low, Vector3 hi); - -public abstract bool SetAngularLimits(BulletConstraint constrain, Vector3 low, Vector3 hi); - -public abstract bool UseFrameOffset(BulletConstraint constrain, float enable); - -public abstract bool TranslationalLimitMotor(BulletConstraint constrain, float enable, float targetVel, float maxMotorForce); - -public abstract bool SetBreakingImpulseThreshold(BulletConstraint constrain, float threshold); - -public abstract bool CalculateTransforms(BulletConstraint constrain); - -public abstract bool SetConstraintParam(BulletConstraint constrain, ConstraintParams paramIndex, float value, ConstraintParamAxis axis); - -public abstract bool DestroyConstraint(BulletWorld world, BulletConstraint constrain); - -// ===================================================================================== -// btCollisionWorld entries -public abstract void UpdateSingleAabb(BulletWorld world, BulletBody obj); - -public abstract void UpdateAabbs(BulletWorld world); - -public abstract bool GetForceUpdateAllAabbs(BulletWorld world); - -public abstract void SetForceUpdateAllAabbs(BulletWorld world, bool force); - -// ===================================================================================== -// btDynamicsWorld entries -public abstract bool AddObjectToWorld(BulletWorld world, BulletBody obj); - -public abstract bool RemoveObjectFromWorld(BulletWorld world, BulletBody obj); - -public abstract bool AddConstraintToWorld(BulletWorld world, BulletConstraint constrain, bool disableCollisionsBetweenLinkedObjects); - -public abstract bool RemoveConstraintFromWorld(BulletWorld world, BulletConstraint constrain); -// ===================================================================================== -// btCollisionObject entries -public abstract Vector3 GetAnisotripicFriction(BulletConstraint constrain); - -public abstract Vector3 SetAnisotripicFriction(BulletConstraint constrain, Vector3 frict); - -public abstract bool HasAnisotripicFriction(BulletConstraint constrain); - -public abstract void SetContactProcessingThreshold(BulletBody obj, float val); - -public abstract float GetContactProcessingThreshold(BulletBody obj); - -public abstract bool IsStaticObject(BulletBody obj); - -public abstract bool IsKinematicObject(BulletBody obj); - -public abstract bool IsStaticOrKinematicObject(BulletBody obj); - -public abstract bool HasContactResponse(BulletBody obj); - -public abstract void SetCollisionShape(BulletWorld sim, BulletBody obj, BulletShape shape); - -public abstract BulletShape GetCollisionShape(BulletBody obj); - -public abstract int GetActivationState(BulletBody obj); - -public abstract void SetActivationState(BulletBody obj, int state); - -public abstract void SetDeactivationTime(BulletBody obj, float dtime); - -public abstract float GetDeactivationTime(BulletBody obj); - -public abstract void ForceActivationState(BulletBody obj, ActivationState state); - -public abstract void Activate(BulletBody obj, bool forceActivation); - -public abstract bool IsActive(BulletBody obj); - -public abstract void SetRestitution(BulletBody obj, float val); - -public abstract float GetRestitution(BulletBody obj); - -public abstract void SetFriction(BulletBody obj, float val); - -public abstract float GetFriction(BulletBody obj); - -public abstract Vector3 GetPosition(BulletBody obj); - -public abstract Quaternion GetOrientation(BulletBody obj); - -public abstract void SetTranslation(BulletBody obj, Vector3 position, Quaternion rotation); - -public abstract IntPtr GetBroadphaseHandle(BulletBody obj); - -public abstract void SetBroadphaseHandle(BulletBody obj, IntPtr handle); - -public abstract void SetInterpolationLinearVelocity(BulletBody obj, Vector3 vel); - -public abstract void SetInterpolationAngularVelocity(BulletBody obj, Vector3 vel); - -public abstract void SetInterpolationVelocity(BulletBody obj, Vector3 linearVel, Vector3 angularVel); - -public abstract float GetHitFraction(BulletBody obj); - -public abstract void SetHitFraction(BulletBody obj, float val); - -public abstract CollisionFlags GetCollisionFlags(BulletBody obj); - -public abstract CollisionFlags SetCollisionFlags(BulletBody obj, CollisionFlags flags); - -public abstract CollisionFlags AddToCollisionFlags(BulletBody obj, CollisionFlags flags); - -public abstract CollisionFlags RemoveFromCollisionFlags(BulletBody obj, CollisionFlags flags); - -public abstract float GetCcdMotionThreshold(BulletBody obj); - -public abstract void SetCcdMotionThreshold(BulletBody obj, float val); - -public abstract float GetCcdSweptSphereRadius(BulletBody obj); - -public abstract void SetCcdSweptSphereRadius(BulletBody obj, float val); - -public abstract IntPtr GetUserPointer(BulletBody obj); - -public abstract void SetUserPointer(BulletBody obj, IntPtr val); - - /* -// ===================================================================================== -// btRigidBody entries -public abstract void ApplyGravity(BulletBody obj); - -public abstract void SetGravity(BulletBody obj, Vector3 val); - -public abstract Vector3 GetGravity(BulletBody obj); - -public abstract void SetDamping(BulletBody obj, float lin_damping, float ang_damping); - -public abstract void SetLinearDamping(BulletBody obj, float lin_damping); - -public abstract void SetAngularDamping(BulletBody obj, float ang_damping); - -public abstract float GetLinearDamping(BulletBody obj); - -public abstract float GetAngularDamping(BulletBody obj); - -public abstract float GetLinearSleepingThreshold(BulletBody obj); - - -public abstract void ApplyDamping(BulletBody obj, float timeStep); - -public abstract void SetMassProps(BulletBody obj, float mass, Vector3 inertia); - -public abstract Vector3 GetLinearFactor(BulletBody obj); - -public abstract void SetLinearFactor(BulletBody obj, Vector3 factor); - -public abstract void SetCenterOfMassByPosRot(BulletBody obj, Vector3 pos, Quaternion rot); - -// Add a force to the object as if its mass is one. -public abstract void ApplyCentralForce(BulletBody obj, Vector3 force); - -// Set the force being applied to the object as if its mass is one. -public abstract void SetObjectForce(BulletBody obj, Vector3 force); - -public abstract Vector3 GetTotalForce(BulletBody obj); - -public abstract Vector3 GetTotalTorque(BulletBody obj); - -public abstract Vector3 GetInvInertiaDiagLocal(BulletBody obj); - -public abstract void SetInvInertiaDiagLocal(BulletBody obj, Vector3 inert); - -public abstract void SetSleepingThresholds(BulletBody obj, float lin_threshold, float ang_threshold); - -public abstract void ApplyTorque(BulletBody obj, Vector3 torque); - -// Apply force at the given point. Will add torque to the object. -public abstract void ApplyForce(BulletBody obj, Vector3 force, Vector3 pos); - -// Apply impulse to the object. Same as "ApplycentralForce" but force scaled by object's mass. -public abstract void ApplyCentralImpulse(BulletBody obj, Vector3 imp); - -// Apply impulse to the object's torque. Force is scaled by object's mass. -public abstract void ApplyTorqueImpulse(BulletBody obj, Vector3 imp); - -// Apply impulse at the point given. For is scaled by object's mass and effects both linear and angular forces. -public abstract void ApplyImpulse(BulletBody obj, Vector3 imp, Vector3 pos); - -public abstract void ClearForces(BulletBody obj); - -public abstract void ClearAllForces(BulletBody obj); - -public abstract void UpdateInertiaTensor(BulletBody obj); - -public abstract Vector3 GetLinearVelocity(BulletBody obj); - -public abstract Vector3 GetAngularVelocity(BulletBody obj); - -public abstract void SetLinearVelocity(BulletBody obj, Vector3 val); - -public abstract void SetAngularVelocity(BulletBody obj, Vector3 angularVelocity); - -public abstract Vector3 GetVelocityInLocalPoint(BulletBody obj, Vector3 pos); - -public abstract void Translate(BulletBody obj, Vector3 trans); - -public abstract void UpdateDeactivation(BulletBody obj, float timeStep); - -public abstract bool WantsSleeping(BulletBody obj); - -public abstract void SetAngularFactor(BulletBody obj, float factor); - -public abstract void SetAngularFactorV(BulletBody obj, Vector3 factor); - -public abstract Vector3 GetAngularFactor(BulletBody obj); - -public abstract bool IsInWorld(BulletBody obj); - -public abstract void AddConstraintRef(BulletBody obj, BulletConstraint constrain); - -public abstract void RemoveConstraintRef(BulletBody obj, BulletConstraint constrain); - -public abstract BulletConstraint GetConstraintRef(BulletBody obj, int index); - -public abstract int GetNumConstraintRefs(BulletBody obj); - -public abstract bool SetCollisionGroupMask(BulletBody body, uint filter, uint mask); - -// ===================================================================================== -// btCollisionShape entries - -public abstract float GetAngularMotionDisc(BulletShape shape); - -public abstract float GetContactBreakingThreshold(BulletShape shape, float defaultFactor); - -public abstract bool IsPolyhedral(BulletShape shape); - -public abstract bool IsConvex2d(BulletShape shape); - -public abstract bool IsConvex(BulletShape shape); - -public abstract bool IsNonMoving(BulletShape shape); - -public abstract bool IsConcave(BulletShape shape); - -public abstract bool IsCompound(BulletShape shape); - -public abstract bool IsSoftBody(BulletShape shape); - -public abstract bool IsInfinite(BulletShape shape); - -public abstract void SetLocalScaling(BulletShape shape, Vector3 scale); - -public abstract Vector3 GetLocalScaling(BulletShape shape); - -public abstract Vector3 CalculateLocalInertia(BulletShape shape, float mass); - -public abstract int GetShapeType(BulletShape shape); - -public abstract void SetMargin(BulletShape shape, float val); - -public abstract float GetMargin(BulletShape shape); - */ - -}; -} diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs index c10d75e..a040928 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs @@ -72,12 +72,12 @@ public class BulletBody public bool HasPhysicalBody { get { return ptr != IntPtr.Zero; } } // Apply the specificed collision mask into the physical world - public bool ApplyCollisionMask() + public bool ApplyCollisionMask(BSScene physicsScene) { // Should assert the body has been added to the physical world. // (The collision masks are stored in the collision proxy cache which only exists for // a collision body that is in the world.) - return BulletSimAPI.SetCollisionGroupMask2(ptr, + return physicsScene.PE.SetCollisionGroupMask(this, BulletSimData.CollisionTypeMasks[collisionType].group, BulletSimData.CollisionTypeMasks[collisionType].mask); } -- cgit v1.1 From 3d0fc708647ceb734385f90e2f22be9774e2171e Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 31 Dec 2012 16:22:45 -0800 Subject: BulletSim: complete movement of BulletSimAPI functions to BSAPITemplate. Update BulletSim DLLs and SOs with simplier step function interface. --- OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs | 4 - OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | 217 +++++++++++++++------ OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs | 78 ++++---- .../Region/Physics/BulletSPlugin/BSApiTemplate.cs | 43 ++-- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 4 +- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 127 ++++++------ .../Physics/BulletSPlugin/BSTerrainHeightmap.cs | 12 +- .../Region/Physics/BulletSPlugin/BulletSimData.cs | 8 +- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 10 +- .../Region/Physics/Manager/PhysicsPluginManager.cs | 2 +- 10 files changed, 311 insertions(+), 194 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs index 9c4ba30..aadb5b2 100644 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs @@ -111,10 +111,6 @@ public sealed class BSPrim : BSPhysObject _mass = CalculateMass(); - // No body or shape yet - PhysBody = new BulletBody(LocalID); - PhysShape = new BulletShape(); - Linkset.Refresh(this); DetailLog("{0},BSPrim.constructor,call", LocalID); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs index 6e68053..0355b94 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs @@ -26,6 +26,7 @@ */ using System; using System.Collections.Generic; +using System.Reflection; using System.Runtime.InteropServices; using System.Security; using System.Text; @@ -36,31 +37,102 @@ namespace OpenSim.Region.Physics.BulletSPlugin { public sealed class BSAPIUnman : BSAPITemplate { - /* + +// We pin the memory passed between the managed and unmanaged code. +GCHandle m_paramsHandle; +private GCHandle m_collisionArrayPinnedHandle; +private GCHandle m_updateArrayPinnedHandle; + +// Handle to the callback used by the unmanaged code to call into the managed code. +// Used for debug logging. +// Need to store the handle in a persistant variable so it won't be freed. +private BSAPICPP.DebugLogCallback m_DebugLogCallbackHandle; + +private BSScene PhysicsScene { get; set; } + +public override string BulletEngineName { get { return "BulletUnmanaged"; } } +public override string BulletEngineVersion { get; protected set; } + +public BSAPIUnman(string paramName, BSScene physScene) +{ + PhysicsScene = physScene; + // Do something fancy with the paramName to get the right DLL implementation + // like "Bullet-2.80-OpenCL-Intel" loading the version for Intel based OpenCL implementation, etc. +} + // Initialization and simulation -public BulletWorld Initialize(Vector3 maxPosition, IntPtr parms, - int maxCollisions, IntPtr collisionArray, - int maxUpdates, IntPtr updateArray - ); +public override BulletWorld Initialize(Vector3 maxPosition, ConfigurationParameters parms, + int maxCollisions, ref CollisionDesc[] collisionArray, + int maxUpdates, ref EntityProperties[] updateArray + ) +{ + // Pin down the memory that will be used to pass object collisions and updates back from unmanaged code + m_paramsHandle = GCHandle.Alloc(parms, GCHandleType.Pinned); + m_collisionArrayPinnedHandle = GCHandle.Alloc(collisionArray, GCHandleType.Pinned); + m_updateArrayPinnedHandle = GCHandle.Alloc(updateArray, GCHandleType.Pinned); -public bool UpdateParameter(BulletWorld world, uint localID, String parm, float value); + // If Debug logging level, enable logging from the unmanaged code + m_DebugLogCallbackHandle = null; + if (BSScene.m_log.IsDebugEnabled || PhysicsScene.PhysicsLogging.Enabled) + { + BSScene.m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", BSScene.LogHeader); + if (PhysicsScene.PhysicsLogging.Enabled) + // The handle is saved in a variable to make sure it doesn't get freed after this call + m_DebugLogCallbackHandle = new BSAPICPP.DebugLogCallback(BulletLoggerPhysLog); + else + m_DebugLogCallbackHandle = new BSAPICPP.DebugLogCallback(BulletLogger); + } -public void SetHeightMap(BulletWorld world, float[] heightmap); + // Get the version of the DLL + // TODO: this doesn't work yet. Something wrong with marshaling the returned string. + // BulletEngineVersion = BulletSimAPI.GetVersion2(); + BulletEngineVersion = ""; + + // Call the unmanaged code with the buffers and other information + return new BulletWorld(0, PhysicsScene, BSAPICPP.Initialize2(maxPosition, m_paramsHandle.AddrOfPinnedObject(), + maxCollisions, m_collisionArrayPinnedHandle.AddrOfPinnedObject(), + maxUpdates, m_updateArrayPinnedHandle.AddrOfPinnedObject(), + m_DebugLogCallbackHandle)); -public void Shutdown(BulletWorld sim); +} -public int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, - out int updatedEntityCount, - out IntPtr updatedEntitiesPtr, - out int collidersCount, - out IntPtr collidersPtr); +// Called directly from unmanaged code so don't do much +private void BulletLogger(string msg) +{ + BSScene.m_log.Debug("[BULLETS UNMANAGED]:" + msg); +} + +// Called directly from unmanaged code so don't do much +private void BulletLoggerPhysLog(string msg) +{ + PhysicsScene.DetailLog("[BULLETS UNMANAGED]:" + msg); +} + + /* +public void SetHeightMap(BulletWorld world, float[] heightmap); */ +public override int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, + out int updatedEntityCount, out int collidersCount) +{ + return BSAPICPP.PhysicsStep2(world.ptr, timeStep, maxSubSteps, fixedTimeStep, out updatedEntityCount, out collidersCount); +} + +public override void Shutdown(BulletWorld sim) +{ + BSAPICPP.Shutdown2(sim.ptr); +} + public override bool PushUpdate(BulletBody obj) { return BSAPICPP.PushUpdate2(obj.ptr); } +public override bool UpdateParameter(BulletWorld world, uint localID, String parm, float value) +{ + return BSAPICPP.UpdateParameter2(world.ptr, localID, parm, value); +} + // ===================================================================================== // Mesh, hull, shape and body creation helper routines public override BulletShape CreateMeshShape(BulletWorld world, @@ -893,11 +965,81 @@ public override float GetMargin(BulletShape shape) return BSAPICPP.GetMargin2(shape.ptr); } +// ===================================================================================== +// Debugging +public override void DumpRigidBody(BulletWorld sim, BulletBody collisionObject) +{ + BSAPICPP.DumpRigidBody2(sim.ptr, collisionObject.ptr); +} + +public override void DumpCollisionShape(BulletWorld sim, BulletShape collisionShape) +{ + BSAPICPP.DumpCollisionShape2(sim.ptr, collisionShape.ptr); +} + +public override void DumpMapInfo(BulletWorld sim, BulletHMapInfo mapInfo) +{ + BSAPICPP.DumpMapInfo2(sim.ptr, mapInfo.ptr); +} + +public override void DumpConstraint(BulletWorld sim, BulletConstraint constrain) +{ + BSAPICPP.DumpConstraint2(sim.ptr, constrain.ptr); +} + +public override void DumpActivationInfo(BulletWorld sim) +{ + BSAPICPP.DumpActivationInfo2(sim.ptr); +} + +public override void DumpAllInfo(BulletWorld sim) +{ + BSAPICPP.DumpAllInfo2(sim.ptr); +} + +public override void DumpPhysicsStatistics(BulletWorld sim) +{ + BSAPICPP.DumpPhysicsStatistics2(sim.ptr); +} + + +// ===================================================================================== +// ===================================================================================== +// ===================================================================================== +// ===================================================================================== +// ===================================================================================== +// The actual interface to the unmanaged code static class BSAPICPP { +// =============================================================================== +// Link back to the managed code for outputting log messages +[UnmanagedFunctionPointer(CallingConvention.Cdecl)] +public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg); + +// =============================================================================== +// Initialization and simulation +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms, + int maxCollisions, IntPtr collisionArray, + int maxUpdates, IntPtr updateArray, + DebugLogCallback logRoutine); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void SetHeightMap2(IntPtr world, float[] heightmap); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern int PhysicsStep2(IntPtr world, float timeStep, int maxSubSteps, float fixedTimeStep, + out int updatedEntityCount, out int collidersCount); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void Shutdown2(IntPtr sim); + [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern bool PushUpdate2(IntPtr obj); +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern bool UpdateParameter2(IntPtr world, uint localID, String parm, float value); + // ===================================================================================== // Mesh, hull, shape and body creation helper routines [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] @@ -1431,52 +1573,6 @@ public static extern void SetMargin2(IntPtr shape, float val); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern float GetMargin2(IntPtr shape); -} -} - -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -// =============================================================================== -static class BulletSimAPI { -// =============================================================================== -// Link back to the managed code for outputting log messages -[UnmanagedFunctionPointer(CallingConvention.Cdecl)] -public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg); - -// =============================================================================== -// Initialization and simulation -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms, - int maxCollisions, IntPtr collisionArray, - int maxUpdates, IntPtr updateArray, - DebugLogCallback logRoutine); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool UpdateParameter2(IntPtr world, uint localID, String parm, float value); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetHeightMap2(IntPtr world, float[] heightmap); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void Shutdown2(IntPtr sim); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern int PhysicsStep2(IntPtr world, float timeStep, int maxSubSteps, float fixedTimeStep, - out int updatedEntityCount, - out IntPtr updatedEntitiesPtr, - out int collidersCount, - out IntPtr collidersPtr); - // ===================================================================================== // Debugging [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] @@ -1501,4 +1597,7 @@ public static extern void DumpAllInfo2(IntPtr sim); public static extern void DumpPhysicsStatistics2(IntPtr sim); } + +} + } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs index a56a817..8ed791e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs @@ -1,39 +1,39 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace OpenSim.Region.Physics.BulletSPlugin -{ - /* -public sealed class BSAPIXNA : BulletSimAPITemplate -{ -} - */ -} +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ + /* +public sealed class BSAPIXNA : BSAPITemplate +{ +} + */ +} diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index fbf362d..64a886b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs @@ -292,26 +292,27 @@ public enum ConstraintParamAxis : int public abstract class BSAPITemplate { - /* +// Returns the name of the underlying Bullet engine +public abstract string BulletEngineName { get; } +public abstract string BulletEngineVersion { get; protected set;} + // Initialization and simulation -public abstract BulletWorld Initialize(Vector3 maxPosition, IntPtr parms, - int maxCollisions, IntPtr collisionArray, - int maxUpdates, IntPtr updateArray +public abstract BulletWorld Initialize(Vector3 maxPosition, ConfigurationParameters parms, + int maxCollisions, ref CollisionDesc[] collisionArray, + int maxUpdates, ref EntityProperties[] updateArray ); -public abstract bool UpdateParameter(BulletWorld world, uint localID, String parm, float value); - + /* public abstract void SetHeightMap(BulletWorld world, float[] heightmap); -public abstract void Shutdown(BulletWorld sim); - + */ public abstract int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, - out int updatedEntityCount, - out IntPtr updatedEntitiesPtr, - out int collidersCount, - out IntPtr collidersPtr); + out int updatedEntityCount, out int collidersCount); + +public abstract bool UpdateParameter(BulletWorld world, uint localID, String parm, float value); + +public abstract void Shutdown(BulletWorld sim); - */ public abstract bool PushUpdate(BulletBody obj); // ===================================================================================== @@ -660,5 +661,21 @@ public abstract void SetMargin(BulletShape shape, float val); public abstract float GetMargin(BulletShape shape); +// ===================================================================================== +// Debugging +public abstract void DumpRigidBody(BulletWorld sim, BulletBody collisionObject); + +public abstract void DumpCollisionShape(BulletWorld sim, BulletShape collisionShape); + +public abstract void DumpMapInfo(BulletWorld sim, BulletHMapInfo mapInfo); + +public abstract void DumpConstraint(BulletWorld sim, BulletConstraint constrain); + +public abstract void DumpActivationInfo(BulletWorld sim); + +public abstract void DumpAllInfo(BulletWorld sim); + +public abstract void DumpPhysicsStatistics(BulletWorld sim); + }; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index e4e3edc..13c2539 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -823,7 +823,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (!IsActive) return; if (PhysicsScene.VehiclePhysicalLoggingEnabled) - BulletSimAPI.DumpRigidBody2(PhysicsScene.World.ptr, Prim.PhysBody.ptr); + PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody); ForgetKnownVehicleProperties(); @@ -840,7 +840,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin PushKnownChanged(); if (PhysicsScene.VehiclePhysicalLoggingEnabled) - BulletSimAPI.DumpRigidBody2(PhysicsScene.World.ptr, Prim.PhysBody.ptr); + PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody); VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", Prim.LocalID, VehiclePosition, Prim.Force, VehicleVelocity, VehicleRotationalVelocity); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 28c6680..258b72f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -26,6 +26,7 @@ */ using System; using System.Collections.Generic; +using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Threading; @@ -42,8 +43,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin { public sealed class BSScene : PhysicsScene, IPhysicsParameters { - private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - private static readonly string LogHeader = "[BULLETS SCENE]"; + internal static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + internal static readonly string LogHeader = "[BULLETS SCENE]"; // The name of the region we're working for. public string RegionName { get; private set; } @@ -51,6 +52,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public string BulletSimVersion = "?"; // The handle to the underlying managed or unmanaged version of Bullet being used. + public string BulletEngineName { get; private set; } public BSAPITemplate PE; public Dictionary PhysObjects; @@ -102,11 +104,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // Pinned memory used to pass step information between managed and unmanaged internal int m_maxCollisionsPerFrame; internal CollisionDesc[] m_collisionArray; - internal GCHandle m_collisionArrayPinnedHandle; internal int m_maxUpdatesPerFrame; internal EntityProperties[] m_updateArray; - internal GCHandle m_updateArrayPinnedHandle; public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero public const uint GROUNDPLANE_ID = 1; @@ -152,12 +152,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // A pointer to an instance if this structure is passed to the C++ code // Used to pass basic configuration values to the unmanaged code. internal ConfigurationParameters[] UnmanagedParams; - GCHandle m_paramsHandle; - - // Handle to the callback used by the unmanaged code to call into the managed code. - // Used for debug logging. - // Need to store the handle in a persistant variable so it won't be freed. - private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle; // Sometimes you just have to log everything. public Logging.LogWriter PhysicsLogging; @@ -194,15 +188,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // Set default values for physics parameters plus any overrides from the ini file GetInitialParameterValues(config); - // For the moment, only one version of the interface - PE = new BSAPIUnman(); - - // Allocate more pinned memory. Do this early to try and get all pinned memory close together. - m_paramsHandle = GCHandle.Alloc(UnmanagedParams, GCHandleType.Pinned); - m_collisionArray = new CollisionDesc[m_maxCollisionsPerFrame]; - m_collisionArrayPinnedHandle = GCHandle.Alloc(m_collisionArray, GCHandleType.Pinned); - m_updateArray = new EntityProperties[m_maxUpdatesPerFrame]; - m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned); + // Get the connection to the physics engine (could be native or one of many DLLs) + PE = SelectUnderlyingBulletEngine(BulletEngineName); // Enable very detailed logging. // By creating an empty logger when not logging, the log message invocation code @@ -217,22 +204,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters PhysicsLogging = new Logging.LogWriter(); } - // If Debug logging level, enable logging from the unmanaged code - m_DebugLogCallbackHandle = null; - if (m_log.IsDebugEnabled || PhysicsLogging.Enabled) - { - m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader); - if (PhysicsLogging.Enabled) - // The handle is saved in a variable to make sure it doesn't get freed after this call - m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLoggerPhysLog); - else - m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger); - } - - // Get the version of the DLL - // TODO: this doesn't work yet. Something wrong with marshaling the returned string. - // BulletSimVersion = BulletSimAPI.GetVersion(); - // m_log.WarnFormat("{0}: BulletSim.dll version='{1}'", LogHeader, BulletSimVersion); + // Allocate memory for returning of the updates and collisions from the physics engine + m_collisionArray = new CollisionDesc[m_maxCollisionsPerFrame]; + m_updateArray = new EntityProperties[m_maxUpdatesPerFrame]; // The bounding box for the simulated world. The origin is 0,0,0 unless we're // a child in a mega-region. @@ -240,11 +214,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // area. It tracks active objects no matter where they are. Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); - // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader); - World = new BulletWorld(0, this, BulletSimAPI.Initialize2(worldExtent, m_paramsHandle.AddrOfPinnedObject(), - m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(), - m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject(), - m_DebugLogCallbackHandle)); + World = PE.Initialize(worldExtent, Params, m_maxCollisionsPerFrame, ref m_collisionArray, m_maxUpdatesPerFrame, ref m_updateArray); Constraints = new BSConstraintCollection(World); @@ -274,6 +244,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters { BSParam.SetParameterConfigurationValues(this, pConfig); + // There are two Bullet implementations to choose from + BulletEngineName = pConfig.GetString("BulletEngine", "BulletUnmanaged"); + // Very detailed logging for physics debugging // TODO: the boolean values can be moved to the normal parameter processing. m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false); @@ -315,16 +288,41 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters return ret; } - // Called directly from unmanaged code so don't do much - private void BulletLogger(string msg) + // Select the connection to the actual Bullet implementation. + // The main engine selection is the engineName up to the first hypen. + // So "Bullet-2.80-OpenCL-Intel" specifies the 'bullet' class here and the whole name + // is passed to the engine to do its special selection, etc. + private BSAPITemplate SelectUnderlyingBulletEngine(string engineName) { - m_log.Debug("[BULLETS UNMANAGED]:" + msg); - } + // For the moment, do a simple switch statement. + // Someday do fancyness with looking up the interfaces in the assembly. + BSAPITemplate ret = null; - // Called directly from unmanaged code so don't do much - private void BulletLoggerPhysLog(string msg) - { - DetailLog("[BULLETS UNMANAGED]:" + msg); + string selectionName = engineName.ToLower(); + int hyphenIndex = engineName.IndexOf("-"); + if (hyphenIndex > 0) + selectionName = engineName.ToLower().Substring(0, hyphenIndex - 1); + + switch (selectionName) + { + case "bulletunmanaged": + ret = new BSAPIUnman(engineName, this); + break; + case "bulletxna": + // ret = new BSAPIXNA(engineName, this); + break; + } + + if (ret == null) + { + m_log.ErrorFormat("{0) COULD NOT SELECT BULLET ENGINE: '[BulletSim]PhysicsEngine' must be either 'BulletUnmanaged-*' or 'BulletXNA-*'", LogHeader); + } + else + { + m_log.WarnFormat("{0} Selected bullet engine {1} -> {2}/{3}", LogHeader, engineName, ret.BulletEngineName, ret.BulletEngineVersion); + } + + return ret; } public override void Dispose() @@ -361,7 +359,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters } // Anything left in the unmanaged code should be cleaned out - BulletSimAPI.Shutdown2(World.ptr); + PE.Shutdown(World); // Not logging any more PhysicsLogging.Close(); @@ -474,9 +472,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters LastTimeStep = timeStep; int updatedEntityCount = 0; - IntPtr updatedEntitiesPtr; int collidersCount = 0; - IntPtr collidersPtr; int beforeTime = 0; int simTime = 0; @@ -492,6 +488,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters TriggerPreStepEvent(timeStep); // the prestep actions might have added taints + numTaints += _taintOperations.Count; ProcessTaints(); InTaintTime = false; // Only used for debugging so locking is not necessary. @@ -499,23 +496,25 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world. // Only enable this in a limited test world with few objects. if (m_physicsPhysicalDumpEnabled) - BulletSimAPI.DumpAllInfo2(World.ptr); + PE.DumpAllInfo(World); // step the physical world one interval m_simulationStep++; int numSubSteps = 0; - try { - if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount(); + if (PhysicsLogging.Enabled) + beforeTime = Util.EnvironmentTickCount(); - numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep, - out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); + numSubSteps = PE.PhysicsStep(World, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out collidersCount); - if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime); - DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}, objWColl={7}", - DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, - updatedEntityCount, collidersCount, ObjectsWithCollisions.Count); + if (PhysicsLogging.Enabled) + { + simTime = Util.EnvironmentTickCountSubtract(beforeTime); + DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}, objWColl={7}", + DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, + updatedEntityCount, collidersCount, ObjectsWithCollisions.Count); + } } catch (Exception e) { @@ -527,8 +526,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters collidersCount = 0; } - // Don't have to use the pointers passed back since we know it is the same pinned memory we passed in. - // Get a value for 'now' so all the collision and update routines don't have to get their own. SimulationNowTime = Util.EnvironmentTickCount(); @@ -570,7 +567,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // Objects that are done colliding are removed from the ObjectsWithCollisions list. // Not done above because it is inside an iteration of ObjectWithCollisions. // This complex collision processing is required to create an empty collision - // event call after all collisions have happened on an object. This enables + // event call after all real collisions have happened on an object. This enables // the simulator to generate the 'collision end' event. if (ObjectsWithNoMoreCollisions.Count > 0) { @@ -599,11 +596,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world. // Only enable this in a limited test world with few objects. if (m_physicsPhysicalDumpEnabled) - BulletSimAPI.DumpAllInfo2(World.ptr); + PE.DumpAllInfo(World); // The physics engine returns the number of milliseconds it simulated this call. // These are summed and normalized to one second and divided by 1000 to give the reported physics FPS. - // Multiply by 55 to give a nominal frame rate of 55. + // Multiply by a fixed nominal frame rate to give a rate similar to the simulator (usually 55). return (float)numSubSteps * m_fixedTimeStep * 1000f * NominalFrameRate; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs index cc28344..0802b3a 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs @@ -44,7 +44,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys { static string LogHeader = "[BULLETSIM TERRAIN HEIGHTMAP]"; - BulletHeightMapInfo m_mapInfo = null; + BulletHMapInfo m_mapInfo = null; // Constructor to build a default, flat heightmap terrain. public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize) @@ -58,7 +58,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys { initialMap[ii] = BSTerrainManager.HEIGHT_INITIALIZATION; } - m_mapInfo = new BulletHeightMapInfo(id, initialMap, IntPtr.Zero); + m_mapInfo = new BulletHMapInfo(id, initialMap, IntPtr.Zero); m_mapInfo.minCoords = minTerrainCoords; m_mapInfo.maxCoords = maxTerrainCoords; m_mapInfo.terrainRegionBase = TerrainBase; @@ -72,7 +72,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys Vector3 minCoords, Vector3 maxCoords) : base(physicsScene, regionBase, id) { - m_mapInfo = new BulletHeightMapInfo(id, initialMap, IntPtr.Zero); + m_mapInfo = new BulletHMapInfo(id, initialMap, IntPtr.Zero); m_mapInfo.minCoords = minCoords; m_mapInfo.maxCoords = maxCoords; m_mapInfo.minZ = minCoords.Z; @@ -91,12 +91,12 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys // Using the information in m_mapInfo, create the physical representation of the heightmap. private void BuildHeightmapTerrain() { - m_mapInfo.Ptr = PhysicsScene.PE.CreateHeightMapInfo(PhysicsScene.World, m_mapInfo.ID, + m_mapInfo.ptr = PhysicsScene.PE.CreateHeightMapInfo(PhysicsScene.World, m_mapInfo.ID, m_mapInfo.minCoords, m_mapInfo.maxCoords, m_mapInfo.heightMap, BSParam.TerrainCollisionMargin); // Create the terrain shape from the mapInfo - m_mapInfo.terrainShape = PhysicsScene.PE.CreateTerrainShape(m_mapInfo.Ptr); + m_mapInfo.terrainShape = PhysicsScene.PE.CreateTerrainShape(m_mapInfo.ptr); // The terrain object initial position is at the center of the object Vector3 centerPos; @@ -138,7 +138,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, m_mapInfo.terrainBody); // Frees both the body and the shape. PhysicsScene.PE.DestroyObject(PhysicsScene.World, m_mapInfo.terrainBody); - PhysicsScene.PE.ReleaseHeightMapInfo(m_mapInfo.Ptr); + PhysicsScene.PE.ReleaseHeightMapInfo(m_mapInfo.ptr); } } m_mapInfo = null; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs index a040928..c8f4602 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs @@ -187,11 +187,11 @@ public class BulletConstraint // Made a class rather than a struct so there would be only one // instance of this and C# will pass around pointers rather // than making copies. -public class BulletHeightMapInfo +public class BulletHMapInfo { - public BulletHeightMapInfo(uint id, float[] hm, IntPtr xx) { + public BulletHMapInfo(uint id, float[] hm, IntPtr xx) { ID = id; - Ptr = xx; + ptr = xx; heightMap = hm; terrainRegionBase = OMV.Vector3.Zero; minCoords = new OMV.Vector3(100f, 100f, 25f); @@ -200,7 +200,7 @@ public class BulletHeightMapInfo sizeX = sizeY = 256f; } public uint ID; - public IntPtr Ptr; + public IntPtr ptr; public float[] heightMap; public OMV.Vector3 terrainRegionBase; public OMV.Vector3 minCoords; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 4cb8e6d..a8a4ff5 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -61,7 +61,8 @@ Incorporate inter-relationship of angular corrections. For instance, angularDefl BULLETSIM TODO LIST: ================================================= -Avatar density is WAY off. Compare and calibrate with what's in SL. +Implement an avatar mesh shape. The Bullet capsule is way too limited. + Consider just hand creating a vertex/index array in a new BSShapeAvatar. Revisit CollisionMargin. Builders notice the 0.04 spacing between prims. Duplicating a physical prim causes old prim to jump away Dup a phys prim and the original become unselected and thus interacts w/ selected prim. @@ -170,6 +171,9 @@ Avatar attachments have no mass? http://forums-archive.secondlife.com/54/f0/3179 INTERNAL IMPROVEMENT/CLEANUP ================================================= +Create the physical wrapper classes (BulletBody, BulletShape) by methods on + BSAPITemplate and make their actual implementation Bullet engine specific. + For the short term, just call the existing functions in ShapeCollection. Consider moving prim/character body and shape destruction in destroy() to postTimeTime rather than protecting all the potential sets that might have been queued up. @@ -204,6 +208,8 @@ Should taints check for existance or activeness of target? Possibly have and 'active' flag that is checked by the taint processor? Parameters for physics logging should be moved from BSScene to BSParam (at least boolean ones) Can some of the physical wrapper classes (BulletBody, BulletWorld, BulletShape) be 'sealed'? +There are TOO MANY interfaces from BulletSim core to Bullet itself + Think of something to eliminate one or more of the layers THREADING ================================================= @@ -262,3 +268,5 @@ llApplyImpulse() (Resolution: tested on SL and OS. AddForce scales the force for timestep) llSetBuoyancy() (DONE) (Resolution: Bullet resets object gravity when added to world. Moved set gravity) +Avatar density is WAY off. Compare and calibrate with what's in SL. (DONE) + (Resolution: set default density to 3.5 (from 60) which is closer to SL) diff --git a/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs b/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs index 8587a2b..8ccfda5 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs @@ -30,7 +30,7 @@ using System.Collections.Generic; using System.IO; using System.Reflection; using Nini.Config; -using log4net; +using log4net; using OpenSim.Framework; namespace OpenSim.Region.Physics.Manager -- cgit v1.1 From 9396ccc078516023d63b5a86b3262ff97a1e97fb Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 31 Dec 2012 16:54:39 -0800 Subject: BulletSim: eliminate the use of the unmanaged HeightMapInfo structure. Remove all related calls from the unmanaged and BSAPITemplate interfaces. Update DLLs and SOs to include the version without HeightMapInfo structures. --- OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | 26 +++++++++------------- .../Region/Physics/BulletSPlugin/BSApiTemplate.cs | 18 ++------------- .../Physics/BulletSPlugin/BSTerrainHeightmap.cs | 14 +++++------- .../Region/Physics/BulletSPlugin/BulletSimData.cs | 4 +--- 4 files changed, 20 insertions(+), 42 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs index 0355b94..cf37e56 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs @@ -108,10 +108,6 @@ private void BulletLoggerPhysLog(string msg) PhysicsScene.DetailLog("[BULLETS UNMANAGED]:" + msg); } - /* -public void SetHeightMap(BulletWorld world, float[] heightmap); - - */ public override int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, out int updatedEntityCount, out int collidersCount) { @@ -277,6 +273,7 @@ public override void DestroyObject(BulletWorld sim, BulletBody obj) // ===================================================================================== // Terrain creation and helper routines + /* public override IntPtr CreateHeightMapInfo(BulletWorld sim, uint id, Vector3 minCoords, Vector3 maxCoords, float[] heightMap, float collisionMargin) { @@ -293,15 +290,18 @@ public override bool ReleaseHeightMapInfo(IntPtr heightMapInfo) { return BSAPICPP.ReleaseHeightMapInfo2(heightMapInfo); } + */ public override BulletShape CreateGroundPlaneShape(uint id, float height, float collisionMargin) { return new BulletShape(BSAPICPP.CreateGroundPlaneShape2(id, height, collisionMargin), BSPhysicsShapeType.SHAPE_GROUNDPLANE); } -public override BulletShape CreateTerrainShape(IntPtr mapInfo) +public override BulletShape CreateTerrainShape(uint id, Vector3 size, float minHeight, float maxHeight, float[] heightMap, + float scaleFactor, float collisionMargin) { - return new BulletShape(BSAPICPP.CreateTerrainShape2(mapInfo), BSPhysicsShapeType.SHAPE_TERRAIN); + return new BulletShape(BSAPICPP.CreateTerrainShape2(id, size, minHeight, maxHeight, heightMap, scaleFactor, collisionMargin), + BSPhysicsShapeType.SHAPE_TERRAIN); } // ===================================================================================== @@ -977,11 +977,6 @@ public override void DumpCollisionShape(BulletWorld sim, BulletShape collisionSh BSAPICPP.DumpCollisionShape2(sim.ptr, collisionShape.ptr); } -public override void DumpMapInfo(BulletWorld sim, BulletHMapInfo mapInfo) -{ - BSAPICPP.DumpMapInfo2(sim.ptr, mapInfo.ptr); -} - public override void DumpConstraint(BulletWorld sim, BulletConstraint constrain) { BSAPICPP.DumpConstraint2(sim.ptr, constrain.ptr); @@ -1025,9 +1020,6 @@ public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms, DebugLogCallback logRoutine); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetHeightMap2(IntPtr world, float[] heightmap); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern int PhysicsStep2(IntPtr world, float timeStep, int maxSubSteps, float fixedTimeStep, out int updatedEntityCount, out int collidersCount); @@ -1119,6 +1111,7 @@ public static extern void DestroyObject2(IntPtr sim, IntPtr obj); // ===================================================================================== // Terrain creation and helper routines + /* [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern IntPtr CreateHeightMapInfo2(IntPtr sim, uint id, Vector3 minCoords, Vector3 maxCoords, [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin); @@ -1129,12 +1122,15 @@ public static extern IntPtr FillHeightMapInfo2(IntPtr sim, IntPtr mapInfo, uint [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern bool ReleaseHeightMapInfo2(IntPtr heightMapInfo); + */ [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern IntPtr CreateGroundPlaneShape2(uint id, float height, float collisionMargin); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateTerrainShape2(IntPtr mapInfo); +public static extern IntPtr CreateTerrainShape2(uint id, Vector3 size, float minHeight, float maxHeight, + [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, + float scaleFactor, float collisionMargin); // ===================================================================================== // Constraint creation and helper routines diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index 64a886b..a618a21 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs @@ -302,10 +302,6 @@ public abstract BulletWorld Initialize(Vector3 maxPosition, ConfigurationParamet int maxUpdates, ref EntityProperties[] updateArray ); - /* -public abstract void SetHeightMap(BulletWorld world, float[] heightmap); - - */ public abstract int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, out int updatedEntityCount, out int collidersCount); @@ -369,18 +365,10 @@ public abstract void ReleaseBodyInfo(IntPtr obj); public abstract void DestroyObject(BulletWorld sim, BulletBody obj); // ===================================================================================== -// Terrain creation and helper routines -public abstract IntPtr CreateHeightMapInfo(BulletWorld sim, uint id, Vector3 minCoords, Vector3 maxCoords, - float[] heightMap, float collisionMargin); - -public abstract IntPtr FillHeightMapInfo(BulletWorld sim, IntPtr mapInfo, uint id, Vector3 minCoords, Vector3 maxCoords, - float[] heightMap, float collisionMargin); - -public abstract bool ReleaseHeightMapInfo(IntPtr heightMapInfo); - public abstract BulletShape CreateGroundPlaneShape(uint id, float height, float collisionMargin); -public abstract BulletShape CreateTerrainShape(IntPtr mapInfo); +public abstract BulletShape CreateTerrainShape(uint id, Vector3 size, float minHeight, float maxHeight, float[] heightMap, + float scaleFactor, float collisionMargin); // ===================================================================================== // Constraint creation and helper routines @@ -667,8 +655,6 @@ public abstract void DumpRigidBody(BulletWorld sim, BulletBody collisionObject); public abstract void DumpCollisionShape(BulletWorld sim, BulletShape collisionShape); -public abstract void DumpMapInfo(BulletWorld sim, BulletHMapInfo mapInfo); - public abstract void DumpConstraint(BulletWorld sim, BulletConstraint constrain); public abstract void DumpActivationInfo(BulletWorld sim); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs index 0802b3a..114c0aa 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs @@ -58,7 +58,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys { initialMap[ii] = BSTerrainManager.HEIGHT_INITIALIZATION; } - m_mapInfo = new BulletHMapInfo(id, initialMap, IntPtr.Zero); + m_mapInfo = new BulletHMapInfo(id, initialMap); m_mapInfo.minCoords = minTerrainCoords; m_mapInfo.maxCoords = maxTerrainCoords; m_mapInfo.terrainRegionBase = TerrainBase; @@ -72,7 +72,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys Vector3 minCoords, Vector3 maxCoords) : base(physicsScene, regionBase, id) { - m_mapInfo = new BulletHMapInfo(id, initialMap, IntPtr.Zero); + m_mapInfo = new BulletHMapInfo(id, initialMap); m_mapInfo.minCoords = minCoords; m_mapInfo.maxCoords = maxCoords; m_mapInfo.minZ = minCoords.Z; @@ -91,12 +91,11 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys // Using the information in m_mapInfo, create the physical representation of the heightmap. private void BuildHeightmapTerrain() { - m_mapInfo.ptr = PhysicsScene.PE.CreateHeightMapInfo(PhysicsScene.World, m_mapInfo.ID, - m_mapInfo.minCoords, m_mapInfo.maxCoords, - m_mapInfo.heightMap, BSParam.TerrainCollisionMargin); - // Create the terrain shape from the mapInfo - m_mapInfo.terrainShape = PhysicsScene.PE.CreateTerrainShape(m_mapInfo.ptr); + m_mapInfo.terrainShape = PhysicsScene.PE.CreateTerrainShape( m_mapInfo.ID, + new Vector3(m_mapInfo.sizeX, m_mapInfo.sizeY, 0), m_mapInfo.minZ, m_mapInfo.maxZ, + m_mapInfo.heightMap, 1f, BSParam.TerrainCollisionMargin); + // The terrain object initial position is at the center of the object Vector3 centerPos; @@ -138,7 +137,6 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, m_mapInfo.terrainBody); // Frees both the body and the shape. PhysicsScene.PE.DestroyObject(PhysicsScene.World, m_mapInfo.terrainBody); - PhysicsScene.PE.ReleaseHeightMapInfo(m_mapInfo.ptr); } } m_mapInfo = null; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs index c8f4602..681d21e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs @@ -189,9 +189,8 @@ public class BulletConstraint // than making copies. public class BulletHMapInfo { - public BulletHMapInfo(uint id, float[] hm, IntPtr xx) { + public BulletHMapInfo(uint id, float[] hm) { ID = id; - ptr = xx; heightMap = hm; terrainRegionBase = OMV.Vector3.Zero; minCoords = new OMV.Vector3(100f, 100f, 25f); @@ -200,7 +199,6 @@ public class BulletHMapInfo sizeX = sizeY = 256f; } public uint ID; - public IntPtr ptr; public float[] heightMap; public OMV.Vector3 terrainRegionBase; public OMV.Vector3 minCoords; -- cgit v1.1 From 6988b5ceaf6387198f0d23769adefdf572757c4a Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 31 Dec 2012 17:06:47 -0800 Subject: BulletSim: remove rigid body contruction functions from BSAPITemplate that relied on prebuilt construction info structures. --- OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | 56 ---------------------- .../Region/Physics/BulletSPlugin/BSApiTemplate.cs | 5 -- 2 files changed, 61 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs index cf37e56..a06f6d0 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs @@ -226,11 +226,6 @@ public override BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape return new BulletShape(BSAPICPP.DuplicateCollisionShape2(sim.ptr, srcShape.ptr, id), srcShape.type); } -public override BulletBody CreateBodyFromShapeAndInfo(BulletWorld sim, BulletShape shape, uint id, IntPtr constructionInfo) -{ - return new BulletBody(id, BSAPICPP.CreateBodyFromShapeAndInfo2(sim.ptr, shape.ptr, id, constructionInfo)); -} - public override bool DeleteCollisionShape(BulletWorld world, BulletShape shape) { return BSAPICPP.DeleteCollisionShape2(world.ptr, shape.ptr); @@ -256,16 +251,6 @@ public override BulletBody CreateGhostFromShape(BulletWorld sim, BulletShape sha return new BulletBody(id, BSAPICPP.CreateGhostFromShape2(sim.ptr, shape.ptr, id, pos, rot)); } -public override IntPtr AllocateBodyInfo(BulletBody obj) -{ - return BSAPICPP.AllocateBodyInfo2(obj.ptr); -} - -public override void ReleaseBodyInfo(IntPtr obj) -{ - BSAPICPP.ReleaseBodyInfo2(obj); -} - public override void DestroyObject(BulletWorld sim, BulletBody obj) { BSAPICPP.DestroyObject2(sim.ptr, obj.ptr); @@ -273,25 +258,6 @@ public override void DestroyObject(BulletWorld sim, BulletBody obj) // ===================================================================================== // Terrain creation and helper routines - /* -public override IntPtr CreateHeightMapInfo(BulletWorld sim, uint id, Vector3 minCoords, Vector3 maxCoords, - float[] heightMap, float collisionMargin) -{ - return BSAPICPP.CreateHeightMapInfo2(sim.ptr, id, minCoords, maxCoords, heightMap, collisionMargin); -} - -public override IntPtr FillHeightMapInfo(BulletWorld sim, IntPtr mapInfo, uint id, Vector3 minCoords, Vector3 maxCoords, - float[] heightMap, float collisionMargin) -{ - return BSAPICPP.FillHeightMapInfo2(sim.ptr, mapInfo, id, minCoords, maxCoords, heightMap, collisionMargin); -} - -public override bool ReleaseHeightMapInfo(IntPtr heightMapInfo) -{ - return BSAPICPP.ReleaseHeightMapInfo2(heightMapInfo); -} - */ - public override BulletShape CreateGroundPlaneShape(uint id, float height, float collisionMargin) { return new BulletShape(BSAPICPP.CreateGroundPlaneShape2(id, height, collisionMargin), BSPhysicsShapeType.SHAPE_GROUNDPLANE); @@ -1083,9 +1049,6 @@ public static extern void RecalculateCompoundShapeLocalAabb2(IntPtr cShape); public static extern IntPtr DuplicateCollisionShape2(IntPtr sim, IntPtr srcShape, uint id); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateBodyFromShapeAndInfo2(IntPtr sim, IntPtr shape, uint id, IntPtr constructionInfo); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern bool DeleteCollisionShape2(IntPtr world, IntPtr shape); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] @@ -1101,29 +1064,10 @@ public static extern IntPtr CreateBodyWithDefaultMotionState2(IntPtr shape, uint public static extern IntPtr CreateGhostFromShape2(IntPtr sim, IntPtr shape, uint id, Vector3 pos, Quaternion rot); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr AllocateBodyInfo2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void ReleaseBodyInfo2(IntPtr obj); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern void DestroyObject2(IntPtr sim, IntPtr obj); // ===================================================================================== // Terrain creation and helper routines - /* -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr CreateHeightMapInfo2(IntPtr sim, uint id, Vector3 minCoords, Vector3 maxCoords, - [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern IntPtr FillHeightMapInfo2(IntPtr sim, IntPtr mapInfo, uint id, Vector3 minCoords, Vector3 maxCoords, - [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin); - -[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern bool ReleaseHeightMapInfo2(IntPtr heightMapInfo); - */ - [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern IntPtr CreateGroundPlaneShape2(uint id, float height, float collisionMargin); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index a618a21..6e67c7a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs @@ -346,7 +346,6 @@ public abstract void RecalculateCompoundShapeLocalAabb(BulletShape cShape); public abstract BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id); -public abstract BulletBody CreateBodyFromShapeAndInfo(BulletWorld sim, BulletShape shape, uint id, IntPtr constructionInfo); public abstract bool DeleteCollisionShape(BulletWorld world, BulletShape shape); @@ -358,10 +357,6 @@ public abstract BulletBody CreateBodyWithDefaultMotionState(BulletShape shape, u public abstract BulletBody CreateGhostFromShape(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot); -public abstract IntPtr AllocateBodyInfo(BulletBody obj); - -public abstract void ReleaseBodyInfo(IntPtr obj); - public abstract void DestroyObject(BulletWorld sim, BulletBody obj); // ===================================================================================== -- cgit v1.1 From db3b6e892133c096f2c4244a0902b4f9f1a87371 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 31 Dec 2012 19:56:32 -0800 Subject: BulletSim: remove unused unmanaged memory reference functions from BSAPITemplate. --- OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | 2 ++ OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs index a06f6d0..3975776 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs @@ -524,6 +524,7 @@ public override void SetTranslation(BulletBody obj, Vector3 position, Quaternion BSAPICPP.SetTranslation2(obj.ptr, position, rotation); } + /* public override IntPtr GetBroadphaseHandle(BulletBody obj) { return BSAPICPP.GetBroadphaseHandle2(obj.ptr); @@ -533,6 +534,7 @@ public override void SetBroadphaseHandle(BulletBody obj, IntPtr handle) { BSAPICPP.SetUserPointer2(obj.ptr, handle); } + */ public override void SetInterpolationLinearVelocity(BulletBody obj, Vector3 vel) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index 6e67c7a..699f055 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs @@ -475,9 +475,9 @@ public abstract Quaternion GetOrientation(BulletBody obj); public abstract void SetTranslation(BulletBody obj, Vector3 position, Quaternion rotation); -public abstract IntPtr GetBroadphaseHandle(BulletBody obj); +// public abstract IntPtr GetBroadphaseHandle(BulletBody obj); -public abstract void SetBroadphaseHandle(BulletBody obj, IntPtr handle); +// public abstract void SetBroadphaseHandle(BulletBody obj, IntPtr handle); public abstract void SetInterpolationLinearVelocity(BulletBody obj, Vector3 vel); -- cgit v1.1 From bc9a7ba0d6c0f7ad90a270c93acbb9b5c5f08645 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 1 Jan 2013 23:57:20 +0000 Subject: minor: Assign names to the different SmartThreadPools for debugging purposes. A different approach to the patch in http://opensimulator.org/mantis/view.php?id=6462 that doesn't involve further forking of SmartThreadPool --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index f38d17d..79cec04 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1487,6 +1487,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine startInfo.StartSuspended = true; m_ThreadPool = new SmartThreadPool(startInfo); + m_ThreadPool.Name = "XEngine"; } // -- cgit v1.1 From 04132d3af4c8f44639ea842091f86274513e2dfd Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 1 Jan 2013 09:30:49 -0800 Subject: BulletSim: subclass Bullet[World|Body|Shape|Constraint] for unmanaged to have pointers and managed to have objects. Initial paste of XNA code. Commented out. --- OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | 654 +++++++--- OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs | 1278 +++++++++++++++++++- .../Region/Physics/BulletSPlugin/BSApiTemplate.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 37 +- .../Physics/BulletSPlugin/BSShapeCollection.cs | 27 +- .../Region/Physics/BulletSPlugin/BulletSimData.cs | 86 +- 6 files changed, 1806 insertions(+), 278 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs index 3975776..2c0cb43 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs @@ -38,6 +38,91 @@ namespace OpenSim.Region.Physics.BulletSPlugin public sealed class BSAPIUnman : BSAPITemplate { +private sealed class BulletWorldUnman : BulletWorld +{ + public IntPtr ptr; + public BulletWorldUnman(uint id, BSScene physScene, IntPtr xx) + : base(id, physScene) + { + ptr = xx; + } +} + +private sealed class BulletBodyUnman : BulletBody +{ + public IntPtr ptr; + public BulletBodyUnman(uint id, IntPtr xx) + : base(id) + { + ptr = xx; + } + public override bool HasPhysicalBody + { + get { return ptr != IntPtr.Zero; } + } + public override void Clear() + { + ptr = IntPtr.Zero; + } + public override string AddrString + { + get { return ptr.ToString("X"); } + } +} + +private sealed class BulletShapeUnman : BulletShape +{ + public IntPtr ptr; + public BulletShapeUnman(IntPtr xx, BSPhysicsShapeType typ) + : base() + { + ptr = xx; + type = typ; + } + public override bool HasPhysicalShape + { + get { return ptr != IntPtr.Zero; } + } + public override void Clear() + { + ptr = IntPtr.Zero; + } + public override BulletShape Clone() + { + return new BulletShapeUnman(ptr, type); + } + public override bool ReferenceSame(BulletShape other) + { + BulletShapeUnman otheru = other as BulletShapeUnman; + return (otheru != null) && (this.ptr == otheru.ptr); + + } + public override string AddrString + { + get { return ptr.ToString("X"); } + } +} +private sealed class BulletConstraintUnman : BulletConstraint +{ + public BulletConstraintUnman(IntPtr xx) : base() + { + ptr = xx; + } + public IntPtr ptr; + + public override void Clear() + { + ptr = IntPtr.Zero; + } + public override bool HasPhysicalConstraint { get { return ptr != IntPtr.Zero; } } + + // Used for log messages for a unique display of the memory/object allocated to this instance + public override string AddrString + { + get { return ptr.ToString("X"); } + } +} + // We pin the memory passed between the managed and unmanaged code. GCHandle m_paramsHandle; private GCHandle m_collisionArrayPinnedHandle; @@ -89,7 +174,7 @@ public override BulletWorld Initialize(Vector3 maxPosition, ConfigurationParamet BulletEngineVersion = ""; // Call the unmanaged code with the buffers and other information - return new BulletWorld(0, PhysicsScene, BSAPICPP.Initialize2(maxPosition, m_paramsHandle.AddrOfPinnedObject(), + return new BulletWorldUnman(0, PhysicsScene, BSAPICPP.Initialize2(maxPosition, m_paramsHandle.AddrOfPinnedObject(), maxCollisions, m_collisionArrayPinnedHandle.AddrOfPinnedObject(), maxUpdates, m_updateArrayPinnedHandle.AddrOfPinnedObject(), m_DebugLogCallbackHandle)); @@ -111,22 +196,26 @@ private void BulletLoggerPhysLog(string msg) public override int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, out int updatedEntityCount, out int collidersCount) { - return BSAPICPP.PhysicsStep2(world.ptr, timeStep, maxSubSteps, fixedTimeStep, out updatedEntityCount, out collidersCount); + BulletWorldUnman worldu = world as BulletWorldUnman; + return BSAPICPP.PhysicsStep2(worldu.ptr, timeStep, maxSubSteps, fixedTimeStep, out updatedEntityCount, out collidersCount); } -public override void Shutdown(BulletWorld sim) +public override void Shutdown(BulletWorld world) { - BSAPICPP.Shutdown2(sim.ptr); + BulletWorldUnman worldu = world as BulletWorldUnman; + BSAPICPP.Shutdown2(worldu.ptr); } public override bool PushUpdate(BulletBody obj) { - return BSAPICPP.PushUpdate2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.PushUpdate2(bodyu.ptr); } public override bool UpdateParameter(BulletWorld world, uint localID, String parm, float value) { - return BSAPICPP.UpdateParameter2(world.ptr, localID, parm, value); + BulletWorldUnman worldu = world as BulletWorldUnman; + return BSAPICPP.UpdateParameter2(worldu.ptr, localID, parm, value); } // ===================================================================================== @@ -135,138 +224,165 @@ public override BulletShape CreateMeshShape(BulletWorld world, int indicesCount, int[] indices, int verticesCount, float[] vertices) { - return new BulletShape( - BSAPICPP.CreateMeshShape2(world.ptr, indicesCount, indices, verticesCount, vertices), + BulletWorldUnman worldu = world as BulletWorldUnman; + return new BulletShapeUnman( + BSAPICPP.CreateMeshShape2(worldu.ptr, indicesCount, indices, verticesCount, vertices), BSPhysicsShapeType.SHAPE_MESH); } public override BulletShape CreateHullShape(BulletWorld world, int hullCount, float[] hulls) { - return new BulletShape( - BSAPICPP.CreateHullShape2(world.ptr, hullCount, hulls), + BulletWorldUnman worldu = world as BulletWorldUnman; + return new BulletShapeUnman( + BSAPICPP.CreateHullShape2(worldu.ptr, hullCount, hulls), BSPhysicsShapeType.SHAPE_HULL); } public override BulletShape BuildHullShapeFromMesh(BulletWorld world, BulletShape meshShape) { - return new BulletShape( - BSAPICPP.BuildHullShapeFromMesh2(world.ptr, meshShape.ptr), + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletShapeUnman shapeu = meshShape as BulletShapeUnman; + return new BulletShapeUnman( + BSAPICPP.BuildHullShapeFromMesh2(worldu.ptr, shapeu.ptr), BSPhysicsShapeType.SHAPE_HULL); } -public override BulletShape BuildNativeShape( BulletWorld world, ShapeData shapeData) +public override BulletShape BuildNativeShape(BulletWorld world, ShapeData shapeData) { - return new BulletShape( - BSAPICPP.BuildNativeShape2(world.ptr, shapeData), - shapeData.Type); + BulletWorldUnman worldu = world as BulletWorldUnman; + return new BulletShapeUnman(BSAPICPP.BuildNativeShape2(worldu.ptr, shapeData), shapeData.Type); } public override bool IsNativeShape(BulletShape shape) { - if (shape.HasPhysicalShape) - return BSAPICPP.IsNativeShape2(shape.ptr); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + if (shapeu != null && shapeu.HasPhysicalShape) + return BSAPICPP.IsNativeShape2(shapeu.ptr); return false; } public override void SetShapeCollisionMargin(BulletShape shape, float margin) { - if (shape.HasPhysicalShape) - BSAPICPP.SetShapeCollisionMargin2(shape.ptr, margin); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + if (shapeu != null && shapeu.HasPhysicalShape) + BSAPICPP.SetShapeCollisionMargin2(shapeu.ptr, margin); } public override BulletShape BuildCapsuleShape(BulletWorld world, float radius, float height, Vector3 scale) { - return new BulletShape( - BSAPICPP.BuildCapsuleShape2(world.ptr, radius, height, scale), + BulletWorldUnman worldu = world as BulletWorldUnman; + return new BulletShapeUnman( + BSAPICPP.BuildCapsuleShape2(worldu.ptr, radius, height, scale), BSPhysicsShapeType.SHAPE_CAPSULE); } -public override BulletShape CreateCompoundShape(BulletWorld sim, bool enableDynamicAabbTree) +public override BulletShape CreateCompoundShape(BulletWorld world, bool enableDynamicAabbTree) { - return new BulletShape( - BSAPICPP.CreateCompoundShape2(sim.ptr, enableDynamicAabbTree), + BulletWorldUnman worldu = world as BulletWorldUnman; + return new BulletShapeUnman( + BSAPICPP.CreateCompoundShape2(worldu.ptr, enableDynamicAabbTree), BSPhysicsShapeType.SHAPE_COMPOUND); } public override int GetNumberOfCompoundChildren(BulletShape shape) { - if (shape.HasPhysicalShape) - return BSAPICPP.GetNumberOfCompoundChildren2(shape.ptr); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + if (shapeu != null && shapeu.HasPhysicalShape) + return BSAPICPP.GetNumberOfCompoundChildren2(shapeu.ptr); return 0; } -public override void AddChildShapeToCompoundShape(BulletShape cShape, BulletShape addShape, Vector3 pos, Quaternion rot) +public override void AddChildShapeToCompoundShape(BulletShape shape, BulletShape addShape, Vector3 pos, Quaternion rot) { - BSAPICPP.AddChildShapeToCompoundShape2(cShape.ptr, addShape.ptr, pos, rot); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + BulletShapeUnman addShapeu = addShape as BulletShapeUnman; + BSAPICPP.AddChildShapeToCompoundShape2(shapeu.ptr, addShapeu.ptr, pos, rot); } -public override BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) +public override BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape shape, int indx) { - return new BulletShape(BSAPICPP.GetChildShapeFromCompoundShapeIndex2(cShape.ptr, indx)); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + return new BulletShapeUnman(BSAPICPP.GetChildShapeFromCompoundShapeIndex2(shapeu.ptr, indx), BSPhysicsShapeType.SHAPE_UNKNOWN); } -public override BulletShape RemoveChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) +public override BulletShape RemoveChildShapeFromCompoundShapeIndex(BulletShape shape, int indx) { - return new BulletShape(BSAPICPP.RemoveChildShapeFromCompoundShapeIndex2(cShape.ptr, indx)); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + return new BulletShapeUnman(BSAPICPP.RemoveChildShapeFromCompoundShapeIndex2(shapeu.ptr, indx), BSPhysicsShapeType.SHAPE_UNKNOWN); } -public override void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape) +public override void RemoveChildShapeFromCompoundShape(BulletShape shape, BulletShape removeShape) { - BSAPICPP.RemoveChildShapeFromCompoundShape2(cShape.ptr, removeShape.ptr); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + BulletShapeUnman removeShapeu = removeShape as BulletShapeUnman; + BSAPICPP.RemoveChildShapeFromCompoundShape2(shapeu.ptr, removeShapeu.ptr); } -public override void RecalculateCompoundShapeLocalAabb(BulletShape cShape) +public override void RecalculateCompoundShapeLocalAabb(BulletShape shape) { - BSAPICPP.RecalculateCompoundShapeLocalAabb2(cShape.ptr); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + BSAPICPP.RecalculateCompoundShapeLocalAabb2(shapeu.ptr); } -public override BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id) +public override BulletShape DuplicateCollisionShape(BulletWorld world, BulletShape srcShape, uint id) { - return new BulletShape(BSAPICPP.DuplicateCollisionShape2(sim.ptr, srcShape.ptr, id), srcShape.type); + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletShapeUnman srcShapeu = srcShape as BulletShapeUnman; + return new BulletShapeUnman(BSAPICPP.DuplicateCollisionShape2(worldu.ptr, srcShapeu.ptr, id), srcShape.type); } public override bool DeleteCollisionShape(BulletWorld world, BulletShape shape) { - return BSAPICPP.DeleteCollisionShape2(world.ptr, shape.ptr); + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletShapeUnman shapeu = shape as BulletShapeUnman; + return BSAPICPP.DeleteCollisionShape2(worldu.ptr, shapeu.ptr); } public override int GetBodyType(BulletBody obj) { - return BSAPICPP.GetBodyType2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetBodyType2(bodyu.ptr); } -public override BulletBody CreateBodyFromShape(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot) +public override BulletBody CreateBodyFromShape(BulletWorld world, BulletShape shape, uint id, Vector3 pos, Quaternion rot) { - return new BulletBody(id, BSAPICPP.CreateBodyFromShape2(sim.ptr, shape.ptr, id, pos, rot)); + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletShapeUnman shapeu = shape as BulletShapeUnman; + return new BulletBodyUnman(id, BSAPICPP.CreateBodyFromShape2(worldu.ptr, shapeu.ptr, id, pos, rot)); } public override BulletBody CreateBodyWithDefaultMotionState(BulletShape shape, uint id, Vector3 pos, Quaternion rot) { - return new BulletBody(id, BSAPICPP.CreateBodyWithDefaultMotionState2(shape.ptr, id, pos, rot)); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + return new BulletBodyUnman(id, BSAPICPP.CreateBodyWithDefaultMotionState2(shapeu.ptr, id, pos, rot)); } -public override BulletBody CreateGhostFromShape(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot) +public override BulletBody CreateGhostFromShape(BulletWorld world, BulletShape shape, uint id, Vector3 pos, Quaternion rot) { - return new BulletBody(id, BSAPICPP.CreateGhostFromShape2(sim.ptr, shape.ptr, id, pos, rot)); + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletShapeUnman shapeu = shape as BulletShapeUnman; + return new BulletBodyUnman(id, BSAPICPP.CreateGhostFromShape2(worldu.ptr, shapeu.ptr, id, pos, rot)); } -public override void DestroyObject(BulletWorld sim, BulletBody obj) +public override void DestroyObject(BulletWorld world, BulletBody obj) { - BSAPICPP.DestroyObject2(sim.ptr, obj.ptr); + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.DestroyObject2(worldu.ptr, bodyu.ptr); } // ===================================================================================== // Terrain creation and helper routines public override BulletShape CreateGroundPlaneShape(uint id, float height, float collisionMargin) { - return new BulletShape(BSAPICPP.CreateGroundPlaneShape2(id, height, collisionMargin), BSPhysicsShapeType.SHAPE_GROUNDPLANE); + return new BulletShapeUnman(BSAPICPP.CreateGroundPlaneShape2(id, height, collisionMargin), BSPhysicsShapeType.SHAPE_GROUNDPLANE); } public override BulletShape CreateTerrainShape(uint id, Vector3 size, float minHeight, float maxHeight, float[] heightMap, float scaleFactor, float collisionMargin) { - return new BulletShape(BSAPICPP.CreateTerrainShape2(id, size, minHeight, maxHeight, heightMap, scaleFactor, collisionMargin), + return new BulletShapeUnman(BSAPICPP.CreateTerrainShape2(id, size, minHeight, maxHeight, heightMap, scaleFactor, collisionMargin), BSPhysicsShapeType.SHAPE_TERRAIN); } @@ -277,7 +393,10 @@ public override BulletConstraint Create6DofConstraint(BulletWorld world, BulletB Vector3 frame2loc, Quaternion frame2rot, bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) { - return new BulletConstraint(BSAPICPP.Create6DofConstraint2(world.ptr, obj1.ptr, obj2.ptr, frame1loc, frame1rot, + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletBodyUnman bodyu1 = obj1 as BulletBodyUnman; + BulletBodyUnman bodyu2 = obj2 as BulletBodyUnman; + return new BulletConstraintUnman(BSAPICPP.Create6DofConstraint2(worldu.ptr, bodyu1.ptr, bodyu2.ptr, frame1loc, frame1rot, frame2loc, frame2rot, useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); } @@ -285,7 +404,10 @@ public override BulletConstraint Create6DofConstraintToPoint(BulletWorld world, Vector3 joinPoint, bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) { - return new BulletConstraint(BSAPICPP.Create6DofConstraintToPoint2(world.ptr, obj1.ptr, obj2.ptr, + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletBodyUnman bodyu1 = obj1 as BulletBodyUnman; + BulletBodyUnman bodyu2 = obj2 as BulletBodyUnman; + return new BulletConstraintUnman(BSAPICPP.Create6DofConstraintToPoint2(worldu.ptr, bodyu1.ptr, bodyu2.ptr, joinPoint, useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); } @@ -294,560 +416,687 @@ public override BulletConstraint CreateHingeConstraint(BulletWorld world, Bullet Vector3 axisInA, Vector3 axisInB, bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) { - return new BulletConstraint(BSAPICPP.CreateHingeConstraint2(world.ptr, obj1.ptr, obj2.ptr, + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletBodyUnman bodyu1 = obj1 as BulletBodyUnman; + BulletBodyUnman bodyu2 = obj2 as BulletBodyUnman; + return new BulletConstraintUnman(BSAPICPP.CreateHingeConstraint2(worldu.ptr, bodyu1.ptr, bodyu2.ptr, pivotinA, pivotinB, axisInA, axisInB, useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); } public override void SetConstraintEnable(BulletConstraint constrain, float numericTrueFalse) { - BSAPICPP.SetConstraintEnable2(constrain.ptr, numericTrueFalse); + BulletConstraintUnman constrainu = constrain as BulletConstraintUnman; + BSAPICPP.SetConstraintEnable2(constrainu.ptr, numericTrueFalse); } public override void SetConstraintNumSolverIterations(BulletConstraint constrain, float iterations) { - BSAPICPP.SetConstraintNumSolverIterations2(constrain.ptr, iterations); + BulletConstraintUnman constrainu = constrain as BulletConstraintUnman; + BSAPICPP.SetConstraintNumSolverIterations2(constrainu.ptr, iterations); } public override bool SetFrames(BulletConstraint constrain, Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot) { - return BSAPICPP.SetFrames2(constrain.ptr, frameA, frameArot, frameB, frameBrot); + BulletConstraintUnman constrainu = constrain as BulletConstraintUnman; + return BSAPICPP.SetFrames2(constrainu.ptr, frameA, frameArot, frameB, frameBrot); } public override bool SetLinearLimits(BulletConstraint constrain, Vector3 low, Vector3 hi) { - return BSAPICPP.SetLinearLimits2(constrain.ptr, low, hi); + BulletConstraintUnman constrainu = constrain as BulletConstraintUnman; + return BSAPICPP.SetLinearLimits2(constrainu.ptr, low, hi); } public override bool SetAngularLimits(BulletConstraint constrain, Vector3 low, Vector3 hi) { - return BSAPICPP.SetAngularLimits2(constrain.ptr, low, hi); + BulletConstraintUnman constrainu = constrain as BulletConstraintUnman; + return BSAPICPP.SetAngularLimits2(constrainu.ptr, low, hi); } public override bool UseFrameOffset(BulletConstraint constrain, float enable) { - return BSAPICPP.UseFrameOffset2(constrain.ptr, enable); + BulletConstraintUnman constrainu = constrain as BulletConstraintUnman; + return BSAPICPP.UseFrameOffset2(constrainu.ptr, enable); } public override bool TranslationalLimitMotor(BulletConstraint constrain, float enable, float targetVel, float maxMotorForce) { - return BSAPICPP.TranslationalLimitMotor2(constrain.ptr, enable, targetVel, maxMotorForce); + BulletConstraintUnman constrainu = constrain as BulletConstraintUnman; + return BSAPICPP.TranslationalLimitMotor2(constrainu.ptr, enable, targetVel, maxMotorForce); } public override bool SetBreakingImpulseThreshold(BulletConstraint constrain, float threshold) { - return BSAPICPP.SetBreakingImpulseThreshold2(constrain.ptr, threshold); + BulletConstraintUnman constrainu = constrain as BulletConstraintUnman; + return BSAPICPP.SetBreakingImpulseThreshold2(constrainu.ptr, threshold); } public override bool CalculateTransforms(BulletConstraint constrain) { - return BSAPICPP.CalculateTransforms2(constrain.ptr); + BulletConstraintUnman constrainu = constrain as BulletConstraintUnman; + return BSAPICPP.CalculateTransforms2(constrainu.ptr); } public override bool SetConstraintParam(BulletConstraint constrain, ConstraintParams paramIndex, float value, ConstraintParamAxis axis) { - return BSAPICPP.SetConstraintParam2(constrain.ptr, paramIndex, value, axis); + BulletConstraintUnman constrainu = constrain as BulletConstraintUnman; + return BSAPICPP.SetConstraintParam2(constrainu.ptr, paramIndex, value, axis); } public override bool DestroyConstraint(BulletWorld world, BulletConstraint constrain) { - return BSAPICPP.DestroyConstraint2(world.ptr, constrain.ptr); + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletConstraintUnman constrainu = constrain as BulletConstraintUnman; + return BSAPICPP.DestroyConstraint2(worldu.ptr, constrainu.ptr); } // ===================================================================================== // btCollisionWorld entries public override void UpdateSingleAabb(BulletWorld world, BulletBody obj) -{ - BSAPICPP.UpdateSingleAabb2(world.ptr, obj.ptr); +{ + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.UpdateSingleAabb2(worldu.ptr, bodyu.ptr); } public override void UpdateAabbs(BulletWorld world) { - BSAPICPP.UpdateAabbs2(world.ptr); + BulletWorldUnman worldu = world as BulletWorldUnman; + BSAPICPP.UpdateAabbs2(worldu.ptr); } public override bool GetForceUpdateAllAabbs(BulletWorld world) { - return BSAPICPP.GetForceUpdateAllAabbs2(world.ptr); + BulletWorldUnman worldu = world as BulletWorldUnman; + return BSAPICPP.GetForceUpdateAllAabbs2(worldu.ptr); } public override void SetForceUpdateAllAabbs(BulletWorld world, bool force) { - BSAPICPP.SetForceUpdateAllAabbs2(world.ptr, force); + BulletWorldUnman worldu = world as BulletWorldUnman; + BSAPICPP.SetForceUpdateAllAabbs2(worldu.ptr, force); } // ===================================================================================== // btDynamicsWorld entries public override bool AddObjectToWorld(BulletWorld world, BulletBody obj) { - return BSAPICPP.AddObjectToWorld2(world.ptr, obj.ptr); + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.AddObjectToWorld2(worldu.ptr, bodyu.ptr); } public override bool RemoveObjectFromWorld(BulletWorld world, BulletBody obj) { - return BSAPICPP.RemoveObjectFromWorld2(world.ptr, obj.ptr); + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.RemoveObjectFromWorld2(worldu.ptr, bodyu.ptr); } public override bool AddConstraintToWorld(BulletWorld world, BulletConstraint constrain, bool disableCollisionsBetweenLinkedObjects) { - return BSAPICPP.AddConstraintToWorld2(world.ptr, constrain.ptr, disableCollisionsBetweenLinkedObjects); + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletConstraintUnman constrainu = constrain as BulletConstraintUnman; + return BSAPICPP.AddConstraintToWorld2(worldu.ptr, constrainu.ptr, disableCollisionsBetweenLinkedObjects); } public override bool RemoveConstraintFromWorld(BulletWorld world, BulletConstraint constrain) { - return BSAPICPP.RemoveConstraintFromWorld2(world.ptr, constrain.ptr); + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletConstraintUnman constrainu = constrain as BulletConstraintUnman; + return BSAPICPP.RemoveConstraintFromWorld2(worldu.ptr, constrainu.ptr); } // ===================================================================================== // btCollisionObject entries public override Vector3 GetAnisotripicFriction(BulletConstraint constrain) { - return BSAPICPP.GetAnisotripicFriction2(constrain.ptr); + BulletConstraintUnman constrainu = constrain as BulletConstraintUnman; + return BSAPICPP.GetAnisotripicFriction2(constrainu.ptr); } public override Vector3 SetAnisotripicFriction(BulletConstraint constrain, Vector3 frict) { - return BSAPICPP.SetAnisotripicFriction2(constrain.ptr, frict); + BulletConstraintUnman constrainu = constrain as BulletConstraintUnman; + return BSAPICPP.SetAnisotripicFriction2(constrainu.ptr, frict); } public override bool HasAnisotripicFriction(BulletConstraint constrain) { - return BSAPICPP.HasAnisotripicFriction2(constrain.ptr); + BulletConstraintUnman constrainu = constrain as BulletConstraintUnman; + return BSAPICPP.HasAnisotripicFriction2(constrainu.ptr); } public override void SetContactProcessingThreshold(BulletBody obj, float val) { - BSAPICPP.SetContactProcessingThreshold2(obj.ptr, val); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetContactProcessingThreshold2(bodyu.ptr, val); } public override float GetContactProcessingThreshold(BulletBody obj) { - return BSAPICPP.GetContactProcessingThreshold2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetContactProcessingThreshold2(bodyu.ptr); } public override bool IsStaticObject(BulletBody obj) { - return BSAPICPP.IsStaticObject2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.IsStaticObject2(bodyu.ptr); } public override bool IsKinematicObject(BulletBody obj) { - return BSAPICPP.IsKinematicObject2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.IsKinematicObject2(bodyu.ptr); } public override bool IsStaticOrKinematicObject(BulletBody obj) { - return BSAPICPP.IsStaticOrKinematicObject2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.IsStaticOrKinematicObject2(bodyu.ptr); } public override bool HasContactResponse(BulletBody obj) { - return BSAPICPP.HasContactResponse2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.HasContactResponse2(bodyu.ptr); } -public override void SetCollisionShape(BulletWorld sim, BulletBody obj, BulletShape shape) +public override void SetCollisionShape(BulletWorld world, BulletBody obj, BulletShape shape) { - BSAPICPP.SetCollisionShape2(sim.ptr, obj.ptr, shape.ptr); + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BulletShapeUnman shapeu = shape as BulletShapeUnman; + if (worldu != null && bodyu != null) + { + // Special case to allow the caller to zero out the reference to any physical shape + if (shapeu != null) + BSAPICPP.SetCollisionShape2(worldu.ptr, bodyu.ptr, shapeu.ptr); + else + BSAPICPP.SetCollisionShape2(worldu.ptr, bodyu.ptr, IntPtr.Zero); + } } public override BulletShape GetCollisionShape(BulletBody obj) { - return new BulletShape(BSAPICPP.GetCollisionShape2(obj.ptr)); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return new BulletShapeUnman(BSAPICPP.GetCollisionShape2(bodyu.ptr), BSPhysicsShapeType.SHAPE_UNKNOWN); } public override int GetActivationState(BulletBody obj) { - return BSAPICPP.GetActivationState2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetActivationState2(bodyu.ptr); } public override void SetActivationState(BulletBody obj, int state) { - BSAPICPP.SetActivationState2(obj.ptr, state); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetActivationState2(bodyu.ptr, state); } public override void SetDeactivationTime(BulletBody obj, float dtime) { - BSAPICPP.SetDeactivationTime2(obj.ptr, dtime); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetDeactivationTime2(bodyu.ptr, dtime); } public override float GetDeactivationTime(BulletBody obj) { - return BSAPICPP.GetDeactivationTime2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetDeactivationTime2(bodyu.ptr); } public override void ForceActivationState(BulletBody obj, ActivationState state) { - BSAPICPP.ForceActivationState2(obj.ptr, state); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.ForceActivationState2(bodyu.ptr, state); } public override void Activate(BulletBody obj, bool forceActivation) { - BSAPICPP.Activate2(obj.ptr, forceActivation); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.Activate2(bodyu.ptr, forceActivation); } public override bool IsActive(BulletBody obj) { - return BSAPICPP.IsActive2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.IsActive2(bodyu.ptr); } public override void SetRestitution(BulletBody obj, float val) { - BSAPICPP.SetRestitution2(obj.ptr, val); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetRestitution2(bodyu.ptr, val); } public override float GetRestitution(BulletBody obj) { - return BSAPICPP.GetRestitution2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetRestitution2(bodyu.ptr); } public override void SetFriction(BulletBody obj, float val) { - BSAPICPP.SetFriction2(obj.ptr, val); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetFriction2(bodyu.ptr, val); } public override float GetFriction(BulletBody obj) { - return BSAPICPP.GetFriction2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetFriction2(bodyu.ptr); } public override Vector3 GetPosition(BulletBody obj) { - return BSAPICPP.GetPosition2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetPosition2(bodyu.ptr); } public override Quaternion GetOrientation(BulletBody obj) { - return BSAPICPP.GetOrientation2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetOrientation2(bodyu.ptr); } public override void SetTranslation(BulletBody obj, Vector3 position, Quaternion rotation) { - BSAPICPP.SetTranslation2(obj.ptr, position, rotation); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetTranslation2(bodyu.ptr, position, rotation); } /* public override IntPtr GetBroadphaseHandle(BulletBody obj) { - return BSAPICPP.GetBroadphaseHandle2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetBroadphaseHandle2(bodyu.ptr); } public override void SetBroadphaseHandle(BulletBody obj, IntPtr handle) { - BSAPICPP.SetUserPointer2(obj.ptr, handle); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetUserPointer2(bodyu.ptr, handle); } */ public override void SetInterpolationLinearVelocity(BulletBody obj, Vector3 vel) { - BSAPICPP.SetInterpolationLinearVelocity2(obj.ptr, vel); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetInterpolationLinearVelocity2(bodyu.ptr, vel); } public override void SetInterpolationAngularVelocity(BulletBody obj, Vector3 vel) { - BSAPICPP.SetInterpolationAngularVelocity2(obj.ptr, vel); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetInterpolationAngularVelocity2(bodyu.ptr, vel); } public override void SetInterpolationVelocity(BulletBody obj, Vector3 linearVel, Vector3 angularVel) { - BSAPICPP.SetInterpolationVelocity2(obj.ptr, linearVel, angularVel); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetInterpolationVelocity2(bodyu.ptr, linearVel, angularVel); } public override float GetHitFraction(BulletBody obj) { - return BSAPICPP.GetHitFraction2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetHitFraction2(bodyu.ptr); } public override void SetHitFraction(BulletBody obj, float val) { - BSAPICPP.SetHitFraction2(obj.ptr, val); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetHitFraction2(bodyu.ptr, val); } public override CollisionFlags GetCollisionFlags(BulletBody obj) { - return BSAPICPP.GetCollisionFlags2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetCollisionFlags2(bodyu.ptr); } public override CollisionFlags SetCollisionFlags(BulletBody obj, CollisionFlags flags) { - return BSAPICPP.SetCollisionFlags2(obj.ptr, flags); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.SetCollisionFlags2(bodyu.ptr, flags); } public override CollisionFlags AddToCollisionFlags(BulletBody obj, CollisionFlags flags) { - return BSAPICPP.AddToCollisionFlags2(obj.ptr, flags); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.AddToCollisionFlags2(bodyu.ptr, flags); } public override CollisionFlags RemoveFromCollisionFlags(BulletBody obj, CollisionFlags flags) { - return BSAPICPP.RemoveFromCollisionFlags2(obj.ptr, flags); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.RemoveFromCollisionFlags2(bodyu.ptr, flags); } public override float GetCcdMotionThreshold(BulletBody obj) { - return BSAPICPP.GetCcdMotionThreshold2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetCcdMotionThreshold2(bodyu.ptr); } public override void SetCcdMotionThreshold(BulletBody obj, float val) { - BSAPICPP.SetCcdMotionThreshold2(obj.ptr, val); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetCcdMotionThreshold2(bodyu.ptr, val); } public override float GetCcdSweptSphereRadius(BulletBody obj) { - return BSAPICPP.GetCcdSweptSphereRadius2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetCcdSweptSphereRadius2(bodyu.ptr); } public override void SetCcdSweptSphereRadius(BulletBody obj, float val) { - BSAPICPP.SetCcdSweptSphereRadius2(obj.ptr, val); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetCcdSweptSphereRadius2(bodyu.ptr, val); } public override IntPtr GetUserPointer(BulletBody obj) { - return BSAPICPP.GetUserPointer2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetUserPointer2(bodyu.ptr); } public override void SetUserPointer(BulletBody obj, IntPtr val) { - BSAPICPP.SetUserPointer2(obj.ptr, val); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetUserPointer2(bodyu.ptr, val); } // ===================================================================================== // btRigidBody entries public override void ApplyGravity(BulletBody obj) { - BSAPICPP.ApplyGravity2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.ApplyGravity2(bodyu.ptr); } public override void SetGravity(BulletBody obj, Vector3 val) { - BSAPICPP.SetGravity2(obj.ptr, val); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetGravity2(bodyu.ptr, val); } public override Vector3 GetGravity(BulletBody obj) { - return BSAPICPP.GetGravity2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetGravity2(bodyu.ptr); } public override void SetDamping(BulletBody obj, float lin_damping, float ang_damping) { - BSAPICPP.SetDamping2(obj.ptr, lin_damping, ang_damping); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetDamping2(bodyu.ptr, lin_damping, ang_damping); } public override void SetLinearDamping(BulletBody obj, float lin_damping) { - BSAPICPP.SetLinearDamping2(obj.ptr, lin_damping); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetLinearDamping2(bodyu.ptr, lin_damping); } public override void SetAngularDamping(BulletBody obj, float ang_damping) { - BSAPICPP.SetAngularDamping2(obj.ptr, ang_damping); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetAngularDamping2(bodyu.ptr, ang_damping); } public override float GetLinearDamping(BulletBody obj) { - return BSAPICPP.GetLinearDamping2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetLinearDamping2(bodyu.ptr); } public override float GetAngularDamping(BulletBody obj) { - return BSAPICPP.GetAngularDamping2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetAngularDamping2(bodyu.ptr); } public override float GetLinearSleepingThreshold(BulletBody obj) { - return BSAPICPP.GetLinearSleepingThreshold2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetLinearSleepingThreshold2(bodyu.ptr); } public override void ApplyDamping(BulletBody obj, float timeStep) { - BSAPICPP.ApplyDamping2(obj.ptr, timeStep); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.ApplyDamping2(bodyu.ptr, timeStep); } public override void SetMassProps(BulletBody obj, float mass, Vector3 inertia) { - BSAPICPP.SetMassProps2(obj.ptr, mass, inertia); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetMassProps2(bodyu.ptr, mass, inertia); } public override Vector3 GetLinearFactor(BulletBody obj) { - return BSAPICPP.GetLinearFactor2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetLinearFactor2(bodyu.ptr); } public override void SetLinearFactor(BulletBody obj, Vector3 factor) { - BSAPICPP.SetLinearFactor2(obj.ptr, factor); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetLinearFactor2(bodyu.ptr, factor); } public override void SetCenterOfMassByPosRot(BulletBody obj, Vector3 pos, Quaternion rot) { - BSAPICPP.SetCenterOfMassByPosRot2(obj.ptr, pos, rot); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetCenterOfMassByPosRot2(bodyu.ptr, pos, rot); } // Add a force to the object as if its mass is one. public override void ApplyCentralForce(BulletBody obj, Vector3 force) { - BSAPICPP.ApplyCentralForce2(obj.ptr, force); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.ApplyCentralForce2(bodyu.ptr, force); } // Set the force being applied to the object as if its mass is one. public override void SetObjectForce(BulletBody obj, Vector3 force) { - BSAPICPP.SetObjectForce2(obj.ptr, force); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetObjectForce2(bodyu.ptr, force); } public override Vector3 GetTotalForce(BulletBody obj) { - return BSAPICPP.GetTotalForce2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetTotalForce2(bodyu.ptr); } public override Vector3 GetTotalTorque(BulletBody obj) { - return BSAPICPP.GetTotalTorque2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetTotalTorque2(bodyu.ptr); } public override Vector3 GetInvInertiaDiagLocal(BulletBody obj) { - return BSAPICPP.GetInvInertiaDiagLocal2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetInvInertiaDiagLocal2(bodyu.ptr); } public override void SetInvInertiaDiagLocal(BulletBody obj, Vector3 inert) { - BSAPICPP.SetInvInertiaDiagLocal2(obj.ptr, inert); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetInvInertiaDiagLocal2(bodyu.ptr, inert); } public override void SetSleepingThresholds(BulletBody obj, float lin_threshold, float ang_threshold) { - BSAPICPP.SetSleepingThresholds2(obj.ptr, lin_threshold, ang_threshold); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetSleepingThresholds2(bodyu.ptr, lin_threshold, ang_threshold); } public override void ApplyTorque(BulletBody obj, Vector3 torque) { - BSAPICPP.ApplyTorque2(obj.ptr, torque); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.ApplyTorque2(bodyu.ptr, torque); } // Apply force at the given point. Will add torque to the object. public override void ApplyForce(BulletBody obj, Vector3 force, Vector3 pos) { - BSAPICPP.ApplyForce2(obj.ptr, force, pos); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.ApplyForce2(bodyu.ptr, force, pos); } // Apply impulse to the object. Same as "ApplycentralForce" but force scaled by object's mass. public override void ApplyCentralImpulse(BulletBody obj, Vector3 imp) { - BSAPICPP.ApplyCentralImpulse2(obj.ptr, imp); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.ApplyCentralImpulse2(bodyu.ptr, imp); } // Apply impulse to the object's torque. Force is scaled by object's mass. public override void ApplyTorqueImpulse(BulletBody obj, Vector3 imp) { - BSAPICPP.ApplyTorqueImpulse2(obj.ptr, imp); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.ApplyTorqueImpulse2(bodyu.ptr, imp); } // Apply impulse at the point given. For is scaled by object's mass and effects both linear and angular forces. public override void ApplyImpulse(BulletBody obj, Vector3 imp, Vector3 pos) { - BSAPICPP.ApplyImpulse2(obj.ptr, imp, pos); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.ApplyImpulse2(bodyu.ptr, imp, pos); } public override void ClearForces(BulletBody obj) { - BSAPICPP.ClearForces2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.ClearForces2(bodyu.ptr); } public override void ClearAllForces(BulletBody obj) { - BSAPICPP.ClearAllForces2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.ClearAllForces2(bodyu.ptr); } public override void UpdateInertiaTensor(BulletBody obj) { - BSAPICPP.UpdateInertiaTensor2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.UpdateInertiaTensor2(bodyu.ptr); } public override Vector3 GetLinearVelocity(BulletBody obj) { - return BSAPICPP.GetLinearVelocity2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetLinearVelocity2(bodyu.ptr); } public override Vector3 GetAngularVelocity(BulletBody obj) { - return BSAPICPP.GetAngularVelocity2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetAngularVelocity2(bodyu.ptr); } public override void SetLinearVelocity(BulletBody obj, Vector3 vel) { - BSAPICPP.SetLinearVelocity2(obj.ptr, vel); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetLinearVelocity2(bodyu.ptr, vel); } public override void SetAngularVelocity(BulletBody obj, Vector3 angularVelocity) { - BSAPICPP.SetAngularVelocity2(obj.ptr, angularVelocity); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetAngularVelocity2(bodyu.ptr, angularVelocity); } public override Vector3 GetVelocityInLocalPoint(BulletBody obj, Vector3 pos) { - return BSAPICPP.GetVelocityInLocalPoint2(obj.ptr, pos); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetVelocityInLocalPoint2(bodyu.ptr, pos); } public override void Translate(BulletBody obj, Vector3 trans) { - BSAPICPP.Translate2(obj.ptr, trans); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.Translate2(bodyu.ptr, trans); } public override void UpdateDeactivation(BulletBody obj, float timeStep) { - BSAPICPP.UpdateDeactivation2(obj.ptr, timeStep); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.UpdateDeactivation2(bodyu.ptr, timeStep); } public override bool WantsSleeping(BulletBody obj) { - return BSAPICPP.WantsSleeping2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.WantsSleeping2(bodyu.ptr); } public override void SetAngularFactor(BulletBody obj, float factor) { - BSAPICPP.SetAngularFactor2(obj.ptr, factor); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetAngularFactor2(bodyu.ptr, factor); } public override void SetAngularFactorV(BulletBody obj, Vector3 factor) { - BSAPICPP.SetAngularFactorV2(obj.ptr, factor); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BSAPICPP.SetAngularFactorV2(bodyu.ptr, factor); } public override Vector3 GetAngularFactor(BulletBody obj) { - return BSAPICPP.GetAngularFactor2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetAngularFactor2(bodyu.ptr); } public override bool IsInWorld(BulletBody obj) { - return BSAPICPP.IsInWorld2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.IsInWorld2(bodyu.ptr); } public override void AddConstraintRef(BulletBody obj, BulletConstraint constrain) { - BSAPICPP.AddConstraintRef2(obj.ptr, constrain.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BulletConstraintUnman constrainu = constrain as BulletConstraintUnman; + BSAPICPP.AddConstraintRef2(bodyu.ptr, constrainu.ptr); } public override void RemoveConstraintRef(BulletBody obj, BulletConstraint constrain) { - BSAPICPP.RemoveConstraintRef2(obj.ptr, constrain.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + BulletConstraintUnman constrainu = constrain as BulletConstraintUnman; + BSAPICPP.RemoveConstraintRef2(bodyu.ptr, constrainu.ptr); } public override BulletConstraint GetConstraintRef(BulletBody obj, int index) { - return new BulletConstraint(BSAPICPP.GetConstraintRef2(obj.ptr, index)); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return new BulletConstraintUnman(BSAPICPP.GetConstraintRef2(bodyu.ptr, index)); } public override int GetNumConstraintRefs(BulletBody obj) { - return BSAPICPP.GetNumConstraintRefs2(obj.ptr); + BulletBodyUnman bodyu = obj as BulletBodyUnman; + return BSAPICPP.GetNumConstraintRefs2(bodyu.ptr); } public override bool SetCollisionGroupMask(BulletBody body, uint filter, uint mask) { - return BSAPICPP.SetCollisionGroupMask2(body.ptr, filter, mask); + BulletBodyUnman bodyu = body as BulletBodyUnman; + return BSAPICPP.SetCollisionGroupMask2(bodyu.ptr, filter, mask); } // ===================================================================================== @@ -855,114 +1104,139 @@ public override bool SetCollisionGroupMask(BulletBody body, uint filter, uint ma public override float GetAngularMotionDisc(BulletShape shape) { - return BSAPICPP.GetAngularMotionDisc2(shape.ptr); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + return BSAPICPP.GetAngularMotionDisc2(shapeu.ptr); } public override float GetContactBreakingThreshold(BulletShape shape, float defaultFactor) { - return BSAPICPP.GetContactBreakingThreshold2(shape.ptr, defaultFactor); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + return BSAPICPP.GetContactBreakingThreshold2(shapeu.ptr, defaultFactor); } public override bool IsPolyhedral(BulletShape shape) { - return BSAPICPP.IsPolyhedral2(shape.ptr); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + return BSAPICPP.IsPolyhedral2(shapeu.ptr); } public override bool IsConvex2d(BulletShape shape) { - return BSAPICPP.IsConvex2d2(shape.ptr); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + return BSAPICPP.IsConvex2d2(shapeu.ptr); } public override bool IsConvex(BulletShape shape) { - return BSAPICPP.IsConvex2(shape.ptr); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + return BSAPICPP.IsConvex2(shapeu.ptr); } public override bool IsNonMoving(BulletShape shape) { - return BSAPICPP.IsNonMoving2(shape.ptr); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + return BSAPICPP.IsNonMoving2(shapeu.ptr); } public override bool IsConcave(BulletShape shape) { - return BSAPICPP.IsConcave2(shape.ptr); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + return BSAPICPP.IsConcave2(shapeu.ptr); } public override bool IsCompound(BulletShape shape) { - return BSAPICPP.IsCompound2(shape.ptr); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + return BSAPICPP.IsCompound2(shapeu.ptr); } public override bool IsSoftBody(BulletShape shape) { - return BSAPICPP.IsSoftBody2(shape.ptr); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + return BSAPICPP.IsSoftBody2(shapeu.ptr); } public override bool IsInfinite(BulletShape shape) { - return BSAPICPP.IsInfinite2(shape.ptr); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + return BSAPICPP.IsInfinite2(shapeu.ptr); } public override void SetLocalScaling(BulletShape shape, Vector3 scale) { - BSAPICPP.SetLocalScaling2(shape.ptr, scale); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + BSAPICPP.SetLocalScaling2(shapeu.ptr, scale); } public override Vector3 GetLocalScaling(BulletShape shape) { - return BSAPICPP.GetLocalScaling2(shape.ptr); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + return BSAPICPP.GetLocalScaling2(shapeu.ptr); } public override Vector3 CalculateLocalInertia(BulletShape shape, float mass) { - return BSAPICPP.CalculateLocalInertia2(shape.ptr, mass); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + return BSAPICPP.CalculateLocalInertia2(shapeu.ptr, mass); } public override int GetShapeType(BulletShape shape) { - return BSAPICPP.GetShapeType2(shape.ptr); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + return BSAPICPP.GetShapeType2(shapeu.ptr); } public override void SetMargin(BulletShape shape, float val) { - BSAPICPP.SetMargin2(shape.ptr, val); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + BSAPICPP.SetMargin2(shapeu.ptr, val); } public override float GetMargin(BulletShape shape) { - return BSAPICPP.GetMargin2(shape.ptr); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + return BSAPICPP.GetMargin2(shapeu.ptr); } // ===================================================================================== // Debugging -public override void DumpRigidBody(BulletWorld sim, BulletBody collisionObject) +public override void DumpRigidBody(BulletWorld world, BulletBody collisionObject) { - BSAPICPP.DumpRigidBody2(sim.ptr, collisionObject.ptr); + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletBodyUnman bodyu = collisionObject as BulletBodyUnman; + BSAPICPP.DumpRigidBody2(worldu.ptr, bodyu.ptr); } -public override void DumpCollisionShape(BulletWorld sim, BulletShape collisionShape) +public override void DumpCollisionShape(BulletWorld world, BulletShape collisionShape) { - BSAPICPP.DumpCollisionShape2(sim.ptr, collisionShape.ptr); + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletShapeUnman shapeu = collisionShape as BulletShapeUnman; + BSAPICPP.DumpCollisionShape2(worldu.ptr, shapeu.ptr); } -public override void DumpConstraint(BulletWorld sim, BulletConstraint constrain) +public override void DumpConstraint(BulletWorld world, BulletConstraint constrain) { - BSAPICPP.DumpConstraint2(sim.ptr, constrain.ptr); + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletConstraintUnman constrainu = constrain as BulletConstraintUnman; + BSAPICPP.DumpConstraint2(worldu.ptr, constrainu.ptr); } -public override void DumpActivationInfo(BulletWorld sim) +public override void DumpActivationInfo(BulletWorld world) { - BSAPICPP.DumpActivationInfo2(sim.ptr); + BulletWorldUnman worldu = world as BulletWorldUnman; + BSAPICPP.DumpActivationInfo2(worldu.ptr); } -public override void DumpAllInfo(BulletWorld sim) +public override void DumpAllInfo(BulletWorld world) { - BSAPICPP.DumpAllInfo2(sim.ptr); + BulletWorldUnman worldu = world as BulletWorldUnman; + BSAPICPP.DumpAllInfo2(worldu.ptr); } -public override void DumpPhysicsStatistics(BulletWorld sim) +public override void DumpPhysicsStatistics(BulletWorld world) { - BSAPICPP.DumpPhysicsStatistics2(sim.ptr); + BulletWorldUnman worldu = world as BulletWorldUnman; + BSAPICPP.DumpPhysicsStatistics2(worldu.ptr); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs index 8ed791e..f70ad30 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs @@ -29,11 +29,1287 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using BulletXNA; +using BulletXNA.LinearMath; +using BulletXNA.BulletCollision; +using BulletXNA.BulletDynamics; +using BulletXNA.BulletCollision.CollisionDispatch; + +using OpenMetaverse; + namespace OpenSim.Region.Physics.BulletSPlugin { /* public sealed class BSAPIXNA : BSAPITemplate { + private static int m_collisionsThisFrame; + private BSScene PhysicsScene { get; set; } + + public override string BulletEngineName { get { return "BulletXNA"; } } + public override string BulletEngineVersion { get; protected set; } + + public BSAPIXNA(string paramName, BSScene physScene) + { + PhysicsScene = physScene; + } + + /// + /// + /// + /// + /// + public override bool RemoveObjectFromWorld2(object pWorld, object pBody) + { + DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + RigidBody body = pBody as RigidBody; + world.RemoveRigidBody(body); + return true; + } + + public override void SetRestitution2(object pBody, float pRestitution) + { + RigidBody body = pBody as RigidBody; + body.SetRestitution(pRestitution); + } + + public override void SetMargin2(object pShape, float pMargin) + { + CollisionShape shape = pShape as CollisionShape; + shape.SetMargin(pMargin); + } + + public override void SetLocalScaling2(object pShape, Vector3 pScale) + { + CollisionShape shape = pShape as CollisionShape; + IndexedVector3 vec = new IndexedVector3(pScale.X, pScale.Y, pScale.Z); + shape.SetLocalScaling(ref vec); + + } + + public override void SetContactProcessingThreshold2(object pBody, float contactprocessingthreshold) + { + RigidBody body = pBody as RigidBody; + body.SetContactProcessingThreshold(contactprocessingthreshold); + } + + public override void SetCcdMotionThreshold2(object pBody, float pccdMotionThreashold) + { + RigidBody body = pBody as RigidBody; + body.SetCcdMotionThreshold(pccdMotionThreashold); + } + + public override void SetCcdSweptSphereRadius2(object pBody, float pCcdSweptSphereRadius) + { + RigidBody body = pBody as RigidBody; + body.SetCcdSweptSphereRadius(pCcdSweptSphereRadius); + } + + public override void SetAngularFactorV2(object pBody, Vector3 pAngularFactor) + { + RigidBody body = pBody as RigidBody; + body.SetAngularFactor(new IndexedVector3(pAngularFactor.X, pAngularFactor.Y, pAngularFactor.Z)); + } + + public override CollisionFlags AddToCollisionFlags2(object pBody, CollisionFlags pcollisionFlags) + { + CollisionObject body = pBody as CollisionObject; + CollisionFlags existingcollisionFlags = (CollisionFlags)(uint)body.GetCollisionFlags(); + existingcollisionFlags |= pcollisionFlags; + body.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags)(uint)existingcollisionFlags); + return (CollisionFlags) (uint) existingcollisionFlags; + } + + public override void AddObjectToWorld2(object pWorld, object pBody) + { + RigidBody body = pBody as RigidBody; + DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + //if (!(body.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.STATIC_PLANE_PROXYTYPE && body.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.TERRAIN_SHAPE_PROXYTYPE)) + + world.AddRigidBody(body); + + //if (body.GetBroadphaseHandle() != null) + // world.UpdateSingleAabb(body); + } + + public override void AddObjectToWorld2(object pWorld, object pBody, Vector3 _position, Quaternion _orientation) + { + RigidBody body = pBody as RigidBody; + DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + //if (!(body.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.STATIC_PLANE_PROXYTYPE && body.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.TERRAIN_SHAPE_PROXYTYPE)) + + world.AddRigidBody(body); + IndexedVector3 vposition = new IndexedVector3(_position.X, _position.Y, _position.Z); + IndexedQuaternion vquaternion = new IndexedQuaternion(_orientation.X, _orientation.Y, _orientation.Z, + _orientation.W); + IndexedMatrix mat = IndexedMatrix.CreateFromQuaternion(vquaternion); + mat._origin = vposition; + body.SetWorldTransform(mat); + //if (body.GetBroadphaseHandle() != null) + // world.UpdateSingleAabb(body); + } + + public override void ForceActivationState2(object pBody, ActivationState pActivationState) + { + CollisionObject body = pBody as CollisionObject; + body.ForceActivationState((BulletXNA.BulletCollision.ActivationState)(uint)pActivationState); + } + + public override void UpdateSingleAabb2(object pWorld, object pBody) + { + CollisionObject body = pBody as CollisionObject; + DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + world.UpdateSingleAabb(body); + } + + public override bool SetCollisionGroupMask2(object pBody, uint pGroup, uint pMask) + { + RigidBody body = pBody as RigidBody; + body.GetBroadphaseHandle().m_collisionFilterGroup = (BulletXNA.BulletCollision.CollisionFilterGroups) pGroup; + body.GetBroadphaseHandle().m_collisionFilterGroup = (BulletXNA.BulletCollision.CollisionFilterGroups) pGroup; + if ((uint) body.GetBroadphaseHandle().m_collisionFilterGroup == 0) + return false; + return true; + } + + public override void ClearAllForces2(object pBody) + { + CollisionObject body = pBody as CollisionObject; + IndexedVector3 zeroVector = new IndexedVector3(0, 0, 0); + body.SetInterpolationLinearVelocity(ref zeroVector); + body.SetInterpolationAngularVelocity(ref zeroVector); + IndexedMatrix bodytransform = body.GetWorldTransform(); + + body.SetInterpolationWorldTransform(ref bodytransform); + + if (body is RigidBody) + { + RigidBody rigidbody = body as RigidBody; + rigidbody.SetLinearVelocity(zeroVector); + rigidbody.SetAngularVelocity(zeroVector); + rigidbody.ClearForces(); + } + } + + public override void SetInterpolationAngularVelocity2(object pBody, Vector3 pVector3) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 vec = new IndexedVector3(pVector3.X, pVector3.Y, pVector3.Z); + body.SetInterpolationAngularVelocity(ref vec); + } + + public override void SetAngularVelocity2(object pBody, Vector3 pVector3) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 vec = new IndexedVector3(pVector3.X, pVector3.Y, pVector3.Z); + body.SetAngularVelocity(ref vec); + } + + public override void ClearForces2(object pBody) + { + RigidBody body = pBody as RigidBody; + body.ClearForces(); + } + + public override void SetTranslation2(object pBody, Vector3 _position, Quaternion _orientation) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 vposition = new IndexedVector3(_position.X, _position.Y, _position.Z); + IndexedQuaternion vquaternion = new IndexedQuaternion(_orientation.X, _orientation.Y, _orientation.Z, + _orientation.W); + IndexedMatrix mat = IndexedMatrix.CreateFromQuaternion(vquaternion); + mat._origin = vposition; + body.SetWorldTransform(mat); + + } + + public override Vector3 GetPosition2(object pBody) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 pos = body.GetInterpolationWorldTransform()._origin; + return new Vector3(pos.X, pos.Y, pos.Z); + } + + public override Vector3 CalculateLocalInertia2(object pShape, float pphysMass) + { + CollisionShape shape = pShape as CollisionShape; + IndexedVector3 inertia = IndexedVector3.Zero; + shape.CalculateLocalInertia(pphysMass, out inertia); + return new Vector3(inertia.X, inertia.Y, inertia.Z); + } + + public override void SetMassProps2(object pBody, float pphysMass, Vector3 plocalInertia) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 inertia = new IndexedVector3(plocalInertia.X, plocalInertia.Y, plocalInertia.Z); + body.SetMassProps(pphysMass, inertia); + } + + + public override void SetObjectForce2(object pBody, Vector3 _force) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 force = new IndexedVector3(_force.X, _force.Y, _force.Z); + body.SetTotalForce(ref force); + } + + public override void SetFriction2(object pBody, float _currentFriction) + { + RigidBody body = pBody as RigidBody; + body.SetFriction(_currentFriction); + } + + public override void SetLinearVelocity2(object pBody, Vector3 _velocity) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 velocity = new IndexedVector3(_velocity.X, _velocity.Y, _velocity.Z); + body.SetLinearVelocity(velocity); + } + + public override void Activate2(object pBody, bool pforceactivation) + { + RigidBody body = pBody as RigidBody; + body.Activate(pforceactivation); + + } + + public override Quaternion GetOrientation2(object pBody) + { + RigidBody body = pBody as RigidBody; + IndexedQuaternion mat = body.GetInterpolationWorldTransform().GetRotation(); + return new Quaternion(mat.X, mat.Y, mat.Z, mat.W); + } + + public override CollisionFlags RemoveFromCollisionFlags2(object pBody, CollisionFlags pcollisionFlags) + { + RigidBody body = pBody as RigidBody; + CollisionFlags existingcollisionFlags = (CollisionFlags)(uint)body.GetCollisionFlags(); + existingcollisionFlags &= ~pcollisionFlags; + body.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags)(uint)existingcollisionFlags); + return (CollisionFlags)(uint)existingcollisionFlags; + } + + public override void SetGravity2(object pBody, Vector3 pGravity) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 gravity = new IndexedVector3(pGravity.X, pGravity.Y, pGravity.Z); + body.SetGravity(gravity); + } + + public override bool DestroyConstraint2(object pBody, object pConstraint) + { + RigidBody body = pBody as RigidBody; + TypedConstraint constraint = pConstraint as TypedConstraint; + body.RemoveConstraintRef(constraint); + return true; + } + + public override bool SetLinearLimits2(object pConstraint, Vector3 low, Vector3 high) + { + Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; + IndexedVector3 lowlimit = new IndexedVector3(low.X, low.Y, low.Z); + IndexedVector3 highlimit = new IndexedVector3(high.X, high.Y, high.Z); + constraint.SetLinearLowerLimit(lowlimit); + constraint.SetLinearUpperLimit(highlimit); + return true; + } + + public override bool SetAngularLimits2(object pConstraint, Vector3 low, Vector3 high) + { + Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; + IndexedVector3 lowlimit = new IndexedVector3(low.X, low.Y, low.Z); + IndexedVector3 highlimit = new IndexedVector3(high.X, high.Y, high.Z); + constraint.SetAngularLowerLimit(lowlimit); + constraint.SetAngularUpperLimit(highlimit); + return true; + } + + public override void SetConstraintNumSolverIterations2(object pConstraint, float cnt) + { + Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; + constraint.SetOverrideNumSolverIterations((int)cnt); + } + + public override void CalculateTransforms2(object pConstraint) + { + Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; + constraint.CalculateTransforms(); + } + + public override void SetConstraintEnable2(object pConstraint, float p_2) + { + Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; + constraint.SetEnabled((p_2 == 0) ? false : true); + } + + + //BulletSimAPI.Create6DofConstraint2(m_world.ptr, m_body1.ptr, m_body2.ptr,frame1, frame1rot,frame2, frame2rot,useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); + public override object Create6DofConstraint2(object pWorld, object pBody1, object pBody2, Vector3 pframe1, Quaternion pframe1rot, Vector3 pframe2, Quaternion pframe2rot, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies) + + { + DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + RigidBody body1 = pBody1 as RigidBody; + RigidBody body2 = pBody2 as RigidBody; + IndexedVector3 frame1v = new IndexedVector3(pframe1.X, pframe1.Y, pframe1.Z); + IndexedQuaternion frame1rot = new IndexedQuaternion(pframe1rot.X, pframe1rot.Y, pframe1rot.Z, pframe1rot.W); + IndexedMatrix frame1 = IndexedMatrix.CreateFromQuaternion(frame1rot); + frame1._origin = frame1v; + + IndexedVector3 frame2v = new IndexedVector3(pframe2.X, pframe2.Y, pframe2.Z); + IndexedQuaternion frame2rot = new IndexedQuaternion(pframe2rot.X, pframe2rot.Y, pframe2rot.Z, pframe2rot.W); + IndexedMatrix frame2 = IndexedMatrix.CreateFromQuaternion(frame2rot); + frame2._origin = frame1v; + + Generic6DofConstraint consttr = new Generic6DofConstraint(body1, body2, ref frame1, ref frame2, + puseLinearReferenceFrameA); + consttr.CalculateTransforms(); + world.AddConstraint(consttr,pdisableCollisionsBetweenLinkedBodies); + + return consttr; + } + + + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public override object Create6DofConstraintToPoint2(object pWorld, object pBody1, object pBody2, Vector3 pjoinPoint, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies) + { + DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + RigidBody body1 = pBody1 as RigidBody; + RigidBody body2 = pBody2 as RigidBody; + IndexedMatrix frame1 = new IndexedMatrix(IndexedBasisMatrix.Identity, new IndexedVector3(0, 0, 0)); + IndexedMatrix frame2 = new IndexedMatrix(IndexedBasisMatrix.Identity, new IndexedVector3(0, 0, 0)); + + IndexedVector3 joinPoint = new IndexedVector3(pjoinPoint.X, pjoinPoint.Y, pjoinPoint.Z); + IndexedMatrix mat = IndexedMatrix.Identity; + mat._origin = new IndexedVector3(pjoinPoint.X, pjoinPoint.Y, pjoinPoint.Z); + frame1._origin = body1.GetWorldTransform().Inverse()*joinPoint; + frame2._origin = body2.GetWorldTransform().Inverse()*joinPoint; + + Generic6DofConstraint consttr = new Generic6DofConstraint(body1, body2, ref frame1, ref frame2, puseLinearReferenceFrameA); + consttr.CalculateTransforms(); + world.AddConstraint(consttr, pdisableCollisionsBetweenLinkedBodies); + + return consttr; + } + //SetFrames2(m_constraint.ptr, frameA, frameArot, frameB, frameBrot); + public override void SetFrames2(object pConstraint, Vector3 pframe1, Quaternion pframe1rot, Vector3 pframe2, Quaternion pframe2rot) + { + Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; + IndexedVector3 frame1v = new IndexedVector3(pframe1.X, pframe1.Y, pframe1.Z); + IndexedQuaternion frame1rot = new IndexedQuaternion(pframe1rot.X, pframe1rot.Y, pframe1rot.Z, pframe1rot.W); + IndexedMatrix frame1 = IndexedMatrix.CreateFromQuaternion(frame1rot); + frame1._origin = frame1v; + + IndexedVector3 frame2v = new IndexedVector3(pframe2.X, pframe2.Y, pframe2.Z); + IndexedQuaternion frame2rot = new IndexedQuaternion(pframe2rot.X, pframe2rot.Y, pframe2rot.Z, pframe2rot.W); + IndexedMatrix frame2 = IndexedMatrix.CreateFromQuaternion(frame2rot); + frame2._origin = frame1v; + constraint.SetFrames(ref frame1, ref frame2); + } + + + + + public override bool IsInWorld2(object pWorld, object pShapeObj) + { + DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + CollisionObject shape = pShapeObj as CollisionObject; + return world.IsInWorld(shape); + } + + public override void SetInterpolationLinearVelocity2(object pBody, Vector3 VehicleVelocity) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 velocity = new IndexedVector3(VehicleVelocity.X, VehicleVelocity.Y, VehicleVelocity.Z); + body.SetInterpolationLinearVelocity(ref velocity); + } + + public override bool UseFrameOffset2(object pConstraint, float onOff) + { + Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; + constraint.SetUseFrameOffset((onOff == 0) ? false : true); + return true; + } + //SetBreakingImpulseThreshold2(m_constraint.ptr, threshold); + public override bool SetBreakingImpulseThreshold2(object pConstraint, float threshold) + { + Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; + constraint.SetBreakingImpulseThreshold(threshold); + return true; + } + //BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, angularDamping); + public override void SetAngularDamping2(object pBody, float angularDamping) + { + RigidBody body = pBody as RigidBody; + float lineardamping = body.GetLinearDamping(); + body.SetDamping(lineardamping, angularDamping); + + } + + public override void UpdateInertiaTensor2(object pBody) + { + RigidBody body = pBody as RigidBody; + body.UpdateInertiaTensor(); + } + + public override void RecalculateCompoundShapeLocalAabb2( object pCompoundShape) + { + + CompoundShape shape = pCompoundShape as CompoundShape; + shape.RecalculateLocalAabb(); + } + + //BulletSimAPI.GetCollisionFlags2(PhysBody.ptr) + public override CollisionFlags GetCollisionFlags2(object pBody) + { + RigidBody body = pBody as RigidBody; + uint flags = (uint)body.GetCollisionFlags(); + return (CollisionFlags) flags; + } + + public override void SetDamping2(object pBody, float pLinear, float pAngular) + { + RigidBody body = pBody as RigidBody; + body.SetDamping(pLinear, pAngular); + } + //PhysBody.ptr, PhysicsScene.Params.deactivationTime); + public override void SetDeactivationTime2(object pBody, float pDeactivationTime) + { + RigidBody body = pBody as RigidBody; + body.SetDeactivationTime(pDeactivationTime); + } + //SetSleepingThresholds2(PhysBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold); + public override void SetSleepingThresholds2(object pBody, float plinearSleepingThreshold, float pangularSleepingThreshold) + { + RigidBody body = pBody as RigidBody; + body.SetSleepingThresholds(plinearSleepingThreshold, pangularSleepingThreshold); + } + + public override CollisionObjectTypes GetBodyType2(object pBody) + { + RigidBody body = pBody as RigidBody; + return (CollisionObjectTypes)(int) body.GetInternalType(); + } + + //BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, fSum); + public override void ApplyCentralForce2(object pBody, Vector3 pfSum) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z); + body.ApplyCentralForce(ref fSum); + } + public override void ApplyCentralImpulse2(object pBody, Vector3 pfSum) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z); + body.ApplyCentralImpulse(ref fSum); + } + public override void ApplyTorque2(object pBody, Vector3 pfSum) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z); + body.ApplyTorque(ref fSum); + } + public override void ApplyTorqueImpulse2(object pBody, Vector3 pfSum) + { + RigidBody body = pBody as RigidBody; + IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z); + body.ApplyTorqueImpulse(ref fSum); + } + + public override void DumpRigidBody2(object p, object p_2) + { + //TODO: + } + + public override void DumpCollisionShape2(object p, object p_2) + { + //TODO: + } + + public override void DestroyObject2(object p, object p_2) + { + //TODO: + } + + public override void Shutdown2(object pWorld) + { + DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + world.Cleanup(); + } + + public override void DeleteCollisionShape2(object p, object p_2) + { + //TODO: + } + //(sim.ptr, shape.ptr, prim.LocalID, prim.RawPosition, prim.RawOrientation); + + public override object CreateBodyFromShape2(object pWorld, object pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation) + { + CollisionWorld world = pWorld as CollisionWorld; + IndexedMatrix mat = + IndexedMatrix.CreateFromQuaternion(new IndexedQuaternion(pRawOrientation.X, pRawOrientation.Y, + pRawOrientation.Z, pRawOrientation.W)); + mat._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z); + CollisionShape shape = pShape as CollisionShape; + //UpdateSingleAabb2(world, shape); + // TODO: Feed Update array into null + RigidBody body = new RigidBody(0,new SimMotionState(world,pLocalID,mat,null),shape,IndexedVector3.Zero); + + body.SetUserPointer(pLocalID); + return body; + } + + + public override object CreateBodyWithDefaultMotionState2( object pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation) + { + + IndexedMatrix mat = + IndexedMatrix.CreateFromQuaternion(new IndexedQuaternion(pRawOrientation.X, pRawOrientation.Y, + pRawOrientation.Z, pRawOrientation.W)); + mat._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z); + + CollisionShape shape = pShape as CollisionShape; + + // TODO: Feed Update array into null + RigidBody body = new RigidBody(0, new DefaultMotionState( mat, IndexedMatrix.Identity), shape, IndexedVector3.Zero); + body.SetWorldTransform(mat); + body.SetUserPointer(pLocalID); + return body; + } + //(m_mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); + public override void SetCollisionFlags2(object pBody, CollisionFlags collisionFlags) + { + RigidBody body = pBody as RigidBody; + body.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags) (uint) collisionFlags); + } + //(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainHitFraction); + public override void SetHitFraction2(object pBody, float pHitFraction) + { + RigidBody body = pBody as RigidBody; + body.SetHitFraction(pHitFraction); + } + //BuildCapsuleShape2(physicsScene.World.ptr, 1f, 1f, prim.Scale); + public override object BuildCapsuleShape2(object pWorld, float pRadius, float pHeight, Vector3 pScale) + { + DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + IndexedVector3 scale = new IndexedVector3(pScale.X, pScale.Y, pScale.Z); + CapsuleShapeZ capsuleShapeZ = new CapsuleShapeZ(pRadius, pHeight); + capsuleShapeZ.SetMargin(world.WorldSettings.Params.collisionMargin); + capsuleShapeZ.SetLocalScaling(ref scale); + + return capsuleShapeZ; + } + + public static object Initialize2(Vector3 worldExtent, ConfigurationParameters[] o, int mMaxCollisionsPerFrame, ref List collisionArray, int mMaxUpdatesPerFrame, ref List updateArray, object mDebugLogCallbackHandle) + { + CollisionWorld.WorldData.ParamData p = new CollisionWorld.WorldData.ParamData(); + + p.angularDamping = o[0].XangularDamping; + p.defaultFriction = o[0].defaultFriction; + p.defaultFriction = o[0].defaultFriction; + p.defaultDensity = o[0].defaultDensity; + p.defaultRestitution = o[0].defaultRestitution; + p.collisionMargin = o[0].collisionMargin; + p.gravity = o[0].gravity; + + p.linearDamping = o[0].XlinearDamping; + p.angularDamping = o[0].XangularDamping; + p.deactivationTime = o[0].XdeactivationTime; + p.linearSleepingThreshold = o[0].XlinearSleepingThreshold; + p.angularSleepingThreshold = o[0].XangularSleepingThreshold; + p.ccdMotionThreshold = o[0].XccdMotionThreshold; + p.ccdSweptSphereRadius = o[0].XccdSweptSphereRadius; + p.contactProcessingThreshold = o[0].XcontactProcessingThreshold; + + p.terrainImplementation = o[0].XterrainImplementation; + p.terrainFriction = o[0].XterrainFriction; + + p.terrainHitFraction = o[0].XterrainHitFraction; + p.terrainRestitution = o[0].XterrainRestitution; + p.terrainCollisionMargin = o[0].XterrainCollisionMargin; + + p.avatarFriction = o[0].XavatarFriction; + p.avatarStandingFriction = o[0].XavatarStandingFriction; + p.avatarDensity = o[0].XavatarDensity; + p.avatarRestitution = o[0].XavatarRestitution; + p.avatarCapsuleWidth = o[0].XavatarCapsuleWidth; + p.avatarCapsuleDepth = o[0].XavatarCapsuleDepth; + p.avatarCapsuleHeight = o[0].XavatarCapsuleHeight; + p.avatarContactProcessingThreshold = o[0].XavatarContactProcessingThreshold; + + p.vehicleAngularDamping = o[0].XvehicleAngularDamping; + + p.maxPersistantManifoldPoolSize = o[0].maxPersistantManifoldPoolSize; + p.maxCollisionAlgorithmPoolSize = o[0].maxCollisionAlgorithmPoolSize; + p.shouldDisableContactPoolDynamicAllocation = o[0].shouldDisableContactPoolDynamicAllocation; + p.shouldForceUpdateAllAabbs = o[0].shouldForceUpdateAllAabbs; + p.shouldRandomizeSolverOrder = o[0].shouldRandomizeSolverOrder; + p.shouldSplitSimulationIslands = o[0].shouldSplitSimulationIslands; + p.shouldEnableFrictionCaching = o[0].shouldEnableFrictionCaching; + p.numberOfSolverIterations = o[0].numberOfSolverIterations; + + p.linksetImplementation = o[0].XlinksetImplementation; + p.linkConstraintUseFrameOffset = o[0].XlinkConstraintUseFrameOffset; + p.linkConstraintEnableTransMotor = o[0].XlinkConstraintEnableTransMotor; + p.linkConstraintTransMotorMaxVel = o[0].XlinkConstraintTransMotorMaxVel; + p.linkConstraintTransMotorMaxForce = o[0].XlinkConstraintTransMotorMaxForce; + p.linkConstraintERP = o[0].XlinkConstraintERP; + p.linkConstraintCFM = o[0].XlinkConstraintCFM; + p.linkConstraintSolverIterations = o[0].XlinkConstraintSolverIterations; + p.physicsLoggingFrames = o[0].physicsLoggingFrames; + DefaultCollisionConstructionInfo ccci = new DefaultCollisionConstructionInfo(); + + DefaultCollisionConfiguration cci = new DefaultCollisionConfiguration(); + CollisionDispatcher m_dispatcher = new CollisionDispatcher(cci); + + + if (p.maxPersistantManifoldPoolSize > 0) + cci.m_persistentManifoldPoolSize = (int)p.maxPersistantManifoldPoolSize; + if (p.shouldDisableContactPoolDynamicAllocation !=0) + m_dispatcher.SetDispatcherFlags(DispatcherFlags.CD_DISABLE_CONTACTPOOL_DYNAMIC_ALLOCATION); + //if (p.maxCollisionAlgorithmPoolSize >0 ) + + DbvtBroadphase m_broadphase = new DbvtBroadphase(); + //IndexedVector3 aabbMin = new IndexedVector3(0, 0, 0); + //IndexedVector3 aabbMax = new IndexedVector3(256, 256, 256); + + //AxisSweep3Internal m_broadphase2 = new AxisSweep3Internal(ref aabbMin, ref aabbMax, Convert.ToInt32(0xfffe), 0xffff, ushort.MaxValue/2, null, true); + m_broadphase.GetOverlappingPairCache().SetInternalGhostPairCallback(new GhostPairCallback()); + + SequentialImpulseConstraintSolver m_solver = new SequentialImpulseConstraintSolver(); + + DiscreteDynamicsWorld world = new DiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, cci); + world.UpdatedObjects = updateArray; + world.UpdatedCollisions = collisionArray; + world.WorldSettings.Params = p; + world.SetForceUpdateAllAabbs(p.shouldForceUpdateAllAabbs != 0); + world.GetSolverInfo().m_solverMode = SolverMode.SOLVER_USE_WARMSTARTING | SolverMode.SOLVER_SIMD; + if (p.shouldRandomizeSolverOrder != 0) + world.GetSolverInfo().m_solverMode |= SolverMode.SOLVER_RANDMIZE_ORDER; + + world.GetSimulationIslandManager().SetSplitIslands(p.shouldSplitSimulationIslands != 0); + //world.GetDispatchInfo().m_enableSatConvex Not implemented in C# port + + if (p.shouldEnableFrictionCaching != 0) + world.GetSolverInfo().m_solverMode |= SolverMode.SOLVER_ENABLE_FRICTION_DIRECTION_CACHING; + + if (p.numberOfSolverIterations > 0) + world.GetSolverInfo().m_numIterations = (int) p.numberOfSolverIterations; + + + world.GetSolverInfo().m_damping = world.WorldSettings.Params.linearDamping; + world.GetSolverInfo().m_restitution = world.WorldSettings.Params.defaultRestitution; + world.GetSolverInfo().m_globalCfm = 0.0f; + world.GetSolverInfo().m_tau = 0.6f; + world.GetSolverInfo().m_friction = 0.3f; + world.GetSolverInfo().m_maxErrorReduction = 20f; + world.GetSolverInfo().m_numIterations = 10; + world.GetSolverInfo().m_erp = 0.2f; + world.GetSolverInfo().m_erp2 = 0.1f; + world.GetSolverInfo().m_sor = 1.0f; + world.GetSolverInfo().m_splitImpulse = false; + world.GetSolverInfo().m_splitImpulsePenetrationThreshold = -0.02f; + world.GetSolverInfo().m_linearSlop = 0.0f; + world.GetSolverInfo().m_warmstartingFactor = 0.85f; + world.GetSolverInfo().m_restingContactRestitutionThreshold = 2; + world.SetForceUpdateAllAabbs(true); + + + world.SetGravity(new IndexedVector3(0,0,p.gravity)); + + return world; + } + //m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL + public override bool SetConstraintParam2(object pConstraint, ConstraintParams paramIndex, float paramvalue, ConstraintParamAxis axis) + { + Generic6DofConstraint constrain = pConstraint as Generic6DofConstraint; + if (axis == ConstraintParamAxis.AXIS_LINEAR_ALL || axis == ConstraintParamAxis.AXIS_ALL) + { + constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams) (int) paramIndex, paramvalue, 0); + constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams) (int) paramIndex, paramvalue, 1); + constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams) (int) paramIndex, paramvalue, 2); + } + if (axis == ConstraintParamAxis.AXIS_ANGULAR_ALL || axis == ConstraintParamAxis.AXIS_ALL) + { + constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams)(int)paramIndex, paramvalue, 3); + constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams)(int)paramIndex, paramvalue, 4); + constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams)(int)paramIndex, paramvalue, 5); + } + if (axis == ConstraintParamAxis.AXIS_LINEAR_ALL) + { + constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams)(int)paramIndex, paramvalue, (int)axis); + } + return true; + } + + public override bool PushUpdate2(object pCollisionObject) + { + bool ret = false; + RigidBody rb = pCollisionObject as RigidBody; + if (rb != null) + { + SimMotionState sms = rb.GetMotionState() as SimMotionState; + if (sms != null) + { + IndexedMatrix wt = IndexedMatrix.Identity; + sms.GetWorldTransform(out wt); + sms.SetWorldTransform(ref wt, true); + ret = true; + } + } + return ret; + + } + + public override bool IsCompound2(object pShape) + { + CollisionShape shape = pShape as CollisionShape; + return shape.IsCompound(); + } + public override bool IsPloyhedral2(object pShape) + { + CollisionShape shape = pShape as CollisionShape; + return shape.IsPolyhedral(); + } + public override bool IsConvex2d2(object pShape) + { + CollisionShape shape = pShape as CollisionShape; + return shape.IsConvex2d(); + } + public override bool IsConvex2(object pShape) + { + CollisionShape shape = pShape as CollisionShape; + return shape.IsConvex(); + } + public override bool IsNonMoving2(object pShape) + { + CollisionShape shape = pShape as CollisionShape; + return shape.IsNonMoving(); + } + public override bool IsConcave2(object pShape) + { + CollisionShape shape = pShape as CollisionShape; + return shape.IsConcave(); + } + public override bool IsInfinite2(object pShape) + { + CollisionShape shape = pShape as CollisionShape; + return shape.IsInfinite(); + } + public override bool IsNativeShape2(object pShape) + { + CollisionShape shape = pShape as CollisionShape; + bool ret; + switch (shape.GetShapeType()) + { + case BroadphaseNativeTypes.BOX_SHAPE_PROXYTYPE: + case BroadphaseNativeTypes.CONE_SHAPE_PROXYTYPE: + case BroadphaseNativeTypes.SPHERE_SHAPE_PROXYTYPE: + case BroadphaseNativeTypes.CYLINDER_SHAPE_PROXYTYPE: + ret = true; + break; + default: + ret = false; + break; + } + return ret; + } + //sim.ptr, shape.ptr,prim.LocalID, prim.RawPosition, prim.RawOrientation + public override object CreateGhostFromShape2(object pWorld, object pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation) + { + IndexedMatrix bodyTransform = new IndexedMatrix(); + bodyTransform._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z); + bodyTransform.SetRotation(new IndexedQuaternion(pRawOrientation.X,pRawOrientation.Y,pRawOrientation.Z,pRawOrientation.W)); + GhostObject gObj = new PairCachingGhostObject(); + gObj.SetWorldTransform(bodyTransform); + CollisionShape shape = pShape as CollisionShape; + gObj.SetCollisionShape(shape); + gObj.SetUserPointer(pLocalID); + // TODO: Add to Special CollisionObjects! + return gObj; + } + + public static void SetCollisionShape2(object pWorld, object pObj, object pShape) + { + var world = pWorld as DiscreteDynamicsWorld; + var obj = pObj as CollisionObject; + var shape = pShape as CollisionShape; + obj.SetCollisionShape(shape); + + } + //(PhysicsScene.World.ptr, nativeShapeData) + public override object BuildNativeShape2(object pWorld, ShapeData pShapeData) + { + var world = pWorld as DiscreteDynamicsWorld; + CollisionShape shape = null; + switch (pShapeData.Type) + { + case BSPhysicsShapeType.SHAPE_BOX: + shape = new BoxShape(new IndexedVector3(0.5f,0.5f,0.5f)); + break; + case BSPhysicsShapeType.SHAPE_CONE: + shape = new ConeShapeZ(0.5f, 1.0f); + break; + case BSPhysicsShapeType.SHAPE_CYLINDER: + shape = new CylinderShapeZ(new IndexedVector3(0.5f, 0.5f, 0.5f)); + break; + case BSPhysicsShapeType.SHAPE_SPHERE: + shape = new SphereShape(0.5f); + break; + + } + if (shape != null) + { + IndexedVector3 scaling = new IndexedVector3(pShapeData.Scale.X, pShapeData.Scale.Y, pShapeData.Scale.Z); + shape.SetMargin(world.WorldSettings.Params.collisionMargin); + shape.SetLocalScaling(ref scaling); + + } + return shape; + } + //PhysicsScene.World.ptr, false + public override object CreateCompoundShape2(object pWorld, bool enableDynamicAabbTree) + { + return new CompoundShape(enableDynamicAabbTree); + } + + public override int GetNumberOfCompoundChildren2(object pCompoundShape) + { + var compoundshape = pCompoundShape as CompoundShape; + return compoundshape.GetNumChildShapes(); + } + //LinksetRoot.PhysShape.ptr, newShape.ptr, displacementPos, displacementRot + public override void AddChildShapeToCompoundShape2(object pCShape, object paddShape, Vector3 displacementPos, Quaternion displacementRot) + { + IndexedMatrix relativeTransform = new IndexedMatrix(); + var compoundshape = pCShape as CompoundShape; + var addshape = paddShape as CollisionShape; + + relativeTransform._origin = new IndexedVector3(displacementPos.X, displacementPos.Y, displacementPos.Z); + relativeTransform.SetRotation(new IndexedQuaternion(displacementRot.X,displacementRot.Y,displacementRot.Z,displacementRot.W)); + compoundshape.AddChildShape(ref relativeTransform, addshape); + + } + + public override object RemoveChildShapeFromCompoundShapeIndex2(object pCShape, int pii) + { + var compoundshape = pCShape as CompoundShape; + CollisionShape ret = null; + ret = compoundshape.GetChildShape(pii); + compoundshape.RemoveChildShapeByIndex(pii); + return ret; + } + + public override object CreateGroundPlaneShape2(uint pLocalId, float pheight, float pcollisionMargin) + { + StaticPlaneShape m_planeshape = new StaticPlaneShape(new IndexedVector3(0,0,1),(int)pheight ); + m_planeshape.SetMargin(pcollisionMargin); + m_planeshape.SetUserPointer(pLocalId); + return m_planeshape; + } + + public override object CreateHingeConstraint2(object pWorld, object pBody1, object ppBody2, Vector3 ppivotInA, Vector3 ppivotInB, Vector3 paxisInA, Vector3 paxisInB, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies) + { + HingeConstraint constrain = null; + var rb1 = pBody1 as RigidBody; + var rb2 = ppBody2 as RigidBody; + if (rb1 != null && rb2 != null) + { + IndexedVector3 pivotInA = new IndexedVector3(ppivotInA.X, ppivotInA.Y, ppivotInA.Z); + IndexedVector3 pivotInB = new IndexedVector3(ppivotInB.X, ppivotInB.Y, ppivotInB.Z); + IndexedVector3 axisInA = new IndexedVector3(paxisInA.X, paxisInA.Y, paxisInA.Z); + IndexedVector3 axisInB = new IndexedVector3(paxisInB.X, paxisInB.Y, paxisInB.Z); + var world = pWorld as DiscreteDynamicsWorld; + world.AddConstraint(constrain, pdisableCollisionsBetweenLinkedBodies); + } + return constrain; + } + + public override bool ReleaseHeightMapInfo2(object pMapInfo) + { + if (pMapInfo != null) + { + BulletHeightMapInfo mapinfo = pMapInfo as BulletHeightMapInfo; + if (mapinfo.heightMap != null) + mapinfo.heightMap = null; + + + } + return true; + } + + public override object CreateHullShape2(object pWorld, int pHullCount, float[] pConvHulls) + { + CompoundShape compoundshape = new CompoundShape(false); + var world = pWorld as DiscreteDynamicsWorld; + + + compoundshape.SetMargin(world.WorldSettings.Params.collisionMargin); + int ii = 1; + + for (int i = 0; i < pHullCount; i++) + { + int vertexCount = (int) pConvHulls[ii]; + + IndexedVector3 centroid = new IndexedVector3(pConvHulls[ii + 1], pConvHulls[ii + 2], pConvHulls[ii + 3]); + IndexedMatrix childTrans = IndexedMatrix.Identity; + childTrans._origin = centroid; + + List virts = new List(); + int ender = ((ii + 4) + (vertexCount*3)); + for (int iii = ii + 4; iii < ender; iii+=3) + { + + virts.Add(new IndexedVector3(pConvHulls[iii], pConvHulls[iii + 1], pConvHulls[iii +2])); + } + ConvexHullShape convexShape = new ConvexHullShape(virts, vertexCount); + convexShape.SetMargin(world.WorldSettings.Params.collisionMargin); + compoundshape.AddChildShape(ref childTrans, convexShape); + ii += (vertexCount*3 + 4); + } + + + return compoundshape; + } + + public override object CreateMeshShape2(object pWorld, int pIndicesCount, int[] indices, int pVerticesCount, float[] verticesAsFloats) + { + //DumpRaw(indices,verticesAsFloats,pIndicesCount,pVerticesCount); + + for (int iter = 0; iter < pVerticesCount; iter++) + { + if (verticesAsFloats[iter] > 0 && verticesAsFloats[iter] < 0.0001) verticesAsFloats[iter] = 0; + if (verticesAsFloats[iter] < 0 && verticesAsFloats[iter] > -0.0001) verticesAsFloats[iter] = 0; + } + + ObjectArray indicesarr = new ObjectArray(indices); + ObjectArray vertices = new ObjectArray(verticesAsFloats); + DumpRaw(indicesarr,vertices,pIndicesCount,pVerticesCount); + var world = pWorld as DiscreteDynamicsWorld; + IndexedMesh mesh = new IndexedMesh(); + mesh.m_indexType = PHY_ScalarType.PHY_INTEGER; + mesh.m_numTriangles = pIndicesCount/3; + mesh.m_numVertices = pVerticesCount; + mesh.m_triangleIndexBase = indicesarr; + mesh.m_vertexBase = vertices; + mesh.m_vertexStride = 3; + mesh.m_vertexType = PHY_ScalarType.PHY_FLOAT; + mesh.m_triangleIndexStride = 3; + + TriangleIndexVertexArray tribuilder = new TriangleIndexVertexArray(); + tribuilder.AddIndexedMesh(mesh, PHY_ScalarType.PHY_INTEGER); + BvhTriangleMeshShape meshShape = new BvhTriangleMeshShape(tribuilder, true,true); + meshShape.SetMargin(world.WorldSettings.Params.collisionMargin); + // world.UpdateSingleAabb(meshShape); + return meshShape; + + } + public static void DumpRaw(ObjectArrayindices, ObjectArray vertices, int pIndicesCount,int pVerticesCount ) + { + + String fileName = "objTest3.raw"; + String completePath = System.IO.Path.Combine(Util.configDir(), fileName); + StreamWriter sw = new StreamWriter(completePath); + IndexedMesh mesh = new IndexedMesh(); + + mesh.m_indexType = PHY_ScalarType.PHY_INTEGER; + mesh.m_numTriangles = pIndicesCount / 3; + mesh.m_numVertices = pVerticesCount; + mesh.m_triangleIndexBase = indices; + mesh.m_vertexBase = vertices; + mesh.m_vertexStride = 3; + mesh.m_vertexType = PHY_ScalarType.PHY_FLOAT; + mesh.m_triangleIndexStride = 3; + + TriangleIndexVertexArray tribuilder = new TriangleIndexVertexArray(); + tribuilder.AddIndexedMesh(mesh, PHY_ScalarType.PHY_INTEGER); + + + + for (int i = 0; i < pVerticesCount; i++) + { + + string s = vertices[indices[i * 3]].ToString("0.0000"); + s += " " + vertices[indices[i * 3 + 1]].ToString("0.0000"); + s += " " + vertices[indices[i * 3 + 2]].ToString("0.0000"); + + sw.Write(s + "\n"); + } + + sw.Close(); + } + public static void DumpRaw(int[] indices, float[] vertices, int pIndicesCount, int pVerticesCount) + { + + String fileName = "objTest6.raw"; + String completePath = System.IO.Path.Combine(Util.configDir(), fileName); + StreamWriter sw = new StreamWriter(completePath); + IndexedMesh mesh = new IndexedMesh(); + + mesh.m_indexType = PHY_ScalarType.PHY_INTEGER; + mesh.m_numTriangles = pIndicesCount / 3; + mesh.m_numVertices = pVerticesCount; + mesh.m_triangleIndexBase = indices; + mesh.m_vertexBase = vertices; + mesh.m_vertexStride = 3; + mesh.m_vertexType = PHY_ScalarType.PHY_FLOAT; + mesh.m_triangleIndexStride = 3; + + TriangleIndexVertexArray tribuilder = new TriangleIndexVertexArray(); + tribuilder.AddIndexedMesh(mesh, PHY_ScalarType.PHY_INTEGER); + + + sw.WriteLine("Indices"); + sw.WriteLine(string.Format("int[] indices = new int[{0}];",pIndicesCount)); + for (int iter = 0; iter < indices.Length; iter++) + { + sw.WriteLine(string.Format("indices[{0}]={1};",iter,indices[iter])); + } + sw.WriteLine("VerticesFloats"); + sw.WriteLine(string.Format("float[] vertices = new float[{0}];", pVerticesCount)); + for (int iter = 0; iter < vertices.Length; iter++) + { + sw.WriteLine(string.Format("Vertices[{0}]={1};", iter, vertices[iter].ToString("0.0000"))); + } + + // for (int i = 0; i < pVerticesCount; i++) + // { + // + // string s = vertices[indices[i * 3]].ToString("0.0000"); + // s += " " + vertices[indices[i * 3 + 1]].ToString("0.0000"); + // s += " " + vertices[indices[i * 3 + 2]].ToString("0.0000"); + // + // sw.Write(s + "\n"); + //} + + sw.Close(); + } + //PhysicsScene.World.ptr, m_mapInfo.ID, m_mapInfo.minCoords, m_mapInfo.maxCoords, m_mapInfo.heightMap, PhysicsScene.Params.terrainCollisionMargin + public override object CreateHeightMapInfo2(object pWorld, uint pId, Vector3 pminCoords, Vector3 pmaxCoords, float[] pheightMap, float pCollisionMargin) + { + BulletHeightMapInfo mapInfo = new BulletHeightMapInfo(pId, pheightMap, null); + mapInfo.heightMap = null; + mapInfo.minCoords = pminCoords; + mapInfo.maxCoords = pmaxCoords; + mapInfo.sizeX = (int) (pmaxCoords.X - pminCoords.X); + mapInfo.sizeY = (int) (pmaxCoords.Y - pminCoords.Y); + mapInfo.ID = pId; + mapInfo.minZ = pminCoords.Z; + mapInfo.maxZ = pmaxCoords.Z; + mapInfo.collisionMargin = pCollisionMargin; + if (mapInfo.minZ == mapInfo.maxZ) + mapInfo.minZ -= 0.2f; + mapInfo.heightMap = pheightMap; + + return mapInfo; + + } + + public override object CreateTerrainShape2(object pMapInfo) + { + BulletHeightMapInfo mapinfo = pMapInfo as BulletHeightMapInfo; + const int upAxis = 2; + const float scaleFactor = 1.0f; + HeightfieldTerrainShape terrainShape = new HeightfieldTerrainShape((int)mapinfo.sizeX, (int)mapinfo.sizeY, + mapinfo.heightMap, scaleFactor, + mapinfo.minZ, mapinfo.maxZ, upAxis, + false); + terrainShape.SetMargin(mapinfo.collisionMargin + 0.5f); + terrainShape.SetUseDiamondSubdivision(true); + terrainShape.SetUserPointer(mapinfo.ID); + return terrainShape; + } + + public override bool TranslationalLimitMotor2(object pConstraint, float ponOff, float targetVelocity, float maxMotorForce) + { + TypedConstraint tconstrain = pConstraint as TypedConstraint; + bool onOff = ponOff != 0; + bool ret = false; + + switch (tconstrain.GetConstraintType()) + { + case TypedConstraintType.D6_CONSTRAINT_TYPE: + Generic6DofConstraint constrain = pConstraint as Generic6DofConstraint; + constrain.GetTranslationalLimitMotor().m_enableMotor[0] = onOff; + constrain.GetTranslationalLimitMotor().m_targetVelocity[0] = targetVelocity; + constrain.GetTranslationalLimitMotor().m_maxMotorForce[0] = maxMotorForce; + ret = true; + break; + } + + + return ret; + + } + + public override int PhysicsStep2(object pWorld, float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount, out List updatedEntities, out int collidersCount, out Listcolliders) + { + int epic = PhysicsStepint2(pWorld, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out updatedEntities, + out collidersCount, out colliders); + return epic; + } + + private static int PhysicsStepint2(object pWorld,float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount, out List updatedEntities, out int collidersCount, out List colliders) + { + int numSimSteps = 0; + + + //if (updatedEntities is null) + // updatedEntities = new List(); + + //if (colliders is null) + // colliders = new List(); + + + if (pWorld is DiscreteDynamicsWorld) + { + DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + + numSimSteps = world.StepSimulation(timeStep, m_maxSubSteps, m_fixedTimeStep); + int updates = 0; + + updatedEntityCount = world.UpdatedObjects.Count; + updatedEntities = new List(world.UpdatedObjects); + updatedEntityCount = updatedEntities.Count; + world.UpdatedObjects.Clear(); + + + collidersCount = world.UpdatedCollisions.Count; + colliders = new List(world.UpdatedCollisions); + + world.UpdatedCollisions.Clear(); + m_collisionsThisFrame = 0; + int numManifolds = world.GetDispatcher().GetNumManifolds(); + for (int j = 0; j < numManifolds; j++) + { + PersistentManifold contactManifold = world.GetDispatcher().GetManifoldByIndexInternal(j); + int numContacts = contactManifold.GetNumContacts(); + if (numContacts == 0) + continue; + + CollisionObject objA = contactManifold.GetBody0() as CollisionObject; + CollisionObject objB = contactManifold.GetBody1() as CollisionObject; + + ManifoldPoint manifoldPoint = contactManifold.GetContactPoint(0); + IndexedVector3 contactPoint = manifoldPoint.GetPositionWorldOnB(); + IndexedVector3 contactNormal = -manifoldPoint.m_normalWorldOnB; // make relative to A + + RecordCollision(world, objA, objB, contactPoint, contactNormal); + m_collisionsThisFrame ++; + if (m_collisionsThisFrame >= 9999999) + break; + + + } + + + } + else + { + //if (updatedEntities is null) + updatedEntities = new List(); + updatedEntityCount = 0; + //if (colliders is null) + colliders = new List(); + collidersCount = 0; + } + return numSimSteps; + } + + private static void RecordCollision(CollisionWorld world,CollisionObject objA, CollisionObject objB, IndexedVector3 contact, IndexedVector3 norm) + { + + IndexedVector3 contactNormal = norm; + if ((objA.GetCollisionFlags() & BulletXNA.BulletCollision.CollisionFlags.BS_WANTS_COLLISIONS) == 0 && + (objB.GetCollisionFlags() & BulletXNA.BulletCollision.CollisionFlags.BS_WANTS_COLLISIONS) == 0) + { + return; + } + uint idA = (uint)objA.GetUserPointer(); + uint idB = (uint)objB.GetUserPointer(); + if (idA > idB) + { + uint temp = idA; + idA = idB; + idB = temp; + contactNormal = -contactNormal; + } + + ulong collisionID = ((ulong) idA << 32) | idB; + + BulletXNA.CollisionDesc cDesc = new BulletXNA.CollisionDesc() + { + aID = idA, + bID = idB, + point = contact, + normal = contactNormal + }; + world.UpdatedCollisions.Add(cDesc); + m_collisionsThisFrame++; + + + } + private static EntityProperties GetDebugProperties(object pWorld, object pBody) + { + EntityProperties ent = new EntityProperties(); + DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + RigidBody body = pBody as RigidBody; + IndexedMatrix transform = body.GetWorldTransform(); + IndexedVector3 LinearVelocity = body.GetInterpolationLinearVelocity(); + IndexedVector3 AngularVelocity = body.GetInterpolationAngularVelocity(); + IndexedQuaternion rotation = transform.GetRotation(); + ent.Acceleration = Vector3.Zero; + ent.ID = (uint)body.GetUserPointer(); + ent.Position = new Vector3(transform._origin.X,transform._origin.Y,transform._origin.Z); + ent.Rotation = new Quaternion(rotation.X,rotation.Y,rotation.Z,rotation.W); + ent.Velocity = new Vector3(LinearVelocity.X, LinearVelocity.Y, LinearVelocity.Z); + ent.RotationalVelocity = new Vector3(AngularVelocity.X, AngularVelocity.Y, AngularVelocity.Z); + return ent; + } + + public override Vector3 GetLocalScaling2(object pBody) + { + CollisionShape shape = pBody as CollisionShape; + IndexedVector3 scale = shape.GetLocalScaling(); + return new Vector3(scale.X,scale.Y,scale.Z); + } + + public override bool RayCastGround(object pWorld, Vector3 _RayOrigin, float pRayHeight, object NotMe) + { + DynamicsWorld world = pWorld as DynamicsWorld; + if (world != null) + { + if (NotMe is CollisionObject || NotMe is RigidBody) + { + CollisionObject AvoidBody = NotMe as CollisionObject; + + IndexedVector3 rOrigin = new IndexedVector3(_RayOrigin.X, _RayOrigin.Y, _RayOrigin.Z); + IndexedVector3 rEnd = new IndexedVector3(_RayOrigin.X, _RayOrigin.Y, _RayOrigin.Z - pRayHeight); + using ( + ClosestNotMeRayResultCallback rayCallback = new ClosestNotMeRayResultCallback(rOrigin, + rEnd, AvoidBody) + ) + { + world.RayTest(ref rOrigin, ref rEnd, rayCallback); + if (rayCallback.HasHit()) + { + IndexedVector3 hitLocation = rayCallback.m_hitPointWorld; + + } + return rayCallback.HasHit(); + } + } + } + return false; + } } - */ +*/ } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index 699f055..2350f59 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs @@ -362,7 +362,7 @@ public abstract void DestroyObject(BulletWorld sim, BulletBody obj); // ===================================================================================== public abstract BulletShape CreateGroundPlaneShape(uint id, float height, float collisionMargin); -public abstract BulletShape CreateTerrainShape(uint id, Vector3 size, float minHeight, float maxHeight, float[] heightMap, +public abstract BulletShape CreateTerrainShape(uint id, Vector3 size, float minHeight, float maxHeight, float[] heightMap, float scaleFactor, float collisionMargin); // ===================================================================================== diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 064ce3c..cb8108d 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -300,7 +300,7 @@ public sealed class BSPrim : BSPhysObject // All positions are given in world positions. if (_position == value) { - DetailLog("{0},BSPrim.setPosition,taint,positionNotChanging,pos={1},orient={2}", LocalID, _position, _orientation); + DetailLog("{0},BSPrim.setPosition,call,positionNotChanging,pos={1},orient={2}", LocalID, _position, _orientation); return; } _position = value; @@ -894,21 +894,26 @@ public sealed class BSPrim : BSPhysObject // Object MUST NOT already be in the world. // This routine exists because some assorted properties get mangled by adding to the world. internal void AddObjectToPhysicalWorld() - { - if (PhysBody.HasPhysicalBody) - { - PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, PhysBody); - - // TODO: Fix this. Total kludge because adding object to world resets its gravity to default. - // Replace this when the new AddObjectToWorld function is complete. - PhysicsScene.PE.SetGravity(PhysBody, ComputeGravity()); - - // Collision filter can be set only when the object is in the world - if (!PhysBody.ApplyCollisionMask(PhysicsScene)) - { - m_log.ErrorFormat("{0} Failed setting object collision mask: id={1}", LogHeader, LocalID); - DetailLog("{0},BSPrim.UpdatePhysicalParameters,failedSetMaskGroup,cType={1}", LocalID, PhysBody.collisionType); - } + { + if (PhysBody.HasPhysicalBody) + { + PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, PhysBody); + + // TODO: Fix this. Total kludge because adding object to world resets its gravity to default. + // Replace this when the new AddObjectToWorld function is complete. + PhysicsScene.PE.SetGravity(PhysBody, ComputeGravity()); + + // Collision filter can be set only when the object is in the world + if (!PhysBody.ApplyCollisionMask(PhysicsScene)) + { + m_log.ErrorFormat("{0} Failed setting object collision mask: id={1}", LogHeader, LocalID); + DetailLog("{0},BSPrim.UpdatePhysicalParameters,failedSetMaskGroup,cType={1}", LocalID, PhysBody.collisionType); + } + } + else + { + 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); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index cd77581..2b652f5 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -45,7 +45,7 @@ public sealed class BSShapeCollection : IDisposable // Description of a Mesh private struct MeshDesc { - public IntPtr ptr; + public BulletShape shape; public int referenceCount; public DateTime lastReferenced; public UInt64 shapeKey; @@ -55,7 +55,7 @@ public sealed class BSShapeCollection : IDisposable // Meshes and hulls have the same shape hash key but we only need hulls for efficient collision calculations. private struct HullDesc { - public IntPtr ptr; + public BulletShape shape; public int referenceCount; public DateTime lastReferenced; public UInt64 shapeKey; @@ -173,7 +173,7 @@ public sealed class BSShapeCollection : IDisposable } // Zero any reference to the shape so it is not freed when the body is deleted. - PhysicsScene.PE.SetCollisionShape(PhysicsScene.World, body, new BulletShape()); + PhysicsScene.PE.SetCollisionShape(PhysicsScene.World, body, null); PhysicsScene.PE.DestroyObject(PhysicsScene.World, body); }); } @@ -202,7 +202,7 @@ public sealed class BSShapeCollection : IDisposable else { // This is a new reference to a mesh - meshDesc.ptr = shape.ptr; + meshDesc.shape = shape.Clone(); meshDesc.shapeKey = shape.shapeKey; // We keep a reference to the underlying IMesh data so a hull can be built meshDesc.referenceCount = 1; @@ -225,7 +225,7 @@ public sealed class BSShapeCollection : IDisposable else { // This is a new reference to a hull - hullDesc.ptr = shape.ptr; + hullDesc.shape = shape.Clone(); hullDesc.shapeKey = shape.shapeKey; hullDesc.referenceCount = 1; if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,newHull,key={1},cnt={2}", @@ -361,15 +361,14 @@ public sealed class BSShapeCollection : IDisposable MeshDesc meshDesc; HullDesc hullDesc; - IntPtr cShape = shapeInfo.ptr; - if (TryGetMeshByPtr(cShape, out meshDesc)) + if (TryGetMeshByPtr(shapeInfo, out meshDesc)) { shapeInfo.type = BSPhysicsShapeType.SHAPE_MESH; shapeInfo.shapeKey = meshDesc.shapeKey; } else { - if (TryGetHullByPtr(cShape, out hullDesc)) + if (TryGetHullByPtr(shapeInfo, out hullDesc)) { shapeInfo.type = BSPhysicsShapeType.SHAPE_HULL; shapeInfo.shapeKey = hullDesc.shapeKey; @@ -632,7 +631,7 @@ public sealed class BSShapeCollection : IDisposable if (Meshes.TryGetValue(newMeshKey, out meshDesc)) { // If the mesh has already been built just use it. - newShape = new BulletShape(meshDesc.ptr, BSPhysicsShapeType.SHAPE_MESH); + newShape = meshDesc.shape.Clone(); } else { @@ -703,7 +702,7 @@ public sealed class BSShapeCollection : IDisposable if (Hulls.TryGetValue(newHullKey, out hullDesc)) { // If the hull shape already is created, just use it. - newShape = new BulletShape(hullDesc.ptr, BSPhysicsShapeType.SHAPE_HULL); + newShape = hullDesc.shape.Clone(); } else { @@ -965,13 +964,13 @@ public sealed class BSShapeCollection : IDisposable return ret; } - private bool TryGetMeshByPtr(IntPtr addr, out MeshDesc outDesc) + private bool TryGetMeshByPtr(BulletShape shape, out MeshDesc outDesc) { bool ret = false; MeshDesc foundDesc = new MeshDesc(); foreach (MeshDesc md in Meshes.Values) { - if (md.ptr == addr) + if (md.shape.ReferenceSame(shape)) { foundDesc = md; ret = true; @@ -983,13 +982,13 @@ public sealed class BSShapeCollection : IDisposable return ret; } - private bool TryGetHullByPtr(IntPtr addr, out HullDesc outDesc) + private bool TryGetHullByPtr(BulletShape shape, out HullDesc outDesc) { bool ret = false; HullDesc foundDesc = new HullDesc(); foreach (HullDesc hd in Hulls.Values) { - if (hd.ptr == addr) + if (hd.shape.ReferenceSame(shape)) { foundDesc = hd; ret = true; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs index 681d21e..662dd68 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs @@ -33,17 +33,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin { // Classes to allow some type checking for the API // These hold pointers to allocated objects in the unmanaged space. +// These classes are subclassed by the various physical implementations of +// objects. In particular, there is a version for physical instances in +// unmanaged memory ("unman") and one for in managed memory ("XNA"). + +// Currently, the instances of these classes are a reference to a +// physical representation and this has no releationship to other +// instances. Someday, refarb the usage of these classes so each instance +// refers to a particular physical instance and this class controls reference +// counts and such. This should be done along with adding BSShapes. -// The physics engine controller class created at initialization public class BulletWorld { - public BulletWorld(uint worldId, BSScene bss, IntPtr xx) + public BulletWorld(uint worldId, BSScene bss) { - ptr = xx; worldID = worldId; physicsScene = bss; } - public IntPtr ptr; public uint worldID; // The scene is only in here so very low level routines have a handle to print debug/error messages public BSScene physicsScene; @@ -52,27 +58,19 @@ public class BulletWorld // An allocated Bullet btRigidBody public class BulletBody { - public BulletBody(uint id) : this(id, IntPtr.Zero) - { - } - public BulletBody(uint id, IntPtr xx) + public BulletBody(uint id) { ID = id; - ptr = xx; collisionType = CollisionType.Static; } - public IntPtr ptr; public uint ID; public CollisionType collisionType; - public void Clear() - { - ptr = IntPtr.Zero; - } - public bool HasPhysicalBody { get { return ptr != IntPtr.Zero; } } + public virtual void Clear() { } + public virtual bool HasPhysicalBody { get { return false; } } // Apply the specificed collision mask into the physical world - public bool ApplyCollisionMask(BSScene physicsScene) + public virtual bool ApplyCollisionMask(BSScene physicsScene) { // Should assert the body has been added to the physical world. // (The collision masks are stored in the collision proxy cache which only exists for @@ -83,12 +81,9 @@ public class BulletBody } // Used for log messages for a unique display of the memory/object allocated to this instance - public string AddrString + public virtual string AddrString { - get - { - return ptr.ToString("X"); - } + get { return "unknown"; } } public override string ToString() @@ -108,38 +103,26 @@ public class BulletBody public class BulletShape { public BulletShape() - : this(IntPtr.Zero, BSPhysicsShapeType.SHAPE_UNKNOWN) - { - } - public BulletShape(IntPtr xx) - : this(xx, BSPhysicsShapeType.SHAPE_UNKNOWN) { - } - public BulletShape(IntPtr xx, BSPhysicsShapeType typ) - { - ptr = xx; - type = typ; + type = BSPhysicsShapeType.SHAPE_UNKNOWN; shapeKey = (System.UInt64)FixedShapeKey.KEY_NONE; isNativeShape = false; } - public IntPtr ptr; public BSPhysicsShapeType type; public System.UInt64 shapeKey; public bool isNativeShape; - public void Clear() - { - ptr = IntPtr.Zero; - } - public bool HasPhysicalShape { get { return ptr != IntPtr.Zero; } } + public virtual void Clear() { } + public virtual bool HasPhysicalShape { get { return false; } } + // Make another reference to this physical object. + public virtual BulletShape Clone() { return new BulletShape(); } + // Return 'true' if this and other refer to the same physical object + public virtual bool ReferenceSame(BulletShape xx) { return false; } // Used for log messages for a unique display of the memory/object allocated to this instance - public string AddrString + public virtual string AddrString { - get - { - return ptr.ToString("X"); - } + get { return "unknown"; } } public override string ToString() @@ -161,25 +144,16 @@ public class BulletShape // An allocated Bullet btConstraint public class BulletConstraint { - public BulletConstraint(IntPtr xx) - { - ptr = xx; - } - public IntPtr ptr; - - public void Clear() + public BulletConstraint() { - ptr = IntPtr.Zero; } - public bool HasPhysicalConstraint { get { return ptr != IntPtr.Zero; } } + public virtual void Clear() { } + public virtual bool HasPhysicalConstraint { get { return false; } } // Used for log messages for a unique display of the memory/object allocated to this instance - public string AddrString + public virtual string AddrString { - get - { - return ptr.ToString("X"); - } + get { return "unknown"; } } } -- cgit v1.1 From 0662d109c2954c7be5f5e9400b1f4afdeab2c298 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 1 Jan 2013 09:32:21 -0800 Subject: BulletSim: fix line endings. --- OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | 64 +++++++++++----------- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 40 +++++++------- 2 files changed, 52 insertions(+), 52 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs index 2c0cb43..9d8f60d 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs @@ -55,10 +55,10 @@ private sealed class BulletBodyUnman : BulletBody : base(id) { ptr = xx; - } - public override bool HasPhysicalBody - { - get { return ptr != IntPtr.Zero; } + } + public override bool HasPhysicalBody + { + get { return ptr != IntPtr.Zero; } } public override void Clear() { @@ -79,10 +79,10 @@ private sealed class BulletShapeUnman : BulletShape ptr = xx; type = typ; } - public override bool HasPhysicalShape - { - get { return ptr != IntPtr.Zero; } - } + public override bool HasPhysicalShape + { + get { return ptr != IntPtr.Zero; } + } public override void Clear() { ptr = IntPtr.Zero; @@ -202,7 +202,7 @@ public override int PhysicsStep(BulletWorld world, float timeStep, int maxSubSte public override void Shutdown(BulletWorld world) { - BulletWorldUnman worldu = world as BulletWorldUnman; + BulletWorldUnman worldu = world as BulletWorldUnman; BSAPICPP.Shutdown2(worldu.ptr); } @@ -249,7 +249,7 @@ public override BulletShape BuildHullShapeFromMesh(BulletWorld world, BulletShap public override BulletShape BuildNativeShape(BulletWorld world, ShapeData shapeData) { - BulletWorldUnman worldu = world as BulletWorldUnman; + BulletWorldUnman worldu = world as BulletWorldUnman; return new BulletShapeUnman(BSAPICPP.BuildNativeShape2(worldu.ptr, shapeData), shapeData.Type); } @@ -334,7 +334,7 @@ public override BulletShape DuplicateCollisionShape(BulletWorld world, BulletSha public override bool DeleteCollisionShape(BulletWorld world, BulletShape shape) { - BulletWorldUnman worldu = world as BulletWorldUnman; + BulletWorldUnman worldu = world as BulletWorldUnman; BulletShapeUnman shapeu = shape as BulletShapeUnman; return BSAPICPP.DeleteCollisionShape2(worldu.ptr, shapeu.ptr); } @@ -360,7 +360,7 @@ public override BulletBody CreateBodyWithDefaultMotionState(BulletShape shape, u public override BulletBody CreateGhostFromShape(BulletWorld world, BulletShape shape, uint id, Vector3 pos, Quaternion rot) { - BulletWorldUnman worldu = world as BulletWorldUnman; + BulletWorldUnman worldu = world as BulletWorldUnman; BulletShapeUnman shapeu = shape as BulletShapeUnman; return new BulletBodyUnman(id, BSAPICPP.CreateGhostFromShape2(worldu.ptr, shapeu.ptr, id, pos, rot)); } @@ -393,7 +393,7 @@ public override BulletConstraint Create6DofConstraint(BulletWorld world, BulletB Vector3 frame2loc, Quaternion frame2rot, bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) { - BulletWorldUnman worldu = world as BulletWorldUnman; + BulletWorldUnman worldu = world as BulletWorldUnman; BulletBodyUnman bodyu1 = obj1 as BulletBodyUnman; BulletBodyUnman bodyu2 = obj2 as BulletBodyUnman; return new BulletConstraintUnman(BSAPICPP.Create6DofConstraint2(worldu.ptr, bodyu1.ptr, bodyu2.ptr, frame1loc, frame1rot, @@ -404,7 +404,7 @@ public override BulletConstraint Create6DofConstraintToPoint(BulletWorld world, Vector3 joinPoint, bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) { - BulletWorldUnman worldu = world as BulletWorldUnman; + BulletWorldUnman worldu = world as BulletWorldUnman; BulletBodyUnman bodyu1 = obj1 as BulletBodyUnman; BulletBodyUnman bodyu2 = obj2 as BulletBodyUnman; return new BulletConstraintUnman(BSAPICPP.Create6DofConstraintToPoint2(worldu.ptr, bodyu1.ptr, bodyu2.ptr, @@ -416,7 +416,7 @@ public override BulletConstraint CreateHingeConstraint(BulletWorld world, Bullet Vector3 axisInA, Vector3 axisInB, bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) { - BulletWorldUnman worldu = world as BulletWorldUnman; + BulletWorldUnman worldu = world as BulletWorldUnman; BulletBodyUnman bodyu1 = obj1 as BulletBodyUnman; BulletBodyUnman bodyu2 = obj2 as BulletBodyUnman; return new BulletConstraintUnman(BSAPICPP.CreateHingeConstraint2(worldu.ptr, bodyu1.ptr, bodyu2.ptr, @@ -494,7 +494,7 @@ public override bool DestroyConstraint(BulletWorld world, BulletConstraint const // ===================================================================================== // btCollisionWorld entries public override void UpdateSingleAabb(BulletWorld world, BulletBody obj) -{ +{ BulletWorldUnman worldu = world as BulletWorldUnman; BulletBodyUnman bodyu = obj as BulletBodyUnman; BSAPICPP.UpdateSingleAabb2(worldu.ptr, bodyu.ptr); @@ -502,19 +502,19 @@ public override void UpdateSingleAabb(BulletWorld world, BulletBody obj) public override void UpdateAabbs(BulletWorld world) { - BulletWorldUnman worldu = world as BulletWorldUnman; + BulletWorldUnman worldu = world as BulletWorldUnman; BSAPICPP.UpdateAabbs2(worldu.ptr); } public override bool GetForceUpdateAllAabbs(BulletWorld world) { - BulletWorldUnman worldu = world as BulletWorldUnman; + BulletWorldUnman worldu = world as BulletWorldUnman; return BSAPICPP.GetForceUpdateAllAabbs2(worldu.ptr); } public override void SetForceUpdateAllAabbs(BulletWorld world, bool force) { - BulletWorldUnman worldu = world as BulletWorldUnman; + BulletWorldUnman worldu = world as BulletWorldUnman; BSAPICPP.SetForceUpdateAllAabbs2(worldu.ptr, force); } @@ -522,28 +522,28 @@ public override void SetForceUpdateAllAabbs(BulletWorld world, bool force) // btDynamicsWorld entries public override bool AddObjectToWorld(BulletWorld world, BulletBody obj) { - BulletWorldUnman worldu = world as BulletWorldUnman; + BulletWorldUnman worldu = world as BulletWorldUnman; BulletBodyUnman bodyu = obj as BulletBodyUnman; return BSAPICPP.AddObjectToWorld2(worldu.ptr, bodyu.ptr); } public override bool RemoveObjectFromWorld(BulletWorld world, BulletBody obj) { - BulletWorldUnman worldu = world as BulletWorldUnman; + BulletWorldUnman worldu = world as BulletWorldUnman; BulletBodyUnman bodyu = obj as BulletBodyUnman; return BSAPICPP.RemoveObjectFromWorld2(worldu.ptr, bodyu.ptr); } public override bool AddConstraintToWorld(BulletWorld world, BulletConstraint constrain, bool disableCollisionsBetweenLinkedObjects) { - BulletWorldUnman worldu = world as BulletWorldUnman; + BulletWorldUnman worldu = world as BulletWorldUnman; BulletConstraintUnman constrainu = constrain as BulletConstraintUnman; return BSAPICPP.AddConstraintToWorld2(worldu.ptr, constrainu.ptr, disableCollisionsBetweenLinkedObjects); } public override bool RemoveConstraintFromWorld(BulletWorld world, BulletConstraint constrain) { - BulletWorldUnman worldu = world as BulletWorldUnman; + BulletWorldUnman worldu = world as BulletWorldUnman; BulletConstraintUnman constrainu = constrain as BulletConstraintUnman; return BSAPICPP.RemoveConstraintFromWorld2(worldu.ptr, constrainu.ptr); } @@ -605,16 +605,16 @@ public override bool HasContactResponse(BulletBody obj) public override void SetCollisionShape(BulletWorld world, BulletBody obj, BulletShape shape) { - BulletWorldUnman worldu = world as BulletWorldUnman; + BulletWorldUnman worldu = world as BulletWorldUnman; BulletBodyUnman bodyu = obj as BulletBodyUnman; - BulletShapeUnman shapeu = shape as BulletShapeUnman; - if (worldu != null && bodyu != null) - { - // Special case to allow the caller to zero out the reference to any physical shape - if (shapeu != null) - BSAPICPP.SetCollisionShape2(worldu.ptr, bodyu.ptr, shapeu.ptr); - else - BSAPICPP.SetCollisionShape2(worldu.ptr, bodyu.ptr, IntPtr.Zero); + BulletShapeUnman shapeu = shape as BulletShapeUnman; + if (worldu != null && bodyu != null) + { + // Special case to allow the caller to zero out the reference to any physical shape + if (shapeu != null) + BSAPICPP.SetCollisionShape2(worldu.ptr, bodyu.ptr, shapeu.ptr); + else + BSAPICPP.SetCollisionShape2(worldu.ptr, bodyu.ptr, IntPtr.Zero); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index cb8108d..d4e2e87 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -894,26 +894,26 @@ public sealed class BSPrim : BSPhysObject // Object MUST NOT already be in the world. // This routine exists because some assorted properties get mangled by adding to the world. internal void AddObjectToPhysicalWorld() - { - if (PhysBody.HasPhysicalBody) - { - PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, PhysBody); - - // TODO: Fix this. Total kludge because adding object to world resets its gravity to default. - // Replace this when the new AddObjectToWorld function is complete. - PhysicsScene.PE.SetGravity(PhysBody, ComputeGravity()); - - // Collision filter can be set only when the object is in the world - if (!PhysBody.ApplyCollisionMask(PhysicsScene)) - { - m_log.ErrorFormat("{0} Failed setting object collision mask: id={1}", LogHeader, LocalID); - DetailLog("{0},BSPrim.UpdatePhysicalParameters,failedSetMaskGroup,cType={1}", LocalID, PhysBody.collisionType); - } - } - else - { - 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); + { + if (PhysBody.HasPhysicalBody) + { + PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, PhysBody); + + // TODO: Fix this. Total kludge because adding object to world resets its gravity to default. + // Replace this when the new AddObjectToWorld function is complete. + PhysicsScene.PE.SetGravity(PhysBody, ComputeGravity()); + + // Collision filter can be set only when the object is in the world + if (!PhysBody.ApplyCollisionMask(PhysicsScene)) + { + m_log.ErrorFormat("{0} Failed setting object collision mask: id={1}", LogHeader, LocalID); + DetailLog("{0},BSPrim.UpdatePhysicalParameters,failedSetMaskGroup,cType={1}", LocalID, PhysBody.collisionType); + } + } + else + { + 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); } } -- cgit v1.1 From 9d840fd2ee5c3e6c6f788e8145f06701e9ea2724 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 1 Jan 2013 16:49:38 -0800 Subject: BulletSim: move over and port the interface for BulletXNA. Copied BulletSNPlugin.BulletSimAPI to a new BulletSPlugin.BSAPIXNA.cs and then modifyed the latter to comply with the BSAPITemplate definition. Not totally debugged but the code is all there for an INI variable to select either unmanaged C++ Bullet or the C# version of Bullet. --- OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | 22 +- OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs | 889 ++++++++++++++------- .../Region/Physics/BulletSPlugin/BSApiTemplate.cs | 6 +- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 11 - OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 2 +- .../Physics/BulletSPlugin/BSShapeCollection.cs | 4 +- .../Physics/BulletSPlugin/BSTerrainHeightmap.cs | 4 +- 7 files changed, 623 insertions(+), 315 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs index 9d8f60d..83e12ba 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs @@ -339,10 +339,10 @@ public override bool DeleteCollisionShape(BulletWorld world, BulletShape shape) return BSAPICPP.DeleteCollisionShape2(worldu.ptr, shapeu.ptr); } -public override int GetBodyType(BulletBody obj) +public override CollisionObjectTypes GetBodyType(BulletBody obj) { BulletBodyUnman bodyu = obj as BulletBodyUnman; - return BSAPICPP.GetBodyType2(bodyu.ptr); + return (CollisionObjectTypes)BSAPICPP.GetBodyType2(bodyu.ptr); } public override BulletBody CreateBodyFromShape(BulletWorld world, BulletShape shape, uint id, Vector3 pos, Quaternion rot) @@ -522,9 +522,22 @@ public override void SetForceUpdateAllAabbs(BulletWorld world, bool force) // btDynamicsWorld entries public override bool AddObjectToWorld(BulletWorld world, BulletBody obj) { + // Bullet resets several variables when an object is added to the world. + // Gravity is reset to world default depending on the static/dynamic + // type. Of course, the collision flags in the broadphase proxy are initialized to default. BulletWorldUnman worldu = world as BulletWorldUnman; BulletBodyUnman bodyu = obj as BulletBodyUnman; - return BSAPICPP.AddObjectToWorld2(worldu.ptr, bodyu.ptr); + + Vector3 origGrav = BSAPICPP.GetGravity2(bodyu.ptr); + + bool ret = BSAPICPP.AddObjectToWorld2(worldu.ptr, bodyu.ptr); + + if (ret) + { + BSAPICPP.SetGravity2(bodyu.ptr, origGrav); + obj.ApplyCollisionMask(world.physicsScene); + } + return ret; } public override bool RemoveObjectFromWorld(BulletWorld world, BulletBody obj) @@ -1061,7 +1074,7 @@ public override Vector3 GetAngularFactor(BulletBody obj) return BSAPICPP.GetAngularFactor2(bodyu.ptr); } -public override bool IsInWorld(BulletBody obj) +public override bool IsInWorld(BulletWorld world, BulletBody obj) { BulletBodyUnman bodyu = obj as BulletBodyUnman; return BSAPICPP.IsInWorld2(bodyu.ptr); @@ -1239,7 +1252,6 @@ public override void DumpPhysicsStatistics(BulletWorld world) BSAPICPP.DumpPhysicsStatistics2(worldu.ptr); } - // ===================================================================================== // ===================================================================================== // ===================================================================================== diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs index f70ad30..aea10ee 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs @@ -26,22 +26,110 @@ */ using System; using System.Collections.Generic; -using System.Linq; +using System.IO; using System.Text; +using OpenSim.Framework; + +using OpenMetaverse; + using BulletXNA; using BulletXNA.LinearMath; using BulletXNA.BulletCollision; using BulletXNA.BulletDynamics; using BulletXNA.BulletCollision.CollisionDispatch; -using OpenMetaverse; - namespace OpenSim.Region.Physics.BulletSPlugin { - /* public sealed class BSAPIXNA : BSAPITemplate { +private sealed class BulletWorldXNA : BulletWorld +{ + public DiscreteDynamicsWorld world; + public BulletWorldXNA(uint id, BSScene physScene, DiscreteDynamicsWorld xx) + : base(id, physScene) + { + world = xx; + } +} + +private sealed class BulletBodyXNA : BulletBody +{ + public CollisionObject body; + public RigidBody rigidBody { get { return RigidBody.Upcast(body); } } + + public BulletBodyXNA(uint id, CollisionObject xx) + : base(id) + { + body = xx; + } + public override bool HasPhysicalBody + { + get { return body != null; } + } + public override void Clear() + { + body = null; + } + public override string AddrString + { + get { return "XNARigidBody"; } + } +} + +private sealed class BulletShapeXNA : BulletShape +{ + public CollisionShape shape; + public BulletShapeXNA(CollisionShape xx, BSPhysicsShapeType typ) + : base() + { + shape = xx; + type = typ; + } + public override bool HasPhysicalShape + { + get { return shape != null; } + } + public override void Clear() + { + shape = null; + } + public override BulletShape Clone() + { + return new BulletShapeXNA(shape, type); + } + public override bool ReferenceSame(BulletShape other) + { + BulletShapeXNA otheru = other as BulletShapeXNA; + return (otheru != null) && (this.shape == otheru.shape); + + } + public override string AddrString + { + get { return "XNACollisionShape"; } + } +} +private sealed class BulletConstraintXNA : BulletConstraint +{ + public TypedConstraint constrain; + public BulletConstraintXNA(TypedConstraint xx) : base() + { + constrain = xx; + } + + public override void Clear() + { + constrain = null; + } + public override bool HasPhysicalConstraint { get { return constrain != null; } } + + // Used for log messages for a unique display of the memory/object allocated to this instance + public override string AddrString + { + get { return "XNAConstraint"; } + } +} + private static int m_collisionsThisFrame; private BSScene PhysicsScene { get; set; } @@ -58,112 +146,135 @@ public sealed class BSAPIXNA : BSAPITemplate /// /// /// - public override bool RemoveObjectFromWorld2(object pWorld, object pBody) + public override bool RemoveObjectFromWorld(BulletWorld pWorld, BulletBody pBody) { - DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; - RigidBody body = pBody as RigidBody; + DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; world.RemoveRigidBody(body); return true; } - public override void SetRestitution2(object pBody, float pRestitution) + public override bool AddConstraintToWorld(BulletWorld world, BulletConstraint constrain, bool disableCollisionsBetweenLinkedObjects) { - RigidBody body = pBody as RigidBody; + /* TODO */ + return false; + } + + public override bool RemoveConstraintFromWorld(BulletWorld world, BulletConstraint constrain) + { + /* TODO */ + return false; + } + + public override void SetRestitution(BulletBody pBody, float pRestitution) + { + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; body.SetRestitution(pRestitution); } - public override void SetMargin2(object pShape, float pMargin) + public override int GetShapeType(BulletShape pShape) + { + CollisionShape shape = ((BulletShapeXNA)pShape).shape; + return (int)shape.GetShapeType(); + } + public override void SetMargin(BulletShape pShape, float pMargin) { - CollisionShape shape = pShape as CollisionShape; + CollisionShape shape = ((BulletShapeXNA)pShape).shape; shape.SetMargin(pMargin); } - public override void SetLocalScaling2(object pShape, Vector3 pScale) + public override float GetMargin(BulletShape pShape) + { + CollisionShape shape = ((BulletShapeXNA)pShape).shape; + return shape.GetMargin(); + } + + public override void SetLocalScaling(BulletShape pShape, Vector3 pScale) { - CollisionShape shape = pShape as CollisionShape; + CollisionShape shape = ((BulletShapeXNA)pShape).shape; IndexedVector3 vec = new IndexedVector3(pScale.X, pScale.Y, pScale.Z); shape.SetLocalScaling(ref vec); } - public override void SetContactProcessingThreshold2(object pBody, float contactprocessingthreshold) + public override void SetContactProcessingThreshold(BulletBody pBody, float contactprocessingthreshold) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; body.SetContactProcessingThreshold(contactprocessingthreshold); } - public override void SetCcdMotionThreshold2(object pBody, float pccdMotionThreashold) + public override void SetCcdMotionThreshold(BulletBody pBody, float pccdMotionThreashold) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; body.SetCcdMotionThreshold(pccdMotionThreashold); } - public override void SetCcdSweptSphereRadius2(object pBody, float pCcdSweptSphereRadius) + public override void SetCcdSweptSphereRadius(BulletBody pBody, float pCcdSweptSphereRadius) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; body.SetCcdSweptSphereRadius(pCcdSweptSphereRadius); } - public override void SetAngularFactorV2(object pBody, Vector3 pAngularFactor) + public override void SetAngularFactorV(BulletBody pBody, Vector3 pAngularFactor) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; body.SetAngularFactor(new IndexedVector3(pAngularFactor.X, pAngularFactor.Y, pAngularFactor.Z)); } - public override CollisionFlags AddToCollisionFlags2(object pBody, CollisionFlags pcollisionFlags) + public override CollisionFlags AddToCollisionFlags(BulletBody pBody, CollisionFlags pcollisionFlags) { - CollisionObject body = pBody as CollisionObject; + CollisionObject body = ((BulletBodyXNA)pBody).body; CollisionFlags existingcollisionFlags = (CollisionFlags)(uint)body.GetCollisionFlags(); existingcollisionFlags |= pcollisionFlags; body.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags)(uint)existingcollisionFlags); return (CollisionFlags) (uint) existingcollisionFlags; } - public override void AddObjectToWorld2(object pWorld, object pBody) + public override bool AddObjectToWorld(BulletWorld pWorld, BulletBody pBody) { - RigidBody body = pBody as RigidBody; - DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + // Bullet resets several variables when an object is added to the world. In particular, + // BulletXNA resets position and rotation. Gravity is also reset depending on the static/dynamic + // type. Of course, the collision flags in the broadphase proxy are initialized to default. + DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + + IndexedMatrix origPos = body.GetWorldTransform(); + IndexedVector3 origGrav = body.GetGravity(); + //if (!(body.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.STATIC_PLANE_PROXYTYPE && body.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.TERRAIN_SHAPE_PROXYTYPE)) world.AddRigidBody(body); - //if (body.GetBroadphaseHandle() != null) - // world.UpdateSingleAabb(body); - } + body.SetWorldTransform(origPos); + body.SetGravity(origGrav); - public override void AddObjectToWorld2(object pWorld, object pBody, Vector3 _position, Quaternion _orientation) - { - RigidBody body = pBody as RigidBody; - DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; - //if (!(body.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.STATIC_PLANE_PROXYTYPE && body.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.TERRAIN_SHAPE_PROXYTYPE)) + pBody.ApplyCollisionMask(pWorld.physicsScene); - world.AddRigidBody(body); - IndexedVector3 vposition = new IndexedVector3(_position.X, _position.Y, _position.Z); - IndexedQuaternion vquaternion = new IndexedQuaternion(_orientation.X, _orientation.Y, _orientation.Z, - _orientation.W); - IndexedMatrix mat = IndexedMatrix.CreateFromQuaternion(vquaternion); - mat._origin = vposition; - body.SetWorldTransform(mat); //if (body.GetBroadphaseHandle() != null) // world.UpdateSingleAabb(body); + return true; } - public override void ForceActivationState2(object pBody, ActivationState pActivationState) + public override void ForceActivationState(BulletBody pBody, ActivationState pActivationState) { - CollisionObject body = pBody as CollisionObject; + CollisionObject body = ((BulletBodyXNA)pBody).body; body.ForceActivationState((BulletXNA.BulletCollision.ActivationState)(uint)pActivationState); } - public override void UpdateSingleAabb2(object pWorld, object pBody) + public override void UpdateSingleAabb(BulletWorld pWorld, BulletBody pBody) { - CollisionObject body = pBody as CollisionObject; - DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; + CollisionObject body = ((BulletBodyXNA)pBody).body; world.UpdateSingleAabb(body); } - public override bool SetCollisionGroupMask2(object pBody, uint pGroup, uint pMask) + public override void UpdateAabbs(BulletWorld world) { /* TODO */ } + public override bool GetForceUpdateAllAabbs(BulletWorld world) { /* TODO */ return false; } + public override void SetForceUpdateAllAabbs(BulletWorld world, bool force) { /* TODO */ } + + public override bool SetCollisionGroupMask(BulletBody pBody, uint pGroup, uint pMask) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; body.GetBroadphaseHandle().m_collisionFilterGroup = (BulletXNA.BulletCollision.CollisionFilterGroups) pGroup; body.GetBroadphaseHandle().m_collisionFilterGroup = (BulletXNA.BulletCollision.CollisionFilterGroups) pGroup; if ((uint) body.GetBroadphaseHandle().m_collisionFilterGroup == 0) @@ -171,9 +282,9 @@ public sealed class BSAPIXNA : BSAPITemplate return true; } - public override void ClearAllForces2(object pBody) + public override void ClearAllForces(BulletBody pBody) { - CollisionObject body = pBody as CollisionObject; + CollisionObject body = ((BulletBodyXNA)pBody).body; IndexedVector3 zeroVector = new IndexedVector3(0, 0, 0); body.SetInterpolationLinearVelocity(ref zeroVector); body.SetInterpolationAngularVelocity(ref zeroVector); @@ -190,29 +301,67 @@ public sealed class BSAPIXNA : BSAPITemplate } } - public override void SetInterpolationAngularVelocity2(object pBody, Vector3 pVector3) + public override void SetInterpolationAngularVelocity(BulletBody pBody, Vector3 pVector3) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; IndexedVector3 vec = new IndexedVector3(pVector3.X, pVector3.Y, pVector3.Z); body.SetInterpolationAngularVelocity(ref vec); } - public override void SetAngularVelocity2(object pBody, Vector3 pVector3) + public override void SetAngularVelocity(BulletBody pBody, Vector3 pVector3) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; IndexedVector3 vec = new IndexedVector3(pVector3.X, pVector3.Y, pVector3.Z); body.SetAngularVelocity(ref vec); } + public override Vector3 GetTotalForce(BulletBody pBody) + { + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + IndexedVector3 iv3 = body.GetTotalForce(); + return new Vector3(iv3.X, iv3.Y, iv3.Z); + } + public override Vector3 GetTotalTorque(BulletBody pBody) + { + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + IndexedVector3 iv3 = body.GetTotalTorque(); + return new Vector3(iv3.X, iv3.Y, iv3.Z); + } + public override Vector3 GetInvInertiaDiagLocal(BulletBody pBody) + { + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + IndexedVector3 iv3 = body.GetInvInertiaDiagLocal(); + return new Vector3(iv3.X, iv3.Y, iv3.Z); + } + public override void SetInvInertiaDiagLocal(BulletBody pBody, Vector3 inert) + { + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + IndexedVector3 iv3 = new IndexedVector3(inert.X, inert.Y, inert.Z); + body.SetInvInertiaDiagLocal(ref iv3); + } + public override void ApplyForce(BulletBody pBody, Vector3 force, Vector3 pos) + { + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + IndexedVector3 forceiv3 = new IndexedVector3(force.X, force.Y, force.Z); + IndexedVector3 posiv3 = new IndexedVector3(pos.X, pos.Y, pos.Z); + body.ApplyForce(ref forceiv3, ref posiv3); + } + public override void ApplyImpulse(BulletBody pBody, Vector3 imp, Vector3 pos) + { + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + IndexedVector3 impiv3 = new IndexedVector3(imp.X, imp.Y, imp.Z); + IndexedVector3 posiv3 = new IndexedVector3(pos.X, pos.Y, pos.Z); + body.ApplyImpulse(ref impiv3, ref posiv3); + } - public override void ClearForces2(object pBody) + public override void ClearForces(BulletBody pBody) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; body.ClearForces(); } - public override void SetTranslation2(object pBody, Vector3 _position, Quaternion _orientation) + public override void SetTranslation(BulletBody pBody, Vector3 _position, Quaternion _orientation) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; IndexedVector3 vposition = new IndexedVector3(_position.X, _position.Y, _position.Z); IndexedQuaternion vquaternion = new IndexedQuaternion(_orientation.X, _orientation.Y, _orientation.Z, _orientation.W); @@ -222,90 +371,98 @@ public sealed class BSAPIXNA : BSAPITemplate } - public override Vector3 GetPosition2(object pBody) + public override Vector3 GetPosition(BulletBody pBody) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; IndexedVector3 pos = body.GetInterpolationWorldTransform()._origin; return new Vector3(pos.X, pos.Y, pos.Z); } - public override Vector3 CalculateLocalInertia2(object pShape, float pphysMass) + public override Vector3 CalculateLocalInertia(BulletShape pShape, float pphysMass) { - CollisionShape shape = pShape as CollisionShape; + CollisionShape shape = ((BulletShapeXNA)pShape).shape; IndexedVector3 inertia = IndexedVector3.Zero; shape.CalculateLocalInertia(pphysMass, out inertia); return new Vector3(inertia.X, inertia.Y, inertia.Z); } - public override void SetMassProps2(object pBody, float pphysMass, Vector3 plocalInertia) + public override void SetMassProps(BulletBody pBody, float pphysMass, Vector3 plocalInertia) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; IndexedVector3 inertia = new IndexedVector3(plocalInertia.X, plocalInertia.Y, plocalInertia.Z); body.SetMassProps(pphysMass, inertia); } - public override void SetObjectForce2(object pBody, Vector3 _force) + public override void SetObjectForce(BulletBody pBody, Vector3 _force) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; IndexedVector3 force = new IndexedVector3(_force.X, _force.Y, _force.Z); body.SetTotalForce(ref force); } - public override void SetFriction2(object pBody, float _currentFriction) + public override void SetFriction(BulletBody pBody, float _currentFriction) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; body.SetFriction(_currentFriction); } - public override void SetLinearVelocity2(object pBody, Vector3 _velocity) + public override void SetLinearVelocity(BulletBody pBody, Vector3 _velocity) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; IndexedVector3 velocity = new IndexedVector3(_velocity.X, _velocity.Y, _velocity.Z); body.SetLinearVelocity(velocity); } - public override void Activate2(object pBody, bool pforceactivation) + public override void Activate(BulletBody pBody, bool pforceactivation) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; body.Activate(pforceactivation); } - public override Quaternion GetOrientation2(object pBody) + public override Quaternion GetOrientation(BulletBody pBody) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; IndexedQuaternion mat = body.GetInterpolationWorldTransform().GetRotation(); return new Quaternion(mat.X, mat.Y, mat.Z, mat.W); } - public override CollisionFlags RemoveFromCollisionFlags2(object pBody, CollisionFlags pcollisionFlags) + public override CollisionFlags RemoveFromCollisionFlags(BulletBody pBody, CollisionFlags pcollisionFlags) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; CollisionFlags existingcollisionFlags = (CollisionFlags)(uint)body.GetCollisionFlags(); existingcollisionFlags &= ~pcollisionFlags; body.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags)(uint)existingcollisionFlags); return (CollisionFlags)(uint)existingcollisionFlags; } - public override void SetGravity2(object pBody, Vector3 pGravity) + public override float GetCcdMotionThreshold(BulletBody obj) { /* TODO */ return 0f; } + + public override float GetCcdSweptSphereRadius(BulletBody obj) { /* TODO */ return 0f; } + + public override IntPtr GetUserPointer(BulletBody obj) { /* TODO */ return IntPtr.Zero; } + + public override void SetUserPointer(BulletBody obj, IntPtr val) { /* TODO */ } + + public override void SetGravity(BulletBody pBody, Vector3 pGravity) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; IndexedVector3 gravity = new IndexedVector3(pGravity.X, pGravity.Y, pGravity.Z); body.SetGravity(gravity); } - public override bool DestroyConstraint2(object pBody, object pConstraint) + public override bool DestroyConstraint(BulletWorld pWorld, BulletConstraint pConstraint) { - RigidBody body = pBody as RigidBody; - TypedConstraint constraint = pConstraint as TypedConstraint; - body.RemoveConstraintRef(constraint); + DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; + TypedConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain; + world.RemoveConstraint(constraint); return true; } - public override bool SetLinearLimits2(object pConstraint, Vector3 low, Vector3 high) + public override bool SetLinearLimits(BulletConstraint pConstraint, Vector3 low, Vector3 high) { - Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; + Generic6DofConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint; IndexedVector3 lowlimit = new IndexedVector3(low.X, low.Y, low.Z); IndexedVector3 highlimit = new IndexedVector3(high.X, high.Y, high.Z); constraint.SetLinearLowerLimit(lowlimit); @@ -313,9 +470,9 @@ public sealed class BSAPIXNA : BSAPITemplate return true; } - public override bool SetAngularLimits2(object pConstraint, Vector3 low, Vector3 high) + public override bool SetAngularLimits(BulletConstraint pConstraint, Vector3 low, Vector3 high) { - Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; + Generic6DofConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint; IndexedVector3 lowlimit = new IndexedVector3(low.X, low.Y, low.Z); IndexedVector3 highlimit = new IndexedVector3(high.X, high.Y, high.Z); constraint.SetAngularLowerLimit(lowlimit); @@ -323,32 +480,33 @@ public sealed class BSAPIXNA : BSAPITemplate return true; } - public override void SetConstraintNumSolverIterations2(object pConstraint, float cnt) + public override void SetConstraintNumSolverIterations(BulletConstraint pConstraint, float cnt) { - Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; + Generic6DofConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint; constraint.SetOverrideNumSolverIterations((int)cnt); } - public override void CalculateTransforms2(object pConstraint) + public override bool CalculateTransforms(BulletConstraint pConstraint) { - Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; + Generic6DofConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint; constraint.CalculateTransforms(); + return true; } - public override void SetConstraintEnable2(object pConstraint, float p_2) + public override void SetConstraintEnable(BulletConstraint pConstraint, float p_2) { - Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; + Generic6DofConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint; constraint.SetEnabled((p_2 == 0) ? false : true); } - //BulletSimAPI.Create6DofConstraint2(m_world.ptr, m_body1.ptr, m_body2.ptr,frame1, frame1rot,frame2, frame2rot,useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); - public override object Create6DofConstraint2(object pWorld, object pBody1, object pBody2, Vector3 pframe1, Quaternion pframe1rot, Vector3 pframe2, Quaternion pframe2rot, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies) + //BulletSimAPI.Create6DofConstraint(m_world.ptr, m_body1.ptr, m_body2.ptr,frame1, frame1rot,frame2, frame2rot,useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); + public override BulletConstraint Create6DofConstraint(BulletWorld pWorld, BulletBody pBody1, BulletBody pBody2, Vector3 pframe1, Quaternion pframe1rot, Vector3 pframe2, Quaternion pframe2rot, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies) { - DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; - RigidBody body1 = pBody1 as RigidBody; - RigidBody body2 = pBody2 as RigidBody; + DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; + RigidBody body1 = ((BulletBodyXNA)pBody1).rigidBody; + RigidBody body2 = ((BulletBodyXNA)pBody2).rigidBody; IndexedVector3 frame1v = new IndexedVector3(pframe1.X, pframe1.Y, pframe1.Z); IndexedQuaternion frame1rot = new IndexedQuaternion(pframe1rot.X, pframe1rot.Y, pframe1rot.Z, pframe1rot.W); IndexedMatrix frame1 = IndexedMatrix.CreateFromQuaternion(frame1rot); @@ -364,7 +522,7 @@ public sealed class BSAPIXNA : BSAPITemplate consttr.CalculateTransforms(); world.AddConstraint(consttr,pdisableCollisionsBetweenLinkedBodies); - return consttr; + return new BulletConstraintXNA(consttr); } @@ -378,11 +536,11 @@ public sealed class BSAPIXNA : BSAPITemplate /// /// /// - public override object Create6DofConstraintToPoint2(object pWorld, object pBody1, object pBody2, Vector3 pjoinPoint, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies) + public override BulletConstraint Create6DofConstraintToPoint(BulletWorld pWorld, BulletBody pBody1, BulletBody pBody2, Vector3 pjoinPoint, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies) { - DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; - RigidBody body1 = pBody1 as RigidBody; - RigidBody body2 = pBody2 as RigidBody; + DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; + RigidBody body1 = ((BulletBodyXNA)pBody1).rigidBody; + RigidBody body2 = ((BulletBodyXNA)pBody2).rigidBody; IndexedMatrix frame1 = new IndexedMatrix(IndexedBasisMatrix.Identity, new IndexedVector3(0, 0, 0)); IndexedMatrix frame2 = new IndexedMatrix(IndexedBasisMatrix.Identity, new IndexedVector3(0, 0, 0)); @@ -396,12 +554,12 @@ public sealed class BSAPIXNA : BSAPITemplate consttr.CalculateTransforms(); world.AddConstraint(consttr, pdisableCollisionsBetweenLinkedBodies); - return consttr; + return new BulletConstraintXNA(consttr); } - //SetFrames2(m_constraint.ptr, frameA, frameArot, frameB, frameBrot); - public override void SetFrames2(object pConstraint, Vector3 pframe1, Quaternion pframe1rot, Vector3 pframe2, Quaternion pframe2rot) + //SetFrames(m_constraint.ptr, frameA, frameArot, frameB, frameBrot); + public override bool SetFrames(BulletConstraint pConstraint, Vector3 pframe1, Quaternion pframe1rot, Vector3 pframe2, Quaternion pframe2rot) { - Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; + Generic6DofConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint; IndexedVector3 frame1v = new IndexedVector3(pframe1.X, pframe1.Y, pframe1.Z); IndexedQuaternion frame1rot = new IndexedQuaternion(pframe1rot.X, pframe1rot.Y, pframe1rot.Z, pframe1rot.W); IndexedMatrix frame1 = IndexedMatrix.CreateFromQuaternion(frame1rot); @@ -412,163 +570,279 @@ public sealed class BSAPIXNA : BSAPITemplate IndexedMatrix frame2 = IndexedMatrix.CreateFromQuaternion(frame2rot); frame2._origin = frame1v; constraint.SetFrames(ref frame1, ref frame2); + return true; } + public override Vector3 GetLinearVelocity(BulletBody pBody) + { + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + IndexedVector3 iv3 = body.GetLinearVelocity(); + return new Vector3(iv3.X, iv3.Y, iv3.Z); + } + public override Vector3 GetAngularVelocity(BulletBody pBody) + { + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + IndexedVector3 iv3 = body.GetAngularVelocity(); + return new Vector3(iv3.X, iv3.Y, iv3.Z); + } + public override Vector3 GetVelocityInLocalPoint(BulletBody pBody, Vector3 pos) + { + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + IndexedVector3 posiv3 = new IndexedVector3(pos.X, pos.Y, pos.Z); + IndexedVector3 iv3 = body.GetVelocityInLocalPoint(ref posiv3); + return new Vector3(iv3.X, iv3.Y, iv3.Z); + } + public override void Translate(BulletBody pBody, Vector3 trans) + { + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + } + public override void UpdateDeactivation(BulletBody pBody, float timeStep) + { + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + body.UpdateDeactivation(timeStep); + } - + public override bool WantsSleeping(BulletBody pBody) + { + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + return body.WantsSleeping(); + } + + public override void SetAngularFactor(BulletBody pBody, float factor) + { + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + body.SetAngularFactor(factor); + } + + public override Vector3 GetAngularFactor(BulletBody pBody) + { + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + IndexedVector3 iv3 = body.GetAngularFactor(); + return new Vector3(iv3.X, iv3.Y, iv3.Z); + } + + public override bool IsInWorld(BulletWorld pWorld, BulletBody pBody) + { + DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; + CollisionObject body = ((BulletBodyXNA)pBody).body; + return world.IsInWorld(body); + } + + public override void AddConstraintRef(BulletBody pBody, BulletConstraint pConstrain) + { + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + TypedConstraint constrain = ((BulletConstraintXNA)pConstrain).constrain; + body.AddConstraintRef(constrain); + } + + public override void RemoveConstraintRef(BulletBody pBody, BulletConstraint pConstrain) + { + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + TypedConstraint constrain = ((BulletConstraintXNA)pConstrain).constrain; + body.RemoveConstraintRef(constrain); + } + + public override BulletConstraint GetConstraintRef(BulletBody pBody, int index) + { + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + return new BulletConstraintXNA(body.GetConstraintRef(index)); + } - public override bool IsInWorld2(object pWorld, object pShapeObj) + public override int GetNumConstraintRefs(BulletBody pBody) { - DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; - CollisionObject shape = pShapeObj as CollisionObject; - return world.IsInWorld(shape); + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + return body.GetNumConstraintRefs(); } - public override void SetInterpolationLinearVelocity2(object pBody, Vector3 VehicleVelocity) + public override void SetInterpolationLinearVelocity(BulletBody pBody, Vector3 VehicleVelocity) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; IndexedVector3 velocity = new IndexedVector3(VehicleVelocity.X, VehicleVelocity.Y, VehicleVelocity.Z); body.SetInterpolationLinearVelocity(ref velocity); } - public override bool UseFrameOffset2(object pConstraint, float onOff) + public override bool UseFrameOffset(BulletConstraint pConstraint, float onOff) { - Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; + Generic6DofConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint; constraint.SetUseFrameOffset((onOff == 0) ? false : true); return true; } - //SetBreakingImpulseThreshold2(m_constraint.ptr, threshold); - public override bool SetBreakingImpulseThreshold2(object pConstraint, float threshold) + //SetBreakingImpulseThreshold(m_constraint.ptr, threshold); + public override bool SetBreakingImpulseThreshold(BulletConstraint pConstraint, float threshold) { - Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; + Generic6DofConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint; constraint.SetBreakingImpulseThreshold(threshold); return true; } - //BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, angularDamping); - public override void SetAngularDamping2(object pBody, float angularDamping) + //BulletSimAPI.SetAngularDamping(Prim.PhysBody.ptr, angularDamping); + public override void SetAngularDamping(BulletBody pBody, float angularDamping) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; float lineardamping = body.GetLinearDamping(); body.SetDamping(lineardamping, angularDamping); } - public override void UpdateInertiaTensor2(object pBody) + public override void UpdateInertiaTensor(BulletBody pBody) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; body.UpdateInertiaTensor(); } - public override void RecalculateCompoundShapeLocalAabb2( object pCompoundShape) + public override void RecalculateCompoundShapeLocalAabb(BulletShape pCompoundShape) { - - CompoundShape shape = pCompoundShape as CompoundShape; + CompoundShape shape = ((BulletShapeXNA)pCompoundShape).shape as CompoundShape; shape.RecalculateLocalAabb(); } - //BulletSimAPI.GetCollisionFlags2(PhysBody.ptr) - public override CollisionFlags GetCollisionFlags2(object pBody) + //BulletSimAPI.GetCollisionFlags(PhysBody.ptr) + public override CollisionFlags GetCollisionFlags(BulletBody pBody) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; uint flags = (uint)body.GetCollisionFlags(); return (CollisionFlags) flags; } - public override void SetDamping2(object pBody, float pLinear, float pAngular) + public override void SetDamping(BulletBody pBody, float pLinear, float pAngular) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; body.SetDamping(pLinear, pAngular); } //PhysBody.ptr, PhysicsScene.Params.deactivationTime); - public override void SetDeactivationTime2(object pBody, float pDeactivationTime) + public override void SetDeactivationTime(BulletBody pBody, float pDeactivationTime) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; body.SetDeactivationTime(pDeactivationTime); } - //SetSleepingThresholds2(PhysBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold); - public override void SetSleepingThresholds2(object pBody, float plinearSleepingThreshold, float pangularSleepingThreshold) + //SetSleepingThresholds(PhysBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold); + public override void SetSleepingThresholds(BulletBody pBody, float plinearSleepingThreshold, float pangularSleepingThreshold) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; body.SetSleepingThresholds(plinearSleepingThreshold, pangularSleepingThreshold); } - public override CollisionObjectTypes GetBodyType2(object pBody) + public override CollisionObjectTypes GetBodyType(BulletBody pBody) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; return (CollisionObjectTypes)(int) body.GetInternalType(); } - //BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, fSum); - public override void ApplyCentralForce2(object pBody, Vector3 pfSum) + public override void ApplyGravity(BulletBody obj) { /* TODO */ } + + public override Vector3 GetGravity(BulletBody obj) { /* TODO */ return Vector3.Zero; } + + public override void SetLinearDamping(BulletBody obj, float lin_damping) { /* TODO */ } + + public override float GetLinearDamping(BulletBody obj) { /* TODO */ return 0f; } + + public override float GetAngularDamping(BulletBody obj) { /* TODO */ return 0f; } + + public override float GetLinearSleepingThreshold(BulletBody obj) { /* TODO */ return 0f; } + + public override void ApplyDamping(BulletBody obj, float timeStep) { /* TODO */ } + + public override Vector3 GetLinearFactor(BulletBody obj) { /* TODO */ return Vector3.Zero; } + + public override void SetLinearFactor(BulletBody obj, Vector3 factor) { /* TODO */ } + + public override void SetCenterOfMassByPosRot(BulletBody obj, Vector3 pos, Quaternion rot) { /* TODO */ } + + //BulletSimAPI.ApplyCentralForce(PhysBody.ptr, fSum); + public override void ApplyCentralForce(BulletBody pBody, Vector3 pfSum) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z); body.ApplyCentralForce(ref fSum); } - public override void ApplyCentralImpulse2(object pBody, Vector3 pfSum) + public override void ApplyCentralImpulse(BulletBody pBody, Vector3 pfSum) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z); body.ApplyCentralImpulse(ref fSum); } - public override void ApplyTorque2(object pBody, Vector3 pfSum) + public override void ApplyTorque(BulletBody pBody, Vector3 pfSum) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z); body.ApplyTorque(ref fSum); } - public override void ApplyTorqueImpulse2(object pBody, Vector3 pfSum) + public override void ApplyTorqueImpulse(BulletBody pBody, Vector3 pfSum) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z); body.ApplyTorqueImpulse(ref fSum); } - public override void DumpRigidBody2(object p, object p_2) + public override void DumpRigidBody(BulletWorld p, BulletBody p_2) + { + //TODO: + } + + public override void DumpCollisionShape(BulletWorld p, BulletShape p_2) + { + //TODO: + } + public override void DumpConstraint(BulletWorld world, BulletConstraint constrain) + { + //TODO: + } + + public override void DumpActivationInfo(BulletWorld world) + { + //TODO: + } + + public override void DumpAllInfo(BulletWorld world) { //TODO: } - public override void DumpCollisionShape2(object p, object p_2) + public override void DumpPhysicsStatistics(BulletWorld world) { //TODO: } - public override void DestroyObject2(object p, object p_2) + public override void DestroyObject(BulletWorld p, BulletBody p_2) { //TODO: } - public override void Shutdown2(object pWorld) + public override void Shutdown(BulletWorld pWorld) { - DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; world.Cleanup(); } - public override void DeleteCollisionShape2(object p, object p_2) + public override BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id) + { + return null; + } + + public override bool DeleteCollisionShape(BulletWorld p, BulletShape p_2) { //TODO: + return false; } //(sim.ptr, shape.ptr, prim.LocalID, prim.RawPosition, prim.RawOrientation); - public override object CreateBodyFromShape2(object pWorld, object pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation) + public override BulletBody CreateBodyFromShape(BulletWorld pWorld, BulletShape pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation) { - CollisionWorld world = pWorld as CollisionWorld; + CollisionWorld world = ((BulletWorldXNA)pWorld).world; IndexedMatrix mat = IndexedMatrix.CreateFromQuaternion(new IndexedQuaternion(pRawOrientation.X, pRawOrientation.Y, pRawOrientation.Z, pRawOrientation.W)); mat._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z); - CollisionShape shape = pShape as CollisionShape; - //UpdateSingleAabb2(world, shape); + CollisionShape shape = ((BulletShapeXNA)pShape).shape; + //UpdateSingleAabb(world, shape); // TODO: Feed Update array into null RigidBody body = new RigidBody(0,new SimMotionState(world,pLocalID,mat,null),shape,IndexedVector3.Zero); body.SetUserPointer(pLocalID); - return body; + return new BulletBodyXNA(pLocalID, body); } - public override object CreateBodyWithDefaultMotionState2( object pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation) + public override BulletBody CreateBodyWithDefaultMotionState( BulletShape pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation) { IndexedMatrix mat = @@ -576,39 +850,71 @@ public sealed class BSAPIXNA : BSAPITemplate pRawOrientation.Z, pRawOrientation.W)); mat._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z); - CollisionShape shape = pShape as CollisionShape; + CollisionShape shape = ((BulletShapeXNA)pShape).shape; // TODO: Feed Update array into null RigidBody body = new RigidBody(0, new DefaultMotionState( mat, IndexedMatrix.Identity), shape, IndexedVector3.Zero); body.SetWorldTransform(mat); body.SetUserPointer(pLocalID); - return body; + return new BulletBodyXNA(pLocalID, body); } //(m_mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); - public override void SetCollisionFlags2(object pBody, CollisionFlags collisionFlags) + public override CollisionFlags SetCollisionFlags(BulletBody pBody, CollisionFlags collisionFlags) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; body.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags) (uint) collisionFlags); - } + return (CollisionFlags)body.GetCollisionFlags(); + } + + public override Vector3 GetAnisotripicFriction(BulletConstraint pconstrain) { /* TODO */ return Vector3.Zero; } + public override Vector3 SetAnisotripicFriction(BulletConstraint pconstrain, Vector3 frict) { /* TODO */ return Vector3.Zero; } + public override bool HasAnisotripicFriction(BulletConstraint pconstrain) { /* TODO */ return false; } + public override float GetContactProcessingThreshold(BulletBody pBody) { /* TODO */ return 0f; } + public override bool IsStaticObject(BulletBody pBody) { /* TODO */ return false; } + public override bool IsKinematicObject(BulletBody pBody) { /* TODO */ return false; } + public override bool IsStaticOrKinematicObject(BulletBody pBody) { /* TODO */ return false; } + public override bool HasContactResponse(BulletBody pBody) { /* TODO */ return false; } + public override int GetActivationState(BulletBody pBody) { /* TODO */ return 0; } + public override void SetActivationState(BulletBody pBody, int state) { /* TODO */ } + public override float GetDeactivationTime(BulletBody pBody) { /* TODO */ return 0f; } + public override bool IsActive(BulletBody pBody) { /* TODO */ return false; } + public override float GetRestitution(BulletBody pBody) { /* TODO */ return 0f; } + public override float GetFriction(BulletBody pBody) { /* TODO */ return 0f; } + public override void SetInterpolationVelocity(BulletBody pBody, Vector3 linearVel, Vector3 angularVel) { /* TODO */ } + public override float GetHitFraction(BulletBody pBody) { /* TODO */ return 0f; } + //(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainHitFraction); - public override void SetHitFraction2(object pBody, float pHitFraction) + public override void SetHitFraction(BulletBody pBody, float pHitFraction) { - RigidBody body = pBody as RigidBody; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; body.SetHitFraction(pHitFraction); } - //BuildCapsuleShape2(physicsScene.World.ptr, 1f, 1f, prim.Scale); - public override object BuildCapsuleShape2(object pWorld, float pRadius, float pHeight, Vector3 pScale) + //BuildCapsuleShape(physicsScene.World.ptr, 1f, 1f, prim.Scale); + public override BulletShape BuildCapsuleShape(BulletWorld pWorld, float pRadius, float pHeight, Vector3 pScale) { - DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; IndexedVector3 scale = new IndexedVector3(pScale.X, pScale.Y, pScale.Z); CapsuleShapeZ capsuleShapeZ = new CapsuleShapeZ(pRadius, pHeight); capsuleShapeZ.SetMargin(world.WorldSettings.Params.collisionMargin); capsuleShapeZ.SetLocalScaling(ref scale); - - return capsuleShapeZ; + + return new BulletShapeXNA(capsuleShapeZ, BSPhysicsShapeType.SHAPE_CAPSULE); ; + } + + public override BulletWorld Initialize(Vector3 maxPosition, ConfigurationParameters parms, + int maxCollisions, ref CollisionDesc[] collisionArray, + int maxUpdates, ref EntityProperties[] updateArray + ) + { + /* TODO */ + return new BulletWorldXNA(1, null, null); } - public static object Initialize2(Vector3 worldExtent, ConfigurationParameters[] o, int mMaxCollisionsPerFrame, ref List collisionArray, int mMaxUpdatesPerFrame, ref List updateArray, object mDebugLogCallbackHandle) + private static object Initialize2(Vector3 worldExtent, + ConfigurationParameters[] o, + int mMaxCollisionsPerFrame, ref List collisionArray, + int mMaxUpdatesPerFrame, ref List updateArray, + object mDebugLogCallbackHandle) { CollisionWorld.WorldData.ParamData p = new CollisionWorld.WorldData.ParamData(); @@ -728,9 +1034,9 @@ public sealed class BSAPIXNA : BSAPITemplate return world; } //m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL - public override bool SetConstraintParam2(object pConstraint, ConstraintParams paramIndex, float paramvalue, ConstraintParamAxis axis) + public override bool SetConstraintParam(BulletConstraint pConstraint, ConstraintParams paramIndex, float paramvalue, ConstraintParamAxis axis) { - Generic6DofConstraint constrain = pConstraint as Generic6DofConstraint; + Generic6DofConstraint constrain = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint; if (axis == ConstraintParamAxis.AXIS_LINEAR_ALL || axis == ConstraintParamAxis.AXIS_ALL) { constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams) (int) paramIndex, paramvalue, 0); @@ -750,10 +1056,10 @@ public sealed class BSAPIXNA : BSAPITemplate return true; } - public override bool PushUpdate2(object pCollisionObject) + public override bool PushUpdate(BulletBody pCollisionObject) { bool ret = false; - RigidBody rb = pCollisionObject as RigidBody; + RigidBody rb = ((BulletBodyXNA)pCollisionObject).rigidBody; if (rb != null) { SimMotionState sms = rb.GetMotionState() as SimMotionState; @@ -769,44 +1075,59 @@ public sealed class BSAPIXNA : BSAPITemplate } - public override bool IsCompound2(object pShape) + public override float GetAngularMotionDisc(BulletShape pShape) { - CollisionShape shape = pShape as CollisionShape; + CollisionShape shape = ((BulletShapeXNA)pShape).shape; + return shape.GetAngularMotionDisc(); + } + public override float GetContactBreakingThreshold(BulletShape pShape, float defaultFactor) + { + CollisionShape shape = ((BulletShapeXNA)pShape).shape; + return shape.GetContactBreakingThreshold(defaultFactor); + } + public override bool IsCompound(BulletShape pShape) + { + CollisionShape shape = ((BulletShapeXNA)pShape).shape; return shape.IsCompound(); } - public override bool IsPloyhedral2(object pShape) + public override bool IsSoftBody(BulletShape pShape) + { + CollisionShape shape = ((BulletShapeXNA)pShape).shape; + return shape.IsSoftBody(); + } + public override bool IsPolyhedral(BulletShape pShape) { - CollisionShape shape = pShape as CollisionShape; + CollisionShape shape = ((BulletShapeXNA)pShape).shape; return shape.IsPolyhedral(); } - public override bool IsConvex2d2(object pShape) + public override bool IsConvex2d(BulletShape pShape) { - CollisionShape shape = pShape as CollisionShape; + CollisionShape shape = ((BulletShapeXNA)pShape).shape; return shape.IsConvex2d(); } - public override bool IsConvex2(object pShape) + public override bool IsConvex(BulletShape pShape) { - CollisionShape shape = pShape as CollisionShape; + CollisionShape shape = ((BulletShapeXNA)pShape).shape; return shape.IsConvex(); } - public override bool IsNonMoving2(object pShape) + public override bool IsNonMoving(BulletShape pShape) { - CollisionShape shape = pShape as CollisionShape; + CollisionShape shape = ((BulletShapeXNA)pShape).shape; return shape.IsNonMoving(); } - public override bool IsConcave2(object pShape) + public override bool IsConcave(BulletShape pShape) { - CollisionShape shape = pShape as CollisionShape; + CollisionShape shape = ((BulletShapeXNA)pShape).shape; return shape.IsConcave(); } - public override bool IsInfinite2(object pShape) + public override bool IsInfinite(BulletShape pShape) { - CollisionShape shape = pShape as CollisionShape; + CollisionShape shape = ((BulletShapeXNA)pShape).shape; return shape.IsInfinite(); } - public override bool IsNativeShape2(object pShape) + public override bool IsNativeShape(BulletShape pShape) { - CollisionShape shape = pShape as CollisionShape; + CollisionShape shape = ((BulletShapeXNA)pShape).shape; bool ret; switch (shape.GetShapeType()) { @@ -822,33 +1143,39 @@ public sealed class BSAPIXNA : BSAPITemplate } return ret; } + + public override void SetShapeCollisionMargin(BulletShape shape, float margin) { /* TODO */ } + //sim.ptr, shape.ptr,prim.LocalID, prim.RawPosition, prim.RawOrientation - public override object CreateGhostFromShape2(object pWorld, object pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation) + public override BulletBody CreateGhostFromShape(BulletWorld pWorld, BulletShape pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation) { + DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; IndexedMatrix bodyTransform = new IndexedMatrix(); bodyTransform._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z); bodyTransform.SetRotation(new IndexedQuaternion(pRawOrientation.X,pRawOrientation.Y,pRawOrientation.Z,pRawOrientation.W)); GhostObject gObj = new PairCachingGhostObject(); gObj.SetWorldTransform(bodyTransform); - CollisionShape shape = pShape as CollisionShape; + CollisionShape shape = ((BulletShapeXNA)pShape).shape; gObj.SetCollisionShape(shape); gObj.SetUserPointer(pLocalID); // TODO: Add to Special CollisionObjects! - return gObj; + return new BulletBodyXNA(pLocalID, gObj); } - public static void SetCollisionShape2(object pWorld, object pObj, object pShape) + public override void SetCollisionShape(BulletWorld pWorld, BulletBody pObj, BulletShape pShape) { - var world = pWorld as DiscreteDynamicsWorld; - var obj = pObj as CollisionObject; - var shape = pShape as CollisionShape; + DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; + CollisionObject obj = ((BulletBodyXNA)pObj).body; + CollisionShape shape = ((BulletShapeXNA)pShape).shape; obj.SetCollisionShape(shape); } + public override BulletShape GetCollisionShape(BulletBody obj) { /* TODO */ return null; } + //(PhysicsScene.World.ptr, nativeShapeData) - public override object BuildNativeShape2(object pWorld, ShapeData pShapeData) + public override BulletShape BuildNativeShape(BulletWorld pWorld, ShapeData pShapeData) { - var world = pWorld as DiscreteDynamicsWorld; + DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; CollisionShape shape = null; switch (pShapeData.Type) { @@ -873,25 +1200,25 @@ public sealed class BSAPIXNA : BSAPITemplate shape.SetLocalScaling(ref scaling); } - return shape; + return new BulletShapeXNA(shape, pShapeData.Type); } //PhysicsScene.World.ptr, false - public override object CreateCompoundShape2(object pWorld, bool enableDynamicAabbTree) + public override BulletShape CreateCompoundShape(BulletWorld pWorld, bool enableDynamicAabbTree) { - return new CompoundShape(enableDynamicAabbTree); + return new BulletShapeXNA(new CompoundShape(enableDynamicAabbTree), BSPhysicsShapeType.SHAPE_COMPOUND); } - public override int GetNumberOfCompoundChildren2(object pCompoundShape) + public override int GetNumberOfCompoundChildren(BulletShape pCompoundShape) { - var compoundshape = pCompoundShape as CompoundShape; + CompoundShape compoundshape = ((BulletShapeXNA)pCompoundShape).shape as CompoundShape; return compoundshape.GetNumChildShapes(); } //LinksetRoot.PhysShape.ptr, newShape.ptr, displacementPos, displacementRot - public override void AddChildShapeToCompoundShape2(object pCShape, object paddShape, Vector3 displacementPos, Quaternion displacementRot) + public override void AddChildShapeToCompoundShape(BulletShape pCShape, BulletShape paddShape, Vector3 displacementPos, Quaternion displacementRot) { IndexedMatrix relativeTransform = new IndexedMatrix(); - var compoundshape = pCShape as CompoundShape; - var addshape = paddShape as CollisionShape; + CompoundShape compoundshape = ((BulletShapeXNA)pCShape).shape as CompoundShape; + CollisionShape addshape = ((BulletShapeXNA)paddShape).shape; relativeTransform._origin = new IndexedVector3(displacementPos.X, displacementPos.Y, displacementPos.Z); relativeTransform.SetRotation(new IndexedQuaternion(displacementRot.X,displacementRot.Y,displacementRot.Z,displacementRot.W)); @@ -899,58 +1226,47 @@ public sealed class BSAPIXNA : BSAPITemplate } - public override object RemoveChildShapeFromCompoundShapeIndex2(object pCShape, int pii) + public override BulletShape RemoveChildShapeFromCompoundShapeIndex(BulletShape pCShape, int pii) { - var compoundshape = pCShape as CompoundShape; + CompoundShape compoundshape = ((BulletShapeXNA)pCShape).shape as CompoundShape; CollisionShape ret = null; ret = compoundshape.GetChildShape(pii); compoundshape.RemoveChildShapeByIndex(pii); - return ret; + return new BulletShapeXNA(ret, BSPhysicsShapeType.SHAPE_UNKNOWN); } - public override object CreateGroundPlaneShape2(uint pLocalId, float pheight, float pcollisionMargin) + public override BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) { /* TODO */ return null; } + public override void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape) { /* TODO */ } + + public override BulletShape CreateGroundPlaneShape(uint pLocalId, float pheight, float pcollisionMargin) { StaticPlaneShape m_planeshape = new StaticPlaneShape(new IndexedVector3(0,0,1),(int)pheight ); m_planeshape.SetMargin(pcollisionMargin); m_planeshape.SetUserPointer(pLocalId); - return m_planeshape; + return new BulletShapeXNA(m_planeshape, BSPhysicsShapeType.SHAPE_GROUNDPLANE); } - public override object CreateHingeConstraint2(object pWorld, object pBody1, object ppBody2, Vector3 ppivotInA, Vector3 ppivotInB, Vector3 paxisInA, Vector3 paxisInB, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies) + public override BulletConstraint CreateHingeConstraint(BulletWorld pWorld, BulletBody pBody1, BulletBody ppBody2, Vector3 ppivotInA, Vector3 ppivotInB, Vector3 paxisInA, Vector3 paxisInB, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies) { HingeConstraint constrain = null; - var rb1 = pBody1 as RigidBody; - var rb2 = ppBody2 as RigidBody; + DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; + RigidBody rb1 = ((BulletBodyXNA)pBody1).rigidBody; + RigidBody rb2 = ((BulletBodyXNA)ppBody2).rigidBody; if (rb1 != null && rb2 != null) { IndexedVector3 pivotInA = new IndexedVector3(ppivotInA.X, ppivotInA.Y, ppivotInA.Z); IndexedVector3 pivotInB = new IndexedVector3(ppivotInB.X, ppivotInB.Y, ppivotInB.Z); IndexedVector3 axisInA = new IndexedVector3(paxisInA.X, paxisInA.Y, paxisInA.Z); IndexedVector3 axisInB = new IndexedVector3(paxisInB.X, paxisInB.Y, paxisInB.Z); - var world = pWorld as DiscreteDynamicsWorld; world.AddConstraint(constrain, pdisableCollisionsBetweenLinkedBodies); } - return constrain; - } - - public override bool ReleaseHeightMapInfo2(object pMapInfo) - { - if (pMapInfo != null) - { - BulletHeightMapInfo mapinfo = pMapInfo as BulletHeightMapInfo; - if (mapinfo.heightMap != null) - mapinfo.heightMap = null; - - - } - return true; + return new BulletConstraintXNA(constrain); } - public override object CreateHullShape2(object pWorld, int pHullCount, float[] pConvHulls) + public override BulletShape CreateHullShape(BulletWorld pWorld, int pHullCount, float[] pConvHulls) { + DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; CompoundShape compoundshape = new CompoundShape(false); - var world = pWorld as DiscreteDynamicsWorld; - compoundshape.SetMargin(world.WorldSettings.Params.collisionMargin); int ii = 1; @@ -975,12 +1291,13 @@ public sealed class BSAPIXNA : BSAPITemplate compoundshape.AddChildShape(ref childTrans, convexShape); ii += (vertexCount*3 + 4); } - - return compoundshape; + return new BulletShapeXNA(compoundshape, BSPhysicsShapeType.SHAPE_HULL); } - public override object CreateMeshShape2(object pWorld, int pIndicesCount, int[] indices, int pVerticesCount, float[] verticesAsFloats) + public override BulletShape BuildHullShapeFromMesh(BulletWorld world, BulletShape meshShape) { /* TODO */ return null; } + + public override BulletShape CreateMeshShape(BulletWorld pWorld, int pIndicesCount, int[] indices, int pVerticesCount, float[] verticesAsFloats) { //DumpRaw(indices,verticesAsFloats,pIndicesCount,pVerticesCount); @@ -993,7 +1310,7 @@ public sealed class BSAPIXNA : BSAPITemplate ObjectArray indicesarr = new ObjectArray(indices); ObjectArray vertices = new ObjectArray(verticesAsFloats); DumpRaw(indicesarr,vertices,pIndicesCount,pVerticesCount); - var world = pWorld as DiscreteDynamicsWorld; + DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; IndexedMesh mesh = new IndexedMesh(); mesh.m_indexType = PHY_ScalarType.PHY_INTEGER; mesh.m_numTriangles = pIndicesCount/3; @@ -1009,7 +1326,7 @@ public sealed class BSAPIXNA : BSAPITemplate BvhTriangleMeshShape meshShape = new BvhTriangleMeshShape(tribuilder, true,true); meshShape.SetMargin(world.WorldSettings.Params.collisionMargin); // world.UpdateSingleAabb(meshShape); - return meshShape; + return new BulletShapeXNA(meshShape, BSPhysicsShapeType.SHAPE_MESH); } public static void DumpRaw(ObjectArrayindices, ObjectArray vertices, int pIndicesCount,int pVerticesCount ) @@ -1092,52 +1409,31 @@ public sealed class BSAPIXNA : BSAPITemplate sw.Close(); } - //PhysicsScene.World.ptr, m_mapInfo.ID, m_mapInfo.minCoords, m_mapInfo.maxCoords, m_mapInfo.heightMap, PhysicsScene.Params.terrainCollisionMargin - public override object CreateHeightMapInfo2(object pWorld, uint pId, Vector3 pminCoords, Vector3 pmaxCoords, float[] pheightMap, float pCollisionMargin) - { - BulletHeightMapInfo mapInfo = new BulletHeightMapInfo(pId, pheightMap, null); - mapInfo.heightMap = null; - mapInfo.minCoords = pminCoords; - mapInfo.maxCoords = pmaxCoords; - mapInfo.sizeX = (int) (pmaxCoords.X - pminCoords.X); - mapInfo.sizeY = (int) (pmaxCoords.Y - pminCoords.Y); - mapInfo.ID = pId; - mapInfo.minZ = pminCoords.Z; - mapInfo.maxZ = pmaxCoords.Z; - mapInfo.collisionMargin = pCollisionMargin; - if (mapInfo.minZ == mapInfo.maxZ) - mapInfo.minZ -= 0.2f; - mapInfo.heightMap = pheightMap; - - return mapInfo; - - } - public override object CreateTerrainShape2(object pMapInfo) + public override BulletShape CreateTerrainShape(uint id, Vector3 size, float minHeight, float maxHeight, float[] heightMap, + float scaleFactor, float collisionMargin) { - BulletHeightMapInfo mapinfo = pMapInfo as BulletHeightMapInfo; const int upAxis = 2; - const float scaleFactor = 1.0f; - HeightfieldTerrainShape terrainShape = new HeightfieldTerrainShape((int)mapinfo.sizeX, (int)mapinfo.sizeY, - mapinfo.heightMap, scaleFactor, - mapinfo.minZ, mapinfo.maxZ, upAxis, + HeightfieldTerrainShape terrainShape = new HeightfieldTerrainShape((int)size.X, (int)size.Y, + heightMap, scaleFactor, + minHeight, maxHeight, upAxis, false); - terrainShape.SetMargin(mapinfo.collisionMargin + 0.5f); + terrainShape.SetMargin(collisionMargin + 0.5f); terrainShape.SetUseDiamondSubdivision(true); - terrainShape.SetUserPointer(mapinfo.ID); - return terrainShape; + terrainShape.SetUserPointer(id); + return new BulletShapeXNA(terrainShape, BSPhysicsShapeType.SHAPE_TERRAIN); } - public override bool TranslationalLimitMotor2(object pConstraint, float ponOff, float targetVelocity, float maxMotorForce) + public override bool TranslationalLimitMotor(BulletConstraint pConstraint, float ponOff, float targetVelocity, float maxMotorForce) { - TypedConstraint tconstrain = pConstraint as TypedConstraint; + TypedConstraint tconstrain = ((BulletConstraintXNA)pConstraint).constrain; bool onOff = ponOff != 0; bool ret = false; switch (tconstrain.GetConstraintType()) { case TypedConstraintType.D6_CONSTRAINT_TYPE: - Generic6DofConstraint constrain = pConstraint as Generic6DofConstraint; + Generic6DofConstraint constrain = tconstrain as Generic6DofConstraint; constrain.GetTranslationalLimitMotor().m_enableMotor[0] = onOff; constrain.GetTranslationalLimitMotor().m_targetVelocity[0] = targetVelocity; constrain.GetTranslationalLimitMotor().m_maxMotorForce[0] = maxMotorForce; @@ -1150,14 +1446,25 @@ public sealed class BSAPIXNA : BSAPITemplate } - public override int PhysicsStep2(object pWorld, float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount, out List updatedEntities, out int collidersCount, out Listcolliders) + public override int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, + out int updatedEntityCount, out int collidersCount) + { + /* TODO */ + updatedEntityCount = 0; + collidersCount = 0; + return 1; + } + + private int PhysicsStep2(BulletWorld pWorld, float timeStep, int m_maxSubSteps, float m_fixedTimeStep, + out int updatedEntityCount, out List updatedEntities, + out int collidersCount, out Listcolliders) { - int epic = PhysicsStepint2(pWorld, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out updatedEntities, + int epic = PhysicsStepint(pWorld, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out updatedEntities, out collidersCount, out colliders); return epic; } - private static int PhysicsStepint2(object pWorld,float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount, out List updatedEntities, out int collidersCount, out List colliders) + private static int PhysicsStepint(BulletWorld pWorld,float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount, out List updatedEntities, out int collidersCount, out List colliders) { int numSimSteps = 0; @@ -1169,9 +1476,9 @@ public sealed class BSAPIXNA : BSAPITemplate // colliders = new List(); - if (pWorld is DiscreteDynamicsWorld) + if (pWorld is BulletWorldXNA) { - DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; + DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; numSimSteps = world.StepSimulation(timeStep, m_maxSubSteps, m_fixedTimeStep); int updates = 0; @@ -1224,7 +1531,7 @@ public sealed class BSAPIXNA : BSAPITemplate return numSimSteps; } - private static void RecordCollision(CollisionWorld world,CollisionObject objA, CollisionObject objB, IndexedVector3 contact, IndexedVector3 norm) + private static void RecordCollision(CollisionWorld world, CollisionObject objA, CollisionObject objB, IndexedVector3 contact, IndexedVector3 norm) { IndexedVector3 contactNormal = norm; @@ -1257,11 +1564,11 @@ public sealed class BSAPIXNA : BSAPITemplate } - private static EntityProperties GetDebugProperties(object pWorld, object pBody) + private static EntityProperties GetDebugProperties(BulletWorld pWorld, BulletBody pBody) { EntityProperties ent = new EntityProperties(); - DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; - RigidBody body = pBody as RigidBody; + DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; + RigidBody body = ((BulletBodyXNA)pBody).rigidBody; IndexedMatrix transform = body.GetWorldTransform(); IndexedVector3 LinearVelocity = body.GetInterpolationLinearVelocity(); IndexedVector3 AngularVelocity = body.GetInterpolationAngularVelocity(); @@ -1275,34 +1582,35 @@ public sealed class BSAPIXNA : BSAPITemplate return ent; } - public override Vector3 GetLocalScaling2(object pBody) + public override bool UpdateParameter(BulletWorld world, uint localID, String parm, float value) { /* TODO */ return false; } + + public override Vector3 GetLocalScaling(BulletShape pShape) { - CollisionShape shape = pBody as CollisionShape; + CollisionShape shape = ((BulletShapeXNA)pShape).shape; IndexedVector3 scale = shape.GetLocalScaling(); return new Vector3(scale.X,scale.Y,scale.Z); } - public override bool RayCastGround(object pWorld, Vector3 _RayOrigin, float pRayHeight, object NotMe) + public bool RayCastGround(BulletWorld pWorld, Vector3 _RayOrigin, float pRayHeight, BulletBody NotMe) { - DynamicsWorld world = pWorld as DynamicsWorld; + DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; if (world != null) { - if (NotMe is CollisionObject || NotMe is RigidBody) + if (NotMe is BulletBodyXNA && NotMe.HasPhysicalBody) { - CollisionObject AvoidBody = NotMe as CollisionObject; + CollisionObject AvoidBody = ((BulletBodyXNA)NotMe).body; IndexedVector3 rOrigin = new IndexedVector3(_RayOrigin.X, _RayOrigin.Y, _RayOrigin.Z); IndexedVector3 rEnd = new IndexedVector3(_RayOrigin.X, _RayOrigin.Y, _RayOrigin.Z - pRayHeight); using ( - ClosestNotMeRayResultCallback rayCallback = new ClosestNotMeRayResultCallback(rOrigin, - rEnd, AvoidBody) + ClosestNotMeRayResultCallback rayCallback = + new ClosestNotMeRayResultCallback(rOrigin, rEnd, AvoidBody) ) { world.RayTest(ref rOrigin, ref rEnd, rayCallback); if (rayCallback.HasHit()) { IndexedVector3 hitLocation = rayCallback.m_hitPointWorld; - } return rayCallback.HasHit(); } @@ -1311,5 +1619,4 @@ public sealed class BSAPIXNA : BSAPITemplate return false; } } -*/ } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index 2350f59..1735be2 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs @@ -346,10 +346,9 @@ public abstract void RecalculateCompoundShapeLocalAabb(BulletShape cShape); public abstract BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id); - public abstract bool DeleteCollisionShape(BulletWorld world, BulletShape shape); -public abstract int GetBodyType(BulletBody obj); +public abstract CollisionObjectTypes GetBodyType(BulletBody obj); public abstract BulletBody CreateBodyFromShape(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot); @@ -416,6 +415,7 @@ public abstract void SetForceUpdateAllAabbs(BulletWorld world, bool force); // ===================================================================================== // btDynamicsWorld entries +// public abstract bool AddObjectToWorld(BulletWorld world, BulletBody obj, Vector3 pos, Quaternion rot); public abstract bool AddObjectToWorld(BulletWorld world, BulletBody obj); public abstract bool RemoveObjectFromWorld(BulletWorld world, BulletBody obj); @@ -597,7 +597,7 @@ public abstract void SetAngularFactorV(BulletBody obj, Vector3 factor); public abstract Vector3 GetAngularFactor(BulletBody obj); -public abstract bool IsInWorld(BulletBody obj); +public abstract bool IsInWorld(BulletWorld world, BulletBody obj); public abstract void AddConstraintRef(BulletBody obj, BulletConstraint constrain); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index d4e2e87..826261c 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -898,17 +898,6 @@ public sealed class BSPrim : BSPhysObject if (PhysBody.HasPhysicalBody) { PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, PhysBody); - - // TODO: Fix this. Total kludge because adding object to world resets its gravity to default. - // Replace this when the new AddObjectToWorld function is complete. - PhysicsScene.PE.SetGravity(PhysBody, ComputeGravity()); - - // Collision filter can be set only when the object is in the world - if (!PhysBody.ApplyCollisionMask(PhysicsScene)) - { - m_log.ErrorFormat("{0} Failed setting object collision mask: id={1}", LogHeader, LocalID); - DetailLog("{0},BSPrim.UpdatePhysicalParameters,failedSetMaskGroup,cType={1}", LocalID, PhysBody.collisionType); - } } else { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 258b72f..3340cda 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -309,7 +309,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters ret = new BSAPIUnman(engineName, this); break; case "bulletxna": - // ret = new BSAPIXNA(engineName, this); + ret = new BSAPIXNA(engineName, this); break; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 2b652f5..d361f18 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -141,7 +141,7 @@ public sealed class BSShapeCollection : IDisposable if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,body={1}", body.ID, body); PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.ReferenceBody", delegate() { - if (!PhysicsScene.PE.IsInWorld(body)) + if (!PhysicsScene.PE.IsInWorld(PhysicsScene.World, body)) { PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, body); if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", body.ID, body); @@ -166,7 +166,7 @@ public sealed class BSShapeCollection : IDisposable // If the caller needs to know the old body is going away, pass the event up. if (bodyCallback != null) bodyCallback(body); - if (PhysicsScene.PE.IsInWorld(body)) + if (PhysicsScene.PE.IsInWorld(PhysicsScene.World, body)) { PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, body); if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,removingFromWorld. Body={1}", body.ID, body); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs index 114c0aa..e4fecc3 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs @@ -92,8 +92,8 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys private void BuildHeightmapTerrain() { // Create the terrain shape from the mapInfo - m_mapInfo.terrainShape = PhysicsScene.PE.CreateTerrainShape( m_mapInfo.ID, - new Vector3(m_mapInfo.sizeX, m_mapInfo.sizeY, 0), m_mapInfo.minZ, m_mapInfo.maxZ, + m_mapInfo.terrainShape = PhysicsScene.PE.CreateTerrainShape( m_mapInfo.ID, + new Vector3(m_mapInfo.sizeX, m_mapInfo.sizeY, 0), m_mapInfo.minZ, m_mapInfo.maxZ, m_mapInfo.heightMap, 1f, BSParam.TerrainCollisionMargin); -- cgit v1.1 From b14b65ea9518e02e518f2a75795385a3c0306495 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 1 Jan 2013 17:01:17 -0800 Subject: BulletSim: move selection of the unmanaged Bullet DLL from BSPlugin into the unmanaged Bullet interface class. --- OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | 8 ++++++++ OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs | 6 ------ 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs index 83e12ba..8c6e7d6 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs @@ -31,6 +31,8 @@ using System.Runtime.InteropServices; using System.Security; using System.Text; +using OpenSim.Framework; + using OpenMetaverse; namespace OpenSim.Region.Physics.BulletSPlugin @@ -141,8 +143,14 @@ public override string BulletEngineVersion { get; protected set; } public BSAPIUnman(string paramName, BSScene physScene) { PhysicsScene = physScene; + // Do something fancy with the paramName to get the right DLL implementation // like "Bullet-2.80-OpenCL-Intel" loading the version for Intel based OpenCL implementation, etc. + if (Util.IsWindows()) + Util.LoadArchSpecificWindowsDll("BulletSim.dll"); + // If not Windows, loading is performed by the + // Mono loader as specified in + // "bin/Physics/OpenSim.Region.Physics.BulletSPlugin.dll.config". } // Initialization and simulation diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs index 20f5180..65be52a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs @@ -59,12 +59,6 @@ public class BSPlugin : IPhysicsPlugin { if (_mScene == null) { - if (Util.IsWindows()) - Util.LoadArchSpecificWindowsDll("BulletSim.dll"); - // If not Windows, loading is performed by the - // Mono loader as specified in - // "bin/Physics/OpenSim.Region.Physics.BulletSPlugin.dll.config". - _mScene = new BSScene(sceneIdentifier); } return (_mScene); -- cgit v1.1 From aa236b2020a16c464a854be2b02ca49ea637cb27 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 1 Jan 2013 17:25:41 -0800 Subject: BulletSim: add parameter to have Bullet output performance statistics every so many frames. Default to off. --- OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs | 4 ++-- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 8 ++++---- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 4 ++++ 4 files changed, 11 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs index aea10ee..30a7bee 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs @@ -970,7 +970,7 @@ private sealed class BulletConstraintXNA : BulletConstraint p.linkConstraintERP = o[0].XlinkConstraintERP; p.linkConstraintCFM = o[0].XlinkConstraintCFM; p.linkConstraintSolverIterations = o[0].XlinkConstraintSolverIterations; - p.physicsLoggingFrames = o[0].physicsLoggingFrames; + p.physicsLoggingFrames = o[0].XphysicsLoggingFrames; DefaultCollisionConstructionInfo ccci = new DefaultCollisionConstructionInfo(); DefaultCollisionConfiguration cci = new DefaultCollisionConfiguration(); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index 1735be2..8ad78ca 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs @@ -198,7 +198,7 @@ public struct ConfigurationParameters public float XlinkConstraintCFM; public float XlinkConstraintSolverIterations; - public float physicsLoggingFrames; + public float XphysicsLoggingFrames; public const float numericTrue = 1f; public const float numericFalse = 0f; @@ -415,7 +415,7 @@ public abstract void SetForceUpdateAllAabbs(BulletWorld world, bool force); // ===================================================================================== // btDynamicsWorld entries -// public abstract bool AddObjectToWorld(BulletWorld world, BulletBody obj, Vector3 pos, Quaternion rot); +// public abstract bool AddObjectToWorld(BulletWorld world, BulletBody obj, Vector3 pos, Quaternion rot); public abstract bool AddObjectToWorld(BulletWorld world, BulletBody obj); public abstract bool RemoveObjectFromWorld(BulletWorld world, BulletBody obj); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 339722e..69ac8cd 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -492,11 +492,11 @@ public static class BSParam (s) => { return LinkConstraintSolverIterations; }, (s,p,l,v) => { LinkConstraintSolverIterations = v; } ), - new ParameterDefn("LogPhysicsStatisticsFrames", "Frames between outputting detailed phys stats. (0 is off)", + new ParameterDefn("PhysicsMetricFrames", "Frames between outputting detailed phys metrics. (0 is off)", 0f, - (s,cf,p,v) => { s.UnmanagedParams[0].physicsLoggingFrames = cf.GetInt(p, (int)v); }, - (s) => { return (float)s.UnmanagedParams[0].physicsLoggingFrames; }, - (s,p,l,v) => { s.UnmanagedParams[0].physicsLoggingFrames = (int)v; } ), + (s,cf,p,v) => { s.PhysicsMetricDumpFrames = cf.GetFloat(p, (int)v); }, + (s) => { return (float)s.PhysicsMetricDumpFrames; }, + (s,p,l,v) => { s.PhysicsMetricDumpFrames = (int)v; } ), }; // Convert a boolean to our numeric true and false values diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 3340cda..7017194 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -161,6 +161,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters private int m_physicsLoggingFileMinutes; private bool m_physicsLoggingDoFlush; private bool m_physicsPhysicalDumpEnabled; + public float PhysicsMetricDumpFrames { get; set; } // 'true' of the vehicle code is to log lots of details public bool VehicleLoggingEnabled { get; private set; } public bool VehiclePhysicalLoggingEnabled { get; private set; } @@ -526,6 +527,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters collidersCount = 0; } + if ((m_simulationStep % PhysicsMetricDumpFrames) == 0) + PE.DumpPhysicsStatistics(World); + // Get a value for 'now' so all the collision and update routines don't have to get their own. SimulationNowTime = Util.EnvironmentTickCount(); -- cgit v1.1 From 30e5e5cce631d8a3a94b149c6ae1bd1170a17a46 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 2 Jan 2013 19:25:52 +0000 Subject: If an NPC is unowned, then always auto-grant permissions requested via llRequestPermissions() This is consistent with all other OSSL NPC functions that allow unowned avatars to be manipulated. Aims to address http://opensimulator.org/mantis/view.php?id=6483 --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index f9b90c5..d69551f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3463,7 +3463,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api INPCModule npcModule = World.RequestModuleInterface(); if (npcModule != null && npcModule.IsNPC(agentID, World)) { - if (agentID == m_host.ParentGroup.OwnerID || npcModule.GetOwner(agentID) == m_host.ParentGroup.OwnerID) + if (npcModule.CheckPermissions(agentID, m_host.OwnerID)) { lock (m_host.TaskInventory) { -- cgit v1.1 From addab1244ecc586b0a6fc8560b94c871567b78da Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 2 Jan 2013 21:38:00 +0000 Subject: Add "show animations" console command for debug purposes. This shows the current animation sequence and default anims for avatars. --- .../Avatar/Animations/AnimationsCommandModule.cs | 215 +++++++++++++++++++++ .../Avatar/Attachments/AttachmentsCommandModule.cs | 1 + 2 files changed, 216 insertions(+) create mode 100644 OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs new file mode 100644 index 0000000..2d418f1 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs @@ -0,0 +1,215 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Framework.Monitoring; +using OpenSim.Region.ClientStack.LindenUDP; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Scenes.Animation; +using OpenSim.Services.Interfaces; + +namespace OpenSim.Region.OptionalModules.Avatar.Animations +{ + /// + /// A module that just holds commands for inspecting avatar animations. + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AnimationsCommandModule")] + public class AnimationsCommandModule : ISharedRegionModule + { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private List m_scenes = new List(); + + public string Name { get { return "Animations Command Module"; } } + + public Type ReplaceableInterface { get { return null; } } + + public void Initialise(IConfigSource source) + { +// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: INITIALIZED MODULE"); + } + + public void PostInitialise() + { +// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: POST INITIALIZED MODULE"); + } + + public void Close() + { +// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: CLOSED MODULE"); + } + + public void AddRegion(Scene scene) + { +// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); + } + + public void RemoveRegion(Scene scene) + { +// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); + + lock (m_scenes) + m_scenes.Remove(scene); + } + + public void RegionLoaded(Scene scene) + { +// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); + + lock (m_scenes) + m_scenes.Add(scene); + + scene.AddCommand( + "Users", this, "show animations", + "show animations [ ]", + "Show animation information for avatars in this simulator.", + "If no name is supplied then information for all avatars is shown.\n" + + "Please note that for inventory animations, the animation name is the name under which the animation was originally uploaded\n" + + ", which is not necessarily the current inventory name.", + HandleShowAnimationsCommand); + } + + protected void HandleShowAnimationsCommand(string module, string[] cmd) + { + if (cmd.Length != 2 && cmd.Length < 4) + { + MainConsole.Instance.OutputFormat("Usage: show animations [ ]"); + return; + } + + bool targetNameSupplied = false; + string optionalTargetFirstName = null; + string optionalTargetLastName = null; + + if (cmd.Length >= 4) + { + targetNameSupplied = true; + optionalTargetFirstName = cmd[2]; + optionalTargetLastName = cmd[3]; + } + + StringBuilder sb = new StringBuilder(); + + lock (m_scenes) + { + foreach (Scene scene in m_scenes) + { + if (targetNameSupplied) + { + ScenePresence sp = scene.GetScenePresence(optionalTargetFirstName, optionalTargetLastName); + if (sp != null && !sp.IsChildAgent) + GetAttachmentsReport(sp, sb); + } + else + { + scene.ForEachRootScenePresence(sp => GetAttachmentsReport(sp, sb)); + } + } + } + + MainConsole.Instance.Output(sb.ToString()); + } + + private void GetAttachmentsReport(ScenePresence sp, StringBuilder sb) + { + sb.AppendFormat("Animations for {0}\n", sp.Name); + + ConsoleDisplayList cdl = new ConsoleDisplayList(); + ScenePresenceAnimator spa = sp.Animator; + AnimationSet anims = sp.Animator.Animations; + + string cma = spa.CurrentMovementAnimation; + cdl.AddRow( + "Current movement anim", + string.Format("{0}, {1}", DefaultAvatarAnimations.GetDefaultAnimation(cma), cma)); + + UUID defaultAnimId = anims.DefaultAnimation.AnimID; + cdl.AddRow( + "Default anim", + string.Format("{0}, {1}", defaultAnimId, GetAnimName(sp.Scene.AssetService, defaultAnimId))); + + UUID implicitDefaultAnimId = anims.ImplicitDefaultAnimation.AnimID; + cdl.AddRow( + "Implicit default anim", + string.Format("{0}, {1}", implicitDefaultAnimId, GetAnimName(sp.Scene.AssetService, implicitDefaultAnimId))); + + cdl.AddToStringBuilder(sb); + + ConsoleDisplayTable cdt = new ConsoleDisplayTable() { Indent = 2 }; + cdt.AddColumn("Animation ID", 36); + cdt.AddColumn("Name", 20); + cdt.AddColumn("Seq", 3); + cdt.AddColumn("Object ID", 36); + + UUID[] animIds; + int[] sequenceNumbers; + UUID[] objectIds; + + sp.Animator.Animations.GetArrays(out animIds, out sequenceNumbers, out objectIds); + + for (int i = 0; i < animIds.Length; i++) + { + UUID animId = animIds[i]; + string animName = GetAnimName(sp.Scene.AssetService, animId); + int seq = sequenceNumbers[i]; + UUID objectId = objectIds[i]; + + cdt.Rows.Add(new ConsoleDisplayTableRow(animId, animName, seq, objectId)); + } + + cdt.AddToStringBuilder(sb); + sb.Append("\n"); + } + + private string GetAnimName(IAssetService assetService, UUID animId) + { + string animName; + + if (!DefaultAvatarAnimations.AnimsNames.TryGetValue(animId, out animName)) + { + AssetMetadata amd = assetService.GetMetadata(animId.ToString()); + if (amd != null) + animName = amd.Name; + else + animName = "Unknown"; + } + + return animName; + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs index 68bcb4a..d97e3b3 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs @@ -97,6 +97,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments "Users", this, "attachments show", "attachments show [ ]", "Show attachment information for avatars in this simulator.", + "If no name is supplied then information for all avatars is shown.", HandleShowAttachmentsCommand); } -- cgit v1.1 From 70695a6ed96064f0bfd94a6e0c6da935b6e8f908 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Wed, 12 Dec 2012 17:10:08 +0200 Subject: Implemented Return Objects when it's invoked from the Top Colliders or Top Scripts dialogs --- .../CoreModules/World/Land/LandManagementModule.cs | 60 ++++++++++++++++++++-- 1 file changed, 55 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 7149aad..e85b7a2 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -1395,15 +1395,65 @@ namespace OpenSim.Region.CoreModules.World.Land public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) { - ILandObject selectedParcel = null; - lock (m_landList) + if (localID != -1) { - m_landList.TryGetValue(localID, out selectedParcel); + ILandObject selectedParcel = null; + lock (m_landList) + { + m_landList.TryGetValue(localID, out selectedParcel); + } + + if (selectedParcel == null) return; + + selectedParcel.ReturnLandObjects(returnType, agentIDs, taskIDs, remoteClient); } + else + { + if (returnType != 1) + { + m_log.WarnFormat("[LAND MANAGEMENT MODULE] ReturnObjectsInParcel: unknown return type {0}", returnType); + return; + } + + // We get here when the user returns objects from the list of Top Colliders or Top Scripts. + // In that case we receive specific object UUID's, but no parcel ID. - if (selectedParcel == null) return; + Dictionary> returns = new Dictionary>(); - selectedParcel.ReturnLandObjects(returnType, agentIDs, taskIDs, remoteClient); + foreach (UUID groupID in taskIDs) + { + SceneObjectGroup obj = m_scene.GetSceneObjectGroup(groupID); + if (obj != null) + { + if (!returns.ContainsKey(obj.OwnerID)) + returns[obj.OwnerID] = new HashSet(); + returns[obj.OwnerID].Add(obj); + } + else + { + m_log.WarnFormat("[LAND MANAGEMENT MODULE] ReturnObjectsInParcel: unknown object {0}", groupID); + } + } + + int num = 0; + foreach (HashSet objs in returns.Values) + num += objs.Count; + m_log.DebugFormat("[LAND MANAGEMENT MODULE] Returning {0} specific object(s)", num); + + foreach (HashSet objs in returns.Values) + { + List objs2 = new List(objs); + if (m_scene.Permissions.CanReturnObjects(null, remoteClient.AgentId, objs2)) + { + m_scene.returnObjects(objs2.ToArray(), remoteClient.AgentId); + } + else + { + m_log.WarnFormat("[LAND MANAGEMENT MODULE] ReturnObjectsInParcel: not permitted to return {0} object(s) belonging to user {1}", + objs2.Count, objs2[0].OwnerID); + } + } + } } public void EventManagerOnNoLandDataFromStorage() -- cgit v1.1 From 6b55f5183787fb719c7bd4547e5894096a7aed51 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 2 Jan 2013 22:11:13 +0000 Subject: minor: Allow objects to be added directly to a row on a ConsoleDisplayTable rather than having to ToString() them first --- .../Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs index 2d418f1..ffef912 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs @@ -189,7 +189,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Animations int seq = sequenceNumbers[i]; UUID objectId = objectIds[i]; - cdt.Rows.Add(new ConsoleDisplayTableRow(animId, animName, seq, objectId)); + cdt.AddRow(animId, animName, seq, objectId); } cdt.AddToStringBuilder(sb); -- cgit v1.1 From d2f4ca0dfed69637892c2346fa87c88f08c9b8e5 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Thu, 23 Aug 2012 21:23:16 +0300 Subject: If Save OAR/IAR times-out while waiting for assets then notify the caller that the operation failed --- .../Archiver/InventoryArchiveWriteRequest.cs | 10 ++++++-- .../World/Archiver/ArchiveWriteRequest.cs | 28 +++++++++++++++------- .../CoreModules/World/Archiver/AssetsArchiver.cs | 7 ------ .../CoreModules/World/Archiver/AssetsRequest.cs | 18 +++++++------- 4 files changed, 37 insertions(+), 26 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index d0e88f6..4c85637 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs @@ -124,7 +124,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver SaveAssets = true; } - protected void ReceivedAllAssets(ICollection assetsFoundUuids, ICollection assetsNotFoundUuids) + protected void ReceivedAllAssets(ICollection assetsFoundUuids, ICollection assetsNotFoundUuids, bool timedOut) { Exception reportedException = null; bool succeeded = true; @@ -143,6 +143,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver m_saveStream.Close(); } + if (timedOut) + { + succeeded = false; + reportedException = new Exception("Loading assets timed out"); + } + m_module.TriggerInventoryArchiveSaved( m_id, succeeded, m_userInfo, m_invPath, m_saveStream, reportedException); } @@ -350,7 +356,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver { m_log.DebugFormat("[INVENTORY ARCHIVER]: Not saving assets since --noassets was specified"); - ReceivedAllAssets(new List(), new List()); + ReceivedAllAssets(new List(), new List(), false); } } catch (Exception) diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs index 7bdd65c..367693d 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs @@ -587,19 +587,29 @@ namespace OpenSim.Region.CoreModules.World.Archiver } } - protected void ReceivedAllAssets( - ICollection assetsFoundUuids, ICollection assetsNotFoundUuids) + protected void ReceivedAllAssets(ICollection assetsFoundUuids, ICollection assetsNotFoundUuids, bool timedOut) { - foreach (UUID uuid in assetsNotFoundUuids) + string errorMessage; + + if (timedOut) { - m_log.DebugFormat("[ARCHIVER]: Could not find asset {0}", uuid); + errorMessage = "Loading assets timed out"; } + else + { + foreach (UUID uuid in assetsNotFoundUuids) + { + m_log.DebugFormat("[ARCHIVER]: Could not find asset {0}", uuid); + } - // m_log.InfoFormat( - // "[ARCHIVER]: Received {0} of {1} assets requested", - // assetsFoundUuids.Count, assetsFoundUuids.Count + assetsNotFoundUuids.Count); + // m_log.InfoFormat( + // "[ARCHIVER]: Received {0} of {1} assets requested", + // assetsFoundUuids.Count, assetsFoundUuids.Count + assetsNotFoundUuids.Count); - CloseArchive(String.Empty); + errorMessage = String.Empty; + } + + CloseArchive(errorMessage); } /// @@ -626,4 +636,4 @@ namespace OpenSim.Region.CoreModules.World.Archiver m_rootScene.EventManager.TriggerOarFileSaved(m_requestId, errorMessage); } } -} \ No newline at end of file +} diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs index 95d109c..c1ff94d 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs @@ -150,12 +150,5 @@ namespace OpenSim.Region.CoreModules.World.Archiver m_log.InfoFormat("[ARCHIVER]: Added {0} assets to archive", m_assetsWritten); } - /// - /// Only call this if you need to force a close on the underlying writer. - /// - public void ForceClose() - { - m_archiveWriter.Close(); - } } } diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs index 103eb47..b22bcf9 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs @@ -50,7 +50,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver /// Method called when all the necessary assets for an archive request have been received. /// public delegate void AssetsRequestCallback( - ICollection assetsFoundUuids, ICollection assetsNotFoundUuids); + ICollection assetsFoundUuids, ICollection assetsNotFoundUuids, bool timedOut); enum RequestState { @@ -148,7 +148,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver if (m_repliesRequired == 0) { m_requestState = RequestState.Completed; - PerformAssetsRequestCallback(null); + PerformAssetsRequestCallback(false); return; } @@ -164,7 +164,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver protected void OnRequestCallbackTimeout(object source, ElapsedEventArgs args) { - bool close = true; + bool timedOut = true; try { @@ -174,7 +174,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver // the final request came in (assuming that such a thing is possible) if (m_requestState == RequestState.Completed) { - close = false; + timedOut = false; return; } @@ -223,8 +223,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver } finally { - if (close) - m_assetsArchiver.ForceClose(); + if (timedOut) + Util.FireAndForget(PerformAssetsRequestCallback, true); } } @@ -294,7 +294,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver // We want to stop using the asset cache thread asap // as we now need to do the work of producing the rest of the archive - Util.FireAndForget(PerformAssetsRequestCallback); + Util.FireAndForget(PerformAssetsRequestCallback, false); } else { @@ -315,9 +315,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver { Culture.SetCurrentCulture(); + Boolean timedOut = (Boolean)o; + try { - m_assetsRequestCallback(m_foundAssetUuids, m_notFoundAssetUuids); + m_assetsRequestCallback(m_foundAssetUuids, m_notFoundAssetUuids, timedOut); } catch (Exception e) { -- cgit v1.1 From 9784e4e07db63a23897876dfbd27974878d5eca9 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Thu, 9 Aug 2012 14:51:05 +0300 Subject: Changed locks to prevent deadlocks (especially during multi-region Load OAR) --- .../World/Archiver/ArchiveReadRequest.cs | 42 ++++++++++++------- .../CoreModules/World/Land/LandManagementModule.cs | 47 +++++++++++++--------- .../CoreModules/World/Land/PrimCountModule.cs | 11 +++-- 3 files changed, 61 insertions(+), 39 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index c810242..32d245f 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs @@ -604,13 +604,18 @@ namespace OpenSim.Region.CoreModules.World.Archiver /// private bool ResolveUserUuid(Scene scene, UUID uuid) { - if (!m_validUserUuids.ContainsKey(uuid)) + lock (m_validUserUuids) { - UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, uuid); - m_validUserUuids.Add(uuid, account != null); - } + if (!m_validUserUuids.ContainsKey(uuid)) + { + // Note: we call GetUserAccount() inside the lock because this UserID is likely + // to occur many times, and we only want to query the users service once. + UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, uuid); + m_validUserUuids.Add(uuid, account != null); + } - return m_validUserUuids[uuid]; + return m_validUserUuids[uuid]; + } } /// @@ -623,19 +628,26 @@ namespace OpenSim.Region.CoreModules.World.Archiver if (uuid == UUID.Zero) return true; // this means the object has no group - if (!m_validGroupUuids.ContainsKey(uuid)) + lock (m_validGroupUuids) { - bool exists; - - if (m_groupsModule == null) - exists = false; - else - exists = (m_groupsModule.GetGroupRecord(uuid) != null); + if (!m_validGroupUuids.ContainsKey(uuid)) + { + bool exists; + if (m_groupsModule == null) + { + exists = false; + } + else + { + // Note: we call GetGroupRecord() inside the lock because this GroupID is likely + // to occur many times, and we only want to query the groups service once. + exists = (m_groupsModule.GetGroupRecord(uuid) != null); + } + m_validGroupUuids.Add(uuid, exists); + } - m_validGroupUuids.Add(uuid, exists); + return m_validGroupUuids[uuid]; } - - return m_validGroupUuids[uuid]; } /// Load an asset diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index e85b7a2..4b1e6b9 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -287,14 +287,15 @@ namespace OpenSim.Region.CoreModules.World.Land LandData newData = data.Copy(); newData.LocalID = local_id; + ILandObject land; lock (m_landList) { - if (m_landList.ContainsKey(local_id)) - { - m_landList[local_id].LandData = newData; - m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, m_landList[local_id]); - } + if (m_landList.TryGetValue(local_id, out land)) + land.LandData = newData; } + + if (land != null) + m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, land); } public bool AllowedForcefulBans @@ -613,7 +614,7 @@ namespace OpenSim.Region.CoreModules.World.Land // Only now can we add the prim counts to the land object - we rely on the global ID which is generated // as a random UUID inside LandData initialization if (m_primCountModule != null) - new_land.PrimCounts = m_primCountModule.GetPrimCounts(new_land.LandData.GlobalID); + new_land.PrimCounts = m_primCountModule.GetPrimCounts(new_land.LandData.GlobalID); lock (m_landList) { @@ -650,6 +651,7 @@ namespace OpenSim.Region.CoreModules.World.Land /// Land.localID of the peice of land to remove. public void removeLandObject(int local_id) { + ILandObject land; lock (m_landList) { for (int x = 0; x < 64; x++) @@ -666,9 +668,11 @@ namespace OpenSim.Region.CoreModules.World.Land } } - m_scene.EventManager.TriggerLandObjectRemoved(m_landList[local_id].LandData.GlobalID); + land = m_landList[local_id]; m_landList.Remove(local_id); } + + m_scene.EventManager.TriggerLandObjectRemoved(land.LandData.GlobalID); } /// @@ -676,21 +680,27 @@ namespace OpenSim.Region.CoreModules.World.Land /// public void Clear(bool setupDefaultParcel) { + List parcels; lock (m_landList) { - foreach (ILandObject lo in m_landList.Values) - { - //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID); - m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID); - } + parcels = new List(m_landList.Values); + } + + foreach (ILandObject lo in parcels) + { + //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID); + m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID); + } + lock (m_landList) + { m_landList.Clear(); ResetSimLandObjects(); - - if (setupDefaultParcel) - CreateDefaultParcel(); } + + if (setupDefaultParcel) + CreateDefaultParcel(); } private void performFinalLandJoin(ILandObject master, ILandObject slave) @@ -1458,11 +1468,8 @@ namespace OpenSim.Region.CoreModules.World.Land public void EventManagerOnNoLandDataFromStorage() { - lock (m_landList) - { - ResetSimLandObjects(); - CreateDefaultParcel(); - } + ResetSimLandObjects(); + CreateDefaultParcel(); } #endregion diff --git a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs index f9cc0cf..9b51cc8 100644 --- a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs @@ -490,11 +490,14 @@ namespace OpenSim.Region.CoreModules.World.Land m_Scene.ForEachSOG(AddObject); - List primcountKeys = new List(m_PrimCounts.Keys); - foreach (UUID k in primcountKeys) + lock (m_PrimCounts) { - if (!m_OwnerMap.ContainsKey(k)) - m_PrimCounts.Remove(k); + List primcountKeys = new List(m_PrimCounts.Keys); + foreach (UUID k in primcountKeys) + { + if (!m_OwnerMap.ContainsKey(k)) + m_PrimCounts.Remove(k); + } } m_Tainted = false; -- cgit v1.1 From 2db1f22b8930a4350f06b11f76fceb359c31d54d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 2 Jan 2013 22:31:18 +0000 Subject: minor: minor code and log formatting fixes to recent changes in LandManagementModule --- OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 4b1e6b9..6e0c007 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -1413,7 +1413,8 @@ namespace OpenSim.Region.CoreModules.World.Land m_landList.TryGetValue(localID, out selectedParcel); } - if (selectedParcel == null) return; + if (selectedParcel == null) + return; selectedParcel.ReturnLandObjects(returnType, agentIDs, taskIDs, remoteClient); } @@ -1421,7 +1422,7 @@ namespace OpenSim.Region.CoreModules.World.Land { if (returnType != 1) { - m_log.WarnFormat("[LAND MANAGEMENT MODULE] ReturnObjectsInParcel: unknown return type {0}", returnType); + m_log.WarnFormat("[LAND MANAGEMENT MODULE]: ReturnObjectsInParcel: unknown return type {0}", returnType); return; } @@ -1441,14 +1442,14 @@ namespace OpenSim.Region.CoreModules.World.Land } else { - m_log.WarnFormat("[LAND MANAGEMENT MODULE] ReturnObjectsInParcel: unknown object {0}", groupID); + m_log.WarnFormat("[LAND MANAGEMENT MODULE]: ReturnObjectsInParcel: unknown object {0}", groupID); } } int num = 0; foreach (HashSet objs in returns.Values) num += objs.Count; - m_log.DebugFormat("[LAND MANAGEMENT MODULE] Returning {0} specific object(s)", num); + m_log.DebugFormat("[LAND MANAGEMENT MODULE]: Returning {0} specific object(s)", num); foreach (HashSet objs in returns.Values) { @@ -1459,7 +1460,7 @@ namespace OpenSim.Region.CoreModules.World.Land } else { - m_log.WarnFormat("[LAND MANAGEMENT MODULE] ReturnObjectsInParcel: not permitted to return {0} object(s) belonging to user {1}", + m_log.WarnFormat("[LAND MANAGEMENT MODULE]: ReturnObjectsInParcel: not permitted to return {0} object(s) belonging to user {1}", objs2.Count, objs2[0].OwnerID); } } -- cgit v1.1 From 8f31649faddfc2f7a28131f592b1e79ae75b863f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 2 Jan 2013 22:37:50 +0000 Subject: Fix indenting on ConsoleDisplayTable, align indenting on "show animations" console command --- .../Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs index ffef912..e951d9e 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs @@ -149,7 +149,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Animations { sb.AppendFormat("Animations for {0}\n", sp.Name); - ConsoleDisplayList cdl = new ConsoleDisplayList(); + ConsoleDisplayList cdl = new ConsoleDisplayList() { Indent = 2 }; ScenePresenceAnimator spa = sp.Animator; AnimationSet anims = sp.Animator.Animations; -- cgit v1.1 From 24e486e9dfd5838b1ce1085586f84998aec3aae3 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Tue, 25 Dec 2012 10:50:03 +0200 Subject: Fixed: the AvatarEnteringNewParcel event wasn't triggered in some cases If an avatar moved between regions: A -> B -> A, then when returning to region A the AvatarEnteringNewParcel wasn't triggered. This happened because the ScenePresence in region A still remembered its previous 'currentParcelUUID', so it appeared as if the avatar didn't change parcels. Now, however, when a ScenePresence becomes a child presence we clear its 'currentParcelUUID'. --- OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 6e0c007..dbf5138 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -133,6 +133,7 @@ namespace OpenSim.Region.CoreModules.World.Land m_scene.EventManager.OnValidateLandBuy += EventManagerOnValidateLandBuy; m_scene.EventManager.OnLandBuy += EventManagerOnLandBuy; m_scene.EventManager.OnNewClient += EventManagerOnNewClient; + m_scene.EventManager.OnMakeChildAgent += EventMakeChildAgent; m_scene.EventManager.OnSignificantClientMovement += EventManagerOnSignificantClientMovement; m_scene.EventManager.OnNoticeNoLandDataFromStorage += EventManagerOnNoLandDataFromStorage; m_scene.EventManager.OnIncomingLandDataFromStorage += EventManagerOnIncomingLandDataFromStorage; @@ -218,6 +219,11 @@ namespace OpenSim.Region.CoreModules.World.Land } } + public void EventMakeChildAgent(ScenePresence avatar) + { + avatar.currentParcelUUID = UUID.Zero; + } + void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) { //If we are forcing a position for them to go -- cgit v1.1 From 1a6694b26487e4b9bd33e1c6c4415fb7d36f0d1d Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Tue, 25 Dec 2012 10:47:45 +0200 Subject: Fixed several problems with the Sun: some settings didn't work, or were inconsistently used. - The sun position is always calculated by combining the sun settings in the Region and Estate. This fixes the problem that 'UseEstateSun' didn't work. - To remove ambiguity, the EstateToolsSunUpdate event no longer accepts the sun's position as parameters. That's because the position is always calculated from the Region and Estate settings. - Use only the 'FixedSun' flag to determine whether the sun is fixed; not the 'UseGlobalTime' flag. - Don't change the region's 'SunPosition' field according to the sun's position: this field is used only to set the position when using a FixedSun. (The 'SunVector' field does get updated according to the sun's position in the sky) --- .../World/Estate/EstateManagementModule.cs | 3 +- OpenSim/Region/CoreModules/World/Sun/SunModule.cs | 44 ++++++++++++---------- OpenSim/Region/Framework/Scenes/EventManager.cs | 13 +++---- OpenSim/Region/Framework/Scenes/Scene.cs | 28 +------------- .../Shared/Api/Implementation/OSSL_Api.cs | 10 ++--- 5 files changed, 37 insertions(+), 61 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index eb06fcc..d05abc5 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -118,7 +118,7 @@ namespace OpenSim.Region.CoreModules.World.Estate { uint sun = 0; - if (!Scene.RegionInfo.EstateSettings.UseGlobalTime) + if (Scene.RegionInfo.EstateSettings.FixedSun) sun = (uint)(Scene.RegionInfo.EstateSettings.SunPosition * 1024.0) + 0x1800; UUID estateOwner; estateOwner = Scene.RegionInfo.EstateSettings.EstateOwner; @@ -1091,6 +1091,7 @@ namespace OpenSim.Region.CoreModules.World.Estate { Scene.RegionInfo.EstateSettings.UseGlobalTime = false; Scene.RegionInfo.EstateSettings.SunPosition = (parms2 - 0x1800)/1024.0; + // Warning: FixedSun should be set to True, otherwise this sun position won't be used. } if ((parms1 & 0x00000010) != 0) diff --git a/OpenSim/Region/CoreModules/World/Sun/SunModule.cs b/OpenSim/Region/CoreModules/World/Sun/SunModule.cs index a321c09..6f344c8 100644 --- a/OpenSim/Region/CoreModules/World/Sun/SunModule.cs +++ b/OpenSim/Region/CoreModules/World/Sun/SunModule.cs @@ -252,12 +252,11 @@ namespace OpenSim.Region.CoreModules } // TODO: Decouple this, so we can get rid of Linden Hour info - // Update Region infor with new Sun Position and Hour + // Update Region with new Sun Vector // set estate settings for region access to sun position if (receivedEstateToolsSunUpdate) { m_scene.RegionInfo.RegionSettings.SunVector = Position; - m_scene.RegionInfo.RegionSettings.SunPosition = GetCurrentTimeAsLindenSunHour(); } } @@ -395,7 +394,7 @@ namespace OpenSim.Region.CoreModules ready = false; // Remove our hooks - m_scene.EventManager.OnFrame -= SunUpdate; + m_scene.EventManager.OnFrame -= SunUpdate; m_scene.EventManager.OnAvatarEnteringNewParcel -= AvatarEnteringParcel; m_scene.EventManager.OnEstateToolsSunUpdate -= EstateToolsSunUpdate; m_scene.EventManager.OnGetCurrentTimeAsLindenSunHour -= GetCurrentTimeAsLindenSunHour; @@ -459,26 +458,33 @@ namespace OpenSim.Region.CoreModules SunToClient(avatar.ControllingClient); } - /// - /// - /// - /// - /// Is the sun's position fixed? - /// Use the Region or Estate Sun hour? - /// What hour of the day is the Sun Fixed at? - public void EstateToolsSunUpdate(ulong regionHandle, bool FixedSun, bool useEstateTime, float FixedSunHour) + public void EstateToolsSunUpdate(ulong regionHandle) { if (m_scene.RegionInfo.RegionHandle == regionHandle) { - // Must limit the Sun Hour to 0 ... 24 - while (FixedSunHour > 24.0f) - FixedSunHour -= 24; + float sunFixedHour; + bool fixedSun; - while (FixedSunHour < 0) - FixedSunHour += 24; + if (m_scene.RegionInfo.RegionSettings.UseEstateSun) + { + sunFixedHour = (float)m_scene.RegionInfo.EstateSettings.SunPosition; + fixedSun = m_scene.RegionInfo.EstateSettings.FixedSun; + } + else + { + sunFixedHour = (float)m_scene.RegionInfo.RegionSettings.SunPosition - 6.0f; + fixedSun = m_scene.RegionInfo.RegionSettings.FixedSun; + } + + // Must limit the Sun Hour to 0 ... 24 + while (sunFixedHour > 24.0f) + sunFixedHour -= 24; - m_SunFixedHour = FixedSunHour; - m_SunFixed = FixedSun; + while (sunFixedHour < 0) + sunFixedHour += 24; + + m_SunFixedHour = sunFixedHour; + m_SunFixed = fixedSun; // m_log.DebugFormat("[SUN]: Sun Settings Update: Fixed Sun? : {0}", m_SunFixed.ToString()); // m_log.DebugFormat("[SUN]: Sun Settings Update: Sun Hour : {0}", m_SunFixedHour.ToString()); @@ -501,7 +507,7 @@ namespace OpenSim.Region.CoreModules { m_scene.ForEachRootClient(delegate(IClientAPI client) { - SunToClient(client); + SunToClient(client); }); } diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 4c49b71..6b08e0f 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -751,7 +751,7 @@ namespace OpenSim.Region.Framework.Scenes public event ScriptTimerEvent OnScriptTimerEvent; */ - public delegate void EstateToolsSunUpdate(ulong regionHandle, bool FixedTime, bool EstateSun, float LindenHour); + public delegate void EstateToolsSunUpdate(ulong regionHandle); public delegate void GetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID); public event EstateToolsSunUpdate OnEstateToolsSunUpdate; @@ -2507,13 +2507,10 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Updates the system as to how the position of the sun should be handled. + /// Called when the sun's position parameters have changed in the Region and/or Estate /// - /// - /// True if the Sun Position is fixed - /// True if the Estate Settings should be used instead of region - /// The hour 0.0 <= FixedSunHour <= 24.0 at which the sun is fixed at. Sun Hour 0 is sun-rise, when Day/Night ratio is 1:1 - public void TriggerEstateToolsSunUpdate(ulong regionHandle, bool FixedTime, bool useEstateTime, float FixedSunHour) + /// The region that changed + public void TriggerEstateToolsSunUpdate(ulong regionHandle) { EstateToolsSunUpdate handlerEstateToolsSunUpdate = OnEstateToolsSunUpdate; if (handlerEstateToolsSunUpdate != null) @@ -2522,7 +2519,7 @@ namespace OpenSim.Region.Framework.Scenes { try { - d(regionHandle, FixedTime, useEstateTime, FixedSunHour); + d(regionHandle); } catch (Exception e) { diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index cca295c..11b63b7 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -5345,33 +5345,7 @@ namespace OpenSim.Region.Framework.Scenes public void TriggerEstateSunUpdate() { - float sun; - if (RegionInfo.RegionSettings.UseEstateSun) - { - sun = (float)RegionInfo.EstateSettings.SunPosition; - if (RegionInfo.EstateSettings.UseGlobalTime) - { - sun = EventManager.GetCurrentTimeAsSunLindenHour() - 6.0f; - } - - // - EventManager.TriggerEstateToolsSunUpdate( - RegionInfo.RegionHandle, - RegionInfo.EstateSettings.FixedSun, - RegionInfo.RegionSettings.UseEstateSun, - sun); - } - else - { - // Use the Sun Position from the Region Settings - sun = (float)RegionInfo.RegionSettings.SunPosition - 6.0f; - - EventManager.TriggerEstateToolsSunUpdate( - RegionInfo.RegionHandle, - RegionInfo.RegionSettings.FixedSun, - RegionInfo.RegionSettings.UseEstateSun, - sun); - } + EventManager.TriggerEstateToolsSunUpdate(RegionInfo.RegionHandle); } private void HandleReloadEstate(string module, string[] cmd) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 828288d..33c02ef 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -1205,12 +1205,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api sunHour += 24.0; World.RegionInfo.RegionSettings.UseEstateSun = useEstateSun; - World.RegionInfo.RegionSettings.SunPosition = sunHour + 6; // LL Region Sun Hour is 6 to 30 - World.RegionInfo.RegionSettings.FixedSun = sunFixed; + World.RegionInfo.RegionSettings.SunPosition = sunHour + 6; // LL Region Sun Hour is 6 to 30 + World.RegionInfo.RegionSettings.FixedSun = sunFixed; World.RegionInfo.RegionSettings.Save(); - World.EventManager.TriggerEstateToolsSunUpdate( - World.RegionInfo.RegionHandle, sunFixed, useEstateSun, (float)sunHour); + World.EventManager.TriggerEstateToolsSunUpdate(World.RegionInfo.RegionHandle); } /// @@ -1235,8 +1234,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api World.RegionInfo.EstateSettings.FixedSun = sunFixed; World.RegionInfo.EstateSettings.Save(); - World.EventManager.TriggerEstateToolsSunUpdate( - World.RegionInfo.RegionHandle, sunFixed, World.RegionInfo.RegionSettings.UseEstateSun, (float)sunHour); + World.EventManager.TriggerEstateToolsSunUpdate(World.RegionInfo.RegionHandle); } /// -- cgit v1.1 From 589e3e868689c70dccd906ee9f17fad5e11dd4a9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 3 Jan 2013 00:03:29 +0000 Subject: minor: Change channel digger replacement message in TerrainModule to Info from Warn. This is to stop this unnecessarily triggering log analysis code which reports warn and error level statements. --- OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index 52b4313..fd30c46 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs @@ -480,7 +480,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain else { m_plugineffects[pluginName] = effect; - m_log.Warn("E ... " + pluginName + " (Replaced)"); + m_log.Info("E ... " + pluginName + " (Replaced)"); } } } -- cgit v1.1 From 79b7c571ffa5cd7b40272dc56642d43f688202f6 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Mon, 29 Oct 2012 11:27:05 +0000 Subject: updating documentation in SampleMoneyModule based on doxygen error log output; changing an xml-style hint to a uri-style hint in the class summary, improving documentation of Initialise method and removing a superfluous parameter, improving documentating of ClientClosed method and documenting an omitted parameter --- .../OptionalModules/World/MoneyModule/SampleMoneyModule.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs index 8f04ede..7bbf500 100644 --- a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs +++ b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs @@ -49,7 +49,7 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule /// (such as land transfers). There is no money code here! Use FORGE as an example for money code. /// Demo Economy/Money Module. This is a purposely crippled module! /// // To land transfer you need to add: - /// -helperuri
+ /// -helperuri http://serveraddress:port/ /// to the command line parameters you use to start up your client /// This commonly looks like -helperuri http://127.0.0.1:9000/ /// @@ -116,10 +116,9 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule } /// - /// Startup + /// Called on startup so the module can be configured. /// - /// - /// + /// Configuration source. public void Initialise(IConfigSource config) { m_gConfig = config; @@ -674,9 +673,12 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule } /// - /// When the client closes the connection we remove their accounting info from memory to free up resources. + /// When the client closes the connection we remove their accounting + /// info from memory to free up resources. /// - /// + /// UUID of agent + /// Scene the agent was connected to. + /// public void ClientClosed(UUID AgentID, Scene scene) { -- cgit v1.1 From a5ac6af16a0b6816fb4edb53f25085b85c21e40f Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Mon, 29 Oct 2012 11:45:47 +0000 Subject: Improving documentation of AttachToAvatar and GetLine methods in LSL_Api.cs based on doxygen error output --- .../Shared/Api/Implementation/LSL_Api.cs | 23 ++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index d69551f..75749a9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3007,7 +3007,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// /// Attach the object containing this script to the avatar that owns it. /// - /// The attachment point (e.g. ATTACH_CHEST) + /// + /// The attachment point (e.g. ATTACH_CHEST) + /// /// true if the attach suceeded, false if it did not public bool AttachToAvatar(int attachmentPoint) { @@ -5418,9 +5420,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } /// - /// Insert the list identified by into the - /// list designated by such that the first - /// new element has the index specified by + /// Insert the list identified by into the + /// list designated by such that the first + /// new element has the index specified by /// public LSL_List llListInsertList(LSL_List dest, LSL_List src, int index) @@ -11520,7 +11522,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// Get a notecard line. ///
/// - /// Lines start at index 0 + /// Lines start at index 0 /// public static string GetLine(UUID assetID, int lineNumber) { @@ -11549,9 +11551,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// Get a notecard line. ///
/// - /// Lines start at index 0 - /// Maximum length of the returned line. Longer lines will be truncated - /// + /// Lines start at index 0 + /// + /// Maximum length of the returned line. + /// + /// + /// If the line length is longer than , + /// the return string will be truncated. + /// public static string GetLine(UUID assetID, int lineNumber, int maxLength) { string line = GetLine(assetID, lineNumber); -- cgit v1.1 From aa78df4a79e4e357f8424a0163525c3254b2c146 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Fri, 26 Oct 2012 11:22:00 +0100 Subject: Scipt modules get the OpenMetaverse types, so lists passed as arguments to script module functions which then later call LSL_Types.list.GetVector3Item() or LSL_Types.list.GetQuaternionItem() methods would then trigger an InvalidCastException, which is now avoided. --- OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs | 29 +++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs index fcb98a5..44fdd1a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs +++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs @@ -631,19 +631,44 @@ namespace OpenSim.Region.ScriptEngine.Shared public LSL_Types.Vector3 GetVector3Item(int itemIndex) { - if(m_data[itemIndex] is LSL_Types.Vector3) + if (m_data[itemIndex] is LSL_Types.Vector3) + { return (LSL_Types.Vector3)m_data[itemIndex]; + } + else if(m_data[itemIndex] is OpenMetaverse.Vector3) + { + return new LSL_Types.Vector3( + (OpenMetaverse.Vector3)m_data[itemIndex]); + } else + { throw new InvalidCastException(string.Format( "{0} expected but {1} given", typeof(LSL_Types.Vector3).Name, m_data[itemIndex] != null ? m_data[itemIndex].GetType().Name : "null")); + } } public LSL_Types.Quaternion GetQuaternionItem(int itemIndex) { - return (LSL_Types.Quaternion)m_data[itemIndex]; + if (m_data[itemIndex] is LSL_Types.Quaternion) + { + return (LSL_Types.Quaternion)m_data[itemIndex]; + } + else if(m_data[itemIndex] is OpenMetaverse.Quaternion) + { + return new LSL_Types.Quaternion( + (OpenMetaverse.Quaternion)m_data[itemIndex]); + } + else + { + throw new InvalidCastException(string.Format( + "{0} expected but {1} given", + typeof(LSL_Types.Quaternion).Name, + m_data[itemIndex] != null ? + m_data[itemIndex].GetType().Name : "null")); + } } public LSL_Types.key GetKeyItem(int itemIndex) -- cgit v1.1 From 7f195de3032e909771a3c066d194f073ee0876d6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 3 Jan 2013 20:57:14 +0000 Subject: Fix problem where object attached from ground often does not get attached properly. It seems this is happening because we send a kill for objects that are selected when attached. A code comment says that this is to get the client to deselect it, but v3 and v1 clients do this just fine without the kill. Aims to address http://opensimulator.org/mantis/view.php?id=6456 --- .../Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 24170fc..da59472 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -654,15 +654,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (!silent) { - // Killing it here will cause the client to deselect it - // It then reappears on the avatar, deselected - // through the full update below - // - if (so.IsSelected) - { - m_scene.SendKillObject(new List { so.RootPart.LocalId }); - } - else if (so.HasPrivateAttachmentPoint) + if (so.HasPrivateAttachmentPoint) { // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: Killing private HUD {0} for avatars other than {1} at attachment point {2}", -- cgit v1.1 From a75f24bb7967e45618f03691e6b9837ef6bcdf27 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 3 Jan 2013 21:06:50 +0000 Subject: minor: Add some doc to the extremely unhelpful 'fudge....' comment as to why we're deselecting the prim in code before scheduling an update on attachment --- OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index da59472..58ed554 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -669,7 +669,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments }); } - so.IsSelected = false; // fudge.... + // Fudge below is an extremely unhelpful comment. It's probably here so that the scheduled full update + // will succeed, as that will not update if an attachment is selected. + so.IsSelected = false; // fudge.... + so.ScheduleGroupForFullUpdate(); } -- cgit v1.1 From 9503383887d6af871e843cbcbb141a50df56f551 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 4 Jan 2013 20:34:39 +0000 Subject: Fix llGetLinkKey() to return the last sat avatar as the last link number. As per http://wiki.secondlife.com/wiki/LlGetLinkKey This is done by keeping a scene-object wide list of sitters. This also fixes bugs in this function where linknums 0 and 1 weren't treated properly if there were sitting avatars on a single prim. This also fixes a minor race condition for multiple concurrent sitters on a prim with no current sitters by locking on the object-wide list rather than individual sop lists Addresses http://opensimulator.org/mantis/view.php?id=6477 --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 35 ++++++++-- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 79 +++++++++++----------- .../Shared/Api/Implementation/LSL_Api.cs | 48 ++++++++----- 3 files changed, 99 insertions(+), 63 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 35e7c45..15795e5 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -647,6 +647,18 @@ namespace OpenSim.Region.Framework.Scenes /// public UUID FromFolderID { get; set; } + /// + /// IDs of all avatars sat on this scene object. + /// + /// + /// We need this so that we can maintain a linkset wide ordering of avatars sat on different parts. + /// This must be locked before it is read or written. + /// SceneObjectPart sitting avatar add/remove code also locks on this object to avoid race conditions. + /// No avatar should appear more than once in this list. + /// Do not manipulate this list directly - use the Add/Remove sitting avatar methods on SceneObjectPart. + /// + protected internal List m_sittingAvatars = new List(); + #endregion // ~SceneObjectGroup() @@ -3564,17 +3576,28 @@ namespace OpenSim.Region.Framework.Scenes } /// + /// Get a copy of the list of sitting avatars on all prims of this object. + /// + /// + /// This is sorted by the order in which avatars sat down. If an avatar stands up then all avatars that sat + /// down after it move one place down the list. + /// + /// A list of the sitting avatars. Returns an empty list if there are no sitting avatars. + public List GetSittingAvatars() + { + lock (m_sittingAvatars) + return new List(m_sittingAvatars); + } + + /// /// Gets the number of sitting avatars. /// /// This applies to all sitting avatars whether there is a sit target set or not. /// public int GetSittingAvatarsCount() { - int count = 0; - - Array.ForEach(m_parts.GetArray(), p => count += p.GetSittingAvatarsCount()); - - return count; + lock (m_sittingAvatars) + return m_sittingAvatars.Count; } public override string ToString() @@ -3583,7 +3606,7 @@ namespace OpenSim.Region.Framework.Scenes } #region ISceneObject - + public virtual ISceneObject CloneForNewScene() { SceneObjectGroup sog = Copy(false); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 7a97e5f..232861e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1256,7 +1256,7 @@ namespace OpenSim.Region.Framework.Scenes public UUID SitTargetAvatar { get; set; } /// - /// IDs of all avatars start on this object part. + /// IDs of all avatars sat on this part. /// /// /// We need to track this so that we can stop sat upon prims from being attached. @@ -4504,18 +4504,22 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal bool AddSittingAvatar(UUID avatarId) { - if (IsSitTargetSet && SitTargetAvatar == UUID.Zero) - SitTargetAvatar = avatarId; + lock (ParentGroup.m_sittingAvatars) + { + if (IsSitTargetSet && SitTargetAvatar == UUID.Zero) + SitTargetAvatar = avatarId; - HashSet sittingAvatars = m_sittingAvatars; + if (m_sittingAvatars == null) + m_sittingAvatars = new HashSet(); - if (sittingAvatars == null) - sittingAvatars = new HashSet(); + if (m_sittingAvatars.Add(avatarId)) + { + ParentGroup.m_sittingAvatars.Add(avatarId); - lock (sittingAvatars) - { - m_sittingAvatars = sittingAvatars; - return m_sittingAvatars.Add(avatarId); + return true; + } + + return false; } } @@ -4529,27 +4533,26 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal bool RemoveSittingAvatar(UUID avatarId) { - if (SitTargetAvatar == avatarId) - SitTargetAvatar = UUID.Zero; - - HashSet sittingAvatars = m_sittingAvatars; + lock (ParentGroup.m_sittingAvatars) + { + if (SitTargetAvatar == avatarId) + SitTargetAvatar = UUID.Zero; - // This can occur under a race condition where another thread - if (sittingAvatars == null) - return false; + if (m_sittingAvatars == null) + return false; - lock (sittingAvatars) - { - if (sittingAvatars.Remove(avatarId)) + if (m_sittingAvatars.Remove(avatarId)) { - if (sittingAvatars.Count == 0) + if (m_sittingAvatars.Count == 0) m_sittingAvatars = null; + ParentGroup.m_sittingAvatars.Remove(avatarId); + return true; } - } - return false; + return false; + } } /// @@ -4559,16 +4562,12 @@ namespace OpenSim.Region.Framework.Scenes /// A hashset of the sitting avatars. Returns null if there are no sitting avatars. public HashSet GetSittingAvatars() { - HashSet sittingAvatars = m_sittingAvatars; - - if (sittingAvatars == null) - { - return null; - } - else + lock (ParentGroup.m_sittingAvatars) { - lock (sittingAvatars) - return new HashSet(sittingAvatars); + if (m_sittingAvatars == null) + return null; + else + return new HashSet(m_sittingAvatars); } } @@ -4579,13 +4578,13 @@ namespace OpenSim.Region.Framework.Scenes /// public int GetSittingAvatarsCount() { - HashSet sittingAvatars = m_sittingAvatars; - - if (sittingAvatars == null) - return 0; - - lock (sittingAvatars) - return sittingAvatars.Count; + lock (ParentGroup.m_sittingAvatars) + { + if (m_sittingAvatars == null) + return 0; + else + return m_sittingAvatars.Count; + } } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 75749a9..f31bbff 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3738,33 +3738,47 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_String llGetLinkKey(int linknum) { m_host.AddScriptLPS(1); - List keytable = new List(); - // parse for sitting avatare-uuids - World.ForEachRootScenePresence(delegate(ScenePresence presence) - { - if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID)) - keytable.Add(presence.UUID); - }); - int totalprims = m_host.ParentGroup.PrimCount + keytable.Count; - if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims) + if (linknum < 0) { - return keytable[totalprims - linknum].ToString(); + if (linknum == ScriptBaseClass.LINK_THIS) + return m_host.UUID.ToString(); + else + return ScriptBaseClass.NULL_KEY; } - if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1) + int actualPrimCount = m_host.ParentGroup.PrimCount; + List sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars(); + int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count; + + // Special case for a single prim. In this case the linknum is zero. However, this will not match a single + // prim that has any avatars sat upon it (in which case the root prim is link 1). + if (linknum == 0) { - return m_host.UUID.ToString(); - } + if (actualPrimCount == 1 && sittingAvatarIds.Count == 0) + return m_host.UUID.ToString(); - SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); - if (part != null) + return ScriptBaseClass.NULL_KEY; + } + // Special case to handle a single prim with sitting avatars. GetLinkPart() would only match zero but + // here we must match 1 (ScriptBaseClass.LINK_ROOT). + else if (linknum == 1 && actualPrimCount == 1) { - return part.UUID.ToString(); + if (sittingAvatarIds.Count > 0) + return m_host.ParentGroup.RootPart.UUID.ToString(); + else + return ScriptBaseClass.NULL_KEY; + } + else if (linknum <= adjustedPrimCount) + { + if (linknum <= actualPrimCount) + return m_host.ParentGroup.GetLinkNumPart(linknum).UUID.ToString(); + else + return sittingAvatarIds[linknum - actualPrimCount - 1].ToString(); } else { - return UUID.Zero.ToString(); + return ScriptBaseClass.NULL_KEY; } } -- cgit v1.1 From 9869ca83b464d3d88cf3f48ff65ea406168c0516 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 4 Jan 2013 20:54:11 +0000 Subject: Fix llGetLinkName() to return the name of the last avatar sat as the last link number. As per http://wiki.secondlife.com/wiki/LlGetLinkName --- .../Shared/Api/Implementation/LSL_Api.cs | 76 ++++++++++------------ 1 file changed, 35 insertions(+), 41 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index f31bbff..f0e0f1a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3824,62 +3824,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_String llGetLinkName(int linknum) { m_host.AddScriptLPS(1); - // simplest case, this prims link number - if (linknum == m_host.LinkNum || linknum == ScriptBaseClass.LINK_THIS) - return m_host.Name; - // parse for sitting avatare-names - List nametable = new List(); - World.ForEachRootScenePresence(delegate(ScenePresence presence) - { - SceneObjectPart sitPart = presence.ParentPart; - if (sitPart != null && m_host.ParentGroup.ContainsPart(sitPart.LocalId)) - nametable.Add(presence.ControllingClient.Name); - }); - - int totalprims = m_host.ParentGroup.PrimCount + nametable.Count; - if (totalprims > m_host.ParentGroup.PrimCount) + if (linknum < 0) { - // sitting Avatar-Name with negativ linknum / SinglePrim - if (linknum < 0 && m_host.ParentGroup.PrimCount == 1 && nametable.Count == 1) - return nametable[0]; - // Prim-Name / SinglePrim Sitting Avatar - if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && nametable.Count == 1) + if (linknum == ScriptBaseClass.LINK_THIS) return m_host.Name; - // LinkNumber > of Real PrimSet = AvatarName - if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims) - return nametable[totalprims - linknum]; + else + return ScriptBaseClass.NULL_KEY; } - // Single prim - if (m_host.LinkNum == 0) + int actualPrimCount = m_host.ParentGroup.PrimCount; + List sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars(); + int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count; + + // Special case for a single prim. In this case the linknum is zero. However, this will not match a single + // prim that has any avatars sat upon it (in which case the root prim is link 1). + if (linknum == 0) { - if (linknum == 0 || linknum == ScriptBaseClass.LINK_ROOT) + if (actualPrimCount == 1 && sittingAvatarIds.Count == 0) return m_host.Name; - else - return UUID.Zero.ToString(); - } - // Link set - SceneObjectPart part = null; - if (m_host.LinkNum == 1) // this is the Root prim + return ScriptBaseClass.NULL_KEY; + } + // Special case to handle a single prim with sitting avatars. GetLinkPart() would only match zero but + // here we must match 1 (ScriptBaseClass.LINK_ROOT). + else if (linknum == 1 && actualPrimCount == 1) { - if (linknum < 0) - part = m_host.ParentGroup.GetLinkNumPart(2); + if (sittingAvatarIds.Count > 0) + return m_host.ParentGroup.RootPart.Name; else - part = m_host.ParentGroup.GetLinkNumPart(linknum); + return ScriptBaseClass.NULL_KEY; } - else // this is a child prim + else if (linknum <= adjustedPrimCount) { - if (linknum < 2) - part = m_host.ParentGroup.GetLinkNumPart(1); + if (linknum <= actualPrimCount) + { + return m_host.ParentGroup.GetLinkNumPart(linknum).Name; + } else - part = m_host.ParentGroup.GetLinkNumPart(linknum); + { + ScenePresence sp = World.GetScenePresence(sittingAvatarIds[linknum - actualPrimCount - 1]); + if (sp != null) + return sp.Name; + else + return ScriptBaseClass.NULL_KEY; + } } - if (part != null) - return part.Name; else - return UUID.Zero.ToString(); + { + return ScriptBaseClass.NULL_KEY; + } } public LSL_Integer llGetInventoryNumber(int type) -- cgit v1.1 From a3bf3a2aa5f0213d238ac31e279dd729bc872769 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 4 Jan 2013 20:56:39 +0000 Subject: refactor: simplify llGetNumberOfPrims() to return prim count + sitting avatar count rather than independently inspecting every scene presence --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index f0e0f1a..14aaa86 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -7891,14 +7891,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer llGetNumberOfPrims() { m_host.AddScriptLPS(1); - int avatarCount = 0; - World.ForEachRootScenePresence(delegate(ScenePresence presence) - { - if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID)) - avatarCount++; - }); - return m_host.ParentGroup.PrimCount + avatarCount; + return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount(); } /// -- cgit v1.1 From dce280913706f7359cac07b98a6126af0bb4240b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 4 Jan 2013 21:18:53 +0000 Subject: Automatically grant sit-related llRequestPermissions() for subsequent avatars sitting on the same scene obejct, instead of wrongly popping up request permissions dialog. Resolves http://opensimulator.org/mantis/view.php?id=6478 --- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 14aaa86..967c249 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3412,21 +3412,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } else { - bool sitting = false; - if (m_host.SitTargetAvatar == agentID) - { - sitting = true; - } - else - { - foreach (SceneObjectPart p in m_host.ParentGroup.Parts) - { - if (p.SitTargetAvatar == agentID) - sitting = true; - } - } - - if (sitting) + if (m_host.ParentGroup.GetSittingAvatars().Contains(agentID) { // When agent is sitting, certain permissions are implicit if requested from sitting agent implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | -- cgit v1.1 From 7e45096314e7b0223197b597e859d6134f1b8355 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 4 Jan 2013 21:22:51 +0000 Subject: Fix build break caused by missing ) from dce2809. Was hand-typing in a line of code I had tested before but not retested this time --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 967c249..115bac9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3412,7 +3412,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } else { - if (m_host.ParentGroup.GetSittingAvatars().Contains(agentID) + if (m_host.ParentGroup.GetSittingAvatars().Contains(agentID)) { // When agent is sitting, certain permissions are implicit if requested from sitting agent implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | -- cgit v1.1 From 7232cedd2b591a010ad11e5fb86448ac4dea460b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 4 Jan 2013 21:37:11 +0000 Subject: Set default particle burst count to 1 instead of 0 in any set particle system script call that does not have an empty list. As per http://opensimulator.org/mantis/view.php?id=6353 --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 115bac9..ea4e609 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -6194,6 +6194,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ps.BurstSpeedMax = 1.0f; ps.BurstRate = 0.1f; ps.PartMaxAge = 10.0f; + ps.BurstPartCount = 1; return ps; } @@ -6215,9 +6216,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api SetParticleSystem(m_host, rules); } - private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { - - + private void SetParticleSystem(SceneObjectPart part, LSL_List rules) + { if (rules.Length == 0) { part.RemoveParticleSystem(); -- cgit v1.1 From 2eda385f5e72e165150d0925c56b1188c77cafe8 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 1 Jan 2013 20:26:31 -0800 Subject: BulletSim: add ResetBroadphasePool and ResetConstraintSolver diagnostic functions. If values set from console, the functions are called. Looking for why the collision pools fill up with unnecessary stuff. --- OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | 22 +++++++-- OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs | 57 ++++++---------------- .../Region/Physics/BulletSPlugin/BSApiTemplate.cs | 16 +++--- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 28 +++++++++++ 4 files changed, 73 insertions(+), 50 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs index 8c6e7d6..45ecf56 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs @@ -530,12 +530,12 @@ public override void SetForceUpdateAllAabbs(BulletWorld world, bool force) // btDynamicsWorld entries public override bool AddObjectToWorld(BulletWorld world, BulletBody obj) { - // Bullet resets several variables when an object is added to the world. - // Gravity is reset to world default depending on the static/dynamic - // type. Of course, the collision flags in the broadphase proxy are initialized to default. BulletWorldUnman worldu = world as BulletWorldUnman; BulletBodyUnman bodyu = obj as BulletBodyUnman; + // Bullet resets several variables when an object is added to the world. + // Gravity is reset to world default depending on the static/dynamic + // type. Of course, the collision flags in the broadphase proxy are initialized to default. Vector3 origGrav = BSAPICPP.GetGravity2(bodyu.ptr); bool ret = BSAPICPP.AddObjectToWorld2(worldu.ptr, bodyu.ptr); @@ -1259,6 +1259,16 @@ public override void DumpPhysicsStatistics(BulletWorld world) BulletWorldUnman worldu = world as BulletWorldUnman; BSAPICPP.DumpPhysicsStatistics2(worldu.ptr); } +public override void ResetBroadphasePool(BulletWorld world) +{ + BulletWorldUnman worldu = world as BulletWorldUnman; + BSAPICPP.ResetBroadphasePool(worldu.ptr); +} +public override void ResetConstraintSolver(BulletWorld world) +{ + BulletWorldUnman worldu = world as BulletWorldUnman; + BSAPICPP.ResetConstraintSolver(worldu.ptr); +} // ===================================================================================== // ===================================================================================== @@ -1832,6 +1842,12 @@ public static extern void DumpAllInfo2(IntPtr sim); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern void DumpPhysicsStatistics2(IntPtr sim); +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ResetBroadphasePool(IntPtr sim); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void ResetConstraintSolver(IntPtr sim); + } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs index 30a7bee..0c7f315 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs @@ -232,21 +232,25 @@ private sealed class BulletConstraintXNA : BulletConstraint public override bool AddObjectToWorld(BulletWorld pWorld, BulletBody pBody) { + DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; + CollisionObject cbody = ((BulletBodyXNA)pBody).body; + RigidBody rbody = cbody as RigidBody; + // Bullet resets several variables when an object is added to the world. In particular, // BulletXNA resets position and rotation. Gravity is also reset depending on the static/dynamic // type. Of course, the collision flags in the broadphase proxy are initialized to default. - DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; - - IndexedMatrix origPos = body.GetWorldTransform(); - IndexedVector3 origGrav = body.GetGravity(); - - //if (!(body.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.STATIC_PLANE_PROXYTYPE && body.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.TERRAIN_SHAPE_PROXYTYPE)) - - world.AddRigidBody(body); - - body.SetWorldTransform(origPos); - body.SetGravity(origGrav); + IndexedMatrix origPos = cbody.GetWorldTransform(); + if (rbody != null) + { + IndexedVector3 origGrav = rbody.GetGravity(); + world.AddRigidBody(rbody); + rbody.SetGravity(origGrav); + } + else + { + world.AddCollisionObject(rbody); + } + cbody.SetWorldTransform(origPos); pBody.ApplyCollisionMask(pWorld.physicsScene); @@ -773,35 +777,6 @@ private sealed class BulletConstraintXNA : BulletConstraint body.ApplyTorqueImpulse(ref fSum); } - public override void DumpRigidBody(BulletWorld p, BulletBody p_2) - { - //TODO: - } - - public override void DumpCollisionShape(BulletWorld p, BulletShape p_2) - { - //TODO: - } - public override void DumpConstraint(BulletWorld world, BulletConstraint constrain) - { - //TODO: - } - - public override void DumpActivationInfo(BulletWorld world) - { - //TODO: - } - - public override void DumpAllInfo(BulletWorld world) - { - //TODO: - } - - public override void DumpPhysicsStatistics(BulletWorld world) - { - //TODO: - } - public override void DestroyObject(BulletWorld p, BulletBody p_2) { //TODO: diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index 8ad78ca..befb076 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs @@ -646,17 +646,21 @@ public abstract float GetMargin(BulletShape shape); // ===================================================================================== // Debugging -public abstract void DumpRigidBody(BulletWorld sim, BulletBody collisionObject); +public virtual void DumpRigidBody(BulletWorld sim, BulletBody collisionObject) { } -public abstract void DumpCollisionShape(BulletWorld sim, BulletShape collisionShape); +public virtual void DumpCollisionShape(BulletWorld sim, BulletShape collisionShape) { } -public abstract void DumpConstraint(BulletWorld sim, BulletConstraint constrain); +public virtual void DumpConstraint(BulletWorld sim, BulletConstraint constrain) { } -public abstract void DumpActivationInfo(BulletWorld sim); +public virtual void DumpActivationInfo(BulletWorld sim) { } -public abstract void DumpAllInfo(BulletWorld sim); +public virtual void DumpAllInfo(BulletWorld sim) { } -public abstract void DumpPhysicsStatistics(BulletWorld sim); +public virtual void DumpPhysicsStatistics(BulletWorld sim) { } + +public virtual void ResetBroadphasePool(BulletWorld sim) { } + +public virtual void ResetConstraintSolver(BulletWorld sim) { } }; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 69ac8cd..b9bd0bf 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -497,6 +497,16 @@ public static class BSParam (s,cf,p,v) => { s.PhysicsMetricDumpFrames = cf.GetFloat(p, (int)v); }, (s) => { return (float)s.PhysicsMetricDumpFrames; }, (s,p,l,v) => { s.PhysicsMetricDumpFrames = (int)v; } ), + new ParameterDefn("ResetBroadphasePool", "Setting this is any value resets the broadphase collision pool", + 0f, + (s,cf,p,v) => { ; }, + (s) => { return 0f; }, + (s,p,l,v) => { BSParam.ResetBroadphasePoolTainted(s, v); } ), + new ParameterDefn("ResetConstraintSolver", "Setting this is any value resets the constraint solver", + 0f, + (s,cf,p,v) => { ; }, + (s) => { return 0f; }, + (s,p,l,v) => { BSParam.ResetConstraintSolverTainted(s, v); } ), }; // Convert a boolean to our numeric true and false values @@ -511,6 +521,24 @@ public static class BSParam return (b == ConfigurationParameters.numericTrue ? true : false); } + private static void ResetBroadphasePoolTainted(BSScene pPhysScene, float v) + { + BSScene physScene = pPhysScene; + physScene.TaintedObject("BSParam.ResetBroadphasePoolTainted", delegate() + { + physScene.PE.ResetBroadphasePool(physScene.World); + }); + } + + private static void ResetConstraintSolverTainted(BSScene pPhysScene, float v) + { + BSScene physScene = pPhysScene; + physScene.TaintedObject("BSParam.ResetConstraintSolver", delegate() + { + physScene.PE.ResetConstraintSolver(physScene.World); + }); + } + // Search through the parameter definitions and return the matching // ParameterDefn structure. // Case does not matter as names are compared after converting to lower case. -- cgit v1.1 From 92a6958b6d56293693b92c082595f46e7c9b1119 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 3 Jan 2013 19:34:14 -0800 Subject: BulletSim: fix problem where pre-step actions would not replaced by new registrations thus causing multiple instances of an action. --- OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index e7cb3e0..534f929 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -343,6 +343,10 @@ public abstract class BSPhysObject : PhysicsActor protected void RegisterPreStepAction(string op, uint id, BSScene.PreStepAction actn) { string identifier = op + "-" + id.ToString(); + + // Clean out any existing action + UnRegisterPreStepAction(op, id); + RegisteredActions[identifier] = actn; PhysicsScene.BeforeStep += actn; DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier); -- cgit v1.1 From 44492b3a4995651cd1d0d508b879d24e4d8f5707 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 3 Jan 2013 19:35:38 -0800 Subject: BulletSim: add comments to force and impulse setting functions so it is clear what Bullet is actually doing with the set values. --- OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs index 45ecf56..14de2eb 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs @@ -921,6 +921,7 @@ public override void SetCenterOfMassByPosRot(BulletBody obj, Vector3 pos, Quater } // Add a force to the object as if its mass is one. +// Deep down in Bullet: m_totalForce += force*m_linearFactor; public override void ApplyCentralForce(BulletBody obj, Vector3 force) { BulletBodyUnman bodyu = obj as BulletBodyUnman; @@ -964,6 +965,7 @@ public override void SetSleepingThresholds(BulletBody obj, float lin_threshold, BSAPICPP.SetSleepingThresholds2(bodyu.ptr, lin_threshold, ang_threshold); } +// Deep down in Bullet: m_totalTorque += torque*m_angularFactor; public override void ApplyTorque(BulletBody obj, Vector3 torque) { BulletBodyUnman bodyu = obj as BulletBodyUnman; @@ -971,6 +973,8 @@ public override void ApplyTorque(BulletBody obj, Vector3 torque) } // Apply force at the given point. Will add torque to the object. +// Deep down in Bullet: applyCentralForce(force); +// applyTorque(rel_pos.cross(force*m_linearFactor)); public override void ApplyForce(BulletBody obj, Vector3 force, Vector3 pos) { BulletBodyUnman bodyu = obj as BulletBodyUnman; @@ -978,6 +982,7 @@ public override void ApplyForce(BulletBody obj, Vector3 force, Vector3 pos) } // Apply impulse to the object. Same as "ApplycentralForce" but force scaled by object's mass. +// Deep down in Bullet: m_linearVelocity += impulse *m_linearFactor * m_inverseMass; public override void ApplyCentralImpulse(BulletBody obj, Vector3 imp) { BulletBodyUnman bodyu = obj as BulletBodyUnman; @@ -985,6 +990,7 @@ public override void ApplyCentralImpulse(BulletBody obj, Vector3 imp) } // Apply impulse to the object's torque. Force is scaled by object's mass. +// Deep down in Bullet: m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor; public override void ApplyTorqueImpulse(BulletBody obj, Vector3 imp) { BulletBodyUnman bodyu = obj as BulletBodyUnman; @@ -992,6 +998,8 @@ public override void ApplyTorqueImpulse(BulletBody obj, Vector3 imp) } // Apply impulse at the point given. For is scaled by object's mass and effects both linear and angular forces. +// Deep down in Bullet: applyCentralImpulse(impulse); +// applyTorqueImpulse(rel_pos.cross(impulse*m_linearFactor)); public override void ApplyImpulse(BulletBody obj, Vector3 imp, Vector3 pos) { BulletBodyUnman bodyu = obj as BulletBodyUnman; -- cgit v1.1 From 54321800277b683d76e80b12334900c82e3c6b50 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 3 Jan 2013 19:37:01 -0800 Subject: BulletSim: reorganize motor code a little to pull together common functions. Add BSFMotor. --- OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 147 ++++++++++++++++++++--- 1 file changed, 129 insertions(+), 18 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index 817a5f7..91255bd 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -59,10 +59,7 @@ public abstract class BSMotor { if (PhysicsScene != null) { - if (PhysicsScene.VehicleLoggingEnabled) - { - PhysicsScene.DetailLog(msg, parms); - } + PhysicsScene.DetailLog(msg, parms); } } } @@ -100,10 +97,13 @@ public class BSVMotor : BSMotor public virtual Vector3 CurrentValue { get; protected set; } public virtual Vector3 LastError { get; protected set; } - public virtual bool ErrorIsZero - { get { - return (LastError == Vector3.Zero || LastError.LengthSquared() <= ErrorZeroThreshold); - } + public virtual bool ErrorIsZero() + { + return ErrorIsZero(LastError); + } + public virtual bool ErrorIsZero(Vector3 err) + { + return (err == Vector3.Zero || err.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)); } public BSVMotor(string useName) @@ -148,7 +148,7 @@ public class BSVMotor : BSMotor Vector3 correction = Vector3.Zero; Vector3 error = TargetValue - CurrentValue; - if (!error.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)) + if (!ErrorIsZero(error)) { correction = Step(timeStep, error); @@ -200,7 +200,7 @@ public class BSVMotor : BSMotor LastError = error; Vector3 returnCorrection = Vector3.Zero; - if (!error.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)) + if (!ErrorIsZero()) { // correction = error / secondsItShouldTakeToCorrect Vector3 correctionAmount; @@ -246,32 +246,139 @@ public class BSVMotor : BSMotor } } +// ============================================================================ +// ============================================================================ public class BSFMotor : BSMotor { - public float TimeScale { get; set; } - public float DecayTimeScale { get; set; } - public float Friction { get; set; } - public float Efficiency { get; set; } + public virtual float TimeScale { get; set; } + public virtual float TargetValueDecayTimeScale { get; set; } + public virtual float FrictionTimescale { get; set; } + public virtual float Efficiency { get; set; } + + public virtual float ErrorZeroThreshold { get; set; } + + public virtual float TargetValue { get; protected set; } + public virtual float CurrentValue { get; protected set; } + public virtual float LastError { get; protected set; } - public float Target { get; private set; } - public float CurrentValue { get; private set; } + public virtual bool ErrorIsZero() + { + return ErrorIsZero(LastError); + } + public virtual bool ErrorIsZero(float err) + { + return (err >= -ErrorZeroThreshold && err <= ErrorZeroThreshold); + } public BSFMotor(string useName, float timeScale, float decayTimescale, float friction, float efficiency) : base(useName) { + TimeScale = TargetValueDecayTimeScale = BSMotor.Infinite; + Efficiency = 1f; + FrictionTimescale = BSMotor.Infinite; + CurrentValue = TargetValue = 0f; + ErrorZeroThreshold = 0.01f; } - public void SetCurrent(float target) + public void SetCurrent(float current) { + CurrentValue = current; } public void SetTarget(float target) { + TargetValue = target; + } + public override void Zero() + { + base.Zero(); + CurrentValue = TargetValue = 0f; } + public virtual float Step(float timeStep) { - return 0f; + if (!Enabled) return TargetValue; + + float origTarget = TargetValue; // DEBUG + float origCurrVal = CurrentValue; // DEBUG + + float correction = 0f; + float error = TargetValue - CurrentValue; + if (!ErrorIsZero(error)) + { + correction = Step(timeStep, error); + + CurrentValue += correction; + + // The desired value reduces to zero which also reduces the difference with current. + // If the decay time is infinite, don't decay at all. + float decayFactor = 0f; + if (TargetValueDecayTimeScale != BSMotor.Infinite) + { + decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep; + TargetValue *= (1f - decayFactor); + } + + // The amount we can correct the error is reduced by the friction + float frictionFactor = 0f; + if (FrictionTimescale != BSMotor.Infinite) + { + // frictionFactor = (Vector3.One / FrictionTimescale) * timeStep; + // Individual friction components can be 'infinite' so compute each separately. + frictionFactor = 1f / FrictionTimescale; + frictionFactor *= timeStep; + CurrentValue *= (1f - frictionFactor); + } + + MDetailLog("{0}, BSFMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},err={5},corr={6}", + BSScene.DetailLogZero, UseName, origCurrVal, origTarget, + timeStep, error, correction); + MDetailLog("{0}, BSFMotor.Step,nonZero,{1},tgtDecayTS={2},decayFact={3},frictTS={4},frictFact={5},tgt={6},curr={7}", + BSScene.DetailLogZero, UseName, + TargetValueDecayTimeScale, decayFactor, FrictionTimescale, frictionFactor, + TargetValue, CurrentValue); + } + else + { + // Difference between what we have and target is small. Motor is done. + CurrentValue = TargetValue; + MDetailLog("{0}, BSFMotor.Step,zero,{1},origTgt={2},origCurr={3},ret={4}", + BSScene.DetailLogZero, UseName, origCurrVal, origTarget, CurrentValue); + } + + return CurrentValue; + } + + public virtual float Step(float timeStep, float error) + { + if (!Enabled) return 0f; + + LastError = error; + float returnCorrection = 0f; + if (!ErrorIsZero()) + { + // correction = error / secondsItShouldTakeToCorrect + float correctionAmount; + if (TimeScale == 0f || TimeScale == BSMotor.Infinite) + correctionAmount = error * timeStep; + else + correctionAmount = error / TimeScale * timeStep; + + returnCorrection = correctionAmount; + MDetailLog("{0}, BSFMotor.Step,nonZero,{1},timeStep={2},timeScale={3},err={4},corr={5}", + BSScene.DetailLogZero, UseName, timeStep, TimeScale, error, correctionAmount); + } + return returnCorrection; + } + + public override string ToString() + { + return String.Format("<{0},curr={1},targ={2},lastErr={3},decayTS={4},frictTS={5}>", + UseName, CurrentValue, TargetValue, LastError, TargetValueDecayTimeScale, FrictionTimescale); } + } +// ============================================================================ +// ============================================================================ // Proportional, Integral, Derivitive Motor // Good description at http://www.answers.com/topic/pid-controller . Includes processes for choosing p, i and d factors. public class BSPIDVMotor : BSVMotor @@ -319,6 +426,7 @@ public class BSPIDVMotor : BSVMotor proportionFactor = new Vector3(factor, factor, factor); integralFactor = new Vector3(factor, factor, factor); derivFactor = new Vector3(factor, factor, factor); + MDetailLog("{0},BSPIDVMotor.setEfficiency,eff={1},factor={2}", BSScene.DetailLogZero, Efficiency, factor); } } @@ -341,6 +449,9 @@ public class BSPIDVMotor : BSVMotor + derivFactor * derivFactor ); + MDetailLog("{0},BSPIDVMotor.step,ts={1},err={2},runnInt={3},derivFact={4},ret={5}", + BSScene.DetailLogZero, timeStep, error, RunningIntegration, derivFactor, ret); + return ret; } } -- cgit v1.1 From 2c6b269b6e53cae70e6de0c4380a9a4183c4f32d Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 3 Jan 2013 19:38:30 -0800 Subject: BulletSim: add initial implementation of llMoveToTarget and hover height. Not all there yet. --- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 157 +++++++++++++++++++++++-- 1 file changed, 147 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 826261c..1904ddd 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -66,9 +66,6 @@ public sealed class BSPrim : BSPhysObject private float _restitution; private bool _setAlwaysRun; private bool _throttleUpdates; - private bool _isColliding; - private bool _collidingGround; - private bool _collidingObj; private bool _floatOnWater; private OMV.Vector3 _rotationalVelocity; private bool _kinematic; @@ -76,13 +73,14 @@ public sealed class BSPrim : BSPhysObject private BSDynamics _vehicle; + private BSVMotor _targetMotor; private OMV.Vector3 _PIDTarget; - private bool _usePID; private float _PIDTau; - private bool _useHoverPID; + + private BSFMotor _hoverMotor; private float _PIDHoverHeight; private PIDHoverType _PIDHoverType; - private float _PIDHoverTao; + private float _PIDHoverTau; public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) @@ -564,6 +562,11 @@ public sealed class BSPrim : BSPhysObject } return; } + public OMV.Vector3 RawVelocity + { + get { return _velocity; } + set { _velocity = value; } + } public override OMV.Vector3 Velocity { get { return _velocity; } set { @@ -1004,13 +1007,120 @@ public sealed class BSPrim : BSPhysObject set { _PIDTau = value; } } public override bool PIDActive { - set { _usePID = value; } + set { + if (value) + { + // Turning the target on + /* + _targetMotor = new BSVMotor("BSPrim.PIDTarget", + _PIDTau, // timeScale + BSMotor.Infinite, // decay time scale + BSMotor.InfiniteVector, // friction timescale + 1f // efficiency + ); + _targetMotor.SetTarget(_PIDTarget); + _targetMotor.SetCurrent(RawPosition); + */ + _targetMotor = new BSPIDVMotor("BSPrim.PIDTarget"); + _targetMotor.SetTarget(_PIDTarget); + _targetMotor.SetCurrent(RawPosition); + _targetMotor.Efficiency = 1f; + + _targetMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages. + + RegisterPreStepAction("BSPrim.PIDTarget", LocalID, delegate(float timeStep) + { + // How far are we away from the target + OMV.Vector3 distance = _PIDTarget - RawPosition; + + // The amount of that distance we should cover per second + OMV.Vector3 movementPerSecond = distance / _PIDTau; + + OMV.Vector3 adjustedVelocity = movementPerSecond - RawVelocity; + + // Apply force to overcome current velocity + AddForce(-RawVelocity * Mass, false, true); + // Get it moving to the point + AddForce(movementPerSecond * Mass, false, true); + + // Apply enough force to get to the speed needed to get to the point + // The physics engine will do only a timestep's worth. + // AddForce(adjustedVelocity * Mass, false, true); + // PhysicsScene.PE.ApplyCentralImpulse(PhysBody, adjustedVelocity); + + DetailLog("{0},BSPrim.PIDTarget,move,tgt={1},pos={2},vel={3},dist={4},tau={5},mvmt={6},newVel={7}", + LocalID, _PIDTarget, RawPosition, RawVelocity, distance, _PIDTau, movementPerSecond, adjustedVelocity); + + /* + OMV.Vector3 movePosition = _targetMotor.Step(timeStep); + + // 'movePosition' is where we'd like the prim to be at this moment. + // Compute the amount of force to push us there. + OMV.Vector3 moveForce = (movePosition - RawPosition) * Mass; + + // If we are very close to our target, turn off the movement motor. + if (_targetMotor.ErrorIsZero()) + { + DetailLog("{0},BSPrim.PIDTarget,zeroMovement,movePos={1},pos={2},mass={3},moveForce={4}", + LocalID, movePosition, RawPosition, Mass, moveForce); + moveForce = OMV.Vector3.Zero; + ForcePosition = _targetMotor.TargetValue; + _targetMotor.Enabled = false; + } + else + { + AddForce(moveForce, false, true); + } + DetailLog("{0},BSPrim.PIDTarget,move,movePos={1},moveForce={2},mass={3}", LocalID, movePosition, moveForce, Mass); + */ + }); + } + else + { + // Stop any targetting + UnRegisterPreStepAction("BSPrim.PIDTarget", LocalID); + } + } } // Used for llSetHoverHeight and maybe vehicle height // Hover Height will override MoveTo target's Z public override bool PIDHoverActive { - set { _useHoverPID = value; } + set { + if (value) + { + // Turning the target on + _hoverMotor = new BSFMotor("BSPrim.Hover", + _PIDHoverTau, // timeScale + BSMotor.Infinite, // decay time scale + BSMotor.Infinite, // friction timescale + 1f // efficiency + ); + _hoverMotor.SetTarget(ComputeCurrentPIDHoverHeight()); + _hoverMotor.SetCurrent(RawPosition.Z); + _hoverMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages. + + RegisterPreStepAction("BSPrim.Hover", LocalID, delegate(float timeStep) + { + // TODO: Decide if the step parameters should be changed depending on the avatar's + // state (flying, colliding, ...). There is code in ODE to do this. + + _hoverMotor.SetTarget(ComputeCurrentPIDHoverHeight()); + float targetHeight = _hoverMotor.Step(timeStep); + + // 'targetHeight' is where we'd like the Z of the prim to be at this moment. + // Compute the amount of force to push us there. + float moveForce = (targetHeight - RawPosition.Z) * Mass / PhysicsScene.LastTimeStep; + + AddForce(new OMV.Vector3(0f, 0f, moveForce), false, true); + DetailLog("{0},BSPrim.Hover,move,targHt={1},moveForce={2},mass={3}", LocalID, targetHeight, moveForce, Mass); + }); + } + else + { + UnRegisterPreStepAction("BSPrim.Hover", LocalID); + } + } } public override float PIDHoverHeight { set { _PIDHoverHeight = value; } @@ -1019,8 +1129,35 @@ public sealed class BSPrim : BSPhysObject set { _PIDHoverType = value; } } public override float PIDHoverTau { - set { _PIDHoverTao = value; } + set { _PIDHoverTau = value; } } + // Based on current position, determine what we should be hovering at now. + // Must recompute often. What if we walked offa cliff> + private float ComputeCurrentPIDHoverHeight() + { + float ret = _PIDHoverHeight; + float groundHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition); + + switch (_PIDHoverType) + { + case PIDHoverType.Ground: + ret = groundHeight + _PIDHoverHeight; + break; + case PIDHoverType.GroundAndWater: + float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(RawPosition); + if (groundHeight > waterHeight) + { + ret = groundHeight + _PIDHoverHeight; + } + else + { + ret = waterHeight + _PIDHoverHeight; + } + break; + } + return ret; + } + // For RotLookAt public override OMV.Quaternion APIDTarget { set { return; } } @@ -1047,7 +1184,7 @@ public sealed class BSPrim : BSPhysObject } OMV.Vector3 addForce = force; - DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); + // DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() { -- cgit v1.1 From 613f516007f8f1c0cd978fec7ec40f579af35d65 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 4 Jan 2013 16:45:34 -0800 Subject: BulletSim: convert avatar movement from a force to an impulse. Shouldn't change functionality but removes an oddity in computing the force. --- OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 103d8fc..c215e3a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -214,7 +214,7 @@ public sealed class BSCharacter : BSPhysObject } // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force. - OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass / PhysicsScene.LastTimeStep; + OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass; /* // If moveForce is very small, zero things so we don't keep sending microscopic updates to the user @@ -231,7 +231,7 @@ public sealed class BSCharacter : BSPhysObject } */ // DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); - AddForce(moveForce, false, true); + PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce); }); } -- cgit v1.1 From d0c7f7f0502b6a5543bb47f734951405f978747b Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 4 Jan 2013 16:46:30 -0800 Subject: BulletSim: add some features to the PID motor to make it more flexible. --- OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 27 ++++++++++++++++-------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index 91255bd..6d0db2e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -388,6 +388,12 @@ public class BSPIDVMotor : BSVMotor public Vector3 integralFactor { get; set; } public Vector3 derivFactor { get; set; } + // The factors are vectors for the three dimensions. This is the proportional of each + // that is applied. This could be multiplied through the actual factors but it + // is sometimes easier to manipulate the factors and their mix separately. + // to + public Vector3 FactorMix; + // Arbritrary factor range. // EfficiencyHigh means move quickly to the correct number. EfficiencyLow means might over correct. public float EfficiencyHigh = 0.4f; @@ -402,6 +408,7 @@ public class BSPIDVMotor : BSVMotor proportionFactor = new Vector3(1.00f, 1.00f, 1.00f); integralFactor = new Vector3(1.00f, 1.00f, 1.00f); derivFactor = new Vector3(1.00f, 1.00f, 1.00f); + FactorMix = new Vector3(0.5f, 0.25f, 0.25f); RunningIntegration = Vector3.Zero; LastError = Vector3.Zero; } @@ -417,15 +424,18 @@ public class BSPIDVMotor : BSVMotor set { base.Efficiency = Util.Clamp(value, 0f, 1f); + // Compute factors based on efficiency. // If efficiency is high (1f), use a factor value that moves the error value to zero with little overshoot. // If efficiency is low (0f), use a factor value that overcorrects. // TODO: might want to vary contribution of different factor depending on efficiency. float factor = ((1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow) / 3f; // float factor = (1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow; + proportionFactor = new Vector3(factor, factor, factor); integralFactor = new Vector3(factor, factor, factor); derivFactor = new Vector3(factor, factor, factor); + MDetailLog("{0},BSPIDVMotor.setEfficiency,eff={1},factor={2}", BSScene.DetailLogZero, Efficiency, factor); } } @@ -439,18 +449,17 @@ public class BSPIDVMotor : BSVMotor RunningIntegration += error * timeStep; // A simple derivitive is the rate of change from the last error. - Vector3 derivFactor = (error - LastError) * timeStep; + Vector3 derivitive = (error - LastError) * timeStep; LastError = error; - // Correction = -(proportionOfPresentError + accumulationOfPastError + rateOfChangeOfError) - Vector3 ret = -( - error * proportionFactor - + RunningIntegration * integralFactor - + derivFactor * derivFactor - ); + // Correction = (proportionOfPresentError + accumulationOfPastError + rateOfChangeOfError) + Vector3 ret = error * timeStep * proportionFactor * FactorMix.X + + RunningIntegration * integralFactor * FactorMix.Y + + derivitive * derivFactor * FactorMix.Z + ; - MDetailLog("{0},BSPIDVMotor.step,ts={1},err={2},runnInt={3},derivFact={4},ret={5}", - BSScene.DetailLogZero, timeStep, error, RunningIntegration, derivFactor, ret); + MDetailLog("{0},BSPIDVMotor.step,ts={1},err={2},runnInt={3},deriv={4},ret={5}", + BSScene.DetailLogZero, timeStep, error, RunningIntegration, derivitive, ret); return ret; } -- cgit v1.1 From 48cfc6d089ae47795d99bf56382c3d1a867e7d03 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 4 Jan 2013 16:47:04 -0800 Subject: BulletSim: implement llMoveToTarget by adding PIDActive, etc. Implementation of non-vehicle hover but haven't tested it a lot. Update TODO list. --- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 63 ++++++++-------------- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 20 ++++--- 2 files changed, 33 insertions(+), 50 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 1904ddd..94b63e5 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -1010,69 +1010,48 @@ public sealed class BSPrim : BSPhysObject set { if (value) { - // Turning the target on - /* + // We're taking over after this. + ZeroMotion(true); + _targetMotor = new BSVMotor("BSPrim.PIDTarget", _PIDTau, // timeScale BSMotor.Infinite, // decay time scale BSMotor.InfiniteVector, // friction timescale 1f // efficiency ); + _targetMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages. _targetMotor.SetTarget(_PIDTarget); _targetMotor.SetCurrent(RawPosition); - */ + /* _targetMotor = new BSPIDVMotor("BSPrim.PIDTarget"); + _targetMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages. + _targetMotor.SetTarget(_PIDTarget); _targetMotor.SetCurrent(RawPosition); + _targetMotor.TimeScale = _PIDTau; _targetMotor.Efficiency = 1f; - - _targetMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages. + */ RegisterPreStepAction("BSPrim.PIDTarget", LocalID, delegate(float timeStep) { - // How far are we away from the target - OMV.Vector3 distance = _PIDTarget - RawPosition; - - // The amount of that distance we should cover per second - OMV.Vector3 movementPerSecond = distance / _PIDTau; - - OMV.Vector3 adjustedVelocity = movementPerSecond - RawVelocity; - - // Apply force to overcome current velocity - AddForce(-RawVelocity * Mass, false, true); - // Get it moving to the point - AddForce(movementPerSecond * Mass, false, true); - - // Apply enough force to get to the speed needed to get to the point - // The physics engine will do only a timestep's worth. - // AddForce(adjustedVelocity * Mass, false, true); - // PhysicsScene.PE.ApplyCentralImpulse(PhysBody, adjustedVelocity); - - DetailLog("{0},BSPrim.PIDTarget,move,tgt={1},pos={2},vel={3},dist={4},tau={5},mvmt={6},newVel={7}", - LocalID, _PIDTarget, RawPosition, RawVelocity, distance, _PIDTau, movementPerSecond, adjustedVelocity); - - /* - OMV.Vector3 movePosition = _targetMotor.Step(timeStep); + OMV.Vector3 origPosition = RawPosition; // DEBUG DEBUG (for printout below) // 'movePosition' is where we'd like the prim to be at this moment. - // Compute the amount of force to push us there. - OMV.Vector3 moveForce = (movePosition - RawPosition) * Mass; + OMV.Vector3 movePosition = _targetMotor.Step(timeStep); // If we are very close to our target, turn off the movement motor. if (_targetMotor.ErrorIsZero()) { - DetailLog("{0},BSPrim.PIDTarget,zeroMovement,movePos={1},pos={2},mass={3},moveForce={4}", - LocalID, movePosition, RawPosition, Mass, moveForce); - moveForce = OMV.Vector3.Zero; + DetailLog("{0},BSPrim.PIDTarget,zeroMovement,movePos={1},pos={2},mass={3}", + LocalID, movePosition, RawPosition, Mass); ForcePosition = _targetMotor.TargetValue; _targetMotor.Enabled = false; } else { - AddForce(moveForce, false, true); + ForcePosition = movePosition; } - DetailLog("{0},BSPrim.PIDTarget,move,movePos={1},moveForce={2},mass={3}", LocalID, movePosition, moveForce, Mass); - */ + DetailLog("{0},BSPrim.PIDTarget,move,fromPos={1},movePos={2}", LocalID, origPosition, movePosition); }); } else @@ -1102,17 +1081,17 @@ public sealed class BSPrim : BSPhysObject RegisterPreStepAction("BSPrim.Hover", LocalID, delegate(float timeStep) { - // TODO: Decide if the step parameters should be changed depending on the avatar's - // state (flying, colliding, ...). There is code in ODE to do this. - + _hoverMotor.SetCurrent(RawPosition.Z); _hoverMotor.SetTarget(ComputeCurrentPIDHoverHeight()); float targetHeight = _hoverMotor.Step(timeStep); // 'targetHeight' is where we'd like the Z of the prim to be at this moment. // Compute the amount of force to push us there. - float moveForce = (targetHeight - RawPosition.Z) * Mass / PhysicsScene.LastTimeStep; + float moveForce = (targetHeight - RawPosition.Z) * Mass; + // Undo anything the object thinks it's doing at the moment + moveForce = -RawVelocity.Z * Mass; - AddForce(new OMV.Vector3(0f, 0f, moveForce), false, true); + PhysicsScene.PE.ApplyCentralImpulse(PhysBody, new OMV.Vector3(0f, 0f, moveForce)); DetailLog("{0},BSPrim.Hover,move,targHt={1},moveForce={2},mass={3}", LocalID, targetHeight, moveForce, Mass); }); } @@ -1174,7 +1153,7 @@ public sealed class BSPrim : BSPhysObject // This added force will only last the next simulation tick. public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { // for an object, doesn't matter if force is a pushforce or not - if (force.IsFinite()) + if (!IsStatic && force.IsFinite()) { float magnitude = force.Length(); if (magnitude > BSParam.MaxAddForceMagnitude) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index a8a4ff5..facf720 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -1,22 +1,26 @@ CURRENT PRIORITIES ================================================= -Redo BulletSimAPI to allow native C# implementation of Bullet option. +Redo BulletSimAPI to allow native C# implementation of Bullet option (DONE) +Meshes rendering as bounding boxes +llMoveToTarget +Vehicle movement on terrain smoothness +limitMotorUp calibration (more down?) +Preferred orientatino angular correction fix +Surfboard go wonky when turning + Angular motor direction is global coordinates rather than local coordinates? +Boats float low in the water Avatar movement - flying into a wall doesn't stop avatar who keeps appearing to move through the obstacle + flying into a wall doesn't stop avatar who keeps appearing to move through the obstacle (DONE) walking up stairs is not calibrated correctly (stairs out of Kepler cabin) - avatar capsule rotation completed -llMoveToTarget + avatar capsule rotation completed (NOT DONE - Bullet's capsule shape is not the solution) Enable vehicle border crossings (at least as poorly as ODE) Terrain skirts Avatar created in previous region and not new region when crossing border Vehicle recreated in new sim at small Z value (offset from root value?) (DONE) -Vehicle movement on terrain smoothness Vehicle script tuning/debugging Avanti speed script Weapon shooter script -limitMotorUp calibration (more down?) -Boats float low in the water -Add material densities to the material types. +Add material densities to the material types CRASHES ================================================= -- cgit v1.1 From 2eba80a8cd254721956bcdc9f7e3b681d415dfed Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 4 Jan 2013 17:05:56 -0800 Subject: BulletSim: fix problem where mesh shapes were physically just their bounding box and not the complete mesh. Fill mesh physical objects are back. --- OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index d361f18..f0c6b99 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -453,6 +453,7 @@ public sealed class BSShapeCollection : IDisposable // If the prim attributes are simple, this could be a simple Bullet native shape if (!haveShape && pbs != null + && !pbs.SculptEntry && nativeShapePossible && ((pbs.SculptEntry && !BSParam.ShouldMeshSculptedPrim) || (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0 -- cgit v1.1 From 939340325396c80e8798ec43361ffd983ce325c9 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 6 Jan 2013 14:01:15 -0800 Subject: BulletSim: update DLLs and SOs with better debugging output. Add definition of hand crafted avatar mesh. Not used yet. Comments and cleanup. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 4 +- OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | 145 +++++++++++++++++++-- .../Region/Physics/BulletSPlugin/BulletSimData.cs | 2 + .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 12 +- 4 files changed, 151 insertions(+), 12 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 13c2539..a9fbc8b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -137,6 +137,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin get { return Type != Vehicle.TYPE_NONE && Prim.IsPhysical; } } + #region Vehicle parameter setting internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) { VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue); @@ -546,6 +547,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f); m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) } + #endregion // Vehicle parameter setting // Some of the properties of this prim may have changed. // Do any updating needed for a vehicle @@ -925,7 +927,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // TODO: Consider taking the rotated size of the object or possibly casting a ray. if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition)) { - // TODO: correct position by applying force rather than forcing position. + // Force position because applying force won't get the vehicle through the terrain Vector3 newPosition = VehiclePosition; newPosition.Z = GetTerrainHeight(VehiclePosition) + 1f; VehiclePosition = newPosition; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs index c75eb9b..cc725e8 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs @@ -27,24 +27,19 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Text; +using OMV = OpenMetaverse; + namespace OpenSim.Region.Physics.BulletSPlugin { public abstract class BSShape { - public IntPtr ptr { get; set; } - public BSPhysicsShapeType type { get; set; } - public System.UInt64 key { get; set; } public int referenceCount { get; set; } public DateTime lastReferenced { get; set; } public BSShape() { - ptr = IntPtr.Zero; - type = BSPhysicsShapeType.SHAPE_UNKNOWN; - key = 0; referenceCount = 0; lastReferenced = DateTime.Now; } @@ -63,7 +58,7 @@ public abstract class BSShape } // Compound shapes are handled special as they are rebuilt from scratch. - // This isn't too great a hardship since most of the child shapes will already been created. + // This isn't too great a hardship since most of the child shapes will have already been created. if (ret == null && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND) { // Getting a reference to a compound shape gets you the compound shape with the root prim shape added @@ -71,6 +66,14 @@ public abstract class BSShape physicsScene.DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, ret); } + // Avatars have their own unique shape + if (ret == null && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_AVATAR) + { + // Getting a reference to a compound shape gets you the compound shape with the root prim shape added + ret = BSShapeAvatar.GetReference(prim); + physicsScene.DetailLog("{0},BSShapeCollection.CreateGeom,avatarShape,shape={1}", prim.LocalID, ret); + } + if (ret == null) ret = GetShapeReferenceNonSpecial(physicsScene, forceRebuild, prim); @@ -228,5 +231,131 @@ public class BSShapeAvatar : BSShape return new BSShapeNull(); } public override void Dereference(BSScene physicsScene) { } + + // From the front: + // A---A + // / \ + // B-------B + // / \ +Z + // C-----------C | + // \ / -Y --+-- +Y + // \ / | + // \ / -Z + // D-----D + // \ / + // E-E + + // From the top A and E are just lines. + // B, C and D are hexagons: + // + // C1--C2 +X + // / \ | + // C0 C3 -Y --+-- +Y + // \ / | + // C5--C4 -X + + // Zero goes directly through the middle so the offsets are from that middle axis + // and up and down from a middle horizon (A and E are the same distance from the zero). + // The height, width and depth is one. All scaling is done by the simulator. + + // Z component -- how far the level is from the middle zero + private const float Aup = 0.5f; + private const float Bup = 0.4f; + private const float Cup = 0.3f; + private const float Dup = -0.4f; + private const float Eup = -0.5f; + + // Y component -- distance from center to x0 and x3 + private const float Awid = 0.25f; + private const float Bwid = 0.3f; + private const float Cwid = 0.5f; + private const float Dwid = 0.3f; + private const float Ewid = 0.2f; + + // Y component -- distance from center to x1, x2, x4 and x5 + private const float Afwid = 0.0f; + private const float Bfwid = 0.2f; + private const float Cfwid = 0.4f; + private const float Dfwid = 0.2f; + private const float Efwid = 0.0f; + + // X component -- distance from zero to the front or back of a level + private const float Adep = 0f; + private const float Bdep = 0.3f; + private const float Cdep = 0.5f; + private const float Ddep = 0.2f; + private const float Edep = 0f; + + private OMV.Vector3[] avatarVertices = { + new OMV.Vector3( 0.0f, -Awid, Aup), // A0 + new OMV.Vector3( 0.0f, +Awid, Aup), // A3 + + new OMV.Vector3( 0.0f, -Bwid, Bup), // B0 + new OMV.Vector3(+Bdep, -Bfwid, Bup), // B1 + new OMV.Vector3(+Bdep, +Bfwid, Bup), // B2 + new OMV.Vector3( 0.0f, +Bwid, Bup), // B3 + new OMV.Vector3(-Bdep, +Bfwid, Bup), // B4 + new OMV.Vector3(-Bdep, -Bfwid, Bup), // B5 + + new OMV.Vector3( 0.0f, -Cwid, Cup), // C0 + new OMV.Vector3(+Cdep, -Cfwid, Cup), // C1 + new OMV.Vector3(+Cdep, +Cfwid, Cup), // C2 + new OMV.Vector3( 0.0f, +Cwid, Cup), // C3 + new OMV.Vector3(-Cdep, +Cfwid, Cup), // C4 + new OMV.Vector3(-Cdep, -Cfwid, Cup), // C5 + + new OMV.Vector3( 0.0f, -Dwid, Dup), // D0 + new OMV.Vector3(+Ddep, -Dfwid, Dup), // D1 + new OMV.Vector3(+Ddep, +Dfwid, Dup), // D2 + new OMV.Vector3( 0.0f, +Dwid, Dup), // D3 + new OMV.Vector3(-Ddep, +Dfwid, Dup), // D4 + new OMV.Vector3(-Ddep, -Dfwid, Dup), // D5 + + new OMV.Vector3( 0.0f, -Ewid, Eup), // E0 + new OMV.Vector3( 0.0f, +Ewid, Eup), // E3 + }; + + // Offsets of the vertices in the vertices array + private enum Ind : int + { + A0, A3, + B0, B1, B2, B3, B4, B5, + C0, C1, C2, C3, C4, C5, + D0, D1, D2, D3, D4, D5, + E0, E3 + } + + // Comments specify trianges and quads in clockwise direction + private Ind[] avatarIndices = { + Ind.A0, Ind.B0, Ind.B1, // A0,B0,B1 + Ind.A0, Ind.B1, Ind.B2, Ind.B2, Ind.A3, Ind.A0, // A0,B1,B2,A3 + Ind.A3, Ind.B2, Ind.B3, // A3,B2,B3 + Ind.A3, Ind.B3, Ind.B4, // A3,B3,B4 + Ind.A3, Ind.B4, Ind.B5, Ind.B5, Ind.A0, Ind.A3, // A3,B4,B5,A0 + Ind.A0, Ind.B5, Ind.B0, // A0,B5,B0 + + Ind.B0, Ind.C0, Ind.C1, Ind.C1, Ind.B1, Ind.B0, // B0,C0,C1,B1 + Ind.B1, Ind.C1, Ind.C2, Ind.C2, Ind.B2, Ind.B1, // B1,C1,C2,B2 + Ind.B2, Ind.C2, Ind.C3, Ind.C3, Ind.B3, Ind.B2, // B2,C2,C3,B3 + Ind.B3, Ind.C3, Ind.C4, Ind.C4, Ind.B4, Ind.B3, // B3,C3,C4,B4 + Ind.B4, Ind.C4, Ind.C5, Ind.C5, Ind.B5, Ind.B4, // B4,C4,C5,B5 + Ind.B5, Ind.C5, Ind.C0, Ind.C0, Ind.B0, Ind.B5, // B5,C5,C0,B0 + + Ind.C0, Ind.D0, Ind.D1, Ind.D1, Ind.C1, Ind.C0, // C0,D0,D1,C1 + Ind.C1, Ind.D1, Ind.D2, Ind.D2, Ind.C2, Ind.C1, // C1,D1,D2,C2 + Ind.C2, Ind.D2, Ind.D3, Ind.D3, Ind.C3, Ind.C2, // C2,D2,D3,C3 + Ind.C3, Ind.D3, Ind.D4, Ind.D4, Ind.C4, Ind.C3, // C3,D3,D4,C4 + Ind.C4, Ind.D4, Ind.D5, Ind.D5, Ind.C5, Ind.C4, // C4,D4,D5,C5 + Ind.C5, Ind.D5, Ind.D0, Ind.D0, Ind.C0, Ind.C5, // C5,D5,D0,C0 + + Ind.E0, Ind.D0, Ind.D1, // E0,D0,D1 + Ind.E0, Ind.D1, Ind.D2, Ind.D2, Ind.E3, Ind.E0, // E0,D1,D2,E3 + Ind.E3, Ind.D2, Ind.D3, // E3,D2,D3 + Ind.E3, Ind.D3, Ind.D4, // E3,D3,D4 + Ind.E3, Ind.D4, Ind.D5, Ind.D5, Ind.E0, Ind.E3, // E3,D4,D5,E0 + Ind.E0, Ind.D5, Ind.D0, // E0,D5,D0 + + }; + } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs index 662dd68..c7a2f7e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs @@ -114,8 +114,10 @@ public class BulletShape public virtual void Clear() { } public virtual bool HasPhysicalShape { get { return false; } } + // Make another reference to this physical object. public virtual BulletShape Clone() { return new BulletShape(); } + // Return 'true' if this and other refer to the same physical object public virtual bool ReferenceSame(BulletShape xx) { return false; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index facf720..7b59e60 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -1,8 +1,6 @@ CURRENT PRIORITIES ================================================= -Redo BulletSimAPI to allow native C# implementation of Bullet option (DONE) -Meshes rendering as bounding boxes -llMoveToTarget +Avatars walking up stairs Vehicle movement on terrain smoothness limitMotorUp calibration (more down?) Preferred orientatino angular correction fix @@ -135,6 +133,9 @@ Eliminate collisions between objects in a linkset. (LinksetConstraint) MORE ====================================================== +Use the HACD convex hull routine in Bullet rather than the C# version. +Do we need to do convex hulls all the time? Can complex meshes be left meshes? + There is some problem with meshes and collisions Test avatar walking up stairs. How does compare with SL. Radius of the capsule affects ability to climb edges. Debounce avatar contact so legs don't keep folding up when standing. @@ -274,3 +275,8 @@ llSetBuoyancy() (DONE) (Resolution: Bullet resets object gravity when added to world. Moved set gravity) Avatar density is WAY off. Compare and calibrate with what's in SL. (DONE) (Resolution: set default density to 3.5 (from 60) which is closer to SL) +Redo BulletSimAPI to allow native C# implementation of Bullet option (DONE) + (Resolution: added BSAPITemplate and then interfaces for C++ Bullet and C# BulletXNA +Meshes rendering as bounding boxes (DONE) + (Resolution: Added test for mesh/sculpties in native shapes so it didn't think it was a box) +llMoveToTarget (Resolution: added simple motor to update the position.) -- cgit v1.1 From 2e5222055ffa1e721221753c26faba342b920712 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 6 Jan 2013 22:56:16 -0800 Subject: BulletSim: comments and removing small compile errors introduced in last commit. --- OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 2 -- OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | 8 ++------ 3 files changed, 3 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index befb076..794ee17 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs @@ -6,7 +6,7 @@ * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD + * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the OpenSimulator Project nor the diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index c215e3a..fe48166 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -58,8 +58,6 @@ public sealed class BSCharacter : BSPhysObject private bool _flying; private bool _setAlwaysRun; private bool _throttleUpdates; - private bool _isColliding; - private bool _collidingObj; private bool _floatOnWater; private OMV.Vector3 _rotationalVelocity; private bool _kinematic; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs index cc725e8..ee18379 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs @@ -95,9 +95,9 @@ public abstract class BSShape // protected abstract static BSShape GetReference(); // Returns a string for debugging that uniquily identifies the memory used by this instance - public string AddrString + public virtual string AddrString { - get { return ptr.ToString("X"); } + get { return "unknown"; } } public override string ToString() @@ -105,10 +105,6 @@ public abstract class BSShape StringBuilder buff = new StringBuilder(); buff.Append(""); -- cgit v1.1 From 599dbc3d9556b7e2693ba61d7e234ef943ebad6d Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 7 Jan 2013 16:04:21 -0800 Subject: BulletSim: fix exception when re-creating the terrain when loading an OAR file --- OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index 1d55ce3..8244f02 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs @@ -142,6 +142,8 @@ public sealed class BSTerrainMesh : BSTerrainPhys PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, m_terrainBody); // Frees both the body and the shape. PhysicsScene.PE.DestroyObject(PhysicsScene.World, m_terrainBody); + m_terrainBody.Clear(); + m_terrainShape.Clear(); } } -- cgit v1.1 From 8452c0a8702ccf7ea045740dd829c69a6f509845 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 7 Jan 2013 16:05:02 -0800 Subject: BulletSim: add function to push avatar up when hitting stairs. It looks like BulletSim and ODE rely on penetration correction to cause the avatar to move up and thus allowing walking up stairs. Object penetration was minimized for walking and flying (so one doesn't go through walls) and this stopped stairs from working. This commit introduces avatar movement code to check for collisions at the feet while walking and attempts to raise the avatar for the steps. Not yet perfect but movement is better. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 97 ++++++++++++++++------ OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 18 ++++ .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 27 ++++++ OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 2 +- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 2 + 5 files changed, 119 insertions(+), 27 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index fe48166..939d38a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -184,10 +184,6 @@ public sealed class BSCharacter : BSPhysObject // standing as well as moving. Destruction of the avatar will destroy the pre-step action. private void SetupMovementMotor() { - - // Someday, use a PID motor for asymmetric speed up and slow down - // _velocityMotor = new BSPIDVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); - // Infinite decay and timescale values so motor only changes current to target values. _velocityMotor = new BSVMotor("BSCharacter.Velocity", 0.2f, // time scale @@ -214,25 +210,68 @@ public sealed class BSCharacter : BSPhysObject // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force. OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass; - /* - // If moveForce is very small, zero things so we don't keep sending microscopic updates to the user - float moveForceMagnitudeSquared = moveForce.LengthSquared(); - if (moveForceMagnitudeSquared < 0.0001) - { - DetailLog("{0},BSCharacter.MoveMotor,zeroMovement,stepVel={1},vel={2},mass={3},magSq={4},moveForce={5}", - LocalID, stepVelocity, _velocity, Mass, moveForceMagnitudeSquared, moveForce); - ForceVelocity = OMV.Vector3.Zero; - } - else - { - AddForce(moveForce, false, true); - } - */ - // DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); + // Should we check for move force being small and forcing velocity to zero? + + // Add special movement force to allow avatars to walk up stepped surfaces. + moveForce += WalkUpStairs(); + + DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce); }); } + // Decide of the character is colliding with a low object and compute a force to pop the + // avatar up so it has a chance of walking up and over the low object. + private OMV.Vector3 WalkUpStairs() + { + OMV.Vector3 ret = OMV.Vector3.Zero; + + // This test is done if moving forward, not flying and is colliding with something. + // DetailLog("{0},BSCharacter.WalkUpStairs,IsColliding={1},flying={2},targSpeed={3},collisions={4}", + // LocalID, IsColliding, Flying, TargetSpeed, CollisionsLastTick.Count); + if (IsColliding && !Flying && TargetSpeed > 0.1f /* && ForwardSpeed < 0.1f */) + { + // The range near the character's feet where we will consider stairs + float nearFeetHeightMin = RawPosition.Z - (Size.Z / 2f) + 0.05f; + float nearFeetHeightMax = nearFeetHeightMin + BSParam.AvatarStepHeight; + + // Look for a collision point that is near the character's feet and is oriented the same as the charactor is + foreach (KeyValuePair kvp in CollisionsLastTick.m_objCollisionList) + { + // Don't care about collisions with the terrain + if (kvp.Key > PhysicsScene.TerrainManager.HighestTerrainID) + { + OMV.Vector3 touchPosition = kvp.Value.Position; + // DetailLog("{0},BSCharacter.WalkUpStairs,min={1},max={2},touch={3}", + // LocalID, nearFeetHeightMin, nearFeetHeightMax, touchPosition); + if (touchPosition.Z >= nearFeetHeightMin && touchPosition.Z <= nearFeetHeightMax) + { + // This contact is within the 'near the feet' range. + // The normal should be our contact point to the object so it is pointing away + // thus the difference between our facing orientation and the normal should be small. + OMV.Vector3 directionFacing = OMV.Vector3.UnitX * RawOrientation; + OMV.Vector3 touchNormal = OMV.Vector3.Normalize(kvp.Value.SurfaceNormal); + float diff = Math.Abs(OMV.Vector3.Distance(directionFacing, touchNormal)); + if (diff < BSParam.AvatarStepApproachFactor) + { + // Found the stairs contact point. Push up a little to raise the character. + float upForce = (touchPosition.Z - nearFeetHeightMin) * Mass * BSParam.AvatarStepForceFactor; + ret = new OMV.Vector3(0f, 0f, upForce); + + // Also move the avatar up for the new height + OMV.Vector3 displacement = new OMV.Vector3(0f, 0f, BSParam.AvatarStepHeight / 2f); + ForcePosition = RawPosition + displacement; + } + DetailLog("{0},BSCharacter.WalkUpStairs,touchPos={1},nearFeetMin={2},faceDir={3},norm={4},diff={5},ret={6}", + LocalID, touchPosition, nearFeetHeightMin, directionFacing, touchNormal, diff, ret); + } + } + } + } + + return ret; + } + public override void RequestPhysicsterseUpdate() { base.RequestPhysicsterseUpdate(); @@ -342,13 +381,11 @@ public sealed class BSCharacter : BSPhysObject } set { _position = value; - PositionSanityCheck(); PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate() { DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); - if (PhysBody.HasPhysicalBody) - PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); + ForcePosition = _position; }); } } @@ -359,8 +396,11 @@ public sealed class BSCharacter : BSPhysObject } set { _position = value; - PositionSanityCheck(); - PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); + if (PhysBody.HasPhysicalBody) + { + PositionSanityCheck(); + PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); + } } } @@ -373,7 +413,7 @@ public sealed class BSCharacter : BSPhysObject bool ret = false; // TODO: check for out of bounds - if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position)) + if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition)) { // The character is out of the known/simulated area. // Upper levels of code will handle the transition to other areas so, for @@ -382,7 +422,7 @@ public sealed class BSCharacter : BSPhysObject } // If below the ground, move the avatar up - float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); + float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition); if (Position.Z < terrainHeight) { DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); @@ -485,6 +525,11 @@ public sealed class BSCharacter : BSPhysObject }); } } + public override OMV.Vector3 RawVelocity + { + get { return _velocity; } + set { _velocity = value; } + } // Directly setting velocity means this is what the user really wants now. public override OMV.Vector3 Velocity { get { return _velocity; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index b9bd0bf..23d573f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -75,6 +75,9 @@ public static class BSParam public static float AvatarCapsuleDepth { get; private set; } public static float AvatarCapsuleHeight { get; private set; } public static float AvatarContactProcessingThreshold { get; private set; } + public static float AvatarStepHeight { get; private set; } + public static float AvatarStepApproachFactor { get; private set; } + public static float AvatarStepForceFactor { get; private set; } public static float VehicleAngularDamping { get; private set; } @@ -403,6 +406,21 @@ public static class BSParam (s,cf,p,v) => { AvatarContactProcessingThreshold = cf.GetFloat(p, v); }, (s) => { return AvatarContactProcessingThreshold; }, (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarContactProcessingThreshold=x;}, p, l, v); } ), + new ParameterDefn("AvatarStepHeight", "Height of a step obstacle to consider step correction", + 0.3f, + (s,cf,p,v) => { AvatarStepHeight = cf.GetFloat(p, v); }, + (s) => { return AvatarStepHeight; }, + (s,p,l,v) => { AvatarStepHeight = v; } ), + new ParameterDefn("AvatarStepApproachFactor", "Factor to control angle of approach to step (0=straight on)", + 0.6f, + (s,cf,p,v) => { AvatarStepApproachFactor = cf.GetFloat(p, v); }, + (s) => { return AvatarStepApproachFactor; }, + (s,p,l,v) => { AvatarStepApproachFactor = v; } ), + new ParameterDefn("AvatarStepForceFactor", "Controls the amount of force up applied to step up onto a step", + 2.0f, + (s,cf,p,v) => { AvatarStepForceFactor = cf.GetFloat(p, v); }, + (s) => { return AvatarStepForceFactor; }, + (s,p,l,v) => { AvatarStepForceFactor = v; } ), new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", 0.95f, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 534f929..e8575f6 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -79,6 +79,7 @@ public abstract class BSPhysObject : PhysicsActor Material = MaterialAttributes.Material.Wood; CollisionCollection = new CollisionEventUpdate(); + CollisionsLastTick = CollisionCollection; SubscribedEventsMs = 0; CollidingStep = 0; CollidingGroundStep = 0; @@ -159,6 +160,7 @@ public abstract class BSPhysObject : PhysicsActor public abstract OMV.Quaternion ForceOrientation { get; set; } // The system is telling us the velocity it wants to move at. + // Velocity in world coordinates. // protected OMV.Vector3 m_targetVelocity; // use the definition in PhysicsActor public override OMV.Vector3 TargetVelocity { @@ -169,6 +171,15 @@ public abstract class BSPhysObject : PhysicsActor Velocity = value; } } + public virtual float TargetSpeed + { + get + { + OMV.Vector3 characterOrientedVelocity = TargetVelocity * OMV.Quaternion.Inverse(OMV.Quaternion.Normalize(RawOrientation)); + return characterOrientedVelocity.X; + } + } + public abstract OMV.Vector3 RawVelocity { get; set; } public abstract OMV.Vector3 ForceVelocity { get; set; } public abstract OMV.Vector3 ForceRotationalVelocity { get; set; } @@ -177,6 +188,15 @@ public abstract class BSPhysObject : PhysicsActor public virtual bool ForceBodyShapeRebuild(bool inTaintTime) { return false; } + public virtual float ForwardSpeed + { + get + { + OMV.Vector3 characterOrientedVelocity = RawVelocity * OMV.Quaternion.Inverse(OMV.Quaternion.Normalize(RawOrientation)); + return characterOrientedVelocity.X; + } + } + #region Collisions // Requested number of milliseconds between collision events. Zero means disabled. @@ -223,9 +243,13 @@ public abstract class BSPhysObject : PhysicsActor // The collisions that have been collected this tick protected CollisionEventUpdate CollisionCollection; + // Remember collisions from last tick for fancy collision based actions + // (like a BSCharacter walking up stairs). + protected CollisionEventUpdate CollisionsLastTick; // The simulation step is telling this object about a collision. // Return 'true' if a collision was processed and should be sent up. + // Return 'false' if this object is not enabled/subscribed/appropriate for or has already seen this collision. // Called at taint time from within the Step() function public virtual bool Collide(uint collidingWith, BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) @@ -286,6 +310,9 @@ public abstract class BSPhysObject : PhysicsActor // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count); base.SendCollisionUpdate(CollisionCollection); + // Remember the collisions from this tick for some collision specific processing. + CollisionsLastTick = CollisionCollection; + // The CollisionCollection instance is passed around in the simulator. // Make sure we don't have a handle to that one and that a new one is used for next time. // This fixes an interesting 'gotcha'. If we call CollisionCollection.Clear() here, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 94b63e5..400d5d6 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -562,7 +562,7 @@ public sealed class BSPrim : BSPhysObject } return; } - public OMV.Vector3 RawVelocity + public override OMV.Vector3 RawVelocity { get { return _velocity; } set { _velocity = value; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 7b59e60..794a6af 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -88,6 +88,8 @@ setForce should set a constant force. Different than AddImpulse. Implement raycast. Implement ShapeCollection.Dispose() Implement water as a plain so raycasting and collisions can happen with same. +Add collision penetration return + Add field passed back by BulletSim.dll and fill with info in ManifoldConstact.GetDistance() Add osGetPhysicsEngineName() so scripters can tell whether BulletSim or ODE Also osGetPhysicsEngineVerion() maybe. Linkset.Position and Linkset.Orientation requre rewrite to properly return -- cgit v1.1 From 1603606f1d8bd62574cf98e051877d836cbeb012 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 7 Jan 2013 22:00:50 -0800 Subject: BulletSim: improve vehicle angular banking and deflection computation. Rotate angular correction forces to be world relative rather than vehicle relative. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 37 +++++++++++----------- 1 file changed, 18 insertions(+), 19 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index a9fbc8b..eb695d9 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -1111,6 +1111,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin + deflectionContribution + bankingContribution; + // Add of the above computation are made relative to vehicle coordinates. + // Convert to world coordinates. + m_lastAngularVelocity *= VehicleOrientation; + // ================================================================== // Apply the correction velocity. // TODO: Should this be applied as an angular force (torque)? @@ -1222,14 +1226,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin public Vector3 ComputeAngularDeflection() { Vector3 ret = Vector3.Zero; - return ret; // DEBUG DEBUG DEBUG - // Disable angular deflection for the moment. + // Since angularMotorUp and angularDeflection are computed independently, they will calculate // approximately the same X or Y correction. When added together (when contributions are combined) // this creates an over-correction and then wabbling as the target is overshot. // TODO: rethink how the different correction computations inter-relate. - if (m_angularDeflectionEfficiency != 0) + if (m_angularDeflectionEfficiency != 0 && VehicleVelocity != Vector3.Zero) { // The direction the vehicle is moving Vector3 movingDirection = VehicleVelocity; @@ -1298,33 +1301,29 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) { - // This works by rotating a unit vector to the orientation of the vehicle. The - // roll (tilt) will be Y component of a tilting Z vector (zero for no tilt - // up to one for full over). + // Rotate a UnitZ vector (pointing up) to how the vehicle is oriented. + // As the vehicle rolls to the right or left, the Y value will increase from + // zero (straight up) to 1 or -1 (full tilt right or left) Vector3 rollComponents = Vector3.UnitZ * VehicleOrientation; - + // Figure out the yaw value for this much roll. - float turnComponent = rollComponents.Y * rollComponents.Y * m_bankingEfficiency; - // Keep the sign - if (rollComponents.Y < 0f) - turnComponent = -turnComponent; - - // TODO: there must be a better computation of the banking force. - float bankingTurnForce = turnComponent; + // Squared because that seems to give a good value + float yawAngle = (float)Math.Asin(rollComponents.Y * rollComponents.Y) * m_bankingEfficiency; // actual error = static turn error + dynamic turn error - float mixedBankingError = bankingTurnForce * (1f - m_bankingMix) + bankingTurnForce * m_bankingMix * VehicleForwardSpeed; + float mixedYawAngle = yawAngle * (1f - m_bankingMix) + yawAngle * m_bankingMix * VehicleForwardSpeed; + // TODO: the banking effect should not go to infinity but what to limit it to? - mixedBankingError = ClampInRange(-20f, mixedBankingError, 20f); + mixedYawAngle = ClampInRange(-20f, mixedYawAngle, 20f); // Build the force vector to change rotation from what it is to what it should be - ret.Z = -mixedBankingError; + ret.Z = -mixedYawAngle; // Don't do it all at once. ret /= m_bankingTimescale; - VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},turnComp={3},bankErr={4},mixedBankErr={5},ret={6}", - Prim.LocalID, rollComponents, VehicleForwardSpeed, turnComponent, bankingTurnForce, mixedBankingError, ret); + VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},rollComp={3},yAng={4},mYAng={5},ret={6}", + Prim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, ret); } return ret; } -- cgit v1.1 From 2ac96dd1813fa90907ef589b98a9bf68f0ab2e9f Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 8 Jan 2013 22:52:14 +0000 Subject: Add the new UpdateAgentInformation cap to make maturity on more recent viewers work. --- .../Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index cc69645..a534522 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -96,8 +96,8 @@ namespace OpenSim.Region.ClientStack.Linden // private static readonly string m_fetchInventoryPath = "0006/"; private static readonly string m_copyFromNotecardPath = "0007/"; // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule. - - + private static readonly string m_UpdateAgentInformationPath = "0500/"; + // These are callbacks which will be setup by the scene so that we can update scene data when we // receive capability calls public NewInventoryItem AddNewInventoryItem = null; @@ -204,6 +204,8 @@ namespace OpenSim.Region.ClientStack.Linden m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req); m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req); m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req); + IRequestHandler UpdateAgentInformationHandler = new RestStreamHandler("POST", capsBase + m_UpdateAgentInformationPath, UpdateAgentInformation); + m_HostCapsObj.RegisterHandler("UpdateAgentInformation", UpdateAgentInformationHandler); m_HostCapsObj.RegisterHandler( "CopyInventoryFromNotecard", @@ -855,6 +857,22 @@ namespace OpenSim.Region.ClientStack.Linden response["int_response_code"] = 200; return LLSDHelpers.SerialiseLLSDReply(response); } + + public string UpdateAgentInformation(string request, string path, + string param, IOSHttpRequest httpRequest, + IOSHttpResponse httpResponse) + { + OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request); + OSDMap resp = new OSDMap(); + + OSDMap accessPrefs = new OSDMap(); + accessPrefs["max"] = "A"; + + resp["access_prefs"] = accessPrefs; + + string response = OSDParser.SerializeLLSDXmlString(resp); + return response; + } } public class AssetUploader -- cgit v1.1 From 5561333668f61f043cdfc0733a4eb50a1bcfb14e Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 8 Jan 2013 23:01:09 +0100 Subject: Prevent empty Anim Packs --- OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs index 65ae445..d2fc7f1 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs @@ -164,7 +164,13 @@ namespace OpenSim.Region.Framework.Scenes.Animation { int defaultSize = 0; if (m_defaultAnimation.AnimID != UUID.Zero) + { + defaultSize++; + } + else if (m_animations.Count == 0) + { defaultSize++; + } animIDs = new UUID[m_animations.Count + defaultSize]; sequenceNums = new int[m_animations.Count + defaultSize]; @@ -176,6 +182,12 @@ namespace OpenSim.Region.Framework.Scenes.Animation sequenceNums[0] = m_defaultAnimation.SequenceNum; objectIDs[0] = m_defaultAnimation.ObjectID; } + else if (m_animations.Count == 0) + { + animIDs[0] = m_implicitDefaultAnimation.AnimID; + sequenceNums[0] = m_defaultAnimation.SequenceNum; + objectIDs[0] = m_implicitDefaultAnimation.ObjectID; + } for (int i = 0; i < m_animations.Count; ++i) { -- cgit v1.1 From a775931a0cec9f65748c6e20dd2695edcbe21b7f Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 8 Jan 2013 23:24:34 +0100 Subject: Fix sequence id fr default anim --- OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs index d2fc7f1..64c31f8 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs @@ -185,7 +185,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation else if (m_animations.Count == 0) { animIDs[0] = m_implicitDefaultAnimation.AnimID; - sequenceNums[0] = m_defaultAnimation.SequenceNum; + sequenceNums[0] = m_implicitDefaultAnimation.SequenceNum; objectIDs[0] = m_implicitDefaultAnimation.ObjectID; } -- cgit v1.1 From 5fa4b8b1445829af66a63869672b76624d51a525 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 9 Jan 2013 00:01:48 +0000 Subject: minor: Allow "script *" console commands to take multiple script item ids --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 62 +++++++++++++------------- 1 file changed, 32 insertions(+), 30 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 79cec04..ba63bb6 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -324,40 +324,40 @@ namespace OpenSim.Region.ScriptEngine.XEngine HandleShowStatus); MainConsole.Instance.Commands.AddCommand( - "Scripts", false, "scripts show", "scripts show []", "Show script information", + "Scripts", false, "scripts show", "scripts show [+]", "Show script information", "Show information on all scripts known to the script engine.\n" - + "If a is given then only information on that script will be shown.", + + "If one or more s are given then only information on that script will be shown.", HandleShowScripts); MainConsole.Instance.Commands.AddCommand( - "Scripts", false, "show scripts", "show scripts []", "Show script information", + "Scripts", false, "show scripts", "show scripts [+]", "Show script information", "Synonym for scripts show command", HandleShowScripts); MainConsole.Instance.Commands.AddCommand( - "Scripts", false, "scripts suspend", "scripts suspend []", "Suspends all running scripts", + "Scripts", false, "scripts suspend", "scripts suspend [+]", "Suspends all running scripts", "Suspends all currently running scripts. This only suspends event delivery, it will not suspend a" + " script that is currently processing an event.\n" + "Suspended scripts will continue to accumulate events but won't process them.\n" - + "If a is given then only that script will be suspended. Otherwise, all suitable scripts are suspended.", + + "If one or more s are given then only that script will be suspended. Otherwise, all suitable scripts are suspended.", (module, cmdparams) => HandleScriptsAction(cmdparams, HandleSuspendScript)); MainConsole.Instance.Commands.AddCommand( - "Scripts", false, "scripts resume", "scripts resume []", "Resumes all suspended scripts", + "Scripts", false, "scripts resume", "scripts resume [+]", "Resumes all suspended scripts", "Resumes all currently suspended scripts.\n" + "Resumed scripts will process all events accumulated whilst suspended.\n" - + "If a is given then only that script will be resumed. Otherwise, all suitable scripts are resumed.", + + "If one or more s are given then only that script will be resumed. Otherwise, all suitable scripts are resumed.", (module, cmdparams) => HandleScriptsAction(cmdparams, HandleResumeScript)); MainConsole.Instance.Commands.AddCommand( - "Scripts", false, "scripts stop", "scripts stop []", "Stops all running scripts", + "Scripts", false, "scripts stop", "scripts stop [+]", "Stops all running scripts", "Stops all running scripts.\n" - + "If a is given then only that script will be stopped. Otherwise, all suitable scripts are stopped.", + + "If one or more s are given then only that script will be stopped. Otherwise, all suitable scripts are stopped.", (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStopScript)); MainConsole.Instance.Commands.AddCommand( - "Scripts", false, "scripts start", "scripts start []", "Starts all stopped scripts", + "Scripts", false, "scripts start", "scripts start [+]", "Starts all stopped scripts", "Starts all stopped scripts.\n" - + "If a is given then only that script will be started. Otherwise, all suitable scripts are started.", + + "If one or more s are given then only that script will be started. Otherwise, all suitable scripts are started.", (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStartScript)); MainConsole.Instance.Commands.AddCommand( @@ -478,29 +478,31 @@ namespace OpenSim.Region.ScriptEngine.XEngine return; } - rawItemId = cmdparams[2]; - - if (!UUID.TryParse(rawItemId, out itemId)) + for (int i = 2; i < cmdparams.Length; i++) { - MainConsole.Instance.OutputFormat("ERROR: {0} is not a valid UUID", rawItemId); - return; - } - - if (itemId != UUID.Zero) - { - IScriptInstance instance = GetInstance(itemId); - if (instance == null) + rawItemId = cmdparams[i]; + + if (!UUID.TryParse(rawItemId, out itemId)) { - // Commented out for now since this will cause false reports on simulators with more than - // one scene where the current command line set region is 'root' (which causes commands to - // go to both regions... (sigh) -// MainConsole.Instance.OutputFormat("Error - No item found with id {0}", itemId); - return; + MainConsole.Instance.OutputFormat("ERROR: {0} is not a valid UUID", rawItemId); + continue; } - else + + if (itemId != UUID.Zero) { - action(instance); - return; + IScriptInstance instance = GetInstance(itemId); + if (instance == null) + { + // Commented out for now since this will cause false reports on simulators with more than + // one scene where the current command line set region is 'root' (which causes commands to + // go to both regions... (sigh) + // MainConsole.Instance.OutputFormat("Error - No item found with id {0}", itemId); + continue; + } + else + { + action(instance); + } } } } -- cgit v1.1 From 3d5e3e35b799fe777066ac0cb27cf1bd3e104651 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 9 Jan 2013 00:08:08 +0000 Subject: minor: Fix command match of "debug script" command to "debug scripts" to match other scripts commands (and it's own short help text) --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index ba63bb6..4bbcb7c 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -361,7 +361,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStartScript)); MainConsole.Instance.Commands.AddCommand( - "Scripts", false, "debug script log", "debug scripts log ", "Extra debug logging for a script", + "Scripts", false, "debug scripts log", "debug scripts log ", "Extra debug logging for a script", "Activates or deactivates extra debug logging for the given script.\n" + "Level == 0, deactivate extra debug logging.\n" + "Level >= 1, log state changes.\n" -- cgit v1.1 From c1c540f454b0c9fd189ed768764fb8a51ee773c6 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 9 Jan 2013 00:20:14 +0000 Subject: Revert "Fix sequence id fr default anim" This reverts commit a775931a0cec9f65748c6e20dd2695edcbe21b7f. --- OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs index 64c31f8..d2fc7f1 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs @@ -185,7 +185,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation else if (m_animations.Count == 0) { animIDs[0] = m_implicitDefaultAnimation.AnimID; - sequenceNums[0] = m_implicitDefaultAnimation.SequenceNum; + sequenceNums[0] = m_defaultAnimation.SequenceNum; objectIDs[0] = m_implicitDefaultAnimation.ObjectID; } -- cgit v1.1 From f16c4a254c263a7fd75799fe79da6b3d0a1c80a2 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 9 Jan 2013 00:20:24 +0000 Subject: Revert "Prevent empty Anim Packs" This reverts commit 5561333668f61f043cdfc0733a4eb50a1bcfb14e. --- OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs index d2fc7f1..65ae445 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs @@ -164,13 +164,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation { int defaultSize = 0; if (m_defaultAnimation.AnimID != UUID.Zero) - { - defaultSize++; - } - else if (m_animations.Count == 0) - { defaultSize++; - } animIDs = new UUID[m_animations.Count + defaultSize]; sequenceNums = new int[m_animations.Count + defaultSize]; @@ -182,12 +176,6 @@ namespace OpenSim.Region.Framework.Scenes.Animation sequenceNums[0] = m_defaultAnimation.SequenceNum; objectIDs[0] = m_defaultAnimation.ObjectID; } - else if (m_animations.Count == 0) - { - animIDs[0] = m_implicitDefaultAnimation.AnimID; - sequenceNums[0] = m_defaultAnimation.SequenceNum; - objectIDs[0] = m_implicitDefaultAnimation.ObjectID; - } for (int i = 0; i < m_animations.Count; ++i) { -- cgit v1.1 From df1d7414adbf329e139201cdb7578c7b64bb50c8 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 8 Jan 2013 16:09:15 -0800 Subject: BulletSim: Fix hover height (boats float at the correct level). Fix problem of vehicles going crazy when backing up. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 16 ++++++++++------ OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | 4 ++-- 2 files changed, 12 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index eb695d9..c34c05a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -856,6 +856,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // The movement computed in the linear motor is relative to the vehicle // coordinates. Rotate the movement to world coordinates. linearMotorContribution *= VehicleOrientation; + // All the contributions after this are world relative (mostly Z modifications) // ================================================================== // Buoyancy: force to overcome gravity. @@ -982,14 +983,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; // TODO: implement m_VhoverEfficiency correctly - if (Math.Abs(verticalError) > m_VhoverEfficiency) - { - ret = new Vector3(0f, 0f, verticalCorrectionVelocity); - } + ret = new Vector3(0f, 0f, verticalCorrectionVelocity); } - VDetailLog("{0}, MoveLinear,hover,pos={1},ret={2},hoverTS={3},height={4},target={5}", - Prim.LocalID, VehiclePosition, ret, m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight); + VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},ret={6}", + Prim.LocalID, VehiclePosition, m_VhoverEfficiency, m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight, ret); } return ret; @@ -1238,6 +1236,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 movingDirection = VehicleVelocity; movingDirection.Normalize(); + // If the vehicle is going backward, it is still pointing forward + movingDirection *= Math.Sign(VehicleForwardSpeed); + // The direction the vehicle is pointing Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation; pointingDirection.Normalize(); @@ -1246,6 +1247,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 deflectionError = movingDirection - pointingDirection; // Don't try to correct very large errors (not our job) + // if (Math.Abs(deflectionError.X) > PIOverFour) deflectionError.X = PIOverTwo * Math.Sign(deflectionError.X); + // if (Math.Abs(deflectionError.Y) > PIOverFour) deflectionError.Y = PIOverTwo * Math.Sign(deflectionError.Y); + // if (Math.Abs(deflectionError.Z) > PIOverFour) deflectionError.Z = PIOverTwo * Math.Sign(deflectionError.Z); if (Math.Abs(deflectionError.X) > PIOverFour) deflectionError.X = 0f; if (Math.Abs(deflectionError.Y) > PIOverFour) deflectionError.Y = 0f; if (Math.Abs(deflectionError.Z) > PIOverFour) deflectionError.Z = 0f; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 794a6af..29bd4e4 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -1,9 +1,9 @@ CURRENT PRIORITIES ================================================= -Avatars walking up stairs +Avatars walking up stairs (HALF DONE) Vehicle movement on terrain smoothness limitMotorUp calibration (more down?) -Preferred orientatino angular correction fix +Preferred orientation angular correction fix Surfboard go wonky when turning Angular motor direction is global coordinates rather than local coordinates? Boats float low in the water -- cgit v1.1 From a0000a034f3d193662d56a1c8147771b0d994b23 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 10 Jan 2013 00:32:22 +0000 Subject: Add "show sensors" command to show script sensor information for debug purposes. --- .../Api/Implementation/Plugins/SensorRepeat.cs | 94 ++++++++++++++-------- .../XEngine/ScriptEngineConsoleCommands.cs | 86 ++++++++++++++++++++ OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 5 ++ 3 files changed, 153 insertions(+), 32 deletions(-) create mode 100644 OpenSim/Region/ScriptEngine/XEngine/ScriptEngineConsoleCommands.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs index 24cceea..37422d7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs @@ -42,6 +42,41 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + /// + /// Used by one-off and repeated sensors + /// + public class SensorInfo + { + public uint localID; + public UUID itemID; + public double interval; + public DateTime next; + + public string name; + public UUID keyID; + public int type; + public double range; + public double arc; + public SceneObjectPart host; + + public SensorInfo Clone() + { + SensorInfo s = new SensorInfo(); + s.localID = localID; + s.itemID = itemID; + s.interval = interval; + s.next = next; + s.name = name; + s.keyID = keyID; + s.type = type; + s.range = range; + s.arc = arc; + s.host = host; + + return s; + } + } + public AsyncCommandManager m_CmdManager; /// @@ -79,24 +114,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins private int maximumToReturn = 16; // - // SenseRepeater and Sensors - // - private class SenseRepeatClass - { - public uint localID; - public UUID itemID; - public double interval; - public DateTime next; - - public string name; - public UUID keyID; - public int type; - public double range; - public double arc; - public SceneObjectPart host; - } - - // // Sensed entity // private class SensedEntity : IComparable @@ -128,7 +145,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins /// /// Always lock SenseRepeatListLock when updating this list. /// - private List SenseRepeaters = new List(); + private List SenseRepeaters = new List(); private object SenseRepeatListLock = new object(); public void SetSenseRepeatEvent(uint m_localID, UUID m_itemID, @@ -142,7 +159,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins return; // Add to timer - SenseRepeatClass ts = new SenseRepeatClass(); + SensorInfo ts = new SensorInfo(); ts.localID = m_localID; ts.itemID = m_itemID; ts.interval = sec; @@ -161,11 +178,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins AddSenseRepeater(ts); } - private void AddSenseRepeater(SenseRepeatClass senseRepeater) + private void AddSenseRepeater(SensorInfo senseRepeater) { lock (SenseRepeatListLock) { - List newSenseRepeaters = new List(SenseRepeaters); + List newSenseRepeaters = new List(SenseRepeaters); newSenseRepeaters.Add(senseRepeater); SenseRepeaters = newSenseRepeaters; } @@ -176,8 +193,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins // Remove from timer lock (SenseRepeatListLock) { - List newSenseRepeaters = new List(); - foreach (SenseRepeatClass ts in SenseRepeaters) + List newSenseRepeaters = new List(); + foreach (SensorInfo ts in SenseRepeaters) { if (ts.localID != m_localID || ts.itemID != m_itemID) { @@ -192,7 +209,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins public void CheckSenseRepeaterEvents() { // Go through all timers - foreach (SenseRepeatClass ts in SenseRepeaters) + foreach (SensorInfo ts in SenseRepeaters) { // Time has passed? if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime()) @@ -209,7 +226,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins double range, double arc, SceneObjectPart host) { // Add to timer - SenseRepeatClass ts = new SenseRepeatClass(); + SensorInfo ts = new SensorInfo(); ts.localID = m_localID; ts.itemID = m_itemID; ts.interval = 0; @@ -225,7 +242,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins SensorSweep(ts); } - private void SensorSweep(SenseRepeatClass ts) + private void SensorSweep(SensorInfo ts) { if (ts.host == null) { @@ -301,7 +318,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins } } - private List doObjectSensor(SenseRepeatClass ts) + private List doObjectSensor(SensorInfo ts) { List Entities; List sensedEntities = new List(); @@ -450,7 +467,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins return sensedEntities; } - private List doAgentSensor(SenseRepeatClass ts) + private List doAgentSensor(SensorInfo ts) { List sensedEntities = new List(); @@ -626,7 +643,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins { List data = new List(); - foreach (SenseRepeatClass ts in SenseRepeaters) + foreach (SensorInfo ts in SenseRepeaters) { if (ts.itemID == itemID) { @@ -656,7 +673,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins while (idx < data.Length) { - SenseRepeatClass ts = new SenseRepeatClass(); + SensorInfo ts = new SensorInfo(); ts.localID = localID; ts.itemID = itemID; @@ -677,5 +694,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins idx += 6; } } + + public List GetSensorInfo() + { + List retList = new List(); + + lock (SenseRepeatListLock) + { + foreach (SensorInfo si in SenseRepeaters) + retList.Add(si.Clone()); + } + + return retList; + } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/XEngine/ScriptEngineConsoleCommands.cs b/OpenSim/Region/ScriptEngine/XEngine/ScriptEngineConsoleCommands.cs new file mode 100644 index 0000000..e47917d --- /dev/null +++ b/OpenSim/Region/ScriptEngine/XEngine/ScriptEngineConsoleCommands.cs @@ -0,0 +1,86 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Region.ScriptEngine.Interfaces; +using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; + +namespace OpenSim.Region.ScriptEngine.XEngine +{ + public class ScriptEngineConsoleCommands + { + IScriptEngine m_engine; + + public ScriptEngineConsoleCommands(IScriptEngine engine) + { + m_engine = engine; + } + + public void RegisterCommands() + { + MainConsole.Instance.Commands.AddCommand( + "Scripts", false, "show sensors", "show sensors", "Show script sensors information", + HandleShowSensors); + } + + private void HandleShowSensors(string module, string[] cmdparams) + { + if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_engine.World)) + return; + + SensorRepeat sr = AsyncCommandManager.GetSensorRepeatPlugin(m_engine); + + if (sr == null) + { + MainConsole.Instance.Output("Sensor plugin not yet initialized"); + return; + } + + List sensorInfo = sr.GetSensorInfo(); + + ConsoleDisplayTable cdt = new ConsoleDisplayTable(); + cdt.AddColumn("Part name", 40); + cdt.AddColumn("Script item ID", 36); + cdt.AddColumn("Type", 4); + cdt.AddColumn("Interval", 8); + cdt.AddColumn("Range", 8); + cdt.AddColumn("Arc", 8); + + foreach (SensorRepeat.SensorInfo s in sensorInfo) + { + cdt.AddRow(s.host.Name, s.itemID, s.type, s.interval, s.range, s.arc); + } + + MainConsole.Instance.Output(cdt.ToString()); + MainConsole.Instance.OutputFormat("Total: {0}", sensorInfo.Count); + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 4bbcb7c..8c3bb5b 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -169,6 +169,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine IWorkItemResult m_CurrentCompile = null; private Dictionary m_CompileDict = new Dictionary(); + private ScriptEngineConsoleCommands m_consoleCommands; + public string ScriptEngineName { get { return "XEngine"; } @@ -318,6 +320,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine OnObjectRemoved += m_XmlRpcRouter.ObjectRemoved; } + m_consoleCommands = new ScriptEngineConsoleCommands(this); + m_consoleCommands.RegisterCommands(); + MainConsole.Instance.Commands.AddCommand( "Scripts", false, "xengine status", "xengine status", "Show status information", "Show status information on the script engine.", -- cgit v1.1 From b1b46872500476cf97b5de8c16012b8545fed0c7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 10 Jan 2013 00:57:49 +0000 Subject: Add "show script timers" command to show script timers. For debug purposes. Also, "show sensors" changes to "show script sensors". --- .../Api/Implementation/Plugins/SensorRepeat.cs | 18 ++------ .../Shared/Api/Implementation/Plugins/Timer.cs | 52 +++++++++++++++------- .../XEngine/ScriptEngineConsoleCommands.cs | 46 +++++++++++++++++-- 3 files changed, 81 insertions(+), 35 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs index 37422d7..dd45406 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs @@ -61,19 +61,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins public SensorInfo Clone() { - SensorInfo s = new SensorInfo(); - s.localID = localID; - s.itemID = itemID; - s.interval = interval; - s.next = next; - s.name = name; - s.keyID = keyID; - s.type = type; - s.range = range; - s.arc = arc; - s.host = host; - - return s; + return (SensorInfo)this.MemberwiseClone(); } } @@ -701,8 +689,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins lock (SenseRepeatListLock) { - foreach (SensorInfo si in SenseRepeaters) - retList.Add(si.Clone()); + foreach (SensorInfo i in SenseRepeaters) + retList.Add(i.Clone()); } return retList; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs index bc63030..0b14565 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs @@ -35,6 +35,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins { public class Timer { + public class TimerInfo + { + public uint localID; + public UUID itemID; + //public double interval; + public long interval; + //public DateTime next; + public long next; + + public TimerInfo Clone() + { + return (TimerInfo)this.MemberwiseClone(); + } + } + public AsyncCommandManager m_CmdManager; public int TimersCount @@ -59,17 +74,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins return localID.ToString() + itemID.ToString(); } - private class TimerClass - { - public uint localID; - public UUID itemID; - //public double interval; - public long interval; - //public DateTime next; - public long next; - } - - private Dictionary Timers = new Dictionary(); + private Dictionary Timers = new Dictionary(); private object TimerListLock = new object(); public void SetTimerEvent(uint m_localID, UUID m_itemID, double sec) @@ -81,7 +86,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins } // Add to timer - TimerClass ts = new TimerClass(); + TimerInfo ts = new TimerInfo(); ts.localID = m_localID; ts.itemID = m_itemID; ts.interval = Convert.ToInt64(sec * 10000000); // How many 100 nanoseconds (ticks) should we wait @@ -121,8 +126,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins lock (TimerListLock) { // Go through all timers - Dictionary.ValueCollection tvals = Timers.Values; - foreach (TimerClass ts in tvals) + Dictionary.ValueCollection tvals = Timers.Values; + foreach (TimerInfo ts in tvals) { // Time has passed? if (ts.next < DateTime.Now.Ticks) @@ -147,8 +152,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins lock (TimerListLock) { - Dictionary.ValueCollection tvals = Timers.Values; - foreach (TimerClass ts in tvals) + Dictionary.ValueCollection tvals = Timers.Values; + foreach (TimerInfo ts in tvals) { if (ts.itemID == itemID) { @@ -167,7 +172,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins while (idx < data.Length) { - TimerClass ts = new TimerClass(); + TimerInfo ts = new TimerInfo(); ts.localID = localID; ts.itemID = itemID; @@ -181,5 +186,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins } } } + + public List GetTimersInfo() + { + List retList = new List(); + + lock (TimerListLock) + { + foreach (TimerInfo i in Timers.Values) + retList.Add(i.Clone()); + } + + return retList; + } } } diff --git a/OpenSim/Region/ScriptEngine/XEngine/ScriptEngineConsoleCommands.cs b/OpenSim/Region/ScriptEngine/XEngine/ScriptEngineConsoleCommands.cs index e47917d..efb854d 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/ScriptEngineConsoleCommands.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/ScriptEngineConsoleCommands.cs @@ -47,20 +47,29 @@ namespace OpenSim.Region.ScriptEngine.XEngine public void RegisterCommands() { MainConsole.Instance.Commands.AddCommand( - "Scripts", false, "show sensors", "show sensors", "Show script sensors information", + "Scripts", false, "show script sensors", "show script sensors", "Show script sensors information", HandleShowSensors); + + MainConsole.Instance.Commands.AddCommand( + "Scripts", false, "show script timers", "show script timers", "Show script sensors information", + HandleShowTimers); + } + + private bool IsSceneSelected() + { + return MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_engine.World; } private void HandleShowSensors(string module, string[] cmdparams) { - if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_engine.World)) + if (!IsSceneSelected()) return; SensorRepeat sr = AsyncCommandManager.GetSensorRepeatPlugin(m_engine); if (sr == null) { - MainConsole.Instance.Output("Sensor plugin not yet initialized"); + MainConsole.Instance.Output("Plugin not yet initialized"); return; } @@ -82,5 +91,36 @@ namespace OpenSim.Region.ScriptEngine.XEngine MainConsole.Instance.Output(cdt.ToString()); MainConsole.Instance.OutputFormat("Total: {0}", sensorInfo.Count); } + + private void HandleShowTimers(string module, string[] cmdparams) + { + if (!IsSceneSelected()) + return; + + Timer timerPlugin = AsyncCommandManager.GetTimerPlugin(m_engine); + + if (timerPlugin == null) + { + MainConsole.Instance.Output("Plugin not yet initialized"); + return; + } + + List timersInfo = timerPlugin.GetTimersInfo(); + + ConsoleDisplayTable cdt = new ConsoleDisplayTable(); + cdt.AddColumn("Part local ID", 13); + cdt.AddColumn("Script item ID", 36); + cdt.AddColumn("Interval", 10); + cdt.AddColumn("Next", 8); + + foreach (Timer.TimerInfo t in timersInfo) + { + // Convert from 100 ns ticks back to seconds + cdt.AddRow(t.localID, t.itemID, (double)t.interval / 10000000, t.next); + } + + MainConsole.Instance.Output(cdt.ToString()); + MainConsole.Instance.OutputFormat("Total: {0}", timersInfo.Count); + } } } \ No newline at end of file -- cgit v1.1 From 170d37696795d70799fb9b402400133088f389e9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 10 Jan 2013 01:45:56 +0000 Subject: On baked texture save, replace any HG ID with an ordinary asset ID so the HGAssetBroker doesn't try to save back to the avatar's originating region --- OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 0a69979..ce79f07 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -287,6 +287,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory if (asset != null) { + // Replace an HG ID with the simple asset ID so that we can persist textures for foreign HG avatars + asset.ID = asset.FullID.ToString(); + asset.Temporary = false; asset.Local = false; m_scene.AssetService.Store(asset); -- cgit v1.1 From 701ca1e4b8b3d54e1e93baf54aada3867d403075 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 10 Jan 2013 22:38:48 +0000 Subject: Add "debug scene pbackup true|false" console command. This enables or disable periodic scene backup. For debug purposes. If false, scene is still saved on shutdown. --- OpenSim/Region/Application/OpenSim.cs | 10 ++++---- OpenSim/Region/Framework/Scenes/Scene.cs | 39 ++++++++++++++++++++++++-------- 2 files changed, 36 insertions(+), 13 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index cffbb3b..492ee4a 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -239,13 +239,15 @@ namespace OpenSim m_console.Commands.AddCommand("Debug", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug); m_console.Commands.AddCommand("Debug", false, "debug scene", - "debug scene active|collisions|physics|scripting|teleport true|false", - "Turn on scene debugging.", + "debug scene active|collisions|pbackup|physics|scripting|teleport|updates true|false", + "Turn on scene debugging options.", "If active is false then main scene update and maintenance loops are suspended.\n" + "If collisions is false then collisions with other objects are turned off.\n" + + "If pbackup is false then periodic scene backup is turned off.\n" + "If physics is false then all physics objects are non-physical.\n" + "If scripting is false then no scripting operations happen.\n" - + "If teleport is true then some extra teleport debug information is logged.", + + "If teleport is true then some extra teleport debug information is logged." + + "If updates is true then any frame which exceeds double the maximum desired frame time is logged.", Debug); m_console.Commands.AddCommand("General", false, "change region", @@ -764,7 +766,7 @@ namespace OpenSim else { MainConsole.Instance.Output( - "Usage: debug scene active|scripting|collisions|physics|teleport true|false"); + "Usage: debug scene active|collisions|pbackup|physics|scripting|teleport|updates true|false"); } break; diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 11b63b7..d0a2115 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -77,6 +77,23 @@ namespace OpenSim.Region.Framework.Scenes /// public bool DebugUpdates { get; private set; } + /// + /// If true then the scene is saved to persistent storage periodically, every m_update_backup frames and + /// if objects meet required conditions (m_dontPersistBefore and m_dontPersistAfter). + /// + /// + /// Even if false, the scene will still be saved on clean shutdown. + /// FIXME: Currently, setting this to false will mean that objects are not periodically returned from parcels. + /// This needs to be fixed. + /// + public bool PeriodicBackup { get; private set; } + + /// + /// If false then the scene is never saved to persistence storage even if PeriodicBackup == true and even + /// if the scene is being shut down for the final time. + /// + public bool UseBackup { get; private set; } + public SynchronizeSceneHandler SynchronizeScene; /// @@ -341,7 +358,6 @@ namespace OpenSim.Region.Framework.Scenes private Timer m_mapGenerationTimer = new Timer(); private bool m_generateMaptiles; - private bool m_useBackup = true; #endregion Fields @@ -594,11 +610,6 @@ namespace OpenSim.Region.Framework.Scenes get { return m_authenticateHandler; } } - public bool UseBackup - { - get { return m_useBackup; } - } - // an instance to the physics plugin's Scene object. public PhysicsScene PhysicsScene { @@ -768,8 +779,8 @@ namespace OpenSim.Region.Framework.Scenes StartDisabled = startupConfig.GetBoolean("StartDisabled", false); m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance", m_defaultDrawDistance); - m_useBackup = startupConfig.GetBoolean("UseSceneBackup", m_useBackup); - if (!m_useBackup) + UseBackup = startupConfig.GetBoolean("UseSceneBackup", UseBackup); + if (!UseBackup) m_log.InfoFormat("[SCENE]: Backup has been disabled for {0}", RegionInfo.RegionName); //Animation states @@ -937,6 +948,8 @@ namespace OpenSim.Region.Framework.Scenes { PhysicalPrims = true; CollidablePrims = true; + PeriodicBackup = true; + UseBackup = true; BordersLocked = true; Border northBorder = new Border(); @@ -1189,6 +1202,14 @@ namespace OpenSim.Region.Framework.Scenes Active = active; } + if (options.ContainsKey("pbackup")) + { + bool active; + + if (bool.TryParse(options["pbackup"], out active)) + PeriodicBackup = active; + } + if (options.ContainsKey("scripting")) { bool enableScripts = true; @@ -1570,7 +1591,7 @@ namespace OpenSim.Region.Framework.Scenes eventMS = Util.EnvironmentTickCountSubtract(tmpMS); } - if (Frame % m_update_backup == 0) + if (PeriodicBackup && Frame % m_update_backup == 0) { tmpMS = Util.EnvironmentTickCount(); UpdateStorageBackup(); -- cgit v1.1 From f566dc06182c51399e9dcb66553645c742d29673 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 10 Jan 2013 22:42:12 +0000 Subject: Remove unimplemented "debug teleport" console command --- OpenSim/Region/Application/OpenSim.cs | 2 -- 1 file changed, 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 492ee4a..fc87b6d 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -236,8 +236,6 @@ namespace OpenSim + "If an avatar name is given then only packets from that avatar are logged", Debug); - m_console.Commands.AddCommand("Debug", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug); - m_console.Commands.AddCommand("Debug", false, "debug scene", "debug scene active|collisions|pbackup|physics|scripting|teleport|updates true|false", "Turn on scene debugging options.", -- cgit v1.1 From e65737be9369cbb39081026577e93748f8a18fdb Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 10 Jan 2013 22:42:33 +0000 Subject: minor: add missing newline to "debug scene" console command --- OpenSim/Region/Application/OpenSim.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index fc87b6d..603cfbc 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -244,7 +244,7 @@ namespace OpenSim + "If pbackup is false then periodic scene backup is turned off.\n" + "If physics is false then all physics objects are non-physical.\n" + "If scripting is false then no scripting operations happen.\n" - + "If teleport is true then some extra teleport debug information is logged." + + "If teleport is true then some extra teleport debug information is logged.\n" + "If updates is true then any frame which exceeds double the maximum desired frame time is logged.", Debug); -- cgit v1.1 From 17f21ba9a0d11f68fa892ab9d83eaa7db89aae37 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 10 Jan 2013 22:46:25 +0000 Subject: minor: Capitalize GroupsModule command category --- OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 193d1db..29f9591 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -126,7 +126,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { scene.RegisterModuleInterface(this); scene.AddCommand( - "debug", + "Debug", this, "debug groups verbose", "debug groups verbose ", -- cgit v1.1 From 983e458bb67defd79c48d6ee66682f8f86e2029c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 10 Jan 2013 22:59:40 +0000 Subject: refactor: route the final scene backup through the same code that handles periodic backup This is rather than making unnecessary duplicate checks that the SOG later performs again. --- OpenSim/Region/Framework/Scenes/Scene.cs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index d0a2115..515184c 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1322,16 +1322,7 @@ namespace OpenSim.Region.Framework.Scenes m_log.Debug("[SCENE]: Persisting changed objects"); EventManager.TriggerSceneShuttingDown(this); - - EntityBase[] entities = GetEntities(); - foreach (EntityBase entity in entities) - { - if (!entity.IsDeleted && entity is SceneObjectGroup && ((SceneObjectGroup)entity).HasGroupChanged) - { - ((SceneObjectGroup)entity).ProcessBackup(SimulationDataService, false); - } - } - + Backup(false); m_sceneGraph.Close(); if (!GridService.DeregisterRegion(RegionInfo.RegionID)) -- cgit v1.1 From a16ae5d7e3e687fdcdae39f848f66087f16433a2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 10 Jan 2013 23:49:48 +0000 Subject: Move scene debug commands into separate module. Command changes from "debug scene " to "debug scene set " to accomodate future settings --- OpenSim/Region/Application/OpenSim.cs | 37 ---- .../World/Estate/EstateManagementModule.cs | 19 +- .../Framework/Interfaces/ISceneCommandsModule.cs | 43 ++++ OpenSim/Region/Framework/Scenes/Scene.cs | 153 ++++++------- .../World/SceneCommands/SceneCommandsModule.cs | 236 +++++++++++++++++++++ 5 files changed, 350 insertions(+), 138 deletions(-) create mode 100644 OpenSim/Region/Framework/Interfaces/ISceneCommandsModule.cs create mode 100644 OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 603cfbc..c4731a3 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -236,18 +236,6 @@ namespace OpenSim + "If an avatar name is given then only packets from that avatar are logged", Debug); - m_console.Commands.AddCommand("Debug", false, "debug scene", - "debug scene active|collisions|pbackup|physics|scripting|teleport|updates true|false", - "Turn on scene debugging options.", - "If active is false then main scene update and maintenance loops are suspended.\n" - + "If collisions is false then collisions with other objects are turned off.\n" - + "If pbackup is false then periodic scene backup is turned off.\n" - + "If physics is false then all physics objects are non-physical.\n" - + "If scripting is false then no scripting operations happen.\n" - + "If teleport is true then some extra teleport debug information is logged.\n" - + "If updates is true then any frame which exceeds double the maximum desired frame time is logged.", - Debug); - m_console.Commands.AddCommand("General", false, "change region", "change region ", "Change current console region", ChangeSelectedRegion); @@ -744,31 +732,6 @@ namespace OpenSim break; - case "scene": - if (args.Length == 4) - { - if (SceneManager.CurrentScene == null) - { - MainConsole.Instance.Output("Please use 'change region ' first"); - } - else - { - string key = args[2]; - string value = args[3]; - SceneManager.CurrentScene.SetSceneCoreDebug( - new Dictionary() { { key, value } }); - - MainConsole.Instance.OutputFormat("Set debug scene {0} = {1}", key, value); - } - } - else - { - MainConsole.Instance.Output( - "Usage: debug scene active|collisions|pbackup|physics|scripting|teleport|updates true|false"); - } - - break; - default: MainConsole.Instance.Output("Unknown debug command"); break; diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index d05abc5..60f6739 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -753,13 +753,18 @@ namespace OpenSim.Region.CoreModules.World.Estate Scene.RegionInfo.RegionSettings.Save(); TriggerRegionInfoChange(); - Scene.SetSceneCoreDebug( - new Dictionary() { - { "scripting", (!disableScripts).ToString() }, - { "collisions", (!disableCollisions).ToString() }, - { "physics", (!disablePhysics).ToString() } - } - ); + ISceneCommandsModule scm = Scene.RequestModuleInterface(); + + if (scm != null) + { + scm.SetSceneDebugOptions( + new Dictionary() { + { "scripting", (!disableScripts).ToString() }, + { "collisions", (!disableCollisions).ToString() }, + { "physics", (!disablePhysics).ToString() } + } + ); + } } private void handleEstateTeleportOneUserHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID, UUID prey) diff --git a/OpenSim/Region/Framework/Interfaces/ISceneCommandsModule.cs b/OpenSim/Region/Framework/Interfaces/ISceneCommandsModule.cs new file mode 100644 index 0000000..c5e678b --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/ISceneCommandsModule.cs @@ -0,0 +1,43 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.Framework.Interfaces +{ + public interface ISceneCommandsModule + { + /// + /// Sets the scene debug options. + /// + void SetSceneDebugOptions(Dictionary options); + } +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 515184c..4859dff 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -70,12 +70,12 @@ namespace OpenSim.Region.Framework.Scenes /// /// Show debug information about teleports. /// - public bool DebugTeleporting { get; private set; } + public bool DebugTeleporting { get; set; } /// /// Show debug information about the scene loop. /// - public bool DebugUpdates { get; private set; } + public bool DebugUpdates { get; set; } /// /// If true then the scene is saved to persistent storage periodically, every m_update_backup frames and @@ -86,13 +86,61 @@ namespace OpenSim.Region.Framework.Scenes /// FIXME: Currently, setting this to false will mean that objects are not periodically returned from parcels. /// This needs to be fixed. /// - public bool PeriodicBackup { get; private set; } + public bool PeriodicBackup { get; set; } /// /// If false then the scene is never saved to persistence storage even if PeriodicBackup == true and even /// if the scene is being shut down for the final time. /// - public bool UseBackup { get; private set; } + public bool UseBackup { get; set; } + + /// + /// If false then physical objects are disabled, though collisions will continue as normal. + /// + public bool PhysicsEnabled { get; set; } + + /// + /// If false then scripts are not enabled on the smiulator + /// + public bool ScriptsEnabled + { + get { return m_scripts_enabled; } + set + { + if (m_scripts_enabled != value) + { + if (!value) + { + m_log.Info("Stopping all Scripts in Scene"); + + EntityBase[] entities = Entities.GetEntities(); + foreach (EntityBase ent in entities) + { + if (ent is SceneObjectGroup) + ((SceneObjectGroup)ent).RemoveScriptInstances(false); + } + } + else + { + m_log.Info("Starting all Scripts in Scene"); + + EntityBase[] entities = Entities.GetEntities(); + foreach (EntityBase ent in entities) + { + if (ent is SceneObjectGroup) + { + SceneObjectGroup sog = (SceneObjectGroup)ent; + sog.CreateScriptInstances(0, false, DefaultScriptEngine, 0); + sog.ResumeScripts(); + } + } + } + + m_scripts_enabled = value; + } + } + } + private bool m_scripts_enabled; public SynchronizeSceneHandler SynchronizeScene; @@ -299,8 +347,6 @@ namespace OpenSim.Region.Framework.Scenes private Dictionary m_returns = new Dictionary(); private Dictionary m_groupsWithTargets = new Dictionary(); - private bool m_physics_enabled = true; - private bool m_scripts_enabled = true; private string m_defaultScriptEngine; /// @@ -762,9 +808,11 @@ namespace OpenSim.Region.Framework.Scenes DumpAssetsToFile = dumpAssetsToFile; + // XXX: Don't set the public property since we don't want to activate here. This needs to be handled + // better in the future. m_scripts_enabled = !RegionInfo.RegionSettings.DisableScripts; - m_physics_enabled = !RegionInfo.RegionSettings.DisablePhysics; + PhysicsEnabled = !RegionInfo.RegionSettings.DisablePhysics; m_simulatorVersion = simulatorVersion + " (" + Util.GetRuntimeInformation() + ")"; @@ -948,6 +996,8 @@ namespace OpenSim.Region.Framework.Scenes { PhysicalPrims = true; CollidablePrims = true; + PhysicsEnabled = true; + PeriodicBackup = true; UseBackup = true; @@ -1192,91 +1242,6 @@ namespace OpenSim.Region.Framework.Scenes } } - public void SetSceneCoreDebug(Dictionary options) - { - if (options.ContainsKey("active")) - { - bool active; - - if (bool.TryParse(options["active"], out active)) - Active = active; - } - - if (options.ContainsKey("pbackup")) - { - bool active; - - if (bool.TryParse(options["pbackup"], out active)) - PeriodicBackup = active; - } - - if (options.ContainsKey("scripting")) - { - bool enableScripts = true; - if (bool.TryParse(options["scripting"], out enableScripts) && m_scripts_enabled != enableScripts) - { - if (!enableScripts) - { - m_log.Info("Stopping all Scripts in Scene"); - - EntityBase[] entities = Entities.GetEntities(); - foreach (EntityBase ent in entities) - { - if (ent is SceneObjectGroup) - ((SceneObjectGroup)ent).RemoveScriptInstances(false); - } - } - else - { - m_log.Info("Starting all Scripts in Scene"); - - EntityBase[] entities = Entities.GetEntities(); - foreach (EntityBase ent in entities) - { - if (ent is SceneObjectGroup) - { - SceneObjectGroup sog = (SceneObjectGroup)ent; - sog.CreateScriptInstances(0, false, DefaultScriptEngine, 0); - sog.ResumeScripts(); - } - } - } - - m_scripts_enabled = enableScripts; - } - } - - if (options.ContainsKey("physics")) - { - bool enablePhysics; - if (bool.TryParse(options["physics"], out enablePhysics)) - m_physics_enabled = enablePhysics; - } - -// if (options.ContainsKey("collisions")) -// { -// // TODO: Implement. If false, should stop objects colliding, though possibly should still allow -// // the avatar themselves to collide with the ground. -// } - - if (options.ContainsKey("teleport")) - { - bool enableTeleportDebugging; - if (bool.TryParse(options["teleport"], out enableTeleportDebugging)) - DebugTeleporting = enableTeleportDebugging; - } - - if (options.ContainsKey("updates")) - { - bool enableUpdateDebugging; - if (bool.TryParse(options["updates"], out enableUpdateDebugging)) - { - DebugUpdates = enableUpdateDebugging; - GcNotify.Enabled = DebugUpdates; - } - } - } - public int GetInaccurateNeighborCount() { return m_neighbours.Count; @@ -1526,7 +1491,7 @@ namespace OpenSim.Region.Framework.Scenes } tmpMS = Util.EnvironmentTickCount(); - if ((Frame % m_update_physics == 0) && m_physics_enabled) + if (PhysicsEnabled && Frame % m_update_physics == 0) m_sceneGraph.UpdatePreparePhysics(); physicsMS2 = Util.EnvironmentTickCountSubtract(tmpMS); @@ -1541,7 +1506,7 @@ namespace OpenSim.Region.Framework.Scenes tmpMS = Util.EnvironmentTickCount(); if (Frame % m_update_physics == 0) { - if (m_physics_enabled) + if (PhysicsEnabled) physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameTime); if (SynchronizeScene != null) diff --git a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs new file mode 100644 index 0000000..5dbf207 --- /dev/null +++ b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs @@ -0,0 +1,236 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Framework.Monitoring; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.OptionalModules.Avatar.Attachments +{ + /// + /// A module that just holds commands for inspecting avatar appearance. + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SceneCommandsModule")] + public class SceneCommandsModule : ISceneCommandsModule, INonSharedRegionModule + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Scene m_scene; +// private IAvatarFactoryModule m_avatarFactory; + + public string Name { get { return "Scene Commands Module"; } } + + public Type ReplaceableInterface { get { return null; } } + + public void Initialise(IConfigSource source) + { +// m_log.DebugFormat("[SCENE COMMANDS MODULE]: INITIALIZED MODULE"); + } + + public void PostInitialise() + { +// m_log.DebugFormat("[SCENE COMMANDS MODULE]: POST INITIALIZED MODULE"); + } + + public void Close() + { +// m_log.DebugFormat("[SCENE COMMANDS MODULE]: CLOSED MODULE"); + } + + public void AddRegion(Scene scene) + { +// m_log.DebugFormat("[SCENE COMMANDS MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); + + m_scene = scene; + } + + public void RemoveRegion(Scene scene) + { +// m_log.DebugFormat("[SCENE COMMANDS MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); + } + + public void RegionLoaded(Scene scene) + { +// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); + + scene.AddCommand( + "Debug", this, "debug scene set", + "debug scene set active|collisions|pbackup|physics|scripting|teleport|updates true|false", + "Turn on scene debugging options.", + "If active is false then main scene update and maintenance loops are suspended.\n" + + "If collisions is false then collisions with other objects are turned off.\n" + + "If pbackup is false then periodic scene backup is turned off.\n" + + "If physics is false then all physics objects are non-physical.\n" + + "If scripting is false then no scripting operations happen.\n" + + "If teleport is true then some extra teleport debug information is logged.\n" + + "If updates is true then any frame which exceeds double the maximum desired frame time is logged.", + HandleDebugSceneCommand); + } + + private void HandleDebugSceneCommand(string module, string[] args) + { + if (args.Length == 5) + { + if (MainConsole.Instance.ConsoleScene == null) + { + MainConsole.Instance.Output("Please use 'change region ' first"); + } + else + { + string key = args[3]; + string value = args[4]; + SetSceneDebugOptions(new Dictionary() { { key, value } }); + + MainConsole.Instance.OutputFormat("Set debug scene {0} = {1}", key, value); + } + } + else + { + MainConsole.Instance.Output( + "Usage: debug scene set active|collisions|pbackup|physics|scripting|teleport|updates true|false"); + } + } + + public void SetSceneDebugOptions(Dictionary options) + { + if (options.ContainsKey("active")) + { + bool active; + + if (bool.TryParse(options["active"], out active)) + m_scene.Active = active; + } + + if (options.ContainsKey("pbackup")) + { + bool active; + + if (bool.TryParse(options["pbackup"], out active)) + m_scene.PeriodicBackup = active; + } + + if (options.ContainsKey("scripting")) + { + bool enableScripts = true; + if (bool.TryParse(options["scripting"], out enableScripts)) + m_scene.ScriptsEnabled = enableScripts; + } + + if (options.ContainsKey("physics")) + { + bool enablePhysics; + if (bool.TryParse(options["physics"], out enablePhysics)) + m_scene.PhysicsEnabled = enablePhysics; + } + +// if (options.ContainsKey("collisions")) +// { +// // TODO: Implement. If false, should stop objects colliding, though possibly should still allow +// // the avatar themselves to collide with the ground. +// } + + if (options.ContainsKey("teleport")) + { + bool enableTeleportDebugging; + if (bool.TryParse(options["teleport"], out enableTeleportDebugging)) + m_scene.DebugTeleporting = enableTeleportDebugging; + } + + if (options.ContainsKey("updates")) + { + bool enableUpdateDebugging; + if (bool.TryParse(options["updates"], out enableUpdateDebugging)) + { + m_scene.DebugUpdates = enableUpdateDebugging; + GcNotify.Enabled = enableUpdateDebugging; + } + } + } + + private void GetAttachmentsReport(ScenePresence sp, StringBuilder sb) + { + sb.AppendFormat("Attachments for {0}\n", sp.Name); + + ConsoleDisplayTable ct = new ConsoleDisplayTable() { Indent = 2 }; + ct.Columns.Add(new ConsoleDisplayTableColumn("Attachment Name", 50)); + ct.Columns.Add(new ConsoleDisplayTableColumn("Local ID", 10)); + ct.Columns.Add(new ConsoleDisplayTableColumn("Item ID", 36)); + ct.Columns.Add(new ConsoleDisplayTableColumn("Attach Point", 14)); + ct.Columns.Add(new ConsoleDisplayTableColumn("Position", 15)); + +// sb.AppendFormat( +// " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n", +// "Attachment Name", "Local ID", "Item ID", "Attach Point", "Position"); + + List attachmentObjects = sp.GetAttachments(); + foreach (SceneObjectGroup attachmentObject in attachmentObjects) + { +// InventoryItemBase attachmentItem +// = m_scenes[0].InventoryService.GetItem(new InventoryItemBase(attachmentObject.FromItemID)); + +// if (attachmentItem == null) +// { +// sb.AppendFormat( +// "WARNING: Couldn't find attachment for item {0} at point {1}\n", +// attachmentData.ItemID, (AttachmentPoint)attachmentData.AttachPoint); +// continue; +// } +// else +// { +// sb.AppendFormat( +// " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n", +// attachmentObject.Name, attachmentObject.LocalId, attachmentObject.FromItemID, +// (AttachmentPoint)attachmentObject.AttachmentPoint, attachmentObject.RootPart.AttachedPos); + ct.Rows.Add( + new ConsoleDisplayTableRow( + new List() + { + attachmentObject.Name, + attachmentObject.LocalId.ToString(), + attachmentObject.FromItemID.ToString(), + ((AttachmentPoint)attachmentObject.AttachmentPoint).ToString(), + attachmentObject.RootPart.AttachedPos.ToString() + })); +// } + } + + ct.AddToStringBuilder(sb); + sb.Append("\n"); + } + } +} \ No newline at end of file -- cgit v1.1 From f3a2bbbd93bd670f54add28fab09c824aa7f9c97 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 10 Jan 2013 23:56:11 +0000 Subject: Add "debug scene get" console command to list current scene options --- .../World/SceneCommands/SceneCommandsModule.cs | 45 +++++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs index 5dbf207..5552317 100644 --- a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs +++ b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs @@ -89,6 +89,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments // m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); scene.AddCommand( + "Debug", this, "debug scene get", + "debug scene get", + "List current scene options.", + "If active is false then main scene update and maintenance loops are suspended.\n" + + "If collisions is false then collisions with other objects are turned off.\n" + + "If pbackup is false then periodic scene backup is turned off.\n" + + "If physics is false then all physics objects are non-physical.\n" + + "If scripting is false then no scripting operations happen.\n" + + "If teleport is true then some extra teleport debug information is logged.\n" + + "If updates is true then any frame which exceeds double the maximum desired frame time is logged.", + HandleDebugSceneGetCommand); + + scene.AddCommand( "Debug", this, "debug scene set", "debug scene set active|collisions|pbackup|physics|scripting|teleport|updates true|false", "Turn on scene debugging options.", @@ -99,10 +112,38 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments + "If scripting is false then no scripting operations happen.\n" + "If teleport is true then some extra teleport debug information is logged.\n" + "If updates is true then any frame which exceeds double the maximum desired frame time is logged.", - HandleDebugSceneCommand); + HandleDebugSceneSetCommand); + } + + private void HandleDebugSceneGetCommand(string module, string[] args) + { + if (args.Length == 3) + { + if (MainConsole.Instance.ConsoleScene == null) + MainConsole.Instance.Output("Please use 'change region ' first"); + else + OutputSceneDebugOptions(); + } + else + { + MainConsole.Instance.Output("Usage: debug scene get"); + } + } + + private void OutputSceneDebugOptions() + { + ConsoleDisplayList cdl = new ConsoleDisplayList(); + cdl.AddRow("active", m_scene.Active); + cdl.AddRow("pbackup", m_scene.PeriodicBackup); + cdl.AddRow("physics", m_scene.PhysicsEnabled); + cdl.AddRow("scripting", m_scene.ScriptsEnabled); + cdl.AddRow("teleport", m_scene.DebugTeleporting); + cdl.AddRow("updates", m_scene.DebugUpdates); + + MainConsole.Instance.Output(cdl.ToString()); } - private void HandleDebugSceneCommand(string module, string[] args) + private void HandleDebugSceneSetCommand(string module, string[] args) { if (args.Length == 5) { -- cgit v1.1 From 26347307ec39f05a138322554787b88d8d07be4a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 11 Jan 2013 00:08:52 +0000 Subject: Fix a regression in the last few scene commands changes where setting these via the viewer estate dialog stopped working. Forgot to register the new interface. Also removes some code which got included by adpating an existing module. --- .../World/SceneCommands/SceneCommandsModule.cs | 54 +--------------------- 1 file changed, 2 insertions(+), 52 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs index 5552317..8b8758e 100644 --- a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs +++ b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs @@ -51,7 +51,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene; -// private IAvatarFactoryModule m_avatarFactory; public string Name { get { return "Scene Commands Module"; } } @@ -77,6 +76,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments // m_log.DebugFormat("[SCENE COMMANDS MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); m_scene = scene; + + m_scene.RegisterModuleInterface(this); } public void RemoveRegion(Scene scene) @@ -222,56 +223,5 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments } } } - - private void GetAttachmentsReport(ScenePresence sp, StringBuilder sb) - { - sb.AppendFormat("Attachments for {0}\n", sp.Name); - - ConsoleDisplayTable ct = new ConsoleDisplayTable() { Indent = 2 }; - ct.Columns.Add(new ConsoleDisplayTableColumn("Attachment Name", 50)); - ct.Columns.Add(new ConsoleDisplayTableColumn("Local ID", 10)); - ct.Columns.Add(new ConsoleDisplayTableColumn("Item ID", 36)); - ct.Columns.Add(new ConsoleDisplayTableColumn("Attach Point", 14)); - ct.Columns.Add(new ConsoleDisplayTableColumn("Position", 15)); - -// sb.AppendFormat( -// " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n", -// "Attachment Name", "Local ID", "Item ID", "Attach Point", "Position"); - - List attachmentObjects = sp.GetAttachments(); - foreach (SceneObjectGroup attachmentObject in attachmentObjects) - { -// InventoryItemBase attachmentItem -// = m_scenes[0].InventoryService.GetItem(new InventoryItemBase(attachmentObject.FromItemID)); - -// if (attachmentItem == null) -// { -// sb.AppendFormat( -// "WARNING: Couldn't find attachment for item {0} at point {1}\n", -// attachmentData.ItemID, (AttachmentPoint)attachmentData.AttachPoint); -// continue; -// } -// else -// { -// sb.AppendFormat( -// " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n", -// attachmentObject.Name, attachmentObject.LocalId, attachmentObject.FromItemID, -// (AttachmentPoint)attachmentObject.AttachmentPoint, attachmentObject.RootPart.AttachedPos); - ct.Rows.Add( - new ConsoleDisplayTableRow( - new List() - { - attachmentObject.Name, - attachmentObject.LocalId.ToString(), - attachmentObject.FromItemID.ToString(), - ((AttachmentPoint)attachmentObject.AttachmentPoint).ToString(), - attachmentObject.RootPart.AttachedPos.ToString() - })); -// } - } - - ct.AddToStringBuilder(sb); - sb.Append("\n"); - } } } \ No newline at end of file -- cgit v1.1 From 05ac6d3209afb640926995d252e8513ef3003819 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 11 Jan 2013 01:46:36 +0000 Subject: Save attachments on detach/exit if a contained script state has been changed. This involves making Attachments module listen for start/stop script changes. It also involves removing the script from the region on detach in the same manner as every other DeleteSceneObject() call rather than simply stopping it This is necessary tue to the bad assymetry of start and stop script triggers but it appears to be the correct behaviour anyway, as detached objects are completely gone from the sim. Not just in a state where their scripts have been stopped. --- .../Avatar/Attachments/AttachmentsModule.cs | 18 +++++++++++++++++- OpenSim/Region/Framework/Scenes/EventManager.cs | 3 +++ 2 files changed, 20 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 58ed554..f9c2142 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -75,10 +75,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments m_scene.RegisterModuleInterface(this); if (Enabled) + { m_scene.EventManager.OnNewClient += SubscribeToClientEvents; + m_scene.EventManager.OnStartScript += HandleScriptStateChange; + m_scene.EventManager.OnStopScript += HandleScriptStateChange; + } // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI } + + /// + /// Listen for client triggered running state changes so that we can persist the script's object if necessary. + /// + /// + /// + private void HandleScriptStateChange(uint localID, UUID itemID) + { + SceneObjectGroup sog = m_scene.GetGroupByPrim(localID); + if (sog != null && sog.IsAttachment) + sog.HasGroupChanged = true; + } public void RemoveRegion(Scene scene) { @@ -743,7 +759,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // Remove the object from the scene so no more updates // are sent. Doing this before the below changes will ensure // updates can't cause "HUD artefacts" - m_scene.DeleteSceneObject(so, false, false); + m_scene.DeleteSceneObject(so, false); // Prepare sog for storage so.AttachedAvatar = UUID.Zero; diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 6b08e0f..902ded1 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -339,6 +339,8 @@ namespace OpenSim.Region.Framework.Scenes /// in /// via , /// via + /// XXX: This is only triggered when it is the client that starts the script, not in other situations where + /// a script is started, unlike OnStopScript! /// public event StartScript OnStartScript; @@ -352,6 +354,7 @@ namespace OpenSim.Region.Framework.Scenes /// in , /// , /// + /// XXX: This is triggered when a sciprt is stopped for any reason, unlike OnStartScript! /// public event StopScript OnStopScript; -- cgit v1.1 From 660d36a5b026e8b6862b9a575e9578d6ae1599a2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 11 Jan 2013 02:28:43 +0000 Subject: Implement a workaround solution for saving manual script state changes by the user before logout instead of wrongly removing the script early. This workaround relies on the fact that a closing client goes inactive before the attachments derez calls happen. This reverts the change to remove scripts too early instead of stopping them, since the the two step stop then remove is necessary to execute the detach event. --- .../Avatar/Attachments/AttachmentsModule.cs | 24 +++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index f9c2142..8a3eeaa 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -77,8 +77,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (Enabled) { m_scene.EventManager.OnNewClient += SubscribeToClientEvents; - m_scene.EventManager.OnStartScript += HandleScriptStateChange; - m_scene.EventManager.OnStopScript += HandleScriptStateChange; + m_scene.EventManager.OnStartScript += (localID, itemID) => HandleScriptStateChange(localID, true); + m_scene.EventManager.OnStopScript += (localID, itemID) => HandleScriptStateChange(localID, false); } // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI @@ -89,11 +89,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// /// /// - private void HandleScriptStateChange(uint localID, UUID itemID) + private void HandleScriptStateChange(uint localID, bool started) { SceneObjectGroup sog = m_scene.GetGroupByPrim(localID); if (sog != null && sog.IsAttachment) - sog.HasGroupChanged = true; + { + if (!started) + { + // FIXME: This is a convoluted way for working out whether the script state has changed to stop + // because it has been manually stopped or because the stop was called in UpdateDetachedObject() below + // This needs to be handled in a less tangled way. + ScenePresence sp = m_scene.GetScenePresence(sog.AttachedAvatar); + if (sp.ControllingClient.IsActive) + sog.HasGroupChanged = true; + } + else + { + sog.HasGroupChanged = true; + } + } } public void RemoveRegion(Scene scene) @@ -759,7 +773,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // Remove the object from the scene so no more updates // are sent. Doing this before the below changes will ensure // updates can't cause "HUD artefacts" - m_scene.DeleteSceneObject(so, false); + m_scene.DeleteSceneObject(so, false, false); // Prepare sog for storage so.AttachedAvatar = UUID.Zero; -- cgit v1.1 From 72cc94cfbc16515515d33e4f130d3ee5f2802866 Mon Sep 17 00:00:00 2001 From: dahlia Date: Thu, 10 Jan 2013 20:21:18 -0800 Subject: add some sanity checking to HandleAgentRequestSit handler --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 504df40..a8517e6 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -6428,8 +6428,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP AgentRequestSit handlerAgentRequestSit = OnAgentRequestSit; if (handlerAgentRequestSit != null) - handlerAgentRequestSit(this, agentRequestSit.AgentData.AgentID, - agentRequestSit.TargetObject.TargetID, agentRequestSit.TargetObject.Offset); + if (!(agentRequestSit.AgentData == null + || agentRequestSit.TargetObject == null + || agentRequestSit.TargetObject.TargetID == null + || agentRequestSit.TargetObject.Offset == null)) + { + var sp = m_scene.GetScenePresence(agentRequestSit.AgentData.AgentID); + if (sp == null || sp.ParentID != 0) // ignore packet if agent is already sitting + return true; + + handlerAgentRequestSit(this, agentRequestSit.AgentData.AgentID, + agentRequestSit.TargetObject.TargetID, agentRequestSit.TargetObject.Offset); + } } return true; } -- cgit v1.1 From b592ec265b6f5928804baff868165f10eee6f5ed Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 11 Jan 2013 16:44:34 -0800 Subject: BulletSim: fix the 'No recognised physics mesh found ...' error spew by remembering that the last asset fetch failed until the simulator resets the shape parameters. --- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 400d5d6..8fd054f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -169,6 +169,7 @@ public sealed class BSPrim : BSPhysObject public override PrimitiveBaseShape Shape { set { BaseShape = value; + LastAssetBuildFailed = false; ForceBodyShapeRebuild(false); } } @@ -178,7 +179,6 @@ public sealed class BSPrim : BSPhysObject public override bool ForceBodyShapeRebuild(bool inTaintTime) { - LastAssetBuildFailed = false; PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ForceBodyShapeRebuild", delegate() { _mass = CalculateMass(); // changing the shape changes the mass -- cgit v1.1 From 98168edc29c7c761121e453d82bf1fab52814b58 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 9 Jan 2013 11:06:49 -0800 Subject: BulletSim: remove double application of buoyancy. Centralize computation of buoyancy. Add motor angular debugging controls. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 42 +++++++++------- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 23 ++------- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 1 + .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 58 ++++++++++++---------- 4 files changed, 59 insertions(+), 65 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index c34c05a..47f2759 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -124,6 +124,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin static readonly float PIOverFour = ((float)Math.PI) / 4f; static readonly float PIOverTwo = ((float)Math.PI) / 2f; + // For debugging, flags to turn on and off individual corrections. + private bool enableAngularVerticalAttraction = true; + private bool enableAngularDeflection = true; + private bool enableAngularBanking = true; + public BSDynamics(BSScene myScene, BSPrim myPrim) { PhysicsScene = myScene; @@ -575,11 +580,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin PhysicsScene.PE.SetMassProps(Prim.PhysBody, m_vehicleMass, localInertia); PhysicsScene.PE.UpdateInertiaTensor(Prim.PhysBody); - Vector3 grav = PhysicsScene.DefaultGravity * (1f - Prim.Buoyancy); + // Set the gravity for the vehicle depending on the buoyancy + // TODO: what should be done if prim and vehicle buoyancy differ? + Vector3 grav = Prim.ComputeGravity(m_VehicleBuoyancy); PhysicsScene.PE.SetGravity(Prim.PhysBody, grav); - VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4}", - Prim.LocalID, m_vehicleMass, friction, localInertia, angularDamping); + VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4},grav={5}", + Prim.LocalID, m_vehicleMass, friction, localInertia, angularDamping, grav); } else { @@ -858,12 +865,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin linearMotorContribution *= VehicleOrientation; // All the contributions after this are world relative (mostly Z modifications) - // ================================================================== - // Buoyancy: force to overcome gravity. - // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; - // So, if zero, don't change anything (let gravity happen). If one, negate the effect of gravity. - Vector3 buoyancyContribution = Prim.PhysicsScene.DefaultGravity * m_VehicleBuoyancy; - Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(pTimestep); Vector3 hoverContribution = ComputeLinearHover(pTimestep); @@ -873,12 +874,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pTimestep); // ================================================================== + // Select between velocities and forces. Forces will happen over time and + // will take into account inertia, collisions, etc. Velocities are + // raw updates to the velocity of the vehicle. Vector3 newVelocity = linearMotorContribution + terrainHeightContribution + hoverContribution + limitMotorUpContribution; - Vector3 newForce = buoyancyContribution; + Vector3 newForce = Vector3.Zero; // If not changing some axis, reduce out velocity if ((m_flags & (VehicleFlag.NO_X)) != 0) @@ -902,6 +906,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ================================================================== // Stuff new linear velocity into the vehicle. // Since the velocity is just being set, it is not scaled by pTimeStep. Bullet will do that for us. + // Also not scaled by mass since this is a super-physical setting of velocity. VehicleVelocity = newVelocity; // Other linear forces are applied as forces. @@ -911,13 +916,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin VehicleAddForce(totalDownForce); } - VDetailLog("{0}, MoveLinear,done,newVel={1},totDown={2},IsColliding={3}", - Prim.LocalID, newVelocity, totalDownForce, Prim.IsColliding); - VDetailLog("{0}, MoveLinear,done,linContrib={1},terrContrib={2},hoverContrib={3},limitContrib={4},buoyContrib={5}", + VDetailLog("{0}, MoveLinear,done,linContrib={1},terrContrib={2},hoverContrib={3},limitContrib={4},totDown={5},isColl={6},newVel={7}", Prim.LocalID, - linearMotorContribution, terrainHeightContribution, hoverContribution, - limitMotorUpContribution, buoyancyContribution - ); + linearMotorContribution, terrainHeightContribution, hoverContribution, limitMotorUpContribution, + totalDownForce, Prim.IsColliding, newVelocity ); } // end MoveLinear() @@ -1088,6 +1090,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin // for preventing ground vehicles with large linear deflection, like bumper cars, // from climbing their linear deflection into the sky. // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement + // TODO: This is here because this is where ODE put it but documentation says it + // is a linear effect. Where should this check go? if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) { angularMotorContribution.X = 0f; @@ -1179,7 +1183,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 ret = Vector3.Zero; // If vertical attaction timescale is reasonable - if (m_verticalAttractionTimescale < m_verticalAttractionCutoff) + if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff) { // Take a vector pointing up and convert it from world to vehicle relative coords. Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; @@ -1230,7 +1234,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // this creates an over-correction and then wabbling as the target is overshot. // TODO: rethink how the different correction computations inter-relate. - if (m_angularDeflectionEfficiency != 0 && VehicleVelocity != Vector3.Zero) + if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleVelocity != Vector3.Zero) { // The direction the vehicle is moving Vector3 movingDirection = VehicleVelocity; @@ -1303,7 +1307,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { Vector3 ret = Vector3.Zero; - if (m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) + if (enableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) { // Rotate a UnitZ vector (pointing up) to how the vehicle is oriented. // As the vehicle rolls to the right or left, the Y value will increase from diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 8fd054f..50ba343 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -410,7 +410,7 @@ public sealed class BSPrim : BSPhysObject } else { - OMV.Vector3 grav = ComputeGravity(); + OMV.Vector3 grav = ComputeGravity(Buoyancy); if (inWorld) { @@ -445,12 +445,12 @@ public sealed class BSPrim : BSPhysObject } // Return what gravity should be set to this very moment - private OMV.Vector3 ComputeGravity() + public OMV.Vector3 ComputeGravity(float buoyancy) { OMV.Vector3 ret = PhysicsScene.DefaultGravity; if (!IsStatic) - ret *= (1f - Buoyancy); + ret *= (1f - buoyancy); return ret; } @@ -1561,21 +1561,6 @@ public sealed class BSPrim : BSPhysObject // The physics engine says that properties have updated. Update same and inform // the world that things have changed. - // TODO: do we really need to check for changed? Maybe just copy values and call RequestPhysicsterseUpdate() - enum UpdatedProperties { - Position = 1 << 0, - Rotation = 1 << 1, - Velocity = 1 << 2, - Acceleration = 1 << 3, - RotationalVel = 1 << 4 - } - - const float ROTATION_TOLERANCE = 0.01f; - const float VELOCITY_TOLERANCE = 0.001f; - const float POSITION_TOLERANCE = 0.05f; - const float ACCELERATION_TOLERANCE = 0.01f; - const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f; - public override void UpdateProperties(EntityProperties entprop) { // Updates only for individual prims and for the root object of a linkset. @@ -1588,7 +1573,7 @@ public sealed class BSPrim : BSPhysObject entprop.RotationalVelocity = OMV.Vector3.Zero; } - // Assign directly to the local variables so the normal set action does not happen + // Assign directly to the local variables so the normal set actions do not happen _position = entprop.Position; _orientation = entprop.Rotation; _velocity = entprop.Velocity; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 7017194..4a6cebd 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -486,6 +486,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters ProcessTaints(); // Some of the physical objects requre individual, pre-step calls + // (vehicles and avatar movement, in particular) TriggerPreStepEvent(timeStep); // the prestep actions might have added taints diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 29bd4e4..1540dbb 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -1,12 +1,17 @@ CURRENT PRIORITIES ================================================= +Nebadon vehicles turning funny in arena +limitMotorUp calibration (more down?) +Vehicle angular vertical attraction +Vehicle angular deflection + Preferred orientation angular correction fix +vehicle angular banking Avatars walking up stairs (HALF DONE) + Radius of the capsule affects ability to climb edges. Vehicle movement on terrain smoothness -limitMotorUp calibration (more down?) -Preferred orientation angular correction fix Surfboard go wonky when turning Angular motor direction is global coordinates rather than local coordinates? -Boats float low in the water +Boats float low in the water (DONE) Avatar movement flying into a wall doesn't stop avatar who keeps appearing to move through the obstacle (DONE) walking up stairs is not calibrated correctly (stairs out of Kepler cabin) @@ -33,19 +38,15 @@ CRASHES VEHICLES TODO LIST: ================================================= -Angular motor direction is global coordinates rather than local coordinates Border crossing with linked vehicle causes crash Vehicles (Move smoothly) -Add vehicle collisions so IsColliding is properly reported. - Needed for banking, limitMotorUp, movementLimiting, ... -VehicleAddForce is not scaled by the simulation step but it is only - applied for one step. Should it be scaled? Some vehicles should not be able to turn if no speed or off ground. Cannot edit/move a vehicle being ridden: it jumps back to the origional position. Neb car jiggling left and right Happens on terrain and any other mesh object. Flat cubes are much smoother. This has been reduced but not eliminated. Implement referenceFrame for all the motion routines. +For limitMotorUp, use raycast down to find if vehicle is in the air. Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE. Verify that angular motion specified around Z moves in the vehicle coordinates. Verify llGetVel() is returning a smooth and good value for vehicle movement. @@ -54,14 +55,13 @@ Implement function efficiency for lineaar and angular motion. After getting off a vehicle, the root prim is phantom (can be walked through) Need to force a position update for the root prim after compound shape destruction Linkset explosion after three "rides" on Nebadon lite vehicle (LinksetConstraint) -For limitMotorUp, use raycast down to find if vehicle is in the air. Remove vehicle angular velocity zeroing in BSPrim.UpdateProperties(). A kludge that isn't fixing the real problem of Bullet adding extra motion. Incorporate inter-relationship of angular corrections. For instance, angularDeflection and angularMotorUp will compute same X or Y correction. When added together creates over-correction and over-shoot and wabbling. -BULLETSIM TODO LIST: +GENERAL TODO LIST: ================================================= Implement an avatar mesh shape. The Bullet capsule is way too limited. Consider just hand creating a vertex/index array in a new BSShapeAvatar. @@ -121,11 +121,9 @@ LinksetCompound: when one of the children changes orientation (like tires Verify/think through scripts in children of linksets. What do they reference and return when getting position, velocity, ... Confirm constraint linksets still work after making all the changes for compound linksets. +Use PostTaint callback to do rebuilds for constraint linksets to reduce rebuilding Add 'changed' flag or similar to reduce the number of times a linkset is rebuilt. For compound linksets, add ability to remove or reposition individual child shapes. -Disable activity of passive linkset children. - Since the linkset is a compound object, the old prims are left lying - around and need to be phantomized so they don't collide, ... Speed up creation of large physical linksets For instance, sitting in Neb's car (130 prims) takes several seconds to become physical. REALLY bad for very large physical linksets (freezes the sim for many seconds). @@ -138,25 +136,21 @@ MORE Use the HACD convex hull routine in Bullet rather than the C# version. Do we need to do convex hulls all the time? Can complex meshes be left meshes? There is some problem with meshes and collisions -Test avatar walking up stairs. How does compare with SL. - Radius of the capsule affects ability to climb edges. + Hulls are not as detailed as meshes. Hulled vehicles insides are different shape. Debounce avatar contact so legs don't keep folding up when standing. Implement LSL physics controls. Like STATUS_ROTATE_X. Add border extensions to terrain to help region crossings and objects leaving region. Use a different capsule shape for avatar when sitting LL uses a pyrimidal shape scaled by the avatar's bounding box http://wiki.secondlife.com/wiki/File:Avmeshforms.png - Performance test with lots of avatars. Can BulletSim support a thousand? Optimize collisions in C++: only send up to the object subscribed to collisions. Use collision subscription and remove the collsion(A,B) and collision(B,A) Check whether SimMotionState needs large if statement (see TODO). - Implement 'top colliders' info. Avatar jump Performance measurement and changes to make quicker. Implement detailed physics stats (GetStats()). - Measure performance improvement from hulls Test not using ghost objects for volume detect implementation. Performance of closures and delegates for taint processing @@ -164,9 +158,7 @@ Performance of closures and delegates for taint processing Is any slowdown introduced by the existing implementation significant? Is there are more efficient method of implementing pre and post step actions? See http://www.codeproject.com/Articles/29922/Weak-Events-in-C - Physics Arena central pyramid: why is one side permiable? - In SL, perfect spheres don't seem to have rolling friction. Add special case. Enforce physical parameter min/max: Gravity: [-1, 28] @@ -197,22 +189,19 @@ Generalize Dynamics and PID with standardized motors. Generalize Linkset and vehicles into PropertyManagers Methods for Refresh, RemoveBodyDependencies, RestoreBodyDependencies Potentially add events for shape destruction, etc. -Complete implemention of preStepActions - Replace vehicle step call with prestep event. - Is there a need for postStepActions? postStepTaints? +Better mechanism for resetting linkset set and vehicle parameters when body rebuilt. + BSPrim.CreateGeomAndObject is kludgy with the callbacks, etc. Implement linkset by setting position of children when root updated. (LinksetManual) Linkset implementation using manual prim movement. LinkablePrim class? Would that simplify/centralize the linkset logic? BSScene.UpdateParameterSet() is broken. How to set params on objects? -Remove HeightmapInfo from terrain specification - Since C++ code does not need terrain height, this structure et al are not needed. Add floating motor for BS_FLOATS_ON_WATER so prim and avatar will - bob at the water level. BSPrim.PositionSanityCheck(). + bob at the water level. BSPrim.PositionSanityCheck() Should taints check for existance or activeness of target? When destroying linksets/etc, taints can be generated for objects that are actually gone when the taint happens. Crashes don't happen because the taint closure keeps the object from being freed, but that is just an accident. - Possibly have and 'active' flag that is checked by the taint processor? + Possibly have an 'active' flag that is checked by the taint processor? Parameters for physics logging should be moved from BSScene to BSParam (at least boolean ones) Can some of the physical wrapper classes (BulletBody, BulletWorld, BulletShape) be 'sealed'? There are TOO MANY interfaces from BulletSim core to Bullet itself @@ -282,3 +271,18 @@ Redo BulletSimAPI to allow native C# implementation of Bullet option (DONE) Meshes rendering as bounding boxes (DONE) (Resolution: Added test for mesh/sculpties in native shapes so it didn't think it was a box) llMoveToTarget (Resolution: added simple motor to update the position.) +Angular motor direction is global coordinates rather than local coordinates (DONE) +Add vehicle collisions so IsColliding is properly reported. (DONE) + Needed for banking, limitMotorUp, movementLimiting, ... + (Resolution: added CollisionFlags.BS_VEHICLE_COLLISION and code to use it) +VehicleAddForce is not scaled by the simulation step but it is only + applied for one step. Should it be scaled? (DONE) + (Resolution: use force for timed things, Impulse for immediate, non-timed things) +Complete implemention of preStepActions (DONE) + Replace vehicle step call with prestep event. + Is there a need for postStepActions? postStepTaints? +Disable activity of passive linkset children. (DONE) + Since the linkset is a compound object, the old prims are left lying + around and need to be phantomized so they don't collide, ... +Remove HeightmapInfo from terrain specification (DONE) + Since C++ code does not need terrain height, this structure et al are not needed. \ No newline at end of file -- cgit v1.1 From 7e58bbaac6c5ebb5bf0d6a7a875a8316ac264128 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 9 Jan 2013 16:27:06 -0800 Subject: BulletSim: Redo linear function coding so they can better interact. New algorithm for limitMotorUp that relies on going up when not colliding rather than distance from ground. Add parameter for turning on and off embedded source vehicle debugging. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 147 ++++++++++++--------- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 6 + 2 files changed, 91 insertions(+), 62 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 47f2759..2e44ab6 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -134,6 +134,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin PhysicsScene = myScene; Prim = myPrim; Type = Vehicle.TYPE_NONE; + SetupVehicleDebugging(); + } + + // Stopgap debugging enablement. Allows source level debugging but still checking + // in changes by making enablement of debugging flags from INI file. + public void SetupVehicleDebugging() + { + enableAngularVerticalAttraction = true; + enableAngularDeflection = true; + enableAngularBanking = true; + if (BSParam.VehicleDebuggingEnabled != ConfigurationParameters.numericFalse) + { + enableAngularVerticalAttraction = false; + enableAngularDeflection = false; + enableAngularBanking = false; + VDetailLog("{0},BSDynamics.SetupVehicleDebugging,settingDebugMode"); + } } // Return 'true' if this vehicle is doing vehicle things @@ -576,8 +593,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Vehicles report collision events so we know when it's on the ground PhysicsScene.PE.AddToCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); - Vector3 localInertia = PhysicsScene.PE.CalculateLocalInertia(Prim.PhysShape, m_vehicleMass); - PhysicsScene.PE.SetMassProps(Prim.PhysBody, m_vehicleMass, localInertia); + Prim.Inertia = PhysicsScene.PE.CalculateLocalInertia(Prim.PhysShape, m_vehicleMass); + PhysicsScene.PE.SetMassProps(Prim.PhysBody, m_vehicleMass, Prim.Inertia); PhysicsScene.PE.UpdateInertiaTensor(Prim.PhysBody); // Set the gravity for the vehicle depending on the buoyancy @@ -586,7 +603,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin PhysicsScene.PE.SetGravity(Prim.PhysBody, grav); VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4},grav={5}", - Prim.LocalID, m_vehicleMass, friction, localInertia, angularDamping, grav); + Prim.LocalID, m_vehicleMass, friction, Prim.Inertia, angularDamping, grav); } else { @@ -863,69 +880,47 @@ namespace OpenSim.Region.Physics.BulletSPlugin // The movement computed in the linear motor is relative to the vehicle // coordinates. Rotate the movement to world coordinates. linearMotorContribution *= VehicleOrientation; - // All the contributions after this are world relative (mostly Z modifications) - Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(pTimestep); + VehicleVelocity = linearMotorContribution; - Vector3 hoverContribution = ComputeLinearHover(pTimestep); + ComputeLinearTerrainHeightCorrection(pTimestep); - ComputeLinearBlockingEndPoint(pTimestep); - - Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pTimestep); + ComputeLinearHover(pTimestep); - // ================================================================== - // Select between velocities and forces. Forces will happen over time and - // will take into account inertia, collisions, etc. Velocities are - // raw updates to the velocity of the vehicle. - Vector3 newVelocity = linearMotorContribution - + terrainHeightContribution - + hoverContribution - + limitMotorUpContribution; + ComputeLinearBlockingEndPoint(pTimestep); - Vector3 newForce = Vector3.Zero; + ComputeLinearMotorUp(pTimestep); // If not changing some axis, reduce out velocity - if ((m_flags & (VehicleFlag.NO_X)) != 0) - newVelocity.X = 0; - if ((m_flags & (VehicleFlag.NO_Y)) != 0) - newVelocity.Y = 0; - if ((m_flags & (VehicleFlag.NO_Z)) != 0) - newVelocity.Z = 0; + if ((m_flags & (VehicleFlag.NO_X | VehicleFlag.NO_Y | VehicleFlag.NO_Z)) != 0) + { + Vector3 vel = VehicleVelocity; + if ((m_flags & (VehicleFlag.NO_X)) != 0) + vel.X = 0; + if ((m_flags & (VehicleFlag.NO_Y)) != 0) + vel.Y = 0; + if ((m_flags & (VehicleFlag.NO_Z)) != 0) + vel.Z = 0; + VehicleVelocity = vel; + } // ================================================================== // Clamp high or low velocities - float newVelocityLengthSq = newVelocity.LengthSquared(); + float newVelocityLengthSq = VehicleVelocity.LengthSquared(); if (newVelocityLengthSq > 1000f) { - newVelocity /= newVelocity.Length(); - newVelocity *= 1000f; + VehicleVelocity /= VehicleVelocity.Length(); + VehicleVelocity *= 1000f; } else if (newVelocityLengthSq < 0.001f) - newVelocity = Vector3.Zero; - - // ================================================================== - // Stuff new linear velocity into the vehicle. - // Since the velocity is just being set, it is not scaled by pTimeStep. Bullet will do that for us. - // Also not scaled by mass since this is a super-physical setting of velocity. - VehicleVelocity = newVelocity; - - // Other linear forces are applied as forces. - Vector3 totalDownForce = newForce * m_vehicleMass; - if (!totalDownForce.ApproxEquals(Vector3.Zero, 0.01f)) - { - VehicleAddForce(totalDownForce); - } + VehicleVelocity = Vector3.Zero; - VDetailLog("{0}, MoveLinear,done,linContrib={1},terrContrib={2},hoverContrib={3},limitContrib={4},totDown={5},isColl={6},newVel={7}", - Prim.LocalID, - linearMotorContribution, terrainHeightContribution, hoverContribution, limitMotorUpContribution, - totalDownForce, Prim.IsColliding, newVelocity ); + VDetailLog("{0}, MoveLinear,done,isColl={1},newVel={2}", Prim.LocalID, Prim.IsColliding, VehicleVelocity ); } // end MoveLinear() - public Vector3 ComputeLinearTerrainHeightCorrection(float pTimestep) + public void ComputeLinearTerrainHeightCorrection(float pTimestep) { - Vector3 ret = Vector3.Zero; // If below the terrain, move us above the ground a little. // TODO: Consider taking the rotated size of the object or possibly casting a ray. if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition)) @@ -937,13 +932,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition); } - return ret; } - public Vector3 ComputeLinearHover(float pTimestep) + public void ComputeLinearHover(float pTimestep) { - Vector3 ret = Vector3.Zero; - // m_VhoverEfficiency: 0=bouncy, 1=totally damped // m_VhoverTimescale: time to achieve height if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) @@ -976,6 +968,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 pos = VehiclePosition; pos.Z = m_VhoverTargetHeight; VehiclePosition = pos; + + VDetailLog("{0}, MoveLinear,hover,pos={1},lockHoverHeight", Prim.LocalID, pos); } } else @@ -985,14 +979,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; // TODO: implement m_VhoverEfficiency correctly - ret = new Vector3(0f, 0f, verticalCorrectionVelocity); + VehicleVelocity += new Vector3(0f, 0f, verticalCorrectionVelocity); + + VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},err={6},corrVel={7}", + Prim.LocalID, VehiclePosition, m_VhoverEfficiency, + m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight, + verticalError, verticalCorrectionVelocity); } - VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},ret={6}", - Prim.LocalID, VehiclePosition, m_VhoverEfficiency, m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight, ret); } - - return ret; } public bool ComputeLinearBlockingEndPoint(float pTimestep) @@ -1047,30 +1042,58 @@ namespace OpenSim.Region.Physics.BulletSPlugin // TODO: this code is wrong. Also, what should it do for boats (height from water)? // This is just using the ground and a general collision check. Should really be using // a downward raycast to find what is below. - public Vector3 ComputeLinearMotorUp(float pTimestep) + public void ComputeLinearMotorUp(float pTimestep) { Vector3 ret = Vector3.Zero; - float distanceAboveGround = 0f; if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) { + // This code tries to decide if the object is not on the ground and then pushing down + /* float targetHeight = Type == Vehicle.TYPE_BOAT ? GetWaterLevel(VehiclePosition) : GetTerrainHeight(VehiclePosition); distanceAboveGround = VehiclePosition.Z - targetHeight; // Not colliding if the vehicle is off the ground if (!Prim.IsColliding) { // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); - ret = new Vector3(0, 0, -distanceAboveGround); + VehicleVelocity += new Vector3(0, 0, -distanceAboveGround); } // TODO: this calculation is wrong. From the description at // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce // has a decay factor. This says this force should // be computed with a motor. // TODO: add interaction with banking. - } - VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},colliding={2},ret={3}", + VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},colliding={2},ret={3}", Prim.LocalID, distanceAboveGround, Prim.IsColliding, ret); - return ret; + */ + + // Another approach is to measure if we're going up. If going up and not colliding, + // the vehicle is in the air. Fix that by pushing down. + if (!Prim.IsColliding && VehicleVelocity.Z > 0.1) + { + // Get rid of any of the velocity vector that is pushing us up. + VehicleVelocity += new Vector3(0, 0, -VehicleVelocity.Z); + + // If we're pointed up into the air, we should nose down + Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation; + // The rotation around the Y axis is pitch up or down + if (pointingDirection.Y > 0.01f) + { + float angularCorrectionForce = -(float)Math.Asin(pointingDirection.Y); + Vector3 angularCorrectionVector = new Vector3(0f, angularCorrectionForce, 0f); + // Rotate into world coordinates and apply to vehicle + angularCorrectionVector *= VehicleOrientation; + VehicleAddAngularForce(angularCorrectionVector); + VDetailLog("{0}, MoveLinear,limitMotorUp,newVel={1},pntDir={2},corrFrc={3},aCorr={4}", + Prim.LocalID, VehicleVelocity, pointingDirection, angularCorrectionForce, angularCorrectionVector); + } + else + { + VDetailLog("{0}, MoveLinear,limitMotorUp,newVel={1},pntDir={2}", + Prim.LocalID, VehicleVelocity, pointingDirection); + } + } + } } // ======================================================================= diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 23d573f..27ff047 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -80,6 +80,7 @@ public static class BSParam public static float AvatarStepForceFactor { get; private set; } public static float VehicleAngularDamping { get; private set; } + public static float VehicleDebuggingEnabled { get; private set; } public static float LinksetImplementation { get; private set; } public static float LinkConstraintUseFrameOffset { get; private set; } @@ -427,6 +428,11 @@ public static class BSParam (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); }, (s) => { return VehicleAngularDamping; }, (s,p,l,v) => { VehicleAngularDamping = v; } ), + new ParameterDefn("VehicleDebuggingEnable", "Turn on/off vehicle debugging", + ConfigurationParameters.numericFalse, + (s,cf,p,v) => { VehicleDebuggingEnabled = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return VehicleDebuggingEnabled; }, + (s,p,l,v) => { VehicleDebuggingEnabled = v; } ), new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", 0f, -- cgit v1.1 From daacd4deed9630b67738b342078f0b334e74aa4b Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 9 Jan 2013 17:40:22 -0800 Subject: Fix exception reporting in SceneObjectPart so it logs what the exception is rather than just saying it happened. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 232861e..44e8fdf 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4050,9 +4050,9 @@ namespace OpenSim.Region.Framework.Scenes rigidBody, m_localId); } - catch + catch (Exception e) { - m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom.", m_uuid); + m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e); pa = null; } -- cgit v1.1 From 93adc4cb6689b156db4db315d44b5ba0ddcd65ac Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 9 Jan 2013 22:45:01 -0800 Subject: BulletSim: Add IsSelected attribute to physical objects. Have vehicles check to see if physical before trying to step. Replace vehicle gravity application. Previously relying on Bullet to apply gravity but since vehicles over-ride the velocity calculation, gravity never had a chance to accelerate the body down. Added AddForceImpulse as well as AddForce for those who need to apply immediate velocity updates. Use the impulse to apply the linear motion. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 4 + OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 126 ++++++++++++++++----- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 1 + OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 81 +++++++++---- 4 files changed, 162 insertions(+), 50 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 939d38a..aadb583 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -328,6 +328,10 @@ public sealed class BSCharacter : BSPhysObject public override bool Selected { set { _selected = value; } } + public override bool IsSelected + { + get { return _selected; } + } public override void CrossingFailure() { return; } public override void link(PhysicsActor obj) { return; } public override void delink() { return; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 2e44ab6..80fdfb9 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -108,10 +108,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin private float m_VhoverEfficiency = 0f; private float m_VhoverTimescale = 0f; private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height - private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle. - // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity) - // KF: So far I have found no good method to combine a script-requested .Z velocity and gravity. - // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity. + // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity) + private float m_VehicleBuoyancy = 0f; + private Vector3 m_VehicleGravity = Vector3.Zero; // Gravity computed when buoyancy set //Attractor properties private BSVMotor m_verticalAttractionMotor = new BSVMotor("VerticalAttraction"); @@ -149,14 +148,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin enableAngularVerticalAttraction = false; enableAngularDeflection = false; enableAngularBanking = false; - VDetailLog("{0},BSDynamics.SetupVehicleDebugging,settingDebugMode"); + VDetailLog("{0},BSDynamics.SetupVehicleDebugging,settingDebugMode", Prim.LocalID); } } // Return 'true' if this vehicle is doing vehicle things public bool IsActive { - get { return Type != Vehicle.TYPE_NONE && Prim.IsPhysical; } + get { return (Type != Vehicle.TYPE_NONE && !Prim.IsStatic); } } #region Vehicle parameter setting @@ -190,6 +189,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin break; case Vehicle.BUOYANCY: m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f); + m_VehicleGravity = Prim.ComputeGravity(m_VehicleBuoyancy); break; case Vehicle.HOVER_EFFICIENCY: m_VhoverEfficiency = ClampInRange(0f, pValue, 1f); @@ -562,12 +562,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin 1f); m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) + /* Not implemented m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale, BSMotor.Infinite, BSMotor.InfiniteVector, m_verticalAttractionEfficiency); // Z goes away and we keep X and Y m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f); m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) + */ } #endregion // Vehicle parameter setting @@ -599,11 +601,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Set the gravity for the vehicle depending on the buoyancy // TODO: what should be done if prim and vehicle buoyancy differ? - Vector3 grav = Prim.ComputeGravity(m_VehicleBuoyancy); - PhysicsScene.PE.SetGravity(Prim.PhysBody, grav); + m_VehicleGravity = Prim.ComputeGravity(m_VehicleBuoyancy); + // The actual vehicle gravity is set to zero in Bullet so we can do all the application of same. + PhysicsScene.PE.SetGravity(Prim.PhysBody, Vector3.Zero); VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4},grav={5}", - Prim.LocalID, m_vehicleMass, friction, Prim.Inertia, angularDamping, grav); + Prim.LocalID, m_vehicleMass, friction, Prim.Inertia, angularDamping, m_VehicleGravity); } else { @@ -643,6 +646,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin private Vector3 m_knownPosition; private Vector3 m_knownVelocity; private Vector3 m_knownForce; + private Vector3 m_knownForceImpulse; private Quaternion m_knownOrientation; private Vector3 m_knownRotationalVelocity; private Vector3 m_knownRotationalForce; @@ -651,12 +655,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin private const int m_knownChangedPosition = 1 << 0; private const int m_knownChangedVelocity = 1 << 1; private const int m_knownChangedForce = 1 << 2; - private const int m_knownChangedOrientation = 1 << 3; - private const int m_knownChangedRotationalVelocity = 1 << 4; - private const int m_knownChangedRotationalForce = 1 << 5; - private const int m_knownChangedTerrainHeight = 1 << 6; - private const int m_knownChangedWaterLevel = 1 << 7; - private const int m_knownChangedForwardVelocity = 1 << 8; + private const int m_knownChangedForceImpulse = 1 << 3; + private const int m_knownChangedOrientation = 1 << 4; + private const int m_knownChangedRotationalVelocity = 1 << 5; + private const int m_knownChangedRotationalForce = 1 << 6; + private const int m_knownChangedTerrainHeight = 1 << 7; + private const int m_knownChangedWaterLevel = 1 << 8; + private const int m_knownChangedForwardVelocity = 1 << 9; private void ForgetKnownVehicleProperties() { @@ -677,21 +682,29 @@ namespace OpenSim.Region.Physics.BulletSPlugin if ((m_knownChanged & m_knownChangedVelocity) != 0) { Prim.ForceVelocity = m_knownVelocity; - PhysicsScene.PE.SetInterpolationLinearVelocity(Prim.PhysBody, VehicleVelocity); + // Fake out Bullet by making it think the velocity is the same as last time. + // Bullet does a bunch of smoothing for changing parameters. + // Since the vehicle is demanding this setting, we override Bullet's smoothing + // by telling Bullet the value was the same last time. + PhysicsScene.PE.SetInterpolationLinearVelocity(Prim.PhysBody, m_knownVelocity); } if ((m_knownChanged & m_knownChangedForce) != 0) Prim.AddForce((Vector3)m_knownForce, false, true); + if ((m_knownChanged & m_knownChangedForceImpulse) != 0) + Prim.AddForceImpulse((Vector3)m_knownForceImpulse, false, true); + if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) { Prim.ForceRotationalVelocity = m_knownRotationalVelocity; - // Fake out Bullet by making it think the velocity is the same as last time. PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity); } if ((m_knownChanged & m_knownChangedRotationalForce) != 0) + { Prim.AddAngularForce((Vector3)m_knownRotationalForce, false, true); + } // If we set one of the values (ie, the physics engine didn't do it) we must force // an UpdateProperties event to send the changes up to the simulator. @@ -781,15 +794,26 @@ namespace OpenSim.Region.Physics.BulletSPlugin } } - private void VehicleAddForce(Vector3 aForce) + private void VehicleAddForce(Vector3 pForce) { if ((m_knownHas & m_knownChangedForce) == 0) { m_knownForce = Vector3.Zero; + m_knownHas |= m_knownChangedForce; } - m_knownForce += aForce; + m_knownForce += pForce; m_knownChanged |= m_knownChangedForce; - m_knownHas |= m_knownChangedForce; + } + + private void VehicleAddForceImpulse(Vector3 pImpulse) + { + if ((m_knownHas & m_knownChangedForceImpulse) == 0) + { + m_knownForceImpulse = Vector3.Zero; + m_knownHas |= m_knownChangedForceImpulse; + } + m_knownForceImpulse += pImpulse; + m_knownChanged |= m_knownChangedForceImpulse; } private Vector3 VehicleRotationalVelocity @@ -868,20 +892,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (PhysicsScene.VehiclePhysicalLoggingEnabled) PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody); - VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", - Prim.LocalID, VehiclePosition, Prim.Force, VehicleVelocity, VehicleRotationalVelocity); + VDetailLog("{0},BSDynamics.Step,done,pos={1}, force={2},velocity={3},angvel={4}", + Prim.LocalID, VehiclePosition, m_knownForce, VehicleVelocity, VehicleRotationalVelocity); } // Apply the effect of the linear motor and other linear motions (like hover and float). private void MoveLinear(float pTimestep) { - Vector3 linearMotorContribution = m_linearMotor.Step(pTimestep); - - // The movement computed in the linear motor is relative to the vehicle - // coordinates. Rotate the movement to world coordinates. - linearMotorContribution *= VehicleOrientation; - - VehicleVelocity = linearMotorContribution; + ComputeLinearVelocity(pTimestep); ComputeLinearTerrainHeightCorrection(pTimestep); @@ -891,6 +909,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin ComputeLinearMotorUp(pTimestep); + ApplyGravity(pTimestep); + // If not changing some axis, reduce out velocity if ((m_flags & (VehicleFlag.NO_X | VehicleFlag.NO_Y | VehicleFlag.NO_Z)) != 0) { @@ -919,6 +939,43 @@ namespace OpenSim.Region.Physics.BulletSPlugin } // end MoveLinear() + public void ComputeLinearVelocity(float pTimestep) + { + Vector3 linearMotorStep = m_linearMotor.Step(pTimestep); + + // The movement computed in the linear motor is relative to the vehicle + // coordinates. Rotate the movement to world coordinates. + Vector3 linearMotorVelocity = linearMotorStep * VehicleOrientation; + + // If we're a ground vehicle, don't loose any Z action (like gravity acceleration). + float mixFactor = 1f; // 1 means use all linear motor Z value, 0 means use all existing Z + if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0) + { + if (!Prim.IsColliding) + { + // If a ground vehicle and not on the ground, I want gravity effect + mixFactor = 0.2f; + } + } + else + { + // I'm not a ground vehicle but don't totally loose the effect of the environment + mixFactor = 0.8f; + } + linearMotorVelocity.Z = mixFactor * linearMotorVelocity.Z + (1f - mixFactor) * VehicleVelocity.Z; + + // What we want to contribute to the vehicle's existing velocity + Vector3 linearMotorForce = linearMotorVelocity - VehicleVelocity; + + // Act against the inertia of the vehicle + linearMotorForce *= m_vehicleMass; + + VehicleAddForceImpulse(linearMotorForce); + + VDetailLog("{0}, MoveLinear,velocity,vehVel={1},step={2},stepVel={3},mix={4},force={5}", + Prim.LocalID, VehicleVelocity, linearMotorStep, linearMotorVelocity, mixFactor, linearMotorForce); + } + public void ComputeLinearTerrainHeightCorrection(float pTimestep) { // If below the terrain, move us above the ground a little. @@ -979,7 +1036,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; // TODO: implement m_VhoverEfficiency correctly - VehicleVelocity += new Vector3(0f, 0f, verticalCorrectionVelocity); + VehicleAddForceImpulse(new Vector3(0f, 0f, verticalCorrectionVelocity)); VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},err={6},corrVel={7}", Prim.LocalID, VehiclePosition, m_VhoverEfficiency, @@ -1096,6 +1153,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin } } + private void ApplyGravity(float pTimeStep) + { + Vector3 appliedGravity = m_VehicleGravity * m_vehicleMass; + VehicleAddForce(appliedGravity); + + VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},appliedForce-{2}", + Prim.LocalID, m_VehicleGravity, appliedGravity); + } + // ======================================================================= // ======================================================================= // Apply the effect of the angular motor. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index e8575f6..2c84293 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -135,6 +135,7 @@ public abstract class BSPhysObject : PhysicsActor public virtual OMV.Vector3 Scale { get; set; } public abstract bool IsSolid { get; } public abstract bool IsStatic { get; } + public abstract bool IsSelected { get; } // Materialness public MaterialAttributes.Material Material { get; private set; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 50ba343..02d06b4 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -204,6 +204,10 @@ public sealed class BSPrim : BSPhysObject } } } + public override bool IsSelected + { + get { return _isSelected; } + } public override void CrossingFailure() { return; } // link me to the specified parent @@ -1153,33 +1157,70 @@ public sealed class BSPrim : BSPhysObject // This added force will only last the next simulation tick. public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { // for an object, doesn't matter if force is a pushforce or not - if (!IsStatic && force.IsFinite()) + if (!IsStatic) { - float magnitude = force.Length(); - if (magnitude > BSParam.MaxAddForceMagnitude) + if (force.IsFinite()) { - // Force has a limit - force = force / magnitude * BSParam.MaxAddForceMagnitude; - } + float magnitude = force.Length(); + if (magnitude > BSParam.MaxAddForceMagnitude) + { + // Force has a limit + force = force / magnitude * BSParam.MaxAddForceMagnitude; + } - OMV.Vector3 addForce = force; - // DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); + OMV.Vector3 addForce = force; + // DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); - PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() - { - // Bullet adds this central force to the total force for this tick - DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce); - if (PhysBody.HasPhysicalBody) + PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() { - PhysicsScene.PE.ApplyCentralForce(PhysBody, addForce); - ActivateIfPhysical(false); - } - }); + // Bullet adds this central force to the total force for this tick + DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce); + if (PhysBody.HasPhysicalBody) + { + PhysicsScene.PE.ApplyCentralForce(PhysBody, addForce); + ActivateIfPhysical(false); + } + }); + } + else + { + m_log.WarnFormat("{0}: AddForce: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID); + return; + } } - else + } + + public void AddForceImpulse(OMV.Vector3 impulse, bool pushforce, bool inTaintTime) { + // for an object, doesn't matter if force is a pushforce or not + if (!IsStatic) { - m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID); - return; + if (impulse.IsFinite()) + { + float magnitude = impulse.Length(); + if (magnitude > BSParam.MaxAddForceMagnitude) + { + // Force has a limit + impulse = impulse / magnitude * BSParam.MaxAddForceMagnitude; + } + + // DetailLog("{0},BSPrim.addForceImpulse,call,impulse={1}", LocalID, impulse); + OMV.Vector3 addImpulse = impulse; + PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddImpulse", delegate() + { + // Bullet adds this impulse immediately to the velocity + DetailLog("{0},BSPrim.addForceImpulse,taint,impulseforce={1}", LocalID, addImpulse); + if (PhysBody.HasPhysicalBody) + { + PhysicsScene.PE.ApplyCentralImpulse(PhysBody, addImpulse); + ActivateIfPhysical(false); + } + }); + } + else + { + m_log.WarnFormat("{0}: AddForceImpulse: Got a NaN impulse applied to a prim. LocalID={1}", LogHeader, LocalID); + return; + } } } -- cgit v1.1 From eacc2561d14dbe9cba6966e3b32bfd776e044f8a Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 10 Jan 2013 17:03:19 -0800 Subject: BulletSim: add osGetPhysicsEngineType() LSL function and update the physics engines to return the name that is specified in the INI file ("physics = XXX") as the type of engine. This os function is a little different than the others in that it does not throw an exception of one is not privilaged to use it. It merely returns an empty string. --- .../BasicPhysicsPlugin/BasicPhysicsPlugin.cs | 2 +- .../BasicPhysicsPlugin/BasicPhysicsScene.cs | 4 +- OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 9 +++- OpenSim/Region/Physics/Manager/PhysicsScene.cs | 11 +++- OpenSim/Region/Physics/OdePlugin/OdePlugin.cs | 2 +- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 3 +- OpenSim/Region/Physics/POSPlugin/POSPlugin.cs | 2 +- OpenSim/Region/Physics/POSPlugin/POSScene.cs | 4 +- .../Shared/Api/Implementation/OSSL_Api.cs | 59 ++++++++++++++++++---- .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 1 + .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 5 ++ 12 files changed, 82 insertions(+), 22 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs index 7ab2a03..373c7e0 100644 --- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs @@ -49,7 +49,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin public PhysicsScene GetScene(string sceneIdentifier) { - return new BasicScene(sceneIdentifier); + return new BasicScene(GetName(), sceneIdentifier); } public string GetName() diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs index f5826ed..c4b9117 100644 --- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs @@ -49,8 +49,10 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin //protected internal string sceneIdentifier; - public BasicScene(string _sceneIdentifier) + public BasicScene(string engineType, string _sceneIdentifier) { + EngineType = engineType; + Name = EngineType + "/" + _sceneIdentifier; //sceneIdentifier = _sceneIdentifier; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs index 65be52a..9442854 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs @@ -59,7 +59,7 @@ public class BSPlugin : IPhysicsPlugin { if (_mScene == null) { - _mScene = new BSScene(sceneIdentifier); + _mScene = new BSScene(GetName(), sceneIdentifier); } return (_mScene); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 4a6cebd..a5bdc07 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -167,11 +167,16 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public bool VehiclePhysicalLoggingEnabled { get; private set; } #region Construction and Initialization - public BSScene(string identifier) + public BSScene(string engineType, string identifier) { m_initialized = false; - // we are passed the name of the region we're working for. + + // The name of the region we're working for is passed to us. Keep for identification. RegionName = identifier; + + // Set identifying variables in the PhysicsScene interface. + EngineType = engineType; + Name = EngineType + "/" + RegionName; } public override void Initialise(IMesher meshmerizer, IConfigSource config) diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index 488900e..201007b 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs @@ -62,13 +62,20 @@ namespace OpenSim.Region.Physics.Manager // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); /// - /// Name of this scene. Useful in debug messages to distinguish one OdeScene instance from another. + /// A unique identifying string for this instance of the physics engine. + /// Useful in debug messages to distinguish one OdeScene instance from another. + /// Usually set to include the region name that the physics engine is acting for. /// public string Name { get; protected set; } + /// + /// A string identifying the family of this physics engine. Most common values returned + /// are "OpenDynamicsEngine" and "BulletSim" but others are possible. + /// + public string EngineType { get; protected set; } + // The only thing that should register for this event is the SceneGraph // Anything else could cause problems. - public event physicsCrash OnPhysicsCrash; public static PhysicsScene Null diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs index 478dd95..07663b3 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs @@ -72,7 +72,7 @@ namespace OpenSim.Region.Physics.OdePlugin // http://opensimulator.org/mantis/view.php?id=2750). d.InitODE(); - m_scene = new OdeScene(sceneIdentifier); + m_scene = new OdeScene(GetName(), sceneIdentifier); } return m_scene; diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index d53bd90..02a0b15 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -526,11 +526,12 @@ namespace OpenSim.Region.Physics.OdePlugin /// These settings need to be tweaked 'exactly' right or weird stuff happens. /// /// Name of the scene. Useful in debug messages. - public OdeScene(string name) + public OdeScene(string engineType, string name) { m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType.ToString() + "." + name); Name = name; + EngineType = engineType; nearCallback = near; triCallback = TriCallback; diff --git a/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs b/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs index e6b42e6..ed086dd 100644 --- a/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs +++ b/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs @@ -49,7 +49,7 @@ namespace OpenSim.Region.Physics.POSPlugin public PhysicsScene GetScene(string sceneIdentifier) { - return new POSScene(sceneIdentifier); + return new POSScene(GetName(), sceneIdentifier); } public string GetName() diff --git a/OpenSim/Region/Physics/POSPlugin/POSScene.cs b/OpenSim/Region/Physics/POSPlugin/POSScene.cs index 2f24a50..d30d482 100644 --- a/OpenSim/Region/Physics/POSPlugin/POSScene.cs +++ b/OpenSim/Region/Physics/POSPlugin/POSScene.cs @@ -43,8 +43,10 @@ namespace OpenSim.Region.Physics.POSPlugin //protected internal string sceneIdentifier; - public POSScene(String _sceneIdentifier) + public POSScene(string engineType, String _sceneIdentifier) { + EngineType = engineType; + Name = EngineType + "/" + _sceneIdentifier; //sceneIdentifier = _sceneIdentifier; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 33c02ef..958a448 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -245,11 +245,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message); } + // Returns of the function is allowed. Throws a script exception if not allowed. public void CheckThreatLevel(ThreatLevel level, string function) { if (!m_OSFunctionsEnabled) OSSLError(String.Format("{0} permission denied. All OS functions are disabled.", function)); // throws + string reasonWhyNot = CheckThreatLevelTest(level, function); + if (!String.IsNullOrEmpty(reasonWhyNot)) + { + OSSLError(reasonWhyNot); + } + } + + // Check to see if function is allowed. Returns an empty string if function permitted + // or a string explaining why this function can't be used. + private string CheckThreatLevelTest(ThreatLevel level, string function) + { if (!m_FunctionPerms.ContainsKey(function)) { FunctionPerms perms = new FunctionPerms(); @@ -329,10 +341,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { // Allow / disallow by threat level if (level > m_MaxThreatLevel) - OSSLError( + return String.Format( "{0} permission denied. Allowed threat level is {1} but function threat level is {2}.", - function, m_MaxThreatLevel, level)); + function, m_MaxThreatLevel, level); } else { @@ -342,7 +354,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (m_FunctionPerms[function].AllowedOwners.Contains(m_host.OwnerID)) { // prim owner is in the list of allowed owners - return; + return String.Empty; } UUID ownerID = m_item.OwnerID; @@ -354,7 +366,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (land.LandData.GroupID == m_item.GroupID && land.LandData.GroupID != UUID.Zero) { - return; + return String.Empty; } } @@ -365,7 +377,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (land.LandData.OwnerID == ownerID) { - return; + return String.Empty; } } @@ -375,7 +387,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api //Only Estate Managers may use the function if (World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(ownerID) && World.RegionInfo.EstateSettings.EstateOwner != ownerID) { - return; + return String.Empty; } } @@ -384,25 +396,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { if (World.RegionInfo.EstateSettings.EstateOwner == ownerID) { - return; + return String.Empty; } } if (!m_FunctionPerms[function].AllowedCreators.Contains(m_item.CreatorID)) - OSSLError( + return( String.Format("{0} permission denied. Script creator is not in the list of users allowed to execute this function and prim owner also has no permission.", function)); if (m_item.CreatorID != ownerID) { if ((m_item.CurrentPermissions & (uint)PermissionMask.Modify) != 0) - OSSLError( - String.Format("{0} permission denied. Script permissions error.", - function)); + return String.Format("{0} permission denied. Script permissions error.", function); } } } + return String.Empty; } internal void OSSLDeprecated(string function, string replacement) @@ -1558,6 +1569,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } + public string osGetPhysicsEngineType() + { + // High because it can be used to target attacks to known weaknesses + // This would allow a new class of griefer scripts that don't even + // require their user to know what they are doing (see script + // kiddie) + // Because it would be nice if scripts didn't blow up if the information + // about the physics engine, this function returns an empty string if + // the user does not have permission to see it. This as opposed to + // throwing an exception. + m_host.AddScriptLPS(1); + string ret = String.Empty; + if (String.IsNullOrEmpty(CheckThreatLevelTest(ThreatLevel.High, "osGetPhysicsEngineType"))) + { + if (m_ScriptEngine.World.PhysicsScene != null) + { + ret = m_ScriptEngine.World.PhysicsScene.EngineType; + // An old physics engine might have an uninitialized engine type + if (ret == null) + ret = "unknown"; + } + } + + return ret; + } + public string osGetSimulatorVersion() { // High because it can be used to target attacks to known weaknesses diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index cdd9ea8..51d0581 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -259,6 +259,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces string osGetScriptEngineName(); string osGetSimulatorVersion(); + string osGetPhysicsEngineType(); Object osParseJSONNew(string JSON); Hashtable osParseJSON(string JSON); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index afa9ae0..c9902e4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -420,6 +420,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_OSSL_Functions.osGetScriptEngineName(); } + public string osGetPhysicsEngineType() + { + return m_OSSL_Functions.osGetPhysicsEngineType(); + } + public string osGetSimulatorVersion() { return m_OSSL_Functions.osGetSimulatorVersion(); -- cgit v1.1 From 459fcd81c9d6e7c92738b40f1b4b4fe746699379 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 11 Jan 2013 16:36:34 -0800 Subject: BulletSim: move center of gravity of linkset to its geometric center. Necessitated allowing simulator and physical position of a body to get out of sync since Bullet assumes that <0,0,0> is the center of mass. Update DLLs and SOs for the UpdateChildTransform so positions of individual prim in a linkset can be implemented. --- OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | 9 ++++ OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs | 1 + .../Region/Physics/BulletSPlugin/BSApiTemplate.cs | 2 + OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 13 +++-- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 4 +- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 55 +++++++++++++++++----- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 10 ++++ OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 40 ++++++++++++---- .../Physics/BulletSPlugin/BSShapeCollection.cs | 2 +- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 2 + 10 files changed, 106 insertions(+), 32 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs index 14de2eb..0fef67c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs @@ -327,6 +327,12 @@ public override void RemoveChildShapeFromCompoundShape(BulletShape shape, Bullet BSAPICPP.RemoveChildShapeFromCompoundShape2(shapeu.ptr, removeShapeu.ptr); } +public override void UpdateChildTransform(BulletShape pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb) +{ + BulletShapeUnman shapeu = pShape as BulletShapeUnman; + BSAPICPP.UpdateChildTransform2(shapeu.ptr, childIndex, pos, rot, shouldRecalculateLocalAabb); +} + public override void RecalculateCompoundShapeLocalAabb(BulletShape shape) { BulletShapeUnman shapeu = shape as BulletShapeUnman; @@ -1357,6 +1363,9 @@ public static extern IntPtr RemoveChildShapeFromCompoundShapeIndex2(IntPtr cShap public static extern void RemoveChildShapeFromCompoundShape2(IntPtr cShape, IntPtr removeShape); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern void UpdateChildTransform2(IntPtr pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern void RecalculateCompoundShapeLocalAabb2(IntPtr cShape); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs index 0c7f315..b6ff52b 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs @@ -1212,6 +1212,7 @@ private sealed class BulletConstraintXNA : BulletConstraint public override BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) { /* TODO */ return null; } public override void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape) { /* TODO */ } + public override void UpdateChildTransform(BulletShape pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb) { /* TODO */ } public override BulletShape CreateGroundPlaneShape(uint pLocalId, float pheight, float pcollisionMargin) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index 794ee17..bc163eb 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs @@ -342,6 +342,8 @@ public abstract BulletShape RemoveChildShapeFromCompoundShapeIndex(BulletShape c public abstract void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape); +public abstract void UpdateChildTransform(BulletShape pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb); + public abstract void RecalculateCompoundShapeLocalAabb(BulletShape cShape); public abstract BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 80fdfb9..bcebaec 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -148,7 +148,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin enableAngularVerticalAttraction = false; enableAngularDeflection = false; enableAngularBanking = false; - VDetailLog("{0},BSDynamics.SetupVehicleDebugging,settingDebugMode", Prim.LocalID); } } @@ -690,10 +689,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin } if ((m_knownChanged & m_knownChangedForce) != 0) - Prim.AddForce((Vector3)m_knownForce, false, true); + Prim.AddForce((Vector3)m_knownForce, false /*pushForce*/, true /*inTaintTime*/); if ((m_knownChanged & m_knownChangedForceImpulse) != 0) - Prim.AddForceImpulse((Vector3)m_knownForceImpulse, false, true); + Prim.AddForceImpulse((Vector3)m_knownForceImpulse, false /*pushforce*/, true /*inTaintTime*/); if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) { @@ -703,7 +702,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin if ((m_knownChanged & m_knownChangedRotationalForce) != 0) { - Prim.AddAngularForce((Vector3)m_knownRotationalForce, false, true); + Prim.AddAngularForce((Vector3)m_knownRotationalForce, false /*pushForce*/, true /*inTaintTime*/); } // If we set one of the values (ie, the physics engine didn't do it) we must force @@ -970,7 +969,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Act against the inertia of the vehicle linearMotorForce *= m_vehicleMass; - VehicleAddForceImpulse(linearMotorForce); + VehicleAddForceImpulse(linearMotorForce * pTimestep); VDetailLog("{0}, MoveLinear,velocity,vehVel={1},step={2},stepVel={3},mix={4},force={5}", Prim.LocalID, VehicleVelocity, linearMotorStep, linearMotorVelocity, mixFactor, linearMotorForce); @@ -1033,7 +1032,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { // Error is positive if below the target and negative if above. float verticalError = m_VhoverTargetHeight - VehiclePosition.Z; - float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; + float verticalCorrectionVelocity = verticalError / m_VhoverTimescale * pTimestep; // TODO: implement m_VhoverEfficiency correctly VehicleAddForceImpulse(new Vector3(0f, 0f, verticalCorrectionVelocity)); @@ -1323,7 +1322,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // this creates an over-correction and then wabbling as the target is overshot. // TODO: rethink how the different correction computations inter-relate. - if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleVelocity != Vector3.Zero) + if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2) { // The direction the vehicle is moving Vector3 movingDirection = VehicleVelocity; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 756faed..cbd160f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -152,6 +152,7 @@ public abstract class BSLinkset if (IsRoot(child)) { // Cannot remove the root from a linkset. + child.PositionDisplacement = OMV.Vector3.Zero; return this; } RemoveChildFromLinkset(child); @@ -159,6 +160,7 @@ public abstract class BSLinkset } // The child is down to a linkset of just itself + child.PositionDisplacement = OMV.Vector3.Zero; return BSLinkset.Factory(PhysicsScene, child); } @@ -310,7 +312,7 @@ public abstract class BSLinkset foreach (BSPhysObject bp in m_children) { - com += bp.Position * bp.RawMass; + com += bp.Position; } com /= (m_children.Count + 1); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index bd03d31..ad8024c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -40,23 +40,33 @@ namespace OpenSim.Region.Physics.BulletSPlugin // removed from the linkset. sealed class BSLinksetCompoundInfo : BSLinksetInfo { - public OMV.Vector3 OffsetPos; + public int Index; + public OMV.Vector3 OffsetFromRoot; + public OMV.Vector3 OffsetFromCenterOfMass; public OMV.Quaternion OffsetRot; - public BSLinksetCompoundInfo(OMV.Vector3 p, OMV.Quaternion r) + public BSLinksetCompoundInfo(int indx, OMV.Vector3 p, OMV.Quaternion r) { - OffsetPos = p; + Index = indx; + OffsetFromRoot = p; + OffsetFromCenterOfMass = p; OffsetRot = r; } public override void Clear() { - OffsetPos = OMV.Vector3.Zero; + Index = 0; + OffsetFromRoot = OMV.Vector3.Zero; + OffsetFromCenterOfMass = OMV.Vector3.Zero; OffsetRot = OMV.Quaternion.Identity; } public override string ToString() { StringBuilder buff = new StringBuilder(); - buff.Append(""); @@ -170,6 +180,8 @@ public sealed class BSLinksetCompound : BSLinkset return ret; } + // 'physicalUpdate' is true if these changes came directly from the physics engine. Don't need to rebuild then. + // Called at taint-time. public override void UpdateProperties(BSPhysObject updated, bool physicalUpdate) { // The user moving a child around requires the rebuilding of the linkset compound shape @@ -182,6 +194,7 @@ public sealed class BSLinksetCompound : BSLinkset && !physicalUpdate && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition)) { + // TODO: replace this with are calculation of the child prim's orientation and pos. updated.LinksetInfo = null; ScheduleRebuild(updated); } @@ -230,7 +243,7 @@ public sealed class BSLinksetCompound : BSLinkset if (inTaintTime) { OMV.Vector3 oldPos = child.RawPosition; - child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetPos; + child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetFromRoot; child.ForceOrientation = LinksetRoot.RawOrientation * lci.OffsetRot; DetailLog("{0},BSLinksetCompound.RecomputeChildWorldPosition,oldPos={1},lci={2},newPos={3}", child.LocalID, oldPos, lci, child.RawPosition); @@ -238,7 +251,7 @@ public sealed class BSLinksetCompound : BSLinkset else { // TaintedObject is not used here so the raw position is set now and not at taint-time. - child.Position = LinksetRoot.RawPosition + lci.OffsetPos; + child.Position = LinksetRoot.RawPosition + lci.OffsetFromRoot; child.Orientation = LinksetRoot.RawOrientation * lci.OffsetRot; } } @@ -316,10 +329,23 @@ public sealed class BSLinksetCompound : BSLinkset // Cause the root shape to be rebuilt as a compound object with just the root in it LinksetRoot.ForceBodyShapeRebuild(true); + // The center of mass for the linkset is the geometric center of the group. + // Compute a displacement for each component so it is relative to the center-of-mass. + OMV.Vector3 centerOfMass = ComputeLinksetGeometricCenter(); + OMV.Vector3 centerDisplacement = centerOfMass - LinksetRoot.RawPosition; + + // Since we're displacing the center of the shape, we need to move the body in the world + LinksetRoot.PositionDisplacement = centerDisplacement * LinksetRoot.RawOrientation; + + PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, -centerDisplacement, OMV.Quaternion.Identity, false); + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}", + LinksetRoot.LocalID, centerOfMass, LinksetRoot.RawPosition, centerDisplacement); + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); // Add a shape for each of the other children in the linkset + int memberIndex = 1; ForEachMember(delegate(BSPhysObject cPrim) { if (!IsRoot(cPrim)) @@ -337,13 +363,14 @@ public sealed class BSLinksetCompound : BSLinkset OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; // Save relative position for recomputing child's world position after moving linkset. - lci = new BSLinksetCompoundInfo(displacementPos, displacementRot); + lci = new BSLinksetCompoundInfo(memberIndex, displacementPos, displacementRot); + lci.OffsetFromCenterOfMass = displacementPos - centerDisplacement; cPrim.LinksetInfo = lci; DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); } - DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}", - LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},lci={3}", + LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci); if (cPrim.PhysShape.isNativeShape) { @@ -359,7 +386,7 @@ public sealed class BSLinksetCompound : BSLinkset PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); BulletShape newShape = cPrim.PhysShape; cPrim.PhysShape = saveShape; - PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetPos, lci.OffsetRot); + PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetFromCenterOfMass, lci.OffsetRot); } else { @@ -371,8 +398,10 @@ public sealed class BSLinksetCompound : BSLinkset PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); } - PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); + PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetFromCenterOfMass, lci.OffsetRot); } + lci.Index = memberIndex; + memberIndex++; } return false; // 'false' says to move onto the next child in the list }); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 2c84293..185f111 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -73,6 +73,8 @@ public abstract class BSPhysObject : PhysicsActor // A linkset of just me Linkset = BSLinkset.Factory(PhysicsScene, this); + PositionDisplacement = OMV.Vector3.Zero; + LastAssetBuildFailed = false; // Default material type @@ -157,6 +159,14 @@ public abstract class BSPhysObject : PhysicsActor public abstract OMV.Vector3 RawPosition { get; set; } public abstract OMV.Vector3 ForcePosition { get; set; } + // Position is what the simulator thinks the positions of the prim is. + // Because Bullet needs the zero coordinate to be the center of mass of the linkset, + // sometimes it is necessary to displace the position the physics engine thinks + // the position is. PositionDisplacement must be added and removed from the + // position as the simulator position is stored and fetched from the physics + // engine. + public virtual OMV.Vector3 PositionDisplacement { get; set; } + public abstract OMV.Quaternion RawOrientation { get; set; } public abstract OMV.Quaternion ForceOrientation { get; set; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 02d06b4..003dc54 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -50,7 +50,10 @@ public sealed class BSPrim : BSPhysObject private bool _grabbed; private bool _isSelected; private bool _isVolumeDetect; + + // _position is what the simulator thinks the positions of the prim is. private OMV.Vector3 _position; + private float _mass; // the mass of this object private float _density; private OMV.Vector3 _force; @@ -320,18 +323,37 @@ public sealed class BSPrim : BSPhysObject } public override OMV.Vector3 ForcePosition { get { - _position = PhysicsScene.PE.GetPosition(PhysBody); + _position = PhysicsScene.PE.GetPosition(PhysBody) - PositionDisplacement; return _position; } set { _position = value; if (PhysBody.HasPhysicalBody) { - PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); + PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation); ActivateIfPhysical(false); } } } + // Override to have position displacement immediately update the physical position. + // A feeble attempt to keep the sim and physical positions in sync + // Must be called at taint time. + public override OMV.Vector3 PositionDisplacement + { + get + { + return base.PositionDisplacement; + } + set + { + base.PositionDisplacement = value; + PhysicsScene.TaintedObject(PhysicsScene.InTaintTime, "BSPrim.setPosition", delegate() + { + if (PhysBody.HasPhysicalBody) + PhysicsScene.PE.SetTranslation(PhysBody, _position + base.PositionDisplacement, _orientation); + }); + } + } // Check that the current position is sane and, if not, modify the position to make it so. // Check for being below terrain and being out of bounds. @@ -590,6 +612,7 @@ public sealed class BSPrim : BSPhysObject _velocity = value; if (PhysBody.HasPhysicalBody) { + DetailLog("{0},BSPrim.ForceVelocity,taint,vel={1}", LocalID, _velocity); PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity); ActivateIfPhysical(false); } @@ -654,12 +677,7 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate() { - if (PhysBody.HasPhysicalBody) - { - // _position = PhysicsScene.PE.GetObjectPosition(PhysicsScene.World, BSBody); - // DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); - PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); - } + ForceOrientation = _orientation; }); } } @@ -674,7 +692,8 @@ public sealed class BSPrim : BSPhysObject set { _orientation = value; - PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); + if (PhysBody.HasPhysicalBody) + PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation); } } public override int PhysicsActorType { @@ -813,7 +832,7 @@ public sealed class BSPrim : BSPhysObject // PhysicsScene.PE.ClearAllForces(BSBody); // For good measure, make sure the transform is set through to the motion state - PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); + PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation); // Center of mass is at the center of the object // DEBUG DEBUG PhysicsScene.PE.SetCenterOfMassByPosRot(Linkset.LinksetRoot.PhysBody, _position, _orientation); @@ -1615,6 +1634,7 @@ public sealed class BSPrim : BSPhysObject } // Assign directly to the local variables so the normal set actions do not happen + entprop.Position -= PositionDisplacement; _position = entprop.Position; _orientation = entprop.Rotation; _velocity = entprop.Velocity; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index f0c6b99..addab29 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -906,7 +906,7 @@ public sealed class BSShapeCollection : IDisposable } } - // While we figure out the real problem, stick a simple native shape on the object. + // While we figure out the real problem, stick in a simple box for the object. BulletShape fillinShape = BuildPhysicalNativeShape(prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 1540dbb..59cbab9 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -170,6 +170,8 @@ Avatar attachments have no mass? http://forums-archive.secondlife.com/54/f0/3179 INTERNAL IMPROVEMENT/CLEANUP ================================================= +Can the 'inTaintTime' flag be cleaned up and used? For instance, a call to + BSScene.TaintedObject() could immediately execute the callback if already in taint time. Create the physical wrapper classes (BulletBody, BulletShape) by methods on BSAPITemplate and make their actual implementation Bullet engine specific. For the short term, just call the existing functions in ShapeCollection. -- cgit v1.1 From 8bf0a9f85dda4b1831630b65620d5c6868196c11 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 13 Jan 2013 22:32:31 -0800 Subject: BulletSim: disable center-of-mass computation for linksets until debugged. Move physical prim above ground if it is underground. Previously tried to correct by applying and up force but the prim would never go through the ground. --- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 35 +++++++++++++++------- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 26 ++++++++-------- 2 files changed, 36 insertions(+), 25 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index ad8024c..5a1b5c7 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -319,6 +319,7 @@ public sealed class BSLinksetCompound : BSLinkset // Constraint linksets are rebuilt every time. // Note that this works for rebuilding just the root after a linkset is taken apart. // Called at taint time!! + private bool disableCOM = true; // disable until we get this debugged private void RecomputeLinksetCompound() { try @@ -331,15 +332,26 @@ public sealed class BSLinksetCompound : BSLinkset // The center of mass for the linkset is the geometric center of the group. // Compute a displacement for each component so it is relative to the center-of-mass. - OMV.Vector3 centerOfMass = ComputeLinksetGeometricCenter(); - OMV.Vector3 centerDisplacement = centerOfMass - LinksetRoot.RawPosition; + // Bullet presumes an object's origin (relative <0,0,0>) is its center-of-mass + OMV.Vector3 centerOfMass; + OMV.Vector3 centerDisplacement = OMV.Vector3.Zero; + if (disableCOM) // DEBUG DEBUG + { // DEBUG DEBUG + centerOfMass = LinksetRoot.RawPosition; // DEBUG DEBUG + LinksetRoot.PositionDisplacement = OMV.Vector3.Zero; + } // DEBUG DEBUG + else + { + centerOfMass = ComputeLinksetGeometricCenter(); + centerDisplacement = centerOfMass - LinksetRoot.RawPosition; - // Since we're displacing the center of the shape, we need to move the body in the world - LinksetRoot.PositionDisplacement = centerDisplacement * LinksetRoot.RawOrientation; + // Since we're displacing the center of the shape, we need to move the body in the world + LinksetRoot.PositionDisplacement = centerDisplacement; - PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, -centerDisplacement, OMV.Quaternion.Identity, false); - DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}", - LinksetRoot.LocalID, centerOfMass, LinksetRoot.RawPosition, centerDisplacement); + PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, -centerDisplacement, OMV.Quaternion.Identity, false); + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}", + LinksetRoot.LocalID, centerOfMass, LinksetRoot.RawPosition, centerDisplacement); + } DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); @@ -357,14 +369,15 @@ public sealed class BSLinksetCompound : BSLinkset BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; if (lci == null) { - // Each child position and rotation is given relative to the root. + // Each child position and rotation is given relative to the center-of-mass. OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); - OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; + OMV.Vector3 displacementFromRoot = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; + OMV.Vector3 displacementFromCOM = displacementFromRoot - centerDisplacement; OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; // Save relative position for recomputing child's world position after moving linkset. - lci = new BSLinksetCompoundInfo(memberIndex, displacementPos, displacementRot); - lci.OffsetFromCenterOfMass = displacementPos - centerDisplacement; + lci = new BSLinksetCompoundInfo(memberIndex, displacementFromCOM, displacementRot); + lci.OffsetFromRoot = displacementFromRoot; cPrim.LinksetInfo = lci; DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 003dc54..e5f7ab7 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -297,7 +297,7 @@ public sealed class BSPrim : BSPhysObject */ // don't do the GetObjectPosition for root elements because this function is called a zillion times. - // _position = PhysicsScene.PE.GetObjectPosition2(PhysicsScene.World, BSBody); + // _position = PhysicsScene.PE.GetObjectPosition2(PhysicsScene.World, BSBody) - PositionDisplacement; return _position; } set { @@ -362,7 +362,7 @@ public sealed class BSPrim : BSPhysObject { bool ret = false; - if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position)) + if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition)) { // The physical object is out of the known/simulated area. // Upper levels of code will handle the transition to other areas so, for @@ -376,8 +376,11 @@ public sealed class BSPrim : BSPhysObject { DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); float targetHeight = terrainHeight + (Size.Z / 2f); - // Upforce proportional to the distance away from the terrain. Correct the error in 1 sec. - upForce.Z = (terrainHeight - RawPosition.Z) * 1f; + // If the object is below ground it just has to be moved up because pushing will + // not get it through the terrain + _position.Z = targetHeight; + if (!inTaintTime) + ForcePosition = _position; ret = true; } @@ -389,20 +392,15 @@ public sealed class BSPrim : BSPhysObject { // Upforce proportional to the distance away from the water. Correct the error in 1 sec. upForce.Z = (waterHeight - RawPosition.Z) * 1f; + + // Apply upforce and overcome gravity. + OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity; + DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce); + AddForce(correctionForce, false, inTaintTime); ret = true; } } - // The above code computes a force to apply to correct any out-of-bounds problems. Apply same. - // TODO: This should be intergrated with a geneal physics action mechanism. - // TODO: This should be moderated with PID'ness. - if (ret) - { - // Apply upforce and overcome gravity. - OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity; - DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce); - AddForce(correctionForce, false, inTaintTime); - } return ret; } -- cgit v1.1 From 7978b349bd400d14b7ecd4f8274af1921f435fee Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 14 Jan 2013 23:19:47 +0000 Subject: refactor: Simplify ScriptInstance by retaining reference to SceneObjectPart instead of sometimes but not always looking it up. --- .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 127 +++++++++------------ 1 file changed, 55 insertions(+), 72 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 01a5e34..f172216 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -157,19 +157,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance public UUID AppDomain { get; set; } + /// + /// Scene part in which this script instance is contained. + /// + public SceneObjectPart Part { get; private set; } + public string PrimName { get; private set; } public string ScriptName { get; private set; } public UUID ItemID { get; private set; } - public UUID ObjectID { get; private set; } + public UUID ObjectID { get { return Part.UUID; } } - public uint LocalID { get; private set; } + public uint LocalID { get { return Part.LocalId; } } - public UUID RootObjectID { get; private set; } + public UUID RootObjectID { get { return Part.ParentGroup.UUID; } } - public uint RootLocalID { get; private set; } + public uint RootLocalID { get { return Part.ParentGroup.LocalId; } } public UUID AssetID { get; private set; } @@ -214,10 +219,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance EventQueue = new Queue(32); Engine = engine; - LocalID = part.LocalId; - ObjectID = part.UUID; - RootLocalID = part.ParentGroup.LocalId; - RootObjectID = part.ParentGroup.UUID; + Part = part; ItemID = itemID; AssetID = assetID; PrimName = primName; @@ -227,17 +229,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance m_MaxScriptQueue = maxScriptQueue; m_stateSource = stateSource; m_postOnRez = postOnRez; - m_AttachedAvatar = part.ParentGroup.AttachedAvatar; - m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID; + m_AttachedAvatar = Part.ParentGroup.AttachedAvatar; + m_RegionID = Part.ParentGroup.Scene.RegionInfo.RegionID; - if (part != null) + lock (Part.TaskInventory) { - lock (part.TaskInventory) + if (Part.TaskInventory.ContainsKey(ItemID)) { - if (part.TaskInventory.ContainsKey(ItemID)) - { - ScriptTask = part.TaskInventory[ItemID]; - } + ScriptTask = Part.TaskInventory[ItemID]; } } @@ -322,7 +321,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance // m_log.DebugFormat("[Script] Successfully retrieved state for script {0}.{1}", PrimName, m_ScriptName); - part.SetScriptEvents(ItemID, + Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); if (!Running) @@ -418,33 +417,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance PostEvent(new EventParams("attach", new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0])); } - } } private void ReleaseControls() { - SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); - - if (part != null) + int permsMask; + UUID permsGranter; + lock (Part.TaskInventory) { - int permsMask; - UUID permsGranter; - lock (part.TaskInventory) - { - if (!part.TaskInventory.ContainsKey(ItemID)) - return; + if (!Part.TaskInventory.ContainsKey(ItemID)) + return; - permsGranter = part.TaskInventory[ItemID].PermsGranter; - permsMask = part.TaskInventory[ItemID].PermsMask; - } + permsGranter = Part.TaskInventory[ItemID].PermsGranter; + permsMask = Part.TaskInventory[ItemID].PermsMask; + } - if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) - { - ScenePresence presence = Engine.World.GetScenePresence(permsGranter); - if (presence != null) - presence.UnRegisterControlEventsToScript(LocalID, ItemID); - } + if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) + { + ScenePresence presence = Engine.World.GetScenePresence(permsGranter); + if (presence != null) + presence.UnRegisterControlEventsToScript(LocalID, ItemID); } } @@ -706,19 +699,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance m_CollisionInQueue = false; } - SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); - if (DebugLevel >= 2) m_log.DebugFormat( "[SCRIPT INSTANCE]: Processing event {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", data.EventName, ScriptName, - part.Name, - part.LocalId, - part.ParentGroup.Name, - part.ParentGroup.UUID, - part.AbsolutePosition, - part.ParentGroup.Scene.Name); + Part.Name, + Part.LocalId, + Part.ParentGroup.Name, + Part.ParentGroup.UUID, + Part.AbsolutePosition, + Part.ParentGroup.Scene.Name); m_DetectParams = data.DetectParams; @@ -731,21 +722,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance "[SCRIPT INSTANCE]: Changing state to {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", State, ScriptName, - part.Name, - part.LocalId, - part.ParentGroup.Name, - part.ParentGroup.UUID, - part.AbsolutePosition, - part.ParentGroup.Scene.Name); + Part.Name, + Part.LocalId, + Part.ParentGroup.Name, + Part.ParentGroup.UUID, + Part.AbsolutePosition, + Part.ParentGroup.Scene.Name); AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); - if (part != null) - { - part.SetScriptEvents(ItemID, - (int)m_Script.GetStateEventFlags(State)); - } + Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); } else { @@ -804,17 +791,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance text = text.Substring(0, 1000); Engine.World.SimChat(Utils.StringToBytes(text), ChatTypeEnum.DebugChannel, 2147483647, - part.AbsolutePosition, - part.Name, part.UUID, false); + Part.AbsolutePosition, + Part.Name, Part.UUID, false); m_log.DebugFormat( "[SCRIPT INSTANCE]: Runtime error in script {0}, part {1} {2} at {3} in {4}, displayed error {5}, actual exception {6}", ScriptName, PrimName, - part.UUID, - part.AbsolutePosition, - part.ParentGroup.Scene.Name, + Part.UUID, + Part.AbsolutePosition, + Part.ParentGroup.Scene.Name, text.Replace("\n", "\\n"), e.InnerException); } @@ -834,14 +821,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) { m_InSelfDelete = true; - if (part != null) - Engine.World.DeleteSceneObject(part.ParentGroup, false); + Engine.World.DeleteSceneObject(Part.ParentGroup, false); } else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException)) { m_InSelfDelete = true; - if (part != null) - part.Inventory.RemoveInventoryItem(ItemID); + Part.Inventory.RemoveInventoryItem(ItemID); } } } @@ -888,15 +873,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance ReleaseControls(); Stop(timeout); - SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); - part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; - part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; + Part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; + Part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); EventQueue.Clear(); m_Script.ResetVars(); State = "default"; - part.SetScriptEvents(ItemID, + Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); if (running) Start(); @@ -913,16 +897,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance ReleaseControls(); m_Script.ResetVars(); - SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); - part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; - part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; + Part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; + Part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); EventQueue.Clear(); m_Script.ResetVars(); State = "default"; - part.SetScriptEvents(ItemID, + Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); if (m_CurrentEvent != "state_entry") -- cgit v1.1 From 4e1ca890c2d41bf244ed7d4847c0d0a4fc7f6c51 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 14 Jan 2013 15:46:46 -0800 Subject: BulletSim: fix not moving physical objects below terrain to over terrain. Add locking on register prestep action list preventing potential race conditions. Little comment and formatting changes. --- OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | 2 +- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 4 +-- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 29 ++++++++++++++-------- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 17 ++++++++++--- 5 files changed, 36 insertions(+), 18 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs index 0fef67c..9ff7084 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs @@ -202,7 +202,7 @@ private void BulletLoggerPhysLog(string msg) } public override int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, - out int updatedEntityCount, out int collidersCount) + out int updatedEntityCount, out int collidersCount) { BulletWorldUnman worldu = world as BulletWorldUnman; return BSAPICPP.PhysicsStep2(worldu.ptr, timeStep, maxSubSteps, fixedTimeStep, out updatedEntityCount, out collidersCount); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index aadb583..a5fec87 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -126,9 +126,9 @@ public sealed class BSCharacter : BSPhysObject DetailLog("{0},BSCharacter.Destroy", LocalID); PhysicsScene.TaintedObject("BSCharacter.destroy", delegate() { - PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null); + PhysicsScene.Shapes.DereferenceBody(PhysBody, true /* inTaintTime */, null /* bodyCallback */); PhysBody.Clear(); - PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null); + PhysicsScene.Shapes.DereferenceShape(PhysShape, true /* inTaintTime */, null /* bodyCallback */); PhysShape.Clear(); }); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 185f111..821f470 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -382,10 +382,13 @@ public abstract class BSPhysObject : PhysicsActor { string identifier = op + "-" + id.ToString(); - // Clean out any existing action - UnRegisterPreStepAction(op, id); + lock (RegisteredActions) + { + // Clean out any existing action + UnRegisterPreStepAction(op, id); - RegisteredActions[identifier] = actn; + RegisteredActions[identifier] = actn; + } PhysicsScene.BeforeStep += actn; DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier); } @@ -395,22 +398,28 @@ public abstract class BSPhysObject : PhysicsActor { string identifier = op + "-" + id.ToString(); bool removed = false; - if (RegisteredActions.ContainsKey(identifier)) + lock (RegisteredActions) { - PhysicsScene.BeforeStep -= RegisteredActions[identifier]; - RegisteredActions.Remove(identifier); - removed = true; + if (RegisteredActions.ContainsKey(identifier)) + { + PhysicsScene.BeforeStep -= RegisteredActions[identifier]; + RegisteredActions.Remove(identifier); + removed = true; + } } DetailLog("{0},BSPhysObject.UnRegisterPreStepAction,id={1},removed={2}", LocalID, identifier, removed); } protected void UnRegisterAllPreStepActions() { - foreach (KeyValuePair kvp in RegisteredActions) + lock (RegisteredActions) { - PhysicsScene.BeforeStep -= kvp.Value; + foreach (KeyValuePair kvp in RegisteredActions) + { + PhysicsScene.BeforeStep -= kvp.Value; + } + RegisteredActions.Clear(); } - RegisteredActions.Clear(); DetailLog("{0},BSPhysObject.UnRegisterAllPreStepActions,", LocalID); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index e5f7ab7..79fe632 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -379,7 +379,7 @@ public sealed class BSPrim : BSPhysObject // If the object is below ground it just has to be moved up because pushing will // not get it through the terrain _position.Z = targetHeight; - if (!inTaintTime) + if (inTaintTime) ForcePosition = _position; ret = true; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index a5bdc07..e0b4992 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -387,12 +387,14 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters if (!m_initialized) return null; BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying); - lock (PhysObjects) PhysObjects.Add(localID, actor); + lock (PhysObjects) + PhysObjects.Add(localID, actor); // TODO: Remove kludge someday. // We must generate a collision for avatars whether they collide or not. // This is required by OpenSim to update avatar animations, etc. - lock (m_avatars) m_avatars.Add(actor); + lock (m_avatars) + m_avatars.Add(actor); return actor; } @@ -408,9 +410,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters { try { - lock (PhysObjects) PhysObjects.Remove(actor.LocalID); + lock (PhysObjects) + PhysObjects.Remove(bsactor.LocalID); // Remove kludge someday - lock (m_avatars) m_avatars.Remove(bsactor); + lock (m_avatars) + m_avatars.Remove(bsactor); } catch (Exception e) { @@ -419,6 +423,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters bsactor.Destroy(); // bsactor.dispose(); } + else + { + m_log.ErrorFormat("{0}: Requested to remove avatar that is not a BSCharacter. ID={1}, type={2}", + LogHeader, actor.LocalID, actor.GetType().Name); + } } public override void RemovePrim(PhysicsActor prim) -- cgit v1.1 From 055b8a2d58a17d5dbc6cdb7f22077e6268578905 Mon Sep 17 00:00:00 2001 From: dahlia Date: Mon, 14 Jan 2013 22:24:24 -0800 Subject: move resit fix to ScenePresence.cs and allow for requesting sit on objects other than the object currently sat on --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 15 +++------------ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 4 ++++ 2 files changed, 7 insertions(+), 12 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index a8517e6..967fa44 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -6427,19 +6427,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion AgentRequestSit handlerAgentRequestSit = OnAgentRequestSit; - if (handlerAgentRequestSit != null) - if (!(agentRequestSit.AgentData == null - || agentRequestSit.TargetObject == null - || agentRequestSit.TargetObject.TargetID == null - || agentRequestSit.TargetObject.Offset == null)) - { - var sp = m_scene.GetScenePresence(agentRequestSit.AgentData.AgentID); - if (sp == null || sp.ParentID != 0) // ignore packet if agent is already sitting - return true; - handlerAgentRequestSit(this, agentRequestSit.AgentData.AgentID, - agentRequestSit.TargetObject.TargetID, agentRequestSit.TargetObject.Offset); - } + if (handlerAgentRequestSit != null) + handlerAgentRequestSit(this, agentRequestSit.AgentData.AgentID, + agentRequestSit.TargetObject.TargetID, agentRequestSit.TargetObject.Offset); } return true; } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 0219540..6979c33 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1954,6 +1954,10 @@ namespace OpenSim.Region.Framework.Scenes { if (ParentID != 0) { + var targetPart = m_scene.GetSceneObjectPart(targetID); + if (targetPart != null && targetPart.LocalId == ParentID) + return; // already sitting here, ignore + StandUp(); } -- cgit v1.1 From 13778c895ae8adca907781c9d8c3a9ada30814e0 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 15 Jan 2013 01:44:34 -0800 Subject: BulletSim: by default, turn on continuious collision detection (CCD) and enable friction computation caching. Remove dangerous BulletSim settings from OpenSimDefaults.ini. --- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 27ff047..862dbf6 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -318,13 +318,13 @@ public static class BSParam (s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularSleepingThreshold=x;}, p, l, v); }, (s,o,v) => { s.PE.SetSleepingThresholds(o.PhysBody, v, v); } ), new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" , - 0f, // set to zero to disable + 0.3f, // set to zero to disable (s,cf,p,v) => { CcdMotionThreshold = cf.GetFloat(p, v); }, (s) => { return CcdMotionThreshold; }, (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdMotionThreshold=x;}, p, l, v); }, (s,o,v) => { s.PE.SetCcdMotionThreshold(o.PhysBody, v); } ), new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" , - 0f, + 0.2f, (s,cf,p,v) => { CcdSweptSphereRadius = cf.GetFloat(p, v); }, (s) => { return CcdSweptSphereRadius; }, (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdSweptSphereRadius=x;}, p, l, v); }, @@ -465,7 +465,7 @@ public static class BSParam (s) => { return s.UnmanagedParams[0].shouldSplitSimulationIslands; }, (s,p,l,v) => { s.UnmanagedParams[0].shouldSplitSimulationIslands = v; } ), new ParameterDefn("ShouldEnableFrictionCaching", "Enable friction computation caching", - ConfigurationParameters.numericFalse, + ConfigurationParameters.numericTrue, (s,cf,p,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, (s) => { return s.UnmanagedParams[0].shouldEnableFrictionCaching; }, (s,p,l,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = v; } ), -- cgit v1.1 From 0374b2a0b4a88706f5269a55bac7aa2640f82256 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 15 Jan 2013 02:21:38 -0800 Subject: BulletSim: fix logic for enabling unmanaged code debug messages. Free pinned memory when physics engine is unloaded. --- OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs index 9ff7084..ae54499 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs @@ -166,7 +166,7 @@ public override BulletWorld Initialize(Vector3 maxPosition, ConfigurationParamet // If Debug logging level, enable logging from the unmanaged code m_DebugLogCallbackHandle = null; - if (BSScene.m_log.IsDebugEnabled || PhysicsScene.PhysicsLogging.Enabled) + if (BSScene.m_log.IsDebugEnabled && PhysicsScene.PhysicsLogging.Enabled) { BSScene.m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", BSScene.LogHeader); if (PhysicsScene.PhysicsLogging.Enabled) @@ -212,6 +212,19 @@ public override void Shutdown(BulletWorld world) { BulletWorldUnman worldu = world as BulletWorldUnman; BSAPICPP.Shutdown2(worldu.ptr); + + if (m_paramsHandle.IsAllocated) + { + m_paramsHandle.Free(); + } + if (m_collisionArrayPinnedHandle.IsAllocated) + { + m_collisionArrayPinnedHandle.Free(); + } + if (m_updateArrayPinnedHandle.IsAllocated) + { + m_updateArrayPinnedHandle.Free(); + } } public override bool PushUpdate(BulletBody obj) -- cgit v1.1 From 181d4c6fcbf1560fcf100b5a6ec98d15ad2fe5cc Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 15 Jan 2013 02:58:14 -0800 Subject: BulletSim: temporarily disable banking and direction deflection because the computations are wrong. Add VehicleTorqueImpulse routines. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 32 ++++++++++++++++------ .../Physics/BulletSPlugin/BSLinksetCompound.cs | 7 +++-- 2 files changed, 29 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index bcebaec..f5826bc 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -124,9 +124,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin static readonly float PIOverTwo = ((float)Math.PI) / 2f; // For debugging, flags to turn on and off individual corrections. - private bool enableAngularVerticalAttraction = true; - private bool enableAngularDeflection = true; - private bool enableAngularBanking = true; + private bool enableAngularVerticalAttraction; + private bool enableAngularDeflection; + private bool enableAngularBanking; public BSDynamics(BSScene myScene, BSPrim myPrim) { @@ -141,8 +141,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin public void SetupVehicleDebugging() { enableAngularVerticalAttraction = true; - enableAngularDeflection = true; - enableAngularBanking = true; + enableAngularDeflection = false; + enableAngularBanking = false; if (BSParam.VehicleDebuggingEnabled != ConfigurationParameters.numericFalse) { enableAngularVerticalAttraction = false; @@ -649,6 +649,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin private Quaternion m_knownOrientation; private Vector3 m_knownRotationalVelocity; private Vector3 m_knownRotationalForce; + private Vector3 m_knownRotationalImpulse; private Vector3 m_knownForwardVelocity; // vehicle relative forward speed private const int m_knownChangedPosition = 1 << 0; @@ -658,9 +659,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin private const int m_knownChangedOrientation = 1 << 4; private const int m_knownChangedRotationalVelocity = 1 << 5; private const int m_knownChangedRotationalForce = 1 << 6; - private const int m_knownChangedTerrainHeight = 1 << 7; - private const int m_knownChangedWaterLevel = 1 << 8; - private const int m_knownChangedForwardVelocity = 1 << 9; + private const int m_knownChangedRotationalImpulse = 1 << 7; + private const int m_knownChangedTerrainHeight = 1 << 8; + private const int m_knownChangedWaterLevel = 1 << 9; + private const int m_knownChangedForwardVelocity = 1 <<10; private void ForgetKnownVehicleProperties() { @@ -700,6 +702,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity); } + if ((m_knownChanged & m_knownChangedRotationalImpulse) != 0) + Prim.ApplyTorqueImpulse((Vector3)m_knownRotationalImpulse, true /*inTaintTime*/); + if ((m_knownChanged & m_knownChangedRotationalForce) != 0) { Prim.AddAngularForce((Vector3)m_knownRotationalForce, false /*pushForce*/, true /*inTaintTime*/); @@ -843,6 +848,17 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_knownChanged |= m_knownChangedRotationalForce; m_knownHas |= m_knownChangedRotationalForce; } + private void VehicleAddRotationalImpulse(Vector3 pImpulse) + { + if ((m_knownHas & m_knownChangedRotationalImpulse) == 0) + { + m_knownRotationalImpulse = Vector3.Zero; + m_knownHas |= m_knownChangedRotationalImpulse; + } + m_knownRotationalImpulse += pImpulse; + m_knownChanged |= m_knownChangedRotationalImpulse; + } + // Vehicle relative forward velocity private Vector3 VehicleForwardVelocity { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 5a1b5c7..2dc89b5 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -195,8 +195,11 @@ public sealed class BSLinksetCompound : BSLinkset && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition)) { // TODO: replace this with are calculation of the child prim's orientation and pos. - updated.LinksetInfo = null; - ScheduleRebuild(updated); + // TODO: for the moment, don't rebuild the compound shape. + // This is often just the car turning its wheels. When we can just reorient the one + // member shape of the compound shape, the overhead of rebuilding won't be a problem. + // updated.LinksetInfo = null; + // ScheduleRebuild(updated); } } -- cgit v1.1 From 021964c6e0648cf0e75b46864bef55afb7ff0a1f Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 15 Jan 2013 04:24:24 -0800 Subject: BulletSim: tweeks to improve hover. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 26 +++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index f5826bc..e434412 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -1047,16 +1047,32 @@ namespace OpenSim.Region.Physics.BulletSPlugin else { // Error is positive if below the target and negative if above. - float verticalError = m_VhoverTargetHeight - VehiclePosition.Z; - float verticalCorrectionVelocity = verticalError / m_VhoverTimescale * pTimestep; + Vector3 hpos = VehiclePosition; + float verticalError = m_VhoverTargetHeight - hpos.Z; + float verticalCorrection = verticalError / m_VhoverTimescale; + verticalCorrection *= m_VhoverEfficiency; + + hpos.Z += verticalCorrection; + VehiclePosition = hpos; + + // Since we are hovering, we need to do the opposite of falling -- get rid of world Z + Vector3 vel = VehicleVelocity; + vel.Z = 0f; + VehicleVelocity = vel; + + /* + float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; + Vector3 verticalCorrection = new Vector3(0f, 0f, verticalCorrectionVelocity); + verticalCorrection *= m_vehicleMass; // TODO: implement m_VhoverEfficiency correctly - VehicleAddForceImpulse(new Vector3(0f, 0f, verticalCorrectionVelocity)); + VehicleAddForceImpulse(verticalCorrection); + */ - VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},err={6},corrVel={7}", + VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},err={6},corr={7}", Prim.LocalID, VehiclePosition, m_VhoverEfficiency, m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight, - verticalError, verticalCorrectionVelocity); + verticalError, verticalCorrection); } } -- cgit v1.1 From fccb03227e3f541a4c2f4e0e619074e4c1fb55dd Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 15 Jan 2013 21:13:22 +0000 Subject: Instead of passing separate engine, part and item components to script APIs, pass down IScriptInstance instead. This is to allow the future co-operative script thread terminate feature to detect and act upon termination requests. This splits the assembly and state loading out from the ScriptInstance() constructor to a separate Load() method in order to facilititate continued script logic regression testing. --- .../Region/ScriptEngine/Interfaces/IScriptApi.cs | 10 ++--- .../ScriptEngine/Interfaces/IScriptInstance.cs | 12 +++++ .../Shared/Api/Implementation/LSL_Api.cs | 16 ++++--- .../Shared/Api/Implementation/LS_Api.cs | 13 +++--- .../Shared/Api/Implementation/MOD_Api.cs | 8 ++-- .../Shared/Api/Implementation/OSSL_Api.cs | 8 ++-- .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 52 ++++++++++++---------- .../Shared/Tests/LSL_ApiInventoryTests.cs | 7 +-- .../Shared/Tests/LSL_ApiLinkingTests.cs | 5 ++- .../ScriptEngine/Shared/Tests/LSL_ApiListTests.cs | 3 +- .../ScriptEngine/Shared/Tests/LSL_ApiTest.cs | 3 +- .../Shared/Tests/OSSL_ApiAppearanceTest.cs | 5 ++- .../Shared/Tests/OSSL_ApiAttachmentTests.cs | 19 +++++--- .../ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs | 17 +++---- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 10 ++--- 15 files changed, 109 insertions(+), 79 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs index 2027ca6..e95cbd7 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs @@ -29,6 +29,7 @@ using System; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.ScriptEngine.Shared; namespace OpenSim.Region.ScriptEngine.Interfaces { @@ -38,11 +39,8 @@ namespace OpenSim.Region.ScriptEngine.Interfaces /// Initialize the API /// /// - /// Each API has an identifier, which is used to load the - /// proper runtime assembly at load time. - /// /param> - /// - /// - void Initialize(IScriptEngine engine, SceneObjectPart part, TaskInventoryItem item); + /// Each API has an identifier, which is used to load the proper runtime assembly at load time. + /// /param> + void Initialize(IScriptInstance scriptInstance); } } \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index 2f5b526..9de2d72 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs @@ -31,6 +31,7 @@ using System.Collections.Generic; using OpenMetaverse; using log4net; using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.ScriptEngine.Interfaces; @@ -105,6 +106,11 @@ namespace OpenSim.Region.ScriptEngine.Interfaces /// long MeasurementPeriodExecutionTime { get; } + /// + /// Scene part in which this script instance is contained. + /// + SceneObjectPart Part { get; } + IScriptEngine Engine { get; } UUID AppDomain { get; set; } string PrimName { get; } @@ -124,6 +130,12 @@ namespace OpenSim.Region.ScriptEngine.Interfaces uint LocalID { get; } UUID AssetID { get; } + + /// + /// Inventory item containing the script used. + /// + TaskInventoryItem ScriptTask { get; } + Queue EventQueue { get; } /// diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index ea4e609..44072c6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -110,11 +110,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. protected ISoundModule m_SoundModule = null; - public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) + public void Initialize(IScriptInstance scriptInstance) { - m_ScriptEngine = ScriptEngine; - m_host = host; - m_item = item; + m_ScriptEngine = scriptInstance.Engine; + m_host = scriptInstance.Part; + m_item = scriptInstance.ScriptTask; LoadLimits(); // read script limits from config. @@ -123,10 +123,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_UrlModule = m_ScriptEngine.World.RequestModuleInterface(); m_SoundModule = m_ScriptEngine.World.RequestModuleInterface(); - AsyncCommands = new AsyncCommandManager(ScriptEngine); + AsyncCommands = new AsyncCommandManager(m_ScriptEngine); } - /* load configuration items that affect script, object and run-time behavior. */ + /// + /// Load configuration items that affect script, object and run-time behavior. */ + /// private void LoadLimits() { m_ScriptDelayFactor = @@ -141,12 +143,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_ScriptEngine.Config.GetInt("NotecardLineReadCharsMax", 255); if (m_notecardLineReadCharsMax > 65535) m_notecardLineReadCharsMax = 65535; + // load limits for particular subsystems. IConfig SMTPConfig; if ((SMTPConfig = m_ScriptEngine.ConfigSource.Configs["SMTP"]) != null) { // there's an smtp config, so load in the snooze time. EMAIL_PAUSE_TIME = SMTPConfig.GetInt("email_pause_time", EMAIL_PAUSE_TIME); } + // Rezzing an object with a velocity can create recoil. This feature seems to have been // removed from recent versions of SL. The code computes recoil (vel*mass) and scales // it by this factor. May be zero to turn off recoil all together. diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs index ceb4660..071c60e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs @@ -61,10 +61,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api internal bool m_LSFunctionsEnabled = false; internal IScriptModuleComms m_comms = null; - public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) + public void Initialize(IScriptInstance scriptInstance) { - m_ScriptEngine = ScriptEngine; - m_host = host; + m_ScriptEngine = scriptInstance.Engine; + m_host = scriptInstance.Part; if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false)) m_LSFunctionsEnabled = true; @@ -92,10 +92,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api get { return m_ScriptEngine.World; } } - // - //Dumps an error message on the debug console. - // - + /// + /// Dumps an error message on the debug console. + /// internal void LSShoutError(string message) { if (message.Length > 1023) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs index 8f34833..cbc69aa 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs @@ -61,11 +61,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api internal bool m_MODFunctionsEnabled = false; internal IScriptModuleComms m_comms = null; - public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) + public void Initialize(IScriptInstance scriptInstance) { - m_ScriptEngine = ScriptEngine; - m_host = host; - m_item = item; + m_ScriptEngine = scriptInstance.Engine; + m_host = scriptInstance.Part; + m_item = scriptInstance.ScriptTask; if (m_ScriptEngine.Config.GetBoolean("AllowMODFunctions", false)) m_MODFunctionsEnabled = true; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 958a448..33ae5f0 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -142,11 +142,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected IUrlModule m_UrlModule = null; - public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) + public void Initialize(IScriptInstance scriptInstance) { - m_ScriptEngine = ScriptEngine; - m_host = host; - m_item = item; + m_ScriptEngine = scriptInstance.Engine; + m_host = scriptInstance.Part; + m_item = scriptInstance.ScriptTask; m_UrlModule = m_ScriptEngine.World.RequestModuleInterface(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index f172216..a2ff51b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -157,9 +157,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance public UUID AppDomain { get; set; } - /// - /// Scene part in which this script instance is contained. - /// public SceneObjectPart Part { get; private set; } public string PrimName { get; private set; } @@ -209,43 +206,52 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance EventQueue.Clear(); } - public ScriptInstance(IScriptEngine engine, SceneObjectPart part, - UUID itemID, UUID assetID, string assembly, - AppDomain dom, string primName, string scriptName, - int startParam, bool postOnRez, StateSource stateSource, - int maxScriptQueue) + public ScriptInstance( + IScriptEngine engine, SceneObjectPart part, TaskInventoryItem item, + int startParam, bool postOnRez, + int maxScriptQueue) { State = "default"; EventQueue = new Queue(32); Engine = engine; Part = part; - ItemID = itemID; - AssetID = assetID; - PrimName = primName; - ScriptName = scriptName; - m_Assembly = assembly; + ScriptTask = item; + + // This is currently only here to allow regression tests to get away without specifying any inventory + // item when they are testing script logic that doesn't require an item. + if (ScriptTask != null) + { + ScriptName = ScriptTask.Name; + ItemID = ScriptTask.ItemID; + AssetID = ScriptTask.AssetID; + } + + PrimName = part.ParentGroup.Name; StartParam = startParam; m_MaxScriptQueue = maxScriptQueue; - m_stateSource = stateSource; m_postOnRez = postOnRez; m_AttachedAvatar = Part.ParentGroup.AttachedAvatar; m_RegionID = Part.ParentGroup.Scene.RegionInfo.RegionID; + } - lock (Part.TaskInventory) - { - if (Part.TaskInventory.ContainsKey(ItemID)) - { - ScriptTask = Part.TaskInventory[ItemID]; - } - } + /// + /// Load the script from an assembly into an AppDomain. + /// + /// + /// + /// + public void Load(AppDomain dom, string assembly, StateSource stateSource) + { + m_Assembly = assembly; + m_stateSource = stateSource; ApiManager am = new ApiManager(); foreach (string api in am.GetApis()) { m_Apis[api] = am.CreateApi(api); - m_Apis[api].Initialize(engine, part, ScriptTask); + m_Apis[api].Initialize(this); } try @@ -279,7 +285,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance // // m_log.Debug("[Script] Script instance created"); - part.SetScriptEvents(ItemID, + Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); } catch (Exception e) diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs index cb7291a..36c7582 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs @@ -41,6 +41,7 @@ using OpenSim.Region.OptionalModules.World.NPC; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Region.ScriptEngine.Shared.Instance; using OpenSim.Services.Interfaces; using OpenSim.Tests.Common; using OpenSim.Tests.Common.Mock; @@ -93,7 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests TaskInventoryHelpers.AddSceneObject(m_scene, so1.RootPart, inventoryItemName, itemId, userId); LSL_Api api = new LSL_Api(); - api.Initialize(m_engine, so1.RootPart, null); + api.Initialize(new ScriptInstance(m_engine, so1.RootPart, null, 0, false, int.MaxValue)); // Create a second object SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, userId, "so2", 0x100); @@ -126,7 +127,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(1, user1Id, "so1", 0x10); m_scene.AddSceneObject(so1); LSL_Api api = new LSL_Api(); - api.Initialize(m_engine, so1.RootPart, null); + api.Initialize(new ScriptInstance(m_engine, so1.RootPart, null, 0, false, int.MaxValue)); // Create an object embedded inside the first UUID itemId = TestHelpers.ParseTail(0x20); @@ -136,7 +137,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, user2Id, "so2", 0x100); m_scene.AddSceneObject(so2); LSL_Api api2 = new LSL_Api(); - api2.Initialize(m_engine, so2.RootPart, null); + api2.Initialize(new ScriptInstance(m_engine, so2.RootPart, null, 0, false, int.MaxValue)); // *** Firstly, we test where llAllowInventoryDrop() has not been called. *** api.llGiveInventory(so2.UUID.ToString(), inventoryItemName); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs index d9b17d7..5121344 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs @@ -41,6 +41,7 @@ using OpenSim.Region.OptionalModules.World.NPC; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Region.ScriptEngine.Shared.Instance; using OpenSim.Region.ScriptEngine.Shared.ScriptBase; using OpenSim.Services.Interfaces; using OpenSim.Tests.Common; @@ -104,7 +105,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(grp2); LSL_Api apiGrp1 = new LSL_Api(); - apiGrp1.Initialize(m_engine, grp1.RootPart, grp1Item); + apiGrp1.Initialize(new ScriptInstance(m_engine, grp1.RootPart, grp1Item, 0, false, int.MaxValue)); apiGrp1.llCreateLink(grp2.UUID.ToString(), ScriptBaseClass.TRUE); @@ -131,7 +132,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests grp1Item.PermsMask |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; LSL_Api apiGrp1 = new LSL_Api(); - apiGrp1.Initialize(m_engine, grp1.RootPart, grp1Item); + apiGrp1.Initialize(new ScriptInstance(m_engine, grp1.RootPart, grp1Item, 0, false, int.MaxValue)); apiGrp1.llBreakLink(2); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs index 98017d8..28e5831 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs @@ -34,6 +34,7 @@ using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.Framework.Scenes; using Nini.Config; using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Region.ScriptEngine.Shared.Instance; using OpenSim.Region.ScriptEngine.Shared.ScriptBase; using OpenMetaverse; using OpenSim.Tests.Common.Mock; @@ -67,7 +68,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests engine.AddRegion(scene); m_lslApi = new LSL_Api(); - m_lslApi.Initialize(engine, part, null); + m_lslApi.Initialize(new ScriptInstance(engine, part, null, 0, false, int.MaxValue)); } [Test] diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs index c41d1e7..48c2465 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs @@ -33,6 +33,7 @@ using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.Framework.Scenes; using Nini.Config; using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Region.ScriptEngine.Shared.Instance; using OpenSim.Region.ScriptEngine.Shared.ScriptBase; using OpenMetaverse; using System; @@ -66,7 +67,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests engine.AddRegion(scene); m_lslApi = new LSL_Api(); - m_lslApi.Initialize(engine, part, null); + m_lslApi.Initialize(new ScriptInstance(engine, part, null, 0, false, int.MaxValue)); } [Test] diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs index 1381d2b..5164d4e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs @@ -41,6 +41,7 @@ using OpenSim.Region.OptionalModules.World.NPC; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Region.ScriptEngine.Shared.Instance; using OpenSim.Services.Interfaces; using OpenSim.Tests.Common; using OpenSim.Tests.Common.Mock; @@ -93,7 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, null); + osslApi.Initialize(new ScriptInstance(m_engine, part, null, 0, false, int.MaxValue)); string notecardName = "appearanceNc"; @@ -134,7 +135,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, null); + osslApi.Initialize(new ScriptInstance(m_engine, part, null, 0, false, int.MaxValue)); string notecardName = "appearanceNc"; diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs index 5ed1f3d..e7b3319 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs @@ -41,6 +41,7 @@ using OpenSim.Region.CoreModules.Framework.InventoryAccess; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Region.ScriptEngine.Shared.Instance; using OpenSim.Services.Interfaces; using OpenSim.Tests.Common; using OpenSim.Tests.Common.Mock; @@ -98,9 +99,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID); TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart); - new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem); + ScriptInstance si = new ScriptInstance(m_engine, inWorldObj.RootPart, scriptItem, 0, false, int.MaxValue); + new LSL_Api().Initialize(si); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem); + osslApi.Initialize(si); // SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ua1.PrincipalID); @@ -144,9 +146,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID); TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart); - new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem); + ScriptInstance si = new ScriptInstance(m_engine, inWorldObj.RootPart, scriptItem, 0, false, int.MaxValue); + new LSL_Api().Initialize(si); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem); + osslApi.Initialize(si); // Create an object embedded inside the first TaskInventoryHelpers.AddNotecard( @@ -192,12 +195,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID); TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart); - new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem); + ScriptInstance si = new ScriptInstance(m_engine, inWorldObj.RootPart, scriptItem, 0, false, int.MaxValue); + new LSL_Api().Initialize(si); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem); + osslApi.Initialize(si); // Create an object embedded inside the first - TaskInventoryHelpers.AddSceneObject(m_scene, inWorldObj.RootPart, taskInvObjItemName, taskInvObjItemId, ua1.PrincipalID); + TaskInventoryHelpers.AddSceneObject( + m_scene, inWorldObj.RootPart, taskInvObjItemName, taskInvObjItemId, ua1.PrincipalID); ScenePresence sp2 = SceneHelpers.AddScenePresence(m_scene, ua2); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs index d6c82f1..584f44f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs @@ -42,6 +42,7 @@ using OpenSim.Region.OptionalModules.World.NPC; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Region.ScriptEngine.Shared.Instance; using OpenSim.Region.ScriptEngine.Shared.ScriptBase; using OpenSim.Services.Interfaces; using OpenSim.Tests.Common; @@ -99,7 +100,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, null); + osslApi.Initialize(new ScriptInstance(m_engine, part, null, 0, false, int.MaxValue)); string notecardName = "appearanceNc"; osslApi.osOwnerSaveAppearance(notecardName); @@ -125,7 +126,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, so.RootPart, null); + osslApi.Initialize(new ScriptInstance(m_engine, so.RootPart, null, 0, false, int.MaxValue)); bool gotExpectedException = false; try @@ -160,7 +161,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, null); + osslApi.Initialize(new ScriptInstance(m_engine, part, null, 0, false, int.MaxValue)); string notecardName = "appearanceNc"; osslApi.osOwnerSaveAppearance(notecardName); @@ -194,7 +195,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, null); + osslApi.Initialize(new ScriptInstance(m_engine, part, null, 0, false, int.MaxValue)); osslApi.osOwnerSaveAppearance(firstAppearanceNcName); @@ -232,7 +233,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, null); + osslApi.Initialize(new ScriptInstance(m_engine, part, null, 0, false, int.MaxValue)); osslApi.osOwnerSaveAppearance(firstAppearanceNcName); @@ -284,10 +285,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(otherSo); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, null); + osslApi.Initialize(new ScriptInstance(m_engine, part, null, 0, false, int.MaxValue)); OSSL_Api otherOsslApi = new OSSL_Api(); - otherOsslApi.Initialize(m_engine, otherPart, null); + otherOsslApi.Initialize(new ScriptInstance(m_engine, otherPart, null, 0, false, int.MaxValue)); string notecardName = "appearanceNc"; osslApi.osOwnerSaveAppearance(notecardName); @@ -331,7 +332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, null); + osslApi.Initialize(new ScriptInstance(m_engine, part, null, 0, false, int.MaxValue)); string notecardName = "appearanceNc"; osslApi.osOwnerSaveAppearance(notecardName); diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 8c3bb5b..186ae04 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1284,11 +1284,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_DomainScripts[appDomain].Add(itemID); instance = new ScriptInstance(this, part, - itemID, assetID, assembly, - m_AppDomains[appDomain], - part.ParentGroup.RootPart.Name, - item.Name, startParam, postOnRez, - stateSource, m_MaxScriptQueue); + item, + startParam, postOnRez, + m_MaxScriptQueue); + + instance.Load(m_AppDomains[appDomain], assembly, stateSource); // if (DebugLevel >= 1) // m_log.DebugFormat( -- cgit v1.1 From 1b5c41c14ad11325be249ea1cce3c65d4d6a89be Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 16 Jan 2013 00:12:40 +0000 Subject: Implement co-operative script termination if termination comes during a script wait event (llSleep(), etc.) This makes use of EventWaitHandles since various web references indicate that Thread.Interrupt() can also cause runtime instability. If co-op termination is enabled, then termination sets the wait handle instead of waiting for a timeout before possibly aborting the thread. This allows the script to cleanly terminate if it's in a llSleep/LL function delay or the next time it enters such a wait without any timeout period. Co-op termination is not yet testable since checking for termination request within loops that never trigger a wait is not yet implemented. --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 26 +++- .../ScriptEngine/Interfaces/IScriptInstance.cs | 13 ++ .../Shared/Api/Implementation/LSL_Api.cs | 31 +++- OpenSim/Region/ScriptEngine/Shared/Helpers.cs | 18 +++ .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 52 ++++++- .../Shared/Instance/Tests/CoopTerminationTests.cs | 157 +++++++++++++++++++++ OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 5 + 7 files changed, 289 insertions(+), 13 deletions(-) create mode 100644 OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 5c8b097..92bf85a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1738,6 +1738,21 @@ namespace OpenSim.Region.Framework.Scenes /// The part where the script was rezzed if successful. False otherwise. public SceneObjectPart RezNewScript(UUID agentID, InventoryItemBase itemBase) { + return RezNewScript( + agentID, + itemBase, + "default\n{\n state_entry()\n {\n llSay(0, \"Script running\");\n }\n}"); + } + + /// + /// Rez a new script from nothing with given script text. + /// + /// + /// Template item. + /// + /// The part where the script was rezzed if successful. False otherwise. + public SceneObjectPart RezNewScript(UUID agentID, InventoryItemBase itemBase, string scriptText) + { // The part ID is the folder ID! SceneObjectPart part = GetSceneObjectPart(itemBase.Folder); if (part == null) @@ -1757,9 +1772,14 @@ namespace OpenSim.Region.Framework.Scenes return null; } - AssetBase asset = CreateAsset(itemBase.Name, itemBase.Description, (sbyte)itemBase.AssetType, - Encoding.ASCII.GetBytes("default\n{\n state_entry()\n {\n llSay(0, \"Script running\");\n }\n}"), - agentID); + AssetBase asset + = CreateAsset( + itemBase.Name, + itemBase.Description, + (sbyte)itemBase.AssetType, + Encoding.ASCII.GetBytes(scriptText), + agentID); + AssetService.Store(asset); TaskInventoryItem taskItem = new TaskInventoryItem(); diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index 9de2d72..38fff52 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs @@ -28,6 +28,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Threading; using OpenMetaverse; using log4net; using OpenSim.Framework; @@ -181,6 +182,18 @@ namespace OpenSim.Region.ScriptEngine.Interfaces void Resume(); /// + /// If true then scripts should look to terminate their threads in co-operation with the script engine rather + /// than through Thread.Abort() + /// + bool CoopTermination { get; } + + /// + /// Used for script sleeps when we are using co-operative script termination. + /// + /// null if CoopTermination is not active + EventWaitHandle CoopSleepHandle { get; } + + /// /// Process the next event queued for this script instance. /// /// diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 44072c6..b992efa 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -83,6 +83,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + /// + /// Instance of this script. + /// + protected IScriptInstance m_scriptInstance; + protected IScriptEngine m_ScriptEngine; protected SceneObjectPart m_host; @@ -112,11 +118,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void Initialize(IScriptInstance scriptInstance) { - m_ScriptEngine = scriptInstance.Engine; - m_host = scriptInstance.Part; - m_item = scriptInstance.ScriptTask; + m_scriptInstance = scriptInstance; + m_ScriptEngine = m_scriptInstance.Engine; + m_host = m_scriptInstance.Part; + m_item = m_scriptInstance.ScriptTask; - LoadLimits(); // read script limits from config. + LoadConfig(); m_TransferModule = m_ScriptEngine.World.RequestModuleInterface(); @@ -129,7 +136,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// /// Load configuration items that affect script, object and run-time behavior. */ /// - private void LoadLimits() + private void LoadConfig() { m_ScriptDelayFactor = m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); @@ -175,7 +182,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api delay = (int)((float)delay * m_ScriptDelayFactor); if (delay == 0) return; - System.Threading.Thread.Sleep(delay); + + Sleep(delay); + } + + protected virtual void Sleep(int delay) + { + if (!m_scriptInstance.CoopTermination) + System.Threading.Thread.Sleep(delay); + else if (m_scriptInstance.CoopSleepHandle.WaitOne(delay)) + throw new ScriptCoopStopException(); } public Scene World @@ -2914,7 +2930,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { // m_log.Info("llSleep snoozing " + sec + "s."); m_host.AddScriptLPS(1); - Thread.Sleep((int)(sec * 1000)); + + Sleep((int)(sec * 1000)); } public LSL_Float llGetMass() diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs index 5a58f73..e02d35e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs @@ -81,6 +81,24 @@ namespace OpenSim.Region.ScriptEngine.Shared } } + /// + /// Used to signal when the script is stopping in co-operation with the script engine + /// (instead of through Thread.Abort()). + /// + [Serializable] + public class ScriptCoopStopException : Exception + { + public ScriptCoopStopException() + { + } + + protected ScriptCoopStopException( + SerializationInfo info, + StreamingContext context) + { + } + } + public class DetectParams { public const int AGENT = 1; diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index a2ff51b..00048a1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -200,6 +200,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance public static readonly long MaxMeasurementPeriod = 30 * TimeSpan.TicksPerMinute; + public bool CoopTermination { get; private set; } + + public EventWaitHandle CoopSleepHandle { get; private set; } + public void ClearQueue() { m_TimerQueued = false; @@ -233,6 +237,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance m_postOnRez = postOnRez; m_AttachedAvatar = Part.ParentGroup.AttachedAvatar; m_RegionID = Part.ParentGroup.Scene.RegionInfo.RegionID; + + if (Engine.Config.GetString("ScriptStopStrategy", "abort") == "co-op") + { + CoopTermination = true; + CoopSleepHandle = new AutoResetEvent(false); + } } /// @@ -532,9 +542,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance } // Wait for the current event to complete. - if (!m_InSelfDelete && workItem.Wait(new TimeSpan((long)timeout * 100000))) + if (!m_InSelfDelete) { - return true; + if (!CoopTermination) + { + // If we're not co-operative terminating then try and wait for the event to complete before stopping + if (workItem.Wait(new TimeSpan((long)timeout * 100000))) + return true; + } + else + { + m_log.DebugFormat( + "[SCRIPT INSTANCE]: Co-operatively stopping script {0} {1} in {2} {3}", + ScriptName, ItemID, PrimName, ObjectID); + + // This will terminate the event on next handle check by the script. + CoopSleepHandle.Set(); + + // For now, we will wait forever since the event should always cleanly terminate once LSL loop + // checking is implemented. May want to allow a shorter timeout option later. + if (workItem.Wait(TimeSpan.MaxValue)) + { + m_log.DebugFormat( + "[SCRIPT INSTANCE]: Co-operatively stopped script {0} {1} in {2} {3}", + ScriptName, ItemID, PrimName, ObjectID); + + return true; + } + } } lock (EventQueue) @@ -547,6 +582,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance // If the event still hasn't stopped and we the stop isn't the result of script or object removal, then // forcibly abort the work item (this aborts the underlying thread). + // Co-operative termination should never reach this point. if (!m_InSelfDelete) { m_log.DebugFormat( @@ -786,7 +822,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance m_InEvent = false; m_CurrentEvent = String.Empty; - if ((!(e is TargetInvocationException) || (!(e.InnerException is SelfDeleteException) && !(e.InnerException is ScriptDeleteException))) && !(e is ThreadAbortException)) + if ((!(e is TargetInvocationException) + || (!(e.InnerException is SelfDeleteException) + && !(e.InnerException is ScriptDeleteException) + && !(e.InnerException is ScriptCoopStopException))) + && !(e is ThreadAbortException)) { try { @@ -834,6 +874,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance m_InSelfDelete = true; Part.Inventory.RemoveInventoryItem(ItemID); } + else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException)) + { + m_log.DebugFormat( + "[SCRIPT INSTANCE]: Script {0}.{1} in event {2}, state {3} stopped co-operatively.", + PrimName, ScriptName, data.EventName, State); + } } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs new file mode 100644 index 0000000..f3a6cc9 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs @@ -0,0 +1,157 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Threading; +using Nini.Config; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.CoreModules.Scripting.WorldComm; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.ScriptEngine.XEngine; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests +{ + /// + /// Test that co-operative script thread termination is working correctly. + /// + [TestFixture] + public class CoopTerminationTests : OpenSimTestCase + { + private TestScene m_scene; + private OpenSim.Region.ScriptEngine.XEngine.XEngine m_xEngine; + + private AutoResetEvent m_chatEvent = new AutoResetEvent(false); + private AutoResetEvent m_stoppedEvent = new AutoResetEvent(false); + + private OSChatMessage m_osChatMessageReceived; + + [TestFixtureSetUp] + public void Init() + { + //AppDomain.CurrentDomain.SetData("APPBASE", Environment.CurrentDirectory + "/bin"); +// Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory); + m_xEngine = new OpenSim.Region.ScriptEngine.XEngine.XEngine(); + + IniConfigSource configSource = new IniConfigSource(); + + IConfig startupConfig = configSource.AddConfig("Startup"); + startupConfig.Set("DefaultScriptEngine", "XEngine"); + + IConfig xEngineConfig = configSource.AddConfig("XEngine"); + xEngineConfig.Set("Enabled", "true"); + xEngineConfig.Set("StartDelay", "0"); + + // These tests will not run with AppDomainLoading = true, at least on mono. For unknown reasons, the call + // to AssemblyResolver.OnAssemblyResolve fails. + xEngineConfig.Set("AppDomainLoading", "false"); + + xEngineConfig.Set("ScriptStopStrategy", "co-op"); + + m_scene = new SceneHelpers().SetupScene("My Test", UUID.Random(), 1000, 1000, configSource); + SceneHelpers.SetupSceneModules(m_scene, configSource, m_xEngine); + m_scene.StartScripts(); + } + + /// + /// Test co-operative termination on derez of an object containing a script with a long-running event. + /// + /// + /// TODO: Actually compiling the script is incidental to this test. Really want a way to compile test scripts + /// within the build itself. + /// + [Test] + public void TestStopOnLongSleep() + { + TestHelpers.InMethod(); + TestHelpers.EnableLogging(); + + UUID userId = TestHelpers.ParseTail(0x1); +// UUID objectId = TestHelpers.ParseTail(0x100); +// UUID itemId = TestHelpers.ParseTail(0x3); + string itemName = "TestStopOnObjectDerezLongSleep() Item"; + + SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, "TestStopOnObjectDerezLongSleep", 0x100); + m_scene.AddNewSceneObject(so, true); + + InventoryItemBase itemTemplate = new InventoryItemBase(); +// itemTemplate.ID = itemId; + itemTemplate.Name = itemName; + itemTemplate.Folder = so.UUID; + itemTemplate.InvType = (int)InventoryType.LSL; + + m_scene.EventManager.OnChatFromWorld += OnChatFromWorld; + + SceneObjectPart partWhereRezzed = m_scene.RezNewScript(userId, itemTemplate, +@"default +{ + state_entry() + { + llSay(0, ""Thin Lizzy""); + llSleep(60); + } +}"); + + TaskInventoryItem rezzedItem = partWhereRezzed.Inventory.GetInventoryItem(itemName); + + // Wait for the script to start the event before we try stopping it. + m_chatEvent.WaitOne(60000); + + Console.WriteLine("Script started with message [{0}]", m_osChatMessageReceived.Message); + + // FIXME: This is a very poor way of trying to avoid a low-probability race condition where the script + // executes llSay() but has not started the sleep before we try to stop it. + Thread.Sleep(1000); + + // We need a way of carrying on if StopScript() fail, since it won't return if the script isn't actually + // stopped. This kind of multi-threading is far from ideal in a regression test. + new Thread(() => { m_xEngine.StopScript(rezzedItem.ItemID); m_stoppedEvent.Set(); }).Start(); + + if (!m_stoppedEvent.WaitOne(30000)) + Assert.Fail("Script did not co-operatively stop."); + + bool running; + TaskInventoryItem scriptItem = partWhereRezzed.Inventory.GetInventoryItem(itemName); + Assert.That( + SceneObjectPartInventory.TryGetScriptInstanceRunning(m_scene, scriptItem, out running), Is.True); + Assert.That(running, Is.False); + } + + private void OnChatFromWorld(object sender, OSChatMessage oscm) + { +// Console.WriteLine("Got chat [{0}]", oscm.Message); + + m_osChatMessageReceived = oscm; + m_chatEvent.Set(); + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 186ae04..a17a018 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1716,9 +1716,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine IScriptInstance instance = GetInstance(itemID); if (instance != null) + { instance.Stop(m_WaitForEventCompletionOnScriptStop); + } else + { +// m_log.DebugFormat("[XENGINE]: Could not find script with ID {0} to stop in {1}", itemID, World.Name); m_runFlags.AddOrUpdate(itemID, false, 240); + } } public DetectParams GetDetectParams(UUID itemID, int idx) -- cgit v1.1 From b8949024bc55c62b9268b35d4f2a568760b9d7d3 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 16 Jan 2013 01:45:09 +0000 Subject: Revert "Implement co-operative script termination if termination comes during a script wait event (llSleep(), etc.)" Doing this as a favour to Melanie. This will be back with passing the wait handles directly to the api. This reverts commit 1b5c41c14ad11325be249ea1cce3c65d4d6a89be. --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 26 +--- .../ScriptEngine/Interfaces/IScriptInstance.cs | 13 -- .../Shared/Api/Implementation/LSL_Api.cs | 31 +--- OpenSim/Region/ScriptEngine/Shared/Helpers.cs | 18 --- .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 52 +------ .../Shared/Instance/Tests/CoopTerminationTests.cs | 157 --------------------- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 5 - 7 files changed, 13 insertions(+), 289 deletions(-) delete mode 100644 OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 92bf85a..5c8b097 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1738,21 +1738,6 @@ namespace OpenSim.Region.Framework.Scenes /// The part where the script was rezzed if successful. False otherwise. public SceneObjectPart RezNewScript(UUID agentID, InventoryItemBase itemBase) { - return RezNewScript( - agentID, - itemBase, - "default\n{\n state_entry()\n {\n llSay(0, \"Script running\");\n }\n}"); - } - - /// - /// Rez a new script from nothing with given script text. - /// - /// - /// Template item. - /// - /// The part where the script was rezzed if successful. False otherwise. - public SceneObjectPart RezNewScript(UUID agentID, InventoryItemBase itemBase, string scriptText) - { // The part ID is the folder ID! SceneObjectPart part = GetSceneObjectPart(itemBase.Folder); if (part == null) @@ -1772,14 +1757,9 @@ namespace OpenSim.Region.Framework.Scenes return null; } - AssetBase asset - = CreateAsset( - itemBase.Name, - itemBase.Description, - (sbyte)itemBase.AssetType, - Encoding.ASCII.GetBytes(scriptText), - agentID); - + AssetBase asset = CreateAsset(itemBase.Name, itemBase.Description, (sbyte)itemBase.AssetType, + Encoding.ASCII.GetBytes("default\n{\n state_entry()\n {\n llSay(0, \"Script running\");\n }\n}"), + agentID); AssetService.Store(asset); TaskInventoryItem taskItem = new TaskInventoryItem(); diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index 38fff52..9de2d72 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs @@ -28,7 +28,6 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Threading; using OpenMetaverse; using log4net; using OpenSim.Framework; @@ -182,18 +181,6 @@ namespace OpenSim.Region.ScriptEngine.Interfaces void Resume(); /// - /// If true then scripts should look to terminate their threads in co-operation with the script engine rather - /// than through Thread.Abort() - /// - bool CoopTermination { get; } - - /// - /// Used for script sleeps when we are using co-operative script termination. - /// - /// null if CoopTermination is not active - EventWaitHandle CoopSleepHandle { get; } - - /// /// Process the next event queued for this script instance. /// /// diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index b992efa..44072c6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -83,12 +83,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - /// - /// Instance of this script. - /// - protected IScriptInstance m_scriptInstance; - protected IScriptEngine m_ScriptEngine; protected SceneObjectPart m_host; @@ -118,12 +112,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void Initialize(IScriptInstance scriptInstance) { - m_scriptInstance = scriptInstance; - m_ScriptEngine = m_scriptInstance.Engine; - m_host = m_scriptInstance.Part; - m_item = m_scriptInstance.ScriptTask; + m_ScriptEngine = scriptInstance.Engine; + m_host = scriptInstance.Part; + m_item = scriptInstance.ScriptTask; - LoadConfig(); + LoadLimits(); // read script limits from config. m_TransferModule = m_ScriptEngine.World.RequestModuleInterface(); @@ -136,7 +129,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// /// Load configuration items that affect script, object and run-time behavior. */ /// - private void LoadConfig() + private void LoadLimits() { m_ScriptDelayFactor = m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); @@ -182,16 +175,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api delay = (int)((float)delay * m_ScriptDelayFactor); if (delay == 0) return; - - Sleep(delay); - } - - protected virtual void Sleep(int delay) - { - if (!m_scriptInstance.CoopTermination) - System.Threading.Thread.Sleep(delay); - else if (m_scriptInstance.CoopSleepHandle.WaitOne(delay)) - throw new ScriptCoopStopException(); + System.Threading.Thread.Sleep(delay); } public Scene World @@ -2930,8 +2914,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { // m_log.Info("llSleep snoozing " + sec + "s."); m_host.AddScriptLPS(1); - - Sleep((int)(sec * 1000)); + Thread.Sleep((int)(sec * 1000)); } public LSL_Float llGetMass() diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs index e02d35e..5a58f73 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs @@ -81,24 +81,6 @@ namespace OpenSim.Region.ScriptEngine.Shared } } - /// - /// Used to signal when the script is stopping in co-operation with the script engine - /// (instead of through Thread.Abort()). - /// - [Serializable] - public class ScriptCoopStopException : Exception - { - public ScriptCoopStopException() - { - } - - protected ScriptCoopStopException( - SerializationInfo info, - StreamingContext context) - { - } - } - public class DetectParams { public const int AGENT = 1; diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 00048a1..a2ff51b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -200,10 +200,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance public static readonly long MaxMeasurementPeriod = 30 * TimeSpan.TicksPerMinute; - public bool CoopTermination { get; private set; } - - public EventWaitHandle CoopSleepHandle { get; private set; } - public void ClearQueue() { m_TimerQueued = false; @@ -237,12 +233,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance m_postOnRez = postOnRez; m_AttachedAvatar = Part.ParentGroup.AttachedAvatar; m_RegionID = Part.ParentGroup.Scene.RegionInfo.RegionID; - - if (Engine.Config.GetString("ScriptStopStrategy", "abort") == "co-op") - { - CoopTermination = true; - CoopSleepHandle = new AutoResetEvent(false); - } } /// @@ -542,34 +532,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance } // Wait for the current event to complete. - if (!m_InSelfDelete) + if (!m_InSelfDelete && workItem.Wait(new TimeSpan((long)timeout * 100000))) { - if (!CoopTermination) - { - // If we're not co-operative terminating then try and wait for the event to complete before stopping - if (workItem.Wait(new TimeSpan((long)timeout * 100000))) - return true; - } - else - { - m_log.DebugFormat( - "[SCRIPT INSTANCE]: Co-operatively stopping script {0} {1} in {2} {3}", - ScriptName, ItemID, PrimName, ObjectID); - - // This will terminate the event on next handle check by the script. - CoopSleepHandle.Set(); - - // For now, we will wait forever since the event should always cleanly terminate once LSL loop - // checking is implemented. May want to allow a shorter timeout option later. - if (workItem.Wait(TimeSpan.MaxValue)) - { - m_log.DebugFormat( - "[SCRIPT INSTANCE]: Co-operatively stopped script {0} {1} in {2} {3}", - ScriptName, ItemID, PrimName, ObjectID); - - return true; - } - } + return true; } lock (EventQueue) @@ -582,7 +547,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance // If the event still hasn't stopped and we the stop isn't the result of script or object removal, then // forcibly abort the work item (this aborts the underlying thread). - // Co-operative termination should never reach this point. if (!m_InSelfDelete) { m_log.DebugFormat( @@ -822,11 +786,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance m_InEvent = false; m_CurrentEvent = String.Empty; - if ((!(e is TargetInvocationException) - || (!(e.InnerException is SelfDeleteException) - && !(e.InnerException is ScriptDeleteException) - && !(e.InnerException is ScriptCoopStopException))) - && !(e is ThreadAbortException)) + if ((!(e is TargetInvocationException) || (!(e.InnerException is SelfDeleteException) && !(e.InnerException is ScriptDeleteException))) && !(e is ThreadAbortException)) { try { @@ -874,12 +834,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance m_InSelfDelete = true; Part.Inventory.RemoveInventoryItem(ItemID); } - else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException)) - { - m_log.DebugFormat( - "[SCRIPT INSTANCE]: Script {0}.{1} in event {2}, state {3} stopped co-operatively.", - PrimName, ScriptName, data.EventName, State); - } } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs deleted file mode 100644 index f3a6cc9..0000000 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Threading; -using Nini.Config; -using NUnit.Framework; -using OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Region.CoreModules.Scripting.WorldComm; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.ScriptEngine.XEngine; -using OpenSim.Tests.Common; -using OpenSim.Tests.Common.Mock; - -namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests -{ - /// - /// Test that co-operative script thread termination is working correctly. - /// - [TestFixture] - public class CoopTerminationTests : OpenSimTestCase - { - private TestScene m_scene; - private OpenSim.Region.ScriptEngine.XEngine.XEngine m_xEngine; - - private AutoResetEvent m_chatEvent = new AutoResetEvent(false); - private AutoResetEvent m_stoppedEvent = new AutoResetEvent(false); - - private OSChatMessage m_osChatMessageReceived; - - [TestFixtureSetUp] - public void Init() - { - //AppDomain.CurrentDomain.SetData("APPBASE", Environment.CurrentDirectory + "/bin"); -// Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory); - m_xEngine = new OpenSim.Region.ScriptEngine.XEngine.XEngine(); - - IniConfigSource configSource = new IniConfigSource(); - - IConfig startupConfig = configSource.AddConfig("Startup"); - startupConfig.Set("DefaultScriptEngine", "XEngine"); - - IConfig xEngineConfig = configSource.AddConfig("XEngine"); - xEngineConfig.Set("Enabled", "true"); - xEngineConfig.Set("StartDelay", "0"); - - // These tests will not run with AppDomainLoading = true, at least on mono. For unknown reasons, the call - // to AssemblyResolver.OnAssemblyResolve fails. - xEngineConfig.Set("AppDomainLoading", "false"); - - xEngineConfig.Set("ScriptStopStrategy", "co-op"); - - m_scene = new SceneHelpers().SetupScene("My Test", UUID.Random(), 1000, 1000, configSource); - SceneHelpers.SetupSceneModules(m_scene, configSource, m_xEngine); - m_scene.StartScripts(); - } - - /// - /// Test co-operative termination on derez of an object containing a script with a long-running event. - /// - /// - /// TODO: Actually compiling the script is incidental to this test. Really want a way to compile test scripts - /// within the build itself. - /// - [Test] - public void TestStopOnLongSleep() - { - TestHelpers.InMethod(); - TestHelpers.EnableLogging(); - - UUID userId = TestHelpers.ParseTail(0x1); -// UUID objectId = TestHelpers.ParseTail(0x100); -// UUID itemId = TestHelpers.ParseTail(0x3); - string itemName = "TestStopOnObjectDerezLongSleep() Item"; - - SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, "TestStopOnObjectDerezLongSleep", 0x100); - m_scene.AddNewSceneObject(so, true); - - InventoryItemBase itemTemplate = new InventoryItemBase(); -// itemTemplate.ID = itemId; - itemTemplate.Name = itemName; - itemTemplate.Folder = so.UUID; - itemTemplate.InvType = (int)InventoryType.LSL; - - m_scene.EventManager.OnChatFromWorld += OnChatFromWorld; - - SceneObjectPart partWhereRezzed = m_scene.RezNewScript(userId, itemTemplate, -@"default -{ - state_entry() - { - llSay(0, ""Thin Lizzy""); - llSleep(60); - } -}"); - - TaskInventoryItem rezzedItem = partWhereRezzed.Inventory.GetInventoryItem(itemName); - - // Wait for the script to start the event before we try stopping it. - m_chatEvent.WaitOne(60000); - - Console.WriteLine("Script started with message [{0}]", m_osChatMessageReceived.Message); - - // FIXME: This is a very poor way of trying to avoid a low-probability race condition where the script - // executes llSay() but has not started the sleep before we try to stop it. - Thread.Sleep(1000); - - // We need a way of carrying on if StopScript() fail, since it won't return if the script isn't actually - // stopped. This kind of multi-threading is far from ideal in a regression test. - new Thread(() => { m_xEngine.StopScript(rezzedItem.ItemID); m_stoppedEvent.Set(); }).Start(); - - if (!m_stoppedEvent.WaitOne(30000)) - Assert.Fail("Script did not co-operatively stop."); - - bool running; - TaskInventoryItem scriptItem = partWhereRezzed.Inventory.GetInventoryItem(itemName); - Assert.That( - SceneObjectPartInventory.TryGetScriptInstanceRunning(m_scene, scriptItem, out running), Is.True); - Assert.That(running, Is.False); - } - - private void OnChatFromWorld(object sender, OSChatMessage oscm) - { -// Console.WriteLine("Got chat [{0}]", oscm.Message); - - m_osChatMessageReceived = oscm; - m_chatEvent.Set(); - } - } -} \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index a17a018..186ae04 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1716,14 +1716,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine IScriptInstance instance = GetInstance(itemID); if (instance != null) - { instance.Stop(m_WaitForEventCompletionOnScriptStop); - } else - { -// m_log.DebugFormat("[XENGINE]: Could not find script with ID {0} to stop in {1}", itemID, World.Name); m_runFlags.AddOrUpdate(itemID, false, 240); - } } public DetectParams GetDetectParams(UUID itemID, int idx) -- cgit v1.1 From 0963ece25bdef16852f5fd8ae4515a2f05d8b6e4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 16 Jan 2013 02:07:43 +0000 Subject: Implement co-operative script termination if termination comes during a script wait event (llSleep(), etc.) This makes use of EventWaitHandles since various web references indicate that Thread.Interrupt() can also cause runtime instability. If co-op termination is enabled, then termination sets the wait handle instead of waiting for a timeout before possibly aborting the thread. This allows the script to cleanly terminate if it's in a llSleep/LL function delay or the next time it enters such a wait without any timeout period. Co-op termination is not yet testable since checking for termination request within loops that never trigger a wait is not yet implemented. This commit, unlike 1b5c41c, passes the wait handle as an extra parameter through IScript.Initialize() instead of passing IScriptInstance itself. --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 26 +++- .../Region/ScriptEngine/Interfaces/IScriptApi.cs | 9 +- .../ScriptEngine/Interfaces/IScriptInstance.cs | 1 + .../Shared/Api/Implementation/LSL_Api.cs | 35 +++-- .../Shared/Api/Implementation/LS_Api.cs | 8 +- .../Shared/Api/Implementation/MOD_Api.cs | 10 +- .../Shared/Api/Implementation/OSSL_Api.cs | 9 +- OpenSim/Region/ScriptEngine/Shared/Helpers.cs | 18 +++ .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 54 ++++++- .../Shared/Instance/Tests/CoopTerminationTests.cs | 157 +++++++++++++++++++++ .../Shared/Tests/LSL_ApiInventoryTests.cs | 6 +- .../Shared/Tests/LSL_ApiLinkingTests.cs | 4 +- .../ScriptEngine/Shared/Tests/LSL_ApiListTests.cs | 2 +- .../ScriptEngine/Shared/Tests/LSL_ApiTest.cs | 2 +- .../Shared/Tests/OSSL_ApiAppearanceTest.cs | 4 +- .../Shared/Tests/OSSL_ApiAttachmentTests.cs | 15 +- .../ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs | 16 +-- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 5 + 18 files changed, 327 insertions(+), 54 deletions(-) create mode 100644 OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 5c8b097..92bf85a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1738,6 +1738,21 @@ namespace OpenSim.Region.Framework.Scenes /// The part where the script was rezzed if successful. False otherwise. public SceneObjectPart RezNewScript(UUID agentID, InventoryItemBase itemBase) { + return RezNewScript( + agentID, + itemBase, + "default\n{\n state_entry()\n {\n llSay(0, \"Script running\");\n }\n}"); + } + + /// + /// Rez a new script from nothing with given script text. + /// + /// + /// Template item. + /// + /// The part where the script was rezzed if successful. False otherwise. + public SceneObjectPart RezNewScript(UUID agentID, InventoryItemBase itemBase, string scriptText) + { // The part ID is the folder ID! SceneObjectPart part = GetSceneObjectPart(itemBase.Folder); if (part == null) @@ -1757,9 +1772,14 @@ namespace OpenSim.Region.Framework.Scenes return null; } - AssetBase asset = CreateAsset(itemBase.Name, itemBase.Description, (sbyte)itemBase.AssetType, - Encoding.ASCII.GetBytes("default\n{\n state_entry()\n {\n llSay(0, \"Script running\");\n }\n}"), - agentID); + AssetBase asset + = CreateAsset( + itemBase.Name, + itemBase.Description, + (sbyte)itemBase.AssetType, + Encoding.ASCII.GetBytes(scriptText), + agentID); + AssetService.Store(asset); TaskInventoryItem taskItem = new TaskInventoryItem(); diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs index e95cbd7..d2323f5 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs @@ -26,6 +26,7 @@ */ using System; +using System.Threading; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; @@ -40,7 +41,11 @@ namespace OpenSim.Region.ScriptEngine.Interfaces /// /// /// Each API has an identifier, which is used to load the proper runtime assembly at load time. - /// /param> - void Initialize(IScriptInstance scriptInstance); + /// /param> + /// /param> + /// /param> + /// /param> + void Initialize( + IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle); } } \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index 9de2d72..f68612c 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs @@ -28,6 +28,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Threading; using OpenMetaverse; using log4net; using OpenSim.Framework; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 44072c6..d47fd6b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -83,10 +83,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + protected IScriptEngine m_ScriptEngine; protected SceneObjectPart m_host; /// + /// Used for script sleeps when we are using co-operative script termination. + /// + /// null if co-operative script termination is not active + EventWaitHandle m_coopSleepHandle; + + /// /// The item that hosts this script /// protected TaskInventoryItem m_item; @@ -110,13 +117,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. protected ISoundModule m_SoundModule = null; - public void Initialize(IScriptInstance scriptInstance) + public void Initialize( + IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle) { - m_ScriptEngine = scriptInstance.Engine; - m_host = scriptInstance.Part; - m_item = scriptInstance.ScriptTask; + m_ScriptEngine = scriptEngine; + m_host = host; + m_item = item; + m_coopSleepHandle = coopSleepHandle; - LoadLimits(); // read script limits from config. + LoadConfig(); m_TransferModule = m_ScriptEngine.World.RequestModuleInterface(); @@ -129,7 +138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// /// Load configuration items that affect script, object and run-time behavior. */ /// - private void LoadLimits() + private void LoadConfig() { m_ScriptDelayFactor = m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); @@ -175,7 +184,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api delay = (int)((float)delay * m_ScriptDelayFactor); if (delay == 0) return; - System.Threading.Thread.Sleep(delay); + + Sleep(delay); + } + + protected virtual void Sleep(int delay) + { + if (m_coopSleepHandle == null) + System.Threading.Thread.Sleep(delay); + else if (m_coopSleepHandle.WaitOne(delay)) + throw new ScriptCoopStopException(); } public Scene World @@ -2914,7 +2932,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { // m_log.Info("llSleep snoozing " + sec + "s."); m_host.AddScriptLPS(1); - Thread.Sleep((int)(sec * 1000)); + + Sleep((int)(sec * 1000)); } public LSL_Float llGetMass() diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs index 071c60e..a08ccc8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs @@ -30,6 +30,7 @@ using System.Reflection; using System.Collections; using System.Collections.Generic; using System.Runtime.Remoting.Lifetime; +using System.Threading; using OpenMetaverse; using Nini.Config; using OpenSim; @@ -61,10 +62,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api internal bool m_LSFunctionsEnabled = false; internal IScriptModuleComms m_comms = null; - public void Initialize(IScriptInstance scriptInstance) + public void Initialize( + IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle) { - m_ScriptEngine = scriptInstance.Engine; - m_host = scriptInstance.Part; + m_ScriptEngine = scriptEngine; + m_host = host; if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false)) m_LSFunctionsEnabled = true; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs index cbc69aa..981499e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs @@ -30,6 +30,7 @@ using System.Reflection; using System.Collections; using System.Collections.Generic; using System.Runtime.Remoting.Lifetime; +using System.Threading; using OpenMetaverse; using Nini.Config; using OpenSim; @@ -61,11 +62,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api internal bool m_MODFunctionsEnabled = false; internal IScriptModuleComms m_comms = null; - public void Initialize(IScriptInstance scriptInstance) + public void Initialize( + IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle) { - m_ScriptEngine = scriptInstance.Engine; - m_host = scriptInstance.Part; - m_item = scriptInstance.ScriptTask; + m_ScriptEngine = scriptEngine; + m_host = host; + m_item = item; if (m_ScriptEngine.Config.GetBoolean("AllowMODFunctions", false)) m_MODFunctionsEnabled = true; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 33ae5f0..25635ff 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -142,11 +142,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected IUrlModule m_UrlModule = null; - public void Initialize(IScriptInstance scriptInstance) + public void Initialize( + IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle) { - m_ScriptEngine = scriptInstance.Engine; - m_host = scriptInstance.Part; - m_item = scriptInstance.ScriptTask; + m_ScriptEngine = scriptEngine; + m_host = host; + m_item = item; m_UrlModule = m_ScriptEngine.World.RequestModuleInterface(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs index 5a58f73..e02d35e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs @@ -81,6 +81,24 @@ namespace OpenSim.Region.ScriptEngine.Shared } } + /// + /// Used to signal when the script is stopping in co-operation with the script engine + /// (instead of through Thread.Abort()). + /// + [Serializable] + public class ScriptCoopStopException : Exception + { + public ScriptCoopStopException() + { + } + + protected ScriptCoopStopException( + SerializationInfo info, + StreamingContext context) + { + } + } + public class DetectParams { public const int AGENT = 1; diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index a2ff51b..75aea2b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -200,6 +200,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance public static readonly long MaxMeasurementPeriod = 30 * TimeSpan.TicksPerMinute; + private bool m_coopTermination; + + private EventWaitHandle m_coopSleepHandle; + public void ClearQueue() { m_TimerQueued = false; @@ -233,6 +237,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance m_postOnRez = postOnRez; m_AttachedAvatar = Part.ParentGroup.AttachedAvatar; m_RegionID = Part.ParentGroup.Scene.RegionInfo.RegionID; + + if (Engine.Config.GetString("ScriptStopStrategy", "abort") == "co-op") + { + m_coopTermination = true; + m_coopSleepHandle = new AutoResetEvent(false); + } } /// @@ -251,7 +261,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance foreach (string api in am.GetApis()) { m_Apis[api] = am.CreateApi(api); - m_Apis[api].Initialize(this); + m_Apis[api].Initialize(Engine, Part, ScriptTask, m_coopSleepHandle); } try @@ -532,9 +542,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance } // Wait for the current event to complete. - if (!m_InSelfDelete && workItem.Wait(new TimeSpan((long)timeout * 100000))) + if (!m_InSelfDelete) { - return true; + if (!m_coopTermination) + { + // If we're not co-operative terminating then try and wait for the event to complete before stopping + if (workItem.Wait(new TimeSpan((long)timeout * 100000))) + return true; + } + else + { + m_log.DebugFormat( + "[SCRIPT INSTANCE]: Co-operatively stopping script {0} {1} in {2} {3}", + ScriptName, ItemID, PrimName, ObjectID); + + // This will terminate the event on next handle check by the script. + m_coopSleepHandle.Set(); + + // For now, we will wait forever since the event should always cleanly terminate once LSL loop + // checking is implemented. May want to allow a shorter timeout option later. + if (workItem.Wait(TimeSpan.MaxValue)) + { + m_log.DebugFormat( + "[SCRIPT INSTANCE]: Co-operatively stopped script {0} {1} in {2} {3}", + ScriptName, ItemID, PrimName, ObjectID); + + return true; + } + } } lock (EventQueue) @@ -547,6 +582,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance // If the event still hasn't stopped and we the stop isn't the result of script or object removal, then // forcibly abort the work item (this aborts the underlying thread). + // Co-operative termination should never reach this point. if (!m_InSelfDelete) { m_log.DebugFormat( @@ -786,7 +822,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance m_InEvent = false; m_CurrentEvent = String.Empty; - if ((!(e is TargetInvocationException) || (!(e.InnerException is SelfDeleteException) && !(e.InnerException is ScriptDeleteException))) && !(e is ThreadAbortException)) + if ((!(e is TargetInvocationException) + || (!(e.InnerException is SelfDeleteException) + && !(e.InnerException is ScriptDeleteException) + && !(e.InnerException is ScriptCoopStopException))) + && !(e is ThreadAbortException)) { try { @@ -834,6 +874,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance m_InSelfDelete = true; Part.Inventory.RemoveInventoryItem(ItemID); } + else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException)) + { + m_log.DebugFormat( + "[SCRIPT INSTANCE]: Script {0}.{1} in event {2}, state {3} stopped co-operatively.", + PrimName, ScriptName, data.EventName, State); + } } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs new file mode 100644 index 0000000..8c3e9e0 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs @@ -0,0 +1,157 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Threading; +using Nini.Config; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.CoreModules.Scripting.WorldComm; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.ScriptEngine.XEngine; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests +{ + /// + /// Test that co-operative script thread termination is working correctly. + /// + [TestFixture] + public class CoopTerminationTests : OpenSimTestCase + { + private TestScene m_scene; + private OpenSim.Region.ScriptEngine.XEngine.XEngine m_xEngine; + + private AutoResetEvent m_chatEvent = new AutoResetEvent(false); + private AutoResetEvent m_stoppedEvent = new AutoResetEvent(false); + + private OSChatMessage m_osChatMessageReceived; + + [TestFixtureSetUp] + public void Init() + { + //AppDomain.CurrentDomain.SetData("APPBASE", Environment.CurrentDirectory + "/bin"); +// Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory); + m_xEngine = new OpenSim.Region.ScriptEngine.XEngine.XEngine(); + + IniConfigSource configSource = new IniConfigSource(); + + IConfig startupConfig = configSource.AddConfig("Startup"); + startupConfig.Set("DefaultScriptEngine", "XEngine"); + + IConfig xEngineConfig = configSource.AddConfig("XEngine"); + xEngineConfig.Set("Enabled", "true"); + xEngineConfig.Set("StartDelay", "0"); + + // These tests will not run with AppDomainLoading = true, at least on mono. For unknown reasons, the call + // to AssemblyResolver.OnAssemblyResolve fails. + xEngineConfig.Set("AppDomainLoading", "false"); + + xEngineConfig.Set("ScriptStopStrategy", "co-op"); + + m_scene = new SceneHelpers().SetupScene("My Test", UUID.Random(), 1000, 1000, configSource); + SceneHelpers.SetupSceneModules(m_scene, configSource, m_xEngine); + m_scene.StartScripts(); + } + + /// + /// Test co-operative termination on derez of an object containing a script with a long-running event. + /// + /// + /// TODO: Actually compiling the script is incidental to this test. Really want a way to compile test scripts + /// within the build itself. + /// + [Test] + public void TestStopOnLongSleep() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID userId = TestHelpers.ParseTail(0x1); +// UUID objectId = TestHelpers.ParseTail(0x100); +// UUID itemId = TestHelpers.ParseTail(0x3); + string itemName = "TestStopOnObjectDerezLongSleep() Item"; + + SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, "TestStopOnObjectDerezLongSleep", 0x100); + m_scene.AddNewSceneObject(so, true); + + InventoryItemBase itemTemplate = new InventoryItemBase(); +// itemTemplate.ID = itemId; + itemTemplate.Name = itemName; + itemTemplate.Folder = so.UUID; + itemTemplate.InvType = (int)InventoryType.LSL; + + m_scene.EventManager.OnChatFromWorld += OnChatFromWorld; + + SceneObjectPart partWhereRezzed = m_scene.RezNewScript(userId, itemTemplate, +@"default +{ + state_entry() + { + llSay(0, ""Thin Lizzy""); + llSleep(60); + } +}"); + + TaskInventoryItem rezzedItem = partWhereRezzed.Inventory.GetInventoryItem(itemName); + + // Wait for the script to start the event before we try stopping it. + m_chatEvent.WaitOne(60000); + + Console.WriteLine("Script started with message [{0}]", m_osChatMessageReceived.Message); + + // FIXME: This is a very poor way of trying to avoid a low-probability race condition where the script + // executes llSay() but has not started the sleep before we try to stop it. + Thread.Sleep(1000); + + // We need a way of carrying on if StopScript() fail, since it won't return if the script isn't actually + // stopped. This kind of multi-threading is far from ideal in a regression test. + new Thread(() => { m_xEngine.StopScript(rezzedItem.ItemID); m_stoppedEvent.Set(); }).Start(); + + if (!m_stoppedEvent.WaitOne(30000)) + Assert.Fail("Script did not co-operatively stop."); + + bool running; + TaskInventoryItem scriptItem = partWhereRezzed.Inventory.GetInventoryItem(itemName); + Assert.That( + SceneObjectPartInventory.TryGetScriptInstanceRunning(m_scene, scriptItem, out running), Is.True); + Assert.That(running, Is.False); + } + + private void OnChatFromWorld(object sender, OSChatMessage oscm) + { +// Console.WriteLine("Got chat [{0}]", oscm.Message); + + m_osChatMessageReceived = oscm; + m_chatEvent.Set(); + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs index 36c7582..6dd6c17 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs @@ -94,7 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests TaskInventoryHelpers.AddSceneObject(m_scene, so1.RootPart, inventoryItemName, itemId, userId); LSL_Api api = new LSL_Api(); - api.Initialize(new ScriptInstance(m_engine, so1.RootPart, null, 0, false, int.MaxValue)); + api.Initialize(m_engine, so1.RootPart, null, null); // Create a second object SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, userId, "so2", 0x100); @@ -127,7 +127,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(1, user1Id, "so1", 0x10); m_scene.AddSceneObject(so1); LSL_Api api = new LSL_Api(); - api.Initialize(new ScriptInstance(m_engine, so1.RootPart, null, 0, false, int.MaxValue)); + api.Initialize(m_engine, so1.RootPart, null, null); // Create an object embedded inside the first UUID itemId = TestHelpers.ParseTail(0x20); @@ -137,7 +137,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, user2Id, "so2", 0x100); m_scene.AddSceneObject(so2); LSL_Api api2 = new LSL_Api(); - api2.Initialize(new ScriptInstance(m_engine, so2.RootPart, null, 0, false, int.MaxValue)); + api2.Initialize(m_engine, so2.RootPart, null, null); // *** Firstly, we test where llAllowInventoryDrop() has not been called. *** api.llGiveInventory(so2.UUID.ToString(), inventoryItemName); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs index 5121344..5b57bbe 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs @@ -105,7 +105,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(grp2); LSL_Api apiGrp1 = new LSL_Api(); - apiGrp1.Initialize(new ScriptInstance(m_engine, grp1.RootPart, grp1Item, 0, false, int.MaxValue)); + apiGrp1.Initialize(m_engine, grp1.RootPart, grp1Item, null); apiGrp1.llCreateLink(grp2.UUID.ToString(), ScriptBaseClass.TRUE); @@ -132,7 +132,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests grp1Item.PermsMask |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; LSL_Api apiGrp1 = new LSL_Api(); - apiGrp1.Initialize(new ScriptInstance(m_engine, grp1.RootPart, grp1Item, 0, false, int.MaxValue)); + apiGrp1.Initialize(m_engine, grp1.RootPart, grp1Item, null); apiGrp1.llBreakLink(2); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs index 28e5831..60de5cb 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs @@ -68,7 +68,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests engine.AddRegion(scene); m_lslApi = new LSL_Api(); - m_lslApi.Initialize(new ScriptInstance(engine, part, null, 0, false, int.MaxValue)); + m_lslApi.Initialize(engine, part, null, null); } [Test] diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs index 48c2465..e97ae06 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs @@ -67,7 +67,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests engine.AddRegion(scene); m_lslApi = new LSL_Api(); - m_lslApi.Initialize(new ScriptInstance(engine, part, null, 0, false, int.MaxValue)); + m_lslApi.Initialize(engine, part, null, null); } [Test] diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs index 5164d4e..c88bad5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs @@ -94,7 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(new ScriptInstance(m_engine, part, null, 0, false, int.MaxValue)); + osslApi.Initialize(m_engine, part, null, null); string notecardName = "appearanceNc"; @@ -135,7 +135,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(new ScriptInstance(m_engine, part, null, 0, false, int.MaxValue)); + osslApi.Initialize(m_engine, part, null, null); string notecardName = "appearanceNc"; diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs index e7b3319..b2803a1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs @@ -99,10 +99,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID); TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart); - ScriptInstance si = new ScriptInstance(m_engine, inWorldObj.RootPart, scriptItem, 0, false, int.MaxValue); - new LSL_Api().Initialize(si); + new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem, null); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(si); + osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem, null); // SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ua1.PrincipalID); @@ -146,10 +145,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID); TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart); - ScriptInstance si = new ScriptInstance(m_engine, inWorldObj.RootPart, scriptItem, 0, false, int.MaxValue); - new LSL_Api().Initialize(si); + new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem, null); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(si); + osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem, null); // Create an object embedded inside the first TaskInventoryHelpers.AddNotecard( @@ -195,10 +193,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID); TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart); - ScriptInstance si = new ScriptInstance(m_engine, inWorldObj.RootPart, scriptItem, 0, false, int.MaxValue); - new LSL_Api().Initialize(si); + new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem, null); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(si); + osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem, null); // Create an object embedded inside the first TaskInventoryHelpers.AddSceneObject( diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs index 584f44f..1f8a6e5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs @@ -100,7 +100,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(new ScriptInstance(m_engine, part, null, 0, false, int.MaxValue)); + osslApi.Initialize(m_engine, part, null, null); string notecardName = "appearanceNc"; osslApi.osOwnerSaveAppearance(notecardName); @@ -126,7 +126,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(new ScriptInstance(m_engine, so.RootPart, null, 0, false, int.MaxValue)); + osslApi.Initialize(m_engine, so.RootPart, null, null); bool gotExpectedException = false; try @@ -161,7 +161,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(new ScriptInstance(m_engine, part, null, 0, false, int.MaxValue)); + osslApi.Initialize(m_engine, part, null, null); string notecardName = "appearanceNc"; osslApi.osOwnerSaveAppearance(notecardName); @@ -195,7 +195,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(new ScriptInstance(m_engine, part, null, 0, false, int.MaxValue)); + osslApi.Initialize(m_engine, part, null, null); osslApi.osOwnerSaveAppearance(firstAppearanceNcName); @@ -233,7 +233,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(new ScriptInstance(m_engine, part, null, 0, false, int.MaxValue)); + osslApi.Initialize(m_engine, part, null, null); osslApi.osOwnerSaveAppearance(firstAppearanceNcName); @@ -285,10 +285,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(otherSo); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(new ScriptInstance(m_engine, part, null, 0, false, int.MaxValue)); + osslApi.Initialize(m_engine, part, null, null); OSSL_Api otherOsslApi = new OSSL_Api(); - otherOsslApi.Initialize(new ScriptInstance(m_engine, otherPart, null, 0, false, int.MaxValue)); + otherOsslApi.Initialize(m_engine, otherPart, null, null); string notecardName = "appearanceNc"; osslApi.osOwnerSaveAppearance(notecardName); @@ -332,7 +332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(new ScriptInstance(m_engine, part, null, 0, false, int.MaxValue)); + osslApi.Initialize(m_engine, part, null, null); string notecardName = "appearanceNc"; osslApi.osOwnerSaveAppearance(notecardName); diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 186ae04..a17a018 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1716,9 +1716,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine IScriptInstance instance = GetInstance(itemID); if (instance != null) + { instance.Stop(m_WaitForEventCompletionOnScriptStop); + } else + { +// m_log.DebugFormat("[XENGINE]: Could not find script with ID {0} to stop in {1}", itemID, World.Name); m_runFlags.AddOrUpdate(itemID, false, 240); + } } public DetectParams GetDetectParams(UUID itemID, int idx) -- cgit v1.1 From daef2b8d87300f02bef7edf01ae67c8c6a50af46 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 15 Jan 2013 12:55:55 -0800 Subject: BulletSim: reduce maximum force a script can apply (like in llApplyImpulse) to the documented maximum from the outragious number previously. --- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 862dbf6..3e80aa4 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -94,16 +94,16 @@ public static class BSParam public static float PID_D { get; private set; } // derivative public static float PID_P { get; private set; } // proportional - // Various constants that come from that other virtual world that shall not be named + // Various constants that come from that other virtual world that shall not be named. public const float MinGravityZ = -1f; public const float MaxGravityZ = 28f; public const float MinFriction = 0f; public const float MaxFriction = 255f; - public const float MinDensity = 0f; + public const float MinDensity = 0.01f; public const float MaxDensity = 22587f; public const float MinRestitution = 0f; public const float MaxRestitution = 1f; - public const float MaxAddForceMagnitude = 20000f; + public const float MaxAddForceMagnitude = 20f; // =========================================================================== public delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val); -- cgit v1.1 From 61ff79587bea373278771f9529b582db2e05afdd Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 15 Jan 2013 12:57:12 -0800 Subject: BulletSim: add debugging messages to know when assets for physical objects have been fetched. Update TODO list with more work. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 5 ++- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 4 +-- .../Physics/BulletSPlugin/BSShapeCollection.cs | 42 ++++++++++++++-------- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 17 +++++++++ 4 files changed, 51 insertions(+), 17 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index a5fec87..2e900b3 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -855,7 +855,10 @@ public sealed class BSCharacter : BSPhysObject _rotationalVelocity = entprop.RotationalVelocity; // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. - PositionSanityCheck(true); + if (PositionSanityCheck(true)) + { + entprop.Position = _position; + } // remember the current and last set values LastEntityProperties = CurrentEntityProperties; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 2dc89b5..eff909c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -108,8 +108,8 @@ public sealed class BSLinksetCompound : BSLinkset // Schedule a refresh to happen after all the other taint processing. private void ScheduleRebuild(BSPhysObject requestor) { - DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1},hasChildren={2}", - requestor.LocalID, Rebuilding, HasAnyChildren); + DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1},hasChildren={2},actuallyScheduling={3}", + requestor.LocalID, Rebuilding, HasAnyChildren, (!Rebuilding && HasAnyChildren)); // When rebuilding, it is possible to set properties that would normally require a rebuild. // If already rebuilding, don't request another rebuild. // If a linkset with just a root prim (simple non-linked prim) don't bother rebuilding. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index addab29..4f0d345 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -513,6 +513,7 @@ public sealed class BSShapeCollection : IDisposable return ret; } + // return 'true' if the shape was changed public bool CreateGeomMeshOrHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback) { @@ -872,8 +873,7 @@ public sealed class BSShapeCollection : IDisposable { prim.LastAssetBuildFailed = true; BSPhysObject xprim = prim; - DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset,lID={1},lastFailed={2}", - LogHeader, prim.LocalID, prim.LastAssetBuildFailed); + DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset,lastFailed={1}", prim.LocalID, prim.LastAssetBuildFailed); Util.FireAndForget(delegate { RequestAssetDelegate assetProvider = PhysicsScene.RequestAssetMethod; @@ -882,19 +882,34 @@ public sealed class BSShapeCollection : IDisposable BSPhysObject yprim = xprim; // probably not necessary, but, just in case. assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset) { - if (!yprim.BaseShape.SculptEntry) - return; - if (yprim.BaseShape.SculptTexture.ToString() != asset.ID) - return; - - yprim.BaseShape.SculptData = asset.Data; - // This will cause the prim to see that the filler shape is not the right - // one and try again to build the object. - // No race condition with the normal shape setting since the rebuild is at taint time. - yprim.ForceBodyShapeRebuild(false); + bool assetFound = false; // DEBUG DEBUG + string mismatchIDs = String.Empty; // DEBUG DEBUG + if (yprim.BaseShape.SculptEntry) + { + if (yprim.BaseShape.SculptTexture.ToString() == asset.ID) + { + yprim.BaseShape.SculptData = asset.Data; + // This will cause the prim to see that the filler shape is not the right + // one and try again to build the object. + // No race condition with the normal shape setting since the rebuild is at taint time. + yprim.ForceBodyShapeRebuild(false /* inTaintTime */); + assetFound = true; + } + else + { + mismatchIDs = yprim.BaseShape.SculptTexture.ToString() + "/" + asset.ID; + } + } + DetailLog("{0},BSShapeCollection,fetchAssetCallback,found={1},isSculpt={2},ids={3}", + yprim.LocalID, assetFound, yprim.BaseShape.SculptEntry, mismatchIDs ); }); } + else + { + PhysicsScene.Logger.ErrorFormat("{0} Physical object requires asset but no asset provider. Name={1}", + LogHeader, PhysicsScene.Name); + } }); } else @@ -907,8 +922,7 @@ public sealed class BSShapeCollection : IDisposable } // While we figure out the real problem, stick in a simple box for the object. - BulletShape fillinShape = - BuildPhysicalNativeShape(prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX); + BulletShape fillinShape = BuildPhysicalNativeShape(prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX); return fillinShape; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 59cbab9..067e64a 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -1,7 +1,23 @@ CURRENT PRIORITIES ================================================= +Crazyness during 20130115 office hours was PositionAdjustUnderground for both char and prim + m1:logs/20130115.0934/physics-BulletSim-20130115083613.log + Creation of Neb's terrain made the terrain "disappear". Everything started to fall + and then get restored to be above terrain. +Create tests for different interface components + Have test objects/scripts measure themselves and turn color if correct/bad + Test functions in SL and calibrate correctness there + Create auto rezzer and tracker to run through the tests +Mantis 6040 script http://opensimulator.org/mantis/view.php?id=6040 + Msg Kayaker on OSGrid when working +Teravus llMoveToTarget script debug + Mixing of hover, buoyancy/gravity, moveToTarget, into one force +Surf board debugging +Boats floating at proper level Nebadon vehicles turning funny in arena limitMotorUp calibration (more down?) +llRotLookAt +llLookAt Vehicle angular vertical attraction Vehicle angular deflection Preferred orientation angular correction fix @@ -167,6 +183,7 @@ Enforce physical parameter min/max: Restitution [0, 1] http://wiki.secondlife.com/wiki/Physics_Material_Settings_test Avatar attachments have no mass? http://forums-archive.secondlife.com/54/f0/31796/1.html +Keep avatar scaling correct. http://pennycow.blogspot.fr/2011/07/matter-of-scale.html INTERNAL IMPROVEMENT/CLEANUP ================================================= -- cgit v1.1 From 5d098d8f17fe24d9ad2999ddce819787d02989ce Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 15 Jan 2013 15:07:38 -0800 Subject: BulletSim: don't modify angular parameters when doing LIMIT_MOTOR_UP. It was a dumb idea to try and do a nose over feature for jumping cars anyway. Add better logging of native shape creation/reuse so can tell the difference. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 12 +++++------ .../Physics/BulletSPlugin/BSLinksetCompound.cs | 2 +- .../Physics/BulletSPlugin/BSShapeCollection.cs | 18 ++++++++-------- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 24 +++++++++++----------- 5 files changed, 30 insertions(+), 28 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 2e900b3..87a06c1 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -215,7 +215,7 @@ public sealed class BSCharacter : BSPhysObject // Add special movement force to allow avatars to walk up stepped surfaces. moveForce += WalkUpStairs(); - DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); + // DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce); }); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index e434412..6601479 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -1160,8 +1160,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (!Prim.IsColliding && VehicleVelocity.Z > 0.1) { // Get rid of any of the velocity vector that is pushing us up. - VehicleVelocity += new Vector3(0, 0, -VehicleVelocity.Z); + float upVelocity = VehicleVelocity.Z; + VehicleVelocity += new Vector3(0, 0, -upVelocity); + /* // If we're pointed up into the air, we should nose down Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation; // The rotation around the Y axis is pitch up or down @@ -1175,11 +1177,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin VDetailLog("{0}, MoveLinear,limitMotorUp,newVel={1},pntDir={2},corrFrc={3},aCorr={4}", Prim.LocalID, VehicleVelocity, pointingDirection, angularCorrectionForce, angularCorrectionVector); } - else - { - VDetailLog("{0}, MoveLinear,limitMotorUp,newVel={1},pntDir={2}", - Prim.LocalID, VehicleVelocity, pointingDirection); - } + */ + VDetailLog("{0}, MoveLinear,limitMotorUp,collide={1},upVel={2},newVel={3}", + Prim.LocalID, Prim.IsColliding, upVelocity, VehicleVelocity); } } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index eff909c..8c9a774 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -311,7 +311,7 @@ public sealed class BSLinksetCompound : BSLinkset else { // Rebuild the compound shape with the child removed - ScheduleRebuild(child); + ScheduleRebuild(LinksetRoot); } } return; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 4f0d345..9fbfcdc 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -442,7 +442,8 @@ public sealed class BSShapeCollection : IDisposable return ret; } - // Create a mesh/hull shape or a native shape if 'nativeShapePossible' is 'true'. + // Create a mesh, hull or native shape. + // Return 'true' if the prim's shape was changed. public bool CreateGeomNonSpecial(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback) { bool ret = false; @@ -472,7 +473,7 @@ public sealed class BSShapeCollection : IDisposable if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,maybeNative,force={1},primScale={2},primSize={3},primShape={4}", prim.LocalID, forceRebuild, prim.Scale, prim.Size, prim.PhysShape.type); - // It doesn't look like Bullet scales spheres so make sure the scales are all equal + // It doesn't look like Bullet scales native spheres so make sure the scales are all equal if ((pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1) && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z) { @@ -484,9 +485,9 @@ public sealed class BSShapeCollection : IDisposable { ret = GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_SPHERE, FixedShapeKey.KEY_SPHERE, shapeCallback); - if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}", - prim.LocalID, forceRebuild, prim.PhysShape); } + if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},rebuilt={2},shape={3}", + prim.LocalID, forceRebuild, ret, prim.PhysShape); } if (!haveShape && pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight) { @@ -498,9 +499,9 @@ public sealed class BSShapeCollection : IDisposable { ret = GetReferenceToNativeShape( prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX, shapeCallback); - if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}", - prim.LocalID, forceRebuild, prim.PhysShape); } + if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},rebuilt={2},shape={3}", + prim.LocalID, forceRebuild, ret, prim.PhysShape); } } @@ -513,7 +514,7 @@ public sealed class BSShapeCollection : IDisposable return ret; } - // return 'true' if the shape was changed + // return 'true' if the prim's shape was changed. public bool CreateGeomMeshOrHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback) { @@ -921,8 +922,9 @@ public sealed class BSShapeCollection : IDisposable } } - // While we figure out the real problem, stick in a simple box for the object. + // While we wait for the mesh defining asset to be loaded, stick in a simple box for the object. BulletShape fillinShape = BuildPhysicalNativeShape(prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX); + DetailLog("{0},BSShapeCollection.VerifyMeshCreated,boxTempShape", prim.LocalID); return fillinShape; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 067e64a..53b5530 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -1,18 +1,9 @@ CURRENT PRIORITIES ================================================= -Crazyness during 20130115 office hours was PositionAdjustUnderground for both char and prim - m1:logs/20130115.0934/physics-BulletSim-20130115083613.log - Creation of Neb's terrain made the terrain "disappear". Everything started to fall - and then get restored to be above terrain. -Create tests for different interface components - Have test objects/scripts measure themselves and turn color if correct/bad - Test functions in SL and calibrate correctness there - Create auto rezzer and tracker to run through the tests Mantis 6040 script http://opensimulator.org/mantis/view.php?id=6040 Msg Kayaker on OSGrid when working Teravus llMoveToTarget script debug Mixing of hover, buoyancy/gravity, moveToTarget, into one force -Surf board debugging Boats floating at proper level Nebadon vehicles turning funny in arena limitMotorUp calibration (more down?) @@ -25,8 +16,6 @@ vehicle angular banking Avatars walking up stairs (HALF DONE) Radius of the capsule affects ability to climb edges. Vehicle movement on terrain smoothness -Surfboard go wonky when turning - Angular motor direction is global coordinates rather than local coordinates? Boats float low in the water (DONE) Avatar movement flying into a wall doesn't stop avatar who keeps appearing to move through the obstacle (DONE) @@ -43,6 +32,10 @@ Add material densities to the material types CRASHES ================================================= +Crazyness during 20130115 office hours was PositionAdjustUnderground for both char and prim + m1:logs/20130115.0934/physics-BulletSim-20130115083613.log + Creation of Neb's terrain made the terrain "disappear". Everything started to fall + and then get restored to be above terrain. 20121129.1411: editting/moving phys object across region boundries causes crash getPos-> btRigidBody::upcast -> getBodyType -> BOOM 20121128.1600: mesh object not rezzing (no physics mesh). @@ -149,6 +142,10 @@ Eliminate collisions between objects in a linkset. (LinksetConstraint) MORE ====================================================== +Create tests for different interface components + Have test objects/scripts measure themselves and turn color if correct/bad + Test functions in SL and calibrate correctness there + Create auto rezzer and tracker to run through the tests Use the HACD convex hull routine in Bullet rather than the C# version. Do we need to do convex hulls all the time? Can complex meshes be left meshes? There is some problem with meshes and collisions @@ -304,4 +301,7 @@ Disable activity of passive linkset children. (DONE) Since the linkset is a compound object, the old prims are left lying around and need to be phantomized so they don't collide, ... Remove HeightmapInfo from terrain specification (DONE) - Since C++ code does not need terrain height, this structure et al are not needed. \ No newline at end of file + Since C++ code does not need terrain height, this structure et al are not needed. +Surfboard go wonky when turning (DONE) + Angular motor direction is global coordinates rather than local coordinates? + (Resolution: made angular motor direction correct coordinate system) \ No newline at end of file -- cgit v1.1 From 8ee9daa121440ad550676814fe60e6b6c0c5d701 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 15 Jan 2013 21:08:11 -0800 Subject: BulletSim: add the editting children in linkset going phantom bug to TODO list. --- OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 53b5530..d4545f7 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -120,6 +120,8 @@ Physical and phantom will drop through the terrain LINKSETS ====================================================== +Editing a child of a linkset causes the child to go phantom + Move a child prim once when it is physical and can never move it again without it going phantom Offset the center of the linkset to be the geometric center of all the prims Not quite the same as the center-of-gravity Linksets should allow collisions to individual children -- cgit v1.1 From 818254916cb562422b3a3301b9f35fafd64ee3fe Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 16 Jan 2013 15:47:55 +0000 Subject: JustinCC's core re-merge --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 26 ++++- .../Region/ScriptEngine/Interfaces/IScriptApi.cs | 15 +-- .../ScriptEngine/Interfaces/IScriptInstance.cs | 13 +++ .../Shared/Api/Implementation/CM_Api.cs | 3 +- .../Shared/Api/Implementation/LSL_Api.cs | 45 ++++++--- .../Shared/Api/Implementation/LS_Api.cs | 13 +-- .../Shared/Api/Implementation/MOD_Api.cs | 6 +- .../Shared/Api/Implementation/OSSL_Api.cs | 5 +- OpenSim/Region/ScriptEngine/Shared/Helpers.cs | 18 ++++ .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 108 +++++++++++++++------ .../Shared/Tests/LSL_ApiInventoryTests.cs | 7 +- .../Shared/Tests/LSL_ApiLinkingTests.cs | 5 +- .../ScriptEngine/Shared/Tests/LSL_ApiListTests.cs | 3 +- .../ScriptEngine/Shared/Tests/LSL_ApiTest.cs | 3 +- .../Shared/Tests/OSSL_ApiAppearanceTest.cs | 5 +- .../Shared/Tests/OSSL_ApiAttachmentTests.cs | 16 +-- .../ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs | 17 ++-- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 14 ++- 18 files changed, 231 insertions(+), 91 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 65c50bf..9f0a0e2 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1783,6 +1783,21 @@ namespace OpenSim.Region.Framework.Scenes /// The part where the script was rezzed if successful. False otherwise. public SceneObjectPart RezNewScript(UUID agentID, InventoryItemBase itemBase) { + return RezNewScript( + agentID, + itemBase, + "default\n{\n state_entry()\n {\n llSay(0, \"Script running\");\n }\n}"); + } + + /// + /// Rez a new script from nothing with given script text. + /// + /// + /// Template item. + /// + /// The part where the script was rezzed if successful. False otherwise. + public SceneObjectPart RezNewScript(UUID agentID, InventoryItemBase itemBase, string scriptText) + { // The part ID is the folder ID! SceneObjectPart part = GetSceneObjectPart(itemBase.Folder); if (part == null) @@ -1802,9 +1817,14 @@ namespace OpenSim.Region.Framework.Scenes return null; } - AssetBase asset = CreateAsset(itemBase.Name, itemBase.Description, (sbyte)itemBase.AssetType, - Encoding.ASCII.GetBytes("default\n{\n state_entry()\n {\n llSay(0, \"Script running\");\n }\n\n touch_start(integer num)\n {\n }\n}"), - agentID); + AssetBase asset + = CreateAsset( + itemBase.Name, + itemBase.Description, + (sbyte)itemBase.AssetType, + Encoding.ASCII.GetBytes(scriptText), + agentID); + AssetService.Store(asset); TaskInventoryItem taskItem = new TaskInventoryItem(); diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs index 2027ca6..d2323f5 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs @@ -26,9 +26,11 @@ */ using System; +using System.Threading; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.ScriptEngine.Shared; namespace OpenSim.Region.ScriptEngine.Interfaces { @@ -38,11 +40,12 @@ namespace OpenSim.Region.ScriptEngine.Interfaces /// Initialize the API /// /// - /// Each API has an identifier, which is used to load the - /// proper runtime assembly at load time. - /// /param> - /// - /// - void Initialize(IScriptEngine engine, SceneObjectPart part, TaskInventoryItem item); + /// Each API has an identifier, which is used to load the proper runtime assembly at load time. + /// /param> + /// /param> + /// /param> + /// /param> + void Initialize( + IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle); } } \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index 2f5b526..f68612c 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs @@ -28,9 +28,11 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Threading; using OpenMetaverse; using log4net; using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.ScriptEngine.Interfaces; @@ -105,6 +107,11 @@ namespace OpenSim.Region.ScriptEngine.Interfaces /// long MeasurementPeriodExecutionTime { get; } + /// + /// Scene part in which this script instance is contained. + /// + SceneObjectPart Part { get; } + IScriptEngine Engine { get; } UUID AppDomain { get; set; } string PrimName { get; } @@ -124,6 +131,12 @@ namespace OpenSim.Region.ScriptEngine.Interfaces uint LocalID { get; } UUID AssetID { get; } + + /// + /// Inventory item containing the script used. + /// + TaskInventoryItem ScriptTask { get; } + Queue EventQueue { get; } /// diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs index b5fa6de..d03955b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs @@ -26,6 +26,7 @@ */ using System; +using System.Threading; using System.Reflection; using System.Collections; using System.Collections.Generic; @@ -62,7 +63,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api internal TaskInventoryItem m_item; internal bool m_CMFunctionsEnabled = false; - public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) + public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle) { m_ScriptEngine = ScriptEngine; m_host = host; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 4ce2afd..e83bbbb 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -87,10 +87,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + protected IScriptEngine m_ScriptEngine; protected SceneObjectPart m_host; /// + /// Used for script sleeps when we are using co-operative script termination. + /// + /// null if co-operative script termination is not active + EventWaitHandle m_coopSleepHandle; + + /// /// The item that hosts this script /// protected TaskInventoryItem m_item; @@ -142,33 +149,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api {"TURNRIGHT", "Turning Right"} }; - public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) + public void Initialize( + IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle) { -/* - m_ShoutSayTimer = new Timer(1000); - m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed; - m_ShoutSayTimer.AutoReset = true; - m_ShoutSayTimer.Start(); -*/ m_lastSayShoutCheck = DateTime.UtcNow; - m_ScriptEngine = ScriptEngine; + m_ScriptEngine = scriptEngine; m_host = host; m_item = item; m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false); + m_coopSleepHandle = coopSleepHandle; - LoadLimits(); // read script limits from config. + LoadConfig(); m_TransferModule = m_ScriptEngine.World.RequestModuleInterface(); m_UrlModule = m_ScriptEngine.World.RequestModuleInterface(); m_SoundModule = m_ScriptEngine.World.RequestModuleInterface(); - AsyncCommands = new AsyncCommandManager(ScriptEngine); + AsyncCommands = new AsyncCommandManager(m_ScriptEngine); } - /* load configuration items that affect script, object and run-time behavior. */ - private void LoadLimits() + /// + /// Load configuration items that affect script, object and run-time behavior. */ + /// + private void LoadConfig() { m_ScriptDelayFactor = m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); @@ -182,12 +187,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_ScriptEngine.Config.GetInt("NotecardLineReadCharsMax", 255); if (m_notecardLineReadCharsMax > 65535) m_notecardLineReadCharsMax = 65535; + // load limits for particular subsystems. IConfig SMTPConfig; if ((SMTPConfig = m_ScriptEngine.ConfigSource.Configs["SMTP"]) != null) { // there's an smtp config, so load in the snooze time. EMAIL_PAUSE_TIME = SMTPConfig.GetInt("email_pause_time", EMAIL_PAUSE_TIME); } + // Rezzing an object with a velocity can create recoil. This feature seems to have been // removed from recent versions of SL. The code computes recoil (vel*mass) and scales // it by this factor. May be zero to turn off recoil all together. @@ -212,7 +219,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api delay = (int)((float)delay * m_ScriptDelayFactor); if (delay == 0) return; - System.Threading.Thread.Sleep(delay); + + Sleep(delay); + } + + protected virtual void Sleep(int delay) + { + if (m_coopSleepHandle == null) + System.Threading.Thread.Sleep(delay); + else if (m_coopSleepHandle.WaitOne(delay)) + throw new ScriptCoopStopException(); } public Scene World @@ -3228,7 +3244,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { // m_log.Info("llSleep snoozing " + sec + "s."); m_host.AddScriptLPS(1); - Thread.Sleep((int)(sec * 1000)); + + Sleep((int)(sec * 1000)); } public LSL_Float llGetMass() diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs index ceb4660..a08ccc8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs @@ -30,6 +30,7 @@ using System.Reflection; using System.Collections; using System.Collections.Generic; using System.Runtime.Remoting.Lifetime; +using System.Threading; using OpenMetaverse; using Nini.Config; using OpenSim; @@ -61,9 +62,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api internal bool m_LSFunctionsEnabled = false; internal IScriptModuleComms m_comms = null; - public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) + public void Initialize( + IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle) { - m_ScriptEngine = ScriptEngine; + m_ScriptEngine = scriptEngine; m_host = host; if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false)) @@ -92,10 +94,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api get { return m_ScriptEngine.World; } } - // - //Dumps an error message on the debug console. - // - + /// + /// Dumps an error message on the debug console. + /// internal void LSShoutError(string message) { if (message.Length > 1023) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs index 8f34833..981499e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs @@ -30,6 +30,7 @@ using System.Reflection; using System.Collections; using System.Collections.Generic; using System.Runtime.Remoting.Lifetime; +using System.Threading; using OpenMetaverse; using Nini.Config; using OpenSim; @@ -61,9 +62,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api internal bool m_MODFunctionsEnabled = false; internal IScriptModuleComms m_comms = null; - public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) + public void Initialize( + IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle) { - m_ScriptEngine = ScriptEngine; + m_ScriptEngine = scriptEngine; m_host = host; m_item = item; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 4a46398..49857cf 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -143,9 +143,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected IUrlModule m_UrlModule = null; - public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) + public void Initialize( + IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle) { - m_ScriptEngine = ScriptEngine; + m_ScriptEngine = scriptEngine; m_host = host; m_item = item; m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false); diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs index 22804f5..e44a106 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs @@ -82,6 +82,24 @@ namespace OpenSim.Region.ScriptEngine.Shared } } + /// + /// Used to signal when the script is stopping in co-operation with the script engine + /// (instead of through Thread.Abort()). + /// + [Serializable] + public class ScriptCoopStopException : Exception + { + public ScriptCoopStopException() + { + } + + protected ScriptCoopStopException( + SerializationInfo info, + StreamingContext context) + { + } + } + public class DetectParams { public const int AGENT = 1; diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index ff4d130..a869a6a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -158,6 +158,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance public UUID AppDomain { get; set; } + public SceneObjectPart Part { get; private set; } + public string PrimName { get; private set; } public string ScriptName { get; private set; } @@ -199,54 +201,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance public static readonly long MaxMeasurementPeriod = 30 * TimeSpan.TicksPerMinute; + private bool m_coopTermination; + + private EventWaitHandle m_coopSleepHandle; + public void ClearQueue() { m_TimerQueued = false; EventQueue.Clear(); } - public ScriptInstance(IScriptEngine engine, SceneObjectPart part, - UUID itemID, UUID assetID, string assembly, - AppDomain dom, string primName, string scriptName, - int startParam, bool postOnRez, StateSource stateSource, - int maxScriptQueue) + public ScriptInstance( + IScriptEngine engine, SceneObjectPart part, TaskInventoryItem item, + int startParam, bool postOnRez, + int maxScriptQueue) { State = "default"; EventQueue = new Queue(32); Engine = engine; - LocalID = part.LocalId; - ObjectID = part.UUID; - RootLocalID = part.ParentGroup.LocalId; - RootObjectID = part.ParentGroup.UUID; - ItemID = itemID; - AssetID = assetID; - PrimName = primName; - ScriptName = scriptName; - m_Assembly = assembly; + Part = part; + ScriptTask = item; + + // This is currently only here to allow regression tests to get away without specifying any inventory + // item when they are testing script logic that doesn't require an item. + if (ScriptTask != null) + { + ScriptName = ScriptTask.Name; + ItemID = ScriptTask.ItemID; + AssetID = ScriptTask.AssetID; + } + + PrimName = part.ParentGroup.Name; StartParam = startParam; m_MaxScriptQueue = maxScriptQueue; - m_stateSource = stateSource; m_postOnRez = postOnRez; m_AttachedAvatar = part.ParentGroup.AttachedAvatar; m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID; - if (part != null) + if (Engine.Config.GetString("ScriptStopStrategy", "abort") == "co-op") { - part.TaskInventory.LockItemsForRead(true); - if (part.TaskInventory.ContainsKey(ItemID)) - { - ScriptTask = part.TaskInventory[ItemID]; - } - part.TaskInventory.LockItemsForRead(false); + m_coopTermination = true; + m_coopSleepHandle = new AutoResetEvent(false); } + } + + /// + /// Load the script from an assembly into an AppDomain. + /// + /// + /// + /// + public void Load(AppDomain dom, string assembly, StateSource stateSource) + { + m_Assembly = assembly; + m_stateSource = stateSource; ApiManager am = new ApiManager(); foreach (string api in am.GetApis()) { m_Apis[api] = am.CreateApi(api); - m_Apis[api].Initialize(engine, part, ScriptTask); + m_Apis[api].Initialize(Engine, Part, ScriptTask, m_coopSleepHandle); } try @@ -280,7 +296,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance // // m_log.Debug("[Script] Script instance created"); - part.SetScriptEvents(ItemID, + Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); } catch (Exception e) @@ -322,7 +338,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance // m_log.DebugFormat("[Script] Successfully retrieved state for script {0}.{1}", PrimName, m_ScriptName); - part.SetScriptEvents(ItemID, + Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); if (!Running) @@ -534,9 +550,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance } // Wait for the current event to complete. - if (!m_InSelfDelete && workItem.Wait(new TimeSpan((long)timeout * 100000))) + if (!m_InSelfDelete) { - return true; + if (!m_coopTermination) + { + // If we're not co-operative terminating then try and wait for the event to complete before stopping + if (workItem.Wait(new TimeSpan((long)timeout * 100000))) + return true; + } + else + { + m_log.DebugFormat( + "[SCRIPT INSTANCE]: Co-operatively stopping script {0} {1} in {2} {3}", + ScriptName, ItemID, PrimName, ObjectID); + + // This will terminate the event on next handle check by the script. + m_coopSleepHandle.Set(); + + // For now, we will wait forever since the event should always cleanly terminate once LSL loop + // checking is implemented. May want to allow a shorter timeout option later. + if (workItem.Wait(TimeSpan.MaxValue)) + { + m_log.DebugFormat( + "[SCRIPT INSTANCE]: Co-operatively stopped script {0} {1} in {2} {3}", + ScriptName, ItemID, PrimName, ObjectID); + + return true; + } + } } lock (EventQueue) @@ -549,6 +590,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance // If the event still hasn't stopped and we the stop isn't the result of script or object removal, then // forcibly abort the work item (this aborts the underlying thread). + // Co-operative termination should never reach this point. if (!m_InSelfDelete) { m_log.DebugFormat( @@ -796,7 +838,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance m_InEvent = false; m_CurrentEvent = String.Empty; - if ((!(e is TargetInvocationException) || (!(e.InnerException is SelfDeleteException) && !(e.InnerException is ScriptDeleteException))) && !(e is ThreadAbortException)) + if ((!(e is TargetInvocationException) + || (!(e.InnerException is SelfDeleteException) + && !(e.InnerException is ScriptDeleteException) + && !(e.InnerException is ScriptCoopStopException))) + && !(e is ThreadAbortException)) { try { @@ -846,6 +892,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance if (part != null) part.Inventory.RemoveInventoryItem(ItemID); } + else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException)) + { + m_log.DebugFormat( + "[SCRIPT INSTANCE]: Script {0}.{1} in event {2}, state {3} stopped co-operatively.", + PrimName, ScriptName, data.EventName, State); + } } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs index cb7291a..6dd6c17 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs @@ -41,6 +41,7 @@ using OpenSim.Region.OptionalModules.World.NPC; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Region.ScriptEngine.Shared.Instance; using OpenSim.Services.Interfaces; using OpenSim.Tests.Common; using OpenSim.Tests.Common.Mock; @@ -93,7 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests TaskInventoryHelpers.AddSceneObject(m_scene, so1.RootPart, inventoryItemName, itemId, userId); LSL_Api api = new LSL_Api(); - api.Initialize(m_engine, so1.RootPart, null); + api.Initialize(m_engine, so1.RootPart, null, null); // Create a second object SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, userId, "so2", 0x100); @@ -126,7 +127,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(1, user1Id, "so1", 0x10); m_scene.AddSceneObject(so1); LSL_Api api = new LSL_Api(); - api.Initialize(m_engine, so1.RootPart, null); + api.Initialize(m_engine, so1.RootPart, null, null); // Create an object embedded inside the first UUID itemId = TestHelpers.ParseTail(0x20); @@ -136,7 +137,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, user2Id, "so2", 0x100); m_scene.AddSceneObject(so2); LSL_Api api2 = new LSL_Api(); - api2.Initialize(m_engine, so2.RootPart, null); + api2.Initialize(m_engine, so2.RootPart, null, null); // *** Firstly, we test where llAllowInventoryDrop() has not been called. *** api.llGiveInventory(so2.UUID.ToString(), inventoryItemName); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs index d9b17d7..5b57bbe 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs @@ -41,6 +41,7 @@ using OpenSim.Region.OptionalModules.World.NPC; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Region.ScriptEngine.Shared.Instance; using OpenSim.Region.ScriptEngine.Shared.ScriptBase; using OpenSim.Services.Interfaces; using OpenSim.Tests.Common; @@ -104,7 +105,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(grp2); LSL_Api apiGrp1 = new LSL_Api(); - apiGrp1.Initialize(m_engine, grp1.RootPart, grp1Item); + apiGrp1.Initialize(m_engine, grp1.RootPart, grp1Item, null); apiGrp1.llCreateLink(grp2.UUID.ToString(), ScriptBaseClass.TRUE); @@ -131,7 +132,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests grp1Item.PermsMask |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; LSL_Api apiGrp1 = new LSL_Api(); - apiGrp1.Initialize(m_engine, grp1.RootPart, grp1Item); + apiGrp1.Initialize(m_engine, grp1.RootPart, grp1Item, null); apiGrp1.llBreakLink(2); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs index 98017d8..60de5cb 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs @@ -34,6 +34,7 @@ using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.Framework.Scenes; using Nini.Config; using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Region.ScriptEngine.Shared.Instance; using OpenSim.Region.ScriptEngine.Shared.ScriptBase; using OpenMetaverse; using OpenSim.Tests.Common.Mock; @@ -67,7 +68,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests engine.AddRegion(scene); m_lslApi = new LSL_Api(); - m_lslApi.Initialize(engine, part, null); + m_lslApi.Initialize(engine, part, null, null); } [Test] diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs index c41d1e7..e97ae06 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs @@ -33,6 +33,7 @@ using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.Framework.Scenes; using Nini.Config; using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Region.ScriptEngine.Shared.Instance; using OpenSim.Region.ScriptEngine.Shared.ScriptBase; using OpenMetaverse; using System; @@ -66,7 +67,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests engine.AddRegion(scene); m_lslApi = new LSL_Api(); - m_lslApi.Initialize(engine, part, null); + m_lslApi.Initialize(engine, part, null, null); } [Test] diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs index 1381d2b..c88bad5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs @@ -41,6 +41,7 @@ using OpenSim.Region.OptionalModules.World.NPC; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Region.ScriptEngine.Shared.Instance; using OpenSim.Services.Interfaces; using OpenSim.Tests.Common; using OpenSim.Tests.Common.Mock; @@ -93,7 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, null); + osslApi.Initialize(m_engine, part, null, null); string notecardName = "appearanceNc"; @@ -134,7 +135,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, null); + osslApi.Initialize(m_engine, part, null, null); string notecardName = "appearanceNc"; diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs index 5ed1f3d..b2803a1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs @@ -41,6 +41,7 @@ using OpenSim.Region.CoreModules.Framework.InventoryAccess; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Region.ScriptEngine.Shared.Instance; using OpenSim.Services.Interfaces; using OpenSim.Tests.Common; using OpenSim.Tests.Common.Mock; @@ -98,9 +99,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID); TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart); - new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem); + new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem, null); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem); + osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem, null); // SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ua1.PrincipalID); @@ -144,9 +145,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID); TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart); - new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem); + new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem, null); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem); + osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem, null); // Create an object embedded inside the first TaskInventoryHelpers.AddNotecard( @@ -192,12 +193,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID); TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart); - new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem); + new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem, null); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem); + osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem, null); // Create an object embedded inside the first - TaskInventoryHelpers.AddSceneObject(m_scene, inWorldObj.RootPart, taskInvObjItemName, taskInvObjItemId, ua1.PrincipalID); + TaskInventoryHelpers.AddSceneObject( + m_scene, inWorldObj.RootPart, taskInvObjItemName, taskInvObjItemId, ua1.PrincipalID); ScenePresence sp2 = SceneHelpers.AddScenePresence(m_scene, ua2); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs index d6c82f1..1f8a6e5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs @@ -42,6 +42,7 @@ using OpenSim.Region.OptionalModules.World.NPC; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Region.ScriptEngine.Shared.Instance; using OpenSim.Region.ScriptEngine.Shared.ScriptBase; using OpenSim.Services.Interfaces; using OpenSim.Tests.Common; @@ -99,7 +100,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, null); + osslApi.Initialize(m_engine, part, null, null); string notecardName = "appearanceNc"; osslApi.osOwnerSaveAppearance(notecardName); @@ -125,7 +126,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, so.RootPart, null); + osslApi.Initialize(m_engine, so.RootPart, null, null); bool gotExpectedException = false; try @@ -160,7 +161,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, null); + osslApi.Initialize(m_engine, part, null, null); string notecardName = "appearanceNc"; osslApi.osOwnerSaveAppearance(notecardName); @@ -194,7 +195,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, null); + osslApi.Initialize(m_engine, part, null, null); osslApi.osOwnerSaveAppearance(firstAppearanceNcName); @@ -232,7 +233,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, null); + osslApi.Initialize(m_engine, part, null, null); osslApi.osOwnerSaveAppearance(firstAppearanceNcName); @@ -284,10 +285,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(otherSo); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, null); + osslApi.Initialize(m_engine, part, null, null); OSSL_Api otherOsslApi = new OSSL_Api(); - otherOsslApi.Initialize(m_engine, otherPart, null); + otherOsslApi.Initialize(m_engine, otherPart, null, null); string notecardName = "appearanceNc"; osslApi.osOwnerSaveAppearance(notecardName); @@ -331,7 +332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_scene.AddSceneObject(so); OSSL_Api osslApi = new OSSL_Api(); - osslApi.Initialize(m_engine, part, null); + osslApi.Initialize(m_engine, part, null, null); string notecardName = "appearanceNc"; osslApi.osOwnerSaveAppearance(notecardName); diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 34fcf0c..2065a46 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1356,12 +1356,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_DomainScripts[appDomain].Add(itemID); instance = new ScriptInstance(this, part, - itemID, assetID, assembly, - m_AppDomains[appDomain], - part.ParentGroup.RootPart.Name, - item.Name, startParam, postOnRez, - stateSource, m_MaxScriptQueue); + item, + startParam, postOnRez, + m_MaxScriptQueue); + instance.Load(m_AppDomains[appDomain], assembly, stateSource); // m_log.DebugFormat( // "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", // part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, @@ -1808,9 +1807,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine IScriptInstance instance = GetInstance(itemID); if (instance != null) + { instance.Stop(m_WaitForEventCompletionOnScriptStop); + } else + { +// m_log.DebugFormat("[XENGINE]: Could not find script with ID {0} to stop in {1}", itemID, World.Name); m_runFlags.AddOrUpdate(itemID, false, 240); + } } public DetectParams GetDetectParams(UUID itemID, int idx) -- cgit v1.1 From 37fcf87946df0cc6824063aa42853048ca4238c9 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 16 Jan 2013 08:20:32 -0800 Subject: Changed a couple of debug messages at the request of osgrid. --- .../CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 41ca13b..b188741 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -212,11 +212,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected override GridRegion GetFinalDestination(GridRegion region) { int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, region.RegionID); - m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionID, flags); + m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionName, flags); if ((flags & (int)OpenSim.Framework.RegionFlags.Hyperlink) != 0) { - m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Destination region {0} is hyperlink", region.RegionID); + m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Destination region is hyperlink"); GridRegion real_destination = m_GatekeeperConnector.GetHyperlinkRegion(region, region.RegionID); if (real_destination != null) m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: GetFinalDestination serveruri -> {0}", real_destination.ServerURI); -- cgit v1.1 From 5563a8916ed5c78f91dccb668453f5782ab19532 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 16 Jan 2013 16:45:18 +0000 Subject: Complete removal of the now unused state queue --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 2 +- OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs | 17 +++-------------- 2 files changed, 4 insertions(+), 15 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index a8517e6..77acacf 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -1588,7 +1588,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (localIDs.Count == 1 && m_scene.GetScenePresence(localIDs[0]) != null) { - OutPacket(kill, ThrottleOutPacketType.State); + OutPacket(kill, ThrottleOutPacketType.Task); } else { diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs index 8963756..621e0fd 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs @@ -278,7 +278,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP public string GetStats() { return string.Format( - "{0,7} {1,7} {2,7} {3,9} {4,7} {5,7} {6,7} {7,7} {8,7} {9,8} {10,7} {11,7} {12,7}", + "{0,7} {1,7} {2,7} {3,9} {4,7} {5,7} {6,7} {7,7} {8,7} {9,8} {10,7} {11,7}", Util.EnvironmentTickCountSubtract(TickLastPacketReceived), PacketsReceived, PacketsSent, @@ -290,8 +290,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_packetOutboxes[(int)ThrottleOutPacketType.Cloud].Count, m_packetOutboxes[(int)ThrottleOutPacketType.Task].Count, m_packetOutboxes[(int)ThrottleOutPacketType.Texture].Count, - m_packetOutboxes[(int)ThrottleOutPacketType.Asset].Count, - m_packetOutboxes[(int)ThrottleOutPacketType.State].Count); + m_packetOutboxes[(int)ThrottleOutPacketType.Asset].Count); } public void SendPacketStats() @@ -337,8 +336,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP int task = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); - // State is a subcategory of task that we allocate a percentage to - int state = 0; // Make sure none of the throttles are set below our packet MTU, // otherwise a throttle could become permanently clogged @@ -375,9 +372,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP bucket = m_throttleCategories[(int)ThrottleOutPacketType.Task]; bucket.RequestedDripRate = task; - bucket = m_throttleCategories[(int)ThrottleOutPacketType.State]; - bucket.RequestedDripRate = state; - bucket = m_throttleCategories[(int)ThrottleOutPacketType.Texture]; bucket.RequestedDripRate = texture; @@ -678,9 +672,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP Texture = 5, /// Non-texture assets Asset = 6, - /// Avatar and primitive data - /// This is a sub-category of Task - State = 7, */ switch (category) @@ -697,11 +688,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP return ThrottleOutPacketTypeFlags.Texture; case ThrottleOutPacketType.Asset: return ThrottleOutPacketTypeFlags.Asset; - case ThrottleOutPacketType.State: - return ThrottleOutPacketTypeFlags.State; default: return 0; } } } -} \ No newline at end of file +} -- cgit v1.1 From 75f710f1e70a3c9d3459d549eb4334a445aca834 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 17 Jan 2013 14:47:35 -0800 Subject: BulletSim: Add one function that all actors who act on the physical can use to know if the object is currently active. Code cleaning including use of Util.ClampV function. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 3 ++ OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 3 +- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 10 +++++-- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 33 +++++++++------------- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 6 +++- 5 files changed, 31 insertions(+), 24 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 87a06c1..6d5e23f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -652,6 +652,9 @@ public sealed class BSCharacter : BSPhysObject public override bool IsStatic { get { return false; } } + public override bool IsPhysicallyActive { + get { return true; } + } public override bool Flying { get { return _flying; } set { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 6601479..f2c7cec 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -35,6 +35,7 @@ using System.Collections.Generic; using System.Reflection; using System.Runtime.InteropServices; using OpenMetaverse; +using OpenSim.Framework; using OpenSim.Region.Physics.Manager; namespace OpenSim.Region.Physics.BulletSPlugin @@ -154,7 +155,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Return 'true' if this vehicle is doing vehicle things public bool IsActive { - get { return (Type != Vehicle.TYPE_NONE && !Prim.IsStatic); } + get { return (Type != Vehicle.TYPE_NONE && Prim.IsPhysicallyActive); } } #region Vehicle parameter setting diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 821f470..bac0427 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -139,6 +139,11 @@ public abstract class BSPhysObject : PhysicsActor public abstract bool IsStatic { get; } public abstract bool IsSelected { get; } + // It can be confusing for an actor to know if it should move or update an object + // depeneding on the setting of 'selected', 'physical, ... + // This flag is the true test -- if true, the object is being acted on in the physical world + public abstract bool IsPhysicallyActive { get; } + // Materialness public MaterialAttributes.Material Material { get; private set; } public override void SetMaterial(int material) @@ -302,8 +307,9 @@ public abstract class BSPhysObject : PhysicsActor public virtual bool SendCollisions() { bool ret = true; + // If the 'no collision' call, force it to happen right now so quick collision_end - bool force = (CollisionCollection.Count == 0); + bool force = (CollisionCollection.Count == 0 && CollisionsLastTick.Count != 0); // throttle the collisions to the number of milliseconds specified in the subscription if (force || (PhysicsScene.SimulationNowTime >= NextCollisionOkTime)) @@ -318,7 +324,7 @@ public abstract class BSPhysObject : PhysicsActor ret = false; } - // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count); + DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count); base.SendCollisionUpdate(CollisionCollection); // Remember the collisions from this tick for some collision specific processing. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 79fe632..7aa2d92 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -132,8 +132,8 @@ public sealed class BSPrim : BSPhysObject base.Destroy(); // Undo any links between me and any other object - BSPhysObject parentBefore = Linkset.LinksetRoot; - int childrenBefore = Linkset.NumberOfChildren; + BSPhysObject parentBefore = Linkset.LinksetRoot; // DEBUG DEBUG + int childrenBefore = Linkset.NumberOfChildren; // DEBUG DEBUG Linkset = Linkset.RemoveMeFromLinkset(this); @@ -727,6 +727,12 @@ public sealed class BSPrim : BSPhysObject get { return !IsPhantom && !_isVolumeDetect; } } + // The object is moving and is actively being dynamic in the physical world + public override bool IsPhysicallyActive + { + get { return !_isSelected && IsPhysical; } + } + // Make gravity work if the object is physical and not selected // Called at taint-time!! private void SetObjectDynamic(bool forceRebuild) @@ -1174,18 +1180,11 @@ public sealed class BSPrim : BSPhysObject // This added force will only last the next simulation tick. public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { // for an object, doesn't matter if force is a pushforce or not - if (!IsStatic) + if (IsPhysicallyActive) { if (force.IsFinite()) { - float magnitude = force.Length(); - if (magnitude > BSParam.MaxAddForceMagnitude) - { - // Force has a limit - force = force / magnitude * BSParam.MaxAddForceMagnitude; - } - - OMV.Vector3 addForce = force; + OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude); // DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() @@ -1209,19 +1208,13 @@ public sealed class BSPrim : BSPhysObject public void AddForceImpulse(OMV.Vector3 impulse, bool pushforce, bool inTaintTime) { // for an object, doesn't matter if force is a pushforce or not - if (!IsStatic) + if (!IsPhysicallyActive) { if (impulse.IsFinite()) { - float magnitude = impulse.Length(); - if (magnitude > BSParam.MaxAddForceMagnitude) - { - // Force has a limit - impulse = impulse / magnitude * BSParam.MaxAddForceMagnitude; - } - + OMV.Vector3 addImpulse = Util.ClampV(impulse, BSParam.MaxAddForceMagnitude); // DetailLog("{0},BSPrim.addForceImpulse,call,impulse={1}", LocalID, impulse); - OMV.Vector3 addImpulse = impulse; + PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddImpulse", delegate() { // Bullet adds this impulse immediately to the velocity diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index d4545f7..9bfec19 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -16,6 +16,7 @@ vehicle angular banking Avatars walking up stairs (HALF DONE) Radius of the capsule affects ability to climb edges. Vehicle movement on terrain smoothness +When is force introduced by SetForce removed? The prestep action could go forever. Boats float low in the water (DONE) Avatar movement flying into a wall doesn't stop avatar who keeps appearing to move through the obstacle (DONE) @@ -72,8 +73,11 @@ Incorporate inter-relationship of angular corrections. For instance, angularDefl GENERAL TODO LIST: ================================================= +Implement llSetPhysicalMaterial. +Implement llSetForceAndTorque. Implement an avatar mesh shape. The Bullet capsule is way too limited. Consider just hand creating a vertex/index array in a new BSShapeAvatar. +Verify/fix phantom, volume-detect objects do not fall to infinity. Should stop at terrain. Revisit CollisionMargin. Builders notice the 0.04 spacing between prims. Duplicating a physical prim causes old prim to jump away Dup a phys prim and the original become unselected and thus interacts w/ selected prim. @@ -121,7 +125,7 @@ Physical and phantom will drop through the terrain LINKSETS ====================================================== Editing a child of a linkset causes the child to go phantom - Move a child prim once when it is physical and can never move it again without it going phantom + Move a child prim once when it is physical and can never move it again without it going phantom Offset the center of the linkset to be the geometric center of all the prims Not quite the same as the center-of-gravity Linksets should allow collisions to individual children -- cgit v1.1 From c8afc8523b9caf931afb3d5b3f9874b26b866a77 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 17 Jan 2013 23:39:09 +0000 Subject: Implement non-wait co-operative termination of scripts for XEngine in addition to termination on wait. This involves inserting opensim_reserved_CheckForCoopTermination() calls in lsl -> c# translation at any place where the script could be in a loop with no wait calls. These places are for, while, do-while, label, user function call and manual event function call. Call goes through to an XEngineScriptBase which extends ScriptBase. IEngine is extended to supply necessary engine-specific parent class references and constructor parameters to Compiler. Unfortunately, since XEngineScriptBase has to be passed WaitHandle in its constructor, older compiled scripts will fail to load with an error on the OpenSim console. Such scripts will need to be recompiled, either by removing all *.dll files from the bin/ScriptEngines/ or by setting DeleteScriptsOnStartup = true in [XEngine] for one run. Automatic recompilation may be implemented in a later commit. This feature should not yet be used, default remains termination with Thread.Abort() which will work as normal once scripts are recompiled. --- .../ScriptEngine/Interfaces/IScriptEngine.cs | 35 +++++- .../Shared/Api/Implementation/LSL_Api.cs | 12 +- .../Shared/CodeTools/CSCodeGenerator.cs | 133 ++++++++++++++------- .../ScriptEngine/Shared/CodeTools/Compiler.cs | 66 ++++++---- .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 24 +++- .../XEngine/Api/Runtime/XEngineScriptBase.cs | 61 ++++++++++ OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 17 ++- 7 files changed, 271 insertions(+), 77 deletions(-) create mode 100644 OpenSim/Region/ScriptEngine/XEngine/Api/Runtime/XEngineScriptBase.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs index 17c2708..20dcac9 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs @@ -25,16 +25,17 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -using log4net; using System; -using OpenSim.Region.ScriptEngine.Shared; +using System.Reflection; +using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Interfaces; -using OpenMetaverse; -using Nini.Config; using OpenSim.Region.ScriptEngine.Interfaces; +using OpenSim.Region.ScriptEngine.Shared; using Amib.Threading; -using OpenSim.Framework; +using log4net; +using Nini.Config; +using OpenMetaverse; namespace OpenSim.Region.ScriptEngine.Interfaces { @@ -76,6 +77,30 @@ namespace OpenSim.Region.ScriptEngine.Interfaces IConfigSource ConfigSource { get; } string ScriptEngineName { get; } string ScriptEnginePath { get; } + + /// + /// Return the name of the base class that will be used for all running scripts. + /// + string ScriptBaseClassName { get; } + + /// + /// Assemblies that need to be referenced when compiling scripts. + /// + /// + /// These are currently additional to those always referenced by the compiler, BUT THIS MAY CHANGE IN THE + /// FUTURE. + /// This can be null if there are no additional assemblies. + /// + string[] ScriptReferencedAssemblies { get; } + + /// + /// Parameters for the generated script's constructor. + /// + /// + /// Can be null if there are no parameters + /// + ParameterInfo[] ScriptBaseClassParameters { get; } + IScriptApi GetApi(UUID itemID, string name); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index d47fd6b..cee10a8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -192,7 +192,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { if (m_coopSleepHandle == null) System.Threading.Thread.Sleep(delay); - else if (m_coopSleepHandle.WaitOne(delay)) + else + CheckForCoopTermination(delay); + } + + /// + /// Check for co-operative termination. + /// + /// If called with 0, then just the check is performed with no wait. + protected virtual void CheckForCoopTermination(int delay) + { + if (m_coopSleepHandle.WaitOne(delay)) throw new ScriptCoopStopException(); } diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs index 97dd0f6..002f9b8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs @@ -49,6 +49,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools private List m_warnings = new List(); private IScriptModuleComms m_comms = null; + private bool m_insertCoopTerminationChecks; + private static string m_coopTerminationCheck = "opensim_reserved_CheckForCoopTermination();"; + + /// + /// Keep a record of the previous node when we do the parsing. + /// + /// + /// We do this here because the parser generated by CSTools does not retain a reference to its parent node. + /// The previous node is required so we can correctly insert co-op termination checks when required. + /// +// private SYMBOL m_previousNode; + /// /// Creates an 'empty' CSCodeGenerator instance. /// @@ -58,9 +70,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools ResetCounters(); } - public CSCodeGenerator(IScriptModuleComms comms) + public CSCodeGenerator(IScriptModuleComms comms, bool insertCoopTerminationChecks) { m_comms = comms; + m_insertCoopTerminationChecks = insertCoopTerminationChecks; ResetCounters(); } @@ -155,7 +168,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools // here's the payload retstr += GenerateLine(); foreach (SYMBOL s in m_astRoot.kids) - retstr += GenerateNode(s); + retstr += GenerateNode(m_astRoot, s); // close braces! m_braceCount--; @@ -165,7 +178,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools // Removes all carriage return characters which may be generated in Windows platform. Is there // cleaner way of doing this? - retstr=retstr.Replace("\r", ""); + retstr = retstr.Replace("\r", ""); return retstr; } @@ -191,9 +204,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools /// Recursively called to generate each type of node. Will generate this /// node, then all it's children. /// + /// The parent node. /// The current node to generate code for. /// String containing C# code for SYMBOL s. - private string GenerateNode(SYMBOL s) + private string GenerateNode(SYMBOL previousSymbol, SYMBOL s) { string retstr = String.Empty; @@ -207,11 +221,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools else if (s is State) retstr += GenerateState((State) s); else if (s is CompoundStatement) - retstr += GenerateCompoundStatement((CompoundStatement) s); + retstr += GenerateCompoundStatement(previousSymbol, (CompoundStatement) s); else if (s is Declaration) retstr += GenerateDeclaration((Declaration) s); else if (s is Statement) - retstr += GenerateStatement((Statement) s); + retstr += GenerateStatement(previousSymbol, (Statement) s); else if (s is ReturnStatement) retstr += GenerateReturnStatement((ReturnStatement) s); else if (s is JumpLabel) @@ -261,7 +275,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools else { foreach (SYMBOL kid in s.kids) - retstr += GenerateNode(kid); + retstr += GenerateNode(s, kid); } return retstr; @@ -295,7 +309,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools retstr += GenerateLine(")"); foreach (SYMBOL kid in remainingKids) - retstr += GenerateNode(kid); + retstr += GenerateNode(gf, kid); return retstr; } @@ -312,7 +326,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools foreach (SYMBOL s in gv.kids) { retstr += Indent(); - retstr += GenerateNode(s); + retstr += GenerateNode(gv, s); retstr += GenerateLine(";"); } @@ -365,7 +379,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools retstr += GenerateLine(")"); foreach (SYMBOL kid in remainingKids) - retstr += GenerateNode(kid); + retstr += GenerateNode(se, kid); return retstr; } @@ -404,7 +418,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools foreach (SYMBOL s in al.kids) { - retstr += GenerateNode(s); + retstr += GenerateNode(al, s); if (0 < comma--) retstr += Generate(", "); } @@ -417,7 +431,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools /// /// The CompoundStatement node. /// String containing C# code for CompoundStatement cs. - private string GenerateCompoundStatement(CompoundStatement cs) + private string GenerateCompoundStatement(SYMBOL previousSymbol, CompoundStatement cs) { string retstr = String.Empty; @@ -425,8 +439,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools retstr += GenerateIndentedLine("{"); m_braceCount++; + if (m_insertCoopTerminationChecks) + { + // We have to check in event functions as well because the user can manually call these. + if (previousSymbol is GlobalFunctionDefinition + || previousSymbol is WhileStatement + || previousSymbol is DoWhileStatement + || previousSymbol is ForLoopStatement + || previousSymbol is StateEvent) + retstr += GenerateIndentedLine(m_coopTerminationCheck); + } + foreach (SYMBOL kid in cs.kids) - retstr += GenerateNode(kid); + retstr += GenerateNode(cs, kid); // closing brace m_braceCount--; @@ -450,13 +475,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools /// /// The Statement node. /// String containing C# code for Statement s. - private string GenerateStatement(Statement s) + private string GenerateStatement(SYMBOL previousSymbol, Statement s) { string retstr = String.Empty; bool printSemicolon = true; retstr += Indent(); + if (m_insertCoopTerminationChecks) + { + // We have to check in event functions as well because the user can manually call these. + if (previousSymbol is GlobalFunctionDefinition + || previousSymbol is WhileStatement + || previousSymbol is DoWhileStatement + || previousSymbol is ForLoop + || previousSymbol is StateEvent) + retstr += Generate(m_coopTerminationCheck); + } + if (0 < s.kids.Count) { // Jump label prints its own colon, we don't need a semicolon. @@ -466,7 +502,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools // (MONO) error. if (!(s.kids.Top is IdentExpression && 1 == s.kids.Count)) foreach (SYMBOL kid in s.kids) - retstr += GenerateNode(kid); + retstr += GenerateNode(s, kid); } if (printSemicolon) @@ -487,10 +523,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools List identifiers = new List(); checkForMultipleAssignments(identifiers, a); - retstr += GenerateNode((SYMBOL) a.kids.Pop()); + retstr += GenerateNode(a, (SYMBOL) a.kids.Pop()); retstr += Generate(String.Format(" {0} ", a.AssignmentType), a); foreach (SYMBOL kid in a.kids) - retstr += GenerateNode(kid); + retstr += GenerateNode(a, kid); return retstr; } @@ -563,7 +599,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools retstr += Generate("return ", rs); foreach (SYMBOL kid in rs.kids) - retstr += GenerateNode(kid); + retstr += GenerateNode(rs, kid); return retstr; } @@ -575,7 +611,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools /// String containing C# code for JumpLabel jl. private string GenerateJumpLabel(JumpLabel jl) { - return Generate(String.Format("{0}:", CheckName(jl.LabelName)), jl) + " NoOp();\n"; + string labelStatement; + + if (m_insertCoopTerminationChecks) + labelStatement = m_coopTerminationCheck + "\n"; + else + labelStatement = "NoOp();\n"; + + return Generate(String.Format("{0}: ", CheckName(jl.LabelName)), jl) + labelStatement; } /// @@ -598,14 +641,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools string retstr = String.Empty; retstr += GenerateIndented("if (", ifs); - retstr += GenerateNode((SYMBOL) ifs.kids.Pop()); + retstr += GenerateNode(ifs, (SYMBOL) ifs.kids.Pop()); retstr += GenerateLine(")"); // CompoundStatement handles indentation itself but we need to do it // otherwise. bool indentHere = ifs.kids.Top is Statement; if (indentHere) m_braceCount++; - retstr += GenerateNode((SYMBOL) ifs.kids.Pop()); + retstr += GenerateNode(ifs, (SYMBOL) ifs.kids.Pop()); if (indentHere) m_braceCount--; if (0 < ifs.kids.Count) // do it again for an else @@ -614,7 +657,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools indentHere = ifs.kids.Top is Statement; if (indentHere) m_braceCount++; - retstr += GenerateNode((SYMBOL) ifs.kids.Pop()); + retstr += GenerateNode(ifs, (SYMBOL) ifs.kids.Pop()); if (indentHere) m_braceCount--; } @@ -641,14 +684,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools string retstr = String.Empty; retstr += GenerateIndented("while (", ws); - retstr += GenerateNode((SYMBOL) ws.kids.Pop()); + retstr += GenerateNode(ws, (SYMBOL) ws.kids.Pop()); retstr += GenerateLine(")"); // CompoundStatement handles indentation itself but we need to do it // otherwise. bool indentHere = ws.kids.Top is Statement; if (indentHere) m_braceCount++; - retstr += GenerateNode((SYMBOL) ws.kids.Pop()); + retstr += GenerateNode(ws, (SYMBOL) ws.kids.Pop()); if (indentHere) m_braceCount--; return retstr; @@ -669,11 +712,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools // otherwise. bool indentHere = dws.kids.Top is Statement; if (indentHere) m_braceCount++; - retstr += GenerateNode((SYMBOL) dws.kids.Pop()); + retstr += GenerateNode(dws, (SYMBOL) dws.kids.Pop()); if (indentHere) m_braceCount--; retstr += GenerateIndented("while (", dws); - retstr += GenerateNode((SYMBOL) dws.kids.Pop()); + retstr += GenerateNode(dws, (SYMBOL) dws.kids.Pop()); retstr += GenerateLine(");"); return retstr; @@ -702,7 +745,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools retstr += Generate("; "); // for (x = 0; x < 10; x++) // ^^^^^^ - retstr += GenerateNode((SYMBOL) fl.kids.Pop()); + retstr += GenerateNode(fl, (SYMBOL) fl.kids.Pop()); retstr += Generate("; "); // for (x = 0; x < 10; x++) // ^^^ @@ -713,7 +756,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools // otherwise. bool indentHere = fl.kids.Top is Statement; if (indentHere) m_braceCount++; - retstr += GenerateNode((SYMBOL) fl.kids.Pop()); + retstr += GenerateNode(fl, (SYMBOL) fl.kids.Pop()); if (indentHere) m_braceCount--; return retstr; @@ -758,7 +801,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools while (s is ParenthesisExpression) s = (SYMBOL)s.kids.Pop(); - retstr += GenerateNode(s); + retstr += GenerateNode(fls, s); if (0 < comma--) retstr += Generate(", "); } @@ -779,20 +822,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools { // special case handling for logical and/or, see Mantis 3174 retstr += "((bool)("; - retstr += GenerateNode((SYMBOL)be.kids.Pop()); + retstr += GenerateNode(be, (SYMBOL)be.kids.Pop()); retstr += "))"; retstr += Generate(String.Format(" {0} ", be.ExpressionSymbol.Substring(0,1)), be); retstr += "((bool)("; foreach (SYMBOL kid in be.kids) - retstr += GenerateNode(kid); + retstr += GenerateNode(be, kid); retstr += "))"; } else { - retstr += GenerateNode((SYMBOL)be.kids.Pop()); + retstr += GenerateNode(be, (SYMBOL)be.kids.Pop()); retstr += Generate(String.Format(" {0} ", be.ExpressionSymbol), be); foreach (SYMBOL kid in be.kids) - retstr += GenerateNode(kid); + retstr += GenerateNode(be, kid); } return retstr; @@ -808,7 +851,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools string retstr = String.Empty; retstr += Generate(ue.UnarySymbol, ue); - retstr += GenerateNode((SYMBOL) ue.kids.Pop()); + retstr += GenerateNode(ue, (SYMBOL) ue.kids.Pop()); return retstr; } @@ -824,7 +867,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools retstr += Generate("("); foreach (SYMBOL kid in pe.kids) - retstr += GenerateNode(kid); + retstr += GenerateNode(pe, kid); retstr += Generate(")"); return retstr; @@ -861,7 +904,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools // we wrap all typecasted statements in parentheses retstr += Generate(String.Format("({0}) (", te.TypecastType), te); - retstr += GenerateNode((SYMBOL) te.kids.Pop()); + retstr += GenerateNode(te, (SYMBOL) te.kids.Pop()); retstr += Generate(")"); return retstr; @@ -931,7 +974,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools } foreach (SYMBOL kid in fc.kids) - retstr += GenerateNode(kid); + retstr += GenerateNode(fc, kid); retstr += Generate(")"); @@ -980,11 +1023,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools string retstr = String.Empty; retstr += Generate(String.Format("new {0}(", vc.Type), vc); - retstr += GenerateNode((SYMBOL) vc.kids.Pop()); + retstr += GenerateNode(vc, (SYMBOL) vc.kids.Pop()); retstr += Generate(", "); - retstr += GenerateNode((SYMBOL) vc.kids.Pop()); + retstr += GenerateNode(vc, (SYMBOL) vc.kids.Pop()); retstr += Generate(", "); - retstr += GenerateNode((SYMBOL) vc.kids.Pop()); + retstr += GenerateNode(vc, (SYMBOL) vc.kids.Pop()); retstr += Generate(")"); return retstr; @@ -1000,13 +1043,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools string retstr = String.Empty; retstr += Generate(String.Format("new {0}(", rc.Type), rc); - retstr += GenerateNode((SYMBOL) rc.kids.Pop()); + retstr += GenerateNode(rc, (SYMBOL) rc.kids.Pop()); retstr += Generate(", "); - retstr += GenerateNode((SYMBOL) rc.kids.Pop()); + retstr += GenerateNode(rc, (SYMBOL) rc.kids.Pop()); retstr += Generate(", "); - retstr += GenerateNode((SYMBOL) rc.kids.Pop()); + retstr += GenerateNode(rc, (SYMBOL) rc.kids.Pop()); retstr += Generate(", "); - retstr += GenerateNode((SYMBOL) rc.kids.Pop()); + retstr += GenerateNode(rc, (SYMBOL) rc.kids.Pop()); retstr += Generate(")"); return retstr; @@ -1024,7 +1067,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools retstr += Generate(String.Format("new {0}(", lc.Type), lc); foreach (SYMBOL kid in lc.kids) - retstr += GenerateNode(kid); + retstr += GenerateNode(lc, kid); retstr += Generate(")"); diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs index 03be2ab..7432202 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs @@ -31,6 +31,7 @@ using System.Collections.Generic; using System.Globalization; using System.Reflection; using System.IO; +using System.Linq; using System.Text; using Microsoft.CSharp; //using Microsoft.JScript; @@ -72,6 +73,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools private bool CompileWithDebugInformation; private Dictionary AllowedCompilers = new Dictionary(StringComparer.CurrentCultureIgnoreCase); private Dictionary LanguageMapping = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + private bool m_insertCoopTerminationCalls; private string FilePrefix; private string ScriptEnginesPath = null; @@ -95,20 +97,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools private Dictionary, KeyValuePair>> m_lineMaps = new Dictionary, KeyValuePair>>(); + public bool in_startup = true; + public Compiler(IScriptEngine scriptEngine) { - m_scriptEngine = scriptEngine;; + m_scriptEngine = scriptEngine; ScriptEnginesPath = scriptEngine.ScriptEnginePath; ReadConfig(); } - public bool in_startup = true; public void ReadConfig() { // Get some config WriteScriptSourceToDebugFile = m_scriptEngine.Config.GetBoolean("WriteScriptSourceToDebugFile", false); CompileWithDebugInformation = m_scriptEngine.Config.GetBoolean("CompileWithDebugInformation", true); bool DeleteScriptsOnStartup = m_scriptEngine.Config.GetBoolean("DeleteScriptsOnStartup", true); + m_insertCoopTerminationCalls = m_scriptEngine.Config.GetString("ScriptStopStrategy", "abort") == "co-op"; // Get file prefix from scriptengine name and make it file system safe: FilePrefix = "CommonCompiler"; @@ -386,7 +390,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools if (language == enumCompileType.lsl) { // Its LSL, convert it to C# - LSL_Converter = (ICodeConverter)new CSCodeGenerator(comms); + LSL_Converter = (ICodeConverter)new CSCodeGenerator(comms, m_insertCoopTerminationCalls); compileScript = LSL_Converter.Convert(Script); // copy converter warnings into our warnings. @@ -411,16 +415,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools { case enumCompileType.cs: case enumCompileType.lsl: - compileScript = CreateCSCompilerScript(compileScript); + compileScript = CreateCSCompilerScript( + compileScript, m_scriptEngine.ScriptBaseClassName, m_scriptEngine.ScriptBaseClassParameters); break; case enumCompileType.vb: - compileScript = CreateVBCompilerScript(compileScript); + compileScript = CreateVBCompilerScript(compileScript, m_scriptEngine.ScriptBaseClassName); break; // case enumCompileType.js: -// compileScript = CreateJSCompilerScript(compileScript); +// compileScript = CreateJSCompilerScript(compileScript, m_scriptEngine.ScriptBaseClassName); // break; case enumCompileType.yp: - compileScript = CreateYPCompilerScript(compileScript); + compileScript = CreateYPCompilerScript(compileScript, m_scriptEngine.ScriptBaseClassName); break; } @@ -451,43 +456,59 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools // return compileScript; // } - private static string CreateCSCompilerScript(string compileScript) + private static string CreateCSCompilerScript( + string compileScript, string baseClassName, ParameterInfo[] constructorParameters) { - compileScript = String.Empty + - "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\r\n" + - String.Empty + "namespace SecondLife { " + - String.Empty + "public class Script : OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass { \r\n" + - @"public Script() { } " + - compileScript + - "} }\r\n"; + compileScript = string.Format( +@"using OpenSim.Region.ScriptEngine.Shared; +using System.Collections.Generic; + +namespace SecondLife +{{ + public class Script : {0} + {{ + public Script({1}) : base({2}) {{}} +{3} + }} +}}", + baseClassName, + constructorParameters != null + ? string.Join(", ", Array.ConvertAll(constructorParameters, pi => pi.ToString())) + : "", + constructorParameters != null + ? string.Join(", ", Array.ConvertAll(constructorParameters, pi => pi.Name)) + : "", + compileScript); + return compileScript; } - private static string CreateYPCompilerScript(string compileScript) + private static string CreateYPCompilerScript(string compileScript, string baseClassName) { compileScript = String.Empty + "using OpenSim.Region.ScriptEngine.Shared.YieldProlog; " + "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\r\n" + String.Empty + "namespace SecondLife { " + - String.Empty + "public class Script : OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass { \r\n" + + String.Empty + "public class Script : " + baseClassName + " { \r\n" + //@"public Script() { } " + @"static OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP YP=null; " + @"public Script() { YP= new OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP(); } " + - compileScript + "} }\r\n"; + return compileScript; } - private static string CreateVBCompilerScript(string compileScript) + private static string CreateVBCompilerScript(string compileScript, string baseClassName) { compileScript = String.Empty + "Imports OpenSim.Region.ScriptEngine.Shared: Imports System.Collections.Generic: " + String.Empty + "NameSpace SecondLife:" + - String.Empty + "Public Class Script: Inherits OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass: " + + String.Empty + "Public Class Script: Inherits " + baseClassName + "\r\nPublic Sub New()\r\nEnd Sub: " + compileScript + ":End Class :End Namespace\r\n"; + return compileScript; } @@ -549,6 +570,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenMetaverseTypes.dll")); + if (m_scriptEngine.ScriptReferencedAssemblies != null) + Array.ForEach( + m_scriptEngine.ScriptReferencedAssemblies, + a => parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, a))); + if (lang == enumCompileType.yp) { parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 75aea2b..e6ec0e1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -267,13 +267,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance try { if (dom != System.AppDomain.CurrentDomain) - m_Script = (IScript)dom.CreateInstanceAndUnwrap( + m_Script + = (IScript)dom.CreateInstanceAndUnwrap( Path.GetFileNameWithoutExtension(assembly), - "SecondLife.Script"); + "SecondLife.Script", + false, + BindingFlags.Default, + null, + new object[] { m_coopSleepHandle }, + null, + null, + null); else - m_Script = (IScript)Assembly.Load( - Path.GetFileNameWithoutExtension(assembly)).CreateInstance( - "SecondLife.Script"); + m_Script + = (IScript)Assembly.Load(Path.GetFileNameWithoutExtension(assembly)).CreateInstance( + "SecondLife.Script", + false, + BindingFlags.Default, + null, + new object[] { m_coopSleepHandle }, + null, + null); //ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); diff --git a/OpenSim/Region/ScriptEngine/XEngine/Api/Runtime/XEngineScriptBase.cs b/OpenSim/Region/ScriptEngine/XEngine/Api/Runtime/XEngineScriptBase.cs new file mode 100644 index 0000000..f4211c8 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/XEngine/Api/Runtime/XEngineScriptBase.cs @@ -0,0 +1,61 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Runtime.Remoting; +using System.Runtime.Remoting.Lifetime; +using System.Security.Permissions; +using System.Threading; +using System.Reflection; +using System.Collections; +using System.Collections.Generic; +using OpenSim.Region.ScriptEngine.Interfaces; +using OpenSim.Region.ScriptEngine.Shared; +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; + +namespace OpenSim.Region.ScriptEngine.XEngine.ScriptBase +{ + public class XEngineScriptBase : ScriptBaseClass + { + /// + /// Used for script sleeps when we are using co-operative script termination. + /// + /// null if co-operative script termination is not active + WaitHandle m_coopSleepHandle; + + public XEngineScriptBase(WaitHandle coopSleepHandle) : base() + { + m_coopSleepHandle = coopSleepHandle; + } + + public void opensim_reserved_CheckForCoopTermination() + { + if (m_coopSleepHandle != null && m_coopSleepHandle.WaitOne(0)) + throw new ScriptCoopStopException(); + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index a17a018..8a02590 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -53,6 +53,7 @@ using OpenSim.Region.ScriptEngine.Shared.Instance; using OpenSim.Region.ScriptEngine.Shared.Api; using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; using OpenSim.Region.ScriptEngine.Interfaces; +using OpenSim.Region.ScriptEngine.XEngine.ScriptBase; using Timer = OpenSim.Region.ScriptEngine.Shared.Api.Plugins.Timer; using ScriptCompileQueue = OpenSim.Framework.LocklessQueue; @@ -176,6 +177,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine get { return "XEngine"; } } + public string ScriptBaseClassName { get; private set; } + + public ParameterInfo[] ScriptBaseClassParameters { get; private set; } + + public string[] ScriptReferencedAssemblies { get; private set; } + public Scene World { get { return m_Scene; } @@ -230,6 +237,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_ScriptConfig = configSource.Configs["XEngine"]; m_ConfigSource = configSource; + + ScriptBaseClassName = typeof(XEngineScriptBase).FullName; + ScriptBaseClassParameters = typeof(XEngineScriptBase).GetConstructor(new Type[] { typeof(WaitHandle) }).GetParameters(); + ScriptReferencedAssemblies = new string[] { Path.GetFileName(typeof(XEngineScriptBase).Assembly.Location) }; + + Console.WriteLine("ASSEMBLY NAME: {0}", ScriptReferencedAssemblies[0]); } public void AddRegion(Scene scene) @@ -1179,7 +1192,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine } catch (Exception e) { -// m_log.ErrorFormat("[XEngine]: Exception when rezzing script {0}{1}", e.Message, e.StackTrace); +// m_log.ErrorFormat( +// "[XEngine]: Exception when rezzing script with item ID {0}, {1}{2}", +// itemID, e.Message, e.StackTrace); // try // { -- cgit v1.1 From 482c7b5368faa034b73b3434fd90ce3702644cb8 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 18 Jan 2013 11:37:36 -0800 Subject: BulletSim: add logic to turn off pre-step actions when object goes non-active. This turns off 'setForce', 'setTorque' and 'moveToTarget' when the object is selected or made non-physical. --- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 7aa2d92..aaa6fe5 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -502,6 +502,12 @@ public sealed class BSPrim : BSPhysObject RegisterPreStepAction("BSPrim.setForce", LocalID, delegate(float timeStep) { + if (!IsPhysicallyActive) + { + UnRegisterPreStepAction("BSPrim.setForce", LocalID); + return; + } + DetailLog("{0},BSPrim.setForce,preStep,force={1}", LocalID, _force); if (PhysBody.HasPhysicalBody) { @@ -627,6 +633,12 @@ public sealed class BSPrim : BSPhysObject RegisterPreStepAction("BSPrim.setTorque", LocalID, delegate(float timeStep) { + if (!IsPhysicallyActive) + { + UnRegisterPreStepAction("BSPrim.setTorque", LocalID); + return; + } + if (PhysBody.HasPhysicalBody) AddAngularForce(_torque, false, true); } @@ -1061,6 +1073,12 @@ public sealed class BSPrim : BSPhysObject RegisterPreStepAction("BSPrim.PIDTarget", LocalID, delegate(float timeStep) { + if (!IsPhysicallyActive) + { + UnRegisterPreStepAction("BSPrim.PIDTarget", LocalID); + return; + } + OMV.Vector3 origPosition = RawPosition; // DEBUG DEBUG (for printout below) // 'movePosition' is where we'd like the prim to be at this moment. @@ -1108,6 +1126,9 @@ public sealed class BSPrim : BSPhysObject RegisterPreStepAction("BSPrim.Hover", LocalID, delegate(float timeStep) { + if (!IsPhysicallyActive) + return; + _hoverMotor.SetCurrent(RawPosition.Z); _hoverMotor.SetTarget(ComputeCurrentPIDHoverHeight()); float targetHeight = _hoverMotor.Step(timeStep); -- cgit v1.1 From c6b6c94ccbbbd5226a377a510a988bedec7a418c Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 18 Jan 2013 11:39:24 -0800 Subject: BulletSim: reduce jitter in avatar velocity when walking or flying. OpenSimulator is VERY sensitive to changes in avatar velocity and will send an avatar update message when velocity changes more than 0.001m/s. This significantly reduces the number of avatar update messages by smoothing the avatar velocity returned by Bullet. --- OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 9 ++++++++- OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 6d5e23f..478aeab 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -853,7 +853,14 @@ public sealed class BSCharacter : BSPhysObject { _position = entprop.Position; _orientation = entprop.Rotation; - _velocity = entprop.Velocity; + + // Smooth velocity. OpenSimulator is very sensitive to changes in velocity of the avatar + // and will send agent updates to the clients if velocity changes by more than + // 0.001m/s. Bullet introduces a lot of jitter in the velocity which causes many + // extra updates. + if (!entprop.Velocity.ApproxEquals(_velocity, 0.1f)) + _velocity = entprop.Velocity; + _acceleration = entprop.Acceleration; _rotationalVelocity = entprop.RotationalVelocity; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index bac0427..5353c75 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -141,7 +141,7 @@ public abstract class BSPhysObject : PhysicsActor // It can be confusing for an actor to know if it should move or update an object // depeneding on the setting of 'selected', 'physical, ... - // This flag is the true test -- if true, the object is being acted on in the physical world + // This flag is the true test -- if true, the object is being acted on in the physical world public abstract bool IsPhysicallyActive { get; } // Materialness -- cgit v1.1 From 74256c0cc47870f6057b64ce117479af79f02ab0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 18 Jan 2013 22:57:09 +0000 Subject: Restore previous client AO behaviour by not allowing them to remove the default animation but continue to allow scripts to do so. This keeps the fix from http://opensimulator.org/mantis/view.php?id=6327 and fixes the behaviour regression in http://opensimulator.org/mantis/view.php?id=6483 Animations may still exhibit different behaviour if both scripts and clients are adjusting animations. A change in the behaviour of client AO to not remove all animations may be a better long term approach. --- OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs | 15 +++++++++++++-- .../Framework/Scenes/Animation/ScenePresenceAnimator.cs | 14 +++++++++++--- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- .../ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 2 +- 5 files changed, 27 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs index 65ae445..66edfed 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs @@ -87,13 +87,24 @@ namespace OpenSim.Region.Framework.Scenes.Animation return false; } - public bool Remove(UUID animID) + /// + /// Remove the specified animation + /// + /// + /// + /// If true, then the default animation can be entirely removed. + /// If false, then removing the default animation will reset it to the simulator default (currently STAND). + /// + public bool Remove(UUID animID, bool allowNoDefault) { lock (m_animations) { if (m_defaultAnimation.AnimID == animID) { - m_defaultAnimation = new OpenSim.Framework.Animation(UUID.Zero, 1, UUID.Zero); + if (allowNoDefault) + m_defaultAnimation = new OpenSim.Framework.Animation(UUID.Zero, 1, UUID.Zero); + else + ResetDefaultAnimation(); } else if (HasAnimation(animID)) { diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index 5b16b67..3657dc4 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -109,14 +109,22 @@ namespace OpenSim.Region.Framework.Scenes.Animation AddAnimation(animID, objectID); } - public void RemoveAnimation(UUID animID) + /// + /// Remove the specified animation + /// + /// + /// + /// If true, then the default animation can be entirely removed. + /// If false, then removing the default animation will reset it to the simulator default (currently STAND). + /// + public void RemoveAnimation(UUID animID, bool allowNoDefault) { if (m_scenePresence.IsChildAgent) return; // m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Removing animation {0} for {1}", animID, m_scenePresence.Name); - if (m_animations.Remove(animID)) + if (m_animations.Remove(animID, allowNoDefault)) SendAnimPack(); } @@ -132,7 +140,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation if (animID == UUID.Zero) return; - RemoveAnimation(animID); + RemoveAnimation(animID, true); } public void ResetAnimations() diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 6979c33..c295305 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2260,7 +2260,7 @@ namespace OpenSim.Region.Framework.Scenes public void HandleStopAnim(IClientAPI remoteClient, UUID animID) { - Animator.RemoveAnimation(animID); + Animator.RemoveAnimation(animID, false); } /// diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index d47fd6b..a2f1ff2 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3364,7 +3364,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (animID == UUID.Zero) presence.Animator.RemoveAnimation(anim); else - presence.Animator.RemoveAnimation(animID); + presence.Animator.RemoveAnimation(animID, true); } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 25635ff..5c0ff1c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -986,7 +986,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (animID == UUID.Zero) target.Animator.RemoveAnimation(animation); else - target.Animator.RemoveAnimation(animID); + target.Animator.RemoveAnimation(animID, true); } } } -- cgit v1.1 From 115e1c2abb7755eb7b5ffeafbc0aecd255ccfc4e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 18 Jan 2013 23:22:02 +0000 Subject: Add "debug set set animations true|false" region console command. Setting this logs extra information about animation add/remove, such as uuid and animation name Unfortunately cannot be done per client yet --- .../Scenes/Animation/ScenePresenceAnimator.cs | 33 ++++++++++++++++++---- OpenSim/Region/Framework/Scenes/Scene.cs | 5 ++++ .../Avatar/Animations/AnimationsCommandModule.cs | 23 +++------------ .../World/SceneCommands/SceneCommandsModule.cs | 11 ++++++++ 4 files changed, 48 insertions(+), 24 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index 3657dc4..e92a087 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -86,7 +86,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation if (m_scenePresence.IsChildAgent) return; -// m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Adding animation {0} for {1}", animID, m_scenePresence.Name); + if (m_scenePresence.Scene.DebugAnimations) + m_log.DebugFormat( + "[SCENE PRESENCE ANIMATOR]: Adding animation {0} {1} for {2}", + GetAnimName(animID), animID, m_scenePresence.Name); if (m_animations.Add(animID, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, objectID)) SendAnimPack(); @@ -122,7 +125,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation if (m_scenePresence.IsChildAgent) return; -// m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Removing animation {0} for {1}", animID, m_scenePresence.Name); + if (m_scenePresence.Scene.DebugAnimations) + m_log.DebugFormat( + "[SCENE PRESENCE ANIMATOR]: Removing animation {0} {1} for {2}", + GetAnimName(animID), animID, m_scenePresence.Name); if (m_animations.Remove(animID, allowNoDefault)) SendAnimPack(); @@ -145,9 +151,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation public void ResetAnimations() { -// m_log.DebugFormat( -// "[SCENE PRESENCE ANIMATOR]: Resetting animations for {0} in {1}", -// m_scenePresence.Name, m_scenePresence.Scene.RegionInfo.RegionName); + if (m_scenePresence.Scene.DebugAnimations) + m_log.DebugFormat( + "[SCENE PRESENCE ANIMATOR]: Resetting animations for {0} in {1}", + m_scenePresence.Name, m_scenePresence.Scene.RegionInfo.RegionName); m_animations.Clear(); } @@ -558,5 +565,21 @@ namespace OpenSim.Region.Framework.Scenes.Animation SendAnimPack(animIDs, sequenceNums, objectIDs); } + + public string GetAnimName(UUID animId) + { + string animName; + + if (!DefaultAvatarAnimations.AnimsNames.TryGetValue(animId, out animName)) + { + AssetMetadata amd = m_scenePresence.Scene.AssetService.GetMetadata(animId.ToString()); + if (amd != null) + animName = amd.Name; + else + animName = "Unknown"; + } + + return animName; + } } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 4859dff..5778176 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -68,6 +68,11 @@ namespace OpenSim.Region.Framework.Scenes public bool EmergencyMonitoring = false; /// + /// Show debug information about animations. + /// + public bool DebugAnimations { get; set; } + + /// /// Show debug information about teleports. /// public bool DebugTeleporting { get; set; } diff --git a/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs index e951d9e..84211a9 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs @@ -161,12 +161,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Animations UUID defaultAnimId = anims.DefaultAnimation.AnimID; cdl.AddRow( "Default anim", - string.Format("{0}, {1}", defaultAnimId, GetAnimName(sp.Scene.AssetService, defaultAnimId))); + string.Format("{0}, {1}", defaultAnimId, sp.Animator.GetAnimName(defaultAnimId))); UUID implicitDefaultAnimId = anims.ImplicitDefaultAnimation.AnimID; cdl.AddRow( "Implicit default anim", - string.Format("{0}, {1}", implicitDefaultAnimId, GetAnimName(sp.Scene.AssetService, implicitDefaultAnimId))); + string.Format("{0}, {1}", + implicitDefaultAnimId, sp.Animator.GetAnimName(implicitDefaultAnimId))); cdl.AddToStringBuilder(sb); @@ -185,7 +186,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Animations for (int i = 0; i < animIds.Length; i++) { UUID animId = animIds[i]; - string animName = GetAnimName(sp.Scene.AssetService, animId); + string animName = sp.Animator.GetAnimName(animId); int seq = sequenceNumbers[i]; UUID objectId = objectIds[i]; @@ -195,21 +196,5 @@ namespace OpenSim.Region.OptionalModules.Avatar.Animations cdt.AddToStringBuilder(sb); sb.Append("\n"); } - - private string GetAnimName(IAssetService assetService, UUID animId) - { - string animName; - - if (!DefaultAvatarAnimations.AnimsNames.TryGetValue(animId, out animName)) - { - AssetMetadata amd = assetService.GetMetadata(animId.ToString()); - if (amd != null) - animName = amd.Name; - else - animName = "Unknown"; - } - - return animName; - } } } \ No newline at end of file diff --git a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs index 8b8758e..521141a 100644 --- a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs +++ b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs @@ -94,6 +94,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments "debug scene get", "List current scene options.", "If active is false then main scene update and maintenance loops are suspended.\n" + + "If animations is true then extra animations debug information is logged.\n" + "If collisions is false then collisions with other objects are turned off.\n" + "If pbackup is false then periodic scene backup is turned off.\n" + "If physics is false then all physics objects are non-physical.\n" @@ -107,6 +108,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments "debug scene set active|collisions|pbackup|physics|scripting|teleport|updates true|false", "Turn on scene debugging options.", "If active is false then main scene update and maintenance loops are suspended.\n" + + "If animations is true then extra animations debug information is logged.\n" + "If collisions is false then collisions with other objects are turned off.\n" + "If pbackup is false then periodic scene backup is turned off.\n" + "If physics is false then all physics objects are non-physical.\n" @@ -135,6 +137,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments { ConsoleDisplayList cdl = new ConsoleDisplayList(); cdl.AddRow("active", m_scene.Active); + cdl.AddRow("animations", m_scene.DebugAnimations); cdl.AddRow("pbackup", m_scene.PeriodicBackup); cdl.AddRow("physics", m_scene.PhysicsEnabled); cdl.AddRow("scripting", m_scene.ScriptsEnabled); @@ -178,6 +181,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments m_scene.Active = active; } + if (options.ContainsKey("animations")) + { + bool active; + + if (bool.TryParse(options["animations"], out active)) + m_scene.DebugAnimations = active; + } + if (options.ContainsKey("pbackup")) { bool active; -- cgit v1.1 From 652cfa2ee2ce54c4b53fc4001a715406d66c3cf1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 19 Jan 2013 00:27:17 +0000 Subject: Fix use of scene debug commands when region is set to root or a specific region where there is more than one region on the simulator. --- .../World/SceneCommands/SceneCommandsModule.cs | 27 ++++++++++------------ 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs index 521141a..12169ab 100644 --- a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs +++ b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs @@ -122,10 +122,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments { if (args.Length == 3) { - if (MainConsole.Instance.ConsoleScene == null) - MainConsole.Instance.Output("Please use 'change region ' first"); - else - OutputSceneDebugOptions(); + if (MainConsole.Instance.ConsoleScene != m_scene && MainConsole.Instance.ConsoleScene != null) + return; + + OutputSceneDebugOptions(); } else { @@ -144,6 +144,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments cdl.AddRow("teleport", m_scene.DebugTeleporting); cdl.AddRow("updates", m_scene.DebugUpdates); + MainConsole.Instance.OutputFormat("Scene {0} options:", m_scene.Name); MainConsole.Instance.Output(cdl.ToString()); } @@ -151,18 +152,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments { if (args.Length == 5) { - if (MainConsole.Instance.ConsoleScene == null) - { - MainConsole.Instance.Output("Please use 'change region ' first"); - } - else - { - string key = args[3]; - string value = args[4]; - SetSceneDebugOptions(new Dictionary() { { key, value } }); + if (MainConsole.Instance.ConsoleScene != m_scene && MainConsole.Instance.ConsoleScene != null) + return; - MainConsole.Instance.OutputFormat("Set debug scene {0} = {1}", key, value); - } + string key = args[3]; + string value = args[4]; + SetSceneDebugOptions(new Dictionary() { { key, value } }); + + MainConsole.Instance.OutputFormat("Set {0} debug scene {1} = {2}", m_scene.Name, key, value); } else { -- cgit v1.1 From 4f70e423df97f3fd52f4a36ac296f696f46b7d34 Mon Sep 17 00:00:00 2001 From: Talun Date: Fri, 18 Jan 2013 19:16:21 +0000 Subject: Mantis 6507 keys returned by llGetAgentList incorrect for llList2Key The type of the keys returned by llGetAgentList corrected to LSL_Key --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index a2f1ff2..50597b7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -5793,13 +5793,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (parcelOwned && land.LandData.OwnerID == id || parcel && land.LandData.GlobalID == id) { - result.Add(ssp.UUID.ToString()); + result.Add(new LSL_Key(ssp.UUID.ToString())); } } } else { - result.Add(ssp.UUID.ToString()); + result.Add(new LSL_Key(ssp.UUID.ToString())); } } // Maximum of 100 results -- cgit v1.1 From 27e2ec177a7e44e5456c7f18c1256b79a9655151 Mon Sep 17 00:00:00 2001 From: Talun Date: Mon, 14 Jan 2013 18:17:33 +0000 Subject: New constants for llGetObjectDetails New constants for llGetObjectDetails OBJECT_CHARACTER_TIME, OBJECT_ROOT, OBJECT_ATTACHED_POINT, OBJECT_PATHFINDING_TYPE, OBJECT_PHYSICS, OBJECT_PHANTOM and OBJECT_TEMP_ON_REZ also Pathfining constants, 3 of which are used by llGetObjectDetails --- .../Shared/Api/Implementation/LSL_Api.cs | 75 ++++++++++++++++++++++ .../Shared/Api/Runtime/LSL_Constants.cs | 17 +++++ 2 files changed, 92 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 50597b7..db5add1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -10590,6 +10590,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api case ScriptBaseClass.OBJECT_PHYSICS_COST: ret.Add(new LSL_Float(0)); break; + case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding + ret.Add(new LSL_Float(0)); + break; + case ScriptBaseClass.OBJECT_ROOT: + SceneObjectPart p = av.ParentPart; + if (p != null) + { + ret.Add(new LSL_String(p.ParentGroup.RootPart.UUID.ToString())); + } + else + { + ret.Add(new LSL_String(id)); + } + break; + case ScriptBaseClass.OBJECT_ATTACHED_POINT: + ret.Add(new LSL_Integer(0)); + break; + case ScriptBaseClass.OBJECT_PATHFINDING_TYPE: // Pathfinding + ret.Add(new LSL_Integer(ScriptBaseClass.OPT_AVATAR)); + break; + case ScriptBaseClass.OBJECT_PHYSICS: + ret.Add(new LSL_Integer(0)); + break; + case ScriptBaseClass.OBJECT_PHANTOM: + ret.Add(new LSL_Integer(0)); + break; + case ScriptBaseClass.OBJECT_TEMP_ON_REZ: + ret.Add(new LSL_Integer(0)); + break; default: // Invalid or unhandled constant. ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); @@ -10685,6 +10714,52 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // The value returned in SL for normal prims looks like the prim count ret.Add(new LSL_Float(0)); break; + case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding + ret.Add(new LSL_Float(0)); + break; + case ScriptBaseClass.OBJECT_ROOT: + ret.Add(new LSL_String(obj.ParentGroup.RootPart.UUID.ToString())); + break; + case ScriptBaseClass.OBJECT_ATTACHED_POINT: + ret.Add(new LSL_Integer(obj.ParentGroup.AttachmentPoint)); + break; + case ScriptBaseClass.OBJECT_PATHFINDING_TYPE: + byte pcode = obj.Shape.PCode; + if (obj.ParentGroup.AttachmentPoint != 0 + || pcode == (byte)PCode.Grass + || pcode == (byte)PCode.Tree + || pcode == (byte)PCode.NewTree) + { + ret.Add(new LSL_Integer(ScriptBaseClass.OPT_OTHER)); + } + else + { + ret.Add(new LSL_Integer(ScriptBaseClass.OPT_LEGACY_LINKSET)); + } + break; + case ScriptBaseClass.OBJECT_PHYSICS: + if (obj.ParentGroup.AttachmentPoint != 0) + { + ret.Add(new LSL_Integer(0)); // Always false if attached + } + else + { + ret.Add(new LSL_Integer(obj.ParentGroup.UsesPhysics ? 1 : 0)); + } + break; + case ScriptBaseClass.OBJECT_PHANTOM: + if (obj.ParentGroup.AttachmentPoint != 0) + { + ret.Add(new LSL_Integer(0)); // Always false if attached + } + else + { + ret.Add(new LSL_Integer(obj.ParentGroup.IsPhantom ? 1 : 0)); + } + break; + case ScriptBaseClass.OBJECT_TEMP_ON_REZ: + ret.Add(new LSL_Integer(obj.ParentGroup.IsTemporary ? 1 : 0)); + break; default: // Invalid or unhandled constant. ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index 880841b..9bf1a64 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -556,6 +556,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int OBJECT_SERVER_COST = 14; public const int OBJECT_STREAMING_COST = 15; public const int OBJECT_PHYSICS_COST = 16; + public const int OBJECT_CHARACTER_TIME = 17; + public const int OBJECT_ROOT = 18; + public const int OBJECT_ATTACHED_POINT = 19; + public const int OBJECT_PATHFINDING_TYPE = 20; + public const int OBJECT_PHYSICS = 21; + public const int OBJECT_PHANTOM = 22; + public const int OBJECT_TEMP_ON_REZ = 23; + + // Pathfinding types + public const int OPT_OTHER = -1; + public const int OPT_LEGACY_LINKSET = 0; + public const int OPT_AVATAR = 1; + public const int OPT_CHARACTER = 2; + public const int OPT_WALKABLE = 3; + public const int OPT_STATIC_OBSTACLE = 4; + public const int OPT_MATERIAL_VOLUME = 5; + public const int OPT_EXCLUSION_VOLUME = 6; // for llGetAgentList public const int AGENT_LIST_PARCEL = 1; -- cgit v1.1 From b77da5039eba6db0f904bfa9ca0852d640436055 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Fri, 4 Jan 2013 08:43:05 +0200 Subject: Assign the SmartThreadPool name in the constructor This is required because some threads are created in the constructor, so assigning the name afterwards would be too late. --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index a17a018..72646f6 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1486,7 +1486,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_MaxScriptQueue = maxScriptQueue; STPStartInfo startInfo = new STPStartInfo(); - startInfo.IdleTimeout = idleTimeout*1000; // convert to seconds as stated in .ini + startInfo.ThreadPoolName = "XEngine"; + startInfo.IdleTimeout = idleTimeout * 1000; // convert to seconds as stated in .ini startInfo.MaxWorkerThreads = maxThreads; startInfo.MinWorkerThreads = minThreads; startInfo.ThreadPriority = threadPriority;; @@ -1494,7 +1495,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine startInfo.StartSuspended = true; m_ThreadPool = new SmartThreadPool(startInfo); - m_ThreadPool.Name = "XEngine"; } // -- cgit v1.1 From fc6115f77755734d5a60b9eeebef25b98696f4e4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 19 Jan 2013 02:29:02 +0000 Subject: Check the existing ScenePresence.ParentPart to make sure we're not trying to sit on a prim we're already sat upon, rather than looking up the part from scratch. An adaptation of commit 055b8a2 Having both ParentID and ParentPart references now is redundant. ParentID should probably be eliminated. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index c295305..a90872e 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1954,8 +1954,7 @@ namespace OpenSim.Region.Framework.Scenes { if (ParentID != 0) { - var targetPart = m_scene.GetSceneObjectPart(targetID); - if (targetPart != null && targetPart.LocalId == ParentID) + if (ParentPart.UUID == targetID) return; // already sitting here, ignore StandUp(); -- cgit v1.1 From 9c590e51b6a1457ccb9eaee525d1e5a244b50274 Mon Sep 17 00:00:00 2001 From: PixelTomsen Date: Sun, 13 Jan 2013 20:18:40 +0100 Subject: IRCBridgeModule: optional agent-alertbox for IRC enabled Regions look in OpenSimDefaults.ini / section [IRC] http://opensimulator.org/mantis/view.php?id=6470 idea: https://github.com/ssm2017/IrcBridgeAlert --- .../OptionalModules/Avatar/Chat/ChannelState.cs | 158 ++++++------ .../OptionalModules/Avatar/Chat/IRCBridgeModule.cs | 41 +-- .../OptionalModules/Avatar/Chat/IRCConnector.cs | 283 +++++++++++---------- .../OptionalModules/Avatar/Chat/RegionState.cs | 96 ++++--- 4 files changed, 305 insertions(+), 273 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs index 66265d8..5a37fad 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs @@ -55,42 +55,42 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // These are the IRC Connector configurable parameters with hard-wired // default values (retained for compatability). - internal string Server = null; - internal string Password = null; - internal string IrcChannel = null; - internal string BaseNickname = "OSimBot"; - internal uint Port = 6667; - internal string User = null; - - internal bool ClientReporting = true; - internal bool RelayChat = true; - internal bool RelayPrivateChannels = false; - internal int RelayChannel = 1; + internal string Server = null; + internal string Password = null; + internal string IrcChannel = null; + internal string BaseNickname = "OSimBot"; + internal uint Port = 6667; + internal string User = null; + + internal bool ClientReporting = true; + internal bool RelayChat = true; + internal bool RelayPrivateChannels = false; + internal int RelayChannel = 1; internal List ValidInWorldChannels = new List(); // Connector agnostic parameters. These values are NOT shared with the // connector and do not differentiate at an IRC level internal string PrivateMessageFormat = "PRIVMSG {0} :<{2}> {1} {3}"; - internal string NoticeMessageFormat = "PRIVMSG {0} :<{2}> {3}"; - internal int RelayChannelOut = -1; - internal bool RandomizeNickname = true; - internal bool CommandsEnabled = false; - internal int CommandChannel = -1; - internal int ConnectDelay = 10; - internal int PingDelay = 15; - internal string DefaultZone = "Sim"; - - internal string _accessPassword = String.Empty; - internal Regex AccessPasswordRegex = null; - internal List ExcludeList = new List(); + internal string NoticeMessageFormat = "PRIVMSG {0} :<{2}> {3}"; + internal int RelayChannelOut = -1; + internal bool RandomizeNickname = true; + internal bool CommandsEnabled = false; + internal int CommandChannel = -1; + internal int ConnectDelay = 10; + internal int PingDelay = 15; + internal string DefaultZone = "Sim"; + + internal string _accessPassword = String.Empty; + internal Regex AccessPasswordRegex = null; + internal List ExcludeList = new List(); internal string AccessPassword { get { return _accessPassword; } - set + set { _accessPassword = value; - AccessPasswordRegex = new Regex(String.Format(@"^{0},\s*(?[^,]+),\s*(?.+)$", _accessPassword), + AccessPasswordRegex = new Regex(String.Format(@"^{0},\s*(?[^,]+),\s*(?.+)$", _accessPassword), RegexOptions.Compiled); } } @@ -99,9 +99,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // IRC connector reference - internal IRCConnector irc = null; + internal IRCConnector irc = null; - internal int idn = _idk_++; + internal int idn = _idk_++; // List of regions dependent upon this connection @@ -119,29 +119,29 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat internal ChannelState(ChannelState model) { - Server = model.Server; - Password = model.Password; - IrcChannel = model.IrcChannel; - Port = model.Port; - BaseNickname = model.BaseNickname; - RandomizeNickname = model.RandomizeNickname; - User = model.User; - CommandsEnabled = model.CommandsEnabled; - CommandChannel = model.CommandChannel; - RelayChat = model.RelayChat; + Server = model.Server; + Password = model.Password; + IrcChannel = model.IrcChannel; + Port = model.Port; + BaseNickname = model.BaseNickname; + RandomizeNickname = model.RandomizeNickname; + User = model.User; + CommandsEnabled = model.CommandsEnabled; + CommandChannel = model.CommandChannel; + RelayChat = model.RelayChat; RelayPrivateChannels = model.RelayPrivateChannels; - RelayChannelOut = model.RelayChannelOut; - RelayChannel = model.RelayChannel; + RelayChannelOut = model.RelayChannelOut; + RelayChannel = model.RelayChannel; ValidInWorldChannels = model.ValidInWorldChannels; PrivateMessageFormat = model.PrivateMessageFormat; - NoticeMessageFormat = model.NoticeMessageFormat; - ClientReporting = model.ClientReporting; - AccessPassword = model.AccessPassword; - DefaultZone = model.DefaultZone; - ConnectDelay = model.ConnectDelay; - PingDelay = model.PingDelay; + NoticeMessageFormat = model.NoticeMessageFormat; + ClientReporting = model.ClientReporting; + AccessPassword = model.AccessPassword; + DefaultZone = model.DefaultZone; + ConnectDelay = model.ConnectDelay; + PingDelay = model.PingDelay; } - + // Read the configuration file, performing variable substitution and any // necessary aliasing. See accompanying documentation for how this works. // If you don't need variables, then this works exactly as before. @@ -160,54 +160,54 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_log.DebugFormat("[IRC-Channel-{0}] Initial request by Region {1} to connect to IRC", cs.idn, rs.Region); - cs.Server = Substitute(rs, config.GetString("server", null)); + cs.Server = Substitute(rs, config.GetString("server", null)); m_log.DebugFormat("[IRC-Channel-{0}] Server : <{1}>", cs.idn, cs.Server); - cs.Password = Substitute(rs, config.GetString("password", null)); + cs.Password = Substitute(rs, config.GetString("password", null)); // probably not a good idea to put a password in the log file - cs.User = Substitute(rs, config.GetString("user", null)); - cs.IrcChannel = Substitute(rs, config.GetString("channel", null)); + cs.User = Substitute(rs, config.GetString("user", null)); + cs.IrcChannel = Substitute(rs, config.GetString("channel", null)); m_log.DebugFormat("[IRC-Channel-{0}] IrcChannel : <{1}>", cs.idn, cs.IrcChannel); - cs.Port = Convert.ToUInt32(Substitute(rs, config.GetString("port", Convert.ToString(cs.Port)))); + cs.Port = Convert.ToUInt32(Substitute(rs, config.GetString("port", Convert.ToString(cs.Port)))); m_log.DebugFormat("[IRC-Channel-{0}] Port : <{1}>", cs.idn, cs.Port); - cs.BaseNickname = Substitute(rs, config.GetString("nick", cs.BaseNickname)); + cs.BaseNickname = Substitute(rs, config.GetString("nick", cs.BaseNickname)); m_log.DebugFormat("[IRC-Channel-{0}] BaseNickname : <{1}>", cs.idn, cs.BaseNickname); - cs.RandomizeNickname = Convert.ToBoolean(Substitute(rs, config.GetString("randomize_nick", Convert.ToString(cs.RandomizeNickname)))); + cs.RandomizeNickname = Convert.ToBoolean(Substitute(rs, config.GetString("randomize_nick", Convert.ToString(cs.RandomizeNickname)))); m_log.DebugFormat("[IRC-Channel-{0}] RandomizeNickname : <{1}>", cs.idn, cs.RandomizeNickname); - cs.RandomizeNickname = Convert.ToBoolean(Substitute(rs, config.GetString("nicknum", Convert.ToString(cs.RandomizeNickname)))); + cs.RandomizeNickname = Convert.ToBoolean(Substitute(rs, config.GetString("nicknum", Convert.ToString(cs.RandomizeNickname)))); m_log.DebugFormat("[IRC-Channel-{0}] RandomizeNickname : <{1}>", cs.idn, cs.RandomizeNickname); - cs.User = Substitute(rs, config.GetString("username", cs.User)); + cs.User = Substitute(rs, config.GetString("username", cs.User)); m_log.DebugFormat("[IRC-Channel-{0}] User : <{1}>", cs.idn, cs.User); - cs.CommandsEnabled = Convert.ToBoolean(Substitute(rs, config.GetString("commands_enabled", Convert.ToString(cs.CommandsEnabled)))); + cs.CommandsEnabled = Convert.ToBoolean(Substitute(rs, config.GetString("commands_enabled", Convert.ToString(cs.CommandsEnabled)))); m_log.DebugFormat("[IRC-Channel-{0}] CommandsEnabled : <{1}>", cs.idn, cs.CommandsEnabled); - cs.CommandChannel = Convert.ToInt32(Substitute(rs, config.GetString("commandchannel", Convert.ToString(cs.CommandChannel)))); + cs.CommandChannel = Convert.ToInt32(Substitute(rs, config.GetString("commandchannel", Convert.ToString(cs.CommandChannel)))); m_log.DebugFormat("[IRC-Channel-{0}] CommandChannel : <{1}>", cs.idn, cs.CommandChannel); - cs.CommandChannel = Convert.ToInt32(Substitute(rs, config.GetString("command_channel", Convert.ToString(cs.CommandChannel)))); + cs.CommandChannel = Convert.ToInt32(Substitute(rs, config.GetString("command_channel", Convert.ToString(cs.CommandChannel)))); m_log.DebugFormat("[IRC-Channel-{0}] CommandChannel : <{1}>", cs.idn, cs.CommandChannel); - cs.RelayChat = Convert.ToBoolean(Substitute(rs, config.GetString("relay_chat", Convert.ToString(cs.RelayChat)))); + cs.RelayChat = Convert.ToBoolean(Substitute(rs, config.GetString("relay_chat", Convert.ToString(cs.RelayChat)))); m_log.DebugFormat("[IRC-Channel-{0}] RelayChat : <{1}>", cs.idn, cs.RelayChat); cs.RelayPrivateChannels = Convert.ToBoolean(Substitute(rs, config.GetString("relay_private_channels", Convert.ToString(cs.RelayPrivateChannels)))); m_log.DebugFormat("[IRC-Channel-{0}] RelayPrivateChannels : <{1}>", cs.idn, cs.RelayPrivateChannels); cs.RelayPrivateChannels = Convert.ToBoolean(Substitute(rs, config.GetString("useworldcomm", Convert.ToString(cs.RelayPrivateChannels)))); m_log.DebugFormat("[IRC-Channel-{0}] RelayPrivateChannels : <{1}>", cs.idn, cs.RelayPrivateChannels); - cs.RelayChannelOut = Convert.ToInt32(Substitute(rs, config.GetString("relay_private_channel_out", Convert.ToString(cs.RelayChannelOut)))); + cs.RelayChannelOut = Convert.ToInt32(Substitute(rs, config.GetString("relay_private_channel_out", Convert.ToString(cs.RelayChannelOut)))); m_log.DebugFormat("[IRC-Channel-{0}] RelayChannelOut : <{1}>", cs.idn, cs.RelayChannelOut); - cs.RelayChannel = Convert.ToInt32(Substitute(rs, config.GetString("relay_private_channel_in", Convert.ToString(cs.RelayChannel)))); + cs.RelayChannel = Convert.ToInt32(Substitute(rs, config.GetString("relay_private_channel_in", Convert.ToString(cs.RelayChannel)))); m_log.DebugFormat("[IRC-Channel-{0}] RelayChannel : <{1}>", cs.idn, cs.RelayChannel); - cs.RelayChannel = Convert.ToInt32(Substitute(rs, config.GetString("inchannel", Convert.ToString(cs.RelayChannel)))); + cs.RelayChannel = Convert.ToInt32(Substitute(rs, config.GetString("inchannel", Convert.ToString(cs.RelayChannel)))); m_log.DebugFormat("[IRC-Channel-{0}] RelayChannel : <{1}>", cs.idn, cs.RelayChannel); cs.PrivateMessageFormat = Substitute(rs, config.GetString("msgformat", cs.PrivateMessageFormat)); m_log.DebugFormat("[IRC-Channel-{0}] PrivateMessageFormat : <{1}>", cs.idn, cs.PrivateMessageFormat); cs.NoticeMessageFormat = Substitute(rs, config.GetString("noticeformat", cs.NoticeMessageFormat)); m_log.DebugFormat("[IRC-Channel-{0}] NoticeMessageFormat : <{1}>", cs.idn, cs.NoticeMessageFormat); - cs.ClientReporting = Convert.ToInt32(Substitute(rs, config.GetString("verbosity", cs.ClientReporting?"1":"0"))) > 0; + cs.ClientReporting = Convert.ToInt32(Substitute(rs, config.GetString("verbosity", cs.ClientReporting ? "1" : "0"))) > 0; m_log.DebugFormat("[IRC-Channel-{0}] ClientReporting : <{1}>", cs.idn, cs.ClientReporting); - cs.ClientReporting = Convert.ToBoolean(Substitute(rs, config.GetString("report_clients", Convert.ToString(cs.ClientReporting)))); + cs.ClientReporting = Convert.ToBoolean(Substitute(rs, config.GetString("report_clients", Convert.ToString(cs.ClientReporting)))); m_log.DebugFormat("[IRC-Channel-{0}] ClientReporting : <{1}>", cs.idn, cs.ClientReporting); - cs.DefaultZone = Substitute(rs, config.GetString("fallback_region", cs.DefaultZone)); + cs.DefaultZone = Substitute(rs, config.GetString("fallback_region", cs.DefaultZone)); m_log.DebugFormat("[IRC-Channel-{0}] DefaultZone : <{1}>", cs.idn, cs.DefaultZone); - cs.ConnectDelay = Convert.ToInt32(Substitute(rs, config.GetString("connect_delay", Convert.ToString(cs.ConnectDelay)))); + cs.ConnectDelay = Convert.ToInt32(Substitute(rs, config.GetString("connect_delay", Convert.ToString(cs.ConnectDelay)))); m_log.DebugFormat("[IRC-Channel-{0}] ConnectDelay : <{1}>", cs.idn, cs.ConnectDelay); - cs.PingDelay = Convert.ToInt32(Substitute(rs, config.GetString("ping_delay", Convert.ToString(cs.PingDelay)))); + cs.PingDelay = Convert.ToInt32(Substitute(rs, config.GetString("ping_delay", Convert.ToString(cs.PingDelay)))); m_log.DebugFormat("[IRC-Channel-{0}] PingDelay : <{1}>", cs.idn, cs.PingDelay); cs.AccessPassword = Substitute(rs, config.GetString("access_password", cs.AccessPassword)); m_log.DebugFormat("[IRC-Channel-{0}] AccessPassword : <{1}>", cs.idn, cs.AccessPassword); @@ -217,7 +217,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat { cs.ExcludeList.Add(name.Trim().ToLower()); } - + // Fail if fundamental information is still missing if (cs.Server == null) @@ -306,8 +306,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat IRCBridgeModule.m_channels.Add(cs); - m_log.InfoFormat("[IRC-Channel-{0}] New channel initialized for {1}, nick: {2}, commands {3}, private channels {4}", - cs.idn, rs.Region, cs.DefaultZone, + m_log.InfoFormat("[IRC-Channel-{0}] New channel initialized for {1}, nick: {2}, commands {3}, private channels {4}", + cs.idn, rs.Region, cs.DefaultZone, cs.CommandsEnabled ? "enabled" : "not enabled", cs.RelayPrivateChannels ? "relayed" : "not relayed"); } @@ -417,7 +417,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat private bool IsAConnectionMatchFor(ChannelState cs) { return ( - Server == cs.Server && + Server == cs.Server && IrcChannel == cs.IrcChannel && Port == cs.Port && BaseNickname == cs.BaseNickname && @@ -473,27 +473,27 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat { string vvar = arg.Match(result).ToString(); - string var = vvar.Substring(1,vvar.Length-2).Trim(); + string var = vvar.Substring(1, vvar.Length - 2).Trim(); switch (var.ToLower()) { - case "%region" : + case "%region": result = result.Replace(vvar, rs.Region); break; - case "%host" : + case "%host": result = result.Replace(vvar, rs.Host); break; - case "%locx" : + case "%locx": result = result.Replace(vvar, rs.LocX); break; - case "%locy" : + case "%locy": result = result.Replace(vvar, rs.LocY); break; - case "%k" : + case "%k": result = result.Replace(vvar, rs.IDK); break; - default : - result = result.Replace(vvar, rs.config.GetString(var,var)); + default: + result = result.Replace(vvar, rs.config.GetString(var, var)); break; } // m_log.DebugFormat("[IRC-Channel] Parse[2]: {0}", result); diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs index 2e1d03d..351dbfe 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs @@ -46,18 +46,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - internal static bool m_pluginEnabled = false; + internal static bool Enabled = false; internal static IConfig m_config = null; internal static List m_channels = new List(); - internal static List m_regions = new List(); + internal static List m_regions = new List(); internal static string m_password = String.Empty; internal RegionState m_region = null; #region INonSharedRegionModule Members - public Type ReplaceableInterface + public Type ReplaceableInterface { get { return null; } } @@ -72,13 +72,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_config = config.Configs["IRC"]; if (m_config == null) { -// m_log.InfoFormat("[IRC-Bridge] module not configured"); + // m_log.InfoFormat("[IRC-Bridge] module not configured"); return; } if (!m_config.GetBoolean("enabled", false)) { -// m_log.InfoFormat("[IRC-Bridge] module disabled in configuration"); + // m_log.InfoFormat("[IRC-Bridge] module disabled in configuration"); return; } @@ -87,19 +87,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_password = config.Configs["RemoteAdmin"].GetString("access_password", m_password); } - m_pluginEnabled = true; - m_log.InfoFormat("[IRC-Bridge]: Module enabled"); + Enabled = true; + + m_log.InfoFormat("[IRC-Bridge]: Module is enabled"); } public void AddRegion(Scene scene) { - if (m_pluginEnabled) + if (Enabled) { try { m_log.InfoFormat("[IRC-Bridge] Connecting region {0}", scene.RegionInfo.RegionName); + if (!String.IsNullOrEmpty(m_password)) MainServer.Instance.AddXmlRPCHandler("irc_admin", XmlRpcAdminMethod, false); + m_region = new RegionState(scene, m_config); lock (m_regions) m_regions.Add(m_region); m_region.Open(); @@ -123,7 +126,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat public void RemoveRegion(Scene scene) { - if (!m_pluginEnabled) + if (!Enabled) return; if (m_region == null) @@ -150,12 +153,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_log.Debug("[IRC-Bridge]: XML RPC Admin Entry"); XmlRpcResponse response = new XmlRpcResponse(); - Hashtable responseData = new Hashtable(); + Hashtable responseData = new Hashtable(); try { Hashtable requestData = (Hashtable)request.Params[0]; - bool found = false; + bool found = false; string region = String.Empty; if (m_password != String.Empty) @@ -169,18 +172,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat if (!requestData.ContainsKey("region")) throw new Exception("No region name specified"); region = (string)requestData["region"]; - + foreach (RegionState rs in m_regions) { if (rs.Region == region) { - responseData["server"] = rs.cs.Server; - responseData["port"] = (int)rs.cs.Port; - responseData["user"] = rs.cs.User; - responseData["channel"] = rs.cs.IrcChannel; - responseData["enabled"] = rs.cs.irc.Enabled; + responseData["server"] = rs.cs.Server; + responseData["port"] = (int)rs.cs.Port; + responseData["user"] = rs.cs.User; + responseData["channel"] = rs.cs.IrcChannel; + responseData["enabled"] = rs.cs.irc.Enabled; responseData["connected"] = rs.cs.irc.Connected; - responseData["nickname"] = rs.cs.irc.Nick; + responseData["nickname"] = rs.cs.irc.Nick; found = true; break; } @@ -195,7 +198,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_log.ErrorFormat("[IRC-Bridge] XML RPC Admin request failed : {0}", e.Message); responseData["success"] = "false"; - responseData["error"] = e.Message; + responseData["error"] = e.Message; } finally { diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs index a014798..c5cba8e 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs @@ -53,16 +53,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // Local constants private static readonly Vector3 CenterOfRegion = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 20); - private static readonly char[] CS_SPACE = { ' ' }; + private static readonly char[] CS_SPACE = { ' ' }; - private const int WD_INTERVAL = 1000; // base watchdog interval - private static int PING_PERIOD = 15; // WD intervals per PING - private static int ICCD_PERIOD = 10; // WD intervals between Connects - private static int L_TIMEOUT = 25; // Login time out interval + private const int WD_INTERVAL = 1000; // base watchdog interval + private static int PING_PERIOD = 15; // WD intervals per PING + private static int ICCD_PERIOD = 10; // WD intervals between Connects + private static int L_TIMEOUT = 25; // Login time out interval - private static int _idk_ = 0; // core connector identifier - private static int _pdk_ = 0; // ping interval counter - private static int _icc_ = ICCD_PERIOD; // IRC connect counter + private static int _idk_ = 0; // core connector identifier + private static int _pdk_ = 0; // ping interval counter + private static int _icc_ = ICCD_PERIOD; // IRC connect counter // List of configured connectors @@ -113,7 +113,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat private Object msyncConnect = new Object(); - internal bool m_randomizeNick = true; // add random suffix + internal bool m_randomizeNick = true; // add random suffix internal string m_baseNick = null; // base name for randomizing internal string m_nick = null; // effective nickname @@ -122,7 +122,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat get { return m_nick; } set { m_nick = value; } } - + private bool m_enabled = false; // connector enablement public bool Enabled { @@ -130,8 +130,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat } private bool m_connected = false; // connection status - private bool m_pending = false; // login disposition - private int m_timeout = L_TIMEOUT; // login timeout counter + private bool m_pending = false; // login disposition + private int m_timeout = L_TIMEOUT; // login timeout counter public bool Connected { get { return m_connected; } @@ -143,9 +143,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat get { return m_ircChannel; } set { m_ircChannel = value; } } - + private uint m_port = 6667; // session port - public uint Port + public uint Port { get { return m_port; } set { m_port = value; } @@ -172,10 +172,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // Network interface - private TcpClient m_tcp; + private TcpClient m_tcp; private NetworkStream m_stream = null; - private StreamReader m_reader; - private StreamWriter m_writer; + private StreamReader m_reader; + private StreamWriter m_writer; // Channel characteristic info (if available) @@ -193,26 +193,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // Prepare network interface - m_tcp = null; + m_tcp = null; m_writer = null; m_reader = null; // Setup IRC session parameters - m_server = cs.Server; - m_password = cs.Password; - m_baseNick = cs.BaseNickname; + m_server = cs.Server; + m_password = cs.Password; + m_baseNick = cs.BaseNickname; m_randomizeNick = cs.RandomizeNickname; - m_ircChannel = cs.IrcChannel; - m_port = cs.Port; - m_user = cs.User; + m_ircChannel = cs.IrcChannel; + m_port = cs.Port; + m_user = cs.User; if (m_watchdog == null) { // Non-differentiating - ICCD_PERIOD = cs.ConnectDelay; - PING_PERIOD = cs.PingDelay; + ICCD_PERIOD = cs.ConnectDelay; + PING_PERIOD = cs.PingDelay; // Smaller values are not reasonable @@ -235,7 +235,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat if (m_randomizeNick) m_nick = m_baseNick + Util.RandomClass.Next(1, 99); - else + else m_nick = m_baseNick; m_log.InfoFormat("[IRC-Connector-{0}]: Initialization complete", idn); @@ -295,18 +295,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_nick, m_ircChannel, m_server)); m_writer.Flush(); } - catch (Exception) {} - + catch (Exception) { } + m_connected = false; - try { m_writer.Close(); } catch (Exception) {} - try { m_reader.Close(); } catch (Exception) {} - try { m_stream.Close(); } catch (Exception) {} - try { m_tcp.Close(); } catch (Exception) {} + try { m_writer.Close(); } + catch (Exception) { } + try { m_reader.Close(); } + catch (Exception) { } + try { m_stream.Close(); } + catch (Exception) { } + try { m_tcp.Close(); } + catch (Exception) { } } - + lock (m_connectors) m_connectors.Remove(this); @@ -347,15 +351,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat if (m_connected) return; m_connected = true; - m_pending = true; - m_timeout = L_TIMEOUT; + m_pending = true; + m_timeout = L_TIMEOUT; - m_tcp = new TcpClient(m_server, (int)m_port); + m_tcp = new TcpClient(m_server, (int)m_port); m_stream = m_tcp.GetStream(); m_reader = new StreamReader(m_stream); m_writer = new StreamWriter(m_stream); - m_log.InfoFormat("[IRC-Connector-{0}]: Connected to {1}:{2}", idn, m_server, m_port); + m_log.InfoFormat("[IRC-Connector-{0}]: Connected to {1}:{2}", idn, m_server, m_port); m_listener = new Thread(new ThreadStart(ListenerRun)); m_listener.Name = "IRCConnectorListenerThread"; @@ -418,12 +422,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // the socket and it will disappear of its own accord, once this // processing is completed. - try { m_writer.Close(); } catch (Exception) {} - try { m_reader.Close(); } catch (Exception) {} - try { m_tcp.Close(); } catch (Exception) {} + try { m_writer.Close(); } + catch (Exception) { } + try { m_reader.Close(); } + catch (Exception) { } + try { m_tcp.Close(); } + catch (Exception) { } m_connected = false; - m_pending = false; + m_pending = false; m_resetk++; } @@ -495,7 +502,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat { string inputLine; - int resetk = m_resetk; + int resetk = m_resetk; try { @@ -555,7 +562,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat Reconnect(); } - private Regex RE = new Regex(@":(?[\w-]*)!(?\S*) PRIVMSG (?\S+) :(?.*)", + private Regex RE = new Regex(@":(?[\w-]*)!(?\S*) PRIVMSG (?\S+) :(?.*)", RegexOptions.Multiline); private Dictionary ExtractMsg(string input) @@ -617,8 +624,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat string[] commArgs; string c_server = m_server; - string pfx = String.Empty; - string cmd = String.Empty; + string pfx = String.Empty; + string cmd = String.Empty; string parms = String.Empty; // ":" indicates that a prefix is present @@ -627,15 +634,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // ":" indicates that the remainder of the // line is a single parameter value. - commArgs = command.Split(CS_SPACE,2); + commArgs = command.Split(CS_SPACE, 2); if (commArgs[0].StartsWith(":")) { pfx = commArgs[0].Substring(1); - commArgs = commArgs[1].Split(CS_SPACE,2); + commArgs = commArgs[1].Split(CS_SPACE, 2); } - cmd = commArgs[0]; + cmd = commArgs[0]; parms = commArgs[1]; // m_log.DebugFormat("[IRC-Connector-{0}] prefix = <{1}> cmd = <{2}>", idn, pfx, cmd); @@ -646,44 +653,44 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // Messages 001-004 are always sent // following signon. - case "001" : // Welcome ... - case "002" : // Server information - case "003" : // Welcome ... + case "001": // Welcome ... + case "002": // Server information + case "003": // Welcome ... break; - case "004" : // Server information + case "004": // Server information m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms); commArgs = parms.Split(CS_SPACE); c_server = commArgs[1]; m_server = c_server; - version = commArgs[2]; - usermod = commArgs[3]; - chanmod = commArgs[4]; + version = commArgs[2]; + usermod = commArgs[3]; + chanmod = commArgs[4]; break; - case "005" : // Server information + case "005": // Server information break; - case "042" : - case "250" : - case "251" : - case "252" : - case "254" : - case "255" : - case "265" : - case "266" : - case "332" : // Subject - case "333" : // Subject owner (?) - case "353" : // Name list - case "366" : // End-of-Name list marker - case "372" : // MOTD body - case "375" : // MOTD start + case "042": + case "250": + case "251": + case "252": + case "254": + case "255": + case "265": + case "266": + case "332": // Subject + case "333": // Subject owner (?) + case "353": // Name list + case "366": // End-of-Name list marker + case "372": // MOTD body + case "375": // MOTD start // m_log.InfoFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); break; - case "376" : // MOTD end + case "376": // MOTD end // m_log.InfoFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); motd = true; break; - case "451" : // Not registered + case "451": // Not registered break; - case "433" : // Nickname in use + case "433": // Nickname in use // Gen a new name m_nick = m_baseNick + Util.RandomClass.Next(1, 99); m_log.ErrorFormat("[IRC-Connector-{0}]: [{1}] IRC SERVER reports NicknameInUse, trying {2}", idn, cmd, m_nick); @@ -695,29 +702,29 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_writer.WriteLine(String.Format("JOIN {0}", m_ircChannel)); m_writer.Flush(); break; - case "479" : // Bad channel name, etc. This will never work, so disable the connection - m_log.ErrorFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); + case "479": // Bad channel name, etc. This will never work, so disable the connection + m_log.ErrorFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE, 2)[1]); m_log.ErrorFormat("[IRC-Connector-{0}] [{1}] Connector disabled", idn, cmd); - m_enabled = false; + m_enabled = false; m_connected = false; - m_pending = false; + m_pending = false; break; - case "NOTICE" : + case "NOTICE": // m_log.WarnFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); break; - case "ERROR" : - m_log.ErrorFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE,2)[1]); + case "ERROR": + m_log.ErrorFormat("[IRC-Connector-{0}] [{1}] {2}", idn, cmd, parms.Split(CS_SPACE, 2)[1]); if (parms.Contains("reconnect too fast")) ICCD_PERIOD++; - m_pending = false; + m_pending = false; Reconnect(); break; - case "PING" : + case "PING": m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms); m_writer.WriteLine(String.Format("PONG {0}", parms)); m_writer.Flush(); break; - case "PONG" : + case "PONG": break; case "JOIN": if (m_pending) @@ -748,19 +755,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms); eventIrcQuit(pfx, cmd, parms); break; - default : + default: m_log.DebugFormat("[IRC-Connector-{0}] Command '{1}' ignored, parms = {2}", idn, cmd, parms); break; } // m_log.DebugFormat("[IRC-Connector-{0}] prefix = <{1}> cmd = <{2}> complete", idn, pfx, cmd); - + } public void eventIrcJoin(string prefix, string command, string parms) { - string[] args = parms.Split(CS_SPACE,2); - string IrcUser = prefix.Split('!')[0]; + string[] args = parms.Split(CS_SPACE, 2); + string IrcUser = prefix.Split('!')[0]; string IrcChannel = args[0]; if (IrcChannel.StartsWith(":")) @@ -772,8 +779,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat public void eventIrcPart(string prefix, string command, string parms) { - string[] args = parms.Split(CS_SPACE,2); - string IrcUser = prefix.Split('!')[0]; + string[] args = parms.Split(CS_SPACE, 2); + string IrcUser = prefix.Split('!')[0]; string IrcChannel = args[0]; m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCPart {1}:{2}", idn, m_server, m_ircChannel); @@ -782,7 +789,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat public void eventIrcMode(string prefix, string command, string parms) { - string[] args = parms.Split(CS_SPACE,2); + string[] args = parms.Split(CS_SPACE, 2); string UserMode = args[1]; m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCMode {1}:{2}", idn, m_server, m_ircChannel); @@ -794,7 +801,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat public void eventIrcNickChange(string prefix, string command, string parms) { - string[] args = parms.Split(CS_SPACE,2); + string[] args = parms.Split(CS_SPACE, 2); string UserOldNick = prefix.Split('!')[0]; string UserNewNick = args[0].Remove(0, 1); @@ -804,11 +811,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat public void eventIrcKick(string prefix, string command, string parms) { - string[] args = parms.Split(CS_SPACE,3); - string UserKicker = prefix.Split('!')[0]; - string IrcChannel = args[0]; - string UserKicked = args[1]; - string KickMessage = args[2]; + string[] args = parms.Split(CS_SPACE, 3); + string UserKicker = prefix.Split('!')[0]; + string IrcChannel = args[0]; + string UserKicked = args[1]; + string KickMessage = args[2]; m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCKick {1}:{2}", idn, m_server, m_ircChannel); BroadcastSim(UserKicker, "/me kicks kicks {0} off {1} saying \"{2}\"", UserKicked, IrcChannel, KickMessage); @@ -822,7 +829,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat public void eventIrcQuit(string prefix, string command, string parms) { - string IrcUser = prefix.Split('!')[0]; + string IrcUser = prefix.Split('!')[0]; string QuitMessage = parms; m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCQuit {1}:{2}", idn, m_server, m_ircChannel); @@ -842,65 +849,65 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // m_log.InfoFormat("[IRC-Watchdog] Status scan, pdk = {0}, icc = {1}", _pdk_, _icc_); - _pdk_ = (_pdk_+1)%PING_PERIOD; // cycle the ping trigger + _pdk_ = (_pdk_ + 1) % PING_PERIOD; // cycle the ping trigger _icc_++; // increment the inter-consecutive-connect-delay counter lock (m_connectors) - foreach (IRCConnector connector in m_connectors) - { + foreach (IRCConnector connector in m_connectors) + { - // m_log.InfoFormat("[IRC-Watchdog] Scanning {0}", connector); + // m_log.InfoFormat("[IRC-Watchdog] Scanning {0}", connector); - if (connector.Enabled) - { - if (!connector.Connected) + if (connector.Enabled) { - try + if (!connector.Connected) { - // m_log.DebugFormat("[IRC-Watchdog] Connecting {1}:{2}", connector.idn, connector.m_server, connector.m_ircChannel); - connector.Connect(); + try + { + // m_log.DebugFormat("[IRC-Watchdog] Connecting {1}:{2}", connector.idn, connector.m_server, connector.m_ircChannel); + connector.Connect(); + } + catch (Exception e) + { + m_log.ErrorFormat("[IRC-Watchdog] Exception on connector {0}: {1} ", connector.idn, e.Message); + } } - catch (Exception e) + else { - m_log.ErrorFormat("[IRC-Watchdog] Exception on connector {0}: {1} ", connector.idn, e.Message); - } - } - else - { - if (connector.m_pending) - { - if (connector.m_timeout == 0) + if (connector.m_pending) { - m_log.ErrorFormat("[IRC-Watchdog] Login timed-out for connector {0}, reconnecting", connector.idn); - connector.Reconnect(); + if (connector.m_timeout == 0) + { + m_log.ErrorFormat("[IRC-Watchdog] Login timed-out for connector {0}, reconnecting", connector.idn); + connector.Reconnect(); + } + else + connector.m_timeout--; } - else - connector.m_timeout--; - } - // Being marked connected is not enough to ping. Socket establishment can sometimes take a long - // time, in which case the watch dog might try to ping the server before the socket has been - // set up, with nasty side-effects. + // Being marked connected is not enough to ping. Socket establishment can sometimes take a long + // time, in which case the watch dog might try to ping the server before the socket has been + // set up, with nasty side-effects. - else if (_pdk_ == 0) - { - try - { - connector.m_writer.WriteLine(String.Format("PING :{0}", connector.m_server)); - connector.m_writer.Flush(); - } - catch (Exception e) + else if (_pdk_ == 0) { - m_log.ErrorFormat("[IRC-PingRun] Exception on connector {0}: {1} ", connector.idn, e.Message); - m_log.Debug(e); - connector.Reconnect(); + try + { + connector.m_writer.WriteLine(String.Format("PING :{0}", connector.m_server)); + connector.m_writer.Flush(); + } + catch (Exception e) + { + m_log.ErrorFormat("[IRC-PingRun] Exception on connector {0}: {1} ", connector.idn, e.Message); + m_log.Debug(e); + connector.Reconnect(); + } } - } + } } } - } // m_log.InfoFormat("[IRC-Watchdog] Status scan completed"); diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs index 53b103e..d4fe5e0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs @@ -41,49 +41,71 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat internal class RegionState { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly OpenMetaverse.Vector3 CenterOfRegion = new OpenMetaverse.Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 20); - private const int DEBUG_CHANNEL = 2147483647; + private const int DEBUG_CHANNEL = 2147483647; - private static int _idk_ = 0; + private static int _idk_ = 0; // Runtime variables; these values are assigned when the // IrcState is created and remain constant thereafter. - internal string Region = String.Empty; - internal string Host = String.Empty; - internal string LocX = String.Empty; - internal string LocY = String.Empty; - internal string IDK = String.Empty; + internal string Region = String.Empty; + internal string Host = String.Empty; + internal string LocX = String.Empty; + internal string LocY = String.Empty; + internal string IDK = String.Empty; // System values - used only be the IRC classes themselves - internal ChannelState cs = null; // associated IRC configuration - internal Scene scene = null; // associated scene - internal IConfig config = null; // configuration file reference - internal bool enabled = true; - + internal ChannelState cs = null; // associated IRC configuration + internal Scene scene = null; // associated scene + internal IConfig config = null; // configuration file reference + internal bool enabled = true; + + //AgentAlert + internal bool showAlert = false; + internal string alertMessage = String.Empty; + internal IDialogModule dialogModule = null; + // This list is used to keep track of who is here, and by // implication, who is not. - internal List clients = new List(); + internal List clients = new List(); // Setup runtime variable values public RegionState(Scene p_scene, IConfig p_config) { - - scene = p_scene; + scene = p_scene; config = p_config; Region = scene.RegionInfo.RegionName; - Host = scene.RegionInfo.ExternalHostName; - LocX = Convert.ToString(scene.RegionInfo.RegionLocX); - LocY = Convert.ToString(scene.RegionInfo.RegionLocY); - IDK = Convert.ToString(_idk_++); + Host = scene.RegionInfo.ExternalHostName; + LocX = Convert.ToString(scene.RegionInfo.RegionLocX); + LocY = Convert.ToString(scene.RegionInfo.RegionLocY); + IDK = Convert.ToString(_idk_++); + + showAlert = config.GetBoolean("alert_show", false); + string alertServerInfo = String.Empty; + + if (showAlert) + { + bool showAlertServerInfo = config.GetBoolean("alert_show_serverinfo", true); + + if (showAlertServerInfo) + alertServerInfo = String.Format("\nServer: {0}\nPort: {1}\nChannel: {2}\n\n", + config.GetString("server", ""), config.GetString("port", ""), config.GetString("channel", "")); + + string alertPreMessage = config.GetString("alert_msg_pre", "This region is linked to Irc."); + string alertPostMessage = config.GetString("alert_msg_post", "Everything you say in public chat can be listened."); + + alertMessage = String.Format("{0}\n{1}{2}", alertPreMessage, alertServerInfo, alertPostMessage); + + dialogModule = scene.RequestModuleInterface(); + } // OpenChannel conditionally establishes a connection to the // IRC server. The request will either succeed, or it will @@ -93,9 +115,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // Connect channel to world events - scene.EventManager.OnChatFromWorld += OnSimChat; + scene.EventManager.OnChatFromWorld += OnSimChat; scene.EventManager.OnChatFromClient += OnSimChat; - scene.EventManager.OnMakeRootAgent += OnMakeRootAgent; + scene.EventManager.OnMakeRootAgent += OnMakeRootAgent; scene.EventManager.OnMakeChildAgent += OnMakeChildAgent; m_log.InfoFormat("[IRC-Region {0}] Initialization complete", Region); @@ -106,8 +128,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat ~RegionState() { - if (cs != null) - cs.RemoveRegion(this); + if (cs != null) + cs.RemoveRegion(this); } // Called by PostInitialize after all regions have been created @@ -138,7 +160,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat { if (clients.Contains(client)) { - if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting)) + if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting)) { m_log.InfoFormat("[IRC-Region {0}]: {1} has left", Region, client.Name); //Check if this person is excluded from IRC @@ -147,7 +169,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat cs.irc.PrivMsg(cs.NoticeMessageFormat, cs.irc.Nick, Region, String.Format("{0} has left", client.Name)); } } - client.OnLogout -= OnClientLoggedOut; + client.OnLogout -= OnClientLoggedOut; client.OnConnectionClosed -= OnClientLoggedOut; clients.Remove(client); } @@ -171,13 +193,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat { if (clients.Contains(client)) { - if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting)) + if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting)) { string clientName = String.Format("{0} {1}", presence.Firstname, presence.Lastname); m_log.DebugFormat("[IRC-Region {0}] {1} has left", Region, clientName); cs.irc.PrivMsg(cs.NoticeMessageFormat, cs.irc.Nick, Region, String.Format("{0} has left", clientName)); } - client.OnLogout -= OnClientLoggedOut; + client.OnLogout -= OnClientLoggedOut; client.OnConnectionClosed -= OnClientLoggedOut; clients.Remove(client); } @@ -195,14 +217,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat private void OnMakeRootAgent(ScenePresence presence) { - IClientAPI client = presence.ControllingClient; try { if (!clients.Contains(client)) { - client.OnLogout += OnClientLoggedOut; + client.OnLogout += OnClientLoggedOut; client.OnConnectionClosed += OnClientLoggedOut; clients.Add(client); if (enabled && (cs.irc.Enabled) && (cs.irc.Connected) && (cs.ClientReporting)) @@ -216,17 +237,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat } } } + + if (dialogModule != null && showAlert) + dialogModule.SendAlertToUser(client, alertMessage, true); } catch (Exception ex) { m_log.ErrorFormat("[IRC-Region {0}]: MakeRootAgent exception: {1}", Region, ex.Message); m_log.Debug(ex); } - } // This handler detects chat events int he virtual world. - public void OnSimChat(Object sender, OSChatMessage msg) { @@ -317,14 +339,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat // that evident. default: - m_log.DebugFormat("[IRC-Region {0}] Forwarding unrecognized command to IRC : {1}", + m_log.DebugFormat("[IRC-Region {0}] Forwarding unrecognized command to IRC : {1}", Region, msg.Message); cs.irc.Send(msg.Message); break; } } catch (Exception ex) - { + { m_log.WarnFormat("[IRC-Region {0}] error processing in-world command channel input: {1}", Region, ex.Message); m_log.Debug(ex); @@ -366,7 +388,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_log.DebugFormat("[IRC-Region {0}] heard on channel {1} : {2}", Region, msg.Channel, msg.Message); - if (null != avatar && cs.RelayChat && (msg.Channel == 0 || msg.Channel == DEBUG_CHANNEL)) + if (null != avatar && cs.RelayChat && (msg.Channel == 0 || msg.Channel == DEBUG_CHANNEL)) { string txt = msg.Message; if (txt.StartsWith("/me ")) @@ -376,13 +398,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat return; } - if (null == avatar && cs.RelayPrivateChannels && null != cs.AccessPassword && + if (null == avatar && cs.RelayPrivateChannels && null != cs.AccessPassword && msg.Channel == cs.RelayChannelOut) { Match m = cs.AccessPasswordRegex.Match(msg.Message); if (null != m) { - m_log.DebugFormat("[IRC] relaying message from {0}: {1}", m.Groups["avatar"].ToString(), + m_log.DebugFormat("[IRC] relaying message from {0}: {1}", m.Groups["avatar"].ToString(), m.Groups["message"].ToString()); cs.irc.PrivMsg(cs.PrivateMessageFormat, m.Groups["avatar"].ToString(), scene.RegionInfo.RegionName, m.Groups["message"].ToString()); -- cgit v1.1 From 82b954b2125acf3c3647422fbbe543e96b6d4e91 Mon Sep 17 00:00:00 2001 From: teravus Date: Sun, 20 Jan 2013 08:06:15 -0500 Subject: * Tweak the BulletSimN API a bit. --- OpenSim/Region/Physics/BulletSNPlugin/BSScene.cs | 8 +++---- .../Region/Physics/BulletSNPlugin/BulletSimAPI.cs | 27 +++++++++++----------- 2 files changed, 18 insertions(+), 17 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSScene.cs index 1a7c34b..4fc3e2a 100644 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSNPlugin/BSScene.cs @@ -106,11 +106,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // Pinned memory used to pass step information between managed and unmanaged internal int m_maxCollisionsPerFrame; - private List m_collisionArray; + private BulletXNA.CollisionDesc[] m_collisionArray; //private GCHandle m_collisionArrayPinnedHandle; internal int m_maxUpdatesPerFrame; - private List m_updateArray; + private BulletXNA.EntityProperties[] m_updateArray; //private GCHandle m_updateArrayPinnedHandle; @@ -201,9 +201,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters GetInitialParameterValues(config); // allocate more pinned memory close to the above in an attempt to get the memory all together - m_collisionArray = new List(); + m_collisionArray = new BulletXNA.CollisionDesc[0]; //m_collisionArrayPinnedHandle = GCHandle.Alloc(m_collisionArray, GCHandleType.Pinned); - m_updateArray = new List(); + m_updateArray = new BulletXNA.EntityProperties[0]; //m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned); // Enable very detailed logging. diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSNPlugin/BulletSimAPI.cs index 93643c9..ba96905 100644 --- a/OpenSim/Region/Physics/BulletSNPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSNPlugin/BulletSimAPI.cs @@ -894,7 +894,7 @@ static class BulletSimAPI { return capsuleShapeZ; } - public static object Initialize2(Vector3 worldExtent, ConfigurationParameters[] o, int mMaxCollisionsPerFrame, ref List collisionArray, int mMaxUpdatesPerFrame, ref List updateArray, object mDebugLogCallbackHandle) + public static object Initialize2(Vector3 worldExtent, ConfigurationParameters[] o, int mMaxCollisionsPerFrame, ref BulletXNA.CollisionDesc[] collisionArray, int mMaxUpdatesPerFrame, ref BulletXNA.EntityProperties[] updateArray, object mDebugLogCallbackHandle) { CollisionWorld.WorldData.ParamData p = new CollisionWorld.WorldData.ParamData(); @@ -1436,14 +1436,14 @@ static class BulletSimAPI { } - internal static int PhysicsStep2(object pWorld, float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount, out List updatedEntities, out int collidersCount, out Listcolliders) + internal static int PhysicsStep2(object pWorld, float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount, out BulletXNA.EntityProperties[] updatedEntities, out int collidersCount, out BulletXNA.CollisionDesc[] colliders) { int epic = PhysicsStepint2(pWorld, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out updatedEntities, out collidersCount, out colliders); return epic; } - private static int PhysicsStepint2(object pWorld,float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount, out List updatedEntities, out int collidersCount, out List colliders) + private static int PhysicsStepint2(object pWorld,float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount, out BulletXNA.EntityProperties[] updatedEntities, out int collidersCount, out BulletXNA.CollisionDesc[] colliders) { int numSimSteps = 0; @@ -1462,16 +1462,16 @@ static class BulletSimAPI { numSimSteps = world.StepSimulation(timeStep, m_maxSubSteps, m_fixedTimeStep); int updates = 0; - updatedEntityCount = world.UpdatedObjects.Count; - updatedEntities = new List(world.UpdatedObjects); - updatedEntityCount = updatedEntities.Count; - world.UpdatedObjects.Clear(); + updatedEntityCount = world.UpdatedObjects.Length; + updatedEntities = (world.UpdatedObjects); + updatedEntityCount = updatedEntities.Length; + //world.UpdatedObjects = ; - collidersCount = world.UpdatedCollisions.Count; - colliders = new List(world.UpdatedCollisions); + collidersCount = world.UpdatedCollisions.Length; + colliders = (world.UpdatedCollisions); - world.UpdatedCollisions.Clear(); + world.UpdatedCollisions = new BulletXNA.CollisionDesc[0]; m_collisionsThisFrame = 0; int numManifolds = world.GetDispatcher().GetNumManifolds(); for (int j = 0; j < numManifolds; j++) @@ -1501,10 +1501,10 @@ static class BulletSimAPI { else { //if (updatedEntities is null) - updatedEntities = new List(); + updatedEntities = new BulletXNA.EntityProperties[0]; updatedEntityCount = 0; //if (colliders is null) - colliders = new List(); + colliders = new BulletXNA.CollisionDesc[0]; collidersCount = 0; } return numSimSteps; @@ -1538,7 +1538,8 @@ static class BulletSimAPI { point = contact, normal = contactNormal }; - world.UpdatedCollisions.Add(cDesc); + if (world.LastCollisionDesc < world.UpdatedCollisions.Length) + world.UpdatedCollisions[world.LastCollisionDesc++] = (cDesc); m_collisionsThisFrame++; -- cgit v1.1 From 6a75949323dedce1e141190cc90175f04afdad0a Mon Sep 17 00:00:00 2001 From: teravus Date: Sun, 20 Jan 2013 08:07:49 -0500 Subject: * Dumping BulletSimNPlugin in favor of combining the API --- .../Region/Physics/BulletSNPlugin/BSCharacter.cs | 814 ---------- .../Region/Physics/BulletSNPlugin/BSConstraint.cs | 135 -- .../Physics/BulletSNPlugin/BSConstraint6Dof.cs | 153 -- .../BulletSNPlugin/BSConstraintCollection.cs | 180 --- .../Physics/BulletSNPlugin/BSConstraintHinge.cs | 57 - .../Region/Physics/BulletSNPlugin/BSDynamics.cs | 1377 ----------------- OpenSim/Region/Physics/BulletSNPlugin/BSLinkset.cs | 329 ---- .../Physics/BulletSNPlugin/BSLinksetCompound.cs | 397 ----- .../Physics/BulletSNPlugin/BSLinksetConstraints.cs | 316 ---- .../Region/Physics/BulletSNPlugin/BSMaterials.cs | 200 --- OpenSim/Region/Physics/BulletSNPlugin/BSMotors.cs | 347 ----- OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs | 559 ------- .../Region/Physics/BulletSNPlugin/BSPhysObject.cs | 346 ----- OpenSim/Region/Physics/BulletSNPlugin/BSPlugin.cs | 81 - OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs | 1494 ------------------ OpenSim/Region/Physics/BulletSNPlugin/BSScene.cs | 957 ------------ .../Physics/BulletSNPlugin/BSShapeCollection.cs | 1015 ------------- OpenSim/Region/Physics/BulletSNPlugin/BSShapes.cs | 208 --- .../Physics/BulletSNPlugin/BSTerrainHeightmap.cs | 175 --- .../Physics/BulletSNPlugin/BSTerrainManager.cs | 461 ------ .../Region/Physics/BulletSNPlugin/BSTerrainMesh.cs | 267 ---- .../Region/Physics/BulletSNPlugin/BulletSimAPI.cs | 1604 -------------------- .../Region/Physics/BulletSNPlugin/BulletSimData.cs | 280 ---- 23 files changed, 11752 deletions(-) delete mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSCharacter.cs delete mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSConstraint.cs delete mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSConstraint6Dof.cs delete mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSConstraintCollection.cs delete mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSConstraintHinge.cs delete mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSDynamics.cs delete mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSLinkset.cs delete mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSLinksetCompound.cs delete mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSLinksetConstraints.cs delete mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSMaterials.cs delete mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSMotors.cs delete mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs delete mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSPhysObject.cs delete mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSPlugin.cs delete mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs delete mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSScene.cs delete mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSShapeCollection.cs delete mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSShapes.cs delete mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSTerrainHeightmap.cs delete mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSTerrainManager.cs delete mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BSTerrainMesh.cs delete mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BulletSimAPI.cs delete mode 100644 OpenSim/Region/Physics/BulletSNPlugin/BulletSimData.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSCharacter.cs deleted file mode 100644 index d91c47f..0000000 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSCharacter.cs +++ /dev/null @@ -1,814 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Reflection; -using log4net; -using OMV = OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Region.Physics.Manager; - -namespace OpenSim.Region.Physics.BulletSNPlugin -{ -public sealed class BSCharacter : BSPhysObject -{ - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private static readonly string LogHeader = "[BULLETS CHAR]"; - - // private bool _stopped; - private OMV.Vector3 _size; - private bool _grabbed; - private bool _selected; - private OMV.Vector3 _position; - private float _mass; - private float _avatarDensity; - private float _avatarVolume; - private OMV.Vector3 _force; - private OMV.Vector3 _velocity; - private OMV.Vector3 _torque; - private float _collisionScore; - private OMV.Vector3 _acceleration; - private OMV.Quaternion _orientation; - private int _physicsActorType; - private bool _isPhysical; - private bool _flying; - private bool _setAlwaysRun; - private bool _throttleUpdates; - private bool _isColliding; - private bool _collidingObj; - private bool _floatOnWater; - private OMV.Vector3 _rotationalVelocity; - private bool _kinematic; - private float _buoyancy; - - // The friction and velocity of the avatar is modified depending on whether walking or not. - private OMV.Vector3 _appliedVelocity; // the last velocity applied to the avatar - private float _currentFriction; // the friction currently being used (changed by setVelocity). - - private BSVMotor _velocityMotor; - - private OMV.Vector3 _PIDTarget; - private bool _usePID; - private float _PIDTau; - private bool _useHoverPID; - private float _PIDHoverHeight; - private PIDHoverType _PIDHoverType; - private float _PIDHoverTao; - - public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying) - : base(parent_scene, localID, avName, "BSCharacter") - { - _physicsActorType = (int)ActorTypes.Agent; - _position = pos; - - // Old versions of ScenePresence passed only the height. If width and/or depth are zero, - // replace with the default values. - _size = size; - if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth; - if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth; - - // A motor to control the acceleration and deceleration of the avatar movement. - // _velocityMotor = new BSVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); - // _velocityMotor = new BSPIDVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); - // Infinite decay and timescale values so motor only changes current to target values. - _velocityMotor = new BSVMotor("BSCharacter.Velocity", - 0.2f, // time scale - BSMotor.Infinite, // decay time scale - BSMotor.InfiniteVector, // friction timescale - 1f // efficiency - ); - _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages. - - _flying = isFlying; - _orientation = OMV.Quaternion.Identity; - _velocity = OMV.Vector3.Zero; - _appliedVelocity = OMV.Vector3.Zero; - _buoyancy = ComputeBuoyancyFromFlying(isFlying); - _currentFriction = BSParam.AvatarStandingFriction; - _avatarDensity = BSParam.AvatarDensity; - - // The dimensions of the avatar capsule are kept in the scale. - // Physics creates a unit capsule which is scaled by the physics engine. - ComputeAvatarScale(_size); - // set _avatarVolume and _mass based on capsule size, _density and Scale - ComputeAvatarVolumeAndMass(); - DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}", - LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass); - - // do actual creation in taint time - PhysicsScene.TaintedObject("BSCharacter.create", delegate() - { - DetailLog("{0},BSCharacter.create,taint", LocalID); - // New body and shape into PhysBody and PhysShape - PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this); - - SetPhysicalProperties(); - }); - return; - } - - // called when this character is being destroyed and the resources should be released - public override void Destroy() - { - base.Destroy(); - - DetailLog("{0},BSCharacter.Destroy", LocalID); - PhysicsScene.TaintedObject("BSCharacter.destroy", delegate() - { - PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null); - PhysBody.Clear(); - PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null); - PhysShape.Clear(); - }); - } - - private void SetPhysicalProperties() - { - BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr); - - ZeroMotion(true); - ForcePosition = _position; - // Set the velocity and compute the proper friction - ForceVelocity = _velocity; - // Setting the current and target in the motor will cause it to start computing any deceleration. - _velocityMotor.Reset(); - _velocityMotor.SetCurrent(_velocity); - _velocityMotor.SetTarget(_velocity); - _velocityMotor.Enabled = false; - - // This will enable or disable the flying buoyancy of the avatar. - // Needs to be reset especially when an avatar is recreated after crossing a region boundry. - Flying = _flying; - - BulletSimAPI.SetRestitution2(PhysBody.ptr, BSParam.AvatarRestitution); - BulletSimAPI.SetMargin2(PhysShape.ptr, PhysicsScene.Params.collisionMargin); - BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale); - BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, BSParam.ContactProcessingThreshold); - if (BSParam.CcdMotionThreshold > 0f) - { - BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, BSParam.CcdMotionThreshold); - BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius); - } - - UpdatePhysicalMassProperties(RawMass, false); - - // Make so capsule does not fall over - BulletSimAPI.SetAngularFactorV2(PhysBody.ptr, OMV.Vector3.Zero); - - BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_CHARACTER_OBJECT); - - BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr, _position, _orientation); - - // BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.ACTIVE_TAG); - BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.DISABLE_DEACTIVATION); - BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); - - // Do this after the object has been added to the world - PhysBody.collisionType = CollisionType.Avatar; - PhysBody.ApplyCollisionMask(); - } - - public override void RequestPhysicsterseUpdate() - { - base.RequestPhysicsterseUpdate(); - } - // No one calls this method so I don't know what it could possibly mean - public override bool Stopped { get { return false; } } - - public override OMV.Vector3 Size { - get - { - // Avatar capsule size is kept in the scale parameter. - return _size; - } - - set { - // When an avatar's size is set, only the height is changed. - _size = value; - // Old versions of ScenePresence passed only the height. If width and/or depth are zero, - // replace with the default values. - if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth; - if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth; - - ComputeAvatarScale(_size); - ComputeAvatarVolumeAndMass(); - DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}", - LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass); - - PhysicsScene.TaintedObject("BSCharacter.setSize", delegate() - { - if (PhysBody.HasPhysicalBody && PhysShape.HasPhysicalShape) - { - BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale); - UpdatePhysicalMassProperties(RawMass, true); - // Make sure this change appears as a property update event - BulletSimAPI.PushUpdate2(PhysBody.ptr); - } - }); - - } - } - - public override PrimitiveBaseShape Shape - { - set { BaseShape = value; } - } - // I want the physics engine to make an avatar capsule - public override BSPhysicsShapeType PreferredPhysicalShape - { - get {return BSPhysicsShapeType.SHAPE_CAPSULE; } - } - - public override bool Grabbed { - set { _grabbed = value; } - } - public override bool Selected { - set { _selected = value; } - } - public override void CrossingFailure() { return; } - public override void link(PhysicsActor obj) { return; } - public override void delink() { return; } - - // Set motion values to zero. - // Do it to the properties so the values get set in the physics engine. - // Push the setting of the values to the viewer. - // Called at taint time! - public override void ZeroMotion(bool inTaintTime) - { - _velocity = OMV.Vector3.Zero; - _acceleration = OMV.Vector3.Zero; - _rotationalVelocity = OMV.Vector3.Zero; - - // Zero some other properties directly into the physics engine - PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate() - { - if (PhysBody.HasPhysicalBody) - BulletSimAPI.ClearAllForces2(PhysBody.ptr); - }); - } - public override void ZeroAngularMotion(bool inTaintTime) - { - _rotationalVelocity = OMV.Vector3.Zero; - - PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate() - { - if (PhysBody.HasPhysicalBody) - { - BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero); - BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero); - // The next also get rid of applied linear force but the linear velocity is untouched. - BulletSimAPI.ClearForces2(PhysBody.ptr); - } - }); - } - - - public override void LockAngularMotion(OMV.Vector3 axis) { return; } - - public override OMV.Vector3 RawPosition - { - get { return _position; } - set { _position = value; } - } - public override OMV.Vector3 Position { - get { - // Don't refetch the position because this function is called a zillion times - // _position = BulletSimAPI.GetObjectPosition2(Scene.World.ptr, LocalID); - return _position; - } - set { - _position = value; - PositionSanityCheck(); - - PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate() - { - DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); - if (PhysBody.HasPhysicalBody) - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); - }); - } - } - public override OMV.Vector3 ForcePosition { - get { - _position = BulletSimAPI.GetPosition2(PhysBody.ptr); - return _position; - } - set { - _position = value; - PositionSanityCheck(); - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); - } - } - - - // Check that the current position is sane and, if not, modify the position to make it so. - // Check for being below terrain or on water. - // Returns 'true' of the position was made sane by some action. - private bool PositionSanityCheck() - { - bool ret = false; - - // TODO: check for out of bounds - if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position)) - { - // The character is out of the known/simulated area. - // Upper levels of code will handle the transition to other areas so, for - // the time, we just ignore the position. - return ret; - } - - // If below the ground, move the avatar up - float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); - if (Position.Z < terrainHeight) - { - DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); - _position.Z = terrainHeight + 2.0f; - ret = true; - } - if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) - { - float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(_position); - if (Position.Z < waterHeight) - { - _position.Z = waterHeight; - ret = true; - } - } - - return ret; - } - - // A version of the sanity check that also makes sure a new position value is - // pushed back to the physics engine. This routine would be used by anyone - // who is not already pushing the value. - private bool PositionSanityCheck(bool inTaintTime) - { - bool ret = false; - if (PositionSanityCheck()) - { - // The new position value must be pushed into the physics engine but we can't - // just assign to "Position" because of potential call loops. - PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.PositionSanityCheck", delegate() - { - DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); - if (PhysBody.HasPhysicalBody) - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); - }); - ret = true; - } - return ret; - } - - public override float Mass { get { return _mass; } } - - // used when we only want this prim's mass and not the linkset thing - public override float RawMass { - get {return _mass; } - } - public override void UpdatePhysicalMassProperties(float physMass, bool inWorld) - { - OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass); - BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, localInertia); - } - - public override OMV.Vector3 Force { - get { return _force; } - set { - _force = value; - // m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force); - PhysicsScene.TaintedObject("BSCharacter.SetForce", delegate() - { - DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force); - if (PhysBody.HasPhysicalBody) - BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force); - }); - } - } - - public bool TouchingGround() - { - bool ret = BulletSimAPI.RayCastGround(PhysicsScene.World.ptr,_position,_size.Z * 0.55f, PhysBody.ptr); - return ret; - } - // Avatars don't do vehicles - public override int VehicleType { get { return (int)Vehicle.TYPE_NONE; } set { return; } } - public override void VehicleFloatParam(int param, float value) { } - public override void VehicleVectorParam(int param, OMV.Vector3 value) {} - public override void VehicleRotationParam(int param, OMV.Quaternion rotation) { } - public override void VehicleFlags(int param, bool remove) { } - - // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more - public override void SetVolumeDetect(int param) { return; } - - public override OMV.Vector3 GeometricCenter { get { return OMV.Vector3.Zero; } } - public override OMV.Vector3 CenterOfMass { get { return OMV.Vector3.Zero; } } - - // Sets the target in the motor. This starts the changing of the avatar's velocity. - public override OMV.Vector3 TargetVelocity - { - get - { - return _velocityMotor.TargetValue; - } - set - { - DetailLog("{0},BSCharacter.setTargetVelocity,call,vel={1}", LocalID, value); - - if (!_flying) - if ((value.Z >= 0.0001f) || (value.Z <= -0.0001f) || _velocity.Z < -0.0001f) - if (!TouchingGround()) - value.Z = _velocity.Z; - if (_setAlwaysRun) - value *= 1.3f; - - OMV.Vector3 targetVel = value; - - PhysicsScene.TaintedObject("BSCharacter.setTargetVelocity", delegate() - { - - _velocityMotor.Reset(); - _velocityMotor.SetTarget(targetVel); - _velocityMotor.SetCurrent(_velocity); - _velocityMotor.Enabled = true; - - // Make sure a property update happens next step so the motor gets incorporated. - BulletSimAPI.PushUpdate2(PhysBody.ptr); - }); - } - } - // Directly setting velocity means this is what the user really wants now. - public override OMV.Vector3 Velocity { - get { return _velocity; } - set { - _velocity = value; - // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity); - PhysicsScene.TaintedObject("BSCharacter.setVelocity", delegate() - { - _velocityMotor.Reset(); - _velocityMotor.SetCurrent(_velocity); - _velocityMotor.SetTarget(_velocity); - // Even though the motor is initialized, it's not used and the velocity goes straight into the avatar. - _velocityMotor.Enabled = false; - - DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity); - ForceVelocity = _velocity; - }); - } - } - public override OMV.Vector3 ForceVelocity { - get { return _velocity; } - set { - PhysicsScene.AssertInTaintTime("BSCharacter.ForceVelocity"); - - _velocity = value; - // Depending on whether the avatar is moving or not, change the friction - // to keep the avatar from slipping around - if (_velocity.Length() == 0) - { - if (_currentFriction != BSParam.AvatarStandingFriction) - { - _currentFriction = BSParam.AvatarStandingFriction; - if (PhysBody.HasPhysicalBody) - BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction); - } - } - else - { - if (_currentFriction != BSParam.AvatarFriction) - { - _currentFriction = BSParam.AvatarFriction; - if (PhysBody.HasPhysicalBody) - BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction); - } - } - // Remember the set velocity so we can suppress the reduction by friction, ... - _appliedVelocity = value; - - BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); - BulletSimAPI.Activate2(PhysBody.ptr, true); - } - } - public override OMV.Vector3 Torque { - get { return _torque; } - set { _torque = value; - } - } - public override float CollisionScore { - get { return _collisionScore; } - set { _collisionScore = value; - } - } - public override OMV.Vector3 Acceleration { - get { return _acceleration; } - set { _acceleration = value; } - } - public override OMV.Quaternion RawOrientation - { - get { return _orientation; } - set { _orientation = value; } - } - public override OMV.Quaternion Orientation { - get { return _orientation; } - set { - _orientation = value; - // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation); - PhysicsScene.TaintedObject("BSCharacter.setOrientation", delegate() - { - if (PhysBody.HasPhysicalBody) - { - // _position = BulletSimAPI.GetPosition2(BSBody.ptr); - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); - } - }); - } - } - // Go directly to Bullet to get/set the value. - public override OMV.Quaternion ForceOrientation - { - get - { - _orientation = BulletSimAPI.GetOrientation2(PhysBody.ptr); - return _orientation; - } - set - { - _orientation = value; - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); - } - } - public override int PhysicsActorType { - get { return _physicsActorType; } - set { _physicsActorType = value; - } - } - public override bool IsPhysical { - get { return _isPhysical; } - set { _isPhysical = value; - } - } - public override bool IsSolid { - get { return true; } - } - public override bool IsStatic { - get { return false; } - } - public override bool Flying { - get { return _flying; } - set { - _flying = value; - - // simulate flying by changing the effect of gravity - Buoyancy = ComputeBuoyancyFromFlying(_flying); - } - } - // Flying is implimented by changing the avatar's buoyancy. - // Would this be done better with a vehicle type? - private float ComputeBuoyancyFromFlying(bool ifFlying) { - return ifFlying ? 1f : 0f; - } - public override bool - SetAlwaysRun { - get { return _setAlwaysRun; } - set { _setAlwaysRun = value; } - } - public override bool ThrottleUpdates { - get { return _throttleUpdates; } - set { _throttleUpdates = value; } - } - public override bool IsColliding { - get { return (CollidingStep == PhysicsScene.SimulationStep); } - set { _isColliding = value; } - } - public override bool CollidingGround { - get { return (CollidingGroundStep == PhysicsScene.SimulationStep); } - set { CollidingGround = value; } - } - public override bool CollidingObj { - get { return _collidingObj; } - set { _collidingObj = value; } - } - public override bool FloatOnWater { - set { - _floatOnWater = value; - PhysicsScene.TaintedObject("BSCharacter.setFloatOnWater", delegate() - { - if (PhysBody.HasPhysicalBody) - { - if (_floatOnWater) - CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); - else - CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); - } - }); - } - } - public override OMV.Vector3 RotationalVelocity { - get { return _rotationalVelocity; } - set { _rotationalVelocity = value; } - } - public override OMV.Vector3 ForceRotationalVelocity { - get { return _rotationalVelocity; } - set { _rotationalVelocity = value; } - } - public override bool Kinematic { - get { return _kinematic; } - set { _kinematic = value; } - } - // neg=fall quickly, 0=1g, 1=0g, pos=float up - public override float Buoyancy { - get { return _buoyancy; } - set { _buoyancy = value; - PhysicsScene.TaintedObject("BSCharacter.setBuoyancy", delegate() - { - DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy); - ForceBuoyancy = _buoyancy; - }); - } - } - public override float ForceBuoyancy { - get { return _buoyancy; } - set { - PhysicsScene.AssertInTaintTime("BSCharacter.ForceBuoyancy"); - - _buoyancy = value; - DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); - // Buoyancy is faked by changing the gravity applied to the object - float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); - if (PhysBody.HasPhysicalBody) - BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav)); - } - } - - // Used for MoveTo - public override OMV.Vector3 PIDTarget { - set { _PIDTarget = value; } - } - public override bool PIDActive { - set { _usePID = value; } - } - public override float PIDTau { - set { _PIDTau = value; } - } - - // Used for llSetHoverHeight and maybe vehicle height - // Hover Height will override MoveTo target's Z - public override bool PIDHoverActive { - set { _useHoverPID = value; } - } - public override float PIDHoverHeight { - set { _PIDHoverHeight = value; } - } - public override PIDHoverType PIDHoverType { - set { _PIDHoverType = value; } - } - public override float PIDHoverTau { - set { _PIDHoverTao = value; } - } - - // For RotLookAt - public override OMV.Quaternion APIDTarget { set { return; } } - public override bool APIDActive { set { return; } } - public override float APIDStrength { set { return; } } - public override float APIDDamping { set { return; } } - - public override void AddForce(OMV.Vector3 force, bool pushforce) { - if (force.IsFinite()) - { - _force.X += force.X; - _force.Y += force.Y; - _force.Z += force.Z; - // m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force); - PhysicsScene.TaintedObject("BSCharacter.AddForce", delegate() - { - DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force); - if (PhysBody.HasPhysicalBody) - BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force); - }); - } - else - { - m_log.ErrorFormat("{0}: Got a NaN force applied to a Character", LogHeader); - } - //m_lastUpdateSent = false; - } - - public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { - } - public override void SetMomentum(OMV.Vector3 momentum) { - } - - private void ComputeAvatarScale(OMV.Vector3 size) - { - OMV.Vector3 newScale = size; - // newScale.X = PhysicsScene.Params.avatarCapsuleWidth; - // newScale.Y = PhysicsScene.Params.avatarCapsuleDepth; - - // From the total height, remove the capsule half spheres that are at each end - // The 1.15f came from ODE. Not sure what this factors in. - // newScale.Z = (size.Z * 1.15f) - (newScale.X + newScale.Y); - - // The total scale height is the central cylindar plus the caps on the two ends. - newScale.Z = size.Z + (Math.Min(size.X, size.Y) * 2f); - - // Convert diameters to radii and height to half height -- the way Bullet expects it. - Scale = newScale / 2f; - } - - // set _avatarVolume and _mass based on capsule size, _density and Scale - private void ComputeAvatarVolumeAndMass() - { - _avatarVolume = (float)( - Math.PI - * Scale.X - * Scale.Y // the area of capsule cylinder - * Scale.Z // times height of capsule cylinder - + 1.33333333f - * Math.PI - * Scale.X - * Math.Min(Scale.X, Scale.Y) - * Scale.Y // plus the volume of the capsule end caps - ); - _mass = _avatarDensity * _avatarVolume; - } - - // The physics engine says that properties have updated. Update same and inform - // the world that things have changed. - public override void UpdateProperties(EntityProperties entprop) - { - _position = entprop.Position; - _orientation = entprop.Rotation; - _velocity = entprop.Velocity; - _acceleration = entprop.Acceleration; - _rotationalVelocity = entprop.RotationalVelocity; - - // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. - PositionSanityCheck(true); - - if (_velocityMotor.Enabled) - { - // TODO: Decide if the step parameters should be changed depending on the avatar's - // state (flying, colliding, ...). - - OMV.Vector3 stepVelocity = _velocityMotor.Step(PhysicsScene.LastTimeStep); - - // If falling, we keep the world's downward vector no matter what the other axis specify. - if (!Flying && !IsColliding) - { - stepVelocity.Z = entprop.Velocity.Z; - DetailLog("{0},BSCharacter.UpdateProperties,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity); - } - - // If the user has said stop and we've stopped applying velocity correction, - // the motor can be turned off. Set the velocity to zero so the zero motion is sent to the viewer. - if (_velocityMotor.TargetValue.ApproxEquals(OMV.Vector3.Zero, 0.01f) && _velocityMotor.ErrorIsZero) - { - ZeroMotion(true); - stepVelocity = OMV.Vector3.Zero; - _velocityMotor.Enabled = false; - DetailLog("{0},BSCharacter.UpdateProperties,taint,disableVelocityMotor,m={1}", LocalID, _velocityMotor); - } - - _velocity = stepVelocity; - entprop.Velocity = _velocity; - BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); - } - - // remember the current and last set values - LastEntityProperties = CurrentEntityProperties; - CurrentEntityProperties = entprop; - - // Tell the linkset about value changes - Linkset.UpdateProperties(this, true); - - // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. - // base.RequestPhysicsterseUpdate(); - - DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", - LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); - } -} -} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSConstraint.cs deleted file mode 100644 index f1bed39..0000000 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSConstraint.cs +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Text; -using OpenMetaverse; - -namespace OpenSim.Region.Physics.BulletSNPlugin -{ - -public abstract class BSConstraint : IDisposable -{ - private static string LogHeader = "[BULLETSIM CONSTRAINT]"; - - protected BulletWorld m_world; - protected BulletBody m_body1; - protected BulletBody m_body2; - protected BulletConstraint m_constraint; - protected bool m_enabled = false; - - public BulletBody Body1 { get { return m_body1; } } - public BulletBody Body2 { get { return m_body2; } } - public BulletConstraint Constraint { get { return m_constraint; } } - public abstract ConstraintType Type { get; } - public bool IsEnabled { get { return m_enabled; } } - - public BSConstraint() - { - } - - public virtual void Dispose() - { - if (m_enabled) - { - m_enabled = false; - if (m_constraint.HasPhysicalConstraint) - { - bool success = BulletSimAPI.DestroyConstraint2(m_world.ptr, m_constraint.ptr); - m_world.physicsScene.DetailLog("{0},BSConstraint.Dispose,taint,id1={1},body1={2},id2={3},body2={4},success={5}", - BSScene.DetailLogZero, - m_body1.ID, m_body1.ptr.ToString(), - m_body2.ID, m_body2.ptr.ToString(), - success); - m_constraint.Clear(); - } - } - } - - public virtual bool SetLinearLimits(Vector3 low, Vector3 high) - { - bool ret = false; - if (m_enabled) - ret = BulletSimAPI.SetLinearLimits2(m_constraint.ptr, low, high); - return ret; - } - - public virtual bool SetAngularLimits(Vector3 low, Vector3 high) - { - bool ret = false; - if (m_enabled) - ret = BulletSimAPI.SetAngularLimits2(m_constraint.ptr, low, high); - return ret; - } - - public virtual bool SetSolverIterations(float cnt) - { - bool ret = false; - if (m_enabled) - { - BulletSimAPI.SetConstraintNumSolverIterations2(m_constraint.ptr, cnt); - ret = true; - } - return ret; - } - - public virtual bool CalculateTransforms() - { - bool ret = false; - if (m_enabled) - { - // Recompute the internal transforms - BulletSimAPI.CalculateTransforms2(m_constraint.ptr); - ret = true; - } - return ret; - } - - // Reset this constraint making sure it has all its internal structures - // recomputed and is enabled and ready to go. - public virtual bool RecomputeConstraintVariables(float mass) - { - bool ret = false; - if (m_enabled) - { - ret = CalculateTransforms(); - if (ret) - { - // Setting an object's mass to zero (making it static like when it's selected) - // automatically disables the constraints. - // If the link is enabled, be sure to set the constraint itself to enabled. - BulletSimAPI.SetConstraintEnable2(m_constraint.ptr, BSParam.NumericBool(true)); - } - else - { - m_world.physicsScene.Logger.ErrorFormat("{0} CalculateTransforms failed. A={1}, B={2}", LogHeader, Body1.ID, Body2.ID); - } - } - return ret; - } -} -} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSConstraint6Dof.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSConstraint6Dof.cs deleted file mode 100644 index d1e3f55..0000000 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSConstraint6Dof.cs +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Text; -using OpenMetaverse; - -namespace OpenSim.Region.Physics.BulletSNPlugin -{ - -public sealed class BSConstraint6Dof : BSConstraint -{ - private static string LogHeader = "[BULLETSIM 6DOF CONSTRAINT]"; - - public override ConstraintType Type { get { return ConstraintType.D6_CONSTRAINT_TYPE; } } - - // Create a btGeneric6DofConstraint - public BSConstraint6Dof(BulletWorld world, BulletBody obj1, BulletBody obj2, - Vector3 frame1, Quaternion frame1rot, - Vector3 frame2, Quaternion frame2rot, - bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) - { - m_world = world; - m_body1 = obj1; - m_body2 = obj2; - m_constraint = new BulletConstraint( - BulletSimAPI.Create6DofConstraint2(m_world.ptr, m_body1.ptr, m_body2.ptr, - frame1, frame1rot, - frame2, frame2rot, - useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); - m_enabled = true; - world.physicsScene.DetailLog("{0},BS6DofConstraint,createFrame,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}", - BSScene.DetailLogZero, world.worldID, - obj1.ID, obj1.ptr.ToString(), obj2.ID, obj2.ptr.ToString()); - } - - public BSConstraint6Dof(BulletWorld world, BulletBody obj1, BulletBody obj2, - Vector3 joinPoint, - bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) - { - m_world = world; - m_body1 = obj1; - m_body2 = obj2; - if (!obj1.HasPhysicalBody || !obj2.HasPhysicalBody) - { - world.physicsScene.DetailLog("{0},BS6DOFConstraint,badBodyPtr,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}", - BSScene.DetailLogZero, world.worldID, - obj1.ID, obj1.ptr.ToString(), obj2.ID, obj2.ptr.ToString()); - world.physicsScene.Logger.ErrorFormat("{0} Attempt to build 6DOF constraint with missing bodies: wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}", - LogHeader, world.worldID, obj1.ID, obj1.ptr.ToString(), obj2.ID, obj2.ptr.ToString()); - m_enabled = false; - } - else - { - m_constraint = new BulletConstraint( - BulletSimAPI.Create6DofConstraintToPoint2(m_world.ptr, m_body1.ptr, m_body2.ptr, - joinPoint, - useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); - world.physicsScene.DetailLog("{0},BS6DofConstraint,createMidPoint,wID={1}, csrt={2}, rID={3}, rBody={4}, cID={5}, cBody={6}", - BSScene.DetailLogZero, world.worldID, m_constraint.ptr.ToString(), - obj1.ID, obj1.ptr.ToString(), obj2.ID, obj2.ptr.ToString()); - if (!m_constraint.HasPhysicalConstraint) - { - world.physicsScene.Logger.ErrorFormat("{0} Failed creation of 6Dof constraint. rootID={1}, childID={2}", - LogHeader, obj1.ID, obj2.ID); - m_enabled = false; - } - else - { - m_enabled = true; - } - } - } - - public bool SetFrames(Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot) - { - bool ret = false; - if (m_enabled) - { - BulletSimAPI.SetFrames2(m_constraint.ptr, frameA, frameArot, frameB, frameBrot); - ret = true; - } - return ret; - } - - public bool SetCFMAndERP(float cfm, float erp) - { - bool ret = false; - if (m_enabled) - { - BulletSimAPI.SetConstraintParam2(m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL); - BulletSimAPI.SetConstraintParam2(m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_ERP, erp, ConstraintParamAxis.AXIS_ALL); - BulletSimAPI.SetConstraintParam2(m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_CFM, cfm, ConstraintParamAxis.AXIS_ALL); - ret = true; - } - return ret; - } - - public bool UseFrameOffset(bool useOffset) - { - bool ret = false; - float onOff = useOffset ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse; - if (m_enabled) - ret = BulletSimAPI.UseFrameOffset2(m_constraint.ptr, onOff); - return ret; - } - - public bool TranslationalLimitMotor(bool enable, float targetVelocity, float maxMotorForce) - { - bool ret = false; - float onOff = enable ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse; - if (m_enabled) - { - ret = BulletSimAPI.TranslationalLimitMotor2(m_constraint.ptr, onOff, targetVelocity, maxMotorForce); - m_world.physicsScene.DetailLog("{0},BS6DOFConstraint,TransLimitMotor,enable={1},vel={2},maxForce={3}", - BSScene.DetailLogZero, enable, targetVelocity, maxMotorForce); - } - return ret; - } - - public bool SetBreakingImpulseThreshold(float threshold) - { - bool ret = false; - if (m_enabled) - ret = BulletSimAPI.SetBreakingImpulseThreshold2(m_constraint.ptr, threshold); - return ret; - } -} -} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSConstraintCollection.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSConstraintCollection.cs deleted file mode 100644 index 87d1e44..0000000 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSConstraintCollection.cs +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Text; -using log4net; -using OpenMetaverse; - -namespace OpenSim.Region.Physics.BulletSNPlugin -{ - -public sealed class BSConstraintCollection : IDisposable -{ - // private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - // private static readonly string LogHeader = "[CONSTRAINT COLLECTION]"; - - delegate bool ConstraintAction(BSConstraint constrain); - - private List m_constraints; - private BulletWorld m_world; - - public BSConstraintCollection(BulletWorld world) - { - m_world = world; - m_constraints = new List(); - } - - public void Dispose() - { - this.Clear(); - } - - public void Clear() - { - lock (m_constraints) - { - foreach (BSConstraint cons in m_constraints) - { - cons.Dispose(); - } - m_constraints.Clear(); - } - } - - public bool AddConstraint(BSConstraint cons) - { - lock (m_constraints) - { - // There is only one constraint between any bodies. Remove any old just to make sure. - RemoveAndDestroyConstraint(cons.Body1, cons.Body2); - - m_constraints.Add(cons); - } - - return true; - } - - // Get the constraint between two bodies. There can be only one. - // Return 'true' if a constraint was found. - public bool TryGetConstraint(BulletBody body1, BulletBody body2, out BSConstraint returnConstraint) - { - bool found = false; - BSConstraint foundConstraint = null; - - uint lookingID1 = body1.ID; - uint lookingID2 = body2.ID; - lock (m_constraints) - { - foreach (BSConstraint constrain in m_constraints) - { - if ((constrain.Body1.ID == lookingID1 && constrain.Body2.ID == lookingID2) - || (constrain.Body1.ID == lookingID2 && constrain.Body2.ID == lookingID1)) - { - foundConstraint = constrain; - found = true; - break; - } - } - } - returnConstraint = foundConstraint; - return found; - } - - // Remove any constraint between the passed bodies. - // Presumed there is only one such constraint possible. - // Return 'true' if a constraint was found and destroyed. - public bool RemoveAndDestroyConstraint(BulletBody body1, BulletBody body2) - { - bool ret = false; - lock (m_constraints) - { - BSConstraint constrain; - if (this.TryGetConstraint(body1, body2, out constrain)) - { - // remove the constraint from our collection - RemoveAndDestroyConstraint(constrain); - ret = true; - } - } - - return ret; - } - - // The constraint MUST exist in the collection - public bool RemoveAndDestroyConstraint(BSConstraint constrain) - { - lock (m_constraints) - { - // remove the constraint from our collection - m_constraints.Remove(constrain); - } - // tell the engine that all its structures need to be freed - constrain.Dispose(); - // we destroyed something - return true; - } - - // Remove all constraints that reference the passed body. - // Return 'true' if any constraints were destroyed. - public bool RemoveAndDestroyConstraint(BulletBody body1) - { - List toRemove = new List(); - uint lookingID = body1.ID; - lock (m_constraints) - { - foreach (BSConstraint constrain in m_constraints) - { - if (constrain.Body1.ID == lookingID || constrain.Body2.ID == lookingID) - { - toRemove.Add(constrain); - } - } - foreach (BSConstraint constrain in toRemove) - { - m_constraints.Remove(constrain); - constrain.Dispose(); - } - } - return (toRemove.Count > 0); - } - - public bool RecalculateAllConstraints() - { - bool ret = false; - lock (m_constraints) - { - foreach (BSConstraint constrain in m_constraints) - { - constrain.CalculateTransforms(); - ret = true; - } - } - return ret; - } -} -} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSConstraintHinge.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSConstraintHinge.cs deleted file mode 100644 index fbd1bc0..0000000 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSConstraintHinge.cs +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Text; -using OpenMetaverse; - -namespace OpenSim.Region.Physics.BulletSNPlugin -{ - -public sealed class BSConstraintHinge : BSConstraint -{ - public override ConstraintType Type { get { return ConstraintType.HINGE_CONSTRAINT_TYPE; } } - - public BSConstraintHinge(BulletWorld world, BulletBody obj1, BulletBody obj2, - Vector3 pivotInA, Vector3 pivotInB, - Vector3 axisInA, Vector3 axisInB, - bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) - { - m_world = world; - m_body1 = obj1; - m_body2 = obj2; - m_constraint = new BulletConstraint( - BulletSimAPI.CreateHingeConstraint2(m_world.ptr, m_body1.ptr, m_body2.ptr, - pivotInA, pivotInB, - axisInA, axisInB, - useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); - m_enabled = true; - } - -} - -} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSDynamics.cs deleted file mode 100644 index 415ad4f..0000000 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSDynamics.cs +++ /dev/null @@ -1,1377 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The quotations from http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial - * are Copyright (c) 2009 Linden Research, Inc and are used under their license - * of Creative Commons Attribution-Share Alike 3.0 - * (http://creativecommons.org/licenses/by-sa/3.0/). - */ - -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Runtime.InteropServices; -using OpenMetaverse; -using OpenSim.Region.Physics.Manager; - -namespace OpenSim.Region.Physics.BulletSNPlugin -{ - public sealed class BSDynamics - { - private static string LogHeader = "[BULLETSIM VEHICLE]"; - - private BSScene PhysicsScene { get; set; } - // the prim this dynamic controller belongs to - private BSPrim Prim { get; set; } - - // mass of the vehicle fetched each time we're calles - private float m_vehicleMass; - - // Vehicle properties - public Vehicle Type { get; set; } - - // private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier - private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings: - // HOVER_TERRAIN_ONLY - // HOVER_GLOBAL_HEIGHT - // NO_DEFLECTION_UP - // HOVER_WATER_ONLY - // HOVER_UP_ONLY - // LIMIT_MOTOR_UP - // LIMIT_ROLL_ONLY - private Vector3 m_BlockingEndPoint = Vector3.Zero; - private Quaternion m_RollreferenceFrame = Quaternion.Identity; - private Quaternion m_referenceFrame = Quaternion.Identity; - - // Linear properties - private BSVMotor m_linearMotor = new BSVMotor("LinearMotor"); - private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time - private Vector3 m_linearMotorOffset = Vector3.Zero; // the point of force can be offset from the center - private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL - private Vector3 m_linearFrictionTimescale = Vector3.Zero; - private float m_linearMotorDecayTimescale = 0; - private float m_linearMotorTimescale = 0; - private Vector3 m_lastLinearVelocityVector = Vector3.Zero; - private Vector3 m_lastPositionVector = Vector3.Zero; - // private bool m_LinearMotorSetLastFrame = false; - // private Vector3 m_linearMotorOffset = Vector3.Zero; - - //Angular properties - private BSVMotor m_angularMotor = new BSVMotor("AngularMotor"); - private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor - // private int m_angularMotorApply = 0; // application frame counter - private Vector3 m_angularMotorVelocity = Vector3.Zero; // current angular motor velocity - private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate - private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate - private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate - private Vector3 m_lastAngularVelocity = Vector3.Zero; - private Vector3 m_lastVertAttractor = Vector3.Zero; // what VA was last applied to body - - //Deflection properties - private BSVMotor m_angularDeflectionMotor = new BSVMotor("AngularDeflection"); - private float m_angularDeflectionEfficiency = 0; - private float m_angularDeflectionTimescale = 0; - private float m_linearDeflectionEfficiency = 0; - private float m_linearDeflectionTimescale = 0; - - //Banking properties - private float m_bankingEfficiency = 0; - private float m_bankingMix = 0; - private float m_bankingTimescale = 0; - - //Hover and Buoyancy properties - private BSVMotor m_hoverMotor = new BSVMotor("Hover"); - private float m_VhoverHeight = 0f; - private float m_VhoverEfficiency = 0f; - private float m_VhoverTimescale = 0f; - private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height - private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle. - // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity) - // KF: So far I have found no good method to combine a script-requested .Z velocity and gravity. - // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity. - - //Attractor properties - private BSVMotor m_verticalAttractionMotor = new BSVMotor("VerticalAttraction"); - private float m_verticalAttractionEfficiency = 1.0f; // damped - private float m_verticalAttractionCutoff = 500f; // per the documentation - // Timescale > cutoff means no vert attractor. - private float m_verticalAttractionTimescale = 510f; - - // Just some recomputed constants: - static readonly float PIOverFour = ((float)Math.PI) / 4f; - static readonly float PIOverTwo = ((float)Math.PI) / 2f; - - public BSDynamics(BSScene myScene, BSPrim myPrim) - { - PhysicsScene = myScene; - Prim = myPrim; - Type = Vehicle.TYPE_NONE; - } - - // Return 'true' if this vehicle is doing vehicle things - public bool IsActive - { - get { return Type != Vehicle.TYPE_NONE && Prim.IsPhysical; } - } - - internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) - { - VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue); - switch (pParam) - { - case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: - m_angularDeflectionEfficiency = Math.Max(pValue, 0.01f); - break; - case Vehicle.ANGULAR_DEFLECTION_TIMESCALE: - m_angularDeflectionTimescale = Math.Max(pValue, 0.01f); - break; - case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE: - m_angularMotorDecayTimescale = ClampInRange(0.01f, pValue, 120); - m_angularMotor.TargetValueDecayTimeScale = m_angularMotorDecayTimescale; - break; - case Vehicle.ANGULAR_MOTOR_TIMESCALE: - m_angularMotorTimescale = Math.Max(pValue, 0.01f); - m_angularMotor.TimeScale = m_angularMotorTimescale; - break; - case Vehicle.BANKING_EFFICIENCY: - m_bankingEfficiency = ClampInRange(-1f, pValue, 1f); - break; - case Vehicle.BANKING_MIX: - m_bankingMix = Math.Max(pValue, 0.01f); - break; - case Vehicle.BANKING_TIMESCALE: - m_bankingTimescale = Math.Max(pValue, 0.01f); - break; - case Vehicle.BUOYANCY: - m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f); - break; - case Vehicle.HOVER_EFFICIENCY: - m_VhoverEfficiency = ClampInRange(0f, pValue, 1f); - break; - case Vehicle.HOVER_HEIGHT: - m_VhoverHeight = pValue; - break; - case Vehicle.HOVER_TIMESCALE: - m_VhoverTimescale = Math.Max(pValue, 0.01f); - break; - case Vehicle.LINEAR_DEFLECTION_EFFICIENCY: - m_linearDeflectionEfficiency = Math.Max(pValue, 0.01f); - break; - case Vehicle.LINEAR_DEFLECTION_TIMESCALE: - m_linearDeflectionTimescale = Math.Max(pValue, 0.01f); - break; - case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE: - m_linearMotorDecayTimescale = ClampInRange(0.01f, pValue, 120); - m_linearMotor.TargetValueDecayTimeScale = m_linearMotorDecayTimescale; - break; - case Vehicle.LINEAR_MOTOR_TIMESCALE: - m_linearMotorTimescale = Math.Max(pValue, 0.01f); - m_linearMotor.TimeScale = m_linearMotorTimescale; - break; - case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: - m_verticalAttractionEfficiency = ClampInRange(0.1f, pValue, 1f); - m_verticalAttractionMotor.Efficiency = m_verticalAttractionEfficiency; - break; - case Vehicle.VERTICAL_ATTRACTION_TIMESCALE: - m_verticalAttractionTimescale = Math.Max(pValue, 0.01f); - m_verticalAttractionMotor.TimeScale = m_verticalAttractionTimescale; - break; - - // These are vector properties but the engine lets you use a single float value to - // set all of the components to the same value - case Vehicle.ANGULAR_FRICTION_TIMESCALE: - m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue); - m_angularMotor.FrictionTimescale = m_angularFrictionTimescale; - break; - case Vehicle.ANGULAR_MOTOR_DIRECTION: - m_angularMotorDirection = new Vector3(pValue, pValue, pValue); - m_angularMotor.SetTarget(m_angularMotorDirection); - break; - case Vehicle.LINEAR_FRICTION_TIMESCALE: - m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue); - m_linearMotor.FrictionTimescale = m_linearFrictionTimescale; - break; - case Vehicle.LINEAR_MOTOR_DIRECTION: - m_linearMotorDirection = new Vector3(pValue, pValue, pValue); - m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue); - m_linearMotor.SetTarget(m_linearMotorDirection); - break; - case Vehicle.LINEAR_MOTOR_OFFSET: - m_linearMotorOffset = new Vector3(pValue, pValue, pValue); - break; - - } - }//end ProcessFloatVehicleParam - - internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue) - { - VDetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue); - switch (pParam) - { - case Vehicle.ANGULAR_FRICTION_TIMESCALE: - m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); - m_angularMotor.FrictionTimescale = m_angularFrictionTimescale; - break; - case Vehicle.ANGULAR_MOTOR_DIRECTION: - // Limit requested angular speed to 2 rps= 4 pi rads/sec - pValue.X = ClampInRange(-12.56f, pValue.X, 12.56f); - pValue.Y = ClampInRange(-12.56f, pValue.Y, 12.56f); - pValue.Z = ClampInRange(-12.56f, pValue.Z, 12.56f); - m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); - m_angularMotor.SetTarget(m_angularMotorDirection); - break; - case Vehicle.LINEAR_FRICTION_TIMESCALE: - m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); - m_linearMotor.FrictionTimescale = m_linearFrictionTimescale; - break; - case Vehicle.LINEAR_MOTOR_DIRECTION: - m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); - m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z); - m_linearMotor.SetTarget(m_linearMotorDirection); - break; - case Vehicle.LINEAR_MOTOR_OFFSET: - m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); - break; - case Vehicle.BLOCK_EXIT: - m_BlockingEndPoint = new Vector3(pValue.X, pValue.Y, pValue.Z); - break; - } - }//end ProcessVectorVehicleParam - - internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) - { - VDetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue); - switch (pParam) - { - case Vehicle.REFERENCE_FRAME: - m_referenceFrame = pValue; - break; - case Vehicle.ROLL_FRAME: - m_RollreferenceFrame = pValue; - break; - } - }//end ProcessRotationVehicleParam - - internal void ProcessVehicleFlags(int pParam, bool remove) - { - VDetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", Prim.LocalID, pParam, remove); - VehicleFlag parm = (VehicleFlag)pParam; - if (pParam == -1) - m_flags = (VehicleFlag)0; - else - { - if (remove) - m_flags &= ~parm; - else - m_flags |= parm; - } - } - - internal void ProcessTypeChange(Vehicle pType) - { - VDetailLog("{0},ProcessTypeChange,type={1}", Prim.LocalID, pType); - // Set Defaults For Type - Type = pType; - switch (pType) - { - case Vehicle.TYPE_NONE: - m_linearMotorDirection = Vector3.Zero; - m_linearMotorTimescale = 0; - m_linearMotorDecayTimescale = 0; - m_linearFrictionTimescale = new Vector3(0, 0, 0); - - m_angularMotorDirection = Vector3.Zero; - m_angularMotorDecayTimescale = 0; - m_angularMotorTimescale = 0; - m_angularFrictionTimescale = new Vector3(0, 0, 0); - - m_VhoverHeight = 0; - m_VhoverEfficiency = 0; - m_VhoverTimescale = 0; - m_VehicleBuoyancy = 0; - - m_linearDeflectionEfficiency = 1; - m_linearDeflectionTimescale = 1; - - m_angularDeflectionEfficiency = 0; - m_angularDeflectionTimescale = 1000; - - m_verticalAttractionEfficiency = 0; - m_verticalAttractionTimescale = 0; - - m_bankingEfficiency = 0; - m_bankingTimescale = 1000; - m_bankingMix = 1; - - m_referenceFrame = Quaternion.Identity; - m_flags = (VehicleFlag)0; - - break; - - case Vehicle.TYPE_SLED: - m_linearMotorDirection = Vector3.Zero; - m_linearMotorTimescale = 1000; - m_linearMotorDecayTimescale = 120; - m_linearFrictionTimescale = new Vector3(30, 1, 1000); - - m_angularMotorDirection = Vector3.Zero; - m_angularMotorTimescale = 1000; - m_angularMotorDecayTimescale = 120; - m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); - - m_VhoverHeight = 0; - m_VhoverEfficiency = 10; // TODO: this looks wrong!! - m_VhoverTimescale = 10; - m_VehicleBuoyancy = 0; - - m_linearDeflectionEfficiency = 1; - m_linearDeflectionTimescale = 1; - - m_angularDeflectionEfficiency = 1; - m_angularDeflectionTimescale = 1000; - - m_verticalAttractionEfficiency = 0; - m_verticalAttractionTimescale = 0; - - m_bankingEfficiency = 0; - m_bankingTimescale = 10; - m_bankingMix = 1; - - m_referenceFrame = Quaternion.Identity; - m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY - | VehicleFlag.HOVER_TERRAIN_ONLY - | VehicleFlag.HOVER_GLOBAL_HEIGHT - | VehicleFlag.HOVER_UP_ONLY); - m_flags |= (VehicleFlag.NO_DEFLECTION_UP - | VehicleFlag.LIMIT_ROLL_ONLY - | VehicleFlag.LIMIT_MOTOR_UP); - - break; - case Vehicle.TYPE_CAR: - m_linearMotorDirection = Vector3.Zero; - m_linearMotorTimescale = 1; - m_linearMotorDecayTimescale = 60; - m_linearFrictionTimescale = new Vector3(100, 2, 1000); - - m_angularMotorDirection = Vector3.Zero; - m_angularMotorTimescale = 1; - m_angularMotorDecayTimescale = 0.8f; - m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); - - m_VhoverHeight = 0; - m_VhoverEfficiency = 0; - m_VhoverTimescale = 1000; - m_VehicleBuoyancy = 0; - - m_linearDeflectionEfficiency = 1; - m_linearDeflectionTimescale = 2; - - m_angularDeflectionEfficiency = 0; - m_angularDeflectionTimescale = 10; - - m_verticalAttractionEfficiency = 1f; - m_verticalAttractionTimescale = 10f; - - m_bankingEfficiency = -0.2f; - m_bankingMix = 1; - m_bankingTimescale = 1; - - m_referenceFrame = Quaternion.Identity; - m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY - | VehicleFlag.HOVER_TERRAIN_ONLY - | VehicleFlag.HOVER_GLOBAL_HEIGHT); - m_flags |= (VehicleFlag.NO_DEFLECTION_UP - | VehicleFlag.LIMIT_ROLL_ONLY - | VehicleFlag.LIMIT_MOTOR_UP - | VehicleFlag.HOVER_UP_ONLY); - break; - case Vehicle.TYPE_BOAT: - m_linearMotorDirection = Vector3.Zero; - m_linearMotorTimescale = 5; - m_linearMotorDecayTimescale = 60; - m_linearFrictionTimescale = new Vector3(10, 3, 2); - - m_angularMotorDirection = Vector3.Zero; - m_angularMotorTimescale = 4; - m_angularMotorDecayTimescale = 4; - m_angularFrictionTimescale = new Vector3(10,10,10); - - m_VhoverHeight = 0; - m_VhoverEfficiency = 0.5f; - m_VhoverTimescale = 2; - m_VehicleBuoyancy = 1; - - m_linearDeflectionEfficiency = 0.5f; - m_linearDeflectionTimescale = 3; - - m_angularDeflectionEfficiency = 0.5f; - m_angularDeflectionTimescale = 5; - - m_verticalAttractionEfficiency = 0.5f; - m_verticalAttractionTimescale = 5f; - - m_bankingEfficiency = -0.3f; - m_bankingMix = 0.8f; - m_bankingTimescale = 1; - - m_referenceFrame = Quaternion.Identity; - m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY - | VehicleFlag.HOVER_GLOBAL_HEIGHT - | VehicleFlag.LIMIT_ROLL_ONLY - | VehicleFlag.HOVER_UP_ONLY); - m_flags |= (VehicleFlag.NO_DEFLECTION_UP - | VehicleFlag.LIMIT_MOTOR_UP - | VehicleFlag.HOVER_WATER_ONLY); - break; - case Vehicle.TYPE_AIRPLANE: - m_linearMotorDirection = Vector3.Zero; - m_linearMotorTimescale = 2; - m_linearMotorDecayTimescale = 60; - m_linearFrictionTimescale = new Vector3(200, 10, 5); - - m_angularMotorDirection = Vector3.Zero; - m_angularMotorTimescale = 4; - m_angularMotorDecayTimescale = 4; - m_angularFrictionTimescale = new Vector3(20, 20, 20); - - m_VhoverHeight = 0; - m_VhoverEfficiency = 0.5f; - m_VhoverTimescale = 1000; - m_VehicleBuoyancy = 0; - - m_linearDeflectionEfficiency = 0.5f; - m_linearDeflectionTimescale = 3; - - m_angularDeflectionEfficiency = 1; - m_angularDeflectionTimescale = 2; - - m_verticalAttractionEfficiency = 0.9f; - m_verticalAttractionTimescale = 2f; - - m_bankingEfficiency = 1; - m_bankingMix = 0.7f; - m_bankingTimescale = 2; - - m_referenceFrame = Quaternion.Identity; - m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY - | VehicleFlag.HOVER_TERRAIN_ONLY - | VehicleFlag.HOVER_GLOBAL_HEIGHT - | VehicleFlag.HOVER_UP_ONLY - | VehicleFlag.NO_DEFLECTION_UP - | VehicleFlag.LIMIT_MOTOR_UP); - m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); - break; - case Vehicle.TYPE_BALLOON: - m_linearMotorDirection = Vector3.Zero; - m_linearMotorTimescale = 5; - m_linearFrictionTimescale = new Vector3(5, 5, 5); - m_linearMotorDecayTimescale = 60; - - m_angularMotorDirection = Vector3.Zero; - m_angularMotorTimescale = 6; - m_angularFrictionTimescale = new Vector3(10, 10, 10); - m_angularMotorDecayTimescale = 10; - - m_VhoverHeight = 5; - m_VhoverEfficiency = 0.8f; - m_VhoverTimescale = 10; - m_VehicleBuoyancy = 1; - - m_linearDeflectionEfficiency = 0; - m_linearDeflectionTimescale = 5; - - m_angularDeflectionEfficiency = 0; - m_angularDeflectionTimescale = 5; - - m_verticalAttractionEfficiency = 1f; - m_verticalAttractionTimescale = 100f; - - m_bankingEfficiency = 0; - m_bankingMix = 0.7f; - m_bankingTimescale = 5; - - m_referenceFrame = Quaternion.Identity; - - m_referenceFrame = Quaternion.Identity; - m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY - | VehicleFlag.HOVER_TERRAIN_ONLY - | VehicleFlag.HOVER_UP_ONLY - | VehicleFlag.NO_DEFLECTION_UP - | VehicleFlag.LIMIT_MOTOR_UP); - m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY - | VehicleFlag.HOVER_GLOBAL_HEIGHT); - break; - } - - // Update any physical parameters based on this type. - Refresh(); - - m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale, - m_linearMotorDecayTimescale, m_linearFrictionTimescale, - 1f); - m_linearMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) - - m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale, - m_angularMotorDecayTimescale, m_angularFrictionTimescale, - 1f); - m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) - - m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale, - BSMotor.Infinite, BSMotor.InfiniteVector, - m_verticalAttractionEfficiency); - // Z goes away and we keep X and Y - m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f); - m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) - } - - // Some of the properties of this prim may have changed. - // Do any updating needed for a vehicle - public void Refresh() - { - if (IsActive) - { - // Remember the mass so we don't have to fetch it every step - m_vehicleMass = Prim.Linkset.LinksetMass; - - // Friction affects are handled by this vehicle code - float friction = 0f; - BulletSimAPI.SetFriction2(Prim.PhysBody.ptr, friction); - - // Moderate angular movement introduced by Bullet. - // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle. - // Maybe compute linear and angular factor and damping from params. - float angularDamping = BSParam.VehicleAngularDamping; - BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, angularDamping); - - // Vehicles report collision events so we know when it's on the ground - BulletSimAPI.AddToCollisionFlags2(Prim.PhysBody.ptr, CollisionFlags.BS_VEHICLE_COLLISIONS); - - Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(Prim.PhysShape.ptr, m_vehicleMass); - BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia); - BulletSimAPI.UpdateInertiaTensor2(Prim.PhysBody.ptr); - - Vector3 grav = PhysicsScene.DefaultGravity * (1f - Prim.Buoyancy); - BulletSimAPI.SetGravity2(Prim.PhysBody.ptr, grav); - - VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4}", - Prim.LocalID, m_vehicleMass, friction, localInertia, angularDamping); - } - else - { - BulletSimAPI.RemoveFromCollisionFlags2(Prim.PhysBody.ptr, CollisionFlags.BS_VEHICLE_COLLISIONS); - } - } - - public bool RemoveBodyDependencies(BSPhysObject prim) - { - // If active, we need to add our properties back when the body is rebuilt. - return IsActive; - } - - public void RestoreBodyDependencies(BSPhysObject prim) - { - if (Prim.LocalID != prim.LocalID) - { - // The call should be on us by our prim. Error if not. - PhysicsScene.Logger.ErrorFormat("{0} RestoreBodyDependencies: called by not my prim. passedLocalID={1}, vehiclePrimLocalID={2}", - LogHeader, prim.LocalID, Prim.LocalID); - return; - } - Refresh(); - } - - #region Known vehicle value functions - // Vehicle physical parameters that we buffer from constant getting and setting. - // The "m_known*" values are unknown until they are fetched and the m_knownHas flag is set. - // Changing is remembered and the parameter is stored back into the physics engine only if updated. - // This does two things: 1) saves continuious calls into unmanaged code, and - // 2) signals when a physics property update must happen back to the simulator - // to update values modified for the vehicle. - private int m_knownChanged; - private int m_knownHas; - private float m_knownTerrainHeight; - private float m_knownWaterLevel; - private Vector3 m_knownPosition; - private Vector3 m_knownVelocity; - private Vector3 m_knownForce; - private Quaternion m_knownOrientation; - private Vector3 m_knownRotationalVelocity; - private Vector3 m_knownRotationalForce; - private Vector3 m_knownForwardVelocity; // vehicle relative forward speed - - private const int m_knownChangedPosition = 1 << 0; - private const int m_knownChangedVelocity = 1 << 1; - private const int m_knownChangedForce = 1 << 2; - private const int m_knownChangedOrientation = 1 << 3; - private const int m_knownChangedRotationalVelocity = 1 << 4; - private const int m_knownChangedRotationalForce = 1 << 5; - private const int m_knownChangedTerrainHeight = 1 << 6; - private const int m_knownChangedWaterLevel = 1 << 7; - private const int m_knownChangedForwardVelocity = 1 << 8; - - private void ForgetKnownVehicleProperties() - { - m_knownHas = 0; - m_knownChanged = 0; - } - // Push all the changed values back into the physics engine - private void PushKnownChanged() - { - if (m_knownChanged != 0) - { - if ((m_knownChanged & m_knownChangedPosition) != 0) - Prim.ForcePosition = m_knownPosition; - - if ((m_knownChanged & m_knownChangedOrientation) != 0) - Prim.ForceOrientation = m_knownOrientation; - - if ((m_knownChanged & m_knownChangedVelocity) != 0) - { - Prim.ForceVelocity = m_knownVelocity; - BulletSimAPI.SetInterpolationLinearVelocity2(Prim.PhysBody.ptr, VehicleVelocity); - } - - if ((m_knownChanged & m_knownChangedForce) != 0) - Prim.AddForce((Vector3)m_knownForce, false, true); - - if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) - { - Prim.ForceRotationalVelocity = m_knownRotationalVelocity; - // Fake out Bullet by making it think the velocity is the same as last time. - BulletSimAPI.SetInterpolationAngularVelocity2(Prim.PhysBody.ptr, m_knownRotationalVelocity); - } - - if ((m_knownChanged & m_knownChangedRotationalForce) != 0) - Prim.AddAngularForce((Vector3)m_knownRotationalForce, false, true); - - // If we set one of the values (ie, the physics engine didn't do it) we must force - // an UpdateProperties event to send the changes up to the simulator. - BulletSimAPI.PushUpdate2(Prim.PhysBody.ptr); - } - m_knownChanged = 0; - } - - // Since the computation of terrain height can be a little involved, this routine - // is used to fetch the height only once for each vehicle simulation step. - private float GetTerrainHeight(Vector3 pos) - { - if ((m_knownHas & m_knownChangedTerrainHeight) == 0) - { - m_knownTerrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); - m_knownHas |= m_knownChangedTerrainHeight; - } - return m_knownTerrainHeight; - } - - // Since the computation of water level can be a little involved, this routine - // is used ot fetch the level only once for each vehicle simulation step. - private float GetWaterLevel(Vector3 pos) - { - if ((m_knownHas & m_knownChangedWaterLevel) == 0) - { - m_knownWaterLevel = Prim.PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(pos); - m_knownHas |= m_knownChangedWaterLevel; - } - return (float)m_knownWaterLevel; - } - - private Vector3 VehiclePosition - { - get - { - if ((m_knownHas & m_knownChangedPosition) == 0) - { - m_knownPosition = Prim.ForcePosition; - m_knownHas |= m_knownChangedPosition; - } - return m_knownPosition; - } - set - { - m_knownPosition = value; - m_knownChanged |= m_knownChangedPosition; - m_knownHas |= m_knownChangedPosition; - } - } - - private Quaternion VehicleOrientation - { - get - { - if ((m_knownHas & m_knownChangedOrientation) == 0) - { - m_knownOrientation = Prim.ForceOrientation; - m_knownHas |= m_knownChangedOrientation; - } - return m_knownOrientation; - } - set - { - m_knownOrientation = value; - m_knownChanged |= m_knownChangedOrientation; - m_knownHas |= m_knownChangedOrientation; - } - } - - private Vector3 VehicleVelocity - { - get - { - if ((m_knownHas & m_knownChangedVelocity) == 0) - { - m_knownVelocity = Prim.ForceVelocity; - m_knownHas |= m_knownChangedVelocity; - } - return (Vector3)m_knownVelocity; - } - set - { - m_knownVelocity = value; - m_knownChanged |= m_knownChangedVelocity; - m_knownHas |= m_knownChangedVelocity; - } - } - - private void VehicleAddForce(Vector3 aForce) - { - if ((m_knownHas & m_knownChangedForce) == 0) - { - m_knownForce = Vector3.Zero; - } - m_knownForce += aForce; - m_knownChanged |= m_knownChangedForce; - m_knownHas |= m_knownChangedForce; - } - - private Vector3 VehicleRotationalVelocity - { - get - { - if ((m_knownHas & m_knownChangedRotationalVelocity) == 0) - { - m_knownRotationalVelocity = Prim.ForceRotationalVelocity; - m_knownHas |= m_knownChangedRotationalVelocity; - } - return (Vector3)m_knownRotationalVelocity; - } - set - { - m_knownRotationalVelocity = value; - m_knownChanged |= m_knownChangedRotationalVelocity; - m_knownHas |= m_knownChangedRotationalVelocity; - } - } - private void VehicleAddAngularForce(Vector3 aForce) - { - if ((m_knownHas & m_knownChangedRotationalForce) == 0) - { - m_knownRotationalForce = Vector3.Zero; - } - m_knownRotationalForce += aForce; - m_knownChanged |= m_knownChangedRotationalForce; - m_knownHas |= m_knownChangedRotationalForce; - } - // Vehicle relative forward velocity - private Vector3 VehicleForwardVelocity - { - get - { - if ((m_knownHas & m_knownChangedForwardVelocity) == 0) - { - m_knownForwardVelocity = VehicleVelocity * Quaternion.Inverse(Quaternion.Normalize(VehicleOrientation)); - m_knownHas |= m_knownChangedForwardVelocity; - } - return m_knownForwardVelocity; - } - } - private float VehicleForwardSpeed - { - get - { - return VehicleForwardVelocity.X; - } - } - - #endregion // Known vehicle value functions - - // One step of the vehicle properties for the next 'pTimestep' seconds. - internal void Step(float pTimestep) - { - if (!IsActive) return; - - ForgetKnownVehicleProperties(); - - MoveLinear(pTimestep); - MoveAngular(pTimestep); - - LimitRotation(pTimestep); - - // remember the position so next step we can limit absolute movement effects - m_lastPositionVector = VehiclePosition; - - // If we forced the changing of some vehicle parameters, update the values and - // for the physics engine to note the changes so an UpdateProperties event will happen. - PushKnownChanged(); - - VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", - Prim.LocalID, VehiclePosition, Prim.Force, VehicleVelocity, VehicleRotationalVelocity); - } - - // Apply the effect of the linear motor and other linear motions (like hover and float). - private void MoveLinear(float pTimestep) - { - Vector3 linearMotorContribution = m_linearMotor.Step(pTimestep); - - // The movement computed in the linear motor is relative to the vehicle - // coordinates. Rotate the movement to world coordinates. - linearMotorContribution *= VehicleOrientation; - - // ================================================================== - // Buoyancy: force to overcome gravity. - // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; - // So, if zero, don't change anything (let gravity happen). If one, negate the effect of gravity. - Vector3 buoyancyContribution = Prim.PhysicsScene.DefaultGravity * m_VehicleBuoyancy; - - Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(pTimestep); - - Vector3 hoverContribution = ComputeLinearHover(pTimestep); - - ComputeLinearBlockingEndPoint(pTimestep); - - Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pTimestep); - - // ================================================================== - Vector3 newVelocity = linearMotorContribution - + terrainHeightContribution - + hoverContribution - + limitMotorUpContribution; - - Vector3 newForce = buoyancyContribution; - - // If not changing some axis, reduce out velocity - if ((m_flags & (VehicleFlag.NO_X)) != 0) - newVelocity.X = 0; - if ((m_flags & (VehicleFlag.NO_Y)) != 0) - newVelocity.Y = 0; - if ((m_flags & (VehicleFlag.NO_Z)) != 0) - newVelocity.Z = 0; - - // ================================================================== - // Clamp high or low velocities - float newVelocityLengthSq = newVelocity.LengthSquared(); - if (newVelocityLengthSq > 1000f) - { - newVelocity /= newVelocity.Length(); - newVelocity *= 1000f; - } - else if (newVelocityLengthSq < 0.001f) - newVelocity = Vector3.Zero; - - // ================================================================== - // Stuff new linear velocity into the vehicle. - // Since the velocity is just being set, it is not scaled by pTimeStep. Bullet will do that for us. - VehicleVelocity = newVelocity; - - // Other linear forces are applied as forces. - Vector3 totalDownForce = newForce * m_vehicleMass; - if (!totalDownForce.ApproxEquals(Vector3.Zero, 0.01f)) - { - VehicleAddForce(totalDownForce); - } - - VDetailLog("{0}, MoveLinear,done,newVel={1},totDown={2},IsColliding={3}", - Prim.LocalID, newVelocity, totalDownForce, Prim.IsColliding); - VDetailLog("{0}, MoveLinear,done,linContrib={1},terrContrib={2},hoverContrib={3},limitContrib={4},buoyContrib={5}", - Prim.LocalID, - linearMotorContribution, terrainHeightContribution, hoverContribution, - limitMotorUpContribution, buoyancyContribution - ); - - } // end MoveLinear() - - public Vector3 ComputeLinearTerrainHeightCorrection(float pTimestep) - { - Vector3 ret = Vector3.Zero; - // If below the terrain, move us above the ground a little. - // TODO: Consider taking the rotated size of the object or possibly casting a ray. - if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition)) - { - // TODO: correct position by applying force rather than forcing position. - Vector3 newPosition = VehiclePosition; - newPosition.Z = GetTerrainHeight(VehiclePosition) + 1f; - VehiclePosition = newPosition; - VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}", - Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition); - } - return ret; - } - - public Vector3 ComputeLinearHover(float pTimestep) - { - Vector3 ret = Vector3.Zero; - - // m_VhoverEfficiency: 0=bouncy, 1=totally damped - // m_VhoverTimescale: time to achieve height - if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) - { - // We should hover, get the target height - if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0) - { - m_VhoverTargetHeight = GetWaterLevel(VehiclePosition) + m_VhoverHeight; - } - if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) - { - m_VhoverTargetHeight = GetTerrainHeight(VehiclePosition) + m_VhoverHeight; - } - if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0) - { - m_VhoverTargetHeight = m_VhoverHeight; - } - - if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0) - { - // If body is already heigher, use its height as target height - if (VehiclePosition.Z > m_VhoverTargetHeight) - m_VhoverTargetHeight = VehiclePosition.Z; - } - - if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) - { - if (Math.Abs(VehiclePosition.Z - m_VhoverTargetHeight) > 0.2f) - { - Vector3 pos = VehiclePosition; - pos.Z = m_VhoverTargetHeight; - VehiclePosition = pos; - } - } - else - { - // Error is positive if below the target and negative if above. - float verticalError = m_VhoverTargetHeight - VehiclePosition.Z; - float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; - - // TODO: implement m_VhoverEfficiency correctly - if (Math.Abs(verticalError) > m_VhoverEfficiency) - { - ret = new Vector3(0f, 0f, verticalCorrectionVelocity); - } - } - - VDetailLog("{0}, MoveLinear,hover,pos={1},ret={2},hoverTS={3},height={4},target={5}", - Prim.LocalID, VehiclePosition, ret, m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight); - } - - return ret; - } - - public bool ComputeLinearBlockingEndPoint(float pTimestep) - { - bool changed = false; - - Vector3 pos = VehiclePosition; - Vector3 posChange = pos - m_lastPositionVector; - if (m_BlockingEndPoint != Vector3.Zero) - { - if (pos.X >= (m_BlockingEndPoint.X - (float)1)) - { - pos.X -= posChange.X + 1; - changed = true; - } - if (pos.Y >= (m_BlockingEndPoint.Y - (float)1)) - { - pos.Y -= posChange.Y + 1; - changed = true; - } - if (pos.Z >= (m_BlockingEndPoint.Z - (float)1)) - { - pos.Z -= posChange.Z + 1; - changed = true; - } - if (pos.X <= 0) - { - pos.X += posChange.X + 1; - changed = true; - } - if (pos.Y <= 0) - { - pos.Y += posChange.Y + 1; - changed = true; - } - if (changed) - { - VehiclePosition = pos; - VDetailLog("{0}, MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}", - Prim.LocalID, m_BlockingEndPoint, posChange, pos); - } - } - return changed; - } - - // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags : - // Prevent ground vehicles from motoring into the sky. This flag has a subtle effect when - // used with conjunction with banking: the strength of the banking will decay when the - // vehicle no longer experiences collisions. The decay timescale is the same as - // VEHICLE_BANKING_TIMESCALE. This is to help prevent ground vehicles from steering - // when they are in mid jump. - // TODO: this code is wrong. Also, what should it do for boats (height from water)? - // This is just using the ground and a general collision check. Should really be using - // a downward raycast to find what is below. - public Vector3 ComputeLinearMotorUp(float pTimestep) - { - Vector3 ret = Vector3.Zero; - float distanceAboveGround = 0f; - - if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) - { - float targetHeight = Type == Vehicle.TYPE_BOAT ? GetWaterLevel(VehiclePosition) : GetTerrainHeight(VehiclePosition); - distanceAboveGround = VehiclePosition.Z - targetHeight; - // Not colliding if the vehicle is off the ground - if (!Prim.IsColliding) - { - // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); - ret = new Vector3(0, 0, -distanceAboveGround); - } - // TODO: this calculation is wrong. From the description at - // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce - // has a decay factor. This says this force should - // be computed with a motor. - // TODO: add interaction with banking. - } - VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},colliding={2},ret={3}", - Prim.LocalID, distanceAboveGround, Prim.IsColliding, ret); - return ret; - } - - // ======================================================================= - // ======================================================================= - // Apply the effect of the angular motor. - // The 'contribution' is how much angular correction velocity each function wants. - // All the contributions are added together and the resulting velocity is - // set directly on the vehicle. - private void MoveAngular(float pTimestep) - { - // The user wants this many radians per second angular change? - Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); - - // ================================================================== - // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags : - // This flag prevents linear deflection parallel to world z-axis. This is useful - // for preventing ground vehicles with large linear deflection, like bumper cars, - // from climbing their linear deflection into the sky. - // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement - if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) - { - angularMotorContribution.X = 0f; - angularMotorContribution.Y = 0f; - VDetailLog("{0}, MoveAngular,noDeflectionUp,angularMotorContrib={1}", Prim.LocalID, angularMotorContribution); - } - - Vector3 verticalAttractionContribution = ComputeAngularVerticalAttraction(); - - Vector3 deflectionContribution = ComputeAngularDeflection(); - - Vector3 bankingContribution = ComputeAngularBanking(); - - // ================================================================== - m_lastVertAttractor = verticalAttractionContribution; - - m_lastAngularVelocity = angularMotorContribution - + verticalAttractionContribution - + deflectionContribution - + bankingContribution; - - // ================================================================== - // Apply the correction velocity. - // TODO: Should this be applied as an angular force (torque)? - if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) - { - VehicleRotationalVelocity = m_lastAngularVelocity; - - VDetailLog("{0}, MoveAngular,done,nonZero,angMotorContrib={1},vertAttrContrib={2},bankContrib={3},deflectContrib={4},totalContrib={5}", - Prim.LocalID, - angularMotorContribution, verticalAttractionContribution, - bankingContribution, deflectionContribution, - m_lastAngularVelocity - ); - } - else - { - // The vehicle is not adding anything angular wise. - VehicleRotationalVelocity = Vector3.Zero; - VDetailLog("{0}, MoveAngular,done,zero", Prim.LocalID); - } - - // ================================================================== - //Offset section - if (m_linearMotorOffset != Vector3.Zero) - { - //Offset of linear velocity doesn't change the linear velocity, - // but causes a torque to be applied, for example... - // - // IIIII >>> IIIII - // IIIII >>> IIIII - // IIIII >>> IIIII - // ^ - // | Applying a force at the arrow will cause the object to move forward, but also rotate - // - // - // The torque created is the linear velocity crossed with the offset - - // TODO: this computation should be in the linear section - // because that is where we know the impulse being applied. - Vector3 torqueFromOffset = Vector3.Zero; - // torqueFromOffset = Vector3.Cross(m_linearMotorOffset, appliedImpulse); - if (float.IsNaN(torqueFromOffset.X)) - torqueFromOffset.X = 0; - if (float.IsNaN(torqueFromOffset.Y)) - torqueFromOffset.Y = 0; - if (float.IsNaN(torqueFromOffset.Z)) - torqueFromOffset.Z = 0; - - VehicleAddAngularForce(torqueFromOffset * m_vehicleMass); - VDetailLog("{0}, BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset); - } - - } - // From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial: - // Some vehicles, like boats, should always keep their up-side up. This can be done by - // enabling the "vertical attractor" behavior that springs the vehicle's local z-axis to - // the world z-axis (a.k.a. "up"). To take advantage of this feature you would set the - // VEHICLE_VERTICAL_ATTRACTION_TIMESCALE to control the period of the spring frequency, - // and then set the VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY to control the damping. An - // efficiency of 0.0 will cause the spring to wobble around its equilibrium, while an - // efficiency of 1.0 will cause the spring to reach its equilibrium with exponential decay. - public Vector3 ComputeAngularVerticalAttraction() - { - Vector3 ret = Vector3.Zero; - - // If vertical attaction timescale is reasonable - if (m_verticalAttractionTimescale < m_verticalAttractionCutoff) - { - // Take a vector pointing up and convert it from world to vehicle relative coords. - Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; - - // If vertical attraction correction is needed, the vector that was pointing up (UnitZ) - // is now: - // leaning to one side: rotated around the X axis with the Y value going - // from zero (nearly straight up) to one (completely to the side)) or - // leaning front-to-back: rotated around the Y axis with the value of X being between - // zero and one. - // The value of Z is how far the rotation is off with 1 meaning none and 0 being 90 degrees. - - // Y error means needed rotation around X axis and visa versa. - // Since the error goes from zero to one, the asin is the corresponding angle. - ret.X = (float)Math.Asin(verticalError.Y); - // (Tilt forward (positive X) needs to tilt back (rotate negative) around Y axis.) - ret.Y = -(float)Math.Asin(verticalError.X); - - // If verticalError.Z is negative, the vehicle is upside down. Add additional push. - if (verticalError.Z < 0f) - { - ret.X += PIOverFour; - ret.Y += PIOverFour; - } - - // 'ret' is now the necessary velocity to correct tilt in one second. - // Correction happens over a number of seconds. - Vector3 unscaledContrib = ret; - ret /= m_verticalAttractionTimescale; - - VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},eff={3},ts={4},vertAttr={5}", - Prim.LocalID, verticalError, unscaledContrib, m_verticalAttractionEfficiency, m_verticalAttractionTimescale, ret); - } - return ret; - } - - // Return the angular correction to correct the direction the vehicle is pointing to be - // the direction is should want to be pointing. - // The vehicle is moving in some direction and correct its orientation to it is pointing - // in that direction. - // TODO: implement reference frame. - public Vector3 ComputeAngularDeflection() - { - Vector3 ret = Vector3.Zero; - return ret; // DEBUG DEBUG DEBUG - // Disable angular deflection for the moment. - // Since angularMotorUp and angularDeflection are computed independently, they will calculate - // approximately the same X or Y correction. When added together (when contributions are combined) - // this creates an over-correction and then wabbling as the target is overshot. - // TODO: rethink how the different correction computations inter-relate. - - if (m_angularDeflectionEfficiency != 0) - { - // The direction the vehicle is moving - Vector3 movingDirection = VehicleVelocity; - movingDirection.Normalize(); - - // The direction the vehicle is pointing - Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation; - pointingDirection.Normalize(); - - // The difference between what is and what should be. - Vector3 deflectionError = movingDirection - pointingDirection; - - // Don't try to correct very large errors (not our job) - if (Math.Abs(deflectionError.X) > PIOverFour) deflectionError.X = 0f; - if (Math.Abs(deflectionError.Y) > PIOverFour) deflectionError.Y = 0f; - if (Math.Abs(deflectionError.Z) > PIOverFour) deflectionError.Z = 0f; - - // ret = m_angularDeflectionCorrectionMotor(1f, deflectionError); - - // Scale the correction by recovery timescale and efficiency - ret = (-deflectionError) * m_angularDeflectionEfficiency; - ret /= m_angularDeflectionTimescale; - - VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}", - Prim.LocalID, movingDirection, pointingDirection, deflectionError, ret); - VDetailLog("{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3}", - Prim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale); - } - return ret; - } - - // Return an angular change to rotate the vehicle around the Z axis when the vehicle - // is tipped around the X axis. - // From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial: - // The vertical attractor feature must be enabled in order for the banking behavior to - // function. The way banking works is this: a rotation around the vehicle's roll-axis will - // produce a angular velocity around the yaw-axis, causing the vehicle to turn. The magnitude - // of the yaw effect will be proportional to the - // VEHICLE_BANKING_EFFICIENCY, the angle of the roll rotation, and sometimes the vehicle's - // velocity along its preferred axis of motion. - // The VEHICLE_BANKING_EFFICIENCY can vary between -1 and +1. When it is positive then any - // positive rotation (by the right-hand rule) about the roll-axis will effect a - // (negative) torque around the yaw-axis, making it turn to the right--that is the - // vehicle will lean into the turn, which is how real airplanes and motorcycle's work. - // Negating the banking coefficient will make it so that the vehicle leans to the - // outside of the turn (not very "physical" but might allow interesting vehicles so why not?). - // The VEHICLE_BANKING_MIX is a fake (i.e. non-physical) parameter that is useful for making - // banking vehicles do what you want rather than what the laws of physics allow. - // For example, consider a real motorcycle...it must be moving forward in order for - // it to turn while banking, however video-game motorcycles are often configured - // to turn in place when at a dead stop--because they are often easier to control - // that way using the limited interface of the keyboard or game controller. The - // VEHICLE_BANKING_MIX enables combinations of both realistic and non-realistic - // banking by functioning as a slider between a banking that is correspondingly - // totally static (0.0) and totally dynamic (1.0). By "static" we mean that the - // banking effect depends only on the vehicle's rotation about its roll-axis compared - // to "dynamic" where the banking is also proportional to its velocity along its - // roll-axis. Finding the best value of the "mixture" will probably require trial and error. - // The time it takes for the banking behavior to defeat a preexisting angular velocity about the - // world z-axis is determined by the VEHICLE_BANKING_TIMESCALE. So if you want the vehicle to - // bank quickly then give it a banking timescale of about a second or less, otherwise you can - // make a sluggish vehicle by giving it a timescale of several seconds. - public Vector3 ComputeAngularBanking() - { - Vector3 ret = Vector3.Zero; - - if (m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) - { - // This works by rotating a unit vector to the orientation of the vehicle. The - // roll (tilt) will be Y component of a tilting Z vector (zero for no tilt - // up to one for full over). - Vector3 rollComponents = Vector3.UnitZ * VehicleOrientation; - - // Figure out the yaw value for this much roll. - float turnComponent = rollComponents.Y * rollComponents.Y * m_bankingEfficiency; - // Keep the sign - if (rollComponents.Y < 0f) - turnComponent = -turnComponent; - - // TODO: there must be a better computation of the banking force. - float bankingTurnForce = turnComponent; - - // actual error = static turn error + dynamic turn error - float mixedBankingError = bankingTurnForce * (1f - m_bankingMix) + bankingTurnForce * m_bankingMix * VehicleForwardSpeed; - // TODO: the banking effect should not go to infinity but what to limit it to? - mixedBankingError = ClampInRange(-20f, mixedBankingError, 20f); - - // Build the force vector to change rotation from what it is to what it should be - ret.Z = -mixedBankingError; - - // Don't do it all at once. - ret /= m_bankingTimescale; - - VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},turnComp={3},bankErr={4},mixedBankErr={5},ret={6}", - Prim.LocalID, rollComponents, VehicleForwardSpeed, turnComponent, bankingTurnForce, mixedBankingError, ret); - } - return ret; - } - - // This is from previous instantiations of XXXDynamics.cs. - // Applies roll reference frame. - // TODO: is this the right way to separate the code to do this operation? - // Should this be in MoveAngular()? - internal void LimitRotation(float timestep) - { - Quaternion rotq = VehicleOrientation; - Quaternion m_rot = rotq; - if (m_RollreferenceFrame != Quaternion.Identity) - { - if (rotq.X >= m_RollreferenceFrame.X) - { - m_rot.X = rotq.X - (m_RollreferenceFrame.X / 2); - } - if (rotq.Y >= m_RollreferenceFrame.Y) - { - m_rot.Y = rotq.Y - (m_RollreferenceFrame.Y / 2); - } - if (rotq.X <= -m_RollreferenceFrame.X) - { - m_rot.X = rotq.X + (m_RollreferenceFrame.X / 2); - } - if (rotq.Y <= -m_RollreferenceFrame.Y) - { - m_rot.Y = rotq.Y + (m_RollreferenceFrame.Y / 2); - } - } - if ((m_flags & VehicleFlag.LOCK_ROTATION) != 0) - { - m_rot.X = 0; - m_rot.Y = 0; - } - if (rotq != m_rot) - { - VehicleOrientation = m_rot; - VDetailLog("{0}, LimitRotation,done,orig={1},new={2}", Prim.LocalID, rotq, m_rot); - } - - } - - private float ClampInRange(float low, float val, float high) - { - return Math.Max(low, Math.Min(val, high)); - // return Utils.Clamp(val, low, high); - } - - // Invoke the detailed logger and output something if it's enabled. - private void VDetailLog(string msg, params Object[] args) - { - if (Prim.PhysicsScene.VehicleLoggingEnabled) - Prim.PhysicsScene.DetailLog(msg, args); - } - } -} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSLinkset.cs deleted file mode 100644 index 845a113..0000000 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSLinkset.cs +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Text; - -using OMV = OpenMetaverse; - -namespace OpenSim.Region.Physics.BulletSNPlugin -{ - -// A BSPrim can get individual information about its linkedness attached -// to it through an instance of a subclass of LinksetInfo. -// Each type of linkset will define the information needed for its type. -public abstract class BSLinksetInfo -{ - public virtual void Clear() { } -} - -public abstract class BSLinkset -{ - // private static string LogHeader = "[BULLETSIM LINKSET]"; - - public enum LinksetImplementation - { - Constraint = 0, // linkset tied together with constraints - Compound = 1, // linkset tied together as a compound object - Manual = 2 // linkset tied together manually (code moves all the pieces) - } - // Create the correct type of linkset for this child - public static BSLinkset Factory(BSScene physScene, BSPhysObject parent) - { - BSLinkset ret = null; - - switch ((int)BSParam.LinksetImplementation) - { - case (int)LinksetImplementation.Constraint: - ret = new BSLinksetConstraints(physScene, parent); - break; - case (int)LinksetImplementation.Compound: - ret = new BSLinksetCompound(physScene, parent); - break; - case (int)LinksetImplementation.Manual: - // ret = new BSLinksetManual(physScene, parent); - break; - default: - ret = new BSLinksetCompound(physScene, parent); - break; - } - return ret; - } - - public BSPhysObject LinksetRoot { get; protected set; } - - public BSScene PhysicsScene { get; private set; } - - static int m_nextLinksetID = 1; - public int LinksetID { get; private set; } - - // The children under the root in this linkset. - protected HashSet m_children; - - // We lock the diddling of linkset classes to prevent any badness. - // This locks the modification of the instances of this class. Changes - // to the physical representation is done via the tainting mechenism. - protected object m_linksetActivityLock = new Object(); - - // Some linksets have a preferred physical shape. - // Returns SHAPE_UNKNOWN if there is no preference. Causes the correct shape to be selected. - public virtual BSPhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor) - { - return BSPhysicsShapeType.SHAPE_UNKNOWN; - } - - // We keep the prim's mass in the linkset structure since it could be dependent on other prims - public float LinksetMass { get; protected set; } - - public virtual bool LinksetIsColliding { get { return false; } } - - public OMV.Vector3 CenterOfMass - { - get { return ComputeLinksetCenterOfMass(); } - } - - public OMV.Vector3 GeometricCenter - { - get { return ComputeLinksetGeometricCenter(); } - } - - protected BSLinkset(BSScene scene, BSPhysObject parent) - { - // A simple linkset of one (no children) - LinksetID = m_nextLinksetID++; - // We create LOTS of linksets. - if (m_nextLinksetID <= 0) - m_nextLinksetID = 1; - PhysicsScene = scene; - LinksetRoot = parent; - m_children = new HashSet(); - LinksetMass = parent.RawMass; - Rebuilding = false; - } - - // Link to a linkset where the child knows the parent. - // Parent changing should not happen so do some sanity checking. - // We return the parent's linkset so the child can track its membership. - // Called at runtime. - public BSLinkset AddMeToLinkset(BSPhysObject child) - { - lock (m_linksetActivityLock) - { - // Don't add the root to its own linkset - if (!IsRoot(child)) - AddChildToLinkset(child); - LinksetMass = ComputeLinksetMass(); - } - return this; - } - - // Remove a child from a linkset. - // Returns a new linkset for the child which is a linkset of one (just the - // orphened child). - // Called at runtime. - public BSLinkset RemoveMeFromLinkset(BSPhysObject child) - { - lock (m_linksetActivityLock) - { - if (IsRoot(child)) - { - // Cannot remove the root from a linkset. - return this; - } - RemoveChildFromLinkset(child); - LinksetMass = ComputeLinksetMass(); - } - - // The child is down to a linkset of just itself - return BSLinkset.Factory(PhysicsScene, child); - } - - // Return 'true' if the passed object is the root object of this linkset - public bool IsRoot(BSPhysObject requestor) - { - return (requestor.LocalID == LinksetRoot.LocalID); - } - - public int NumberOfChildren { get { return m_children.Count; } } - - // Return 'true' if this linkset has any children (more than the root member) - public bool HasAnyChildren { get { return (m_children.Count > 0); } } - - // Return 'true' if this child is in this linkset - public bool HasChild(BSPhysObject child) - { - bool ret = false; - lock (m_linksetActivityLock) - { - ret = m_children.Contains(child); - /* Safer version but the above should work - foreach (BSPhysObject bp in m_children) - { - if (child.LocalID == bp.LocalID) - { - ret = true; - break; - } - } - */ - } - return ret; - } - - // Perform an action on each member of the linkset including root prim. - // Depends on the action on whether this should be done at taint time. - public delegate bool ForEachMemberAction(BSPhysObject obj); - public virtual bool ForEachMember(ForEachMemberAction action) - { - bool ret = false; - lock (m_linksetActivityLock) - { - action(LinksetRoot); - foreach (BSPhysObject po in m_children) - { - if (action(po)) - break; - } - } - return ret; - } - - // I am the root of a linkset and a new child is being added - // Called while LinkActivity is locked. - protected abstract void AddChildToLinkset(BSPhysObject child); - - // I am the root of a linkset and one of my children is being removed. - // Safe to call even if the child is not really in my linkset. - protected abstract void RemoveChildFromLinkset(BSPhysObject child); - - // When physical properties are changed the linkset needs to recalculate - // its internal properties. - // May be called at runtime or taint-time. - public virtual void Refresh(BSPhysObject requestor) - { - LinksetMass = ComputeLinksetMass(); - } - - // Flag denoting the linkset is in the process of being rebuilt. - // Used to know not the schedule a rebuild in the middle of a rebuild. - protected bool Rebuilding { get; set; } - - // The object is going dynamic (physical). Do any setup necessary - // for a dynamic linkset. - // Only the state of the passed object can be modified. The rest of the linkset - // has not yet been fully constructed. - // Return 'true' if any properties updated on the passed object. - // Called at taint-time! - public abstract bool MakeDynamic(BSPhysObject child); - - // The object is going static (non-physical). Do any setup necessary - // for a static linkset. - // Return 'true' if any properties updated on the passed object. - // Called at taint-time! - public abstract bool MakeStatic(BSPhysObject child); - - // Called when a parameter update comes from the physics engine for any object - // of the linkset is received. - // Passed flag is update came from physics engine (true) or the user (false). - // Called at taint-time!! - public abstract void UpdateProperties(BSPhysObject physObject, bool physicalUpdate); - - // Routine used when rebuilding the body of the root of the linkset - // Destroy all the constraints have have been made to root. - // This is called when the root body is changing. - // Returns 'true' of something was actually removed and would need restoring - // Called at taint-time!! - public abstract bool RemoveBodyDependencies(BSPrim child); - - // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true', - // this routine will restore the removed constraints. - // Called at taint-time!! - public abstract void RestoreBodyDependencies(BSPrim child); - - // ================================================================ - protected virtual float ComputeLinksetMass() - { - float mass = LinksetRoot.RawMass; - if (HasAnyChildren) - { - lock (m_linksetActivityLock) - { - foreach (BSPhysObject bp in m_children) - { - mass += bp.RawMass; - } - } - } - return mass; - } - - protected virtual OMV.Vector3 ComputeLinksetCenterOfMass() - { - OMV.Vector3 com; - lock (m_linksetActivityLock) - { - com = LinksetRoot.Position * LinksetRoot.RawMass; - float totalMass = LinksetRoot.RawMass; - - foreach (BSPhysObject bp in m_children) - { - com += bp.Position * bp.RawMass; - totalMass += bp.RawMass; - } - if (totalMass != 0f) - com /= totalMass; - } - - return com; - } - - protected virtual OMV.Vector3 ComputeLinksetGeometricCenter() - { - OMV.Vector3 com; - lock (m_linksetActivityLock) - { - com = LinksetRoot.Position; - - foreach (BSPhysObject bp in m_children) - { - com += bp.Position * bp.RawMass; - } - com /= (m_children.Count + 1); - } - - return com; - } - - // Invoke the detailed logger and output something if it's enabled. - protected void DetailLog(string msg, params Object[] args) - { - if (PhysicsScene.PhysicsLogging.Enabled) - PhysicsScene.DetailLog(msg, args); - } - -} -} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetCompound.cs deleted file mode 100644 index 9a977e6..0000000 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetCompound.cs +++ /dev/null @@ -1,397 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Text; - -using OpenSim.Framework; - -using OMV = OpenMetaverse; - -namespace OpenSim.Region.Physics.BulletSNPlugin -{ - -// When a child is linked, the relationship position of the child to the parent -// is remembered so the child's world position can be recomputed when it is -// removed from the linkset. -sealed class BSLinksetCompoundInfo : BSLinksetInfo -{ - public OMV.Vector3 OffsetPos; - public OMV.Quaternion OffsetRot; - public BSLinksetCompoundInfo(OMV.Vector3 p, OMV.Quaternion r) - { - OffsetPos = p; - OffsetRot = r; - } - public override void Clear() - { - OffsetPos = OMV.Vector3.Zero; - OffsetRot = OMV.Quaternion.Identity; - } - public override string ToString() - { - StringBuilder buff = new StringBuilder(); - buff.Append(""); - return buff.ToString(); - } -}; - -public sealed class BSLinksetCompound : BSLinkset -{ - private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]"; - - public BSLinksetCompound(BSScene scene, BSPhysObject parent) : base(scene, parent) - { - } - - // For compound implimented linksets, if there are children, use compound shape for the root. - public override BSPhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor) - { - // Returning 'unknown' means we don't have a preference. - BSPhysicsShapeType ret = BSPhysicsShapeType.SHAPE_UNKNOWN; - if (IsRoot(requestor) && HasAnyChildren) - { - ret = BSPhysicsShapeType.SHAPE_COMPOUND; - } - // DetailLog("{0},BSLinksetCompound.PreferredPhysicalShape,call,shape={1}", LinksetRoot.LocalID, ret); - return ret; - } - - // When physical properties are changed the linkset needs to recalculate - // its internal properties. - public override void Refresh(BSPhysObject requestor) - { - base.Refresh(requestor); - - // Something changed so do the rebuilding thing - // ScheduleRebuild(); - } - - // Schedule a refresh to happen after all the other taint processing. - private void ScheduleRebuild(BSPhysObject requestor) - { - DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1}", - requestor.LocalID, Rebuilding); - // When rebuilding, it is possible to set properties that would normally require a rebuild. - // If already rebuilding, don't request another rebuild. - if (!Rebuilding) - { - PhysicsScene.PostTaintObject("BSLinksetCompound.ScheduleRebuild", LinksetRoot.LocalID, delegate() - { - if (HasAnyChildren) - RecomputeLinksetCompound(); - }); - } - } - - // The object is going dynamic (physical). Do any setup necessary - // for a dynamic linkset. - // Only the state of the passed object can be modified. The rest of the linkset - // has not yet been fully constructed. - // Return 'true' if any properties updated on the passed object. - // Called at taint-time! - public override bool MakeDynamic(BSPhysObject child) - { - bool ret = false; - DetailLog("{0},BSLinksetCompound.MakeDynamic,call,IsRoot={1}", child.LocalID, IsRoot(child)); - if (IsRoot(child)) - { - // The root is going dynamic. Make sure mass is properly set. - ScheduleRebuild(LinksetRoot); - } - else - { - // The origional prims are removed from the world as the shape of the root compound - // shape takes over. - BulletSimAPI.AddToCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); - BulletSimAPI.ForceActivationState2(child.PhysBody.ptr, ActivationState.DISABLE_SIMULATION); - // We don't want collisions from the old linkset children. - BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); - - child.PhysBody.collisionType = CollisionType.LinksetChild; - - ret = true; - } - return ret; - } - - // The object is going static (non-physical). Do any setup necessary for a static linkset. - // Return 'true' if any properties updated on the passed object. - // This doesn't normally happen -- OpenSim removes the objects from the physical - // world if it is a static linkset. - // Called at taint-time! - public override bool MakeStatic(BSPhysObject child) - { - bool ret = false; - DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child)); - if (IsRoot(child)) - { - ScheduleRebuild(LinksetRoot); - } - else - { - // The non-physical children can come back to life. - BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); - - child.PhysBody.collisionType = CollisionType.LinksetChild; - - // Don't force activation so setting of DISABLE_SIMULATION can stay if used. - BulletSimAPI.Activate2(child.PhysBody.ptr, false); - ret = true; - } - return ret; - } - - public override void UpdateProperties(BSPhysObject updated, bool physicalUpdate) - { - // The user moving a child around requires the rebuilding of the linkset compound shape - // One problem is this happens when a border is crossed -- the simulator implementation - // is to store the position into the group which causes the move of the object - // but it also means all the child positions get updated. - // What would cause an unnecessary rebuild so we make sure the linkset is in a - // region before bothering to do a rebuild. - if (!IsRoot(updated) - && !physicalUpdate - && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition)) - { - updated.LinksetInfo = null; - ScheduleRebuild(updated); - } - } - - // Routine called when rebuilding the body of some member of the linkset. - // Since we don't keep in world relationships, do nothing unless it's a child changing. - // Returns 'true' of something was actually removed and would need restoring - // Called at taint-time!! - public override bool RemoveBodyDependencies(BSPrim child) - { - bool ret = false; - - DetailLog("{0},BSLinksetCompound.RemoveBodyDependencies,refreshIfChild,rID={1},rBody={2},isRoot={3}", - child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString(), IsRoot(child)); - - if (!IsRoot(child)) - { - // Because it is a convenient time, recompute child world position and rotation based on - // its position in the linkset. - RecomputeChildWorldPosition(child, true); - } - - // Cannot schedule a refresh/rebuild here because this routine is called when - // the linkset is being rebuilt. - // InternalRefresh(LinksetRoot); - - return ret; - } - - // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true', - // this routine will restore the removed constraints. - // Called at taint-time!! - public override void RestoreBodyDependencies(BSPrim child) - { - } - - // When the linkset is built, the child shape is added to the compound shape relative to the - // root shape. The linkset then moves around but this does not move the actual child - // prim. The child prim's location must be recomputed based on the location of the root shape. - private void RecomputeChildWorldPosition(BSPhysObject child, bool inTaintTime) - { - BSLinksetCompoundInfo lci = child.LinksetInfo as BSLinksetCompoundInfo; - if (lci != null) - { - if (inTaintTime) - { - OMV.Vector3 oldPos = child.RawPosition; - child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetPos; - child.ForceOrientation = LinksetRoot.RawOrientation * lci.OffsetRot; - DetailLog("{0},BSLinksetCompound.RecomputeChildWorldPosition,oldPos={1},lci={2},newPos={3}", - child.LocalID, oldPos, lci, child.RawPosition); - } - else - { - // TaintedObject is not used here so the raw position is set now and not at taint-time. - child.Position = LinksetRoot.RawPosition + lci.OffsetPos; - child.Orientation = LinksetRoot.RawOrientation * lci.OffsetRot; - } - } - else - { - // This happens when children have been added to the linkset but the linkset - // has not been constructed yet. So like, at taint time, adding children to a linkset - // and then changing properties of the children (makePhysical, for instance) - // but the post-print action of actually rebuilding the linkset has not yet happened. - // PhysicsScene.Logger.WarnFormat("{0} Restoring linkset child position failed because of no relative position computed. ID={1}", - // LogHeader, child.LocalID); - DetailLog("{0},BSLinksetCompound.recomputeChildWorldPosition,noRelativePositonInfo", child.LocalID); - } - } - - // ================================================================ - - // Add a new child to the linkset. - // Called while LinkActivity is locked. - protected override void AddChildToLinkset(BSPhysObject child) - { - if (!HasChild(child)) - { - m_children.Add(child); - - DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); - - // Rebuild the compound shape with the new child shape included - ScheduleRebuild(child); - } - return; - } - - // Remove the specified child from the linkset. - // Safe to call even if the child is not really in the linkset. - protected override void RemoveChildFromLinkset(BSPhysObject child) - { - if (m_children.Remove(child)) - { - DetailLog("{0},BSLinksetCompound.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}", - child.LocalID, - LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString(), - child.LocalID, child.PhysBody.ptr.ToString()); - - // Cause the child's body to be rebuilt and thus restored to normal operation - RecomputeChildWorldPosition(child, false); - child.ForceBodyShapeRebuild(false); - - if (!HasAnyChildren) - { - // The linkset is now empty. The root needs rebuilding. - LinksetRoot.ForceBodyShapeRebuild(false); - } - else - { - // Rebuild the compound shape with the child removed - ScheduleRebuild(child); - } - } - return; - } - - // Called before the simulation step to make sure the compound based linkset - // is all initialized. - // Constraint linksets are rebuilt every time. - // Note that this works for rebuilding just the root after a linkset is taken apart. - // Called at taint time!! - private void RecomputeLinksetCompound() - { - try - { - // Suppress rebuilding while rebuilding - Rebuilding = true; - - // Cause the root shape to be rebuilt as a compound object with just the root in it - LinksetRoot.ForceBodyShapeRebuild(true); - - DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", - LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); - - // Add a shape for each of the other children in the linkset - ForEachMember(delegate(BSPhysObject cPrim) - { - if (!IsRoot(cPrim)) - { - // Compute the displacement of the child from the root of the linkset. - // This info is saved in the child prim so the relationship does not - // change over time and the new child position can be computed - // when the linkset is being disassembled (the linkset may have moved). - BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; - if (lci == null) - { - // Each child position and rotation is given relative to the root. - OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); - OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; - OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; - - // Save relative position for recomputing child's world position after moving linkset. - lci = new BSLinksetCompoundInfo(displacementPos, displacementRot); - cPrim.LinksetInfo = lci; - DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); - } - - DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}", - LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); - - if (cPrim.PhysShape.isNativeShape) - { - // A native shape is turning into a hull collision shape because native - // shapes are not shared so we have to hullify it so it will be tracked - // and freed at the correct time. This also solves the scaling problem - // (native shapes scaled but hull/meshes are assumed to not be). - // TODO: decide of the native shape can just be used in the compound shape. - // Use call to CreateGeomNonSpecial(). - BulletShape saveShape = cPrim.PhysShape; - cPrim.PhysShape.Clear(); // Don't let the create free the child's shape - // PhysicsScene.Shapes.CreateGeomNonSpecial(true, cPrim, null); - PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); - BulletShape newShape = cPrim.PhysShape; - cPrim.PhysShape = saveShape; - BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, newShape.ptr, lci.OffsetPos, lci.OffsetRot); - } - else - { - // For the shared shapes (meshes and hulls), just use the shape in the child. - // The reference count added here will be decremented when the compound shape - // is destroyed in BSShapeCollection (the child shapes are looped over and dereferenced). - if (PhysicsScene.Shapes.ReferenceShape(cPrim.PhysShape)) - { - PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", - LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); - } - BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, cPrim.PhysShape.ptr, lci.OffsetPos, lci.OffsetRot); - } - } - return false; // 'false' says to move onto the next child in the list - }); - - // With all of the linkset packed into the root prim, it has the mass of everyone. - LinksetMass = LinksetMass; - LinksetRoot.UpdatePhysicalMassProperties(LinksetMass, true); - } - finally - { - Rebuilding = false; - } - - BulletSimAPI.RecalculateCompoundShapeLocalAabb2(LinksetRoot.PhysShape.ptr); - - // DEBUG: see of inter-linkset collisions are causing problems for constraint linksets. - // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, - // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); - - } -} -} \ No newline at end of file diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetConstraints.cs deleted file mode 100644 index 46ff99f..0000000 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSLinksetConstraints.cs +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Text; - -using OMV = OpenMetaverse; - -namespace OpenSim.Region.Physics.BulletSNPlugin -{ -public sealed class BSLinksetConstraints : BSLinkset -{ - // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]"; - - public BSLinksetConstraints(BSScene scene, BSPhysObject parent) : base(scene, parent) - { - } - - // When physical properties are changed the linkset needs to recalculate - // its internal properties. - // This is queued in the 'post taint' queue so the - // refresh will happen once after all the other taints are applied. - public override void Refresh(BSPhysObject requestor) - { - base.Refresh(requestor); - - // Queue to happen after all the other taint processing - PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate() - { - if (HasAnyChildren && IsRoot(requestor)) - RecomputeLinksetConstraints(); - }); - } - - // The object is going dynamic (physical). Do any setup necessary - // for a dynamic linkset. - // Only the state of the passed object can be modified. The rest of the linkset - // has not yet been fully constructed. - // Return 'true' if any properties updated on the passed object. - // Called at taint-time! - public override bool MakeDynamic(BSPhysObject child) - { - // What is done for each object in BSPrim is what we want. - return false; - } - - // The object is going static (non-physical). Do any setup necessary for a static linkset. - // Return 'true' if any properties updated on the passed object. - // This doesn't normally happen -- OpenSim removes the objects from the physical - // world if it is a static linkset. - // Called at taint-time! - public override bool MakeStatic(BSPhysObject child) - { - // What is done for each object in BSPrim is what we want. - return false; - } - - // Called at taint-time!! - public override void UpdateProperties(BSPhysObject updated, bool inTaintTime) - { - // Nothing to do for constraints on property updates - } - - // Routine called when rebuilding the body of some member of the linkset. - // Destroy all the constraints have have been made to root and set - // up to rebuild the constraints before the next simulation step. - // Returns 'true' of something was actually removed and would need restoring - // Called at taint-time!! - public override bool RemoveBodyDependencies(BSPrim child) - { - bool ret = false; - - DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}", - child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString()); - - lock (m_linksetActivityLock) - { - // Just undo all the constraints for this linkset. Rebuild at the end of the step. - ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot); - // Cause the constraints, et al to be rebuilt before the next simulation step. - Refresh(LinksetRoot); - } - return ret; - } - - // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true', - // this routine will restore the removed constraints. - // Called at taint-time!! - public override void RestoreBodyDependencies(BSPrim child) - { - // The Refresh operation queued by RemoveBodyDependencies() will build any missing constraints. - } - - // ================================================================ - - // Add a new child to the linkset. - // Called while LinkActivity is locked. - protected override void AddChildToLinkset(BSPhysObject child) - { - if (!HasChild(child)) - { - m_children.Add(child); - - DetailLog("{0},BSLinksetConstraints.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); - - // Cause constraints and assorted properties to be recomputed before the next simulation step. - Refresh(LinksetRoot); - } - return; - } - - // Remove the specified child from the linkset. - // Safe to call even if the child is not really in my linkset. - protected override void RemoveChildFromLinkset(BSPhysObject child) - { - if (m_children.Remove(child)) - { - BSPhysObject rootx = LinksetRoot; // capture the root and body as of now - BSPhysObject childx = child; - - DetailLog("{0},BSLinksetConstraints.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}", - childx.LocalID, - rootx.LocalID, rootx.PhysBody.ptr.ToString(), - childx.LocalID, childx.PhysBody.ptr.ToString()); - - PhysicsScene.TaintedObject("BSLinksetConstraints.RemoveChildFromLinkset", delegate() - { - PhysicallyUnlinkAChildFromRoot(rootx, childx); - }); - // See that the linkset parameters are recomputed at the end of the taint time. - Refresh(LinksetRoot); - } - else - { - // Non-fatal occurance. - // PhysicsScene.Logger.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset", LogHeader); - } - return; - } - - // Create a constraint between me (root of linkset) and the passed prim (the child). - // Called at taint time! - private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BSPhysObject childPrim) - { - // Don't build the constraint when asked. Put it off until just before the simulation step. - Refresh(rootPrim); - } - - private BSConstraint BuildConstraint(BSPhysObject rootPrim, BSPhysObject childPrim) - { - // Zero motion for children so they don't interpolate - childPrim.ZeroMotion(true); - - // Relative position normalized to the root prim - // Essentually a vector pointing from center of rootPrim to center of childPrim - OMV.Vector3 childRelativePosition = childPrim.Position - rootPrim.Position; - - // real world coordinate of midpoint between the two objects - OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2); - - DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", - rootPrim.LocalID, - rootPrim.LocalID, rootPrim.PhysBody.ptr.ToString(), - childPrim.LocalID, childPrim.PhysBody.ptr.ToString(), - rootPrim.Position, childPrim.Position, midPoint); - - // create a constraint that allows no freedom of movement between the two objects - // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 - - BSConstraint6Dof constrain = new BSConstraint6Dof( - PhysicsScene.World, rootPrim.PhysBody, childPrim.PhysBody, midPoint, true, true ); - // PhysicsScene.World, childPrim.BSBody, rootPrim.BSBody, midPoint, true, true ); - - /* NOTE: below is an attempt to build constraint with full frame computation, etc. - * Using the midpoint is easier since it lets the Bullet code manipulate the transforms - * of the objects. - * Code left for future programmers. - // ================================================================================== - // relative position normalized to the root prim - OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation); - OMV.Vector3 childRelativePosition = (childPrim.Position - rootPrim.Position) * invThisOrientation; - - // relative rotation of the child to the parent - OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation; - OMV.Quaternion inverseChildRelativeRotation = OMV.Quaternion.Inverse(childRelativeRotation); - - DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); - BS6DofConstraint constrain = new BS6DofConstraint( - PhysicsScene.World, rootPrim.Body, childPrim.Body, - OMV.Vector3.Zero, - OMV.Quaternion.Inverse(rootPrim.Orientation), - OMV.Vector3.Zero, - OMV.Quaternion.Inverse(childPrim.Orientation), - true, - true - ); - // ================================================================================== - */ - - PhysicsScene.Constraints.AddConstraint(constrain); - - // zero linear and angular limits makes the objects unable to move in relation to each other - constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); - constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); - - // tweek the constraint to increase stability - constrain.UseFrameOffset(BSParam.BoolNumeric(BSParam.LinkConstraintUseFrameOffset)); - constrain.TranslationalLimitMotor(BSParam.BoolNumeric(BSParam.LinkConstraintEnableTransMotor), - BSParam.LinkConstraintTransMotorMaxVel, - BSParam.LinkConstraintTransMotorMaxForce); - constrain.SetCFMAndERP(BSParam.LinkConstraintCFM, BSParam.LinkConstraintERP); - if (BSParam.LinkConstraintSolverIterations != 0f) - { - constrain.SetSolverIterations(BSParam.LinkConstraintSolverIterations); - } - return constrain; - } - - // Remove linkage between the linkset root and a particular child - // The root and child bodies are passed in because we need to remove the constraint between - // the bodies that were present at unlink time. - // Called at taint time! - private bool PhysicallyUnlinkAChildFromRoot(BSPhysObject rootPrim, BSPhysObject childPrim) - { - bool ret = false; - DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}", - rootPrim.LocalID, - rootPrim.LocalID, rootPrim.PhysBody.ptr.ToString(), - childPrim.LocalID, childPrim.PhysBody.ptr.ToString()); - - // Find the constraint for this link and get rid of it from the overall collection and from my list - if (PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody, childPrim.PhysBody)) - { - // Make the child refresh its location - BulletSimAPI.PushUpdate2(childPrim.PhysBody.ptr); - ret = true; - } - - return ret; - } - - // Remove linkage between myself and any possible children I might have. - // Returns 'true' of any constraints were destroyed. - // Called at taint time! - private bool PhysicallyUnlinkAllChildrenFromRoot(BSPhysObject rootPrim) - { - DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); - - return PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody); - } - - // Call each of the constraints that make up this linkset and recompute the - // various transforms and variables. Create constraints of not created yet. - // Called before the simulation step to make sure the constraint based linkset - // is all initialized. - // Called at taint time!! - private void RecomputeLinksetConstraints() - { - float linksetMass = LinksetMass; - LinksetRoot.UpdatePhysicalMassProperties(linksetMass, true); - - // DEBUG: see of inter-linkset collisions are causing problems - // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, - // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); - DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}", - LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString(), linksetMass); - - foreach (BSPhysObject child in m_children) - { - // A child in the linkset physically shows the mass of the whole linkset. - // This allows Bullet to apply enough force on the child to move the whole linkset. - // (Also do the mass stuff before recomputing the constraint so mass is not zero.) - child.UpdatePhysicalMassProperties(linksetMass, true); - - BSConstraint constrain; - if (!PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, child.PhysBody, out constrain)) - { - // If constraint doesn't exist yet, create it. - constrain = BuildConstraint(LinksetRoot, child); - } - constrain.RecomputeConstraintVariables(linksetMass); - - // DEBUG: see of inter-linkset collisions are causing problems - // BulletSimAPI.SetCollisionFilterMask2(child.BSBody.ptr, - // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); - - // BulletSimAPI.DumpConstraint2(PhysicsScene.World.ptr, constrain.Constraint.ptr); // DEBUG DEBUG - } - - } -} -} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSMaterials.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSMaterials.cs deleted file mode 100644 index d7941b6..0000000 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSMaterials.cs +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Text; -using System.Reflection; -using Nini.Config; - -namespace OpenSim.Region.Physics.BulletSNPlugin -{ - -public struct MaterialAttributes -{ - // Material type values that correspond with definitions for LSL - public enum Material : int - { - Stone = 0, - Metal, - Glass, - Wood, - Flesh, - Plastic, - Rubber, - Light, - // Hereafter are BulletSim additions - Avatar, - NumberOfTypes // the count of types in the enum. - } - - // Names must be in the order of the above enum. - // These names must coorespond to the lower case field names in the MaterialAttributes - // structure as reflection is used to select the field to put the value in. - public static readonly string[] MaterialAttribs = { "Density", "Friction", "Restitution"}; - - public MaterialAttributes(string t, float d, float f, float r) - { - type = t; - density = d; - friction = f; - restitution = r; - } - public string type; - public float density; - public float friction; - public float restitution; -} - -public static class BSMaterials -{ - // Attributes for each material type - private static readonly MaterialAttributes[] Attributes; - - // Map of material name to material type code - public static readonly Dictionary MaterialMap; - - static BSMaterials() - { - // Attribute sets for both the non-physical and physical instances of materials. - Attributes = new MaterialAttributes[(int)MaterialAttributes.Material.NumberOfTypes * 2]; - - // Map of name to type code. - MaterialMap = new Dictionary(); - MaterialMap.Add("Stone", MaterialAttributes.Material.Stone); - MaterialMap.Add("Metal", MaterialAttributes.Material.Metal); - MaterialMap.Add("Glass", MaterialAttributes.Material.Glass); - MaterialMap.Add("Wood", MaterialAttributes.Material.Wood); - MaterialMap.Add("Flesh", MaterialAttributes.Material.Flesh); - MaterialMap.Add("Plastic", MaterialAttributes.Material.Plastic); - MaterialMap.Add("Rubber", MaterialAttributes.Material.Rubber); - MaterialMap.Add("Light", MaterialAttributes.Material.Light); - MaterialMap.Add("Avatar", MaterialAttributes.Material.Avatar); - } - - // This is where all the default material attributes are defined. - public static void InitializeFromDefaults(ConfigurationParameters parms) - { - // Values from http://wiki.secondlife.com/wiki/PRIM_MATERIAL - float dDensity = parms.defaultDensity; - float dFriction = parms.defaultFriction; - float dRestitution = parms.defaultRestitution; - Attributes[(int)MaterialAttributes.Material.Stone] = - new MaterialAttributes("stone",dDensity, 0.8f, 0.4f); - Attributes[(int)MaterialAttributes.Material.Metal] = - new MaterialAttributes("metal",dDensity, 0.3f, 0.4f); - Attributes[(int)MaterialAttributes.Material.Glass] = - new MaterialAttributes("glass",dDensity, 0.2f, 0.7f); - Attributes[(int)MaterialAttributes.Material.Wood] = - new MaterialAttributes("wood",dDensity, 0.6f, 0.5f); - Attributes[(int)MaterialAttributes.Material.Flesh] = - new MaterialAttributes("flesh",dDensity, 0.9f, 0.3f); - Attributes[(int)MaterialAttributes.Material.Plastic] = - new MaterialAttributes("plastic",dDensity, 0.4f, 0.7f); - Attributes[(int)MaterialAttributes.Material.Rubber] = - new MaterialAttributes("rubber",dDensity, 0.9f, 0.9f); - Attributes[(int)MaterialAttributes.Material.Light] = - new MaterialAttributes("light",dDensity, dFriction, dRestitution); - Attributes[(int)MaterialAttributes.Material.Avatar] = - new MaterialAttributes("avatar",3.5f, 0.2f, 0f); - - Attributes[(int)MaterialAttributes.Material.Stone + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("stonePhysical",dDensity, 0.8f, 0.4f); - Attributes[(int)MaterialAttributes.Material.Metal + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("metalPhysical",dDensity, 0.3f, 0.4f); - Attributes[(int)MaterialAttributes.Material.Glass + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("glassPhysical",dDensity, 0.2f, 0.7f); - Attributes[(int)MaterialAttributes.Material.Wood + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("woodPhysical",dDensity, 0.6f, 0.5f); - Attributes[(int)MaterialAttributes.Material.Flesh + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("fleshPhysical",dDensity, 0.9f, 0.3f); - Attributes[(int)MaterialAttributes.Material.Plastic + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("plasticPhysical",dDensity, 0.4f, 0.7f); - Attributes[(int)MaterialAttributes.Material.Rubber + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("rubberPhysical",dDensity, 0.9f, 0.9f); - Attributes[(int)MaterialAttributes.Material.Light + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("lightPhysical",dDensity, dFriction, dRestitution); - Attributes[(int)MaterialAttributes.Material.Avatar + (int)MaterialAttributes.Material.NumberOfTypes] = - new MaterialAttributes("avatarPhysical",3.5f, 0.2f, 0f); - } - - // Under the [BulletSim] section, one can change the individual material - // attribute values. The format of the configuration parameter is: - // ["Physical"] = floatValue - // For instance: - // [BulletSim] - // StoneFriction = 0.2 - // FleshRestitutionPhysical = 0.8 - // Materials can have different parameters for their static and - // physical instantiations. When setting the non-physical value, - // both values are changed. Setting the physical value only changes - // the physical value. - public static void InitializefromParameters(IConfig pConfig) - { - foreach (KeyValuePair kvp in MaterialMap) - { - string matName = kvp.Key; - foreach (string attribName in MaterialAttributes.MaterialAttribs) - { - string paramName = matName + attribName; - if (pConfig.Contains(paramName)) - { - float paramValue = pConfig.GetFloat(paramName); - SetAttributeValue((int)kvp.Value, attribName, paramValue); - // set the physical value also - SetAttributeValue((int)kvp.Value + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue); - } - paramName += "Physical"; - if (pConfig.Contains(paramName)) - { - float paramValue = pConfig.GetFloat(paramName); - SetAttributeValue((int)kvp.Value + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue); - } - } - } - } - - // Use reflection to set the value in the attribute structure. - private static void SetAttributeValue(int matType, string attribName, float val) - { - MaterialAttributes thisAttrib = Attributes[matType]; - FieldInfo fieldInfo = thisAttrib.GetType().GetField(attribName.ToLower()); - if (fieldInfo != null) - { - fieldInfo.SetValue(thisAttrib, val); - Attributes[matType] = thisAttrib; - } - } - - // Given a material type, return a structure of attributes. - public static MaterialAttributes GetAttributes(MaterialAttributes.Material type, bool isPhysical) - { - int ind = (int)type; - if (isPhysical) ind += (int)MaterialAttributes.Material.NumberOfTypes; - return Attributes[ind]; - } -} -} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSMotors.cs deleted file mode 100644 index 7abc9b2..0000000 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSMotors.cs +++ /dev/null @@ -1,347 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ -using System; -using System.Collections.Generic; -using System.Text; -using OpenMetaverse; -using OpenSim.Framework; - -namespace OpenSim.Region.Physics.BulletSNPlugin -{ -public abstract class BSMotor -{ - // Timescales and other things can be turned off by setting them to 'infinite'. - public const float Infinite = 12345.6f; - public readonly static Vector3 InfiniteVector = new Vector3(BSMotor.Infinite, BSMotor.Infinite, BSMotor.Infinite); - - public BSMotor(string useName) - { - UseName = useName; - PhysicsScene = null; - Enabled = true; - } - public virtual bool Enabled { get; set; } - public virtual void Reset() { } - public virtual void Zero() { } - public virtual void GenerateTestOutput(float timeStep) { } - - // A name passed at motor creation for easily identifyable debugging messages. - public string UseName { get; private set; } - - // Used only for outputting debug information. Might not be set so check for null. - public BSScene PhysicsScene { get; set; } - protected void MDetailLog(string msg, params Object[] parms) - { - if (PhysicsScene != null) - { - if (PhysicsScene.VehicleLoggingEnabled) - { - PhysicsScene.DetailLog(msg, parms); - } - } - } -} - -// Motor which moves CurrentValue to TargetValue over TimeScale seconds. -// The TargetValue decays in TargetValueDecayTimeScale and -// the CurrentValue will be held back by FrictionTimeScale. -// This motor will "zero itself" over time in that the targetValue will -// decay to zero and the currentValue will follow it to that zero. -// The overall effect is for the returned correction value to go from large -// values (the total difference between current and target minus friction) -// to small and eventually zero values. -// TimeScale and TargetDelayTimeScale may be 'infinite' which means no decay. - -// For instance, if something is moving at speed X and the desired speed is Y, -// CurrentValue is X and TargetValue is Y. As the motor is stepped, new -// values of CurrentValue are returned that approach the TargetValue. -// The feature of decaying TargetValue is so vehicles will eventually -// come to a stop rather than run forever. This can be disabled by -// setting TargetValueDecayTimescale to 'infinite'. -// The change from CurrentValue to TargetValue is linear over TimeScale seconds. -public class BSVMotor : BSMotor -{ - // public Vector3 FrameOfReference { get; set; } - // public Vector3 Offset { get; set; } - - public virtual float TimeScale { get; set; } - public virtual float TargetValueDecayTimeScale { get; set; } - public virtual Vector3 FrictionTimescale { get; set; } - public virtual float Efficiency { get; set; } - - public virtual float ErrorZeroThreshold { get; set; } - - public virtual Vector3 TargetValue { get; protected set; } - public virtual Vector3 CurrentValue { get; protected set; } - public virtual Vector3 LastError { get; protected set; } - - public virtual bool ErrorIsZero - { get { - return (LastError == Vector3.Zero || LastError.LengthSquared() <= ErrorZeroThreshold); - } - } - - public BSVMotor(string useName) - : base(useName) - { - TimeScale = TargetValueDecayTimeScale = BSMotor.Infinite; - Efficiency = 1f; - FrictionTimescale = BSMotor.InfiniteVector; - CurrentValue = TargetValue = Vector3.Zero; - ErrorZeroThreshold = 0.001f; - } - public BSVMotor(string useName, float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency) - : this(useName) - { - TimeScale = timeScale; - TargetValueDecayTimeScale = decayTimeScale; - FrictionTimescale = frictionTimeScale; - Efficiency = efficiency; - CurrentValue = TargetValue = Vector3.Zero; - } - public void SetCurrent(Vector3 current) - { - CurrentValue = current; - } - public void SetTarget(Vector3 target) - { - TargetValue = target; - } - public override void Zero() - { - base.Zero(); - CurrentValue = TargetValue = Vector3.Zero; - } - - // Compute the next step and return the new current value - public virtual Vector3 Step(float timeStep) - { - if (!Enabled) return TargetValue; - - Vector3 origTarget = TargetValue; // DEBUG - Vector3 origCurrVal = CurrentValue; // DEBUG - - Vector3 correction = Vector3.Zero; - Vector3 error = TargetValue - CurrentValue; - if (!error.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)) - { - correction = Step(timeStep, error); - - CurrentValue += correction; - - // The desired value reduces to zero which also reduces the difference with current. - // If the decay time is infinite, don't decay at all. - float decayFactor = 0f; - if (TargetValueDecayTimeScale != BSMotor.Infinite) - { - decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep; - TargetValue *= (1f - decayFactor); - } - - // The amount we can correct the error is reduced by the friction - Vector3 frictionFactor = Vector3.Zero; - if (FrictionTimescale != BSMotor.InfiniteVector) - { - // frictionFactor = (Vector3.One / FrictionTimescale) * timeStep; - // Individual friction components can be 'infinite' so compute each separately. - frictionFactor.X = (FrictionTimescale.X == BSMotor.Infinite) ? 0f : (1f / FrictionTimescale.X); - frictionFactor.Y = (FrictionTimescale.Y == BSMotor.Infinite) ? 0f : (1f / FrictionTimescale.Y); - frictionFactor.Z = (FrictionTimescale.Z == BSMotor.Infinite) ? 0f : (1f / FrictionTimescale.Z); - frictionFactor *= timeStep; - CurrentValue *= (Vector3.One - frictionFactor); - } - - MDetailLog("{0}, BSVMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},err={5},corr={6}", - BSScene.DetailLogZero, UseName, origCurrVal, origTarget, - timeStep, error, correction); - MDetailLog("{0}, BSVMotor.Step,nonZero,{1},tgtDecayTS={2},decayFact={3},frictTS={4},frictFact={5},tgt={6},curr={7}", - BSScene.DetailLogZero, UseName, - TargetValueDecayTimeScale, decayFactor, FrictionTimescale, frictionFactor, - TargetValue, CurrentValue); - } - else - { - // Difference between what we have and target is small. Motor is done. - CurrentValue = TargetValue; - MDetailLog("{0}, BSVMotor.Step,zero,{1},origTgt={2},origCurr={3},ret={4}", - BSScene.DetailLogZero, UseName, origCurrVal, origTarget, CurrentValue); - } - - return CurrentValue; - } - public virtual Vector3 Step(float timeStep, Vector3 error) - { - if (!Enabled) return Vector3.Zero; - - LastError = error; - Vector3 returnCorrection = Vector3.Zero; - if (!error.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)) - { - // correction = error / secondsItShouldTakeToCorrect - Vector3 correctionAmount; - if (TimeScale == 0f || TimeScale == BSMotor.Infinite) - correctionAmount = error * timeStep; - else - correctionAmount = error / TimeScale * timeStep; - - returnCorrection = correctionAmount; - MDetailLog("{0}, BSVMotor.Step,nonZero,{1},timeStep={2},timeScale={3},err={4},corr={5}", - BSScene.DetailLogZero, UseName, timeStep, TimeScale, error, correctionAmount); - } - return returnCorrection; - } - - // The user sets all the parameters and calls this which outputs values until error is zero. - public override void GenerateTestOutput(float timeStep) - { - // maximum number of outputs to generate. - int maxOutput = 50; - MDetailLog("{0},BSVMotor.Test,{1},===================================== BEGIN Test Output", BSScene.DetailLogZero, UseName); - MDetailLog("{0},BSVMotor.Test,{1},timeScale={2},targDlyTS={3},frictTS={4},eff={5},curr={6},tgt={7}", - BSScene.DetailLogZero, UseName, - TimeScale, TargetValueDecayTimeScale, FrictionTimescale, Efficiency, - CurrentValue, TargetValue); - - LastError = BSMotor.InfiniteVector; - while (maxOutput-- > 0 && !LastError.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)) - { - Vector3 lastStep = Step(timeStep); - MDetailLog("{0},BSVMotor.Test,{1},cur={2},tgt={3},lastError={4},lastStep={5}", - BSScene.DetailLogZero, UseName, CurrentValue, TargetValue, LastError, lastStep); - } - MDetailLog("{0},BSVMotor.Test,{1},===================================== END Test Output", BSScene.DetailLogZero, UseName); - - - } - - public override string ToString() - { - return String.Format("<{0},curr={1},targ={2},decayTS={3},frictTS={4}>", - UseName, CurrentValue, TargetValue, TargetValueDecayTimeScale, FrictionTimescale); - } -} - -public class BSFMotor : BSMotor -{ - public float TimeScale { get; set; } - public float DecayTimeScale { get; set; } - public float Friction { get; set; } - public float Efficiency { get; set; } - - public float Target { get; private set; } - public float CurrentValue { get; private set; } - - public BSFMotor(string useName, float timeScale, float decayTimescale, float friction, float efficiency) - : base(useName) - { - } - public void SetCurrent(float target) - { - } - public void SetTarget(float target) - { - } - public virtual float Step(float timeStep) - { - return 0f; - } -} - -// Proportional, Integral, Derivitive Motor -// Good description at http://www.answers.com/topic/pid-controller . Includes processes for choosing p, i and d factors. -public class BSPIDVMotor : BSVMotor -{ - // Larger makes more overshoot, smaller means converge quicker. Range of 0.1 to 10. - public Vector3 proportionFactor { get; set; } - public Vector3 integralFactor { get; set; } - public Vector3 derivFactor { get; set; } - - // Arbritrary factor range. - // EfficiencyHigh means move quickly to the correct number. EfficiencyLow means might over correct. - public float EfficiencyHigh = 0.4f; - public float EfficiencyLow = 4.0f; - - // Running integration of the error - Vector3 RunningIntegration { get; set; } - - public BSPIDVMotor(string useName) - : base(useName) - { - proportionFactor = new Vector3(1.00f, 1.00f, 1.00f); - integralFactor = new Vector3(1.00f, 1.00f, 1.00f); - derivFactor = new Vector3(1.00f, 1.00f, 1.00f); - RunningIntegration = Vector3.Zero; - LastError = Vector3.Zero; - } - - public override void Zero() - { - base.Zero(); - } - - public override float Efficiency - { - get { return base.Efficiency; } - set - { - base.Efficiency = Util.Clamp(value, 0f, 1f); - // Compute factors based on efficiency. - // If efficiency is high (1f), use a factor value that moves the error value to zero with little overshoot. - // If efficiency is low (0f), use a factor value that overcorrects. - // TODO: might want to vary contribution of different factor depending on efficiency. - float factor = ((1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow) / 3f; - // float factor = (1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow; - proportionFactor = new Vector3(factor, factor, factor); - integralFactor = new Vector3(factor, factor, factor); - derivFactor = new Vector3(factor, factor, factor); - } - } - - // Ignore Current and Target Values and just advance the PID computation on this error. - public override Vector3 Step(float timeStep, Vector3 error) - { - if (!Enabled) return Vector3.Zero; - - // Add up the error so we can integrate over the accumulated errors - RunningIntegration += error * timeStep; - - // A simple derivitive is the rate of change from the last error. - Vector3 derivFactor = (error - LastError) * timeStep; - LastError = error; - - // Correction = -(proportionOfPresentError + accumulationOfPastError + rateOfChangeOfError) - Vector3 ret = -( - error * proportionFactor - + RunningIntegration * integralFactor - + derivFactor * derivFactor - ); - - return ret; - } -} -} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs deleted file mode 100644 index 5e93a03..0000000 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSParam.cs +++ /dev/null @@ -1,559 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Text; - -using OpenSim.Region.Physics.Manager; - -using OpenMetaverse; -using Nini.Config; - -namespace OpenSim.Region.Physics.BulletSNPlugin -{ -public static class BSParam -{ - // Level of Detail values kept as float because that's what the Meshmerizer wants - public static float MeshLOD { get; private set; } - public static float MeshMegaPrimLOD { get; private set; } - public static float MeshMegaPrimThreshold { get; private set; } - public static float SculptLOD { get; private set; } - - public static float MinimumObjectMass { get; private set; } - public static float MaximumObjectMass { get; private set; } - - public static float LinearDamping { get; private set; } - public static float AngularDamping { get; private set; } - public static float DeactivationTime { get; private set; } - public static float LinearSleepingThreshold { get; private set; } - public static float AngularSleepingThreshold { get; private set; } - public static float CcdMotionThreshold { get; private set; } - public static float CcdSweptSphereRadius { get; private set; } - public static float ContactProcessingThreshold { get; private set; } - - public static bool ShouldMeshSculptedPrim { get; private set; } // cause scuplted prims to get meshed - public static bool ShouldForceSimplePrimMeshing { get; private set; } // if a cube or sphere, let Bullet do internal shapes - public static bool ShouldUseHullsForPhysicalObjects { get; private set; } // 'true' if should create hulls for physical objects - - public static float TerrainImplementation { get; private set; } - public static float TerrainFriction { get; private set; } - public static float TerrainHitFraction { get; private set; } - public static float TerrainRestitution { get; private set; } - public static float TerrainCollisionMargin { get; private set; } - - // Avatar parameters - public static float AvatarFriction { get; private set; } - public static float AvatarStandingFriction { get; private set; } - public static float AvatarDensity { get; private set; } - public static float AvatarRestitution { get; private set; } - public static float AvatarCapsuleWidth { get; private set; } - public static float AvatarCapsuleDepth { get; private set; } - public static float AvatarCapsuleHeight { get; private set; } - public static float AvatarContactProcessingThreshold { get; private set; } - - public static float VehicleAngularDamping { get; private set; } - - public static float LinksetImplementation { get; private set; } - public static float LinkConstraintUseFrameOffset { get; private set; } - public static float LinkConstraintEnableTransMotor { get; private set; } - public static float LinkConstraintTransMotorMaxVel { get; private set; } - public static float LinkConstraintTransMotorMaxForce { get; private set; } - public static float LinkConstraintERP { get; private set; } - public static float LinkConstraintCFM { get; private set; } - public static float LinkConstraintSolverIterations { get; private set; } - - public static float PID_D { get; private set; } // derivative - public static float PID_P { get; private set; } // proportional - - public delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val); - public delegate float ParamGet(BSScene scene); - public delegate void ParamSet(BSScene scene, string paramName, uint localID, float val); - public delegate void SetOnObject(BSScene scene, BSPhysObject obj, float val); - - public struct ParameterDefn - { - public string name; // string name of the parameter - public string desc; // a short description of what the parameter means - public float defaultValue; // default value if not specified anywhere else - public ParamUser userParam; // get the value from the configuration file - public ParamGet getter; // return the current value stored for this parameter - public ParamSet setter; // set the current value for this parameter - public SetOnObject onObject; // set the value on an object in the physical domain - public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s) - { - name = n; - desc = d; - defaultValue = v; - userParam = u; - getter = g; - setter = s; - onObject = null; - } - public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s, SetOnObject o) - { - name = n; - desc = d; - defaultValue = v; - userParam = u; - getter = g; - setter = s; - onObject = o; - } - } - - // List of all of the externally visible parameters. - // For each parameter, this table maps a text name to getter and setters. - // To add a new externally referencable/settable parameter, add the paramter storage - // location somewhere in the program and make an entry in this table with the - // getters and setters. - // It is easiest to find an existing definition and copy it. - // Parameter values are floats. Booleans are converted to a floating value. - // - // A ParameterDefn() takes the following parameters: - // -- the text name of the parameter. This is used for console input and ini file. - // -- a short text description of the parameter. This shows up in the console listing. - // -- a default value (float) - // -- a delegate for fetching the parameter from the ini file. - // Should handle fetching the right type from the ini file and converting it. - // -- a delegate for getting the value as a float - // -- a delegate for setting the value from a float - // -- an optional delegate to update the value in the world. Most often used to - // push the new value to an in-world object. - // - // The single letter parameters for the delegates are: - // s = BSScene - // o = BSPhysObject - // p = string parameter name - // l = localID of referenced object - // v = value (float) - // cf = parameter configuration class (for fetching values from ini file) - private static ParameterDefn[] ParameterDefinitions = - { - new ParameterDefn("MeshSculptedPrim", "Whether to create meshes for sculpties", - ConfigurationParameters.numericTrue, - (s,cf,p,v) => { ShouldMeshSculptedPrim = cf.GetBoolean(p, BSParam.BoolNumeric(v)); }, - (s) => { return BSParam.NumericBool(ShouldMeshSculptedPrim); }, - (s,p,l,v) => { ShouldMeshSculptedPrim = BSParam.BoolNumeric(v); } ), - new ParameterDefn("ForceSimplePrimMeshing", "If true, only use primitive meshes for objects", - ConfigurationParameters.numericFalse, - (s,cf,p,v) => { ShouldForceSimplePrimMeshing = cf.GetBoolean(p, BSParam.BoolNumeric(v)); }, - (s) => { return BSParam.NumericBool(ShouldForceSimplePrimMeshing); }, - (s,p,l,v) => { ShouldForceSimplePrimMeshing = BSParam.BoolNumeric(v); } ), - new ParameterDefn("UseHullsForPhysicalObjects", "If true, create hulls for physical objects", - ConfigurationParameters.numericTrue, - (s,cf,p,v) => { ShouldUseHullsForPhysicalObjects = cf.GetBoolean(p, BSParam.BoolNumeric(v)); }, - (s) => { return BSParam.NumericBool(ShouldUseHullsForPhysicalObjects); }, - (s,p,l,v) => { ShouldUseHullsForPhysicalObjects = BSParam.BoolNumeric(v); } ), - - new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", - 8f, - (s,cf,p,v) => { MeshLOD = (float)cf.GetInt(p, (int)v); }, - (s) => { return MeshLOD; }, - (s,p,l,v) => { MeshLOD = v; } ), - new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters", - 16f, - (s,cf,p,v) => { MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); }, - (s) => { return MeshMegaPrimLOD; }, - (s,p,l,v) => { MeshMegaPrimLOD = v; } ), - new ParameterDefn("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD", - 10f, - (s,cf,p,v) => { MeshMegaPrimThreshold = (float)cf.GetInt(p, (int)v); }, - (s) => { return MeshMegaPrimThreshold; }, - (s,p,l,v) => { MeshMegaPrimThreshold = v; } ), - new ParameterDefn("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)", - 32f, - (s,cf,p,v) => { SculptLOD = (float)cf.GetInt(p, (int)v); }, - (s) => { return SculptLOD; }, - (s,p,l,v) => { SculptLOD = v; } ), - - new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps", - 10f, - (s,cf,p,v) => { s.m_maxSubSteps = cf.GetInt(p, (int)v); }, - (s) => { return (float)s.m_maxSubSteps; }, - (s,p,l,v) => { s.m_maxSubSteps = (int)v; } ), - new ParameterDefn("FixedTimeStep", "In simulation step, seconds of one substep (1/60)", - 1f / 60f, - (s,cf,p,v) => { s.m_fixedTimeStep = cf.GetFloat(p, v); }, - (s) => { return (float)s.m_fixedTimeStep; }, - (s,p,l,v) => { s.m_fixedTimeStep = v; } ), - new ParameterDefn("MaxCollisionsPerFrame", "Max collisions returned at end of each frame", - 2048f, - (s,cf,p,v) => { s.m_maxCollisionsPerFrame = cf.GetInt(p, (int)v); }, - (s) => { return (float)s.m_maxCollisionsPerFrame; }, - (s,p,l,v) => { s.m_maxCollisionsPerFrame = (int)v; } ), - new ParameterDefn("MaxUpdatesPerFrame", "Max updates returned at end of each frame", - 8000f, - (s,cf,p,v) => { s.m_maxUpdatesPerFrame = cf.GetInt(p, (int)v); }, - (s) => { return (float)s.m_maxUpdatesPerFrame; }, - (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ), - new ParameterDefn("MaxTaintsToProcessPerStep", "Number of update taints to process before each simulation step", - 500f, - (s,cf,p,v) => { s.m_taintsToProcessPerStep = cf.GetInt(p, (int)v); }, - (s) => { return (float)s.m_taintsToProcessPerStep; }, - (s,p,l,v) => { s.m_taintsToProcessPerStep = (int)v; } ), - new ParameterDefn("MinObjectMass", "Minimum object mass (0.0001)", - 0.0001f, - (s,cf,p,v) => { MinimumObjectMass = cf.GetFloat(p, v); }, - (s) => { return (float)MinimumObjectMass; }, - (s,p,l,v) => { MinimumObjectMass = v; } ), - new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)", - 10000.01f, - (s,cf,p,v) => { MaximumObjectMass = cf.GetFloat(p, v); }, - (s) => { return (float)MaximumObjectMass; }, - (s,p,l,v) => { MaximumObjectMass = v; } ), - - new ParameterDefn("PID_D", "Derivitive factor for motion smoothing", - 2200f, - (s,cf,p,v) => { PID_D = cf.GetFloat(p, v); }, - (s) => { return (float)PID_D; }, - (s,p,l,v) => { PID_D = v; } ), - new ParameterDefn("PID_P", "Parameteric factor for motion smoothing", - 900f, - (s,cf,p,v) => { PID_P = cf.GetFloat(p, v); }, - (s) => { return (float)PID_P; }, - (s,p,l,v) => { PID_P = v; } ), - - new ParameterDefn("DefaultFriction", "Friction factor used on new objects", - 0.2f, - (s,cf,p,v) => { s.UnmanagedParams[0].defaultFriction = cf.GetFloat(p, v); }, - (s) => { return s.UnmanagedParams[0].defaultFriction; }, - (s,p,l,v) => { s.UnmanagedParams[0].defaultFriction = v; } ), - new ParameterDefn("DefaultDensity", "Density for new objects" , - 10.000006836f, // Aluminum g/cm3 - (s,cf,p,v) => { s.UnmanagedParams[0].defaultDensity = cf.GetFloat(p, v); }, - (s) => { return s.UnmanagedParams[0].defaultDensity; }, - (s,p,l,v) => { s.UnmanagedParams[0].defaultDensity = v; } ), - new ParameterDefn("DefaultRestitution", "Bouncyness of an object" , - 0f, - (s,cf,p,v) => { s.UnmanagedParams[0].defaultRestitution = cf.GetFloat(p, v); }, - (s) => { return s.UnmanagedParams[0].defaultRestitution; }, - (s,p,l,v) => { s.UnmanagedParams[0].defaultRestitution = v; } ), - new ParameterDefn("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!)", - 0.04f, - (s,cf,p,v) => { s.UnmanagedParams[0].collisionMargin = cf.GetFloat(p, v); }, - (s) => { return s.UnmanagedParams[0].collisionMargin; }, - (s,p,l,v) => { s.UnmanagedParams[0].collisionMargin = v; } ), - new ParameterDefn("Gravity", "Vertical force of gravity (negative means down)", - -9.80665f, - (s,cf,p,v) => { s.UnmanagedParams[0].gravity = cf.GetFloat(p, v); }, - (s) => { return s.UnmanagedParams[0].gravity; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{s.UnmanagedParams[0].gravity=x;}, p, PhysParameterEntry.APPLY_TO_NONE, v); }, - (s,o,v) => { BulletSimAPI.SetGravity2(s.World.ptr, new Vector3(0f,0f,v)); } ), - - - new ParameterDefn("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)", - 0f, - (s,cf,p,v) => { LinearDamping = cf.GetFloat(p, v); }, - (s) => { return LinearDamping; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{LinearDamping=x;}, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, v, AngularDamping); } ), - new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)", - 0f, - (s,cf,p,v) => { AngularDamping = cf.GetFloat(p, v); }, - (s) => { return AngularDamping; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularDamping=x;}, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, LinearDamping, v); } ), - new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static", - 0.2f, - (s,cf,p,v) => { DeactivationTime = cf.GetFloat(p, v); }, - (s) => { return DeactivationTime; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{DeactivationTime=x;}, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetDeactivationTime2(o.PhysBody.ptr, v); } ), - new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static", - 0.8f, - (s,cf,p,v) => { LinearSleepingThreshold = cf.GetFloat(p, v); }, - (s) => { return LinearSleepingThreshold; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{LinearSleepingThreshold=x;}, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ), - new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static", - 1.0f, - (s,cf,p,v) => { AngularSleepingThreshold = cf.GetFloat(p, v); }, - (s) => { return AngularSleepingThreshold; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularSleepingThreshold=x;}, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ), - new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" , - 0f, // set to zero to disable - (s,cf,p,v) => { CcdMotionThreshold = cf.GetFloat(p, v); }, - (s) => { return CcdMotionThreshold; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdMotionThreshold=x;}, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetCcdMotionThreshold2(o.PhysBody.ptr, v); } ), - new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" , - 0f, - (s,cf,p,v) => { CcdSweptSphereRadius = cf.GetFloat(p, v); }, - (s) => { return CcdSweptSphereRadius; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdSweptSphereRadius=x;}, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetCcdSweptSphereRadius2(o.PhysBody.ptr, v); } ), - new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" , - 0.1f, - (s,cf,p,v) => { ContactProcessingThreshold = cf.GetFloat(p, v); }, - (s) => { return ContactProcessingThreshold; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{ContactProcessingThreshold=x;}, p, l, v); }, - (s,o,v) => { BulletSimAPI.SetContactProcessingThreshold2(o.PhysBody.ptr, v); } ), - - new ParameterDefn("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)", - (float)BSTerrainPhys.TerrainImplementation.Heightmap, - (s,cf,p,v) => { TerrainImplementation = cf.GetFloat(p,v); }, - (s) => { return TerrainImplementation; }, - (s,p,l,v) => { TerrainImplementation = v; } ), - new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" , - 0.3f, - (s,cf,p,v) => { TerrainFriction = cf.GetFloat(p, v); }, - (s) => { return TerrainFriction; }, - (s,p,l,v) => { TerrainFriction = v; /* TODO: set on real terrain */} ), - new ParameterDefn("TerrainHitFraction", "Distance to measure hit collisions" , - 0.8f, - (s,cf,p,v) => { TerrainHitFraction = cf.GetFloat(p, v); }, - (s) => { return TerrainHitFraction; }, - (s,p,l,v) => { TerrainHitFraction = v; /* TODO: set on real terrain */ } ), - new ParameterDefn("TerrainRestitution", "Bouncyness" , - 0f, - (s,cf,p,v) => { TerrainRestitution = cf.GetFloat(p, v); }, - (s) => { return TerrainRestitution; }, - (s,p,l,v) => { TerrainRestitution = v; /* TODO: set on real terrain */ } ), - new ParameterDefn("TerrainCollisionMargin", "Margin where collision checking starts" , - 0.04f, - (s,cf,p,v) => { TerrainCollisionMargin = cf.GetFloat(p, v); }, - (s) => { return TerrainCollisionMargin; }, - (s,p,l,v) => { TerrainCollisionMargin = v; /* TODO: set on real terrain */ } ), - - new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.", - 0.2f, - (s,cf,p,v) => { AvatarFriction = cf.GetFloat(p, v); }, - (s) => { return AvatarFriction; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarFriction=x;}, p, l, v); } ), - new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", - 10.0f, - (s,cf,p,v) => { AvatarStandingFriction = cf.GetFloat(p, v); }, - (s) => { return AvatarStandingFriction; }, - (s,p,l,v) => { AvatarStandingFriction = v; } ), - new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.", - 3.5f, - (s,cf,p,v) => { AvatarDensity = cf.GetFloat(p, v); }, - (s) => { return AvatarDensity; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarDensity=x;}, p, l, v); } ), - new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.", - 0f, - (s,cf,p,v) => { AvatarRestitution = cf.GetFloat(p, v); }, - (s) => { return AvatarRestitution; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarRestitution=x;}, p, l, v); } ), - new ParameterDefn("AvatarCapsuleWidth", "The distance between the sides of the avatar capsule", - 0.6f, - (s,cf,p,v) => { AvatarCapsuleWidth = cf.GetFloat(p, v); }, - (s) => { return AvatarCapsuleWidth; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleWidth=x;}, p, l, v); } ), - new ParameterDefn("AvatarCapsuleDepth", "The distance between the front and back of the avatar capsule", - 0.45f, - (s,cf,p,v) => { AvatarCapsuleDepth = cf.GetFloat(p, v); }, - (s) => { return AvatarCapsuleDepth; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleDepth=x;}, p, l, v); } ), - new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar", - 1.5f, - (s,cf,p,v) => { AvatarCapsuleHeight = cf.GetFloat(p, v); }, - (s) => { return AvatarCapsuleHeight; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleHeight=x;}, p, l, v); } ), - new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", - 0.1f, - (s,cf,p,v) => { AvatarContactProcessingThreshold = cf.GetFloat(p, v); }, - (s) => { return AvatarContactProcessingThreshold; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarContactProcessingThreshold=x;}, p, l, v); } ), - - new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", - 0.95f, - (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); }, - (s) => { return VehicleAngularDamping; }, - (s,p,l,v) => { VehicleAngularDamping = v; } ), - - new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", - 0f, - (s,cf,p,v) => { s.UnmanagedParams[0].maxPersistantManifoldPoolSize = cf.GetFloat(p, v); }, - (s) => { return s.UnmanagedParams[0].maxPersistantManifoldPoolSize; }, - (s,p,l,v) => { s.UnmanagedParams[0].maxPersistantManifoldPoolSize = v; } ), - new ParameterDefn("MaxCollisionAlgorithmPoolSize", "Number of collisions pooled (0 means default of 4096)", - 0f, - (s,cf,p,v) => { s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = cf.GetFloat(p, v); }, - (s) => { return s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize; }, - (s,p,l,v) => { s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = v; } ), - new ParameterDefn("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count", - ConfigurationParameters.numericFalse, - (s,cf,p,v) => { s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, - (s) => { return s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation; }, - (s,p,l,v) => { s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = v; } ), - new ParameterDefn("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step", - ConfigurationParameters.numericFalse, - (s,cf,p,v) => { s.UnmanagedParams[0].shouldForceUpdateAllAabbs = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, - (s) => { return s.UnmanagedParams[0].shouldForceUpdateAllAabbs; }, - (s,p,l,v) => { s.UnmanagedParams[0].shouldForceUpdateAllAabbs = v; } ), - new ParameterDefn("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction", - ConfigurationParameters.numericTrue, - (s,cf,p,v) => { s.UnmanagedParams[0].shouldRandomizeSolverOrder = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, - (s) => { return s.UnmanagedParams[0].shouldRandomizeSolverOrder; }, - (s,p,l,v) => { s.UnmanagedParams[0].shouldRandomizeSolverOrder = v; } ), - new ParameterDefn("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands", - ConfigurationParameters.numericTrue, - (s,cf,p,v) => { s.UnmanagedParams[0].shouldSplitSimulationIslands = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, - (s) => { return s.UnmanagedParams[0].shouldSplitSimulationIslands; }, - (s,p,l,v) => { s.UnmanagedParams[0].shouldSplitSimulationIslands = v; } ), - new ParameterDefn("ShouldEnableFrictionCaching", "Enable friction computation caching", - ConfigurationParameters.numericFalse, - (s,cf,p,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, - (s) => { return s.UnmanagedParams[0].shouldEnableFrictionCaching; }, - (s,p,l,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = v; } ), - new ParameterDefn("NumberOfSolverIterations", "Number of internal iterations (0 means default)", - 0f, // zero says use Bullet default - (s,cf,p,v) => { s.UnmanagedParams[0].numberOfSolverIterations = cf.GetFloat(p, v); }, - (s) => { return s.UnmanagedParams[0].numberOfSolverIterations; }, - (s,p,l,v) => { s.UnmanagedParams[0].numberOfSolverIterations = v; } ), - - new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", - (float)BSLinkset.LinksetImplementation.Compound, - (s,cf,p,v) => { LinksetImplementation = cf.GetFloat(p,v); }, - (s) => { return LinksetImplementation; }, - (s,p,l,v) => { LinksetImplementation = v; } ), - new ParameterDefn("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.", - ConfigurationParameters.numericFalse, - (s,cf,p,v) => { LinkConstraintUseFrameOffset = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, - (s) => { return LinkConstraintUseFrameOffset; }, - (s,p,l,v) => { LinkConstraintUseFrameOffset = v; } ), - new ParameterDefn("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints", - ConfigurationParameters.numericTrue, - (s,cf,p,v) => { LinkConstraintEnableTransMotor = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, - (s) => { return LinkConstraintEnableTransMotor; }, - (s,p,l,v) => { LinkConstraintEnableTransMotor = v; } ), - new ParameterDefn("LinkConstraintTransMotorMaxVel", "Maximum velocity to be applied by translational motor in linkset constraints", - 5.0f, - (s,cf,p,v) => { LinkConstraintTransMotorMaxVel = cf.GetFloat(p, v); }, - (s) => { return LinkConstraintTransMotorMaxVel; }, - (s,p,l,v) => { LinkConstraintTransMotorMaxVel = v; } ), - new ParameterDefn("LinkConstraintTransMotorMaxForce", "Maximum force to be applied by translational motor in linkset constraints", - 0.1f, - (s,cf,p,v) => { LinkConstraintTransMotorMaxForce = cf.GetFloat(p, v); }, - (s) => { return LinkConstraintTransMotorMaxForce; }, - (s,p,l,v) => { LinkConstraintTransMotorMaxForce = v; } ), - new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1", - 0.1f, - (s,cf,p,v) => { LinkConstraintCFM = cf.GetFloat(p, v); }, - (s) => { return LinkConstraintCFM; }, - (s,p,l,v) => { LinkConstraintCFM = v; } ), - new ParameterDefn("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2", - 0.1f, - (s,cf,p,v) => { LinkConstraintERP = cf.GetFloat(p, v); }, - (s) => { return LinkConstraintERP; }, - (s,p,l,v) => { LinkConstraintERP = v; } ), - new ParameterDefn("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)", - 40, - (s,cf,p,v) => { LinkConstraintSolverIterations = cf.GetFloat(p, v); }, - (s) => { return LinkConstraintSolverIterations; }, - (s,p,l,v) => { LinkConstraintSolverIterations = v; } ), - - new ParameterDefn("LogPhysicsStatisticsFrames", "Frames between outputting detailed phys stats. (0 is off)", - 0f, - (s,cf,p,v) => { s.UnmanagedParams[0].physicsLoggingFrames = cf.GetInt(p, (int)v); }, - (s) => { return (float)s.UnmanagedParams[0].physicsLoggingFrames; }, - (s,p,l,v) => { s.UnmanagedParams[0].physicsLoggingFrames = (int)v; } ), - }; - - // Convert a boolean to our numeric true and false values - public static float NumericBool(bool b) - { - return (b ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse); - } - - // Convert numeric true and false values to a boolean - public static bool BoolNumeric(float b) - { - return (b == ConfigurationParameters.numericTrue ? true : false); - } - - // Search through the parameter definitions and return the matching - // ParameterDefn structure. - // Case does not matter as names are compared after converting to lower case. - // Returns 'false' if the parameter is not found. - internal static bool TryGetParameter(string paramName, out ParameterDefn defn) - { - bool ret = false; - ParameterDefn foundDefn = new ParameterDefn(); - string pName = paramName.ToLower(); - - foreach (ParameterDefn parm in ParameterDefinitions) - { - if (pName == parm.name.ToLower()) - { - foundDefn = parm; - ret = true; - break; - } - } - defn = foundDefn; - return ret; - } - - // Pass through the settable parameters and set the default values - internal static void SetParameterDefaultValues(BSScene physicsScene) - { - foreach (ParameterDefn parm in ParameterDefinitions) - { - parm.setter(physicsScene, parm.name, PhysParameterEntry.APPLY_TO_NONE, parm.defaultValue); - } - } - - // Get user set values out of the ini file. - internal static void SetParameterConfigurationValues(BSScene physicsScene, IConfig cfg) - { - foreach (ParameterDefn parm in ParameterDefinitions) - { - parm.userParam(physicsScene, cfg, parm.name, parm.defaultValue); - } - } - - internal static PhysParameterEntry[] SettableParameters = new PhysParameterEntry[1]; - - // This creates an array in the correct format for returning the list of - // parameters. This is used by the 'list' option of the 'physics' command. - internal static void BuildParameterTable() - { - if (SettableParameters.Length < ParameterDefinitions.Length) - { - List entries = new List(); - for (int ii = 0; ii < ParameterDefinitions.Length; ii++) - { - ParameterDefn pd = ParameterDefinitions[ii]; - entries.Add(new PhysParameterEntry(pd.name, pd.desc)); - } - - // make the list in alphabetical order for estetic reasons - entries.Sort(delegate(PhysParameterEntry ppe1, PhysParameterEntry ppe2) - { - return ppe1.name.CompareTo(ppe2.name); - }); - - SettableParameters = entries.ToArray(); - } - } - - -} -} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSPhysObject.cs deleted file mode 100644 index 689da7f..0000000 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSPhysObject.cs +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Text; - -using OMV = OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Region.Physics.Manager; - -namespace OpenSim.Region.Physics.BulletSNPlugin -{ -/* - * Class to wrap all objects. - * The rest of BulletSim doesn't need to keep checking for avatars or prims - * unless the difference is significant. - * - * Variables in the physicsl objects are in three forms: - * VariableName: used by the simulator and performs taint operations, etc - * RawVariableName: direct reference to the BulletSim storage for the variable value - * ForceVariableName: direct reference (store and fetch) to the value in the physics engine. - * The last two (and certainly the last one) should be referenced only in taint-time. - */ - -/* - * As of 20121221, the following are the call sequences (going down) for different script physical functions: - * llApplyImpulse llApplyRotImpulse llSetTorque llSetForce - * SOP.ApplyImpulse SOP.ApplyAngularImpulse SOP.SetAngularImpulse SOP.SetForce - * SOG.ApplyImpulse SOG.ApplyAngularImpulse SOG.SetAngularImpulse - * PA.AddForce PA.AddAngularForce PA.Torque = v PA.Force = v - * BS.ApplyCentralForce BS.ApplyTorque - */ - -public abstract class BSPhysObject : PhysicsActor -{ - protected BSPhysObject() - { - } - protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName) - { - PhysicsScene = parentScene; - LocalID = localID; - PhysObjectName = name; - TypeName = typeName; - - Linkset = BSLinkset.Factory(PhysicsScene, this); - LastAssetBuildFailed = false; - - // Default material type - Material = MaterialAttributes.Material.Wood; - - CollisionCollection = new CollisionEventUpdate(); - SubscribedEventsMs = 0; - CollidingStep = 0; - CollidingGroundStep = 0; - } - - // Tell the object to clean up. - public virtual void Destroy() - { - UnRegisterAllPreStepActions(); - } - - public BSScene PhysicsScene { get; protected set; } - // public override uint LocalID { get; set; } // Use the LocalID definition in PhysicsActor - public string PhysObjectName { get; protected set; } - public string TypeName { get; protected set; } - - public BSLinkset Linkset { get; set; } - public BSLinksetInfo LinksetInfo { get; set; } - - // Return the object mass without calculating it or having side effects - public abstract float RawMass { get; } - // Set the raw mass but also update physical mass properties (inertia, ...) - // 'inWorld' true if the object has already been added to the dynamic world. - public abstract void UpdatePhysicalMassProperties(float mass, bool inWorld); - - // The last value calculated for the prim's inertia - public OMV.Vector3 Inertia { get; set; } - - // Reference to the physical body (btCollisionObject) of this object - public BulletBody PhysBody; - // Reference to the physical shape (btCollisionShape) of this object - public BulletShape PhysShape; - - // 'true' if the mesh's underlying asset failed to build. - // This will keep us from looping after the first time the build failed. - public bool LastAssetBuildFailed { get; set; } - - // The objects base shape information. Null if not a prim type shape. - public PrimitiveBaseShape BaseShape { get; protected set; } - // Some types of objects have preferred physical representations. - // Returns SHAPE_UNKNOWN if there is no preference. - public virtual BSPhysicsShapeType PreferredPhysicalShape - { - get { return BSPhysicsShapeType.SHAPE_UNKNOWN; } - } - - // When the physical properties are updated, an EntityProperty holds the update values. - // Keep the current and last EntityProperties to enable computation of differences - // between the current update and the previous values. - public EntityProperties CurrentEntityProperties { get; set; } - public EntityProperties LastEntityProperties { get; set; } - - public virtual OMV.Vector3 Scale { get; set; } - public abstract bool IsSolid { get; } - public abstract bool IsStatic { get; } - - // Materialness - public MaterialAttributes.Material Material { get; private set; } - public override void SetMaterial(int material) - { - Material = (MaterialAttributes.Material)material; - } - - // Stop all physical motion. - public abstract void ZeroMotion(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. - public abstract void UpdateProperties(EntityProperties entprop); - - public abstract OMV.Vector3 RawPosition { get; set; } - public abstract OMV.Vector3 ForcePosition { get; set; } - - public abstract OMV.Quaternion RawOrientation { get; set; } - public abstract OMV.Quaternion ForceOrientation { get; set; } - - // The system is telling us the velocity it wants to move at. - // protected OMV.Vector3 m_targetVelocity; // use the definition in PhysicsActor - public override OMV.Vector3 TargetVelocity - { - get { return m_targetVelocity; } - set - { - m_targetVelocity = value; - Velocity = value; - } - } - public abstract OMV.Vector3 ForceVelocity { get; set; } - - public abstract OMV.Vector3 ForceRotationalVelocity { get; set; } - - public abstract float ForceBuoyancy { get; set; } - - public virtual bool ForceBodyShapeRebuild(bool inTaintTime) { return false; } - - #region Collisions - - // Requested number of milliseconds between collision events. Zero means disabled. - protected int SubscribedEventsMs { get; set; } - // Given subscription, the time that a collision may be passed up - protected int NextCollisionOkTime { get; set; } - // The simulation step that last had a collision - protected long CollidingStep { get; set; } - // The simulation step that last had a collision with the ground - protected long CollidingGroundStep { get; set; } - // The collision flags we think are set in Bullet - protected CollisionFlags CurrentCollisionFlags { get; set; } - - // The collisions that have been collected this tick - protected CollisionEventUpdate CollisionCollection; - - // The simulation step is telling this object about a collision. - // Return 'true' if a collision was processed and should be sent up. - // Called at taint time from within the Step() function - public virtual bool Collide(uint collidingWith, BSPhysObject collidee, - OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) - { - bool ret = false; - - // The following lines make IsColliding() and IsCollidingGround() work - CollidingStep = PhysicsScene.SimulationStep; - if (collidingWith <= PhysicsScene.TerrainManager.HighestTerrainID) - { - CollidingGroundStep = PhysicsScene.SimulationStep; - } - - // prims in the same linkset cannot collide with each other - if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID)) - { - return ret; - } - - // if someone has subscribed for collision events.... - if (SubscribedEvents()) { - CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); - DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5}", - LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth); - - ret = true; - } - return ret; - } - - // Send the collected collisions into the simulator. - // Called at taint time from within the Step() function thus no locking problems - // with CollisionCollection and ObjectsWithNoMoreCollisions. - // Return 'true' if there were some actual collisions passed up - public virtual bool SendCollisions() - { - bool ret = true; - // If the 'no collision' call, force it to happen right now so quick collision_end - bool force = (CollisionCollection.Count == 0); - - // throttle the collisions to the number of milliseconds specified in the subscription - if (force || (PhysicsScene.SimulationNowTime >= NextCollisionOkTime)) - { - NextCollisionOkTime = PhysicsScene.SimulationNowTime + SubscribedEventsMs; - - // We are called if we previously had collisions. If there are no collisions - // this time, send up one last empty event so OpenSim can sense collision end. - if (CollisionCollection.Count == 0) - { - // If I have no collisions this time, remove me from the list of objects with collisions. - ret = false; - } - - // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count); - base.SendCollisionUpdate(CollisionCollection); - - // The CollisionCollection instance is passed around in the simulator. - // Make sure we don't have a handle to that one and that a new one is used for next time. - // This fixes an interesting 'gotcha'. If we call CollisionCollection.Clear() here, - // a race condition is created for the other users of this instance. - CollisionCollection = new CollisionEventUpdate(); - } - return ret; - } - - // Subscribe for collision events. - // Parameter is the millisecond rate the caller wishes collision events to occur. - public override void SubscribeEvents(int ms) { - // DetailLog("{0},{1}.SubscribeEvents,subscribing,ms={2}", LocalID, TypeName, ms); - SubscribedEventsMs = ms; - if (ms > 0) - { - // make sure first collision happens - NextCollisionOkTime = Util.EnvironmentTickCountSubtract(SubscribedEventsMs); - - PhysicsScene.TaintedObject(TypeName+".SubscribeEvents", delegate() - { - if (PhysBody.HasPhysicalBody) - CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); - }); - } - else - { - // Subscribing for zero or less is the same as unsubscribing - UnSubscribeEvents(); - } - } - public override void UnSubscribeEvents() { - // DetailLog("{0},{1}.UnSubscribeEvents,unsubscribing", LocalID, TypeName); - SubscribedEventsMs = 0; - PhysicsScene.TaintedObject(TypeName+".UnSubscribeEvents", delegate() - { - // Make sure there is a body there because sometimes destruction happens in an un-ideal order. - if (PhysBody.HasPhysicalBody) - CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); - }); - } - // Return 'true' if the simulator wants collision events - public override bool SubscribedEvents() { - return (SubscribedEventsMs > 0); - } - - #endregion // Collisions - - #region Per Simulation Step actions - // There are some actions that must be performed for a physical object before each simulation step. - // These actions are optional so, rather than scanning all the physical objects and asking them - // if they have anything to do, a physical object registers for an event call before the step is performed. - // This bookkeeping makes it easy to add, remove and clean up after all these registrations. - private Dictionary RegisteredActions = new Dictionary(); - protected void RegisterPreStepAction(string op, uint id, BSScene.PreStepAction actn) - { - string identifier = op + "-" + id.ToString(); - RegisteredActions[identifier] = actn; - PhysicsScene.BeforeStep += actn; - DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier); - } - - // Unregister a pre step action. Safe to call if the action has not been registered. - protected void UnRegisterPreStepAction(string op, uint id) - { - string identifier = op + "-" + id.ToString(); - bool removed = false; - if (RegisteredActions.ContainsKey(identifier)) - { - PhysicsScene.BeforeStep -= RegisteredActions[identifier]; - RegisteredActions.Remove(identifier); - removed = true; - } - DetailLog("{0},BSPhysObject.UnRegisterPreStepAction,id={1},removed={2}", LocalID, identifier, removed); - } - - protected void UnRegisterAllPreStepActions() - { - foreach (KeyValuePair kvp in RegisteredActions) - { - PhysicsScene.BeforeStep -= kvp.Value; - } - RegisteredActions.Clear(); - DetailLog("{0},BSPhysObject.UnRegisterAllPreStepActions,", LocalID); - } - - - #endregion // Per Simulation Step actions - - // High performance detailed logging routine used by the physical objects. - protected void DetailLog(string msg, params Object[] args) - { - if (PhysicsScene.PhysicsLogging.Enabled) - PhysicsScene.DetailLog(msg, args); - } - -} -} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSPlugin.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSPlugin.cs deleted file mode 100644 index 75963ee..0000000 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSPlugin.cs +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using OpenSim.Framework; -using OpenSim.Region.Physics.Manager; -using OpenMetaverse; - -namespace OpenSim.Region.Physics.BulletSNPlugin -{ - /// - /// Entry for a port of Bullet (http://bulletphysics.org/) to OpenSim. - /// This module interfaces to an unmanaged C++ library which makes the - /// actual calls into the Bullet physics engine. - /// The unmanaged library is found in opensim-libs::trunk/unmanaged/BulletSim/. - /// The unmanaged library is compiled and linked statically with Bullet - /// to create BulletSim.dll and libBulletSim.so (for both 32 and 64 bit). - /// -public class BSPlugin : IPhysicsPlugin -{ - //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - - private BSScene _mScene; - - public BSPlugin() - { - } - - public bool Init() - { - return true; - } - - public PhysicsScene GetScene(String sceneIdentifier) - { - if (_mScene == null) - { - - // If not Windows, loading is performed by the - // Mono loader as specified in - // "bin/Physics/OpenSim.Region.Physics.BulletSNPlugin.dll.config". - - _mScene = new BSScene(sceneIdentifier); - } - return (_mScene); - } - - public string GetName() - { - return ("BulletSimN"); - } - - public void Dispose() - { - } -} -} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs deleted file mode 100644 index aadb5b2..0000000 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSPrim.cs +++ /dev/null @@ -1,1494 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Reflection; -using System.Collections.Generic; -using System.Xml; -using log4net; -using OMV = OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Region.Physics.Manager; -using OpenSim.Region.Physics.ConvexDecompositionDotNet; - -namespace OpenSim.Region.Physics.BulletSNPlugin -{ - - [Serializable] -public sealed class BSPrim : BSPhysObject -{ - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private static readonly string LogHeader = "[BULLETS PRIM]"; - - // _size is what the user passed. Scale is what we pass to the physics engine with the mesh. - private OMV.Vector3 _size; // the multiplier for each mesh dimension as passed by the user - - private bool _grabbed; - private bool _isSelected; - private bool _isVolumeDetect; - private OMV.Vector3 _position; - private float _mass; // the mass of this object - private float _density; - private OMV.Vector3 _force; - private OMV.Vector3 _velocity; - private OMV.Vector3 _torque; - private float _collisionScore; - private OMV.Vector3 _acceleration; - private OMV.Quaternion _orientation; - private int _physicsActorType; - private bool _isPhysical; - private bool _flying; - private float _friction; - private float _restitution; - private bool _setAlwaysRun; - private bool _throttleUpdates; - private bool _isColliding; - private bool _collidingGround; - private bool _collidingObj; - private bool _floatOnWater; - private OMV.Vector3 _rotationalVelocity; - private bool _kinematic; - private float _buoyancy; - - private BSDynamics _vehicle; - - private OMV.Vector3 _PIDTarget; - private bool _usePID; - private float _PIDTau; - private bool _useHoverPID; - private float _PIDHoverHeight; - private PIDHoverType _PIDHoverType; - private float _PIDHoverTao; - - public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, - OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) - : base(parent_scene, localID, primName, "BSPrim") - { - // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID); - _physicsActorType = (int)ActorTypes.Prim; - _position = pos; - _size = size; - Scale = size; // prims are the size the user wants them to be (different for BSCharactes). - _orientation = rotation; - _buoyancy = 1f; - _velocity = OMV.Vector3.Zero; - _rotationalVelocity = OMV.Vector3.Zero; - BaseShape = pbs; - _isPhysical = pisPhysical; - _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; - - _vehicle = new BSDynamics(PhysicsScene, this); // add vehicleness - - _mass = CalculateMass(); - - Linkset.Refresh(this); - - DetailLog("{0},BSPrim.constructor,call", LocalID); - // do the actual object creation at taint time - PhysicsScene.TaintedObject("BSPrim.create", delegate() - { - CreateGeomAndObject(true); - - CurrentCollisionFlags = BulletSimAPI.GetCollisionFlags2(PhysBody.ptr); - }); - } - - // called when this prim is being destroyed and we should free all the resources - public override void Destroy() - { - // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); - base.Destroy(); - - // Undo any links between me and any other object - BSPhysObject parentBefore = Linkset.LinksetRoot; - int childrenBefore = Linkset.NumberOfChildren; - - Linkset = Linkset.RemoveMeFromLinkset(this); - - DetailLog("{0},BSPrim.Destroy,call,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}", - LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren); - - // Undo any vehicle properties - this.VehicleType = (int)Vehicle.TYPE_NONE; - - PhysicsScene.TaintedObject("BSPrim.destroy", delegate() - { - DetailLog("{0},BSPrim.Destroy,taint,", LocalID); - // If there are physical body and shape, release my use of same. - PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null); - PhysBody.Clear(); - PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null); - PhysShape.Clear(); - }); - } - - // No one uses this property. - public override bool Stopped { - get { return false; } - } - public override OMV.Vector3 Size { - get { return _size; } - set { - // We presume the scale and size are the same. If scale must be changed for - // the physical shape, that is done when the geometry is built. - _size = value; - Scale = _size; - ForceBodyShapeRebuild(false); - } - } - - public override PrimitiveBaseShape Shape { - set { - BaseShape = value; - ForceBodyShapeRebuild(false); - } - } - // Whatever the linkset wants is what I want. - public override BSPhysicsShapeType PreferredPhysicalShape - { get { return Linkset.PreferredPhysicalShape(this); } } - - public override bool ForceBodyShapeRebuild(bool inTaintTime) - { - LastAssetBuildFailed = false; - PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ForceBodyShapeRebuild", delegate() - { - _mass = CalculateMass(); // changing the shape changes the mass - CreateGeomAndObject(true); - }); - return true; - } - public override bool Grabbed { - set { _grabbed = value; - } - } - public override bool Selected { - set - { - if (value != _isSelected) - { - _isSelected = value; - PhysicsScene.TaintedObject("BSPrim.setSelected", delegate() - { - DetailLog("{0},BSPrim.selected,taint,selected={1}", LocalID, _isSelected); - SetObjectDynamic(false); - }); - } - } - } - public override void CrossingFailure() { return; } - - // link me to the specified parent - public override void link(PhysicsActor obj) { - BSPrim parent = obj as BSPrim; - if (parent != null) - { - BSPhysObject parentBefore = Linkset.LinksetRoot; - int childrenBefore = Linkset.NumberOfChildren; - - Linkset = parent.Linkset.AddMeToLinkset(this); - - DetailLog("{0},BSPrim.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}", - LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren); - } - return; - } - - // delink me from my linkset - public override void delink() { - // TODO: decide if this parent checking needs to happen at taint time - // Race condition here: if link() and delink() in same simulation tick, the delink will not happen - - BSPhysObject parentBefore = Linkset.LinksetRoot; - int childrenBefore = Linkset.NumberOfChildren; - - Linkset = Linkset.RemoveMeFromLinkset(this); - - DetailLog("{0},BSPrim.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ", - LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren); - return; - } - - // Set motion values to zero. - // Do it to the properties so the values get set in the physics engine. - // Push the setting of the values to the viewer. - // Called at taint time! - public override void ZeroMotion(bool inTaintTime) - { - _velocity = OMV.Vector3.Zero; - _acceleration = OMV.Vector3.Zero; - _rotationalVelocity = OMV.Vector3.Zero; - - // Zero some other properties in the physics engine - PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate() - { - if (PhysBody.HasPhysicalBody) - BulletSimAPI.ClearAllForces2(PhysBody.ptr); - }); - } - public override void ZeroAngularMotion(bool inTaintTime) - { - _rotationalVelocity = OMV.Vector3.Zero; - // Zero some other properties in the physics engine - PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate() - { - // DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity); - if (PhysBody.HasPhysicalBody) - { - BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, _rotationalVelocity); - BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity); - } - }); - } - - public override void LockAngularMotion(OMV.Vector3 axis) - { - DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis); - return; - } - - public override OMV.Vector3 RawPosition - { - get { return _position; } - set { _position = value; } - } - public override OMV.Vector3 Position { - get { - /* NOTE: this refetch is not necessary. The simulator knows about linkset children - * and does not fetch this position info for children. Thus this is commented out. - // child prims move around based on their parent. Need to get the latest location - if (!Linkset.IsRoot(this)) - _position = Linkset.PositionGet(this); - */ - - // don't do the GetObjectPosition for root elements because this function is called a zillion times. - // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr); - return _position; - } - set { - // If the position must be forced into the physics engine, use ForcePosition. - // All positions are given in world positions. - if (_position == value) - { - DetailLog("{0},BSPrim.setPosition,taint,positionNotChanging,pos={1},orient={2}", LocalID, _position, _orientation); - return; - } - _position = value; - PositionSanityCheck(false); - - // A linkset might need to know if a component information changed. - Linkset.UpdateProperties(this, false); - - PhysicsScene.TaintedObject("BSPrim.setPosition", delegate() - { - DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); - ForcePosition = _position; - }); - } - } - public override OMV.Vector3 ForcePosition { - get { - _position = BulletSimAPI.GetPosition2(PhysBody.ptr); - return _position; - } - set { - _position = value; - if (PhysBody.HasPhysicalBody) - { - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); - ActivateIfPhysical(false); - } - } - } - - // Check that the current position is sane and, if not, modify the position to make it so. - // Check for being below terrain and being out of bounds. - // Returns 'true' of the position was made sane by some action. - private bool PositionSanityCheck(bool inTaintTime) - { - bool ret = false; - - if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position)) - { - // The physical object is out of the known/simulated area. - // Upper levels of code will handle the transition to other areas so, for - // the time, we just ignore the position. - return ret; - } - - float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); - OMV.Vector3 upForce = OMV.Vector3.Zero; - if (RawPosition.Z < terrainHeight) - { - DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); - float targetHeight = terrainHeight + (Size.Z / 2f); - // Upforce proportional to the distance away from the terrain. Correct the error in 1 sec. - upForce.Z = (terrainHeight - RawPosition.Z) * 1f; - ret = true; - } - - if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) - { - float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(_position); - // TODO: a floating motor so object will bob in the water - if (Math.Abs(RawPosition.Z - waterHeight) > 0.1f) - { - // Upforce proportional to the distance away from the water. Correct the error in 1 sec. - upForce.Z = (waterHeight - RawPosition.Z) * 1f; - ret = true; - } - } - - // The above code computes a force to apply to correct any out-of-bounds problems. Apply same. - // TODO: This should be intergrated with a geneal physics action mechanism. - // TODO: This should be moderated with PID'ness. - if (ret) - { - // Apply upforce and overcome gravity. - OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity; - DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce); - AddForce(correctionForce, false, inTaintTime); - } - return ret; - } - - // Return the effective mass of the object. - // The definition of this call is to return the mass of the prim. - // If the simulator cares about the mass of the linkset, it will sum it itself. - public override float Mass - { - get - { - return _mass; - } - } - - // used when we only want this prim's mass and not the linkset thing - public override float RawMass { - get { return _mass; } - } - // Set the physical mass to the passed mass. - // Note that this does not change _mass! - public override void UpdatePhysicalMassProperties(float physMass, bool inWorld) - { - if (PhysBody.HasPhysicalBody) - { - if (IsStatic) - { - Inertia = OMV.Vector3.Zero; - BulletSimAPI.SetMassProps2(PhysBody.ptr, 0f, Inertia); - BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); - } - else - { - if (inWorld) - { - // Changing interesting properties doesn't change proxy and collision cache - // information. The Bullet solution is to re-add the object to the world - // after parameters are changed. - BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr); - } - - Inertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass); - BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, Inertia); - BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); - - // center of mass is at the zero of the object - // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(PhysBody.ptr, ForcePosition, ForceOrientation); - DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2},inWorld={3}", LocalID, physMass, Inertia, inWorld); - - if (inWorld) - { - BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr,_position,_orientation); - } - - // 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 - OMV.Vector3 grav = PhysicsScene.DefaultGravity * (1f - Buoyancy); - BulletSimAPI.SetGravity2(PhysBody.ptr, grav); - - } - } - } - - // Is this used? - public override OMV.Vector3 CenterOfMass - { - get { return Linkset.CenterOfMass; } - } - - // Is this used? - public override OMV.Vector3 GeometricCenter - { - get { return Linkset.GeometricCenter; } - } - - public override OMV.Vector3 Force { - get { return _force; } - set { - _force = value; - if (_force != OMV.Vector3.Zero) - { - // If the force is non-zero, it must be reapplied each tick because - // Bullet clears the forces applied last frame. - RegisterPreStepAction("BSPrim.setForce", LocalID, - delegate(float timeStep) - { - DetailLog("{0},BSPrim.setForce,preStep,force={1}", LocalID, _force); - if (PhysBody.HasPhysicalBody) - { - BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, _force); - ActivateIfPhysical(false); - } - } - ); - } - else - { - UnRegisterPreStepAction("BSPrim.setForce", LocalID); - } - } - } - - public override int VehicleType { - get { - return (int)_vehicle.Type; // if we are a vehicle, return that type - } - set { - Vehicle type = (Vehicle)value; - - PhysicsScene.TaintedObject("setVehicleType", delegate() - { - // Done at taint time so we're sure the physics engine is not using the variables - // Vehicle code changes the parameters for this vehicle type. - _vehicle.ProcessTypeChange(type); - ActivateIfPhysical(false); - - // If an active vehicle, register the vehicle code to be called before each step - if (_vehicle.Type == Vehicle.TYPE_NONE) - UnRegisterPreStepAction("BSPrim.Vehicle", LocalID); - else - RegisterPreStepAction("BSPrim.Vehicle", LocalID, _vehicle.Step); - }); - } - } - public override void VehicleFloatParam(int param, float value) - { - PhysicsScene.TaintedObject("BSPrim.VehicleFloatParam", delegate() - { - _vehicle.ProcessFloatVehicleParam((Vehicle)param, value); - ActivateIfPhysical(false); - }); - } - public override void VehicleVectorParam(int param, OMV.Vector3 value) - { - PhysicsScene.TaintedObject("BSPrim.VehicleVectorParam", delegate() - { - _vehicle.ProcessVectorVehicleParam((Vehicle)param, value); - ActivateIfPhysical(false); - }); - } - public override void VehicleRotationParam(int param, OMV.Quaternion rotation) - { - PhysicsScene.TaintedObject("BSPrim.VehicleRotationParam", delegate() - { - _vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation); - ActivateIfPhysical(false); - }); - } - public override void VehicleFlags(int param, bool remove) - { - PhysicsScene.TaintedObject("BSPrim.VehicleFlags", delegate() - { - _vehicle.ProcessVehicleFlags(param, remove); - }); - } - - // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more - public override void SetVolumeDetect(int param) { - bool newValue = (param != 0); - if (_isVolumeDetect != newValue) - { - _isVolumeDetect = newValue; - PhysicsScene.TaintedObject("BSPrim.SetVolumeDetect", delegate() - { - // DetailLog("{0},setVolumeDetect,taint,volDetect={1}", LocalID, _isVolumeDetect); - SetObjectDynamic(true); - }); - } - return; - } - public override OMV.Vector3 Velocity { - get { return _velocity; } - set { - _velocity = value; - PhysicsScene.TaintedObject("BSPrim.setVelocity", delegate() - { - // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); - ForceVelocity = _velocity; - }); - } - } - public override OMV.Vector3 ForceVelocity { - get { return _velocity; } - set { - PhysicsScene.AssertInTaintTime("BSPrim.ForceVelocity"); - - _velocity = value; - if (PhysBody.HasPhysicalBody) - { - BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); - ActivateIfPhysical(false); - } - } - } - public override OMV.Vector3 Torque { - get { return _torque; } - set { - _torque = value; - if (_torque != OMV.Vector3.Zero) - { - // If the torque is non-zero, it must be reapplied each tick because - // Bullet clears the forces applied last frame. - RegisterPreStepAction("BSPrim.setTorque", LocalID, - delegate(float timeStep) - { - if (PhysBody.HasPhysicalBody) - AddAngularForce(_torque, false, true); - } - ); - } - else - { - UnRegisterPreStepAction("BSPrim.setTorque", LocalID); - } - // DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque); - } - } - public override float CollisionScore { - get { return _collisionScore; } - set { _collisionScore = value; - } - } - public override OMV.Vector3 Acceleration { - get { return _acceleration; } - set { _acceleration = value; } - } - public override OMV.Quaternion RawOrientation - { - get { return _orientation; } - set { _orientation = value; } - } - public override OMV.Quaternion Orientation { - get { - /* NOTE: this refetch is not necessary. The simulator knows about linkset children - * and does not fetch this position info for children. Thus this is commented out. - // Children move around because tied to parent. Get a fresh value. - if (!Linkset.IsRoot(this)) - { - _orientation = Linkset.OrientationGet(this); - } - */ - return _orientation; - } - set { - if (_orientation == value) - return; - _orientation = value; - - // A linkset might need to know if a component information changed. - Linkset.UpdateProperties(this, false); - - PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate() - { - if (PhysBody.HasPhysicalBody) - { - // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr); - // DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); - } - }); - } - } - // Go directly to Bullet to get/set the value. - public override OMV.Quaternion ForceOrientation - { - get - { - _orientation = BulletSimAPI.GetOrientation2(PhysBody.ptr); - return _orientation; - } - set - { - _orientation = value; - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); - } - } - public override int PhysicsActorType { - get { return _physicsActorType; } - set { _physicsActorType = value; } - } - public override bool IsPhysical { - get { return _isPhysical; } - set { - if (_isPhysical != value) - { - _isPhysical = value; - PhysicsScene.TaintedObject("BSPrim.setIsPhysical", delegate() - { - // DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical); - SetObjectDynamic(true); - // whether phys-to-static or static-to-phys, the object is not moving. - ZeroMotion(true); - }); - } - } - } - - // An object is static (does not move) if selected or not physical - public override bool IsStatic - { - get { return _isSelected || !IsPhysical; } - } - - // An object is solid if it's not phantom and if it's not doing VolumeDetect - public override bool IsSolid - { - get { return !IsPhantom && !_isVolumeDetect; } - } - - // Make gravity work if the object is physical and not selected - // Called at taint-time!! - private void SetObjectDynamic(bool forceRebuild) - { - // Recreate the physical object if necessary - CreateGeomAndObject(forceRebuild); - } - - // Convert the simulator's physical properties into settings on BulletSim objects. - // There are four flags we're interested in: - // IsStatic: Object does not move, otherwise the object has mass and moves - // isSolid: other objects bounce off of this object - // isVolumeDetect: other objects pass through but can generate collisions - // collisionEvents: whether this object returns collision events - private void UpdatePhysicalParameters() - { - // DetailLog("{0},BSPrim.UpdatePhysicalParameters,entry,body={1},shape={2}", LocalID, BSBody, BSShape); - - // 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). - BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr); - - // Set up the object physicalness (does gravity and collisions move this object) - MakeDynamic(IsStatic); - - // Update vehicle specific parameters (after MakeDynamic() so can change physical parameters) - _vehicle.Refresh(); - - // Arrange for collision events if the simulator wants them - EnableCollisions(SubscribedEvents()); - - // Make solid or not (do things bounce off or pass through this object). - MakeSolid(IsSolid); - - BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr, _position, _orientation); - - // Rebuild its shape - BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); - - // Collision filter can be set only when the object is in the world - PhysBody.ApplyCollisionMask(); - - // Recompute any linkset parameters. - // When going from non-physical to physical, this re-enables the constraints that - // had been automatically disabled when the mass was set to zero. - // For compound based linksets, this enables and disables interactions of the children. - Linkset.Refresh(this); - - DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},body={6},shape={7}", - LocalID, IsStatic, IsSolid, Mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody, PhysShape); - } - - // "Making dynamic" means changing to and from static. - // When static, gravity does not effect the object and it is fixed in space. - // When dynamic, the object can fall and be pushed by others. - // This is independent of its 'solidness' which controls what passes through - // this object and what interacts with it. - private void MakeDynamic(bool makeStatic) - { - if (makeStatic) - { - // Become a Bullet 'static' object type - CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT); - // Stop all movement - ZeroMotion(true); - - // Set various physical properties so other object interact properly - MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false); - BulletSimAPI.SetFriction2(PhysBody.ptr, matAttrib.friction); - BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution); - - // Mass is zero which disables a bunch of physics stuff in Bullet - UpdatePhysicalMassProperties(0f, false); - // Set collision detection parameters - if (BSParam.CcdMotionThreshold > 0f) - { - BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, BSParam.CcdMotionThreshold); - BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius); - } - - // The activation state is 'disabled' so Bullet will not try to act on it. - // BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.DISABLE_SIMULATION); - // Start it out sleeping and physical actions could wake it up. - BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ISLAND_SLEEPING); - - // This collides like a static object - PhysBody.collisionType = CollisionType.Static; - - // There can be special things needed for implementing linksets - Linkset.MakeStatic(this); - } - else - { - // Not a Bullet static object - CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT); - - // Set various physical properties so other object interact properly - MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, true); - BulletSimAPI.SetFriction2(PhysBody.ptr, matAttrib.friction); - BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution); - - // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382 - // Since this can be called multiple times, only zero forces when becoming physical - // BulletSimAPI.ClearAllForces2(BSBody.ptr); - - // For good measure, make sure the transform is set through to the motion state - BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); - - // Center of mass is at the center of the object - // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.PhysBody.ptr, _position, _orientation); - - // A dynamic object has mass - UpdatePhysicalMassProperties(RawMass, false); - - // Set collision detection parameters - if (BSParam.CcdMotionThreshold > 0f) - { - BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, BSParam.CcdMotionThreshold); - BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius); - } - - // Various values for simulation limits - BulletSimAPI.SetDamping2(PhysBody.ptr, BSParam.LinearDamping, BSParam.AngularDamping); - BulletSimAPI.SetDeactivationTime2(PhysBody.ptr, BSParam.DeactivationTime); - BulletSimAPI.SetSleepingThresholds2(PhysBody.ptr, BSParam.LinearSleepingThreshold, BSParam.AngularSleepingThreshold); - BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, BSParam.ContactProcessingThreshold); - - // This collides like an object. - PhysBody.collisionType = CollisionType.Dynamic; - - // Force activation of the object so Bullet will act on it. - // Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects. - BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ACTIVE_TAG); - - // There might be special things needed for implementing linksets. - Linkset.MakeDynamic(this); - } - } - - // "Making solid" means that other object will not pass through this object. - // To make transparent, we create a Bullet ghost object. - // Note: This expects to be called from the UpdatePhysicalParameters() routine as - // the functions after this one set up the state of a possibly newly created collision body. - private void MakeSolid(bool makeSolid) - { - CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(PhysBody.ptr); - if (makeSolid) - { - // Verify the previous code created the correct shape for this type of thing. - if ((bodyType & CollisionObjectTypes.CO_RIGID_BODY) == 0) - { - m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for solidity. id={1}, type={2}", LogHeader, LocalID, bodyType); - } - CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); - } - else - { - if ((bodyType & CollisionObjectTypes.CO_GHOST_OBJECT) == 0) - { - m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for non-solidness. id={1}, type={2}", LogHeader, LocalID, bodyType); - } - CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); - - // Change collision info from a static object to a ghosty collision object - PhysBody.collisionType = CollisionType.VolumeDetect; - } - } - - // Enable physical actions. Bullet will keep sleeping non-moving physical objects so - // they need waking up when parameters are changed. - // Called in taint-time!! - private void ActivateIfPhysical(bool forceIt) - { - if (IsPhysical && PhysBody.HasPhysicalBody) - BulletSimAPI.Activate2(PhysBody.ptr, forceIt); - } - - // Turn on or off the flag controlling whether collision events are returned to the simulator. - private void EnableCollisions(bool wantsCollisionEvents) - { - if (wantsCollisionEvents) - { - CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); - } - else - { - CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); - } - } - - // prims don't fly - public override bool Flying { - get { return _flying; } - set { - _flying = value; - } - } - public override bool SetAlwaysRun { - get { return _setAlwaysRun; } - set { _setAlwaysRun = value; } - } - public override bool ThrottleUpdates { - get { return _throttleUpdates; } - set { _throttleUpdates = value; } - } - public override bool IsColliding { - get { return (CollidingStep == PhysicsScene.SimulationStep); } - set { _isColliding = value; } - } - public override bool CollidingGround { - get { return (CollidingGroundStep == PhysicsScene.SimulationStep); } - set { _collidingGround = value; } - } - public override bool CollidingObj { - get { return _collidingObj; } - set { _collidingObj = value; } - } - public bool IsPhantom { - get { - // SceneObjectPart removes phantom objects from the physics scene - // so, although we could implement touching and such, we never - // are invoked as a phantom object - return false; - } - } - public override bool FloatOnWater { - set { - _floatOnWater = value; - PhysicsScene.TaintedObject("BSPrim.setFloatOnWater", delegate() - { - if (_floatOnWater) - CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); - else - CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER); - }); - } - } - public override OMV.Vector3 RotationalVelocity { - get { - return _rotationalVelocity; - } - set { - _rotationalVelocity = value; - // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); - PhysicsScene.TaintedObject("BSPrim.setRotationalVelocity", delegate() - { - DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); - ForceRotationalVelocity = _rotationalVelocity; - }); - } - } - public override OMV.Vector3 ForceRotationalVelocity { - get { - return _rotationalVelocity; - } - set { - _rotationalVelocity = value; - if (PhysBody.HasPhysicalBody) - { - BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity); - ActivateIfPhysical(false); - } - } - } - public override bool Kinematic { - get { return _kinematic; } - set { _kinematic = value; - // m_log.DebugFormat("{0}: Kinematic={1}", LogHeader, _kinematic); - } - } - public override float Buoyancy { - get { return _buoyancy; } - set { - _buoyancy = value; - PhysicsScene.TaintedObject("BSPrim.setBuoyancy", delegate() - { - ForceBuoyancy = _buoyancy; - }); - } - } - public override float ForceBuoyancy { - get { return _buoyancy; } - set { - _buoyancy = value; - // DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); - // Force the recalculation of the various inertia,etc variables in the object - UpdatePhysicalMassProperties(_mass, true); - ActivateIfPhysical(false); - } - } - - // Used for MoveTo - public override OMV.Vector3 PIDTarget { - set { _PIDTarget = value; } - } - public override bool PIDActive { - set { _usePID = value; } - } - public override float PIDTau { - set { _PIDTau = value; } - } - - // Used for llSetHoverHeight and maybe vehicle height - // Hover Height will override MoveTo target's Z - public override bool PIDHoverActive { - set { _useHoverPID = value; } - } - public override float PIDHoverHeight { - set { _PIDHoverHeight = value; } - } - public override PIDHoverType PIDHoverType { - set { _PIDHoverType = value; } - } - public override float PIDHoverTau { - set { _PIDHoverTao = value; } - } - - // For RotLookAt - public override OMV.Quaternion APIDTarget { set { return; } } - public override bool APIDActive { set { return; } } - public override float APIDStrength { set { return; } } - public override float APIDDamping { set { return; } } - - public override void AddForce(OMV.Vector3 force, bool pushforce) { - // Since this force is being applied in only one step, make this a force per second. - OMV.Vector3 addForce = force / PhysicsScene.LastTimeStep; - AddForce(addForce, pushforce, false); - } - // Applying a force just adds this to the total force on the object. - // This added force will only last the next simulation tick. - public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { - // for an object, doesn't matter if force is a pushforce or not - if (force.IsFinite()) - { - float magnitude = force.Length(); - if (magnitude > 20000f) - { - // Force has a limit - force = force / magnitude * 20000f; - } - - OMV.Vector3 addForce = force; - DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); - - PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() - { - // Bullet adds this central force to the total force for this tick - DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce); - if (PhysBody.HasPhysicalBody) - { - BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, addForce); - ActivateIfPhysical(false); - } - }); - } - else - { - m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID); - return; - } - } - - public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { - AddAngularForce(force, pushforce, false); - } - public void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) - { - if (force.IsFinite()) - { - OMV.Vector3 angForce = force; - PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddAngularForce", delegate() - { - if (PhysBody.HasPhysicalBody) - { - BulletSimAPI.ApplyTorque2(PhysBody.ptr, angForce); - ActivateIfPhysical(false); - } - }); - } - else - { - m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID); - return; - } - } - - // A torque impulse. - // ApplyTorqueImpulse adds torque directly to the angularVelocity. - // AddAngularForce accumulates the force and applied it to the angular velocity all at once. - // Computed as: angularVelocity += impulse * inertia; - public void ApplyTorqueImpulse(OMV.Vector3 impulse, bool inTaintTime) - { - OMV.Vector3 applyImpulse = impulse; - PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ApplyTorqueImpulse", delegate() - { - if (PhysBody.HasPhysicalBody) - { - BulletSimAPI.ApplyTorqueImpulse2(PhysBody.ptr, applyImpulse); - ActivateIfPhysical(false); - } - }); - } - - public override void SetMomentum(OMV.Vector3 momentum) { - // DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum); - } - #region Mass Calculation - - private float CalculateMass() - { - float volume = _size.X * _size.Y * _size.Z; // default - float tmp; - - float returnMass = 0; - float hollowAmount = (float)BaseShape.ProfileHollow * 2.0e-5f; - float hollowVolume = hollowAmount * hollowAmount; - - switch (BaseShape.ProfileShape) - { - case ProfileShape.Square: - // default box - - if (BaseShape.PathCurve == (byte)Extrusion.Straight) - { - if (hollowAmount > 0.0) - { - switch (BaseShape.HollowShape) - { - case HollowShape.Square: - case HollowShape.Same: - break; - - case HollowShape.Circle: - - hollowVolume *= 0.78539816339f; - break; - - case HollowShape.Triangle: - - hollowVolume *= (0.5f * .5f); - break; - - default: - hollowVolume = 0; - break; - } - volume *= (1.0f - hollowVolume); - } - } - - else if (BaseShape.PathCurve == (byte)Extrusion.Curve1) - { - //a tube - - volume *= 0.78539816339e-2f * (float)(200 - BaseShape.PathScaleX); - tmp= 1.0f -2.0e-2f * (float)(200 - BaseShape.PathScaleY); - volume -= volume*tmp*tmp; - - if (hollowAmount > 0.0) - { - hollowVolume *= hollowAmount; - - switch (BaseShape.HollowShape) - { - case HollowShape.Square: - case HollowShape.Same: - break; - - case HollowShape.Circle: - hollowVolume *= 0.78539816339f;; - break; - - case HollowShape.Triangle: - hollowVolume *= 0.5f * 0.5f; - break; - default: - hollowVolume = 0; - break; - } - volume *= (1.0f - hollowVolume); - } - } - - break; - - case ProfileShape.Circle: - - if (BaseShape.PathCurve == (byte)Extrusion.Straight) - { - volume *= 0.78539816339f; // elipse base - - if (hollowAmount > 0.0) - { - switch (BaseShape.HollowShape) - { - case HollowShape.Same: - case HollowShape.Circle: - break; - - case HollowShape.Square: - hollowVolume *= 0.5f * 2.5984480504799f; - break; - - case HollowShape.Triangle: - hollowVolume *= .5f * 1.27323954473516f; - break; - - default: - hollowVolume = 0; - break; - } - volume *= (1.0f - hollowVolume); - } - } - - else if (BaseShape.PathCurve == (byte)Extrusion.Curve1) - { - volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - BaseShape.PathScaleX); - tmp = 1.0f - .02f * (float)(200 - BaseShape.PathScaleY); - volume *= (1.0f - tmp * tmp); - - if (hollowAmount > 0.0) - { - - // calculate the hollow volume by it's shape compared to the prim shape - hollowVolume *= hollowAmount; - - switch (BaseShape.HollowShape) - { - case HollowShape.Same: - case HollowShape.Circle: - break; - - case HollowShape.Square: - hollowVolume *= 0.5f * 2.5984480504799f; - break; - - case HollowShape.Triangle: - hollowVolume *= .5f * 1.27323954473516f; - break; - - default: - hollowVolume = 0; - break; - } - volume *= (1.0f - hollowVolume); - } - } - break; - - case ProfileShape.HalfCircle: - if (BaseShape.PathCurve == (byte)Extrusion.Curve1) - { - volume *= 0.52359877559829887307710723054658f; - } - break; - - case ProfileShape.EquilateralTriangle: - - if (BaseShape.PathCurve == (byte)Extrusion.Straight) - { - volume *= 0.32475953f; - - if (hollowAmount > 0.0) - { - - // calculate the hollow volume by it's shape compared to the prim shape - switch (BaseShape.HollowShape) - { - case HollowShape.Same: - case HollowShape.Triangle: - hollowVolume *= .25f; - break; - - case HollowShape.Square: - hollowVolume *= 0.499849f * 3.07920140172638f; - break; - - case HollowShape.Circle: - // Hollow shape is a perfect cyllinder in respect to the cube's scale - // Cyllinder hollow volume calculation - - hollowVolume *= 0.1963495f * 3.07920140172638f; - break; - - default: - hollowVolume = 0; - break; - } - volume *= (1.0f - hollowVolume); - } - } - else if (BaseShape.PathCurve == (byte)Extrusion.Curve1) - { - volume *= 0.32475953f; - volume *= 0.01f * (float)(200 - BaseShape.PathScaleX); - tmp = 1.0f - .02f * (float)(200 - BaseShape.PathScaleY); - volume *= (1.0f - tmp * tmp); - - if (hollowAmount > 0.0) - { - - hollowVolume *= hollowAmount; - - switch (BaseShape.HollowShape) - { - case HollowShape.Same: - case HollowShape.Triangle: - hollowVolume *= .25f; - break; - - case HollowShape.Square: - hollowVolume *= 0.499849f * 3.07920140172638f; - break; - - case HollowShape.Circle: - - hollowVolume *= 0.1963495f * 3.07920140172638f; - break; - - default: - hollowVolume = 0; - break; - } - volume *= (1.0f - hollowVolume); - } - } - break; - - default: - break; - } - - - - float taperX1; - float taperY1; - float taperX; - float taperY; - float pathBegin; - float pathEnd; - float profileBegin; - float profileEnd; - - if (BaseShape.PathCurve == (byte)Extrusion.Straight || BaseShape.PathCurve == (byte)Extrusion.Flexible) - { - taperX1 = BaseShape.PathScaleX * 0.01f; - if (taperX1 > 1.0f) - taperX1 = 2.0f - taperX1; - taperX = 1.0f - taperX1; - - taperY1 = BaseShape.PathScaleY * 0.01f; - if (taperY1 > 1.0f) - taperY1 = 2.0f - taperY1; - taperY = 1.0f - taperY1; - } - else - { - taperX = BaseShape.PathTaperX * 0.01f; - if (taperX < 0.0f) - taperX = -taperX; - taperX1 = 1.0f - taperX; - - taperY = BaseShape.PathTaperY * 0.01f; - if (taperY < 0.0f) - taperY = -taperY; - taperY1 = 1.0f - taperY; - - } - - - volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY); - - pathBegin = (float)BaseShape.PathBegin * 2.0e-5f; - pathEnd = 1.0f - (float)BaseShape.PathEnd * 2.0e-5f; - volume *= (pathEnd - pathBegin); - - // this is crude aproximation - profileBegin = (float)BaseShape.ProfileBegin * 2.0e-5f; - profileEnd = 1.0f - (float)BaseShape.ProfileEnd * 2.0e-5f; - volume *= (profileEnd - profileBegin); - - returnMass = _density * volume; - - /* Comment out code that computes the mass of the linkset. That is done in the Linkset class. - if (IsRootOfLinkset) - { - foreach (BSPrim prim in _childrenPrims) - { - returnMass += prim.CalculateMass(); - } - } - */ - - returnMass = Util.Clamp(returnMass, BSParam.MinimumObjectMass, BSParam.MaximumObjectMass); - - return returnMass; - }// end CalculateMass - #endregion Mass Calculation - - // Rebuild the geometry and object. - // This is called when the shape changes so we need to recreate the mesh/hull. - // Called at taint-time!!! - public void CreateGeomAndObject(bool forceRebuild) - { - // If this prim is part of a linkset, we must remove and restore the physical - // links if the body is rebuilt. - bool needToRestoreLinkset = false; - bool needToRestoreVehicle = false; - - // Create the correct physical representation for this type of object. - // Updates PhysBody and PhysShape with the new information. - // Ignore 'forceRebuild'. This routine makes the right choices and changes of necessary. - PhysicsScene.Shapes.GetBodyAndShape(false, PhysicsScene.World, this, null, delegate(BulletBody dBody) - { - // Called if the current prim body is about to be destroyed. - // Remove all the physical dependencies on the old body. - // (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...) - needToRestoreLinkset = Linkset.RemoveBodyDependencies(this); - needToRestoreVehicle = _vehicle.RemoveBodyDependencies(this); - }); - - if (needToRestoreLinkset) - { - // If physical body dependencies were removed, restore them - Linkset.RestoreBodyDependencies(this); - } - if (needToRestoreVehicle) - { - // If physical body dependencies were removed, restore them - _vehicle.RestoreBodyDependencies(this); - } - - // Make sure the properties are set on the new object - UpdatePhysicalParameters(); - return; - } - - // The physics engine says that properties have updated. Update same and inform - // the world that things have changed. - // TODO: do we really need to check for changed? Maybe just copy values and call RequestPhysicsterseUpdate() - enum UpdatedProperties { - Position = 1 << 0, - Rotation = 1 << 1, - Velocity = 1 << 2, - Acceleration = 1 << 3, - RotationalVel = 1 << 4 - } - - const float ROTATION_TOLERANCE = 0.01f; - const float VELOCITY_TOLERANCE = 0.001f; - const float POSITION_TOLERANCE = 0.05f; - const float ACCELERATION_TOLERANCE = 0.01f; - const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f; - - public override void UpdateProperties(EntityProperties entprop) - { - // Updates only for individual prims and for the root object of a linkset. - if (Linkset.IsRoot(this)) - { - // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet - // TODO: handle physics introduced by Bullet with computed vehicle physics. - if (_vehicle.IsActive) - { - entprop.RotationalVelocity = OMV.Vector3.Zero; - } - - // Assign directly to the local variables so the normal set action does not happen - _position = entprop.Position; - _orientation = entprop.Rotation; - _velocity = entprop.Velocity; - _acceleration = entprop.Acceleration; - _rotationalVelocity = entprop.RotationalVelocity; - - // The sanity check can change the velocity and/or position. - if (IsPhysical && PositionSanityCheck(true)) - { - entprop.Position = _position; - entprop.Velocity = _velocity; - } - - OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG - DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}", - LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity); - - // remember the current and last set values - LastEntityProperties = CurrentEntityProperties; - CurrentEntityProperties = entprop; - - base.RequestPhysicsterseUpdate(); - } - /* - else - { - // For debugging, report the movement of children - DetailLog("{0},BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}", - LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, - entprop.Acceleration, entprop.RotationalVelocity); - } - */ - - // The linkset implimentation might want to know about this. - Linkset.UpdateProperties(this, true); - } -} -} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSScene.cs deleted file mode 100644 index 4fc3e2a..0000000 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSScene.cs +++ /dev/null @@ -1,957 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading; -using OpenSim.Framework; -using OpenSim.Region.Framework; -using OpenSim.Region.CoreModules; -using Logging = OpenSim.Region.CoreModules.Framework.Statistics.Logging; -using OpenSim.Region.Physics.Manager; -using Nini.Config; -using log4net; -using OpenMetaverse; - -// TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim) -// Based on material, set density and friction -// More efficient memory usage when passing hull information from BSPrim to BulletSim -// Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect -// Implement LockAngularMotion -// Add PID movement operations. What does ScenePresence.MoveToTarget do? -// Check terrain size. 128 or 127? -// Raycast -// -namespace OpenSim.Region.Physics.BulletSNPlugin -{ -public sealed class BSScene : PhysicsScene, IPhysicsParameters -{ - private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - private static readonly string LogHeader = "[BULLETS SCENE]"; - - // The name of the region we're working for. - public string RegionName { get; private set; } - - public string BulletSimVersion = "?"; - - public Dictionary PhysObjects; - public BSShapeCollection Shapes; - - // Keeping track of the objects with collisions so we can report begin and end of a collision - public HashSet ObjectsWithCollisions = new HashSet(); - public HashSet ObjectsWithNoMoreCollisions = new HashSet(); - // Keep track of all the avatars so we can send them a collision event - // every tick so OpenSim will update its animation. - private HashSet m_avatars = new HashSet(); - - // let my minuions use my logger - public ILog Logger { get { return m_log; } } - - public IMesher mesher; - public uint WorldID { get; private set; } - public BulletWorld World { get; private set; } - - // All the constraints that have been allocated in this instance. - public BSConstraintCollection Constraints { get; private set; } - - // Simulation parameters - internal int m_maxSubSteps; - internal float m_fixedTimeStep; - internal long m_simulationStep = 0; - public long SimulationStep { get { return m_simulationStep; } } - internal int m_taintsToProcessPerStep; - internal float LastTimeStep { get; private set; } - - // Physical objects can register for prestep or poststep events - public delegate void PreStepAction(float timeStep); - public delegate void PostStepAction(float timeStep); - public event PreStepAction BeforeStep; - public event PreStepAction AfterStep; - - // A value of the time now so all the collision and update routines do not have to get their own - // Set to 'now' just before all the prims and actors are called for collisions and updates - public int SimulationNowTime { get; private set; } - - // True if initialized and ready to do simulation steps - private bool m_initialized = false; - - // Flag which is true when processing taints. - // Not guaranteed to be correct all the time (don't depend on this) but good for debugging. - public bool InTaintTime { get; private set; } - - // Pinned memory used to pass step information between managed and unmanaged - internal int m_maxCollisionsPerFrame; - private BulletXNA.CollisionDesc[] m_collisionArray; - //private GCHandle m_collisionArrayPinnedHandle; - - internal int m_maxUpdatesPerFrame; - private BulletXNA.EntityProperties[] m_updateArray; - //private GCHandle m_updateArrayPinnedHandle; - - - public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero - public const uint GROUNDPLANE_ID = 1; - public const uint CHILDTERRAIN_ID = 2; // Terrain allocated based on our mega-prim childre start here - - public float SimpleWaterLevel { get; set; } - public BSTerrainManager TerrainManager { get; private set; } - - public ConfigurationParameters Params - { - get { return UnmanagedParams[0]; } - } - public Vector3 DefaultGravity - { - get { return new Vector3(0f, 0f, Params.gravity); } - } - // Just the Z value of the gravity - public float DefaultGravityZ - { - get { return Params.gravity; } - } - - // When functions in the unmanaged code must be called, it is only - // done at a known time just before the simulation step. The taint - // system saves all these function calls and executes them in - // order before the simulation. - public delegate void TaintCallback(); - private struct TaintCallbackEntry - { - public String ident; - public TaintCallback callback; - public TaintCallbackEntry(string i, TaintCallback c) - { - ident = i; - callback = c; - } - } - private Object _taintLock = new Object(); // lock for using the next object - private List _taintOperations; - private Dictionary _postTaintOperations; - private List _postStepOperations; - - // A pointer to an instance if this structure is passed to the C++ code - // Used to pass basic configuration values to the unmanaged code. - internal ConfigurationParameters[] UnmanagedParams; - //GCHandle m_paramsHandle; - - // Handle to the callback used by the unmanaged code to call into the managed code. - // Used for debug logging. - // Need to store the handle in a persistant variable so it won't be freed. - private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle; - - // Sometimes you just have to log everything. - public Logging.LogWriter PhysicsLogging; - private bool m_physicsLoggingEnabled; - private string m_physicsLoggingDir; - private string m_physicsLoggingPrefix; - private int m_physicsLoggingFileMinutes; - private bool m_physicsLoggingDoFlush; - // 'true' of the vehicle code is to log lots of details - public bool VehicleLoggingEnabled { get; private set; } - public bool VehiclePhysicalLoggingEnabled { get; private set; } - - #region Construction and Initialization - public BSScene(string identifier) - { - m_initialized = false; - // we are passed the name of the region we're working for. - RegionName = identifier; - } - - public override void Initialise(IMesher meshmerizer, IConfigSource config) - { - mesher = meshmerizer; - _taintOperations = new List(); - _postTaintOperations = new Dictionary(); - _postStepOperations = new List(); - PhysObjects = new Dictionary(); - Shapes = new BSShapeCollection(this); - - // Allocate pinned memory to pass parameters. - UnmanagedParams = new ConfigurationParameters[1]; - //m_paramsHandle = GCHandle.Alloc(UnmanagedParams, GCHandleType.Pinned); - - // Set default values for physics parameters plus any overrides from the ini file - GetInitialParameterValues(config); - - // allocate more pinned memory close to the above in an attempt to get the memory all together - m_collisionArray = new BulletXNA.CollisionDesc[0]; - //m_collisionArrayPinnedHandle = GCHandle.Alloc(m_collisionArray, GCHandleType.Pinned); - m_updateArray = new BulletXNA.EntityProperties[0]; - //m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned); - - // Enable very detailed logging. - // By creating an empty logger when not logging, the log message invocation code - // can be left in and every call doesn't have to check for null. - if (m_physicsLoggingEnabled) - { - PhysicsLogging = new Logging.LogWriter(m_physicsLoggingDir, m_physicsLoggingPrefix, m_physicsLoggingFileMinutes); - PhysicsLogging.ErrorLogger = m_log; // for DEBUG. Let's the logger output error messages. - } - else - { - PhysicsLogging = new Logging.LogWriter(); - } - - // If Debug logging level, enable logging from the unmanaged code - m_DebugLogCallbackHandle = null; - if (m_log.IsDebugEnabled || PhysicsLogging.Enabled) - { - m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader); - if (PhysicsLogging.Enabled) - // The handle is saved in a variable to make sure it doesn't get freed after this call - m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLoggerPhysLog); - else - m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger); - } - - // Get the version of the DLL - // TODO: this doesn't work yet. Something wrong with marshaling the returned string. - // BulletSimVersion = BulletSimAPI.GetVersion(); - // m_log.WarnFormat("{0}: BulletSim.dll version='{1}'", LogHeader, BulletSimVersion); - - // The bounding box for the simulated world. The origin is 0,0,0 unless we're - // a child in a mega-region. - // Bullet actually doesn't care about the extents of the simulated - // area. It tracks active objects no matter where they are. - Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); - - // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader); - - World = new BulletWorld(0, this, BulletSimAPI.Initialize2(worldExtent, UnmanagedParams, - m_maxCollisionsPerFrame, ref m_collisionArray, - m_maxUpdatesPerFrame,ref m_updateArray, - m_DebugLogCallbackHandle)); - - Constraints = new BSConstraintCollection(World); - - TerrainManager = new BSTerrainManager(this); - TerrainManager.CreateInitialGroundPlaneAndTerrain(); - - m_log.WarnFormat("{0} Linksets implemented with {1}", LogHeader, (BSLinkset.LinksetImplementation)BSParam.LinksetImplementation); - - InTaintTime = false; - m_initialized = true; - } - - // All default parameter values are set here. There should be no values set in the - // variable definitions. - private void GetInitialParameterValues(IConfigSource config) - { - ConfigurationParameters parms = new ConfigurationParameters(); - UnmanagedParams[0] = parms; - - BSParam.SetParameterDefaultValues(this); - - if (config != null) - { - // If there are specifications in the ini file, use those values - IConfig pConfig = config.Configs["BulletSim"]; - if (pConfig != null) - { - BSParam.SetParameterConfigurationValues(this, pConfig); - - // Very detailed logging for physics debugging - m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false); - m_physicsLoggingDir = pConfig.GetString("PhysicsLoggingDir", "."); - m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-%REGIONNAME%-"); - m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5); - m_physicsLoggingDoFlush = pConfig.GetBoolean("PhysicsLoggingDoFlush", false); - // Very detailed logging for vehicle debugging - VehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false); - VehiclePhysicalLoggingEnabled = pConfig.GetBoolean("VehiclePhysicalLoggingEnabled", false); - - // Do any replacements in the parameters - m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName); - } - - // The material characteristics. - BSMaterials.InitializeFromDefaults(Params); - if (pConfig != null) - { - // Let the user add new and interesting material property values. - BSMaterials.InitializefromParameters(pConfig); - } - } - } - - // A helper function that handles a true/false parameter and returns the proper float number encoding - float ParamBoolean(IConfig config, string parmName, float deflt) - { - float ret = deflt; - if (config.Contains(parmName)) - { - ret = ConfigurationParameters.numericFalse; - if (config.GetBoolean(parmName, false)) - { - ret = ConfigurationParameters.numericTrue; - } - } - return ret; - } - - // Called directly from unmanaged code so don't do much - private void BulletLogger(string msg) - { - m_log.Debug("[BULLETS UNMANAGED]:" + msg); - } - - // Called directly from unmanaged code so don't do much - private void BulletLoggerPhysLog(string msg) - { - DetailLog("[BULLETS UNMANAGED]:" + msg); - } - - public override void Dispose() - { - // m_log.DebugFormat("{0}: Dispose()", LogHeader); - - // make sure no stepping happens while we're deleting stuff - m_initialized = false; - - foreach (KeyValuePair kvp in PhysObjects) - { - kvp.Value.Destroy(); - } - PhysObjects.Clear(); - - // Now that the prims are all cleaned up, there should be no constraints left - if (Constraints != null) - { - Constraints.Dispose(); - Constraints = null; - } - - if (Shapes != null) - { - Shapes.Dispose(); - Shapes = null; - } - - if (TerrainManager != null) - { - TerrainManager.ReleaseGroundPlaneAndTerrain(); - TerrainManager.Dispose(); - TerrainManager = null; - } - - // Anything left in the unmanaged code should be cleaned out - BulletSimAPI.Shutdown2(World.ptr); - - // Not logging any more - PhysicsLogging.Close(); - } - #endregion // Construction and Initialization - - #region Prim and Avatar addition and removal - - public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying) - { - m_log.ErrorFormat("{0}: CALL TO AddAvatar in BSScene. NOT IMPLEMENTED", LogHeader); - return null; - } - - public override PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, bool isFlying) - { - // m_log.DebugFormat("{0}: AddAvatar: {1}", LogHeader, avName); - - if (!m_initialized) return null; - - BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying); - lock (PhysObjects) PhysObjects.Add(localID, actor); - - // TODO: Remove kludge someday. - // We must generate a collision for avatars whether they collide or not. - // This is required by OpenSim to update avatar animations, etc. - lock (m_avatars) m_avatars.Add(actor); - - return actor; - } - - public override void RemoveAvatar(PhysicsActor actor) - { - // m_log.DebugFormat("{0}: RemoveAvatar", LogHeader); - - if (!m_initialized) return; - - BSCharacter bsactor = actor as BSCharacter; - if (bsactor != null) - { - try - { - lock (PhysObjects) PhysObjects.Remove(actor.LocalID); - // Remove kludge someday - lock (m_avatars) m_avatars.Remove(bsactor); - } - catch (Exception e) - { - m_log.WarnFormat("{0}: Attempt to remove avatar that is not in physics scene: {1}", LogHeader, e); - } - bsactor.Destroy(); - // bsactor.dispose(); - } - } - - public override void RemovePrim(PhysicsActor prim) - { - if (!m_initialized) return; - - BSPrim bsprim = prim as BSPrim; - if (bsprim != null) - { - DetailLog("{0},RemovePrim,call", bsprim.LocalID); - // m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID); - try - { - lock (PhysObjects) PhysObjects.Remove(bsprim.LocalID); - } - catch (Exception e) - { - m_log.ErrorFormat("{0}: Attempt to remove prim that is not in physics scene: {1}", LogHeader, e); - } - bsprim.Destroy(); - // bsprim.dispose(); - } - else - { - m_log.ErrorFormat("{0}: Attempt to remove prim that is not a BSPrim type.", LogHeader); - } - } - - public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, - Vector3 size, Quaternion rotation, bool isPhysical, uint localID) - { - // m_log.DebugFormat("{0}: AddPrimShape2: {1}", LogHeader, primName); - - if (!m_initialized) return null; - - DetailLog("{0},AddPrimShape,call", localID); - - BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical); - lock (PhysObjects) PhysObjects.Add(localID, prim); - return prim; - } - - // This is a call from the simulator saying that some physical property has been updated. - // The BulletSim driver senses the changing of relevant properties so this taint - // information call is not needed. - public override void AddPhysicsActorTaint(PhysicsActor prim) { } - - #endregion // Prim and Avatar addition and removal - - #region Simulation - // Simulate one timestep - public override float Simulate(float timeStep) - { - // prevent simulation until we've been initialized - if (!m_initialized) return 5.0f; - - LastTimeStep = timeStep; - - int updatedEntityCount = 0; - //Object updatedEntitiesPtr; - int collidersCount = 0; - //Object collidersPtr; - - int beforeTime = 0; - int simTime = 0; - - // update the prim states while we know the physics engine is not busy - int numTaints = _taintOperations.Count; - - InTaintTime = true; // Only used for debugging so locking is not necessary. - - ProcessTaints(); - - // Some of the physical objects requre individual, pre-step calls - TriggerPreStepEvent(timeStep); - - // the prestep actions might have added taints - ProcessTaints(); - - InTaintTime = false; // Only used for debugging so locking is not necessary. - - // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world. - // Only enable this in a limited test world with few objects. - // BulletSimAPI.DumpAllInfo2(World.ptr); // DEBUG DEBUG DEBUG - - // step the physical world one interval - m_simulationStep++; - int numSubSteps = 0; - - try - { - if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount(); - - numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep, - out updatedEntityCount, out m_updateArray, out collidersCount, out m_collisionArray); - - if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime); - DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}, objWColl={7}", - DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, - updatedEntityCount, collidersCount, ObjectsWithCollisions.Count); - } - catch (Exception e) - { - m_log.WarnFormat("{0},PhysicsStep Exception: nTaints={1}, substeps={2}, updates={3}, colliders={4}, e={5}", - LogHeader, numTaints, numSubSteps, updatedEntityCount, collidersCount, e); - DetailLog("{0},PhysicsStepException,call, nTaints={1}, substeps={2}, updates={3}, colliders={4}", - DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount); - updatedEntityCount = 0; - collidersCount = 0; - } - - // Don't have to use the pointers passed back since we know it is the same pinned memory we passed in. - - // Get a value for 'now' so all the collision and update routines don't have to get their own. - SimulationNowTime = Util.EnvironmentTickCount(); - - // If there were collisions, process them by sending the event to the prim. - // Collisions must be processed before updates. - if (collidersCount > 0) - { - for (int ii = 0; ii < collidersCount; ii++) - { - uint cA = m_collisionArray[ii].aID; - uint cB = m_collisionArray[ii].bID; - Vector3 point = new Vector3(m_collisionArray[ii].point.X, m_collisionArray[ii].point.Y, - m_collisionArray[ii].point.Z); - Vector3 normal = new Vector3(m_collisionArray[ii].normal.X, m_collisionArray[ii].normal.Y, - m_collisionArray[ii].normal.Z); - SendCollision(cA, cB, point, normal, 0.01f); - SendCollision(cB, cA, point, -normal, 0.01f); - } - } - - // The above SendCollision's batch up the collisions on the objects. - // Now push the collisions into the simulator. - if (ObjectsWithCollisions.Count > 0) - { - foreach (BSPhysObject bsp in ObjectsWithCollisions) - if (!bsp.SendCollisions()) - { - // If the object is done colliding, see that it's removed from the colliding list - ObjectsWithNoMoreCollisions.Add(bsp); - } - } - - // This is a kludge to get avatar movement updates. - // The simulator expects collisions for avatars even if there are have been no collisions. - // The event updates avatar animations and stuff. - // If you fix avatar animation updates, remove this overhead and let normal collision processing happen. - foreach (BSPhysObject bsp in m_avatars) - if (!ObjectsWithCollisions.Contains(bsp)) // don't call avatars twice - bsp.SendCollisions(); - - // Objects that are done colliding are removed from the ObjectsWithCollisions list. - // Not done above because it is inside an iteration of ObjectWithCollisions. - // This complex collision processing is required to create an empty collision - // event call after all collisions have happened on an object. This enables - // the simulator to generate the 'collision end' event. - if (ObjectsWithNoMoreCollisions.Count > 0) - { - foreach (BSPhysObject po in ObjectsWithNoMoreCollisions) - ObjectsWithCollisions.Remove(po); - ObjectsWithNoMoreCollisions.Clear(); - } - // Done with collisions. - - // If any of the objects had updated properties, tell the object it has been changed by the physics engine - if (updatedEntityCount > 0) - { - for (int ii = 0; ii < updatedEntityCount; ii++) - { - - BulletXNA.EntityProperties entprop = m_updateArray[ii]; - BSPhysObject pobj; - if (PhysObjects.TryGetValue(entprop.ID, out pobj)) - { - EntityProperties prop = new EntityProperties() - { - Acceleration = new Vector3(entprop.Acceleration.X, entprop.Acceleration.Y, entprop.Acceleration.Z), - ID = entprop.ID, - Position = new Vector3(entprop.Position.X,entprop.Position.Y,entprop.Position.Z), - Rotation = new Quaternion(entprop.Rotation.X,entprop.Rotation.Y,entprop.Rotation.Z,entprop.Rotation.W), - RotationalVelocity = new Vector3(entprop.AngularVelocity.X,entprop.AngularVelocity.Y,entprop.AngularVelocity.Z), - Velocity = new Vector3(entprop.Velocity.X,entprop.Velocity.Y,entprop.Velocity.Z) - }; - //m_log.Debug(pobj.Name + ":" + prop.ToString() + "\n"); - pobj.UpdateProperties(prop); - } - } - } - - TriggerPostStepEvent(timeStep); - - // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world. - // Only enable this in a limited test world with few objects. - // BulletSimAPI.DumpAllInfo2(World.ptr); // DEBUG DEBUG DEBUG - - // The physics engine returns the number of milliseconds it simulated this call. - // These are summed and normalized to one second and divided by 1000 to give the reported physics FPS. - // Multiply by 55 to give a nominal frame rate of 55. - return (float)numSubSteps * m_fixedTimeStep * 1000f * 55f; - } - - // Something has collided - private void SendCollision(uint localID, uint collidingWith, Vector3 collidePoint, Vector3 collideNormal, float penetration) - { - if (localID <= TerrainManager.HighestTerrainID) - { - return; // don't send collisions to the terrain - } - - BSPhysObject collider; - if (!PhysObjects.TryGetValue(localID, out collider)) - { - // If the object that is colliding cannot be found, just ignore the collision. - DetailLog("{0},BSScene.SendCollision,colliderNotInObjectList,id={1},with={2}", DetailLogZero, localID, collidingWith); - return; - } - - // The terrain is not in the physical object list so 'collidee' can be null when Collide() is called. - BSPhysObject collidee = null; - PhysObjects.TryGetValue(collidingWith, out collidee); - - // DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith); - - if (collider.Collide(collidingWith, collidee, collidePoint, collideNormal, penetration)) - { - // If a collision was posted, remember to send it to the simulator - ObjectsWithCollisions.Add(collider); - } - - return; - } - - #endregion // Simulation - - public override void GetResults() { } - - #region Terrain - - public override void SetTerrain(float[] heightMap) { - TerrainManager.SetTerrain(heightMap); - } - - public override void SetWaterLevel(float baseheight) - { - SimpleWaterLevel = baseheight; - } - - public override void DeleteTerrain() - { - // m_log.DebugFormat("{0}: DeleteTerrain()", LogHeader); - } - - // Although no one seems to check this, I do support combining. - public override bool SupportsCombining() - { - return TerrainManager.SupportsCombining(); - } - // This call says I am a child to region zero in a mega-region. 'pScene' is that - // of region zero, 'offset' is my offset from regions zero's origin, and - // 'extents' is the largest XY that is handled in my region. - public override void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents) - { - TerrainManager.Combine(pScene, offset, extents); - } - - // Unhook all the combining that I know about. - public override void UnCombine(PhysicsScene pScene) - { - TerrainManager.UnCombine(pScene); - } - - #endregion // Terrain - - public override Dictionary GetTopColliders() - { - return new Dictionary(); - } - - public override bool IsThreaded { get { return false; } } - - #region Taints - // The simulation execution order is: - // Simulate() - // DoOneTimeTaints - // TriggerPreStepEvent - // DoOneTimeTaints - // Step() - // ProcessAndForwardCollisions - // ProcessAndForwardPropertyUpdates - // TriggerPostStepEvent - - // Calls to the PhysicsActors can't directly call into the physics engine - // because it might be busy. We delay changes to a known time. - // We rely on C#'s closure to save and restore the context for the delegate. - public void TaintedObject(String ident, TaintCallback callback) - { - if (!m_initialized) return; - - lock (_taintLock) - { - _taintOperations.Add(new TaintCallbackEntry(ident, callback)); - } - - return; - } - - // Sometimes a potentially tainted operation can be used in and out of taint time. - // This routine executes the command immediately if in taint-time otherwise it is queued. - public void TaintedObject(bool inTaintTime, string ident, TaintCallback callback) - { - if (inTaintTime) - callback(); - else - TaintedObject(ident, callback); - } - - private void TriggerPreStepEvent(float timeStep) - { - PreStepAction actions = BeforeStep; - if (actions != null) - actions(timeStep); - - } - - private void TriggerPostStepEvent(float timeStep) - { - PreStepAction actions = AfterStep; - if (actions != null) - actions(timeStep); - - } - - // When someone tries to change a property on a BSPrim or BSCharacter, the object queues - // a callback into itself to do the actual property change. That callback is called - // here just before the physics engine is called to step the simulation. - public void ProcessTaints() - { - ProcessRegularTaints(); - ProcessPostTaintTaints(); - } - - private void ProcessRegularTaints() - { - if (_taintOperations.Count > 0) // save allocating new list if there is nothing to process - { - // swizzle a new list into the list location so we can process what's there - List oldList; - lock (_taintLock) - { - oldList = _taintOperations; - _taintOperations = new List(); - } - - foreach (TaintCallbackEntry tcbe in oldList) - { - try - { - DetailLog("{0},BSScene.ProcessTaints,doTaint,id={1}", DetailLogZero, tcbe.ident); // DEBUG DEBUG DEBUG - tcbe.callback(); - } - catch (Exception e) - { - m_log.ErrorFormat("{0}: ProcessTaints: {1}: Exception: {2}", LogHeader, tcbe.ident, e); - } - } - oldList.Clear(); - } - } - - // Schedule an update to happen after all the regular taints are processed. - // Note that new requests for the same operation ("ident") for the same object ("ID") - // will replace any previous operation by the same object. - public void PostTaintObject(String ident, uint ID, TaintCallback callback) - { - string uniqueIdent = ident + "-" + ID.ToString(); - lock (_taintLock) - { - _postTaintOperations[uniqueIdent] = new TaintCallbackEntry(uniqueIdent, callback); - } - - return; - } - - // Taints that happen after the normal taint processing but before the simulation step. - private void ProcessPostTaintTaints() - { - if (_postTaintOperations.Count > 0) - { - Dictionary oldList; - lock (_taintLock) - { - oldList = _postTaintOperations; - _postTaintOperations = new Dictionary(); - } - - foreach (KeyValuePair kvp in oldList) - { - try - { - DetailLog("{0},BSScene.ProcessPostTaintTaints,doTaint,id={1}", DetailLogZero, kvp.Key); // DEBUG DEBUG DEBUG - kvp.Value.callback(); - } - catch (Exception e) - { - m_log.ErrorFormat("{0}: ProcessPostTaintTaints: {1}: Exception: {2}", LogHeader, kvp.Key, e); - } - } - oldList.Clear(); - } - } - - // Only used for debugging. Does not change state of anything so locking is not necessary. - public bool AssertInTaintTime(string whereFrom) - { - if (!InTaintTime) - { - DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom); - m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom); - Util.PrintCallStack(DetailLog); - } - return InTaintTime; - } - - #endregion // Taints - - #region INI and command line parameter processing - - #region IPhysicsParameters - // Get the list of parameters this physics engine supports - public PhysParameterEntry[] GetParameterList() - { - BSParam.BuildParameterTable(); - return BSParam.SettableParameters; - } - - // Set parameter on a specific or all instances. - // Return 'false' if not able to set the parameter. - // Setting the value in the m_params block will change the value the physics engine - // will use the next time since it's pinned and shared memory. - // Some of the values require calling into the physics engine to get the new - // value activated ('terrainFriction' for instance). - public bool SetPhysicsParameter(string parm, float val, uint localID) - { - bool ret = false; - BSParam.ParameterDefn theParam; - if (BSParam.TryGetParameter(parm, out theParam)) - { - theParam.setter(this, parm, localID, val); - ret = true; - } - return ret; - } - - // update all the localIDs specified - // If the local ID is APPLY_TO_NONE, just change the default value - // If the localID is APPLY_TO_ALL change the default value and apply the new value to all the lIDs - // If the localID is a specific object, apply the parameter change to only that object - internal delegate void AssignVal(float x); - internal void UpdateParameterObject(AssignVal setDefault, string parm, uint localID, float val) - { - List objectIDs = new List(); - switch (localID) - { - case PhysParameterEntry.APPLY_TO_NONE: - setDefault(val); // setting only the default value - // This will cause a call into the physical world if some operation is specified (SetOnObject). - objectIDs.Add(TERRAIN_ID); - TaintedUpdateParameter(parm, objectIDs, val); - break; - case PhysParameterEntry.APPLY_TO_ALL: - setDefault(val); // setting ALL also sets the default value - lock (PhysObjects) objectIDs = new List(PhysObjects.Keys); - TaintedUpdateParameter(parm, objectIDs, val); - break; - default: - // setting only one localID - objectIDs.Add(localID); - TaintedUpdateParameter(parm, objectIDs, val); - break; - } - } - - // schedule the actual updating of the paramter to when the phys engine is not busy - private void TaintedUpdateParameter(string parm, List lIDs, float val) - { - float xval = val; - List xlIDs = lIDs; - string xparm = parm; - TaintedObject("BSScene.UpdateParameterSet", delegate() { - BSParam.ParameterDefn thisParam; - if (BSParam.TryGetParameter(xparm, out thisParam)) - { - if (thisParam.onObject != null) - { - foreach (uint lID in xlIDs) - { - BSPhysObject theObject = null; - PhysObjects.TryGetValue(lID, out theObject); - thisParam.onObject(this, theObject, xval); - } - } - } - }); - } - - // Get parameter. - // Return 'false' if not able to get the parameter. - public bool GetPhysicsParameter(string parm, out float value) - { - float val = 0f; - bool ret = false; - BSParam.ParameterDefn theParam; - if (BSParam.TryGetParameter(parm, out theParam)) - { - val = theParam.getter(this); - ret = true; - } - value = val; - return ret; - } - - #endregion IPhysicsParameters - - #endregion Runtime settable parameters - - // Invoke the detailed logger and output something if it's enabled. - public void DetailLog(string msg, params Object[] args) - { - PhysicsLogging.Write(msg, args); - // Add the Flush() if debugging crashes. Gets all the messages written out. - if (m_physicsLoggingDoFlush) PhysicsLogging.Flush(); - } - // Used to fill in the LocalID when there isn't one. It's the correct number of characters. - public const string DetailLogZero = "0000000000"; - -} -} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSShapeCollection.cs deleted file mode 100644 index 47fb768..0000000 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSShapeCollection.cs +++ /dev/null @@ -1,1015 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Text; -using OMV = OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Region.Physics.Manager; -using OpenSim.Region.Physics.ConvexDecompositionDotNet; - -namespace OpenSim.Region.Physics.BulletSNPlugin -{ -public sealed class BSShapeCollection : IDisposable -{ - private static string LogHeader = "[BULLETSIM SHAPE COLLECTION]"; - - private BSScene PhysicsScene { get; set; } - - private Object m_collectionActivityLock = new Object(); - - // Description of a Mesh - private struct MeshDesc - { - public Object ptr; - public int referenceCount; - public DateTime lastReferenced; - public UInt64 shapeKey; - } - - // Description of a hull. - // Meshes and hulls have the same shape hash key but we only need hulls for efficient collision calculations. - private struct HullDesc - { - public Object ptr; - public int referenceCount; - public DateTime lastReferenced; - public UInt64 shapeKey; - } - - // The sharable set of meshes and hulls. Indexed by their shape hash. - private Dictionary Meshes = new Dictionary(); - private Dictionary Hulls = new Dictionary(); - - private bool DDetail = false; - - public BSShapeCollection(BSScene physScene) - { - PhysicsScene = physScene; - // Set the next to 'true' for very detailed shape update detailed logging (detailed details?) - // While detailed debugging is still active, this is better than commenting out all the - // DetailLog statements. When debugging slows down, this and the protected logging - // statements can be commented/removed. - DDetail = true; - } - - public void Dispose() - { - // TODO!!!!!!!!! - } - - // Callbacks called just before either the body or shape is destroyed. - // Mostly used for changing bodies out from under Linksets. - // Useful for other cases where parameters need saving. - // Passing 'null' says no callback. - public delegate void ShapeDestructionCallback(BulletShape shape); - public delegate void BodyDestructionCallback(BulletBody body); - - // Called to update/change the body and shape for an object. - // First checks the shape and updates that if necessary then makes - // sure the body is of the right type. - // Return 'true' if either the body or the shape changed. - // 'shapeCallback' and 'bodyCallback' are, if non-null, functions called just before - // the current shape or body is destroyed. This allows the caller to remove any - // higher level dependencies on the shape or body. Mostly used for LinkSets to - // remove the physical constraints before the body is destroyed. - // Called at taint-time!! - public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim, - ShapeDestructionCallback shapeCallback, BodyDestructionCallback bodyCallback) - { - PhysicsScene.AssertInTaintTime("BSShapeCollection.GetBodyAndShape"); - - bool ret = false; - - // This lock could probably be pushed down lower but building shouldn't take long - lock (m_collectionActivityLock) - { - // Do we have the correct geometry for this type of object? - // Updates prim.BSShape with information/pointers to shape. - // Returns 'true' of BSShape is changed to a new shape. - bool newGeom = CreateGeom(forceRebuild, prim, shapeCallback); - // If we had to select a new shape geometry for the object, - // rebuild the body around it. - // Updates prim.BSBody with information/pointers to requested body - // Returns 'true' if BSBody was changed. - bool newBody = CreateBody((newGeom || forceRebuild), prim, PhysicsScene.World, - prim.PhysShape, bodyCallback); - ret = newGeom || newBody; - } - DetailLog("{0},BSShapeCollection.GetBodyAndShape,taintExit,force={1},ret={2},body={3},shape={4}", - prim.LocalID, forceRebuild, ret, prim.PhysBody, prim.PhysShape); - - return ret; - } - - public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim) - { - return GetBodyAndShape(forceRebuild, sim, prim, null, null); - } - - // Track another user of a body. - // We presume the caller has allocated the body. - // Bodies only have one user so the body is just put into the world if not already there. - public void ReferenceBody(BulletBody body, bool inTaintTime) - { - lock (m_collectionActivityLock) - { - if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,body={1}", body.ID, body); - PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.ReferenceBody", delegate() - { - if (!BulletSimAPI.IsInWorld2(PhysicsScene.World.ptr, body.ptr)) - { - BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, body.ptr); - if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", body.ID, body); - } - }); - } - } - - // Release the usage of a body. - // Called when releasing use of a BSBody. BSShape is handled separately. - public void DereferenceBody(BulletBody body, bool inTaintTime, BodyDestructionCallback bodyCallback ) - { - if (!body.HasPhysicalBody) - return; - - lock (m_collectionActivityLock) - { - PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceBody", delegate() - { - if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1},inTaintTime={2}", - body.ID, body, inTaintTime); - // If the caller needs to know the old body is going away, pass the event up. - if (bodyCallback != null) bodyCallback(body); - - if (BulletSimAPI.IsInWorld2(PhysicsScene.World.ptr, body.ptr)) - { - BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr); - if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,removingFromWorld. Body={1}", body.ID, body); - } - - // Zero any reference to the shape so it is not freed when the body is deleted. - BulletSimAPI.SetCollisionShape2(PhysicsScene.World.ptr, body.ptr, null); - BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, body.ptr); - }); - } - } - - // Track the datastructures and use count for a shape. - // When creating a hull, this is called first to reference the mesh - // and then again to reference the hull. - // Meshes and hulls for the same shape have the same hash key. - // NOTE that native shapes are not added to the mesh list or removed. - // Returns 'true' if this is the initial reference to the shape. Otherwise reused. - public bool ReferenceShape(BulletShape shape) - { - bool ret = false; - switch (shape.type) - { - case BSPhysicsShapeType.SHAPE_MESH: - MeshDesc meshDesc; - if (Meshes.TryGetValue(shape.shapeKey, out meshDesc)) - { - // There is an existing instance of this mesh. - meshDesc.referenceCount++; - if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,existingMesh,key={1},cnt={2}", - BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount); - } - else - { - // This is a new reference to a mesh - meshDesc.ptr = shape.ptr; - meshDesc.shapeKey = shape.shapeKey; - // We keep a reference to the underlying IMesh data so a hull can be built - meshDesc.referenceCount = 1; - if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,newMesh,key={1},cnt={2}", - BSScene.DetailLogZero, shape.shapeKey.ToString("X"), meshDesc.referenceCount); - ret = true; - } - meshDesc.lastReferenced = System.DateTime.Now; - Meshes[shape.shapeKey] = meshDesc; - break; - case BSPhysicsShapeType.SHAPE_HULL: - HullDesc hullDesc; - if (Hulls.TryGetValue(shape.shapeKey, out hullDesc)) - { - // There is an existing instance of this hull. - hullDesc.referenceCount++; - if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,existingHull,key={1},cnt={2}", - BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount); - } - else - { - // This is a new reference to a hull - hullDesc.ptr = shape.ptr; - hullDesc.shapeKey = shape.shapeKey; - hullDesc.referenceCount = 1; - if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceShape,newHull,key={1},cnt={2}", - BSScene.DetailLogZero, shape.shapeKey.ToString("X"), hullDesc.referenceCount); - ret = true; - - } - hullDesc.lastReferenced = System.DateTime.Now; - Hulls[shape.shapeKey] = hullDesc; - break; - case BSPhysicsShapeType.SHAPE_UNKNOWN: - break; - default: - // Native shapes are not tracked and they don't go into any list - break; - } - return ret; - } - - // Release the usage of a shape. - public void DereferenceShape(BulletShape shape, bool inTaintTime, ShapeDestructionCallback shapeCallback) - { - if (!shape.HasPhysicalShape) - return; - - PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceShape", delegate() - { - if (shape.HasPhysicalShape) - { - if (shape.isNativeShape) - { - // Native shapes are not tracked and are released immediately - if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}", - BSScene.DetailLogZero, shape.ptr.ToString(), inTaintTime); - if (shapeCallback != null) shapeCallback(shape); - BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr); - } - else - { - switch (shape.type) - { - case BSPhysicsShapeType.SHAPE_HULL: - DereferenceHull(shape, shapeCallback); - break; - case BSPhysicsShapeType.SHAPE_MESH: - DereferenceMesh(shape, shapeCallback); - break; - case BSPhysicsShapeType.SHAPE_COMPOUND: - DereferenceCompound(shape, shapeCallback); - break; - case BSPhysicsShapeType.SHAPE_UNKNOWN: - break; - default: - break; - } - } - } - }); - } - - // Count down the reference count for a mesh shape - // Called at taint-time. - private void DereferenceMesh(BulletShape shape, ShapeDestructionCallback shapeCallback) - { - MeshDesc meshDesc; - if (Meshes.TryGetValue(shape.shapeKey, out meshDesc)) - { - meshDesc.referenceCount--; - // TODO: release the Bullet storage - if (shapeCallback != null) shapeCallback(shape); - meshDesc.lastReferenced = System.DateTime.Now; - Meshes[shape.shapeKey] = meshDesc; - if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceMesh,shape={1},refCnt={2}", - BSScene.DetailLogZero, shape, meshDesc.referenceCount); - - } - } - - // Count down the reference count for a hull shape - // Called at taint-time. - private void DereferenceHull(BulletShape shape, ShapeDestructionCallback shapeCallback) - { - HullDesc hullDesc; - if (Hulls.TryGetValue(shape.shapeKey, out hullDesc)) - { - hullDesc.referenceCount--; - // TODO: release the Bullet storage (aging old entries?) - - // Tell upper layers that, if they have dependencies on this shape, this link is going away - if (shapeCallback != null) shapeCallback(shape); - - hullDesc.lastReferenced = System.DateTime.Now; - Hulls[shape.shapeKey] = hullDesc; - if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceHull,shape={1},refCnt={2}", - BSScene.DetailLogZero, shape, hullDesc.referenceCount); - } - } - - // Remove a reference to a compound shape. - // Taking a compound shape apart is a little tricky because if you just delete the - // physical shape, it will free all the underlying children. We can't do that because - // they could be shared. So, this removes each of the children from the compound and - // dereferences them separately before destroying the compound collision object itself. - // Called at taint-time. - private void DereferenceCompound(BulletShape shape, ShapeDestructionCallback shapeCallback) - { - if (!BulletSimAPI.IsCompound2(shape.ptr)) - { - // Failed the sanity check!! - PhysicsScene.Logger.ErrorFormat("{0} Attempt to free a compound shape that is not compound!! type={1}, ptr={2}", - LogHeader, shape.type, shape.ptr.ToString()); - if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceCompound,notACompoundShape,type={1},ptr={2}", - BSScene.DetailLogZero, shape.type, shape.ptr.ToString()); - return; - } - - int numChildren = BulletSimAPI.GetNumberOfCompoundChildren2(shape.ptr); - if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceCompound,shape={1},children={2}", BSScene.DetailLogZero, shape, numChildren); - - for (int ii = numChildren - 1; ii >= 0; ii--) - { - Object childShape = BulletSimAPI.RemoveChildShapeFromCompoundShapeIndex2(shape.ptr, ii); - DereferenceAnonCollisionShape(childShape); - } - BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr); - } - - // Sometimes we have a pointer to a collision shape but don't know what type it is. - // Figure out type and call the correct dereference routine. - // Called at taint-time. - private void DereferenceAnonCollisionShape(Object cShape) - { - MeshDesc meshDesc; - HullDesc hullDesc; - - BulletShape shapeInfo = new BulletShape(cShape); - if (TryGetMeshByPtr(cShape, out meshDesc)) - { - shapeInfo.type = BSPhysicsShapeType.SHAPE_MESH; - shapeInfo.shapeKey = meshDesc.shapeKey; - } - else - { - if (TryGetHullByPtr(cShape, out hullDesc)) - { - shapeInfo.type = BSPhysicsShapeType.SHAPE_HULL; - shapeInfo.shapeKey = hullDesc.shapeKey; - } - else - { - if (BulletSimAPI.IsCompound2(cShape)) - { - shapeInfo.type = BSPhysicsShapeType.SHAPE_COMPOUND; - } - else - { - if (BulletSimAPI.IsNativeShape2(cShape)) - { - shapeInfo.isNativeShape = true; - shapeInfo.type = BSPhysicsShapeType.SHAPE_BOX; // (technically, type doesn't matter) - } - } - } - } - - if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceAnonCollisionShape,shape={1}", BSScene.DetailLogZero, shapeInfo); - - if (shapeInfo.type != BSPhysicsShapeType.SHAPE_UNKNOWN) - { - DereferenceShape(shapeInfo, true, null); - } - else - { - PhysicsScene.Logger.ErrorFormat("{0} Could not decypher shape type. Region={1}, addr={2}", - LogHeader, PhysicsScene.RegionName, cShape.ToString()); - } - } - - // Create the geometry information in Bullet for later use. - // The objects needs a hull if it's physical otherwise a mesh is enough. - // if 'forceRebuild' is true, the geometry is unconditionally rebuilt. For meshes and hulls, - // shared geometries will be used. If the parameters of the existing shape are the same - // as this request, the shape is not rebuilt. - // Info in prim.BSShape is updated to the new shape. - // Returns 'true' if the geometry was rebuilt. - // Called at taint-time! - private bool CreateGeom(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback) - { - bool ret = false; - bool haveShape = false; - - if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_CAPSULE) - { - // an avatar capsule is close to a native shape (it is not shared) - GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_CAPSULE, - FixedShapeKey.KEY_CAPSULE, shapeCallback); - if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape); - ret = true; - haveShape = true; - } - - // Compound shapes are handled special as they are rebuilt from scratch. - // This isn't too great a hardship since most of the child shapes will have already been created. - if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND) - { - ret = GetReferenceToCompoundShape(prim, shapeCallback); - if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, prim.PhysShape); - haveShape = true; - } - - if (!haveShape) - { - ret = CreateGeomNonSpecial(forceRebuild, prim, shapeCallback); - } - - return ret; - } - - // Create a mesh/hull shape or a native shape if 'nativeShapePossible' is 'true'. - public bool CreateGeomNonSpecial(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback) - { - bool ret = false; - bool haveShape = false; - bool nativeShapePossible = true; - PrimitiveBaseShape pbs = prim.BaseShape; - - // If the prim attributes are simple, this could be a simple Bullet native shape - if (!haveShape - && pbs != null - && nativeShapePossible - && ((pbs.SculptEntry && !BSParam.ShouldMeshSculptedPrim) - || (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0 - && pbs.ProfileHollow == 0 - && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0 - && pbs.PathBegin == 0 && pbs.PathEnd == 0 - && pbs.PathTaperX == 0 && pbs.PathTaperY == 0 - && pbs.PathScaleX == 100 && pbs.PathScaleY == 100 - && pbs.PathShearX == 0 && pbs.PathShearY == 0) ) ) - { - // Get the scale of any existing shape so we can see if the new shape is same native type and same size. - OMV.Vector3 scaleOfExistingShape = OMV.Vector3.Zero; - if (prim.PhysShape.HasPhysicalShape) - scaleOfExistingShape = BulletSimAPI.GetLocalScaling2(prim.PhysShape.ptr); - - if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,maybeNative,force={1},primScale={2},primSize={3},primShape={4}", - prim.LocalID, forceRebuild, prim.Scale, prim.Size, prim.PhysShape.type); - - // It doesn't look like Bullet scales spheres so make sure the scales are all equal - if ((pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1) - && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z) - { - haveShape = true; - if (forceRebuild - || prim.Scale != scaleOfExistingShape - || prim.PhysShape.type != BSPhysicsShapeType.SHAPE_SPHERE - ) - { - ret = GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_SPHERE, - FixedShapeKey.KEY_SPHERE, shapeCallback); - if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}", - prim.LocalID, forceRebuild, prim.PhysShape); - } - } - if (!haveShape && pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight) - { - haveShape = true; - if (forceRebuild - || prim.Scale != scaleOfExistingShape - || prim.PhysShape.type != BSPhysicsShapeType.SHAPE_BOX - ) - { - ret = GetReferenceToNativeShape( prim, BSPhysicsShapeType.SHAPE_BOX, - FixedShapeKey.KEY_BOX, shapeCallback); - if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}", - prim.LocalID, forceRebuild, prim.PhysShape); - } - } - } - - // If a simple shape is not happening, create a mesh and possibly a hull. - if (!haveShape && pbs != null) - { - ret = CreateGeomMeshOrHull(prim, shapeCallback); - } - - return ret; - } - - public bool CreateGeomMeshOrHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback) - { - - bool ret = false; - // Note that if it's a native shape, the check for physical/non-physical is not - // made. Native shapes work in either case. - if (prim.IsPhysical && BSParam.ShouldUseHullsForPhysicalObjects) - { - // Update prim.BSShape to reference a hull of this shape. - ret = GetReferenceToHull(prim,shapeCallback); - if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", - prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); - } - else - { - ret = GetReferenceToMesh(prim, shapeCallback); - if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}", - prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); - } - return ret; - } - - // Creates a native shape and assignes it to prim.BSShape. - // "Native" shapes are never shared. they are created here and destroyed in DereferenceShape(). - private bool GetReferenceToNativeShape(BSPhysObject prim, - BSPhysicsShapeType shapeType, FixedShapeKey shapeKey, - ShapeDestructionCallback shapeCallback) - { - // release any previous shape - DereferenceShape(prim.PhysShape, true, shapeCallback); - - BulletShape newShape = BuildPhysicalNativeShape(prim, shapeType, shapeKey); - - // Don't need to do a 'ReferenceShape()' here because native shapes are not shared. - if (DDetail) DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1},scale={2}", - prim.LocalID, newShape, prim.Scale); - - // native shapes are scaled by Bullet - prim.PhysShape = newShape; - return true; - } - - private BulletShape BuildPhysicalNativeShape(BSPhysObject prim, BSPhysicsShapeType shapeType, - FixedShapeKey shapeKey) - { - BulletShape newShape; - // Need to make sure the passed shape information is for the native type. - ShapeData nativeShapeData = new ShapeData(); - nativeShapeData.Type = shapeType; - nativeShapeData.ID = prim.LocalID; - nativeShapeData.Scale = prim.Scale; - nativeShapeData.Size = prim.Scale; // unneeded, I think. - nativeShapeData.MeshKey = (ulong)shapeKey; - nativeShapeData.HullKey = (ulong)shapeKey; - - if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE) - { - // The proper scale has been calculated in the prim. - newShape = new BulletShape( - BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale) - , shapeType); - if (DDetail) DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); - } - else - { - // Native shapes are scaled in Bullet so set the scaling to the size - newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, nativeShapeData), shapeType); - } - if (!newShape.HasPhysicalShape) - { - PhysicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}", - LogHeader, prim.LocalID, shapeType); - } - newShape.shapeKey = (System.UInt64)shapeKey; - newShape.isNativeShape = true; - - return newShape; - } - - // Builds a mesh shape in the physical world and updates prim.BSShape. - // Dereferences previous shape in BSShape and adds a reference for this new shape. - // Returns 'true' of a mesh was actually built. Otherwise . - // Called at taint-time! - private bool GetReferenceToMesh(BSPhysObject prim, ShapeDestructionCallback shapeCallback) - { - BulletShape newShape = new BulletShape(); - - float lod; - System.UInt64 newMeshKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod); - - // if this new shape is the same as last time, don't recreate the mesh - if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_MESH) - return false; - - if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToMesh,create,oldKey={1},newKey={2}", - prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X")); - - // Since we're recreating new, get rid of the reference to the previous shape - DereferenceShape(prim.PhysShape, true, shapeCallback); - - newShape = CreatePhysicalMesh(prim.PhysObjectName, newMeshKey, prim.BaseShape, prim.Size, lod); - // Take evasive action if the mesh was not constructed. - newShape = VerifyMeshCreated(newShape, prim); - - ReferenceShape(newShape); - - prim.PhysShape = newShape; - - return true; // 'true' means a new shape has been added to this prim - } - - private BulletShape CreatePhysicalMesh(string objName, System.UInt64 newMeshKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) - { - IMesh meshData = null; - Object meshPtr = null; - MeshDesc meshDesc; - if (Meshes.TryGetValue(newMeshKey, out meshDesc)) - { - // If the mesh has already been built just use it. - meshPtr = meshDesc.ptr; - } - else - { - meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false); - - if (meshData != null) - { - int[] indices = meshData.getIndexListAsInt(); - List vertices = meshData.getVertexList(); - - float[] verticesAsFloats = new float[vertices.Count * 3]; - int vi = 0; - foreach (OMV.Vector3 vv in vertices) - { - verticesAsFloats[vi++] = vv.X; - verticesAsFloats[vi++] = vv.Y; - verticesAsFloats[vi++] = vv.Z; - } - - // m_log.DebugFormat("{0}: BSShapeCollection.CreatePhysicalMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}", - // LogHeader, prim.LocalID, newMeshKey, indices.Length, vertices.Count); - - meshPtr = BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, - indices.GetLength(0), indices, vertices.Count, verticesAsFloats); - } - } - BulletShape newShape = new BulletShape(meshPtr, BSPhysicsShapeType.SHAPE_MESH); - newShape.shapeKey = newMeshKey; - - return newShape; - } - - // See that hull shape exists in the physical world and update prim.BSShape. - // We could be creating the hull because scale changed or whatever. - private bool GetReferenceToHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback) - { - BulletShape newShape; - - float lod; - System.UInt64 newHullKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod); - - // if the hull hasn't changed, don't rebuild it - if (newHullKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_HULL) - return false; - - if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToHull,create,oldKey={1},newKey={2}", - prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newHullKey.ToString("X")); - - // Remove usage of the previous shape. - DereferenceShape(prim.PhysShape, true, shapeCallback); - - newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, prim.BaseShape, prim.Size, lod); - newShape = VerifyMeshCreated(newShape, prim); - - ReferenceShape(newShape); - - prim.PhysShape = newShape; - return true; // 'true' means a new shape has been added to this prim - } - - List m_hulls; - private BulletShape CreatePhysicalHull(string objName, System.UInt64 newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) - { - - Object hullPtr = null; - HullDesc hullDesc; - if (Hulls.TryGetValue(newHullKey, out hullDesc)) - { - // If the hull shape already is created, just use it. - hullPtr = hullDesc.ptr; - } - else - { - // Build a new hull in the physical world - // Pass true for physicalness as this creates some sort of bounding box which we don't need - IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false); - if (meshData != null) - { - - int[] indices = meshData.getIndexListAsInt(); - List vertices = meshData.getVertexList(); - - //format conversion from IMesh format to DecompDesc format - List convIndices = new List(); - List convVertices = new List(); - for (int ii = 0; ii < indices.GetLength(0); ii++) - { - convIndices.Add(indices[ii]); - } - foreach (OMV.Vector3 vv in vertices) - { - convVertices.Add(new float3(vv.X, vv.Y, vv.Z)); - } - - // setup and do convex hull conversion - m_hulls = new List(); - DecompDesc dcomp = new DecompDesc(); - dcomp.mIndices = convIndices; - dcomp.mVertices = convVertices; - ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn); - // create the hull into the _hulls variable - convexBuilder.process(dcomp); - - // Convert the vertices and indices for passing to unmanaged. - // The hull information is passed as a large floating point array. - // The format is: - // convHulls[0] = number of hulls - // convHulls[1] = number of vertices in first hull - // convHulls[2] = hull centroid X coordinate - // convHulls[3] = hull centroid Y coordinate - // convHulls[4] = hull centroid Z coordinate - // convHulls[5] = first hull vertex X - // convHulls[6] = first hull vertex Y - // convHulls[7] = first hull vertex Z - // convHulls[8] = second hull vertex X - // ... - // convHulls[n] = number of vertices in second hull - // convHulls[n+1] = second hull centroid X coordinate - // ... - // - // TODO: is is very inefficient. Someday change the convex hull generator to return - // data structures that do not need to be converted in order to pass to Bullet. - // And maybe put the values directly into pinned memory rather than marshaling. - int hullCount = m_hulls.Count; - int totalVertices = 1; // include one for the count of the hulls - foreach (ConvexResult cr in m_hulls) - { - totalVertices += 4; // add four for the vertex count and centroid - totalVertices += cr.HullIndices.Count * 3; // we pass just triangles - } - float[] convHulls = new float[totalVertices]; - - convHulls[0] = (float)hullCount; - int jj = 1; - foreach (ConvexResult cr in m_hulls) - { - // copy vertices for index access - float3[] verts = new float3[cr.HullVertices.Count]; - int kk = 0; - foreach (float3 ff in cr.HullVertices) - { - verts[kk++] = ff; - } - - // add to the array one hull's worth of data - convHulls[jj++] = cr.HullIndices.Count; - convHulls[jj++] = 0f; // centroid x,y,z - convHulls[jj++] = 0f; - convHulls[jj++] = 0f; - foreach (int ind in cr.HullIndices) - { - convHulls[jj++] = verts[ind].x; - convHulls[jj++] = verts[ind].y; - convHulls[jj++] = verts[ind].z; - } - } - // create the hull data structure in Bullet - hullPtr = BulletSimAPI.CreateHullShape2(PhysicsScene.World.ptr, hullCount, convHulls); - } - } - - BulletShape newShape = new BulletShape(hullPtr, BSPhysicsShapeType.SHAPE_HULL); - newShape.shapeKey = newHullKey; - - return newShape; - } - - // Callback from convex hull creater with a newly created hull. - // Just add it to our collection of hulls for this shape. - private void HullReturn(ConvexResult result) - { - m_hulls.Add(result); - return; - } - - // Compound shapes are always built from scratch. - // This shouldn't be to bad since most of the parts will be meshes that had been built previously. - private bool GetReferenceToCompoundShape(BSPhysObject prim, ShapeDestructionCallback shapeCallback) - { - // Remove reference to the old shape - // Don't need to do this as the shape is freed when the new root shape is created below. - // DereferenceShape(prim.PhysShape, true, shapeCallback); - - BulletShape cShape = new BulletShape( - BulletSimAPI.CreateCompoundShape2(PhysicsScene.World.ptr, false), BSPhysicsShapeType.SHAPE_COMPOUND); - - // Create the shape for the root prim and add it to the compound shape. Cannot be a native shape. - CreateGeomMeshOrHull(prim, shapeCallback); - BulletSimAPI.AddChildShapeToCompoundShape2(cShape.ptr, prim.PhysShape.ptr, OMV.Vector3.Zero, OMV.Quaternion.Identity); - if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToCompoundShape,addRootPrim,compShape={1},rootShape={2}", - prim.LocalID, cShape, prim.PhysShape); - - prim.PhysShape = cShape; - - return true; - } - - // Create a hash of all the shape parameters to be used as a key - // for this particular shape. - private System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs, out float retLod) - { - // level of detail based on size and type of the object - float lod = BSParam.MeshLOD; - if (pbs.SculptEntry) - lod = BSParam.SculptLOD; - - // Mega prims usually get more detail because one can interact with shape approximations at this size. - float maxAxis = Math.Max(size.X, Math.Max(size.Y, size.Z)); - if (maxAxis > BSParam.MeshMegaPrimThreshold) - lod = BSParam.MeshMegaPrimLOD; - - retLod = lod; - return pbs.GetMeshKey(size, lod); - } - // For those who don't want the LOD - private System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs) - { - float lod; - return ComputeShapeKey(size, pbs, out lod); - } - - // The creation of a mesh or hull can fail if an underlying asset is not available. - // There are two cases: 1) the asset is not in the cache and it needs to be fetched; - // and 2) the asset cannot be converted (like failed decompression of JPEG2000s). - // The first case causes the asset to be fetched. The second case requires - // us to not loop forever. - // Called after creating a physical mesh or hull. If the physical shape was created, - // just return. - private BulletShape VerifyMeshCreated(BulletShape newShape, BSPhysObject prim) - { - // If the shape was successfully created, nothing more to do - if (newShape.HasPhysicalShape) - return newShape; - - // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset - if (prim.BaseShape.SculptEntry && !prim.LastAssetBuildFailed && prim.BaseShape.SculptTexture != OMV.UUID.Zero) - { - prim.LastAssetBuildFailed = true; - BSPhysObject xprim = prim; - DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset,lID={1},lastFailed={2}", - LogHeader, prim.LocalID, prim.LastAssetBuildFailed); - Util.FireAndForget(delegate - { - RequestAssetDelegate assetProvider = PhysicsScene.RequestAssetMethod; - if (assetProvider != null) - { - BSPhysObject yprim = xprim; // probably not necessary, but, just in case. - assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset) - { - if (!yprim.BaseShape.SculptEntry) - return; - if (yprim.BaseShape.SculptTexture.ToString() != asset.ID) - return; - - yprim.BaseShape.SculptData = asset.Data; - // This will cause the prim to see that the filler shape is not the right - // one and try again to build the object. - // No race condition with the normal shape setting since the rebuild is at taint time. - yprim.ForceBodyShapeRebuild(false); - - }); - } - }); - } - else - { - if (prim.LastAssetBuildFailed) - { - PhysicsScene.Logger.ErrorFormat("{0} Mesh failed to fetch asset. lID={1}, texture={2}", - LogHeader, prim.LocalID, prim.BaseShape.SculptTexture); - } - } - - // While we figure out the real problem, stick a simple native shape on the object. - BulletShape fillinShape = - BuildPhysicalNativeShape(prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX); - - return fillinShape; - } - - // Create a body object in Bullet. - // Updates prim.BSBody with the information about the new body if one is created. - // Returns 'true' if an object was actually created. - // Called at taint-time. - private bool CreateBody(bool forceRebuild, BSPhysObject prim, BulletWorld sim, BulletShape shape, - BodyDestructionCallback bodyCallback) - { - bool ret = false; - - // the mesh, hull or native shape must have already been created in Bullet - bool mustRebuild = !prim.PhysBody.HasPhysicalBody; - - // If there is an existing body, verify it's of an acceptable type. - // If not a solid object, body is a GhostObject. Otherwise a RigidBody. - if (!mustRebuild) - { - CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(prim.PhysBody.ptr); - if (prim.IsSolid && bodyType != CollisionObjectTypes.CO_RIGID_BODY - || !prim.IsSolid && bodyType != CollisionObjectTypes.CO_GHOST_OBJECT) - { - // If the collisionObject is not the correct type for solidness, rebuild what's there - mustRebuild = true; - } - } - - if (mustRebuild || forceRebuild) - { - // Free any old body - DereferenceBody(prim.PhysBody, true, bodyCallback); - - BulletBody aBody; - Object bodyPtr = null; - if (prim.IsSolid) - { - bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr, - prim.LocalID, prim.RawPosition, prim.RawOrientation); - if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString()); - } - else - { - bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr, - prim.LocalID, prim.RawPosition, prim.RawOrientation); - if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString()); - } - aBody = new BulletBody(prim.LocalID, bodyPtr); - - ReferenceBody(aBody, true); - - prim.PhysBody = aBody; - - ret = true; - } - - return ret; - } - - private bool TryGetMeshByPtr(Object addr, out MeshDesc outDesc) - { - bool ret = false; - MeshDesc foundDesc = new MeshDesc(); - foreach (MeshDesc md in Meshes.Values) - { - if (md.ptr == addr) - { - foundDesc = md; - ret = true; - break; - } - - } - outDesc = foundDesc; - return ret; - } - - private bool TryGetHullByPtr(Object addr, out HullDesc outDesc) - { - bool ret = false; - HullDesc foundDesc = new HullDesc(); - foreach (HullDesc hd in Hulls.Values) - { - if (hd.ptr == addr) - { - foundDesc = hd; - ret = true; - break; - } - - } - outDesc = foundDesc; - return ret; - } - - private void DetailLog(string msg, params Object[] args) - { - if (PhysicsScene.PhysicsLogging.Enabled) - PhysicsScene.DetailLog(msg, args); - } -} -} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSShapes.cs deleted file mode 100644 index 8ff0275..0000000 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSShapes.cs +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace OpenSim.Region.Physics.BulletSNPlugin -{ -public abstract class BSShape -{ - public Object ptr { get; set; } - public BSPhysicsShapeType type { get; set; } - public System.UInt64 key { get; set; } - public int referenceCount { get; set; } - public DateTime lastReferenced { get; set; } - - public BSShape() - { - ptr = null; - type = BSPhysicsShapeType.SHAPE_UNKNOWN; - key = 0; - referenceCount = 0; - lastReferenced = DateTime.Now; - } - - // Get a reference to a physical shape. Create if it doesn't exist - public static BSShape GetShapeReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) - { - BSShape ret = null; - - if (prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_CAPSULE) - { - // an avatar capsule is close to a native shape (it is not shared) - ret = BSShapeNative.GetReference(physicsScene, prim, BSPhysicsShapeType.SHAPE_CAPSULE, - FixedShapeKey.KEY_CAPSULE); - physicsScene.DetailLog("{0},BSShape.GetShapeReference,avatarCapsule,shape={1}", prim.LocalID, ret); - } - - // Compound shapes are handled special as they are rebuilt from scratch. - // This isn't too great a hardship since most of the child shapes will already been created. - if (ret == null && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND) - { - // Getting a reference to a compound shape gets you the compound shape with the root prim shape added - ret = BSShapeCompound.GetReference(prim); - physicsScene.DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, ret); - } - - if (ret == null) - ret = GetShapeReferenceNonSpecial(physicsScene, forceRebuild, prim); - - return ret; - } - public static BSShape GetShapeReferenceNonSpecial(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) - { - return null; - } - public static BSShape GetShapeReferenceNonNative(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) - { - return null; - } - - // Release the use of a physical shape. - public abstract void Dereference(BSScene physicsScene); - - // All shapes have a static call to get a reference to the physical shape - // protected abstract static BSShape GetReference(); - - public override string ToString() - { - StringBuilder buff = new StringBuilder(); - buff.Append(""); - return buff.ToString(); - } -} - -public class BSShapeNull : BSShape -{ - public BSShapeNull() : base() - { - } - public static BSShape GetReference() { return new BSShapeNull(); } - public override void Dereference(BSScene physicsScene) { /* The magic of garbage collection will make this go away */ } -} - -public class BSShapeNative : BSShape -{ - private static string LogHeader = "[BULLETSIM SHAPE NATIVE]"; - public BSShapeNative() : base() - { - } - public static BSShape GetReference(BSScene physicsScene, BSPhysObject prim, - BSPhysicsShapeType shapeType, FixedShapeKey shapeKey) - { - // Native shapes are not shared and are always built anew. - return new BSShapeNative(physicsScene, prim, shapeType, shapeKey); - } - - private BSShapeNative(BSScene physicsScene, BSPhysObject prim, - BSPhysicsShapeType shapeType, FixedShapeKey shapeKey) - { - ShapeData nativeShapeData = new ShapeData(); - nativeShapeData.Type = shapeType; - nativeShapeData.ID = prim.LocalID; - nativeShapeData.Scale = prim.Scale; - nativeShapeData.Size = prim.Scale; - nativeShapeData.MeshKey = (ulong)shapeKey; - nativeShapeData.HullKey = (ulong)shapeKey; - - - if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE) - { - ptr = BulletSimAPI.BuildCapsuleShape2(physicsScene.World.ptr, 1f, 1f, prim.Scale); - physicsScene.DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); - } - else - { - ptr = BulletSimAPI.BuildNativeShape2(physicsScene.World.ptr, nativeShapeData); - } - if (ptr == null) - { - physicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}", - LogHeader, prim.LocalID, shapeType); - } - type = shapeType; - key = (UInt64)shapeKey; - } - // Make this reference to the physical shape go away since native shapes are not shared. - public override void Dereference(BSScene physicsScene) - { - // Native shapes are not tracked and are released immediately - physicsScene.DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,shape={1}", BSScene.DetailLogZero, this); - BulletSimAPI.DeleteCollisionShape2(physicsScene.World.ptr, ptr); - ptr = null; - // Garbage collection will free up this instance. - } -} - -public class BSShapeMesh : BSShape -{ - private static string LogHeader = "[BULLETSIM SHAPE MESH]"; - private static Dictionary Meshes = new Dictionary(); - - public BSShapeMesh() : base() - { - } - public static BSShape GetReference() { return new BSShapeNull(); } - public override void Dereference(BSScene physicsScene) { } -} - -public class BSShapeHull : BSShape -{ - private static string LogHeader = "[BULLETSIM SHAPE HULL]"; - private static Dictionary Hulls = new Dictionary(); - - public BSShapeHull() : base() - { - } - public static BSShape GetReference() { return new BSShapeNull(); } - public override void Dereference(BSScene physicsScene) { } -} - -public class BSShapeCompound : BSShape -{ - private static string LogHeader = "[BULLETSIM SHAPE COMPOUND]"; - public BSShapeCompound() : base() - { - } - public static BSShape GetReference(BSPhysObject prim) - { - return new BSShapeNull(); - } - public override void Dereference(BSScene physicsScene) { } -} -} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainHeightmap.cs deleted file mode 100644 index ba17059..0000000 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainHeightmap.cs +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Text; - -using OpenSim.Framework; -using OpenSim.Region.Framework; -using OpenSim.Region.CoreModules; -using OpenSim.Region.Physics.Manager; - -using Nini.Config; -using log4net; - -using OpenMetaverse; - -namespace OpenSim.Region.Physics.BulletSNPlugin -{ -public sealed class BSTerrainHeightmap : BSTerrainPhys -{ - static string LogHeader = "[BULLETSIM TERRAIN HEIGHTMAP]"; - - BulletHeightMapInfo m_mapInfo = null; - - // Constructor to build a default, flat heightmap terrain. - public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize) - : base(physicsScene, regionBase, id) - { - Vector3 minTerrainCoords = new Vector3(0f, 0f, BSTerrainManager.HEIGHT_INITIALIZATION - BSTerrainManager.HEIGHT_EQUAL_FUDGE); - Vector3 maxTerrainCoords = new Vector3(regionSize.X, regionSize.Y, BSTerrainManager.HEIGHT_INITIALIZATION); - int totalHeights = (int)maxTerrainCoords.X * (int)maxTerrainCoords.Y; - float[] initialMap = new float[totalHeights]; - for (int ii = 0; ii < totalHeights; ii++) - { - initialMap[ii] = BSTerrainManager.HEIGHT_INITIALIZATION; - } - m_mapInfo = new BulletHeightMapInfo(id, initialMap, null); - m_mapInfo.minCoords = minTerrainCoords; - m_mapInfo.maxCoords = maxTerrainCoords; - m_mapInfo.terrainRegionBase = TerrainBase; - // Don't have to free any previous since we just got here. - BuildHeightmapTerrain(); - } - - // This minCoords and maxCoords passed in give the size of the terrain (min and max Z - // are the high and low points of the heightmap). - public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap, - Vector3 minCoords, Vector3 maxCoords) - : base(physicsScene, regionBase, id) - { - m_mapInfo = new BulletHeightMapInfo(id, initialMap, null); - m_mapInfo.minCoords = minCoords; - m_mapInfo.maxCoords = maxCoords; - m_mapInfo.minZ = minCoords.Z; - m_mapInfo.maxZ = maxCoords.Z; - m_mapInfo.terrainRegionBase = TerrainBase; - - // Don't have to free any previous since we just got here. - BuildHeightmapTerrain(); - } - - public override void Dispose() - { - ReleaseHeightMapTerrain(); - } - - // Using the information in m_mapInfo, create the physical representation of the heightmap. - private void BuildHeightmapTerrain() - { - m_mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, m_mapInfo.ID, - m_mapInfo.minCoords, m_mapInfo.maxCoords, - m_mapInfo.heightMap, BSParam.TerrainCollisionMargin); - - // Create the terrain shape from the mapInfo - m_mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(m_mapInfo.Ptr), - BSPhysicsShapeType.SHAPE_TERRAIN); - - // The terrain object initial position is at the center of the object - Vector3 centerPos; - centerPos.X = m_mapInfo.minCoords.X + (m_mapInfo.sizeX / 2f); - centerPos.Y = m_mapInfo.minCoords.Y + (m_mapInfo.sizeY / 2f); - centerPos.Z = m_mapInfo.minZ + ((m_mapInfo.maxZ - m_mapInfo.minZ) / 2f - 0.5f); - - m_mapInfo.terrainBody = new BulletBody(m_mapInfo.ID, - BulletSimAPI.CreateBodyWithDefaultMotionState2(m_mapInfo.terrainShape.ptr, - m_mapInfo.ID, centerPos, Quaternion.Identity)); - - // Set current terrain attributes - BulletSimAPI.SetFriction2(m_mapInfo.terrainBody.ptr, BSParam.TerrainFriction); - BulletSimAPI.SetHitFraction2(m_mapInfo.terrainBody.ptr, BSParam.TerrainHitFraction); - BulletSimAPI.SetRestitution2(m_mapInfo.terrainBody.ptr, BSParam.TerrainRestitution); - BulletSimAPI.SetCollisionFlags2(m_mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); - - // Return the new terrain to the world of physical objects - BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr, centerPos, Quaternion.Identity); - - // redo its bounding box now that it is in the world - BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); - - m_mapInfo.terrainBody.collisionType = CollisionType.Terrain; - m_mapInfo.terrainBody.ApplyCollisionMask(); - - // Make it so the terrain will not move or be considered for movement. - BulletSimAPI.ForceActivationState2(m_mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION); - - return; - } - - // If there is information in m_mapInfo pointing to physical structures, release same. - private void ReleaseHeightMapTerrain() - { - if (m_mapInfo != null) - { - if (m_mapInfo.terrainBody.HasPhysicalBody) - { - BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); - // Frees both the body and the shape. - BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); - BulletSimAPI.ReleaseHeightMapInfo2(m_mapInfo.Ptr); - } - } - m_mapInfo = null; - } - - // The passed position is relative to the base of the region. - public override float GetTerrainHeightAtXYZ(Vector3 pos) - { - float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; - - int mapIndex = (int)pos.Y * (int)m_mapInfo.sizeY + (int)pos.X; - try - { - ret = m_mapInfo.heightMap[mapIndex]; - } - catch - { - // Sometimes they give us wonky values of X and Y. Give a warning and return something. - PhysicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, pos={2}", - LogHeader, m_mapInfo.terrainRegionBase, pos); - ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; - } - return ret; - } - - // The passed position is relative to the base of the region. - public override float GetWaterLevelAtXYZ(Vector3 pos) - { - return PhysicsScene.SimpleWaterLevel; - } -} -} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainManager.cs deleted file mode 100644 index 66d62f0..0000000 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainManager.cs +++ /dev/null @@ -1,461 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Text; - -using OpenSim.Framework; -using OpenSim.Region.Framework; -using OpenSim.Region.CoreModules; -using OpenSim.Region.Physics.Manager; - -using Nini.Config; -using log4net; - -using OpenMetaverse; - -namespace OpenSim.Region.Physics.BulletSNPlugin -{ - -// The physical implementation of the terrain is wrapped in this class. -public abstract class BSTerrainPhys : IDisposable -{ - public enum TerrainImplementation - { - Heightmap = 0, - Mesh = 1 - } - - public BSScene PhysicsScene { get; private set; } - // Base of the region in world coordinates. Coordinates inside the region are relative to this. - public Vector3 TerrainBase { get; private set; } - public uint ID { get; private set; } - - public BSTerrainPhys(BSScene physicsScene, Vector3 regionBase, uint id) - { - PhysicsScene = physicsScene; - TerrainBase = regionBase; - ID = id; - } - public abstract void Dispose(); - public abstract float GetTerrainHeightAtXYZ(Vector3 pos); - public abstract float GetWaterLevelAtXYZ(Vector3 pos); -} - -// ========================================================================================== -public sealed class BSTerrainManager : IDisposable -{ - static string LogHeader = "[BULLETSIM TERRAIN MANAGER]"; - - // These height values are fractional so the odd values will be - // noticable when debugging. - public const float HEIGHT_INITIALIZATION = 24.987f; - public const float HEIGHT_INITIAL_LASTHEIGHT = 24.876f; - public const float HEIGHT_GETHEIGHT_RET = 24.765f; - public const float WATER_HEIGHT_GETHEIGHT_RET = 19.998f; - - // If the min and max height are equal, we reduce the min by this - // amount to make sure that a bounding box is built for the terrain. - public const float HEIGHT_EQUAL_FUDGE = 0.2f; - - // Until the whole simulator is changed to pass us the region size, we rely on constants. - public Vector3 DefaultRegionSize = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); - - // The scene that I am part of - private BSScene PhysicsScene { get; set; } - - // The ground plane created to keep thing from falling to infinity. - private BulletBody m_groundPlane; - - // If doing mega-regions, if we're region zero we will be managing multiple - // region terrains since region zero does the physics for the whole mega-region. - private Dictionary m_terrains; - - // Flags used to know when to recalculate the height. - private bool m_terrainModified = false; - - // If we are doing mega-regions, terrains are added from TERRAIN_ID to m_terrainCount. - // This is incremented before assigning to new region so it is the last ID allocated. - private uint m_terrainCount = BSScene.CHILDTERRAIN_ID - 1; - public uint HighestTerrainID { get {return m_terrainCount; } } - - // If doing mega-regions, this holds our offset from region zero of - // the mega-regions. "parentScene" points to the PhysicsScene of region zero. - private Vector3 m_worldOffset; - // If the parent region (region 0), this is the extent of the combined regions - // relative to the origin of region zero - private Vector3 m_worldMax; - private PhysicsScene MegaRegionParentPhysicsScene { get; set; } - - public BSTerrainManager(BSScene physicsScene) - { - PhysicsScene = physicsScene; - m_terrains = new Dictionary(); - - // Assume one region of default size - m_worldOffset = Vector3.Zero; - m_worldMax = new Vector3(DefaultRegionSize); - MegaRegionParentPhysicsScene = null; - } - - public void Dispose() - { - ReleaseGroundPlaneAndTerrain(); - } - - // Create the initial instance of terrain and the underlying ground plane. - // This is called from the initialization routine so we presume it is - // safe to call Bullet in real time. We hope no one is moving prims around yet. - public void CreateInitialGroundPlaneAndTerrain() - { - // The ground plane is here to catch things that are trying to drop to negative infinity - BulletShape groundPlaneShape = new BulletShape( - BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, - BSParam.TerrainCollisionMargin), - BSPhysicsShapeType.SHAPE_GROUNDPLANE); - m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID, - BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID, - Vector3.Zero, Quaternion.Identity)); - BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr, Vector3.Zero, Quaternion.Identity); - BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_groundPlane.ptr); - // Ground plane does not move - BulletSimAPI.ForceActivationState2(m_groundPlane.ptr, ActivationState.DISABLE_SIMULATION); - // Everything collides with the ground plane. - m_groundPlane.collisionType = CollisionType.Groundplane; - m_groundPlane.ApplyCollisionMask(); - - // Build an initial terrain and put it in the world. This quickly gets replaced by the real region terrain. - BSTerrainPhys initialTerrain = new BSTerrainHeightmap(PhysicsScene, Vector3.Zero, BSScene.TERRAIN_ID, DefaultRegionSize); - m_terrains.Add(Vector3.Zero, initialTerrain); - } - - // Release all the terrain structures we might have allocated - public void ReleaseGroundPlaneAndTerrain() - { - if (m_groundPlane.HasPhysicalBody) - { - if (BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr)) - { - BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_groundPlane.ptr); - } - m_groundPlane.Clear(); - } - - ReleaseTerrain(); - } - - // Release all the terrain we have allocated - public void ReleaseTerrain() - { - lock (m_terrains) - { - foreach (KeyValuePair kvp in m_terrains) - { - kvp.Value.Dispose(); - } - m_terrains.Clear(); - } - } - - // The simulator wants to set a new heightmap for the terrain. - public void SetTerrain(float[] heightMap) { - float[] localHeightMap = heightMap; - // If there are multiple requests for changes to the same terrain between ticks, - // only do that last one. - PhysicsScene.PostTaintObject("TerrainManager.SetTerrain-"+ m_worldOffset.ToString(), 0, delegate() - { - if (m_worldOffset != Vector3.Zero && MegaRegionParentPhysicsScene != null) - { - // If a child of a mega-region, we shouldn't have any terrain allocated for us - ReleaseGroundPlaneAndTerrain(); - // If doing the mega-prim stuff and we are the child of the zero region, - // the terrain is added to our parent - if (MegaRegionParentPhysicsScene is BSScene) - { - DetailLog("{0},SetTerrain.ToParent,offset={1},worldMax={2}", - BSScene.DetailLogZero, m_worldOffset, m_worldMax); - ((BSScene)MegaRegionParentPhysicsScene).TerrainManager.UpdateTerrain( - BSScene.CHILDTERRAIN_ID, localHeightMap, - m_worldOffset, m_worldOffset + DefaultRegionSize, true); - } - } - else - { - // If not doing the mega-prim thing, just change the terrain - DetailLog("{0},SetTerrain.Existing", BSScene.DetailLogZero); - - UpdateTerrain(BSScene.TERRAIN_ID, localHeightMap, - m_worldOffset, m_worldOffset + DefaultRegionSize, true); - } - }); - } - - // If called with no mapInfo for the terrain, this will create a new mapInfo and terrain - // based on the passed information. The 'id' should be either the terrain id or - // BSScene.CHILDTERRAIN_ID. If the latter, a new child terrain ID will be allocated and used. - // The latter feature is for creating child terrains for mega-regions. - // If called with a mapInfo in m_heightMaps and there is an existing terrain body, a new - // terrain shape is created and added to the body. - // This call is most often used to update the heightMap and parameters of the terrain. - // (The above does suggest that some simplification/refactoring is in order.) - // Called during taint-time. - private void UpdateTerrain(uint id, float[] heightMap, - Vector3 minCoords, Vector3 maxCoords, bool inTaintTime) - { - DetailLog("{0},BSTerrainManager.UpdateTerrain,call,minC={1},maxC={2},inTaintTime={3}", - BSScene.DetailLogZero, minCoords, maxCoords, inTaintTime); - - // Find high and low points of passed heightmap. - // The min and max passed in is usually the area objects can be in (maximum - // object height, for instance). The terrain wants the bounding box for the - // terrain so replace passed min and max Z with the actual terrain min/max Z. - float minZ = float.MaxValue; - float maxZ = float.MinValue; - foreach (float height in heightMap) - { - if (height < minZ) minZ = height; - if (height > maxZ) maxZ = height; - } - if (minZ == maxZ) - { - // If min and max are the same, reduce min a little bit so a good bounding box is created. - minZ -= BSTerrainManager.HEIGHT_EQUAL_FUDGE; - } - minCoords.Z = minZ; - maxCoords.Z = maxZ; - - Vector3 terrainRegionBase = new Vector3(minCoords.X, minCoords.Y, 0f); - - lock (m_terrains) - { - BSTerrainPhys terrainPhys; - if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys)) - { - // There is already a terrain in this spot. Free the old and build the new. - DetailLog("{0},UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}", - BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords); - - // Remove old terrain from the collection - m_terrains.Remove(terrainRegionBase); - // Release any physical memory it may be using. - terrainPhys.Dispose(); - - if (MegaRegionParentPhysicsScene == null) - { - BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords); - m_terrains.Add(terrainRegionBase, newTerrainPhys); - - m_terrainModified = true; - } - else - { - // It's possible that Combine() was called after this code was queued. - // If we are a child of combined regions, we don't create any terrain for us. - DetailLog("{0},BSTerrainManager.UpdateTerrain:AmACombineChild,taint", BSScene.DetailLogZero); - - // Get rid of any terrain that may have been allocated for us. - ReleaseGroundPlaneAndTerrain(); - - // I hate doing this, but just bail - return; - } - } - else - { - // We don't know about this terrain so either we are creating a new terrain or - // our mega-prim child is giving us a new terrain to add to the phys world - - // if this is a child terrain, calculate a unique terrain id - uint newTerrainID = id; - if (newTerrainID >= BSScene.CHILDTERRAIN_ID) - newTerrainID = ++m_terrainCount; - - DetailLog("{0},UpdateTerrain:NewTerrain,taint,newID={1},minCoord={2},maxCoord={3}", - BSScene.DetailLogZero, newTerrainID, minCoords, minCoords); - BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords); - m_terrains.Add(terrainRegionBase, newTerrainPhys); - - m_terrainModified = true; - } - } - } - - // TODO: redo terrain implementation selection to allow other base types than heightMap. - private BSTerrainPhys BuildPhysicalTerrain(Vector3 terrainRegionBase, uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords) - { - PhysicsScene.Logger.DebugFormat("{0} Terrain for {1}/{2} created with {3}", - LogHeader, PhysicsScene.RegionName, terrainRegionBase, - (BSTerrainPhys.TerrainImplementation)BSParam.TerrainImplementation); - BSTerrainPhys newTerrainPhys = null; - switch ((int)BSParam.TerrainImplementation) - { - case (int)BSTerrainPhys.TerrainImplementation.Heightmap: - newTerrainPhys = new BSTerrainHeightmap(PhysicsScene, terrainRegionBase, id, - heightMap, minCoords, maxCoords); - break; - case (int)BSTerrainPhys.TerrainImplementation.Mesh: - newTerrainPhys = new BSTerrainMesh(PhysicsScene, terrainRegionBase, id, - heightMap, minCoords, maxCoords); - break; - default: - PhysicsScene.Logger.ErrorFormat("{0} Bad terrain implementation specified. Type={1}/{2},Region={3}/{4}", - LogHeader, - (int)BSParam.TerrainImplementation, - BSParam.TerrainImplementation, - PhysicsScene.RegionName, terrainRegionBase); - break; - } - return newTerrainPhys; - } - - // Return 'true' of this position is somewhere in known physical terrain space - public bool IsWithinKnownTerrain(Vector3 pos) - { - Vector3 terrainBaseXYZ; - BSTerrainPhys physTerrain; - return GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ); - } - - // Given an X and Y, find the height of the terrain. - // Since we could be handling multiple terrains for a mega-region, - // the base of the region is calcuated assuming all regions are - // the same size and that is the default. - // Once the heightMapInfo is found, we have all the information to - // compute the offset into the array. - private float lastHeightTX = 999999f; - private float lastHeightTY = 999999f; - private float lastHeight = HEIGHT_INITIAL_LASTHEIGHT; - public float GetTerrainHeightAtXYZ(Vector3 pos) - { - float tX = pos.X; - float tY = pos.Y; - // You'd be surprized at the number of times this routine is called - // with the same parameters as last time. - if (!m_terrainModified && (lastHeightTX == tX) && (lastHeightTY == tY)) - return lastHeight; - m_terrainModified = false; - - lastHeightTX = tX; - lastHeightTY = tY; - float ret = HEIGHT_GETHEIGHT_RET; - - Vector3 terrainBaseXYZ; - BSTerrainPhys physTerrain; - if (GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ)) - { - ret = physTerrain.GetTerrainHeightAtXYZ(pos - terrainBaseXYZ); - } - else - { - PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}", - LogHeader, PhysicsScene.RegionName, tX, tY); - DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXYZ,terrainNotFound,pos={1},base={2}", - BSScene.DetailLogZero, pos, terrainBaseXYZ); - } - - lastHeight = ret; - return ret; - } - - public float GetWaterLevelAtXYZ(Vector3 pos) - { - float ret = WATER_HEIGHT_GETHEIGHT_RET; - - Vector3 terrainBaseXYZ; - BSTerrainPhys physTerrain; - if (GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ)) - { - ret = physTerrain.GetWaterLevelAtXYZ(pos); - } - else - { - PhysicsScene.Logger.ErrorFormat("{0} GetWaterHeightAtXY: terrain not found: pos={1}, terrainBase={2}, height={3}", - LogHeader, PhysicsScene.RegionName, pos, terrainBaseXYZ, ret); - } - return ret; - } - - // Given an address, return 'true' of there is a description of that terrain and output - // the descriptor class and the 'base' fo the addresses therein. - private bool GetTerrainPhysicalAtXYZ(Vector3 pos, out BSTerrainPhys outPhysTerrain, out Vector3 outTerrainBase) - { - int offsetX = ((int)(pos.X / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X; - int offsetY = ((int)(pos.Y / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y; - Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f); - - BSTerrainPhys physTerrain = null; - lock (m_terrains) - { - m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain); - } - outTerrainBase = terrainBaseXYZ; - outPhysTerrain = physTerrain; - return (physTerrain != null); - } - - // Although no one seems to check this, I do support combining. - public bool SupportsCombining() - { - return true; - } - - // This routine is called two ways: - // One with 'offset' and 'pScene' zero and null but 'extents' giving the maximum - // extent of the combined regions. This is to inform the parent of the size - // of the combined regions. - // and one with 'offset' as the offset of the child region to the base region, - // 'pScene' pointing to the parent and 'extents' of zero. This informs the - // child of its relative base and new parent. - public void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents) - { - m_worldOffset = offset; - m_worldMax = extents; - MegaRegionParentPhysicsScene = pScene; - if (pScene != null) - { - // We are a child. - // We want m_worldMax to be the highest coordinate of our piece of terrain. - m_worldMax = offset + DefaultRegionSize; - } - DetailLog("{0},BSTerrainManager.Combine,offset={1},extents={2},wOffset={3},wMax={4}", - BSScene.DetailLogZero, offset, extents, m_worldOffset, m_worldMax); - } - - // Unhook all the combining that I know about. - public void UnCombine(PhysicsScene pScene) - { - // Just like ODE, we don't do anything yet. - DetailLog("{0},BSTerrainManager.UnCombine", BSScene.DetailLogZero); - } - - - private void DetailLog(string msg, params Object[] args) - { - PhysicsScene.PhysicsLogging.Write(msg, args); - } -} -} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainMesh.cs deleted file mode 100644 index 6083dd4..0000000 --- a/OpenSim/Region/Physics/BulletSNPlugin/BSTerrainMesh.cs +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Text; - -using OpenSim.Framework; -using OpenSim.Region.Framework; -using OpenSim.Region.CoreModules; -using OpenSim.Region.Physics.Manager; - -using Nini.Config; -using log4net; - -using OpenMetaverse; - -namespace OpenSim.Region.Physics.BulletSNPlugin -{ -public sealed class BSTerrainMesh : BSTerrainPhys -{ - static string LogHeader = "[BULLETSIM TERRAIN MESH]"; - - private float[] m_savedHeightMap; - int m_sizeX; - int m_sizeY; - - BulletShape m_terrainShape; - BulletBody m_terrainBody; - - public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize) - : base(physicsScene, regionBase, id) - { - } - - public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id /* parameters for making mesh */) - : base(physicsScene, regionBase, id) - { - } - - // Create terrain mesh from a heightmap. - public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap, - Vector3 minCoords, Vector3 maxCoords) - : base(physicsScene, regionBase, id) - { - int indicesCount; - int[] indices; - int verticesCount; - float[] vertices; - - m_savedHeightMap = initialMap; - - m_sizeX = (int)(maxCoords.X - minCoords.X); - m_sizeY = (int)(maxCoords.Y - minCoords.Y); - - if (!BSTerrainMesh.ConvertHeightmapToMesh(PhysicsScene, initialMap, - m_sizeX, m_sizeY, - (float)m_sizeX, (float)m_sizeY, - Vector3.Zero, 1.0f, - out indicesCount, out indices, out verticesCount, out vertices)) - { - // DISASTER!! - PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedConversionOfHeightmap", ID); - PhysicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh! base={1}", LogHeader, TerrainBase); - // Something is very messed up and a crash is in our future. - return; - } - PhysicsScene.DetailLog("{0},BSTerrainMesh.create,meshed,indices={1},indSz={2},vertices={3},vertSz={4}", - ID, indicesCount, indices.Length, verticesCount, vertices.Length); - - m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, - indicesCount, indices, verticesCount, vertices), - BSPhysicsShapeType.SHAPE_MESH); - if (!m_terrainShape.HasPhysicalShape) - { - // DISASTER!! - PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape", ID); - physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain mesh! base={1}", LogHeader, TerrainBase); - // Something is very messed up and a crash is in our future. - return; - } - - Vector3 pos = regionBase; - Quaternion rot = Quaternion.Identity; - - m_terrainBody = new BulletBody(id, BulletSimAPI.CreateBodyWithDefaultMotionState2( m_terrainShape.ptr, ID, pos, rot)); - if (!m_terrainBody.HasPhysicalBody) - { - // DISASTER!! - physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain body! base={1}", LogHeader, TerrainBase); - // Something is very messed up and a crash is in our future. - return; - } - - // Set current terrain attributes - BulletSimAPI.SetFriction2(m_terrainBody.ptr, BSParam.TerrainFriction); - BulletSimAPI.SetHitFraction2(m_terrainBody.ptr, BSParam.TerrainHitFraction); - BulletSimAPI.SetRestitution2(m_terrainBody.ptr, BSParam.TerrainRestitution); - BulletSimAPI.SetCollisionFlags2(m_terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); - - // Static objects are not very massive. - BulletSimAPI.SetMassProps2(m_terrainBody.ptr, 0f, Vector3.Zero); - - // Put the new terrain to the world of physical objects - BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr, pos, rot); - - // Redo its bounding box now that it is in the world - BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr); - - m_terrainBody.collisionType = CollisionType.Terrain; - m_terrainBody.ApplyCollisionMask(); - - // Make it so the terrain will not move or be considered for movement. - BulletSimAPI.ForceActivationState2(m_terrainBody.ptr, ActivationState.DISABLE_SIMULATION); - } - - public override void Dispose() - { - if (m_terrainBody.HasPhysicalBody) - { - BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr); - // Frees both the body and the shape. - BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_terrainBody.ptr); - } - } - - public override float GetTerrainHeightAtXYZ(Vector3 pos) - { - // For the moment use the saved heightmap to get the terrain height. - // TODO: raycast downward to find the true terrain below the position. - float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; - - int mapIndex = (int)pos.Y * m_sizeY + (int)pos.X; - try - { - ret = m_savedHeightMap[mapIndex]; - } - catch - { - // Sometimes they give us wonky values of X and Y. Give a warning and return something. - PhysicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, pos={2}", - LogHeader, TerrainBase, pos); - ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; - } - return ret; - } - - // The passed position is relative to the base of the region. - public override float GetWaterLevelAtXYZ(Vector3 pos) - { - return PhysicsScene.SimpleWaterLevel; - } - - // Convert the passed heightmap to mesh information suitable for CreateMeshShape2(). - // Return 'true' if successfully created. - public static bool ConvertHeightmapToMesh( - BSScene physicsScene, - float[] heightMap, int sizeX, int sizeY, // parameters of incoming heightmap - float extentX, float extentY, // zero based range for output vertices - Vector3 extentBase, // base to be added to all vertices - float magnification, // number of vertices to create between heightMap coords - out int indicesCountO, out int[] indicesO, - out int verticesCountO, out float[] verticesO) - { - bool ret = false; - - int indicesCount = 0; - int verticesCount = 0; - int[] indices = new int[0]; - float[] vertices = new float[0]; - - // Simple mesh creation which assumes magnification == 1. - // TODO: do a more general solution that scales, adds new vertices and smoothes the result. - - // Create an array of vertices that is sizeX+1 by sizeY+1 (note the loop - // from zero to <= sizeX). The triangle indices are then generated as two triangles - // per heightmap point. There are sizeX by sizeY of these squares. The extra row and - // column of vertices are used to complete the triangles of the last row and column - // of the heightmap. - try - { - // One vertice per heightmap value plus the vertices off the top and bottom edge. - int totalVertices = (sizeX + 1) * (sizeY + 1); - vertices = new float[totalVertices * 3]; - int totalIndices = sizeX * sizeY * 6; - indices = new int[totalIndices]; - - float magX = (float)sizeX / extentX; - float magY = (float)sizeY / extentY; - physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2},extentBase={3},magX={4},magY={5}", - BSScene.DetailLogZero, totalVertices, totalIndices, extentBase, magX, magY); - float minHeight = float.MaxValue; - // Note that sizeX+1 vertices are created since there is land between this and the next region. - for (int yy = 0; yy <= sizeY; yy++) - { - for (int xx = 0; xx <= sizeX; xx++) // Hint: the "<=" means we go around sizeX + 1 times - { - int offset = yy * sizeX + xx; - // Extend the height with the height from the last row or column - if (yy == sizeY) offset -= sizeX; - if (xx == sizeX) offset -= 1; - float height = heightMap[offset]; - minHeight = Math.Min(minHeight, height); - vertices[verticesCount + 0] = (float)xx * magX + extentBase.X; - vertices[verticesCount + 1] = (float)yy * magY + extentBase.Y; - vertices[verticesCount + 2] = height + extentBase.Z; - verticesCount += 3; - } - } - verticesCount = verticesCount / 3; - - for (int yy = 0; yy < sizeY; yy++) - { - for (int xx = 0; xx < sizeX; xx++) - { - int offset = yy * (sizeX + 1) + xx; - // Each vertices is presumed to be the upper left corner of a box of two triangles - indices[indicesCount + 0] = offset; - indices[indicesCount + 1] = offset + 1; - indices[indicesCount + 2] = offset + sizeX + 1; // accounting for the extra column - indices[indicesCount + 3] = offset + 1; - indices[indicesCount + 4] = offset + sizeX + 2; - indices[indicesCount + 5] = offset + sizeX + 1; - indicesCount += 6; - } - } - - ret = true; - } - catch (Exception e) - { - physicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh. For={1}/{2}, e={3}", - LogHeader, physicsScene.RegionName, extentBase, e); - } - - indicesCountO = indicesCount; - indicesO = indices; - verticesCountO = verticesCount; - verticesO = vertices; - - return ret; - } -} -} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSNPlugin/BulletSimAPI.cs deleted file mode 100644 index ba96905..0000000 --- a/OpenSim/Region/Physics/BulletSNPlugin/BulletSimAPI.cs +++ /dev/null @@ -1,1604 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.IO; -using System.Runtime.InteropServices; -using System.Security; -using System.Text; -using BulletXNA; -using OpenMetaverse; -using BulletXNA.LinearMath; -using BulletXNA.BulletCollision; -using BulletXNA.BulletDynamics; -using BulletXNA.BulletCollision.CollisionDispatch; -using OpenSim.Framework; - -namespace OpenSim.Region.Physics.BulletSNPlugin { - -// Classes to allow some type checking for the API -// These hold pointers to allocated objects in the unmanaged space. - - - - // Constraint type values as defined by Bullet -public enum ConstraintType : int -{ - POINT2POINT_CONSTRAINT_TYPE = 3, - HINGE_CONSTRAINT_TYPE, - CONETWIST_CONSTRAINT_TYPE, - D6_CONSTRAINT_TYPE, - SLIDER_CONSTRAINT_TYPE, - CONTACT_CONSTRAINT_TYPE, - D6_SPRING_CONSTRAINT_TYPE, - MAX_CONSTRAINT_TYPE -} - -// =============================================================================== -[StructLayout(LayoutKind.Sequential)] -public struct ConvexHull -{ - Vector3 Offset; - int VertexCount; - Vector3[] Vertices; -} -public enum BSPhysicsShapeType -{ - SHAPE_UNKNOWN = 0, - SHAPE_CAPSULE = 1, - SHAPE_BOX = 2, - SHAPE_CONE = 3, - SHAPE_CYLINDER = 4, - SHAPE_SPHERE = 5, - SHAPE_MESH = 6, - SHAPE_HULL = 7, - // following defined by BulletSim - SHAPE_GROUNDPLANE = 20, - SHAPE_TERRAIN = 21, - SHAPE_COMPOUND = 22, - SHAPE_HEIGHTMAP = 23, -}; - -// The native shapes have predefined shape hash keys -public enum FixedShapeKey : ulong -{ - KEY_NONE = 0, - KEY_BOX = 1, - KEY_SPHERE = 2, - KEY_CONE = 3, - KEY_CYLINDER = 4, - KEY_CAPSULE = 5, -} - -[StructLayout(LayoutKind.Sequential)] -public struct ShapeData -{ - public uint ID; - public BSPhysicsShapeType Type; - public Vector3 Position; - public Quaternion Rotation; - public Vector3 Velocity; - public Vector3 Scale; - public float Mass; - public float Buoyancy; - public System.UInt64 HullKey; - public System.UInt64 MeshKey; - public float Friction; - public float Restitution; - public float Collidable; // true of things bump into this - public float Static; // true if a static object. Otherwise gravity, etc. - public float Solid; // true if object cannot be passed through - public Vector3 Size; - - // note that bools are passed as floats since bool size changes by language and architecture - public const float numericTrue = 1f; - public const float numericFalse = 0f; -} -[StructLayout(LayoutKind.Sequential)] -public struct SweepHit -{ - public uint ID; - public float Fraction; - public Vector3 Normal; - public Vector3 Point; -} -[StructLayout(LayoutKind.Sequential)] -public struct RaycastHit -{ - public uint ID; - public float Fraction; - public Vector3 Normal; -} -[StructLayout(LayoutKind.Sequential)] -public struct CollisionDesc -{ - public uint aID; - public uint bID; - public Vector3 point; - public Vector3 normal; -} -[StructLayout(LayoutKind.Sequential)] -public struct EntityProperties -{ - public uint ID; - public Vector3 Position; - public Quaternion Rotation; - public Vector3 Velocity; - public Vector3 Acceleration; - public Vector3 RotationalVelocity; - public override string ToString() - { - return string.Format("ID:{0}, Pos:<{1:F},{2:F},{3:F}>, Rot:<{4:F},{5:F},{6:F},{7:F}>, LVel:<{8:F},{9:F},{10:F}>, AVel:<{11:F},{12:F},{13:F}>", - ID.ToString(), - Position.X,Position.Y,Position.Z, - Rotation.X,Rotation.Y,Rotation.Z,Rotation.W, - Velocity.X,Velocity.Y,Velocity.Z, - RotationalVelocity.X,RotationalVelocity.Y,RotationalVelocity.Z - ); - } -} - -// Format of this structure must match the definition in the C++ code -// NOTE: adding the X causes compile breaks if used. These are unused symbols -// that can be removed from both here and the unmanaged definition of this structure. -[StructLayout(LayoutKind.Sequential)] -public struct ConfigurationParameters -{ - public float defaultFriction; - public float defaultDensity; - public float defaultRestitution; - public float collisionMargin; - public float gravity; - - public float XlinearDamping; - public float XangularDamping; - public float XdeactivationTime; - public float XlinearSleepingThreshold; - public float XangularSleepingThreshold; - public float XccdMotionThreshold; - public float XccdSweptSphereRadius; - public float XcontactProcessingThreshold; - - public float XterrainImplementation; - public float XterrainFriction; - public float XterrainHitFraction; - public float XterrainRestitution; - public float XterrainCollisionMargin; - - public float XavatarFriction; - public float XavatarStandingFriction; - public float XavatarDensity; - public float XavatarRestitution; - public float XavatarCapsuleWidth; - public float XavatarCapsuleDepth; - public float XavatarCapsuleHeight; - public float XavatarContactProcessingThreshold; - - public float XvehicleAngularDamping; - - public float maxPersistantManifoldPoolSize; - public float maxCollisionAlgorithmPoolSize; - public float shouldDisableContactPoolDynamicAllocation; - public float shouldForceUpdateAllAabbs; - public float shouldRandomizeSolverOrder; - public float shouldSplitSimulationIslands; - public float shouldEnableFrictionCaching; - public float numberOfSolverIterations; - - public float XlinksetImplementation; - public float XlinkConstraintUseFrameOffset; - public float XlinkConstraintEnableTransMotor; - public float XlinkConstraintTransMotorMaxVel; - public float XlinkConstraintTransMotorMaxForce; - public float XlinkConstraintERP; - public float XlinkConstraintCFM; - public float XlinkConstraintSolverIterations; - - public float physicsLoggingFrames; - - public const float numericTrue = 1f; - public const float numericFalse = 0f; -} - - -// The states a bullet collision object can have - -public enum ActivationState : uint -{ - UNDEFINED = 0, - ACTIVE_TAG = 1, - ISLAND_SLEEPING = 2, - WANTS_DEACTIVATION = 3, - DISABLE_DEACTIVATION = 4, - DISABLE_SIMULATION = 5, -} - -public enum CollisionObjectTypes : int -{ - CO_COLLISION_OBJECT = 1 << 0, - CO_RIGID_BODY = 1 << 1, - CO_GHOST_OBJECT = 1 << 2, - CO_SOFT_BODY = 1 << 3, - CO_HF_FLUID = 1 << 4, - CO_USER_TYPE = 1 << 5, -} - -// Values used by Bullet and BulletSim to control object properties. -// Bullet's "CollisionFlags" has more to do with operations on the -// object (if collisions happen, if gravity effects it, ...). - [Flags] -public enum CollisionFlags : uint -{ - CF_STATIC_OBJECT = 1 << 0, - CF_KINEMATIC_OBJECT = 1 << 1, - CF_NO_CONTACT_RESPONSE = 1 << 2, - CF_CUSTOM_MATERIAL_CALLBACK = 1 << 3, - CF_CHARACTER_OBJECT = 1 << 4, - CF_DISABLE_VISUALIZE_OBJECT = 1 << 5, - CF_DISABLE_SPU_COLLISION_PROCESS = 1 << 6, - // Following used by BulletSim to control collisions and updates - BS_SUBSCRIBE_COLLISION_EVENTS = 1 << 10, - BS_FLOATS_ON_WATER = 1 << 11, - BS_VEHICLE_COLLISIONS = 1 << 12, - BS_NONE = 0, - BS_ALL = 0xFFFFFFFF, - - // These are the collision flags switched depending on physical state. - // The other flags are used for other things and should not be fooled with. - BS_ACTIVE = CF_STATIC_OBJECT - | CF_KINEMATIC_OBJECT - | CF_NO_CONTACT_RESPONSE -}; - -// Values for collisions groups and masks -public enum CollisionFilterGroups : uint -{ - // Don't use the bit definitions!! Define the use in a - // filter/mask definition below. This way collision interactions - // are more easily debugged. - BNoneGroup = 0, - BDefaultGroup = 1 << 0, - BStaticGroup = 1 << 1, - BKinematicGroup = 1 << 2, - BDebrisGroup = 1 << 3, - BSensorTrigger = 1 << 4, - BCharacterGroup = 1 << 5, - BAllGroup = 0xFFFFFFFF, - // Filter groups defined by BulletSim - BGroundPlaneGroup = 1 << 10, - BTerrainGroup = 1 << 11, - BRaycastGroup = 1 << 12, - BSolidGroup = 1 << 13, - // BLinksetGroup = xx // a linkset proper is either static or dynamic - BLinksetChildGroup = 1 << 14, - // The collsion filters and masked are defined in one place -- don't want them scattered - AvatarGroup = BCharacterGroup, - AvatarMask = BAllGroup, - ObjectGroup = BSolidGroup, - ObjectMask = BAllGroup, - StaticObjectGroup = BStaticGroup, - StaticObjectMask = AvatarGroup | ObjectGroup, // static things don't interact with much - LinksetGroup = BLinksetChildGroup, - LinksetMask = BAllGroup & ~BLinksetChildGroup, // linkset objects don't collide with each other - VolumeDetectGroup = BSensorTrigger, - VolumeDetectMask = ~BSensorTrigger, - TerrainGroup = BTerrainGroup, - TerrainMask = BAllGroup & ~BStaticGroup, // static objects on the ground don't collide - GroundPlaneGroup = BGroundPlaneGroup, - GroundPlaneMask = BAllGroup - -}; - -// CFM controls the 'hardness' of the constraint. 0=fixed, 0..1=violatable. Default=0 -// ERP controls amount of correction per tick. Usable range=0.1..0.8. Default=0.2. -public enum ConstraintParams : int -{ - BT_CONSTRAINT_ERP = 1, // this one is not used in Bullet as of 20120730 - BT_CONSTRAINT_STOP_ERP, - BT_CONSTRAINT_CFM, - BT_CONSTRAINT_STOP_CFM, -}; -public enum ConstraintParamAxis : int -{ - AXIS_LINEAR_X = 0, - AXIS_LINEAR_Y, - AXIS_LINEAR_Z, - AXIS_ANGULAR_X, - AXIS_ANGULAR_Y, - AXIS_ANGULAR_Z, - AXIS_LINEAR_ALL = 20, // these last three added by BulletSim so we don't have to do zillions of calls - AXIS_ANGULAR_ALL, - AXIS_ALL -}; - -// =============================================================================== -static class BulletSimAPI { - private static int m_collisionsThisFrame; - public delegate void DebugLogCallback(string msg); - /// - /// - /// - /// - /// - internal static bool RemoveObjectFromWorld2(object pWorld, object pBody) - { - DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; - RigidBody body = pBody as RigidBody; - world.RemoveRigidBody(body); - return true; - } - - internal static void SetRestitution2(object pBody, float pRestitution) - { - RigidBody body = pBody as RigidBody; - body.SetRestitution(pRestitution); - } - - internal static void SetMargin2(object pShape, float pMargin) - { - CollisionShape shape = pShape as CollisionShape; - shape.SetMargin(pMargin); - } - - internal static void SetLocalScaling2(object pShape, Vector3 pScale) - { - CollisionShape shape = pShape as CollisionShape; - IndexedVector3 vec = new IndexedVector3(pScale.X, pScale.Y, pScale.Z); - shape.SetLocalScaling(ref vec); - - } - - internal static void SetContactProcessingThreshold2(object pBody, float contactprocessingthreshold) - { - RigidBody body = pBody as RigidBody; - body.SetContactProcessingThreshold(contactprocessingthreshold); - } - - internal static void SetCcdMotionThreshold2(object pBody, float pccdMotionThreashold) - { - RigidBody body = pBody as RigidBody; - body.SetCcdMotionThreshold(pccdMotionThreashold); - } - - internal static void SetCcdSweptSphereRadius2(object pBody, float pCcdSweptSphereRadius) - { - RigidBody body = pBody as RigidBody; - body.SetCcdSweptSphereRadius(pCcdSweptSphereRadius); - } - - internal static void SetAngularFactorV2(object pBody, Vector3 pAngularFactor) - { - RigidBody body = pBody as RigidBody; - body.SetAngularFactor(new IndexedVector3(pAngularFactor.X, pAngularFactor.Y, pAngularFactor.Z)); - } - - internal static CollisionFlags AddToCollisionFlags2(object pBody, CollisionFlags pcollisionFlags) - { - CollisionObject body = pBody as CollisionObject; - CollisionFlags existingcollisionFlags = (CollisionFlags)(uint)body.GetCollisionFlags(); - existingcollisionFlags |= pcollisionFlags; - body.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags)(uint)existingcollisionFlags); - return (CollisionFlags) (uint) existingcollisionFlags; - } - - internal static void AddObjectToWorld2(object pWorld, object pBody) - { - RigidBody body = pBody as RigidBody; - DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; - //if (!(body.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.STATIC_PLANE_PROXYTYPE && body.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.TERRAIN_SHAPE_PROXYTYPE)) - - world.AddRigidBody(body); - - //if (body.GetBroadphaseHandle() != null) - // world.UpdateSingleAabb(body); - } - - internal static void AddObjectToWorld2(object pWorld, object pBody, Vector3 _position, Quaternion _orientation) - { - RigidBody body = pBody as RigidBody; - DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; - //if (!(body.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.STATIC_PLANE_PROXYTYPE && body.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.TERRAIN_SHAPE_PROXYTYPE)) - - world.AddRigidBody(body); - IndexedVector3 vposition = new IndexedVector3(_position.X, _position.Y, _position.Z); - IndexedQuaternion vquaternion = new IndexedQuaternion(_orientation.X, _orientation.Y, _orientation.Z, - _orientation.W); - IndexedMatrix mat = IndexedMatrix.CreateFromQuaternion(vquaternion); - mat._origin = vposition; - body.SetWorldTransform(mat); - //if (body.GetBroadphaseHandle() != null) - // world.UpdateSingleAabb(body); - } - - internal static void ForceActivationState2(object pBody, ActivationState pActivationState) - { - CollisionObject body = pBody as CollisionObject; - body.ForceActivationState((BulletXNA.BulletCollision.ActivationState)(uint)pActivationState); - } - - internal static void UpdateSingleAabb2(object pWorld, object pBody) - { - CollisionObject body = pBody as CollisionObject; - DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; - world.UpdateSingleAabb(body); - } - - internal static bool SetCollisionGroupMask2(object pBody, uint pGroup, uint pMask) - { - RigidBody body = pBody as RigidBody; - body.GetBroadphaseHandle().m_collisionFilterGroup = (BulletXNA.BulletCollision.CollisionFilterGroups) pGroup; - body.GetBroadphaseHandle().m_collisionFilterGroup = (BulletXNA.BulletCollision.CollisionFilterGroups) pGroup; - if ((uint) body.GetBroadphaseHandle().m_collisionFilterGroup == 0) - return false; - return true; - } - - internal static void ClearAllForces2(object pBody) - { - CollisionObject body = pBody as CollisionObject; - IndexedVector3 zeroVector = new IndexedVector3(0, 0, 0); - body.SetInterpolationLinearVelocity(ref zeroVector); - body.SetInterpolationAngularVelocity(ref zeroVector); - IndexedMatrix bodytransform = body.GetWorldTransform(); - - body.SetInterpolationWorldTransform(ref bodytransform); - - if (body is RigidBody) - { - RigidBody rigidbody = body as RigidBody; - rigidbody.SetLinearVelocity(zeroVector); - rigidbody.SetAngularVelocity(zeroVector); - rigidbody.ClearForces(); - } - } - - internal static void SetInterpolationAngularVelocity2(object pBody, Vector3 pVector3) - { - RigidBody body = pBody as RigidBody; - IndexedVector3 vec = new IndexedVector3(pVector3.X, pVector3.Y, pVector3.Z); - body.SetInterpolationAngularVelocity(ref vec); - } - - internal static void SetAngularVelocity2(object pBody, Vector3 pVector3) - { - RigidBody body = pBody as RigidBody; - IndexedVector3 vec = new IndexedVector3(pVector3.X, pVector3.Y, pVector3.Z); - body.SetAngularVelocity(ref vec); - } - - internal static void ClearForces2(object pBody) - { - RigidBody body = pBody as RigidBody; - body.ClearForces(); - } - - internal static void SetTranslation2(object pBody, Vector3 _position, Quaternion _orientation) - { - RigidBody body = pBody as RigidBody; - IndexedVector3 vposition = new IndexedVector3(_position.X, _position.Y, _position.Z); - IndexedQuaternion vquaternion = new IndexedQuaternion(_orientation.X, _orientation.Y, _orientation.Z, - _orientation.W); - IndexedMatrix mat = IndexedMatrix.CreateFromQuaternion(vquaternion); - mat._origin = vposition; - body.SetWorldTransform(mat); - - } - - internal static Vector3 GetPosition2(object pBody) - { - RigidBody body = pBody as RigidBody; - IndexedVector3 pos = body.GetInterpolationWorldTransform()._origin; - return new Vector3(pos.X, pos.Y, pos.Z); - } - - internal static Vector3 CalculateLocalInertia2(object pShape, float pphysMass) - { - CollisionShape shape = pShape as CollisionShape; - IndexedVector3 inertia = IndexedVector3.Zero; - shape.CalculateLocalInertia(pphysMass, out inertia); - return new Vector3(inertia.X, inertia.Y, inertia.Z); - } - - internal static void SetMassProps2(object pBody, float pphysMass, Vector3 plocalInertia) - { - RigidBody body = pBody as RigidBody; - IndexedVector3 inertia = new IndexedVector3(plocalInertia.X, plocalInertia.Y, plocalInertia.Z); - body.SetMassProps(pphysMass, inertia); - } - - - internal static void SetObjectForce2(object pBody, Vector3 _force) - { - RigidBody body = pBody as RigidBody; - IndexedVector3 force = new IndexedVector3(_force.X, _force.Y, _force.Z); - body.SetTotalForce(ref force); - } - - internal static void SetFriction2(object pBody, float _currentFriction) - { - RigidBody body = pBody as RigidBody; - body.SetFriction(_currentFriction); - } - - internal static void SetLinearVelocity2(object pBody, Vector3 _velocity) - { - RigidBody body = pBody as RigidBody; - IndexedVector3 velocity = new IndexedVector3(_velocity.X, _velocity.Y, _velocity.Z); - body.SetLinearVelocity(velocity); - } - - internal static void Activate2(object pBody, bool pforceactivation) - { - RigidBody body = pBody as RigidBody; - body.Activate(pforceactivation); - - } - - internal static Quaternion GetOrientation2(object pBody) - { - RigidBody body = pBody as RigidBody; - IndexedQuaternion mat = body.GetInterpolationWorldTransform().GetRotation(); - return new Quaternion(mat.X, mat.Y, mat.Z, mat.W); - } - - internal static CollisionFlags RemoveFromCollisionFlags2(object pBody, CollisionFlags pcollisionFlags) - { - RigidBody body = pBody as RigidBody; - CollisionFlags existingcollisionFlags = (CollisionFlags)(uint)body.GetCollisionFlags(); - existingcollisionFlags &= ~pcollisionFlags; - body.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags)(uint)existingcollisionFlags); - return (CollisionFlags)(uint)existingcollisionFlags; - } - - internal static void SetGravity2(object pBody, Vector3 pGravity) - { - RigidBody body = pBody as RigidBody; - IndexedVector3 gravity = new IndexedVector3(pGravity.X, pGravity.Y, pGravity.Z); - body.SetGravity(gravity); - } - - internal static bool DestroyConstraint2(object pBody, object pConstraint) - { - RigidBody body = pBody as RigidBody; - TypedConstraint constraint = pConstraint as TypedConstraint; - body.RemoveConstraintRef(constraint); - return true; - } - - internal static bool SetLinearLimits2(object pConstraint, Vector3 low, Vector3 high) - { - Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; - IndexedVector3 lowlimit = new IndexedVector3(low.X, low.Y, low.Z); - IndexedVector3 highlimit = new IndexedVector3(high.X, high.Y, high.Z); - constraint.SetLinearLowerLimit(lowlimit); - constraint.SetLinearUpperLimit(highlimit); - return true; - } - - internal static bool SetAngularLimits2(object pConstraint, Vector3 low, Vector3 high) - { - Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; - IndexedVector3 lowlimit = new IndexedVector3(low.X, low.Y, low.Z); - IndexedVector3 highlimit = new IndexedVector3(high.X, high.Y, high.Z); - constraint.SetAngularLowerLimit(lowlimit); - constraint.SetAngularUpperLimit(highlimit); - return true; - } - - internal static void SetConstraintNumSolverIterations2(object pConstraint, float cnt) - { - Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; - constraint.SetOverrideNumSolverIterations((int)cnt); - } - - internal static void CalculateTransforms2(object pConstraint) - { - Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; - constraint.CalculateTransforms(); - } - - internal static void SetConstraintEnable2(object pConstraint, float p_2) - { - Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; - constraint.SetEnabled((p_2 == 0) ? false : true); - } - - - //BulletSimAPI.Create6DofConstraint2(m_world.ptr, m_body1.ptr, m_body2.ptr,frame1, frame1rot,frame2, frame2rot,useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); - internal static object Create6DofConstraint2(object pWorld, object pBody1, object pBody2, Vector3 pframe1, Quaternion pframe1rot, Vector3 pframe2, Quaternion pframe2rot, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies) - - { - DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; - RigidBody body1 = pBody1 as RigidBody; - RigidBody body2 = pBody2 as RigidBody; - IndexedVector3 frame1v = new IndexedVector3(pframe1.X, pframe1.Y, pframe1.Z); - IndexedQuaternion frame1rot = new IndexedQuaternion(pframe1rot.X, pframe1rot.Y, pframe1rot.Z, pframe1rot.W); - IndexedMatrix frame1 = IndexedMatrix.CreateFromQuaternion(frame1rot); - frame1._origin = frame1v; - - IndexedVector3 frame2v = new IndexedVector3(pframe2.X, pframe2.Y, pframe2.Z); - IndexedQuaternion frame2rot = new IndexedQuaternion(pframe2rot.X, pframe2rot.Y, pframe2rot.Z, pframe2rot.W); - IndexedMatrix frame2 = IndexedMatrix.CreateFromQuaternion(frame2rot); - frame2._origin = frame1v; - - Generic6DofConstraint consttr = new Generic6DofConstraint(body1, body2, ref frame1, ref frame2, - puseLinearReferenceFrameA); - consttr.CalculateTransforms(); - world.AddConstraint(consttr,pdisableCollisionsBetweenLinkedBodies); - - return consttr; - } - - - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - internal static object Create6DofConstraintToPoint2(object pWorld, object pBody1, object pBody2, Vector3 pjoinPoint, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies) - { - DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; - RigidBody body1 = pBody1 as RigidBody; - RigidBody body2 = pBody2 as RigidBody; - IndexedMatrix frame1 = new IndexedMatrix(IndexedBasisMatrix.Identity, new IndexedVector3(0, 0, 0)); - IndexedMatrix frame2 = new IndexedMatrix(IndexedBasisMatrix.Identity, new IndexedVector3(0, 0, 0)); - - IndexedVector3 joinPoint = new IndexedVector3(pjoinPoint.X, pjoinPoint.Y, pjoinPoint.Z); - IndexedMatrix mat = IndexedMatrix.Identity; - mat._origin = new IndexedVector3(pjoinPoint.X, pjoinPoint.Y, pjoinPoint.Z); - frame1._origin = body1.GetWorldTransform().Inverse()*joinPoint; - frame2._origin = body2.GetWorldTransform().Inverse()*joinPoint; - - Generic6DofConstraint consttr = new Generic6DofConstraint(body1, body2, ref frame1, ref frame2, puseLinearReferenceFrameA); - consttr.CalculateTransforms(); - world.AddConstraint(consttr, pdisableCollisionsBetweenLinkedBodies); - - return consttr; - } - //SetFrames2(m_constraint.ptr, frameA, frameArot, frameB, frameBrot); - internal static void SetFrames2(object pConstraint, Vector3 pframe1, Quaternion pframe1rot, Vector3 pframe2, Quaternion pframe2rot) - { - Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; - IndexedVector3 frame1v = new IndexedVector3(pframe1.X, pframe1.Y, pframe1.Z); - IndexedQuaternion frame1rot = new IndexedQuaternion(pframe1rot.X, pframe1rot.Y, pframe1rot.Z, pframe1rot.W); - IndexedMatrix frame1 = IndexedMatrix.CreateFromQuaternion(frame1rot); - frame1._origin = frame1v; - - IndexedVector3 frame2v = new IndexedVector3(pframe2.X, pframe2.Y, pframe2.Z); - IndexedQuaternion frame2rot = new IndexedQuaternion(pframe2rot.X, pframe2rot.Y, pframe2rot.Z, pframe2rot.W); - IndexedMatrix frame2 = IndexedMatrix.CreateFromQuaternion(frame2rot); - frame2._origin = frame1v; - constraint.SetFrames(ref frame1, ref frame2); - } - - - - - internal static bool IsInWorld2(object pWorld, object pShapeObj) - { - DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; - CollisionObject shape = pShapeObj as CollisionObject; - return world.IsInWorld(shape); - } - - internal static void SetInterpolationLinearVelocity2(object pBody, Vector3 VehicleVelocity) - { - RigidBody body = pBody as RigidBody; - IndexedVector3 velocity = new IndexedVector3(VehicleVelocity.X, VehicleVelocity.Y, VehicleVelocity.Z); - body.SetInterpolationLinearVelocity(ref velocity); - } - - internal static bool UseFrameOffset2(object pConstraint, float onOff) - { - Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; - constraint.SetUseFrameOffset((onOff == 0) ? false : true); - return true; - } - //SetBreakingImpulseThreshold2(m_constraint.ptr, threshold); - internal static bool SetBreakingImpulseThreshold2(object pConstraint, float threshold) - { - Generic6DofConstraint constraint = pConstraint as Generic6DofConstraint; - constraint.SetBreakingImpulseThreshold(threshold); - return true; - } - //BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, angularDamping); - internal static void SetAngularDamping2(object pBody, float angularDamping) - { - RigidBody body = pBody as RigidBody; - float lineardamping = body.GetLinearDamping(); - body.SetDamping(lineardamping, angularDamping); - - } - - internal static void UpdateInertiaTensor2(object pBody) - { - RigidBody body = pBody as RigidBody; - body.UpdateInertiaTensor(); - } - - internal static void RecalculateCompoundShapeLocalAabb2( object pCompoundShape) - { - - CompoundShape shape = pCompoundShape as CompoundShape; - shape.RecalculateLocalAabb(); - } - - //BulletSimAPI.GetCollisionFlags2(PhysBody.ptr) - internal static CollisionFlags GetCollisionFlags2(object pBody) - { - RigidBody body = pBody as RigidBody; - uint flags = (uint)body.GetCollisionFlags(); - return (CollisionFlags) flags; - } - - internal static void SetDamping2(object pBody, float pLinear, float pAngular) - { - RigidBody body = pBody as RigidBody; - body.SetDamping(pLinear, pAngular); - } - //PhysBody.ptr, PhysicsScene.Params.deactivationTime); - internal static void SetDeactivationTime2(object pBody, float pDeactivationTime) - { - RigidBody body = pBody as RigidBody; - body.SetDeactivationTime(pDeactivationTime); - } - //SetSleepingThresholds2(PhysBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold); - internal static void SetSleepingThresholds2(object pBody, float plinearSleepingThreshold, float pangularSleepingThreshold) - { - RigidBody body = pBody as RigidBody; - body.SetSleepingThresholds(plinearSleepingThreshold, pangularSleepingThreshold); - } - - internal static CollisionObjectTypes GetBodyType2(object pBody) - { - RigidBody body = pBody as RigidBody; - return (CollisionObjectTypes)(int) body.GetInternalType(); - } - - //BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, fSum); - internal static void ApplyCentralForce2(object pBody, Vector3 pfSum) - { - RigidBody body = pBody as RigidBody; - IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z); - body.ApplyCentralForce(ref fSum); - } - internal static void ApplyCentralImpulse2(object pBody, Vector3 pfSum) - { - RigidBody body = pBody as RigidBody; - IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z); - body.ApplyCentralImpulse(ref fSum); - } - internal static void ApplyTorque2(object pBody, Vector3 pfSum) - { - RigidBody body = pBody as RigidBody; - IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z); - body.ApplyTorque(ref fSum); - } - internal static void ApplyTorqueImpulse2(object pBody, Vector3 pfSum) - { - RigidBody body = pBody as RigidBody; - IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z); - body.ApplyTorqueImpulse(ref fSum); - } - - internal static void DumpRigidBody2(object p, object p_2) - { - //TODO: - } - - internal static void DumpCollisionShape2(object p, object p_2) - { - //TODO: - } - - internal static void DestroyObject2(object p, object p_2) - { - //TODO: - } - - internal static void Shutdown2(object pWorld) - { - DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; - world.Cleanup(); - } - - internal static void DeleteCollisionShape2(object p, object p_2) - { - //TODO: - } - //(sim.ptr, shape.ptr, prim.LocalID, prim.RawPosition, prim.RawOrientation); - - internal static object CreateBodyFromShape2(object pWorld, object pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation) - { - CollisionWorld world = pWorld as CollisionWorld; - IndexedMatrix mat = - IndexedMatrix.CreateFromQuaternion(new IndexedQuaternion(pRawOrientation.X, pRawOrientation.Y, - pRawOrientation.Z, pRawOrientation.W)); - mat._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z); - CollisionShape shape = pShape as CollisionShape; - //UpdateSingleAabb2(world, shape); - // TODO: Feed Update array into null - RigidBody body = new RigidBody(0,new SimMotionState(world,pLocalID,mat,null),shape,IndexedVector3.Zero); - - body.SetUserPointer(pLocalID); - return body; - } - - - internal static object CreateBodyWithDefaultMotionState2( object pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation) - { - - IndexedMatrix mat = - IndexedMatrix.CreateFromQuaternion(new IndexedQuaternion(pRawOrientation.X, pRawOrientation.Y, - pRawOrientation.Z, pRawOrientation.W)); - mat._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z); - - CollisionShape shape = pShape as CollisionShape; - - // TODO: Feed Update array into null - RigidBody body = new RigidBody(0, new DefaultMotionState( mat, IndexedMatrix.Identity), shape, IndexedVector3.Zero); - body.SetWorldTransform(mat); - body.SetUserPointer(pLocalID); - return body; - } - //(m_mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); - internal static void SetCollisionFlags2(object pBody, CollisionFlags collisionFlags) - { - RigidBody body = pBody as RigidBody; - body.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags) (uint) collisionFlags); - } - //(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainHitFraction); - internal static void SetHitFraction2(object pBody, float pHitFraction) - { - RigidBody body = pBody as RigidBody; - body.SetHitFraction(pHitFraction); - } - //BuildCapsuleShape2(physicsScene.World.ptr, 1f, 1f, prim.Scale); - internal static object BuildCapsuleShape2(object pWorld, float pRadius, float pHeight, Vector3 pScale) - { - DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; - IndexedVector3 scale = new IndexedVector3(pScale.X, pScale.Y, pScale.Z); - CapsuleShapeZ capsuleShapeZ = new CapsuleShapeZ(pRadius, pHeight); - capsuleShapeZ.SetMargin(world.WorldSettings.Params.collisionMargin); - capsuleShapeZ.SetLocalScaling(ref scale); - - return capsuleShapeZ; - } - - public static object Initialize2(Vector3 worldExtent, ConfigurationParameters[] o, int mMaxCollisionsPerFrame, ref BulletXNA.CollisionDesc[] collisionArray, int mMaxUpdatesPerFrame, ref BulletXNA.EntityProperties[] updateArray, object mDebugLogCallbackHandle) - { - CollisionWorld.WorldData.ParamData p = new CollisionWorld.WorldData.ParamData(); - - p.angularDamping = o[0].XangularDamping; - p.defaultFriction = o[0].defaultFriction; - p.defaultFriction = o[0].defaultFriction; - p.defaultDensity = o[0].defaultDensity; - p.defaultRestitution = o[0].defaultRestitution; - p.collisionMargin = o[0].collisionMargin; - p.gravity = o[0].gravity; - - p.linearDamping = o[0].XlinearDamping; - p.angularDamping = o[0].XangularDamping; - p.deactivationTime = o[0].XdeactivationTime; - p.linearSleepingThreshold = o[0].XlinearSleepingThreshold; - p.angularSleepingThreshold = o[0].XangularSleepingThreshold; - p.ccdMotionThreshold = o[0].XccdMotionThreshold; - p.ccdSweptSphereRadius = o[0].XccdSweptSphereRadius; - p.contactProcessingThreshold = o[0].XcontactProcessingThreshold; - - p.terrainImplementation = o[0].XterrainImplementation; - p.terrainFriction = o[0].XterrainFriction; - - p.terrainHitFraction = o[0].XterrainHitFraction; - p.terrainRestitution = o[0].XterrainRestitution; - p.terrainCollisionMargin = o[0].XterrainCollisionMargin; - - p.avatarFriction = o[0].XavatarFriction; - p.avatarStandingFriction = o[0].XavatarStandingFriction; - p.avatarDensity = o[0].XavatarDensity; - p.avatarRestitution = o[0].XavatarRestitution; - p.avatarCapsuleWidth = o[0].XavatarCapsuleWidth; - p.avatarCapsuleDepth = o[0].XavatarCapsuleDepth; - p.avatarCapsuleHeight = o[0].XavatarCapsuleHeight; - p.avatarContactProcessingThreshold = o[0].XavatarContactProcessingThreshold; - - p.vehicleAngularDamping = o[0].XvehicleAngularDamping; - - p.maxPersistantManifoldPoolSize = o[0].maxPersistantManifoldPoolSize; - p.maxCollisionAlgorithmPoolSize = o[0].maxCollisionAlgorithmPoolSize; - p.shouldDisableContactPoolDynamicAllocation = o[0].shouldDisableContactPoolDynamicAllocation; - p.shouldForceUpdateAllAabbs = o[0].shouldForceUpdateAllAabbs; - p.shouldRandomizeSolverOrder = o[0].shouldRandomizeSolverOrder; - p.shouldSplitSimulationIslands = o[0].shouldSplitSimulationIslands; - p.shouldEnableFrictionCaching = o[0].shouldEnableFrictionCaching; - p.numberOfSolverIterations = o[0].numberOfSolverIterations; - - p.linksetImplementation = o[0].XlinksetImplementation; - p.linkConstraintUseFrameOffset = o[0].XlinkConstraintUseFrameOffset; - p.linkConstraintEnableTransMotor = o[0].XlinkConstraintEnableTransMotor; - p.linkConstraintTransMotorMaxVel = o[0].XlinkConstraintTransMotorMaxVel; - p.linkConstraintTransMotorMaxForce = o[0].XlinkConstraintTransMotorMaxForce; - p.linkConstraintERP = o[0].XlinkConstraintERP; - p.linkConstraintCFM = o[0].XlinkConstraintCFM; - p.linkConstraintSolverIterations = o[0].XlinkConstraintSolverIterations; - p.physicsLoggingFrames = o[0].physicsLoggingFrames; - DefaultCollisionConstructionInfo ccci = new DefaultCollisionConstructionInfo(); - - DefaultCollisionConfiguration cci = new DefaultCollisionConfiguration(); - CollisionDispatcher m_dispatcher = new CollisionDispatcher(cci); - - - if (p.maxPersistantManifoldPoolSize > 0) - cci.m_persistentManifoldPoolSize = (int)p.maxPersistantManifoldPoolSize; - if (p.shouldDisableContactPoolDynamicAllocation !=0) - m_dispatcher.SetDispatcherFlags(DispatcherFlags.CD_DISABLE_CONTACTPOOL_DYNAMIC_ALLOCATION); - //if (p.maxCollisionAlgorithmPoolSize >0 ) - - DbvtBroadphase m_broadphase = new DbvtBroadphase(); - //IndexedVector3 aabbMin = new IndexedVector3(0, 0, 0); - //IndexedVector3 aabbMax = new IndexedVector3(256, 256, 256); - - //AxisSweep3Internal m_broadphase2 = new AxisSweep3Internal(ref aabbMin, ref aabbMax, Convert.ToInt32(0xfffe), 0xffff, ushort.MaxValue/2, null, true); - m_broadphase.GetOverlappingPairCache().SetInternalGhostPairCallback(new GhostPairCallback()); - - SequentialImpulseConstraintSolver m_solver = new SequentialImpulseConstraintSolver(); - - DiscreteDynamicsWorld world = new DiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, cci); - world.UpdatedObjects = updateArray; - world.UpdatedCollisions = collisionArray; - world.WorldSettings.Params = p; - world.SetForceUpdateAllAabbs(p.shouldForceUpdateAllAabbs != 0); - world.GetSolverInfo().m_solverMode = SolverMode.SOLVER_USE_WARMSTARTING | SolverMode.SOLVER_SIMD; - if (p.shouldRandomizeSolverOrder != 0) - world.GetSolverInfo().m_solverMode |= SolverMode.SOLVER_RANDMIZE_ORDER; - - world.GetSimulationIslandManager().SetSplitIslands(p.shouldSplitSimulationIslands != 0); - //world.GetDispatchInfo().m_enableSatConvex Not implemented in C# port - - if (p.shouldEnableFrictionCaching != 0) - world.GetSolverInfo().m_solverMode |= SolverMode.SOLVER_ENABLE_FRICTION_DIRECTION_CACHING; - - if (p.numberOfSolverIterations > 0) - world.GetSolverInfo().m_numIterations = (int) p.numberOfSolverIterations; - - - world.GetSolverInfo().m_damping = world.WorldSettings.Params.linearDamping; - world.GetSolverInfo().m_restitution = world.WorldSettings.Params.defaultRestitution; - world.GetSolverInfo().m_globalCfm = 0.0f; - world.GetSolverInfo().m_tau = 0.6f; - world.GetSolverInfo().m_friction = 0.3f; - world.GetSolverInfo().m_maxErrorReduction = 20f; - world.GetSolverInfo().m_numIterations = 10; - world.GetSolverInfo().m_erp = 0.2f; - world.GetSolverInfo().m_erp2 = 0.1f; - world.GetSolverInfo().m_sor = 1.0f; - world.GetSolverInfo().m_splitImpulse = false; - world.GetSolverInfo().m_splitImpulsePenetrationThreshold = -0.02f; - world.GetSolverInfo().m_linearSlop = 0.0f; - world.GetSolverInfo().m_warmstartingFactor = 0.85f; - world.GetSolverInfo().m_restingContactRestitutionThreshold = 2; - world.SetForceUpdateAllAabbs(true); - - - world.SetGravity(new IndexedVector3(0,0,p.gravity)); - - return world; - } - //m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL - internal static bool SetConstraintParam2(object pConstraint, ConstraintParams paramIndex, float paramvalue, ConstraintParamAxis axis) - { - Generic6DofConstraint constrain = pConstraint as Generic6DofConstraint; - if (axis == ConstraintParamAxis.AXIS_LINEAR_ALL || axis == ConstraintParamAxis.AXIS_ALL) - { - constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams) (int) paramIndex, paramvalue, 0); - constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams) (int) paramIndex, paramvalue, 1); - constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams) (int) paramIndex, paramvalue, 2); - } - if (axis == ConstraintParamAxis.AXIS_ANGULAR_ALL || axis == ConstraintParamAxis.AXIS_ALL) - { - constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams)(int)paramIndex, paramvalue, 3); - constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams)(int)paramIndex, paramvalue, 4); - constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams)(int)paramIndex, paramvalue, 5); - } - if (axis == ConstraintParamAxis.AXIS_LINEAR_ALL) - { - constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams)(int)paramIndex, paramvalue, (int)axis); - } - return true; - } - - internal static bool PushUpdate2(object pCollisionObject) - { - bool ret = false; - RigidBody rb = pCollisionObject as RigidBody; - if (rb != null) - { - SimMotionState sms = rb.GetMotionState() as SimMotionState; - if (sms != null) - { - IndexedMatrix wt = IndexedMatrix.Identity; - sms.GetWorldTransform(out wt); - sms.SetWorldTransform(ref wt, true); - ret = true; - } - } - return ret; - - } - - internal static bool IsCompound2(object pShape) - { - CollisionShape shape = pShape as CollisionShape; - return shape.IsCompound(); - } - internal static bool IsPloyhedral2(object pShape) - { - CollisionShape shape = pShape as CollisionShape; - return shape.IsPolyhedral(); - } - internal static bool IsConvex2d2(object pShape) - { - CollisionShape shape = pShape as CollisionShape; - return shape.IsConvex2d(); - } - internal static bool IsConvex2(object pShape) - { - CollisionShape shape = pShape as CollisionShape; - return shape.IsConvex(); - } - internal static bool IsNonMoving2(object pShape) - { - CollisionShape shape = pShape as CollisionShape; - return shape.IsNonMoving(); - } - internal static bool IsConcave2(object pShape) - { - CollisionShape shape = pShape as CollisionShape; - return shape.IsConcave(); - } - internal static bool IsInfinite2(object pShape) - { - CollisionShape shape = pShape as CollisionShape; - return shape.IsInfinite(); - } - internal static bool IsNativeShape2(object pShape) - { - CollisionShape shape = pShape as CollisionShape; - bool ret; - switch (shape.GetShapeType()) - { - case BroadphaseNativeTypes.BOX_SHAPE_PROXYTYPE: - case BroadphaseNativeTypes.CONE_SHAPE_PROXYTYPE: - case BroadphaseNativeTypes.SPHERE_SHAPE_PROXYTYPE: - case BroadphaseNativeTypes.CYLINDER_SHAPE_PROXYTYPE: - ret = true; - break; - default: - ret = false; - break; - } - return ret; - } - //sim.ptr, shape.ptr,prim.LocalID, prim.RawPosition, prim.RawOrientation - internal static object CreateGhostFromShape2(object pWorld, object pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation) - { - IndexedMatrix bodyTransform = new IndexedMatrix(); - bodyTransform._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z); - bodyTransform.SetRotation(new IndexedQuaternion(pRawOrientation.X,pRawOrientation.Y,pRawOrientation.Z,pRawOrientation.W)); - GhostObject gObj = new PairCachingGhostObject(); - gObj.SetWorldTransform(bodyTransform); - CollisionShape shape = pShape as CollisionShape; - gObj.SetCollisionShape(shape); - gObj.SetUserPointer(pLocalID); - // TODO: Add to Special CollisionObjects! - return gObj; - } - - public static void SetCollisionShape2(object pWorld, object pObj, object pShape) - { - var world = pWorld as DiscreteDynamicsWorld; - var obj = pObj as CollisionObject; - var shape = pShape as CollisionShape; - obj.SetCollisionShape(shape); - - } - //(PhysicsScene.World.ptr, nativeShapeData) - internal static object BuildNativeShape2(object pWorld, ShapeData pShapeData) - { - var world = pWorld as DiscreteDynamicsWorld; - CollisionShape shape = null; - switch (pShapeData.Type) - { - case BSPhysicsShapeType.SHAPE_BOX: - shape = new BoxShape(new IndexedVector3(0.5f,0.5f,0.5f)); - break; - case BSPhysicsShapeType.SHAPE_CONE: - shape = new ConeShapeZ(0.5f, 1.0f); - break; - case BSPhysicsShapeType.SHAPE_CYLINDER: - shape = new CylinderShapeZ(new IndexedVector3(0.5f, 0.5f, 0.5f)); - break; - case BSPhysicsShapeType.SHAPE_SPHERE: - shape = new SphereShape(0.5f); - break; - - } - if (shape != null) - { - IndexedVector3 scaling = new IndexedVector3(pShapeData.Scale.X, pShapeData.Scale.Y, pShapeData.Scale.Z); - shape.SetMargin(world.WorldSettings.Params.collisionMargin); - shape.SetLocalScaling(ref scaling); - - } - return shape; - } - //PhysicsScene.World.ptr, false - internal static object CreateCompoundShape2(object pWorld, bool enableDynamicAabbTree) - { - return new CompoundShape(enableDynamicAabbTree); - } - - internal static int GetNumberOfCompoundChildren2(object pCompoundShape) - { - var compoundshape = pCompoundShape as CompoundShape; - return compoundshape.GetNumChildShapes(); - } - //LinksetRoot.PhysShape.ptr, newShape.ptr, displacementPos, displacementRot - internal static void AddChildShapeToCompoundShape2(object pCShape, object paddShape, Vector3 displacementPos, Quaternion displacementRot) - { - IndexedMatrix relativeTransform = new IndexedMatrix(); - var compoundshape = pCShape as CompoundShape; - var addshape = paddShape as CollisionShape; - - relativeTransform._origin = new IndexedVector3(displacementPos.X, displacementPos.Y, displacementPos.Z); - relativeTransform.SetRotation(new IndexedQuaternion(displacementRot.X,displacementRot.Y,displacementRot.Z,displacementRot.W)); - compoundshape.AddChildShape(ref relativeTransform, addshape); - - } - - internal static object RemoveChildShapeFromCompoundShapeIndex2(object pCShape, int pii) - { - var compoundshape = pCShape as CompoundShape; - CollisionShape ret = null; - ret = compoundshape.GetChildShape(pii); - compoundshape.RemoveChildShapeByIndex(pii); - return ret; - } - - internal static object CreateGroundPlaneShape2(uint pLocalId, float pheight, float pcollisionMargin) - { - StaticPlaneShape m_planeshape = new StaticPlaneShape(new IndexedVector3(0,0,1),(int)pheight ); - m_planeshape.SetMargin(pcollisionMargin); - m_planeshape.SetUserPointer(pLocalId); - return m_planeshape; - } - - internal static object CreateHingeConstraint2(object pWorld, object pBody1, object ppBody2, Vector3 ppivotInA, Vector3 ppivotInB, Vector3 paxisInA, Vector3 paxisInB, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies) - { - HingeConstraint constrain = null; - var rb1 = pBody1 as RigidBody; - var rb2 = ppBody2 as RigidBody; - if (rb1 != null && rb2 != null) - { - IndexedVector3 pivotInA = new IndexedVector3(ppivotInA.X, ppivotInA.Y, ppivotInA.Z); - IndexedVector3 pivotInB = new IndexedVector3(ppivotInB.X, ppivotInB.Y, ppivotInB.Z); - IndexedVector3 axisInA = new IndexedVector3(paxisInA.X, paxisInA.Y, paxisInA.Z); - IndexedVector3 axisInB = new IndexedVector3(paxisInB.X, paxisInB.Y, paxisInB.Z); - var world = pWorld as DiscreteDynamicsWorld; - world.AddConstraint(constrain, pdisableCollisionsBetweenLinkedBodies); - } - return constrain; - } - - internal static bool ReleaseHeightMapInfo2(object pMapInfo) - { - if (pMapInfo != null) - { - BulletHeightMapInfo mapinfo = pMapInfo as BulletHeightMapInfo; - if (mapinfo.heightMap != null) - mapinfo.heightMap = null; - - - } - return true; - } - - internal static object CreateHullShape2(object pWorld, int pHullCount, float[] pConvHulls) - { - CompoundShape compoundshape = new CompoundShape(false); - var world = pWorld as DiscreteDynamicsWorld; - - - compoundshape.SetMargin(world.WorldSettings.Params.collisionMargin); - int ii = 1; - - for (int i = 0; i < pHullCount; i++) - { - int vertexCount = (int) pConvHulls[ii]; - - IndexedVector3 centroid = new IndexedVector3(pConvHulls[ii + 1], pConvHulls[ii + 2], pConvHulls[ii + 3]); - IndexedMatrix childTrans = IndexedMatrix.Identity; - childTrans._origin = centroid; - - List virts = new List(); - int ender = ((ii + 4) + (vertexCount*3)); - for (int iii = ii + 4; iii < ender; iii+=3) - { - - virts.Add(new IndexedVector3(pConvHulls[iii], pConvHulls[iii + 1], pConvHulls[iii +2])); - } - ConvexHullShape convexShape = new ConvexHullShape(virts, vertexCount); - convexShape.SetMargin(world.WorldSettings.Params.collisionMargin); - compoundshape.AddChildShape(ref childTrans, convexShape); - ii += (vertexCount*3 + 4); - } - - - return compoundshape; - } - - internal static object CreateMeshShape2(object pWorld, int pIndicesCount, int[] indices, int pVerticesCount, float[] verticesAsFloats) - { - //DumpRaw(indices,verticesAsFloats,pIndicesCount,pVerticesCount); - - for (int iter = 0; iter < pVerticesCount; iter++) - { - if (verticesAsFloats[iter] > 0 && verticesAsFloats[iter] < 0.0001) verticesAsFloats[iter] = 0; - if (verticesAsFloats[iter] < 0 && verticesAsFloats[iter] > -0.0001) verticesAsFloats[iter] = 0; - } - - ObjectArray indicesarr = new ObjectArray(indices); - ObjectArray vertices = new ObjectArray(verticesAsFloats); - DumpRaw(indicesarr,vertices,pIndicesCount,pVerticesCount); - var world = pWorld as DiscreteDynamicsWorld; - IndexedMesh mesh = new IndexedMesh(); - mesh.m_indexType = PHY_ScalarType.PHY_INTEGER; - mesh.m_numTriangles = pIndicesCount/3; - mesh.m_numVertices = pVerticesCount; - mesh.m_triangleIndexBase = indicesarr; - mesh.m_vertexBase = vertices; - mesh.m_vertexStride = 3; - mesh.m_vertexType = PHY_ScalarType.PHY_FLOAT; - mesh.m_triangleIndexStride = 3; - - TriangleIndexVertexArray tribuilder = new TriangleIndexVertexArray(); - tribuilder.AddIndexedMesh(mesh, PHY_ScalarType.PHY_INTEGER); - BvhTriangleMeshShape meshShape = new BvhTriangleMeshShape(tribuilder, true,true); - meshShape.SetMargin(world.WorldSettings.Params.collisionMargin); - // world.UpdateSingleAabb(meshShape); - return meshShape; - - } - public static void DumpRaw(ObjectArrayindices, ObjectArray vertices, int pIndicesCount,int pVerticesCount ) - { - - String fileName = "objTest3.raw"; - String completePath = System.IO.Path.Combine(Util.configDir(), fileName); - StreamWriter sw = new StreamWriter(completePath); - IndexedMesh mesh = new IndexedMesh(); - - mesh.m_indexType = PHY_ScalarType.PHY_INTEGER; - mesh.m_numTriangles = pIndicesCount / 3; - mesh.m_numVertices = pVerticesCount; - mesh.m_triangleIndexBase = indices; - mesh.m_vertexBase = vertices; - mesh.m_vertexStride = 3; - mesh.m_vertexType = PHY_ScalarType.PHY_FLOAT; - mesh.m_triangleIndexStride = 3; - - TriangleIndexVertexArray tribuilder = new TriangleIndexVertexArray(); - tribuilder.AddIndexedMesh(mesh, PHY_ScalarType.PHY_INTEGER); - - - - for (int i = 0; i < pVerticesCount; i++) - { - - string s = vertices[indices[i * 3]].ToString("0.0000"); - s += " " + vertices[indices[i * 3 + 1]].ToString("0.0000"); - s += " " + vertices[indices[i * 3 + 2]].ToString("0.0000"); - - sw.Write(s + "\n"); - } - - sw.Close(); - } - public static void DumpRaw(int[] indices, float[] vertices, int pIndicesCount, int pVerticesCount) - { - - String fileName = "objTest6.raw"; - String completePath = System.IO.Path.Combine(Util.configDir(), fileName); - StreamWriter sw = new StreamWriter(completePath); - IndexedMesh mesh = new IndexedMesh(); - - mesh.m_indexType = PHY_ScalarType.PHY_INTEGER; - mesh.m_numTriangles = pIndicesCount / 3; - mesh.m_numVertices = pVerticesCount; - mesh.m_triangleIndexBase = indices; - mesh.m_vertexBase = vertices; - mesh.m_vertexStride = 3; - mesh.m_vertexType = PHY_ScalarType.PHY_FLOAT; - mesh.m_triangleIndexStride = 3; - - TriangleIndexVertexArray tribuilder = new TriangleIndexVertexArray(); - tribuilder.AddIndexedMesh(mesh, PHY_ScalarType.PHY_INTEGER); - - - sw.WriteLine("Indices"); - sw.WriteLine(string.Format("int[] indices = new int[{0}];",pIndicesCount)); - for (int iter = 0; iter < indices.Length; iter++) - { - sw.WriteLine(string.Format("indices[{0}]={1};",iter,indices[iter])); - } - sw.WriteLine("VerticesFloats"); - sw.WriteLine(string.Format("float[] vertices = new float[{0}];", pVerticesCount)); - for (int iter = 0; iter < vertices.Length; iter++) - { - sw.WriteLine(string.Format("Vertices[{0}]={1};", iter, vertices[iter].ToString("0.0000"))); - } - - // for (int i = 0; i < pVerticesCount; i++) - // { - // - // string s = vertices[indices[i * 3]].ToString("0.0000"); - // s += " " + vertices[indices[i * 3 + 1]].ToString("0.0000"); - // s += " " + vertices[indices[i * 3 + 2]].ToString("0.0000"); - // - // sw.Write(s + "\n"); - //} - - sw.Close(); - } - //PhysicsScene.World.ptr, m_mapInfo.ID, m_mapInfo.minCoords, m_mapInfo.maxCoords, m_mapInfo.heightMap, PhysicsScene.Params.terrainCollisionMargin - internal static object CreateHeightMapInfo2(object pWorld, uint pId, Vector3 pminCoords, Vector3 pmaxCoords, float[] pheightMap, float pCollisionMargin) - { - BulletHeightMapInfo mapInfo = new BulletHeightMapInfo(pId, pheightMap, null); - mapInfo.heightMap = null; - mapInfo.minCoords = pminCoords; - mapInfo.maxCoords = pmaxCoords; - mapInfo.sizeX = (int) (pmaxCoords.X - pminCoords.X); - mapInfo.sizeY = (int) (pmaxCoords.Y - pminCoords.Y); - mapInfo.ID = pId; - mapInfo.minZ = pminCoords.Z; - mapInfo.maxZ = pmaxCoords.Z; - mapInfo.collisionMargin = pCollisionMargin; - if (mapInfo.minZ == mapInfo.maxZ) - mapInfo.minZ -= 0.2f; - mapInfo.heightMap = pheightMap; - - return mapInfo; - - } - - internal static object CreateTerrainShape2(object pMapInfo) - { - BulletHeightMapInfo mapinfo = pMapInfo as BulletHeightMapInfo; - const int upAxis = 2; - const float scaleFactor = 1.0f; - HeightfieldTerrainShape terrainShape = new HeightfieldTerrainShape((int)mapinfo.sizeX, (int)mapinfo.sizeY, - mapinfo.heightMap, scaleFactor, - mapinfo.minZ, mapinfo.maxZ, upAxis, - false); - terrainShape.SetMargin(mapinfo.collisionMargin + 0.5f); - terrainShape.SetUseDiamondSubdivision(true); - terrainShape.SetUserPointer(mapinfo.ID); - return terrainShape; - } - - internal static bool TranslationalLimitMotor2(object pConstraint, float ponOff, float targetVelocity, float maxMotorForce) - { - TypedConstraint tconstrain = pConstraint as TypedConstraint; - bool onOff = ponOff != 0; - bool ret = false; - - switch (tconstrain.GetConstraintType()) - { - case TypedConstraintType.D6_CONSTRAINT_TYPE: - Generic6DofConstraint constrain = pConstraint as Generic6DofConstraint; - constrain.GetTranslationalLimitMotor().m_enableMotor[0] = onOff; - constrain.GetTranslationalLimitMotor().m_targetVelocity[0] = targetVelocity; - constrain.GetTranslationalLimitMotor().m_maxMotorForce[0] = maxMotorForce; - ret = true; - break; - } - - - return ret; - - } - - internal static int PhysicsStep2(object pWorld, float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount, out BulletXNA.EntityProperties[] updatedEntities, out int collidersCount, out BulletXNA.CollisionDesc[] colliders) - { - int epic = PhysicsStepint2(pWorld, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out updatedEntities, - out collidersCount, out colliders); - return epic; - } - - private static int PhysicsStepint2(object pWorld,float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount, out BulletXNA.EntityProperties[] updatedEntities, out int collidersCount, out BulletXNA.CollisionDesc[] colliders) - { - int numSimSteps = 0; - - - //if (updatedEntities is null) - // updatedEntities = new List(); - - //if (colliders is null) - // colliders = new List(); - - - if (pWorld is DiscreteDynamicsWorld) - { - DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; - - numSimSteps = world.StepSimulation(timeStep, m_maxSubSteps, m_fixedTimeStep); - int updates = 0; - - updatedEntityCount = world.UpdatedObjects.Length; - updatedEntities = (world.UpdatedObjects); - updatedEntityCount = updatedEntities.Length; - //world.UpdatedObjects = ; - - - collidersCount = world.UpdatedCollisions.Length; - colliders = (world.UpdatedCollisions); - - world.UpdatedCollisions = new BulletXNA.CollisionDesc[0]; - m_collisionsThisFrame = 0; - int numManifolds = world.GetDispatcher().GetNumManifolds(); - for (int j = 0; j < numManifolds; j++) - { - PersistentManifold contactManifold = world.GetDispatcher().GetManifoldByIndexInternal(j); - int numContacts = contactManifold.GetNumContacts(); - if (numContacts == 0) - continue; - - CollisionObject objA = contactManifold.GetBody0() as CollisionObject; - CollisionObject objB = contactManifold.GetBody1() as CollisionObject; - - ManifoldPoint manifoldPoint = contactManifold.GetContactPoint(0); - IndexedVector3 contactPoint = manifoldPoint.GetPositionWorldOnB(); - IndexedVector3 contactNormal = -manifoldPoint.m_normalWorldOnB; // make relative to A - - RecordCollision(world, objA, objB, contactPoint, contactNormal); - m_collisionsThisFrame ++; - if (m_collisionsThisFrame >= 9999999) - break; - - - } - - - } - else - { - //if (updatedEntities is null) - updatedEntities = new BulletXNA.EntityProperties[0]; - updatedEntityCount = 0; - //if (colliders is null) - colliders = new BulletXNA.CollisionDesc[0]; - collidersCount = 0; - } - return numSimSteps; - } - - private static void RecordCollision(CollisionWorld world,CollisionObject objA, CollisionObject objB, IndexedVector3 contact, IndexedVector3 norm) - { - - IndexedVector3 contactNormal = norm; - if ((objA.GetCollisionFlags() & BulletXNA.BulletCollision.CollisionFlags.BS_WANTS_COLLISIONS) == 0 && - (objB.GetCollisionFlags() & BulletXNA.BulletCollision.CollisionFlags.BS_WANTS_COLLISIONS) == 0) - { - return; - } - uint idA = (uint)objA.GetUserPointer(); - uint idB = (uint)objB.GetUserPointer(); - if (idA > idB) - { - uint temp = idA; - idA = idB; - idB = temp; - contactNormal = -contactNormal; - } - - ulong collisionID = ((ulong) idA << 32) | idB; - - BulletXNA.CollisionDesc cDesc = new BulletXNA.CollisionDesc() - { - aID = idA, - bID = idB, - point = contact, - normal = contactNormal - }; - if (world.LastCollisionDesc < world.UpdatedCollisions.Length) - world.UpdatedCollisions[world.LastCollisionDesc++] = (cDesc); - m_collisionsThisFrame++; - - - } - private static EntityProperties GetDebugProperties(object pWorld, object pBody) - { - EntityProperties ent = new EntityProperties(); - DiscreteDynamicsWorld world = pWorld as DiscreteDynamicsWorld; - RigidBody body = pBody as RigidBody; - IndexedMatrix transform = body.GetWorldTransform(); - IndexedVector3 LinearVelocity = body.GetInterpolationLinearVelocity(); - IndexedVector3 AngularVelocity = body.GetInterpolationAngularVelocity(); - IndexedQuaternion rotation = transform.GetRotation(); - ent.Acceleration = Vector3.Zero; - ent.ID = (uint)body.GetUserPointer(); - ent.Position = new Vector3(transform._origin.X,transform._origin.Y,transform._origin.Z); - ent.Rotation = new Quaternion(rotation.X,rotation.Y,rotation.Z,rotation.W); - ent.Velocity = new Vector3(LinearVelocity.X, LinearVelocity.Y, LinearVelocity.Z); - ent.RotationalVelocity = new Vector3(AngularVelocity.X, AngularVelocity.Y, AngularVelocity.Z); - return ent; - - - } - - - internal static Vector3 GetLocalScaling2(object pBody) - { - CollisionShape shape = pBody as CollisionShape; - IndexedVector3 scale = shape.GetLocalScaling(); - return new Vector3(scale.X,scale.Y,scale.Z); - } - - internal static bool RayCastGround(object pWorld, Vector3 _RayOrigin, float pRayHeight, object NotMe) - { - DynamicsWorld world = pWorld as DynamicsWorld; - if (world != null) - { - if (NotMe is CollisionObject || NotMe is RigidBody) - { - CollisionObject AvoidBody = NotMe as CollisionObject; - - IndexedVector3 rOrigin = new IndexedVector3(_RayOrigin.X, _RayOrigin.Y, _RayOrigin.Z); - IndexedVector3 rEnd = new IndexedVector3(_RayOrigin.X, _RayOrigin.Y, _RayOrigin.Z - pRayHeight); - using ( - ClosestNotMeRayResultCallback rayCallback = new ClosestNotMeRayResultCallback(rOrigin, - rEnd, AvoidBody) - ) - { - world.RayTest(ref rOrigin, ref rEnd, rayCallback); - if (rayCallback.HasHit()) - { - IndexedVector3 hitLocation = rayCallback.m_hitPointWorld; - - } - return rayCallback.HasHit(); - } - } - } - return false; - } -} -} diff --git a/OpenSim/Region/Physics/BulletSNPlugin/BulletSimData.cs b/OpenSim/Region/Physics/BulletSNPlugin/BulletSimData.cs deleted file mode 100644 index f509dc4..0000000 --- a/OpenSim/Region/Physics/BulletSNPlugin/BulletSimData.cs +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyrightD - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -using System; -using System.Collections.Generic; -using System.Text; -using OMV = OpenMetaverse; - -namespace OpenSim.Region.Physics.BulletSNPlugin -{ -// Classes to allow some type checking for the API -// These hold pointers to allocated objects in the unmanaged space. - -// The physics engine controller class created at initialization -public struct BulletWorld -{ - public BulletWorld(uint worldId, BSScene bss, object xx) - { - ptr = xx; - worldID = worldId; - physicsScene = bss; - } - public object ptr; - public uint worldID; - // The scene is only in here so very low level routines have a handle to print debug/error messages - public BSScene physicsScene; -} - -// An allocated Bullet btRigidBody -public struct BulletBody -{ - public BulletBody(uint id) : this(id, null) - { - } - public BulletBody(uint id, object xx) - { - ID = id; - ptr = xx; - collisionType = CollisionType.Static; - } - public object ptr; - public uint ID; - public CollisionType collisionType; - - public void Clear() - { - ptr = null; - } - public bool HasPhysicalBody { get { return ptr != null; } } - - // Apply the specificed collision mask into the physical world - public void ApplyCollisionMask() - { - // Should assert the body has been added to the physical world. - // (The collision masks are stored in the collision proxy cache which only exists for - // a collision body that is in the world.) - BulletSimAPI.SetCollisionGroupMask2(ptr, - BulletSimData.CollisionTypeMasks[collisionType].group, - BulletSimData.CollisionTypeMasks[collisionType].mask); - } - - public override string ToString() - { - StringBuilder buff = new StringBuilder(); - buff.Append(""); - return buff.ToString(); - } -} - -public struct BulletShape -{ - public BulletShape(object xx) : this(xx, BSPhysicsShapeType.SHAPE_UNKNOWN) - { - } - public BulletShape(object xx, BSPhysicsShapeType typ) - { - ptr = xx; - type = typ; - shapeKey = (System.UInt64)FixedShapeKey.KEY_NONE; - isNativeShape = false; - } - public object ptr; - public BSPhysicsShapeType type; - public System.UInt64 shapeKey; - public bool isNativeShape; - - public void Clear() - { - ptr = null; - } - public bool HasPhysicalShape { get { return ptr != null; } } - - public override string ToString() - { - StringBuilder buff = new StringBuilder(); - buff.Append(""); - return buff.ToString(); - } -} - -// An allocated Bullet btConstraint -public struct BulletConstraint -{ - public BulletConstraint(object xx) - { - ptr = xx; - } - public object ptr; - - public void Clear() - { - ptr = null; - } - public bool HasPhysicalConstraint { get { return ptr != null; } } -} - -// An allocated HeightMapThing which holds various heightmap info. -// Made a class rather than a struct so there would be only one -// instance of this and C# will pass around pointers rather -// than making copies. -public class BulletHeightMapInfo -{ - public BulletHeightMapInfo(uint id, float[] hm, object xx) { - ID = id; - Ptr = xx; - heightMap = hm; - terrainRegionBase = OMV.Vector3.Zero; - minCoords = new OMV.Vector3(100f, 100f, 25f); - maxCoords = new OMV.Vector3(101f, 101f, 26f); - minZ = maxZ = 0f; - sizeX = sizeY = 256f; - } - public uint ID; - public object Ptr; - public float[] heightMap; - public OMV.Vector3 terrainRegionBase; - public OMV.Vector3 minCoords; - public OMV.Vector3 maxCoords; - public float sizeX, sizeY; - public float minZ, maxZ; - public BulletShape terrainShape; - public BulletBody terrainBody; - - public float collisionMargin { get; set; } -} - -// The general class of collsion object. -public enum CollisionType -{ - Avatar, - Groundplane, - Terrain, - Static, - Dynamic, - VolumeDetect, - // Linkset, // A linkset should be either Static or Dynamic - LinksetChild, - Unknown -}; - -// Hold specification of group and mask collision flags for a CollisionType -public struct CollisionTypeFilterGroup -{ - public CollisionTypeFilterGroup(CollisionType t, uint g, uint m) - { - type = t; - group = g; - mask = m; - } - public CollisionType type; - public uint group; - public uint mask; -}; - - /* NOTE: old definitions kept for reference. Delete when things are working. - // The collsion filters and masked are defined in one place -- don't want them scattered - AvatarGroup = BCharacterGroup, - AvatarMask = BAllGroup, - ObjectGroup = BSolidGroup, - ObjectMask = BAllGroup, - StaticObjectGroup = BStaticGroup, - StaticObjectMask = AvatarGroup | ObjectGroup, // static things don't interact with much - LinksetGroup = BLinksetGroup, - LinksetMask = BAllGroup, - LinksetChildGroup = BLinksetChildGroup, - LinksetChildMask = BNoneGroup, // Linkset children disappear from the world - VolumeDetectGroup = BSensorTrigger, - VolumeDetectMask = ~BSensorTrigger, - TerrainGroup = BTerrainGroup, - TerrainMask = BAllGroup & ~BStaticGroup, // static objects on the ground don't collide - GroundPlaneGroup = BGroundPlaneGroup, - GroundPlaneMask = BAllGroup - */ - -public static class BulletSimData -{ - -// Map of collisionTypes to flags for collision groups and masks. -// As mentioned above, don't use the CollisionFilterGroups definitions directly in the code -// but, instead, use references to this dictionary. Finding and debugging -// collision flag problems will be made easier. -public static Dictionary CollisionTypeMasks - = new Dictionary() -{ - { CollisionType.Avatar, - new CollisionTypeFilterGroup(CollisionType.Avatar, - (uint)CollisionFilterGroups.BCharacterGroup, - (uint)CollisionFilterGroups.BAllGroup) - }, - { CollisionType.Groundplane, - new CollisionTypeFilterGroup(CollisionType.Groundplane, - (uint)CollisionFilterGroups.BGroundPlaneGroup, - (uint)CollisionFilterGroups.BAllGroup) - }, - { CollisionType.Terrain, - new CollisionTypeFilterGroup(CollisionType.Terrain, - (uint)CollisionFilterGroups.BTerrainGroup, - (uint)(CollisionFilterGroups.BAllGroup & ~CollisionFilterGroups.BStaticGroup)) - }, - { CollisionType.Static, - new CollisionTypeFilterGroup(CollisionType.Static, - (uint)CollisionFilterGroups.BStaticGroup, - (uint)(CollisionFilterGroups.BCharacterGroup | CollisionFilterGroups.BSolidGroup)) - }, - { CollisionType.Dynamic, - new CollisionTypeFilterGroup(CollisionType.Dynamic, - (uint)CollisionFilterGroups.BSolidGroup, - (uint)(CollisionFilterGroups.BAllGroup)) - }, - { CollisionType.VolumeDetect, - new CollisionTypeFilterGroup(CollisionType.VolumeDetect, - (uint)CollisionFilterGroups.BSensorTrigger, - (uint)(~CollisionFilterGroups.BSensorTrigger)) - }, - { CollisionType.LinksetChild, - new CollisionTypeFilterGroup(CollisionType.LinksetChild, - (uint)CollisionFilterGroups.BTerrainGroup, - (uint)(CollisionFilterGroups.BNoneGroup)) - }, -}; - -} -} -- cgit v1.1 From 2c517d792f0440c2705458e01a5067628b6b2c7c Mon Sep 17 00:00:00 2001 From: teravus Date: Sun, 20 Jan 2013 08:18:16 -0500 Subject: This updates prebuild to remove BulletSimN, implements the BulletSim API in BulletSPlugin using the BulletXNA Bullet physics engine. It also updates the BulletXNA library to be compatible with the changes. OpenSimDefaults has been updated to describe how to switch engines and terrain implementations. --- OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs | 885 ++++++++++++++++------- 1 file changed, 623 insertions(+), 262 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs index b6ff52b..49b1730 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs @@ -129,7 +129,12 @@ private sealed class BulletConstraintXNA : BulletConstraint get { return "XNAConstraint"; } } } + internal int m_maxCollisions; + internal CollisionDesc[] m_collisionArray; + internal int m_maxUpdatesPerFrame; + internal EntityProperties[] m_updateArray; + private static int m_collisionsThisFrame; private BSScene PhysicsScene { get; set; } @@ -148,92 +153,98 @@ private sealed class BulletConstraintXNA : BulletConstraint /// public override bool RemoveObjectFromWorld(BulletWorld pWorld, BulletBody pBody) { - DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; RigidBody body = ((BulletBodyXNA)pBody).rigidBody; world.RemoveRigidBody(body); return true; } - public override bool AddConstraintToWorld(BulletWorld world, BulletConstraint constrain, bool disableCollisionsBetweenLinkedObjects) + public override bool AddConstraintToWorld(BulletWorld pWorld, BulletConstraint pConstraint, bool pDisableCollisionsBetweenLinkedObjects) { - /* TODO */ - return false; + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; + TypedConstraint constraint = (pConstraint as BulletConstraintXNA).constrain; + world.AddConstraint(constraint, pDisableCollisionsBetweenLinkedObjects); + + return true; + } - public override bool RemoveConstraintFromWorld(BulletWorld world, BulletConstraint constrain) + public override bool RemoveConstraintFromWorld(BulletWorld pWorld, BulletConstraint pConstraint) { - /* TODO */ - return false; + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; + TypedConstraint constraint = (pConstraint as BulletConstraintXNA).constrain; + world.RemoveConstraint(constraint); + return true; } - public override void SetRestitution(BulletBody pBody, float pRestitution) + public override void SetRestitution(BulletBody pCollisionObject, float pRestitution) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; - body.SetRestitution(pRestitution); + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + collisionObject.SetRestitution(pRestitution); } public override int GetShapeType(BulletShape pShape) { - CollisionShape shape = ((BulletShapeXNA)pShape).shape; + CollisionShape shape = (pShape as BulletShapeXNA).shape; return (int)shape.GetShapeType(); } public override void SetMargin(BulletShape pShape, float pMargin) { - CollisionShape shape = ((BulletShapeXNA)pShape).shape; + CollisionShape shape = (pShape as BulletShapeXNA).shape; shape.SetMargin(pMargin); } public override float GetMargin(BulletShape pShape) { - CollisionShape shape = ((BulletShapeXNA)pShape).shape; + CollisionShape shape = (pShape as BulletShapeXNA).shape; return shape.GetMargin(); } public override void SetLocalScaling(BulletShape pShape, Vector3 pScale) { - CollisionShape shape = ((BulletShapeXNA)pShape).shape; + CollisionShape shape = (pShape as BulletShapeXNA).shape; IndexedVector3 vec = new IndexedVector3(pScale.X, pScale.Y, pScale.Z); shape.SetLocalScaling(ref vec); } - public override void SetContactProcessingThreshold(BulletBody pBody, float contactprocessingthreshold) + public override void SetContactProcessingThreshold(BulletBody pCollisionObject, float contactprocessingthreshold) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; - body.SetContactProcessingThreshold(contactprocessingthreshold); + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + collisionObject.SetContactProcessingThreshold(contactprocessingthreshold); } - public override void SetCcdMotionThreshold(BulletBody pBody, float pccdMotionThreashold) + public override void SetCcdMotionThreshold(BulletBody pCollisionObject, float pccdMotionThreashold) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; - body.SetCcdMotionThreshold(pccdMotionThreashold); + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + collisionObject.SetCcdMotionThreshold(pccdMotionThreashold); } - public override void SetCcdSweptSphereRadius(BulletBody pBody, float pCcdSweptSphereRadius) + public override void SetCcdSweptSphereRadius(BulletBody pCollisionObject, float pCcdSweptSphereRadius) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; - body.SetCcdSweptSphereRadius(pCcdSweptSphereRadius); + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + collisionObject.SetCcdSweptSphereRadius(pCcdSweptSphereRadius); } public override void SetAngularFactorV(BulletBody pBody, Vector3 pAngularFactor) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; body.SetAngularFactor(new IndexedVector3(pAngularFactor.X, pAngularFactor.Y, pAngularFactor.Z)); } - public override CollisionFlags AddToCollisionFlags(BulletBody pBody, CollisionFlags pcollisionFlags) + public override CollisionFlags AddToCollisionFlags(BulletBody pCollisionObject, CollisionFlags pcollisionFlags) { - CollisionObject body = ((BulletBodyXNA)pBody).body; - CollisionFlags existingcollisionFlags = (CollisionFlags)(uint)body.GetCollisionFlags(); + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).body; + CollisionFlags existingcollisionFlags = (CollisionFlags)(uint)collisionObject.GetCollisionFlags(); existingcollisionFlags |= pcollisionFlags; - body.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags)(uint)existingcollisionFlags); + collisionObject.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags)(uint)existingcollisionFlags); return (CollisionFlags) (uint) existingcollisionFlags; } public override bool AddObjectToWorld(BulletWorld pWorld, BulletBody pBody) { - DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; - CollisionObject cbody = ((BulletBodyXNA)pBody).body; + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; + CollisionObject cbody = (pBody as BulletBodyXNA).body; RigidBody rbody = cbody as RigidBody; // Bullet resets several variables when an object is added to the world. In particular, @@ -259,99 +270,110 @@ private sealed class BulletConstraintXNA : BulletConstraint return true; } - public override void ForceActivationState(BulletBody pBody, ActivationState pActivationState) + public override void ForceActivationState(BulletBody pCollisionObject, ActivationState pActivationState) { - CollisionObject body = ((BulletBodyXNA)pBody).body; - body.ForceActivationState((BulletXNA.BulletCollision.ActivationState)(uint)pActivationState); + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).body; + collisionObject.ForceActivationState((BulletXNA.BulletCollision.ActivationState)(uint)pActivationState); } - public override void UpdateSingleAabb(BulletWorld pWorld, BulletBody pBody) + public override void UpdateSingleAabb(BulletWorld pWorld, BulletBody pCollisionObject) { - DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; - CollisionObject body = ((BulletBodyXNA)pBody).body; - world.UpdateSingleAabb(body); + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).body; + world.UpdateSingleAabb(collisionObject); } - public override void UpdateAabbs(BulletWorld world) { /* TODO */ } - public override bool GetForceUpdateAllAabbs(BulletWorld world) { /* TODO */ return false; } - public override void SetForceUpdateAllAabbs(BulletWorld world, bool force) { /* TODO */ } + public override void UpdateAabbs(BulletWorld pWorld) { + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; + world.UpdateAabbs(); + } + public override bool GetForceUpdateAllAabbs(BulletWorld pWorld) { + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; + return world.GetForceUpdateAllAabbs(); + + } + public override void SetForceUpdateAllAabbs(BulletWorld pWorld, bool pForce) + { + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; + world.SetForceUpdateAllAabbs(pForce); + } - public override bool SetCollisionGroupMask(BulletBody pBody, uint pGroup, uint pMask) + public override bool SetCollisionGroupMask(BulletBody pCollisionObject, uint pGroup, uint pMask) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; - body.GetBroadphaseHandle().m_collisionFilterGroup = (BulletXNA.BulletCollision.CollisionFilterGroups) pGroup; - body.GetBroadphaseHandle().m_collisionFilterGroup = (BulletXNA.BulletCollision.CollisionFilterGroups) pGroup; - if ((uint) body.GetBroadphaseHandle().m_collisionFilterGroup == 0) + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + collisionObject.GetBroadphaseHandle().m_collisionFilterGroup = (BulletXNA.BulletCollision.CollisionFilterGroups) pGroup; + collisionObject.GetBroadphaseHandle().m_collisionFilterGroup = (BulletXNA.BulletCollision.CollisionFilterGroups) pGroup; + if ((uint) collisionObject.GetBroadphaseHandle().m_collisionFilterGroup == 0) return false; return true; } - public override void ClearAllForces(BulletBody pBody) + public override void ClearAllForces(BulletBody pCollisionObject) { - CollisionObject body = ((BulletBodyXNA)pBody).body; + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).body; IndexedVector3 zeroVector = new IndexedVector3(0, 0, 0); - body.SetInterpolationLinearVelocity(ref zeroVector); - body.SetInterpolationAngularVelocity(ref zeroVector); - IndexedMatrix bodytransform = body.GetWorldTransform(); + collisionObject.SetInterpolationLinearVelocity(ref zeroVector); + collisionObject.SetInterpolationAngularVelocity(ref zeroVector); + IndexedMatrix bodytransform = collisionObject.GetWorldTransform(); - body.SetInterpolationWorldTransform(ref bodytransform); + collisionObject.SetInterpolationWorldTransform(ref bodytransform); - if (body is RigidBody) + if (collisionObject is RigidBody) { - RigidBody rigidbody = body as RigidBody; + RigidBody rigidbody = collisionObject as RigidBody; rigidbody.SetLinearVelocity(zeroVector); rigidbody.SetAngularVelocity(zeroVector); rigidbody.ClearForces(); } } - public override void SetInterpolationAngularVelocity(BulletBody pBody, Vector3 pVector3) + public override void SetInterpolationAngularVelocity(BulletBody pCollisionObject, Vector3 pVector3) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; IndexedVector3 vec = new IndexedVector3(pVector3.X, pVector3.Y, pVector3.Z); - body.SetInterpolationAngularVelocity(ref vec); + collisionObject.SetInterpolationAngularVelocity(ref vec); } public override void SetAngularVelocity(BulletBody pBody, Vector3 pVector3) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; IndexedVector3 vec = new IndexedVector3(pVector3.X, pVector3.Y, pVector3.Z); body.SetAngularVelocity(ref vec); } public override Vector3 GetTotalForce(BulletBody pBody) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; IndexedVector3 iv3 = body.GetTotalForce(); return new Vector3(iv3.X, iv3.Y, iv3.Z); } public override Vector3 GetTotalTorque(BulletBody pBody) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; IndexedVector3 iv3 = body.GetTotalTorque(); return new Vector3(iv3.X, iv3.Y, iv3.Z); } public override Vector3 GetInvInertiaDiagLocal(BulletBody pBody) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; IndexedVector3 iv3 = body.GetInvInertiaDiagLocal(); return new Vector3(iv3.X, iv3.Y, iv3.Z); } public override void SetInvInertiaDiagLocal(BulletBody pBody, Vector3 inert) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; IndexedVector3 iv3 = new IndexedVector3(inert.X, inert.Y, inert.Z); body.SetInvInertiaDiagLocal(ref iv3); } public override void ApplyForce(BulletBody pBody, Vector3 force, Vector3 pos) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; IndexedVector3 forceiv3 = new IndexedVector3(force.X, force.Y, force.Z); IndexedVector3 posiv3 = new IndexedVector3(pos.X, pos.Y, pos.Z); body.ApplyForce(ref forceiv3, ref posiv3); } public override void ApplyImpulse(BulletBody pBody, Vector3 imp, Vector3 pos) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; IndexedVector3 impiv3 = new IndexedVector3(imp.X, imp.Y, imp.Z); IndexedVector3 posiv3 = new IndexedVector3(pos.X, pos.Y, pos.Z); body.ApplyImpulse(ref impiv3, ref posiv3); @@ -359,32 +381,32 @@ private sealed class BulletConstraintXNA : BulletConstraint public override void ClearForces(BulletBody pBody) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; body.ClearForces(); } - public override void SetTranslation(BulletBody pBody, Vector3 _position, Quaternion _orientation) + public override void SetTranslation(BulletBody pCollisionObject, Vector3 _position, Quaternion _orientation) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; IndexedVector3 vposition = new IndexedVector3(_position.X, _position.Y, _position.Z); IndexedQuaternion vquaternion = new IndexedQuaternion(_orientation.X, _orientation.Y, _orientation.Z, _orientation.W); IndexedMatrix mat = IndexedMatrix.CreateFromQuaternion(vquaternion); mat._origin = vposition; - body.SetWorldTransform(mat); + collisionObject.SetWorldTransform(mat); } - public override Vector3 GetPosition(BulletBody pBody) + public override Vector3 GetPosition(BulletBody pCollisionObject) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; - IndexedVector3 pos = body.GetInterpolationWorldTransform()._origin; + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + IndexedVector3 pos = collisionObject.GetInterpolationWorldTransform()._origin; return new Vector3(pos.X, pos.Y, pos.Z); } public override Vector3 CalculateLocalInertia(BulletShape pShape, float pphysMass) { - CollisionShape shape = ((BulletShapeXNA)pShape).shape; + CollisionShape shape = (pShape as BulletShapeXNA).shape; IndexedVector3 inertia = IndexedVector3.Zero; shape.CalculateLocalInertia(pphysMass, out inertia); return new Vector3(inertia.X, inertia.Y, inertia.Z); @@ -392,7 +414,7 @@ private sealed class BulletConstraintXNA : BulletConstraint public override void SetMassProps(BulletBody pBody, float pphysMass, Vector3 plocalInertia) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; IndexedVector3 inertia = new IndexedVector3(plocalInertia.X, plocalInertia.Y, plocalInertia.Z); body.SetMassProps(pphysMass, inertia); } @@ -400,73 +422,90 @@ private sealed class BulletConstraintXNA : BulletConstraint public override void SetObjectForce(BulletBody pBody, Vector3 _force) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; IndexedVector3 force = new IndexedVector3(_force.X, _force.Y, _force.Z); body.SetTotalForce(ref force); } - public override void SetFriction(BulletBody pBody, float _currentFriction) + public override void SetFriction(BulletBody pCollisionObject, float _currentFriction) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; - body.SetFriction(_currentFriction); + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + collisionObject.SetFriction(_currentFriction); } public override void SetLinearVelocity(BulletBody pBody, Vector3 _velocity) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; IndexedVector3 velocity = new IndexedVector3(_velocity.X, _velocity.Y, _velocity.Z); body.SetLinearVelocity(velocity); } - public override void Activate(BulletBody pBody, bool pforceactivation) + public override void Activate(BulletBody pCollisionObject, bool pforceactivation) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; - body.Activate(pforceactivation); + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + collisionObject.Activate(pforceactivation); } - public override Quaternion GetOrientation(BulletBody pBody) + public override Quaternion GetOrientation(BulletBody pCollisionObject) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; - IndexedQuaternion mat = body.GetInterpolationWorldTransform().GetRotation(); + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + IndexedQuaternion mat = collisionObject.GetInterpolationWorldTransform().GetRotation(); return new Quaternion(mat.X, mat.Y, mat.Z, mat.W); } - public override CollisionFlags RemoveFromCollisionFlags(BulletBody pBody, CollisionFlags pcollisionFlags) + public override CollisionFlags RemoveFromCollisionFlags(BulletBody pCollisionObject, CollisionFlags pcollisionFlags) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; - CollisionFlags existingcollisionFlags = (CollisionFlags)(uint)body.GetCollisionFlags(); + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + CollisionFlags existingcollisionFlags = (CollisionFlags)(uint)collisionObject.GetCollisionFlags(); existingcollisionFlags &= ~pcollisionFlags; - body.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags)(uint)existingcollisionFlags); + collisionObject.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags)(uint)existingcollisionFlags); return (CollisionFlags)(uint)existingcollisionFlags; } - public override float GetCcdMotionThreshold(BulletBody obj) { /* TODO */ return 0f; } + public override float GetCcdMotionThreshold(BulletBody pCollisionObject) + { + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + return collisionObject.GetCcdSquareMotionThreshold(); + } - public override float GetCcdSweptSphereRadius(BulletBody obj) { /* TODO */ return 0f; } + public override float GetCcdSweptSphereRadius(BulletBody pCollisionObject) + { + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + return collisionObject.GetCcdSweptSphereRadius(); + + } - public override IntPtr GetUserPointer(BulletBody obj) { /* TODO */ return IntPtr.Zero; } + public override IntPtr GetUserPointer(BulletBody pCollisionObject) + { + CollisionObject shape = (pCollisionObject as BulletBodyXNA).body; + return (IntPtr)shape.GetUserPointer(); + } - public override void SetUserPointer(BulletBody obj, IntPtr val) { /* TODO */ } + public override void SetUserPointer(BulletBody pCollisionObject, IntPtr val) + { + CollisionObject shape = (pCollisionObject as BulletBodyXNA).body; + shape.SetUserPointer(val); + } public override void SetGravity(BulletBody pBody, Vector3 pGravity) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; IndexedVector3 gravity = new IndexedVector3(pGravity.X, pGravity.Y, pGravity.Z); body.SetGravity(gravity); } public override bool DestroyConstraint(BulletWorld pWorld, BulletConstraint pConstraint) { - DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; - TypedConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain; + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; + TypedConstraint constraint = (pConstraint as BulletConstraintXNA).constrain; world.RemoveConstraint(constraint); return true; } public override bool SetLinearLimits(BulletConstraint pConstraint, Vector3 low, Vector3 high) { - Generic6DofConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint; + Generic6DofConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofConstraint; IndexedVector3 lowlimit = new IndexedVector3(low.X, low.Y, low.Z); IndexedVector3 highlimit = new IndexedVector3(high.X, high.Y, high.Z); constraint.SetLinearLowerLimit(lowlimit); @@ -476,7 +515,7 @@ private sealed class BulletConstraintXNA : BulletConstraint public override bool SetAngularLimits(BulletConstraint pConstraint, Vector3 low, Vector3 high) { - Generic6DofConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint; + Generic6DofConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofConstraint; IndexedVector3 lowlimit = new IndexedVector3(low.X, low.Y, low.Z); IndexedVector3 highlimit = new IndexedVector3(high.X, high.Y, high.Z); constraint.SetAngularLowerLimit(lowlimit); @@ -486,20 +525,20 @@ private sealed class BulletConstraintXNA : BulletConstraint public override void SetConstraintNumSolverIterations(BulletConstraint pConstraint, float cnt) { - Generic6DofConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint; + Generic6DofConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofConstraint; constraint.SetOverrideNumSolverIterations((int)cnt); } public override bool CalculateTransforms(BulletConstraint pConstraint) { - Generic6DofConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint; + Generic6DofConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofConstraint; constraint.CalculateTransforms(); return true; } public override void SetConstraintEnable(BulletConstraint pConstraint, float p_2) { - Generic6DofConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint; + Generic6DofConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofConstraint; constraint.SetEnabled((p_2 == 0) ? false : true); } @@ -508,9 +547,9 @@ private sealed class BulletConstraintXNA : BulletConstraint public override BulletConstraint Create6DofConstraint(BulletWorld pWorld, BulletBody pBody1, BulletBody pBody2, Vector3 pframe1, Quaternion pframe1rot, Vector3 pframe2, Quaternion pframe2rot, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies) { - DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; - RigidBody body1 = ((BulletBodyXNA)pBody1).rigidBody; - RigidBody body2 = ((BulletBodyXNA)pBody2).rigidBody; + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; + RigidBody body1 = (pBody1 as BulletBodyXNA).rigidBody; + RigidBody body2 = (pBody2 as BulletBodyXNA).rigidBody; IndexedVector3 frame1v = new IndexedVector3(pframe1.X, pframe1.Y, pframe1.Z); IndexedQuaternion frame1rot = new IndexedQuaternion(pframe1rot.X, pframe1rot.Y, pframe1rot.Z, pframe1rot.W); IndexedMatrix frame1 = IndexedMatrix.CreateFromQuaternion(frame1rot); @@ -542,9 +581,9 @@ private sealed class BulletConstraintXNA : BulletConstraint /// public override BulletConstraint Create6DofConstraintToPoint(BulletWorld pWorld, BulletBody pBody1, BulletBody pBody2, Vector3 pjoinPoint, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies) { - DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; - RigidBody body1 = ((BulletBodyXNA)pBody1).rigidBody; - RigidBody body2 = ((BulletBodyXNA)pBody2).rigidBody; + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; + RigidBody body1 = (pBody1 as BulletBodyXNA).rigidBody; + RigidBody body2 = (pBody2 as BulletBodyXNA).rigidBody; IndexedMatrix frame1 = new IndexedMatrix(IndexedBasisMatrix.Identity, new IndexedVector3(0, 0, 0)); IndexedMatrix frame2 = new IndexedMatrix(IndexedBasisMatrix.Identity, new IndexedVector3(0, 0, 0)); @@ -563,7 +602,7 @@ private sealed class BulletConstraintXNA : BulletConstraint //SetFrames(m_constraint.ptr, frameA, frameArot, frameB, frameBrot); public override bool SetFrames(BulletConstraint pConstraint, Vector3 pframe1, Quaternion pframe1rot, Vector3 pframe2, Quaternion pframe2rot) { - Generic6DofConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint; + Generic6DofConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofConstraint; IndexedVector3 frame1v = new IndexedVector3(pframe1.X, pframe1.Y, pframe1.Z); IndexedQuaternion frame1rot = new IndexedQuaternion(pframe1rot.X, pframe1rot.Y, pframe1rot.Z, pframe1rot.W); IndexedMatrix frame1 = IndexedMatrix.CreateFromQuaternion(frame1rot); @@ -579,109 +618,110 @@ private sealed class BulletConstraintXNA : BulletConstraint public override Vector3 GetLinearVelocity(BulletBody pBody) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; IndexedVector3 iv3 = body.GetLinearVelocity(); return new Vector3(iv3.X, iv3.Y, iv3.Z); } public override Vector3 GetAngularVelocity(BulletBody pBody) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; IndexedVector3 iv3 = body.GetAngularVelocity(); return new Vector3(iv3.X, iv3.Y, iv3.Z); } public override Vector3 GetVelocityInLocalPoint(BulletBody pBody, Vector3 pos) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; IndexedVector3 posiv3 = new IndexedVector3(pos.X, pos.Y, pos.Z); IndexedVector3 iv3 = body.GetVelocityInLocalPoint(ref posiv3); return new Vector3(iv3.X, iv3.Y, iv3.Z); } - public override void Translate(BulletBody pBody, Vector3 trans) + public override void Translate(BulletBody pCollisionObject, Vector3 trans) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + collisionObject.Translate(new IndexedVector3(trans.X,trans.Y,trans.Z)); } public override void UpdateDeactivation(BulletBody pBody, float timeStep) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; body.UpdateDeactivation(timeStep); } public override bool WantsSleeping(BulletBody pBody) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; return body.WantsSleeping(); } public override void SetAngularFactor(BulletBody pBody, float factor) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; body.SetAngularFactor(factor); } public override Vector3 GetAngularFactor(BulletBody pBody) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; IndexedVector3 iv3 = body.GetAngularFactor(); return new Vector3(iv3.X, iv3.Y, iv3.Z); } - public override bool IsInWorld(BulletWorld pWorld, BulletBody pBody) + public override bool IsInWorld(BulletWorld pWorld, BulletBody pCollisionObject) { - DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; - CollisionObject body = ((BulletBodyXNA)pBody).body; - return world.IsInWorld(body); + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).body; + return world.IsInWorld(collisionObject); } - public override void AddConstraintRef(BulletBody pBody, BulletConstraint pConstrain) + public override void AddConstraintRef(BulletBody pBody, BulletConstraint pConstraint) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; - TypedConstraint constrain = ((BulletConstraintXNA)pConstrain).constrain; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; + TypedConstraint constrain = (pConstraint as BulletConstraintXNA).constrain; body.AddConstraintRef(constrain); } - public override void RemoveConstraintRef(BulletBody pBody, BulletConstraint pConstrain) + public override void RemoveConstraintRef(BulletBody pBody, BulletConstraint pConstraint) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; - TypedConstraint constrain = ((BulletConstraintXNA)pConstrain).constrain; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; + TypedConstraint constrain = (pConstraint as BulletConstraintXNA).constrain; body.RemoveConstraintRef(constrain); } public override BulletConstraint GetConstraintRef(BulletBody pBody, int index) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; return new BulletConstraintXNA(body.GetConstraintRef(index)); } public override int GetNumConstraintRefs(BulletBody pBody) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; return body.GetNumConstraintRefs(); } - public override void SetInterpolationLinearVelocity(BulletBody pBody, Vector3 VehicleVelocity) + public override void SetInterpolationLinearVelocity(BulletBody pCollisionObject, Vector3 VehicleVelocity) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; IndexedVector3 velocity = new IndexedVector3(VehicleVelocity.X, VehicleVelocity.Y, VehicleVelocity.Z); - body.SetInterpolationLinearVelocity(ref velocity); + collisionObject.SetInterpolationLinearVelocity(ref velocity); } public override bool UseFrameOffset(BulletConstraint pConstraint, float onOff) { - Generic6DofConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint; + Generic6DofConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofConstraint; constraint.SetUseFrameOffset((onOff == 0) ? false : true); return true; } //SetBreakingImpulseThreshold(m_constraint.ptr, threshold); public override bool SetBreakingImpulseThreshold(BulletConstraint pConstraint, float threshold) { - Generic6DofConstraint constraint = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint; + Generic6DofConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofConstraint; constraint.SetBreakingImpulseThreshold(threshold); return true; } //BulletSimAPI.SetAngularDamping(Prim.PhysBody.ptr, angularDamping); public override void SetAngularDamping(BulletBody pBody, float angularDamping) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; float lineardamping = body.GetLinearDamping(); body.SetDamping(lineardamping, angularDamping); @@ -689,111 +729,183 @@ private sealed class BulletConstraintXNA : BulletConstraint public override void UpdateInertiaTensor(BulletBody pBody) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; body.UpdateInertiaTensor(); } public override void RecalculateCompoundShapeLocalAabb(BulletShape pCompoundShape) { - CompoundShape shape = ((BulletShapeXNA)pCompoundShape).shape as CompoundShape; + CompoundShape shape = (pCompoundShape as BulletShapeXNA).shape as CompoundShape; shape.RecalculateLocalAabb(); } //BulletSimAPI.GetCollisionFlags(PhysBody.ptr) - public override CollisionFlags GetCollisionFlags(BulletBody pBody) + public override CollisionFlags GetCollisionFlags(BulletBody pCollisionObject) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; - uint flags = (uint)body.GetCollisionFlags(); + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + uint flags = (uint)collisionObject.GetCollisionFlags(); return (CollisionFlags) flags; } public override void SetDamping(BulletBody pBody, float pLinear, float pAngular) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; body.SetDamping(pLinear, pAngular); } //PhysBody.ptr, PhysicsScene.Params.deactivationTime); - public override void SetDeactivationTime(BulletBody pBody, float pDeactivationTime) + public override void SetDeactivationTime(BulletBody pCollisionObject, float pDeactivationTime) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; - body.SetDeactivationTime(pDeactivationTime); + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + collisionObject.SetDeactivationTime(pDeactivationTime); } //SetSleepingThresholds(PhysBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold); public override void SetSleepingThresholds(BulletBody pBody, float plinearSleepingThreshold, float pangularSleepingThreshold) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; body.SetSleepingThresholds(plinearSleepingThreshold, pangularSleepingThreshold); } - public override CollisionObjectTypes GetBodyType(BulletBody pBody) + public override CollisionObjectTypes GetBodyType(BulletBody pCollisionObject) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; - return (CollisionObjectTypes)(int) body.GetInternalType(); + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + return (CollisionObjectTypes)(int) collisionObject.GetInternalType(); } - public override void ApplyGravity(BulletBody obj) { /* TODO */ } + public override void ApplyGravity(BulletBody pBody) + { - public override Vector3 GetGravity(BulletBody obj) { /* TODO */ return Vector3.Zero; } + RigidBody body = (pBody as BulletBodyXNA).rigidBody; + body.ApplyGravity(); + } - public override void SetLinearDamping(BulletBody obj, float lin_damping) { /* TODO */ } + public override Vector3 GetGravity(BulletBody pBody) + { + RigidBody body = (pBody as BulletBodyXNA).rigidBody; + IndexedVector3 gravity = body.GetGravity(); + return new Vector3(gravity.X, gravity.Y, gravity.Z); + } - public override float GetLinearDamping(BulletBody obj) { /* TODO */ return 0f; } + public override void SetLinearDamping(BulletBody pBody, float lin_damping) + { + RigidBody body = (pBody as BulletBodyXNA).rigidBody; + float angularDamping = body.GetAngularDamping(); + body.SetDamping(lin_damping, angularDamping); + } - public override float GetAngularDamping(BulletBody obj) { /* TODO */ return 0f; } + public override float GetLinearDamping(BulletBody pBody) + { + RigidBody body = (pBody as BulletBodyXNA).rigidBody; + return body.GetLinearDamping(); + } + + public override float GetAngularDamping(BulletBody pBody) + { + RigidBody body = (pBody as BulletBodyXNA).rigidBody; + return body.GetAngularDamping(); + } - public override float GetLinearSleepingThreshold(BulletBody obj) { /* TODO */ return 0f; } + public override float GetLinearSleepingThreshold(BulletBody pBody) + { + RigidBody body = (pBody as BulletBodyXNA).rigidBody; + return body.GetLinearSleepingThreshold(); + } - public override void ApplyDamping(BulletBody obj, float timeStep) { /* TODO */ } + public override void ApplyDamping(BulletBody pBody, float timeStep) + { + RigidBody body = (pBody as BulletBodyXNA).rigidBody; + body.ApplyDamping(timeStep); + } - public override Vector3 GetLinearFactor(BulletBody obj) { /* TODO */ return Vector3.Zero; } + public override Vector3 GetLinearFactor(BulletBody pBody) + { + RigidBody body = (pBody as BulletBodyXNA).rigidBody; + IndexedVector3 linearFactor = body.GetLinearFactor(); + return new Vector3(linearFactor.X, linearFactor.Y, linearFactor.Z); + } - public override void SetLinearFactor(BulletBody obj, Vector3 factor) { /* TODO */ } + public override void SetLinearFactor(BulletBody pBody, Vector3 factor) + { + RigidBody body = (pBody as BulletBodyXNA).rigidBody; + body.SetLinearFactor(new IndexedVector3(factor.X, factor.Y, factor.Z)); + } - public override void SetCenterOfMassByPosRot(BulletBody obj, Vector3 pos, Quaternion rot) { /* TODO */ } + public override void SetCenterOfMassByPosRot(BulletBody pBody, Vector3 pos, Quaternion rot) + { + RigidBody body = (pBody as BulletBodyXNA).rigidBody; + IndexedQuaternion quat = new IndexedQuaternion(rot.X, rot.Y, rot.Z,rot.W); + IndexedMatrix mat = IndexedMatrix.CreateFromQuaternion(quat); + mat._origin = new IndexedVector3(pos.X, pos.Y, pos.Z); + body.SetCenterOfMassTransform( ref mat); + /* TODO: double check this */ + } //BulletSimAPI.ApplyCentralForce(PhysBody.ptr, fSum); public override void ApplyCentralForce(BulletBody pBody, Vector3 pfSum) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z); body.ApplyCentralForce(ref fSum); } public override void ApplyCentralImpulse(BulletBody pBody, Vector3 pfSum) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z); body.ApplyCentralImpulse(ref fSum); } public override void ApplyTorque(BulletBody pBody, Vector3 pfSum) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z); body.ApplyTorque(ref fSum); } public override void ApplyTorqueImpulse(BulletBody pBody, Vector3 pfSum) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; + RigidBody body = (pBody as BulletBodyXNA).rigidBody; IndexedVector3 fSum = new IndexedVector3(pfSum.X, pfSum.Y, pfSum.Z); body.ApplyTorqueImpulse(ref fSum); } - public override void DestroyObject(BulletWorld p, BulletBody p_2) + public override void DestroyObject(BulletWorld pWorld, BulletBody pBody) { - //TODO: + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; + CollisionObject co = (pBody as BulletBodyXNA).rigidBody; + RigidBody bo = co as RigidBody; + if (bo == null) + { + + if (world.IsInWorld(co)) + { + world.RemoveCollisionObject(co); + } + } + else + { + + if (world.IsInWorld(bo)) + { + world.RemoveRigidBody(bo); + } + } + } public override void Shutdown(BulletWorld pWorld) { - DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; world.Cleanup(); } - public override BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id) + public override BulletShape DuplicateCollisionShape(BulletWorld pWorld, BulletShape pShape, uint id) { - return null; + CollisionShape shape1 = (pShape as BulletShapeXNA).shape; + + // TODO: Turn this from a reference copy to a Value Copy. + BulletShapeXNA shape2 = new BulletShapeXNA(shape1, BSPhysicsShapeType.SHAPE_UNKNOWN); + + return shape2; } - public override bool DeleteCollisionShape(BulletWorld p, BulletShape p_2) + public override bool DeleteCollisionShape(BulletWorld pWorld, BulletShape pShape) { //TODO: return false; @@ -802,17 +914,40 @@ private sealed class BulletConstraintXNA : BulletConstraint public override BulletBody CreateBodyFromShape(BulletWorld pWorld, BulletShape pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation) { - CollisionWorld world = ((BulletWorldXNA)pWorld).world; + CollisionWorld world = (pWorld as BulletWorldXNA).world; IndexedMatrix mat = IndexedMatrix.CreateFromQuaternion(new IndexedQuaternion(pRawOrientation.X, pRawOrientation.Y, pRawOrientation.Z, pRawOrientation.W)); mat._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z); - CollisionShape shape = ((BulletShapeXNA)pShape).shape; + CollisionShape shape = (pShape as BulletShapeXNA).shape; //UpdateSingleAabb(world, shape); // TODO: Feed Update array into null - RigidBody body = new RigidBody(0,new SimMotionState(world,pLocalID,mat,null),shape,IndexedVector3.Zero); - + SimMotionState motionState = new SimMotionState(world, pLocalID, mat, null); + RigidBody body = new RigidBody(0,motionState,shape,IndexedVector3.Zero); + RigidBodyConstructionInfo constructionInfo = new RigidBodyConstructionInfo(0, new SimMotionState(world, pLocalID, mat, null),shape,IndexedVector3.Zero) + { + m_mass = 0 + }; + /* + m_mass = mass; + m_motionState =motionState; + m_collisionShape = collisionShape; + m_localInertia = localInertia; + m_linearDamping = 0f; + m_angularDamping = 0f; + m_friction = 0.5f; + m_restitution = 0f; + m_linearSleepingThreshold = 0.8f; + m_angularSleepingThreshold = 1f; + m_additionalDamping = false; + m_additionalDampingFactor = 0.005f; + m_additionalLinearDampingThresholdSqr = 0.01f; + m_additionalAngularDampingThresholdSqr = 0.01f; + m_additionalAngularDampingFactor = 0.01f; + m_startWorldTransform = IndexedMatrix.Identity; + */ body.SetUserPointer(pLocalID); + return new BulletBodyXNA(pLocalID, body); } @@ -825,7 +960,7 @@ private sealed class BulletConstraintXNA : BulletConstraint pRawOrientation.Z, pRawOrientation.W)); mat._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z); - CollisionShape shape = ((BulletShapeXNA)pShape).shape; + CollisionShape shape = (pShape as BulletShapeXNA).shape; // TODO: Feed Update array into null RigidBody body = new RigidBody(0, new DefaultMotionState( mat, IndexedMatrix.Identity), shape, IndexedVector3.Zero); @@ -834,21 +969,43 @@ private sealed class BulletConstraintXNA : BulletConstraint return new BulletBodyXNA(pLocalID, body); } //(m_mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); - public override CollisionFlags SetCollisionFlags(BulletBody pBody, CollisionFlags collisionFlags) + public override CollisionFlags SetCollisionFlags(BulletBody pCollisionObject, CollisionFlags collisionFlags) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; - body.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags) (uint) collisionFlags); - return (CollisionFlags)body.GetCollisionFlags(); + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + collisionObject.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags) (uint) collisionFlags); + return (CollisionFlags)collisionObject.GetCollisionFlags(); } - public override Vector3 GetAnisotripicFriction(BulletConstraint pconstrain) { /* TODO */ return Vector3.Zero; } + public override Vector3 GetAnisotripicFriction(BulletConstraint pconstrain) + { + + /* TODO */ + return Vector3.Zero; + } public override Vector3 SetAnisotripicFriction(BulletConstraint pconstrain, Vector3 frict) { /* TODO */ return Vector3.Zero; } public override bool HasAnisotripicFriction(BulletConstraint pconstrain) { /* TODO */ return false; } public override float GetContactProcessingThreshold(BulletBody pBody) { /* TODO */ return 0f; } - public override bool IsStaticObject(BulletBody pBody) { /* TODO */ return false; } - public override bool IsKinematicObject(BulletBody pBody) { /* TODO */ return false; } - public override bool IsStaticOrKinematicObject(BulletBody pBody) { /* TODO */ return false; } - public override bool HasContactResponse(BulletBody pBody) { /* TODO */ return false; } + public override bool IsStaticObject(BulletBody pCollisionObject) + { + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + return collisionObject.IsStaticObject(); + + } + public override bool IsKinematicObject(BulletBody pCollisionObject) + { + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + return collisionObject.IsKinematicObject(); + } + public override bool IsStaticOrKinematicObject(BulletBody pCollisionObject) + { + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + return collisionObject.IsStaticOrKinematicObject(); + } + public override bool HasContactResponse(BulletBody pCollisionObject) + { + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + return collisionObject.HasContactResponse(); + } public override int GetActivationState(BulletBody pBody) { /* TODO */ return 0; } public override void SetActivationState(BulletBody pBody, int state) { /* TODO */ } public override float GetDeactivationTime(BulletBody pBody) { /* TODO */ return 0f; } @@ -859,15 +1016,15 @@ private sealed class BulletConstraintXNA : BulletConstraint public override float GetHitFraction(BulletBody pBody) { /* TODO */ return 0f; } //(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainHitFraction); - public override void SetHitFraction(BulletBody pBody, float pHitFraction) + public override void SetHitFraction(BulletBody pCollisionObject, float pHitFraction) { - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; - body.SetHitFraction(pHitFraction); + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + collisionObject.SetHitFraction(pHitFraction); } //BuildCapsuleShape(physicsScene.World.ptr, 1f, 1f, prim.Scale); public override BulletShape BuildCapsuleShape(BulletWorld pWorld, float pRadius, float pHeight, Vector3 pScale) { - DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; IndexedVector3 scale = new IndexedVector3(pScale.X, pScale.Y, pScale.Z); CapsuleShapeZ capsuleShapeZ = new CapsuleShapeZ(pRadius, pHeight); capsuleShapeZ.SetMargin(world.WorldSettings.Params.collisionMargin); @@ -881,14 +1038,24 @@ private sealed class BulletConstraintXNA : BulletConstraint int maxUpdates, ref EntityProperties[] updateArray ) { + + m_updateArray = updateArray; + m_collisionArray = collisionArray; /* TODO */ - return new BulletWorldXNA(1, null, null); + ConfigurationParameters[] configparms = new ConfigurationParameters[1]; + configparms[0] = parms; + Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); + m_maxCollisions = maxCollisions; + m_maxUpdatesPerFrame = maxUpdates; + + + return new BulletWorldXNA(1, PhysicsScene, BSAPIXNA.Initialize2(worldExtent, configparms, maxCollisions, ref collisionArray, maxUpdates, ref updateArray, null)); } - private static object Initialize2(Vector3 worldExtent, + private static DiscreteDynamicsWorld Initialize2(Vector3 worldExtent, ConfigurationParameters[] o, - int mMaxCollisionsPerFrame, ref List collisionArray, - int mMaxUpdatesPerFrame, ref List updateArray, + int mMaxCollisionsPerFrame, ref CollisionDesc[] collisionArray, + int mMaxUpdatesPerFrame, ref EntityProperties[] updateArray, object mDebugLogCallbackHandle) { CollisionWorld.WorldData.ParamData p = new CollisionWorld.WorldData.ParamData(); @@ -968,8 +1135,13 @@ private sealed class BulletConstraintXNA : BulletConstraint SequentialImpulseConstraintSolver m_solver = new SequentialImpulseConstraintSolver(); DiscreteDynamicsWorld world = new DiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, cci); - world.UpdatedObjects = updateArray; - world.UpdatedCollisions = collisionArray; + + + world.UpdatedObjects = BSAPIXNA.GetBulletXNAEntityStruct(BSAPIXNA.BulletSimEntityStructToByteArray(updateArray, updateArray.Length)); + world.UpdatedCollisions = BSAPIXNA.GetBulletXNACollisionStruct(BSAPIXNA.BulletSimCollisionStructToByteArray(collisionArray, collisionArray.Length)); + world.LastCollisionDesc = 0; + world.LastEntityProperty = 0; + world.WorldSettings.Params = p; world.SetForceUpdateAllAabbs(p.shouldForceUpdateAllAabbs != 0); world.GetSolverInfo().m_solverMode = SolverMode.SOLVER_USE_WARMSTARTING | SolverMode.SOLVER_SIMD; @@ -1003,7 +1175,7 @@ private sealed class BulletConstraintXNA : BulletConstraint world.GetSolverInfo().m_restingContactRestitutionThreshold = 2; world.SetForceUpdateAllAabbs(true); - + //BSParam.TerrainImplementation = 0; world.SetGravity(new IndexedVector3(0,0,p.gravity)); return world; @@ -1011,7 +1183,7 @@ private sealed class BulletConstraintXNA : BulletConstraint //m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL public override bool SetConstraintParam(BulletConstraint pConstraint, ConstraintParams paramIndex, float paramvalue, ConstraintParamAxis axis) { - Generic6DofConstraint constrain = ((BulletConstraintXNA)pConstraint).constrain as Generic6DofConstraint; + Generic6DofConstraint constrain = (pConstraint as BulletConstraintXNA).constrain as Generic6DofConstraint; if (axis == ConstraintParamAxis.AXIS_LINEAR_ALL || axis == ConstraintParamAxis.AXIS_ALL) { constrain.SetParam((BulletXNA.BulletDynamics.ConstraintParams) (int) paramIndex, paramvalue, 0); @@ -1034,7 +1206,8 @@ private sealed class BulletConstraintXNA : BulletConstraint public override bool PushUpdate(BulletBody pCollisionObject) { bool ret = false; - RigidBody rb = ((BulletBodyXNA)pCollisionObject).rigidBody; + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + RigidBody rb = collisionObject as RigidBody; if (rb != null) { SimMotionState sms = rb.GetMotionState() as SimMotionState; @@ -1052,57 +1225,57 @@ private sealed class BulletConstraintXNA : BulletConstraint public override float GetAngularMotionDisc(BulletShape pShape) { - CollisionShape shape = ((BulletShapeXNA)pShape).shape; + CollisionShape shape = (pShape as BulletShapeXNA).shape; return shape.GetAngularMotionDisc(); } public override float GetContactBreakingThreshold(BulletShape pShape, float defaultFactor) { - CollisionShape shape = ((BulletShapeXNA)pShape).shape; + CollisionShape shape = (pShape as BulletShapeXNA).shape; return shape.GetContactBreakingThreshold(defaultFactor); } public override bool IsCompound(BulletShape pShape) { - CollisionShape shape = ((BulletShapeXNA)pShape).shape; + CollisionShape shape = (pShape as BulletShapeXNA).shape; return shape.IsCompound(); } public override bool IsSoftBody(BulletShape pShape) { - CollisionShape shape = ((BulletShapeXNA)pShape).shape; + CollisionShape shape = (pShape as BulletShapeXNA).shape; return shape.IsSoftBody(); } public override bool IsPolyhedral(BulletShape pShape) { - CollisionShape shape = ((BulletShapeXNA)pShape).shape; + CollisionShape shape = (pShape as BulletShapeXNA).shape; return shape.IsPolyhedral(); } public override bool IsConvex2d(BulletShape pShape) { - CollisionShape shape = ((BulletShapeXNA)pShape).shape; + CollisionShape shape = (pShape as BulletShapeXNA).shape; return shape.IsConvex2d(); } public override bool IsConvex(BulletShape pShape) { - CollisionShape shape = ((BulletShapeXNA)pShape).shape; + CollisionShape shape = (pShape as BulletShapeXNA).shape; return shape.IsConvex(); } public override bool IsNonMoving(BulletShape pShape) { - CollisionShape shape = ((BulletShapeXNA)pShape).shape; + CollisionShape shape = (pShape as BulletShapeXNA).shape; return shape.IsNonMoving(); } public override bool IsConcave(BulletShape pShape) { - CollisionShape shape = ((BulletShapeXNA)pShape).shape; + CollisionShape shape = (pShape as BulletShapeXNA).shape; return shape.IsConcave(); } public override bool IsInfinite(BulletShape pShape) { - CollisionShape shape = ((BulletShapeXNA)pShape).shape; + CollisionShape shape = (pShape as BulletShapeXNA).shape; return shape.IsInfinite(); } public override bool IsNativeShape(BulletShape pShape) { - CollisionShape shape = ((BulletShapeXNA)pShape).shape; + CollisionShape shape = (pShape as BulletShapeXNA).shape; bool ret; switch (shape.GetShapeType()) { @@ -1119,38 +1292,53 @@ private sealed class BulletConstraintXNA : BulletConstraint return ret; } - public override void SetShapeCollisionMargin(BulletShape shape, float margin) { /* TODO */ } + public override void SetShapeCollisionMargin(BulletShape pShape, float pMargin) + { + CollisionShape shape = (pShape as BulletShapeXNA).shape; + shape.SetMargin(pMargin); + } //sim.ptr, shape.ptr,prim.LocalID, prim.RawPosition, prim.RawOrientation public override BulletBody CreateGhostFromShape(BulletWorld pWorld, BulletShape pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation) { - DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; IndexedMatrix bodyTransform = new IndexedMatrix(); bodyTransform._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z); bodyTransform.SetRotation(new IndexedQuaternion(pRawOrientation.X,pRawOrientation.Y,pRawOrientation.Z,pRawOrientation.W)); GhostObject gObj = new PairCachingGhostObject(); gObj.SetWorldTransform(bodyTransform); - CollisionShape shape = ((BulletShapeXNA)pShape).shape; + CollisionShape shape = (pShape as BulletShapeXNA).shape; gObj.SetCollisionShape(shape); gObj.SetUserPointer(pLocalID); // TODO: Add to Special CollisionObjects! return new BulletBodyXNA(pLocalID, gObj); } - public override void SetCollisionShape(BulletWorld pWorld, BulletBody pObj, BulletShape pShape) + public override void SetCollisionShape(BulletWorld pWorld, BulletBody pCollisionObject, BulletShape pShape) { - DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; - CollisionObject obj = ((BulletBodyXNA)pObj).body; - CollisionShape shape = ((BulletShapeXNA)pShape).shape; - obj.SetCollisionShape(shape); - + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).body; + if (pShape == null) + { + collisionObject.SetCollisionShape(new EmptyShape()); + } + else + { + CollisionShape shape = (pShape as BulletShapeXNA).shape; + collisionObject.SetCollisionShape(shape); + } + } + public override BulletShape GetCollisionShape(BulletBody pCollisionObject) + { + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + CollisionShape shape = collisionObject.GetCollisionShape(); + return new BulletShapeXNA(shape,BSPhysicsShapeType.SHAPE_UNKNOWN); } - public override BulletShape GetCollisionShape(BulletBody obj) { /* TODO */ return null; } //(PhysicsScene.World.ptr, nativeShapeData) public override BulletShape BuildNativeShape(BulletWorld pWorld, ShapeData pShapeData) { - DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; CollisionShape shape = null; switch (pShapeData.Type) { @@ -1185,15 +1373,15 @@ private sealed class BulletConstraintXNA : BulletConstraint public override int GetNumberOfCompoundChildren(BulletShape pCompoundShape) { - CompoundShape compoundshape = ((BulletShapeXNA)pCompoundShape).shape as CompoundShape; + CompoundShape compoundshape = (pCompoundShape as BulletShapeXNA).shape as CompoundShape; return compoundshape.GetNumChildShapes(); } //LinksetRoot.PhysShape.ptr, newShape.ptr, displacementPos, displacementRot public override void AddChildShapeToCompoundShape(BulletShape pCShape, BulletShape paddShape, Vector3 displacementPos, Quaternion displacementRot) { IndexedMatrix relativeTransform = new IndexedMatrix(); - CompoundShape compoundshape = ((BulletShapeXNA)pCShape).shape as CompoundShape; - CollisionShape addshape = ((BulletShapeXNA)paddShape).shape; + CompoundShape compoundshape = (pCShape as BulletShapeXNA).shape as CompoundShape; + CollisionShape addshape = (paddShape as BulletShapeXNA).shape; relativeTransform._origin = new IndexedVector3(displacementPos.X, displacementPos.Y, displacementPos.Z); relativeTransform.SetRotation(new IndexedQuaternion(displacementRot.X,displacementRot.Y,displacementRot.Z,displacementRot.W)); @@ -1203,7 +1391,7 @@ private sealed class BulletConstraintXNA : BulletConstraint public override BulletShape RemoveChildShapeFromCompoundShapeIndex(BulletShape pCShape, int pii) { - CompoundShape compoundshape = ((BulletShapeXNA)pCShape).shape as CompoundShape; + CompoundShape compoundshape = (pCShape as BulletShapeXNA).shape as CompoundShape; CollisionShape ret = null; ret = compoundshape.GetChildShape(pii); compoundshape.RemoveChildShapeByIndex(pii); @@ -1222,12 +1410,12 @@ private sealed class BulletConstraintXNA : BulletConstraint return new BulletShapeXNA(m_planeshape, BSPhysicsShapeType.SHAPE_GROUNDPLANE); } - public override BulletConstraint CreateHingeConstraint(BulletWorld pWorld, BulletBody pBody1, BulletBody ppBody2, Vector3 ppivotInA, Vector3 ppivotInB, Vector3 paxisInA, Vector3 paxisInB, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies) + public override BulletConstraint CreateHingeConstraint(BulletWorld pWorld, BulletBody pBody1, BulletBody pBody2, Vector3 ppivotInA, Vector3 ppivotInB, Vector3 paxisInA, Vector3 paxisInB, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies) { HingeConstraint constrain = null; - DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; - RigidBody rb1 = ((BulletBodyXNA)pBody1).rigidBody; - RigidBody rb2 = ((BulletBodyXNA)ppBody2).rigidBody; + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; + RigidBody rb1 = (pBody1 as BulletBodyXNA).rigidBody; + RigidBody rb2 = (pBody2 as BulletBodyXNA).rigidBody; if (rb1 != null && rb2 != null) { IndexedVector3 pivotInA = new IndexedVector3(ppivotInA.X, ppivotInA.Y, ppivotInA.Z); @@ -1241,7 +1429,7 @@ private sealed class BulletConstraintXNA : BulletConstraint public override BulletShape CreateHullShape(BulletWorld pWorld, int pHullCount, float[] pConvHulls) { - DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; CompoundShape compoundshape = new CompoundShape(false); compoundshape.SetMargin(world.WorldSettings.Params.collisionMargin); @@ -1271,7 +1459,11 @@ private sealed class BulletConstraintXNA : BulletConstraint return new BulletShapeXNA(compoundshape, BSPhysicsShapeType.SHAPE_HULL); } - public override BulletShape BuildHullShapeFromMesh(BulletWorld world, BulletShape meshShape) { /* TODO */ return null; } + public override BulletShape BuildHullShapeFromMesh(BulletWorld world, BulletShape meshShape) + { + /* TODO */ return null; + + } public override BulletShape CreateMeshShape(BulletWorld pWorld, int pIndicesCount, int[] indices, int pVerticesCount, float[] verticesAsFloats) { @@ -1286,7 +1478,7 @@ private sealed class BulletConstraintXNA : BulletConstraint ObjectArray indicesarr = new ObjectArray(indices); ObjectArray vertices = new ObjectArray(verticesAsFloats); DumpRaw(indicesarr,vertices,pIndicesCount,pVerticesCount); - DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; IndexedMesh mesh = new IndexedMesh(); mesh.m_indexType = PHY_ScalarType.PHY_INTEGER; mesh.m_numTriangles = pIndicesCount/3; @@ -1402,7 +1594,7 @@ private sealed class BulletConstraintXNA : BulletConstraint public override bool TranslationalLimitMotor(BulletConstraint pConstraint, float ponOff, float targetVelocity, float maxMotorForce) { - TypedConstraint tconstrain = ((BulletConstraintXNA)pConstraint).constrain; + TypedConstraint tconstrain = (pConstraint as BulletConstraintXNA).constrain; bool onOff = ponOff != 0; bool ret = false; @@ -1428,47 +1620,45 @@ private sealed class BulletConstraintXNA : BulletConstraint /* TODO */ updatedEntityCount = 0; collidersCount = 0; - return 1; + + + int ret = PhysicsStep2(world,timeStep,maxSubSteps,fixedTimeStep,out updatedEntityCount,out world.physicsScene.m_updateArray, out collidersCount, out world.physicsScene.m_collisionArray); + + return ret; } private int PhysicsStep2(BulletWorld pWorld, float timeStep, int m_maxSubSteps, float m_fixedTimeStep, - out int updatedEntityCount, out List updatedEntities, - out int collidersCount, out Listcolliders) + out int updatedEntityCount, out EntityProperties[] updatedEntities, + out int collidersCount, out CollisionDesc[] colliders) { int epic = PhysicsStepint(pWorld, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out updatedEntities, - out collidersCount, out colliders); + out collidersCount, out colliders, m_maxCollisions, m_maxUpdatesPerFrame); return epic; } - private static int PhysicsStepint(BulletWorld pWorld,float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount, out List updatedEntities, out int collidersCount, out List colliders) + private static int PhysicsStepint(BulletWorld pWorld,float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount, + out EntityProperties[] updatedEntities, out int collidersCount, out CollisionDesc[] colliders, int maxCollisions, int maxUpdates) { int numSimSteps = 0; - - //if (updatedEntities is null) - // updatedEntities = new List(); - - //if (colliders is null) - // colliders = new List(); + updatedEntityCount = 0; + collidersCount = 0; if (pWorld is BulletWorldXNA) { - DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; + world.LastCollisionDesc = 0; + world.LastEntityProperty = 0; + world.UpdatedObjects = new BulletXNA.EntityProperties[maxUpdates]; + world.UpdatedCollisions = new BulletXNA.CollisionDesc[maxCollisions]; numSimSteps = world.StepSimulation(timeStep, m_maxSubSteps, m_fixedTimeStep); int updates = 0; - updatedEntityCount = world.UpdatedObjects.Count; - updatedEntities = new List(world.UpdatedObjects); - updatedEntityCount = updatedEntities.Count; - world.UpdatedObjects.Clear(); + - collidersCount = world.UpdatedCollisions.Count; - colliders = new List(world.UpdatedCollisions); - - world.UpdatedCollisions.Clear(); m_collisionsThisFrame = 0; int numManifolds = world.GetDispatcher().GetNumManifolds(); for (int j = 0; j < numManifolds; j++) @@ -1493,16 +1683,31 @@ private sealed class BulletConstraintXNA : BulletConstraint } + updatedEntityCount = world.LastEntityProperty; + updatedEntities = GetBulletSimEntityStruct(BulletXNAEntityStructToByteArray(world.UpdatedObjects, world.LastEntityProperty)); + + + + + collidersCount = world.LastCollisionDesc; + colliders = + GetBulletSimCollisionStruct(BulletXNACollisionStructToByteArray(world.UpdatedCollisions, world.LastCollisionDesc));//new List(world.UpdatedCollisions); } else { //if (updatedEntities is null) - updatedEntities = new List(); - updatedEntityCount = 0; + //updatedEntities = new List(); + //updatedEntityCount = 0; //if (colliders is null) - colliders = new List(); - collidersCount = 0; + //colliders = new List(); + //collidersCount = 0; + + updatedEntities = new EntityProperties[0]; + + + colliders = new CollisionDesc[0]; + } return numSimSteps; } @@ -1535,22 +1740,23 @@ private sealed class BulletConstraintXNA : BulletConstraint point = contact, normal = contactNormal }; - world.UpdatedCollisions.Add(cDesc); + if (world.LastCollisionDesc < world.UpdatedCollisions.Length) + world.UpdatedCollisions[world.LastCollisionDesc++] = (cDesc); m_collisionsThisFrame++; } - private static EntityProperties GetDebugProperties(BulletWorld pWorld, BulletBody pBody) + private static EntityProperties GetDebugProperties(BulletWorld pWorld, BulletBody pCollisionObject) { EntityProperties ent = new EntityProperties(); - DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; - RigidBody body = ((BulletBodyXNA)pBody).rigidBody; - IndexedMatrix transform = body.GetWorldTransform(); - IndexedVector3 LinearVelocity = body.GetInterpolationLinearVelocity(); - IndexedVector3 AngularVelocity = body.GetInterpolationAngularVelocity(); + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + IndexedMatrix transform = collisionObject.GetWorldTransform(); + IndexedVector3 LinearVelocity = collisionObject.GetInterpolationLinearVelocity(); + IndexedVector3 AngularVelocity = collisionObject.GetInterpolationAngularVelocity(); IndexedQuaternion rotation = transform.GetRotation(); ent.Acceleration = Vector3.Zero; - ent.ID = (uint)body.GetUserPointer(); + ent.ID = (uint)collisionObject.GetUserPointer(); ent.Position = new Vector3(transform._origin.X,transform._origin.Y,transform._origin.Z); ent.Rotation = new Quaternion(rotation.X,rotation.Y,rotation.Z,rotation.W); ent.Velocity = new Vector3(LinearVelocity.X, LinearVelocity.Y, LinearVelocity.Z); @@ -1562,19 +1768,19 @@ private sealed class BulletConstraintXNA : BulletConstraint public override Vector3 GetLocalScaling(BulletShape pShape) { - CollisionShape shape = ((BulletShapeXNA)pShape).shape; + CollisionShape shape = (pShape as BulletShapeXNA).shape; IndexedVector3 scale = shape.GetLocalScaling(); return new Vector3(scale.X,scale.Y,scale.Z); } public bool RayCastGround(BulletWorld pWorld, Vector3 _RayOrigin, float pRayHeight, BulletBody NotMe) { - DiscreteDynamicsWorld world = ((BulletWorldXNA)pWorld).world; + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; if (world != null) { if (NotMe is BulletBodyXNA && NotMe.HasPhysicalBody) { - CollisionObject AvoidBody = ((BulletBodyXNA)NotMe).body; + CollisionObject AvoidBody = (NotMe as BulletBodyXNA).body; IndexedVector3 rOrigin = new IndexedVector3(_RayOrigin.X, _RayOrigin.Y, _RayOrigin.Z); IndexedVector3 rEnd = new IndexedVector3(_RayOrigin.X, _RayOrigin.Y, _RayOrigin.Z - pRayHeight); @@ -1594,5 +1800,160 @@ private sealed class BulletConstraintXNA : BulletConstraint } return false; } + + public static unsafe BulletXNA.CollisionDesc[] GetBulletXNACollisionStruct(byte[] buffer) + { + int count = buffer.Length/sizeof (BulletXNA.CollisionDesc); + BulletXNA.CollisionDesc[] result = new BulletXNA.CollisionDesc[count]; + BulletXNA.CollisionDesc* ptr; + fixed (byte* localBytes = new byte[buffer.Length]) + { + for (int i = 0; i < buffer.Length; i++) + { + localBytes[i] = buffer[i]; + } + for (int i=0;i count ? count : CollisionDescArray.Length; + byte[] byteArray = new byte[sizeof(CollisionDesc) * arrayLength]; + fixed (CollisionDesc* floatPointer = CollisionDescArray) + { + fixed (byte* bytePointer = byteArray) + { + CollisionDesc* read = floatPointer; + CollisionDesc* write = (CollisionDesc*)bytePointer; + for (int i = 0; i < arrayLength; i++) + { + *write++ = *read++; + } + } + } + return byteArray; + } + public static unsafe byte[] BulletXNACollisionStructToByteArray(BulletXNA.CollisionDesc[] CollisionDescArray, int count) + { + int arrayLength = CollisionDescArray.Length > count ? count : CollisionDescArray.Length; + byte[] byteArray = new byte[sizeof(BulletXNA.CollisionDesc) * arrayLength]; + fixed (BulletXNA.CollisionDesc* floatPointer = CollisionDescArray) + { + fixed (byte* bytePointer = byteArray) + { + BulletXNA.CollisionDesc* read = floatPointer; + BulletXNA.CollisionDesc* write = (BulletXNA.CollisionDesc*)bytePointer; + for (int i = 0; i < arrayLength; i++) + { + *write++ = *read++; + } + } + } + return byteArray; + } + public static unsafe BulletXNA.EntityProperties[] GetBulletXNAEntityStruct(byte[] buffer) + { + int count = buffer.Length / sizeof(BulletXNA.EntityProperties); + BulletXNA.EntityProperties[] result = new BulletXNA.EntityProperties[count]; + BulletXNA.EntityProperties* ptr; + fixed (byte* localBytes = new byte[buffer.Length]) + { + for (int i = 0; i < buffer.Length; i++) + { + localBytes[i] = buffer[i]; + } + for (int i = 0; i < count; i++) + { + ptr = (BulletXNA.EntityProperties*)(localBytes + sizeof(BulletXNA.EntityProperties) * i); + result[i] = new BulletXNA.EntityProperties(); + result[i] = *ptr; + } + } + return result; + } + + public static unsafe EntityProperties[] GetBulletSimEntityStruct(byte[] buffer) + { + int count = buffer.Length / sizeof(EntityProperties); + EntityProperties[] result = new EntityProperties[count]; + EntityProperties* ptr; + fixed (byte* localBytes = new byte[buffer.Length]) + { + for (int i = 0; i < buffer.Length; i++) + { + localBytes[i] = buffer[i]; + } + for (int i = 0; i < count; i++) + { + ptr = (EntityProperties*)(localBytes + sizeof(EntityProperties) * i); + result[i] = new EntityProperties(); + result[i] = *ptr; + } + } + return result; + } + public static unsafe byte[] BulletSimEntityStructToByteArray(EntityProperties[] CollisionDescArray, int count) + { + int arrayLength = CollisionDescArray.Length > count ? count : CollisionDescArray.Length; + byte[] byteArray = new byte[sizeof(EntityProperties) * arrayLength]; + fixed (EntityProperties* floatPointer = CollisionDescArray) + { + fixed (byte* bytePointer = byteArray) + { + EntityProperties* read = floatPointer; + EntityProperties* write = (EntityProperties*)bytePointer; + for (int i = 0; i < arrayLength; i++) + { + *write++ = *read++; + } + } + } + return byteArray; + } + public static unsafe byte[] BulletXNAEntityStructToByteArray(BulletXNA.EntityProperties[] CollisionDescArray, int count) + { + int arrayLength = CollisionDescArray.Length > count ? count : CollisionDescArray.Length; + byte[] byteArray = new byte[sizeof(BulletXNA.EntityProperties) * arrayLength]; + fixed (BulletXNA.EntityProperties* floatPointer = CollisionDescArray) + { + fixed (byte* bytePointer = byteArray) + { + BulletXNA.EntityProperties* read = floatPointer; + BulletXNA.EntityProperties* write = (BulletXNA.EntityProperties*)bytePointer; + for (int i = 0; i < arrayLength; i++) + { + *write++ = *read++; + } + } + } + return byteArray; + } } } -- cgit v1.1 From 3b0df52d10c157cd2711d64ef9007d2afccbd468 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 20 Jan 2013 09:33:13 -0800 Subject: BulletSim: modify motors to return correction rather than current value to better use them for incremental updates. Modify prim and character to use the new motors. Simplify the vehicle linear movement code to just update the velocity directly or the basic movement. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 3 +- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 41 ++++++++-------------- OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 25 ++++++++----- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 2 +- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 3 ++ 5 files changed, 36 insertions(+), 38 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 478aeab..696c4bd 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -198,7 +198,8 @@ public sealed class BSCharacter : BSPhysObject // TODO: Decide if the step parameters should be changed depending on the avatar's // state (flying, colliding, ...). There is code in ODE to do this. - OMV.Vector3 stepVelocity = _velocityMotor.Step(timeStep); + _velocityMotor.Step(timeStep); + OMV.Vector3 stepVelocity = _velocityMotor.CurrentValue; // If falling, we keep the world's downward vector no matter what the other axis specify. if (!Flying && !IsColliding) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index f2c7cec..7c9b83b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -957,39 +957,25 @@ namespace OpenSim.Region.Physics.BulletSPlugin public void ComputeLinearVelocity(float pTimestep) { - Vector3 linearMotorStep = m_linearMotor.Step(pTimestep); + // Step the motor from the current value. Get the correction needed this step. + Vector3 currentVel = VehicleVelocity * Quaternion.Inverse(VehicleOrientation); + Vector3 linearMotorCorrection = m_linearMotor.Step(pTimestep, currentVel); - // The movement computed in the linear motor is relative to the vehicle - // coordinates. Rotate the movement to world coordinates. - Vector3 linearMotorVelocity = linearMotorStep * VehicleOrientation; + // Motor is vehicle coordinates. Rotate it to world coordinates + Vector3 linearMotorVelocity = linearMotorCorrection * VehicleOrientation; - // If we're a ground vehicle, don't loose any Z action (like gravity acceleration). - float mixFactor = 1f; // 1 means use all linear motor Z value, 0 means use all existing Z + // If we're a ground vehicle, don't add any upward Z movement if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0) { - if (!Prim.IsColliding) - { - // If a ground vehicle and not on the ground, I want gravity effect - mixFactor = 0.2f; - } - } - else - { - // I'm not a ground vehicle but don't totally loose the effect of the environment - mixFactor = 0.8f; + if (linearMotorVelocity.Z > 0f) + linearMotorVelocity.Z = 0f; } - linearMotorVelocity.Z = mixFactor * linearMotorVelocity.Z + (1f - mixFactor) * VehicleVelocity.Z; - - // What we want to contribute to the vehicle's existing velocity - Vector3 linearMotorForce = linearMotorVelocity - VehicleVelocity; - - // Act against the inertia of the vehicle - linearMotorForce *= m_vehicleMass; - VehicleAddForceImpulse(linearMotorForce * pTimestep); + // Add this correction to the velocity to make it faster/slower. + VehicleVelocity += linearMotorVelocity; - VDetailLog("{0}, MoveLinear,velocity,vehVel={1},step={2},stepVel={3},mix={4},force={5}", - Prim.LocalID, VehicleVelocity, linearMotorStep, linearMotorVelocity, mixFactor, linearMotorForce); + VDetailLog("{0}, MoveLinear,velocity,vehVel={1},correction={2},force={3}", + Prim.LocalID, VehicleVelocity, linearMotorCorrection, linearMotorVelocity); } public void ComputeLinearTerrainHeightCorrection(float pTimestep) @@ -1204,6 +1190,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { // The user wants this many radians per second angular change? Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); + angularMotorContribution = m_angularMotor.CurrentValue; // ================================================================== // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags : @@ -1234,7 +1221,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin + deflectionContribution + bankingContribution; - // Add of the above computation are made relative to vehicle coordinates. + // All of the above computation are made relative to vehicle coordinates. // Convert to world coordinates. m_lastAngularVelocity *= VehicleOrientation; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index 6d0db2e..82fd2d2 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -138,7 +138,8 @@ public class BSVMotor : BSMotor CurrentValue = TargetValue = Vector3.Zero; } - // Compute the next step and return the new current value + // Compute the next step and return the new current value. + // Returns the correction needed to move 'current' to 'target'. public virtual Vector3 Step(float timeStep) { if (!Enabled) return TargetValue; @@ -150,7 +151,7 @@ public class BSVMotor : BSMotor Vector3 error = TargetValue - CurrentValue; if (!ErrorIsZero(error)) { - correction = Step(timeStep, error); + correction = StepError(timeStep, error); CurrentValue += correction; @@ -187,14 +188,20 @@ public class BSVMotor : BSMotor else { // Difference between what we have and target is small. Motor is done. - CurrentValue = TargetValue; + CurrentValue = TargetValue = Vector3.Zero; MDetailLog("{0}, BSVMotor.Step,zero,{1},origTgt={2},origCurr={3},ret={4}", BSScene.DetailLogZero, UseName, origCurrVal, origTarget, CurrentValue); } - return CurrentValue; + return correction; + } + // version of step that sets the current value before doing the step + public virtual Vector3 Step(float timeStep, Vector3 current) + { + CurrentValue = current; + return Step(timeStep); } - public virtual Vector3 Step(float timeStep, Vector3 error) + public virtual Vector3 StepError(float timeStep, Vector3 error) { if (!Enabled) return Vector3.Zero; @@ -304,7 +311,7 @@ public class BSFMotor : BSMotor float error = TargetValue - CurrentValue; if (!ErrorIsZero(error)) { - correction = Step(timeStep, error); + correction = StepError(timeStep, error); CurrentValue += correction; @@ -347,7 +354,7 @@ public class BSFMotor : BSMotor return CurrentValue; } - public virtual float Step(float timeStep, float error) + public virtual float StepError(float timeStep, float error) { if (!Enabled) return 0f; @@ -440,8 +447,8 @@ public class BSPIDVMotor : BSVMotor } } - // Ignore Current and Target Values and just advance the PID computation on this error. - public override Vector3 Step(float timeStep, Vector3 error) + // Advance the PID computation on this error. + public override Vector3 StepError(float timeStep, Vector3 error) { if (!Enabled) return Vector3.Zero; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index aaa6fe5..22afdc9 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -1082,7 +1082,7 @@ public sealed class BSPrim : BSPhysObject OMV.Vector3 origPosition = RawPosition; // DEBUG DEBUG (for printout below) // 'movePosition' is where we'd like the prim to be at this moment. - OMV.Vector3 movePosition = _targetMotor.Step(timeStep); + OMV.Vector3 movePosition = RawPosition + _targetMotor.Step(timeStep); // If we are very close to our target, turn off the movement motor. if (_targetMotor.ErrorIsZero()) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 9bfec19..23b7ca8 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -74,7 +74,10 @@ Incorporate inter-relationship of angular corrections. For instance, angularDefl GENERAL TODO LIST: ================================================= Implement llSetPhysicalMaterial. + extend it with Center-of-mass, rolling friction, density Implement llSetForceAndTorque. +Change BSPrim.moveToTarget to used forces rather than changing position + Changing position allows one to move through walls Implement an avatar mesh shape. The Bullet capsule is way too limited. Consider just hand creating a vertex/index array in a new BSShapeAvatar. Verify/fix phantom, volume-detect objects do not fall to infinity. Should stop at terrain. -- cgit v1.1 From 2cb1d5240e41639b9c84aa6607aab0df49f353a7 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 20 Jan 2013 13:11:00 -0800 Subject: BulletSim: small fix making sure terrain height is calculated properly if the vehicle moves during vehicle actions. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 7c9b83b..388d4f9 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -720,10 +720,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Since the computation of terrain height can be a little involved, this routine // is used to fetch the height only once for each vehicle simulation step. + Vector3 lastRememberedHeightPos; private float GetTerrainHeight(Vector3 pos) { - if ((m_knownHas & m_knownChangedTerrainHeight) == 0) + if ((m_knownHas & m_knownChangedTerrainHeight) == 0 || pos != lastRememberedHeightPos) { + lastRememberedHeightPos = pos; m_knownTerrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); m_knownHas |= m_knownChangedTerrainHeight; } -- cgit v1.1 From 3c4868f61362c2c86cef9f98e197362f57ca627b Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 20 Jan 2013 19:13:18 -0800 Subject: BulletSim: fix problem of avatar sliding very slowly occasionally after stopping walking. Consolidate movement tests into the one prestep motion action --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 75 ++++++++++++---------- 1 file changed, 41 insertions(+), 34 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 696c4bd..cd279e3 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -56,6 +56,7 @@ public sealed class BSCharacter : BSPhysObject private int _physicsActorType; private bool _isPhysical; private bool _flying; + private bool _wasWalking; // 'true' if the avatar was walking/moving last frame private bool _setAlwaysRun; private bool _throttleUpdates; private bool _floatOnWater; @@ -83,6 +84,7 @@ public sealed class BSCharacter : BSPhysObject _position = pos; _flying = isFlying; + _wasWalking = true; // causes first step to initialize standing _orientation = OMV.Quaternion.Identity; _velocity = OMV.Vector3.Zero; _buoyancy = ComputeBuoyancyFromFlying(isFlying); @@ -199,25 +201,51 @@ public sealed class BSCharacter : BSPhysObject // state (flying, colliding, ...). There is code in ODE to do this. _velocityMotor.Step(timeStep); - OMV.Vector3 stepVelocity = _velocityMotor.CurrentValue; - // If falling, we keep the world's downward vector no matter what the other axis specify. - if (!Flying && !IsColliding) + // If we're not supposed to be moving, make sure things are zero. + if (_velocityMotor.ErrorIsZero() && _velocityMotor.TargetValue.ApproxEquals(OMV.Vector3.Zero, 0.01f)) { - stepVelocity.Z = _velocity.Z; - // DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity); + if (_wasWalking) + { + _velocityMotor.Zero(); + _velocity = OMV.Vector3.Zero; + PhysicsScene.PE.SetLinearVelocity(PhysBody, OMV.Vector3.Zero); + _currentFriction = BSParam.AvatarStandingFriction; + PhysicsScene.PE.SetFriction(PhysBody, _currentFriction); + // DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1}", LocalID, _velocityMotor.TargetValue); + } + _wasWalking = false; } + else + { + OMV.Vector3 stepVelocity = _velocityMotor.CurrentValue; + + if (_currentFriction != BSParam.AvatarFriction) + { + // Probably starting up walking. Set friction to moving friction. + _currentFriction = BSParam.AvatarFriction; + PhysicsScene.PE.SetFriction(PhysBody, _currentFriction); + } - // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force. - OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass; + // If falling, we keep the world's downward vector no matter what the other axis specify. + if (!Flying && !IsColliding) + { + stepVelocity.Z = _velocity.Z; + // DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity); + } + + // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force. + OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass; - // Should we check for move force being small and forcing velocity to zero? + // Should we check for move force being small and forcing velocity to zero? - // Add special movement force to allow avatars to walk up stepped surfaces. - moveForce += WalkUpStairs(); + // Add special movement force to allow avatars to walk up stepped surfaces. + moveForce += WalkUpStairs(); - // DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); - PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce); + // DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); + PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce); + _wasWalking = true; + } }); } @@ -560,27 +588,6 @@ public sealed class BSCharacter : BSPhysObject PhysicsScene.AssertInTaintTime("BSCharacter.ForceVelocity"); _velocity = value; - // Depending on whether the avatar is moving or not, change the friction - // to keep the avatar from slipping around - if (_velocity.Length() == 0) - { - if (_currentFriction != BSParam.AvatarStandingFriction) - { - _currentFriction = BSParam.AvatarStandingFriction; - if (PhysBody.HasPhysicalBody) - PhysicsScene.PE.SetFriction(PhysBody, _currentFriction); - } - } - else - { - if (_currentFriction != BSParam.AvatarFriction) - { - _currentFriction = BSParam.AvatarFriction; - if (PhysBody.HasPhysicalBody) - PhysicsScene.PE.SetFriction(PhysBody, _currentFriction); - } - } - PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity); PhysicsScene.PE.Activate(PhysBody, true); } @@ -855,7 +862,7 @@ public sealed class BSCharacter : BSPhysObject _position = entprop.Position; _orientation = entprop.Rotation; - // Smooth velocity. OpenSimulator is very sensitive to changes in velocity of the avatar + // Smooth velocity. OpenSimulator is VERY sensitive to changes in velocity of the avatar // and will send agent updates to the clients if velocity changes by more than // 0.001m/s. Bullet introduces a lot of jitter in the velocity which causes many // extra updates. -- cgit v1.1 From 52b341e2e24384395fddc7d32fd66358f5062468 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 20 Jan 2013 22:35:42 -0800 Subject: BulletSim: More aggressive as setting character velocity to zero when should be standing. Modify angular force routines to be the same pattern as linear force routines. BulletSim vehicle turning is scaled like SL and is DIFFERENT THAN ODE!! Fix some bugs in BSMotor dealing with the motor going to zero. Add a bunch of parameters: MaxLinearVelocity, MaxAngularVelocity, MaxAddForceMagnitude, VehicleMaxLinearVelocity, VehicleMaxAngularVelocity, and most of the values are defaulted to values that are larger than in SL. Use the new parameters in BSPrim, BSCharacter and BSDynamic. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 30 ++++- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 143 ++++++++++----------- OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 26 +++- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 32 ++++- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 13 +- 5 files changed, 153 insertions(+), 91 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index cd279e3..a9e16e6 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -200,20 +200,36 @@ public sealed class BSCharacter : BSPhysObject // TODO: Decide if the step parameters should be changed depending on the avatar's // state (flying, colliding, ...). There is code in ODE to do this. + // COMMENTARY: when the user is making the avatar walk, except for falling, the velocity + // specified for the avatar is the one that should be used. For falling, if the avatar + // is not flying and is not colliding then it is presumed to be falling and the Z + // component is not fooled with (thus allowing gravity to do its thing). + // When the avatar is standing, though, the user has specified a velocity of zero and + // the avatar should be standing. But if the avatar is pushed by something in the world + // (raising elevator platform, moving vehicle, ...) the avatar should be allowed to + // move. Thus, the velocity cannot be forced to zero. The problem is that small velocity + // errors can creap in and the avatar will slowly float off in some direction. + // So, the problem is that, when an avatar is standing, we cannot tell creaping error + // from real pushing.OMV.Vector3.Zero; + // The code below keeps setting the velocity to zero hoping the world will keep pushing. + _velocityMotor.Step(timeStep); // If we're not supposed to be moving, make sure things are zero. - if (_velocityMotor.ErrorIsZero() && _velocityMotor.TargetValue.ApproxEquals(OMV.Vector3.Zero, 0.01f)) + if (_velocityMotor.ErrorIsZero() && _velocityMotor.TargetValue == OMV.Vector3.Zero && IsColliding) { - if (_wasWalking) + // The avatar shouldn't be moving + _velocityMotor.Zero(); + ZeroMotion(true /* inTaintTime */); + + // Standing has more friction on the ground + if (_currentFriction != BSParam.AvatarStandingFriction) { - _velocityMotor.Zero(); - _velocity = OMV.Vector3.Zero; - PhysicsScene.PE.SetLinearVelocity(PhysBody, OMV.Vector3.Zero); _currentFriction = BSParam.AvatarStandingFriction; PhysicsScene.PE.SetFriction(PhysBody, _currentFriction); - // DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1}", LocalID, _velocityMotor.TargetValue); } + DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1}", LocalID, _velocityMotor.TargetValue); + _wasWalking = false; } else @@ -242,7 +258,7 @@ public sealed class BSCharacter : BSPhysObject // Add special movement force to allow avatars to walk up stepped surfaces. moveForce += WalkUpStairs(); - // DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); + DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce); _wasWalking = true; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 388d4f9..f8fc3de 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -231,6 +231,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin break; case Vehicle.ANGULAR_MOTOR_DIRECTION: m_angularMotorDirection = new Vector3(pValue, pValue, pValue); + m_angularMotor.Zero(); m_angularMotor.SetTarget(m_angularMotorDirection); break; case Vehicle.LINEAR_FRICTION_TIMESCALE: @@ -264,6 +265,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin pValue.Y = ClampInRange(-12.56f, pValue.Y, 12.56f); pValue.Z = ClampInRange(-12.56f, pValue.Z, 12.56f); m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); + m_angularMotor.Zero(); m_angularMotor.SetTarget(m_angularMotorDirection); break; case Vehicle.LINEAR_FRICTION_TIMESCALE: @@ -945,10 +947,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ================================================================== // Clamp high or low velocities float newVelocityLengthSq = VehicleVelocity.LengthSquared(); - if (newVelocityLengthSq > 1000f) + if (newVelocityLengthSq > BSParam.VehicleMaxLinearVelocity) { VehicleVelocity /= VehicleVelocity.Length(); - VehicleVelocity *= 1000f; + VehicleVelocity *= BSParam.VehicleMaxLinearVelocity; } else if (newVelocityLengthSq < 0.001f) VehicleVelocity = Vector3.Zero; @@ -1190,63 +1192,33 @@ namespace OpenSim.Region.Physics.BulletSPlugin // set directly on the vehicle. private void MoveAngular(float pTimestep) { - // The user wants this many radians per second angular change? - Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); - angularMotorContribution = m_angularMotor.CurrentValue; + VehicleRotationalVelocity = Vector3.Zero; - // ================================================================== - // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags : - // This flag prevents linear deflection parallel to world z-axis. This is useful - // for preventing ground vehicles with large linear deflection, like bumper cars, - // from climbing their linear deflection into the sky. - // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement - // TODO: This is here because this is where ODE put it but documentation says it - // is a linear effect. Where should this check go? - if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) - { - angularMotorContribution.X = 0f; - angularMotorContribution.Y = 0f; - VDetailLog("{0}, MoveAngular,noDeflectionUp,angularMotorContrib={1}", Prim.LocalID, angularMotorContribution); - } + ComputeAngularTurning(pTimestep); - Vector3 verticalAttractionContribution = ComputeAngularVerticalAttraction(); + ComputeAngularVerticalAttraction(); - Vector3 deflectionContribution = ComputeAngularDeflection(); + ComputeAngularDeflection(); - Vector3 bankingContribution = ComputeAngularBanking(); + ComputeAngularBanking(); // ================================================================== - m_lastVertAttractor = verticalAttractionContribution; - - m_lastAngularVelocity = angularMotorContribution - + verticalAttractionContribution - + deflectionContribution - + bankingContribution; - // All of the above computation are made relative to vehicle coordinates. // Convert to world coordinates. - m_lastAngularVelocity *= VehicleOrientation; + // TODO: Should this be applied as an angular force (torque)? + VehicleRotationalVelocity *= VehicleOrientation; // ================================================================== - // Apply the correction velocity. - // TODO: Should this be applied as an angular force (torque)? - if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) - { - VehicleRotationalVelocity = m_lastAngularVelocity; - - VDetailLog("{0}, MoveAngular,done,nonZero,angMotorContrib={1},vertAttrContrib={2},bankContrib={3},deflectContrib={4},totalContrib={5}", - Prim.LocalID, - angularMotorContribution, verticalAttractionContribution, - bankingContribution, deflectionContribution, - m_lastAngularVelocity - ); - } - else + if (VehicleRotationalVelocity.ApproxEquals(Vector3.Zero, 0.01f)) { // The vehicle is not adding anything angular wise. VehicleRotationalVelocity = Vector3.Zero; VDetailLog("{0}, MoveAngular,done,zero", Prim.LocalID); } + else + { + VDetailLog("{0}, MoveAngular,done,nonZero,angVel={1}", Prim.LocalID, VehicleRotationalVelocity); + } // ================================================================== //Offset section @@ -1280,6 +1252,30 @@ namespace OpenSim.Region.Physics.BulletSPlugin } } + + private void ComputeAngularTurning(float pTimestep) + { + // The user wants this many radians per second angular change? + Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); + + // ================================================================== + // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags : + // This flag prevents linear deflection parallel to world z-axis. This is useful + // for preventing ground vehicles with large linear deflection, like bumper cars, + // from climbing their linear deflection into the sky. + // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement + // TODO: This is here because this is where ODE put it but documentation says it + // is a linear effect. Where should this check go? + if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) + { + angularMotorContribution.X = 0f; + angularMotorContribution.Y = 0f; + } + + VehicleRotationalVelocity += angularMotorContribution; + VDetailLog("{0}, MoveAngular,angularTurning,angularMotorContrib={1}", Prim.LocalID, angularMotorContribution); + } + // From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial: // Some vehicles, like boats, should always keep their up-side up. This can be done by // enabling the "vertical attractor" behavior that springs the vehicle's local z-axis to @@ -1288,13 +1284,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin // and then set the VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY to control the damping. An // efficiency of 0.0 will cause the spring to wobble around its equilibrium, while an // efficiency of 1.0 will cause the spring to reach its equilibrium with exponential decay. - public Vector3 ComputeAngularVerticalAttraction() + public void ComputeAngularVerticalAttraction() { - Vector3 ret = Vector3.Zero; - // If vertical attaction timescale is reasonable if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff) { + Vector3 vertContribution = Vector3.Zero; + // Take a vector pointing up and convert it from world to vehicle relative coords. Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; @@ -1308,37 +1304,36 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Y error means needed rotation around X axis and visa versa. // Since the error goes from zero to one, the asin is the corresponding angle. - ret.X = (float)Math.Asin(verticalError.Y); + vertContribution.X = (float)Math.Asin(verticalError.Y); // (Tilt forward (positive X) needs to tilt back (rotate negative) around Y axis.) - ret.Y = -(float)Math.Asin(verticalError.X); + vertContribution.Y = -(float)Math.Asin(verticalError.X); // If verticalError.Z is negative, the vehicle is upside down. Add additional push. if (verticalError.Z < 0f) { - ret.X += PIOverFour; - ret.Y += PIOverFour; + vertContribution.X += PIOverFour; + vertContribution.Y += PIOverFour; } - // 'ret' is now the necessary velocity to correct tilt in one second. + // 'vertContrbution' is now the necessary angular correction to correct tilt in one second. // Correction happens over a number of seconds. - Vector3 unscaledContrib = ret; - ret /= m_verticalAttractionTimescale; + Vector3 unscaledContrib = vertContribution; // DEBUG DEBUG + vertContribution /= m_verticalAttractionTimescale; + + VehicleRotationalVelocity += vertContribution; VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},eff={3},ts={4},vertAttr={5}", - Prim.LocalID, verticalError, unscaledContrib, m_verticalAttractionEfficiency, m_verticalAttractionTimescale, ret); + Prim.LocalID, verticalError, unscaledContrib, m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContribution); } - return ret; } - // Return the angular correction to correct the direction the vehicle is pointing to be + // Angular correction to correct the direction the vehicle is pointing to be // the direction is should want to be pointing. // The vehicle is moving in some direction and correct its orientation to it is pointing // in that direction. // TODO: implement reference frame. - public Vector3 ComputeAngularDeflection() + public void ComputeAngularDeflection() { - Vector3 ret = Vector3.Zero; - // Since angularMotorUp and angularDeflection are computed independently, they will calculate // approximately the same X or Y correction. When added together (when contributions are combined) // this creates an over-correction and then wabbling as the target is overshot. @@ -1346,6 +1341,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2) { + Vector3 deflectContribution = Vector3.Zero; + // The direction the vehicle is moving Vector3 movingDirection = VehicleVelocity; movingDirection.Normalize(); @@ -1371,18 +1368,19 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ret = m_angularDeflectionCorrectionMotor(1f, deflectionError); // Scale the correction by recovery timescale and efficiency - ret = (-deflectionError) * m_angularDeflectionEfficiency; - ret /= m_angularDeflectionTimescale; + deflectContribution = (-deflectionError) * m_angularDeflectionEfficiency; + deflectContribution /= m_angularDeflectionTimescale; + + VehicleRotationalVelocity += deflectContribution; VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}", - Prim.LocalID, movingDirection, pointingDirection, deflectionError, ret); + Prim.LocalID, movingDirection, pointingDirection, deflectionError, deflectContribution); VDetailLog("{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3}", Prim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale); } - return ret; } - // Return an angular change to rotate the vehicle around the Z axis when the vehicle + // Angular change to rotate the vehicle around the Z axis when the vehicle // is tipped around the X axis. // From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial: // The vertical attractor feature must be enabled in order for the banking behavior to @@ -1413,12 +1411,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin // world z-axis is determined by the VEHICLE_BANKING_TIMESCALE. So if you want the vehicle to // bank quickly then give it a banking timescale of about a second or less, otherwise you can // make a sluggish vehicle by giving it a timescale of several seconds. - public Vector3 ComputeAngularBanking() + public void ComputeAngularBanking() { - Vector3 ret = Vector3.Zero; - if (enableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) { + Vector3 bankingContribution = Vector3.Zero; + // Rotate a UnitZ vector (pointing up) to how the vehicle is oriented. // As the vehicle rolls to the right or left, the Y value will increase from // zero (straight up) to 1 or -1 (full tilt right or left) @@ -1435,15 +1433,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin mixedYawAngle = ClampInRange(-20f, mixedYawAngle, 20f); // Build the force vector to change rotation from what it is to what it should be - ret.Z = -mixedYawAngle; + bankingContribution.Z = -mixedYawAngle; // Don't do it all at once. - ret /= m_bankingTimescale; + bankingContribution /= m_bankingTimescale; + + VehicleRotationalVelocity += bankingContribution; VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},rollComp={3},yAng={4},mYAng={5},ret={6}", - Prim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, ret); + Prim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, bankingContribution); } - return ret; } // This is from previous instantiations of XXXDynamics.cs. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index 82fd2d2..9501e2d 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -149,6 +149,7 @@ public class BSVMotor : BSMotor Vector3 correction = Vector3.Zero; Vector3 error = TargetValue - CurrentValue; + LastError = error; if (!ErrorIsZero(error)) { correction = StepError(timeStep, error); @@ -188,9 +189,15 @@ public class BSVMotor : BSMotor else { // Difference between what we have and target is small. Motor is done. - CurrentValue = TargetValue = Vector3.Zero; - MDetailLog("{0}, BSVMotor.Step,zero,{1},origTgt={2},origCurr={3},ret={4}", - BSScene.DetailLogZero, UseName, origCurrVal, origTarget, CurrentValue); + if (TargetValue.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)) + { + // The target can step down to nearly zero but not get there. If close to zero + // it is really zero. + TargetValue = Vector3.Zero; + } + CurrentValue = TargetValue; + MDetailLog("{0}, BSVMotor.Step,zero,{1},origTgt={2},origCurr={3},currTgt={4},currCurr={5}", + BSScene.DetailLogZero, UseName, origCurrVal, origTarget, TargetValue, CurrentValue); } return correction; @@ -205,9 +212,8 @@ public class BSVMotor : BSMotor { if (!Enabled) return Vector3.Zero; - LastError = error; Vector3 returnCorrection = Vector3.Zero; - if (!ErrorIsZero()) + if (!ErrorIsZero(error)) { // correction = error / secondsItShouldTakeToCorrect Vector3 correctionAmount; @@ -309,6 +315,7 @@ public class BSFMotor : BSMotor float correction = 0f; float error = TargetValue - CurrentValue; + LastError = error; if (!ErrorIsZero(error)) { correction = StepError(timeStep, error); @@ -346,6 +353,12 @@ public class BSFMotor : BSMotor else { // Difference between what we have and target is small. Motor is done. + if (Util.InRange(TargetValue, -ErrorZeroThreshold, ErrorZeroThreshold)) + { + // The target can step down to nearly zero but not get there. If close to zero + // it is really zero. + TargetValue = 0f; + } CurrentValue = TargetValue; MDetailLog("{0}, BSFMotor.Step,zero,{1},origTgt={2},origCurr={3},ret={4}", BSScene.DetailLogZero, UseName, origCurrVal, origTarget, CurrentValue); @@ -358,9 +371,8 @@ public class BSFMotor : BSMotor { if (!Enabled) return 0f; - LastError = error; float returnCorrection = 0f; - if (!ErrorIsZero()) + if (!ErrorIsZero(error)) { // correction = error / secondsItShouldTakeToCorrect float correctionAmount; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 3e80aa4..6a92365 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -45,6 +45,9 @@ public static class BSParam public static float MinimumObjectMass { get; private set; } public static float MaximumObjectMass { get; private set; } + public static float MaxLinearVelocity { get; private set; } + public static float MaxAngularVelocity { get; private set; } + public static float MaxAddForceMagnitude { get; private set; } public static float LinearDamping { get; private set; } public static float AngularDamping { get; private set; } @@ -79,6 +82,8 @@ public static class BSParam public static float AvatarStepApproachFactor { get; private set; } public static float AvatarStepForceFactor { get; private set; } + public static float VehicleMaxLinearVelocity { get; private set; } + public static float VehicleMaxAngularVelocity { get; private set; } public static float VehicleAngularDamping { get; private set; } public static float VehicleDebuggingEnabled { get; private set; } @@ -103,7 +108,6 @@ public static class BSParam public const float MaxDensity = 22587f; public const float MinRestitution = 0f; public const float MaxRestitution = 1f; - public const float MaxAddForceMagnitude = 20f; // =========================================================================== public delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val); @@ -247,6 +251,22 @@ public static class BSParam (s,cf,p,v) => { MaximumObjectMass = cf.GetFloat(p, v); }, (s) => { return (float)MaximumObjectMass; }, (s,p,l,v) => { MaximumObjectMass = v; } ), + new ParameterDefn("MaxLinearVelocity", "Maximum velocity magnitude that can be assigned to an object", + 1000.0f, + (s,cf,p,v) => { MaxLinearVelocity = cf.GetFloat(p, v); }, + (s) => { return (float)MaxLinearVelocity; }, + (s,p,l,v) => { MaxLinearVelocity = v; } ), + new ParameterDefn("MaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to an object", + 1000.0f, + (s,cf,p,v) => { MaxAngularVelocity = cf.GetFloat(p, v); }, + (s) => { return (float)MaxAngularVelocity; }, + (s,p,l,v) => { MaxAngularVelocity = v; } ), + // LL documentation says thie number should be 20f + new ParameterDefn("MaxAddForceMagnitude", "Maximum force that can be applied by llApplyImpulse (SL says 20f)", + 200.0f, + (s,cf,p,v) => { MaxAddForceMagnitude = cf.GetFloat(p, v); }, + (s) => { return (float)MaxAddForceMagnitude; }, + (s,p,l,v) => { MaxAddForceMagnitude = v; } ), new ParameterDefn("PID_D", "Derivitive factor for motion smoothing", 2200f, @@ -423,6 +443,16 @@ public static class BSParam (s) => { return AvatarStepForceFactor; }, (s,p,l,v) => { AvatarStepForceFactor = v; } ), + new ParameterDefn("VehicleMaxLinearVelocity", "Maximum velocity magnitude that can be assigned to a vehicle", + 1000.0f, + (s,cf,p,v) => { VehicleMaxLinearVelocity = cf.GetFloat(p, v); }, + (s) => { return (float)VehicleMaxLinearVelocity; }, + (s,p,l,v) => { VehicleMaxLinearVelocity = v; } ), + new ParameterDefn("VehicleMaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to a vehicle", + 12.0f, + (s,cf,p,v) => { VehicleMaxAngularVelocity = cf.GetFloat(p, v); }, + (s) => { return (float)VehicleMaxAngularVelocity; }, + (s,p,l,v) => { VehicleMaxAngularVelocity = v; } ), new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", 0.95f, (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); }, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 22afdc9..b63523c 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -989,10 +989,10 @@ public sealed class BSPrim : BSPhysObject } set { _rotationalVelocity = value; + Util.ClampV(_rotationalVelocity, BSParam.MaxAngularVelocity); // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); PhysicsScene.TaintedObject("BSPrim.setRotationalVelocity", delegate() { - DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); ForceRotationalVelocity = _rotationalVelocity; }); } @@ -1005,6 +1005,7 @@ public sealed class BSPrim : BSPhysObject _rotationalVelocity = value; if (PhysBody.HasPhysicalBody) { + DetailLog("{0},BSPrim.ForceRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); PhysicsScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity); ActivateIfPhysical(false); } @@ -1193,10 +1194,14 @@ public sealed class BSPrim : BSPhysObject public override float APIDDamping { set { return; } } public override void AddForce(OMV.Vector3 force, bool pushforce) { + // Per documentation, max force is limited. + OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude); + // Since this force is being applied in only one step, make this a force per second. - OMV.Vector3 addForce = force / PhysicsScene.LastTimeStep; - AddForce(addForce, pushforce, false); + addForce /= PhysicsScene.LastTimeStep; + AddForce(addForce, pushforce, false /* inTaintTime */); } + // Applying a force just adds this to the total force on the object. // This added force will only last the next simulation tick. public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { @@ -1205,9 +1210,9 @@ public sealed class BSPrim : BSPhysObject { if (force.IsFinite()) { - OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude); // DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); + OMV.Vector3 addForce = force; PhysicsScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() { // Bullet adds this central force to the total force for this tick -- cgit v1.1 From 3f6698a595593edc4027ff58cbebf947a6b5ac1f Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 21 Jan 2013 09:19:09 -0800 Subject: BulletSim: remove unused MaxTaintsToProcessPerStep parameter --- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 10 +++------- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 1 - OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | 2 ++ 3 files changed, 5 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 6a92365..2b4488a 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -236,11 +236,7 @@ public static class BSParam (s,cf,p,v) => { s.m_maxUpdatesPerFrame = cf.GetInt(p, (int)v); }, (s) => { return (float)s.m_maxUpdatesPerFrame; }, (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ), - new ParameterDefn("MaxTaintsToProcessPerStep", "Number of update taints to process before each simulation step", - 500f, - (s,cf,p,v) => { s.m_taintsToProcessPerStep = cf.GetInt(p, (int)v); }, - (s) => { return (float)s.m_taintsToProcessPerStep; }, - (s,p,l,v) => { s.m_taintsToProcessPerStep = (int)v; } ), + new ParameterDefn("MinObjectMass", "Minimum object mass (0.0001)", 0.0001f, (s,cf,p,v) => { MinimumObjectMass = cf.GetFloat(p, v); }, @@ -261,9 +257,9 @@ public static class BSParam (s,cf,p,v) => { MaxAngularVelocity = cf.GetFloat(p, v); }, (s) => { return (float)MaxAngularVelocity; }, (s,p,l,v) => { MaxAngularVelocity = v; } ), - // LL documentation says thie number should be 20f + // LL documentation says thie number should be 20f for llApplyImpulse and 200f for llRezObject new ParameterDefn("MaxAddForceMagnitude", "Maximum force that can be applied by llApplyImpulse (SL says 20f)", - 200.0f, + 20000.0f, (s,cf,p,v) => { MaxAddForceMagnitude = cf.GetFloat(p, v); }, (s) => { return (float)MaxAddForceMagnitude; }, (s,p,l,v) => { MaxAddForceMagnitude = v; } ), diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index e0b4992..12b1ef1 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -81,7 +81,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters internal long m_simulationStep = 0; internal float NominalFrameRate { get; set; } public long SimulationStep { get { return m_simulationStep; } } - internal int m_taintsToProcessPerStep; internal float LastTimeStep { get; private set; } // Physical objects can register for prestep or poststep events diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 23b7ca8..c1bf766 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -2,6 +2,8 @@ CURRENT PRIORITIES ================================================= Mantis 6040 script http://opensimulator.org/mantis/view.php?id=6040 Msg Kayaker on OSGrid when working +when should angular and linear motor targets be zeroed? when selected? + Need a vehicle.clear()? Or an 'else' in prestep if not physical. Teravus llMoveToTarget script debug Mixing of hover, buoyancy/gravity, moveToTarget, into one force Boats floating at proper level -- cgit v1.1 From 95c53ecae708c8f915e02c4f872c931efdd6c29a Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 21 Jan 2013 15:55:54 -0800 Subject: Have SOP and LSL_Api call the proper GetCenterOfMass and GetGeometricCenter routines on the physics engine. Won't make a difference for any existing scripts since ODE always returned Vector3.Zero. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 10 ++++++++++ .../Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 44e8fdf..e0ea344 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1952,6 +1952,16 @@ namespace OpenSim.Region.Framework.Scenes PhysicsActor pa = PhysActor; if (pa != null) + return new Vector3(pa.GeometricCenter.X, pa.GeometricCenter.Y, pa.GeometricCenter.Z); + else + return new Vector3(0, 0, 0); + } + + public Vector3 GetCenterOfMass() + { + PhysicsActor pa = PhysActor; + + if (pa != null) return new Vector3(pa.CenterOfMass.X, pa.CenterOfMass.Y, pa.CenterOfMass.Z); else return new Vector3(0, 0, 0); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index db5add1..507c399 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4923,7 +4923,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector llGetCenterOfMass() { m_host.AddScriptLPS(1); - Vector3 center = m_host.GetGeometricCenter(); + Vector3 center = m_host.GetCenterOfMass(); return new LSL_Vector(center.X,center.Y,center.Z); } -- cgit v1.1 From 471c4778639aec60078e6cee7c964682c959f033 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 21 Jan 2013 15:58:22 -0800 Subject: BulletSim: allow changing position and rotation of a child of a linkset without rebuilding the whole compound shape. Should make vehicles move smoother. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 2 +- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 94 +++++++++++++++++----- .../Physics/BulletSPlugin/BSLinksetConstraints.cs | 2 +- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 10 +++ OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 16 ++-- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 4 - .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 28 ++++--- 8 files changed, 112 insertions(+), 46 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index a9e16e6..7603254 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -899,7 +899,7 @@ public sealed class BSCharacter : BSPhysObject CurrentEntityProperties = entprop; // Tell the linkset about value changes - Linkset.UpdateProperties(this, true); + Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this); // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. // base.RequestPhysicsterseUpdate(); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index cbd160f..580ea4e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -252,7 +252,7 @@ public abstract class BSLinkset // of the linkset is received. // Passed flag is update came from physics engine (true) or the user (false). // Called at taint-time!! - public abstract void UpdateProperties(BSPhysObject physObject, bool physicalUpdate); + public abstract void UpdateProperties(UpdatedProperties whichUpdated, BSPhysObject physObject); // Routine used when rebuilding the body of the root of the linkset // Destroy all the constraints have have been made to root. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 8c9a774..27d8ad0 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -51,6 +51,21 @@ sealed class BSLinksetCompoundInfo : BSLinksetInfo OffsetFromCenterOfMass = p; OffsetRot = r; } + // 'centerDisplacement' is the distance from the root the the center-of-mass (Bullet 'zero' of the shape) + public BSLinksetCompoundInfo(int indx, BSPhysObject root, BSPhysObject child, OMV.Vector3 centerDisplacement) + { + // Each child position and rotation is given relative to the center-of-mass. + OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(root.RawOrientation); + OMV.Vector3 displacementFromRoot = (child.RawPosition - root.RawPosition) * invRootOrientation; + OMV.Vector3 displacementFromCOM = displacementFromRoot - centerDisplacement; + OMV.Quaternion displacementRot = child.RawOrientation * invRootOrientation; + + // Save relative position for recomputing child's world position after moving linkset. + Index = indx; + OffsetFromRoot = displacementFromRoot; + OffsetFromCenterOfMass = displacementFromCOM; + OffsetRot = displacementRot; + } public override void Clear() { Index = 0; @@ -182,24 +197,71 @@ public sealed class BSLinksetCompound : BSLinkset // 'physicalUpdate' is true if these changes came directly from the physics engine. Don't need to rebuild then. // Called at taint-time. - public override void UpdateProperties(BSPhysObject updated, bool physicalUpdate) + public override void UpdateProperties(UpdatedProperties whichUpdated, BSPhysObject updated) { // The user moving a child around requires the rebuilding of the linkset compound shape // One problem is this happens when a border is crossed -- the simulator implementation - // is to store the position into the group which causes the move of the object + // stores the position into the group which causes the move of the object // but it also means all the child positions get updated. // What would cause an unnecessary rebuild so we make sure the linkset is in a // region before bothering to do a rebuild. - if (!IsRoot(updated) - && !physicalUpdate - && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition)) + if (!IsRoot(updated) && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition)) { - // TODO: replace this with are calculation of the child prim's orientation and pos. - // TODO: for the moment, don't rebuild the compound shape. - // This is often just the car turning its wheels. When we can just reorient the one - // member shape of the compound shape, the overhead of rebuilding won't be a problem. - // updated.LinksetInfo = null; - // ScheduleRebuild(updated); + // If a child of the linkset is updating only the position or rotation, that can be done + // without rebuilding the linkset. + // If a handle for the child can be fetch, we update the child here. If a rebuild was + // scheduled by someone else, the rebuild will just replace this setting. + + bool updatedChild = false; + // Anything other than updating position or orientation usually means a physical update + // and that is caused by us updating the object. + if ((whichUpdated & ~(UpdatedProperties.Position | UpdatedProperties.Orientation)) == 0) + { + // Gather the child info. It might not be there if the linkset is in transition. + BSLinksetCompoundInfo lsi = updated.LinksetInfo as BSLinksetCompoundInfo; + if (LinksetRoot.PhysShape.HasPhysicalShape && lsi != null) + { + if (PhysicsScene.PE.IsCompound(LinksetRoot.PhysShape)) + { + BulletShape linksetChildShape = PhysicsScene.PE.GetChildShapeFromCompoundShapeIndex(LinksetRoot.PhysShape, lsi.Index); + if (linksetChildShape.HasPhysicalShape) + { + // Compute the offset from the center-of-gravity + BSLinksetCompoundInfo newLsi = new BSLinksetCompoundInfo(lsi.Index, LinksetRoot, updated, LinksetRoot.PositionDisplacement); + PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, lsi.Index, + newLsi.OffsetFromCenterOfMass, + newLsi.OffsetRot, + true /* shouldRecalculateLocalAabb */); + DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1}newLsi={2}", + updated.LocalID, whichUpdated, newLsi); + updated.LinksetInfo = newLsi; + updatedChild = true; + } + else // DEBUG DEBUG + { // DEBUG DEBUG + DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noChildShape,shape={1}", + updated.LocalID, linksetChildShape); + } // DEBUG DEBUG + } + else // DEBUG DEBUG + { // DEBUG DEBUG + DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,notCompound", updated.LocalID); + } // DEBUG DEBUG + } + else // DEBUG DEBUG + { // DEBUG DEBUG + DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,rootPhysShape={1},lsi={2}", + updated.LocalID, LinksetRoot.PhysShape, lsi == null ? "NULL" : lsi.ToString()); + } // DEBUG DEBUG + if (!updatedChild) + { + // If couldn't do the individual child, the linkset needs a rebuild to incorporate the new child info. + DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild.schedulingRebuild,whichUpdated={1}", + updated.LocalID, whichUpdated); + updated.LinksetInfo = null; // setting to 'null' causes relative position to be recomputed. + ScheduleRebuild(updated); + } + } } } @@ -372,15 +434,7 @@ public sealed class BSLinksetCompound : BSLinkset BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; if (lci == null) { - // Each child position and rotation is given relative to the center-of-mass. - OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); - OMV.Vector3 displacementFromRoot = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; - OMV.Vector3 displacementFromCOM = displacementFromRoot - centerDisplacement; - OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; - - // Save relative position for recomputing child's world position after moving linkset. - lci = new BSLinksetCompoundInfo(memberIndex, displacementFromCOM, displacementRot); - lci.OffsetFromRoot = displacementFromRoot; + lci = new BSLinksetCompoundInfo(memberIndex, LinksetRoot, cPrim, centerDisplacement); cPrim.LinksetInfo = lci; DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index d0b2a56..89f186c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -83,7 +83,7 @@ public sealed class BSLinksetConstraints : BSLinkset } // Called at taint-time!! - public override void UpdateProperties(BSPhysObject updated, bool inTaintTime) + public override void UpdateProperties(UpdatedProperties whichUpdated, BSPhysObject pObj) { // Nothing to do for constraints on property updates } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 5353c75..027c786 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -55,6 +55,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin * BS.ApplyCentralForce BS.ApplyTorque */ +// Flags used to denote which properties updates when making UpdateProperties calls to linksets, etc. +public enum UpdatedProperties : uint +{ + Position = 1 << 0, + Orientation = 1 << 1, + Velocity = 1 << 2, + Acceleration = 1 << 3, + RotationalVelocity = 1 << 4, + EntPropUpdates = Position | Orientation | Velocity | Acceleration | RotationalVelocity, +} public abstract class BSPhysObject : PhysicsActor { protected BSPhysObject() diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index b63523c..468ff40 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -311,13 +311,14 @@ public sealed class BSPrim : BSPhysObject _position = value; PositionSanityCheck(false); - // A linkset might need to know if a component information changed. - Linkset.UpdateProperties(this, false); - PhysicsScene.TaintedObject("BSPrim.setPosition", delegate() { DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); ForcePosition = _position; + + // A linkset might need to know if a component information changed. + Linkset.UpdateProperties(UpdatedProperties.Position, this); + }); } } @@ -682,12 +683,13 @@ public sealed class BSPrim : BSPhysObject return; _orientation = value; - // A linkset might need to know if a component information changed. - Linkset.UpdateProperties(this, false); - PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate() { ForceOrientation = _orientation; + + // A linkset might need to know if a component information changed. + Linkset.UpdateProperties(UpdatedProperties.Orientation, this); + }); } } @@ -1686,7 +1688,7 @@ public sealed class BSPrim : BSPhysObject */ // The linkset implimentation might want to know about this. - Linkset.UpdateProperties(this, true); + Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this); } } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 12b1ef1..8075b73 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -846,8 +846,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters #endregion // Taints - #region INI and command line parameter processing - #region IPhysicsParameters // Get the list of parameters this physics engine supports public PhysParameterEntry[] GetParameterList() @@ -944,8 +942,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters #endregion IPhysicsParameters - #endregion Runtime settable parameters - // Invoke the detailed logger and output something if it's enabled. public void DetailLog(string msg, params Object[] args) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index c1bf766..41bab26 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -1,25 +1,20 @@ CURRENT PRIORITIES ================================================= -Mantis 6040 script http://opensimulator.org/mantis/view.php?id=6040 - Msg Kayaker on OSGrid when working +Child movement in linkset (don't rebuild linkset) +Vehicle angular vertical attraction +vehicle angular banking +Center-of-gravity +Vehicle angular deflection + Preferred orientation angular correction fix when should angular and linear motor targets be zeroed? when selected? Need a vehicle.clear()? Or an 'else' in prestep if not physical. Teravus llMoveToTarget script debug Mixing of hover, buoyancy/gravity, moveToTarget, into one force -Boats floating at proper level Nebadon vehicles turning funny in arena limitMotorUp calibration (more down?) llRotLookAt llLookAt -Vehicle angular vertical attraction -Vehicle angular deflection - Preferred orientation angular correction fix -vehicle angular banking Avatars walking up stairs (HALF DONE) - Radius of the capsule affects ability to climb edges. -Vehicle movement on terrain smoothness -When is force introduced by SetForce removed? The prestep action could go forever. -Boats float low in the water (DONE) Avatar movement flying into a wall doesn't stop avatar who keeps appearing to move through the obstacle (DONE) walking up stairs is not calibrated correctly (stairs out of Kepler cabin) @@ -75,6 +70,7 @@ Incorporate inter-relationship of angular corrections. For instance, angularDefl GENERAL TODO LIST: ================================================= +llMoveToTarget objects are not effected by gravity until target is removed. Implement llSetPhysicalMaterial. extend it with Center-of-mass, rolling friction, density Implement llSetForceAndTorque. @@ -315,4 +311,12 @@ Remove HeightmapInfo from terrain specification (DONE) Since C++ code does not need terrain height, this structure et al are not needed. Surfboard go wonky when turning (DONE) Angular motor direction is global coordinates rather than local coordinates? - (Resolution: made angular motor direction correct coordinate system) \ No newline at end of file + (Resolution: made angular motor direction correct coordinate system) +Mantis 6040 script http://opensimulator.org/mantis/view.php?id=6040 (DONE) + Msg Kayaker on OSGrid when working + (Resolution: LINEAR_DIRECTION is in vehicle coords. Test script does the + same in SL as in OS/BulletSim) +Boats float low in the water (DONE) +Boats floating at proper level (DONE) +When is force introduced by SetForce removed? The prestep action could go forever. (DONE) + (Resolution: setForce registers a prestep action which keeps applying the force) \ No newline at end of file -- cgit v1.1 From 49d674c74d6390b33e3d5d655df70eb7adda6065 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 22 Jan 2013 00:35:56 +0000 Subject: refactor: rename XEngineTest to more descriptive XEngineBasicTests --- .../XEngine/Tests/XEngineBasicTests.cs | 130 +++++++++++++++++++++ .../ScriptEngine/XEngine/Tests/XEngineTest.cs | 130 --------------------- 2 files changed, 130 insertions(+), 130 deletions(-) create mode 100644 OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs delete mode 100644 OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs new file mode 100644 index 0000000..5abfe9a --- /dev/null +++ b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs @@ -0,0 +1,130 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Threading; +using Nini.Config; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.CoreModules.Scripting.WorldComm; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Region.ScriptEngine.XEngine.Tests +{ + /// + /// XEngine tests. + /// + [TestFixture] + public class XEngineTest : OpenSimTestCase + { + private TestScene m_scene; + private XEngine m_xEngine; + private AutoResetEvent m_chatEvent = new AutoResetEvent(false); + private OSChatMessage m_osChatMessageReceived; + + [TestFixtureSetUp] + public void Init() + { + //AppDomain.CurrentDomain.SetData("APPBASE", Environment.CurrentDirectory + "/bin"); +// Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory); + m_xEngine = new XEngine(); + + IniConfigSource configSource = new IniConfigSource(); + + IConfig startupConfig = configSource.AddConfig("Startup"); + startupConfig.Set("DefaultScriptEngine", "XEngine"); + + IConfig xEngineConfig = configSource.AddConfig("XEngine"); + xEngineConfig.Set("Enabled", "true"); + xEngineConfig.Set("StartDelay", "0"); + + // These tests will not run with AppDomainLoading = true, at least on mono. For unknown reasons, the call + // to AssemblyResolver.OnAssemblyResolve fails. + xEngineConfig.Set("AppDomainLoading", "false"); + + m_scene = new SceneHelpers().SetupScene("My Test", UUID.Random(), 1000, 1000, configSource); + SceneHelpers.SetupSceneModules(m_scene, configSource, m_xEngine); + m_scene.StartScripts(); + } + + /// + /// Test compilation and starting of a script. + /// + /// + /// This is a less than ideal regression test since it involves an asynchronous operation (in this case, + /// compilation of the script). + /// + [Test] + public void TestCompileAndStartScript() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + UUID userId = TestHelpers.ParseTail(0x1); +// UUID objectId = TestHelpers.ParseTail(0x100); +// UUID itemId = TestHelpers.ParseTail(0x3); + string itemName = "TestStartScript() Item"; + + SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, "TestStartScriptPart_", 0x100); + m_scene.AddNewSceneObject(so, true); + + InventoryItemBase itemTemplate = new InventoryItemBase(); +// itemTemplate.ID = itemId; + itemTemplate.Name = itemName; + itemTemplate.Folder = so.UUID; + itemTemplate.InvType = (int)InventoryType.LSL; + + m_scene.EventManager.OnChatFromWorld += OnChatFromWorld; + + SceneObjectPart partWhereRezzed = m_scene.RezNewScript(userId, itemTemplate); + + m_chatEvent.WaitOne(60000); + + Assert.That(m_osChatMessageReceived, Is.Not.Null, "No chat message received in TestStartScript()"); + Assert.That(m_osChatMessageReceived.Message, Is.EqualTo("Script running")); + + bool running; + TaskInventoryItem scriptItem = partWhereRezzed.Inventory.GetInventoryItem(itemName); + Assert.That( + SceneObjectPartInventory.TryGetScriptInstanceRunning(m_scene, scriptItem, out running), Is.True); + Assert.That(running, Is.True); + } + + private void OnChatFromWorld(object sender, OSChatMessage oscm) + { +// Console.WriteLine("Got chat [{0}]", oscm.Message); + + m_osChatMessageReceived = oscm; + m_chatEvent.Set(); + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs deleted file mode 100644 index 5abfe9a..0000000 --- a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Threading; -using Nini.Config; -using NUnit.Framework; -using OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Region.CoreModules.Scripting.WorldComm; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Tests.Common; -using OpenSim.Tests.Common.Mock; - -namespace OpenSim.Region.ScriptEngine.XEngine.Tests -{ - /// - /// XEngine tests. - /// - [TestFixture] - public class XEngineTest : OpenSimTestCase - { - private TestScene m_scene; - private XEngine m_xEngine; - private AutoResetEvent m_chatEvent = new AutoResetEvent(false); - private OSChatMessage m_osChatMessageReceived; - - [TestFixtureSetUp] - public void Init() - { - //AppDomain.CurrentDomain.SetData("APPBASE", Environment.CurrentDirectory + "/bin"); -// Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory); - m_xEngine = new XEngine(); - - IniConfigSource configSource = new IniConfigSource(); - - IConfig startupConfig = configSource.AddConfig("Startup"); - startupConfig.Set("DefaultScriptEngine", "XEngine"); - - IConfig xEngineConfig = configSource.AddConfig("XEngine"); - xEngineConfig.Set("Enabled", "true"); - xEngineConfig.Set("StartDelay", "0"); - - // These tests will not run with AppDomainLoading = true, at least on mono. For unknown reasons, the call - // to AssemblyResolver.OnAssemblyResolve fails. - xEngineConfig.Set("AppDomainLoading", "false"); - - m_scene = new SceneHelpers().SetupScene("My Test", UUID.Random(), 1000, 1000, configSource); - SceneHelpers.SetupSceneModules(m_scene, configSource, m_xEngine); - m_scene.StartScripts(); - } - - /// - /// Test compilation and starting of a script. - /// - /// - /// This is a less than ideal regression test since it involves an asynchronous operation (in this case, - /// compilation of the script). - /// - [Test] - public void TestCompileAndStartScript() - { - TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); - - UUID userId = TestHelpers.ParseTail(0x1); -// UUID objectId = TestHelpers.ParseTail(0x100); -// UUID itemId = TestHelpers.ParseTail(0x3); - string itemName = "TestStartScript() Item"; - - SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, "TestStartScriptPart_", 0x100); - m_scene.AddNewSceneObject(so, true); - - InventoryItemBase itemTemplate = new InventoryItemBase(); -// itemTemplate.ID = itemId; - itemTemplate.Name = itemName; - itemTemplate.Folder = so.UUID; - itemTemplate.InvType = (int)InventoryType.LSL; - - m_scene.EventManager.OnChatFromWorld += OnChatFromWorld; - - SceneObjectPart partWhereRezzed = m_scene.RezNewScript(userId, itemTemplate); - - m_chatEvent.WaitOne(60000); - - Assert.That(m_osChatMessageReceived, Is.Not.Null, "No chat message received in TestStartScript()"); - Assert.That(m_osChatMessageReceived.Message, Is.EqualTo("Script running")); - - bool running; - TaskInventoryItem scriptItem = partWhereRezzed.Inventory.GetInventoryItem(itemName); - Assert.That( - SceneObjectPartInventory.TryGetScriptInstanceRunning(m_scene, scriptItem, out running), Is.True); - Assert.That(running, Is.True); - } - - private void OnChatFromWorld(object sender, OSChatMessage oscm) - { -// Console.WriteLine("Got chat [{0}]", oscm.Message); - - m_osChatMessageReceived = oscm; - m_chatEvent.Set(); - } - } -} \ No newline at end of file -- cgit v1.1 From cd446c32d6d4c6453dbc85c5d8ac75c65a6db979 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 22 Jan 2013 00:59:46 +0000 Subject: Add regression test TestStopOnLongForLoop() --- .../Shared/Instance/Tests/CoopTerminationTests.cs | 59 ++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs index 8c3e9e0..c23d7a6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs @@ -146,6 +146,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests Assert.That(running, Is.False); } + [Test] + public void TestStopOnLongForLoop() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID userId = TestHelpers.ParseTail(0x1); +// UUID objectId = TestHelpers.ParseTail(0x100); +// UUID itemId = TestHelpers.ParseTail(0x3); + string itemName = "TestStopOnLongForLoop() Item"; + + SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, "TestStopOnLongForLoop", 0x100); + m_scene.AddNewSceneObject(so, true); + + InventoryItemBase itemTemplate = new InventoryItemBase(); +// itemTemplate.ID = itemId; + itemTemplate.Name = itemName; + itemTemplate.Folder = so.UUID; + itemTemplate.InvType = (int)InventoryType.LSL; + + m_scene.EventManager.OnChatFromWorld += OnChatFromWorld; + + SceneObjectPart partWhereRezzed = m_scene.RezNewScript(userId, itemTemplate, +@"default +{ + state_entry() + { + llSay(0, ""Thin Lizzy""); + integer i = 0; + for (i = 0; i < 2147483647; i++) + llSay(0, ""Iter "" + (string)i); + } +}"); + + TaskInventoryItem rezzedItem = partWhereRezzed.Inventory.GetInventoryItem(itemName); + + // Wait for the script to start the event before we try stopping it. + m_chatEvent.WaitOne(60000); + + Console.WriteLine("Script started with message [{0}]", m_osChatMessageReceived.Message); + + // FIXME: This is a very poor way of trying to avoid a low-probability race condition where the script + // executes llSay() but has not started the sleep before we try to stop it. + Thread.Sleep(1000); + + // We need a way of carrying on if StopScript() fail, since it won't return if the script isn't actually + // stopped. This kind of multi-threading is far from ideal in a regression test. + new Thread(() => { m_xEngine.StopScript(rezzedItem.ItemID); m_stoppedEvent.Set(); }).Start(); + + if (!m_stoppedEvent.WaitOne(30000)) + Assert.Fail("Script did not co-operatively stop."); + + bool running; + TaskInventoryItem scriptItem = partWhereRezzed.Inventory.GetInventoryItem(itemName); + Assert.That( + SceneObjectPartInventory.TryGetScriptInstanceRunning(m_scene, scriptItem, out running), Is.True); + Assert.That(running, Is.False); + } + private void OnChatFromWorld(object sender, OSChatMessage oscm) { // Console.WriteLine("Got chat [{0}]", oscm.Message); -- cgit v1.1 From 1730de14a4cfd78d6d87f12b5b1dcd268aba7fbd Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 22 Jan 2013 01:00:53 +0000 Subject: minor: comment out Console.WriteLine debugging message in XEngine --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 8a02590..c1f9271 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -242,7 +242,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine ScriptBaseClassParameters = typeof(XEngineScriptBase).GetConstructor(new Type[] { typeof(WaitHandle) }).GetParameters(); ScriptReferencedAssemblies = new string[] { Path.GetFileName(typeof(XEngineScriptBase).Assembly.Location) }; - Console.WriteLine("ASSEMBLY NAME: {0}", ScriptReferencedAssemblies[0]); +// Console.WriteLine("ASSEMBLY NAME: {0}", ScriptReferencedAssemblies[0]); } public void AddRegion(Scene scene) -- cgit v1.1 From 419f8e0f76ba765044d2ac29e03ee714356f42e3 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 22 Jan 2013 01:08:24 +0000 Subject: Increase WaitForEventCompletionOnScriptStop to 120 secs to show that the co-op setting is active in its regression tests. --- .../Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs index c23d7a6..53b992d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs @@ -77,6 +77,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests xEngineConfig.Set("ScriptStopStrategy", "co-op"); + // This is not currently used at all for co-op termination. Bumping up to demonstrate that co-op termination + // has an effect - without it tests will fail due to a 120 second wait for the event to finish. + xEngineConfig.Set("WaitForEventCompletionOnScriptStop", 120000); + m_scene = new SceneHelpers().SetupScene("My Test", UUID.Random(), 1000, 1000, configSource); SceneHelpers.SetupSceneModules(m_scene, configSource, m_xEngine); m_scene.StartScripts(); -- cgit v1.1 From a558f9797d3a2af00f6472adfc46ad5363d9bc1b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 22 Jan 2013 01:13:45 +0000 Subject: factor out common code in existing co-op termination regression tests --- .../Shared/Instance/Tests/CoopTerminationTests.cs | 79 +++++++--------------- 1 file changed, 24 insertions(+), 55 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs index 53b992d..952ae40 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs @@ -99,23 +99,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests TestHelpers.InMethod(); // TestHelpers.EnableLogging(); - UUID userId = TestHelpers.ParseTail(0x1); -// UUID objectId = TestHelpers.ParseTail(0x100); -// UUID itemId = TestHelpers.ParseTail(0x3); - string itemName = "TestStopOnObjectDerezLongSleep() Item"; - - SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, "TestStopOnObjectDerezLongSleep", 0x100); - m_scene.AddNewSceneObject(so, true); - - InventoryItemBase itemTemplate = new InventoryItemBase(); -// itemTemplate.ID = itemId; - itemTemplate.Name = itemName; - itemTemplate.Folder = so.UUID; - itemTemplate.InvType = (int)InventoryType.LSL; - - m_scene.EventManager.OnChatFromWorld += OnChatFromWorld; - - SceneObjectPart partWhereRezzed = m_scene.RezNewScript(userId, itemTemplate, + string script = @"default { state_entry() @@ -123,31 +107,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests llSay(0, ""Thin Lizzy""); llSleep(60); } -}"); - - TaskInventoryItem rezzedItem = partWhereRezzed.Inventory.GetInventoryItem(itemName); - - // Wait for the script to start the event before we try stopping it. - m_chatEvent.WaitOne(60000); - - Console.WriteLine("Script started with message [{0}]", m_osChatMessageReceived.Message); - - // FIXME: This is a very poor way of trying to avoid a low-probability race condition where the script - // executes llSay() but has not started the sleep before we try to stop it. - Thread.Sleep(1000); - - // We need a way of carrying on if StopScript() fail, since it won't return if the script isn't actually - // stopped. This kind of multi-threading is far from ideal in a regression test. - new Thread(() => { m_xEngine.StopScript(rezzedItem.ItemID); m_stoppedEvent.Set(); }).Start(); - - if (!m_stoppedEvent.WaitOne(30000)) - Assert.Fail("Script did not co-operatively stop."); +}"; - bool running; - TaskInventoryItem scriptItem = partWhereRezzed.Inventory.GetInventoryItem(itemName); - Assert.That( - SceneObjectPartInventory.TryGetScriptInstanceRunning(m_scene, scriptItem, out running), Is.True); - Assert.That(running, Is.False); + TestStop(script); } [Test] @@ -156,12 +118,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests TestHelpers.InMethod(); // TestHelpers.EnableLogging(); + string script = +@"default +{ + state_entry() + { + llSay(0, ""Thin Lizzy""); + integer i = 0; + for (i = 0; i < 2147483647; i++) + llSay(0, ""Iter "" + (string)i); + } +}"; + + TestStop(script); + } + + private void TestStop(string script) + { UUID userId = TestHelpers.ParseTail(0x1); // UUID objectId = TestHelpers.ParseTail(0x100); // UUID itemId = TestHelpers.ParseTail(0x3); - string itemName = "TestStopOnLongForLoop() Item"; + string itemName = "TestStop() Item"; - SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, "TestStopOnLongForLoop", 0x100); + SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, "TestStop", 0x100); m_scene.AddNewSceneObject(so, true); InventoryItemBase itemTemplate = new InventoryItemBase(); @@ -172,17 +151,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests m_scene.EventManager.OnChatFromWorld += OnChatFromWorld; - SceneObjectPart partWhereRezzed = m_scene.RezNewScript(userId, itemTemplate, -@"default -{ - state_entry() - { - llSay(0, ""Thin Lizzy""); - integer i = 0; - for (i = 0; i < 2147483647; i++) - llSay(0, ""Iter "" + (string)i); - } -}"); + SceneObjectPart partWhereRezzed = m_scene.RezNewScript(userId, itemTemplate, script); TaskInventoryItem rezzedItem = partWhereRezzed.Inventory.GetInventoryItem(itemName); @@ -192,7 +161,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests Console.WriteLine("Script started with message [{0}]", m_osChatMessageReceived.Message); // FIXME: This is a very poor way of trying to avoid a low-probability race condition where the script - // executes llSay() but has not started the sleep before we try to stop it. + // executes llSay() but has not started the next statement before we try to stop it. Thread.Sleep(1000); // We need a way of carrying on if StopScript() fail, since it won't return if the script isn't actually -- cgit v1.1 From c6ba27d096a3008bc0128aebddf4d2e9708d2498 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 22 Jan 2013 01:23:10 +0000 Subject: Fix bug in generating termination checks in compound statement for loop. Add regression test for this case. --- .../Shared/CodeTools/CSCodeGenerator.cs | 2 +- .../Shared/Instance/Tests/CoopTerminationTests.cs | 28 ++++++++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs index 002f9b8..985e598 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs @@ -445,7 +445,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools if (previousSymbol is GlobalFunctionDefinition || previousSymbol is WhileStatement || previousSymbol is DoWhileStatement - || previousSymbol is ForLoopStatement + || previousSymbol is ForLoop || previousSymbol is StateEvent) retstr += GenerateIndentedLine(m_coopTerminationCheck); } diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs index 952ae40..c83a6ba 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs @@ -76,12 +76,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests xEngineConfig.Set("AppDomainLoading", "false"); xEngineConfig.Set("ScriptStopStrategy", "co-op"); + xEngineConfig.Set("WriteScriptSourceToDebugFile", true); // This is not currently used at all for co-op termination. Bumping up to demonstrate that co-op termination // has an effect - without it tests will fail due to a 120 second wait for the event to finish. xEngineConfig.Set("WaitForEventCompletionOnScriptStop", 120000); - m_scene = new SceneHelpers().SetupScene("My Test", UUID.Random(), 1000, 1000, configSource); + m_scene = new SceneHelpers().SetupScene("My Test", TestHelpers.ParseTail(0x9999), 1000, 1000, configSource); SceneHelpers.SetupSceneModules(m_scene, configSource, m_xEngine); m_scene.StartScripts(); } @@ -113,7 +114,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests } [Test] - public void TestStopOnLongForLoop() + public void TestStopOnLongSingleStatementForLoop() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); @@ -133,6 +134,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests TestStop(script); } + [Test] + public void TestStopOnLongCompoundStatementForLoop() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + string script = +@"default +{ + state_entry() + { + llSay(0, ""Thin Lizzy""); + integer i = 0; + for (i = 0; i < 2147483647; i++) + { + llSay(0, ""Iter "" + (string)i); + } + } +}"; + + TestStop(script); + } + private void TestStop(string script) { UUID userId = TestHelpers.ParseTail(0x1); -- cgit v1.1 From fbdfe43d75cb99066ce5fcfa803b135aff6e1fe0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 22 Jan 2013 01:40:18 +0000 Subject: Add single and comound while loop co-op termination test --- .../Shared/Instance/Tests/CoopTerminationTests.cs | 44 ++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs index c83a6ba..87951f9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs @@ -157,6 +157,50 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests TestStop(script); } + [Test] + public void TestStopOnLongSingleStatementWhileLoop() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + string script = +@"default +{ + state_entry() + { + llSay(0, ""Thin Lizzy""); + + while (1 == 1) + llSay(0, ""Iter "" + (string)i); + } +}"; + + TestStop(script); + } + + [Test] + public void TestStopOnLongCompoundStatementWhileLoop() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + string script = +@"default +{ + state_entry() + { + llSay(0, ""Thin Lizzy""); + + while (1 == 1) + { + llSay(0, ""Iter "" + (string)i); + } + } +}"; + + TestStop(script); + } + private void TestStop(string script) { UUID userId = TestHelpers.ParseTail(0x1); -- cgit v1.1 From cf0b5e4f279e36e506c46a8c1d980f015fe5cfb2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 22 Jan 2013 01:53:10 +0000 Subject: Add do-while co-op termination test Minor changes to scripts in other tests. --- .../Shared/Instance/Tests/CoopTerminationTests.cs | 32 ++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs index 87951f9..33d2175 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs @@ -124,8 +124,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests { state_entry() { - llSay(0, ""Thin Lizzy""); integer i = 0; + llSay(0, ""Thin Lizzy""); + for (i = 0; i < 2147483647; i++) llSay(0, ""Iter "" + (string)i); } @@ -145,8 +146,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests { state_entry() { - llSay(0, ""Thin Lizzy""); integer i = 0; + llSay(0, ""Thin Lizzy""); + for (i = 0; i < 2147483647; i++) { llSay(0, ""Iter "" + (string)i); @@ -168,6 +170,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests { state_entry() { + integer i = 0; llSay(0, ""Thin Lizzy""); while (1 == 1) @@ -189,6 +192,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests { state_entry() { + integer i = 0; llSay(0, ""Thin Lizzy""); while (1 == 1) @@ -201,6 +205,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests TestStop(script); } + [Test] + public void TestStopOnLongDoWhileLoop() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + string script = +@"default +{ + state_entry() + { + integer i = 0; + llSay(0, ""Thin Lizzy""); + + do + { + llSay(0, ""Iter "" + (string)i); + } while (1 == 1) + } +}"; + + TestStop(script); + } + private void TestStop(string script) { UUID userId = TestHelpers.ParseTail(0x1); -- cgit v1.1 From b93e8020e25ab22973e5ef25cc563ee39a9c3f66 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 22 Jan 2013 02:16:10 +0000 Subject: Add regression test for co-op stop of an infinite jump loop Also fixes bug in do-while test Improves detection of failure due to invalid script in test Sets up xengine anew for each test rather than once for the while testsuite to improve isolation between tests. Stop listening for chat after the first 'script is running' chat is received to reduce test run time. --- .../Shared/Instance/Tests/CoopTerminationTests.cs | 49 ++++++++++++++++++---- 1 file changed, 41 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs index 33d2175..3365c92 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs @@ -50,14 +50,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests private TestScene m_scene; private OpenSim.Region.ScriptEngine.XEngine.XEngine m_xEngine; - private AutoResetEvent m_chatEvent = new AutoResetEvent(false); - private AutoResetEvent m_stoppedEvent = new AutoResetEvent(false); + private AutoResetEvent m_chatEvent; + private AutoResetEvent m_stoppedEvent; private OSChatMessage m_osChatMessageReceived; - [TestFixtureSetUp] + [SetUp] public void Init() { + m_osChatMessageReceived = null; + m_chatEvent = new AutoResetEvent(false); + m_stoppedEvent = new AutoResetEvent(false); + //AppDomain.CurrentDomain.SetData("APPBASE", Environment.CurrentDirectory + "/bin"); // Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory); m_xEngine = new OpenSim.Region.ScriptEngine.XEngine.XEngine(); @@ -76,8 +80,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests xEngineConfig.Set("AppDomainLoading", "false"); xEngineConfig.Set("ScriptStopStrategy", "co-op"); + + // This is really just set for debugging the test. xEngineConfig.Set("WriteScriptSourceToDebugFile", true); + // Set to false if we need to debug test so the old scripts don't get wiped before each separate test +// xEngineConfig.Set("DeleteScriptsOnStartup", false); + // This is not currently used at all for co-op termination. Bumping up to demonstrate that co-op termination // has an effect - without it tests will fail due to a 120 second wait for the event to finish. xEngineConfig.Set("WaitForEventCompletionOnScriptStop", 120000); @@ -174,7 +183,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests llSay(0, ""Thin Lizzy""); while (1 == 1) - llSay(0, ""Iter "" + (string)i); + llSay(0, ""Iter "" + (string)i++); } }"; @@ -197,7 +206,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests while (1 == 1) { - llSay(0, ""Iter "" + (string)i); + llSay(0, ""Iter "" + (string)i++); } } }"; @@ -221,8 +230,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests do { - llSay(0, ""Iter "" + (string)i); - } while (1 == 1) + llSay(0, ""Iter "" + (string)i++); +} while (1 == 1); + } +}"; + + TestStop(script); + } + + [Test] + public void TestStopOnInfiniteJumpLoop() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + string script = +@"default +{ + state_entry() + { + integer i = 0; + llSay(0, ""Thin Lizzy""); + + @p1; + llSay(0, ""Iter "" + (string)i++); + jump p1; } }"; @@ -276,7 +308,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests private void OnChatFromWorld(object sender, OSChatMessage oscm) { -// Console.WriteLine("Got chat [{0}]", oscm.Message); + m_scene.EventManager.OnChatFromWorld -= OnChatFromWorld; + Console.WriteLine("Got chat [{0}]", oscm.Message); m_osChatMessageReceived = oscm; m_chatEvent.Set(); -- cgit v1.1 From 679dc811dda95bd3d037e9bd691a9cd10fbf032a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 22 Jan 2013 02:22:58 +0000 Subject: Add regression test for co-op termination on infinite user function call regression. Such a script would probably run out of stack pretty quickly anyway. --- .../Shared/Instance/Tests/CoopTerminationTests.cs | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs index 3365c92..149a27b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs @@ -261,6 +261,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests TestStop(script); } + [Test] + public void TestStopOnInfiniteUserFunctionCallLoop() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + string script = +@" +integer i = 0; + +ufn1() +{ + llSay(0, ""Iter ufn1() "" + (string)i++); + ufn1(); +} + +default +{ + state_entry() + { + integer i = 0; + llSay(0, ""Thin Lizzy""); + + ufn1(); + } +}"; + + TestStop(script); + } + private void TestStop(string script) { UUID userId = TestHelpers.ParseTail(0x1); -- cgit v1.1 From 0727784186ec906804e0b6d3cdc17877f1da9e06 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 22 Jan 2013 02:26:04 +0000 Subject: Set script delay factor to 0 in co-op termination tests This is to ensure loops aren't actually terminating from a wait on an LSL function. This was not the case with any of the existing tests. --- .../Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs index 149a27b..019375d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs @@ -81,6 +81,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests xEngineConfig.Set("ScriptStopStrategy", "co-op"); + // Make sure loops aren't actually being terminated by a script delay wait. + xEngineConfig.Set("ScriptDelayFactor", 0); + // This is really just set for debugging the test. xEngineConfig.Set("WriteScriptSourceToDebugFile", true); -- cgit v1.1 From 9a4914e58cace98228e12e4d2e44064cc1db20bf Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 22 Jan 2013 02:32:40 +0000 Subject: Add co-op termination regression test for infinite recursive manual call on event function. Such code would normally terminate quickly with a stack overflow exception anyway. --- .../Shared/Instance/Tests/CoopTerminationTests.cs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs index 019375d..bd882f9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs @@ -294,6 +294,28 @@ default TestStop(script); } + [Test] + public void TestStopOnInfiniteManualEventCallLoop() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + string script = +@"default +{ + state_entry() + { + integer i = 0; + llSay(0, ""Thin Lizzy""); + + llSay(0, ""Iter"" + (string)i++); + default_event_state_entry(); + } +}"; + + TestStop(script); + } + private void TestStop(string script) { UUID userId = TestHelpers.ParseTail(0x1); -- cgit v1.1 From 80b1e32bfa00a2d3354f0d7e0df83a5b0b3e2c49 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 21 Jan 2013 23:43:24 -0800 Subject: BulletSim: Tweeks to vehicle motion. Pass through old angular velocity making for smoother transitions. Remove some old kludges for angular motion (damping and rotvel suppression). --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 21 ++++++++------------- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 3 ++- 3 files changed, 11 insertions(+), 15 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index f8fc3de..dbe44de 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -1192,7 +1192,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // set directly on the vehicle. private void MoveAngular(float pTimestep) { - VehicleRotationalVelocity = Vector3.Zero; + // VehicleRotationalVelocity = Vector3.Zero; ComputeAngularTurning(pTimestep); @@ -1203,12 +1203,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin ComputeAngularBanking(); // ================================================================== - // All of the above computation are made relative to vehicle coordinates. - // Convert to world coordinates. - // TODO: Should this be applied as an angular force (torque)? - VehicleRotationalVelocity *= VehicleOrientation; - - // ================================================================== if (VehicleRotationalVelocity.ApproxEquals(Vector3.Zero, 0.01f)) { // The vehicle is not adding anything angular wise. @@ -1256,7 +1250,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin private void ComputeAngularTurning(float pTimestep) { // The user wants this many radians per second angular change? - Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); + Vector3 currentAngular = VehicleRotationalVelocity * Quaternion.Inverse(VehicleOrientation); + Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep, currentAngular); // ================================================================== // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags : @@ -1272,7 +1267,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin angularMotorContribution.Y = 0f; } - VehicleRotationalVelocity += angularMotorContribution; + VehicleRotationalVelocity += angularMotorContribution * VehicleOrientation; VDetailLog("{0}, MoveAngular,angularTurning,angularMotorContrib={1}", Prim.LocalID, angularMotorContribution); } @@ -1312,7 +1307,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (verticalError.Z < 0f) { vertContribution.X += PIOverFour; - vertContribution.Y += PIOverFour; + // vertContribution.Y -= PIOverFour; } // 'vertContrbution' is now the necessary angular correction to correct tilt in one second. @@ -1320,7 +1315,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 unscaledContrib = vertContribution; // DEBUG DEBUG vertContribution /= m_verticalAttractionTimescale; - VehicleRotationalVelocity += vertContribution; + VehicleRotationalVelocity += vertContribution * VehicleOrientation; VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},eff={3},ts={4},vertAttr={5}", Prim.LocalID, verticalError, unscaledContrib, m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContribution); @@ -1371,7 +1366,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin deflectContribution = (-deflectionError) * m_angularDeflectionEfficiency; deflectContribution /= m_angularDeflectionTimescale; - VehicleRotationalVelocity += deflectContribution; + VehicleRotationalVelocity += deflectContribution * VehicleOrientation; VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}", Prim.LocalID, movingDirection, pointingDirection, deflectionError, deflectContribution); @@ -1438,7 +1433,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Don't do it all at once. bankingContribution /= m_bankingTimescale; - VehicleRotationalVelocity += bankingContribution; + VehicleRotationalVelocity += bankingContribution * VehicleOrientation; VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},rollComp={3},yAng={4},mYAng={5},ret={6}", Prim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, bankingContribution); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 2b4488a..da7438a 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -450,7 +450,7 @@ public static class BSParam (s) => { return (float)VehicleMaxAngularVelocity; }, (s,p,l,v) => { VehicleMaxAngularVelocity = v; } ), new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", - 0.95f, + 0.0f, (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); }, (s) => { return VehicleAngularDamping; }, (s,p,l,v) => { VehicleAngularDamping = v; } ), diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 468ff40..e6b8507 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -1009,6 +1009,7 @@ public sealed class BSPrim : BSPhysObject { DetailLog("{0},BSPrim.ForceRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); PhysicsScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity); + // PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, _rotationalVelocity); ActivateIfPhysical(false); } } @@ -1649,7 +1650,7 @@ public sealed class BSPrim : BSPhysObject // TODO: handle physics introduced by Bullet with computed vehicle physics. if (_vehicle.IsActive) { - entprop.RotationalVelocity = OMV.Vector3.Zero; + // entprop.RotationalVelocity = OMV.Vector3.Zero; } // Assign directly to the local variables so the normal set actions do not happen -- cgit v1.1 From cf168194e5968c1fab33266bdbb57465f303860b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 23 Jan 2013 02:28:27 +0000 Subject: If ScriptStopStrategy hasn't been set to co-op in [XEngine] config, then continue to generate C# that is functionality identical to historical generation This is to eliminate disruption until co-op termination has been well-tested. In non co-op mode, XEngine will continue to load DLLs of the existing Script class and the new XEngineScript class. Moving to co-op mode still requires existing script DLL deletion to force recompilation, either manually or by setting DeleteScriptsOnStartup = true for one run. This change also means that scripts which fail to initialize do not still show up as running scripts. --- .../ScriptEngine/Interfaces/IScriptEngine.cs | 8 ++++ .../ScriptEngine/Shared/CodeTools/Compiler.cs | 30 ++++++++------ .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 48 ++++++++++++++++++---- .../Shared/Instance/Tests/CoopTerminationTests.cs | 2 +- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 26 +++++++++--- 5 files changed, 87 insertions(+), 27 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs index 20dcac9..b8fdd01 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs @@ -79,6 +79,14 @@ namespace OpenSim.Region.ScriptEngine.Interfaces string ScriptEnginePath { get; } /// + /// Return the name of the class that will be used for all running scripts. + /// + /// + /// Each class goes in its own assembly so we don't need to otherwise distinguish the class name. + /// + string ScriptClassName { get; } + + /// /// Return the name of the base class that will be used for all running scripts. /// string ScriptBaseClassName { get; } diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs index 7432202..002e852 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs @@ -416,16 +416,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools case enumCompileType.cs: case enumCompileType.lsl: compileScript = CreateCSCompilerScript( - compileScript, m_scriptEngine.ScriptBaseClassName, m_scriptEngine.ScriptBaseClassParameters); + compileScript, + m_scriptEngine.ScriptClassName, + m_scriptEngine.ScriptBaseClassName, + m_scriptEngine.ScriptBaseClassParameters); break; case enumCompileType.vb: - compileScript = CreateVBCompilerScript(compileScript, m_scriptEngine.ScriptBaseClassName); + compileScript = CreateVBCompilerScript( + compileScript, m_scriptEngine.ScriptClassName, m_scriptEngine.ScriptBaseClassName); break; // case enumCompileType.js: // compileScript = CreateJSCompilerScript(compileScript, m_scriptEngine.ScriptBaseClassName); // break; case enumCompileType.yp: - compileScript = CreateYPCompilerScript(compileScript, m_scriptEngine.ScriptBaseClassName); + compileScript = CreateYPCompilerScript( + compileScript, m_scriptEngine.ScriptClassName,m_scriptEngine.ScriptBaseClassName); break; } @@ -457,7 +462,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools // } private static string CreateCSCompilerScript( - string compileScript, string baseClassName, ParameterInfo[] constructorParameters) + string compileScript, string className, string baseClassName, ParameterInfo[] constructorParameters) { compileScript = string.Format( @"using OpenSim.Region.ScriptEngine.Shared; @@ -465,12 +470,13 @@ using System.Collections.Generic; namespace SecondLife {{ - public class Script : {0} + public class {0} : {1} {{ - public Script({1}) : base({2}) {{}} -{3} + public {0}({2}) : base({3}) {{}} +{4} }} }}", + className, baseClassName, constructorParameters != null ? string.Join(", ", Array.ConvertAll(constructorParameters, pi => pi.ToString())) @@ -483,28 +489,28 @@ namespace SecondLife return compileScript; } - private static string CreateYPCompilerScript(string compileScript, string baseClassName) + private static string CreateYPCompilerScript(string compileScript, string className, string baseClassName) { compileScript = String.Empty + "using OpenSim.Region.ScriptEngine.Shared.YieldProlog; " + "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\r\n" + String.Empty + "namespace SecondLife { " + - String.Empty + "public class Script : " + baseClassName + " { \r\n" + + String.Empty + "public class " + className + " : " + baseClassName + " { \r\n" + //@"public Script() { } " + @"static OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP YP=null; " + - @"public Script() { YP= new OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP(); } " + + @"public " + className + "() { YP= new OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP(); } " + compileScript + "} }\r\n"; return compileScript; } - private static string CreateVBCompilerScript(string compileScript, string baseClassName) + private static string CreateVBCompilerScript(string compileScript, string className, string baseClassName) { compileScript = String.Empty + "Imports OpenSim.Region.ScriptEngine.Shared: Imports System.Collections.Generic: " + String.Empty + "NameSpace SecondLife:" + - String.Empty + "Public Class Script: Inherits " + baseClassName + + String.Empty + "Public Class " + className + ": Inherits " + baseClassName + "\r\nPublic Sub New()\r\nEnd Sub: " + compileScript + ":End Class :End Namespace\r\n"; diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index e6ec0e1..4cfcb75 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -251,7 +251,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance /// /// /// - public void Load(AppDomain dom, string assembly, StateSource stateSource) + /// false if load failed, true if suceeded + public bool Load(AppDomain dom, string assembly, StateSource stateSource) { m_Assembly = assembly; m_stateSource = stateSource; @@ -266,26 +267,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance try { + object[] constructorParams; + + Assembly scriptAssembly = dom.Load(Path.GetFileNameWithoutExtension(assembly)); + Type scriptType = scriptAssembly.GetType("SecondLife.XEngineScript"); + + if (scriptType != null) + { + constructorParams = new object[] { m_coopSleepHandle }; + } + else if (!m_coopTermination) + { + scriptType = scriptAssembly.GetType("SecondLife.Script"); + constructorParams = null; + } + else + { + m_log.ErrorFormat( + "[SCRIPT INSTANCE]: You must remove all existing script DLLs before using enabling co-op termination" + + ", either by setting DeleteScriptsOnStartup = true in [XEngine] for one run" + + " or by deleting all *.dll* files in the relevant bin/ScriptEngines// directory"); + + return false; + } + +// m_log.DebugFormat( +// "[SCRIPT INSTANCE]: Looking to load {0} from assembly {1} in {2}", +// scriptType.FullName, Path.GetFileNameWithoutExtension(assembly), Engine.World.Name); + if (dom != System.AppDomain.CurrentDomain) m_Script = (IScript)dom.CreateInstanceAndUnwrap( Path.GetFileNameWithoutExtension(assembly), - "SecondLife.Script", + scriptType.FullName, false, BindingFlags.Default, null, - new object[] { m_coopSleepHandle }, - null, + constructorParams, null, null); else m_Script - = (IScript)Assembly.Load(Path.GetFileNameWithoutExtension(assembly)).CreateInstance( - "SecondLife.Script", + = (IScript)scriptAssembly.CreateInstance( + scriptType.FullName, false, BindingFlags.Default, null, - new object[] { m_coopSleepHandle }, + constructorParams, null, null); @@ -298,6 +326,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance m_log.ErrorFormat( "[SCRIPT INSTANCE]: Error loading assembly {0}. Exception {1}{2}", assembly, e.Message, e.StackTrace); + + return false; } try @@ -318,7 +348,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance "[SCRIPT INSTANCE]: Error loading script instance from assembly {0}. Exception {1}{2}", assembly, e.Message, e.StackTrace); - return; + return false; } m_SaveState = true; @@ -390,6 +420,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance // presence.ControllingClient.SendAgentAlertMessage("Compile successful", false); // } + + return true; } public void Init() diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs index bd882f9..52d75a0 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs @@ -245,7 +245,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests public void TestStopOnInfiniteJumpLoop() { TestHelpers.InMethod(); -// TestHelpers.EnableLogging(); + TestHelpers.EnableLogging(); string script = @"default diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index c1f9271..604924b 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -46,13 +46,14 @@ using OpenSim.Framework; using OpenSim.Framework.Console; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.ScriptEngine.Interfaces; using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.ScriptEngine.Shared.ScriptBase; using OpenSim.Region.ScriptEngine.Shared.CodeTools; using OpenSim.Region.ScriptEngine.Shared.Instance; using OpenSim.Region.ScriptEngine.Shared.Api; using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; -using OpenSim.Region.ScriptEngine.Interfaces; +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; using OpenSim.Region.ScriptEngine.XEngine.ScriptBase; using Timer = OpenSim.Region.ScriptEngine.Shared.Api.Plugins.Timer; @@ -177,6 +178,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine get { return "XEngine"; } } + public string ScriptClassName { get; private set; } + public string ScriptBaseClassName { get; private set; } public ParameterInfo[] ScriptBaseClassParameters { get; private set; } @@ -238,9 +241,18 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_ScriptConfig = configSource.Configs["XEngine"]; m_ConfigSource = configSource; - ScriptBaseClassName = typeof(XEngineScriptBase).FullName; - ScriptBaseClassParameters = typeof(XEngineScriptBase).GetConstructor(new Type[] { typeof(WaitHandle) }).GetParameters(); - ScriptReferencedAssemblies = new string[] { Path.GetFileName(typeof(XEngineScriptBase).Assembly.Location) }; + if (m_ScriptConfig.GetString("ScriptStopStrategy", "abort") == "co-op") + { + ScriptClassName = "XEngineScript"; + ScriptBaseClassName = typeof(XEngineScriptBase).FullName; + ScriptBaseClassParameters = typeof(XEngineScriptBase).GetConstructor(new Type[] { typeof(WaitHandle) }).GetParameters(); + ScriptReferencedAssemblies = new string[] { Path.GetFileName(typeof(XEngineScriptBase).Assembly.Location) }; + } + else + { + ScriptClassName = "Script"; + ScriptBaseClassName = typeof(ScriptBaseClass).FullName; + } // Console.WriteLine("ASSEMBLY NAME: {0}", ScriptReferencedAssemblies[0]); } @@ -1122,7 +1134,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine } m_log.DebugFormat( - "[XEngine] Loading script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", + "[XEngine]: Loading script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); @@ -1143,6 +1155,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine lock (m_AddingAssemblies) { m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, out assembly, out linemap); + if (!m_AddingAssemblies.ContainsKey(assembly)) { m_AddingAssemblies[assembly] = 1; } else { @@ -1303,7 +1316,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine startParam, postOnRez, m_MaxScriptQueue); - instance.Load(m_AppDomains[appDomain], assembly, stateSource); + if (!instance.Load(m_AppDomains[appDomain], assembly, stateSource)) + return false; // if (DebugLevel >= 1) // m_log.DebugFormat( -- cgit v1.1 From 6a2b673fca6fcff4e358cf4ef6bd773f8a0488ba Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 23 Jan 2013 18:58:29 +0100 Subject: Remove the return value from llGiveMoney and add llTransferLindenDollars. Also make llGiveMoney async so the script thread is not held up waiting for comms to an external server. --- .../Shared/Api/Implementation/LSL_Api.cs | 135 ++++++++++++++++----- .../ScriptEngine/Shared/Api/Interface/ILSL_Api.cs | 3 +- .../ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs | 9 +- 3 files changed, 114 insertions(+), 33 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 507c399..632b73f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2738,42 +2738,40 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return src.ToLower(); } - public LSL_Integer llGiveMoney(string destination, int amount) + public void llGiveMoney(string destination, int amount) { - m_host.AddScriptLPS(1); - - if (m_item.PermsGranter == UUID.Zero) - return 0; - - if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0) + Util.FireAndForget(x => { - LSLError("No permissions to give money"); - return 0; - } + m_host.AddScriptLPS(1); - UUID toID = new UUID(); + if (m_item.PermsGranter == UUID.Zero) + return; - if (!UUID.TryParse(destination, out toID)) - { - LSLError("Bad key in llGiveMoney"); - return 0; - } + if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0) + { + LSLError("No permissions to give money"); + return; + } - IMoneyModule money = World.RequestModuleInterface(); + UUID toID = new UUID(); - if (money == null) - { - NotImplemented("llGiveMoney"); - return 0; - } + if (!UUID.TryParse(destination, out toID)) + { + LSLError("Bad key in llGiveMoney"); + return; + } - bool result = money.ObjectGiveMoney( - m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); + IMoneyModule money = World.RequestModuleInterface(); - if (result) - return 1; + if (money == null) + { + NotImplemented("llGiveMoney"); + return; + } - return 0; + money.ObjectGiveMoney( + m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); + }); } public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) @@ -6839,7 +6837,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface(); - if (xmlrpcMod.IsEnabled()) + if (xmlrpcMod != null && xmlrpcMod.IsEnabled()) { UUID channelID = xmlrpcMod.OpenXMLRPCChannel(m_host.LocalId, m_item.ItemID, UUID.Zero); IXmlRpcRouter xmlRpcRouter = m_ScriptEngine.World.RequestModuleInterface(); @@ -6871,6 +6869,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface(); ScriptSleep(3000); + if (xmlrpcMod == null) + return ""; return (xmlrpcMod.SendRemoteData(m_host.LocalId, m_item.ItemID, channel, dest, idata, sdata)).ToString(); } @@ -6878,7 +6878,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface(); - xmlrpcMod.RemoteDataReply(channel, message_id, sdata, idata); + if (xmlrpcMod != null) + xmlrpcMod.RemoteDataReply(channel, message_id, sdata, idata); ScriptSleep(3000); } @@ -6893,7 +6894,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface(); - xmlrpcMod.CloseXMLRPCChannel((UUID)channel); + if (xmlrpcMod != null) + xmlrpcMod.CloseXMLRPCChannel((UUID)channel); ScriptSleep(1000); } @@ -11554,6 +11556,79 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api NotImplemented("llGodLikeRezObject"); } + public LSL_String llTransferLindenDollars(string destination, int amount) + { + UUID txn = UUID.Random(); + + Util.FireAndForget(delegate(object x) + { + int replycode = 0; + string replydata = destination + "," + amount.ToString(); + + try + { + TaskInventoryItem item = m_item; + if (item == null) + { + replydata = "SERVICE_ERROR"; + return; + } + + m_host.AddScriptLPS(1); + + if (item.PermsGranter == UUID.Zero) + { + replydata = "MISSING_PERMISSION_DEBIT"; + return; + } + + if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0) + { + replydata = "MISSING_PERMISSION_DEBIT"; + return; + } + + UUID toID = new UUID(); + + if (!UUID.TryParse(destination, out toID)) + { + replydata = "INVALID_AGENT"; + return; + } + + IMoneyModule money = World.RequestModuleInterface(); + + if (money == null) + { + replydata = "TRANSFERS_DISABLED"; + return; + } + + bool result = money.ObjectGiveMoney( + m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); + + if (result) + { + replycode = 1; + return; + } + + replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS"; + } + finally + { + m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( + "transaction_result", new Object[] { + new LSL_String(txn.ToString()), + new LSL_Integer(replycode), + new LSL_String(replydata) }, + new DetectParams[0])); + } + }); + + return txn.ToString(); + } + #endregion } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index 98f8be7..4ac179a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs @@ -207,7 +207,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_Float llGetWallclock(); void llGiveInventory(string destination, string inventory); void llGiveInventoryList(string destination, string category, LSL_List inventory); - LSL_Integer llGiveMoney(string destination, int amount); + void llGiveMoney(string destination, int amount); + LSL_String llTransferLindenDollars(string destination, int amount); void llGodLikeRezObject(string inventory, LSL_Vector pos); LSL_Float llGround(LSL_Vector offset); LSL_Vector llGroundContour(LSL_Vector offset); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index 36803a4..c7a7cf6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs @@ -869,9 +869,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_LSL_Functions.llGiveInventoryList(destination, category, inventory); } - public LSL_Integer llGiveMoney(string destination, int amount) + public void llGiveMoney(string destination, int amount) { - return m_LSL_Functions.llGiveMoney(destination, amount); + m_LSL_Functions.llGiveMoney(destination, amount); + } + + public LSL_String llTransferLindenDollars(string destination, int amount) + { + return m_LSL_Functions.llTransferLindenDollars(destination, amount); } public void llGodLikeRezObject(string inventory, LSL_Vector pos) -- cgit v1.1 From c1795ed399c187ba739bc271c6837e26b9bfdf3d Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 23 Jan 2013 21:03:24 +0000 Subject: Add the Avination physics raycast glue so Core Physics can implement raycast --- OpenSim/Region/Framework/Scenes/Scene.cs | 13 ++++ OpenSim/Region/Physics/Manager/PhysicsScene.cs | 39 ++++++++++ .../Shared/Api/Implementation/LSL_Api.cs | 90 ++++++++++++++++++---- 3 files changed, 129 insertions(+), 13 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 5778176..f2cb117 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1983,6 +1983,19 @@ namespace OpenSim.Region.Framework.Scenes EventManager.TriggerPrimsLoaded(this); } + public bool SupportsRayCastFiltered() + { + if (PhysicsScene == null) + return false; + return PhysicsScene.SupportsRaycastWorldFiltered(); + } + + public object RayCastFiltered(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter) + { + if (PhysicsScene == null) + return null; + return PhysicsScene.RaycastWorld(position, direction, length, Count,filter); + } /// /// Gets a new rez location based on the raycast and the size of the object that is being rezzed. diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index 201007b..96a9ff7 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs @@ -43,6 +43,35 @@ namespace OpenSim.Region.Physics.Manager public delegate void JointDeactivated(PhysicsJoint joint); public delegate void JointErrorMessage(PhysicsJoint joint, string message); // this refers to an "error message due to a problem", not "amount of joint constraint violation" + public enum RayFilterFlags:ushort + { + // the flags + water = 0x01, + land = 0x02, + agent = 0x04, + nonphysical = 0x08, + physical = 0x10, + phantom = 0x20, + volumedtc = 0x40, + + // ray cast colision control (may only work for meshs) + ContactsUnImportant = 0x2000, + BackFaceCull = 0x4000, + ClosestHit = 0x8000, + + // some combinations + LSLPhanton = phantom | volumedtc, + PrimsNonPhantom = nonphysical | physical, + PrimsNonPhantomAgents = nonphysical | physical | agent, + + AllPrims = nonphysical | phantom | volumedtc | physical, + AllButLand = agent | nonphysical | physical | phantom | volumedtc, + + ClosestAndBackCull = ClosestHit | BackFaceCull, + + All = 0x3f + } + public delegate void RequestAssetDelegate(UUID assetID, AssetReceivedDelegate callback); public delegate void AssetReceivedDelegate(AssetBase asset); @@ -286,5 +315,15 @@ namespace OpenSim.Region.Physics.Manager { return new List(); } + + public virtual object RaycastWorld(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter) + { + return null; + } + + public virtual bool SupportsRaycastWorldFiltered() + { + return false; + } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 632b73f..3a7e1c7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -11340,25 +11340,89 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); - if (checkTerrain) + if (World.SupportsRayCastFiltered()) { - ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); - if (groundContact != null) - results.Add((ContactResult)groundContact); - } + if (dist == 0) + return list; + + RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull; + if (checkTerrain) + rayfilter |= RayFilterFlags.land; +// if (checkAgents) +// rayfilter |= RayFilterFlags.agent; + if (checkPhysical) + rayfilter |= RayFilterFlags.physical; + if (checkNonPhysical) + rayfilter |= RayFilterFlags.nonphysical; + if (detectPhantom) + rayfilter |= RayFilterFlags.LSLPhanton; + + Vector3 direction = dir * ( 1/dist); + + if(rayfilter == 0) + { + list.Add(new LSL_Integer(0)); + return list; + } + + // get some more contacts to sort ??? + int physcount = 4 * count; + if (physcount > 20) + physcount = 20; + + object physresults; + physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter); + + if (physresults == null) + { + list.Add(new LSL_Integer(-3)); // timeout error + return list; + } + + results = (List)physresults; - if (checkAgents) + // for now physics doesn't detect sitted avatars so do it outside physics + if (checkAgents) + { + ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); + foreach (ContactResult r in agentHits) + results.Add(r); + } + + // TODO: Replace this with a better solution. ObjectIntersection can only + // detect nonphysical phantoms. They are detected by virtue of being + // nonphysical (e.g. no PhysActor) so will not conflict with detecting + // physicsl phantoms as done by the physics scene + // We don't want anything else but phantoms here. + if (detectPhantom) + { + ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true); + foreach (ContactResult r in objectHits) + results.Add(r); + } + } + else { - ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); - foreach (ContactResult r in agentHits) - results.Add(r); + if (checkAgents) + { + ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); + foreach (ContactResult r in agentHits) + results.Add(r); + } + + if (checkPhysical || checkNonPhysical || detectPhantom) + { + ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); + foreach (ContactResult r in objectHits) + results.Add(r); + } } - if (checkPhysical || checkNonPhysical || detectPhantom) + if (checkTerrain) { - ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); - foreach (ContactResult r in objectHits) - results.Add(r); + ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); + if (groundContact != null) + results.Add((ContactResult)groundContact); } results.Sort(delegate(ContactResult a, ContactResult b) -- cgit v1.1 From a0d460e6bfa64a6c43ff327dcf19b696cc380fbb Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 18 Jan 2013 12:10:03 -0800 Subject: BulletSim: remove the unused RestoreBodyDependencies used by linksets and vehicles and clean up code by removing their kludgyness. --- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 7 ------- .../Physics/BulletSPlugin/BSLinksetConstraints.cs | 8 -------- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 20 ++------------------ 3 files changed, 2 insertions(+), 33 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 27d8ad0..0077da7 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -290,13 +290,6 @@ public sealed class BSLinksetCompound : BSLinkset return ret; } - // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true', - // this routine will restore the removed constraints. - // Called at taint-time!! - public override void RestoreBodyDependencies(BSPrim child) - { - } - // When the linkset is built, the child shape is added to the compound shape relative to the // root shape. The linkset then moves around but this does not move the actual child // prim. The child prim's location must be recomputed based on the location of the root shape. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index 89f186c..3011465 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -110,14 +110,6 @@ public sealed class BSLinksetConstraints : BSLinkset return ret; } - // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true', - // this routine will restore the removed constraints. - // Called at taint-time!! - public override void RestoreBodyDependencies(BSPrim child) - { - // The Refresh operation queued by RemoveBodyDependencies() will build any missing constraints. - } - // ================================================================ // Add a new child to the linkset. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index e6b8507..b37a1f8 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -1606,11 +1606,6 @@ public sealed class BSPrim : BSPhysObject // Called at taint-time!!! public void CreateGeomAndObject(bool forceRebuild) { - // If this prim is part of a linkset, we must remove and restore the physical - // links if the body is rebuilt. - bool needToRestoreLinkset = false; - bool needToRestoreVehicle = false; - // Create the correct physical representation for this type of object. // Updates PhysBody and PhysShape with the new information. // Ignore 'forceRebuild'. This routine makes the right choices and changes of necessary. @@ -1619,21 +1614,10 @@ public sealed class BSPrim : BSPhysObject // Called if the current prim body is about to be destroyed. // Remove all the physical dependencies on the old body. // (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...) - needToRestoreLinkset = Linkset.RemoveBodyDependencies(this); - needToRestoreVehicle = _vehicle.RemoveBodyDependencies(this); + Linkset.RemoveBodyDependencies(this); + _vehicle.RemoveBodyDependencies(this); }); - if (needToRestoreLinkset) - { - // If physical body dependencies were removed, restore them - Linkset.RestoreBodyDependencies(this); - } - if (needToRestoreVehicle) - { - // If physical body dependencies were removed, restore them - _vehicle.RestoreBodyDependencies(this); - } - // Make sure the properties are set on the new object UpdatePhysicalParameters(); return; -- cgit v1.1 From 775fd6f8cc27c80974b59a79be477a99950a7095 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 18 Jan 2013 12:12:45 -0800 Subject: BulletSim: fix build break introduced by previous commit --- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 5 ----- 1 file changed, 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 580ea4e..1e3e5d8 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -261,11 +261,6 @@ public abstract class BSLinkset // Called at taint-time!! public abstract bool RemoveBodyDependencies(BSPrim child); - // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true', - // this routine will restore the removed constraints. - // Called at taint-time!! - public abstract void RestoreBodyDependencies(BSPrim child); - // ================================================================ protected virtual float ComputeLinksetMass() { -- cgit v1.1 From c1371ab786a699ce91693e6e575bb81144a79c57 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 23 Jan 2013 08:28:36 -0800 Subject: BulletSim: working on COM --- OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs | 19 +++++++++++++++++++ .../Region/Physics/BulletSPlugin/BSLinksetCompound.cs | 7 ++++--- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 15 +++++++++++---- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 2 ++ 4 files changed, 36 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index bc163eb..2828cab 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs @@ -140,6 +140,25 @@ public struct EntityProperties public Vector3 Velocity; public Vector3 Acceleration; public Vector3 RotationalVelocity; + + public override string ToString() + { + StringBuilder buff = new StringBuilder(); + buff.Append(""); + return buff.ToString(); + } } // Format of this structure must match the definition in the C++ code diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 0077da7..d8e4028 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -377,7 +377,7 @@ public sealed class BSLinksetCompound : BSLinkset // Constraint linksets are rebuilt every time. // Note that this works for rebuilding just the root after a linkset is taken apart. // Called at taint time!! - private bool disableCOM = true; // disable until we get this debugged + private bool disableCOM = false; // disable until we get this debugged private void RecomputeLinksetCompound() { try @@ -400,8 +400,9 @@ public sealed class BSLinksetCompound : BSLinkset } // DEBUG DEBUG else { - centerOfMass = ComputeLinksetGeometricCenter(); - centerDisplacement = centerOfMass - LinksetRoot.RawPosition; + centerOfMass = ComputeLinksetCenterOfMass(); + // 'centerDisplacement' is the value to *add* to all the shape offsets + centerDisplacement = LinksetRoot.RawPosition - centerOfMass; // Since we're displacing the center of the shape, we need to move the body in the world LinksetRoot.PositionDisplacement = centerDisplacement; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index b37a1f8..dad7250 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -336,6 +336,7 @@ public sealed class BSPrim : BSPhysObject } } } + /* Disable. Presume whoever is setting displacement is already adjusting position, etc. // Override to have position displacement immediately update the physical position. // A feeble attempt to keep the sim and physical positions in sync // Must be called at taint time. @@ -355,6 +356,7 @@ public sealed class BSPrim : BSPhysObject }); } } + */ // Check that the current position is sane and, if not, modify the position to make it so. // Check for being below terrain and being out of bounds. @@ -371,11 +373,11 @@ public sealed class BSPrim : BSPhysObject return ret; } - float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); + float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition); OMV.Vector3 upForce = OMV.Vector3.Zero; if (RawPosition.Z < terrainHeight) { - DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); + DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, RawPosition, terrainHeight); float targetHeight = terrainHeight + (Size.Z / 2f); // If the object is below ground it just has to be moved up because pushing will // not get it through the terrain @@ -1637,7 +1639,11 @@ public sealed class BSPrim : BSPhysObject // entprop.RotationalVelocity = OMV.Vector3.Zero; } + DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG + // Assign directly to the local variables so the normal set actions do not happen + + // Undo any center-of-mass displacement that might have been done. entprop.Position -= PositionDisplacement; _position = entprop.Position; _orientation = entprop.Rotation; @@ -1645,6 +1651,8 @@ public sealed class BSPrim : BSPhysObject _acceleration = entprop.Acceleration; _rotationalVelocity = entprop.RotationalVelocity; + DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG + // The sanity check can change the velocity and/or position. if (IsPhysical && PositionSanityCheck(true)) { @@ -1653,8 +1661,7 @@ public sealed class BSPrim : BSPhysObject } OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG - DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}", - LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity); + DetailLog("{0},BSPrim.UpdateProperties,call,entProp={1},dir={2}", LocalID, entprop, direction); // remember the current and last set values LastEntityProperties = CurrentEntityProperties; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 41bab26..801f690 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -1,5 +1,7 @@ CURRENT PRIORITIES ================================================= +Deleting a linkset while standing on the root will leave the physical shape of the root behind. + Not sure if it is because standing on it. Done with large prim linksets. Child movement in linkset (don't rebuild linkset) Vehicle angular vertical attraction vehicle angular banking -- cgit v1.1 From a5e9c665f08059fef16d0b0875697cb08e16351e Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 23 Jan 2013 09:09:17 -0800 Subject: BulletSim: center-of-gravity linkset changes. Not working yet. Conflicts: OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs --- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 5 ++++- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 7 ++----- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 22 +--------------------- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 4 ++-- 4 files changed, 9 insertions(+), 29 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index d8e4028..2c8dd23 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -407,6 +407,9 @@ public sealed class BSLinksetCompound : BSLinkset // Since we're displacing the center of the shape, we need to move the body in the world LinksetRoot.PositionDisplacement = centerDisplacement; + // This causes the root prim position to be set properly based on the new PositionDisplacement + LinksetRoot.ForcePosition = LinksetRoot.RawPosition; + // Update the local transform for the root child shape so it is offset from the <0,0,0> which is COM PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, -centerDisplacement, OMV.Quaternion.Identity, false); DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}", LinksetRoot.LocalID, centerOfMass, LinksetRoot.RawPosition, centerDisplacement); @@ -438,7 +441,7 @@ public sealed class BSLinksetCompound : BSLinkset if (cPrim.PhysShape.isNativeShape) { - // A native shape is turning into a hull collision shape because native + // A native shape is turned into a hull collision shape because native // shapes are not shared so we have to hullify it so it will be tracked // and freed at the correct time. This also solves the scaling problem // (native shapes scaled but hull/meshes are assumed to not be). diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index da7438a..9460daf 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -645,11 +645,8 @@ public static class BSParam entries.Add(new PhysParameterEntry(pd.name, pd.desc)); } - // make the list in alphabetical order for estetic reasons - entries.Sort(delegate(PhysParameterEntry ppe1, PhysParameterEntry ppe2) - { - return ppe1.name.CompareTo(ppe2.name); - }); + // make the list alphabetical for estetic reasons + entries.Sort((ppe1, ppe2) => { return ppe1.name.CompareTo(ppe2.name); }); SettableParameters = entries.ToArray(); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index dad7250..ee2bfa0 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -322,6 +322,7 @@ public sealed class BSPrim : BSPhysObject }); } } + public override OMV.Vector3 ForcePosition { get { _position = PhysicsScene.PE.GetPosition(PhysBody) - PositionDisplacement; @@ -336,27 +337,6 @@ public sealed class BSPrim : BSPhysObject } } } - /* Disable. Presume whoever is setting displacement is already adjusting position, etc. - // Override to have position displacement immediately update the physical position. - // A feeble attempt to keep the sim and physical positions in sync - // Must be called at taint time. - public override OMV.Vector3 PositionDisplacement - { - get - { - return base.PositionDisplacement; - } - set - { - base.PositionDisplacement = value; - PhysicsScene.TaintedObject(PhysicsScene.InTaintTime, "BSPrim.setPosition", delegate() - { - if (PhysBody.HasPhysicalBody) - PhysicsScene.PE.SetTranslation(PhysBody, _position + base.PositionDisplacement, _orientation); - }); - } - } - */ // Check that the current position is sane and, if not, modify the position to make it so. // Check for being below terrain and being out of bounds. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 8075b73..34fd2a0 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -708,8 +708,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // TriggerPreStepEvent // DoOneTimeTaints // Step() - // ProcessAndForwardCollisions - // ProcessAndForwardPropertyUpdates + // ProcessAndSendToSimulatorCollisions + // ProcessAndSendToSimulatorPropertyUpdates // TriggerPostStepEvent // Calls to the PhysicsActors can't directly call into the physics engine -- cgit v1.1 From 13182904da897be1dad0bb86d8099bd0956ffac4 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 23 Jan 2013 09:11:01 -0800 Subject: BulletSim: small change to center-of-mass computation left out last commit --- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index ee2bfa0..731ab7b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -1621,10 +1621,15 @@ public sealed class BSPrim : BSPhysObject DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG - // Assign directly to the local variables so the normal set actions do not happen - // Undo any center-of-mass displacement that might have been done. - entprop.Position -= PositionDisplacement; + if (PositionDisplacement != OMV.Vector3.Zero) + { + // Correct for any rotation around the center-of-mass + // TODO!!! + entprop.Position -= PositionDisplacement; + } + + // Assign directly to the local variables so the normal set actions do not happen _position = entprop.Position; _orientation = entprop.Rotation; _velocity = entprop.Velocity; -- cgit v1.1 From a7b810ddeebda8b13af3ab9fbeb24bef1a8094c6 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 23 Jan 2013 14:21:52 -0800 Subject: BulletSim: remove setting of vehicle InterpolationRotationalVelocity. This doesn't seem to help the vehicle stability. Rename vehicle internal variables adding a "V" or "W" so it is clear when coordinates are vehicle or world relative. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 66 +++++++++++----------- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 4 +- 2 files changed, 34 insertions(+), 36 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index dbe44de..fe7891e 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -690,7 +690,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Bullet does a bunch of smoothing for changing parameters. // Since the vehicle is demanding this setting, we override Bullet's smoothing // by telling Bullet the value was the same last time. - PhysicsScene.PE.SetInterpolationLinearVelocity(Prim.PhysBody, m_knownVelocity); + // PhysicsScene.PE.SetInterpolationLinearVelocity(Prim.PhysBody, m_knownVelocity); } if ((m_knownChanged & m_knownChangedForce) != 0) @@ -702,7 +702,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) { Prim.ForceRotationalVelocity = m_knownRotationalVelocity; - PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity); + // PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity); } if ((m_knownChanged & m_knownChangedRotationalImpulse) != 0) @@ -963,23 +963,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin { // Step the motor from the current value. Get the correction needed this step. Vector3 currentVel = VehicleVelocity * Quaternion.Inverse(VehicleOrientation); - Vector3 linearMotorCorrection = m_linearMotor.Step(pTimestep, currentVel); + Vector3 linearMotorCorrectionV = m_linearMotor.Step(pTimestep, currentVel); // Motor is vehicle coordinates. Rotate it to world coordinates - Vector3 linearMotorVelocity = linearMotorCorrection * VehicleOrientation; + Vector3 linearMotorVelocityW = linearMotorCorrectionV * VehicleOrientation; // If we're a ground vehicle, don't add any upward Z movement if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0) { - if (linearMotorVelocity.Z > 0f) - linearMotorVelocity.Z = 0f; + if (linearMotorVelocityW.Z > 0f) + linearMotorVelocityW.Z = 0f; } // Add this correction to the velocity to make it faster/slower. - VehicleVelocity += linearMotorVelocity; + VehicleVelocity += linearMotorVelocityW; VDetailLog("{0}, MoveLinear,velocity,vehVel={1},correction={2},force={3}", - Prim.LocalID, VehicleVelocity, linearMotorCorrection, linearMotorVelocity); + Prim.LocalID, VehicleVelocity, linearMotorCorrectionV, linearMotorVelocityW); } public void ComputeLinearTerrainHeightCorrection(float pTimestep) @@ -1123,8 +1123,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin // a downward raycast to find what is below. public void ComputeLinearMotorUp(float pTimestep) { - Vector3 ret = Vector3.Zero; - if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) { // This code tries to decide if the object is not on the ground and then pushing down @@ -1250,8 +1248,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin private void ComputeAngularTurning(float pTimestep) { // The user wants this many radians per second angular change? - Vector3 currentAngular = VehicleRotationalVelocity * Quaternion.Inverse(VehicleOrientation); - Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep, currentAngular); + Vector3 currentAngularV = VehicleRotationalVelocity * Quaternion.Inverse(VehicleOrientation); + Vector3 angularMotorContributionV = m_angularMotor.Step(pTimestep, currentAngularV); // ================================================================== // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags : @@ -1263,12 +1261,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin // is a linear effect. Where should this check go? if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) { - angularMotorContribution.X = 0f; - angularMotorContribution.Y = 0f; + angularMotorContributionV.X = 0f; + angularMotorContributionV.Y = 0f; } - VehicleRotationalVelocity += angularMotorContribution * VehicleOrientation; - VDetailLog("{0}, MoveAngular,angularTurning,angularMotorContrib={1}", Prim.LocalID, angularMotorContribution); + VehicleRotationalVelocity += angularMotorContributionV * VehicleOrientation; + VDetailLog("{0}, MoveAngular,angularTurning,angularMotorContrib={1}", Prim.LocalID, angularMotorContributionV); } // From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial: @@ -1284,7 +1282,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // If vertical attaction timescale is reasonable if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff) { - Vector3 vertContribution = Vector3.Zero; + Vector3 vertContributionV = Vector3.Zero; // Take a vector pointing up and convert it from world to vehicle relative coords. Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; @@ -1299,26 +1297,26 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Y error means needed rotation around X axis and visa versa. // Since the error goes from zero to one, the asin is the corresponding angle. - vertContribution.X = (float)Math.Asin(verticalError.Y); + vertContributionV.X = (float)Math.Asin(verticalError.Y); // (Tilt forward (positive X) needs to tilt back (rotate negative) around Y axis.) - vertContribution.Y = -(float)Math.Asin(verticalError.X); + vertContributionV.Y = -(float)Math.Asin(verticalError.X); // If verticalError.Z is negative, the vehicle is upside down. Add additional push. if (verticalError.Z < 0f) { - vertContribution.X += PIOverFour; + vertContributionV.X += PIOverFour; // vertContribution.Y -= PIOverFour; } // 'vertContrbution' is now the necessary angular correction to correct tilt in one second. // Correction happens over a number of seconds. - Vector3 unscaledContrib = vertContribution; // DEBUG DEBUG - vertContribution /= m_verticalAttractionTimescale; + Vector3 unscaledContrib = vertContributionV; // DEBUG DEBUG + vertContributionV /= m_verticalAttractionTimescale; - VehicleRotationalVelocity += vertContribution * VehicleOrientation; + VehicleRotationalVelocity += vertContributionV * VehicleOrientation; VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},eff={3},ts={4},vertAttr={5}", - Prim.LocalID, verticalError, unscaledContrib, m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContribution); + Prim.LocalID, verticalError, unscaledContrib, m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContributionV); } } @@ -1336,7 +1334,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2) { - Vector3 deflectContribution = Vector3.Zero; + Vector3 deflectContributionV = Vector3.Zero; // The direction the vehicle is moving Vector3 movingDirection = VehicleVelocity; @@ -1363,13 +1361,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ret = m_angularDeflectionCorrectionMotor(1f, deflectionError); // Scale the correction by recovery timescale and efficiency - deflectContribution = (-deflectionError) * m_angularDeflectionEfficiency; - deflectContribution /= m_angularDeflectionTimescale; + deflectContributionV = (-deflectionError) * m_angularDeflectionEfficiency; + deflectContributionV /= m_angularDeflectionTimescale; - VehicleRotationalVelocity += deflectContribution * VehicleOrientation; + VehicleRotationalVelocity += deflectContributionV * VehicleOrientation; VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}", - Prim.LocalID, movingDirection, pointingDirection, deflectionError, deflectContribution); + Prim.LocalID, movingDirection, pointingDirection, deflectionError, deflectContributionV); VDetailLog("{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3}", Prim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale); } @@ -1410,7 +1408,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { if (enableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) { - Vector3 bankingContribution = Vector3.Zero; + Vector3 bankingContributionV = Vector3.Zero; // Rotate a UnitZ vector (pointing up) to how the vehicle is oriented. // As the vehicle rolls to the right or left, the Y value will increase from @@ -1428,15 +1426,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin mixedYawAngle = ClampInRange(-20f, mixedYawAngle, 20f); // Build the force vector to change rotation from what it is to what it should be - bankingContribution.Z = -mixedYawAngle; + bankingContributionV.Z = -mixedYawAngle; // Don't do it all at once. - bankingContribution /= m_bankingTimescale; + bankingContributionV /= m_bankingTimescale; - VehicleRotationalVelocity += bankingContribution * VehicleOrientation; + VehicleRotationalVelocity += bankingContributionV * VehicleOrientation; VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},rollComp={3},yAng={4},mYAng={5},ret={6}", - Prim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, bankingContribution); + Prim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, bankingContributionV); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 731ab7b..f80084a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -1619,7 +1619,7 @@ public sealed class BSPrim : BSPhysObject // entprop.RotationalVelocity = OMV.Vector3.Zero; } - DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG + // DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG // Undo any center-of-mass displacement that might have been done. if (PositionDisplacement != OMV.Vector3.Zero) @@ -1636,7 +1636,7 @@ public sealed class BSPrim : BSPhysObject _acceleration = entprop.Acceleration; _rotationalVelocity = entprop.RotationalVelocity; - DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG + // DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG // The sanity check can change the velocity and/or position. if (IsPhysical && PositionSanityCheck(true)) -- cgit v1.1 From 72dd3633eeb74c64620ffedb1618e732cbbca641 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 23 Jan 2013 23:34:15 +0000 Subject: Improve logging by making it clearer which script is failing if an assembly fails to load. Moves the noise co-op start/stop debug log messages to only display if xengine debug level >= 1 Logs which stop strategy is being used (abort or co-op) Adjusts some other logging to remove not very useful stuff --- .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 42 ++++++++++++---------- .../Region/ScriptEngine/XEngine/EventManager.cs | 4 +-- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 13 ++++--- 3 files changed, 31 insertions(+), 28 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 4cfcb75..5bc585e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -284,9 +284,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance else { m_log.ErrorFormat( - "[SCRIPT INSTANCE]: You must remove all existing script DLLs before using enabling co-op termination" + "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. You must remove all existing {6}* script DLL files before using enabling co-op termination" + ", either by setting DeleteScriptsOnStartup = true in [XEngine] for one run" - + " or by deleting all *.dll* files in the relevant bin/ScriptEngines// directory"); + + " or by deleting these files manually.", + ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, assembly); return false; } @@ -324,8 +325,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance catch (Exception e) { m_log.ErrorFormat( - "[SCRIPT INSTANCE]: Error loading assembly {0}. Exception {1}{2}", - assembly, e.Message, e.StackTrace); + "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Error loading assembly {6}. Exception {7}{8}", + ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, assembly, e.Message, e.StackTrace); return false; } @@ -345,8 +346,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance catch (Exception e) { m_log.ErrorFormat( - "[SCRIPT INSTANCE]: Error loading script instance from assembly {0}. Exception {1}{2}", - assembly, e.Message, e.StackTrace); + "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Error initializing script instance. Exception {6}{7}", + ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, e.Message, e.StackTrace); return false; } @@ -401,15 +402,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance else { m_log.WarnFormat( - "[SCRIPT INSTANCE]: Unable to load script state file {0} for script {1} {2} in {3} {4} (assembly {5}). Memory limit exceeded", - savedState, ScriptName, ItemID, PrimName, ObjectID, assembly); + "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Unable to load script state file {6}. Memory limit exceeded.", + ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, savedState); } } catch (Exception e) { m_log.ErrorFormat( - "[SCRIPT INSTANCE]: Unable to load script state file {0} for script {1} {2} in {3} {4} (assembly {5}). XML is {6}. Exception {7}{8}", - savedState, ScriptName, ItemID, PrimName, ObjectID, assembly, xml, e.Message, e.StackTrace); + "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Unable to load script state file {6}. XML is {7}. Exception {8}{9}", + ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, savedState, xml, e.Message, e.StackTrace); } } // else @@ -598,9 +599,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance } else { - m_log.DebugFormat( - "[SCRIPT INSTANCE]: Co-operatively stopping script {0} {1} in {2} {3}", - ScriptName, ItemID, PrimName, ObjectID); + if (DebugLevel >= 1) + m_log.DebugFormat( + "[SCRIPT INSTANCE]: Co-operatively stopping script {0} {1} in {2} {3}", + ScriptName, ItemID, PrimName, ObjectID); // This will terminate the event on next handle check by the script. m_coopSleepHandle.Set(); @@ -609,9 +611,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance // checking is implemented. May want to allow a shorter timeout option later. if (workItem.Wait(TimeSpan.MaxValue)) { - m_log.DebugFormat( - "[SCRIPT INSTANCE]: Co-operatively stopped script {0} {1} in {2} {3}", - ScriptName, ItemID, PrimName, ObjectID); + if (DebugLevel >= 1) + m_log.DebugFormat( + "[SCRIPT INSTANCE]: Co-operatively stopped script {0} {1} in {2} {3}", + ScriptName, ItemID, PrimName, ObjectID); return true; } @@ -922,9 +925,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance } else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException)) { - m_log.DebugFormat( - "[SCRIPT INSTANCE]: Script {0}.{1} in event {2}, state {3} stopped co-operatively.", - PrimName, ScriptName, data.EventName, State); + if (DebugLevel >= 1) + m_log.DebugFormat( + "[SCRIPT INSTANCE]: Script {0}.{1} in event {2}, state {3} stopped co-operatively.", + PrimName, ScriptName, data.EventName, State); } } } diff --git a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs index 9405075..afde685 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs @@ -52,7 +52,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine { myScriptEngine = _ScriptEngine; - m_log.Info("[XEngine] Hooking up to server events"); +// m_log.Info("[XEngine] Hooking up to server events"); myScriptEngine.World.EventManager.OnAttach += attach; myScriptEngine.World.EventManager.OnObjectGrab += touch_start; myScriptEngine.World.EventManager.OnObjectGrabbing += touch; @@ -69,7 +69,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine myScriptEngine.World.EventManager.OnScriptLandColliderStart += land_collision_start; myScriptEngine.World.EventManager.OnScriptLandColliding += land_collision; myScriptEngine.World.EventManager.OnScriptLandColliderEnd += land_collision_end; - IMoneyModule money=myScriptEngine.World.RequestModuleInterface(); + IMoneyModule money = myScriptEngine.World.RequestModuleInterface(); if (money != null) { money.OnObjectPaid+=HandleObjectPaid; diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 604924b..ad79a9b 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -241,7 +241,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_ScriptConfig = configSource.Configs["XEngine"]; m_ConfigSource = configSource; - if (m_ScriptConfig.GetString("ScriptStopStrategy", "abort") == "co-op") + string rawScriptStopStrategy = m_ScriptConfig.GetString("ScriptStopStrategy", "abort"); + + m_log.InfoFormat("[XEngine]: Script stop strategy is {0}", rawScriptStopStrategy); + + if (rawScriptStopStrategy == "co-op") { ScriptClassName = "XEngineScript"; ScriptBaseClassName = typeof(XEngineScriptBase).FullName; @@ -261,15 +265,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine { if (m_ScriptConfig == null) return; + m_ScriptFailCount = 0; m_ScriptErrorMessage = String.Empty; - if (m_ScriptConfig == null) - { -// m_log.ErrorFormat("[XEngine] No script configuration found. Scripts disabled"); - return; - } - m_Enabled = m_ScriptConfig.GetBoolean("Enabled", true); if (!m_Enabled) -- cgit v1.1 From 8a22ac3f94a3b8275d794721e0daca5c58e952a2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 23 Jan 2013 23:38:08 +0000 Subject: Pass narrower WaitHandle rather than EventWaitHandle as co-op termination wait handle to script APIs. APIs don't need to reference any methods on EventWaitHandle --- OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 4 ++-- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs index d2323f5..30e99b0 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs @@ -46,6 +46,6 @@ namespace OpenSim.Region.ScriptEngine.Interfaces /// /param> /// /param> void Initialize( - IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle); + IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle); } } \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index cee10a8..89ea4e9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -91,7 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// Used for script sleeps when we are using co-operative script termination. /// /// null if co-operative script termination is not active - EventWaitHandle m_coopSleepHandle; + WaitHandle m_coopSleepHandle; /// /// The item that hosts this script @@ -118,7 +118,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected ISoundModule m_SoundModule = null; public void Initialize( - IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle) + IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) { m_ScriptEngine = scriptEngine; m_host = host; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs index a08ccc8..1d6cb6d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs @@ -63,7 +63,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api internal IScriptModuleComms m_comms = null; public void Initialize( - IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle) + IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) { m_ScriptEngine = scriptEngine; m_host = host; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs index 981499e..9045672 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs @@ -63,7 +63,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api internal IScriptModuleComms m_comms = null; public void Initialize( - IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle) + IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) { m_ScriptEngine = scriptEngine; m_host = host; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 25635ff..f2f8fd6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -143,7 +143,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected IUrlModule m_UrlModule = null; public void Initialize( - IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle) + IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) { m_ScriptEngine = scriptEngine; m_host = host; -- cgit v1.1 From 1c3d84fe03811aad3896031a6391bd37e140f80c Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 23 Jan 2013 16:14:15 -0800 Subject: BulletSim: pass up and report the real collision penetration. --- OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs | 1 + OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index 2828cab..f25b447 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs @@ -130,6 +130,7 @@ public struct CollisionDesc public uint bID; public Vector3 point; public Vector3 normal; + public float penetration; } [StructLayout(LayoutKind.Sequential)] public struct EntityProperties diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 34fd2a0..35dba9b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -557,8 +557,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters uint cB = m_collisionArray[ii].bID; Vector3 point = m_collisionArray[ii].point; Vector3 normal = m_collisionArray[ii].normal; - SendCollision(cA, cB, point, normal, 0.01f); - SendCollision(cB, cA, point, -normal, 0.01f); + float penetration = m_collisionArray[ii].penetration; + SendCollision(cA, cB, point, normal, penetration); + SendCollision(cB, cA, point, -normal, penetration); } } -- cgit v1.1 From 1a610f30d8163271b8014aa020d71a025fc9fe98 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 24 Jan 2013 00:23:12 +0000 Subject: Fix mono 2.4.3 build break by using CreateInstanceAndUnwrap 9 method call deprecated in later .net versions --- OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 5bc585e..669cc37 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -306,6 +306,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance null, constructorParams, null, + null, null); else m_Script -- cgit v1.1 From b7757611047e45a7157f6b05bd900505d1bf32d8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 24 Jan 2013 00:31:42 +0000 Subject: Disable the not very useful infinite recursion co-op termination tests for now as they appear to cause failures with testing in jenkins. These tests are not very useful anyway as they never actually get a chance to try termination before the script runs out of stack --- .../ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs index 52d75a0..3b13386 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs @@ -264,7 +264,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests TestStop(script); } - [Test] + // Disabling for now as these are not particularly useful tests (since they fail due to stack overflow before + // termination can even be tried. +// [Test] public void TestStopOnInfiniteUserFunctionCallLoop() { TestHelpers.InMethod(); @@ -294,7 +296,9 @@ default TestStop(script); } - [Test] + // Disabling for now as these are not particularly useful tests (since they fail due to stack overflow before + // termination can even be tried. +// [Test] public void TestStopOnInfiniteManualEventCallLoop() { TestHelpers.InMethod(); -- cgit v1.1 From f7feed4d44ab3c2d0ad942d1ca8d04e3ab3417c3 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 24 Jan 2013 01:11:04 +0000 Subject: Remove unnecessary System.Linq reference from Compiler.cs Hopefully will fix windows build via compile.bat --- OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs index 002e852..9d20c9e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs @@ -31,7 +31,6 @@ using System.Collections.Generic; using System.Globalization; using System.Reflection; using System.IO; -using System.Linq; using System.Text; using Microsoft.CSharp; //using Microsoft.JScript; -- cgit v1.1 From 878df52515ea3519130ba646a050c8d8c1f09b29 Mon Sep 17 00:00:00 2001 From: teravus Date: Wed, 23 Jan 2013 21:58:51 -0500 Subject: * This makes the non-physics llCastRay 'better'. It's not 'correctly working', and if you look deep enough, you see that the results are not really stable depending on the direction of the ray. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 1 + .../Shared/Api/Implementation/LSL_Api.cs | 21 +++++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index e0ea344..6720635 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3628,6 +3628,7 @@ namespace OpenSim.Region.Framework.Scenes result.distance = distance2; result.HitTF = true; result.ipoint = q; + result.face = i; //m_log.Info("[FACE]:" + i.ToString()); //m_log.Info("[POINT]: " + q.ToString()); //m_log.Info("[DIST]: " + distance2.ToString()); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 63f4800..001f4d9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -11152,12 +11152,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api radius = Math.Abs(maxY); if (Math.Abs(maxZ) > radius) radius = Math.Abs(maxZ); - + radius = radius*1.413f; Vector3 ac = group.AbsolutePosition - rayStart; Vector3 bc = group.AbsolutePosition - rayEnd; double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); - + // Too far off ray, don't bother if (d > radius) return; @@ -11167,11 +11167,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (d2 > 0) return; + ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart)); EntityIntersection intersection = group.TestIntersection(ray, true, false); // Miss. if (!intersection.HitTF) return; + Vector3 b1 = group.AbsolutePosition + new Vector3(minX, minY, minZ); + Vector3 b2 = group.AbsolutePosition + new Vector3(maxX, maxY, maxZ); + //m_log.DebugFormat("[LLCASTRAY]: min<{0},{1},{2}>, max<{3},{4},{5}> = hitp<{6},{7},{8}>", b1.X,b1.Y,b1.Z,b2.X,b2.Y,b2.Z,intersection.ipoint.X,intersection.ipoint.Y,intersection.ipoint.Z); + if (!(intersection.ipoint.X >= b1.X && intersection.ipoint.X <= b2.X && + intersection.ipoint.Y >= b1.Y && intersection.ipoint.Y <= b2.Y && + intersection.ipoint.Z >= b1.Z && intersection.ipoint.Z <= b2.Z)) + return; + ContactResult result = new ContactResult (); result.ConsumerID = group.LocalId; result.Depth = intersection.distance; @@ -11423,8 +11432,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (checkPhysical || checkNonPhysical || detectPhantom) { ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); - foreach (ContactResult r in objectHits) - results.Add(r); + for (int iter = 0; iter < objectHits.Length; iter++) + { + // Redistance the Depth because the Scene RayCaster returns distance from center to make the rezzing code simpler. + objectHits[iter].Depth = Vector3.Distance(objectHits[iter].Pos, rayStart); + results.Add(objectHits[iter]); + } } } -- cgit v1.1 From ba9d6b7337d7e95a9c8d3bd7f2e98c323f1a00be Mon Sep 17 00:00:00 2001 From: teravus Date: Thu, 24 Jan 2013 07:11:32 -0500 Subject: * Repairs the Object updates, Collision updates, and Child Prim methods making the bulletXNA engine work again. * The only thing that had an issue was when creating a new RigidBody, BulletXNA didn't know the type SimMotionState and the upcast type is unknown in the constructor. Therefore, I had to update the IMotionState with a new method 'SetBody'. All of the duplicated type information has been removed and BulletXNA is not relying on any non-standard types external to the library. --- OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs | 446 ++++++++++++++--------- 1 file changed, 282 insertions(+), 164 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs index 49b1730..57c1308 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Runtime.InteropServices; using System.Text; using OpenSim.Framework; @@ -130,10 +131,12 @@ private sealed class BulletConstraintXNA : BulletConstraint } } internal int m_maxCollisions; - internal CollisionDesc[] m_collisionArray; - + internal CollisionDesc[] UpdatedCollisions; + internal int LastCollisionDesc = 0; internal int m_maxUpdatesPerFrame; - internal EntityProperties[] m_updateArray; + internal int LastEntityProperty = 0; + + internal EntityProperties[] UpdatedObjects; private static int m_collisionsThisFrame; private BSScene PhysicsScene { get; set; } @@ -900,7 +903,7 @@ private sealed class BulletConstraintXNA : BulletConstraint CollisionShape shape1 = (pShape as BulletShapeXNA).shape; // TODO: Turn this from a reference copy to a Value Copy. - BulletShapeXNA shape2 = new BulletShapeXNA(shape1, BSPhysicsShapeType.SHAPE_UNKNOWN); + BulletShapeXNA shape2 = new BulletShapeXNA(shape1, BSShapeTypeFromBroadPhaseNativeType(shape1.GetShapeType())); return shape2; } @@ -922,9 +925,9 @@ private sealed class BulletConstraintXNA : BulletConstraint CollisionShape shape = (pShape as BulletShapeXNA).shape; //UpdateSingleAabb(world, shape); // TODO: Feed Update array into null - SimMotionState motionState = new SimMotionState(world, pLocalID, mat, null); + SimMotionState motionState = new SimMotionState(this, pLocalID, mat, null); RigidBody body = new RigidBody(0,motionState,shape,IndexedVector3.Zero); - RigidBodyConstructionInfo constructionInfo = new RigidBodyConstructionInfo(0, new SimMotionState(world, pLocalID, mat, null),shape,IndexedVector3.Zero) + RigidBodyConstructionInfo constructionInfo = new RigidBodyConstructionInfo(0, motionState, shape, IndexedVector3.Zero) { m_mass = 0 }; @@ -1039,8 +1042,8 @@ private sealed class BulletConstraintXNA : BulletConstraint ) { - m_updateArray = updateArray; - m_collisionArray = collisionArray; + UpdatedObjects = updateArray; + UpdatedCollisions = collisionArray; /* TODO */ ConfigurationParameters[] configparms = new ConfigurationParameters[1]; configparms[0] = parms; @@ -1135,10 +1138,7 @@ private sealed class BulletConstraintXNA : BulletConstraint SequentialImpulseConstraintSolver m_solver = new SequentialImpulseConstraintSolver(); DiscreteDynamicsWorld world = new DiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, cci); - - - world.UpdatedObjects = BSAPIXNA.GetBulletXNAEntityStruct(BSAPIXNA.BulletSimEntityStructToByteArray(updateArray, updateArray.Length)); - world.UpdatedCollisions = BSAPIXNA.GetBulletXNACollisionStruct(BSAPIXNA.BulletSimCollisionStructToByteArray(collisionArray, collisionArray.Length)); + world.LastCollisionDesc = 0; world.LastEntityProperty = 0; @@ -1332,7 +1332,7 @@ private sealed class BulletConstraintXNA : BulletConstraint { CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; CollisionShape shape = collisionObject.GetCollisionShape(); - return new BulletShapeXNA(shape,BSPhysicsShapeType.SHAPE_UNKNOWN); + return new BulletShapeXNA(shape, BSShapeTypeFromBroadPhaseNativeType(shape.GetShapeType())); } //(PhysicsScene.World.ptr, nativeShapeData) @@ -1395,10 +1395,148 @@ private sealed class BulletConstraintXNA : BulletConstraint CollisionShape ret = null; ret = compoundshape.GetChildShape(pii); compoundshape.RemoveChildShapeByIndex(pii); - return new BulletShapeXNA(ret, BSPhysicsShapeType.SHAPE_UNKNOWN); + return new BulletShapeXNA(ret, BSShapeTypeFromBroadPhaseNativeType(ret.GetShapeType())); + } + + public override BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) { + /* TODO */ + if (cShape == null) + return null; + CompoundShape compoundShape = (cShape as BulletShapeXNA).shape as CompoundShape; + CollisionShape shape = compoundShape.GetChildShape(indx); + BulletShape retShape = new BulletShapeXNA(shape, BSShapeTypeFromBroadPhaseNativeType(shape.GetShapeType())); + + + return null; + } + + public BSPhysicsShapeType BSShapeTypeFromBroadPhaseNativeType(BroadphaseNativeTypes pin) + { + switch (pin) + { + case BroadphaseNativeTypes.BOX_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_BOX; + break; + case BroadphaseNativeTypes.TRIANGLE_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + + case BroadphaseNativeTypes.TETRAHEDRAL_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_MESH; + break; + case BroadphaseNativeTypes.CONVEX_HULL_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_HULL; + break; + case BroadphaseNativeTypes.CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.CUSTOM_POLYHEDRAL_SHAPE_TYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + //implicit convex shapes + case BroadphaseNativeTypes.IMPLICIT_CONVEX_SHAPES_START_HERE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.SPHERE_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_SPHERE; + break; + case BroadphaseNativeTypes.MULTI_SPHERE_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.CAPSULE_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_CAPSULE; + break; + case BroadphaseNativeTypes.CONE_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_CONE; + break; + case BroadphaseNativeTypes.CONVEX_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.CYLINDER_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_CYLINDER; + break; + case BroadphaseNativeTypes.UNIFORM_SCALING_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.MINKOWSKI_SUM_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.BOX_2D_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.CONVEX_2D_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.CUSTOM_CONVEX_SHAPE_TYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + //concave shape + case BroadphaseNativeTypes.CONCAVE_SHAPES_START_HERE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + //keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy! + case BroadphaseNativeTypes.TRIANGLE_MESH_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_MESH; + break; + case BroadphaseNativeTypes.SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_MESH; + break; + ///used for demo integration FAST/Swift collision library and Bullet + case BroadphaseNativeTypes.FAST_CONCAVE_MESH_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_MESH; + break; + //terrain + case BroadphaseNativeTypes.TERRAIN_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_HEIGHTMAP; + break; + ///Used for GIMPACT Trimesh integration + case BroadphaseNativeTypes.GIMPACT_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_MESH; + break; + ///Multimaterial mesh + case BroadphaseNativeTypes.MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_MESH; + break; + + case BroadphaseNativeTypes.EMPTY_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.STATIC_PLANE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_GROUNDPLANE; + break; + case BroadphaseNativeTypes.CUSTOM_CONCAVE_SHAPE_TYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.CONCAVE_SHAPES_END_HERE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + + case BroadphaseNativeTypes.COMPOUND_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_COMPOUND; + break; + + case BroadphaseNativeTypes.SOFTBODY_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_MESH; + break; + case BroadphaseNativeTypes.HFFLUID_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + case BroadphaseNativeTypes.INVALID_SHAPE_PROXYTYPE: + return BSPhysicsShapeType.SHAPE_UNKNOWN; + break; + } + return BSPhysicsShapeType.SHAPE_UNKNOWN; } - public override BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) { /* TODO */ return null; } public override void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape) { /* TODO */ } public override void UpdateChildTransform(BulletShape pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb) { /* TODO */ } @@ -1636,11 +1774,21 @@ private sealed class BulletConstraintXNA : BulletConstraint return epic; } - private static int PhysicsStepint(BulletWorld pWorld,float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount, + private int PhysicsStepint(BulletWorld pWorld,float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount, out EntityProperties[] updatedEntities, out int collidersCount, out CollisionDesc[] colliders, int maxCollisions, int maxUpdates) { int numSimSteps = 0; + Array.Clear(UpdatedObjects, 0, UpdatedObjects.Length); + Array.Clear(UpdatedCollisions, 0, UpdatedCollisions.Length); + LastEntityProperty=0; + + + + + + LastCollisionDesc=0; + updatedEntityCount = 0; collidersCount = 0; @@ -1651,8 +1799,6 @@ private sealed class BulletConstraintXNA : BulletConstraint world.LastCollisionDesc = 0; world.LastEntityProperty = 0; - world.UpdatedObjects = new BulletXNA.EntityProperties[maxUpdates]; - world.UpdatedCollisions = new BulletXNA.CollisionDesc[maxCollisions]; numSimSteps = world.StepSimulation(timeStep, m_maxSubSteps, m_fixedTimeStep); int updates = 0; @@ -1675,7 +1821,7 @@ private sealed class BulletConstraintXNA : BulletConstraint IndexedVector3 contactPoint = manifoldPoint.GetPositionWorldOnB(); IndexedVector3 contactNormal = -manifoldPoint.m_normalWorldOnB; // make relative to A - RecordCollision(world, objA, objB, contactPoint, contactNormal); + RecordCollision(this, objA, objB, contactPoint, contactNormal); m_collisionsThisFrame ++; if (m_collisionsThisFrame >= 9999999) break; @@ -1683,15 +1829,16 @@ private sealed class BulletConstraintXNA : BulletConstraint } - updatedEntityCount = world.LastEntityProperty; - updatedEntities = GetBulletSimEntityStruct(BulletXNAEntityStructToByteArray(world.UpdatedObjects, world.LastEntityProperty)); + updatedEntityCount = LastEntityProperty; + updatedEntities = UpdatedObjects; + - collidersCount = world.LastCollisionDesc; - colliders = - GetBulletSimCollisionStruct(BulletXNACollisionStructToByteArray(world.UpdatedCollisions, world.LastCollisionDesc));//new List(world.UpdatedCollisions); + collidersCount = LastCollisionDesc; + colliders = UpdatedCollisions; + } else @@ -1699,8 +1846,8 @@ private sealed class BulletConstraintXNA : BulletConstraint //if (updatedEntities is null) //updatedEntities = new List(); //updatedEntityCount = 0; - //if (colliders is null) - //colliders = new List(); + + //collidersCount = 0; updatedEntities = new EntityProperties[0]; @@ -1712,7 +1859,7 @@ private sealed class BulletConstraintXNA : BulletConstraint return numSimSteps; } - private static void RecordCollision(CollisionWorld world, CollisionObject objA, CollisionObject objB, IndexedVector3 contact, IndexedVector3 norm) + private static void RecordCollision(BSAPIXNA world, CollisionObject objA, CollisionObject objB, IndexedVector3 contact, IndexedVector3 norm) { IndexedVector3 contactNormal = norm; @@ -1733,12 +1880,12 @@ private sealed class BulletConstraintXNA : BulletConstraint ulong collisionID = ((ulong) idA << 32) | idB; - BulletXNA.CollisionDesc cDesc = new BulletXNA.CollisionDesc() + CollisionDesc cDesc = new CollisionDesc() { aID = idA, bID = idB, - point = contact, - normal = contactNormal + point = new Vector3(contact.X,contact.Y,contact.Z), + normal = new Vector3(contactNormal.X,contactNormal.Y,contactNormal.Z) }; if (world.LastCollisionDesc < world.UpdatedCollisions.Length) world.UpdatedCollisions[world.LastCollisionDesc++] = (cDesc); @@ -1800,160 +1947,131 @@ private sealed class BulletConstraintXNA : BulletConstraint } return false; } - - public static unsafe BulletXNA.CollisionDesc[] GetBulletXNACollisionStruct(byte[] buffer) +} + + + + + public class SimMotionState : DefaultMotionState { - int count = buffer.Length/sizeof (BulletXNA.CollisionDesc); - BulletXNA.CollisionDesc[] result = new BulletXNA.CollisionDesc[count]; - BulletXNA.CollisionDesc* ptr; - fixed (byte* localBytes = new byte[buffer.Length]) + public RigidBody Rigidbody; + public Vector3 ZeroVect; + + private IndexedMatrix m_xform; + + private EntityProperties m_properties; + private EntityProperties m_lastProperties; + private BSAPIXNA m_world; + + const float POSITION_TOLERANCE = 0.05f; + const float VELOCITY_TOLERANCE = 0.001f; + const float ROTATION_TOLERANCE = 0.01f; + const float ANGULARVELOCITY_TOLERANCE = 0.01f; + + public SimMotionState(BSAPIXNA pWorld, uint id, IndexedMatrix starTransform, object frameUpdates) { - for (int i = 0; i < buffer.Length; i++) + IndexedQuaternion OrientationQuaterion = starTransform.GetRotation(); + m_properties = new EntityProperties() + { + ID = id, + Position = new Vector3(starTransform._origin.X, starTransform._origin.Y,starTransform._origin.Z), + Rotation = new Quaternion(OrientationQuaterion.X,OrientationQuaterion.Y,OrientationQuaterion.Z,OrientationQuaterion.W) + }; + m_lastProperties = new EntityProperties() { - localBytes[i] = buffer[i]; - } - for (int i=0;i count ? count : CollisionDescArray.Length; - byte[] byteArray = new byte[sizeof(CollisionDesc) * arrayLength]; - fixed (CollisionDesc* floatPointer = CollisionDescArray) + + public override void SetWorldTransform(IndexedMatrix worldTrans) { - fixed (byte* bytePointer = byteArray) - { - CollisionDesc* read = floatPointer; - CollisionDesc* write = (CollisionDesc*)bytePointer; - for (int i = 0; i < arrayLength; i++) - { - *write++ = *read++; - } - } + SetWorldTransform(ref worldTrans); } - return byteArray; - } - public static unsafe byte[] BulletXNACollisionStructToByteArray(BulletXNA.CollisionDesc[] CollisionDescArray, int count) - { - int arrayLength = CollisionDescArray.Length > count ? count : CollisionDescArray.Length; - byte[] byteArray = new byte[sizeof(BulletXNA.CollisionDesc) * arrayLength]; - fixed (BulletXNA.CollisionDesc* floatPointer = CollisionDescArray) + + public override void SetWorldTransform(ref IndexedMatrix worldTrans) { - fixed (byte* bytePointer = byteArray) - { - BulletXNA.CollisionDesc* read = floatPointer; - BulletXNA.CollisionDesc* write = (BulletXNA.CollisionDesc*)bytePointer; - for (int i = 0; i < arrayLength; i++) - { - *write++ = *read++; - } - } + SetWorldTransform(ref worldTrans, false); } - return byteArray; - } - public static unsafe BulletXNA.EntityProperties[] GetBulletXNAEntityStruct(byte[] buffer) - { - int count = buffer.Length / sizeof(BulletXNA.EntityProperties); - BulletXNA.EntityProperties[] result = new BulletXNA.EntityProperties[count]; - BulletXNA.EntityProperties* ptr; - fixed (byte* localBytes = new byte[buffer.Length]) + public void SetWorldTransform(ref IndexedMatrix worldTrans, bool force) { - for (int i = 0; i < buffer.Length; i++) - { - localBytes[i] = buffer[i]; - } - for (int i = 0; i < count; i++) + m_xform = worldTrans; + // Put the new transform into m_properties + IndexedQuaternion OrientationQuaternion = m_xform.GetRotation(); + IndexedVector3 LinearVelocityVector = Rigidbody.GetLinearVelocity(); + IndexedVector3 AngularVelocityVector = Rigidbody.GetAngularVelocity(); + m_properties.Position = new Vector3(m_xform._origin.X, m_xform._origin.Y, m_xform._origin.Z); + m_properties.Rotation = new Quaternion(OrientationQuaternion.X, OrientationQuaternion.Y, + OrientationQuaternion.Z, OrientationQuaternion.W); + // A problem with stock Bullet is that we don't get an event when an object is deactivated. + // This means that the last non-zero values for linear and angular velocity + // are left in the viewer who does dead reconning and the objects look like + // they float off. + // BulletSim ships with a patch to Bullet which creates such an event. + m_properties.Velocity = new Vector3(LinearVelocityVector.X, LinearVelocityVector.Y, LinearVelocityVector.Z); + m_properties.RotationalVelocity = new Vector3(AngularVelocityVector.X, AngularVelocityVector.Y, AngularVelocityVector.Z); + + if (force + + || !AlmostEqual(ref m_lastProperties.Position, ref m_properties.Position, POSITION_TOLERANCE) + || !AlmostEqual(ref m_properties.Rotation, ref m_lastProperties.Rotation, ROTATION_TOLERANCE) + // If the Velocity and AngularVelocity are zero, most likely the object has + // been deactivated. If they both are zero and they have become zero recently, + // make sure a property update is sent so the zeros make it to the viewer. + || ((m_properties.Velocity == ZeroVect && m_properties.RotationalVelocity == ZeroVect) + && + (m_properties.Velocity != m_lastProperties.Velocity || + m_properties.RotationalVelocity != m_lastProperties.RotationalVelocity)) + // If Velocity and AngularVelocity are non-zero but have changed, send an update. + || !AlmostEqual(ref m_properties.Velocity, ref m_lastProperties.Velocity, VELOCITY_TOLERANCE) + || + !AlmostEqual(ref m_properties.RotationalVelocity, ref m_lastProperties.RotationalVelocity, + ANGULARVELOCITY_TOLERANCE) + ) + + { - ptr = (BulletXNA.EntityProperties*)(localBytes + sizeof(BulletXNA.EntityProperties) * i); - result[i] = new BulletXNA.EntityProperties(); - result[i] = *ptr; + // Add this update to the list of updates for this frame. + m_lastProperties = m_properties; + if (m_world.LastEntityProperty < m_world.UpdatedObjects.Length) + m_world.UpdatedObjects[m_world.LastEntityProperty++]=(m_properties); + + //(*m_updatesThisFrame)[m_properties.ID] = &m_properties; } - } - return result; - } + + + - public static unsafe EntityProperties[] GetBulletSimEntityStruct(byte[] buffer) - { - int count = buffer.Length / sizeof(EntityProperties); - EntityProperties[] result = new EntityProperties[count]; - EntityProperties* ptr; - fixed (byte* localBytes = new byte[buffer.Length]) + } + public override void SetRigidBody(RigidBody body) { - for (int i = 0; i < buffer.Length; i++) - { - localBytes[i] = buffer[i]; - } - for (int i = 0; i < count; i++) - { - ptr = (EntityProperties*)(localBytes + sizeof(EntityProperties) * i); - result[i] = new EntityProperties(); - result[i] = *ptr; - } + Rigidbody = body; } - return result; - } - public static unsafe byte[] BulletSimEntityStructToByteArray(EntityProperties[] CollisionDescArray, int count) - { - int arrayLength = CollisionDescArray.Length > count ? count : CollisionDescArray.Length; - byte[] byteArray = new byte[sizeof(EntityProperties) * arrayLength]; - fixed (EntityProperties* floatPointer = CollisionDescArray) + internal static bool AlmostEqual(ref Vector3 v1, ref Vector3 v2, float nEpsilon) { - fixed (byte* bytePointer = byteArray) - { - EntityProperties* read = floatPointer; - EntityProperties* write = (EntityProperties*)bytePointer; - for (int i = 0; i < arrayLength; i++) - { - *write++ = *read++; - } - } + return + (((v1.X - nEpsilon) < v2.X) && (v2.X < (v1.X + nEpsilon))) && + (((v1.Y - nEpsilon) < v2.Y) && (v2.Y < (v1.Y + nEpsilon))) && + (((v1.Z - nEpsilon) < v2.Z) && (v2.Z < (v1.Z + nEpsilon))); } - return byteArray; - } - public static unsafe byte[] BulletXNAEntityStructToByteArray(BulletXNA.EntityProperties[] CollisionDescArray, int count) - { - int arrayLength = CollisionDescArray.Length > count ? count : CollisionDescArray.Length; - byte[] byteArray = new byte[sizeof(BulletXNA.EntityProperties) * arrayLength]; - fixed (BulletXNA.EntityProperties* floatPointer = CollisionDescArray) + + internal static bool AlmostEqual(ref Quaternion v1, ref Quaternion v2, float nEpsilon) { - fixed (byte* bytePointer = byteArray) - { - BulletXNA.EntityProperties* read = floatPointer; - BulletXNA.EntityProperties* write = (BulletXNA.EntityProperties*)bytePointer; - for (int i = 0; i < arrayLength; i++) - { - *write++ = *read++; - } - } + return + (((v1.X - nEpsilon) < v2.X) && (v2.X < (v1.X + nEpsilon))) && + (((v1.Y - nEpsilon) < v2.Y) && (v2.Y < (v1.Y + nEpsilon))) && + (((v1.Z - nEpsilon) < v2.Z) && (v2.Z < (v1.Z + nEpsilon))) && + (((v1.W - nEpsilon) < v2.W) && (v2.W < (v1.W + nEpsilon))); } - return byteArray; + } } -} + -- cgit v1.1 From d5b950633d1fea8c868dd21fbdbc548553b1b13c Mon Sep 17 00:00:00 2001 From: teravus Date: Thu, 24 Jan 2013 07:36:24 -0500 Subject: * Added in the manifold point dept on collision desc. In BulletSim engine BulletXNA. --- OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs | 69 ++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs index 57c1308..f63d83c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs @@ -1821,7 +1821,7 @@ private sealed class BulletConstraintXNA : BulletConstraint IndexedVector3 contactPoint = manifoldPoint.GetPositionWorldOnB(); IndexedVector3 contactNormal = -manifoldPoint.m_normalWorldOnB; // make relative to A - RecordCollision(this, objA, objB, contactPoint, contactNormal); + RecordCollision(this, objA, objB, contactPoint, contactNormal,manifoldPoint.GetDistance()); m_collisionsThisFrame ++; if (m_collisionsThisFrame >= 9999999) break; @@ -1858,8 +1858,64 @@ private sealed class BulletConstraintXNA : BulletConstraint } return numSimSteps; } - - private static void RecordCollision(BSAPIXNA world, CollisionObject objA, CollisionObject objB, IndexedVector3 contact, IndexedVector3 norm) + public void RecordGhostCollisions(PairCachingGhostObject obj) + { + /* + *void BulletSim::RecordGhostCollisions(btPairCachingGhostObject* obj) +{ + btManifoldArray manifoldArray; + btBroadphasePairArray& pairArray = obj->getOverlappingPairCache()->getOverlappingPairArray(); + int numPairs = pairArray.size(); + + // For all the pairs of sets of contact points + for (int i=0; i < numPairs; i++) + { + if (m_collisionsThisFrame >= m_maxCollisionsPerFrame) + break; + + manifoldArray.clear(); + const btBroadphasePair& pair = pairArray[i]; + + // The real representation is over in the world pair cache + btBroadphasePair* collisionPair = m_worldData.dynamicsWorld->getPairCache()->findPair(pair.m_pProxy0,pair.m_pProxy1); + if (!collisionPair) + continue; + + if (collisionPair->m_algorithm) + collisionPair->m_algorithm->getAllContactManifolds(manifoldArray); + + // The collision pair has sets of collision points (manifolds) + for (int j=0; j < manifoldArray.size(); j++) + { + btPersistentManifold* contactManifold = manifoldArray[j]; + int numContacts = contactManifold->getNumContacts(); + + const btCollisionObject* objA = static_cast(contactManifold->getBody0()); + const btCollisionObject* objB = static_cast(contactManifold->getBody1()); + + // TODO: this is a more thurough check than the regular collision code -- + // here we find the penetrating contact in the manifold but for regular + // collisions we assume the first point in the manifold is good enough. + // Decide of this extra checking is required or if first point is good enough. + for (int p=0; p < numContacts; p++) + { + const btManifoldPoint& pt = contactManifold->getContactPoint(p); + // If a penetrating contact, this is a hit + if (pt.getDistance()<0.f) + { + const btVector3& contactPoint = pt.getPositionWorldOnA(); + const btVector3& normalOnA = -pt.m_normalWorldOnB; + RecordCollision(objA, objB, contactPoint, normalOnA, pt.getDistance()); + // Only one contact point for each set of colliding objects + break; + } + } + } + } +} + */ + } + private static void RecordCollision(BSAPIXNA world, CollisionObject objA, CollisionObject objB, IndexedVector3 contact, IndexedVector3 norm, float penetration) { IndexedVector3 contactNormal = norm; @@ -1885,7 +1941,9 @@ private sealed class BulletConstraintXNA : BulletConstraint aID = idA, bID = idB, point = new Vector3(contact.X,contact.Y,contact.Z), - normal = new Vector3(contactNormal.X,contactNormal.Y,contactNormal.Z) + normal = new Vector3(contactNormal.X,contactNormal.Y,contactNormal.Z), + penetration = penetration + }; if (world.LastCollisionDesc < world.UpdatedCollisions.Length) world.UpdatedCollisions[world.LastCollisionDesc++] = (cDesc); @@ -1911,7 +1969,8 @@ private sealed class BulletConstraintXNA : BulletConstraint return ent; } - public override bool UpdateParameter(BulletWorld world, uint localID, String parm, float value) { /* TODO */ return false; } + public override bool UpdateParameter(BulletWorld world, uint localID, String parm, float value) { /* TODO */ + return false; } public override Vector3 GetLocalScaling(BulletShape pShape) { -- cgit v1.1 From 427ab219b8ecf7f039d03ed3067e183db1434fb2 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 24 Jan 2013 10:44:57 -0800 Subject: Add JSONification of WebStats module. Adds a '?json' query parameter to the fetch URL to return the data in JSON format. Also adds a simple 'sim.html' that uses JavaScript to display the JSON data. Not pretty but an example. --- .../Region/UserStatistics/ActiveConnectionsAJAX.cs | 84 +++++++++++++++++++++- OpenSim/Region/UserStatistics/Clients_report.cs | 27 +++++++ OpenSim/Region/UserStatistics/Default_Report.cs | 27 +++++++ OpenSim/Region/UserStatistics/IStatsReport.cs | 1 + OpenSim/Region/UserStatistics/LogLinesAJAX.cs | 29 ++++++++ .../Region/UserStatistics/Prototype_distributor.cs | 31 +++++--- OpenSim/Region/UserStatistics/Sessions_Report.cs | 5 ++ OpenSim/Region/UserStatistics/SimStatsAJAX.cs | 59 +++++++++++++++ .../Region/UserStatistics/Updater_distributor.cs | 4 ++ OpenSim/Region/UserStatistics/WebStatsModule.cs | 25 ++++++- 10 files changed, 281 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs b/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs index 3243a9a..6a1112c 100644 --- a/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs +++ b/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs @@ -32,6 +32,7 @@ using System.Reflection; using System.Text; using Mono.Data.SqliteClient; using OpenMetaverse; +using OpenMetaverse.StructuredData; using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; using OpenSim.Framework.Monitoring; @@ -51,7 +52,6 @@ namespace OpenSim.Region.UserStatistics public Hashtable ProcessModel(Hashtable pParams) { - List m_scene = (List)pParams["Scenes"]; Hashtable nh = new Hashtable(); @@ -129,6 +129,86 @@ namespace OpenSim.Region.UserStatistics return output.ToString(); } + /// + /// Convert active connections information to JSON string. Returns a structure: + ///
+        /// {"regionName": {
+        ///     "presenceName": {
+        ///         "name": "presenceName",
+        ///         "position": "",
+        ///         "isRoot": "false",
+        ///         "throttle": {
+        ///         },
+        ///         "queue": {
+        ///         }
+        ///     },
+        ///     ... // multiple presences in the scene
+        ///   },
+        ///   ...   // multiple regions in the sim
+        /// }
+        ///
+        /// 
+ ///
+ /// + /// + public string RenderJson(Hashtable pModelResult) + { + List all_scenes = (List) pModelResult["hdata"]; + + OSDMap regionInfo = new OSDMap(); + foreach (Scene scene in all_scenes) + { + OSDMap sceneInfo = new OpenMetaverse.StructuredData.OSDMap(); + List avatarInScene = scene.GetScenePresences(); + foreach (ScenePresence av in avatarInScene) + { + OSDMap presenceInfo = new OSDMap(); + presenceInfo.Add("Name", new OSDString(av.Name)); + + Dictionary queues = new Dictionary(); + if (av.ControllingClient is IStatsCollector) + { + IStatsCollector isClient = (IStatsCollector) av.ControllingClient; + queues = decodeQueueReport(isClient.Report()); + } + OSDMap queueInfo = new OpenMetaverse.StructuredData.OSDMap(); + foreach (KeyValuePair kvp in queues) { + queueInfo.Add(kvp.Key, new OSDString(kvp.Value)); + } + sceneInfo.Add("queues", queueInfo); + + if (av.IsChildAgent) + presenceInfo.Add("isRoot", new OSDString("false")); + else + presenceInfo.Add("isRoot", new OSDString("true")); + + if (av.AbsolutePosition == DefaultNeighborPosition) + { + presenceInfo.Add("position", new OSDString("<0, 0, 0>")); + } + else + { + presenceInfo.Add("position", new OSDString(string.Format("<{0},{1},{2}>", + (int)av.AbsolutePosition.X, + (int) av.AbsolutePosition.Y, + (int) av.AbsolutePosition.Z)) ); + } + + Dictionary throttles = DecodeClientThrottles(av.ControllingClient.GetThrottlesPacked(1)); + OSDMap throttleInfo = new OpenMetaverse.StructuredData.OSDMap(); + foreach (string throttlename in throttles.Keys) + { + throttleInfo.Add(throttlename, new OSDString(throttles[throttlename].ToString())); + } + presenceInfo.Add("throttle", throttleInfo); + + sceneInfo.Add(av.Name, presenceInfo); + } + regionInfo.Add(scene.RegionInfo.RegionName, sceneInfo); + } + return regionInfo.ToString(); + } + public Dictionary DecodeClientThrottles(byte[] throttle) { Dictionary returndict = new Dictionary(); @@ -203,7 +283,7 @@ namespace OpenSim.Region.UserStatistics returndic.Add("Cloud", rep.Substring((7 * pos) , 8)); pos++; returndic.Add("Task", rep.Substring((7 * pos) , 8)); pos++; returndic.Add("Texture", rep.Substring((7 * pos), 8)); pos++; - returndic.Add("Asset", rep.Substring((7 * pos), 8)); + returndic.Add("Asset", rep.Substring((7 * pos), 8)); /* * return string.Format("{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}", SendQueue.Count(), diff --git a/OpenSim/Region/UserStatistics/Clients_report.cs b/OpenSim/Region/UserStatistics/Clients_report.cs index b2bb33b..4a6f7be 100644 --- a/OpenSim/Region/UserStatistics/Clients_report.cs +++ b/OpenSim/Region/UserStatistics/Clients_report.cs @@ -31,6 +31,7 @@ using System.Collections.Generic; using System.Text; using Mono.Data.SqliteClient; using OpenMetaverse; +using OpenMetaverse.StructuredData; using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.UserStatistics @@ -44,6 +45,32 @@ namespace OpenSim.Region.UserStatistics get { return "Client"; } } + /// + /// Return summar information in the form: + ///
+        /// {"totalUsers": "34",
+        ///  "totalSessions": "233",
+        ///  ...
+        /// }
+        /// 
+ ///
+ /// + /// + public string RenderJson(Hashtable pModelResult) { + stats_default_page_values values = (stats_default_page_values) pModelResult["hdata"]; + + OSDMap summaryInfo = new OpenMetaverse.StructuredData.OSDMap(); + summaryInfo.Add("totalUsers", new OSDString(values.total_num_users.ToString())); + summaryInfo.Add("totalSessions", new OSDString(values.total_num_sessions.ToString())); + summaryInfo.Add("averageClientFPS", new OSDString(values.avg_client_fps.ToString())); + summaryInfo.Add("averageClientMem", new OSDString(values.avg_client_mem_use.ToString())); + summaryInfo.Add("averageSimFPS", new OSDString(values.avg_sim_fps.ToString())); + summaryInfo.Add("averagePingTime", new OSDString(values.avg_ping.ToString())); + summaryInfo.Add("totalKBOut", new OSDString(values.total_kb_out.ToString())); + summaryInfo.Add("totalKBIn", new OSDString(values.total_kb_in.ToString())); + return summaryInfo.ToString(); + } + public Hashtable ProcessModel(Hashtable pParams) { SqliteConnection dbConn = (SqliteConnection)pParams["DatabaseConnection"]; diff --git a/OpenSim/Region/UserStatistics/Default_Report.cs b/OpenSim/Region/UserStatistics/Default_Report.cs index cdc615c..fabe3d4 100644 --- a/OpenSim/Region/UserStatistics/Default_Report.cs +++ b/OpenSim/Region/UserStatistics/Default_Report.cs @@ -32,6 +32,7 @@ using System.Reflection; using System.Text; using Mono.Data.SqliteClient; using OpenMetaverse; +using OpenMetaverse.StructuredData; using OpenSim.Region.Framework.Scenes; using OpenSim.Framework.Monitoring; @@ -230,6 +231,31 @@ TD.align_top { vertical-align: top; } return returnstruct; } + /// + /// Return summar information in the form: + ///
+        /// {"totalUsers": "34",
+        ///  "totalSessions": "233",
+        ///  ...
+        /// }
+        /// 
+ ///
+ /// + /// + public string RenderJson(Hashtable pModelResult) { + stats_default_page_values values = (stats_default_page_values) pModelResult["hdata"]; + + OSDMap summaryInfo = new OSDMap(); + summaryInfo.Add("totalUsers", new OSDString(values.total_num_users.ToString())); + summaryInfo.Add("totalSessions", new OSDString(values.total_num_sessions.ToString())); + summaryInfo.Add("averageClientFPS", new OSDString(values.avg_client_fps.ToString())); + summaryInfo.Add("averageClientMem", new OSDString(values.avg_client_mem_use.ToString())); + summaryInfo.Add("averageSimFPS", new OSDString(values.avg_sim_fps.ToString())); + summaryInfo.Add("averagePingTime", new OSDString(values.avg_ping.ToString())); + summaryInfo.Add("totalKBOut", new OSDString(values.total_kb_out.ToString())); + summaryInfo.Add("totalKBIn", new OSDString(values.total_kb_in.ToString())); + return summaryInfo.ToString(); + } } public struct stats_default_page_values @@ -247,4 +273,5 @@ TD.align_top { vertical-align: top; } public Dictionary sim_stat_data; public Dictionary stats_reports; } + } diff --git a/OpenSim/Region/UserStatistics/IStatsReport.cs b/OpenSim/Region/UserStatistics/IStatsReport.cs index e0ecce4..80c4487 100644 --- a/OpenSim/Region/UserStatistics/IStatsReport.cs +++ b/OpenSim/Region/UserStatistics/IStatsReport.cs @@ -34,5 +34,6 @@ namespace OpenSim.Region.UserStatistics string ReportName { get; } Hashtable ProcessModel(Hashtable pParams); string RenderView(Hashtable pModelResult); + string RenderJson(Hashtable pModelResult); } } diff --git a/OpenSim/Region/UserStatistics/LogLinesAJAX.cs b/OpenSim/Region/UserStatistics/LogLinesAJAX.cs index 74de46b..4d45b80 100644 --- a/OpenSim/Region/UserStatistics/LogLinesAJAX.cs +++ b/OpenSim/Region/UserStatistics/LogLinesAJAX.cs @@ -33,6 +33,7 @@ using System.Text; using System.Text.RegularExpressions; using Mono.Data.SqliteClient; using OpenMetaverse; +using OpenMetaverse.StructuredData; using OpenSim.Region.Framework.Scenes; using OpenSim.Framework.Monitoring; @@ -125,6 +126,34 @@ namespace OpenSim.Region.UserStatistics return output.ToString(); } + /// + /// Return the last log lines. Output in the format: + ///
+        /// {"logLines": [
+        /// "line1",
+        /// "line2",
+        /// ...
+        /// ]
+        /// }
+        /// 
+ ///
+ /// + /// + public string RenderJson(Hashtable pModelResult) + { + OSDMap logInfo = new OpenMetaverse.StructuredData.OSDMap(); + + OSDArray logLines = new OpenMetaverse.StructuredData.OSDArray(); + string tmp = normalizeEndLines.Replace(pModelResult["loglines"].ToString(), "\n"); + string[] result = Regex.Split(tmp, "\n"); + for (int i = 0; i < result.Length; i++) + { + logLines.Add(new OSDString(result[i])); + } + logInfo.Add("logLines", logLines); + return logInfo.ToString(); + } + #endregion } } diff --git a/OpenSim/Region/UserStatistics/Prototype_distributor.cs b/OpenSim/Region/UserStatistics/Prototype_distributor.cs index 53ae557..6f8b2aa 100644 --- a/OpenSim/Region/UserStatistics/Prototype_distributor.cs +++ b/OpenSim/Region/UserStatistics/Prototype_distributor.cs @@ -36,7 +36,18 @@ namespace OpenSim.Region.UserStatistics { public class Prototype_distributor : IStatsController { - private string prototypejs=string.Empty; + private string jsFileName = "prototype.js"; + private string prototypejs = string.Empty; + + public Prototype_distributor() + { + jsFileName = "prototype.js"; + } + + public Prototype_distributor(string jsName) + { + jsFileName = jsName; + } public string ReportName { @@ -45,20 +56,24 @@ namespace OpenSim.Region.UserStatistics public Hashtable ProcessModel(Hashtable pParams) { Hashtable pResult = new Hashtable(); - if (prototypejs.Length == 0) + pResult["js"] = jsFileName; + return pResult; + } + + public string RenderView(Hashtable pModelResult) + { + string fileName = (string)pModelResult["js"]; + using (StreamReader fs = new StreamReader(new FileStream(Util.dataDir() + "/data/" + fileName, FileMode.Open))) { - StreamReader fs = new StreamReader(new FileStream(Util.dataDir() + "/data/prototype.js", FileMode.Open)); prototypejs = fs.ReadToEnd(); fs.Close(); - fs.Dispose(); } - pResult["js"] = prototypejs; - return pResult; + return prototypejs; } - public string RenderView(Hashtable pModelResult) + public string RenderJson(Hashtable pModelResult) { - return pModelResult["js"].ToString(); + return "{}"; } } diff --git a/OpenSim/Region/UserStatistics/Sessions_Report.cs b/OpenSim/Region/UserStatistics/Sessions_Report.cs index 1a2d460..0e94912 100644 --- a/OpenSim/Region/UserStatistics/Sessions_Report.cs +++ b/OpenSim/Region/UserStatistics/Sessions_Report.cs @@ -278,6 +278,11 @@ TD.align_top { vertical-align: top; } public DateTime start_time; } + public string RenderJson(Hashtable pModelResult) + { + return "{}"; + } #endregion } + } diff --git a/OpenSim/Region/UserStatistics/SimStatsAJAX.cs b/OpenSim/Region/UserStatistics/SimStatsAJAX.cs index 28051fb..ad848a1 100644 --- a/OpenSim/Region/UserStatistics/SimStatsAJAX.cs +++ b/OpenSim/Region/UserStatistics/SimStatsAJAX.cs @@ -32,6 +32,7 @@ using System.Reflection; using System.Text; using Mono.Data.SqliteClient; using OpenMetaverse; +using OpenMetaverse.StructuredData; using OpenSim.Region.Framework.Scenes; using OpenSim.Framework.Monitoring; @@ -218,6 +219,64 @@ namespace OpenSim.Region.UserStatistics return output.ToString(); } + /// + /// Return stat information for all regions in the sim. Returns data of the form: + ///
+        /// {"REGIONNAME": {
+        ///     "region": "REGIONNAME",
+        ///     "timeDilation": "101", 
+        ///     ...     // the rest of the stat info
+        ///     },
+        ///  ...    // entries for each region
+        ///  }
+        /// 
+ ///
+ /// + /// + public string RenderJson(Hashtable pModelResult) + { + List all_scenes = (List) pModelResult["hdata"]; + Dictionary sdatadic = (Dictionary)pModelResult["simstats"]; + + OSDMap allStatsInfo = new OpenMetaverse.StructuredData.OSDMap(); + foreach (USimStatsData sdata in sdatadic.Values) + { + OSDMap statsInfo = new OpenMetaverse.StructuredData.OSDMap(); + string regionName = "unknown"; + foreach (Scene sn in all_scenes) + { + if (sn.RegionInfo.RegionID == sdata.RegionId) + { + regionName = sn.RegionInfo.RegionName; + break; + } + } + statsInfo.Add("region", new OSDString(regionName)); + statsInfo.Add("timeDilation", new OSDString(sdata.TimeDilation.ToString())); + statsInfo.Add("simFPS", new OSDString(sdata.SimFps.ToString())); + statsInfo.Add("physicsFPS", new OSDString(sdata.PhysicsFps.ToString())); + statsInfo.Add("agentUpdates", new OSDString(sdata.AgentUpdates.ToString())); + statsInfo.Add("rootAgents", new OSDString(sdata.RootAgents.ToString())); + statsInfo.Add("childAgents", new OSDString(sdata.ChildAgents.ToString())); + statsInfo.Add("totalPrims", new OSDString(sdata.TotalPrims.ToString())); + statsInfo.Add("activePrims", new OSDString(sdata.ActivePrims.ToString())); + statsInfo.Add("activeScripts", new OSDString(sdata.ActiveScripts.ToString())); + statsInfo.Add("scriptLinesPerSec", new OSDString(sdata.ScriptLinesPerSecond.ToString())); + statsInfo.Add("totalFrameTime", new OSDString(sdata.TotalFrameTime.ToString())); + statsInfo.Add("agentFrameTime", new OSDString(sdata.AgentFrameTime.ToString())); + statsInfo.Add("physicsFrameTime", new OSDString(sdata.PhysicsFrameTime.ToString())); + statsInfo.Add("otherFrameTime", new OSDString(sdata.OtherFrameTime.ToString())); + statsInfo.Add("outPacketsPerSec", new OSDString(sdata.OutPacketsPerSecond.ToString())); + statsInfo.Add("inPacketsPerSec", new OSDString(sdata.InPacketsPerSecond.ToString())); + statsInfo.Add("unackedByptes", new OSDString(sdata.UnackedBytes.ToString())); + statsInfo.Add("pendingDownloads", new OSDString(sdata.PendingDownloads.ToString())); + statsInfo.Add("pendingUploads", new OSDString(sdata.PendingUploads.ToString())); + + allStatsInfo.Add(regionName, statsInfo); + } + return allStatsInfo.ToString(); + } + #endregion } } diff --git a/OpenSim/Region/UserStatistics/Updater_distributor.cs b/OpenSim/Region/UserStatistics/Updater_distributor.cs index 9593cc9..601e06b 100644 --- a/OpenSim/Region/UserStatistics/Updater_distributor.cs +++ b/OpenSim/Region/UserStatistics/Updater_distributor.cs @@ -62,5 +62,9 @@ namespace OpenSim.Region.UserStatistics return pModelResult["js"].ToString(); } + public string RenderJson(Hashtable pModelResult) { + return "{}"; + } + } } \ No newline at end of file diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs index 64cb577..438ef48 100644 --- a/OpenSim/Region/UserStatistics/WebStatsModule.cs +++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs @@ -121,6 +121,10 @@ namespace OpenSim.Region.UserStatistics reports.Add("clients.report", clientReport); reports.Add("sessions.report", sessionsReport); + reports.Add("sim.css", new Prototype_distributor("sim.css")); + reports.Add("sim.html", new Prototype_distributor("sim.html")); + reports.Add("jquery.js", new Prototype_distributor("jquery.js")); + //// // Add Your own Reports here (Do Not Modify Lines here Devs!) //// @@ -255,9 +259,12 @@ namespace OpenSim.Region.UserStatistics string regpath = request["uri"].ToString(); int response_code = 404; string contenttype = "text/html"; + bool jsonFormatOutput = false; string strOut = string.Empty; + // The request patch should be "/SStats/reportName" where 'reportName' + // is one of the names added to the 'reports' hashmap. regpath = regpath.Remove(0, 8); if (regpath.Length == 0) regpath = "default.report"; if (reports.ContainsKey(regpath)) @@ -265,6 +272,9 @@ namespace OpenSim.Region.UserStatistics IStatsController rep = reports[regpath]; Hashtable repParams = new Hashtable(); + if (request.ContainsKey("json")) + jsonFormatOutput = true; + if (request.ContainsKey("requestvars")) repParams["RequestVars"] = request["requestvars"]; else @@ -284,13 +294,26 @@ namespace OpenSim.Region.UserStatistics concurrencyCounter++; - strOut = rep.RenderView(rep.ProcessModel(repParams)); + if (jsonFormatOutput) + { + strOut = rep.RenderJson(rep.ProcessModel(repParams)); + contenttype = "text/json"; + } + else + { + strOut = rep.RenderView(rep.ProcessModel(repParams)); + } if (regpath.EndsWith("js")) { contenttype = "text/javascript"; } + if (regpath.EndsWith("css")) + { + contenttype = "text/css"; + } + concurrencyCounter--; response_code = 200; -- cgit v1.1 From 71f7bfc2ff195106254712654fdd549ea9f2a3e3 Mon Sep 17 00:00:00 2001 From: Talun Date: Thu, 24 Jan 2013 21:08:57 +0000 Subject: Mantis 6508 llHTTPResponse body is incorrectly interpreted by IE This patch html escapes responses going to IE so that they cannot be interpreted as HTML if the response type is "text/plain". This has no effect if the reponse type has been set to "text/html" by osSetContentType Signed-off-by: nebadon --- .../Region/CoreModules/Scripting/LSLHttp/UrlModule.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index a654477..be617a5 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -328,8 +328,22 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp if (m_RequestMap.ContainsKey(request)) { UrlData urlData = m_RequestMap[request]; + string responseBody = body; + if (urlData.requests[request].responseType.Equals("text/plain")) + { + string value; + if (urlData.requests[request].headers.TryGetValue("user-agent", out value)) + { + if (value != null && value.IndexOf("MSIE") >= 0) + { + // wrap the html escaped response if the target client is IE + // It ignores "text/plain" if the body is html + responseBody = "" + System.Web.HttpUtility.HtmlEncode(body) + ""; + } + } + } urlData.requests[request].responseCode = status; - urlData.requests[request].responseBody = body; + urlData.requests[request].responseBody = responseBody; //urlData.requests[request].ev.Set(); urlData.requests[request].requestDone =true; } -- cgit v1.1 From 3ecfddd791e7159723e4d9af89091e84a8f6f710 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 24 Jan 2013 12:22:49 -0800 Subject: BulletSim: remove exception that can happen when setting physics parameters from the console. --- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 35dba9b..cb304b6 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -917,8 +917,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters foreach (uint lID in xlIDs) { BSPhysObject theObject = null; - PhysObjects.TryGetValue(lID, out theObject); - thisParam.onObject(this, theObject, xval); + if (PhysObjects.TryGetValue(lID, out theObject)) + thisParam.onObject(this, theObject, xval); } } } -- cgit v1.1 From 2cf29c87bccb5b359fc74e1a0520bfd394d86d15 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 24 Jan 2013 14:26:11 -0800 Subject: BulletSim: zero motion on an object that we pop up because it is below terrain. If the position is being corrected because it is out of bounds, all other movement rules are out the window. --- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index f80084a..8b00a33 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -363,7 +363,11 @@ public sealed class BSPrim : BSPhysObject // not get it through the terrain _position.Z = targetHeight; if (inTaintTime) + { ForcePosition = _position; + } + // If we are throwing the object around, zero its other forces + ZeroMotion(inTaintTime); ret = true; } @@ -1639,10 +1643,12 @@ public sealed class BSPrim : BSPhysObject // DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG // The sanity check can change the velocity and/or position. - if (IsPhysical && PositionSanityCheck(true)) + if (IsPhysical && PositionSanityCheck(true /* inTaintTime */ )) { entprop.Position = _position; entprop.Velocity = _velocity; + entprop.RotationalVelocity = _rotationalVelocity; + entprop.Acceleration = _acceleration; } OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG -- cgit v1.1 From 591faac3ac236ea676ebd2787d824abd9f30c2b6 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 24 Jan 2013 14:28:25 -0800 Subject: BulletSim: disable CCD (continuious collision detection) and contact processing threshold since the first didn't solve tunneling problems but used resources and the latter caused instabilities. --- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 9460daf..06186b0 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -334,7 +334,7 @@ public static class BSParam (s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularSleepingThreshold=x;}, p, l, v); }, (s,o,v) => { s.PE.SetSleepingThresholds(o.PhysBody, v, v); } ), new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" , - 0.3f, // set to zero to disable + 0.0f, // set to zero to disable (s,cf,p,v) => { CcdMotionThreshold = cf.GetFloat(p, v); }, (s) => { return CcdMotionThreshold; }, (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdMotionThreshold=x;}, p, l, v); }, @@ -345,8 +345,8 @@ public static class BSParam (s) => { return CcdSweptSphereRadius; }, (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdSweptSphereRadius=x;}, p, l, v); }, (s,o,v) => { s.PE.SetCcdSweptSphereRadius(o.PhysBody, v); } ), - new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" , - 0.1f, + new ParameterDefn("ContactProcessingThreshold", "Distance above which contacts can be discarded (0 means no discard)" , + 0.0f, (s,cf,p,v) => { ContactProcessingThreshold = cf.GetFloat(p, v); }, (s) => { return ContactProcessingThreshold; }, (s,p,l,v) => { s.UpdateParameterObject((x)=>{ContactProcessingThreshold=x;}, p, l, v); }, -- cgit v1.1 From a2a32fc8448e9cfb1292f7ff781875aec6d684cc Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 24 Jan 2013 14:30:12 -0800 Subject: BulletSim: reduce the zeroing threshold for rotational velocity. Sometimes settling of a vehicle from gravity introduces small velocities that need to be kept. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index fe7891e..f1ef449 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -1190,8 +1190,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin // set directly on the vehicle. private void MoveAngular(float pTimestep) { - // VehicleRotationalVelocity = Vector3.Zero; - ComputeAngularTurning(pTimestep); ComputeAngularVerticalAttraction(); @@ -1201,7 +1199,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin ComputeAngularBanking(); // ================================================================== - if (VehicleRotationalVelocity.ApproxEquals(Vector3.Zero, 0.01f)) + if (VehicleRotationalVelocity.ApproxEquals(Vector3.Zero, 0.0001f)) { // The vehicle is not adding anything angular wise. VehicleRotationalVelocity = Vector3.Zero; -- cgit v1.1 From 6a5d08819725a836a4072dec3bd3f84a1bd39ffb Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 24 Jan 2013 16:26:04 -0800 Subject: BulletSim: reduce the force of gravity on ground vehicles when they are on the ground. Makes them a little more stable. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index f1ef449..7ad7c89 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -158,6 +158,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin get { return (Type != Vehicle.TYPE_NONE && Prim.IsPhysicallyActive); } } + // Return 'true' if this a vehicle that should be sitting on the ground + public bool IsGroundVehicle + { + get { return (Type == Vehicle.TYPE_CAR || Type == Vehicle.TYPE_SLED); } + } + #region Vehicle parameter setting internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) { @@ -1176,6 +1182,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin private void ApplyGravity(float pTimeStep) { Vector3 appliedGravity = m_VehicleGravity * m_vehicleMass; + + // Hack to reduce downward force if the vehicle is probably sitting on the ground + if (Prim.IsColliding && IsGroundVehicle) + appliedGravity *= 0.2f; + VehicleAddForce(appliedGravity); VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},appliedForce-{2}", -- cgit v1.1 From f557d7e82821c931c6ca2faf97c668fa94cacfb0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 25 Jan 2013 01:48:31 +0000 Subject: Add basic JsonCreateStore() regression test --- .../ScriptModuleComms/ScriptModuleCommsModule.cs | 2 +- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 86 ++++++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs index f6e1d39..6bf50d2 100644 --- a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs @@ -41,7 +41,7 @@ using System.Linq.Expressions; namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ScriptModuleCommsModule")] - class ScriptModuleCommsModule : INonSharedRegionModule, IScriptModuleComms + public class ScriptModuleCommsModule : INonSharedRegionModule, IScriptModuleComms { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs new file mode 100644 index 0000000..4b6ddd6 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -0,0 +1,86 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using log4net; +using Nini.Config; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.CoreModules.Scripting.ScriptModuleComms; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.ScriptEngine.Shared; +using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Services.Interfaces; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests +{ + /// + /// Tests for inventory functions in LSL + /// + [TestFixture] + public class LSL_ApiInventoryTests : OpenSimTestCase + { + private Scene m_scene; + private MockScriptEngine m_engine; + private ScriptModuleCommsModule m_smcm; + + [SetUp] + public override void SetUp() + { + base.SetUp(); + + IConfigSource configSource = new IniConfigSource(); + IConfig jsonStoreConfig = configSource.AddConfig("JsonStore"); + jsonStoreConfig.Set("Enabled", "true"); + + m_engine = new MockScriptEngine(); + m_smcm = new ScriptModuleCommsModule(); + JsonStoreModule jsm = new JsonStoreModule(); + JsonStoreScriptModule jssm = new JsonStoreScriptModule(); + + m_scene = new SceneHelpers().SetupScene(); + SceneHelpers.SetupSceneModules(m_scene, configSource, m_engine, m_smcm, jsm, jssm); + } + + [Test] + public void TestJsonCreateStore() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + UUID storeId = (UUID)m_smcm.InvokeOperation(UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{}" }); + + Assert.That(storeId, Is.Not.EqualTo(UUID.Zero)); + } + } +} \ No newline at end of file -- cgit v1.1 From ba369c5cfe89706c0e7261e699dac1d0c3c68cd6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 25 Jan 2013 01:55:27 +0000 Subject: Add basic JsonGetValue() regression test. --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 4b6ddd6..204bab1 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -82,5 +82,22 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests Assert.That(storeId, Is.Not.EqualTo(UUID.Zero)); } + + [Test] + public void TestJsonGetValue() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + UUID storeId + = (UUID)m_smcm.InvokeOperation( + UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{ 'Hello' : 'World' }" }); + + string value + = (string)m_smcm.InvokeOperation( + UUID.Zero, UUID.Zero, "JsonGetValue", new object[] { storeId, "Hello" }); + + Assert.That(value, Is.EqualTo("World")); + } } } \ No newline at end of file -- cgit v1.1 From b914fb98c4c178987e23580ceb3f8b48415831d1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 25 Jan 2013 01:56:41 +0000 Subject: minor: remove mono compiler warning in SceneCommandsModule --- .../Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs index 12169ab..5fb74b0 100644 --- a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs +++ b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs @@ -48,7 +48,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SceneCommandsModule")] public class SceneCommandsModule : ISceneCommandsModule, INonSharedRegionModule { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene; -- cgit v1.1 From f32361d595e0ee11066fa78627fe91936743a5e8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 25 Jan 2013 02:08:33 +0000 Subject: Add regression test for JsonSetValue() --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 204bab1..0e8b1ca 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -99,5 +99,28 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests Assert.That(value, Is.EqualTo("World")); } + + [Test] + public void TestJsonSetValue() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + UUID storeId + = (UUID)m_smcm.InvokeOperation( + UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{ }" }); + + int result + = (int)m_smcm.InvokeOperation( + UUID.Zero, UUID.Zero, "JsonSetValue", new object[] { storeId, "Hello", "World" }); + + Assert.That(result, Is.EqualTo(1)); + + string value + = (string)m_smcm.InvokeOperation( + UUID.Zero, UUID.Zero, "JsonGetValue", new object[] { storeId, "Hello" }); + + Assert.That(value, Is.EqualTo("World")); + } } } \ No newline at end of file -- cgit v1.1 From 844e60da0f81454318519445f7c30fa02cf524f2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 25 Jan 2013 02:12:15 +0000 Subject: Add JsonTestPath() regression test --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 0e8b1ca..06e4761 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -101,6 +101,23 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests } [Test] + public void TestJsonTestPath() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + UUID storeId + = (UUID)m_smcm.InvokeOperation( + UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{ 'Hello' : 'World' }" }); + + int result + = (int)m_smcm.InvokeOperation( + UUID.Zero, UUID.Zero, "JsonTestPath", new object[] { storeId, "Hello" }); + + Assert.That(result, Is.EqualTo(1)); + } + + [Test] public void TestJsonSetValue() { TestHelpers.InMethod(); -- cgit v1.1 From 8c68451856756a6c43e90c533352a1b5c3b42210 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 25 Jan 2013 02:22:24 +0000 Subject: Enable logging in new json store tests to find out why they fail on jenkins but not locally. --- .../Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 06e4761..0cbc5d9 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -76,7 +76,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests public void TestJsonCreateStore() { TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); + TestHelpers.EnableLogging(); UUID storeId = (UUID)m_smcm.InvokeOperation(UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{}" }); @@ -87,7 +87,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests public void TestJsonGetValue() { TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); + TestHelpers.EnableLogging(); UUID storeId = (UUID)m_smcm.InvokeOperation( @@ -104,7 +104,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests public void TestJsonTestPath() { TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); + TestHelpers.EnableLogging(); UUID storeId = (UUID)m_smcm.InvokeOperation( @@ -121,7 +121,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests public void TestJsonSetValue() { TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); + TestHelpers.EnableLogging(); UUID storeId = (UUID)m_smcm.InvokeOperation( -- cgit v1.1 From 4f52acaa833b4c1c99e13f6ca7177efc7b2d15ab Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 25 Jan 2013 02:32:38 +0000 Subject: Increase logging by enabling during test setup rather than during individual tests of for JsonStore --- .../Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 0cbc5d9..b50bc0b 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -59,6 +59,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests { base.SetUp(); + TestHelpers.EnableLogging(); + IConfigSource configSource = new IniConfigSource(); IConfig jsonStoreConfig = configSource.AddConfig("JsonStore"); jsonStoreConfig.Set("Enabled", "true"); @@ -76,7 +78,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests public void TestJsonCreateStore() { TestHelpers.InMethod(); - TestHelpers.EnableLogging(); +// TestHelpers.EnableLogging(); UUID storeId = (UUID)m_smcm.InvokeOperation(UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{}" }); @@ -87,7 +89,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests public void TestJsonGetValue() { TestHelpers.InMethod(); - TestHelpers.EnableLogging(); +// TestHelpers.EnableLogging(); UUID storeId = (UUID)m_smcm.InvokeOperation( @@ -104,7 +106,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests public void TestJsonTestPath() { TestHelpers.InMethod(); - TestHelpers.EnableLogging(); +// TestHelpers.EnableLogging(); UUID storeId = (UUID)m_smcm.InvokeOperation( @@ -121,7 +123,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests public void TestJsonSetValue() { TestHelpers.InMethod(); - TestHelpers.EnableLogging(); +// TestHelpers.EnableLogging(); UUID storeId = (UUID)m_smcm.InvokeOperation( -- cgit v1.1 From 614d4eda3ee2889e7b122b4a5c522c6ef72a7765 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 25 Jan 2013 03:02:08 +0000 Subject: See if getting the registering JsonReadNotecard with MethodInfo works around an apparent issue with registering methods with more than 5 parameters on mono 2.4.3 --- .../OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index 0c175ca..77be828 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs @@ -168,7 +168,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore m_comms.RegisterScriptInvocation(this,"JsonCreateStore"); m_comms.RegisterScriptInvocation(this,"JsonDestroyStore"); - m_comms.RegisterScriptInvocation(this,"JsonReadNotecard"); + m_comms.RegisterScriptInvocation( + this, this.GetType().GetMethod( + "JsonReadNotecard", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(UUID), typeof(UUID), typeof(UUID), typeof(string), typeof(UUID)}, null)); + m_comms.RegisterScriptInvocation(this,"JsonWriteNotecard"); m_comms.RegisterScriptInvocation(this,"JsonTestPath"); @@ -191,7 +194,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore catch (Exception e) { // See http://opensimulator.org/mantis/view.php?id=5971 for more information - m_log.WarnFormat("[JsonStroreScripts] script method registration failed; {0}",e.Message); + m_log.WarnFormat("[JsonStoreScripts]: script method registration failed; {0}", e.Message); m_enabled = false; } } -- cgit v1.1 From d977bb77cb39eef927cf0b7487b500019a537114 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 25 Jan 2013 03:19:56 +0000 Subject: Disable json tests for now - I see this is failing on jenkins because mono 2.4.3 doesn't have Funcs >5 params, though mono 2.6 onwards does. Standardize logging in JsonStoreScriptModule and some minor code formatting. --- .../Scripting/JsonStore/JsonStoreScriptModule.cs | 53 ++++++++++------------ .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 8 ++-- 2 files changed, 29 insertions(+), 32 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index 77be828..b9dcfea 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs @@ -92,12 +92,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } catch (Exception e) { - m_log.ErrorFormat("[JsonStoreScripts] initialization error: {0}",e.Message); + m_log.ErrorFormat("[JsonStoreScripts]: initialization error: {0}", e.Message); return; } if (m_enabled) - m_log.DebugFormat("[JsonStoreScripts] module is enabled"); + m_log.DebugFormat("[JsonStoreScripts]: module is enabled"); } // ----------------------------------------------------------------- @@ -150,7 +150,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore m_comms = m_scene.RequestModuleInterface(); if (m_comms == null) { - m_log.ErrorFormat("[JsonStoreScripts] ScriptModuleComms interface not defined"); + m_log.ErrorFormat("[JsonStoreScripts]: ScriptModuleComms interface not defined"); m_enabled = false; return; } @@ -158,38 +158,35 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore m_store = m_scene.RequestModuleInterface(); if (m_store == null) { - m_log.ErrorFormat("[JsonStoreScripts] JsonModule interface not defined"); + m_log.ErrorFormat("[JsonStoreScripts]: JsonModule interface not defined"); m_enabled = false; return; } - + try { - m_comms.RegisterScriptInvocation(this,"JsonCreateStore"); - m_comms.RegisterScriptInvocation(this,"JsonDestroyStore"); - - m_comms.RegisterScriptInvocation( - this, this.GetType().GetMethod( - "JsonReadNotecard", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(UUID), typeof(UUID), typeof(UUID), typeof(string), typeof(UUID)}, null)); + m_comms.RegisterScriptInvocation(this, "JsonCreateStore"); + m_comms.RegisterScriptInvocation(this, "JsonDestroyStore"); - m_comms.RegisterScriptInvocation(this,"JsonWriteNotecard"); + m_comms.RegisterScriptInvocation(this, "JsonReadNotecard"); + m_comms.RegisterScriptInvocation(this, "JsonWriteNotecard"); - m_comms.RegisterScriptInvocation(this,"JsonTestPath"); - m_comms.RegisterScriptInvocation(this,"JsonTestPathJson"); + m_comms.RegisterScriptInvocation(this, "JsonTestPath"); + m_comms.RegisterScriptInvocation(this, "JsonTestPathJson"); - m_comms.RegisterScriptInvocation(this,"JsonGetValue"); - m_comms.RegisterScriptInvocation(this,"JsonGetValueJson"); + m_comms.RegisterScriptInvocation(this, "JsonGetValue"); + m_comms.RegisterScriptInvocation(this, "JsonGetValueJson"); - m_comms.RegisterScriptInvocation(this,"JsonTakeValue"); - m_comms.RegisterScriptInvocation(this,"JsonTakeValueJson"); + m_comms.RegisterScriptInvocation(this, "JsonTakeValue"); + m_comms.RegisterScriptInvocation(this, "JsonTakeValueJson"); - m_comms.RegisterScriptInvocation(this,"JsonReadValue"); - m_comms.RegisterScriptInvocation(this,"JsonReadValueJson"); + m_comms.RegisterScriptInvocation(this, "JsonReadValue"); + m_comms.RegisterScriptInvocation(this, "JsonReadValueJson"); - m_comms.RegisterScriptInvocation(this,"JsonSetValue"); - m_comms.RegisterScriptInvocation(this,"JsonSetValueJson"); + m_comms.RegisterScriptInvocation(this, "JsonSetValue"); + m_comms.RegisterScriptInvocation(this, "JsonSetValueJson"); - m_comms.RegisterScriptInvocation(this,"JsonRemoveValue"); + m_comms.RegisterScriptInvocation(this, "JsonRemoveValue"); } catch (Exception e) { @@ -357,7 +354,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } catch (Exception e) { - m_log.InfoFormat("[JsonStoreScripts] unable to retrieve value; {0}",e.ToString()); + m_log.InfoFormat("[JsonStoreScripts]: unable to retrieve value; {0}",e.ToString()); } DispatchValue(scriptID,reqID,String.Empty); @@ -392,7 +389,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } catch (Exception e) { - m_log.InfoFormat("[JsonStoreScripts] unable to retrieve value; {0}",e.ToString()); + m_log.InfoFormat("[JsonStoreScripts]: unable to retrieve value; {0}",e.ToString()); } DispatchValue(scriptID,reqID,String.Empty); @@ -424,7 +421,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore if (a.Type != (sbyte)AssetType.Notecard) GenerateRuntimeError(String.Format("Invalid notecard asset {0}",assetID)); - m_log.DebugFormat("[JsonStoreScripts] read notecard in context {0}",storeID); + m_log.DebugFormat("[JsonStoreScripts]: read notecard in context {0}",storeID); try { @@ -435,7 +432,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } catch (Exception e) { - m_log.WarnFormat("[JsonStoreScripts] Json parsing failed; {0}",e.Message); + m_log.WarnFormat("[JsonStoreScripts]: Json parsing failed; {0}",e.Message); } GenerateRuntimeError(String.Format("Json parsing failed for {0}",assetID.ToString())); @@ -498,4 +495,4 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore m_comms.DispatchReply(scriptID,1,assetID.ToString(),reqID.ToString()); } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index b50bc0b..397dd93 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -74,7 +74,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests SceneHelpers.SetupSceneModules(m_scene, configSource, m_engine, m_smcm, jsm, jssm); } - [Test] +// [Test] public void TestJsonCreateStore() { TestHelpers.InMethod(); @@ -85,7 +85,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests Assert.That(storeId, Is.Not.EqualTo(UUID.Zero)); } - [Test] +// [Test] public void TestJsonGetValue() { TestHelpers.InMethod(); @@ -102,7 +102,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests Assert.That(value, Is.EqualTo("World")); } - [Test] +// [Test] public void TestJsonTestPath() { TestHelpers.InMethod(); @@ -119,7 +119,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests Assert.That(result, Is.EqualTo(1)); } - [Test] +// [Test] public void TestJsonSetValue() { TestHelpers.InMethod(); -- cgit v1.1 From 1bd0b06ec1a0a5a7d6302d8017edcea7faf557e0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 16 Aug 2010 20:38:20 +0100 Subject: Implement Dynamic Attributes for SOP and PBS. Implement storage in SQLite --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 6720635..2a9b99e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -37,6 +37,7 @@ using System.Xml.Serialization; using log4net; using OpenMetaverse; using OpenMetaverse.Packets; +using OpenMetaverse.StructuredData; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes.Scripting; @@ -124,6 +125,11 @@ namespace OpenSim.Region.Framework.Scenes private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + /// + /// Dynamic attributes can be created and deleted as required. + /// + public DynAttrsOSDMap DynAttrs { get; set; } + /// /// Is this a root part? /// @@ -335,6 +341,7 @@ namespace OpenSim.Region.Framework.Scenes m_particleSystem = Utils.EmptyBytes; Rezzed = DateTime.UtcNow; Description = String.Empty; + DynAttrs = new DynAttrsOSDMap(); // Prims currently only contain a single folder (Contents). From looking at the Second Life protocol, // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from @@ -4598,4 +4605,4 @@ namespace OpenSim.Region.Framework.Scenes } } } -} \ No newline at end of file +} -- cgit v1.1 From d3095e26493c15ce146e36fe38443722e86ac832 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 16 Aug 2010 21:31:36 +0100 Subject: Add DAExampleModule to demonstrate dynamic attributes This module demonstrates that we can add an arbitrary persisted value to SOP without any changes to core code. Every time the object is moved, the move record is updated and the users in the scene alerted The number of moves is persisted over server restarts in sqlite --- .../Framework/DynamicAttributes/DAExampleModule.cs | 98 ++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs new file mode 100644 index 0000000..2aca93a --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs @@ -0,0 +1,98 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenMetaverse; +using OpenMetaverse.Packets; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Region.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.Framework.DynamicAttributes.DAExampleModule +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DAExampleModule")] + public class DAExampleModule : INonSharedRegionModule + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + protected Scene m_scene; + protected IDialogModule m_dialogMod; + + public string Name { get { return "DAExample Module"; } } + public Type ReplaceableInterface { get { return null; } } + + public void Initialise(IConfigSource source) {} + + public void AddRegion(Scene scene) + { + m_scene = scene; + m_scene.EventManager.OnSceneGroupMove += OnSceneGroupMove; + m_dialogMod = m_scene.RequestModuleInterface(); + } + + public void RemoveRegion(Scene scene) + { + m_scene.EventManager.OnSceneGroupMove -= OnSceneGroupMove; + } + + public void RegionLoaded(Scene scene) {} + + public void Close() + { + RemoveRegion(m_scene); + } + + protected bool OnSceneGroupMove(UUID groupId, Vector3 delta) + { + SceneObjectPart sop = m_scene.GetSceneObjectPart(groupId); + OSDMap attrs = sop.DynAttrs; + + lock (attrs) + { + OSDInteger newValue; + + if (!attrs.ContainsKey("moves")) + newValue = new OSDInteger(1); + else + newValue = new OSDInteger(((OSDInteger)attrs["moves"]).AsInteger() + 1); + + attrs["moves"] = newValue; + + m_dialogMod.SendGeneralAlert(string.Format("{0} {1} moved {2} times", sop.Name, sop.UUID, newValue)); + } + + return true; + } + } +} \ No newline at end of file -- cgit v1.1 From a6d9c263650cc23d60f941718f87a64aa2f360b2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 16 Aug 2010 22:21:46 +0100 Subject: Encapsulate an OSDMap in DAMap (was DynAttrsOSDMap) rather than inheriting from it This is the easier way to give us control over locking, rather than asking that OSDMap IDictionary methods be virtual --- .../Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs index 2aca93a..d6fb15b 100644 --- a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs +++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs @@ -76,7 +76,7 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DAExampleModule protected bool OnSceneGroupMove(UUID groupId, Vector3 delta) { SceneObjectPart sop = m_scene.GetSceneObjectPart(groupId); - OSDMap attrs = sop.DynAttrs; + DAMap attrs = sop.DynAttrs; lock (attrs) { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 2a9b99e..27f3a4d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -128,7 +128,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// Dynamic attributes can be created and deleted as required. /// - public DynAttrsOSDMap DynAttrs { get; set; } + public DAMap DynAttrs { get; set; } /// /// Is this a root part? @@ -341,7 +341,7 @@ namespace OpenSim.Region.Framework.Scenes m_particleSystem = Utils.EmptyBytes; Rezzed = DateTime.UtcNow; Description = String.Empty; - DynAttrs = new DynAttrsOSDMap(); + DynAttrs = new DAMap(); // Prims currently only contain a single folder (Contents). From looking at the Second Life protocol, // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from -- cgit v1.1 From 8b4441d940a55da90645580477ece33d15849078 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Tue, 22 Jan 2013 08:41:32 +0200 Subject: Changed DAMap to be the container of "data stores", which are OSDMaps. Store names must have at least 4 characters. --- .../Framework/DynamicAttributes/DAExampleModule.cs | 25 +++++++++++----------- 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs index d6fb15b..084fb5f 100644 --- a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs +++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs @@ -75,22 +75,23 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DAExampleModule protected bool OnSceneGroupMove(UUID groupId, Vector3 delta) { + OSDMap attrs = null; SceneObjectPart sop = m_scene.GetSceneObjectPart(groupId); - DAMap attrs = sop.DynAttrs; + if (!sop.DynAttrs.TryGetValue(Name, out attrs)) + attrs = new OSDMap(); - lock (attrs) - { - OSDInteger newValue; + OSDInteger newValue; - if (!attrs.ContainsKey("moves")) - newValue = new OSDInteger(1); - else - newValue = new OSDInteger(((OSDInteger)attrs["moves"]).AsInteger() + 1); + if (!attrs.ContainsKey("moves")) + newValue = new OSDInteger(1); + else + newValue = new OSDInteger(((OSDInteger)attrs["moves"]).AsInteger() + 1); - attrs["moves"] = newValue; - - m_dialogMod.SendGeneralAlert(string.Format("{0} {1} moved {2} times", sop.Name, sop.UUID, newValue)); - } + attrs["moves"] = newValue; + + sop.DynAttrs[Name] = attrs; + + m_dialogMod.SendGeneralAlert(string.Format("{0} {1} moved {2} times", sop.Name, sop.UUID, newValue)); return true; } -- cgit v1.1 From af6a7cf95df76708d013932d8ef92c9bbeda0e5d Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Tue, 22 Jan 2013 11:59:20 +0200 Subject: Added DynAttrs to the serialized XML format of prims. When copying prims, use deep copy for DynAttrs. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 ++ .../Scenes/Serialization/SceneObjectSerializer.cs | 14 ++++++++++++++ 2 files changed, 16 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 27f3a4d..189d298 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1625,6 +1625,8 @@ namespace OpenSim.Region.Framework.Scenes Array.Copy(Shape.ExtraParams, extraP, extraP.Length); dupe.Shape.ExtraParams = extraP; + dupe.DynAttrs.CopyFrom(DynAttrs); + if (userExposed) { /* diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 2d4c60a..4a2a47e 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -359,6 +359,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization m_SOPXmlProcessors.Add("CollisionSound", ProcessCollisionSound); m_SOPXmlProcessors.Add("CollisionSoundVolume", ProcessCollisionSoundVolume); m_SOPXmlProcessors.Add("MediaUrl", ProcessMediaUrl); + m_SOPXmlProcessors.Add("DynAttrs", ProcessDynAttrs); m_SOPXmlProcessors.Add("TextureAnimation", ProcessTextureAnimation); m_SOPXmlProcessors.Add("ParticleSystem", ProcessParticleSystem); m_SOPXmlProcessors.Add("PayPrice0", ProcessPayPrice0); @@ -722,6 +723,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization obj.MediaUrl = reader.ReadElementContentAsString("MediaUrl", String.Empty); } + private static void ProcessDynAttrs(SceneObjectPart obj, XmlTextReader reader) + { + obj.DynAttrs.ReadXml(reader); + } + private static void ProcessTextureAnimation(SceneObjectPart obj, XmlTextReader reader) { obj.TextureAnimation = Convert.FromBase64String(reader.ReadElementContentAsString("TextureAnimation", String.Empty)); @@ -1235,6 +1241,14 @@ namespace OpenSim.Region.Framework.Scenes.Serialization writer.WriteElementString("CollisionSoundVolume", sop.CollisionSoundVolume.ToString()); if (sop.MediaUrl != null) writer.WriteElementString("MediaUrl", sop.MediaUrl.ToString()); + + if (sop.DynAttrs.Count > 0) + { + writer.WriteStartElement("DynAttrs"); + sop.DynAttrs.WriteXml(writer); + writer.WriteEndElement(); + } + WriteBytes(writer, "TextureAnimation", sop.TextureAnimation); WriteBytes(writer, "ParticleSystem", sop.ParticleSystem); writer.WriteElementString("PayPrice0", sop.PayPrice[0].ToString()); -- cgit v1.1 From 23f0610f0ce33a7308fc2c9190204b2d8882ce85 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Tue, 22 Jan 2013 12:17:16 +0200 Subject: Disabled DAExampleModule --- .../Framework/DynamicAttributes/DAExampleModule.cs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs index 084fb5f..d36f65a 100644 --- a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs +++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs @@ -45,7 +45,9 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DAExampleModule public class DAExampleModule : INonSharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - + + private static readonly bool ENABLED = false; // enable for testing + protected Scene m_scene; protected IDialogModule m_dialogMod; @@ -56,14 +58,20 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DAExampleModule public void AddRegion(Scene scene) { - m_scene = scene; - m_scene.EventManager.OnSceneGroupMove += OnSceneGroupMove; - m_dialogMod = m_scene.RequestModuleInterface(); + if (ENABLED) + { + m_scene = scene; + m_scene.EventManager.OnSceneGroupMove += OnSceneGroupMove; + m_dialogMod = m_scene.RequestModuleInterface(); + } } public void RemoveRegion(Scene scene) { - m_scene.EventManager.OnSceneGroupMove -= OnSceneGroupMove; + if (ENABLED) + { + m_scene.EventManager.OnSceneGroupMove -= OnSceneGroupMove; + } } public void RegionLoaded(Scene scene) {} -- cgit v1.1 From 6daf559fb678435779d766cc4435b4ec141fb7df Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Tue, 22 Jan 2013 12:50:23 +0200 Subject: Added unit tests for Dynamic Attributes --- .../World/Serialiser/Tests/SerialiserTests.cs | 37 ++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs b/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs index bcb8e2f..b4348c9 100644 --- a/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs +++ b/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs @@ -35,6 +35,7 @@ using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes.Serialization; using OpenSim.Tests.Common; +using OpenMetaverse.StructuredData; namespace OpenSim.Region.CoreModules.World.Serialiser.Tests { @@ -143,6 +144,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests None 00000000-0000-0000-0000-000000000000 0 + MyStorethe answer42 @@ -331,6 +333,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests 0 2147483647 None + MyStorelast wordsRosebud 00000000-0000-0000-0000-000000000000 @@ -359,6 +362,8 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests Assert.That(rootPart.UUID, Is.EqualTo(new UUID("e6a5a05e-e8cc-4816-8701-04165e335790"))); Assert.That(rootPart.CreatorID, Is.EqualTo(new UUID("a6dacf01-4636-4bb9-8a97-30609438af9d"))); Assert.That(rootPart.Name, Is.EqualTo("PrimMyRide")); + OSDMap store = rootPart.DynAttrs["MyStore"]; + Assert.AreEqual(42, store["the answer"].AsInteger()); // TODO: Check other properties } @@ -409,6 +414,14 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests rp.CreatorID = rpCreatorId; rp.Shape = shape; + string daStoreName = "MyStore"; + string daKey = "foo"; + string daValue = "bar"; + OSDMap myStore = new OSDMap(); + myStore.Add(daKey, daValue); + rp.DynAttrs = new DAMap(); + rp.DynAttrs[daStoreName] = myStore; + SceneObjectGroup so = new SceneObjectGroup(rp); // Need to add the object to the scene so that the request to get script state succeeds @@ -424,6 +437,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests UUID uuid = UUID.Zero; string name = null; UUID creatorId = UUID.Zero; + DAMap daMap = null; while (xtr.Read() && xtr.Name != "SceneObjectPart") { @@ -449,6 +463,10 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests creatorId = UUID.Parse(xtr.ReadElementString("UUID")); xtr.ReadEndElement(); break; + case "DynAttrs": + daMap = new DAMap(); + daMap.ReadXml(xtr); + break; } } @@ -462,6 +480,8 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests Assert.That(uuid, Is.EqualTo(rpUuid)); Assert.That(name, Is.EqualTo(rpName)); Assert.That(creatorId, Is.EqualTo(rpCreatorId)); + Assert.NotNull(daMap); + Assert.AreEqual(daValue, daMap[daStoreName][daKey].AsString()); } [Test] @@ -476,6 +496,8 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests Assert.That(rootPart.UUID, Is.EqualTo(new UUID("9be68fdd-f740-4a0f-9675-dfbbb536b946"))); Assert.That(rootPart.CreatorID, Is.EqualTo(new UUID("b46ef588-411e-4a8b-a284-d7dcfe8e74ef"))); Assert.That(rootPart.Name, Is.EqualTo("PrimFun")); + OSDMap store = rootPart.DynAttrs["MyStore"]; + Assert.AreEqual("Rosebud", store["last words"].AsString()); // TODO: Check other properties } @@ -500,6 +522,14 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests rp.CreatorID = rpCreatorId; rp.Shape = shape; + string daStoreName = "MyStore"; + string daKey = "foo"; + string daValue = "bar"; + OSDMap myStore = new OSDMap(); + myStore.Add(daKey, daValue); + rp.DynAttrs = new DAMap(); + rp.DynAttrs[daStoreName] = myStore; + SceneObjectGroup so = new SceneObjectGroup(rp); // Need to add the object to the scene so that the request to get script state succeeds @@ -516,6 +546,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests UUID uuid = UUID.Zero; string name = null; UUID creatorId = UUID.Zero; + DAMap daMap = null; while (xtr.Read() && xtr.Name != "SceneObjectPart") { @@ -537,6 +568,10 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests creatorId = UUID.Parse(xtr.ReadElementString("Guid")); xtr.ReadEndElement(); break; + case "DynAttrs": + daMap = new DAMap(); + daMap.ReadXml(xtr); + break; } } @@ -549,6 +584,8 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests Assert.That(uuid, Is.EqualTo(rpUuid)); Assert.That(name, Is.EqualTo(rpName)); Assert.That(creatorId, Is.EqualTo(rpCreatorId)); + Assert.NotNull(daMap); + Assert.AreEqual(daValue, daMap[daStoreName][daKey].AsString()); } } } \ No newline at end of file -- cgit v1.1 From d6d6618f62a3a66e0d660d634c2c0f8722e3692f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 26 Jan 2013 00:28:45 +0000 Subject: minor: Call down to base OpenSimTestCase.SetUp() in NPCModuleTests to disable any enabled logging from previous tests --- OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index a522277..bf23040 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -74,6 +74,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests [SetUp] public void Init() { + base.SetUp(); + IConfigSource config = new IniConfigSource(); config.AddConfig("NPC"); config.Configs["NPC"].Set("Enabled", "true"); -- cgit v1.1 From c3fb1144614d85562169a7bb6cf8b10c9724b189 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 26 Jan 2013 00:31:19 +0000 Subject: minor: Fix full scene part console report to show proper Light* names rather than all wrongly FlexiDrag --- .../CoreModules/World/Objects/Commands/ObjectCommandsModule.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs index 7b235ae..9fc2daf 100644 --- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs @@ -592,11 +592,11 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands cdl.AddRow( "LightColor", string.Format("<{0},{1},{2},{3}>", s.LightColorR, s.LightColorB, s.LightColorG, s.LightColorA)); - cdl.AddRow("FlexiDrag", s.LightCutoff); - cdl.AddRow("FlexiDrag", s.LightEntry); - cdl.AddRow("FlexiDrag", s.LightFalloff); - cdl.AddRow("FlexiDrag", s.LightIntensity); - cdl.AddRow("FlexiDrag", s.LightRadius); + cdl.AddRow("LightCutoff", s.LightCutoff); + cdl.AddRow("LightEntry", s.LightEntry); + cdl.AddRow("LightFalloff", s.LightFalloff); + cdl.AddRow("LightIntensity", s.LightIntensity); + cdl.AddRow("LightRadius", s.LightRadius); cdl.AddRow("Media", string.Format("{0} entries", s.Media != null ? s.Media.Count.ToString() : "n/a")); cdl.AddRow("PathBegin", s.PathBegin); cdl.AddRow("PathEnd", s.PathEnd); -- cgit v1.1 From 5128ae7b8685a583b3d53428f5bbba5ba5e65549 Mon Sep 17 00:00:00 2001 From: teravus Date: Fri, 25 Jan 2013 20:15:37 -0500 Subject: * This adds llVolumeDetect functionality to the C# implementation of BulletSim. --- OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs | 202 +++++++++++++---------- 1 file changed, 116 insertions(+), 86 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs index f63d83c..04e77b8 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs @@ -137,6 +137,7 @@ private sealed class BulletConstraintXNA : BulletConstraint internal int LastEntityProperty = 0; internal EntityProperties[] UpdatedObjects; + internal Dictionary specialCollisionObjects; private static int m_collisionsThisFrame; private BSScene PhysicsScene { get; set; } @@ -158,7 +159,13 @@ private sealed class BulletConstraintXNA : BulletConstraint { DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; RigidBody body = ((BulletBodyXNA)pBody).rigidBody; - world.RemoveRigidBody(body); + CollisionObject collisionObject = ((BulletBodyXNA)pBody).body; + if (body != null) + world.RemoveRigidBody(body); + else if (collisionObject != null) + world.RemoveCollisionObject(collisionObject); + else + return false; return true; } @@ -182,7 +189,7 @@ private sealed class BulletConstraintXNA : BulletConstraint public override void SetRestitution(BulletBody pCollisionObject, float pRestitution) { - CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).body; collisionObject.SetRestitution(pRestitution); } @@ -219,13 +226,13 @@ private sealed class BulletConstraintXNA : BulletConstraint public override void SetCcdMotionThreshold(BulletBody pCollisionObject, float pccdMotionThreashold) { - CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).body; collisionObject.SetCcdMotionThreshold(pccdMotionThreashold); } public override void SetCcdSweptSphereRadius(BulletBody pCollisionObject, float pCcdSweptSphereRadius) { - CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).body; collisionObject.SetCcdSweptSphereRadius(pCcdSweptSphereRadius); } @@ -262,7 +269,7 @@ private sealed class BulletConstraintXNA : BulletConstraint } else { - world.AddCollisionObject(rbody); + world.AddCollisionObject(cbody); } cbody.SetWorldTransform(origPos); @@ -303,7 +310,7 @@ private sealed class BulletConstraintXNA : BulletConstraint public override bool SetCollisionGroupMask(BulletBody pCollisionObject, uint pGroup, uint pMask) { - CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).body; collisionObject.GetBroadphaseHandle().m_collisionFilterGroup = (BulletXNA.BulletCollision.CollisionFilterGroups) pGroup; collisionObject.GetBroadphaseHandle().m_collisionFilterGroup = (BulletXNA.BulletCollision.CollisionFilterGroups) pGroup; if ((uint) collisionObject.GetBroadphaseHandle().m_collisionFilterGroup == 0) @@ -390,7 +397,7 @@ private sealed class BulletConstraintXNA : BulletConstraint public override void SetTranslation(BulletBody pCollisionObject, Vector3 _position, Quaternion _orientation) { - CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).body; IndexedVector3 vposition = new IndexedVector3(_position.X, _position.Y, _position.Z); IndexedQuaternion vquaternion = new IndexedQuaternion(_orientation.X, _orientation.Y, _orientation.Z, _orientation.W); @@ -418,8 +425,11 @@ private sealed class BulletConstraintXNA : BulletConstraint public override void SetMassProps(BulletBody pBody, float pphysMass, Vector3 plocalInertia) { RigidBody body = (pBody as BulletBodyXNA).rigidBody; - IndexedVector3 inertia = new IndexedVector3(plocalInertia.X, plocalInertia.Y, plocalInertia.Z); - body.SetMassProps(pphysMass, inertia); + if (body != null) // Can't set mass props on collision object. + { + IndexedVector3 inertia = new IndexedVector3(plocalInertia.X, plocalInertia.Y, plocalInertia.Z); + body.SetMassProps(pphysMass, inertia); + } } @@ -432,7 +442,7 @@ private sealed class BulletConstraintXNA : BulletConstraint public override void SetFriction(BulletBody pCollisionObject, float _currentFriction) { - CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).body; collisionObject.SetFriction(_currentFriction); } @@ -459,7 +469,7 @@ private sealed class BulletConstraintXNA : BulletConstraint public override CollisionFlags RemoveFromCollisionFlags(BulletBody pCollisionObject, CollisionFlags pcollisionFlags) { - CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).body; CollisionFlags existingcollisionFlags = (CollisionFlags)(uint)collisionObject.GetCollisionFlags(); existingcollisionFlags &= ~pcollisionFlags; collisionObject.SetCollisionFlags((BulletXNA.BulletCollision.CollisionFlags)(uint)existingcollisionFlags); @@ -494,8 +504,11 @@ private sealed class BulletConstraintXNA : BulletConstraint public override void SetGravity(BulletBody pBody, Vector3 pGravity) { RigidBody body = (pBody as BulletBodyXNA).rigidBody; - IndexedVector3 gravity = new IndexedVector3(pGravity.X, pGravity.Y, pGravity.Z); - body.SetGravity(gravity); + if (body != null) // Can't set collisionobject.set gravity + { + IndexedVector3 gravity = new IndexedVector3(pGravity.X, pGravity.Y, pGravity.Z); + body.SetGravity(gravity); + } } public override bool DestroyConstraint(BulletWorld pWorld, BulletConstraint pConstraint) @@ -733,7 +746,8 @@ private sealed class BulletConstraintXNA : BulletConstraint public override void UpdateInertiaTensor(BulletBody pBody) { RigidBody body = (pBody as BulletBodyXNA).rigidBody; - body.UpdateInertiaTensor(); + if (body != null) // can't update inertia tensor on CollisionObject + body.UpdateInertiaTensor(); } public override void RecalculateCompoundShapeLocalAabb(BulletShape pCompoundShape) @@ -770,7 +784,7 @@ private sealed class BulletConstraintXNA : BulletConstraint public override CollisionObjectTypes GetBodyType(BulletBody pCollisionObject) { - CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; + CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).body; return (CollisionObjectTypes)(int) collisionObject.GetInternalType(); } @@ -889,7 +903,18 @@ private sealed class BulletConstraintXNA : BulletConstraint world.RemoveRigidBody(bo); } } - + if (co != null) + { + if (co.GetUserPointer() != null) + { + uint localId = (uint) co.GetUserPointer(); + if (specialCollisionObjects.ContainsKey(localId)) + { + specialCollisionObjects.Remove(localId); + } + } + } + } public override void Shutdown(BulletWorld pWorld) @@ -1050,7 +1075,7 @@ private sealed class BulletConstraintXNA : BulletConstraint Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); m_maxCollisions = maxCollisions; m_maxUpdatesPerFrame = maxUpdates; - + specialCollisionObjects = new Dictionary(); return new BulletWorldXNA(1, PhysicsScene, BSAPIXNA.Initialize2(worldExtent, configparms, maxCollisions, ref collisionArray, maxUpdates, ref updateArray, null)); } @@ -1310,6 +1335,12 @@ private sealed class BulletConstraintXNA : BulletConstraint CollisionShape shape = (pShape as BulletShapeXNA).shape; gObj.SetCollisionShape(shape); gObj.SetUserPointer(pLocalID); + + if (specialCollisionObjects.ContainsKey(pLocalID)) + specialCollisionObjects[pLocalID] = gObj; + else + specialCollisionObjects.Add(pLocalID, gObj); + // TODO: Add to Special CollisionObjects! return new BulletBodyXNA(pLocalID, gObj); } @@ -1399,7 +1430,7 @@ private sealed class BulletConstraintXNA : BulletConstraint } public override BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) { - /* TODO */ + if (cShape == null) return null; CompoundShape compoundShape = (cShape as BulletShapeXNA).shape as CompoundShape; @@ -1407,7 +1438,7 @@ private sealed class BulletConstraintXNA : BulletConstraint BulletShape retShape = new BulletShapeXNA(shape, BSShapeTypeFromBroadPhaseNativeType(shape.GetShapeType())); - return null; + return retShape; } public BSPhysicsShapeType BSShapeTypeFromBroadPhaseNativeType(BroadphaseNativeTypes pin) @@ -1802,26 +1833,29 @@ private sealed class BulletConstraintXNA : BulletConstraint numSimSteps = world.StepSimulation(timeStep, m_maxSubSteps, m_fixedTimeStep); int updates = 0; - - + PersistentManifold contactManifold; + CollisionObject objA; + CollisionObject objB; + ManifoldPoint manifoldPoint; + PairCachingGhostObject pairCachingGhostObject; m_collisionsThisFrame = 0; int numManifolds = world.GetDispatcher().GetNumManifolds(); for (int j = 0; j < numManifolds; j++) { - PersistentManifold contactManifold = world.GetDispatcher().GetManifoldByIndexInternal(j); + contactManifold = world.GetDispatcher().GetManifoldByIndexInternal(j); int numContacts = contactManifold.GetNumContacts(); if (numContacts == 0) continue; - CollisionObject objA = contactManifold.GetBody0() as CollisionObject; - CollisionObject objB = contactManifold.GetBody1() as CollisionObject; + objA = contactManifold.GetBody0() as CollisionObject; + objB = contactManifold.GetBody1() as CollisionObject; - ManifoldPoint manifoldPoint = contactManifold.GetContactPoint(0); - IndexedVector3 contactPoint = manifoldPoint.GetPositionWorldOnB(); - IndexedVector3 contactNormal = -manifoldPoint.m_normalWorldOnB; // make relative to A + manifoldPoint = contactManifold.GetContactPoint(0); + //IndexedVector3 contactPoint = manifoldPoint.GetPositionWorldOnB(); + // IndexedVector3 contactNormal = -manifoldPoint.m_normalWorldOnB; // make relative to A - RecordCollision(this, objA, objB, contactPoint, contactNormal,manifoldPoint.GetDistance()); + RecordCollision(this, objA, objB, manifoldPoint.GetPositionWorldOnB(), -manifoldPoint.m_normalWorldOnB, manifoldPoint.GetDistance()); m_collisionsThisFrame ++; if (m_collisionsThisFrame >= 9999999) break; @@ -1829,12 +1863,19 @@ private sealed class BulletConstraintXNA : BulletConstraint } - updatedEntityCount = LastEntityProperty; - updatedEntities = UpdatedObjects; - + foreach (GhostObject ghostObject in specialCollisionObjects.Values) + { + pairCachingGhostObject = ghostObject as PairCachingGhostObject; + if (pairCachingGhostObject != null) + { + RecordGhostCollisions(pairCachingGhostObject); + } + } + updatedEntityCount = LastEntityProperty; + updatedEntities = UpdatedObjects; collidersCount = LastCollisionDesc; colliders = UpdatedCollisions; @@ -1860,60 +1901,49 @@ private sealed class BulletConstraintXNA : BulletConstraint } public void RecordGhostCollisions(PairCachingGhostObject obj) { - /* - *void BulletSim::RecordGhostCollisions(btPairCachingGhostObject* obj) -{ - btManifoldArray manifoldArray; - btBroadphasePairArray& pairArray = obj->getOverlappingPairCache()->getOverlappingPairArray(); - int numPairs = pairArray.size(); - - // For all the pairs of sets of contact points - for (int i=0; i < numPairs; i++) - { - if (m_collisionsThisFrame >= m_maxCollisionsPerFrame) - break; - - manifoldArray.clear(); - const btBroadphasePair& pair = pairArray[i]; - - // The real representation is over in the world pair cache - btBroadphasePair* collisionPair = m_worldData.dynamicsWorld->getPairCache()->findPair(pair.m_pProxy0,pair.m_pProxy1); - if (!collisionPair) - continue; - - if (collisionPair->m_algorithm) - collisionPair->m_algorithm->getAllContactManifolds(manifoldArray); - - // The collision pair has sets of collision points (manifolds) - for (int j=0; j < manifoldArray.size(); j++) - { - btPersistentManifold* contactManifold = manifoldArray[j]; - int numContacts = contactManifold->getNumContacts(); - - const btCollisionObject* objA = static_cast(contactManifold->getBody0()); - const btCollisionObject* objB = static_cast(contactManifold->getBody1()); - - // TODO: this is a more thurough check than the regular collision code -- - // here we find the penetrating contact in the manifold but for regular - // collisions we assume the first point in the manifold is good enough. - // Decide of this extra checking is required or if first point is good enough. - for (int p=0; p < numContacts; p++) - { - const btManifoldPoint& pt = contactManifold->getContactPoint(p); - // If a penetrating contact, this is a hit - if (pt.getDistance()<0.f) - { - const btVector3& contactPoint = pt.getPositionWorldOnA(); - const btVector3& normalOnA = -pt.m_normalWorldOnB; - RecordCollision(objA, objB, contactPoint, normalOnA, pt.getDistance()); - // Only one contact point for each set of colliding objects - break; - } - } - } - } -} - */ + IOverlappingPairCache cache = obj.GetOverlappingPairCache(); + ObjectArray pairs = cache.GetOverlappingPairArray(); + + DiscreteDynamicsWorld world = (PhysicsScene.World as BulletWorldXNA).world; + PersistentManifoldArray manifoldArray = new PersistentManifoldArray(); + BroadphasePair collisionPair; + PersistentManifold contactManifold; + + CollisionObject objA; + CollisionObject objB; + + ManifoldPoint pt; + + int numPairs = pairs.Count; + + for (int i = 0; i < numPairs; i++) + { + manifoldArray.Clear(); + if (LastCollisionDesc < UpdatedCollisions.Length) + break; + collisionPair = world.GetPairCache().FindPair(pairs[i].m_pProxy0, pairs[i].m_pProxy1); + if (collisionPair == null) + continue; + + collisionPair.m_algorithm.GetAllContactManifolds(manifoldArray); + for (int j = 0; j < manifoldArray.Count; j++) + { + contactManifold = manifoldArray[j]; + int numContacts = contactManifold.GetNumContacts(); + objA = contactManifold.GetBody0() as CollisionObject; + objB = contactManifold.GetBody1() as CollisionObject; + for (int p = 0; p < numContacts; p++) + { + pt = contactManifold.GetContactPoint(p); + if (pt.GetDistance() < 0.0f) + { + RecordCollision(this, objA, objB, pt.GetPositionWorldOnA(), -pt.m_normalWorldOnB,pt.GetDistance()); + break; + } + } + } + } + } private static void RecordCollision(BSAPIXNA world, CollisionObject objA, CollisionObject objB, IndexedVector3 contact, IndexedVector3 norm, float penetration) { @@ -1934,7 +1964,7 @@ private sealed class BulletConstraintXNA : BulletConstraint contactNormal = -contactNormal; } - ulong collisionID = ((ulong) idA << 32) | idB; + //ulong collisionID = ((ulong) idA << 32) | idB; CollisionDesc cDesc = new CollisionDesc() { -- cgit v1.1 From ceabb1b49ae40b31659082a2f7622c1f3586ce46 Mon Sep 17 00:00:00 2001 From: Talun Date: Sat, 26 Jan 2013 00:34:42 +0000 Subject: Mantis 6343: Turn a prim to flexy to OFF don't work llSetPrimParams Correction so that scripts can turn Flexi off as well as on. --- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 001f4d9..81de9ab 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1700,10 +1700,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api part.Shape.FlexiForceX = (float)Force.x; part.Shape.FlexiForceY = (float)Force.y; part.Shape.FlexiForceZ = (float)Force.z; - part.Shape.PathCurve = 0x80; - part.ParentGroup.HasGroupChanged = true; - part.ScheduleFullUpdate(); + part.Shape.PathCurve = (byte)Extrusion.Flexible; + } + else + { + // Other values not set, they do not seem to be sent to the viewer + // Setting PathCurve appears to be what actually toggles the check box and turns Flexi on and off + part.Shape.PathCurve = (byte)Extrusion.Straight; + part.Shape.FlexiEntry = false; } + part.ParentGroup.HasGroupChanged = true; + part.ScheduleFullUpdate(); } /// -- cgit v1.1 From 53833babf99d83a27d0be2b820efbe41067ef723 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 26 Jan 2013 03:57:51 +0000 Subject: Add OnScriptMovingStartEvent and OnScriptMovingEndEvent to EventManager so that these can be triggered by future code (not yet implemented). Also hooks up moving_start and moving_end script events, eliminating itemID on XEngine EventManager methods since this is completely unused. An adaptation of the patch in http://opensimulator.org/mantis/view.php?id=6515 Thanks Garmin Kawaguichi and Signpost Marv. --- OpenSim/Region/Framework/Scenes/EventManager.cs | 56 ++++++++++++++++++++++ .../Region/ScriptEngine/XEngine/EventManager.cs | 6 ++- 2 files changed, 60 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 902ded1..9ee1520 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -549,6 +549,20 @@ namespace OpenSim.Region.Framework.Scenes /// public event ScriptControlEvent OnScriptControlEvent; + public delegate void ScriptMovingStartEvent(uint localID); + + /// + /// TODO: Should be triggered when a physics object starts moving. + /// + public event ScriptMovingStartEvent OnScriptMovingStartEvent; + + public delegate void ScriptMovingEndEvent(uint localID); + + /// + /// TODO: Should be triggered when a physics object stops moving. + /// + public event ScriptMovingEndEvent OnScriptMovingEndEvent; + public delegate void ScriptAtTargetEvent(uint localID, uint handle, Vector3 targetpos, Vector3 atpos); /// @@ -2212,6 +2226,48 @@ namespace OpenSim.Region.Framework.Scenes } } + public void TriggerMovingStartEvent(uint localID) + { + ScriptMovingStartEvent handlerScriptMovingStartEvent = OnScriptMovingStartEvent; + if (handlerScriptMovingStartEvent != null) + { + foreach (ScriptMovingStartEvent d in handlerScriptMovingStartEvent.GetInvocationList()) + { + try + { + d(localID); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[EVENT MANAGER]: Delegate for TriggerMovingStartEvent failed - continuing. {0} {1}", + e.Message, e.StackTrace); + } + } + } + } + + public void TriggerMovingEndEvent(uint localID) + { + ScriptMovingEndEvent handlerScriptMovingEndEvent = OnScriptMovingEndEvent; + if (handlerScriptMovingEndEvent != null) + { + foreach (ScriptMovingEndEvent d in handlerScriptMovingEndEvent.GetInvocationList()) + { + try + { + d(localID); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[EVENT MANAGER]: Delegate for TriggerMovingEndEvent failed - continuing. {0} {1}", + e.Message, e.StackTrace); + } + } + } + } + public void TriggerRequestChangeWaterHeight(float height) { if (height < 0) diff --git a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs index afde685..0ff2da3 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs @@ -62,6 +62,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine myScriptEngine.World.EventManager.OnScriptNotAtTargetEvent += not_at_target; myScriptEngine.World.EventManager.OnScriptAtRotTargetEvent += at_rot_target; myScriptEngine.World.EventManager.OnScriptNotAtRotTargetEvent += not_at_rot_target; + myScriptEngine.World.EventManager.OnScriptMovingStartEvent += moving_start; + myScriptEngine.World.EventManager.OnScriptMovingEndEvent += moving_end; myScriptEngine.World.EventManager.OnScriptControlEvent += control; myScriptEngine.World.EventManager.OnScriptColliderStart += collision_start; myScriptEngine.World.EventManager.OnScriptColliding += collision; @@ -419,14 +421,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine // dataserver: not handled here // link_message: not handled here - public void moving_start(uint localID, UUID itemID) + public void moving_start(uint localID) { myScriptEngine.PostObjectEvent(localID, new EventParams( "moving_start",new object[0], new DetectParams[0])); } - public void moving_end(uint localID, UUID itemID) + public void moving_end(uint localID) { myScriptEngine.PostObjectEvent(localID, new EventParams( "moving_end",new object[0], -- cgit v1.1 From b0cff35d96de4e9cbb252476f49640a4bf1f94e6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 26 Jan 2013 04:27:01 +0000 Subject: Fix issue where the "set terrain texture" console command did not tell the viewers that textures had updated (hence they did not display the changes). Addresses http://opensimulator.org/mantis/view.php?id=6513 --- OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs index 3b84d57..4d49794 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs @@ -117,7 +117,7 @@ namespace OpenSim.Region.CoreModules.World.Estate m_module.Scene.RegionInfo.RegionSettings.Save(); m_module.TriggerRegionInfoChange(); - m_module.sendRegionInfoPacketToAll(); + m_module.sendRegionHandshakeToAll(); } } } -- cgit v1.1 From 776cc33541d5b0576f28c02953be728ab3154e22 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 27 Jan 2013 01:07:37 +0000 Subject: Prevent items being destroyed by rename operations. Renaming of a wearable also sends an asset transaciton but it is empty. So we can't ignore name data when a transaction is present and can't treat every transaction as valid. Conflicts: OpenSim/Region/Framework/Scenes/Scene.Inventory.cs --- .../CoreModules/Agent/AssetTransaction/AssetXferUploader.cs | 3 ++- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 11 ++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs index 8add4bb..11efe6d 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs @@ -321,7 +321,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction // to avoid a race condition when the appearance module retrieves the item to set the asset id in // the AvatarAppearance structure. item.AssetID = m_asset.FullID; - m_Scene.InventoryService.UpdateItem(item); + if (item.AssetID != UUID.Zero) + m_Scene.InventoryService.UpdateItem(item); if (m_uploadState == UploadState.Complete) { diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 92bf85a..6808017 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -407,16 +407,16 @@ namespace OpenSim.Region.Framework.Scenes if (item.Owner != remoteClient.AgentId) return; - if (UUID.Zero == transactionID) - { - item.Name = itemUpd.Name; - item.Description = itemUpd.Description; + item.Name = itemUpd.Name; + item.Description = itemUpd.Description; // m_log.DebugFormat( // "[USER INVENTORY]: itemUpd {0} {1} {2} {3}, item {4} {5} {6} {7}", // itemUpd.NextPermissions, itemUpd.GroupPermissions, itemUpd.EveryOnePermissions, item.Flags, // item.NextPermissions, item.GroupPermissions, item.EveryOnePermissions, item.CurrentPermissions); + if (itemUpd.NextPermissions != 0) // Use this to determine validity. Can never be 0 if valid + { if (item.NextPermissions != (itemUpd.NextPermissions & item.BasePermissions)) item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner; item.NextPermissions = itemUpd.NextPermissions & item.BasePermissions; @@ -451,7 +451,8 @@ namespace OpenSim.Region.Framework.Scenes InventoryService.UpdateItem(item); } - else + + if (UUID.Zero != transactionID) { if (AgentTransactionsModule != null) { -- cgit v1.1 From c44a8e9f925c0195c4754c5e763af06dae657b53 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 25 Jan 2013 10:17:20 -0800 Subject: BulletSim: finish the post step event for physical object actions. Modify vehicle to use post step event for logging. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 14 ++++- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 66 ++++++++++++++++++---- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 6 ++ 3 files changed, 73 insertions(+), 13 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 7ad7c89..a369c1f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -583,6 +583,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Some of the properties of this prim may have changed. // Do any updating needed for a vehicle + Vector3 m_physicsLinearFactor = new Vector3(0.2f, 0.2f, 0.2f); // DEBUG DEBUG + Vector3 m_physicsAngularFactor = new Vector3(0.2f, 0.2f, 0.2f); // DEBUG DEBUG public void Refresh() { if (IsActive) @@ -599,6 +601,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Maybe compute linear and angular factor and damping from params. float angularDamping = BSParam.VehicleAngularDamping; PhysicsScene.PE.SetAngularDamping(Prim.PhysBody, angularDamping); + PhysicsScene.PE.SetLinearFactor(Prim.PhysBody, m_physicsLinearFactor); // DEBUG DEBUG + PhysicsScene.PE.SetAngularFactorV(Prim.PhysBody, m_physicsAngularFactor); // DEBUG DEBUG // Vehicles report collision events so we know when it's on the ground PhysicsScene.PE.AddToCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); @@ -898,9 +902,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin { if (!IsActive) return; - if (PhysicsScene.VehiclePhysicalLoggingEnabled) - PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody); - ForgetKnownVehicleProperties(); MoveLinear(pTimestep); @@ -922,6 +923,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin Prim.LocalID, VehiclePosition, m_knownForce, VehicleVelocity, VehicleRotationalVelocity); } + // Called after the simulation step + internal void PostStep(float pTimestep) + { + if (PhysicsScene.VehiclePhysicalLoggingEnabled) + PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody); + } + // Apply the effect of the linear motor and other linear motions (like hover and float). private void MoveLinear(float pTimestep) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 027c786..285d4a2 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -101,6 +101,7 @@ public abstract class BSPhysObject : PhysicsActor public virtual void Destroy() { UnRegisterAllPreStepActions(); + UnRegisterAllPostStepActions(); } public BSScene PhysicsScene { get; protected set; } @@ -393,17 +394,18 @@ public abstract class BSPhysObject : PhysicsActor // These actions are optional so, rather than scanning all the physical objects and asking them // if they have anything to do, a physical object registers for an event call before the step is performed. // This bookkeeping makes it easy to add, remove and clean up after all these registrations. - private Dictionary RegisteredActions = new Dictionary(); + private Dictionary RegisteredPrestepActions = new Dictionary(); + private Dictionary RegisteredPoststepActions = new Dictionary(); protected void RegisterPreStepAction(string op, uint id, BSScene.PreStepAction actn) { string identifier = op + "-" + id.ToString(); - lock (RegisteredActions) + lock (RegisteredPrestepActions) { // Clean out any existing action UnRegisterPreStepAction(op, id); - RegisteredActions[identifier] = actn; + RegisteredPrestepActions[identifier] = actn; } PhysicsScene.BeforeStep += actn; DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier); @@ -414,12 +416,12 @@ public abstract class BSPhysObject : PhysicsActor { string identifier = op + "-" + id.ToString(); bool removed = false; - lock (RegisteredActions) + lock (RegisteredPrestepActions) { - if (RegisteredActions.ContainsKey(identifier)) + if (RegisteredPrestepActions.ContainsKey(identifier)) { - PhysicsScene.BeforeStep -= RegisteredActions[identifier]; - RegisteredActions.Remove(identifier); + PhysicsScene.BeforeStep -= RegisteredPrestepActions[identifier]; + RegisteredPrestepActions.Remove(identifier); removed = true; } } @@ -428,17 +430,61 @@ public abstract class BSPhysObject : PhysicsActor protected void UnRegisterAllPreStepActions() { - lock (RegisteredActions) + lock (RegisteredPrestepActions) { - foreach (KeyValuePair kvp in RegisteredActions) + foreach (KeyValuePair kvp in RegisteredPrestepActions) { PhysicsScene.BeforeStep -= kvp.Value; } - RegisteredActions.Clear(); + RegisteredPrestepActions.Clear(); } DetailLog("{0},BSPhysObject.UnRegisterAllPreStepActions,", LocalID); } + + protected void RegisterPostStepAction(string op, uint id, BSScene.PostStepAction actn) + { + string identifier = op + "-" + id.ToString(); + + lock (RegisteredPoststepActions) + { + // Clean out any existing action + UnRegisterPostStepAction(op, id); + + RegisteredPoststepActions[identifier] = actn; + } + PhysicsScene.AfterStep += actn; + DetailLog("{0},BSPhysObject.RegisterPostStepAction,id={1}", LocalID, identifier); + } + + // Unregister a pre step action. Safe to call if the action has not been registered. + protected void UnRegisterPostStepAction(string op, uint id) + { + string identifier = op + "-" + id.ToString(); + bool removed = false; + lock (RegisteredPoststepActions) + { + if (RegisteredPoststepActions.ContainsKey(identifier)) + { + PhysicsScene.AfterStep -= RegisteredPoststepActions[identifier]; + RegisteredPoststepActions.Remove(identifier); + removed = true; + } + } + DetailLog("{0},BSPhysObject.UnRegisterPostStepAction,id={1},removed={2}", LocalID, identifier, removed); + } + protected void UnRegisterAllPostStepActions() + { + lock (RegisteredPoststepActions) + { + foreach (KeyValuePair kvp in RegisteredPoststepActions) + { + PhysicsScene.AfterStep -= kvp.Value; + } + RegisteredPoststepActions.Clear(); + } + DetailLog("{0},BSPhysObject.UnRegisterAllPostStepActions,", LocalID); + } #endregion // Per Simulation Step actions diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 8b00a33..99903f5 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -527,9 +527,15 @@ public sealed class BSPrim : BSPhysObject // If an active vehicle, register the vehicle code to be called before each step if (_vehicle.Type == Vehicle.TYPE_NONE) + { UnRegisterPreStepAction("BSPrim.Vehicle", LocalID); + PhysicsScene.AfterStep -= _vehicle.PostStep; + } else + { RegisterPreStepAction("BSPrim.Vehicle", LocalID, _vehicle.Step); + PhysicsScene.AfterStep += _vehicle.PostStep; + } }); } } -- cgit v1.1 From dd08e1fba6e154002a7fe8f46c8c01e6e61d39db Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 25 Jan 2013 12:00:19 -0800 Subject: BulletSim: parameterize several vehicle debugging values: physical linear and angular force factors now default to less than 1 (0.2) vehicle friction and restitution now default to low values --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 12 +++--- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 45 ++++++++++++++++++++++ .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 9 ++++- 3 files changed, 57 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index a369c1f..5c531fc 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -583,8 +583,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Some of the properties of this prim may have changed. // Do any updating needed for a vehicle - Vector3 m_physicsLinearFactor = new Vector3(0.2f, 0.2f, 0.2f); // DEBUG DEBUG - Vector3 m_physicsAngularFactor = new Vector3(0.2f, 0.2f, 0.2f); // DEBUG DEBUG public void Refresh() { if (IsActive) @@ -593,16 +591,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_vehicleMass = Prim.Linkset.LinksetMass; // Friction affects are handled by this vehicle code - float friction = 0f; - PhysicsScene.PE.SetFriction(Prim.PhysBody, friction); + PhysicsScene.PE.SetFriction(Prim.PhysBody, BSParam.VehicleFriction); + PhysicsScene.PE.SetRestitution(Prim.PhysBody, BSParam.VehicleRestitution); // Moderate angular movement introduced by Bullet. // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle. // Maybe compute linear and angular factor and damping from params. float angularDamping = BSParam.VehicleAngularDamping; PhysicsScene.PE.SetAngularDamping(Prim.PhysBody, angularDamping); - PhysicsScene.PE.SetLinearFactor(Prim.PhysBody, m_physicsLinearFactor); // DEBUG DEBUG - PhysicsScene.PE.SetAngularFactorV(Prim.PhysBody, m_physicsAngularFactor); // DEBUG DEBUG + PhysicsScene.PE.SetLinearFactor(Prim.PhysBody, BSParam.VehicleLinearFactorV); + PhysicsScene.PE.SetAngularFactorV(Prim.PhysBody, BSParam.VehicleAngularFactorV); // Vehicles report collision events so we know when it's on the ground PhysicsScene.PE.AddToCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); @@ -618,7 +616,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin PhysicsScene.PE.SetGravity(Prim.PhysBody, Vector3.Zero); VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4},grav={5}", - Prim.LocalID, m_vehicleMass, friction, Prim.Inertia, angularDamping, m_VehicleGravity); + Prim.LocalID, m_vehicleMass, Prim.Inertia, angularDamping, m_VehicleGravity); } else { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 06186b0..8de8905 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -82,9 +82,34 @@ public static class BSParam public static float AvatarStepApproachFactor { get; private set; } public static float AvatarStepForceFactor { get; private set; } + // Vehicle parameters public static float VehicleMaxLinearVelocity { get; private set; } public static float VehicleMaxAngularVelocity { get; private set; } public static float VehicleAngularDamping { get; private set; } + public static float VehicleFriction { get; private set; } + public static float VehicleRestitution { get; private set; } + public static float VehicleLinearFactor { get; private set; } + private static Vector3? vehicleLinearFactorV; + public static Vector3 VehicleLinearFactorV + { + get + { + if (!vehicleLinearFactorV.HasValue) + vehicleLinearFactorV = new Vector3(VehicleLinearFactor, VehicleLinearFactor, VehicleLinearFactor); + return (Vector3)vehicleLinearFactorV; + } + } + public static float VehicleAngularFactor { get; private set; } + private static Vector3? vehicleAngularFactorV; + public static Vector3 VehicleAngularFactorV + { + get + { + if (!vehicleAngularFactorV.HasValue) + vehicleAngularFactorV = new Vector3(VehicleAngularFactor, VehicleAngularFactor, VehicleAngularFactor); + return (Vector3)vehicleAngularFactorV; + } + } public static float VehicleDebuggingEnabled { get; private set; } public static float LinksetImplementation { get; private set; } @@ -454,6 +479,26 @@ public static class BSParam (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); }, (s) => { return VehicleAngularDamping; }, (s,p,l,v) => { VehicleAngularDamping = v; } ), + new ParameterDefn("VehicleLinearFactor", "Fraction of physical linear changes applied to vehicle (0.0 - 1.0)", + 0.2f, + (s,cf,p,v) => { VehicleLinearFactor = cf.GetFloat(p, v); }, + (s) => { return VehicleLinearFactor; }, + (s,p,l,v) => { VehicleLinearFactor = v; } ), + new ParameterDefn("VehicleAngularFactor", "Fraction of physical angular changes applied to vehicle (0.0 - 1.0)", + 0.2f, + (s,cf,p,v) => { VehicleAngularFactor = cf.GetFloat(p, v); }, + (s) => { return VehicleAngularFactor; }, + (s,p,l,v) => { VehicleAngularFactor = v; } ), + new ParameterDefn("VehicleFriction", "Friction of vehicle on the ground (0.0 - 1.0)", + 0.0f, + (s,cf,p,v) => { VehicleFriction = cf.GetFloat(p, v); }, + (s) => { return VehicleFriction; }, + (s,p,l,v) => { VehicleFriction = v; } ), + new ParameterDefn("VehicleRestitution", "Bouncyness factor for vehicles (0.0 - 1.0)", + 0.0f, + (s,cf,p,v) => { VehicleRestitution = cf.GetFloat(p, v); }, + (s) => { return VehicleRestitution; }, + (s,p,l,v) => { VehicleRestitution = v; } ), new ParameterDefn("VehicleDebuggingEnable", "Turn on/off vehicle debugging", ConfigurationParameters.numericFalse, (s,cf,p,v) => { VehicleDebuggingEnabled = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 801f690..7917795 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -2,7 +2,6 @@ CURRENT PRIORITIES ================================================= Deleting a linkset while standing on the root will leave the physical shape of the root behind. Not sure if it is because standing on it. Done with large prim linksets. -Child movement in linkset (don't rebuild linkset) Vehicle angular vertical attraction vehicle angular banking Center-of-gravity @@ -12,6 +11,7 @@ when should angular and linear motor targets be zeroed? when selected? Need a vehicle.clear()? Or an 'else' in prestep if not physical. Teravus llMoveToTarget script debug Mixing of hover, buoyancy/gravity, moveToTarget, into one force + Setting hover height to zero disables hover even if hover flags are on (from SL wiki) Nebadon vehicles turning funny in arena limitMotorUp calibration (more down?) llRotLookAt @@ -72,7 +72,11 @@ Incorporate inter-relationship of angular corrections. For instance, angularDefl GENERAL TODO LIST: ================================================= +Avatar standing on a moving object should start to move with the object. llMoveToTarget objects are not effected by gravity until target is removed. +Compute CCD parameters based on body size +Can solver iterations be changed per body/shape? Can be for constraints but what + about regular vehicles? Implement llSetPhysicalMaterial. extend it with Center-of-mass, rolling friction, density Implement llSetForceAndTorque. @@ -321,4 +325,5 @@ Mantis 6040 script http://opensimulator.org/mantis/view.php?id=6040 (DONE) Boats float low in the water (DONE) Boats floating at proper level (DONE) When is force introduced by SetForce removed? The prestep action could go forever. (DONE) - (Resolution: setForce registers a prestep action which keeps applying the force) \ No newline at end of file + (Resolution: setForce registers a prestep action which keeps applying the force) +Child movement in linkset (don't rebuild linkset) (DONE 20130122)) \ No newline at end of file -- cgit v1.1 From ddef8f16e58471d19baa63f14134b25309cf2570 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 25 Jan 2013 16:00:17 -0800 Subject: BulletSim: first attempt at reporting top colliders --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 10 ++++++---- OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | 17 +++++++++++++++++ OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 6 ------ OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 17 ++++++++++++++++- OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | 4 ++++ 5 files changed, 43 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 5c531fc..06b4620 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -597,8 +597,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Moderate angular movement introduced by Bullet. // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle. // Maybe compute linear and angular factor and damping from params. - float angularDamping = BSParam.VehicleAngularDamping; - PhysicsScene.PE.SetAngularDamping(Prim.PhysBody, angularDamping); + PhysicsScene.PE.SetAngularDamping(Prim.PhysBody, BSParam.VehicleAngularDamping); PhysicsScene.PE.SetLinearFactor(Prim.PhysBody, BSParam.VehicleLinearFactorV); PhysicsScene.PE.SetAngularFactorV(Prim.PhysBody, BSParam.VehicleAngularFactorV); @@ -615,8 +614,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin // The actual vehicle gravity is set to zero in Bullet so we can do all the application of same. PhysicsScene.PE.SetGravity(Prim.PhysBody, Vector3.Zero); - VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4},grav={5}", - Prim.LocalID, m_vehicleMass, Prim.Inertia, angularDamping, m_VehicleGravity); + VDetailLog("{0},BSDynamics.Refresh,mass={1},inert={2},grav={3},aDamp={4},frict={5},rest={6},lFact={7},aFact={8}", + Prim.LocalID, m_vehicleMass, Prim.Inertia, m_VehicleGravity, + BSParam.VehicleAngularDamping, BSParam.VehicleFriction, BSParam.VehicleRestitution, + BSParam.VehicleLinearFactor, BSParam.VehicleAngularFactor + ); } else { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 285d4a2..5e8143c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -95,6 +95,8 @@ public abstract class BSPhysObject : PhysicsActor SubscribedEventsMs = 0; CollidingStep = 0; CollidingGroundStep = 0; + CollisionAccumulation = 0; + CollisionScore = 0; } // Tell the object to clean up. @@ -239,6 +241,9 @@ public abstract class BSPhysObject : PhysicsActor // The collision flags we think are set in Bullet protected CollisionFlags CurrentCollisionFlags { get; set; } + // Count of collisions for this object + protected long CollisionAccumulation { get; set; } + public override bool IsColliding { get { return (CollidingStep == PhysicsScene.SimulationStep); } set { @@ -300,6 +305,8 @@ public abstract class BSPhysObject : PhysicsActor return ret; } + CollisionAccumulation++; + // if someone has subscribed for collision events.... if (SubscribedEvents()) { CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); @@ -386,6 +393,16 @@ public abstract class BSPhysObject : PhysicsActor public override bool SubscribedEvents() { return (SubscribedEventsMs > 0); } + // Because 'CollisionScore' is calls many times while sorting it should not be recomputed + // each time called. So this is built to be light weight for each collision and to do + // all the processing when the user asks for the info. + public void ComputeCollisionScore() + { + // Scale the collision count by the time since the last collision + long timeAgo = PhysicsScene.SimulationStep - CollidingStep + 1; + CollisionScore = CollisionAccumulation / timeAgo; + } + public override float CollisionScore { get; set; } #endregion // Collisions diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 99903f5..17fddd7 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -59,7 +59,6 @@ public sealed class BSPrim : BSPhysObject private OMV.Vector3 _force; private OMV.Vector3 _velocity; private OMV.Vector3 _torque; - private float _collisionScore; private OMV.Vector3 _acceleration; private OMV.Quaternion _orientation; private int _physicsActorType; @@ -644,11 +643,6 @@ public sealed class BSPrim : BSPhysObject // DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque); } } - public override float CollisionScore { - get { return _collisionScore; } - set { _collisionScore = value; - } - } public override OMV.Vector3 Acceleration { get { return _acceleration; } set { _acceleration = value; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index cb304b6..4442650 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -26,6 +26,7 @@ */ using System; using System.Collections.Generic; +using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; @@ -697,7 +698,21 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public override Dictionary GetTopColliders() { - return new Dictionary(); + Dictionary topColliders; + + lock (PhysObjects) + { + foreach (KeyValuePair kvp in PhysObjects) + { + kvp.Value.ComputeCollisionScore(); + } + + List orderedPrims = new List(PhysObjects.Values); + orderedPrims.OrderByDescending(p => p.CollisionScore).Take(25); + topColliders = orderedPrims.ToDictionary(p => p.LocalID, p => p.CollisionScore); + } + + return topColliders; } public override bool IsThreaded { get { return false; } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 7917795..a95e169 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -1,5 +1,9 @@ CURRENT PRIORITIES ================================================= +One sided meshes? Should terrain be built into a closed shape? + When meshes get partially wedged into the terrain, they cannot push themselves out. + It is possible that Bullet processes collisions whether entering or leaving a mesh. + Ref: http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4869 Deleting a linkset while standing on the root will leave the physical shape of the root behind. Not sure if it is because standing on it. Done with large prim linksets. Vehicle angular vertical attraction -- cgit v1.1 From 36f401d85011b0ffb548e79923381be894dbfabb Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 25 Jan 2013 16:52:16 -0800 Subject: BulletSim: parameterize the value for gravity reduction for ground vehicles on the ground. Set defaults for vehicle factors to one. Debug logging changes. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 15 ++++++++------- OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 12 +++++++++--- 3 files changed, 18 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 06b4620..90482fd 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -976,8 +976,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin public void ComputeLinearVelocity(float pTimestep) { // Step the motor from the current value. Get the correction needed this step. - Vector3 currentVel = VehicleVelocity * Quaternion.Inverse(VehicleOrientation); - Vector3 linearMotorCorrectionV = m_linearMotor.Step(pTimestep, currentVel); + Vector3 origVelW = VehicleVelocity; // DEBUG + Vector3 currentVelV = VehicleVelocity * Quaternion.Inverse(VehicleOrientation); + Vector3 linearMotorCorrectionV = m_linearMotor.Step(pTimestep, currentVelV); // Motor is vehicle coordinates. Rotate it to world coordinates Vector3 linearMotorVelocityW = linearMotorCorrectionV * VehicleOrientation; @@ -992,8 +993,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Add this correction to the velocity to make it faster/slower. VehicleVelocity += linearMotorVelocityW; - VDetailLog("{0}, MoveLinear,velocity,vehVel={1},correction={2},force={3}", - Prim.LocalID, VehicleVelocity, linearMotorCorrectionV, linearMotorVelocityW); + VDetailLog("{0}, MoveLinear,velocity,origVelW={1},velV={2},correctV={3},correctW={4},newVelW={5}", + Prim.LocalID, origVelW, currentVelV, linearMotorCorrectionV, linearMotorVelocityW, VehicleVelocity); } public void ComputeLinearTerrainHeightCorrection(float pTimestep) @@ -1193,12 +1194,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Hack to reduce downward force if the vehicle is probably sitting on the ground if (Prim.IsColliding && IsGroundVehicle) - appliedGravity *= 0.2f; + appliedGravity *= BSParam.VehicleGroundGravityFudge; VehicleAddForce(appliedGravity); - VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},appliedForce-{2}", - Prim.LocalID, m_VehicleGravity, appliedGravity); + VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},collid={2},appliedForce={3}", + Prim.LocalID, m_VehicleGravity, Prim.IsColliding, appliedGravity); } // ======================================================================= diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 2c8dd23..6c53c50 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -232,7 +232,7 @@ public sealed class BSLinksetCompound : BSLinkset newLsi.OffsetFromCenterOfMass, newLsi.OffsetRot, true /* shouldRecalculateLocalAabb */); - DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1}newLsi={2}", + DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1},newLsi={2}", updated.LocalID, whichUpdated, newLsi); updated.LinksetInfo = newLsi; updatedChild = true; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 8de8905..75eed86 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -110,6 +110,7 @@ public static class BSParam return (Vector3)vehicleAngularFactorV; } } + public static float VehicleGroundGravityFudge { get; private set; } public static float VehicleDebuggingEnabled { get; private set; } public static float LinksetImplementation { get; private set; } @@ -480,12 +481,12 @@ public static class BSParam (s) => { return VehicleAngularDamping; }, (s,p,l,v) => { VehicleAngularDamping = v; } ), new ParameterDefn("VehicleLinearFactor", "Fraction of physical linear changes applied to vehicle (0.0 - 1.0)", - 0.2f, + 1.0f, (s,cf,p,v) => { VehicleLinearFactor = cf.GetFloat(p, v); }, (s) => { return VehicleLinearFactor; }, (s,p,l,v) => { VehicleLinearFactor = v; } ), new ParameterDefn("VehicleAngularFactor", "Fraction of physical angular changes applied to vehicle (0.0 - 1.0)", - 0.2f, + 1.0f, (s,cf,p,v) => { VehicleAngularFactor = cf.GetFloat(p, v); }, (s) => { return VehicleAngularFactor; }, (s,p,l,v) => { VehicleAngularFactor = v; } ), @@ -495,10 +496,15 @@ public static class BSParam (s) => { return VehicleFriction; }, (s,p,l,v) => { VehicleFriction = v; } ), new ParameterDefn("VehicleRestitution", "Bouncyness factor for vehicles (0.0 - 1.0)", - 0.0f, + 0.2f, (s,cf,p,v) => { VehicleRestitution = cf.GetFloat(p, v); }, (s) => { return VehicleRestitution; }, (s,p,l,v) => { VehicleRestitution = v; } ), + new ParameterDefn("VehicleGroundGravityFudge", "Factor to multiple gravity if a ground vehicle is probably on the ground (0.0 - 1.0)", + 1.0f, + (s,cf,p,v) => { VehicleGroundGravityFudge = cf.GetFloat(p, v); }, + (s) => { return VehicleGroundGravityFudge; }, + (s,p,l,v) => { VehicleGroundGravityFudge = v; } ), new ParameterDefn("VehicleDebuggingEnable", "Turn on/off vehicle debugging", ConfigurationParameters.numericFalse, (s,cf,p,v) => { VehicleDebuggingEnabled = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, -- cgit v1.1 From 80f0a978db50f8fa3a36e012f92d7ff3755be332 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 27 Jan 2013 09:00:47 -0800 Subject: BulletSim: fix compile error from last commit --- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 4442650..86eb773 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -88,7 +88,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters public delegate void PreStepAction(float timeStep); public delegate void PostStepAction(float timeStep); public event PreStepAction BeforeStep; - public event PreStepAction AfterStep; + public event PostStepAction AfterStep; // A value of the time now so all the collision and update routines do not have to get their own // Set to 'now' just before all the prims and actors are called for collisions and updates @@ -763,7 +763,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters private void TriggerPostStepEvent(float timeStep) { - PreStepAction actions = AfterStep; + PostStepAction actions = AfterStep; if (actions != null) actions(timeStep); -- cgit v1.1 From 05adf4b30f2a7cdb63c63a178bd44b0fecbe9c45 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 27 Jan 2013 09:01:24 -0800 Subject: BulletSim: disable center-of-mass computation because it does not work yet --- OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 6c53c50..54dc458 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -377,7 +377,7 @@ public sealed class BSLinksetCompound : BSLinkset // Constraint linksets are rebuilt every time. // Note that this works for rebuilding just the root after a linkset is taken apart. // Called at taint time!! - private bool disableCOM = false; // disable until we get this debugged + private bool disableCOM = true; // disable until we get this debugged private void RecomputeLinksetCompound() { try -- cgit v1.1 From a345a2feb794d05dcb628aa916569b19394c2337 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 27 Jan 2013 10:31:08 -0800 Subject: BulletSim: add framework for BulletSim unit tests. No tests yet. --- .../Physics/BulletSPlugin/Tests/BasicVehicles.cs | 56 +++++++++++++++ .../Physics/BulletSPlugin/Tests/BulletSimTests.cs | 56 +++++++++++++++ .../BulletSPlugin/Tests/BulletSimTestsUtil.cs | 81 ++++++++++++++++++++++ 3 files changed, 193 insertions(+) create mode 100755 OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs create mode 100755 OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTests.cs create mode 100755 OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs b/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs new file mode 100755 index 0000000..41ef67b --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs @@ -0,0 +1,56 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using NUnit.Framework; +using log4net; + +using OpenSim.Tests.Common; + +namespace OpenSim.Region.Physics.BulletSPlugin.Tests +{ +[TestFixture] +public class BasicVehicles : OpenSimTestCase +{ + // Documentation on attributes: http://www.nunit.org/index.php?p=attributes&r=2.6.1 + // Documentation on assertions: http://www.nunit.org/index.php?p=assertions&r=2.6.1 + + [TestFixtureSetUp] + public void Init() + { + } + + [TestFixtureTearDown] + public void TearDown() + { + } +} +} \ No newline at end of file diff --git a/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTests.cs b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTests.cs new file mode 100755 index 0000000..35cbc1d --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTests.cs @@ -0,0 +1,56 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using NUnit.Framework; +using log4net; + +using OpenSim.Tests.Common; + +namespace OpenSim.Region.Physics.BulletSPlugin.Tests +{ +[TestFixture] +public class BulletSimTests : OpenSimTestCase +{ + // Documentation on attributes: http://www.nunit.org/index.php?p=attributes&r=2.6.1 + // Documentation on assertions: http://www.nunit.org/index.php?p=assertions&r=2.6.1 + + [TestFixtureSetUp] + public void Init() + { + } + + [TestFixtureTearDown] + public void TearDown() + { + } +} +} diff --git a/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs new file mode 100755 index 0000000..6c2247a --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs @@ -0,0 +1,81 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Nini.Config; + +using OpenSim.Framework; +using OpenSim.Region.Physics.BulletSPlugin; +using OpenSim.Region.Physics.Meshing; + +namespace OpenSim.Region.Physics.BulletSPlugin.Tests +{ +// Utility functions for building up and tearing down the sample physics environments +public static class BulletSimTestsUtil +{ + // 'engineName' is the Bullet engine to use. Either null (for unmanaged), "BulletUnmanaged" or "BulletXNA" + // 'params' is a set of keyValue pairs to set in the engine's configuration file (override defaults) + // May be 'null' if there are no overrides. + public static BSScene CreateBasicPhysicsEngine(string engineName, Dictionary paramOverrides) + { + if (engineName == null) + engineName = "BulletUnmanaged"; + + IConfigSource openSimINI = new IniConfigSource(); + IConfig startupConfig = openSimINI.AddConfig("StartUp"); + startupConfig.Set("meshing", "Meshmerizer"); + startupConfig.Set("physics", "BulletSim"); + + IConfig bulletSimConfig = openSimINI.AddConfig("BulletSim"); + bulletSimConfig.Set("BulletEngine", engineName); + if (paramOverrides != null) + { + foreach (KeyValuePair kvp in paramOverrides) + { + bulletSimConfig.Set(kvp.Key, kvp.Value); + } + } + // bulletSimConfig.Set("PhysicsLoggingEnabled","True"); + // bulletSimConfig.Set("PhysicsLoggingDoFlush","True"); + // bulletSimConfig.Set("VehicleLoggingEnabled","True"); + + BSPlugin bsPlugin = new BSPlugin(); + + BSScene bsScene = (BSScene)bsPlugin.GetScene("BSTestRegion"); + + Meshing.Meshmerizer mesher = new Meshmerizer(openSimINI); + bsScene.Initialise(mesher, openSimINI); + + return bsScene; + } + +} +} -- cgit v1.1 From 26d4596080295d7509ef16bce9eb571d326c3ba6 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 27 Jan 2013 12:48:16 -0800 Subject: BulletSim: reinstate the supression of rotational velocity for vehicles --- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 17fddd7..998836c 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -1620,7 +1620,7 @@ public sealed class BSPrim : BSPhysObject // TODO: handle physics introduced by Bullet with computed vehicle physics. if (_vehicle.IsActive) { - // entprop.RotationalVelocity = OMV.Vector3.Zero; + entprop.RotationalVelocity = OMV.Vector3.Zero; } // DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG -- cgit v1.1 From b546af9ac290951f22e8c8e56798adb176076591 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 27 Jan 2013 12:48:36 -0800 Subject: BulletSim: simplify the initialization of some of the parameters. Disable vertical attraction for vehicles by default (for the moment). Fix bug where vehicle would go crazy when velocity got above a certain speed. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 19 ++++++++---- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 36 ++++++---------------- 2 files changed, 23 insertions(+), 32 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 90482fd..94194b0 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -141,7 +141,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // in changes by making enablement of debugging flags from INI file. public void SetupVehicleDebugging() { - enableAngularVerticalAttraction = true; + enableAngularVerticalAttraction = false; enableAngularDeflection = false; enableAngularBanking = false; if (BSParam.VehicleDebuggingEnabled != ConfigurationParameters.numericFalse) @@ -803,7 +803,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_knownVelocity = Prim.ForceVelocity; m_knownHas |= m_knownChangedVelocity; } - return (Vector3)m_knownVelocity; + return m_knownVelocity; } set { @@ -926,6 +926,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Called after the simulation step internal void PostStep(float pTimestep) { + if (!IsActive) return; + if (PhysicsScene.VehiclePhysicalLoggingEnabled) PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody); } @@ -961,10 +963,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ================================================================== // Clamp high or low velocities float newVelocityLengthSq = VehicleVelocity.LengthSquared(); - if (newVelocityLengthSq > BSParam.VehicleMaxLinearVelocity) + if (newVelocityLengthSq > BSParam.VehicleMaxLinearVelocitySq) { + Vector3 origVelW = VehicleVelocity; // DEBUG DEBUG VehicleVelocity /= VehicleVelocity.Length(); VehicleVelocity *= BSParam.VehicleMaxLinearVelocity; + VDetailLog("{0}, MoveLinear,clampMax,origVelW={1},lenSq={2},maxVelSq={3},,newVelW={4}", + Prim.LocalID, origVelW, newVelocityLengthSq, BSParam.VehicleMaxLinearVelocitySq, VehicleVelocity); } else if (newVelocityLengthSq < 0.001f) VehicleVelocity = Vector3.Zero; @@ -1301,6 +1306,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff) { Vector3 vertContributionV = Vector3.Zero; + Vector3 origRotVelW = VehicleRotationalVelocity; // DEBUG DEBUG // Take a vector pointing up and convert it from world to vehicle relative coords. Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; @@ -1328,13 +1334,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin // 'vertContrbution' is now the necessary angular correction to correct tilt in one second. // Correction happens over a number of seconds. - Vector3 unscaledContrib = vertContributionV; // DEBUG DEBUG + Vector3 unscaledContribVerticalErrorV = vertContributionV; // DEBUG DEBUG vertContributionV /= m_verticalAttractionTimescale; VehicleRotationalVelocity += vertContributionV * VehicleOrientation; - VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},eff={3},ts={4},vertAttr={5}", - Prim.LocalID, verticalError, unscaledContrib, m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContributionV); + VDetailLog("{0}, MoveAngular,verticalAttraction,,origRotVW={1},vertError={2},unscaledV={3},eff={4},ts={5},vertContribV={6}", + Prim.LocalID, origRotVelW, verticalError, unscaledContribVerticalErrorV, + m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContributionV); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 75eed86..4ece944 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -84,32 +84,16 @@ public static class BSParam // Vehicle parameters public static float VehicleMaxLinearVelocity { get; private set; } + public static float VehicleMaxLinearVelocitySq { get; private set; } public static float VehicleMaxAngularVelocity { get; private set; } + public static float VehicleMaxAngularVelocitySq { get; private set; } public static float VehicleAngularDamping { get; private set; } public static float VehicleFriction { get; private set; } public static float VehicleRestitution { get; private set; } public static float VehicleLinearFactor { get; private set; } - private static Vector3? vehicleLinearFactorV; - public static Vector3 VehicleLinearFactorV - { - get - { - if (!vehicleLinearFactorV.HasValue) - vehicleLinearFactorV = new Vector3(VehicleLinearFactor, VehicleLinearFactor, VehicleLinearFactor); - return (Vector3)vehicleLinearFactorV; - } - } + public static Vector3 VehicleLinearFactorV { get; private set; } public static float VehicleAngularFactor { get; private set; } - private static Vector3? vehicleAngularFactorV; - public static Vector3 VehicleAngularFactorV - { - get - { - if (!vehicleAngularFactorV.HasValue) - vehicleAngularFactorV = new Vector3(VehicleAngularFactor, VehicleAngularFactor, VehicleAngularFactor); - return (Vector3)vehicleAngularFactorV; - } - } + public static Vector3 VehicleAngularFactorV { get; private set; } public static float VehicleGroundGravityFudge { get; private set; } public static float VehicleDebuggingEnabled { get; private set; } @@ -469,12 +453,12 @@ public static class BSParam 1000.0f, (s,cf,p,v) => { VehicleMaxLinearVelocity = cf.GetFloat(p, v); }, (s) => { return (float)VehicleMaxLinearVelocity; }, - (s,p,l,v) => { VehicleMaxLinearVelocity = v; } ), + (s,p,l,v) => { VehicleMaxLinearVelocity = v; VehicleMaxLinearVelocitySq = v * v; } ), new ParameterDefn("VehicleMaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to a vehicle", 12.0f, (s,cf,p,v) => { VehicleMaxAngularVelocity = cf.GetFloat(p, v); }, (s) => { return (float)VehicleMaxAngularVelocity; }, - (s,p,l,v) => { VehicleMaxAngularVelocity = v; } ), + (s,p,l,v) => { VehicleMaxAngularVelocity = v; VehicleMaxAngularVelocitySq = v * v; } ), new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", 0.0f, (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); }, @@ -484,24 +468,24 @@ public static class BSParam 1.0f, (s,cf,p,v) => { VehicleLinearFactor = cf.GetFloat(p, v); }, (s) => { return VehicleLinearFactor; }, - (s,p,l,v) => { VehicleLinearFactor = v; } ), + (s,p,l,v) => { VehicleLinearFactor = v; VehicleLinearFactorV = new Vector3(v, v, v); } ), new ParameterDefn("VehicleAngularFactor", "Fraction of physical angular changes applied to vehicle (0.0 - 1.0)", 1.0f, (s,cf,p,v) => { VehicleAngularFactor = cf.GetFloat(p, v); }, (s) => { return VehicleAngularFactor; }, - (s,p,l,v) => { VehicleAngularFactor = v; } ), + (s,p,l,v) => { VehicleAngularFactor = v; VehicleAngularFactorV = new Vector3(v, v, v); } ), new ParameterDefn("VehicleFriction", "Friction of vehicle on the ground (0.0 - 1.0)", 0.0f, (s,cf,p,v) => { VehicleFriction = cf.GetFloat(p, v); }, (s) => { return VehicleFriction; }, (s,p,l,v) => { VehicleFriction = v; } ), new ParameterDefn("VehicleRestitution", "Bouncyness factor for vehicles (0.0 - 1.0)", - 0.2f, + 0.0f, (s,cf,p,v) => { VehicleRestitution = cf.GetFloat(p, v); }, (s) => { return VehicleRestitution; }, (s,p,l,v) => { VehicleRestitution = v; } ), new ParameterDefn("VehicleGroundGravityFudge", "Factor to multiple gravity if a ground vehicle is probably on the ground (0.0 - 1.0)", - 1.0f, + 0.2f, (s,cf,p,v) => { VehicleGroundGravityFudge = cf.GetFloat(p, v); }, (s) => { return VehicleGroundGravityFudge; }, (s,p,l,v) => { VehicleGroundGravityFudge = v; } ), -- cgit v1.1 From f6380a3ad3ee9479886415a117849eb5bd3f40f7 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 28 Jan 2013 09:02:01 -0800 Subject: BulletSim: fix the trimming of colliders so only the top 25 are returned. --- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 4 ++-- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 86eb773..b23be91 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -708,8 +708,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters } List orderedPrims = new List(PhysObjects.Values); - orderedPrims.OrderByDescending(p => p.CollisionScore).Take(25); - topColliders = orderedPrims.ToDictionary(p => p.LocalID, p => p.CollisionScore); + orderedPrims.OrderByDescending(p => p.CollisionScore); + topColliders = orderedPrims.Take(25).ToDictionary(p => p.LocalID, p => p.CollisionScore); } return topColliders; diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 02a0b15..6d7f079 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -4096,8 +4096,8 @@ namespace OpenSim.Region.Physics.OdePlugin lock (_prims) { List orderedPrims = new List(_prims); - orderedPrims.OrderByDescending(p => p.CollisionScore).Take(25); - topColliders = orderedPrims.ToDictionary(p => p.LocalID, p => p.CollisionScore); + orderedPrims.OrderByDescending(p => p.CollisionScore); + topColliders = orderedPrims.Take(25).ToDictionary(p => p.LocalID, p => p.CollisionScore); foreach (OdePrim p in _prims) p.CollisionScore = 0; -- cgit v1.1 From e4c6a19940fe0bb4dfce7fa53de282bdd6fbfb08 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 28 Jan 2013 15:11:20 -0800 Subject: BulletSim: rename 'uint' to 'UInt32' to make clear the type that is passed to unmanaged code. --- .../Region/Physics/BulletSPlugin/BSApiTemplate.cs | 28 +++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index f25b447..abbd22c 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs @@ -87,7 +87,7 @@ public enum FixedShapeKey : ulong [StructLayout(LayoutKind.Sequential)] public struct ShapeData { - public uint ID; + public UInt32 ID; public BSPhysicsShapeType Type; public Vector3 Position; public Quaternion Rotation; @@ -111,7 +111,7 @@ public struct ShapeData [StructLayout(LayoutKind.Sequential)] public struct SweepHit { - public uint ID; + public UInt32 ID; public float Fraction; public Vector3 Normal; public Vector3 Point; @@ -119,15 +119,15 @@ public struct SweepHit [StructLayout(LayoutKind.Sequential)] public struct RaycastHit { - public uint ID; + public UInt32 ID; public float Fraction; public Vector3 Normal; } [StructLayout(LayoutKind.Sequential)] public struct CollisionDesc { - public uint aID; - public uint bID; + public UInt32 aID; + public UInt32 bID; public Vector3 point; public Vector3 normal; public float penetration; @@ -135,7 +135,7 @@ public struct CollisionDesc [StructLayout(LayoutKind.Sequential)] public struct EntityProperties { - public uint ID; + public UInt32 ID; public Vector3 Position; public Quaternion Rotation; public Vector3 Velocity; @@ -325,7 +325,7 @@ public abstract BulletWorld Initialize(Vector3 maxPosition, ConfigurationParamet public abstract int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, out int updatedEntityCount, out int collidersCount); -public abstract bool UpdateParameter(BulletWorld world, uint localID, String parm, float value); +public abstract bool UpdateParameter(BulletWorld world, UInt32 localID, String parm, float value); public abstract void Shutdown(BulletWorld sim); @@ -366,24 +366,24 @@ public abstract void UpdateChildTransform(BulletShape pShape, int childIndex, Ve public abstract void RecalculateCompoundShapeLocalAabb(BulletShape cShape); -public abstract BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id); +public abstract BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, UInt32 id); public abstract bool DeleteCollisionShape(BulletWorld world, BulletShape shape); public abstract CollisionObjectTypes GetBodyType(BulletBody obj); -public abstract BulletBody CreateBodyFromShape(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot); +public abstract BulletBody CreateBodyFromShape(BulletWorld sim, BulletShape shape, UInt32 id, Vector3 pos, Quaternion rot); -public abstract BulletBody CreateBodyWithDefaultMotionState(BulletShape shape, uint id, Vector3 pos, Quaternion rot); +public abstract BulletBody CreateBodyWithDefaultMotionState(BulletShape shape, UInt32 id, Vector3 pos, Quaternion rot); -public abstract BulletBody CreateGhostFromShape(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot); +public abstract BulletBody CreateGhostFromShape(BulletWorld sim, BulletShape shape, UInt32 id, Vector3 pos, Quaternion rot); public abstract void DestroyObject(BulletWorld sim, BulletBody obj); // ===================================================================================== -public abstract BulletShape CreateGroundPlaneShape(uint id, float height, float collisionMargin); +public abstract BulletShape CreateGroundPlaneShape(UInt32 id, float height, float collisionMargin); -public abstract BulletShape CreateTerrainShape(uint id, Vector3 size, float minHeight, float maxHeight, float[] heightMap, +public abstract BulletShape CreateTerrainShape(UInt32 id, Vector3 size, float minHeight, float maxHeight, float[] heightMap, float scaleFactor, float collisionMargin); // ===================================================================================== @@ -629,7 +629,7 @@ public abstract BulletConstraint GetConstraintRef(BulletBody obj, int index); public abstract int GetNumConstraintRefs(BulletBody obj); -public abstract bool SetCollisionGroupMask(BulletBody body, uint filter, uint mask); +public abstract bool SetCollisionGroupMask(BulletBody body, UInt32 filter, UInt32 mask); // ===================================================================================== // btCollisionShape entries -- cgit v1.1 From e9aff0a91d6a4d02498ce45759389bb09b34fcbc Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 28 Jan 2013 15:11:50 -0800 Subject: BulletSim: do not zero an avatar's standing velocity if it is standing on a moving object. Rearrange pre/post action subscription code to put more in locks. Add meshmerizer params to BulletSimTestUtil scene creation (and fix line endings). Rebuilt version of DLLs and SOs with cleaned up code and no profiling for sure. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 13 +- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 33 ++-- .../BulletSPlugin/Tests/BulletSimTestsUtil.cs | 168 +++++++++++---------- 3 files changed, 118 insertions(+), 96 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 7603254..3884a5d 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -56,7 +56,6 @@ public sealed class BSCharacter : BSPhysObject private int _physicsActorType; private bool _isPhysical; private bool _flying; - private bool _wasWalking; // 'true' if the avatar was walking/moving last frame private bool _setAlwaysRun; private bool _throttleUpdates; private bool _floatOnWater; @@ -84,7 +83,6 @@ public sealed class BSCharacter : BSPhysObject _position = pos; _flying = isFlying; - _wasWalking = true; // causes first step to initialize standing _orientation = OMV.Quaternion.Identity; _velocity = OMV.Vector3.Zero; _buoyancy = ComputeBuoyancyFromFlying(isFlying); @@ -220,7 +218,13 @@ public sealed class BSCharacter : BSPhysObject { // The avatar shouldn't be moving _velocityMotor.Zero(); - ZeroMotion(true /* inTaintTime */); + + // If we are colliding with a stationary object, presume we're standing and don't move around + if (!ColliderIsMoving) + { + DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", LocalID); + ZeroMotion(true /* inTaintTime */); + } // Standing has more friction on the ground if (_currentFriction != BSParam.AvatarStandingFriction) @@ -229,8 +233,6 @@ public sealed class BSCharacter : BSPhysObject PhysicsScene.PE.SetFriction(PhysBody, _currentFriction); } DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1}", LocalID, _velocityMotor.TargetValue); - - _wasWalking = false; } else { @@ -260,7 +262,6 @@ public sealed class BSCharacter : BSPhysObject DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce); - _wasWalking = true; } }); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 5e8143c..a113530 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -96,6 +96,7 @@ public abstract class BSPhysObject : PhysicsActor CollidingStep = 0; CollidingGroundStep = 0; CollisionAccumulation = 0; + ColliderIsMoving = false; CollisionScore = 0; } @@ -177,13 +178,14 @@ public abstract class BSPhysObject : PhysicsActor public abstract OMV.Vector3 RawPosition { get; set; } public abstract OMV.Vector3 ForcePosition { get; set; } - // Position is what the simulator thinks the positions of the prim is. + // 'Position' and 'Orientation' is what the simulator thinks the positions of the prim is. // Because Bullet needs the zero coordinate to be the center of mass of the linkset, // sometimes it is necessary to displace the position the physics engine thinks // the position is. PositionDisplacement must be added and removed from the // position as the simulator position is stored and fetched from the physics - // engine. + // engine. Similar to OrientationDisplacement. public virtual OMV.Vector3 PositionDisplacement { get; set; } + public virtual OMV.Quaternion OrientationDisplacement { get; set; } public abstract OMV.Quaternion RawOrientation { get; set; } public abstract OMV.Quaternion ForceOrientation { get; set; } @@ -240,6 +242,9 @@ public abstract class BSPhysObject : PhysicsActor protected long CollidingObjectStep { get; set; } // The collision flags we think are set in Bullet protected CollisionFlags CurrentCollisionFlags { get; set; } + // On a collision, check the collider and remember if the last collider was moving + // Used to modify the standing of avatars (avatars on stationary things stand still) + protected bool ColliderIsMoving; // Count of collisions for this object protected long CollisionAccumulation { get; set; } @@ -307,7 +312,10 @@ public abstract class BSPhysObject : PhysicsActor CollisionAccumulation++; - // if someone has subscribed for collision events.... + // For movement tests, remember if we are colliding with an object that is moving. + ColliderIsMoving = collidee != null ? collidee.RawVelocity != OMV.Vector3.Zero : false; + + // If someone has subscribed for collision events log the collision so it will be reported up if (SubscribedEvents()) { CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5}", @@ -393,12 +401,13 @@ public abstract class BSPhysObject : PhysicsActor public override bool SubscribedEvents() { return (SubscribedEventsMs > 0); } - // Because 'CollisionScore' is calls many times while sorting it should not be recomputed + // Because 'CollisionScore' is called many times while sorting, it should not be recomputed // each time called. So this is built to be light weight for each collision and to do // all the processing when the user asks for the info. public void ComputeCollisionScore() { - // Scale the collision count by the time since the last collision + // Scale the collision count by the time since the last collision. + // The "+1" prevents dividing by zero. long timeAgo = PhysicsScene.SimulationStep - CollidingStep + 1; CollisionScore = CollisionAccumulation / timeAgo; } @@ -423,13 +432,15 @@ public abstract class BSPhysObject : PhysicsActor UnRegisterPreStepAction(op, id); RegisteredPrestepActions[identifier] = actn; + + PhysicsScene.BeforeStep += actn; } - PhysicsScene.BeforeStep += actn; DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier); } // Unregister a pre step action. Safe to call if the action has not been registered. - protected void UnRegisterPreStepAction(string op, uint id) + // Returns 'true' if an action was actually removed + protected bool UnRegisterPreStepAction(string op, uint id) { string identifier = op + "-" + id.ToString(); bool removed = false; @@ -443,6 +454,7 @@ public abstract class BSPhysObject : PhysicsActor } } DetailLog("{0},BSPhysObject.UnRegisterPreStepAction,id={1},removed={2}", LocalID, identifier, removed); + return removed; } protected void UnRegisterAllPreStepActions() @@ -468,13 +480,15 @@ public abstract class BSPhysObject : PhysicsActor UnRegisterPostStepAction(op, id); RegisteredPoststepActions[identifier] = actn; + + PhysicsScene.AfterStep += actn; } - PhysicsScene.AfterStep += actn; DetailLog("{0},BSPhysObject.RegisterPostStepAction,id={1}", LocalID, identifier); } // Unregister a pre step action. Safe to call if the action has not been registered. - protected void UnRegisterPostStepAction(string op, uint id) + // Returns 'true' if an action was actually removed. + protected bool UnRegisterPostStepAction(string op, uint id) { string identifier = op + "-" + id.ToString(); bool removed = false; @@ -488,6 +502,7 @@ public abstract class BSPhysObject : PhysicsActor } } DetailLog("{0},BSPhysObject.UnRegisterPostStepAction,id={1},removed={2}", LocalID, identifier, removed); + return removed; } protected void UnRegisterAllPostStepActions() diff --git a/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs index 6c2247a..e7657f9 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs @@ -1,81 +1,87 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -using Nini.Config; - -using OpenSim.Framework; -using OpenSim.Region.Physics.BulletSPlugin; -using OpenSim.Region.Physics.Meshing; - -namespace OpenSim.Region.Physics.BulletSPlugin.Tests -{ -// Utility functions for building up and tearing down the sample physics environments -public static class BulletSimTestsUtil -{ - // 'engineName' is the Bullet engine to use. Either null (for unmanaged), "BulletUnmanaged" or "BulletXNA" - // 'params' is a set of keyValue pairs to set in the engine's configuration file (override defaults) - // May be 'null' if there are no overrides. - public static BSScene CreateBasicPhysicsEngine(string engineName, Dictionary paramOverrides) - { - if (engineName == null) - engineName = "BulletUnmanaged"; - - IConfigSource openSimINI = new IniConfigSource(); - IConfig startupConfig = openSimINI.AddConfig("StartUp"); - startupConfig.Set("meshing", "Meshmerizer"); - startupConfig.Set("physics", "BulletSim"); - - IConfig bulletSimConfig = openSimINI.AddConfig("BulletSim"); - bulletSimConfig.Set("BulletEngine", engineName); - if (paramOverrides != null) - { - foreach (KeyValuePair kvp in paramOverrides) - { - bulletSimConfig.Set(kvp.Key, kvp.Value); - } - } - // bulletSimConfig.Set("PhysicsLoggingEnabled","True"); - // bulletSimConfig.Set("PhysicsLoggingDoFlush","True"); - // bulletSimConfig.Set("VehicleLoggingEnabled","True"); - - BSPlugin bsPlugin = new BSPlugin(); - - BSScene bsScene = (BSScene)bsPlugin.GetScene("BSTestRegion"); - - Meshing.Meshmerizer mesher = new Meshmerizer(openSimINI); - bsScene.Initialise(mesher, openSimINI); - - return bsScene; - } - -} -} +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Nini.Config; + +using OpenSim.Framework; +using OpenSim.Region.Physics.BulletSPlugin; +using OpenSim.Region.Physics.Meshing; + +namespace OpenSim.Region.Physics.BulletSPlugin.Tests +{ +// Utility functions for building up and tearing down the sample physics environments +public static class BulletSimTestsUtil +{ + // 'engineName' is the Bullet engine to use. Either null (for unmanaged), "BulletUnmanaged" or "BulletXNA" + // 'params' is a set of keyValue pairs to set in the engine's configuration file (override defaults) + // May be 'null' if there are no overrides. + public static BSScene CreateBasicPhysicsEngine(Dictionary paramOverrides) + { + IConfigSource openSimINI = new IniConfigSource(); + IConfig startupConfig = openSimINI.AddConfig("StartUp"); + startupConfig.Set("physics", "BulletSim"); + startupConfig.Set("meshing", "Meshmerizer"); + startupConfig.Set("cacheSculptMaps", "false"); // meshmerizer shouldn't save maps + + IConfig bulletSimConfig = openSimINI.AddConfig("BulletSim"); + // If the caller cares, specify the bullet engine otherwise it will default to "BulletUnmanaged". + // bulletSimConfig.Set("BulletEngine", "BulletUnmanaged"); + // bulletSimConfig.Set("BulletEngine", "BulletXNA"); + bulletSimConfig.Set("MeshSculptedPrim", "false"); + bulletSimConfig.Set("ForceSimplePrimMeshing", "true"); + if (paramOverrides != null) + { + foreach (KeyValuePair kvp in paramOverrides) + { + bulletSimConfig.Set(kvp.Key, kvp.Value); + } + } + // bulletSimConfig.Set("PhysicsLoggingEnabled","True"); + // bulletSimConfig.Set("PhysicsLoggingDoFlush","True"); + // bulletSimConfig.Set("VehicleLoggingEnabled","True"); + + BSPlugin bsPlugin = new BSPlugin(); + + BSScene bsScene = (BSScene)bsPlugin.GetScene("BSTestRegion"); + + // Since the asset requestor is not initialized, any mesh or sculptie will be a cube. + // In the future, add a fake asset fetcher to get meshes and sculpts. + // bsScene.RequestAssetMethod = ???; + + Meshing.Meshmerizer mesher = new Meshmerizer(openSimINI); + bsScene.Initialise(mesher, openSimINI); + + return bsScene; + } + +} +} -- cgit v1.1 From 531d0429d1cc49a1959f6f7a0028ed3111dd6bd4 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 28 Jan 2013 17:08:34 -0800 Subject: BulletSim: first unit test: vehicle angular attraction --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 12 +- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 32 ++-- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 2 +- .../Physics/BulletSPlugin/Tests/BasicVehicles.cs | 181 ++++++++++++++------- .../BulletSPlugin/Tests/BulletSimTestsUtil.cs | 2 +- 5 files changed, 150 insertions(+), 79 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 94194b0..05a0dcc 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -125,9 +125,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin static readonly float PIOverTwo = ((float)Math.PI) / 2f; // For debugging, flags to turn on and off individual corrections. - private bool enableAngularVerticalAttraction; - private bool enableAngularDeflection; - private bool enableAngularBanking; + public bool enableAngularVerticalAttraction; + public bool enableAngularDeflection; + public bool enableAngularBanking; public BSDynamics(BSScene myScene, BSPrim myPrim) { @@ -165,7 +165,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin } #region Vehicle parameter setting - internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) + public void ProcessFloatVehicleParam(Vehicle pParam, float pValue) { VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue); switch (pParam) @@ -677,13 +677,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin private const int m_knownChangedWaterLevel = 1 << 9; private const int m_knownChangedForwardVelocity = 1 <<10; - private void ForgetKnownVehicleProperties() + public void ForgetKnownVehicleProperties() { m_knownHas = 0; m_knownChanged = 0; } // Push all the changed values back into the physics engine - private void PushKnownChanged() + public void PushKnownChanged() { if (m_knownChanged != 0) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 998836c..2b0a539 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -73,7 +73,7 @@ public sealed class BSPrim : BSPhysObject private bool _kinematic; private float _buoyancy; - private BSDynamics _vehicle; + public BSDynamics VehicleController { get; private set; } private BSVMotor _targetMotor; private OMV.Vector3 _PIDTarget; @@ -107,7 +107,7 @@ public sealed class BSPrim : BSPhysObject _friction = PhysicsScene.Params.defaultFriction; _restitution = PhysicsScene.Params.defaultRestitution; - _vehicle = new BSDynamics(PhysicsScene, this); // add vehicleness + VehicleController = new BSDynamics(PhysicsScene, this); // add vehicleness _mass = CalculateMass(); @@ -512,7 +512,7 @@ public sealed class BSPrim : BSPhysObject public override int VehicleType { get { - return (int)_vehicle.Type; // if we are a vehicle, return that type + return (int)VehicleController.Type; // if we are a vehicle, return that type } set { Vehicle type = (Vehicle)value; @@ -521,19 +521,19 @@ public sealed class BSPrim : BSPhysObject { // Done at taint time so we're sure the physics engine is not using the variables // Vehicle code changes the parameters for this vehicle type. - _vehicle.ProcessTypeChange(type); + VehicleController.ProcessTypeChange(type); ActivateIfPhysical(false); // If an active vehicle, register the vehicle code to be called before each step - if (_vehicle.Type == Vehicle.TYPE_NONE) + if (VehicleController.Type == Vehicle.TYPE_NONE) { UnRegisterPreStepAction("BSPrim.Vehicle", LocalID); - PhysicsScene.AfterStep -= _vehicle.PostStep; + PhysicsScene.AfterStep -= VehicleController.PostStep; } else { - RegisterPreStepAction("BSPrim.Vehicle", LocalID, _vehicle.Step); - PhysicsScene.AfterStep += _vehicle.PostStep; + RegisterPreStepAction("BSPrim.Vehicle", LocalID, VehicleController.Step); + PhysicsScene.AfterStep += VehicleController.PostStep; } }); } @@ -542,7 +542,7 @@ public sealed class BSPrim : BSPhysObject { PhysicsScene.TaintedObject("BSPrim.VehicleFloatParam", delegate() { - _vehicle.ProcessFloatVehicleParam((Vehicle)param, value); + VehicleController.ProcessFloatVehicleParam((Vehicle)param, value); ActivateIfPhysical(false); }); } @@ -550,7 +550,7 @@ public sealed class BSPrim : BSPhysObject { PhysicsScene.TaintedObject("BSPrim.VehicleVectorParam", delegate() { - _vehicle.ProcessVectorVehicleParam((Vehicle)param, value); + VehicleController.ProcessVectorVehicleParam((Vehicle)param, value); ActivateIfPhysical(false); }); } @@ -558,7 +558,7 @@ public sealed class BSPrim : BSPhysObject { PhysicsScene.TaintedObject("BSPrim.VehicleRotationParam", delegate() { - _vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation); + VehicleController.ProcessRotationVehicleParam((Vehicle)param, rotation); ActivateIfPhysical(false); }); } @@ -566,7 +566,7 @@ public sealed class BSPrim : BSPhysObject { PhysicsScene.TaintedObject("BSPrim.VehicleFlags", delegate() { - _vehicle.ProcessVehicleFlags(param, remove); + VehicleController.ProcessVehicleFlags(param, remove); }); } @@ -747,7 +747,7 @@ public sealed class BSPrim : BSPhysObject // isSolid: other objects bounce off of this object // isVolumeDetect: other objects pass through but can generate collisions // collisionEvents: whether this object returns collision events - private void UpdatePhysicalParameters() + public void UpdatePhysicalParameters() { // DetailLog("{0},BSPrim.UpdatePhysicalParameters,entry,body={1},shape={2}", LocalID, BSBody, BSShape); @@ -759,7 +759,7 @@ public sealed class BSPrim : BSPhysObject MakeDynamic(IsStatic); // Update vehicle specific parameters (after MakeDynamic() so can change physical parameters) - _vehicle.Refresh(); + VehicleController.Refresh(); // Arrange for collision events if the simulator wants them EnableCollisions(SubscribedEvents()); @@ -1601,7 +1601,7 @@ public sealed class BSPrim : BSPhysObject // Remove all the physical dependencies on the old body. // (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...) Linkset.RemoveBodyDependencies(this); - _vehicle.RemoveBodyDependencies(this); + VehicleController.RemoveBodyDependencies(this); }); // Make sure the properties are set on the new object @@ -1618,7 +1618,7 @@ public sealed class BSPrim : BSPhysObject { // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet // TODO: handle physics introduced by Bullet with computed vehicle physics. - if (_vehicle.IsActive) + if (VehicleController.IsActive) { entprop.RotationalVelocity = OMV.Vector3.Zero; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index b23be91..a4690ba 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -855,7 +855,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters { DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom); m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom); - Util.PrintCallStack(DetailLog); + // Util.PrintCallStack(DetailLog); } return InTaintTime; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs b/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs index 41ef67b..5900103 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs @@ -1,56 +1,127 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -using NUnit.Framework; -using log4net; - -using OpenSim.Tests.Common; - -namespace OpenSim.Region.Physics.BulletSPlugin.Tests -{ -[TestFixture] -public class BasicVehicles : OpenSimTestCase -{ - // Documentation on attributes: http://www.nunit.org/index.php?p=attributes&r=2.6.1 - // Documentation on assertions: http://www.nunit.org/index.php?p=assertions&r=2.6.1 - - [TestFixtureSetUp] - public void Init() - { - } - - [TestFixtureTearDown] - public void TearDown() - { - } -} +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using NUnit.Framework; +using log4net; + +using OpenSim.Framework; +using OpenSim.Region.Physics.BulletSPlugin; +using OpenSim.Region.Physics.Manager; +using OpenSim.Tests.Common; + +using OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSPlugin.Tests +{ +[TestFixture] +public class BasicVehicles : OpenSimTestCase +{ + // Documentation on attributes: http://www.nunit.org/index.php?p=attributes&r=2.6.1 + // Documentation on assertions: http://www.nunit.org/index.php?p=assertions&r=2.6.1 + + BSScene PhysicsScene { get; set; } + BSPrim TestVehicle { get; set; } + Vector3 TestVehicleInitPosition { get; set; } + float timeStep = 0.089f; + + [TestFixtureSetUp] + public void Init() + { + Dictionary engineParams = new Dictionary(); + PhysicsScene = BulletSimTestsUtil.CreateBasicPhysicsEngine(engineParams); + + PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateSphere(); + Vector3 pos = new Vector3(100.0f, 100.0f, 0f); + pos.Z = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos) + 2f; + TestVehicleInitPosition = pos; + Vector3 size = new Vector3(1f, 1f, 1f); + pbs.Scale = size; + Quaternion rot = Quaternion.Identity; + bool isPhys = false; + uint localID = 123; + + PhysicsScene.AddPrimShape("testPrim", pbs, pos, size, rot, isPhys, localID); + TestVehicle = (BSPrim)PhysicsScene.PhysObjects[localID]; + // The actual prim shape creation happens at taint time + PhysicsScene.ProcessTaints(); + + } + + [TestFixtureTearDown] + public void TearDown() + { + if (PhysicsScene != null) + { + // The Dispose() will also free any physical objects in the scene + PhysicsScene.Dispose(); + PhysicsScene = null; + } + } + + [TestCase(25, 0.25f, 0.25f, 0.25f)] + [TestCase(25, -0.25f, 0.25f, 0.25f)] + [TestCase(25, 0.25f, -0.25f, 0.25f)] + [TestCase(25, -0.25f, -0.25f, 0.25f)] + public void VerticalAttraction(int simSteps, float initRoll, float initPitch, float initYaw) + { + Quaternion initOrientation = Quaternion.CreateFromEulers(initRoll, initPitch, initYaw); + TestVehicle.Orientation = initOrientation; + + TestVehicle.Position = TestVehicleInitPosition; + + // The vehicle controller is not enabled directly (set a vehicle type). + // Instead the appropriate values are set and calls are made just the parts of the + // controller we want to exercise. Stepping the physics engine then applies + // the actions of that one feature. + TestVehicle.VehicleController.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_EFFICIENCY, 0.2f); + TestVehicle.VehicleController.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_TIMESCALE, 2f); + TestVehicle.VehicleController.enableAngularVerticalAttraction = true; + + TestVehicle.IsPhysical = true; + PhysicsScene.ProcessTaints(); + + // Step the simulator a bunch of times and and vertical attraction should orient the vehicle up + for (int ii = 0; ii < simSteps; ii++) + { + TestVehicle.VehicleController.ForgetKnownVehicleProperties(); + TestVehicle.VehicleController.ComputeAngularVerticalAttraction(); + TestVehicle.VehicleController.PushKnownChanged(); + + PhysicsScene.Simulate(timeStep); + } + + // After these steps, the vehicle should be upright + Vector3 upPointer = Vector3.UnitZ * TestVehicle.Orientation; + Assert.That(upPointer.Z, Is.GreaterThan(0.99f)); + } +} } \ No newline at end of file diff --git a/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs index e7657f9..215e92f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs @@ -47,7 +47,7 @@ public static class BulletSimTestsUtil public static BSScene CreateBasicPhysicsEngine(Dictionary paramOverrides) { IConfigSource openSimINI = new IniConfigSource(); - IConfig startupConfig = openSimINI.AddConfig("StartUp"); + IConfig startupConfig = openSimINI.AddConfig("Startup"); startupConfig.Set("physics", "BulletSim"); startupConfig.Set("meshing", "Meshmerizer"); startupConfig.Set("cacheSculptMaps", "false"); // meshmerizer shouldn't save maps -- cgit v1.1 From 47f09ed4c1d6a5d9763b6d1f5f86169e452281c8 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 28 Jan 2013 17:21:13 -0800 Subject: BulletSim: enable angular vertical attraction. Increase terrain collision margin to help vehicles from tunneling into same. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 4 ++-- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 05a0dcc..05ab180 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -141,12 +141,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin // in changes by making enablement of debugging flags from INI file. public void SetupVehicleDebugging() { - enableAngularVerticalAttraction = false; + enableAngularVerticalAttraction = true; enableAngularDeflection = false; enableAngularBanking = false; if (BSParam.VehicleDebuggingEnabled != ConfigurationParameters.numericFalse) { - enableAngularVerticalAttraction = false; + enableAngularVerticalAttraction = true; enableAngularDeflection = false; enableAngularBanking = false; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 4ece944..8c098b2 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -383,7 +383,7 @@ public static class BSParam (s) => { return TerrainRestitution; }, (s,p,l,v) => { TerrainRestitution = v; /* TODO: set on real terrain */ } ), new ParameterDefn("TerrainCollisionMargin", "Margin where collision checking starts" , - 0.04f, + 0.08f, (s,cf,p,v) => { TerrainCollisionMargin = cf.GetFloat(p, v); }, (s) => { return TerrainCollisionMargin; }, (s,p,l,v) => { TerrainCollisionMargin = v; /* TODO: set on real terrain */ } ), -- cgit v1.1 From ca26ff9436ab60a73ec1fbd6ab23b86f83a64e78 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 29 Jan 2013 03:58:11 +0000 Subject: minor: remove some mono compile warnings in XEngine.cs --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 2 -- 1 file changed, 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index d483219..8931be4 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -48,7 +48,6 @@ using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.ScriptEngine.Interfaces; using OpenSim.Region.ScriptEngine.Shared; -using OpenSim.Region.ScriptEngine.Shared.ScriptBase; using OpenSim.Region.ScriptEngine.Shared.CodeTools; using OpenSim.Region.ScriptEngine.Shared.Instance; using OpenSim.Region.ScriptEngine.Shared.Api; @@ -630,7 +629,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine } StringBuilder sb = new StringBuilder(); - Queue eq = instance.EventQueue; sb.AppendFormat("Script name : {0}\n", instance.ScriptName); sb.AppendFormat("Status : {0}\n", status); -- cgit v1.1 From fd34a75cdec2ad31595722bc726baecc6d071356 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 29 Jan 2013 04:03:33 +0000 Subject: minor: Tidy up disabled logging on AssetTransactionModule for future use. Make it clear that transaction parameter to HandleUDPUploadRequest is an ID. --- .../Agent/AssetTransaction/AssetTransactionModule.cs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs index e973652..d1ad74f 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs @@ -214,9 +214,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction public void HandleTaskItemUpdateFromTransaction( IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item) { - m_log.DebugFormat( - "[ASSET TRANSACTION MODULE] Called HandleTaskItemUpdateFromTransaction with item {0} in {1} for {2} in {3}", - item.Name, part.Name, remoteClient.Name, m_Scene.RegionInfo.RegionName); +// m_log.DebugFormat( +// "[ASSET TRANSACTION MODULE]: Called HandleTaskItemUpdateFromTransaction with item {0} in {1} for {2} in {3}", +// item.Name, part.Name, remoteClient.Name, m_Scene.RegionInfo.RegionName); AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); @@ -230,15 +230,17 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction /// /// /// - /// + /// /// /// /// public void HandleUDPUploadRequest(IClientAPI remoteClient, - UUID assetID, UUID transaction, sbyte type, byte[] data, + UUID assetID, UUID transactionID, sbyte type, byte[] data, bool storeLocal, bool tempFile) { -// m_log.Debug("HandleUDPUploadRequest - assetID: " + assetID.ToString() + " transaction: " + transaction.ToString() + " type: " + type.ToString() + " storelocal: " + storeLocal + " tempFile: " + tempFile); +// m_log.DebugFormat( +// "[ASSET TRANSACTION MODULE]: HandleUDPUploadRequest - assetID: {0}, transaction {1}, type {2}, storeLocal {3}, tempFile {4}, data.Length {5}", +// assetID, transactionID, type, storeLocal, tempFile, data.Length); if (((AssetType)type == AssetType.Texture || (AssetType)type == AssetType.Sound || @@ -274,8 +276,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction } AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); - AssetXferUploader uploader = transactions.RequestXferUploader(transaction); - uploader.StartUpload(remoteClient, assetID, transaction, type, data, storeLocal, tempFile); + AssetXferUploader uploader = transactions.RequestXferUploader(transactionID); + uploader.StartUpload(remoteClient, assetID, transactionID, type, data, storeLocal, tempFile); } /// -- cgit v1.1 From e0f4e91d224c7a3f478a1bdea3d563ce97bb07c0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 29 Jan 2013 04:26:26 +0000 Subject: Try ignoring json tests if they can't be run due to being on <=.net 3.5 --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 23 ++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 397dd93..5b2931e 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -59,8 +59,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests { base.SetUp(); - TestHelpers.EnableLogging(); - IConfigSource configSource = new IniConfigSource(); IConfig jsonStoreConfig = configSource.AddConfig("JsonStore"); jsonStoreConfig.Set("Enabled", "true"); @@ -72,9 +70,20 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests m_scene = new SceneHelpers().SetupScene(); SceneHelpers.SetupSceneModules(m_scene, configSource, m_engine, m_smcm, jsm, jssm); + + try + { + m_smcm.RegisterScriptInvocation(this, "DummyTestMethod"); + } + catch (ArgumentException) + { + Assert.Ignore("Ignoring test since running on .NET 3.5 or earlier."); + } + + // XXX: Unfortunately, ICommsModule currently has no way of deregistering methods. } -// [Test] + [Test] public void TestJsonCreateStore() { TestHelpers.InMethod(); @@ -85,7 +94,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests Assert.That(storeId, Is.Not.EqualTo(UUID.Zero)); } -// [Test] + [Test] public void TestJsonGetValue() { TestHelpers.InMethod(); @@ -102,7 +111,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests Assert.That(value, Is.EqualTo("World")); } -// [Test] + [Test] public void TestJsonTestPath() { TestHelpers.InMethod(); @@ -119,7 +128,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests Assert.That(result, Is.EqualTo(1)); } -// [Test] + [Test] public void TestJsonSetValue() { TestHelpers.InMethod(); @@ -141,5 +150,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests Assert.That(value, Is.EqualTo("World")); } + + public object DummyTestMethod(object o1, object o2, object o3, object o4, object o5) { return null; } } } \ No newline at end of file -- cgit v1.1 From ccdf86c73719fa17557ac9a6bd1db657796b12ba Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 29 Jan 2013 04:35:05 +0000 Subject: minor: remove EnableLogging() left over in CoopTerminationTests --- .../Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs index 3b13386..2c80826 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs @@ -245,7 +245,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests public void TestStopOnInfiniteJumpLoop() { TestHelpers.InMethod(); - TestHelpers.EnableLogging(); +// TestHelpers.EnableLogging(); string script = @"default -- cgit v1.1 From 39700445f257108305f576c7af67623cc145906c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 29 Jan 2013 04:36:41 +0000 Subject: minor: change name of json script tests to JsonStoreScriptModuleTests instead of copy/pasted LSL_ApiInventoryTests --- .../Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 5b2931e..9f91728 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -48,7 +48,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests /// Tests for inventory functions in LSL /// [TestFixture] - public class LSL_ApiInventoryTests : OpenSimTestCase + public class JsonStoreScriptModuleTests : OpenSimTestCase { private Scene m_scene; private MockScriptEngine m_engine; -- cgit v1.1 From a61ecee227450ea81c9afe85a62b207fefa888a9 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 29 Jan 2013 17:01:27 -0800 Subject: BulletSim: fix physics repositioning when under ground to only happen for physical objects. Non-physical objects can go anywhere they want. --- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 6 ++- .../Physics/BulletSPlugin/Tests/BasicVehicles.cs | 45 ++++++++++++++++------ .../BulletSPlugin/Tests/BulletSimTestsUtil.cs | 14 +++++-- 3 files changed, 50 insertions(+), 15 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 2b0a539..b5dd131 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -344,6 +344,10 @@ public sealed class BSPrim : BSPhysObject { bool ret = false; + // We don't care where non-physical items are placed + if (!IsPhysicallyActive) + return ret; + if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition)) { // The physical object is out of the known/simulated area. @@ -1643,7 +1647,7 @@ public sealed class BSPrim : BSPhysObject // DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG // The sanity check can change the velocity and/or position. - if (IsPhysical && PositionSanityCheck(true /* inTaintTime */ )) + if (PositionSanityCheck(true /* inTaintTime */ )) { entprop.Position = _position; entprop.Velocity = _velocity; diff --git a/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs b/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs index 5900103..33232bd 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs @@ -51,7 +51,7 @@ public class BasicVehicles : OpenSimTestCase BSScene PhysicsScene { get; set; } BSPrim TestVehicle { get; set; } Vector3 TestVehicleInitPosition { get; set; } - float timeStep = 0.089f; + float simulationTimeStep = 0.089f; [TestFixtureSetUp] public void Init() @@ -87,39 +87,62 @@ public class BasicVehicles : OpenSimTestCase } } - [TestCase(25, 0.25f, 0.25f, 0.25f)] - [TestCase(25, -0.25f, 0.25f, 0.25f)] - [TestCase(25, 0.25f, -0.25f, 0.25f)] - [TestCase(25, -0.25f, -0.25f, 0.25f)] - public void VerticalAttraction(int simSteps, float initRoll, float initPitch, float initYaw) + [TestCase(2f, 0.2f, 0.25f, 0.25f, 0.25f)] + [TestCase(2f, 0.2f, -0.25f, 0.25f, 0.25f)] + [TestCase(2f, 0.2f, 0.25f, -0.25f, 0.25f)] + [TestCase(2f, 0.2f, -0.25f, -0.25f, 0.25f)] + // [TestCase(2f, 0.2f, 0.785f, 0.0f, 0.25f) /*, "Leaning 45 degrees to the side" */] + // [TestCase(2f, 0.2f, 1.650f, 0.0f, 0.25f) /*, "Leaning more than 90 degrees to the side" */] + // [TestCase(2f, 0.2f, 2.750f, 0.0f, 0.25f) /*, "Almost upside down, tipped right" */] + // [TestCase(2f, 0.2f,-2.750f, 0.0f, 0.25f) /*, "Almost upside down, tipped left" */] + // [TestCase(2f, 0.2f, 0.0f, 0.785f, 0.25f) /*, "Tipped back 45 degrees" */] + // [TestCase(2f, 0.2f, 0.0f, 1.650f, 0.25f) /*, "Tipped back more than 90 degrees" */] + // [TestCase(2f, 0.2f, 0.0f, 2.750f, 0.25f) /*, "Almost upside down, tipped back" */] + // [TestCase(2f, 0.2f, 0.0f,-2.750f, 0.25f) /*, "Almost upside down, tipped forward" */] + public void AngularVerticalAttraction(float timeScale, float efficiency, float initRoll, float initPitch, float initYaw) { + // Enough simulation steps to cover the timescale the operation should take + int simSteps = (int)(timeScale / simulationTimeStep) + 1; + + // Tip the vehicle Quaternion initOrientation = Quaternion.CreateFromEulers(initRoll, initPitch, initYaw); TestVehicle.Orientation = initOrientation; TestVehicle.Position = TestVehicleInitPosition; - // The vehicle controller is not enabled directly (set a vehicle type). + // The vehicle controller is not enabled directly (by setting a vehicle type). // Instead the appropriate values are set and calls are made just the parts of the // controller we want to exercise. Stepping the physics engine then applies // the actions of that one feature. - TestVehicle.VehicleController.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_EFFICIENCY, 0.2f); - TestVehicle.VehicleController.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_TIMESCALE, 2f); + TestVehicle.VehicleController.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_EFFICIENCY, efficiency); + TestVehicle.VehicleController.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_TIMESCALE, timeScale); TestVehicle.VehicleController.enableAngularVerticalAttraction = true; TestVehicle.IsPhysical = true; PhysicsScene.ProcessTaints(); - // Step the simulator a bunch of times and and vertical attraction should orient the vehicle up + // Step the simulator a bunch of times and vertical attraction should orient the vehicle up for (int ii = 0; ii < simSteps; ii++) { TestVehicle.VehicleController.ForgetKnownVehicleProperties(); TestVehicle.VehicleController.ComputeAngularVerticalAttraction(); TestVehicle.VehicleController.PushKnownChanged(); - PhysicsScene.Simulate(timeStep); + PhysicsScene.Simulate(simulationTimeStep); } + TestVehicle.IsPhysical = false; + PhysicsScene.ProcessTaints(); + // After these steps, the vehicle should be upright + /* + float finalRoll, finalPitch, finalYaw; + TestVehicle.Orientation.GetEulerAngles(out finalRoll, out finalPitch, out finalYaw); + Assert.That(finalRoll, Is.InRange(-0.01f, 0.01f)); + Assert.That(finalPitch, Is.InRange(-0.01f, 0.01f)); + Assert.That(finalYaw, Is.InRange(initYaw - 0.1f, initYaw + 0.1f)); + */ + Vector3 upPointer = Vector3.UnitZ * TestVehicle.Orientation; Assert.That(upPointer.Z, Is.GreaterThan(0.99f)); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs index 215e92f..28207a4 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs @@ -26,6 +26,7 @@ */ using System; +using System.IO; using System.Collections.Generic; using System.Linq; using System.Text; @@ -65,9 +66,16 @@ public static class BulletSimTestsUtil bulletSimConfig.Set(kvp.Key, kvp.Value); } } - // bulletSimConfig.Set("PhysicsLoggingEnabled","True"); - // bulletSimConfig.Set("PhysicsLoggingDoFlush","True"); - // bulletSimConfig.Set("VehicleLoggingEnabled","True"); + + // If a special directory exists, put detailed logging therein. + // This allows local testing/debugging without having to worry that the build engine will output logs. + if (Directory.Exists("physlogs")) + { + bulletSimConfig.Set("PhysicsLoggingDir","./physlogs"); + bulletSimConfig.Set("PhysicsLoggingEnabled","True"); + bulletSimConfig.Set("PhysicsLoggingDoFlush","True"); + bulletSimConfig.Set("VehicleLoggingEnabled","True"); + } BSPlugin bsPlugin = new BSPlugin(); -- cgit v1.1 From 5ac84a37935d8e1c62484032259d09f5ac95c0e7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 30 Jan 2013 03:44:56 +0000 Subject: Fix issue where lsl -> c# generation in co-operative termination mode did not correctly handle single statement versions of for, while and do-while loops. Add regression tests to validate the fix. This problem will not affect the default abort termination mode. --- .../Shared/CodeTools/CSCodeGenerator.cs | 30 ++-- .../Shared/Instance/Tests/CoopTerminationTests.cs | 163 +++++++++++++++++++-- 2 files changed, 171 insertions(+), 22 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs index 985e598..9e32f40 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs @@ -31,7 +31,6 @@ using System.Collections.Generic; using System.Reflection; using log4net; using Tools; - using OpenSim.Region.Framework.Interfaces; namespace OpenSim.Region.ScriptEngine.Shared.CodeTools @@ -479,20 +478,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools { string retstr = String.Empty; bool printSemicolon = true; - - retstr += Indent(); + bool transformToBlock = false; if (m_insertCoopTerminationChecks) { - // We have to check in event functions as well because the user can manually call these. - if (previousSymbol is GlobalFunctionDefinition - || previousSymbol is WhileStatement + // A non-braced single line do while structure cannot contain multiple statements. + // So to insert the termination check we change this to a braced control structure instead. + if (previousSymbol is WhileStatement || previousSymbol is DoWhileStatement - || previousSymbol is ForLoop - || previousSymbol is StateEvent) - retstr += Generate(m_coopTerminationCheck); + || previousSymbol is ForLoop) + { + transformToBlock = true; + + // FIXME: This will be wrongly indented because the previous for/while/dowhile will have already indented. + retstr += GenerateIndentedLine("{"); + + retstr += GenerateIndentedLine(m_coopTerminationCheck); + } } + retstr += Indent(); + if (0 < s.kids.Count) { // Jump label prints its own colon, we don't need a semicolon. @@ -508,6 +514,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools if (printSemicolon) retstr += GenerateLine(";"); + if (transformToBlock) + { + // FIXME: This will be wrongly indented because the for/while/dowhile is currently handling the unindent + retstr += GenerateIndentedLine("}"); + } + return retstr; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs index 2c80826..7ea30bf1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs @@ -55,10 +55,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests private OSChatMessage m_osChatMessageReceived; + /// + /// Number of chat messages received so far. Reset before each test. + /// + private int m_chatMessagesReceived; + + /// + /// Number of chat messages expected. m_chatEvent is not fired until this number is reached or exceeded. + /// + private int m_chatMessagesThreshold; + [SetUp] public void Init() { m_osChatMessageReceived = null; + m_chatMessagesReceived = 0; + m_chatMessagesThreshold = 0; m_chatEvent = new AutoResetEvent(false); m_stoppedEvent = new AutoResetEvent(false); @@ -126,6 +138,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests } [Test] + public void TestNoStopOnSingleStatementForLoop() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + string script = +@"default +{ + state_entry() + { + integer i = 0; + for (i = 0; i <= 1; i++) llSay(0, ""Iter "" + (string)i); + } +}"; + + TestSingleStatementNoStop(script); + } + + [Test] public void TestStopOnLongSingleStatementForLoop() { TestHelpers.InMethod(); @@ -139,8 +170,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests integer i = 0; llSay(0, ""Thin Lizzy""); - for (i = 0; i < 2147483647; i++) - llSay(0, ""Iter "" + (string)i); + for (i = 0; i < 2147483647; i++) llSay(0, ""Iter "" + (string)i); } }"; @@ -172,6 +202,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests } [Test] + public void TestNoStopOnSingleStatementWhileLoop() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + string script = +@"default +{ + state_entry() + { + integer i = 0; + while (i < 2) llSay(0, ""Iter "" + (string)i++); + } +}"; + + TestSingleStatementNoStop(script); + } + + [Test] public void TestStopOnLongSingleStatementWhileLoop() { TestHelpers.InMethod(); @@ -218,7 +267,50 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests } [Test] - public void TestStopOnLongDoWhileLoop() + public void TestNoStopOnSingleStatementDoWhileLoop() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + string script = +@"default +{ + state_entry() + { + integer i = 0; + + do llSay(0, ""Iter "" + (string)i++); + while (i < 2); + } +}"; + + TestSingleStatementNoStop(script); + } + + [Test] + public void TestStopOnLongSingleStatementDoWhileLoop() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + string script = +@"default +{ + state_entry() + { + integer i = 0; + llSay(0, ""Thin Lizzy""); + + do llSay(0, ""Iter "" + (string)i++); + while (1 == 1); + } +}"; + + TestStop(script); + } + + [Test] + public void TestStopOnLongCompoundStatementDoWhileLoop() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); @@ -234,7 +326,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests do { llSay(0, ""Iter "" + (string)i++); -} while (1 == 1); + } while (1 == 1); } }"; @@ -320,14 +412,13 @@ default TestStop(script); } - private void TestStop(string script) + private SceneObjectPart CreateScript(string script, string itemName, UUID userId) { - UUID userId = TestHelpers.ParseTail(0x1); // UUID objectId = TestHelpers.ParseTail(0x100); // UUID itemId = TestHelpers.ParseTail(0x3); - string itemName = "TestStop() Item"; - SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, "TestStop", 0x100); + SceneObjectGroup so + = SceneHelpers.CreateSceneObject(1, userId, string.Format("Object for {0}", itemName), 0x100); m_scene.AddNewSceneObject(so, true); InventoryItemBase itemTemplate = new InventoryItemBase(); @@ -338,14 +429,57 @@ default m_scene.EventManager.OnChatFromWorld += OnChatFromWorld; - SceneObjectPart partWhereRezzed = m_scene.RezNewScript(userId, itemTemplate, script); + return m_scene.RezNewScript(userId, itemTemplate, script); + } + + private void TestSingleStatementNoStop(string script) + { + // In these tests we expect to see at least 2 chat messages to confirm that the loop is working properly. + m_chatMessagesThreshold = 2; + UUID userId = TestHelpers.ParseTail(0x1); +// UUID objectId = TestHelpers.ParseTail(0x100); +// UUID itemId = TestHelpers.ParseTail(0x3); + string itemName = "TestNoStop"; + + SceneObjectPart partWhereRezzed = CreateScript(script, itemName, userId); TaskInventoryItem rezzedItem = partWhereRezzed.Inventory.GetInventoryItem(itemName); // Wait for the script to start the event before we try stopping it. m_chatEvent.WaitOne(60000); - Console.WriteLine("Script started with message [{0}]", m_osChatMessageReceived.Message); + if (m_osChatMessageReceived == null) + Assert.Fail("Script did not start"); + else + Assert.That(m_chatMessagesReceived, Is.EqualTo(2)); + + bool running; + TaskInventoryItem scriptItem = partWhereRezzed.Inventory.GetInventoryItem(itemName); + Assert.That( + SceneObjectPartInventory.TryGetScriptInstanceRunning(m_scene, scriptItem, out running), Is.True); + Assert.That(running, Is.True); + } + + private void TestStop(string script) + { + // In these tests we're only interested in the first message to confirm that the script has started. + m_chatMessagesThreshold = 1; + + UUID userId = TestHelpers.ParseTail(0x1); +// UUID objectId = TestHelpers.ParseTail(0x100); +// UUID itemId = TestHelpers.ParseTail(0x3); + string itemName = "TestStop"; + + SceneObjectPart partWhereRezzed = CreateScript(script, itemName, userId); + TaskInventoryItem rezzedItem = partWhereRezzed.Inventory.GetInventoryItem(itemName); + + // Wait for the script to start the event before we try stopping it. + m_chatEvent.WaitOne(60000); + + if (m_osChatMessageReceived != null) + Console.WriteLine("Script started with message [{0}]", m_osChatMessageReceived.Message); + else + Assert.Fail("Script did not start"); // FIXME: This is a very poor way of trying to avoid a low-probability race condition where the script // executes llSay() but has not started the next statement before we try to stop it. @@ -367,11 +501,14 @@ default private void OnChatFromWorld(object sender, OSChatMessage oscm) { - m_scene.EventManager.OnChatFromWorld -= OnChatFromWorld; Console.WriteLine("Got chat [{0}]", oscm.Message); - m_osChatMessageReceived = oscm; - m_chatEvent.Set(); + + if (++m_chatMessagesReceived >= m_chatMessagesThreshold) + { + m_scene.EventManager.OnChatFromWorld -= OnChatFromWorld; + m_chatEvent.Set(); + } } } } \ No newline at end of file -- cgit v1.1 From addf9ada49f35a40f8739d0614c1d48fbbb82ec1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 30 Jan 2013 05:39:34 +0000 Subject: Add regression test for script func JsonRemoveValue() --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 52 ++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 9f91728..d209551 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -111,6 +111,58 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests Assert.That(value, Is.EqualTo("World")); } +// [Test] +// public void TestJsonTakeValue() +// { +// TestHelpers.InMethod(); +//// TestHelpers.EnableLogging(); +// +// UUID storeId +// = (UUID)m_smcm.InvokeOperation( +// UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{ 'Hello' : 'World' }" }); +// +// string value +// = (string)m_smcm.InvokeOperation( +// UUID.Zero, UUID.Zero, "JsonTakeValue", new object[] { storeId, "Hello" }); +// +// Assert.That(value, Is.EqualTo("World")); +// +// string value2 +// = (string)m_smcm.InvokeOperation( +// UUID.Zero, UUID.Zero, "JsonGetValue", new object[] { storeId, "Hello" }); +// +// Assert.That(value, Is.Null); +// } + + [Test] + public void TestJsonRemoveValue() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID storeId + = (UUID)m_smcm.InvokeOperation( + UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{ 'Hello' : 'World' }" }); + + int returnValue + = (int)m_smcm.InvokeOperation( + UUID.Zero, UUID.Zero, "JsonRemoveValue", new object[] { storeId, "Hello" }); + + Assert.That(returnValue, Is.EqualTo(1)); + + int result + = (int)m_smcm.InvokeOperation( + UUID.Zero, UUID.Zero, "JsonTestPath", new object[] { storeId, "Hello" }); + + Assert.That(result, Is.EqualTo(0)); + + string returnValue2 + = (string)m_smcm.InvokeOperation( + UUID.Zero, UUID.Zero, "JsonGetValue", new object[] { storeId, "Hello" }); + + Assert.That(returnValue2, Is.EqualTo("")); + } + [Test] public void TestJsonTestPath() { -- cgit v1.1 From 5a22efe69cb75972d2fa9446d8b98734af7c653a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 30 Jan 2013 05:49:28 +0000 Subject: refactor: Make invocations of json store functions from the regression test simpler --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 59 +++++++--------------- 1 file changed, 17 insertions(+), 42 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index d209551..297d7c1 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -83,14 +83,18 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests // XXX: Unfortunately, ICommsModule currently has no way of deregistering methods. } + private object InvokeOp(string name, params object[] args) + { + return m_smcm.InvokeOperation(UUID.Zero, UUID.Zero, name, args); + } + [Test] public void TestJsonCreateStore() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); - UUID storeId = (UUID)m_smcm.InvokeOperation(UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{}" }); - + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); Assert.That(storeId, Is.Not.EqualTo(UUID.Zero)); } @@ -100,14 +104,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests TestHelpers.InMethod(); // TestHelpers.EnableLogging(); - UUID storeId - = (UUID)m_smcm.InvokeOperation( - UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{ 'Hello' : 'World' }" }); - - string value - = (string)m_smcm.InvokeOperation( - UUID.Zero, UUID.Zero, "JsonGetValue", new object[] { storeId, "Hello" }); + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }"); + string value = (string)InvokeOp("JsonGetValue", storeId, "Hello"); Assert.That(value, Is.EqualTo("World")); } @@ -140,26 +139,15 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests TestHelpers.InMethod(); // TestHelpers.EnableLogging(); - UUID storeId - = (UUID)m_smcm.InvokeOperation( - UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{ 'Hello' : 'World' }" }); - - int returnValue - = (int)m_smcm.InvokeOperation( - UUID.Zero, UUID.Zero, "JsonRemoveValue", new object[] { storeId, "Hello" }); + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }"); + int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello"); Assert.That(returnValue, Is.EqualTo(1)); - int result - = (int)m_smcm.InvokeOperation( - UUID.Zero, UUID.Zero, "JsonTestPath", new object[] { storeId, "Hello" }); - + int result = (int)InvokeOp("JsonTestPath", storeId, "Hello"); Assert.That(result, Is.EqualTo(0)); - string returnValue2 - = (string)m_smcm.InvokeOperation( - UUID.Zero, UUID.Zero, "JsonGetValue", new object[] { storeId, "Hello" }); - + string returnValue2 = (string)InvokeOp("JsonGetValue", storeId, "Hello"); Assert.That(returnValue2, Is.EqualTo("")); } @@ -169,14 +157,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests TestHelpers.InMethod(); // TestHelpers.EnableLogging(); - UUID storeId - = (UUID)m_smcm.InvokeOperation( - UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{ 'Hello' : 'World' }" }); - - int result - = (int)m_smcm.InvokeOperation( - UUID.Zero, UUID.Zero, "JsonTestPath", new object[] { storeId, "Hello" }); + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }"); + int result = (int)InvokeOp("JsonTestPath", storeId, "Hello"); Assert.That(result, Is.EqualTo(1)); } @@ -186,20 +169,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests TestHelpers.InMethod(); // TestHelpers.EnableLogging(); - UUID storeId - = (UUID)m_smcm.InvokeOperation( - UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{ }" }); - - int result - = (int)m_smcm.InvokeOperation( - UUID.Zero, UUID.Zero, "JsonSetValue", new object[] { storeId, "Hello", "World" }); + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + int result = (int)InvokeOp("JsonSetValue", storeId, "Hello", "World"); Assert.That(result, Is.EqualTo(1)); - string value - = (string)m_smcm.InvokeOperation( - UUID.Zero, UUID.Zero, "JsonGetValue", new object[] { storeId, "Hello" }); - + string value = (string)InvokeOp("JsonGetValue", storeId, "Hello"); Assert.That(value, Is.EqualTo("World")); } -- cgit v1.1 From d42c7afe3fc5d226dffea3bb50e4e2963eb96f3b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 30 Jan 2013 05:56:30 +0000 Subject: Add JsonDestroyStore() basic regression test --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 297d7c1..8042a93 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -99,6 +99,21 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests } [Test] + public void TestJsonDestroyStore() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }"); + int dsrv = (int)InvokeOp("JsonDestroyStore", storeId); + + Assert.That(dsrv, Is.EqualTo(1)); + + int tprv = (int)InvokeOp("JsonTestPath", storeId, "Hello"); + Assert.That(tprv, Is.EqualTo(0)); + } + + [Test] public void TestJsonGetValue() { TestHelpers.InMethod(); -- cgit v1.1 From 7c4e0ff03c5ba9331feb777247594e94fc0f7ac1 Mon Sep 17 00:00:00 2001 From: teravus Date: Wed, 30 Jan 2013 06:22:05 -0500 Subject: * Adds a satisfying angular roll when an avatar is flying and turning. (General, not physics). Makes flying not feel as stiff. --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 2 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 81 ++++++++++++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 0ccd69a..88b64f5 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -4893,7 +4893,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // may improve movement smoothness. // acceleration = new Vector3(1, 0, 0); - angularVelocity = Vector3.Zero; + angularVelocity = presence.AngularVelocity; rotation = presence.Rotation; if (sendTexture) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index a90872e..1d22560 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -200,6 +200,11 @@ namespace OpenSim.Region.Framework.Scenes private const int LAND_VELOCITYMAG_MAX = 12; + private const float FLY_ROLL_MAX_RADIANS = 1.1f; + + private const float FLY_ROLL_RADIANS_PER_SECOND = 0.06f; + private const float FLY_ROLL_RESET_RADIANS_PER_SECOND = 0.02f; + private float m_health = 100f; protected ulong crossingFromRegion; @@ -568,6 +573,14 @@ namespace OpenSim.Region.Framework.Scenes } } + // Used for limited viewer 'fake' user rotations. + private Vector3 m_AngularVelocity = Vector3.Zero; + + public Vector3 AngularVelocity + { + get { return m_AngularVelocity; } + } + public bool IsChildAgent { get; set; } /// @@ -690,6 +703,8 @@ namespace OpenSim.Region.Framework.Scenes #endregion + + #region Constructor(s) public ScenePresence( @@ -1033,6 +1048,49 @@ namespace OpenSim.Region.Framework.Scenes ControllingClient.StopFlying(this); } + /// + /// Applies a roll accumulator to the avatar's angular velocity for the avatar fly roll effect. + /// + /// Postive or negative roll amount in radians + private void ApplyFlyingRoll(float amount) + { + float noise = ((float)(Util.RandomClass.NextDouble()*0.2f)-0.1f); + float rollAmount = Util.Clamp(m_AngularVelocity.Z + amount, -FLY_ROLL_MAX_RADIANS, FLY_ROLL_MAX_RADIANS) + noise; + m_AngularVelocity.Z = rollAmount; + } + + /// + /// incrementally sets roll amount to zero + /// + /// Positive roll amount in radians + /// + private float CalculateFlyingRollResetToZero(float amount) + { + const float rollMinRadians = 0f; + + if (m_AngularVelocity.Z > 0) + { + + float leftOverToMin = m_AngularVelocity.Z - rollMinRadians; + if (amount > leftOverToMin) + return -leftOverToMin; + else + return -amount; + + } + else + { + + float leftOverToMin = -m_AngularVelocity.Z - rollMinRadians; + if (amount > leftOverToMin) + return leftOverToMin; + else + return amount; + } + } + + + // neighbouring regions we have enabled a child agent in // holds the seed cap for the child agent in that region private Dictionary m_knownChildRegions = new Dictionary(); @@ -1513,6 +1571,29 @@ namespace OpenSim.Region.Framework.Scenes bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); + + + // Applies a satisfying roll effect to the avatar when flying. + if (((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) != 0) && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0)) + { + ApplyFlyingRoll(FLY_ROLL_RADIANS_PER_SECOND); + + } + else if (((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) != 0) && + ((flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)) + { + ApplyFlyingRoll(-FLY_ROLL_RADIANS_PER_SECOND); + + } + else + { + if (m_AngularVelocity.Z != 0) + m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_SECOND); + + } + + + if (Flying && IsColliding && controlland) { // nesting this check because LengthSquared() is expensive and we don't -- cgit v1.1 From 52ea6eadaed5e5d2d43807999e6bb805c60056fd Mon Sep 17 00:00:00 2001 From: teravus Date: Wed, 30 Jan 2013 07:34:48 -0500 Subject: * This adds a bit more to the previous flying roll effect by adding additional roll when pressing page down, and reducing your roll when pressing page up to make it feel more responsive and give the user more visual feedback. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 60 ++++++++++++++++++++---- 1 file changed, 50 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 1d22560..e0dfb34 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -202,8 +202,8 @@ namespace OpenSim.Region.Framework.Scenes private const float FLY_ROLL_MAX_RADIANS = 1.1f; - private const float FLY_ROLL_RADIANS_PER_SECOND = 0.06f; - private const float FLY_ROLL_RESET_RADIANS_PER_SECOND = 0.02f; + private const float FLY_ROLL_RADIANS_PER_UPDATE = 0.06f; + private const float FLY_ROLL_RESET_RADIANS_PER_UPDATE = 0.02f; private float m_health = 100f; @@ -1052,11 +1052,47 @@ namespace OpenSim.Region.Framework.Scenes /// Applies a roll accumulator to the avatar's angular velocity for the avatar fly roll effect. /// /// Postive or negative roll amount in radians - private void ApplyFlyingRoll(float amount) + private void ApplyFlyingRoll(float amount, bool PressingUp, bool PressingDown) { - float noise = ((float)(Util.RandomClass.NextDouble()*0.2f)-0.1f); - float rollAmount = Util.Clamp(m_AngularVelocity.Z + amount, -FLY_ROLL_MAX_RADIANS, FLY_ROLL_MAX_RADIANS) + noise; + + float rollAmount = Util.Clamp(m_AngularVelocity.Z + amount, -FLY_ROLL_MAX_RADIANS, FLY_ROLL_MAX_RADIANS); m_AngularVelocity.Z = rollAmount; + + // APPLY EXTRA consideration for flying up and flying down during this time. + // if we're turning left + if (amount > 0) + { + + // If we're at the max roll and pressing up, we want to swing BACK a bit + // Automatically adds noise + if (PressingUp) + { + if (m_AngularVelocity.Z >= FLY_ROLL_MAX_RADIANS - 0.04f) + m_AngularVelocity.Z -= 0.9f; + } + // If we're at the max roll and pressing down, we want to swing MORE a bit + if (PressingDown) + { + if (m_AngularVelocity.Z >= FLY_ROLL_MAX_RADIANS && m_AngularVelocity.Z < FLY_ROLL_MAX_RADIANS + 0.6f) + m_AngularVelocity.Z += 0.6f; + } + } + else // we're turning right. + { + // If we're at the max roll and pressing up, we want to swing BACK a bit + // Automatically adds noise + if (PressingUp) + { + if (m_AngularVelocity.Z <= (-FLY_ROLL_MAX_RADIANS)) + m_AngularVelocity.Z += 0.6f; + } + // If we're at the max roll and pressing down, we want to swing MORE a bit + if (PressingDown) + { + if (m_AngularVelocity.Z >= -FLY_ROLL_MAX_RADIANS - 0.6f) + m_AngularVelocity.Z -= 0.6f; + } + } } /// @@ -1572,26 +1608,30 @@ namespace OpenSim.Region.Framework.Scenes ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); - + //m_log.Debug("[CONTROL]: " +flags); // Applies a satisfying roll effect to the avatar when flying. if (((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) != 0) && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0)) { - ApplyFlyingRoll(FLY_ROLL_RADIANS_PER_SECOND); + + ApplyFlyingRoll(FLY_ROLL_RADIANS_PER_UPDATE, ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0), ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0)); + } else if (((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) != 0) && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)) { - ApplyFlyingRoll(-FLY_ROLL_RADIANS_PER_SECOND); + ApplyFlyingRoll(-FLY_ROLL_RADIANS_PER_UPDATE, ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0), ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0)); + } else { if (m_AngularVelocity.Z != 0) - m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_SECOND); + m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_UPDATE); } - + + if (Flying && IsColliding && controlland) -- cgit v1.1 From a0ef3df1941147cfc894493950e4d204f6b34216 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Wed, 30 Jan 2013 14:45:03 -0800 Subject: Add JsonTestStore to determine if a JsonStore is associated with a particular UUID. --- OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs | 1 + .../OptionalModules/Scripting/JsonStore/JsonStoreModule.cs | 13 +++++++++++++ .../Scripting/JsonStore/JsonStoreScriptModule.cs | 11 +++++++++++ 3 files changed, 25 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs index da39e95..0bb4567 100644 --- a/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs @@ -37,6 +37,7 @@ namespace OpenSim.Region.Framework.Interfaces { bool CreateStore(string value, ref UUID result); bool DestroyStore(UUID storeID); + bool TestStore(UUID storeID); bool TestPath(UUID storeID, string path, bool useJson); bool SetValue(UUID storeID, string path, string value, bool useJson); bool RemoveValue(UUID storeID, string path); diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs index e68764a..b9b3ebc 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs @@ -221,6 +221,19 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- + public bool TestStore(UUID storeID) + { + if (! m_enabled) return false; + + lock (m_JsonValueStore) + return m_JsonValueStore.ContainsKey(storeID); + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- public bool TestPath(UUID storeID, string path, bool useJson) { if (! m_enabled) return false; diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index b9dcfea..29955af 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs @@ -167,6 +167,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore { m_comms.RegisterScriptInvocation(this, "JsonCreateStore"); m_comms.RegisterScriptInvocation(this, "JsonDestroyStore"); + m_comms.RegisterScriptInvocation(this, "JsonTestStore"); m_comms.RegisterScriptInvocation(this, "JsonReadNotecard"); m_comms.RegisterScriptInvocation(this, "JsonWriteNotecard"); @@ -248,6 +249,16 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- + protected int JsonTestStore(UUID hostID, UUID scriptID, UUID storeID) + { + return m_store.TestStore(storeID) ? 1 : 0; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- protected UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, UUID assetID) { UUID reqID = UUID.Random(); -- cgit v1.1 From fac72d540b029ba72195dca69c56034167835d60 Mon Sep 17 00:00:00 2001 From: Jak Daniels Date: Wed, 30 Jan 2013 21:43:35 +0000 Subject: Allow use of MaptileStaticUUID in Regions.ini to override the global setting in OpenSim.ini for each region. Signed-off-by: BlueWall --- .../CoreModules/World/LegacyMap/MapImageModule.cs | 81 +++++++++++++++++----- OpenSim/Region/Framework/Scenes/Scene.cs | 7 +- 2 files changed, 69 insertions(+), 19 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs index 8a422b0..d412efc 100644 --- a/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs +++ b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs @@ -77,42 +77,52 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap { bool drawPrimVolume = true; bool textureTerrain = false; + bool generateMaptiles = true; + Bitmap mapbmp; try { IConfig startupConfig = m_config.Configs["Startup"]; drawPrimVolume = startupConfig.GetBoolean("DrawPrimOnMapTile", drawPrimVolume); textureTerrain = startupConfig.GetBoolean("TextureOnMapTile", textureTerrain); + generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", generateMaptiles); } catch { m_log.Warn("[MAPTILE]: Failed to load StartupConfig"); } - if (textureTerrain) + if (generateMaptiles) { - terrainRenderer = new TexturedMapTileRenderer(); - } - else - { - terrainRenderer = new ShadedMapTileRenderer(); - } - terrainRenderer.Initialise(m_scene, m_config); + if (textureTerrain) + { + terrainRenderer = new TexturedMapTileRenderer(); + } + else + { + terrainRenderer = new ShadedMapTileRenderer(); + } + + terrainRenderer.Initialise(m_scene, m_config); - Bitmap mapbmp = new Bitmap((int)Constants.RegionSize, (int)Constants.RegionSize, System.Drawing.Imaging.PixelFormat.Format24bppRgb); - //long t = System.Environment.TickCount; - //for (int i = 0; i < 10; ++i) { - terrainRenderer.TerrainToBitmap(mapbmp); - //} - //t = System.Environment.TickCount - t; - //m_log.InfoFormat("[MAPTILE] generation of 10 maptiles needed {0} ms", t); + mapbmp = new Bitmap((int)Constants.RegionSize, (int)Constants.RegionSize, System.Drawing.Imaging.PixelFormat.Format24bppRgb); + //long t = System.Environment.TickCount; + //for (int i = 0; i < 10; ++i) { + terrainRenderer.TerrainToBitmap(mapbmp); + //} + //t = System.Environment.TickCount - t; + //m_log.InfoFormat("[MAPTILE] generation of 10 maptiles needed {0} ms", t); - if (drawPrimVolume) + if (drawPrimVolume) + { + DrawObjectVolume(m_scene, mapbmp); + } + } + else { - DrawObjectVolume(m_scene, mapbmp); + mapbmp = fetchTexture(m_scene.RegionInfo.RegionSettings.TerrainImageID); } - return mapbmp; } @@ -222,6 +232,41 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap // } // } + private Bitmap fetchTexture(UUID id) + { + AssetBase asset = m_scene.AssetService.Get(id.ToString()); + m_log.DebugFormat("[MAPTILE]: Fetched static texture {0}, found: {1}", id, asset != null); + if (asset == null) return null; + + ManagedImage managedImage; + Image image; + + try + { + if (OpenJPEG.DecodeToImage(asset.Data, out managedImage, out image)) + return new Bitmap(image); + else + return null; + } + catch (DllNotFoundException) + { + m_log.ErrorFormat("[MAPTILE]: OpenJpeg is not installed correctly on this system. Asset Data is empty for {0}", id); + + } + catch (IndexOutOfRangeException) + { + m_log.ErrorFormat("[MAPTILE]: OpenJpeg was unable to decode this. Asset Data is empty for {0}", id); + + } + catch (Exception) + { + m_log.ErrorFormat("[MAPTILE]: OpenJpeg was unable to decode this. Asset Data is empty for {0}", id); + + } + return null; + + } + private Bitmap DrawObjectVolume(Scene whichScene, Bitmap mapbmp) { int tc = 0; diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index f2cb117..9e3d60f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -917,10 +917,15 @@ namespace OpenSim.Region.Framework.Scenes string tile = startupConfig.GetString("MaptileStaticUUID", UUID.Zero.ToString()); UUID tileID; - if (UUID.TryParse(tile, out tileID)) + if ((tile!=UUID.Zero.ToString()) && UUID.TryParse(tile, out tileID)) { RegionInfo.RegionSettings.TerrainImageID = tileID; } + else + { + RegionInfo.RegionSettings.TerrainImageID = RegionInfo.MaptileStaticUUID; + m_log.InfoFormat("[SCENE]: Region {0}, maptile set to {1}", RegionInfo.RegionName, RegionInfo.MaptileStaticUUID.ToString()); + } } string grant = startupConfig.GetString("AllowedClients", String.Empty); -- cgit v1.1 From 17440d8a2960005d0d88cfe5248930986331d520 Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Thu, 31 Jan 2013 11:14:43 -0800 Subject: Added option for UUID as command parameters. This lets the command handle the UUID parsing and type checking before the command is executed. --- OpenSim/Region/CoreModules/Framework/InterfaceCommander/Command.cs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/InterfaceCommander/Command.cs b/OpenSim/Region/CoreModules/Framework/InterfaceCommander/Command.cs index 4004135..b9786ae 100644 --- a/OpenSim/Region/CoreModules/Framework/InterfaceCommander/Command.cs +++ b/OpenSim/Region/CoreModules/Framework/InterfaceCommander/Command.cs @@ -28,6 +28,7 @@ using System; using System.Collections.Generic; using OpenSim.Region.Framework.Interfaces; +using OpenMetaverse; namespace OpenSim.Region.CoreModules.Framework.InterfaceCommander { @@ -152,6 +153,9 @@ namespace OpenSim.Region.CoreModules.Framework.InterfaceCommander case "Boolean": m_args[i].ArgumentValue = Boolean.Parse(arg.ToString()); break; + case "UUID": + m_args[i].ArgumentValue = UUID.Parse(arg.ToString()); + break; default: Console.WriteLine("ERROR: Unknown desired type for argument " + m_args[i].Name + " on command " + m_name); break; -- cgit v1.1 From 6a4c8824ea6568290fe7a2ff1b6a9b4d96896d5f Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 31 Jan 2013 20:46:41 +0000 Subject: Whitespace fix and removing unneccessary parentheses --- OpenSim/Region/Framework/Scenes/Scene.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 9e3d60f..f8d84e3 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -917,7 +917,7 @@ namespace OpenSim.Region.Framework.Scenes string tile = startupConfig.GetString("MaptileStaticUUID", UUID.Zero.ToString()); UUID tileID; - if ((tile!=UUID.Zero.ToString()) && UUID.TryParse(tile, out tileID)) + if (tile != UUID.Zero.ToString() && UUID.TryParse(tile, out tileID)) { RegionInfo.RegionSettings.TerrainImageID = tileID; } -- cgit v1.1 From 1e0420431f754ff71a97d01fae5617c1ea26cae0 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Thu, 31 Jan 2013 14:53:16 -0800 Subject: Move the JsonStore regular expressions to static variables to avoid recompiling on every operation. Added JsonList2Path script function to simplify array iteration. --- .../Scripting/JsonStore/JsonStore.cs | 73 +++++--- .../Scripting/JsonStore/JsonStoreScriptModule.cs | 204 ++++++++++++++------- 2 files changed, 190 insertions(+), 87 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs index 34894ba..0b7b31b 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs @@ -68,12 +68,46 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore protected List m_TakeStore; protected List m_ReadStore; + // add separators for quoted paths + protected static Regex m_ParsePassOne = new Regex("{[^}]+}"); + + // add separators for array references + protected static Regex m_ParsePassTwo = new Regex("(\\[[0-9]+\\]|\\[\\+\\])"); + + // add quotes to bare identifiers which are limited to alphabetic characters + protected static Regex m_ParsePassThree = new Regex("\\.([a-zA-Z]+)"); + + // remove extra separator characters + protected static Regex m_ParsePassFour = new Regex("\\.+"); + + // expression used to validate the full path, this is canonical representation + protected static Regex m_ValidatePath = new Regex("^\\.(({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])\\.)+$"); + + // expression used to match path components + protected static Regex m_PathComponent = new Regex("\\.({[^}]+}|\\[[0-9]+\\]|\\[\\+\\]+)"); + + // extract the internals of an array reference + protected static Regex m_SimpleArrayPattern = new Regex("\\[([0-9]+)\\]"); + protected static Regex m_ArrayPattern = new Regex("\\[([0-9]+|\\+)\\]"); + + // extract the internals of a has reference + protected static Regex m_HashPattern = new Regex("{([^}]+)}"); // ----------------------------------------------------------------- /// /// /// // ----------------------------------------------------------------- + public static string CanonicalPathExpression(string path) + { + return PathExpressionToKey(ParsePathExpression(path)); + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- public JsonStore() : this("") {} public JsonStore(string value) @@ -224,9 +258,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore if (result == null) return false; - Regex aPattern = new Regex("\\[([0-9]+|\\+)\\]"); - MatchCollection amatches = aPattern.Matches(pkey,0); - + // Check for and extract array references + MatchCollection amatches = m_ArrayPattern.Matches(pkey,0); if (amatches.Count > 0) { if (result.Type != OSDType.Array) @@ -263,9 +296,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore return false; } - Regex hPattern = new Regex("{([^}]+)}"); - MatchCollection hmatches = hPattern.Matches(pkey,0); - + // Check for and extract hash references + MatchCollection hmatches = m_HashPattern.Matches(pkey,0); if (hmatches.Count > 0) { Match match = hmatches[0]; @@ -340,26 +372,21 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore path = "." + path + "."; // add separators for quoted paths - Regex pass1 = new Regex("{[^}]+}"); - path = pass1.Replace(path,".$0.",-1,0); + path = m_ParsePassOne.Replace(path,".$0.",-1,0); // add separators for array references - Regex pass2 = new Regex("(\\[[0-9]+\\]|\\[\\+\\])"); - path = pass2.Replace(path,".$0.",-1,0); + path = m_ParsePassTwo.Replace(path,".$0.",-1,0); // add quotes to bare identifier - Regex pass3 = new Regex("\\.([a-zA-Z]+)"); - path = pass3.Replace(path,".{$1}",-1,0); + path = m_ParsePassThree.Replace(path,".{$1}",-1,0); // remove extra separators - Regex pass4 = new Regex("\\.+"); - path = pass4.Replace(path,".",-1,0); + path = m_ParsePassFour.Replace(path,".",-1,0); - Regex validate = new Regex("^\\.(({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])\\.)+$"); - if (validate.IsMatch(path)) + // validate the results (catches extra quote characters for example) + if (m_ValidatePath.IsMatch(path)) { - Regex parser = new Regex("\\.({[^}]+}|\\[[0-9]+\\]|\\[\\+\\]+)"); - MatchCollection matches = parser.Matches(path,0); + MatchCollection matches = m_PathComponent.Matches(path,0); foreach (Match match in matches) m_path.Push(match.Groups[1].Value); } @@ -385,9 +412,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore return null; // ---------- Check for an array index ---------- - Regex aPattern = new Regex("\\[([0-9]+)\\]"); - MatchCollection amatches = aPattern.Matches(pkey,0); - + MatchCollection amatches = m_SimpleArrayPattern.Matches(pkey,0); + if (amatches.Count > 0) { if (rmap.Type != OSDType.Array) @@ -410,9 +436,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } // ---------- Check for a hash index ---------- - Regex hPattern = new Regex("{([^}]+)}"); - MatchCollection hmatches = hPattern.Matches(pkey,0); - + MatchCollection hmatches = m_HashPattern.Matches(pkey,0); + if (hmatches.Count > 0) { if (rmap.Type != OSDType.Map) diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index 29955af..5b7a79d 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs @@ -165,29 +165,32 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore try { - m_comms.RegisterScriptInvocation(this, "JsonCreateStore"); - m_comms.RegisterScriptInvocation(this, "JsonDestroyStore"); - m_comms.RegisterScriptInvocation(this, "JsonTestStore"); + m_comms.RegisterScriptInvocations(this); - m_comms.RegisterScriptInvocation(this, "JsonReadNotecard"); - m_comms.RegisterScriptInvocation(this, "JsonWriteNotecard"); + // m_comms.RegisterScriptInvocation(this, "JsonCreateStore"); + // m_comms.RegisterScriptInvocation(this, "JsonDestroyStore"); + // m_comms.RegisterScriptInvocation(this, "JsonTestStore"); - m_comms.RegisterScriptInvocation(this, "JsonTestPath"); - m_comms.RegisterScriptInvocation(this, "JsonTestPathJson"); + // m_comms.RegisterScriptInvocation(this, "JsonReadNotecard"); + // m_comms.RegisterScriptInvocation(this, "JsonWriteNotecard"); - m_comms.RegisterScriptInvocation(this, "JsonGetValue"); - m_comms.RegisterScriptInvocation(this, "JsonGetValueJson"); + // m_comms.RegisterScriptInvocation(this, "JsonTestPathList"); + // m_comms.RegisterScriptInvocation(this, "JsonTestPath"); + // m_comms.RegisterScriptInvocation(this, "JsonTestPathJson"); - m_comms.RegisterScriptInvocation(this, "JsonTakeValue"); - m_comms.RegisterScriptInvocation(this, "JsonTakeValueJson"); + // m_comms.RegisterScriptInvocation(this, "JsonGetValue"); + // m_comms.RegisterScriptInvocation(this, "JsonGetValueJson"); - m_comms.RegisterScriptInvocation(this, "JsonReadValue"); - m_comms.RegisterScriptInvocation(this, "JsonReadValueJson"); + // m_comms.RegisterScriptInvocation(this, "JsonTakeValue"); + // m_comms.RegisterScriptInvocation(this, "JsonTakeValueJson"); - m_comms.RegisterScriptInvocation(this, "JsonSetValue"); - m_comms.RegisterScriptInvocation(this, "JsonSetValueJson"); + // m_comms.RegisterScriptInvocation(this, "JsonReadValue"); + // m_comms.RegisterScriptInvocation(this, "JsonReadValueJson"); - m_comms.RegisterScriptInvocation(this, "JsonRemoveValue"); + // m_comms.RegisterScriptInvocation(this, "JsonSetValue"); + // m_comms.RegisterScriptInvocation(this, "JsonSetValueJson"); + + // m_comms.RegisterScriptInvocation(this, "JsonRemoveValue"); } catch (Exception e) { @@ -215,17 +218,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// ///
// ----------------------------------------------------------------- - protected void GenerateRuntimeError(string msg) - { - throw new Exception("JsonStore Runtime Error: " + msg); - } - - // ----------------------------------------------------------------- - /// - /// - /// - // ----------------------------------------------------------------- - protected UUID JsonCreateStore(UUID hostID, UUID scriptID, string value) + [ScriptInvocation] + public UUID JsonCreateStore(UUID hostID, UUID scriptID, string value) { UUID uuid = UUID.Zero; if (! m_store.CreateStore(value, ref uuid)) @@ -239,7 +233,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// ///
// ----------------------------------------------------------------- - protected int JsonDestroyStore(UUID hostID, UUID scriptID, UUID storeID) + [ScriptInvocation] + public int JsonDestroyStore(UUID hostID, UUID scriptID, UUID storeID) { return m_store.DestroyStore(storeID) ? 1 : 0; } @@ -249,7 +244,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// ///
// ----------------------------------------------------------------- - protected int JsonTestStore(UUID hostID, UUID scriptID, UUID storeID) + [ScriptInvocation] + public int JsonTestStore(UUID hostID, UUID scriptID, UUID storeID) { return m_store.TestStore(storeID) ? 1 : 0; } @@ -259,7 +255,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - protected UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, UUID assetID) + [ScriptInvocation] + public UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, UUID assetID) { UUID reqID = UUID.Random(); Util.FireAndForget(delegate(object o) { DoJsonReadNotecard(reqID,hostID,scriptID,storeID,path,assetID); }); @@ -271,7 +268,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - protected UUID JsonWriteNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string name) + [ScriptInvocation] + public UUID JsonWriteNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string name) { UUID reqID = UUID.Random(); Util.FireAndForget(delegate(object o) { DoJsonWriteNotecard(reqID,hostID,scriptID,storeID,path,name); }); @@ -283,12 +281,25 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - protected int JsonTestPath(UUID hostID, UUID scriptID, UUID storeID, string path) + [ScriptInvocation] + public string JsonList2Path(UUID hostID, UUID scriptID, object[] pathlist) + { + return JsonStore.CanonicalPathExpression(ConvertList2Path(pathlist)); + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + [ScriptInvocation] + public int JsonTestPath(UUID hostID, UUID scriptID, UUID storeID, string path) { return m_store.TestPath(storeID,path,false) ? 1 : 0; } - protected int JsonTestPathJson(UUID hostID, UUID scriptID, UUID storeID, string path) + [ScriptInvocation] + public int JsonTestPathJson(UUID hostID, UUID scriptID, UUID storeID, string path) { return m_store.TestPath(storeID,path,true) ? 1 : 0; } @@ -298,12 +309,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - protected int JsonSetValue(UUID hostID, UUID scriptID, UUID storeID, string path, string value) + [ScriptInvocation] + public int JsonSetValue(UUID hostID, UUID scriptID, UUID storeID, string path, string value) { return m_store.SetValue(storeID,path,value,false) ? 1 : 0; } - protected int JsonSetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path, string value) + [ScriptInvocation] + public int JsonSetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path, string value) { return m_store.SetValue(storeID,path,value,true) ? 1 : 0; } @@ -313,7 +326,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - protected int JsonRemoveValue(UUID hostID, UUID scriptID, UUID storeID, string path) + [ScriptInvocation] + public int JsonRemoveValue(UUID hostID, UUID scriptID, UUID storeID, string path) { return m_store.RemoveValue(storeID,path) ? 1 : 0; } @@ -323,14 +337,16 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - protected string JsonGetValue(UUID hostID, UUID scriptID, UUID storeID, string path) + [ScriptInvocation] + public string JsonGetValue(UUID hostID, UUID scriptID, UUID storeID, string path) { string value = String.Empty; m_store.GetValue(storeID,path,false,out value); return value; } - protected string JsonGetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) + [ScriptInvocation] + public string JsonGetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) { string value = String.Empty; m_store.GetValue(storeID,path,true, out value); @@ -342,60 +358,75 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - protected UUID JsonTakeValue(UUID hostID, UUID scriptID, UUID storeID, string path) + [ScriptInvocation] + public UUID JsonTakeValue(UUID hostID, UUID scriptID, UUID storeID, string path) { UUID reqID = UUID.Random(); Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,false); }); return reqID; } - protected UUID JsonTakeValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) + [ScriptInvocation] + public UUID JsonTakeValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) { UUID reqID = UUID.Random(); Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,true); }); return reqID; } - private void DoJsonTakeValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson) - { - try - { - m_store.TakeValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); }); - return; - } - catch (Exception e) - { - m_log.InfoFormat("[JsonStoreScripts]: unable to retrieve value; {0}",e.ToString()); - } - - DispatchValue(scriptID,reqID,String.Empty); - } - - // ----------------------------------------------------------------- /// /// /// // ----------------------------------------------------------------- - protected UUID JsonReadValue(UUID hostID, UUID scriptID, UUID storeID, string path) + [ScriptInvocation] + public UUID JsonReadValue(UUID hostID, UUID scriptID, UUID storeID, string path) { UUID reqID = UUID.Random(); Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,false); }); return reqID; } - protected UUID JsonReadValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) + [ScriptInvocation] + public UUID JsonReadValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) { UUID reqID = UUID.Random(); Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,true); }); return reqID; } - private void DoJsonReadValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson) +#endregion + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + protected void GenerateRuntimeError(string msg) + { + throw new Exception("JsonStore Runtime Error: " + msg); + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + protected void DispatchValue(UUID scriptID, UUID reqID, string value) + { + m_comms.DispatchReply(scriptID,1,value,reqID.ToString()); + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + private void DoJsonTakeValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson) { try { - m_store.ReadValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); }); + m_store.TakeValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); }); return; } catch (Exception e) @@ -406,16 +437,25 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore DispatchValue(scriptID,reqID,String.Empty); } -#endregion // ----------------------------------------------------------------- /// /// /// // ----------------------------------------------------------------- - protected void DispatchValue(UUID scriptID, UUID reqID, string value) + private void DoJsonReadValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson) { - m_comms.DispatchReply(scriptID,1,value,reqID.ToString()); + try + { + m_store.ReadValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); }); + return; + } + catch (Exception e) + { + m_log.InfoFormat("[JsonStoreScripts]: unable to retrieve value; {0}",e.ToString()); + } + + DispatchValue(scriptID,reqID,String.Empty); } // ----------------------------------------------------------------- @@ -505,5 +545,43 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore m_comms.DispatchReply(scriptID,1,assetID.ToString(),reqID.ToString()); } + + // ----------------------------------------------------------------- + /// + /// Convert a list of values that are path components to a single string path + /// + // ----------------------------------------------------------------- + protected static Regex m_ArrayPattern = new Regex("^([0-9]+|\\+)$"); + private string ConvertList2Path(object[] pathlist) + { + string path = ""; + for (int i = 0; i < pathlist.Length; i++) + { + string token = ""; + + if (pathlist[i] is string) + { + token = pathlist[i].ToString(); + + // Check to see if this is a bare number which would not be a valid + // identifier otherwise + if (m_ArrayPattern.IsMatch(token)) + token = '[' + token + ']'; + } + else if (pathlist[i] is int) + { + token = "[" + pathlist[i].ToString() + "]"; + } + else + { + token = "." + pathlist[i].ToString() + "."; + } + + path += token + "."; + } + + return path; + } + } } \ No newline at end of file -- cgit v1.1 From 371449db2ff27ffcd6d8317ffec1c0176937f38f Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 30 Jan 2013 14:38:19 -0800 Subject: BulletSim: clean up TargetVelocity implementation by using the default defn in the PhysicsActor base class. --- OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 4 ++-- OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | 12 ------------ 2 files changed, 2 insertions(+), 14 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 3884a5d..73354bb 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -557,11 +557,12 @@ public sealed class BSCharacter : BSPhysObject { get { - return _velocityMotor.TargetValue; + return m_targetVelocity; } set { DetailLog("{0},BSCharacter.setTargetVelocity,call,vel={1}", LocalID, value); + m_targetVelocity = value; OMV.Vector3 targetVel = value; if (_setAlwaysRun) targetVel *= BSParam.AvatarAlwaysRunFactor; @@ -591,7 +592,6 @@ public sealed class BSCharacter : BSPhysObject _velocityMotor.Reset(); _velocityMotor.SetCurrent(_velocity); _velocityMotor.SetTarget(_velocity); - // Even though the motor is initialized, it's not used and the velocity goes straight into the avatar. _velocityMotor.Enabled = false; DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index a113530..823402b 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -190,18 +190,6 @@ public abstract class BSPhysObject : PhysicsActor public abstract OMV.Quaternion RawOrientation { get; set; } public abstract OMV.Quaternion ForceOrientation { get; set; } - // The system is telling us the velocity it wants to move at. - // Velocity in world coordinates. - // protected OMV.Vector3 m_targetVelocity; // use the definition in PhysicsActor - public override OMV.Vector3 TargetVelocity - { - get { return m_targetVelocity; } - set - { - m_targetVelocity = value; - Velocity = value; - } - } public virtual float TargetSpeed { get -- cgit v1.1 From ed71c939fc22059b03572fe6380fcc754c89a284 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 31 Jan 2013 10:26:53 -0800 Subject: BulletSim: make sure vehicle physical properties are set when going physical by delaying setting until pre-step time. Change vehicle.Refresh() to schedule the pre-step setting. Comments and updating of TODO list. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 30 ++++++++++------------ .../Physics/BulletSPlugin/BSLinksetCompound.cs | 6 ++--- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 4 +-- .../Physics/BulletSPlugin/BSShapeCollection.cs | 11 ++++---- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 30 ++++++++-------------- 5 files changed, 35 insertions(+), 46 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 05ab180..8ecf2ff 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -581,9 +581,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin } #endregion // Vehicle parameter setting + public void Refresh() + { + // If asking for a refresh, reset the physical parameters before the next simulation step. + PhysicsScene.PostTaintObject("BSDynamics.Refresh", Prim.LocalID, delegate() + { + SetPhysicalParameters(); + }); + } + // Some of the properties of this prim may have changed. // Do any updating needed for a vehicle - public void Refresh() + private void SetPhysicalParameters() { if (IsActive) { @@ -614,7 +623,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // The actual vehicle gravity is set to zero in Bullet so we can do all the application of same. PhysicsScene.PE.SetGravity(Prim.PhysBody, Vector3.Zero); - VDetailLog("{0},BSDynamics.Refresh,mass={1},inert={2},grav={3},aDamp={4},frict={5},rest={6},lFact={7},aFact={8}", + VDetailLog("{0},BSDynamics.SetPhysicalParameters,mass={1},inert={2},vehGrav={3},aDamp={4},frict={5},rest={6},lFact={7},aFact={8}", Prim.LocalID, m_vehicleMass, Prim.Inertia, m_VehicleGravity, BSParam.VehicleAngularDamping, BSParam.VehicleFriction, BSParam.VehicleRestitution, BSParam.VehicleLinearFactor, BSParam.VehicleAngularFactor @@ -622,26 +631,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin } else { - PhysicsScene.PE.RemoveFromCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); + if (Prim.PhysBody.HasPhysicalBody) + PhysicsScene.PE.RemoveFromCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); } } public bool RemoveBodyDependencies(BSPhysObject prim) { - // If active, we need to add our properties back when the body is rebuilt. - return IsActive; - } - - public void RestoreBodyDependencies(BSPhysObject prim) - { - if (Prim.LocalID != prim.LocalID) - { - // The call should be on us by our prim. Error if not. - PhysicsScene.Logger.ErrorFormat("{0} RestoreBodyDependencies: called by not my prim. passedLocalID={1}, vehiclePrimLocalID={2}", - LogHeader, prim.LocalID, Prim.LocalID); - return; - } Refresh(); + return IsActive; } #region Known vehicle value functions diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 54dc458..92f6ee2 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -274,7 +274,7 @@ public sealed class BSLinksetCompound : BSLinkset bool ret = false; DetailLog("{0},BSLinksetCompound.RemoveBodyDependencies,refreshIfChild,rID={1},rBody={2},isRoot={3}", - child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString, IsRoot(child)); + child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody, IsRoot(child)); if (!IsRoot(child)) { @@ -382,11 +382,11 @@ public sealed class BSLinksetCompound : BSLinkset { try { - // Suppress rebuilding while rebuilding + // Suppress rebuilding while rebuilding. (We know rebuilding is on only one thread.) Rebuilding = true; // Cause the root shape to be rebuilt as a compound object with just the root in it - LinksetRoot.ForceBodyShapeRebuild(true); + LinksetRoot.ForceBodyShapeRebuild(true /* inTaintTime */); // The center of mass for the linkset is the geometric center of the group. // Compute a displacement for each component so it is relative to the center-of-mass. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index b5dd131..0b81122 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -1597,9 +1597,9 @@ public sealed class BSPrim : BSPhysObject public void CreateGeomAndObject(bool forceRebuild) { // Create the correct physical representation for this type of object. - // Updates PhysBody and PhysShape with the new information. + // Updates base.PhysBody and base.PhysShape with the new information. // Ignore 'forceRebuild'. This routine makes the right choices and changes of necessary. - PhysicsScene.Shapes.GetBodyAndShape(false, PhysicsScene.World, this, null, delegate(BulletBody dBody) + PhysicsScene.Shapes.GetBodyAndShape(false /*forceRebuild */, PhysicsScene.World, this, null, delegate(BulletBody dBody) { // Called if the current prim body is about to be destroyed. // Remove all the physical dependencies on the old body. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 9fbfcdc..e2daa72 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -116,8 +116,7 @@ public sealed class BSShapeCollection : IDisposable // rebuild the body around it. // Updates prim.BSBody with information/pointers to requested body // Returns 'true' if BSBody was changed. - bool newBody = CreateBody((newGeom || forceRebuild), prim, PhysicsScene.World, - prim.PhysShape, bodyCallback); + bool newBody = CreateBody((newGeom || forceRebuild), prim, PhysicsScene.World, bodyCallback); ret = newGeom || newBody; } DetailLog("{0},BSShapeCollection.GetBodyAndShape,taintExit,force={1},ret={2},body={3},shape={4}", @@ -933,8 +932,7 @@ public sealed class BSShapeCollection : IDisposable // Updates prim.BSBody with the information about the new body if one is created. // Returns 'true' if an object was actually created. // Called at taint-time. - private bool CreateBody(bool forceRebuild, BSPhysObject prim, BulletWorld sim, BulletShape shape, - BodyDestructionCallback bodyCallback) + private bool CreateBody(bool forceRebuild, BSPhysObject prim, BulletWorld sim, BodyDestructionCallback bodyCallback) { bool ret = false; @@ -951,6 +949,7 @@ public sealed class BSShapeCollection : IDisposable { // If the collisionObject is not the correct type for solidness, rebuild what's there mustRebuild = true; + if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,forceRebuildBecauseChangingBodyType,bodyType={1}", prim.LocalID, bodyType); } } @@ -962,12 +961,12 @@ public sealed class BSShapeCollection : IDisposable BulletBody aBody; if (prim.IsSolid) { - aBody = PhysicsScene.PE.CreateBodyFromShape(sim, shape, prim.LocalID, prim.RawPosition, prim.RawOrientation); + aBody = PhysicsScene.PE.CreateBodyFromShape(sim, prim.PhysShape, prim.LocalID, prim.RawPosition, prim.RawOrientation); if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,mesh,body={1}", prim.LocalID, aBody); } else { - aBody = PhysicsScene.PE.CreateGhostFromShape(sim, shape, prim.LocalID, prim.RawPosition, prim.RawOrientation); + aBody = PhysicsScene.PE.CreateGhostFromShape(sim, prim.PhysShape, prim.LocalID, prim.RawPosition, prim.RawOrientation); if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,ghost,body={1}", prim.LocalID, aBody); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index a95e169..d574a49 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -6,6 +6,7 @@ One sided meshes? Should terrain be built into a closed shape? Ref: http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4869 Deleting a linkset while standing on the root will leave the physical shape of the root behind. Not sure if it is because standing on it. Done with large prim linksets. +Terrain detail: double terrain mesh detail Vehicle angular vertical attraction vehicle angular banking Center-of-gravity @@ -34,34 +35,20 @@ Vehicle script tuning/debugging Weapon shooter script Add material densities to the material types -CRASHES -================================================= -Crazyness during 20130115 office hours was PositionAdjustUnderground for both char and prim - m1:logs/20130115.0934/physics-BulletSim-20130115083613.log - Creation of Neb's terrain made the terrain "disappear". Everything started to fall - and then get restored to be above terrain. -20121129.1411: editting/moving phys object across region boundries causes crash - getPos-> btRigidBody::upcast -> getBodyType -> BOOM -20121128.1600: mesh object not rezzing (no physics mesh). - Causes many errors. Doesn't stop after first error with box shape. - Eventually crashes when deleting the object. -20121206.1434: rez Sam-pan into OSGrid BulletSim11 region - Immediate simulator crash. Mono does not output any stacktrace and - log just stops after reporting taint-time linking of the linkset. - VEHICLES TODO LIST: ================================================= Border crossing with linked vehicle causes crash + 20121129.1411: editting/moving phys object across region boundries causes crash + getPos-> btRigidBody::upcast -> getBodyType -> BOOM Vehicles (Move smoothly) Some vehicles should not be able to turn if no speed or off ground. +What to do if vehicle and prim buoyancy differ? Cannot edit/move a vehicle being ridden: it jumps back to the origional position. Neb car jiggling left and right Happens on terrain and any other mesh object. Flat cubes are much smoother. This has been reduced but not eliminated. Implement referenceFrame for all the motion routines. For limitMotorUp, use raycast down to find if vehicle is in the air. -Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE. - Verify that angular motion specified around Z moves in the vehicle coordinates. Verify llGetVel() is returning a smooth and good value for vehicle movement. llGetVel() should return the root's velocity if requested in a child prim. Implement function efficiency for lineaar and angular motion. @@ -73,10 +60,11 @@ Remove vehicle angular velocity zeroing in BSPrim.UpdateProperties(). Incorporate inter-relationship of angular corrections. For instance, angularDeflection and angularMotorUp will compute same X or Y correction. When added together creates over-correction and over-shoot and wabbling. +Vehicle attributes are not restored when a vehicle is rezzed on region creation + Create vehicle, setup vehicle properties, restart region, vehicle is not reinitialized. GENERAL TODO LIST: ================================================= -Avatar standing on a moving object should start to move with the object. llMoveToTarget objects are not effected by gravity until target is removed. Compute CCD parameters based on body size Can solver iterations be changed per body/shape? Can be for constraints but what @@ -330,4 +318,8 @@ Boats float low in the water (DONE) Boats floating at proper level (DONE) When is force introduced by SetForce removed? The prestep action could go forever. (DONE) (Resolution: setForce registers a prestep action which keeps applying the force) -Child movement in linkset (don't rebuild linkset) (DONE 20130122)) \ No newline at end of file +Child movement in linkset (don't rebuild linkset) (DONE 20130122)) +Avatar standing on a moving object should start to move with the object. (DONE 20130125) +Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE. + Verify that angular motion specified around Z moves in the vehicle coordinates. + DONE 20130120: BulletSim properly applies force in vehicle relative coordinates. \ No newline at end of file -- cgit v1.1 From 75a05c16c5c0ec0712f7f564b60530e0a3fd1c82 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 31 Jan 2013 15:52:50 -0800 Subject: BulletSim: fix crash caused when linksets were rebuilt. A problem added when individual child pos/rot changes were implementated a week or so ago. Remove some passing of inTaintTime flag when it was never false. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 4 +- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 48 ++++++--- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 16 ++- .../Physics/BulletSPlugin/BSShapeCollection.cs | 114 ++++++++++----------- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 4 + 5 files changed, 106 insertions(+), 80 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 73354bb..192bcb5 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -126,9 +126,9 @@ public sealed class BSCharacter : BSPhysObject DetailLog("{0},BSCharacter.Destroy", LocalID); PhysicsScene.TaintedObject("BSCharacter.destroy", delegate() { - PhysicsScene.Shapes.DereferenceBody(PhysBody, true /* inTaintTime */, null /* bodyCallback */); + PhysicsScene.Shapes.DereferenceBody(PhysBody, null /* bodyCallback */); PhysBody.Clear(); - PhysicsScene.Shapes.DereferenceShape(PhysShape, true /* inTaintTime */, null /* bodyCallback */); + PhysicsScene.Shapes.DereferenceShape(PhysShape, null /* bodyCallback */); PhysShape.Clear(); }); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 92f6ee2..6c6ca09 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -219,28 +219,45 @@ public sealed class BSLinksetCompound : BSLinkset { // Gather the child info. It might not be there if the linkset is in transition. BSLinksetCompoundInfo lsi = updated.LinksetInfo as BSLinksetCompoundInfo; + + // The linksetInfo will need to be rebuilt either here or when the linkset is rebuilt if (LinksetRoot.PhysShape.HasPhysicalShape && lsi != null) { if (PhysicsScene.PE.IsCompound(LinksetRoot.PhysShape)) { - BulletShape linksetChildShape = PhysicsScene.PE.GetChildShapeFromCompoundShapeIndex(LinksetRoot.PhysShape, lsi.Index); - if (linksetChildShape.HasPhysicalShape) + int numLinksetChildren = PhysicsScene.PE.GetNumberOfCompoundChildren(LinksetRoot.PhysShape); + if (lsi.Index < numLinksetChildren) { - // Compute the offset from the center-of-gravity - BSLinksetCompoundInfo newLsi = new BSLinksetCompoundInfo(lsi.Index, LinksetRoot, updated, LinksetRoot.PositionDisplacement); - PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, lsi.Index, - newLsi.OffsetFromCenterOfMass, - newLsi.OffsetRot, - true /* shouldRecalculateLocalAabb */); - DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1},newLsi={2}", - updated.LocalID, whichUpdated, newLsi); - updated.LinksetInfo = newLsi; - updatedChild = true; + // It is possible that the linkset is still under construction and the child is not yet + // inserted into the compound shape. A rebuild of the linkset in a pre-step action will + // build the whole thing with the new position or rotation. + // This must be checked for because Bullet references the child array but does no validity + // checking of the child index passed. + BulletShape linksetChildShape = PhysicsScene.PE.GetChildShapeFromCompoundShapeIndex(LinksetRoot.PhysShape, lsi.Index); + if (linksetChildShape.HasPhysicalShape) + { + // Compute the offset from the center-of-gravity + BSLinksetCompoundInfo newLsi = new BSLinksetCompoundInfo(lsi.Index, LinksetRoot, updated, LinksetRoot.PositionDisplacement); + PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, lsi.Index, + newLsi.OffsetFromCenterOfMass, + newLsi.OffsetRot, + true /* shouldRecalculateLocalAabb */); + updated.LinksetInfo = newLsi; + updatedChild = true; + DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1},newLsi={2}", + updated.LocalID, whichUpdated, newLsi); + } + else // DEBUG DEBUG + { // DEBUG DEBUG + DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noChildShape,shape={1}", + updated.LocalID, linksetChildShape); + } // DEBUG DEBUG } else // DEBUG DEBUG { // DEBUG DEBUG - DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noChildShape,shape={1}", - updated.LocalID, linksetChildShape); + // the child is not yet in the compound shape. This is non-fatal. + DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,childNotInCompoundShape,numChildren={1},index={2}", + updated.LocalID, numLinksetChildren, lsi.Index); } // DEBUG DEBUG } else // DEBUG DEBUG @@ -256,6 +273,9 @@ public sealed class BSLinksetCompound : BSLinkset if (!updatedChild) { // If couldn't do the individual child, the linkset needs a rebuild to incorporate the new child info. + // Note that there are several ways through this code that will not update the child that can + // occur if the linkset is being rebuilt. In this case, scheduling a rebuild is a NOOP since + // there will already be a rebuild scheduled. DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild.schedulingRebuild,whichUpdated={1}", updated.LocalID, whichUpdated); updated.LinksetInfo = null; // setting to 'null' causes relative position to be recomputed. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 0b81122..54bf063 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -146,9 +146,9 @@ public sealed class BSPrim : BSPhysObject { DetailLog("{0},BSPrim.Destroy,taint,", LocalID); // If there are physical body and shape, release my use of same. - PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null); + PhysicsScene.Shapes.DereferenceBody(PhysBody, null); PhysBody.Clear(); - PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null); + PhysicsScene.Shapes.DereferenceShape(PhysShape, null); PhysShape.Clear(); }); } @@ -181,11 +181,19 @@ public sealed class BSPrim : BSPhysObject public override bool ForceBodyShapeRebuild(bool inTaintTime) { - PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ForceBodyShapeRebuild", delegate() + if (inTaintTime) { _mass = CalculateMass(); // changing the shape changes the mass CreateGeomAndObject(true); - }); + } + else + { + PhysicsScene.TaintedObject("BSPrim.ForceBodyShapeRebuild", delegate() + { + _mass = CalculateMass(); // changing the shape changes the mass + CreateGeomAndObject(true); + }); + } return true; } public override bool Grabbed { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index e2daa72..9febd90 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -133,48 +133,44 @@ public sealed class BSShapeCollection : IDisposable // Track another user of a body. // We presume the caller has allocated the body. // Bodies only have one user so the body is just put into the world if not already there. - public void ReferenceBody(BulletBody body, bool inTaintTime) + private void ReferenceBody(BulletBody body) { lock (m_collectionActivityLock) { if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,body={1}", body.ID, body); - PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.ReferenceBody", delegate() + if (!PhysicsScene.PE.IsInWorld(PhysicsScene.World, body)) { - if (!PhysicsScene.PE.IsInWorld(PhysicsScene.World, body)) - { - PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, body); - if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", body.ID, body); - } - }); + PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, body); + if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", body.ID, body); + } } } // Release the usage of a body. // Called when releasing use of a BSBody. BSShape is handled separately. - public void DereferenceBody(BulletBody body, bool inTaintTime, BodyDestructionCallback bodyCallback ) + // Called in taint time. + public void DereferenceBody(BulletBody body, BodyDestructionCallback bodyCallback ) { if (!body.HasPhysicalBody) return; + PhysicsScene.AssertInTaintTime("BSShapeCollection.DereferenceBody"); + lock (m_collectionActivityLock) { - PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceBody", delegate() - { - if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1},inTaintTime={2}", - body.ID, body, inTaintTime); - // If the caller needs to know the old body is going away, pass the event up. - if (bodyCallback != null) bodyCallback(body); + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1}", body.ID, body); + // If the caller needs to know the old body is going away, pass the event up. + if (bodyCallback != null) bodyCallback(body); - if (PhysicsScene.PE.IsInWorld(PhysicsScene.World, body)) - { - PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, body); - if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,removingFromWorld. Body={1}", body.ID, body); - } + if (PhysicsScene.PE.IsInWorld(PhysicsScene.World, body)) + { + PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, body); + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,removingFromWorld. Body={1}", body.ID, body); + } - // Zero any reference to the shape so it is not freed when the body is deleted. - PhysicsScene.PE.SetCollisionShape(PhysicsScene.World, body, null); - PhysicsScene.PE.DestroyObject(PhysicsScene.World, body); - }); + // Zero any reference to the shape so it is not freed when the body is deleted. + PhysicsScene.PE.SetCollisionShape(PhysicsScene.World, body, null); + PhysicsScene.PE.DestroyObject(PhysicsScene.World, body); } } @@ -245,44 +241,43 @@ public sealed class BSShapeCollection : IDisposable } // Release the usage of a shape. - public void DereferenceShape(BulletShape shape, bool inTaintTime, ShapeDestructionCallback shapeCallback) + public void DereferenceShape(BulletShape shape, ShapeDestructionCallback shapeCallback) { if (!shape.HasPhysicalShape) return; - PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.DereferenceShape", delegate() + PhysicsScene.AssertInTaintTime("BSShapeCollection.DereferenceShape"); + + if (shape.HasPhysicalShape) { - if (shape.HasPhysicalShape) + if (shape.isNativeShape) { - if (shape.isNativeShape) - { - // Native shapes are not tracked and are released immediately - if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}", - BSScene.DetailLogZero, shape.AddrString, inTaintTime); - if (shapeCallback != null) shapeCallback(shape); - PhysicsScene.PE.DeleteCollisionShape(PhysicsScene.World, shape); - } - else + // Native shapes are not tracked and are released immediately + if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1}", + BSScene.DetailLogZero, shape.AddrString); + if (shapeCallback != null) shapeCallback(shape); + PhysicsScene.PE.DeleteCollisionShape(PhysicsScene.World, shape); + } + else + { + switch (shape.type) { - switch (shape.type) - { - case BSPhysicsShapeType.SHAPE_HULL: - DereferenceHull(shape, shapeCallback); - break; - case BSPhysicsShapeType.SHAPE_MESH: - DereferenceMesh(shape, shapeCallback); - break; - case BSPhysicsShapeType.SHAPE_COMPOUND: - DereferenceCompound(shape, shapeCallback); - break; - case BSPhysicsShapeType.SHAPE_UNKNOWN: - break; - default: - break; - } + case BSPhysicsShapeType.SHAPE_HULL: + DereferenceHull(shape, shapeCallback); + break; + case BSPhysicsShapeType.SHAPE_MESH: + DereferenceMesh(shape, shapeCallback); + break; + case BSPhysicsShapeType.SHAPE_COMPOUND: + DereferenceCompound(shape, shapeCallback); + break; + case BSPhysicsShapeType.SHAPE_UNKNOWN: + break; + default: + break; } } - }); + } } // Count down the reference count for a mesh shape @@ -393,7 +388,7 @@ public sealed class BSShapeCollection : IDisposable if (shapeInfo.type != BSPhysicsShapeType.SHAPE_UNKNOWN) { - DereferenceShape(shapeInfo, true, null); + DereferenceShape(shapeInfo, null); } else { @@ -543,7 +538,7 @@ public sealed class BSShapeCollection : IDisposable ShapeDestructionCallback shapeCallback) { // release any previous shape - DereferenceShape(prim.PhysShape, true, shapeCallback); + DereferenceShape(prim.PhysShape, shapeCallback); BulletShape newShape = BuildPhysicalNativeShape(prim, shapeType, shapeKey); @@ -611,7 +606,7 @@ public sealed class BSShapeCollection : IDisposable prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X")); // Since we're recreating new, get rid of the reference to the previous shape - DereferenceShape(prim.PhysShape, true, shapeCallback); + DereferenceShape(prim.PhysShape, shapeCallback); newShape = CreatePhysicalMesh(prim.PhysObjectName, newMeshKey, prim.BaseShape, prim.Size, lod); // Take evasive action if the mesh was not constructed. @@ -682,7 +677,7 @@ public sealed class BSShapeCollection : IDisposable prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newHullKey.ToString("X")); // Remove usage of the previous shape. - DereferenceShape(prim.PhysShape, true, shapeCallback); + DereferenceShape(prim.PhysShape, shapeCallback); newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, prim.BaseShape, prim.Size, lod); newShape = VerifyMeshCreated(newShape, prim); @@ -817,7 +812,6 @@ public sealed class BSShapeCollection : IDisposable // Don't need to do this as the shape is freed when the new root shape is created below. // DereferenceShape(prim.PhysShape, true, shapeCallback); - BulletShape cShape = PhysicsScene.PE.CreateCompoundShape(PhysicsScene.World, false); // Create the shape for the root prim and add it to the compound shape. Cannot be a native shape. @@ -956,7 +950,7 @@ public sealed class BSShapeCollection : IDisposable if (mustRebuild || forceRebuild) { // Free any old body - DereferenceBody(prim.PhysBody, true, bodyCallback); + DereferenceBody(prim.PhysBody, bodyCallback); BulletBody aBody; if (prim.IsSolid) @@ -970,7 +964,7 @@ public sealed class BSShapeCollection : IDisposable if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,ghost,body={1}", prim.LocalID, aBody); } - ReferenceBody(aBody, true); + ReferenceBody(aBody); prim.PhysBody = aBody; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index d574a49..7dfdec1 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -65,6 +65,10 @@ Vehicle attributes are not restored when a vehicle is rezzed on region creation GENERAL TODO LIST: ================================================= +Collisions are inconsistant: arrows are supposed to hit and report collision. Often don't. + If arrow show at prim, collision reported about 1/3 of time. If collision reported, + both arrow and prim report it. The arrow bounces off the prim 9 out of 10 times. + Shooting 5m sphere "arrows" at 60m/s. llMoveToTarget objects are not effected by gravity until target is removed. Compute CCD parameters based on body size Can solver iterations be changed per body/shape? Can be for constraints but what -- cgit v1.1 From 5bb85a14d46ad280b045e945edcc9e9bc6045612 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 1 Feb 2013 11:52:27 -0800 Subject: BulletSim: fix problem where editting a physical linkset caused the child prim physical positions to get out of sync with the view. More reliably compute the offset of children in a physical linkset. --- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 51 ++++++++++++++-------- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 1 + 2 files changed, 33 insertions(+), 19 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 6c6ca09..0c4db40 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -219,30 +219,31 @@ public sealed class BSLinksetCompound : BSLinkset { // Gather the child info. It might not be there if the linkset is in transition. BSLinksetCompoundInfo lsi = updated.LinksetInfo as BSLinksetCompoundInfo; - - // The linksetInfo will need to be rebuilt either here or when the linkset is rebuilt - if (LinksetRoot.PhysShape.HasPhysicalShape && lsi != null) + if (lsi != null) { - if (PhysicsScene.PE.IsCompound(LinksetRoot.PhysShape)) + // Since the child moved or rotationed, it needs a new relative position within the linkset + BSLinksetCompoundInfo newLsi = new BSLinksetCompoundInfo(lsi.Index, LinksetRoot, updated, LinksetRoot.PositionDisplacement); + updated.LinksetInfo = newLsi; + + // Find the physical instance of the child + if (LinksetRoot.PhysShape.HasPhysicalShape && PhysicsScene.PE.IsCompound(LinksetRoot.PhysShape)) { + // It is possible that the linkset is still under construction and the child is not yet + // inserted into the compound shape. A rebuild of the linkset in a pre-step action will + // build the whole thing with the new position or rotation. + // The index must be checked because Bullet references the child array but does no validity + // checking of the child index passed. int numLinksetChildren = PhysicsScene.PE.GetNumberOfCompoundChildren(LinksetRoot.PhysShape); if (lsi.Index < numLinksetChildren) { - // It is possible that the linkset is still under construction and the child is not yet - // inserted into the compound shape. A rebuild of the linkset in a pre-step action will - // build the whole thing with the new position or rotation. - // This must be checked for because Bullet references the child array but does no validity - // checking of the child index passed. BulletShape linksetChildShape = PhysicsScene.PE.GetChildShapeFromCompoundShapeIndex(LinksetRoot.PhysShape, lsi.Index); if (linksetChildShape.HasPhysicalShape) { - // Compute the offset from the center-of-gravity - BSLinksetCompoundInfo newLsi = new BSLinksetCompoundInfo(lsi.Index, LinksetRoot, updated, LinksetRoot.PositionDisplacement); + // Found the child shape within the compound shape PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, lsi.Index, newLsi.OffsetFromCenterOfMass, newLsi.OffsetRot, true /* shouldRecalculateLocalAabb */); - updated.LinksetInfo = newLsi; updatedChild = true; DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1},newLsi={2}", updated.LocalID, whichUpdated, newLsi); @@ -262,19 +263,20 @@ public sealed class BSLinksetCompound : BSLinkset } else // DEBUG DEBUG { // DEBUG DEBUG - DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,notCompound", updated.LocalID); + DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noBodyOrNotCompound", updated.LocalID); } // DEBUG DEBUG } else // DEBUG DEBUG { // DEBUG DEBUG - DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,rootPhysShape={1},lsi={2}", - updated.LocalID, LinksetRoot.PhysShape, lsi == null ? "NULL" : lsi.ToString()); + DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noLinkSetInfo,rootPhysShape={1}", + updated.LocalID, LinksetRoot.PhysShape); } // DEBUG DEBUG + if (!updatedChild) { // If couldn't do the individual child, the linkset needs a rebuild to incorporate the new child info. - // Note that there are several ways through this code that will not update the child that can - // occur if the linkset is being rebuilt. In this case, scheduling a rebuild is a NOOP since + // Note: there are several ways through this code that will not update the child if + // the linkset is being rebuilt. In this case, scheduling a rebuild is a NOOP since // there will already be a rebuild scheduled. DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild.schedulingRebuild,whichUpdated={1}", updated.LocalID, whichUpdated); @@ -300,7 +302,8 @@ public sealed class BSLinksetCompound : BSLinkset { // Because it is a convenient time, recompute child world position and rotation based on // its position in the linkset. - RecomputeChildWorldPosition(child, true); + RecomputeChildWorldPosition(child, true /* inTaintTime */); + child.LinksetInfo = null; } // Cannot schedule a refresh/rebuild here because this routine is called when @@ -315,6 +318,14 @@ public sealed class BSLinksetCompound : BSLinkset // prim. The child prim's location must be recomputed based on the location of the root shape. private void RecomputeChildWorldPosition(BSPhysObject child, bool inTaintTime) { + // For the moment (20130201), disable this computation (converting the child physical addr back to + // a region address) until we have a good handle on center-of-mass offsets and what the physics + // engine moving a child actually means. + // The simulator keeps track of where children should be as the linkset moves. Setting + // the pos/rot here does not effect that knowledge as there is no good way for the + // physics engine to send the simulator an update for a child. + + /* BSLinksetCompoundInfo lci = child.LinksetInfo as BSLinksetCompoundInfo; if (lci != null) { @@ -343,6 +354,7 @@ public sealed class BSLinksetCompound : BSLinkset // LogHeader, child.LocalID); DetailLog("{0},BSLinksetCompound.recomputeChildWorldPosition,noRelativePositonInfo", child.LocalID); } + */ } // ================================================================ @@ -376,6 +388,7 @@ public sealed class BSLinksetCompound : BSLinkset // Cause the child's body to be rebuilt and thus restored to normal operation RecomputeChildWorldPosition(child, false); + child.LinksetInfo = null; child.ForceBodyShapeRebuild(false); if (!HasAnyChildren) @@ -397,7 +410,7 @@ public sealed class BSLinksetCompound : BSLinkset // Constraint linksets are rebuilt every time. // Note that this works for rebuilding just the root after a linkset is taken apart. // Called at taint time!! - private bool disableCOM = true; // disable until we get this debugged + private bool disableCOM = true; // DEBUG DEBUG: disable until we get this debugged private void RecomputeLinksetCompound() { try diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 7dfdec1..a3b3556 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -127,6 +127,7 @@ Physical and phantom will drop through the terrain LINKSETS ====================================================== +Child prims do not report collisions Editing a child of a linkset causes the child to go phantom Move a child prim once when it is physical and can never move it again without it going phantom Offset the center of the linkset to be the geometric center of all the prims -- cgit v1.1 From d8d4e7f236346d8dd7d66dbc187bb5362c00f039 Mon Sep 17 00:00:00 2001 From: teravus Date: Fri, 1 Feb 2013 15:42:24 -0500 Subject: Sit and Spin reduction. If sitting, slam avatar angular velocity to zero. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index e0dfb34..6e41774 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2342,7 +2342,7 @@ namespace OpenSim.Region.Framework.Scenes ParentPart = m_scene.GetSceneObjectPart(m_requestedSitTargetID); ParentID = m_requestedSitTargetID; - + m_AngularVelocity = Vector3.Zero; Velocity = Vector3.Zero; RemoveFromPhysicalScene(); @@ -2358,7 +2358,8 @@ namespace OpenSim.Region.Framework.Scenes public void HandleAgentSitOnGround() { -// m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick. +// m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.. + m_AngularVelocity = Vector3.Zero; Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); SitGround = true; RemoveFromPhysicalScene(); -- cgit v1.1 From 9588328242f4004446b5cc08251995b8d004b4f2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 2 Feb 2013 00:59:26 +0000 Subject: Stop exceptions being thrown if GenerateMapTiles = false but no static map tile has been set. Do more informative warn instead. --- .../MapImage/MapImageServiceModule.cs | 8 ++++++-- .../CoreModules/World/LegacyMap/MapImageModule.cs | 17 ++++++++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs index a839086..26d22b8 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs @@ -75,7 +75,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage public void Close() { } public void PostInitialise() { } - /// /// /// @@ -133,7 +132,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage /// public void AddRegion(Scene scene) { - if (! m_enabled) + if (!m_enabled) return; // Every shared region module has to maintain an indepedent list of @@ -206,6 +205,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage using (Image mapTile = tileGenerator.CreateMapTile()) { + // XXX: The MapImageModule will return a null if the user has chosen not to create map tiles and there + // is no static map tile. + if (mapTile == null) + return; + using (MemoryStream stream = new MemoryStream()) { mapTile.Save(stream, ImageFormat.Jpeg); diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs index d412efc..e7065dc 100644 --- a/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs +++ b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs @@ -113,7 +113,6 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap //t = System.Environment.TickCount - t; //m_log.InfoFormat("[MAPTILE] generation of 10 maptiles needed {0} ms", t); - if (drawPrimVolume) { DrawObjectVolume(m_scene, mapbmp); @@ -121,7 +120,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap } else { - mapbmp = fetchTexture(m_scene.RegionInfo.RegionSettings.TerrainImageID); + mapbmp = FetchTexture(m_scene.RegionInfo.RegionSettings.TerrainImageID); } return mapbmp; } @@ -232,11 +231,19 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap // } // } - private Bitmap fetchTexture(UUID id) + private Bitmap FetchTexture(UUID id) { AssetBase asset = m_scene.AssetService.Get(id.ToString()); - m_log.DebugFormat("[MAPTILE]: Fetched static texture {0}, found: {1}", id, asset != null); - if (asset == null) return null; + + if (asset != null) + { + m_log.DebugFormat("[MAPTILE]: Static map image texture {0} found for {1}", id, m_scene.Name); + } + else + { + m_log.WarnFormat("[MAPTILE]: Static map image texture {0} not found for {1}", id, m_scene.Name); + return null; + } ManagedImage managedImage; Image image; -- cgit v1.1 From 2ff301ca113842c9a865a941833ca7231d3866b6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 2 Feb 2013 01:34:49 +0000 Subject: Correct spelling mistake in new RayFilterFlags, LSLPhanton -> LSLPhantom --- OpenSim/Region/Physics/Manager/PhysicsScene.cs | 4 ++-- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index 96a9ff7..c4d7ef3 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs @@ -43,7 +43,7 @@ namespace OpenSim.Region.Physics.Manager public delegate void JointDeactivated(PhysicsJoint joint); public delegate void JointErrorMessage(PhysicsJoint joint, string message); // this refers to an "error message due to a problem", not "amount of joint constraint violation" - public enum RayFilterFlags:ushort + public enum RayFilterFlags : ushort { // the flags water = 0x01, @@ -60,7 +60,7 @@ namespace OpenSim.Region.Physics.Manager ClosestHit = 0x8000, // some combinations - LSLPhanton = phantom | volumedtc, + LSLPhantom = phantom | volumedtc, PrimsNonPhantom = nonphysical | physical, PrimsNonPhantomAgents = nonphysical | physical | agent, diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 81de9ab..0db6fe3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -11381,7 +11381,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (checkNonPhysical) rayfilter |= RayFilterFlags.nonphysical; if (detectPhantom) - rayfilter |= RayFilterFlags.LSLPhanton; + rayfilter |= RayFilterFlags.LSLPhantom; Vector3 direction = dir * ( 1/dist); -- cgit v1.1 From 9822bb664b58693790201606126e3fd26f7a4d52 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 2 Feb 2013 02:57:38 +0000 Subject: Log missing assets on "fcache assets" found. This ignores references found by scanning LSL/notecard files since these are the source of false positives. This also changes UuidGatherer to reutn an AssetType.Unknown for embedded script/lsl references instead of Texture, since these are often not textures. This is added to help people in determining when they have missing assets such as textures, etc. In this case, one wants to run "fcache clear" first. --- .../Region/CoreModules/Asset/FlotsamAssetCache.cs | 41 ++++++++++++++-------- OpenSim/Region/Framework/Scenes/UuidGatherer.cs | 7 ++-- 2 files changed, 31 insertions(+), 17 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index 8e800cb..00af175 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -707,32 +707,43 @@ namespace OpenSim.Region.CoreModules.Asset { UuidGatherer gatherer = new UuidGatherer(m_AssetService); + HashSet uniqueUuids = new HashSet(); Dictionary assets = new Dictionary(); + foreach (Scene s in m_Scenes) { StampRegionStatusFile(s.RegionInfo.RegionID); s.ForEachSOG(delegate(SceneObjectGroup e) - { + { gatherer.GatherAssetUuids(e, assets); - }); - } - foreach (UUID assetID in assets.Keys) - { - string filename = GetFileName(assetID.ToString()); + foreach (UUID assetID in assets.Keys) + { + uniqueUuids.Add(assetID); - if (File.Exists(filename)) - { - File.SetLastAccessTime(filename, DateTime.Now); - } - else if (storeUncached) - { - m_AssetService.Get(assetID.ToString()); - } + string filename = GetFileName(assetID.ToString()); + + if (File.Exists(filename)) + { + File.SetLastAccessTime(filename, DateTime.Now); + } + else if (storeUncached) + { + AssetBase cachedAsset = m_AssetService.Get(assetID.ToString()); + if (cachedAsset == null && assets[assetID] != AssetType.Unknown) + m_log.DebugFormat( + "[FLOTSAM ASSET CACHE]: Could not find asset {0}, type {1} referenced by object {2} at {3} in scene {4} when pre-caching all scene assets", + assetID, assets[assetID], e.Name, e.AbsolutePosition, s.Name); + } + } + + assets.Clear(); + }); } - return assets.Keys.Count; + + return uniqueUuids.Count; } /// diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs index e238d01..c7cec41 100644 --- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs +++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs @@ -131,7 +131,10 @@ namespace OpenSim.Region.Framework.Scenes /// within this object). /// /// The scene object for which to gather assets - /// The assets gathered + /// + /// A dictionary which is populated with the asset UUIDs gathered and the type of that asset. + /// For assets where the type is not clear (e.g. UUIDs extracted from LSL and notecards), the type is Unknown. + /// public void GatherAssetUuids(SceneObjectGroup sceneObject, IDictionary assetUuids) { // m_log.DebugFormat( @@ -262,7 +265,7 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat("[ARCHIVER]: Recording {0} in text", uuid); // Assume AssetIDs embedded are textures. - assetUuids[uuid] = AssetType.Texture; + assetUuids[uuid] = AssetType.Unknown; } } } -- cgit v1.1 From 141ad829f448b9138b12be7cf99c834c1f3977ec Mon Sep 17 00:00:00 2001 From: BlueWall Date: Fri, 1 Feb 2013 21:57:49 -0500 Subject: Update assembly version numbers --- OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/ClientStack/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/DataSnapshot/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/Framework/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs | 2 +- .../Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/Physics/Manager/AssemblyInfo.cs | 2 +- OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/Physics/OdePlugin/AssemblyInfo.cs | 2 +- OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs | 2 +- OpenSim/Region/RegionCombinerModule/Properties/AssemblyInfo.cs | 2 +- .../ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs | 2 +- .../Region/ScriptEngine/Shared/Api/Runtime/Properties/AssemblyInfo.cs | 2 +- .../Shared/Api/Runtime/YieldProlog/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/UserStatistics/Properties/AssemblyInfo.cs | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs b/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs index 060a61c..d29a001 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs b/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs index af2f6f8..8f9dad3 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ClientStack/Properties/AssemblyInfo.cs b/OpenSim/Region/ClientStack/Properties/AssemblyInfo.cs index e72bd86..0b6ee2f 100644 --- a/OpenSim/Region/ClientStack/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ClientStack/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs b/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs index 5a8c4a2..f6353f9 100644 --- a/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs @@ -30,7 +30,7 @@ using Mono.Addins; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: Addin("OpenSim.Region.CoreModules", "0.1")] diff --git a/OpenSim/Region/DataSnapshot/Properties/AssemblyInfo.cs b/OpenSim/Region/DataSnapshot/Properties/AssemblyInfo.cs index b926264..0f083c7 100644 --- a/OpenSim/Region/DataSnapshot/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/DataSnapshot/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/Framework/Properties/AssemblyInfo.cs b/OpenSim/Region/Framework/Properties/AssemblyInfo.cs index 9b504c0..2a5828e 100644 --- a/OpenSim/Region/Framework/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/Framework/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs b/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs index 217b2d5..0065531 100644 --- a/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs @@ -30,7 +30,7 @@ using Mono.Addins; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: Addin("OpenSim.Region.OptionalModules", "0.1")] diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs index fb9cb66..6fd6f7e 100644 --- a/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs @@ -55,4 +55,4 @@ using System.Runtime.InteropServices; // You can specify all values by your own or you can build default build and revision // numbers with the '*' character (the default): -[assembly : AssemblyVersion("0.7.5.*")] +[assembly : AssemblyVersion("0.7.6.*")] diff --git a/OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs b/OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs index 0d1db3b..d240c71 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs index 5ff945d..cafd7f4 100644 --- a/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/Physics/Manager/AssemblyInfo.cs b/OpenSim/Region/Physics/Manager/AssemblyInfo.cs index 36b4235..5da3956 100644 --- a/OpenSim/Region/Physics/Manager/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/Manager/AssemblyInfo.cs @@ -55,4 +55,4 @@ using System.Runtime.InteropServices; // You can specify all values by your own or you can build default build and revision // numbers with the '*' character (the default): -[assembly : AssemblyVersion("0.7.5.*")] +[assembly : AssemblyVersion("0.7.6.*")] diff --git a/OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs b/OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs index 4cc1731..bd70296 100644 --- a/OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/Physics/OdePlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/OdePlugin/AssemblyInfo.cs index 3c4f06a..f477ed1 100644 --- a/OpenSim/Region/Physics/OdePlugin/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/OdePlugin/AssemblyInfo.cs @@ -55,4 +55,4 @@ using System.Runtime.InteropServices; // You can specify all values by your own or you can build default build and revision // numbers with the '*' character (the default): -[assembly : AssemblyVersion("0.7.5.*")] +[assembly : AssemblyVersion("0.7.6.*")] diff --git a/OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs index d07df02..4289863 100644 --- a/OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs @@ -55,4 +55,4 @@ using System.Runtime.InteropServices; // You can specify all values by your own or you can build default build and revision // numbers with the '*' character (the default): -[assembly : AssemblyVersion("0.7.5.*")] +[assembly : AssemblyVersion("0.7.6.*")] diff --git a/OpenSim/Region/RegionCombinerModule/Properties/AssemblyInfo.cs b/OpenSim/Region/RegionCombinerModule/Properties/AssemblyInfo.cs index 085eb59..ca945b5 100644 --- a/OpenSim/Region/RegionCombinerModule/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/RegionCombinerModule/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs index d173db0..3c01eec 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Properties/AssemblyInfo.cs index 573a803..b1825ac 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/Properties/AssemblyInfo.cs index f6d5d41..342dbff 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs index c65caa8..fd37753 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs index 470e1a1..74747a2 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ScriptEngine/Shared/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/Properties/AssemblyInfo.cs index e6e8777..d08b0a6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs index bd26a8b..a887171 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/UserStatistics/Properties/AssemblyInfo.cs b/OpenSim/Region/UserStatistics/Properties/AssemblyInfo.cs index 100cf99..caa6d4e 100644 --- a/OpenSim/Region/UserStatistics/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/UserStatistics/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] -- cgit v1.1 From 0d0bfa4dcd2fe61a489abc39e53755762d759490 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 2 Feb 2013 03:02:04 +0000 Subject: minor: change comment about assuming script references are textures in UuidGatherer since this is no longer the behaviour. --- OpenSim/Region/Framework/Scenes/UuidGatherer.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs index c7cec41..ad33607 100644 --- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs +++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs @@ -264,7 +264,8 @@ namespace OpenSim.Region.Framework.Scenes UUID uuid = new UUID(uuidMatch.Value); // m_log.DebugFormat("[ARCHIVER]: Recording {0} in text", uuid); - // Assume AssetIDs embedded are textures. + // Embedded asset references (if not false positives) could be for many types of asset, so we will + // label these as unknown. assetUuids[uuid] = AssetType.Unknown; } } -- cgit v1.1 From 0ab68f6c31c5540789bbd8311b4a87678e0276d3 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Fri, 1 Feb 2013 23:13:33 -0500 Subject: Revert "Update assembly version numbers" This reverts commit 141ad829f448b9138b12be7cf99c834c1f3977ec. --- OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/ClientStack/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/DataSnapshot/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/Framework/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs | 2 +- .../Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/Physics/Manager/AssemblyInfo.cs | 2 +- OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/Physics/OdePlugin/AssemblyInfo.cs | 2 +- OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs | 2 +- OpenSim/Region/RegionCombinerModule/Properties/AssemblyInfo.cs | 2 +- .../ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs | 2 +- .../Region/ScriptEngine/Shared/Api/Runtime/Properties/AssemblyInfo.cs | 2 +- .../Shared/Api/Runtime/YieldProlog/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/UserStatistics/Properties/AssemblyInfo.cs | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs b/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs index d29a001..060a61c 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.6.*")] +[assembly: AssemblyVersion("0.7.5.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs b/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs index 8f9dad3..af2f6f8 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.6.*")] +[assembly: AssemblyVersion("0.7.5.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ClientStack/Properties/AssemblyInfo.cs b/OpenSim/Region/ClientStack/Properties/AssemblyInfo.cs index 0b6ee2f..e72bd86 100644 --- a/OpenSim/Region/ClientStack/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ClientStack/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.6.*")] +[assembly: AssemblyVersion("0.7.5.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs b/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs index f6353f9..5a8c4a2 100644 --- a/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs @@ -30,7 +30,7 @@ using Mono.Addins; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.6.*")] +[assembly: AssemblyVersion("0.7.5.*")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: Addin("OpenSim.Region.CoreModules", "0.1")] diff --git a/OpenSim/Region/DataSnapshot/Properties/AssemblyInfo.cs b/OpenSim/Region/DataSnapshot/Properties/AssemblyInfo.cs index 0f083c7..b926264 100644 --- a/OpenSim/Region/DataSnapshot/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/DataSnapshot/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.6.*")] +[assembly: AssemblyVersion("0.7.5.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/Framework/Properties/AssemblyInfo.cs b/OpenSim/Region/Framework/Properties/AssemblyInfo.cs index 2a5828e..9b504c0 100644 --- a/OpenSim/Region/Framework/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/Framework/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.6.*")] +[assembly: AssemblyVersion("0.7.5.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs b/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs index 0065531..217b2d5 100644 --- a/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs @@ -30,7 +30,7 @@ using Mono.Addins; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.6.*")] +[assembly: AssemblyVersion("0.7.5.*")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: Addin("OpenSim.Region.OptionalModules", "0.1")] diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs index 6fd6f7e..fb9cb66 100644 --- a/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs @@ -55,4 +55,4 @@ using System.Runtime.InteropServices; // You can specify all values by your own or you can build default build and revision // numbers with the '*' character (the default): -[assembly : AssemblyVersion("0.7.6.*")] +[assembly : AssemblyVersion("0.7.5.*")] diff --git a/OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs b/OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs index d240c71..0d1db3b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.6.*")] +[assembly: AssemblyVersion("0.7.5.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs index cafd7f4..5ff945d 100644 --- a/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.7.6.*")] +[assembly: AssemblyVersion("0.7.5.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/Physics/Manager/AssemblyInfo.cs b/OpenSim/Region/Physics/Manager/AssemblyInfo.cs index 5da3956..36b4235 100644 --- a/OpenSim/Region/Physics/Manager/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/Manager/AssemblyInfo.cs @@ -55,4 +55,4 @@ using System.Runtime.InteropServices; // You can specify all values by your own or you can build default build and revision // numbers with the '*' character (the default): -[assembly : AssemblyVersion("0.7.6.*")] +[assembly : AssemblyVersion("0.7.5.*")] diff --git a/OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs b/OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs index bd70296..4cc1731 100644 --- a/OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.6.*")] +[assembly: AssemblyVersion("0.7.5.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/Physics/OdePlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/OdePlugin/AssemblyInfo.cs index f477ed1..3c4f06a 100644 --- a/OpenSim/Region/Physics/OdePlugin/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/OdePlugin/AssemblyInfo.cs @@ -55,4 +55,4 @@ using System.Runtime.InteropServices; // You can specify all values by your own or you can build default build and revision // numbers with the '*' character (the default): -[assembly : AssemblyVersion("0.7.6.*")] +[assembly : AssemblyVersion("0.7.5.*")] diff --git a/OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs index 4289863..d07df02 100644 --- a/OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs @@ -55,4 +55,4 @@ using System.Runtime.InteropServices; // You can specify all values by your own or you can build default build and revision // numbers with the '*' character (the default): -[assembly : AssemblyVersion("0.7.6.*")] +[assembly : AssemblyVersion("0.7.5.*")] diff --git a/OpenSim/Region/RegionCombinerModule/Properties/AssemblyInfo.cs b/OpenSim/Region/RegionCombinerModule/Properties/AssemblyInfo.cs index ca945b5..085eb59 100644 --- a/OpenSim/Region/RegionCombinerModule/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/RegionCombinerModule/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.6.*")] +[assembly: AssemblyVersion("0.7.5.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs index 3c01eec..d173db0 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.6.*")] +[assembly: AssemblyVersion("0.7.5.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Properties/AssemblyInfo.cs index b1825ac..573a803 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.6.*")] +[assembly: AssemblyVersion("0.7.5.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/Properties/AssemblyInfo.cs index 342dbff..f6d5d41 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.6.*")] +[assembly: AssemblyVersion("0.7.5.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs index fd37753..c65caa8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.6.*")] +[assembly: AssemblyVersion("0.7.5.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs index 74747a2..470e1a1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.6.*")] +[assembly: AssemblyVersion("0.7.5.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ScriptEngine/Shared/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/Properties/AssemblyInfo.cs index d08b0a6..e6e8777 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.6.*")] +[assembly: AssemblyVersion("0.7.5.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs index a887171..bd26a8b 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.6.*")] +[assembly: AssemblyVersion("0.7.5.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/UserStatistics/Properties/AssemblyInfo.cs b/OpenSim/Region/UserStatistics/Properties/AssemblyInfo.cs index caa6d4e..100cf99 100644 --- a/OpenSim/Region/UserStatistics/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/UserStatistics/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.6.*")] +[assembly: AssemblyVersion("0.7.5.*")] [assembly: AssemblyFileVersion("1.0.0.0")] -- cgit v1.1 From 6b0310b82973031fdf35c570bc69450f2f700eb7 Mon Sep 17 00:00:00 2001 From: teravus Date: Sun, 3 Feb 2013 07:44:45 -0500 Subject: Adds the ability to load more then one IClientNetworkServer thereby allowing additional client network servers at the same time. Use comma separated values in clientstack_plugin in your config. Additional plugins lying around shouldn't be picked up because the loader only loads configured dll assemblies and breaks at the first IClientNetworkServer found in the assembly. (the only new functionality is the ability to specify more in config). Note: The existing functionality also passes in a nini config.. and has a boolean to determine if the client network server should be initialized for a specific scene. --- OpenSim/Region/Application/OpenSimBase.cs | 37 ++++++----- OpenSim/Region/ClientStack/ClientStackManager.cs | 83 +++++++++++++++--------- 2 files changed, 73 insertions(+), 47 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index c3c87e7..f5c06df 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -316,7 +316,7 @@ namespace OpenSim /// /// /// - public IClientNetworkServer CreateRegion(RegionInfo regionInfo, bool portadd_flag, out IScene scene) + public List CreateRegion(RegionInfo regionInfo, bool portadd_flag, out IScene scene) { return CreateRegion(regionInfo, portadd_flag, false, out scene); } @@ -326,7 +326,7 @@ namespace OpenSim /// /// /// - public IClientNetworkServer CreateRegion(RegionInfo regionInfo, out IScene scene) + public List CreateRegion(RegionInfo regionInfo, out IScene scene) { return CreateRegion(regionInfo, false, true, out scene); } @@ -338,7 +338,7 @@ namespace OpenSim /// /// /// - public IClientNetworkServer CreateRegion(RegionInfo regionInfo, bool portadd_flag, bool do_post_init, out IScene mscene) + public List CreateRegion(RegionInfo regionInfo, bool portadd_flag, bool do_post_init, out IScene mscene) { int port = regionInfo.InternalEndPoint.Port; @@ -363,8 +363,8 @@ namespace OpenSim Util.XmlRpcCommand(proxyUrl, "AddPort", port, port + proxyOffset, regionInfo.ExternalHostName); } - IClientNetworkServer clientServer; - Scene scene = SetupScene(regionInfo, proxyOffset, Config, out clientServer); + List clientServers; + Scene scene = SetupScene(regionInfo, proxyOffset, Config, out clientServers); m_log.Info("[MODULES]: Loading Region's modules (old style)"); @@ -414,8 +414,11 @@ namespace OpenSim if (m_autoCreateClientStack) { - m_clientServers.Add(clientServer); - clientServer.Start(); + foreach (IClientNetworkServer clientserver in clientServers) + { + m_clientServers.Add(clientserver); + clientserver.Start(); + } } scene.EventManager.OnShutdown += delegate() { ShutdownRegion(scene); }; @@ -425,7 +428,7 @@ namespace OpenSim scene.Start(); scene.StartScripts(); - return clientServer; + return clientServers; } /// @@ -641,7 +644,7 @@ namespace OpenSim /// /// /// - protected Scene SetupScene(RegionInfo regionInfo, out IClientNetworkServer clientServer) + protected Scene SetupScene(RegionInfo regionInfo, out List clientServer) { return SetupScene(regionInfo, 0, null, out clientServer); } @@ -655,19 +658,20 @@ namespace OpenSim /// /// protected Scene SetupScene( - RegionInfo regionInfo, int proxyOffset, IConfigSource configSource, out IClientNetworkServer clientServer) + RegionInfo regionInfo, int proxyOffset, IConfigSource configSource, out List clientServer) { + List clientNetworkServers = null; + AgentCircuitManager circuitManager = new AgentCircuitManager(); IPAddress listenIP = regionInfo.InternalEndPoint.Address; //if (!IPAddress.TryParse(regionInfo.InternalEndPoint, out listenIP)) // listenIP = IPAddress.Parse("0.0.0.0"); uint port = (uint) regionInfo.InternalEndPoint.Port; - + IClientNetworkServer clientNetworkServer; if (m_autoCreateClientStack) { - clientServer - = m_clientStackManager.CreateServer( + clientNetworkServers = m_clientStackManager.CreateServers( listenIP, ref port, proxyOffset, regionInfo.m_allow_alternate_ports, configSource, circuitManager); } @@ -682,9 +686,12 @@ namespace OpenSim if (m_autoCreateClientStack) { - clientServer.AddScene(scene); + foreach (IClientNetworkServer clientnetserver in clientNetworkServers) + { + clientnetserver.AddScene(scene); + } } - + clientServer = clientNetworkServers; scene.LoadWorldMap(); scene.PhysicsScene = GetPhysicsScene(scene.RegionInfo.RegionName); diff --git a/OpenSim/Region/ClientStack/ClientStackManager.cs b/OpenSim/Region/ClientStack/ClientStackManager.cs index 84ea0b3..299aabd 100644 --- a/OpenSim/Region/ClientStack/ClientStackManager.cs +++ b/OpenSim/Region/ClientStack/ClientStackManager.cs @@ -26,6 +26,7 @@ */ using System; +using System.Collections.Generic; using System.Net; using System.Reflection; using log4net; @@ -38,39 +39,53 @@ namespace OpenSim.Region.ClientStack { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private Type plugin; - private Assembly pluginAssembly; + private List plugin = new List(); + private List pluginAssembly = new List(); - public ClientStackManager(string dllName) + public ClientStackManager(string pDllName) { - m_log.Info("[CLIENTSTACK]: Attempting to load " + dllName); - - try + List clientstacks = new List(); + if (pDllName.Contains(",")) + { + clientstacks = new List(pDllName.Split(',')); + } + else { - plugin = null; - pluginAssembly = Assembly.LoadFrom(dllName); + clientstacks.Add(pDllName); + } + foreach (string dllName in clientstacks) + { + m_log.Info("[CLIENTSTACK]: Attempting to load " + dllName); - foreach (Type pluginType in pluginAssembly.GetTypes()) + try { - if (pluginType.IsPublic) - { - Type typeInterface = pluginType.GetInterface("IClientNetworkServer", true); + //plugin = null; + Assembly itemAssembly = Assembly.LoadFrom(dllName); + pluginAssembly.Add(itemAssembly); - if (typeInterface != null) + foreach (Type pluginType in itemAssembly.GetTypes()) + { + if (pluginType.IsPublic) { - m_log.Info("[CLIENTSTACK]: Added IClientNetworkServer Interface"); - plugin = pluginType; - return; + Type typeInterface = pluginType.GetInterface("IClientNetworkServer", true); + + if (typeInterface != null) + { + m_log.Info("[CLIENTSTACK]: Added IClientNetworkServer Interface"); + plugin.Add(pluginType); + break; + } } } } - } catch (ReflectionTypeLoadException e) - { - foreach (Exception e2 in e.LoaderExceptions) + catch (ReflectionTypeLoadException e) { - m_log.Error(e2.ToString()); + foreach (Exception e2 in e.LoaderExceptions) + { + m_log.Error(e2.ToString()); + } + throw e; } - throw e; } } @@ -84,11 +99,11 @@ namespace OpenSim.Region.ClientStack /// /// /// - public IClientNetworkServer CreateServer( + public List CreateServers( IPAddress _listenIP, ref uint port, int proxyPortOffset, bool allow_alternate_port, AgentCircuitManager authenticateClass) { - return CreateServer( + return CreateServers( _listenIP, ref port, proxyPortOffset, allow_alternate_port, null, authenticateClass); } @@ -105,20 +120,24 @@ namespace OpenSim.Region.ClientStack /// /// /// - public IClientNetworkServer CreateServer( + public List CreateServers( IPAddress _listenIP, ref uint port, int proxyPortOffset, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager authenticateClass) { + List servers = new List(); if (plugin != null) { - IClientNetworkServer server = - (IClientNetworkServer)Activator.CreateInstance(pluginAssembly.GetType(plugin.ToString())); - - server.Initialise( - _listenIP, ref port, proxyPortOffset, allow_alternate_port, - configSource, authenticateClass); - - return server; + for (int i = 0; i < plugin.Count; i++) + { + IClientNetworkServer server = + (IClientNetworkServer) Activator.CreateInstance(pluginAssembly[i].GetType(plugin[i].ToString())); + + server.Initialise( + _listenIP, ref port, proxyPortOffset, allow_alternate_port, + configSource, authenticateClass); + servers.Add(server); + } + return servers; } m_log.Error("[CLIENTSTACK]: Couldn't initialize a new server"); -- cgit v1.1 From 1f1da230976451d30d920c237d53c699ba96b9d9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 5 Feb 2013 00:23:17 +0000 Subject: Bump version and assembly version numbers from 0.7.5 to 0.7.6 This is mostly Bluewall's work but I am also bumping the general version number OpenSimulator 0.7.5 remains in the release candidate stage. I'm doing this because master is significantly adding things that will not be in 0.7.5 This update should not cause issues with existing external binary DLLs because our DLLs do not have strong names and so the exact version match requirement is not in force. --- OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/ClientStack/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/DataSnapshot/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/Framework/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs | 2 +- .../Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/Physics/Manager/AssemblyInfo.cs | 2 +- OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/Physics/OdePlugin/AssemblyInfo.cs | 2 +- OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs | 2 +- OpenSim/Region/RegionCombinerModule/Properties/AssemblyInfo.cs | 2 +- .../ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs | 2 +- .../Region/ScriptEngine/Shared/Api/Runtime/Properties/AssemblyInfo.cs | 2 +- .../Shared/Api/Runtime/YieldProlog/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/UserStatistics/Properties/AssemblyInfo.cs | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs b/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs index 060a61c..d29a001 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs b/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs index af2f6f8..8f9dad3 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ClientStack/Properties/AssemblyInfo.cs b/OpenSim/Region/ClientStack/Properties/AssemblyInfo.cs index e72bd86..0b6ee2f 100644 --- a/OpenSim/Region/ClientStack/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ClientStack/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs b/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs index 5a8c4a2..f6353f9 100644 --- a/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs @@ -30,7 +30,7 @@ using Mono.Addins; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: Addin("OpenSim.Region.CoreModules", "0.1")] diff --git a/OpenSim/Region/DataSnapshot/Properties/AssemblyInfo.cs b/OpenSim/Region/DataSnapshot/Properties/AssemblyInfo.cs index b926264..0f083c7 100644 --- a/OpenSim/Region/DataSnapshot/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/DataSnapshot/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/Framework/Properties/AssemblyInfo.cs b/OpenSim/Region/Framework/Properties/AssemblyInfo.cs index 9b504c0..2a5828e 100644 --- a/OpenSim/Region/Framework/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/Framework/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs b/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs index 217b2d5..0065531 100644 --- a/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs @@ -30,7 +30,7 @@ using Mono.Addins; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: Addin("OpenSim.Region.OptionalModules", "0.1")] diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs index fb9cb66..6fd6f7e 100644 --- a/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs @@ -55,4 +55,4 @@ using System.Runtime.InteropServices; // You can specify all values by your own or you can build default build and revision // numbers with the '*' character (the default): -[assembly : AssemblyVersion("0.7.5.*")] +[assembly : AssemblyVersion("0.7.6.*")] diff --git a/OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs b/OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs index 0d1db3b..d240c71 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs index 5ff945d..cafd7f4 100644 --- a/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/Physics/Manager/AssemblyInfo.cs b/OpenSim/Region/Physics/Manager/AssemblyInfo.cs index 36b4235..5da3956 100644 --- a/OpenSim/Region/Physics/Manager/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/Manager/AssemblyInfo.cs @@ -55,4 +55,4 @@ using System.Runtime.InteropServices; // You can specify all values by your own or you can build default build and revision // numbers with the '*' character (the default): -[assembly : AssemblyVersion("0.7.5.*")] +[assembly : AssemblyVersion("0.7.6.*")] diff --git a/OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs b/OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs index 4cc1731..bd70296 100644 --- a/OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/Physics/OdePlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/OdePlugin/AssemblyInfo.cs index 3c4f06a..f477ed1 100644 --- a/OpenSim/Region/Physics/OdePlugin/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/OdePlugin/AssemblyInfo.cs @@ -55,4 +55,4 @@ using System.Runtime.InteropServices; // You can specify all values by your own or you can build default build and revision // numbers with the '*' character (the default): -[assembly : AssemblyVersion("0.7.5.*")] +[assembly : AssemblyVersion("0.7.6.*")] diff --git a/OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs index d07df02..4289863 100644 --- a/OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs @@ -55,4 +55,4 @@ using System.Runtime.InteropServices; // You can specify all values by your own or you can build default build and revision // numbers with the '*' character (the default): -[assembly : AssemblyVersion("0.7.5.*")] +[assembly : AssemblyVersion("0.7.6.*")] diff --git a/OpenSim/Region/RegionCombinerModule/Properties/AssemblyInfo.cs b/OpenSim/Region/RegionCombinerModule/Properties/AssemblyInfo.cs index 085eb59..ca945b5 100644 --- a/OpenSim/Region/RegionCombinerModule/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/RegionCombinerModule/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs index d173db0..3c01eec 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Properties/AssemblyInfo.cs index 573a803..b1825ac 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/Properties/AssemblyInfo.cs index f6d5d41..342dbff 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs index c65caa8..fd37753 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs index 470e1a1..74747a2 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ScriptEngine/Shared/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/Properties/AssemblyInfo.cs index e6e8777..d08b0a6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs index bd26a8b..a887171 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/UserStatistics/Properties/AssemblyInfo.cs b/OpenSim/Region/UserStatistics/Properties/AssemblyInfo.cs index 100cf99..caa6d4e 100644 --- a/OpenSim/Region/UserStatistics/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/UserStatistics/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.7.5.*")] +[assembly: AssemblyVersion("0.7.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")] -- cgit v1.1 From 562067eb16e2e6f4d097cae7795c5c86d4064db7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 5 Feb 2013 02:09:21 +0000 Subject: Fix bug where viewers would not see the "Module command functions not enabled" error if these were disabled and a viewer attempted to call one. This was not working because the shouter was wrongly signalled as an agent rather than a prim --- .../Shared/Api/Implementation/MOD_Api.cs | 64 +++++++++++++++++++++- 1 file changed, 62 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs index 9045672..2fe6948 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs @@ -29,8 +29,10 @@ using System; using System.Reflection; using System.Collections; using System.Collections.Generic; +using System.Reflection; using System.Runtime.Remoting.Lifetime; using System.Threading; +using log4net; using OpenMetaverse; using Nini.Config; using OpenSim; @@ -56,6 +58,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api [Serializable] public class MOD_Api : MarshalByRefObject, IMOD_Api, IScriptApi { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + internal IScriptEngine m_ScriptEngine; internal SceneObjectPart m_host; internal TaskInventoryItem m_item; @@ -109,8 +113,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (message.Length > 1023) message = message.Substring(0, 1023); - World.SimChat(Utils.StringToBytes(message), - ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, true); + World.SimChat( + Utils.StringToBytes(message), + ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, + m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, false); IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface(); wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message); @@ -124,6 +130,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// string result of the invocation public void modInvokeN(string fname, params object[] parms) { +// m_log.DebugFormat( +// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type", +// fname, +// string.Join(",", Array.ConvertAll(parms, o => o.ToString())), +// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); + Type returntype = m_comms.LookupReturnType(fname); if (returntype != typeof(string)) MODError(String.Format("return type mismatch for {0}",fname)); @@ -133,6 +145,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_String modInvokeS(string fname, params object[] parms) { +// m_log.DebugFormat( +// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type", +// fname, +// string.Join(",", Array.ConvertAll(parms, o => o.ToString())), +// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); + Type returntype = m_comms.LookupReturnType(fname); if (returntype != typeof(string)) MODError(String.Format("return type mismatch for {0}",fname)); @@ -143,6 +161,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer modInvokeI(string fname, params object[] parms) { +// m_log.DebugFormat( +// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type", +// fname, +// string.Join(",", Array.ConvertAll(parms, o => o.ToString())), +// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); + Type returntype = m_comms.LookupReturnType(fname); if (returntype != typeof(int)) MODError(String.Format("return type mismatch for {0}",fname)); @@ -153,6 +177,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Float modInvokeF(string fname, params object[] parms) { +// m_log.DebugFormat( +// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type", +// fname, +// string.Join(",", Array.ConvertAll(parms, o => o.ToString())), +// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); + Type returntype = m_comms.LookupReturnType(fname); if (returntype != typeof(float)) MODError(String.Format("return type mismatch for {0}",fname)); @@ -163,6 +193,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Key modInvokeK(string fname, params object[] parms) { +// m_log.DebugFormat( +// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type", +// fname, +// string.Join(",", Array.ConvertAll(parms, o => o.ToString())), +// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); + Type returntype = m_comms.LookupReturnType(fname); if (returntype != typeof(UUID)) MODError(String.Format("return type mismatch for {0}",fname)); @@ -173,6 +209,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector modInvokeV(string fname, params object[] parms) { +// m_log.DebugFormat( +// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type", +// fname, +// string.Join(",", Array.ConvertAll(parms, o => o.ToString())), +// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); + Type returntype = m_comms.LookupReturnType(fname); if (returntype != typeof(OpenMetaverse.Vector3)) MODError(String.Format("return type mismatch for {0}",fname)); @@ -183,6 +225,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Rotation modInvokeR(string fname, params object[] parms) { +// m_log.DebugFormat( +// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type", +// fname, +// string.Join(",", Array.ConvertAll(parms, o => o.ToString())), +// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); + Type returntype = m_comms.LookupReturnType(fname); if (returntype != typeof(OpenMetaverse.Quaternion)) MODError(String.Format("return type mismatch for {0}",fname)); @@ -193,6 +241,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_List modInvokeL(string fname, params object[] parms) { +// m_log.DebugFormat( +// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type", +// fname, +// string.Join(",", Array.ConvertAll(parms, o => o.ToString())), +// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); + Type returntype = m_comms.LookupReturnType(fname); if (returntype != typeof(object[])) MODError(String.Format("return type mismatch for {0}",fname)); @@ -250,6 +304,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return ""; } +// m_log.DebugFormat( +// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type", +// fname, +// string.Join(",", Array.ConvertAll(parms, o => o.ToString())), +// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); + Type[] signature = m_comms.LookupTypeSignature(fname); if (signature.Length != parms.Length) MODError(String.Format("wrong number of parameters to function {0}",fname)); -- cgit v1.1 From 2163bebeb40755b59b0b186f0d75aae5f16d8c84 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 5 Feb 2013 20:09:02 +0000 Subject: Try to fix uploaded mesh rotations - code from Avination code base. --- .../Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 39 +++++++++++++++------- 1 file changed, 27 insertions(+), 12 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index a534522..6ebe660 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -641,25 +641,40 @@ namespace OpenSim.Region.ClientStack.Linden grp.AddPart(prim); } - // Fix first link number + Vector3 rootPos = positions[0]; + if (grp.Parts.Length > 1) + { + // Fix first link number grp.RootPart.LinkNum++; - Vector3 rootPos = positions[0]; - grp.AbsolutePosition = rootPos; - for (int i = 0; i < positions.Count; i++) - { - Vector3 offset = positions[i] - rootPos; - grp.Parts[i].OffsetPosition = offset; - } + Quaternion rootRotConj = Quaternion.Conjugate(rotations[0]); + Quaternion tmprot; + Vector3 offset; + + // fix children rotations and positions + for (int i = 1; i < rotations.Count; i++) + { + tmprot = rotations[i]; + tmprot = rootRotConj * tmprot; + + grp.Parts[i].RotationOffset = tmprot; - for (int i = 0; i < rotations.Count; i++) + offset = positions[i] - rootPos; + + offset *= rootRotConj; + grp.Parts[i].OffsetPosition = offset; + } + + grp.AbsolutePosition = rootPos; + grp.UpdateGroupRotationR(rotations[0]); + } + else { - if (i != 0) - grp.Parts[i].RotationOffset = rotations[i]; + grp.AbsolutePosition = rootPos; + grp.UpdateGroupRotationR(rotations[0]); } - grp.UpdateGroupRotationR(rotations[0]); data = ASCIIEncoding.ASCII.GetBytes(SceneObjectSerializer.ToOriginalXmlFormat(grp)); } -- cgit v1.1 From 2104e4d4d4367c0516f52d53490abb02bb459745 Mon Sep 17 00:00:00 2001 From: teravus Date: Tue, 5 Feb 2013 18:46:02 -0500 Subject: * the root prim was being given an OffsetPosition in addition to setting the position when creating the root prim. The offset position caused the positioning code to re-move the root prim when you selected it and released it. --- OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index 6ebe660..568e216 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -617,7 +617,7 @@ namespace OpenSim.Region.ClientStack.Linden = new SceneObjectPart(owner_id, pbs, position, Quaternion.Identity, Vector3.Zero); prim.Scale = scale; - prim.OffsetPosition = position; + //prim.OffsetPosition = position; rotations.Add(rotation); positions.Add(position); prim.UUID = UUID.Random(); -- cgit v1.1 From 2b6d22691141b8cdccfc44d25890f99e1f72b3dd Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 2 Feb 2013 13:33:44 -0800 Subject: BulletSim: correct angular vertical attraction to properly correct an upside down vehicle. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 8ecf2ff..b51e9fd 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -1326,7 +1326,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // If verticalError.Z is negative, the vehicle is upside down. Add additional push. if (verticalError.Z < 0f) { - vertContributionV.X += PIOverFour; + vertContributionV.X += Math.Sign(vertContributionV.X) * PIOverFour; // vertContribution.Y -= PIOverFour; } -- cgit v1.1 From ad438ee59fce1b262135ef0f7cd1213f3a79df50 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 3 Feb 2013 16:08:09 -0800 Subject: BulletSim: rework some parameter setting implementation moving functionality that was in BSScene to BSParam. Remove unused parameters that were passed to the unmanaged code. Update DLLs and SOs for the new param block. --- OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs | 70 +++++------ .../Region/Physics/BulletSPlugin/BSApiTemplate.cs | 38 +----- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 131 ++++++++++++--------- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 58 ++++----- .../Region/Physics/BulletSPlugin/BSTerrainMesh.cs | 13 +- 5 files changed, 152 insertions(+), 158 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs index 04e77b8..39e62dd 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs @@ -1088,7 +1088,7 @@ private sealed class BulletConstraintXNA : BulletConstraint { CollisionWorld.WorldData.ParamData p = new CollisionWorld.WorldData.ParamData(); - p.angularDamping = o[0].XangularDamping; + p.angularDamping = BSParam.AngularDamping; p.defaultFriction = o[0].defaultFriction; p.defaultFriction = o[0].defaultFriction; p.defaultDensity = o[0].defaultDensity; @@ -1096,32 +1096,32 @@ private sealed class BulletConstraintXNA : BulletConstraint p.collisionMargin = o[0].collisionMargin; p.gravity = o[0].gravity; - p.linearDamping = o[0].XlinearDamping; - p.angularDamping = o[0].XangularDamping; - p.deactivationTime = o[0].XdeactivationTime; - p.linearSleepingThreshold = o[0].XlinearSleepingThreshold; - p.angularSleepingThreshold = o[0].XangularSleepingThreshold; - p.ccdMotionThreshold = o[0].XccdMotionThreshold; - p.ccdSweptSphereRadius = o[0].XccdSweptSphereRadius; - p.contactProcessingThreshold = o[0].XcontactProcessingThreshold; - - p.terrainImplementation = o[0].XterrainImplementation; - p.terrainFriction = o[0].XterrainFriction; - - p.terrainHitFraction = o[0].XterrainHitFraction; - p.terrainRestitution = o[0].XterrainRestitution; - p.terrainCollisionMargin = o[0].XterrainCollisionMargin; - - p.avatarFriction = o[0].XavatarFriction; - p.avatarStandingFriction = o[0].XavatarStandingFriction; - p.avatarDensity = o[0].XavatarDensity; - p.avatarRestitution = o[0].XavatarRestitution; - p.avatarCapsuleWidth = o[0].XavatarCapsuleWidth; - p.avatarCapsuleDepth = o[0].XavatarCapsuleDepth; - p.avatarCapsuleHeight = o[0].XavatarCapsuleHeight; - p.avatarContactProcessingThreshold = o[0].XavatarContactProcessingThreshold; + p.linearDamping = BSParam.LinearDamping; + p.angularDamping = BSParam.AngularDamping; + p.deactivationTime = BSParam.DeactivationTime; + p.linearSleepingThreshold = BSParam.LinearSleepingThreshold; + p.angularSleepingThreshold = BSParam.AngularSleepingThreshold; + p.ccdMotionThreshold = BSParam.CcdMotionThreshold; + p.ccdSweptSphereRadius = BSParam.CcdSweptSphereRadius; + p.contactProcessingThreshold = BSParam.ContactProcessingThreshold; + + p.terrainImplementation = BSParam.TerrainImplementation; + p.terrainFriction = BSParam.TerrainFriction; + + p.terrainHitFraction = BSParam.TerrainHitFraction; + p.terrainRestitution = BSParam.TerrainRestitution; + p.terrainCollisionMargin = BSParam.TerrainCollisionMargin; + + p.avatarFriction = BSParam.AvatarFriction; + p.avatarStandingFriction = BSParam.AvatarStandingFriction; + p.avatarDensity = BSParam.AvatarDensity; + p.avatarRestitution = BSParam.AvatarRestitution; + p.avatarCapsuleWidth = BSParam.AvatarCapsuleWidth; + p.avatarCapsuleDepth = BSParam.AvatarCapsuleDepth; + p.avatarCapsuleHeight = BSParam.AvatarCapsuleHeight; + p.avatarContactProcessingThreshold = BSParam.AvatarContactProcessingThreshold; - p.vehicleAngularDamping = o[0].XvehicleAngularDamping; + p.vehicleAngularDamping = BSParam.VehicleAngularDamping; p.maxPersistantManifoldPoolSize = o[0].maxPersistantManifoldPoolSize; p.maxCollisionAlgorithmPoolSize = o[0].maxCollisionAlgorithmPoolSize; @@ -1132,15 +1132,15 @@ private sealed class BulletConstraintXNA : BulletConstraint p.shouldEnableFrictionCaching = o[0].shouldEnableFrictionCaching; p.numberOfSolverIterations = o[0].numberOfSolverIterations; - p.linksetImplementation = o[0].XlinksetImplementation; - p.linkConstraintUseFrameOffset = o[0].XlinkConstraintUseFrameOffset; - p.linkConstraintEnableTransMotor = o[0].XlinkConstraintEnableTransMotor; - p.linkConstraintTransMotorMaxVel = o[0].XlinkConstraintTransMotorMaxVel; - p.linkConstraintTransMotorMaxForce = o[0].XlinkConstraintTransMotorMaxForce; - p.linkConstraintERP = o[0].XlinkConstraintERP; - p.linkConstraintCFM = o[0].XlinkConstraintCFM; - p.linkConstraintSolverIterations = o[0].XlinkConstraintSolverIterations; - p.physicsLoggingFrames = o[0].XphysicsLoggingFrames; + p.linksetImplementation = BSParam.LinksetImplementation; + p.linkConstraintUseFrameOffset = BSParam.LinkConstraintUseFrameOffset; + p.linkConstraintEnableTransMotor = BSParam.LinkConstraintEnableTransMotor; + p.linkConstraintTransMotorMaxVel = BSParam.LinkConstraintTransMotorMaxVel; + p.linkConstraintTransMotorMaxForce = BSParam.LinkConstraintTransMotorMaxForce; + p.linkConstraintERP = BSParam.LinkConstraintERP; + p.linkConstraintCFM = BSParam.LinkConstraintCFM; + p.linkConstraintSolverIterations = BSParam.LinkConstraintSolverIterations; + p.physicsLoggingFrames = o[0].physicsLoggingFrames; DefaultCollisionConstructionInfo ccci = new DefaultCollisionConstructionInfo(); DefaultCollisionConfiguration cci = new DefaultCollisionConfiguration(); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index abbd22c..5e06c1e 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs @@ -174,32 +174,6 @@ public struct ConfigurationParameters public float collisionMargin; public float gravity; - public float XlinearDamping; - public float XangularDamping; - public float XdeactivationTime; - public float XlinearSleepingThreshold; - public float XangularSleepingThreshold; - public float XccdMotionThreshold; - public float XccdSweptSphereRadius; - public float XcontactProcessingThreshold; - - public float XterrainImplementation; - public float XterrainFriction; - public float XterrainHitFraction; - public float XterrainRestitution; - public float XterrainCollisionMargin; - - public float XavatarFriction; - public float XavatarStandingFriction; - public float XavatarDensity; - public float XavatarRestitution; - public float XavatarCapsuleWidth; - public float XavatarCapsuleDepth; - public float XavatarCapsuleHeight; - public float XavatarContactProcessingThreshold; - - public float XvehicleAngularDamping; - public float maxPersistantManifoldPoolSize; public float maxCollisionAlgorithmPoolSize; public float shouldDisableContactPoolDynamicAllocation; @@ -208,17 +182,9 @@ public struct ConfigurationParameters public float shouldSplitSimulationIslands; public float shouldEnableFrictionCaching; public float numberOfSolverIterations; + public float useSingleSidedMeshes; - public float XlinksetImplementation; - public float XlinkConstraintUseFrameOffset; - public float XlinkConstraintEnableTransMotor; - public float XlinkConstraintTransMotorMaxVel; - public float XlinkConstraintTransMotorMaxForce; - public float XlinkConstraintERP; - public float XlinkConstraintCFM; - public float XlinkConstraintSolverIterations; - - public float XphysicsLoggingFrames; + public float physicsLoggingFrames; public const float numericTrue = 1f; public const float numericFalse = 0f; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 8c098b2..fbef7e7 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -68,6 +68,24 @@ public static class BSParam public static float TerrainRestitution { get; private set; } public static float TerrainCollisionMargin { get; private set; } + public static float DefaultFriction; + public static float DefaultDensity; + public static float DefaultRestitution; + public static float CollisionMargin; + public static float Gravity; + + // Physics Engine operation + public static float MaxPersistantManifoldPoolSize; + public static float MaxCollisionAlgorithmPoolSize; + public static float ShouldDisableContactPoolDynamicAllocation; + public static float ShouldForceUpdateAllAabbs; + public static float ShouldRandomizeSolverOrder; + public static float ShouldSplitSimulationIslands; + public static float ShouldEnableFrictionCaching; + public static float NumberOfSolverIterations; + public static bool UseSingleSidedMeshes { get { return UseSingleSidedMeshesF != ConfigurationParameters.numericFalse; } } + public static float UseSingleSidedMeshesF; + // Avatar parameters public static float AvatarFriction { get; private set; } public static float AvatarStandingFriction { get; private set; } @@ -287,29 +305,29 @@ public static class BSParam new ParameterDefn("DefaultFriction", "Friction factor used on new objects", 0.2f, - (s,cf,p,v) => { s.UnmanagedParams[0].defaultFriction = cf.GetFloat(p, v); }, - (s) => { return s.UnmanagedParams[0].defaultFriction; }, - (s,p,l,v) => { s.UnmanagedParams[0].defaultFriction = v; } ), + (s,cf,p,v) => { DefaultFriction = cf.GetFloat(p, v); }, + (s) => { return DefaultFriction; }, + (s,p,l,v) => { DefaultFriction = v; s.UnmanagedParams[0].defaultFriction = v; } ), new ParameterDefn("DefaultDensity", "Density for new objects" , 10.000006836f, // Aluminum g/cm3 - (s,cf,p,v) => { s.UnmanagedParams[0].defaultDensity = cf.GetFloat(p, v); }, - (s) => { return s.UnmanagedParams[0].defaultDensity; }, - (s,p,l,v) => { s.UnmanagedParams[0].defaultDensity = v; } ), + (s,cf,p,v) => { DefaultDensity = cf.GetFloat(p, v); }, + (s) => { return DefaultDensity; }, + (s,p,l,v) => { DefaultDensity = v; s.UnmanagedParams[0].defaultDensity = v; } ), new ParameterDefn("DefaultRestitution", "Bouncyness of an object" , 0f, - (s,cf,p,v) => { s.UnmanagedParams[0].defaultRestitution = cf.GetFloat(p, v); }, - (s) => { return s.UnmanagedParams[0].defaultRestitution; }, - (s,p,l,v) => { s.UnmanagedParams[0].defaultRestitution = v; } ), + (s,cf,p,v) => { DefaultRestitution = cf.GetFloat(p, v); }, + (s) => { return DefaultRestitution; }, + (s,p,l,v) => { DefaultRestitution = v; s.UnmanagedParams[0].defaultRestitution = v; } ), new ParameterDefn("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!)", 0.04f, - (s,cf,p,v) => { s.UnmanagedParams[0].collisionMargin = cf.GetFloat(p, v); }, - (s) => { return s.UnmanagedParams[0].collisionMargin; }, - (s,p,l,v) => { s.UnmanagedParams[0].collisionMargin = v; } ), + (s,cf,p,v) => { CollisionMargin = cf.GetFloat(p, v); }, + (s) => { return CollisionMargin; }, + (s,p,l,v) => { CollisionMargin = v; s.UnmanagedParams[0].collisionMargin = v; } ), new ParameterDefn("Gravity", "Vertical force of gravity (negative means down)", -9.80665f, - (s,cf,p,v) => { s.UnmanagedParams[0].gravity = cf.GetFloat(p, v); }, - (s) => { return s.UnmanagedParams[0].gravity; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{s.UnmanagedParams[0].gravity=x;}, p, PhysParameterEntry.APPLY_TO_NONE, v); }, + (s,cf,p,v) => { Gravity = cf.GetFloat(p, v); }, + (s) => { return Gravity; }, + (s,p,l,v) => { Gravity = v; s.UnmanagedParams[0].gravity = v; }, (s,o,v) => { s.PE.SetGravity(o.PhysBody, new Vector3(0f,0f,v)); } ), @@ -317,49 +335,49 @@ public static class BSParam 0f, (s,cf,p,v) => { LinearDamping = cf.GetFloat(p, v); }, (s) => { return LinearDamping; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{LinearDamping=x;}, p, l, v); }, + (s,p,l,v) => { LinearDamping = v; }, (s,o,v) => { s.PE.SetDamping(o.PhysBody, v, AngularDamping); } ), new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)", 0f, (s,cf,p,v) => { AngularDamping = cf.GetFloat(p, v); }, (s) => { return AngularDamping; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularDamping=x;}, p, l, v); }, + (s,p,l,v) => { AngularDamping = v; }, (s,o,v) => { s.PE.SetDamping(o.PhysBody, LinearDamping, v); } ), new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static", 0.2f, (s,cf,p,v) => { DeactivationTime = cf.GetFloat(p, v); }, (s) => { return DeactivationTime; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{DeactivationTime=x;}, p, l, v); }, + (s,p,l,v) => { DeactivationTime = v; }, (s,o,v) => { s.PE.SetDeactivationTime(o.PhysBody, v); } ), new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static", 0.8f, (s,cf,p,v) => { LinearSleepingThreshold = cf.GetFloat(p, v); }, (s) => { return LinearSleepingThreshold; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{LinearSleepingThreshold=x;}, p, l, v); }, + (s,p,l,v) => { LinearSleepingThreshold = v;}, (s,o,v) => { s.PE.SetSleepingThresholds(o.PhysBody, v, v); } ), new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static", 1.0f, (s,cf,p,v) => { AngularSleepingThreshold = cf.GetFloat(p, v); }, (s) => { return AngularSleepingThreshold; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularSleepingThreshold=x;}, p, l, v); }, + (s,p,l,v) => { AngularSleepingThreshold = v;}, (s,o,v) => { s.PE.SetSleepingThresholds(o.PhysBody, v, v); } ), new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" , 0.0f, // set to zero to disable (s,cf,p,v) => { CcdMotionThreshold = cf.GetFloat(p, v); }, (s) => { return CcdMotionThreshold; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdMotionThreshold=x;}, p, l, v); }, + (s,p,l,v) => { CcdMotionThreshold = v;}, (s,o,v) => { s.PE.SetCcdMotionThreshold(o.PhysBody, v); } ), new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" , 0.2f, (s,cf,p,v) => { CcdSweptSphereRadius = cf.GetFloat(p, v); }, (s) => { return CcdSweptSphereRadius; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdSweptSphereRadius=x;}, p, l, v); }, + (s,p,l,v) => { CcdSweptSphereRadius = v;}, (s,o,v) => { s.PE.SetCcdSweptSphereRadius(o.PhysBody, v); } ), new ParameterDefn("ContactProcessingThreshold", "Distance above which contacts can be discarded (0 means no discard)" , 0.0f, (s,cf,p,v) => { ContactProcessingThreshold = cf.GetFloat(p, v); }, (s) => { return ContactProcessingThreshold; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{ContactProcessingThreshold=x;}, p, l, v); }, + (s,p,l,v) => { ContactProcessingThreshold = v;}, (s,o,v) => { s.PE.SetContactProcessingThreshold(o.PhysBody, v); } ), new ParameterDefn("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)", @@ -392,7 +410,7 @@ public static class BSParam 0.2f, (s,cf,p,v) => { AvatarFriction = cf.GetFloat(p, v); }, (s) => { return AvatarFriction; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarFriction=x;}, p, l, v); } ), + (s,p,l,v) => { AvatarFriction = v; } ), new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", 10.0f, (s,cf,p,v) => { AvatarStandingFriction = cf.GetFloat(p, v); }, @@ -407,32 +425,32 @@ public static class BSParam 3.5f, (s,cf,p,v) => { AvatarDensity = cf.GetFloat(p, v); }, (s) => { return AvatarDensity; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarDensity=x;}, p, l, v); } ), + (s,p,l,v) => { AvatarDensity = v; } ), new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.", 0f, (s,cf,p,v) => { AvatarRestitution = cf.GetFloat(p, v); }, (s) => { return AvatarRestitution; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarRestitution=x;}, p, l, v); } ), + (s,p,l,v) => { AvatarRestitution = v; } ), new ParameterDefn("AvatarCapsuleWidth", "The distance between the sides of the avatar capsule", 0.6f, (s,cf,p,v) => { AvatarCapsuleWidth = cf.GetFloat(p, v); }, (s) => { return AvatarCapsuleWidth; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleWidth=x;}, p, l, v); } ), + (s,p,l,v) => { AvatarCapsuleWidth = v; } ), new ParameterDefn("AvatarCapsuleDepth", "The distance between the front and back of the avatar capsule", 0.45f, (s,cf,p,v) => { AvatarCapsuleDepth = cf.GetFloat(p, v); }, (s) => { return AvatarCapsuleDepth; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleDepth=x;}, p, l, v); } ), + (s,p,l,v) => { AvatarCapsuleDepth = v; } ), new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar", 1.5f, (s,cf,p,v) => { AvatarCapsuleHeight = cf.GetFloat(p, v); }, (s) => { return AvatarCapsuleHeight; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarCapsuleHeight=x;}, p, l, v); } ), + (s,p,l,v) => { AvatarCapsuleHeight = v; } ), new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", 0.1f, (s,cf,p,v) => { AvatarContactProcessingThreshold = cf.GetFloat(p, v); }, (s) => { return AvatarContactProcessingThreshold; }, - (s,p,l,v) => { s.UpdateParameterObject((x)=>{AvatarContactProcessingThreshold=x;}, p, l, v); } ), + (s,p,l,v) => { AvatarContactProcessingThreshold = v; } ), new ParameterDefn("AvatarStepHeight", "Height of a step obstacle to consider step correction", 0.3f, (s,cf,p,v) => { AvatarStepHeight = cf.GetFloat(p, v); }, @@ -497,44 +515,49 @@ public static class BSParam new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", 0f, - (s,cf,p,v) => { s.UnmanagedParams[0].maxPersistantManifoldPoolSize = cf.GetFloat(p, v); }, - (s) => { return s.UnmanagedParams[0].maxPersistantManifoldPoolSize; }, - (s,p,l,v) => { s.UnmanagedParams[0].maxPersistantManifoldPoolSize = v; } ), + (s,cf,p,v) => { MaxPersistantManifoldPoolSize = cf.GetFloat(p, v); }, + (s) => { return MaxPersistantManifoldPoolSize; }, + (s,p,l,v) => { MaxPersistantManifoldPoolSize = v; s.UnmanagedParams[0].maxPersistantManifoldPoolSize = v; } ), new ParameterDefn("MaxCollisionAlgorithmPoolSize", "Number of collisions pooled (0 means default of 4096)", 0f, - (s,cf,p,v) => { s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = cf.GetFloat(p, v); }, - (s) => { return s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize; }, - (s,p,l,v) => { s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = v; } ), + (s,cf,p,v) => { MaxCollisionAlgorithmPoolSize = cf.GetFloat(p, v); }, + (s) => { return MaxCollisionAlgorithmPoolSize; }, + (s,p,l,v) => { MaxCollisionAlgorithmPoolSize = v; s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = v; } ), new ParameterDefn("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count", ConfigurationParameters.numericFalse, - (s,cf,p,v) => { s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, - (s) => { return s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation; }, - (s,p,l,v) => { s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = v; } ), + (s,cf,p,v) => { ShouldDisableContactPoolDynamicAllocation = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return ShouldDisableContactPoolDynamicAllocation; }, + (s,p,l,v) => { ShouldDisableContactPoolDynamicAllocation = v; s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = v; } ), new ParameterDefn("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step", ConfigurationParameters.numericFalse, - (s,cf,p,v) => { s.UnmanagedParams[0].shouldForceUpdateAllAabbs = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, - (s) => { return s.UnmanagedParams[0].shouldForceUpdateAllAabbs; }, - (s,p,l,v) => { s.UnmanagedParams[0].shouldForceUpdateAllAabbs = v; } ), + (s,cf,p,v) => { ShouldForceUpdateAllAabbs = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return ShouldForceUpdateAllAabbs; }, + (s,p,l,v) => { ShouldForceUpdateAllAabbs = v; s.UnmanagedParams[0].shouldForceUpdateAllAabbs = v; } ), new ParameterDefn("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction", ConfigurationParameters.numericTrue, - (s,cf,p,v) => { s.UnmanagedParams[0].shouldRandomizeSolverOrder = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, - (s) => { return s.UnmanagedParams[0].shouldRandomizeSolverOrder; }, - (s,p,l,v) => { s.UnmanagedParams[0].shouldRandomizeSolverOrder = v; } ), + (s,cf,p,v) => { ShouldRandomizeSolverOrder = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return ShouldRandomizeSolverOrder; }, + (s,p,l,v) => { ShouldRandomizeSolverOrder = v; s.UnmanagedParams[0].shouldRandomizeSolverOrder = v; } ), new ParameterDefn("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands", ConfigurationParameters.numericTrue, - (s,cf,p,v) => { s.UnmanagedParams[0].shouldSplitSimulationIslands = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, - (s) => { return s.UnmanagedParams[0].shouldSplitSimulationIslands; }, - (s,p,l,v) => { s.UnmanagedParams[0].shouldSplitSimulationIslands = v; } ), + (s,cf,p,v) => { ShouldSplitSimulationIslands = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return ShouldSplitSimulationIslands; }, + (s,p,l,v) => { ShouldSplitSimulationIslands = v; s.UnmanagedParams[0].shouldSplitSimulationIslands = v; } ), new ParameterDefn("ShouldEnableFrictionCaching", "Enable friction computation caching", ConfigurationParameters.numericTrue, - (s,cf,p,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, - (s) => { return s.UnmanagedParams[0].shouldEnableFrictionCaching; }, - (s,p,l,v) => { s.UnmanagedParams[0].shouldEnableFrictionCaching = v; } ), + (s,cf,p,v) => { ShouldEnableFrictionCaching = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return ShouldEnableFrictionCaching; }, + (s,p,l,v) => { ShouldEnableFrictionCaching = v; s.UnmanagedParams[0].shouldEnableFrictionCaching = v; } ), new ParameterDefn("NumberOfSolverIterations", "Number of internal iterations (0 means default)", 0f, // zero says use Bullet default - (s,cf,p,v) => { s.UnmanagedParams[0].numberOfSolverIterations = cf.GetFloat(p, v); }, - (s) => { return s.UnmanagedParams[0].numberOfSolverIterations; }, - (s,p,l,v) => { s.UnmanagedParams[0].numberOfSolverIterations = v; } ), + (s,cf,p,v) => { NumberOfSolverIterations = cf.GetFloat(p, v); }, + (s) => { return NumberOfSolverIterations; }, + (s,p,l,v) => { NumberOfSolverIterations = v; s.UnmanagedParams[0].numberOfSolverIterations = v; } ), + new ParameterDefn("UseSingleSidedMeshes", "Whether to compute collisions based on single sided meshes.", + ConfigurationParameters.numericTrue, + (s,cf,p,v) => { UseSingleSidedMeshesF = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s) => { return UseSingleSidedMeshesF; }, + (s,p,l,v) => { UseSingleSidedMeshesF = v; s.UnmanagedParams[0].useSingleSidedMeshes = v; } ), new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", (float)BSLinkset.LinksetImplementation.Compound, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index a4690ba..6cd72f2 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -882,41 +882,41 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters BSParam.ParameterDefn theParam; if (BSParam.TryGetParameter(parm, out theParam)) { + // Set the value in the C# code theParam.setter(this, parm, localID, val); + + // Optionally set the parameter in the unmanaged code + if (theParam.onObject != null) + { + // update all the localIDs specified + // If the local ID is APPLY_TO_NONE, just change the default value + // If the localID is APPLY_TO_ALL change the default value and apply the new value to all the lIDs + // If the localID is a specific object, apply the parameter change to only that object + List objectIDs = new List(); + switch (localID) + { + case PhysParameterEntry.APPLY_TO_NONE: + // This will cause a call into the physical world if some operation is specified (SetOnObject). + objectIDs.Add(TERRAIN_ID); + TaintedUpdateParameter(parm, objectIDs, val); + break; + case PhysParameterEntry.APPLY_TO_ALL: + lock (PhysObjects) objectIDs = new List(PhysObjects.Keys); + TaintedUpdateParameter(parm, objectIDs, val); + break; + default: + // setting only one localID + objectIDs.Add(localID); + TaintedUpdateParameter(parm, objectIDs, val); + break; + } + } + ret = true; } return ret; } - // update all the localIDs specified - // If the local ID is APPLY_TO_NONE, just change the default value - // If the localID is APPLY_TO_ALL change the default value and apply the new value to all the lIDs - // If the localID is a specific object, apply the parameter change to only that object - internal delegate void AssignVal(float x); - internal void UpdateParameterObject(AssignVal setDefault, string parm, uint localID, float val) - { - List objectIDs = new List(); - switch (localID) - { - case PhysParameterEntry.APPLY_TO_NONE: - setDefault(val); // setting only the default value - // This will cause a call into the physical world if some operation is specified (SetOnObject). - objectIDs.Add(TERRAIN_ID); - TaintedUpdateParameter(parm, objectIDs, val); - break; - case PhysParameterEntry.APPLY_TO_ALL: - setDefault(val); // setting ALL also sets the default value - lock (PhysObjects) objectIDs = new List(PhysObjects.Keys); - TaintedUpdateParameter(parm, objectIDs, val); - break; - default: - // setting only one localID - objectIDs.Add(localID); - TaintedUpdateParameter(parm, objectIDs, val); - break; - } - } - // schedule the actual updating of the paramter to when the phys engine is not busy private void TaintedUpdateParameter(string parm, List lIDs, float val) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index 8244f02..d7e800d 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs @@ -96,7 +96,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys { // DISASTER!! PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape", ID); - physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain mesh! base={1}", LogHeader, TerrainBase); + PhysicsScene.Logger.ErrorFormat("{0} Failed creation of terrain mesh! base={1}", LogHeader, TerrainBase); // Something is very messed up and a crash is in our future. return; } @@ -108,7 +108,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys if (!m_terrainBody.HasPhysicalBody) { // DISASTER!! - physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain body! base={1}", LogHeader, TerrainBase); + PhysicsScene.Logger.ErrorFormat("{0} Failed creation of terrain body! base={1}", LogHeader, TerrainBase); // Something is very messed up and a crash is in our future. return; } @@ -131,6 +131,12 @@ public sealed class BSTerrainMesh : BSTerrainPhys m_terrainBody.collisionType = CollisionType.Terrain; m_terrainBody.ApplyCollisionMask(PhysicsScene); + if (BSParam.UseSingleSidedMeshes) + { + PhysicsScene.DetailLog("{0},BSTerrainMesh.settingCustomMaterial", id); + PhysicsScene.PE.AddToCollisionFlags(m_terrainBody, CollisionFlags.CF_CUSTOM_MATERIAL_CALLBACK); + } + // Make it so the terrain will not move or be considered for movement. PhysicsScene.PE.ForceActivationState(m_terrainBody, ActivationState.DISABLE_SIMULATION); } @@ -176,8 +182,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys // Convert the passed heightmap to mesh information suitable for CreateMeshShape2(). // Return 'true' if successfully created. - public static bool ConvertHeightmapToMesh( - BSScene physicsScene, + public static bool ConvertHeightmapToMesh( BSScene physicsScene, float[] heightMap, int sizeX, int sizeY, // parameters of incoming heightmap float extentX, float extentY, // zero based range for output vertices Vector3 extentBase, // base to be added to all vertices -- cgit v1.1 From 13233da66c96e9fb8b4f8c5c98aa34c8b6ccf1b7 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 3 Feb 2013 21:48:11 -0800 Subject: BulletSim: add debugging looking for doorway sculpty problems --- .../Physics/BulletSPlugin/BSShapeCollection.cs | 30 +++++++++++++++++++--- .../Region/Physics/BulletSPlugin/BulletSimData.cs | 4 +++ .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 3 +++ 3 files changed, 33 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 9febd90..0af8e13 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -622,7 +622,6 @@ public sealed class BSShapeCollection : IDisposable private BulletShape CreatePhysicalMesh(string objName, System.UInt64 newMeshKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) { BulletShape newShape = new BulletShape(); - IMesh meshData = null; MeshDesc meshDesc; if (Meshes.TryGetValue(newMeshKey, out meshDesc)) @@ -632,7 +631,7 @@ public sealed class BSShapeCollection : IDisposable } else { - meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false); + IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false); if (meshData != null) { @@ -648,8 +647,31 @@ public sealed class BSShapeCollection : IDisposable verticesAsFloats[vi++] = vv.Z; } - // m_log.DebugFormat("{0}: BSShapeCollection.CreatePhysicalMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}", - // LogHeader, prim.LocalID, newMeshKey, indices.Length, vertices.Count); + // DetailLog("{0},BSShapeCollection.CreatePhysicalMesh,key={1},lod={2},size={3},indices={4},vertices={5}", + // BSScene.DetailLogZero, newMeshKey.ToString("X"), lod, size, indices.Length, vertices.Count); + + /* + // DEBUG DEBUG + for (int ii = 0; ii < indices.Length; ii += 3) + { + DetailLog("{0,3}: {1,3},{2,3},{3,3}: <{4,10},{5,10},{6,10}>, <{7,10},{8,10},{9,10}>, <{10,10},{11,10},{12,10}>", + ii / 3, + indices[ii + 0], + indices[ii + 1], + indices[ii + 2], + verticesAsFloats[indices[ii+0] + 0], + verticesAsFloats[indices[ii+0] + 1], + verticesAsFloats[indices[ii+0] + 2], + verticesAsFloats[indices[ii+1] + 0], + verticesAsFloats[indices[ii+1] + 1], + verticesAsFloats[indices[ii+1] + 2], + verticesAsFloats[indices[ii+2] + 0], + verticesAsFloats[indices[ii+2] + 1], + verticesAsFloats[indices[ii+2] + 2] + ); + } + // END DEBUG DEBUG + */ newShape = PhysicsScene.PE.CreateMeshShape(PhysicsScene.World, indices.GetLength(0), indices, vertices.Count, verticesAsFloats); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs index c7a2f7e..8012d91 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs @@ -217,6 +217,10 @@ public static class BulletSimData { // Map of collisionTypes to flags for collision groups and masks. +// An object's 'group' is the collison groups this object belongs to +// An object's 'filter' is the groups another object has to belong to in order to collide with me +// A collision happens if ((obj1.group & obj2.filter) != 0) || ((obj2.group & obj1.filter) != 0) +// // As mentioned above, don't use the CollisionFilterGroups definitions directly in the code // but, instead, use references to this dictionary. Finding and debugging // collision flag problems will be made easier. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index a3b3556..1eaa523 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -128,6 +128,9 @@ Physical and phantom will drop through the terrain LINKSETS ====================================================== Child prims do not report collisions +Allow children of a linkset to be phantom: + http://opensim-dev.2196679.n2.nabble.com/Setting-a-single-child-prim-to-Phantom-tp7578513.html + Add OS_STATUS_PHANTOM_PRIM to llSetLinkPrimitaveParamsFast. Editing a child of a linkset causes the child to go phantom Move a child prim once when it is physical and can never move it again without it going phantom Offset the center of the linkset to be the geometric center of all the prims -- cgit v1.1 From dce9e323f4f0fdccd2f34266e870de9cbcebd2f0 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 5 Feb 2013 16:51:02 -0800 Subject: BulletSim: remove degenerate triangles from meshes. This fixes the invisible barriers in sculptie doorways (Mantis 6529). Bump up level-of-detail for physical meshes to 32 (the max). This fixes the invisible barriers that showed up in prim cut arches. NOTE: the default LOD values are removed from OpenSimDefaults.ini. If you don't change your OpenSimDefaults.ini, you will continue to see the arch problem. --- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 18 +++-- .../Physics/BulletSPlugin/BSShapeCollection.cs | 81 ++++++++++++---------- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 2 + OpenSim/Region/Physics/Manager/IMesher.cs | 1 + OpenSim/Region/Physics/Meshing/Mesh.cs | 2 +- 5 files changed, 59 insertions(+), 45 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index fbef7e7..bdd9ce4 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -39,6 +39,7 @@ public static class BSParam { // Level of Detail values kept as float because that's what the Meshmerizer wants public static float MeshLOD { get; private set; } + public static float MeshCircularLOD { get; private set; } public static float MeshMegaPrimLOD { get; private set; } public static float MeshMegaPrimThreshold { get; private set; } public static float SculptLOD { get; private set; } @@ -219,20 +220,25 @@ public static class BSParam (s,p,l,v) => { ShouldUseHullsForPhysicalObjects = BSParam.BoolNumeric(v); } ), new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", - 8f, + 32f, (s,cf,p,v) => { MeshLOD = (float)cf.GetInt(p, (int)v); }, (s) => { return MeshLOD; }, (s,p,l,v) => { MeshLOD = v; } ), - new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters", - 16f, - (s,cf,p,v) => { MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); }, - (s) => { return MeshMegaPrimLOD; }, - (s,p,l,v) => { MeshMegaPrimLOD = v; } ), + new ParameterDefn("MeshLevelOfDetailCircular", "Level of detail for prims with circular cuts or shapes", + 32f, + (s,cf,p,v) => { MeshCircularLOD = (float)cf.GetInt(p, (int)v); }, + (s) => { return MeshCircularLOD; }, + (s,p,l,v) => { MeshCircularLOD = v; } ), new ParameterDefn("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD", 10f, (s,cf,p,v) => { MeshMegaPrimThreshold = (float)cf.GetInt(p, (int)v); }, (s) => { return MeshMegaPrimThreshold; }, (s,p,l,v) => { MeshMegaPrimThreshold = v; } ), + new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters", + 32f, + (s,cf,p,v) => { MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); }, + (s) => { return MeshMegaPrimLOD; }, + (s,p,l,v) => { MeshMegaPrimLOD = v; } ), new ParameterDefn("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)", 32f, (s,cf,p,v) => { SculptLOD = (float)cf.GetInt(p, (int)v); }, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 0af8e13..f17e513 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -602,8 +602,8 @@ public sealed class BSShapeCollection : IDisposable if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_MESH) return false; - if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToMesh,create,oldKey={1},newKey={2}", - prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X")); + if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToMesh,create,oldKey={1},newKey={2},size={3},lod={4}", + prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X"), prim.Size, lod); // Since we're recreating new, get rid of the reference to the previous shape DereferenceShape(prim.PhysShape, shapeCallback); @@ -631,50 +631,50 @@ public sealed class BSShapeCollection : IDisposable } else { - IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false); + IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, + false, // say it is not physical so a bounding box is not built + false // do not cache the mesh and do not use previously built versions + ); if (meshData != null) { - int[] indices = meshData.getIndexListAsInt(); - List vertices = meshData.getVertexList(); - - float[] verticesAsFloats = new float[vertices.Count * 3]; - int vi = 0; - foreach (OMV.Vector3 vv in vertices) - { - verticesAsFloats[vi++] = vv.X; - verticesAsFloats[vi++] = vv.Y; - verticesAsFloats[vi++] = vv.Z; - } - // DetailLog("{0},BSShapeCollection.CreatePhysicalMesh,key={1},lod={2},size={3},indices={4},vertices={5}", - // BSScene.DetailLogZero, newMeshKey.ToString("X"), lod, size, indices.Length, vertices.Count); - - /* - // DEBUG DEBUG - for (int ii = 0; ii < indices.Length; ii += 3) + int[] indices = meshData.getIndexListAsInt(); + // int realIndicesIndex = indices.Length; + float[] verticesAsFloats = meshData.getVertexListAsFloat(); + + // Remove degenerate triangles. These are triangles with two of the vertices + // are the same. This is complicated by the problem that vertices are not + // made unique in sculpties so we have to compare the values in the vertex. + int realIndicesIndex = 0; + for (int tri = 0; tri < indices.Length; tri += 3) { - DetailLog("{0,3}: {1,3},{2,3},{3,3}: <{4,10},{5,10},{6,10}>, <{7,10},{8,10},{9,10}>, <{10,10},{11,10},{12,10}>", - ii / 3, - indices[ii + 0], - indices[ii + 1], - indices[ii + 2], - verticesAsFloats[indices[ii+0] + 0], - verticesAsFloats[indices[ii+0] + 1], - verticesAsFloats[indices[ii+0] + 2], - verticesAsFloats[indices[ii+1] + 0], - verticesAsFloats[indices[ii+1] + 1], - verticesAsFloats[indices[ii+1] + 2], - verticesAsFloats[indices[ii+2] + 0], - verticesAsFloats[indices[ii+2] + 1], - verticesAsFloats[indices[ii+2] + 2] - ); + int v1 = indices[tri + 0] * 3; + int v2 = indices[tri + 1] * 3; + int v3 = indices[tri + 2] * 3; + if (!( ( verticesAsFloats[v1 + 0] == verticesAsFloats[v2 + 0] + && verticesAsFloats[v1 + 1] == verticesAsFloats[v2 + 1] + && verticesAsFloats[v1 + 2] == verticesAsFloats[v2 + 2] ) + || ( verticesAsFloats[v2 + 0] == verticesAsFloats[v3 + 0] + && verticesAsFloats[v2 + 1] == verticesAsFloats[v3 + 1] + && verticesAsFloats[v2 + 2] == verticesAsFloats[v3 + 2] ) + || ( verticesAsFloats[v1 + 0] == verticesAsFloats[v3 + 0] + && verticesAsFloats[v1 + 1] == verticesAsFloats[v3 + 1] + && verticesAsFloats[v1 + 2] == verticesAsFloats[v3 + 2] ) ) + ) + { + // None of the vertices of the triangles are the same. This is a good triangle; + indices[realIndicesIndex + 0] = indices[tri + 0]; + indices[realIndicesIndex + 1] = indices[tri + 1]; + indices[realIndicesIndex + 2] = indices[tri + 2]; + realIndicesIndex += 3; + } } - // END DEBUG DEBUG - */ + DetailLog("{0},BSShapeCollection.CreatePhysicalMesh,origTri={1},realTri={2},numVerts={3}", + BSScene.DetailLogZero, indices.Length / 3, realIndicesIndex / 3, verticesAsFloats.Length / 3); newShape = PhysicsScene.PE.CreateMeshShape(PhysicsScene.World, - indices.GetLength(0), indices, vertices.Count, verticesAsFloats); + realIndicesIndex, indices, verticesAsFloats.Length/3, verticesAsFloats); } } newShape.shapeKey = newMeshKey; @@ -853,6 +853,11 @@ public sealed class BSShapeCollection : IDisposable { // level of detail based on size and type of the object float lod = BSParam.MeshLOD; + + // prims with curvy internal cuts need higher lod + if (pbs.HollowShape == HollowShape.Circle) + lod = BSParam.MeshCircularLOD; + if (pbs.SculptEntry) lod = BSParam.SculptLOD; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 1eaa523..bda7c47 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -65,6 +65,8 @@ Vehicle attributes are not restored when a vehicle is rezzed on region creation GENERAL TODO LIST: ================================================= +Level-of-detail for mesh creation. Prims with circular interiors require lod of 32. + Is much saved with lower LODs? At the moment, all set to 32. Collisions are inconsistant: arrows are supposed to hit and report collision. Often don't. If arrow show at prim, collision reported about 1/3 of time. If collision reported, both arrow and prim report it. The arrow bounces off the prim 9 out of 10 times. diff --git a/OpenSim/Region/Physics/Manager/IMesher.cs b/OpenSim/Region/Physics/Manager/IMesher.cs index 10c4bd3..2e7bb5d 100644 --- a/OpenSim/Region/Physics/Manager/IMesher.cs +++ b/OpenSim/Region/Physics/Manager/IMesher.cs @@ -59,6 +59,7 @@ namespace OpenSim.Region.Physics.Manager List getVertexList(); int[] getIndexListAsInt(); int[] getIndexListAsIntLocked(); + float[] getVertexListAsFloat(); float[] getVertexListAsFloatLocked(); void getIndexListAsPtrToIntArray(out IntPtr indices, out int triStride, out int indexCount); void getVertexListAsPtrToFloatArray(out IntPtr vertexList, out int vertexStride, out int vertexCount); diff --git a/OpenSim/Region/Physics/Meshing/Mesh.cs b/OpenSim/Region/Physics/Meshing/Mesh.cs index f781ff9..bd8e306 100644 --- a/OpenSim/Region/Physics/Meshing/Mesh.cs +++ b/OpenSim/Region/Physics/Meshing/Mesh.cs @@ -152,7 +152,7 @@ namespace OpenSim.Region.Physics.Meshing return result; } - private float[] getVertexListAsFloat() + public float[] getVertexListAsFloat() { if (m_vertices == null) throw new NotSupportedException(); -- cgit v1.1 From 5c94346bd7fd218ede591182b045aeb4a57b108e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 6 Feb 2013 01:17:19 +0000 Subject: refactor: Move functions that lookup asset ids from task inventory or pass them through to ScriptUtils class in OpenSim.Region.Framework.dll Renames functions to better reflect what they do. This is so that code registering with modInvoke() can reuse this code to provide functions that behave in a consistent manner with existing LSL/OSSL functions. --- .../Framework/Scenes/Scripting/ScriptUtils.cs | 122 +++++++++++++++++++++ .../Shared/Api/Implementation/LSL_Api.cs | 104 +++--------------- 2 files changed, 137 insertions(+), 89 deletions(-) create mode 100644 OpenSim/Region/Framework/Scenes/Scripting/ScriptUtils.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scripting/ScriptUtils.cs b/OpenSim/Region/Framework/Scenes/Scripting/ScriptUtils.cs new file mode 100644 index 0000000..d8aa258 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Scripting/ScriptUtils.cs @@ -0,0 +1,122 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using OpenMetaverse; +using OpenSim.Framework; + +namespace OpenSim.Region.Framework.Scenes.Scripting +{ + /// + /// Utility functions for use by scripts manipulating the scene. + /// + public static class ScriptUtils + { + /// + /// Get an asset id given an item name and an item type. + /// + /// UUID.Zero if the name and type did not match any item. + /// + /// + /// + public static UUID GetAssetIdFromItemName(SceneObjectPart part, string name, int type) + { + TaskInventoryItem item = part.Inventory.GetInventoryItem(name); + + if (item != null && item.Type == type) + return item.AssetID; + else + return UUID.Zero; + } + + /// + /// accepts a valid UUID, -or- a name of an inventory item. + /// Returns a valid UUID or UUID.Zero if key invalid and item not found + /// in prim inventory. + /// + /// Scene object part to search for inventory item + /// + /// + public static UUID GetAssetIdFromKeyOrItemName(SceneObjectPart part, string identifier) + { + UUID key; + + // if we can parse the string as a key, use it. + // else try to locate the name in inventory of object. found returns key, + // not found returns UUID.Zero + if (!UUID.TryParse(identifier, out key)) + { + TaskInventoryItem item = part.Inventory.GetInventoryItem(identifier); + + if (item != null) + key = item.AssetID; + else + key = UUID.Zero; + } + + return key; + } + + + /// + /// Return the UUID of the asset matching the specified key or name + /// and asset type. + /// + /// Scene object part to search for inventory item + /// + /// + /// + public static UUID GetAssetIdFromKeyOrItemName(SceneObjectPart part, string identifier, AssetType type) + { + UUID key; + + if (!UUID.TryParse(identifier, out key)) + { + TaskInventoryItem item = part.Inventory.GetInventoryItem(identifier); + if (item != null && item.Type == (int)type) + key = item.AssetID; + } + else + { + lock (part.TaskInventory) + { + foreach (KeyValuePair item in part.TaskInventory) + { + if (item.Value.Type == (int)type && item.Value.Name == identifier) + { + key = item.Value.ItemID; + break; + } + } + } + } + + return key; + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 0db6fe3..4fa3c60 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -45,6 +45,7 @@ using OpenSim.Region.CoreModules.World.Terrain; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes.Animation; +using OpenSim.Region.Framework.Scenes.Scripting; using OpenSim.Region.Physics.Manager; using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; @@ -333,79 +334,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - protected UUID InventoryKey(string name, int type) - { - TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); - - if (item != null && item.Type == type) - return item.AssetID; - else - return UUID.Zero; - } - - /// - /// accepts a valid UUID, -or- a name of an inventory item. - /// Returns a valid UUID or UUID.Zero if key invalid and item not found - /// in prim inventory. - /// - /// - /// - protected UUID KeyOrName(string k) - { - UUID key; - - // if we can parse the string as a key, use it. - // else try to locate the name in inventory of object. found returns key, - // not found returns UUID.Zero - if (!UUID.TryParse(k, out key)) - { - TaskInventoryItem item = m_host.Inventory.GetInventoryItem(k); - - if (item != null) - key = item.AssetID; - else - key = UUID.Zero; - } - - return key; - } - - /// - /// Return the UUID of the asset matching the specified key or name - /// and asset type. - /// - /// - /// - /// - protected UUID KeyOrName(string k, AssetType type) - { - UUID key; - - if (!UUID.TryParse(k, out key)) - { - TaskInventoryItem item = m_host.Inventory.GetInventoryItem(k); - if (item != null && item.Type == (int)type) - key = item.AssetID; - } - else - { - lock (m_host.TaskInventory) - { - foreach (KeyValuePair item in m_host.TaskInventory) - { - if (item.Value.Type == (int)type && item.Value.Name == k) - { - key = item.Value.ItemID; - break; - } - } - } - } - - - return key; - } - //These are the implementations of the various ll-functions used by the LSL scripts. public LSL_Float llSin(double f) { @@ -1816,7 +1744,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { UUID textureID = new UUID(); - textureID = InventoryKey(texture, (int)AssetType.Texture); + textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture); if (textureID == UUID.Zero) { if (!UUID.TryParse(texture, out textureID)) @@ -2450,7 +2378,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (m_SoundModule != null) { m_SoundModule.SendSound(m_host.UUID, - KeyOrName(sound, AssetType.Sound), volume, false, 0, + ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, false, 0, 0, false, false); } } @@ -2460,7 +2388,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); if (m_SoundModule != null) { - m_SoundModule.LoopSound(m_host.UUID, KeyOrName(sound), + m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), volume, 20, false); } } @@ -2470,7 +2398,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); if (m_SoundModule != null) { - m_SoundModule.LoopSound(m_host.UUID, KeyOrName(sound), + m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), volume, 20, true); } } @@ -2492,7 +2420,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (m_SoundModule != null) { m_SoundModule.SendSound(m_host.UUID, - KeyOrName(sound, AssetType.Sound), volume, false, 0, + ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, false, 0, 0, true, false); } } @@ -2504,7 +2432,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (m_SoundModule != null) { m_SoundModule.SendSound(m_host.UUID, - KeyOrName(sound, AssetType.Sound), volume, true, 0, 0, + ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, true, 0, 0, false, false); } } @@ -2521,7 +2449,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); if (m_SoundModule != null) - m_SoundModule.PreloadSound(m_host.UUID, KeyOrName(sound), 0); + m_SoundModule.PreloadSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), 0); ScriptSleep(1000); } @@ -3352,7 +3280,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (presence != null) { // Do NOT try to parse UUID, animations cannot be triggered by ID - UUID animID = InventoryKey(anim, (int)AssetType.Animation); + UUID animID = ScriptUtils.GetAssetIdFromItemName(m_host, anim, (int)AssetType.Animation); if (animID == UUID.Zero) presence.Animator.AddAnimation(anim, m_host.UUID); else @@ -3374,7 +3302,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (presence != null) { - UUID animID = KeyOrName(anim); + UUID animID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, anim); if (animID == UUID.Zero) presence.Animator.RemoveAnimation(anim); @@ -4319,7 +4247,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api private void DoLLTeleport(ScenePresence sp, string destination, Vector3 targetPos, Vector3 targetLookAt) { - UUID assetID = KeyOrName(destination); + UUID assetID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, destination); // The destinaion is not an asset ID and also doesn't name a landmark. // Use it as a sim name @@ -4386,7 +4314,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); // TODO: Parameter check logic required. - m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound); + m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound); m_host.CollisionSoundVolume = (float)impact_volume; } @@ -5912,7 +5840,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (m_SoundModule != null) { m_SoundModule.TriggerSoundLimited(m_host.UUID, - KeyOrName(sound, AssetType.Sound), volume, + ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, bottom_south_west, top_north_east); } } @@ -6346,7 +6274,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api break; case (int)ScriptBaseClass.PSYS_SRC_TEXTURE: - prules.Texture = KeyOrName(rules.GetLSLStringItem(i + 1)); + prules.Texture = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, rules.GetLSLStringItem(i + 1)); break; case (int)ScriptBaseClass.PSYS_SRC_BURST_RATE: @@ -7269,9 +7197,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID sculptId; if (!UUID.TryParse(map, out sculptId)) - { - sculptId = InventoryKey(map, (int)AssetType.Texture); - } + sculptId = ScriptUtils.GetAssetIdFromItemName(m_host, map, (int)AssetType.Texture); if (sculptId == UUID.Zero) return; -- cgit v1.1 From 36463612794f95776e8ddea14333827cbce35eff Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 5 Feb 2013 17:19:55 -0800 Subject: BulletSim: make removing zero width triangles from meshes optional and, for the moment, default to 'off'. --- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 6 +++ .../Physics/BulletSPlugin/BSShapeCollection.cs | 51 ++++++++++++---------- 2 files changed, 33 insertions(+), 24 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index bdd9ce4..306928a 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -62,6 +62,7 @@ public static class BSParam public static bool ShouldMeshSculptedPrim { get; private set; } // cause scuplted prims to get meshed public static bool ShouldForceSimplePrimMeshing { get; private set; } // if a cube or sphere, let Bullet do internal shapes public static bool ShouldUseHullsForPhysicalObjects { get; private set; } // 'true' if should create hulls for physical objects + public static bool ShouldRemoveZeroWidthTriangles { get; private set; } public static float TerrainImplementation { get; private set; } public static float TerrainFriction { get; private set; } @@ -218,6 +219,11 @@ public static class BSParam (s,cf,p,v) => { ShouldUseHullsForPhysicalObjects = cf.GetBoolean(p, BSParam.BoolNumeric(v)); }, (s) => { return BSParam.NumericBool(ShouldUseHullsForPhysicalObjects); }, (s,p,l,v) => { ShouldUseHullsForPhysicalObjects = BSParam.BoolNumeric(v); } ), + new ParameterDefn("ShouldRemoveZeroWidthTriangles", "If true, remove degenerate triangles from meshes", + ConfigurationParameters.numericFalse, + (s,cf,p,v) => { ShouldRemoveZeroWidthTriangles = cf.GetBoolean(p, BSParam.BoolNumeric(v)); }, + (s) => { return BSParam.NumericBool(ShouldRemoveZeroWidthTriangles); }, + (s,p,l,v) => { ShouldRemoveZeroWidthTriangles = BSParam.BoolNumeric(v); } ), new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", 32f, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index f17e513..f59b9d9 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -640,34 +640,37 @@ public sealed class BSShapeCollection : IDisposable { int[] indices = meshData.getIndexListAsInt(); - // int realIndicesIndex = indices.Length; + int realIndicesIndex = indices.Length; float[] verticesAsFloats = meshData.getVertexListAsFloat(); - // Remove degenerate triangles. These are triangles with two of the vertices - // are the same. This is complicated by the problem that vertices are not - // made unique in sculpties so we have to compare the values in the vertex. - int realIndicesIndex = 0; - for (int tri = 0; tri < indices.Length; tri += 3) + if (BSParam.ShouldRemoveZeroWidthTriangles) { - int v1 = indices[tri + 0] * 3; - int v2 = indices[tri + 1] * 3; - int v3 = indices[tri + 2] * 3; - if (!( ( verticesAsFloats[v1 + 0] == verticesAsFloats[v2 + 0] - && verticesAsFloats[v1 + 1] == verticesAsFloats[v2 + 1] - && verticesAsFloats[v1 + 2] == verticesAsFloats[v2 + 2] ) - || ( verticesAsFloats[v2 + 0] == verticesAsFloats[v3 + 0] - && verticesAsFloats[v2 + 1] == verticesAsFloats[v3 + 1] - && verticesAsFloats[v2 + 2] == verticesAsFloats[v3 + 2] ) - || ( verticesAsFloats[v1 + 0] == verticesAsFloats[v3 + 0] - && verticesAsFloats[v1 + 1] == verticesAsFloats[v3 + 1] - && verticesAsFloats[v1 + 2] == verticesAsFloats[v3 + 2] ) ) - ) + // Remove degenerate triangles. These are triangles with two of the vertices + // are the same. This is complicated by the problem that vertices are not + // made unique in sculpties so we have to compare the values in the vertex. + realIndicesIndex = 0; + for (int tri = 0; tri < indices.Length; tri += 3) { - // None of the vertices of the triangles are the same. This is a good triangle; - indices[realIndicesIndex + 0] = indices[tri + 0]; - indices[realIndicesIndex + 1] = indices[tri + 1]; - indices[realIndicesIndex + 2] = indices[tri + 2]; - realIndicesIndex += 3; + int v1 = indices[tri + 0] * 3; + int v2 = indices[tri + 1] * 3; + int v3 = indices[tri + 2] * 3; + if (!((verticesAsFloats[v1 + 0] == verticesAsFloats[v2 + 0] + && verticesAsFloats[v1 + 1] == verticesAsFloats[v2 + 1] + && verticesAsFloats[v1 + 2] == verticesAsFloats[v2 + 2]) + || (verticesAsFloats[v2 + 0] == verticesAsFloats[v3 + 0] + && verticesAsFloats[v2 + 1] == verticesAsFloats[v3 + 1] + && verticesAsFloats[v2 + 2] == verticesAsFloats[v3 + 2]) + || (verticesAsFloats[v1 + 0] == verticesAsFloats[v3 + 0] + && verticesAsFloats[v1 + 1] == verticesAsFloats[v3 + 1] + && verticesAsFloats[v1 + 2] == verticesAsFloats[v3 + 2])) + ) + { + // None of the vertices of the triangles are the same. This is a good triangle; + indices[realIndicesIndex + 0] = indices[tri + 0]; + indices[realIndicesIndex + 1] = indices[tri + 1]; + indices[realIndicesIndex + 2] = indices[tri + 2]; + realIndicesIndex += 3; + } } } DetailLog("{0},BSShapeCollection.CreatePhysicalMesh,origTri={1},realTri={2},numVerts={3}", -- cgit v1.1 From eddfed3812354c5990631be0ac985cc25d5aa0e9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 6 Feb 2013 01:37:22 +0000 Subject: Allow JsonReadNotecard() to accept the name of the notecard as well as the asset ID. Agreed in discussion with cmickeyb. This is to make this consistent with similar existing LSL/OSSL functions such as llTriggerSound() and osNpcLoadAppearance() that allow an item name or an asset id. --- .../Scripting/JsonStore/JsonStoreScriptModule.cs | 26 +++++++++++++++------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index 5b7a79d..ec880a7 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs @@ -39,6 +39,7 @@ using OpenMetaverse.StructuredData; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Scenes.Scripting; using System.Collections.Generic; using System.Text.RegularExpressions; @@ -256,10 +257,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// // ----------------------------------------------------------------- [ScriptInvocation] - public UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, UUID assetID) + public UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string notecardIdentifier) { UUID reqID = UUID.Random(); - Util.FireAndForget(delegate(object o) { DoJsonReadNotecard(reqID,hostID,scriptID,storeID,path,assetID); }); + Util.FireAndForget(o => DoJsonReadNotecard(reqID, hostID, scriptID, storeID, path, notecardIdentifier)); return reqID; } @@ -463,14 +464,23 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - private void DoJsonReadNotecard(UUID reqID, UUID hostID, UUID scriptID, UUID storeID, string path, UUID assetID) + private void DoJsonReadNotecard( + UUID reqID, UUID hostID, UUID scriptID, UUID storeID, string path, string notecardIdentifier) { + UUID assetID; + + if (!UUID.TryParse(notecardIdentifier, out assetID)) + { + SceneObjectPart part = m_scene.GetSceneObjectPart(hostID); + assetID = ScriptUtils.GetAssetIdFromItemName(part, notecardIdentifier, (int)AssetType.Notecard); + } + AssetBase a = m_scene.AssetService.Get(assetID.ToString()); if (a == null) - GenerateRuntimeError(String.Format("Unable to find notecard asset {0}",assetID)); + GenerateRuntimeError(String.Format("Unable to find notecard asset {0}", assetID)); if (a.Type != (sbyte)AssetType.Notecard) - GenerateRuntimeError(String.Format("Invalid notecard asset {0}",assetID)); + GenerateRuntimeError(String.Format("Invalid notecard asset {0}", assetID)); m_log.DebugFormat("[JsonStoreScripts]: read notecard in context {0}",storeID); @@ -483,11 +493,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } catch (Exception e) { - m_log.WarnFormat("[JsonStoreScripts]: Json parsing failed; {0}",e.Message); + m_log.WarnFormat("[JsonStoreScripts]: Json parsing failed; {0}", e.Message); } - GenerateRuntimeError(String.Format("Json parsing failed for {0}",assetID.ToString())); - m_comms.DispatchReply(scriptID,0,"",reqID.ToString()); + GenerateRuntimeError(String.Format("Json parsing failed for {0}", assetID)); + m_comms.DispatchReply(scriptID, 0, "", reqID.ToString()); } // ----------------------------------------------------------------- -- cgit v1.1 From dfe5826f9fd8854ddb5f0cc465564d8f124d7786 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 6 Feb 2013 01:44:37 +0000 Subject: Remove wrong code in ScriptUtils.GetAssetIdFromKeyOrItemName which would return the item ID instead of the asset ID if the identifier was a uuid that matched an inventory item name. This would practically never happen. This makes this overloaded version of the function consistent with the other version. It looks like this accidentally came over in commit c5af16a from Tue Oct 16 12:40:21 2012 However, there's arguably a case for looking for an item name that matches a UUID before assuming that the identifier is already an asset ID. --- OpenSim/Region/Framework/Scenes/Scripting/ScriptUtils.cs | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scripting/ScriptUtils.cs b/OpenSim/Region/Framework/Scenes/Scripting/ScriptUtils.cs index d8aa258..f08ba59 100644 --- a/OpenSim/Region/Framework/Scenes/Scripting/ScriptUtils.cs +++ b/OpenSim/Region/Framework/Scenes/Scripting/ScriptUtils.cs @@ -82,7 +82,6 @@ namespace OpenSim.Region.Framework.Scenes.Scripting return key; } - /// /// Return the UUID of the asset matching the specified key or name /// and asset type. @@ -101,20 +100,6 @@ namespace OpenSim.Region.Framework.Scenes.Scripting if (item != null && item.Type == (int)type) key = item.AssetID; } - else - { - lock (part.TaskInventory) - { - foreach (KeyValuePair item in part.TaskInventory) - { - if (item.Value.Type == (int)type && item.Value.Name == identifier) - { - key = item.Value.ItemID; - break; - } - } - } - } return key; } -- cgit v1.1 From 9ebad38c34315302d6ed26356fc4da5c0465e3cb Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 6 Feb 2013 02:08:44 +0000 Subject: Remove unused ScriptEngineLoader and ScriptEngineInterface in OpenSim.Region.Framework.dll I believe this predates the generic system of registering interfaces and is very long unused. --- OpenSim/Region/Framework/Scenes/Scene.cs | 11 -- .../Scenes/Scripting/ScriptEngineInterface.cs | 38 ------- .../Scenes/Scripting/ScriptEngineLoader.cs | 119 --------------------- 3 files changed, 168 deletions(-) delete mode 100644 OpenSim/Region/Framework/Scenes/Scripting/ScriptEngineInterface.cs delete mode 100644 OpenSim/Region/Framework/Scenes/Scripting/ScriptEngineLoader.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index f8d84e3..482235c 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -4482,19 +4482,8 @@ namespace OpenSim.Region.Framework.Scenes #region Script Engine - private List ScriptEngines = new List(); public bool DumpAssetsToFile; - /// - /// - /// - /// - public void AddScriptEngine(ScriptEngineInterface scriptEngine) - { - ScriptEngines.Add(scriptEngine); - scriptEngine.InitializeEngine(this); - } - private bool ScriptDanger(SceneObjectPart part,Vector3 pos) { ILandObject parcel = LandChannel.GetLandObject(pos.X, pos.Y); diff --git a/OpenSim/Region/Framework/Scenes/Scripting/ScriptEngineInterface.cs b/OpenSim/Region/Framework/Scenes/Scripting/ScriptEngineInterface.cs deleted file mode 100644 index 812a21c..0000000 --- a/OpenSim/Region/Framework/Scenes/Scripting/ScriptEngineInterface.cs +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -//TODO: WHERE TO PLACE THIS? - -namespace OpenSim.Region.Framework.Scenes.Scripting -{ - public interface ScriptEngineInterface - { - void InitializeEngine(Scene Sceneworld); - void Shutdown(); -// void StartScript(string ScriptID, IScriptHost ObjectID); - } -} diff --git a/OpenSim/Region/Framework/Scenes/Scripting/ScriptEngineLoader.cs b/OpenSim/Region/Framework/Scenes/Scripting/ScriptEngineLoader.cs deleted file mode 100644 index c58ccc5..0000000 --- a/OpenSim/Region/Framework/Scenes/Scripting/ScriptEngineLoader.cs +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* Original code: Tedd Hansen */ -using System; -using System.IO; -using System.Reflection; -using log4net; - -namespace OpenSim.Region.Framework.Scenes.Scripting -{ - public class ScriptEngineLoader - { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - public ScriptEngineInterface LoadScriptEngine(string EngineName) - { - ScriptEngineInterface ret = null; - try - { - ret = - LoadAndInitAssembly( - Path.Combine("ScriptEngines", "OpenSim.Region.ScriptEngine." + EngineName + ".dll"), - "OpenSim.Region.ScriptEngine." + EngineName + ".ScriptEngine"); - } - catch (Exception e) - { - m_log.Error("[ScriptEngine]: " + - "Error loading assembly \"" + EngineName + "\": " + e.Message + ", " + - e.StackTrace.ToString()); - } - return ret; - } - - /// - /// Does actual loading and initialization of script Assembly - /// - /// AppDomain to load script into - /// FileName of script assembly (.dll) - /// - private ScriptEngineInterface LoadAndInitAssembly(string FileName, string NameSpace) - { - //Common.SendToDebug("Loading ScriptEngine Assembly " + FileName); - // Load .Net Assembly (.dll) - // Initialize and return it - - // TODO: Add error handling - - Assembly a; - //try - //{ - - - // Load to default appdomain (temporary) - a = Assembly.LoadFrom(FileName); - // Load to specified appdomain - // TODO: Insert security - //a = FreeAppDomain.Load(FileName); - //} - //catch (Exception e) - //{ - // m_log.Error("[ScriptEngine]: Error loading assembly \String.Empty + FileName + "\": " + e.ToString()); - //} - - - //m_log.Debug("Loading: " + FileName); - //foreach (Type _t in a.GetTypes()) - //{ - // m_log.Debug("Type: " + _t.ToString()); - //} - - Type t; - //try - //{ - t = a.GetType(NameSpace, true); - //} - //catch (Exception e) - //{ - // m_log.Error("[ScriptEngine]: Error initializing type \String.Empty + NameSpace + "\" from \String.Empty + FileName + "\": " + e.ToString()); - //} - - ScriptEngineInterface ret; - //try - //{ - ret = (ScriptEngineInterface) Activator.CreateInstance(t); - //} - //catch (Exception e) - //{ - // m_log.Error("[ScriptEngine]: Error initializing type \String.Empty + NameSpace + "\" from \String.Empty + FileName + "\": " + e.ToString()); - //} - - return ret; - } - } -} -- cgit v1.1 From 2ce8a050e4181c2f2a9ee215a400c02678d88865 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 6 Feb 2013 02:15:54 +0000 Subject: Remove very long unused IScriptHost and NullScriptHost --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 +- .../Framework/Scenes/Scripting/IScriptHost.cs | 46 ----------- .../Framework/Scenes/Scripting/NullScriptHost.cs | 91 ---------------------- 3 files changed, 1 insertion(+), 138 deletions(-) delete mode 100644 OpenSim/Region/Framework/Scenes/Scripting/IScriptHost.cs delete mode 100644 OpenSim/Region/Framework/Scenes/Scripting/NullScriptHost.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 189d298..19e6d37 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -116,7 +116,7 @@ namespace OpenSim.Region.Framework.Scenes #endregion Enumerations - public class SceneObjectPart : IScriptHost, ISceneEntity + public class SceneObjectPart : ISceneEntity { /// /// Denote all sides of the prim diff --git a/OpenSim/Region/Framework/Scenes/Scripting/IScriptHost.cs b/OpenSim/Region/Framework/Scenes/Scripting/IScriptHost.cs deleted file mode 100644 index f3be028..0000000 --- a/OpenSim/Region/Framework/Scenes/Scripting/IScriptHost.cs +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using OpenMetaverse; - -namespace OpenSim.Region.Framework.Scenes.Scripting -{ - public interface IScriptHost - { - string Name { get; set; } - string Description { get; set; } - - UUID UUID { get; } - UUID OwnerID { get; } - UUID CreatorID { get; } - Vector3 AbsolutePosition { get; } - - string SitName { get; set; } - string TouchName { get; set; } - void SetText(string text, Vector3 color, double alpha); - } -} diff --git a/OpenSim/Region/Framework/Scenes/Scripting/NullScriptHost.cs b/OpenSim/Region/Framework/Scenes/Scripting/NullScriptHost.cs deleted file mode 100644 index d7198f0..0000000 --- a/OpenSim/Region/Framework/Scenes/Scripting/NullScriptHost.cs +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using OpenMetaverse; -using log4net; -using System.Reflection; -using OpenSim.Framework; - -namespace OpenSim.Region.Framework.Scenes.Scripting -{ - public class NullScriptHost : IScriptHost - { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private Vector3 m_pos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 30); - - public string Name - { - get { return "Object"; } - set { } - } - - public string SitName - { - get { return String.Empty; } - set { } - } - - public string TouchName - { - get { return String.Empty; } - set { } - } - - public string Description - { - get { return String.Empty; } - set { } - } - - public UUID UUID - { - get { return UUID.Zero; } - } - - public UUID OwnerID - { - get { return UUID.Zero; } - } - - public UUID CreatorID - { - get { return UUID.Zero; } - } - - public Vector3 AbsolutePosition - { - get { return m_pos; } - } - - public void SetText(string text, Vector3 color, double alpha) - { - m_log.Warn("Tried to SetText "+text+" on NullScriptHost"); - } - } -} -- cgit v1.1 From 145e38e5e9bed04d5c41880a5d508cab4603cc1d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 6 Feb 2013 02:21:17 +0000 Subject: Remove long unused Scene.DumpAssetsToFile boolean. --- OpenSim/Region/Application/OpenSimBase.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.cs | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index f5c06df..3c8e199 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -714,7 +714,7 @@ namespace OpenSim return new Scene( regionInfo, circuitManager, sceneGridService, - simDataService, estateDataService, false, + simDataService, estateDataService, Config, m_version); } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 482235c..de3978c 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -720,7 +720,6 @@ namespace OpenSim.Region.Framework.Scenes public Scene(RegionInfo regInfo, AgentCircuitManager authen, SceneCommunicationService sceneGridService, ISimulationDataService simDataService, IEstateDataService estateDataService, - bool dumpAssetsToFile, IConfigSource config, string simulatorVersion) : this(regInfo) { @@ -811,8 +810,6 @@ namespace OpenSim.Region.Framework.Scenes RegisterDefaultSceneEvents(); - DumpAssetsToFile = dumpAssetsToFile; - // XXX: Don't set the public property since we don't want to activate here. This needs to be handled // better in the future. m_scripts_enabled = !RegionInfo.RegionSettings.DisableScripts; @@ -4482,8 +4479,6 @@ namespace OpenSim.Region.Framework.Scenes #region Script Engine - public bool DumpAssetsToFile; - private bool ScriptDanger(SceneObjectPart part,Vector3 pos) { ILandObject parcel = LandChannel.GetLandObject(pos.X, pos.Y); -- cgit v1.1 From e5beb480eaf23fa7454728724de80b2a67ded1e8 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 6 Feb 2013 08:03:04 +0000 Subject: Partial port of Avination's support for the new physics parameters. Implements the parameters as properties, the serialization and database storage (MySQL only). Implements llSetPrimitiveParams for prim physics shape and the other 4 extra params. Only the prim shape type "None" is currently functional. No support for the Viewer UI (yet), that will be ported in due course. Lots more to port, this is a large-ish changeset. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 96 +++++++++++++++++++++- .../Scenes/Serialization/SceneObjectSerializer.cs | 43 ++++++++++ .../Shared/Api/Implementation/LSL_Api.cs | 16 ++++ .../Shared/Api/Runtime/LSL_Constants.cs | 11 +++ 4 files changed, 163 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 19e6d37..55b5462 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -302,6 +302,13 @@ namespace OpenSim.Region.Framework.Scenes protected Vector3 m_lastAcceleration; protected Vector3 m_lastAngularVelocity; protected int m_lastTerseSent; + + protected byte m_physicsShapeType = (byte)PhysShapeType.prim; + // TODO: Implement these + //protected float m_density = 1000.0f; // in kg/m^3 + //protected float m_gravitymod = 1.0f; + //protected float m_friction = 0.6f; // wood + //protected float m_bounce = 0.5f; // wood /// /// Stores media texture data @@ -1322,6 +1329,69 @@ namespace OpenSim.Region.Framework.Scenes set { m_collisionSoundVolume = value; } } + public byte DefaultPhysicsShapeType() + { + byte type; + + if (Shape != null && (Shape.SculptType == (byte)SculptType.Mesh)) + type = (byte)PhysShapeType.convex; + else + type = (byte)PhysShapeType.prim; + + return type; + } + + public byte PhysicsShapeType + { + get { return m_physicsShapeType; } + set + { + byte oldv = m_physicsShapeType; + + if (value >= 0 && value <= (byte)PhysShapeType.convex) + { + if (value == (byte)PhysShapeType.none && ParentGroup != null && ParentGroup.RootPart == this) + m_physicsShapeType = DefaultPhysicsShapeType(); + else + m_physicsShapeType = value; + } + else + m_physicsShapeType = DefaultPhysicsShapeType(); + + if (m_physicsShapeType != oldv && ParentGroup != null) + { + if (m_physicsShapeType == (byte)PhysShapeType.none) + { + if (PhysActor != null) + { + Velocity = new Vector3(0, 0, 0); + Acceleration = new Vector3(0, 0, 0); + if (ParentGroup.RootPart == this) + AngularVelocity = new Vector3(0, 0, 0); + ParentGroup.Scene.RemovePhysicalPrim(1); + RemoveFromPhysics(); + } + } + else if (PhysActor == null) + { + ApplyPhysics((uint)Flags, VolumeDetectActive); + } + else + { + // TODO: Update physics actor + } + + if (ParentGroup != null) + ParentGroup.HasGroupChanged = true; + } + } + } + + public float Density { get; set; } + public float GravityModifier { get; set; } + public float Friction { get; set; } + public float Bounciness { get; set; } + #endregion Public Properties with only Get private uint ApplyMask(uint val, bool set, uint mask) @@ -1523,9 +1593,8 @@ namespace OpenSim.Region.Framework.Scenes if (!ParentGroup.Scene.CollidablePrims) return; -// m_log.DebugFormat( -// "[SCENE OBJECT PART]: Applying physics to {0} {1}, m_physicalPrim {2}", -// Name, LocalId, UUID, m_physicalPrim); + if (PhysicsShapeType == (byte)PhysShapeType.none) + return; bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0; bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0; @@ -3878,6 +3947,26 @@ namespace OpenSim.Region.Framework.Scenes } } + public void UpdateExtraPhysics(ExtraPhysicsData physdata) + { + if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null) + return; + + if (PhysicsShapeType != (byte)physdata.PhysShapeType) + { + PhysicsShapeType = (byte)physdata.PhysShapeType; + + } + + if(Density != physdata.Density) + Density = physdata.Density; + if(GravityModifier != physdata.GravitationModifier) + GravityModifier = physdata.GravitationModifier; + if(Friction != physdata.Friction) + Friction = physdata.Friction; + if(Bounciness != physdata.Bounce) + Bounciness = physdata.Bounce; + } /// /// Update the flags on this prim. This covers properties such as phantom, physics and temporary. /// @@ -3949,6 +4038,7 @@ namespace OpenSim.Region.Framework.Scenes if (SetPhantom || ParentGroup.IsAttachment + || PhysicsShapeType == (byte)PhysShapeType.none || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints { AddFlag(PrimFlags.Phantom); diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 4a2a47e..78229fe 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -367,6 +367,13 @@ namespace OpenSim.Region.Framework.Scenes.Serialization m_SOPXmlProcessors.Add("PayPrice2", ProcessPayPrice2); m_SOPXmlProcessors.Add("PayPrice3", ProcessPayPrice3); m_SOPXmlProcessors.Add("PayPrice4", ProcessPayPrice4); + + m_SOPXmlProcessors.Add("PhysicsShapeType", ProcessPhysicsShapeType); + m_SOPXmlProcessors.Add("Density", ProcessDensity); + m_SOPXmlProcessors.Add("Friction", ProcessFriction); + m_SOPXmlProcessors.Add("Bounce", ProcessBounce); + m_SOPXmlProcessors.Add("GravityModifier", ProcessGravityModifier); + #endregion #region TaskInventoryXmlProcessors initialization @@ -594,6 +601,31 @@ namespace OpenSim.Region.Framework.Scenes.Serialization obj.ClickAction = (byte)reader.ReadElementContentAsInt("ClickAction", String.Empty); } + private static void ProcessPhysicsShapeType(SceneObjectPart obj, XmlTextReader reader) + { + obj.PhysicsShapeType = (byte)reader.ReadElementContentAsInt("PhysicsShapeType", String.Empty); + } + + private static void ProcessDensity(SceneObjectPart obj, XmlTextReader reader) + { + obj.Density = reader.ReadElementContentAsFloat("Density", String.Empty); + } + + private static void ProcessFriction(SceneObjectPart obj, XmlTextReader reader) + { + obj.Friction = reader.ReadElementContentAsFloat("Friction", String.Empty); + } + + private static void ProcessBounce(SceneObjectPart obj, XmlTextReader reader) + { + obj.Bounciness = reader.ReadElementContentAsFloat("Bounce", String.Empty); + } + + private static void ProcessGravityModifier(SceneObjectPart obj, XmlTextReader reader) + { + obj.GravityModifier = reader.ReadElementContentAsFloat("GravityModifier", String.Empty); + } + private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader) { List errorNodeNames; @@ -1257,6 +1289,17 @@ namespace OpenSim.Region.Framework.Scenes.Serialization writer.WriteElementString("PayPrice3", sop.PayPrice[3].ToString()); writer.WriteElementString("PayPrice4", sop.PayPrice[4].ToString()); + if(sop.PhysicsShapeType != sop.DefaultPhysicsShapeType()) + writer.WriteElementString("PhysicsShapeType", sop.PhysicsShapeType.ToString().ToLower()); + if (sop.Density != 1000.0f) + writer.WriteElementString("Density", sop.Density.ToString().ToLower()); + if (sop.Friction != 0.6f) + writer.WriteElementString("Friction", sop.Friction.ToString().ToLower()); + if (sop.Bounciness != 0.5f) + writer.WriteElementString("Bounce", sop.Bounciness.ToString().ToLower()); + if (sop.GravityModifier != 1.0f) + writer.WriteElementString("GravityModifier", sop.GravityModifier.ToString().ToLower()); + writer.WriteEndElement(); } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 4fa3c60..64052ae 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -7594,6 +7594,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api part.ScriptSetPhysicsStatus(physics); break; + case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE: + if (remain < 1) + return null; + + int shape_type = rules.GetLSLIntegerItem(idx++); + + ExtraPhysicsData physdata = new ExtraPhysicsData(); + physdata.Density = part.Density; + physdata.Bounce = part.Bounciness; + physdata.GravitationModifier = part.GravityModifier; + physdata.PhysShapeType = (PhysShapeType)shape_type; + + part.UpdateExtraPhysics(physdata); + + break; + case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: if (remain < 1) return null; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index 9bf1a64..bd66ba3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -661,6 +661,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int PRIM_MEDIA_PERM_GROUP = 2; public const int PRIM_MEDIA_PERM_ANYONE = 4; + public const int PRIM_PHYSICS_SHAPE_TYPE = 30; + public const int PRIM_PHYSICS_SHAPE_PRIM = 0; + public const int PRIM_PHYSICS_SHAPE_CONVEX = 2; + public const int PRIM_PHYSICS_SHAPE_NONE = 1; + + public const int PRIM_PHYSICS_MATERIAL = 31; + public const int DENSITY = 1; + public const int FRICTION = 2; + public const int RESTITUTION = 4; + public const int GRAVITY_MULTIPLIER = 8; + // extra constants for llSetPrimMediaParams public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); public static readonly LSLInteger LSL_STATUS_MALFORMED_PARAMS = new LSLInteger(1000); -- cgit v1.1 From 67d92e4e168bf0861024e3be5cd069c77c9144f6 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 6 Feb 2013 11:49:10 -0800 Subject: BulletSim: remove an exception which occurs if a physics mesh asset is not found. --- OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index f59b9d9..fe0f984 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -895,9 +895,11 @@ public sealed class BSShapeCollection : IDisposable // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset if (prim.BaseShape.SculptEntry && !prim.LastAssetBuildFailed && prim.BaseShape.SculptTexture != OMV.UUID.Zero) { + DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset,lastFailed={1}", prim.LocalID, prim.LastAssetBuildFailed); + // This will prevent looping through this code as we keep trying to get the failed shape prim.LastAssetBuildFailed = true; + BSPhysObject xprim = prim; - DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset,lastFailed={1}", prim.LocalID, prim.LastAssetBuildFailed); Util.FireAndForget(delegate { RequestAssetDelegate assetProvider = PhysicsScene.RequestAssetMethod; @@ -908,7 +910,7 @@ public sealed class BSShapeCollection : IDisposable { bool assetFound = false; // DEBUG DEBUG string mismatchIDs = String.Empty; // DEBUG DEBUG - if (yprim.BaseShape.SculptEntry) + if (asset != null && yprim.BaseShape.SculptEntry) { if (yprim.BaseShape.SculptTexture.ToString() == asset.ID) { -- cgit v1.1 From 0baa2590bef8ad4e0a78a7c88d55acd0848e0068 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 6 Feb 2013 15:52:28 -0800 Subject: BulletSim: check for completely degenerate meshes (ones with all triangles having zero width) and output an error rather than throwing and exception. --- .../Physics/BulletSPlugin/BSShapeCollection.cs | 28 +++++++++++++++------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index fe0f984..15747c9 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -608,7 +608,7 @@ public sealed class BSShapeCollection : IDisposable // Since we're recreating new, get rid of the reference to the previous shape DereferenceShape(prim.PhysShape, shapeCallback); - newShape = CreatePhysicalMesh(prim.PhysObjectName, newMeshKey, prim.BaseShape, prim.Size, lod); + newShape = CreatePhysicalMesh(prim, newMeshKey, prim.BaseShape, prim.Size, lod); // Take evasive action if the mesh was not constructed. newShape = VerifyMeshCreated(newShape, prim); @@ -619,7 +619,7 @@ public sealed class BSShapeCollection : IDisposable return true; // 'true' means a new shape has been added to this prim } - private BulletShape CreatePhysicalMesh(string objName, System.UInt64 newMeshKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) + private BulletShape CreatePhysicalMesh(BSPhysObject prim, System.UInt64 newMeshKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) { BulletShape newShape = new BulletShape(); @@ -631,7 +631,7 @@ public sealed class BSShapeCollection : IDisposable } else { - IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, + IMesh meshData = PhysicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, false, // say it is not physical so a bounding box is not built false // do not cache the mesh and do not use previously built versions ); @@ -651,18 +651,20 @@ public sealed class BSShapeCollection : IDisposable realIndicesIndex = 0; for (int tri = 0; tri < indices.Length; tri += 3) { + // Compute displacements into vertex array for each vertex of the triangle int v1 = indices[tri + 0] * 3; int v2 = indices[tri + 1] * 3; int v3 = indices[tri + 2] * 3; - if (!((verticesAsFloats[v1 + 0] == verticesAsFloats[v2 + 0] + // Check to see if any two of the vertices are the same + if (!( ( verticesAsFloats[v1 + 0] == verticesAsFloats[v2 + 0] && verticesAsFloats[v1 + 1] == verticesAsFloats[v2 + 1] && verticesAsFloats[v1 + 2] == verticesAsFloats[v2 + 2]) - || (verticesAsFloats[v2 + 0] == verticesAsFloats[v3 + 0] + || ( verticesAsFloats[v2 + 0] == verticesAsFloats[v3 + 0] && verticesAsFloats[v2 + 1] == verticesAsFloats[v3 + 1] && verticesAsFloats[v2 + 2] == verticesAsFloats[v3 + 2]) - || (verticesAsFloats[v1 + 0] == verticesAsFloats[v3 + 0] + || ( verticesAsFloats[v1 + 0] == verticesAsFloats[v3 + 0] && verticesAsFloats[v1 + 1] == verticesAsFloats[v3 + 1] - && verticesAsFloats[v1 + 2] == verticesAsFloats[v3 + 2])) + && verticesAsFloats[v1 + 2] == verticesAsFloats[v3 + 2]) ) ) { // None of the vertices of the triangles are the same. This is a good triangle; @@ -676,8 +678,16 @@ public sealed class BSShapeCollection : IDisposable DetailLog("{0},BSShapeCollection.CreatePhysicalMesh,origTri={1},realTri={2},numVerts={3}", BSScene.DetailLogZero, indices.Length / 3, realIndicesIndex / 3, verticesAsFloats.Length / 3); - newShape = PhysicsScene.PE.CreateMeshShape(PhysicsScene.World, - realIndicesIndex, indices, verticesAsFloats.Length/3, verticesAsFloats); + if (realIndicesIndex != 0) + { + newShape = PhysicsScene.PE.CreateMeshShape(PhysicsScene.World, + realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats); + } + else + { + PhysicsScene.Logger.ErrorFormat("{0} All mesh triangles degenerate. Prim {1} at {2} in {3}", + LogHeader, prim.PhysObjectName, prim.RawPosition, PhysicsScene.Name); + } } } newShape.shapeKey = newMeshKey; -- cgit v1.1 From d2ece00e68c070bf9ffbda3f76e4eccf3c33545f Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 6 Feb 2013 15:59:59 -0800 Subject: BulletSim: set removing zero width triangles in meshes to be enabled by default. This should fix the invisible barrier in sculptie doorways bug. --- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 306928a..965c382 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -220,7 +220,7 @@ public static class BSParam (s) => { return BSParam.NumericBool(ShouldUseHullsForPhysicalObjects); }, (s,p,l,v) => { ShouldUseHullsForPhysicalObjects = BSParam.BoolNumeric(v); } ), new ParameterDefn("ShouldRemoveZeroWidthTriangles", "If true, remove degenerate triangles from meshes", - ConfigurationParameters.numericFalse, + ConfigurationParameters.numericTrue, (s,cf,p,v) => { ShouldRemoveZeroWidthTriangles = cf.GetBoolean(p, BSParam.BoolNumeric(v)); }, (s) => { return BSParam.NumericBool(ShouldRemoveZeroWidthTriangles); }, (s,p,l,v) => { ShouldRemoveZeroWidthTriangles = BSParam.BoolNumeric(v); } ), diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 823402b..ec25aa9 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -75,6 +75,7 @@ public abstract class BSPhysObject : PhysicsActor PhysicsScene = parentScene; LocalID = localID; PhysObjectName = name; + Name = name; // PhysicsActor also has the name of the object. Someday consolidate. TypeName = typeName; // We don't have any physical representation yet. -- cgit v1.1 From df37738ce7702774c4d3ff1f3835bfe87e0f1a5e Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Wed, 6 Feb 2013 16:42:55 -0800 Subject: WebStats will now use actual logfile as specified in OpenSim.exe.config rather than hardcoded ./OpenSim.log. This allows for rotating logs and other file appender types --- OpenSim/Region/UserStatistics/WebStatsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs index 438ef48..b98b762 100644 --- a/OpenSim/Region/UserStatistics/WebStatsModule.cs +++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs @@ -420,7 +420,7 @@ namespace OpenSim.Region.UserStatistics Encoding encoding = Encoding.ASCII; int sizeOfChar = encoding.GetByteCount("\n"); byte[] buffer = encoding.GetBytes("\n"); - string logfile = Util.logDir() + "/" + "OpenSim.log"; + string logfile = Util.logFile(); FileStream fs = new FileStream(logfile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); Int64 tokenCount = 0; Int64 endPosition = fs.Length / sizeOfChar; -- cgit v1.1 From 4d1758985f64fbdbfd142684c1a4ac82c9a4b97a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 7 Feb 2013 00:54:09 +0000 Subject: Make json store tests operate on a single thread to ensure we don't run into any race related test failures in the future. --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 8042a93..34422b4 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -54,6 +54,22 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests private MockScriptEngine m_engine; private ScriptModuleCommsModule m_smcm; + [TestFixtureSetUp] + public void FixtureInit() + { + // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread. + Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest; + } + + [TestFixtureTearDown] + public void TearDown() + { + // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple + // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression + // tests really shouldn't). + Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; + } + [SetUp] public override void SetUp() { -- cgit v1.1 From e17392acbb46e1e48e169069a822f8b814762214 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Wed, 6 Feb 2013 17:29:17 -0800 Subject: Enables script access to the per object dynamic attributes through the JsonStore script functions. Adds JsonAttachObjectStore to associate a store identifier with an object (scripts can only access the store in their host object, this could be extended but isn't necessary for now). Note this opens a method to the DAMap OSDMap. This will be removed later, but greatly simplifies the code for now. The JsonStore and these scripts are disabled by default. --- .../Framework/Interfaces/IJsonStoreModule.cs | 1 + .../Scripting/JsonStore/JsonStore.cs | 64 +++++++++++++++++----- .../Scripting/JsonStore/JsonStoreModule.cs | 28 ++++++++++ .../Scripting/JsonStore/JsonStoreScriptModule.cs | 16 ++++++ 4 files changed, 96 insertions(+), 13 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs index 0bb4567..cc7885a 100644 --- a/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs @@ -35,6 +35,7 @@ namespace OpenSim.Region.Framework.Interfaces public interface IJsonStoreModule { + bool AttachObjectStore(UUID objectID); bool CreateStore(string value, ref UUID result); bool DestroyStore(UUID storeID); bool TestStore(UUID storeID); diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs index 0b7b31b..751e463 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs @@ -49,7 +49,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private OSD m_ValueStore; + protected virtual OSD ValueStore { get; set; } protected class TakeValueCallbackClass { @@ -108,17 +108,18 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - public JsonStore() : this("") {} - - public JsonStore(string value) + public JsonStore() { m_TakeStore = new List(); m_ReadStore = new List(); - + } + + public JsonStore(string value) + { if (String.IsNullOrEmpty(value)) - m_ValueStore = new OSDMap(); + ValueStore = new OSDMap(); else - m_ValueStore = OSDParser.DeserializeJson(value); + ValueStore = OSDParser.DeserializeJson(value); } // ----------------------------------------------------------------- @@ -129,7 +130,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore public bool TestPath(string expr, bool useJson) { Stack path = ParsePathExpression(expr); - OSD result = ProcessPathExpression(m_ValueStore,path); + OSD result = ProcessPathExpression(ValueStore,path); if (result == null) return false; @@ -148,7 +149,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore public bool GetValue(string expr, out string value, bool useJson) { Stack path = ParsePathExpression(expr); - OSD result = ProcessPathExpression(m_ValueStore,path); + OSD result = ProcessPathExpression(ValueStore,path); return ConvertOutputValue(result,out value,useJson); } @@ -184,7 +185,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore Stack path = ParsePathExpression(expr); string pexpr = PathExpressionToKey(path); - OSD result = ProcessPathExpression(m_ValueStore,path); + OSD result = ProcessPathExpression(ValueStore,path); if (result == null) { m_TakeStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback)); @@ -215,7 +216,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore Stack path = ParsePathExpression(expr); string pexpr = PathExpressionToKey(path); - OSD result = ProcessPathExpression(m_ValueStore,path); + OSD result = ProcessPathExpression(ValueStore,path); if (result == null) { m_ReadStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback)); @@ -245,7 +246,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore Stack path = ParsePathExpression(expr); if (path.Count == 0) { - m_ValueStore = ovalue; + ValueStore = ovalue; return true; } @@ -254,7 +255,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore if (pexpr != "") pexpr += "."; - OSD result = ProcessPathExpression(m_ValueStore,path); + OSD result = ProcessPathExpression(ValueStore,path); if (result == null) return false; @@ -522,4 +523,41 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore return pkey; } } + + public class JsonObjectStore : JsonStore + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Scene m_scene; + private UUID m_objectID; + + protected override OSD ValueStore + { + get + { + SceneObjectPart sop = m_scene.GetSceneObjectPart(m_objectID); + if (sop == null) + { + // This is bad + return null; + } + + return sop.DynAttrs.TopLevelMap; + } + + // cannot set the top level + set + { + m_log.InfoFormat("[JsonStore] cannot set top level value in object store"); + } + } + + public JsonObjectStore(Scene scene, UUID oid) : base() + { + m_scene = scene; + m_objectID = oid; + } + } + } diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs index b9b3ebc..a36ef42 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs @@ -175,6 +175,34 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- + public bool AttachObjectStore(UUID objectID) + { + if (! m_enabled) return false; + + SceneObjectPart sop = m_scene.GetSceneObjectPart(objectID); + if (sop == null) + { + m_log.InfoFormat("[JsonStore] unable to attach to unknown object; {0}",objectID); + return false; + } + + lock (m_JsonValueStore) + { + if (m_JsonValueStore.ContainsKey(objectID)) + return true; + + JsonStore map = new JsonObjectStore(m_scene,objectID); + m_JsonValueStore.Add(objectID,map); + } + + return true; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- public bool CreateStore(string value, ref UUID result) { if (result == UUID.Zero) diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index ec880a7..48b4a9f 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs @@ -169,6 +169,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore m_comms.RegisterScriptInvocations(this); // m_comms.RegisterScriptInvocation(this, "JsonCreateStore"); + // m_comms.RegisterScriptInvocation(this, "JsonAttachObjectStore"); // m_comms.RegisterScriptInvocation(this, "JsonDestroyStore"); // m_comms.RegisterScriptInvocation(this, "JsonTestStore"); @@ -220,6 +221,21 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// // ----------------------------------------------------------------- [ScriptInvocation] + public UUID JsonAttachObjectStore(UUID hostID, UUID scriptID) + { + UUID uuid = UUID.Zero; + if (! m_store.AttachObjectStore(hostID)) + GenerateRuntimeError("Failed to create Json store"); + + return hostID; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + [ScriptInvocation] public UUID JsonCreateStore(UUID hostID, UUID scriptID, string value) { UUID uuid = UUID.Zero; -- cgit v1.1 From 3657a08844731e5a24eeda3195c23f417b4570a5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 7 Feb 2013 02:19:26 +0000 Subject: Add TestJsonWriteReadNotecard() regression test --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 45 +++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 34422b4..98b5624 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -101,7 +101,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests private object InvokeOp(string name, params object[] args) { - return m_smcm.InvokeOperation(UUID.Zero, UUID.Zero, name, args); + return InvokeOpOnHost(name, UUID.Zero, args); + } + + private object InvokeOpOnHost(string name, UUID hostId, params object[] args) + { + return m_smcm.InvokeOperation(hostId, UUID.Zero, name, args); } [Test] @@ -209,6 +214,44 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests Assert.That(value, Is.EqualTo("World")); } + /// + /// Test for reading and writing json to a notecard + /// + /// + /// TODO: Really needs to test correct receipt of the link_message event. Could do this by directly fetching + /// it via the MockScriptEngine or perhaps by a dummy script instance. + /// + [Test] + public void TestJsonWriteReadNotecard() + { + TestHelpers.InMethod(); + TestHelpers.EnableLogging(); + + string notecardName = "nc1"; + + SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1)); + m_scene.AddSceneObject(so); + + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }"); + + // Write notecard + UUID writeNotecardRequestId = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "/", notecardName); + Assert.That(writeNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); + + TaskInventoryItem nc1Item = so.RootPart.Inventory.GetInventoryItem(notecardName); + Assert.That(nc1Item, Is.Not.Null); + + // TODO: Should probably independently check the contents. + + // Read notecard + UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }"); + UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "/", notecardName); + Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "Hello"); + Assert.That(value, Is.EqualTo("World")); + } + public object DummyTestMethod(object o1, object o2, object o3, object o4, object o5) { return null; } } } \ No newline at end of file -- cgit v1.1 From 6504e3d4cee1573115e8a83c06227a297a32f093 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 7 Feb 2013 03:30:02 +0000 Subject: Rename "Bounciness" to "Restitution" --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 6 +++--- .../Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs | 6 +++--- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 55b5462..b00f388 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1390,7 +1390,7 @@ namespace OpenSim.Region.Framework.Scenes public float Density { get; set; } public float GravityModifier { get; set; } public float Friction { get; set; } - public float Bounciness { get; set; } + public float Restitution { get; set; } #endregion Public Properties with only Get @@ -3964,8 +3964,8 @@ namespace OpenSim.Region.Framework.Scenes GravityModifier = physdata.GravitationModifier; if(Friction != physdata.Friction) Friction = physdata.Friction; - if(Bounciness != physdata.Bounce) - Bounciness = physdata.Bounce; + if(Restitution != physdata.Bounce) + Restitution = physdata.Bounce; } /// /// Update the flags on this prim. This covers properties such as phantom, physics and temporary. diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 78229fe..39420a6 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -618,7 +618,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessBounce(SceneObjectPart obj, XmlTextReader reader) { - obj.Bounciness = reader.ReadElementContentAsFloat("Bounce", String.Empty); + obj.Restitution = reader.ReadElementContentAsFloat("Bounce", String.Empty); } private static void ProcessGravityModifier(SceneObjectPart obj, XmlTextReader reader) @@ -1295,8 +1295,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization writer.WriteElementString("Density", sop.Density.ToString().ToLower()); if (sop.Friction != 0.6f) writer.WriteElementString("Friction", sop.Friction.ToString().ToLower()); - if (sop.Bounciness != 0.5f) - writer.WriteElementString("Bounce", sop.Bounciness.ToString().ToLower()); + if (sop.Restitution != 0.5f) + writer.WriteElementString("Bounce", sop.Restitution.ToString().ToLower()); if (sop.GravityModifier != 1.0f) writer.WriteElementString("GravityModifier", sop.GravityModifier.ToString().ToLower()); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 64052ae..be6ac0a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -7602,7 +7602,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ExtraPhysicsData physdata = new ExtraPhysicsData(); physdata.Density = part.Density; - physdata.Bounce = part.Bounciness; + physdata.Bounce = part.Restitution; physdata.GravitationModifier = part.GravityModifier; physdata.PhysShapeType = (PhysShapeType)shape_type; -- cgit v1.1 From 6aa876a83b08390ab057eb012fd2c730010f79d8 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 7 Feb 2013 03:40:48 +0000 Subject: Rename Bounciness to Restitution --- OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 2 +- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 6 +++--- .../Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs | 6 +++--- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index 83347e2..d7d4708 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -1316,7 +1316,7 @@ namespace OpenSim.Region.ClientStack.Linden object_data["PhysicsShapeType"] = obj.PhysicsShapeType; object_data["Density"] = obj.Density; object_data["Friction"] = obj.Friction; - object_data["Restitution"] = obj.Bounciness; + object_data["Restitution"] = obj.Restitution; object_data["GravityMultiplier"] = obj.GravityModifier; resp[uuid.ToString()] = object_data; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 0a39ded..f1fe6e1 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -2654,7 +2654,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP byte physshapetype = part.PhysicsShapeType; float density = part.Density; float friction = part.Friction; - float bounce = part.Bounciness; + float bounce = part.Restitution; float gravmod = part.GravityModifier; eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 05b69c1..415a82b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1736,7 +1736,7 @@ namespace OpenSim.Region.Framework.Scenes } } - public float Bounciness + public float Restitution { get { return m_bounce; } set @@ -4494,8 +4494,8 @@ namespace OpenSim.Region.Framework.Scenes GravityModifier = physdata.GravitationModifier; if(Friction != physdata.Friction) Friction = physdata.Friction; - if(Bounciness != physdata.Bounce) - Bounciness = physdata.Bounce; + if(Restitution != physdata.Bounce) + Restitution = physdata.Bounce; } /// /// Update the flags on this prim. This covers properties such as phantom, physics and temporary. diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 5c37c07..ce4fb40 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -634,7 +634,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessBounce(SceneObjectPart obj, XmlTextReader reader) { - obj.Bounciness = reader.ReadElementContentAsFloat("Bounce", String.Empty); + obj.Restitution = reader.ReadElementContentAsFloat("Bounce", String.Empty); } private static void ProcessGravityModifier(SceneObjectPart obj, XmlTextReader reader) @@ -1377,8 +1377,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization writer.WriteElementString("Density", sop.Density.ToString().ToLower()); if (sop.Friction != 0.6f) writer.WriteElementString("Friction", sop.Friction.ToString().ToLower()); - if (sop.Bounciness != 0.5f) - writer.WriteElementString("Bounce", sop.Bounciness.ToString().ToLower()); + if (sop.Restitution != 0.5f) + writer.WriteElementString("Bounce", sop.Restitution.ToString().ToLower()); if (sop.GravityModifier != 1.0f) writer.WriteElementString("GravityModifier", sop.GravityModifier.ToString().ToLower()); WriteVector(writer, "CameraEyeOffset", sop.GetCameraEyeOffset()); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 8be39a7..19214ec 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -7801,7 +7801,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType; physdata.Density = part.Density; physdata.Friction = part.Friction; - physdata.Bounce = part.Bounciness; + physdata.Bounce = part.Restitution; physdata.GravitationModifier = part.GravityModifier; if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0) @@ -8194,7 +8194,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ExtraPhysicsData physdata = new ExtraPhysicsData(); physdata.Density = part.Density; - physdata.Bounce = part.Bounciness; + physdata.Bounce = part.Restitution; physdata.GravitationModifier = part.GravityModifier; physdata.PhysShapeType = (PhysShapeType)shape_type; -- cgit v1.1 From 4bd1794b5a05147788950208f9644c2b9d731859 Mon Sep 17 00:00:00 2001 From: teravus Date: Thu, 7 Feb 2013 12:19:54 -0500 Subject: * missing example module.. Oops. --- .../WebSocketEchoTest/WebSocketEchoModule.cs | 174 +++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 OpenSim/Region/OptionalModules/Example/WebSocketEchoTest/WebSocketEchoModule.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Example/WebSocketEchoTest/WebSocketEchoModule.cs b/OpenSim/Region/OptionalModules/Example/WebSocketEchoTest/WebSocketEchoModule.cs new file mode 100644 index 0000000..34e20b7 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Example/WebSocketEchoTest/WebSocketEchoModule.cs @@ -0,0 +1,174 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using OpenSim.Framework.Servers; +using Mono.Addins; +using log4net; +using Nini.Config; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +using OpenSim.Framework.Servers.HttpServer; + + +namespace OpenSim.Region.OptionalModules.WebSocketEchoModule +{ + + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WebSocketEchoModule")] + public class WebSocketEchoModule : ISharedRegionModule + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private bool enabled; + public string Name { get { return "WebSocketEchoModule"; } } + + public Type ReplaceableInterface { get { return null; } } + + + private HashSet _activeHandlers = new HashSet(); + + public void Initialise(IConfigSource pConfig) + { + enabled = true;// (pConfig.Configs["WebSocketEcho"] != null); + if (enabled) + m_log.DebugFormat("[WebSocketEchoModule]: INITIALIZED MODULE"); + } + + /// + /// This method sets up the callback to WebSocketHandlerCallback below when a HTTPRequest comes in for /echo + /// + public void PostInitialise() + { + if (enabled) + MainServer.Instance.AddWebSocketHandler("/echo", WebSocketHandlerCallback); + } + + // This gets called by BaseHttpServer and gives us an opportunity to set things on the WebSocket handler before we turn it on + public void WebSocketHandlerCallback(string path, WebSocketHttpServerHandler handler) + { + SubscribeToEvents(handler); + handler.SetChunksize(8192); + handler.NoDelay_TCP_Nagle = true; + handler.HandshakeAndUpgrade(); + } + + //These are our normal events + public void SubscribeToEvents(WebSocketHttpServerHandler handler) + { + handler.OnClose += HandlerOnOnClose; + handler.OnText += HandlerOnOnText; + handler.OnUpgradeCompleted += HandlerOnOnUpgradeCompleted; + handler.OnData += HandlerOnOnData; + handler.OnPong += HandlerOnOnPong; + } + + public void UnSubscribeToEvents(WebSocketHttpServerHandler handler) + { + handler.OnClose -= HandlerOnOnClose; + handler.OnText -= HandlerOnOnText; + handler.OnUpgradeCompleted -= HandlerOnOnUpgradeCompleted; + handler.OnData -= HandlerOnOnData; + handler.OnPong -= HandlerOnOnPong; + } + + private void HandlerOnOnPong(object sender, PongEventArgs pongdata) + { + m_log.Info("[WebSocketEchoModule]: Got a pong.. ping time: " + pongdata.PingResponseMS); + } + + private void HandlerOnOnData(object sender, WebsocketDataEventArgs data) + { + WebSocketHttpServerHandler obj = sender as WebSocketHttpServerHandler; + obj.SendData(data.Data); + m_log.Info("[WebSocketEchoModule]: We received a bunch of ugly non-printable bytes"); + obj.SendPingCheck(); + } + + + private void HandlerOnOnUpgradeCompleted(object sender, UpgradeCompletedEventArgs completeddata) + { + WebSocketHttpServerHandler obj = sender as WebSocketHttpServerHandler; + _activeHandlers.Add(obj); + } + + private void HandlerOnOnText(object sender, WebsocketTextEventArgs text) + { + WebSocketHttpServerHandler obj = sender as WebSocketHttpServerHandler; + obj.SendMessage(text.Data); + m_log.Info("[WebSocketEchoModule]: We received this: " + text.Data); + } + + // Remove the references to our handler + private void HandlerOnOnClose(object sender, CloseEventArgs closedata) + { + WebSocketHttpServerHandler obj = sender as WebSocketHttpServerHandler; + UnSubscribeToEvents(obj); + + lock (_activeHandlers) + _activeHandlers.Remove(obj); + obj.Dispose(); + } + + // Shutting down.. so shut down all sockets. + // Note.. this should be done outside of an ienumerable if you're also hook to the close event. + public void Close() + { + if (!enabled) + return; + + // We convert this to a for loop so we're not in in an IEnumerable when the close + //call triggers an event which then removes item from _activeHandlers that we're enumerating + WebSocketHttpServerHandler[] items = new WebSocketHttpServerHandler[_activeHandlers.Count]; + _activeHandlers.CopyTo(items); + + for (int i = 0; i < items.Length; i++) + { + items[i].Close(string.Empty); + items[i].Dispose(); + } + _activeHandlers.Clear(); + MainServer.Instance.RemoveWebSocketHandler("/echo"); + } + + public void AddRegion(Scene scene) + { + m_log.DebugFormat("[WebSocketEchoModule]: REGION {0} ADDED", scene.RegionInfo.RegionName); + } + + public void RemoveRegion(Scene scene) + { + m_log.DebugFormat("[WebSocketEchoModule]: REGION {0} REMOVED", scene.RegionInfo.RegionName); + } + + public void RegionLoaded(Scene scene) + { + m_log.DebugFormat("[WebSocketEchoModule]: REGION {0} LOADED", scene.RegionInfo.RegionName); + } + } +} \ No newline at end of file -- cgit v1.1 From a5c83f7505bf897c2d445391802f1ac7a2143d3d Mon Sep 17 00:00:00 2001 From: teravus Date: Thu, 7 Feb 2013 12:22:03 -0500 Subject: Websocket Echo module should not be on by default. --- .../OptionalModules/Example/WebSocketEchoTest/WebSocketEchoModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Example/WebSocketEchoTest/WebSocketEchoModule.cs b/OpenSim/Region/OptionalModules/Example/WebSocketEchoTest/WebSocketEchoModule.cs index 34e20b7..112ba4e 100644 --- a/OpenSim/Region/OptionalModules/Example/WebSocketEchoTest/WebSocketEchoModule.cs +++ b/OpenSim/Region/OptionalModules/Example/WebSocketEchoTest/WebSocketEchoModule.cs @@ -55,7 +55,7 @@ namespace OpenSim.Region.OptionalModules.WebSocketEchoModule public void Initialise(IConfigSource pConfig) { - enabled = true;// (pConfig.Configs["WebSocketEcho"] != null); + enabled =(pConfig.Configs["WebSocketEcho"] != null); if (enabled) m_log.DebugFormat("[WebSocketEchoModule]: INITIALIZED MODULE"); } -- cgit v1.1 From af73ea909cad78eee78bd4e9d9e3a42cf8856263 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 6 Feb 2013 22:34:03 -0800 Subject: Change passed PhysicsParameter value from float to the more general string value --- .../PhysicsParameters/PhysicsParameters.cs | 19 +++------- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 34 +++++++++--------- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 41 +++++++++++++++++----- .../Region/Physics/Manager/IPhysicsParameters.cs | 6 ++-- 4 files changed, 57 insertions(+), 43 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs b/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs index 40f7fbc..3083a33 100755 --- a/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs +++ b/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs @@ -146,7 +146,7 @@ namespace OpenSim.Region.OptionalModules.PhysicsParameters { foreach (PhysParameterEntry ppe in physScene.GetParameterList()) { - float val = 0.0f; + string val = string.Empty; if (physScene.GetPhysicsParameter(ppe.name, out val)) { WriteOut(" {0}/{1} = {2}", scene.RegionInfo.RegionName, ppe.name, val); @@ -159,7 +159,7 @@ namespace OpenSim.Region.OptionalModules.PhysicsParameters } else { - float val = 0.0f; + string val = string.Empty; if (physScene.GetPhysicsParameter(parm, out val)) { WriteOut(" {0}/{1} = {2}", scene.RegionInfo.RegionName, parm, val); @@ -185,21 +185,12 @@ namespace OpenSim.Region.OptionalModules.PhysicsParameters return; } string parm = "xxx"; - float val = 0f; + string valparm = String.Empty; uint localID = (uint)PhysParameterEntry.APPLY_TO_NONE; // set default value try { parm = cmdparms[2]; - string valparm = cmdparms[3].ToLower(); - if (valparm == "true") - val = PhysParameterEntry.NUMERIC_TRUE; - else - { - if (valparm == "false") - val = PhysParameterEntry.NUMERIC_FALSE; - else - val = float.Parse(valparm, Culture.NumberFormatInfo); - } + valparm = cmdparms[3].ToLower(); if (cmdparms.Length > 4) { if (cmdparms[4].ToLower() == "all") @@ -224,7 +215,7 @@ namespace OpenSim.Region.OptionalModules.PhysicsParameters IPhysicsParameters physScene = scene.PhysicsScene as IPhysicsParameters; if (physScene != null) { - if (!physScene.SetPhysicsParameter(parm, val, localID)) + if (!physScene.SetPhysicsParameter(parm, valparm, localID)) { WriteError("Failed set of parameter '{0}' for region '{1}'", parm, scene.RegionInfo.RegionName); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 965c382..601c78c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -641,24 +641,6 @@ public static class BSParam return (b == ConfigurationParameters.numericTrue ? true : false); } - private static void ResetBroadphasePoolTainted(BSScene pPhysScene, float v) - { - BSScene physScene = pPhysScene; - physScene.TaintedObject("BSParam.ResetBroadphasePoolTainted", delegate() - { - physScene.PE.ResetBroadphasePool(physScene.World); - }); - } - - private static void ResetConstraintSolverTainted(BSScene pPhysScene, float v) - { - BSScene physScene = pPhysScene; - physScene.TaintedObject("BSParam.ResetConstraintSolver", delegate() - { - physScene.PE.ResetConstraintSolver(physScene.World); - }); - } - // Search through the parameter definitions and return the matching // ParameterDefn structure. // Case does not matter as names are compared after converting to lower case. @@ -722,6 +704,22 @@ public static class BSParam } } + private static void ResetBroadphasePoolTainted(BSScene pPhysScene, float v) + { + BSScene physScene = pPhysScene; + physScene.TaintedObject("BSParam.ResetBroadphasePoolTainted", delegate() + { + physScene.PE.ResetBroadphasePool(physScene.World); + }); + } + private static void ResetConstraintSolverTainted(BSScene pPhysScene, float v) + { + BSScene physScene = pPhysScene; + physScene.TaintedObject("BSParam.ResetConstraintSolver", delegate() + { + physScene.PE.ResetConstraintSolver(physScene.World); + }); + } } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 6cd72f2..f8a0c1e 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -876,14 +876,39 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // will use the next time since it's pinned and shared memory. // Some of the values require calling into the physics engine to get the new // value activated ('terrainFriction' for instance). - public bool SetPhysicsParameter(string parm, float val, uint localID) + public bool SetPhysicsParameter(string parm, string val, uint localID) { bool ret = false; + + float valf = 0f; + if (val.ToLower() == "true") + { + valf = PhysParameterEntry.NUMERIC_TRUE; + } + else + { + if (val.ToLower() == "false") + { + valf = PhysParameterEntry.NUMERIC_FALSE; + } + else + { + try + { + valf = float.Parse(val); + } + catch + { + valf = 0f; + } + } + } + BSParam.ParameterDefn theParam; if (BSParam.TryGetParameter(parm, out theParam)) { // Set the value in the C# code - theParam.setter(this, parm, localID, val); + theParam.setter(this, parm, localID, valf); // Optionally set the parameter in the unmanaged code if (theParam.onObject != null) @@ -898,16 +923,16 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters case PhysParameterEntry.APPLY_TO_NONE: // This will cause a call into the physical world if some operation is specified (SetOnObject). objectIDs.Add(TERRAIN_ID); - TaintedUpdateParameter(parm, objectIDs, val); + TaintedUpdateParameter(parm, objectIDs, valf); break; case PhysParameterEntry.APPLY_TO_ALL: lock (PhysObjects) objectIDs = new List(PhysObjects.Keys); - TaintedUpdateParameter(parm, objectIDs, val); + TaintedUpdateParameter(parm, objectIDs, valf); break; default: // setting only one localID objectIDs.Add(localID); - TaintedUpdateParameter(parm, objectIDs, val); + TaintedUpdateParameter(parm, objectIDs, valf); break; } } @@ -942,14 +967,14 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // Get parameter. // Return 'false' if not able to get the parameter. - public bool GetPhysicsParameter(string parm, out float value) + public bool GetPhysicsParameter(string parm, out string value) { - float val = 0f; + string val = String.Empty; bool ret = false; BSParam.ParameterDefn theParam; if (BSParam.TryGetParameter(parm, out theParam)) { - val = theParam.getter(this); + val = theParam.getter(this).ToString(); ret = true; } value = val; diff --git a/OpenSim/Region/Physics/Manager/IPhysicsParameters.cs b/OpenSim/Region/Physics/Manager/IPhysicsParameters.cs index b8676ba..31a397c 100755 --- a/OpenSim/Region/Physics/Manager/IPhysicsParameters.cs +++ b/OpenSim/Region/Physics/Manager/IPhysicsParameters.cs @@ -60,14 +60,14 @@ namespace OpenSim.Region.Physics.Manager // Set parameter on a specific or all instances. // Return 'false' if not able to set the parameter. - bool SetPhysicsParameter(string parm, float value, uint localID); + bool SetPhysicsParameter(string parm, string value, uint localID); // Get parameter. // Return 'false' if not able to get the parameter. - bool GetPhysicsParameter(string parm, out float value); + bool GetPhysicsParameter(string parm, out string value); // Get parameter from a particular object // TODO: - // bool GetPhysicsParameter(string parm, out float value, uint localID); + // bool GetPhysicsParameter(string parm, out string value, uint localID); } } -- cgit v1.1 From c658fa1c0dd83f23c66ccfedb12e8ab02ff01d0a Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 7 Feb 2013 11:05:21 -0800 Subject: Add plumbing for physics properties to get to the physics engine. Addition of entries to PhysicsActor and setting code in SceneObjectPart. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 56 +++++++++++++++++++--- OpenSim/Region/Physics/Manager/PhysicsActor.cs | 5 ++ 2 files changed, 55 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index b00f388..a3c7ed3 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1387,10 +1387,46 @@ namespace OpenSim.Region.Framework.Scenes } } - public float Density { get; set; } - public float GravityModifier { get; set; } - public float Friction { get; set; } - public float Restitution { get; set; } + private float m_density = 10f; + public float Density { + get { return m_density; } + set + { + m_density = value; + if (PhysActor != null) + PhysActor.Density = m_density; + } + } + private float m_gravityModifier = 1f; + public float GravityModifier { + get { return m_gravityModifier; } + set + { + m_gravityModifier = value; + if (PhysActor != null) + PhysActor.GravityModifier = m_gravityModifier; + } + } + private float m_friction = 0.5f; + public float Friction { + get { return m_friction; } + set + { + m_friction = value; + if (PhysActor != null) + PhysActor.Friction = m_friction; + } + } + private float m_restitution = 0f; + public float Restitution { + get { return m_restitution; } + set + { + m_restitution = value; + if (PhysActor != null) + PhysActor.Restitution = m_restitution; + } + } #endregion Public Properties with only Get @@ -1896,8 +1932,18 @@ namespace OpenSim.Region.Framework.Scenes { ParentGroup.Scene.AddPhysicalPrim(1); + // Update initial values for various physical properties + pa.SetMaterial(Material); + pa.Density = Density; + pa.Friction = Friction; + pa.Restitution = Restitution; + pa.GravityModifier = GravityModifier; + + // Link up callbacks for property updates from the physics engine pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; pa.OnOutOfBounds += PhysicsOutOfBounds; + + // If this is a child prim, tell the physics engine about the parent if (ParentID != 0 && ParentID != LocalId) { PhysicsActor parentPa = ParentGroup.RootPart.PhysActor; @@ -4062,7 +4108,6 @@ namespace OpenSim.Region.Framework.Scenes if (pa != null) { - pa.SetMaterial(Material); DoPhysicsPropertyUpdate(UsePhysics, true); if ( @@ -4175,7 +4220,6 @@ namespace OpenSim.Region.Framework.Scenes if (pa != null) { pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info - pa.SetMaterial(Material); DoPhysicsPropertyUpdate(rigidBody, true); } diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index d119791..4820ca4 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs @@ -235,6 +235,11 @@ namespace OpenSim.Region.Physics.Manager public abstract float Mass { get; } public abstract Vector3 Force { get; set; } + public virtual float Density { get; set; } + public virtual float Friction { get; set; } + public virtual float Restitution { get; set; } + public virtual float GravityModifier { get; set; } + public abstract int VehicleType { get; set; } public abstract void VehicleFloatParam(int param, float value); public abstract void VehicleVectorParam(int param, Vector3 value); -- cgit v1.1 From 9089757ea2cabe49f40de64b7e6befa13a4553c1 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 7 Feb 2013 21:05:58 +0000 Subject: Revert "Add plumbing for physics properties to get to the physics engine." This reverts commit c658fa1c0dd83f23c66ccfedb12e8ab02ff01d0a. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 56 +++------------------- OpenSim/Region/Physics/Manager/PhysicsActor.cs | 5 -- 2 files changed, 6 insertions(+), 55 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index a3c7ed3..b00f388 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1387,46 +1387,10 @@ namespace OpenSim.Region.Framework.Scenes } } - private float m_density = 10f; - public float Density { - get { return m_density; } - set - { - m_density = value; - if (PhysActor != null) - PhysActor.Density = m_density; - } - } - private float m_gravityModifier = 1f; - public float GravityModifier { - get { return m_gravityModifier; } - set - { - m_gravityModifier = value; - if (PhysActor != null) - PhysActor.GravityModifier = m_gravityModifier; - } - } - private float m_friction = 0.5f; - public float Friction { - get { return m_friction; } - set - { - m_friction = value; - if (PhysActor != null) - PhysActor.Friction = m_friction; - } - } - private float m_restitution = 0f; - public float Restitution { - get { return m_restitution; } - set - { - m_restitution = value; - if (PhysActor != null) - PhysActor.Restitution = m_restitution; - } - } + public float Density { get; set; } + public float GravityModifier { get; set; } + public float Friction { get; set; } + public float Restitution { get; set; } #endregion Public Properties with only Get @@ -1932,18 +1896,8 @@ namespace OpenSim.Region.Framework.Scenes { ParentGroup.Scene.AddPhysicalPrim(1); - // Update initial values for various physical properties - pa.SetMaterial(Material); - pa.Density = Density; - pa.Friction = Friction; - pa.Restitution = Restitution; - pa.GravityModifier = GravityModifier; - - // Link up callbacks for property updates from the physics engine pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; pa.OnOutOfBounds += PhysicsOutOfBounds; - - // If this is a child prim, tell the physics engine about the parent if (ParentID != 0 && ParentID != LocalId) { PhysicsActor parentPa = ParentGroup.RootPart.PhysActor; @@ -4108,6 +4062,7 @@ namespace OpenSim.Region.Framework.Scenes if (pa != null) { + pa.SetMaterial(Material); DoPhysicsPropertyUpdate(UsePhysics, true); if ( @@ -4220,6 +4175,7 @@ namespace OpenSim.Region.Framework.Scenes if (pa != null) { pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info + pa.SetMaterial(Material); DoPhysicsPropertyUpdate(rigidBody, true); } diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index 4820ca4..d119791 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs @@ -235,11 +235,6 @@ namespace OpenSim.Region.Physics.Manager public abstract float Mass { get; } public abstract Vector3 Force { get; set; } - public virtual float Density { get; set; } - public virtual float Friction { get; set; } - public virtual float Restitution { get; set; } - public virtual float GravityModifier { get; set; } - public abstract int VehicleType { get; set; } public abstract void VehicleFloatParam(int param, float value); public abstract void VehicleVectorParam(int param, Vector3 value); -- cgit v1.1 From 338b02a8bc51d1dc5c1161a2a5a10b85521d1f8e Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 7 Feb 2013 21:23:35 +0000 Subject: Send the new physics params to the viewer build dialog --- .../Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index 568e216..1af61db 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -96,6 +96,8 @@ namespace OpenSim.Region.ClientStack.Linden // private static readonly string m_fetchInventoryPath = "0006/"; private static readonly string m_copyFromNotecardPath = "0007/"; // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule. + private static readonly string m_getObjectPhysicsDataPath = "0101/"; + /* 0102 - 0103 RESERVED */ private static readonly string m_UpdateAgentInformationPath = "0500/"; // These are callbacks which will be setup by the scene so that we can update scene data when we @@ -204,6 +206,8 @@ namespace OpenSim.Region.ClientStack.Linden m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req); m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req); m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req); + IRequestHandler getObjectPhysicsDataHandler = new RestStreamHandler("POST", capsBase + m_getObjectPhysicsDataPath, GetObjectPhysicsData); + m_HostCapsObj.RegisterHandler("GetObjectPhysicsData", getObjectPhysicsDataHandler); IRequestHandler UpdateAgentInformationHandler = new RestStreamHandler("POST", capsBase + m_UpdateAgentInformationPath, UpdateAgentInformation); m_HostCapsObj.RegisterHandler("UpdateAgentInformation", UpdateAgentInformationHandler); @@ -873,6 +877,37 @@ namespace OpenSim.Region.ClientStack.Linden return LLSDHelpers.SerialiseLLSDReply(response); } + public string GetObjectPhysicsData(string request, string path, + string param, IOSHttpRequest httpRequest, + IOSHttpResponse httpResponse) + { + OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request); + OSDMap resp = new OSDMap(); + OSDArray object_ids = (OSDArray)req["object_ids"]; + + for (int i = 0 ; i < object_ids.Count ; i++) + { + UUID uuid = object_ids[i].AsUUID(); + + SceneObjectPart obj = m_Scene.GetSceneObjectPart(uuid); + if (obj != null) + { + OSDMap object_data = new OSDMap(); + + object_data["PhysicsShapeType"] = obj.PhysicsShapeType; + object_data["Density"] = obj.Density; + object_data["Friction"] = obj.Friction; + object_data["Restitution"] = obj.Restitution; + object_data["GravityMultiplier"] = obj.GravityModifier; + + resp[uuid.ToString()] = object_data; + } + } + + string response = OSDParser.SerializeLLSDXmlString(resp); + return response; + } + public string UpdateAgentInformation(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) -- cgit v1.1 From 7bf33d333af6e7393a05940d1ab436f5dce73814 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 7 Feb 2013 22:25:28 +0000 Subject: Plumb the path from the client to the extra physics params and back --- .../Linden/Caps/EventQueue/EventQueueGetModule.cs | 8 +++ .../Linden/Caps/EventQueue/EventQueueHelper.cs | 20 ++++++++ .../Region/ClientStack/Linden/UDP/LLClientView.cs | 59 ++++++++++++++++++++-- OpenSim/Region/Framework/Interfaces/IEventQueue.cs | 2 + OpenSim/Region/Framework/Scenes/SceneGraph.cs | 25 ++++++++- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 1 + .../Server/IRCClientView.cs | 5 ++ .../Region/OptionalModules/World/NPC/NPCAvatar.cs | 5 ++ 8 files changed, 119 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index 4d2c0f2..3cc3950 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -807,5 +807,13 @@ namespace OpenSim.Region.ClientStack.Linden { return EventQueueHelper.BuildEvent(eventName, eventBody); } + + public void partPhysicsProperties(uint localID, byte physhapetype, + float density, float friction, float bounce, float gravmod,UUID avatarID) + { + OSD item = EventQueueHelper.partPhysicsProperties(localID, physhapetype, + density, friction, bounce, gravmod); + Enqueue(item, avatarID); + } } } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs index 3f49aba..dab727f 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs @@ -395,5 +395,25 @@ namespace OpenSim.Region.ClientStack.Linden return message; } + public static OSD partPhysicsProperties(uint localID, byte physhapetype, + float density, float friction, float bounce, float gravmod) + { + + OSDMap physinfo = new OSDMap(6); + physinfo["LocalID"] = localID; + physinfo["Density"] = density; + physinfo["Friction"] = friction; + physinfo["GravityMultiplier"] = gravmod; + physinfo["Restitution"] = bounce; + physinfo["PhysicsShapeType"] = (int)physhapetype; + + OSDArray array = new OSDArray(1); + array.Add(physinfo); + + OSDMap llsdBody = new OSDMap(1); + llsdBody.Add("ObjectData", array); + + return BuildEvent("ObjectPhysicsProperties", llsdBody); + } } } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 88b64f5..bd4a2d1 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -2627,6 +2627,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } + public void SendPartPhysicsProprieties(ISceneEntity entity) + { + SceneObjectPart part = (SceneObjectPart)entity; + if (part != null && AgentId != UUID.Zero) + { + try + { + IEventQueue eq = Scene.RequestModuleInterface(); + if (eq != null) + { + uint localid = part.LocalId; + byte physshapetype = part.PhysicsShapeType; + float density = part.Density; + float friction = part.Friction; + float bounce = part.Restitution; + float gravmod = part.GravityModifier; + eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId); + } + } + catch (Exception ex) + { + m_log.Error("Unable to send part Physics Proprieties - exception: " + ex.ToString()); + } + part.UpdatePhysRequired = false; + } + } + + public void SendGroupNameReply(UUID groupLLUID, string GroupName) { @@ -7035,10 +7063,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP // 46,47,48 are special positions within the packet // This may change so perhaps we need a better way // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?) - bool UsePhysics = (data[46] != 0) ? true : false; - bool IsTemporary = (data[47] != 0) ? true : false; - bool IsPhantom = (data[48] != 0) ? true : false; - handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this); + /* + bool UsePhysics = (data[46] != 0) ? true : false; + bool IsTemporary = (data[47] != 0) ? true : false; + bool IsPhantom = (data[48] != 0) ? true : false; + handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this); + */ + bool UsePhysics = flags.AgentData.UsePhysics; + bool IsPhantom = flags.AgentData.IsPhantom; + bool IsTemporary = flags.AgentData.IsTemporary; + ObjectFlagUpdatePacket.ExtraPhysicsBlock[] blocks = flags.ExtraPhysics; + ExtraPhysicsData physdata = new ExtraPhysicsData(); + + if (blocks == null || blocks.Length == 0) + { + physdata.PhysShapeType = PhysShapeType.invalid; + } + else + { + ObjectFlagUpdatePacket.ExtraPhysicsBlock phsblock = blocks[0]; + physdata.PhysShapeType = (PhysShapeType)phsblock.PhysicsShapeType; + physdata.Bounce = phsblock.Restitution; + physdata.Density = phsblock.Density; + physdata.Friction = phsblock.Friction; + physdata.GravitationModifier = phsblock.GravityMultiplier; + } + + handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this); } return true; } diff --git a/OpenSim/Region/Framework/Interfaces/IEventQueue.cs b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs index bfa5d17..5512642 100644 --- a/OpenSim/Region/Framework/Interfaces/IEventQueue.cs +++ b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs @@ -59,5 +59,7 @@ namespace OpenSim.Region.Framework.Interfaces void GroupMembership(AgentGroupDataUpdatePacket groupUpdate, UUID avatarID); OSD ScriptRunningEvent(UUID objectID, UUID itemID, bool running, bool mono); OSD BuildEvent(string eventName, OSD eventBody); + void partPhysicsProperties(uint localID, byte physhapetype, float density, float friction, float bounce, float gravmod, UUID avatarID); + } } diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index a4383fd..a84f6d3 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1408,7 +1408,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// protected internal void UpdatePrimFlags( - uint localID, bool UsePhysics, bool SetTemporary, bool SetPhantom, IClientAPI remoteClient) + uint localID, bool UsePhysics, bool SetTemporary, bool SetPhantom, ExtraPhysicsData PhysData, IClientAPI remoteClient) { SceneObjectGroup group = GetGroupByPrim(localID); if (group != null) @@ -1416,7 +1416,28 @@ namespace OpenSim.Region.Framework.Scenes if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) { // VolumeDetect can't be set via UI and will always be off when a change is made there - group.UpdatePrimFlags(localID, UsePhysics, SetTemporary, SetPhantom, false); + // now only change volume dtc if phantom off + + if (PhysData.PhysShapeType == PhysShapeType.invalid) // check for extraPhysics data + { + bool vdtc; + if (SetPhantom) // if phantom keep volumedtc + vdtc = group.RootPart.VolumeDetectActive; + else // else turn it off + vdtc = false; + + group.UpdatePrimFlags(localID, UsePhysics, SetTemporary, SetPhantom, vdtc); + } + else + { + SceneObjectPart part = GetSceneObjectPart(localID); + if (part != null) + { + part.UpdateExtraPhysics(PhysData); + if (part.UpdatePhysRequired) + remoteClient.SendPartPhysicsProprieties(part); + } + } } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index b00f388..cd40b29 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1042,6 +1042,7 @@ namespace OpenSim.Region.Framework.Scenes } public UpdateRequired UpdateFlag { get; set; } + public bool UpdatePhysRequired { get; set; } /// /// Used for media on a prim. diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 781539a..0ac56fa 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -1678,5 +1678,10 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server public void SendPlacesReply(UUID queryID, UUID transactionID, PlacesReplyData[] data) { } + + public void SendPartPhysicsProprieties(ISceneEntity entity) + { + } + } } diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 5ea2bcd..6bd27f0 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -1234,5 +1234,10 @@ namespace OpenSim.Region.OptionalModules.World.NPC public void SendPlacesReply(UUID queryID, UUID transactionID, PlacesReplyData[] data) { } + + public void SendPartPhysicsProprieties(ISceneEntity entity) + { + } + } } -- cgit v1.1 From c135c3224fcdc88a610b0d66da0c0dd6cd1211f9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 7 Feb 2013 23:08:19 +0000 Subject: Fix a recent regression in e17392a where JsonSetValue() stopped working (probably other functions as well). Fix is to call through to the no-arg constructor from the string constructor in JsonStore, which I suspect was just forgotten. This was actually picked up by the TestJsonSetValue() regression test failing But this isn't being run on jenkins due to the .net version issue. This commit also puts the full stack trace in logged messages and makes these error level messages instead of info --- .../OptionalModules/Scripting/JsonStore/JsonStore.cs | 2 +- .../Scripting/JsonStore/JsonStoreModule.cs | 20 ++++++++++---------- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 8 ++++---- 3 files changed, 15 insertions(+), 15 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs index 751e463..5808d46 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs @@ -114,7 +114,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore m_ReadStore = new List(); } - public JsonStore(string value) + public JsonStore(string value) : this() { if (String.IsNullOrEmpty(value)) ValueStore = new OSDMap(); diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs index a36ef42..3b52e44 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs @@ -93,12 +93,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } catch (Exception e) { - m_log.ErrorFormat("[JsonStore] initialization error: {0}",e.Message); + m_log.Error("[JsonStore]: initialization error: {0}", e); return; } if (m_enabled) - m_log.DebugFormat("[JsonStore] module is enabled"); + m_log.DebugFormat("[JsonStore]: module is enabled"); } // ----------------------------------------------------------------- @@ -182,7 +182,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore SceneObjectPart sop = m_scene.GetSceneObjectPart(objectID); if (sop == null) { - m_log.InfoFormat("[JsonStore] unable to attach to unknown object; {0}",objectID); + m_log.ErrorFormat("[JsonStore] unable to attach to unknown object; {0}", objectID); return false; } @@ -219,7 +219,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } catch (Exception e) { - m_log.InfoFormat("[JsonStore] Unable to initialize store from {0}; {1}",value,e.Message); + m_log.Error(string.Format("[JsonStore]: Unable to initialize store from {0}", value), e); return false; } @@ -283,7 +283,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } catch (Exception e) { - m_log.InfoFormat("[JsonStore] Path test failed for {0} in {1}; {2}",path,storeID,e.Message); + m_log.Error(string.Format("[JsonStore]: Path test failed for {0} in {1}", path, storeID), e); } return false; @@ -316,7 +316,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } catch (Exception e) { - m_log.InfoFormat("[JsonStore] Unable to assign {0} to {1} in {2}; {3}",value,path,storeID,e.Message); + m_log.Error(string.Format("[JsonStore]: Unable to assign {0} to {1} in {2}", value, path, storeID), e); } return false; @@ -349,7 +349,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } catch (Exception e) { - m_log.InfoFormat("[JsonStore] Unable to remove {0} in {1}; {2}",path,storeID,e.Message); + m_log.Error(string.Format("[JsonStore]: Unable to remove {0} in {1}", path, storeID), e); } return false; @@ -382,7 +382,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } catch (Exception e) { - m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.Message); + m_log.Error("[JsonStore]: unable to retrieve value", e); } return false; @@ -421,7 +421,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } catch (Exception e) { - m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.ToString()); + m_log.Error("[JsonStore] unable to retrieve value", e); } cback(String.Empty); @@ -460,7 +460,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } catch (Exception e) { - m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.ToString()); + m_log.Error("[JsonStore]: unable to retrieve value", e); } cback(String.Empty); diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 8042a93..eddae38 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -184,13 +184,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests TestHelpers.InMethod(); // TestHelpers.EnableLogging(); - UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); - int result = (int)InvokeOp("JsonSetValue", storeId, "Hello", "World"); + int result = (int)InvokeOp("JsonSetValue", storeId, "Fun", "Times"); Assert.That(result, Is.EqualTo(1)); - string value = (string)InvokeOp("JsonGetValue", storeId, "Hello"); - Assert.That(value, Is.EqualTo("World")); + string value = (string)InvokeOp("JsonGetValue", storeId, "Fun"); + Assert.That(value, Is.EqualTo("Times")); } public object DummyTestMethod(object o1, object o2, object o3, object o4, object o5) { return null; } -- cgit v1.1 From 22675e6b14ce1b180f517c1ab92627d283192032 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 7 Feb 2013 23:22:00 +0000 Subject: Add some more code from Avination. This changes physics actor stuff around to work with the new params. Not actually plumbed just yet. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 189 +++++++++++++++++---- OpenSim/Region/Physics/Manager/PhysicsActor.cs | 10 +- OpenSim/Region/Physics/Manager/PhysicsScene.cs | 6 + 3 files changed, 165 insertions(+), 40 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index cd40b29..9f602f7 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -304,11 +304,10 @@ namespace OpenSim.Region.Framework.Scenes protected int m_lastTerseSent; protected byte m_physicsShapeType = (byte)PhysShapeType.prim; - // TODO: Implement these - //protected float m_density = 1000.0f; // in kg/m^3 - //protected float m_gravitymod = 1.0f; - //protected float m_friction = 0.6f; // wood - //protected float m_bounce = 0.5f; // wood + protected float m_density = 1000.0f; // in kg/m^3 + protected float m_gravitymod = 1.0f; + protected float m_friction = 0.6f; // wood + protected float m_bounce = 0.5f; // wood /// /// Stores media texture data @@ -1379,19 +1378,92 @@ namespace OpenSim.Region.Framework.Scenes } else { - // TODO: Update physics actor + PhysActor.PhysicsShapeType = m_physicsShapeType; } if (ParentGroup != null) ParentGroup.HasGroupChanged = true; } + + if (m_physicsShapeType != value) + { + UpdatePhysRequired = true; + } } } - public float Density { get; set; } - public float GravityModifier { get; set; } - public float Friction { get; set; } - public float Restitution { get; set; } + public float Density // in kg/m^3 + { + get { return m_density; } + set + { + if (value >=1 && value <= 22587.0) + { + m_density = value; + UpdatePhysRequired = true; + } + + ScheduleFullUpdateIfNone(); + + if (ParentGroup != null) + ParentGroup.HasGroupChanged = true; + } + } + + public float GravityModifier + { + get { return m_gravitymod; } + set + { + if( value >= -1 && value <=28.0f) + { + m_gravitymod = value; + UpdatePhysRequired = true; + } + + ScheduleFullUpdateIfNone(); + + if (ParentGroup != null) + ParentGroup.HasGroupChanged = true; + + } + } + + public float Friction + { + get { return m_friction; } + set + { + if (value >= 0 && value <= 255.0f) + { + m_friction = value; + UpdatePhysRequired = true; + } + + ScheduleFullUpdateIfNone(); + + if (ParentGroup != null) + ParentGroup.HasGroupChanged = true; + } + } + + public float Restitution + { + get { return m_bounce; } + set + { + if (value >= 0 && value <= 1.0f) + { + m_bounce = value; + UpdatePhysRequired = true; + } + + ScheduleFullUpdateIfNone(); + + if (ParentGroup != null) + ParentGroup.HasGroupChanged = true; + } + } #endregion Public Properties with only Get @@ -1589,8 +1661,10 @@ namespace OpenSim.Region.Framework.Scenes /// /// /// - public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive) + public void ApplyPhysics(uint rootObjectFlags, bool _VolumeDetectActive) { + VolumeDetectActive = _VolumeDetectActive; + if (!ParentGroup.Scene.CollidablePrims) return; @@ -1600,28 +1674,22 @@ namespace OpenSim.Region.Framework.Scenes bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0; bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0; + if (_VolumeDetectActive) + isPhantom = true; + if (IsJoint()) { DoPhysicsPropertyUpdate(isPhysical, true); } else { - // Special case for VolumeDetection: If VolumeDetection is set, the phantom flag is locally ignored - if (VolumeDetectActive) - isPhantom = false; - - // The only time the physics scene shouldn't know about the prim is if it's phantom or an attachment, which is phantom by definition - // or flexible - if (!isPhantom && !ParentGroup.IsAttachment && !(Shape.PathCurve == (byte)Extrusion.Flexible)) + if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment + && !(Shape.PathCurve == (byte)Extrusion.Flexible)) { - // Added clarification.. since A rigid body is an object that you can kick around, etc. - bool rigidBody = isPhysical && !isPhantom; - - PhysicsActor pa = AddToPhysics(rigidBody); - - if (pa != null) - pa.SetVolumeDetect(VolumeDetectActive ? 1 : 0); + AddToPhysics(isPhysical, isPhantom, isPhysical); } + else + PhysActor = null; // just to be sure } } @@ -2503,6 +2571,19 @@ namespace OpenSim.Region.Framework.Scenes APIDTarget = Quaternion.Identity; } + + + public void ScheduleFullUpdateIfNone() + { + if (ParentGroup == null) + return; + +// ??? ParentGroup.HasGroupChanged = true; + + if (UpdateFlag != UpdateRequired.FULL) + ScheduleFullUpdate(); + } + /// /// Schedules this prim for a full update /// @@ -4059,7 +4140,9 @@ namespace OpenSim.Region.Framework.Scenes if (ParentGroup.Scene.CollidablePrims && pa == null) { - pa = AddToPhysics(UsePhysics); + AddToPhysics(UsePhysics, SetPhantom, false); + pa = PhysActor; + if (pa != null) { @@ -4146,10 +4229,13 @@ namespace OpenSim.Region.Framework.Scenes /// /// The physics actor. null if there was a failure. /// - private PhysicsActor AddToPhysics(bool rigidBody) + private void AddToPhysics(bool isPhysical, bool isPhantom, bool applyDynamics) { PhysicsActor pa; + Vector3 velocity = Velocity; + Vector3 rotationalVelocity = AngularVelocity;; + try { pa = ParentGroup.Scene.PhysicsScene.AddPrimShape( @@ -4157,8 +4243,10 @@ namespace OpenSim.Region.Framework.Scenes Shape, AbsolutePosition, Scale, - RotationOffset, - rigidBody, + GetWorldRotation(), + isPhysical, + isPhantom, + PhysicsShapeType, m_localId); } catch (Exception e) @@ -4167,20 +4255,47 @@ namespace OpenSim.Region.Framework.Scenes pa = null; } - // FIXME: Ideally we wouldn't set the property here to reduce situations where threads changing physical - // properties can stop on each other. However, DoPhysicsPropertyUpdate() currently relies on PhysActor - // being set. - PhysActor = pa; - - // Basic Physics can also return null as well as an exception catch. if (pa != null) { pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info pa.SetMaterial(Material); - DoPhysicsPropertyUpdate(rigidBody, true); + + if (VolumeDetectActive) // change if not the default only + pa.SetVolumeDetect(1); + // we are going to tell rest of code about physics so better have this here + PhysActor = pa; + + if (isPhysical) + { + ParentGroup.Scene.AddPhysicalPrim(1); + + pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; + pa.OnOutOfBounds += PhysicsOutOfBounds; + + if (ParentID != 0 && ParentID != LocalId) + { + PhysicsActor parentPa = ParentGroup.RootPart.PhysActor; + + if (parentPa != null) + { + pa.link(parentPa); + } + } + } + + if (applyDynamics) + // do independent of isphysical so parameters get setted (at least some) + { + Velocity = velocity; + AngularVelocity = rotationalVelocity; +// pa.Velocity = velocity; + pa.RotationalVelocity = rotationalVelocity; + } + + ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); } - return pa; + PhysActor = pa; } /// diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index d119791..bd806eb 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs @@ -147,6 +147,8 @@ namespace OpenSim.Region.Physics.Manager public abstract Vector3 Size { get; set; } + public virtual byte PhysicsShapeType { get; set; } + public abstract PrimitiveBaseShape Shape { set; } uint m_baseLocalID; @@ -218,9 +220,11 @@ namespace OpenSim.Region.Physics.Manager handler(e); } - public virtual void SetMaterial (int material) - { - } + public virtual void SetMaterial (int material) { } + public virtual float Density { get; set; } + public virtual float GravModifier { get; set; } + public virtual float Friction { get; set; } + public virtual float Restitution { get; set; } /// /// Position of this actor. diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index c4d7ef3..290b72e 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs @@ -166,6 +166,12 @@ namespace OpenSim.Region.Physics.Manager public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, Vector3 size, Quaternion rotation, bool isPhysical, uint localid); + public virtual PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, + Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, byte shapetype, uint localid) + { + return AddPrimShape(primName, pbs, position, size, rotation, isPhysical, localid); + } + public virtual float TimeDilation { get { return 1.0f; } -- cgit v1.1 From 2e86978b609e3e2013a8f4c53f9afc9ed239d20b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 7 Feb 2013 23:30:03 +0000 Subject: Add TestJsonDestoreStoreNotExists() This still returns true even if we ask to destroy a store that does not exist. Need to check that this is more appropriate behaviour. --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index aea94ea..5484d8d 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -135,6 +135,20 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests } [Test] + public void TestJsonDestroyStoreNotExists() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID fakeStoreId = TestHelpers.ParseTail(0x500); + + int dsrv = (int)InvokeOp("JsonDestroyStore", fakeStoreId); + + // XXX: Current returns 'true' even though no such store existed. Need to ask if this is best behaviour. + Assert.That(dsrv, Is.EqualTo(1)); + } + + [Test] public void TestJsonGetValue() { TestHelpers.InMethod(); -- cgit v1.1 From a2dad09172ce462ea38ff77b684f07ae4b22fbd8 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 7 Feb 2013 23:34:47 +0000 Subject: Actually plumb the new values to physics. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 9f602f7..9b29973 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1407,6 +1407,10 @@ namespace OpenSim.Region.Framework.Scenes if (ParentGroup != null) ParentGroup.HasGroupChanged = true; + + PhysicsActor pa = PhysActor; + if (pa != null) + pa.Density = Density; } } @@ -1426,6 +1430,9 @@ namespace OpenSim.Region.Framework.Scenes if (ParentGroup != null) ParentGroup.HasGroupChanged = true; + PhysicsActor pa = PhysActor; + if (pa != null) + pa.GravModifier = GravityModifier; } } @@ -1444,6 +1451,10 @@ namespace OpenSim.Region.Framework.Scenes if (ParentGroup != null) ParentGroup.HasGroupChanged = true; + + PhysicsActor pa = PhysActor; + if (pa != null) + pa.Friction = Friction; } } @@ -1462,6 +1473,10 @@ namespace OpenSim.Region.Framework.Scenes if (ParentGroup != null) ParentGroup.HasGroupChanged = true; + + PhysicsActor pa = PhysActor; + if (pa != null) + pa.Restitution = Restitution; } } @@ -4260,6 +4275,11 @@ namespace OpenSim.Region.Framework.Scenes pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info pa.SetMaterial(Material); + pa.Density = Density; + pa.GravModifier = GravityModifier; + pa.Friction = Friction; + pa.Restitution = Restitution; + if (VolumeDetectActive) // change if not the default only pa.SetVolumeDetect(1); // we are going to tell rest of code about physics so better have this here -- cgit v1.1 From 715d6f2da1fa9fb770899a399ccbece2d35a2323 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 7 Feb 2013 23:52:28 +0000 Subject: Add testing for getting non-existing values and values from a non-existing datastore to TestJsonGetValue() --- .../Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 5484d8d..d341901 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -158,6 +158,15 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests string value = (string)InvokeOp("JsonGetValue", storeId, "Hello"); Assert.That(value, Is.EqualTo("World")); + + // Test get of non-existing value + string fakeValueGet = (string)InvokeOp("JsonGetValue", storeId, "foo"); + Assert.That(fakeValueGet, Is.EqualTo("")); + + // Test get from non-existing store + UUID fakeStoreId = TestHelpers.ParseTail(0x500); + string fakeStoreValueGet = (string)InvokeOp("JsonGetValue", fakeStoreId, "Hello"); + Assert.That(fakeStoreValueGet, Is.EqualTo("")); } // [Test] @@ -239,7 +248,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests public void TestJsonWriteReadNotecard() { TestHelpers.InMethod(); - TestHelpers.EnableLogging(); +// TestHelpers.EnableLogging(); string notecardName = "nc1"; -- cgit v1.1 From 75f1e0431580975e5588b63025c7c94aedafb050 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 7 Feb 2013 23:58:19 +0000 Subject: Add tests for removing fake values/from fake store in TestJsonRemoveValue() Again, need to check if returning true for removing a value that doesn't exist is most appropriate. --- .../Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index d341901..297c33c 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -208,6 +208,17 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests string returnValue2 = (string)InvokeOp("JsonGetValue", storeId, "Hello"); Assert.That(returnValue2, Is.EqualTo("")); + + // Test remove of non-existing value + int fakeValueRemove = (int)InvokeOp("JsonRemoveValue", storeId, "Hello"); + + // XXX: Is this the best response to removing a value that isn't there? + Assert.That(fakeValueRemove, Is.EqualTo(1)); + + // Test get from non-existing store + UUID fakeStoreId = TestHelpers.ParseTail(0x500); + int fakeStoreValueRemove = (int)InvokeOp("JsonRemoveValue", fakeStoreId, "Hello"); + Assert.That(fakeStoreValueRemove, Is.EqualTo(0)); } [Test] -- cgit v1.1 From be982666fb403aa5ee254903cdae0231131c6d70 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 8 Feb 2013 00:01:06 +0000 Subject: Extend TestJsonTestPath() regression test with checks against fake values and fake stores --- .../Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 297c33c..f2de0af 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -231,6 +231,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests int result = (int)InvokeOp("JsonTestPath", storeId, "Hello"); Assert.That(result, Is.EqualTo(1)); + + int result2 = (int)InvokeOp("JsonTestPath", storeId, "foo"); + Assert.That(result2, Is.EqualTo(0)); + + // Test with fake store + UUID fakeStoreId = TestHelpers.ParseTail(0x500); + int fakeStoreValueRemove = (int)InvokeOp("JsonTestPath", fakeStoreId, "Hello"); + Assert.That(fakeStoreValueRemove, Is.EqualTo(0)); } [Test] -- cgit v1.1 From bef8961578d060faea8900e3be4fb9a8a4fe783d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 8 Feb 2013 00:04:05 +0000 Subject: Extend TestJsonSetValue() regressio ntes tto test against a fake store --- .../Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index f2de0af..73bc955 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -254,6 +254,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests string value = (string)InvokeOp("JsonGetValue", storeId, "Fun"); Assert.That(value, Is.EqualTo("Times")); + + // Test with fake store + UUID fakeStoreId = TestHelpers.ParseTail(0x500); + int fakeStoreValueSet = (int)InvokeOp("JsonSetValue", fakeStoreId, "Hello", "World"); + Assert.That(fakeStoreValueSet, Is.EqualTo(0)); } /// -- cgit v1.1 From 24bfdbfb804293362bbdc86dd5bb46e6add26bcb Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 8 Feb 2013 00:36:20 +0000 Subject: Extend TestJsonWriteNotecard() regression test for cases with fake paths and fake stores. Also separates out TestJsonWriteReadNotecard() into separate write and read tests --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 69 +++++++++++++++++++--- 1 file changed, 61 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 73bc955..ce586be 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -262,6 +262,65 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests } /// + /// Test for writing json to a notecard + /// + /// + /// TODO: Really needs to test correct receipt of the link_message event. Could do this by directly fetching + /// it via the MockScriptEngine or perhaps by a dummy script instance. + /// + [Test] + public void TestJsonWriteNotecard() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1)); + m_scene.AddSceneObject(so); + + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }"); + + { + string notecardName = "nc1"; + + // Write notecard + UUID writeNotecardRequestId = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "/", notecardName); + Assert.That(writeNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); + + TaskInventoryItem nc1Item = so.RootPart.Inventory.GetInventoryItem(notecardName); + Assert.That(nc1Item, Is.Not.Null); + + // TODO: Should independently check the contents. + } + + { + // Try to write notecard against bad path + // In this case we do get a request id but no notecard is written. + string badPathNotecardName = "badPathNotecardName"; + + UUID writeNotecardBadPathRequestId + = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "flibble", badPathNotecardName); + Assert.That(writeNotecardBadPathRequestId, Is.Not.EqualTo(UUID.Zero)); + + TaskInventoryItem badPathItem = so.RootPart.Inventory.GetInventoryItem(badPathNotecardName); + Assert.That(badPathItem, Is.Null); + } + + { + // Test with fake store + // In this case we do get a request id but no notecard is written. + string fakeStoreNotecardName = "fakeStoreNotecardName"; + + UUID fakeStoreId = TestHelpers.ParseTail(0x500); + UUID fakeStoreWriteNotecardValue + = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, fakeStoreId, "/", fakeStoreNotecardName); + Assert.That(fakeStoreWriteNotecardValue, Is.Not.EqualTo(UUID.Zero)); + + TaskInventoryItem fakeStoreItem = so.RootPart.Inventory.GetInventoryItem(fakeStoreNotecardName); + Assert.That(fakeStoreItem, Is.Null); + } + } + + /// /// Test for reading and writing json to a notecard /// /// @@ -269,7 +328,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests /// it via the MockScriptEngine or perhaps by a dummy script instance. /// [Test] - public void TestJsonWriteReadNotecard() + public void TestJsonReadNotecard() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); @@ -282,13 +341,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }"); // Write notecard - UUID writeNotecardRequestId = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "/", notecardName); - Assert.That(writeNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); - - TaskInventoryItem nc1Item = so.RootPart.Inventory.GetInventoryItem(notecardName); - Assert.That(nc1Item, Is.Not.Null); - - // TODO: Should probably independently check the contents. + InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "/", notecardName); // Read notecard UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }"); -- cgit v1.1 From 9c9b48b29a97d97625330bbad7cddbe6d2dcd28d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 8 Feb 2013 00:38:30 +0000 Subject: Stop wrongly create a receiving store already populated with "Hello":"World" in TestJsonReadNotecard() --- .../Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index ce586be..6658e1e 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -344,12 +344,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "/", notecardName); // Read notecard - UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }"); + UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ }"); UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "/", notecardName); Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); string value = (string)InvokeOp("JsonGetValue", storeId, "Hello"); Assert.That(value, Is.EqualTo("World")); + + } public object DummyTestMethod(object o1, object o2, object o3, object o4, object o5) { return null; } -- cgit v1.1 From 528f23beab703e60ec522117a2a442e733565727 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 8 Feb 2013 01:02:25 +0000 Subject: Extend TestJsonReadNotecard() for reads to non-root locations and fake stores. Assertions for loading to non-root paths are currently commented out because this doesn't seem to be working. Will be raising mantis to resolve. --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 42 +++++++++++++++++----- 1 file changed, 33 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 6658e1e..7e0f03c 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -321,7 +321,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests } /// - /// Test for reading and writing json to a notecard + /// Test for reading json from a notecard /// /// /// TODO: Really needs to test correct receipt of the link_message event. Could do this by directly fetching @@ -338,20 +338,44 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1)); m_scene.AddSceneObject(so); - UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }"); + UUID creatingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }"); // Write notecard - InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "/", notecardName); + InvokeOpOnHost("JsonWriteNotecard", so.UUID, creatingStoreId, "/", notecardName); - // Read notecard - UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ }"); - UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "/", notecardName); - Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); + { + // Read notecard + UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ }"); + UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "/", notecardName); + Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); - string value = (string)InvokeOp("JsonGetValue", storeId, "Hello"); - Assert.That(value, Is.EqualTo("World")); + string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); + Assert.That(value, Is.EqualTo("World")); + } + + { + // Read notecard to non-root path + UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ }"); + UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make/it/so", 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/so/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; } -- cgit v1.1 From ebb63b55aab98da6d44e82fc0ecfd5d22f245172 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 7 Feb 2013 11:53:49 -0800 Subject: BulletSim: add user setting of friction, density and restitution. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 5 +- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 17 ++-- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 99 +++++++++++++++++----- 3 files changed, 94 insertions(+), 27 deletions(-) (limited to 'OpenSim/Region') 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 _buoyancy = value; DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); // 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) - PhysicsScene.PE.SetGravity(PhysBody, new OMV.Vector3(0f, 0f, grav)); + PhysicsScene.PE.SetGravity(PhysBody, Gravity); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index ec25aa9..0b35f3a 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -78,6 +78,10 @@ public abstract class BSPhysObject : PhysicsActor Name = name; // PhysicsActor also has the name of the object. Someday consolidate. TypeName = typeName; + // Initialize variables kept in base. + GravityModifier = 1.0f; + Gravity = new OMV.Vector3(0f, 0f, BSParam.Gravity); + // We don't have any physical representation yet. PhysBody = new BulletBody(localID); PhysShape = new BulletShape(); @@ -88,8 +92,8 @@ public abstract class BSPhysObject : PhysicsActor LastAssetBuildFailed = false; - // Default material type - Material = MaterialAttributes.Material.Wood; + // Default material type. Also sets Friction, Restitution and Density. + SetMaterial((int)MaterialAttributes.Material.Wood); CollisionCollection = new CollisionEventUpdate(); CollisionsLastTick = CollisionCollection; @@ -122,6 +126,8 @@ public abstract class BSPhysObject : PhysicsActor // 'inWorld' true if the object has already been added to the dynamic world. 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 public OMV.Vector3 Inertia { get; set; } @@ -164,15 +170,16 @@ public abstract class BSPhysObject : PhysicsActor public override void SetMaterial(int material) { Material = (MaterialAttributes.Material)material; + MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false); + Friction = matAttrib.friction; + Restitution = matAttrib.restitution; + Density = matAttrib.density; } // Stop all physical motion. public abstract void ZeroMotion(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. public abstract void UpdateProperties(EntityProperties entprop); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 54bf063..a86932a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -55,7 +55,6 @@ public sealed class BSPrim : BSPhysObject private OMV.Vector3 _position; private float _mass; // the mass of this object - private float _density; private OMV.Vector3 _force; private OMV.Vector3 _velocity; private OMV.Vector3 _torque; @@ -64,8 +63,6 @@ public sealed class BSPrim : BSPhysObject private int _physicsActorType; private bool _isPhysical; private bool _flying; - private float _friction; - private float _restitution; private bool _setAlwaysRun; private bool _throttleUpdates; private bool _floatOnWater; @@ -101,12 +98,6 @@ public sealed class BSPrim : BSPhysObject _isPhysical = pisPhysical; _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 _mass = CalculateMass(); @@ -457,11 +448,6 @@ public sealed class BSPrim : BSPhysObject { 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); - } } } @@ -469,7 +455,7 @@ public sealed class BSPrim : BSPhysObject // Return what gravity should be set to this very moment public OMV.Vector3 ComputeGravity(float buoyancy) { - OMV.Vector3 ret = PhysicsScene.DefaultGravity; + OMV.Vector3 ret = PhysicsScene.DefaultGravity * GravityModifier; if (!IsStatic) ret *= (1f - buoyancy); @@ -596,6 +582,74 @@ public sealed class BSPrim : BSPhysObject } 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 GravityModifier + { + get { return base.GravityModifier; } + set + { + if (base.GravityModifier != value) + { + base.GravityModifier = value; + PhysicsScene.TaintedObject("BSPrim.setGravityModifier", delegate() + { + UpdatePhysicalParameters(); + }); + } + } + } public override OMV.Vector3 RawVelocity { get { return _velocity; } @@ -810,8 +864,8 @@ public sealed class BSPrim : BSPhysObject // Set various physical properties so other object interact properly MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false); - PhysicsScene.PE.SetFriction(PhysBody, matAttrib.friction); - PhysicsScene.PE.SetRestitution(PhysBody, matAttrib.restitution); + PhysicsScene.PE.SetFriction(PhysBody, Friction); + PhysicsScene.PE.SetRestitution(PhysBody, Restitution); // Mass is zero which disables a bunch of physics stuff in Bullet UpdatePhysicalMassProperties(0f, false); @@ -840,8 +894,8 @@ public sealed class BSPrim : BSPhysObject // Set various physical properties so other object interact properly MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, true); - PhysicsScene.PE.SetFriction(PhysBody, matAttrib.friction); - PhysicsScene.PE.SetRestitution(PhysBody, matAttrib.restitution); + PhysicsScene.PE.SetFriction(PhysBody, Friction); + PhysicsScene.PE.SetRestitution(PhysBody, Restitution); // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382 // Since this can be called multiple times, only zero forces when becoming physical @@ -940,6 +994,11 @@ public sealed class BSPrim : BSPhysObject if (PhysBody.HasPhysicalBody) { PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, PhysBody); + + // 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 + OMV.Vector3 grav = ComputeGravity(Buoyancy); + PhysicsScene.PE.SetGravity(PhysBody, grav); } else { @@ -1581,7 +1640,7 @@ public sealed class BSPrim : BSPhysObject profileEnd = 1.0f - (float)BaseShape.ProfileEnd * 2.0e-5f; 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. if (IsRootOfLinkset) -- cgit v1.1 From b545e131846f38cc96757d5c4456c1ee8e7abe75 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 7 Feb 2013 14:44:12 -0800 Subject: BulletSim: fix exceptions caused by setting physical properties before the prim body is initialized. --- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index a86932a..38adb72 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -587,7 +587,8 @@ public sealed class BSPrim : BSPhysObject base.SetMaterial(material); PhysicsScene.TaintedObject("BSPrim.SetMaterial", delegate() { - UpdatePhysicalParameters(); + if (PhysBody.HasPhysicalBody) + UpdatePhysicalParameters(); }); } public override float Friction @@ -600,7 +601,8 @@ public sealed class BSPrim : BSPhysObject base.Friction = value; PhysicsScene.TaintedObject("BSPrim.setFriction", delegate() { - UpdatePhysicalParameters(); + if (PhysBody.HasPhysicalBody) + UpdatePhysicalParameters(); }); } } @@ -615,7 +617,8 @@ public sealed class BSPrim : BSPhysObject base.Restitution = value; PhysicsScene.TaintedObject("BSPrim.setRestitution", delegate() { - UpdatePhysicalParameters(); + if (PhysBody.HasPhysicalBody) + UpdatePhysicalParameters(); }); } } @@ -630,7 +633,8 @@ public sealed class BSPrim : BSPhysObject base.Density = value; PhysicsScene.TaintedObject("BSPrim.setDensity", delegate() { - UpdatePhysicalParameters(); + if (PhysBody.HasPhysicalBody) + UpdatePhysicalParameters(); }); } } @@ -645,7 +649,8 @@ public sealed class BSPrim : BSPhysObject base.GravityModifier = value; PhysicsScene.TaintedObject("BSPrim.setGravityModifier", delegate() { - UpdatePhysicalParameters(); + if (PhysBody.HasPhysicalBody) + UpdatePhysicalParameters(); }); } } -- cgit v1.1 From 913965256fecd4e25e06fe374fa5d8b8712a3b15 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 7 Feb 2013 17:05:40 -0800 Subject: BulletSim: Adapt BulletSim to the newer physical properties. Viewer dialog setting of friction, restitution, ... working. --- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 4 +- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 54 ++++++++++------------ 2 files changed, 28 insertions(+), 30 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 0b35f3a..0d8bb03 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -79,7 +79,7 @@ public abstract class BSPhysObject : PhysicsActor TypeName = typeName; // Initialize variables kept in base. - GravityModifier = 1.0f; + GravModifier = 1.0f; Gravity = new OMV.Vector3(0f, 0f, BSParam.Gravity); // We don't have any physical representation yet. @@ -170,6 +170,8 @@ public abstract class BSPhysObject : PhysicsActor public override void SetMaterial(int 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; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 38adb72..85c2627 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -423,8 +423,6 @@ public sealed class BSPrim : BSPhysObject } else { - OMV.Vector3 grav = ComputeGravity(Buoyancy); - if (inWorld) { // Changing interesting properties doesn't change proxy and collision cache @@ -434,15 +432,15 @@ public sealed class BSPrim : BSPhysObject } // 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); PhysicsScene.PE.SetMassProps(PhysBody, physMass, Inertia); PhysicsScene.PE.UpdateInertiaTensor(PhysBody); - // center of mass is at the zero of the object - // DEBUG DEBUG PhysicsScene.PE.SetCenterOfMassByPosRot(PhysBody, ForcePosition, ForceOrientation); - DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2},grav={3},inWorld={4}", LocalID, physMass, Inertia, grav, inWorld); + DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2},grav={3},inWorld={4}", + LocalID, physMass, Inertia, Gravity, inWorld); if (inWorld) { @@ -455,10 +453,13 @@ public sealed class BSPrim : BSPhysObject // Return what gravity should be set to this very moment public OMV.Vector3 ComputeGravity(float buoyancy) { - OMV.Vector3 ret = PhysicsScene.DefaultGravity * GravityModifier; + OMV.Vector3 ret = PhysicsScene.DefaultGravity; if (!IsStatic) + { ret *= (1f - buoyancy); + ret *= GravModifier; + } return ret; } @@ -587,8 +588,7 @@ public sealed class BSPrim : BSPhysObject base.SetMaterial(material); PhysicsScene.TaintedObject("BSPrim.SetMaterial", delegate() { - if (PhysBody.HasPhysicalBody) - UpdatePhysicalParameters(); + UpdatePhysicalParameters(); }); } public override float Friction @@ -601,8 +601,7 @@ public sealed class BSPrim : BSPhysObject base.Friction = value; PhysicsScene.TaintedObject("BSPrim.setFriction", delegate() { - if (PhysBody.HasPhysicalBody) - UpdatePhysicalParameters(); + UpdatePhysicalParameters(); }); } } @@ -617,8 +616,7 @@ public sealed class BSPrim : BSPhysObject base.Restitution = value; PhysicsScene.TaintedObject("BSPrim.setRestitution", delegate() { - if (PhysBody.HasPhysicalBody) - UpdatePhysicalParameters(); + UpdatePhysicalParameters(); }); } } @@ -633,24 +631,22 @@ public sealed class BSPrim : BSPhysObject base.Density = value; PhysicsScene.TaintedObject("BSPrim.setDensity", delegate() { - if (PhysBody.HasPhysicalBody) - UpdatePhysicalParameters(); + UpdatePhysicalParameters(); }); } } } - public override float GravityModifier + public override float GravModifier { - get { return base.GravityModifier; } + get { return base.GravModifier; } set { - if (base.GravityModifier != value) + if (base.GravModifier != value) { - base.GravityModifier = value; + base.GravModifier = value; PhysicsScene.TaintedObject("BSPrim.setGravityModifier", delegate() { - if (PhysBody.HasPhysicalBody) - UpdatePhysicalParameters(); + UpdatePhysicalParameters(); }); } } @@ -820,7 +816,12 @@ public sealed class BSPrim : BSPhysObject // collisionEvents: whether this object returns collision events 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. // This is a NOOP if the object is not in the world (BulletSim and Bullet ignore objects not found). @@ -898,9 +899,9 @@ public sealed class BSPrim : BSPhysObject CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.CF_STATIC_OBJECT); // Set various physical properties so other object interact properly - MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, true); PhysicsScene.PE.SetFriction(PhysBody, Friction); PhysicsScene.PE.SetRestitution(PhysBody, Restitution); + // DetailLog("{0},BSPrim.MakeDynamic,frict={1},rest={2}", LocalID, Friction, Restitution); // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382 // Since this can be called multiple times, only zero forces when becoming physical @@ -999,16 +1000,11 @@ public sealed class BSPrim : BSPhysObject if (PhysBody.HasPhysicalBody) { PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, PhysBody); - - // 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 - OMV.Vector3 grav = ComputeGravity(Buoyancy); - PhysicsScene.PE.SetGravity(PhysBody, grav); } else { 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); } } -- cgit v1.1 From 42f724f38011286733351a46dd8369951a581ce9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 8 Feb 2013 01:59:27 +0000 Subject: Refine TestJsonReadNotecard() and use / instead of . to separate paths. An attack of the stupid meant that I was using / as a path separator. Fixing this makes the tests behave better, though still with some questions. Also, I imagine / shouldn't really put data in the root as that's not a valid identifier. This commit also fix the / mistake in other tests those this does not affect their outcomes. --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 61 ++++++++++++++++------ 1 file changed, 46 insertions(+), 15 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 7e0f03c..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 string notecardName = "nc1"; // 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)); 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: 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. string badPathNotecardName = "badPathNotecardName"; @@ -312,7 +314,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests UUID fakeStoreId = TestHelpers.ParseTail(0x500); UUID fakeStoreWriteNotecardValue - = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, fakeStoreId, "/", fakeStoreNotecardName); + = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, fakeStoreId, "", fakeStoreNotecardName); Assert.That(fakeStoreWriteNotecardValue, Is.Not.EqualTo(UUID.Zero)); TaskInventoryItem fakeStoreItem = so.RootPart.Inventory.GetInventoryItem(fakeStoreNotecardName); @@ -341,12 +343,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests UUID creatingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }"); // Write notecard - InvokeOpOnHost("JsonWriteNotecard", so.UUID, creatingStoreId, "/", notecardName); + InvokeOpOnHost("JsonWriteNotecard", so.UUID, creatingStoreId, "", notecardName); { // Read notecard - UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ }"); - UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "/", notecardName); + UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}"); + UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "", notecardName); Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); @@ -354,23 +356,52 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests } { - // Read notecard to non-root path - UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ }"); - UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make/it/so", notecardName); + // 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/it/so/Hello"); -// Assert.That(value, Is.EqualTo("World")); + 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); + UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, fakeStoreId, "", notecardName); Assert.That(fakeStoreId, Is.Not.EqualTo(UUID.Zero)); string value = (string)InvokeOp("JsonGetValue", fakeStoreId, "Hello"); -- cgit v1.1 From 221a90e3a16a16708d183bab92bd4bff92c8139c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 8 Feb 2013 02:34:13 +0000 Subject: On IAR loading, if loading of a coaleseced item entirely fails, then continue with the IAR load rather than failing completely. --- .../Inventory/Archiver/InventoryArchiveReadRequest.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs index 5069803..ecbd07f 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 { // m_log.DebugFormat( // "[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); } @@ -495,7 +503,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver SceneObjectGroup deserializedObject = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); if (deserializedObject != null) + { 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) -- cgit v1.1 From c2bf91c5e3bda35034a49f4cfacc30f73c0ee688 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 8 Feb 2013 02:45:30 +0000 Subject: If a component of a coalesced object fails to deserialization, do not add a null where the object should be. This prevents a later load IAR failure. This code is currently only used by IAR loading. --- .../CoalescedSceneObjectsSerializer.cs | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') 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 /// /// Serialize and deserialize coalesced scene objects. /// - /// - /// Deserialization not yet here. - /// public class CoalescedSceneObjectsSerializer { 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); coa = null; + int i = 0; using (StringReader sr = new StringReader(xml)) { @@ -153,7 +151,23 @@ namespace OpenSim.Region.Framework.Scenes.Serialization if (reader.Name == "SceneObjectGroup") { 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++; } } -- cgit v1.1 From 2b5eba9c7438ef0175c91c1910ce2d660d930fed Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Fri, 8 Feb 2013 12:00:16 -0800 Subject: Fix the return values for JsonDestroyStore, JsonRemoveValue, and JsonSetValue. Fix the link message status when reading a notecard. --- .../OptionalModules/Scripting/JsonStore/JsonStore.cs | 17 +++++++++++++---- .../Scripting/JsonStore/JsonStoreModule.cs | 8 +++----- .../Scripting/JsonStore/JsonStoreScriptModule.cs | 2 +- 3 files changed, 17 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs index 5808d46..c7f0001 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs @@ -250,6 +250,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore 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 pexpr = PathExpressionToKey(path); if (pexpr != "") @@ -259,7 +261,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore if (result == null) 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); if (amatches.Count > 0) { @@ -307,16 +309,23 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore if (result is OSDMap) { + // this is the assignment case OSDMap hmap = result as OSDMap; if (ovalue != null) { hmap[hkey] = ovalue; InvokeNextCallback(pexpr + pkey); + return true; } - else if (hmap.ContainsKey(hkey)) + + // this is the remove case + if (hmap.ContainsKey(hkey)) + { hmap.Remove(hkey); - - return true; + return true; + } + + return false; } return false; diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs index 3b52e44..3249aa3 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs @@ -239,7 +239,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore if (! m_enabled) return false; lock (m_JsonValueStore) - m_JsonValueStore.Remove(storeID); + return m_JsonValueStore.Remove(storeID); return true; } @@ -311,8 +311,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore try { lock (map) - if (map.SetValue(path,value,useJson)) - return true; + return map.SetValue(path,value,useJson); } catch (Exception e) { @@ -344,8 +343,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore try { lock (map) - if (map.RemoveValue(path)) - return true; + return map.RemoveValue(path); } catch (Exception e) { 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 { string jsondata = SLUtil.ParseNotecardToString(Encoding.UTF8.GetString(a.Data)); 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; } catch (Exception e) -- cgit v1.1 From b08977ea7d9e35066e3cbf367fad58c2d8bc227e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 8 Feb 2013 21:21:20 +0000 Subject: Don't allow exceptions to propogate from FlotsamAssetCache which may occur when deleting expired files or stamping the region status file. Changes various error level log lines to warn since these are not fatal to the operation of OpenSimulator --- .../Region/CoreModules/Asset/FlotsamAssetCache.cs | 89 ++++++++++++++-------- 1 file changed, 57 insertions(+), 32 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index 00af175..3cba9b4 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -299,7 +299,7 @@ namespace OpenSim.Region.CoreModules.Asset } catch (Exception e) { - m_log.ErrorFormat( + m_log.WarnFormat( "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}", asset.ID, e.Message, e.StackTrace); } @@ -339,12 +339,13 @@ namespace OpenSim.Region.CoreModules.Asset /// Try to get an asset from the file cache. /// /// - /// + /// An asset retrieved from the file cache. null if there was a problem retrieving an asset. private AssetBase GetFromFileCache(string id) { AssetBase asset = null; - + string filename = GetFileName(id); + if (File.Exists(filename)) { FileStream stream = null; @@ -359,7 +360,7 @@ namespace OpenSim.Region.CoreModules.Asset } 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}", filename, id, e.Message, e.StackTrace); @@ -371,7 +372,7 @@ namespace OpenSim.Region.CoreModules.Asset } catch (Exception e) { - m_log.ErrorFormat( + m_log.WarnFormat( "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", filename, id, e.Message, e.StackTrace); } @@ -469,7 +470,7 @@ namespace OpenSim.Region.CoreModules.Asset } catch (Exception e) { - m_log.ErrorFormat( + m_log.WarnFormat( "[FLOTSAM ASSET CACHE]: Failed to expire cached file {0}. Exception {1} {2}", id, e.Message, e.StackTrace); } @@ -520,29 +521,39 @@ namespace OpenSim.Region.CoreModules.Asset /// 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); - } + // 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); + // 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); + } } - else if (dirSize >= m_CacheWarnAt) + catch (Exception e) { - m_log.WarnFormat("[FLOTSAM ASSET CACHE]: Cache folder exceeded CacheWarnAt limit {0} {1}. Suggest increasing tiers, tier length, or reducing cache expiration", dir, dirSize); + m_log.Warn( + string.Format("[FLOTSAM ASSET CACHE]: Could not complete clean of expired files in {0}, exception ", dir), e); } } @@ -601,7 +612,7 @@ namespace OpenSim.Region.CoreModules.Asset } 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}.", asset.ID, tempname, filename, directory, e.Message, e.StackTrace); @@ -680,17 +691,31 @@ namespace OpenSim.Region.CoreModules.Asset /// /// This notes the last time the Region had a deep asset scan performed on it. /// - /// - private void StampRegionStatusFile(UUID RegionID) + /// + private void StampRegionStatusFile(UUID regionID) { - string RegionCacheStatusFile = Path.Combine(m_CacheDirectory, "RegionStatus_" + RegionID.ToString() + ".fac"); - if (File.Exists(RegionCacheStatusFile)) + string RegionCacheStatusFile = Path.Combine(m_CacheDirectory, "RegionStatus_" + regionID.ToString() + ".fac"); + + 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); } } @@ -759,7 +784,7 @@ namespace OpenSim.Region.CoreModules.Asset } catch (Exception e) { - m_log.ErrorFormat( + m_log.WarnFormat( "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache directory {0} from {1}. Exception {2} {3}", dir, m_CacheDirectory, e.Message, e.StackTrace); } @@ -773,7 +798,7 @@ namespace OpenSim.Region.CoreModules.Asset } catch (Exception e) { - m_log.ErrorFormat( + m_log.WarnFormat( "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache file {0} from {1}. Exception {1} {2}", file, m_CacheDirectory, e.Message, e.StackTrace); } -- cgit v1.1 From e93defd0ca326754d1bd5a1a503d6d47428272be Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Fri, 8 Feb 2013 15:07:43 -0800 Subject: Adds size limits to JsonStore. Adds a separate configuration variable to enable binding to dynamic attributes. --- .../Scripting/JsonStore/JsonStore.cs | 51 +++++++++++++++++++++- .../Scripting/JsonStore/JsonStoreModule.cs | 17 ++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs index c7f0001..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 // ----------------------------------------------------------------- /// + /// 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 + /// + // ----------------------------------------------------------------- + public int StringSpace { get; set; } + + // ----------------------------------------------------------------- + /// /// /// // ----------------------------------------------------------------- @@ -110,6 +119,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore // ----------------------------------------------------------------- public JsonStore() { + StringSpace = 0; m_TakeStore = new List(); m_ReadStore = new List(); } @@ -247,6 +257,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore if (path.Count == 0) { ValueStore = ovalue; + StringSpace = 0; return true; } @@ -278,8 +289,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore { string npkey = String.Format("[{0}]",amap.Count); - amap.Add(ovalue); - InvokeNextCallback(pexpr + npkey); + if (ovalue != null) + { + StringSpace += ComputeSizeOf(ovalue); + + amap.Add(ovalue); + InvokeNextCallback(pexpr + npkey); + } return true; } @@ -287,9 +303,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore if (0 <= aval && aval < amap.Count) { if (ovalue == null) + { + StringSpace -= ComputeSizeOf(amap[aval]); amap.RemoveAt(aval); + } else { + StringSpace -= ComputeSizeOf(amap[aval]); + StringSpace += ComputeSizeOf(ovalue); amap[aval] = ovalue; InvokeNextCallback(pexpr + pkey); } @@ -313,6 +334,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore OSDMap hmap = result as OSDMap; if (ovalue != null) { + StringSpace -= ComputeSizeOf(hmap[hkey]); + StringSpace += ComputeSizeOf(ovalue); + hmap[hkey] = ovalue; InvokeNextCallback(pexpr + pkey); return true; @@ -321,6 +345,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore // this is the remove case if (hmap.ContainsKey(hkey)) { + StringSpace -= ComputeSizeOf(hmap[hkey]); hmap.Remove(hkey); return true; } @@ -531,8 +556,27 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore return pkey; } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + protected static int ComputeSizeOf(OSD value) + { + string sval; + + if (ConvertOutputValue(value,out sval,true)) + return sval.Length; + + return 0; + } } + // ----------------------------------------------------------------- + /// + /// + // ----------------------------------------------------------------- public class JsonObjectStore : JsonStore { private static readonly ILog m_log = @@ -566,6 +610,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore { m_scene = scene; m_objectID = oid; + + // the size limit is imposed on whatever is already in the store + StringSpace = ComputeSizeOf(ValueStore); } } diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs index 3249aa3..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 private IConfig m_config = null; private bool m_enabled = false; + private bool m_enableObjectStore = false; + private int m_maxStringSpace = Int32.MaxValue; + private Scene m_scene = null; private Dictionary m_JsonValueStore; @@ -90,6 +93,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } 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) { @@ -178,6 +185,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore public bool AttachObjectStore(UUID objectID) { if (! m_enabled) return false; + if (! m_enableObjectStore) return false; SceneObjectPart sop = m_scene.GetSceneObjectPart(objectID); if (sop == null) @@ -311,7 +319,16 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore try { lock (map) + { + 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) { -- cgit v1.1 From 6d825d7ea22f5accd1324a4ef8800eddb8dc86da Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Fri, 8 Feb 2013 15:46:42 -0800 Subject: Broaden the internal OSD type checks to parse JSON that has non string values. --- .../Scripting/JsonStore/JsonStore.cs | 31 ++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs index 088d0cd..5c89717 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs @@ -145,7 +145,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore if (result == null) return false; - if (useJson || result.Type == OSDType.String) + if (useJson || OSDBaseType(result.Type)) return true; return false; @@ -531,7 +531,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore return true; } - if (result.Type == OSDType.String) + if (OSDBaseType(result.Type)) { value = result.AsString(); return true; @@ -562,6 +562,33 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- + protected static bool OSDBaseType(OSDType type) + { + // Should be the list of base types for which AsString() returns + // something useful + if (type == OSDType.Boolean) + return true; + if (type == OSDType.Integer) + return true; + if (type == OSDType.Real) + return true; + if (type == OSDType.String) + return true; + if (type == OSDType.UUID) + return true; + if (type == OSDType.Date) + return true; + if (type == OSDType.URI) + return true; + + return false; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- protected static int ComputeSizeOf(OSD value) { string sval; -- cgit v1.1 From 2fd184e350874d3751a30e368d5f7ee0f41d4b85 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 7 Feb 2013 21:54:48 -0800 Subject: BulletSim: reclass BSPrim into layers so linkset and physical world displacement is implemented as overlay classes rather than if statements scattered about. --- .../Physics/BulletSPlugin/BSPrimDisplaced.cs | 118 ++++++++++++++ .../Region/Physics/BulletSPlugin/BSPrimLinkable.cs | 179 +++++++++++++++++++++ 2 files changed, 297 insertions(+) create mode 100755 OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs create mode 100755 OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs new file mode 100755 index 0000000..6401308 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs @@ -0,0 +1,118 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The quotations from http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial + * are Copyright (c) 2009 Linden Research, Inc and are used under their license + * of Creative Commons Attribution-Share Alike 3.0 + * (http://creativecommons.org/licenses/by-sa/3.0/). + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.InteropServices; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Physics.Manager; + +using OMV = OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ +public class BSPrimDisplaced : BSPrim +{ + // 'Position' and 'Orientation' is what the simulator thinks the positions of the prim is. + // Because Bullet needs the zero coordinate to be the center of mass of the linkset, + // sometimes it is necessary to displace the position the physics engine thinks + // the position is. PositionDisplacement must be added and removed from the + // position as the simulator position is stored and fetched from the physics + // engine. Similar to OrientationDisplacement. + public virtual OMV.Vector3 PositionDisplacement { get; set; } + public virtual OMV.Quaternion OrientationDisplacement { get; set; } + public virtual OMV.Vector3 CenterOfMassLocation { get; set; } + public virtual OMV.Vector3 GeometricCenterLocation { get; set; } + + public BSPrimDisplaced(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, + OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) + : base(localID, primName, parent_scene, pos, size, rotation, pbs, pisPhysical) + { + CenterOfMassLocation = RawPosition; + GeometricCenterLocation = RawPosition; + } + + public override Vector3 ForcePosition + { + get + { + return base.ForcePosition; + } + set + { + base.ForcePosition = value; + CenterOfMassLocation = RawPosition; + GeometricCenterLocation = RawPosition; + } + } + + public override Quaternion ForceOrientation + { + get + { + return base.ForceOrientation; + } + set + { + base.ForceOrientation = value; + } + } + + // Is this used? + public override OMV.Vector3 CenterOfMass + { + get { return CenterOfMassLocation; } + } + + // Is this used? + public override OMV.Vector3 GeometricCenter + { + get { return GeometricCenterLocation; } + } + + + public override void UpdateProperties(EntityProperties entprop) + { + // Undo any center-of-mass displacement that might have been done. + if (PositionDisplacement != OMV.Vector3.Zero) + { + // Correct for any rotation around the center-of-mass + // TODO!!! + entprop.Position -= PositionDisplacement; + } + + base.UpdateProperties(entprop); + } +} +} diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs new file mode 100755 index 0000000..fd66d1c --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs @@ -0,0 +1,179 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using OpenSim.Framework; + +using OMV = OpenMetaverse; + +namespace OpenSim.Region.Physics.BulletSPlugin +{ +public class BSPrimLinkable : BSPrimDisplaced +{ + public BSLinkset Linkset { get; set; } + public BSLinksetInfo LinksetInfo { get; set; } + + public BSPrimLinkable(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, + OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) + : base(localID, primName, parent_scene, pos, size, rotation, pbs, pisPhysical) + { + Linkset = BSLinkset.Factory(PhysicsScene, this); + + PhysicsScene.TaintedObject("BSPrimLinksetCompound.Refresh", delegate() + { + Linkset.Refresh(this); + }); + } + + public override void Destroy() + { + Linkset = Linkset.RemoveMeFromLinkset(this); + base.Destroy(); + } + + public override BSPhysicsShapeType PreferredPhysicalShape + { get { return Linkset.PreferredPhysicalShape(this); } } + + public override void link(Manager.PhysicsActor obj) + { + BSPrimLinkable parent = obj as BSPrimLinkable; + if (parent != null) + { + BSPhysObject parentBefore = Linkset.LinksetRoot; + int childrenBefore = Linkset.NumberOfChildren; + + Linkset = parent.Linkset.AddMeToLinkset(this); + + DetailLog("{0},BSPrimLinkset.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}", + LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren); + } + return; + } + + public override void delink() + { + // TODO: decide if this parent checking needs to happen at taint time + // Race condition here: if link() and delink() in same simulation tick, the delink will not happen + + BSPhysObject parentBefore = Linkset.LinksetRoot; + int childrenBefore = Linkset.NumberOfChildren; + + Linkset = Linkset.RemoveMeFromLinkset(this); + + DetailLog("{0},BSPrimLinkset.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ", + LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren); + return; + base.delink(); + } + + // When simulator changes position, this might be moving a child of the linkset. + public override OMV.Vector3 Position + { + get { return base.Position; } + set + { + base.Position = value; + PhysicsScene.TaintedObject("BSPrimLinkset.setPosition", delegate() + { + Linkset.UpdateProperties(UpdatedProperties.Position, this); + }); + } + } + + // When simulator changes orientation, this might be moving a child of the linkset. + public override OMV.Quaternion Orientation + { + get { return base.Orientation; } + set + { + base.Orientation = value; + PhysicsScene.TaintedObject("BSPrimLinkset.setOrientation", delegate() + { + Linkset.UpdateProperties(UpdatedProperties.Orientation, this); + }); + } + } + + public override float TotalMass + { + get { return Linkset.LinksetMass; } + } + + public override void UpdatePhysicalParameters() + { + base.UpdatePhysicalParameters(); + // Recompute any linkset parameters. + // When going from non-physical to physical, this re-enables the constraints that + // had been automatically disabled when the mass was set to zero. + // For compound based linksets, this enables and disables interactions of the children. + Linkset.Refresh(this); + } + + protected override void MakeDynamic(bool makeStatic) + { + base.MakeDynamic(makeStatic); + if (makeStatic) + Linkset.MakeStatic(this); + else + Linkset.MakeDynamic(this); + } + + // Body is being taken apart. Remove physical dependencies and schedule a rebuild. + protected override void RemoveBodyDependencies() + { + Linkset.RemoveBodyDependencies(this); + base.RemoveBodyDependencies(); + } + + public override void UpdateProperties(EntityProperties entprop) + { + if (Linkset.IsRoot(this)) + { + // Properties are only updated for the roots of a linkset. + // TODO: this will have to change when linksets are articulated. + base.UpdateProperties(entprop); + } + Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this); + + } + + public override bool Collide(uint collidingWith, BSPhysObject collidee, + OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) + { + // prims in the same linkset cannot collide with each other + BSPrimLinkable convCollidee = collidee as BSPrimLinkable; + if (convCollidee != null && (this.Linkset.LinksetID == convCollidee.Linkset.LinksetID)) + { + return false; + } + return base.Collide(collidingWith, collidee, contactPoint, contactNormal, pentrationDepth); + } +} +} -- cgit v1.1 From 1b203601f43662541526369f540dd04f5b485be6 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 7 Feb 2013 21:57:31 -0800 Subject: BulletSim: include the linkage to the layered prim implementation. Separate layers for physical (vs simulator) location displacement and linksets. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 48 +++-- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 32 ++-- .../Physics/BulletSPlugin/BSLinksetConstraints.cs | 30 ++-- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 21 --- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 195 ++++++--------------- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 4 +- 8 files changed, 109 insertions(+), 225 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index d694a6a..0afc437 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -901,7 +901,7 @@ public sealed class BSCharacter : BSPhysObject CurrentEntityProperties = entprop; // Tell the linkset about value changes - Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this); + // Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this); // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. // base.RequestPhysicsterseUpdate(); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index b51e9fd..41d353a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -597,7 +597,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin if (IsActive) { // Remember the mass so we don't have to fetch it every step - m_vehicleMass = Prim.Linkset.LinksetMass; + m_vehicleMass = Prim.TotalMass; // Friction affects are handled by this vehicle code PhysicsScene.PE.SetFriction(Prim.PhysBody, BSParam.VehicleFriction); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 1e3e5d8..8e69db3 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -52,7 +52,7 @@ public abstract class BSLinkset Manual = 2 // linkset tied together manually (code moves all the pieces) } // Create the correct type of linkset for this child - public static BSLinkset Factory(BSScene physScene, BSPhysObject parent) + public static BSLinkset Factory(BSScene physScene, BSPrimLinkable parent) { BSLinkset ret = null; @@ -74,7 +74,7 @@ public abstract class BSLinkset return ret; } - public BSPhysObject LinksetRoot { get; protected set; } + public BSPrimLinkable LinksetRoot { get; protected set; } public BSScene PhysicsScene { get; private set; } @@ -82,7 +82,7 @@ public abstract class BSLinkset public int LinksetID { get; private set; } // The children under the root in this linkset. - protected HashSet m_children; + protected HashSet m_children; // We lock the diddling of linkset classes to prevent any badness. // This locks the modification of the instances of this class. Changes @@ -91,7 +91,7 @@ public abstract class BSLinkset // Some linksets have a preferred physical shape. // Returns SHAPE_UNKNOWN if there is no preference. Causes the correct shape to be selected. - public virtual BSPhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor) + public virtual BSPhysicsShapeType PreferredPhysicalShape(BSPrimLinkable requestor) { return BSPhysicsShapeType.SHAPE_UNKNOWN; } @@ -111,7 +111,7 @@ public abstract class BSLinkset get { return ComputeLinksetGeometricCenter(); } } - protected BSLinkset(BSScene scene, BSPhysObject parent) + protected BSLinkset(BSScene scene, BSPrimLinkable parent) { // A simple linkset of one (no children) LinksetID = m_nextLinksetID++; @@ -120,7 +120,7 @@ public abstract class BSLinkset m_nextLinksetID = 1; PhysicsScene = scene; LinksetRoot = parent; - m_children = new HashSet(); + m_children = new HashSet(); LinksetMass = parent.RawMass; Rebuilding = false; } @@ -129,7 +129,7 @@ public abstract class BSLinkset // Parent changing should not happen so do some sanity checking. // We return the parent's linkset so the child can track its membership. // Called at runtime. - public BSLinkset AddMeToLinkset(BSPhysObject child) + public BSLinkset AddMeToLinkset(BSPrimLinkable child) { lock (m_linksetActivityLock) { @@ -145,14 +145,13 @@ public abstract class BSLinkset // Returns a new linkset for the child which is a linkset of one (just the // orphened child). // Called at runtime. - public BSLinkset RemoveMeFromLinkset(BSPhysObject child) + public BSLinkset RemoveMeFromLinkset(BSPrimLinkable child) { lock (m_linksetActivityLock) { if (IsRoot(child)) { // Cannot remove the root from a linkset. - child.PositionDisplacement = OMV.Vector3.Zero; return this; } RemoveChildFromLinkset(child); @@ -160,12 +159,11 @@ public abstract class BSLinkset } // The child is down to a linkset of just itself - child.PositionDisplacement = OMV.Vector3.Zero; return BSLinkset.Factory(PhysicsScene, child); } // Return 'true' if the passed object is the root object of this linkset - public bool IsRoot(BSPhysObject requestor) + public bool IsRoot(BSPrimLinkable requestor) { return (requestor.LocalID == LinksetRoot.LocalID); } @@ -176,14 +174,14 @@ public abstract class BSLinkset public bool HasAnyChildren { get { return (m_children.Count > 0); } } // Return 'true' if this child is in this linkset - public bool HasChild(BSPhysObject child) + public bool HasChild(BSPrimLinkable child) { bool ret = false; lock (m_linksetActivityLock) { ret = m_children.Contains(child); /* Safer version but the above should work - foreach (BSPhysObject bp in m_children) + foreach (BSPrimLinkable bp in m_children) { if (child.LocalID == bp.LocalID) { @@ -198,14 +196,14 @@ public abstract class BSLinkset // Perform an action on each member of the linkset including root prim. // Depends on the action on whether this should be done at taint time. - public delegate bool ForEachMemberAction(BSPhysObject obj); + public delegate bool ForEachMemberAction(BSPrimLinkable obj); public virtual bool ForEachMember(ForEachMemberAction action) { bool ret = false; lock (m_linksetActivityLock) { action(LinksetRoot); - foreach (BSPhysObject po in m_children) + foreach (BSPrimLinkable po in m_children) { if (action(po)) break; @@ -216,16 +214,16 @@ public abstract class BSLinkset // I am the root of a linkset and a new child is being added // Called while LinkActivity is locked. - protected abstract void AddChildToLinkset(BSPhysObject child); + protected abstract void AddChildToLinkset(BSPrimLinkable child); // I am the root of a linkset and one of my children is being removed. // Safe to call even if the child is not really in my linkset. - protected abstract void RemoveChildFromLinkset(BSPhysObject child); + protected abstract void RemoveChildFromLinkset(BSPrimLinkable child); // When physical properties are changed the linkset needs to recalculate // its internal properties. // May be called at runtime or taint-time. - public virtual void Refresh(BSPhysObject requestor) + public virtual void Refresh(BSPrimLinkable requestor) { LinksetMass = ComputeLinksetMass(); } @@ -240,26 +238,26 @@ public abstract class BSLinkset // has not yet been fully constructed. // Return 'true' if any properties updated on the passed object. // Called at taint-time! - public abstract bool MakeDynamic(BSPhysObject child); + public abstract bool MakeDynamic(BSPrimLinkable child); // The object is going static (non-physical). Do any setup necessary // for a static linkset. // Return 'true' if any properties updated on the passed object. // Called at taint-time! - public abstract bool MakeStatic(BSPhysObject child); + public abstract bool MakeStatic(BSPrimLinkable child); // Called when a parameter update comes from the physics engine for any object // of the linkset is received. // Passed flag is update came from physics engine (true) or the user (false). // Called at taint-time!! - public abstract void UpdateProperties(UpdatedProperties whichUpdated, BSPhysObject physObject); + public abstract void UpdateProperties(UpdatedProperties whichUpdated, BSPrimLinkable physObject); // Routine used when rebuilding the body of the root of the linkset // Destroy all the constraints have have been made to root. // This is called when the root body is changing. // Returns 'true' of something was actually removed and would need restoring // Called at taint-time!! - public abstract bool RemoveBodyDependencies(BSPrim child); + public abstract bool RemoveBodyDependencies(BSPrimLinkable child); // ================================================================ protected virtual float ComputeLinksetMass() @@ -269,7 +267,7 @@ public abstract class BSLinkset { lock (m_linksetActivityLock) { - foreach (BSPhysObject bp in m_children) + foreach (BSPrimLinkable bp in m_children) { mass += bp.RawMass; } @@ -286,7 +284,7 @@ public abstract class BSLinkset com = LinksetRoot.Position * LinksetRoot.RawMass; float totalMass = LinksetRoot.RawMass; - foreach (BSPhysObject bp in m_children) + foreach (BSPrimLinkable bp in m_children) { com += bp.Position * bp.RawMass; totalMass += bp.RawMass; @@ -305,7 +303,7 @@ public abstract class BSLinkset { com = LinksetRoot.Position; - foreach (BSPhysObject bp in m_children) + foreach (BSPrimLinkable bp in m_children) { com += bp.Position; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 0c4db40..36bae9b 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -52,7 +52,7 @@ sealed class BSLinksetCompoundInfo : BSLinksetInfo OffsetRot = r; } // 'centerDisplacement' is the distance from the root the the center-of-mass (Bullet 'zero' of the shape) - public BSLinksetCompoundInfo(int indx, BSPhysObject root, BSPhysObject child, OMV.Vector3 centerDisplacement) + public BSLinksetCompoundInfo(int indx, BSPrimLinkable root, BSPrimLinkable child, OMV.Vector3 centerDisplacement) { // Each child position and rotation is given relative to the center-of-mass. OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(root.RawOrientation); @@ -93,12 +93,12 @@ public sealed class BSLinksetCompound : BSLinkset { private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]"; - public BSLinksetCompound(BSScene scene, BSPhysObject parent) : base(scene, parent) + public BSLinksetCompound(BSScene scene, BSPrimLinkable parent) : base(scene, parent) { } // For compound implimented linksets, if there are children, use compound shape for the root. - public override BSPhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor) + public override BSPhysicsShapeType PreferredPhysicalShape(BSPrimLinkable requestor) { // Returning 'unknown' means we don't have a preference. BSPhysicsShapeType ret = BSPhysicsShapeType.SHAPE_UNKNOWN; @@ -112,7 +112,7 @@ public sealed class BSLinksetCompound : BSLinkset // When physical properties are changed the linkset needs to recalculate // its internal properties. - public override void Refresh(BSPhysObject requestor) + public override void Refresh(BSPrimLinkable requestor) { base.Refresh(requestor); @@ -121,7 +121,7 @@ public sealed class BSLinksetCompound : BSLinkset } // Schedule a refresh to happen after all the other taint processing. - private void ScheduleRebuild(BSPhysObject requestor) + private void ScheduleRebuild(BSPrimLinkable requestor) { DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1},hasChildren={2},actuallyScheduling={3}", requestor.LocalID, Rebuilding, HasAnyChildren, (!Rebuilding && HasAnyChildren)); @@ -143,7 +143,7 @@ public sealed class BSLinksetCompound : BSLinkset // has not yet been fully constructed. // Return 'true' if any properties updated on the passed object. // Called at taint-time! - public override bool MakeDynamic(BSPhysObject child) + public override bool MakeDynamic(BSPrimLinkable child) { bool ret = false; DetailLog("{0},BSLinksetCompound.MakeDynamic,call,IsRoot={1}", child.LocalID, IsRoot(child)); @@ -173,7 +173,7 @@ public sealed class BSLinksetCompound : BSLinkset // This doesn't normally happen -- OpenSim removes the objects from the physical // world if it is a static linkset. // Called at taint-time! - public override bool MakeStatic(BSPhysObject child) + public override bool MakeStatic(BSPrimLinkable child) { bool ret = false; DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child)); @@ -197,7 +197,7 @@ public sealed class BSLinksetCompound : BSLinkset // 'physicalUpdate' is true if these changes came directly from the physics engine. Don't need to rebuild then. // Called at taint-time. - public override void UpdateProperties(UpdatedProperties whichUpdated, BSPhysObject updated) + public override void UpdateProperties(UpdatedProperties whichUpdated, BSPrimLinkable updated) { // The user moving a child around requires the rebuilding of the linkset compound shape // One problem is this happens when a border is crossed -- the simulator implementation @@ -222,7 +222,7 @@ public sealed class BSLinksetCompound : BSLinkset if (lsi != null) { // Since the child moved or rotationed, it needs a new relative position within the linkset - BSLinksetCompoundInfo newLsi = new BSLinksetCompoundInfo(lsi.Index, LinksetRoot, updated, LinksetRoot.PositionDisplacement); + BSLinksetCompoundInfo newLsi = new BSLinksetCompoundInfo(lsi.Index, LinksetRoot, updated, OMV.Vector3.Zero); updated.LinksetInfo = newLsi; // Find the physical instance of the child @@ -291,7 +291,7 @@ public sealed class BSLinksetCompound : BSLinkset // Since we don't keep in world relationships, do nothing unless it's a child changing. // Returns 'true' of something was actually removed and would need restoring // Called at taint-time!! - public override bool RemoveBodyDependencies(BSPrim child) + public override bool RemoveBodyDependencies(BSPrimLinkable child) { bool ret = false; @@ -316,7 +316,7 @@ public sealed class BSLinksetCompound : BSLinkset // When the linkset is built, the child shape is added to the compound shape relative to the // root shape. The linkset then moves around but this does not move the actual child // prim. The child prim's location must be recomputed based on the location of the root shape. - private void RecomputeChildWorldPosition(BSPhysObject child, bool inTaintTime) + private void RecomputeChildWorldPosition(BSPrimLinkable child, bool inTaintTime) { // For the moment (20130201), disable this computation (converting the child physical addr back to // a region address) until we have a good handle on center-of-mass offsets and what the physics @@ -361,7 +361,7 @@ public sealed class BSLinksetCompound : BSLinkset // Add a new child to the linkset. // Called while LinkActivity is locked. - protected override void AddChildToLinkset(BSPhysObject child) + protected override void AddChildToLinkset(BSPrimLinkable child) { if (!HasChild(child)) { @@ -377,7 +377,7 @@ public sealed class BSLinksetCompound : BSLinkset // Remove the specified child from the linkset. // Safe to call even if the child is not really in the linkset. - protected override void RemoveChildFromLinkset(BSPhysObject child) + protected override void RemoveChildFromLinkset(BSPrimLinkable child) { if (m_children.Remove(child)) { @@ -429,7 +429,7 @@ public sealed class BSLinksetCompound : BSLinkset if (disableCOM) // DEBUG DEBUG { // DEBUG DEBUG centerOfMass = LinksetRoot.RawPosition; // DEBUG DEBUG - LinksetRoot.PositionDisplacement = OMV.Vector3.Zero; + // LinksetRoot.PositionDisplacement = OMV.Vector3.Zero; } // DEBUG DEBUG else { @@ -438,7 +438,7 @@ public sealed class BSLinksetCompound : BSLinkset centerDisplacement = LinksetRoot.RawPosition - centerOfMass; // Since we're displacing the center of the shape, we need to move the body in the world - LinksetRoot.PositionDisplacement = centerDisplacement; + // LinksetRoot.PositionDisplacement = centerDisplacement; // This causes the root prim position to be set properly based on the new PositionDisplacement LinksetRoot.ForcePosition = LinksetRoot.RawPosition; @@ -453,7 +453,7 @@ public sealed class BSLinksetCompound : BSLinkset // Add a shape for each of the other children in the linkset int memberIndex = 1; - ForEachMember(delegate(BSPhysObject cPrim) + ForEachMember(delegate(BSPrimLinkable cPrim) { if (!IsRoot(cPrim)) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index 3011465..cc814d1 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -36,7 +36,7 @@ public sealed class BSLinksetConstraints : BSLinkset { // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]"; - public BSLinksetConstraints(BSScene scene, BSPhysObject parent) : base(scene, parent) + public BSLinksetConstraints(BSScene scene, BSPrimLinkable parent) : base(scene, parent) { } @@ -44,7 +44,7 @@ public sealed class BSLinksetConstraints : BSLinkset // its internal properties. // This is queued in the 'post taint' queue so the // refresh will happen once after all the other taints are applied. - public override void Refresh(BSPhysObject requestor) + public override void Refresh(BSPrimLinkable requestor) { base.Refresh(requestor); @@ -65,7 +65,7 @@ public sealed class BSLinksetConstraints : BSLinkset // has not yet been fully constructed. // Return 'true' if any properties updated on the passed object. // Called at taint-time! - public override bool MakeDynamic(BSPhysObject child) + public override bool MakeDynamic(BSPrimLinkable child) { // What is done for each object in BSPrim is what we want. return false; @@ -76,14 +76,14 @@ public sealed class BSLinksetConstraints : BSLinkset // This doesn't normally happen -- OpenSim removes the objects from the physical // world if it is a static linkset. // Called at taint-time! - public override bool MakeStatic(BSPhysObject child) + public override bool MakeStatic(BSPrimLinkable child) { // What is done for each object in BSPrim is what we want. return false; } // Called at taint-time!! - public override void UpdateProperties(UpdatedProperties whichUpdated, BSPhysObject pObj) + public override void UpdateProperties(UpdatedProperties whichUpdated, BSPrimLinkable pObj) { // Nothing to do for constraints on property updates } @@ -93,7 +93,7 @@ public sealed class BSLinksetConstraints : BSLinkset // up to rebuild the constraints before the next simulation step. // Returns 'true' of something was actually removed and would need restoring // Called at taint-time!! - public override bool RemoveBodyDependencies(BSPrim child) + public override bool RemoveBodyDependencies(BSPrimLinkable child) { bool ret = false; @@ -114,7 +114,7 @@ public sealed class BSLinksetConstraints : BSLinkset // Add a new child to the linkset. // Called while LinkActivity is locked. - protected override void AddChildToLinkset(BSPhysObject child) + protected override void AddChildToLinkset(BSPrimLinkable child) { if (!HasChild(child)) { @@ -130,12 +130,12 @@ public sealed class BSLinksetConstraints : BSLinkset // Remove the specified child from the linkset. // Safe to call even if the child is not really in my linkset. - protected override void RemoveChildFromLinkset(BSPhysObject child) + protected override void RemoveChildFromLinkset(BSPrimLinkable child) { if (m_children.Remove(child)) { - BSPhysObject rootx = LinksetRoot; // capture the root and body as of now - BSPhysObject childx = child; + BSPrimLinkable rootx = LinksetRoot; // capture the root and body as of now + BSPrimLinkable childx = child; DetailLog("{0},BSLinksetConstraints.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}", childx.LocalID, @@ -159,13 +159,13 @@ public sealed class BSLinksetConstraints : BSLinkset // Create a constraint between me (root of linkset) and the passed prim (the child). // Called at taint time! - private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BSPhysObject childPrim) + private void PhysicallyLinkAChildToRoot(BSPrimLinkable rootPrim, BSPrimLinkable childPrim) { // Don't build the constraint when asked. Put it off until just before the simulation step. Refresh(rootPrim); } - private BSConstraint BuildConstraint(BSPhysObject rootPrim, BSPhysObject childPrim) + private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSPrimLinkable childPrim) { // Zero motion for children so they don't interpolate childPrim.ZeroMotion(true); @@ -239,7 +239,7 @@ public sealed class BSLinksetConstraints : BSLinkset // The root and child bodies are passed in because we need to remove the constraint between // the bodies that were present at unlink time. // Called at taint time! - private bool PhysicallyUnlinkAChildFromRoot(BSPhysObject rootPrim, BSPhysObject childPrim) + private bool PhysicallyUnlinkAChildFromRoot(BSPrimLinkable rootPrim, BSPrimLinkable childPrim) { bool ret = false; DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}", @@ -261,7 +261,7 @@ public sealed class BSLinksetConstraints : BSLinkset // Remove linkage between myself and any possible children I might have. // Returns 'true' of any constraints were destroyed. // Called at taint time! - private bool PhysicallyUnlinkAllChildrenFromRoot(BSPhysObject rootPrim) + private bool PhysicallyUnlinkAllChildrenFromRoot(BSPrimLinkable rootPrim) { DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); @@ -281,7 +281,7 @@ public sealed class BSLinksetConstraints : BSLinkset DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}", LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString, linksetMass); - foreach (BSPhysObject child in m_children) + foreach (BSPrimLinkable child in m_children) { // A child in the linkset physically shows the mass of the whole linkset. // This allows Bullet to apply enough force on the child to move the whole linkset. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 0d8bb03..e1d269a 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -86,10 +86,6 @@ public abstract class BSPhysObject : PhysicsActor PhysBody = new BulletBody(localID); PhysShape = new BulletShape(); - // A linkset of just me - Linkset = BSLinkset.Factory(PhysicsScene, this); - PositionDisplacement = OMV.Vector3.Zero; - LastAssetBuildFailed = false; // Default material type. Also sets Friction, Restitution and Density. @@ -117,8 +113,6 @@ public abstract class BSPhysObject : PhysicsActor public string PhysObjectName { get; protected set; } public string TypeName { get; protected set; } - public BSLinkset Linkset { get; set; } - public BSLinksetInfo LinksetInfo { get; set; } // Return the object mass without calculating it or having side effects public abstract float RawMass { get; } @@ -188,15 +182,6 @@ public abstract class BSPhysObject : PhysicsActor public abstract OMV.Vector3 RawPosition { get; set; } public abstract OMV.Vector3 ForcePosition { get; set; } - // 'Position' and 'Orientation' is what the simulator thinks the positions of the prim is. - // Because Bullet needs the zero coordinate to be the center of mass of the linkset, - // sometimes it is necessary to displace the position the physics engine thinks - // the position is. PositionDisplacement must be added and removed from the - // position as the simulator position is stored and fetched from the physics - // engine. Similar to OrientationDisplacement. - public virtual OMV.Vector3 PositionDisplacement { get; set; } - public virtual OMV.Quaternion OrientationDisplacement { get; set; } - public abstract OMV.Quaternion RawOrientation { get; set; } public abstract OMV.Quaternion ForceOrientation { get; set; } @@ -302,12 +287,6 @@ public abstract class BSPhysObject : PhysicsActor CollidingObjectStep = PhysicsScene.SimulationStep; } - // prims in the same linkset cannot collide with each other - if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID)) - { - return ret; - } - CollisionAccumulation++; // For movement tests, remember if we are colliding with an object that is moving. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 85c2627..cf7aa0f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -39,7 +39,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { [Serializable] -public sealed class BSPrim : BSPhysObject +public class BSPrim : BSPhysObject { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly string LogHeader = "[BULLETS PRIM]"; @@ -102,9 +102,6 @@ public sealed class BSPrim : BSPhysObject _mass = CalculateMass(); - // Cause linkset variables to be initialized (like mass) - Linkset.Refresh(this); - DetailLog("{0},BSPrim.constructor,call", LocalID); // do the actual object creation at taint time PhysicsScene.TaintedObject("BSPrim.create", delegate() @@ -121,15 +118,6 @@ public sealed class BSPrim : BSPhysObject // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); base.Destroy(); - // Undo any links between me and any other object - BSPhysObject parentBefore = Linkset.LinksetRoot; // DEBUG DEBUG - int childrenBefore = Linkset.NumberOfChildren; // DEBUG DEBUG - - Linkset = Linkset.RemoveMeFromLinkset(this); - - DetailLog("{0},BSPrim.Destroy,call,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}", - LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren); - // Undo any vehicle properties this.VehicleType = (int)Vehicle.TYPE_NONE; @@ -166,9 +154,9 @@ public sealed class BSPrim : BSPhysObject ForceBodyShapeRebuild(false); } } - // Whatever the linkset wants is what I want. + // 'unknown' says to choose the best type public override BSPhysicsShapeType PreferredPhysicalShape - { get { return Linkset.PreferredPhysicalShape(this); } } + { get { return BSPhysicsShapeType.SHAPE_UNKNOWN; } } public override bool ForceBodyShapeRebuild(bool inTaintTime) { @@ -213,33 +201,10 @@ public sealed class BSPrim : BSPhysObject // link me to the specified parent public override void link(PhysicsActor obj) { - BSPrim parent = obj as BSPrim; - if (parent != null) - { - BSPhysObject parentBefore = Linkset.LinksetRoot; - int childrenBefore = Linkset.NumberOfChildren; - - Linkset = parent.Linkset.AddMeToLinkset(this); - - DetailLog("{0},BSPrim.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}", - LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren); - } - return; } // delink me from my linkset public override void delink() { - // TODO: decide if this parent checking needs to happen at taint time - // Race condition here: if link() and delink() in same simulation tick, the delink will not happen - - BSPhysObject parentBefore = Linkset.LinksetRoot; - int childrenBefore = Linkset.NumberOfChildren; - - Linkset = Linkset.RemoveMeFromLinkset(this); - - DetailLog("{0},BSPrim.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ", - LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren); - return; } // Set motion values to zero. @@ -287,15 +252,8 @@ public sealed class BSPrim : BSPhysObject } public override OMV.Vector3 Position { get { - /* NOTE: this refetch is not necessary. The simulator knows about linkset children - * and does not fetch this position info for children. Thus this is commented out. - // child prims move around based on their parent. Need to get the latest location - if (!Linkset.IsRoot(this)) - _position = Linkset.PositionGet(this); - */ - // don't do the GetObjectPosition for root elements because this function is called a zillion times. - // _position = PhysicsScene.PE.GetObjectPosition2(PhysicsScene.World, BSBody) - PositionDisplacement; + // _position = ForcePosition; return _position; } set { @@ -313,24 +271,20 @@ public sealed class BSPrim : BSPhysObject { DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); ForcePosition = _position; - - // A linkset might need to know if a component information changed. - Linkset.UpdateProperties(UpdatedProperties.Position, this); - }); } } public override OMV.Vector3 ForcePosition { get { - _position = PhysicsScene.PE.GetPosition(PhysBody) - PositionDisplacement; + _position = PhysicsScene.PE.GetPosition(PhysBody); return _position; } set { _position = value; if (PhysBody.HasPhysicalBody) { - PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation); + PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); ActivateIfPhysical(false); } } @@ -398,12 +352,13 @@ public sealed class BSPrim : BSPhysObject // If the simulator cares about the mass of the linkset, it will sum it itself. public override float Mass { - get - { - return _mass; - } + get { return _mass; } + } + // TotalMass returns the mass of the large object the prim may be in (overridden by linkset code) + public virtual float TotalMass + { + get { return _mass; } } - // used when we only want this prim's mass and not the linkset thing public override float RawMass { get { return _mass; } @@ -467,13 +422,13 @@ public sealed class BSPrim : BSPhysObject // Is this used? public override OMV.Vector3 CenterOfMass { - get { return Linkset.CenterOfMass; } + get { return RawPosition; } } // Is this used? public override OMV.Vector3 GeometricCenter { - get { return Linkset.GeometricCenter; } + get { return RawPosition; } } public override OMV.Vector3 Force { @@ -721,14 +676,6 @@ public sealed class BSPrim : BSPhysObject } public override OMV.Quaternion Orientation { get { - /* NOTE: this refetch is not necessary. The simulator knows about linkset children - * and does not fetch this position info for children. Thus this is commented out. - // Children move around because tied to parent. Get a fresh value. - if (!Linkset.IsRoot(this)) - { - _orientation = Linkset.OrientationGet(this); - } - */ return _orientation; } set { @@ -739,10 +686,6 @@ public sealed class BSPrim : BSPhysObject PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate() { ForceOrientation = _orientation; - - // A linkset might need to know if a component information changed. - Linkset.UpdateProperties(UpdatedProperties.Orientation, this); - }); } } @@ -758,7 +701,7 @@ public sealed class BSPrim : BSPhysObject { _orientation = value; if (PhysBody.HasPhysicalBody) - PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation); + PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); } } public override int PhysicsActorType { @@ -814,7 +757,7 @@ public sealed class BSPrim : BSPhysObject // isSolid: other objects bounce off of this object // isVolumeDetect: other objects pass through but can generate collisions // collisionEvents: whether this object returns collision events - public void UpdatePhysicalParameters() + public virtual void UpdatePhysicalParameters() { if (!PhysBody.HasPhysicalBody) { @@ -844,12 +787,6 @@ public sealed class BSPrim : BSPhysObject // Rebuild its shape PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, PhysBody); - // Recompute any linkset parameters. - // When going from non-physical to physical, this re-enables the constraints that - // had been automatically disabled when the mass was set to zero. - // For compound based linksets, this enables and disables interactions of the children. - Linkset.Refresh(this); - DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},cType={6},body={7},shape={8}", LocalID, IsStatic, IsSolid, Mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody.collisionType, PhysBody, PhysShape); } @@ -859,7 +796,7 @@ public sealed class BSPrim : BSPhysObject // When dynamic, the object can fall and be pushed by others. // This is independent of its 'solidness' which controls what passes through // this object and what interacts with it. - private void MakeDynamic(bool makeStatic) + protected virtual void MakeDynamic(bool makeStatic) { if (makeStatic) { @@ -889,9 +826,6 @@ public sealed class BSPrim : BSPhysObject // This collides like a static object PhysBody.collisionType = CollisionType.Static; - - // There can be special things needed for implementing linksets - Linkset.MakeStatic(this); } else { @@ -908,10 +842,7 @@ public sealed class BSPrim : BSPhysObject // PhysicsScene.PE.ClearAllForces(BSBody); // For good measure, make sure the transform is set through to the motion state - PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation); - - // Center of mass is at the center of the object - // DEBUG DEBUG PhysicsScene.PE.SetCenterOfMassByPosRot(Linkset.LinksetRoot.PhysBody, _position, _orientation); + ForcePosition = _position; // A dynamic object has mass UpdatePhysicalMassProperties(RawMass, false); @@ -935,9 +866,6 @@ public sealed class BSPrim : BSPhysObject // Force activation of the object so Bullet will act on it. // Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects. PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.ACTIVE_TAG); - - // There might be special things needed for implementing linksets. - Linkset.MakeDynamic(this); } } @@ -1643,16 +1571,6 @@ public sealed class BSPrim : BSPhysObject returnMass = Density * volume; - /* Comment out code that computes the mass of the linkset. That is done in the Linkset class. - if (IsRootOfLinkset) - { - foreach (BSPrim prim in _childrenPrims) - { - returnMass += prim.CalculateMass(); - } - } - */ - returnMass = Util.Clamp(returnMass, BSParam.MinimumObjectMass, BSParam.MaximumObjectMass); return returnMass; @@ -1672,8 +1590,7 @@ public sealed class BSPrim : BSPhysObject // Called if the current prim body is about to be destroyed. // Remove all the physical dependencies on the old body. // (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...) - Linkset.RemoveBodyDependencies(this); - VehicleController.RemoveBodyDependencies(this); + RemoveBodyDependencies(); }); // Make sure the properties are set on the new object @@ -1681,57 +1598,50 @@ public sealed class BSPrim : BSPhysObject return; } + protected virtual void RemoveBodyDependencies() + { + VehicleController.RemoveBodyDependencies(this); + } + // The physics engine says that properties have updated. Update same and inform // the world that things have changed. public override void UpdateProperties(EntityProperties entprop) { - // Updates only for individual prims and for the root object of a linkset. - if (Linkset.IsRoot(this)) + // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet + // TODO: handle physics introduced by Bullet with computed vehicle physics. + if (VehicleController.IsActive) { - // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet - // TODO: handle physics introduced by Bullet with computed vehicle physics. - if (VehicleController.IsActive) - { - entprop.RotationalVelocity = OMV.Vector3.Zero; - } - - // DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG + entprop.RotationalVelocity = OMV.Vector3.Zero; + } - // Undo any center-of-mass displacement that might have been done. - if (PositionDisplacement != OMV.Vector3.Zero) - { - // Correct for any rotation around the center-of-mass - // TODO!!! - entprop.Position -= PositionDisplacement; - } + // DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG - // Assign directly to the local variables so the normal set actions do not happen - _position = entprop.Position; - _orientation = entprop.Rotation; - _velocity = entprop.Velocity; - _acceleration = entprop.Acceleration; - _rotationalVelocity = entprop.RotationalVelocity; + // Assign directly to the local variables so the normal set actions do not happen + _position = entprop.Position; + _orientation = entprop.Rotation; + _velocity = entprop.Velocity; + _acceleration = entprop.Acceleration; + _rotationalVelocity = entprop.RotationalVelocity; - // DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG + // DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG - // The sanity check can change the velocity and/or position. - if (PositionSanityCheck(true /* inTaintTime */ )) - { - entprop.Position = _position; - entprop.Velocity = _velocity; - entprop.RotationalVelocity = _rotationalVelocity; - entprop.Acceleration = _acceleration; - } + // The sanity check can change the velocity and/or position. + if (PositionSanityCheck(true /* inTaintTime */ )) + { + entprop.Position = _position; + entprop.Velocity = _velocity; + entprop.RotationalVelocity = _rotationalVelocity; + entprop.Acceleration = _acceleration; + } - OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG - DetailLog("{0},BSPrim.UpdateProperties,call,entProp={1},dir={2}", LocalID, entprop, direction); + OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG + DetailLog("{0},BSPrim.UpdateProperties,call,entProp={1},dir={2}", LocalID, entprop, direction); - // remember the current and last set values - LastEntityProperties = CurrentEntityProperties; - CurrentEntityProperties = entprop; + // remember the current and last set values + LastEntityProperties = CurrentEntityProperties; + CurrentEntityProperties = entprop; - base.RequestPhysicsterseUpdate(); - } + base.RequestPhysicsterseUpdate(); /* else { @@ -1741,9 +1651,6 @@ public sealed class BSPrim : BSPhysObject entprop.Acceleration, entprop.RotationalVelocity); } */ - - // The linkset implimentation might want to know about this. - Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this); } } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index f8a0c1e..e506d22 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -434,7 +434,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters { if (!m_initialized) return; - BSPrim bsprim = prim as BSPrim; + BSPhysObject bsprim = prim as BSPhysObject; if (bsprim != null) { DetailLog("{0},RemovePrim,call", bsprim.LocalID); @@ -465,7 +465,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters DetailLog("{0},AddPrimShape,call", localID); - BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical); + BSPhysObject prim = new BSPrimLinkable(localID, primName, this, position, size, rotation, pbs, isPhysical); lock (PhysObjects) PhysObjects.Add(localID, prim); return prim; } -- cgit v1.1 From d92eb803734956c1e0b260eb7740910e1fa3b891 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 7 Feb 2013 21:57:46 -0800 Subject: BulletSim: add initial instance of the ExtendedPhysics region module which adds new LSL commands for extended physics functions. Uses the modInvoke system. Disabled by default. --- .../Scripting/ExtendedPhysics/ExtendedPhysics.cs | 163 +++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100755 OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs new file mode 100755 index 0000000..aaa349f --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs @@ -0,0 +1,163 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyrightD + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; + +using OpenSim.Framework; +using OpenSim.Region.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.CoreModules; + +using Mono.Addins; +using Nini.Config; +using log4net; +using OpenMetaverse; + +namespace OpenSim.Region.OptionalModules.Scripting +{ +[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] +public class ExtendedPhysics : INonSharedRegionModule +{ + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static string LogHeader = "[EXTENDED PHYSICS]"; + + private IConfig Configuration { get; set; } + private bool Enabled { get; set; } + private Scene BaseScene { get; set; } + private IScriptModuleComms Comms { get; set; } + + #region INonSharedRegionModule + + public string Name { get { return this.GetType().Name; } } + + public void Initialise(IConfigSource config) + { + BaseScene = null; + Enabled = false; + Configuration = null; + Comms = null; + + try + { + if ((Configuration = config.Configs["ExtendedPhysics"]) != null) + { + Enabled = Configuration.GetBoolean("Enabled", Enabled); + } + } + catch (Exception e) + { + m_log.ErrorFormat("{0} Initialization error: {0}", LogHeader, e); + } + + m_log.ErrorFormat("{0} module {1} enabled", LogHeader, (Enabled ? "is" : "is not")); + } + + public void Close() + { + if (BaseScene != null) + { + BaseScene.EventManager.OnSceneObjectPartUpdated -= EventManager_OnSceneObjectPartUpdated; + BaseScene = null; + } + } + + public void AddRegion(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + if (BaseScene != null && BaseScene == scene) + { + Close(); + } + } + + public void RegionLoaded(Scene scene) + { + if (!Enabled) return; + + BaseScene = scene; + + Comms = BaseScene.RequestModuleInterface(); + if (Comms == null) + { + m_log.WarnFormat("{0} ScriptModuleComms interface not defined", LogHeader); + Enabled = false; + + return; + } + + // Register as LSL functions all the [ScriptInvocation] marked methods. + Comms.RegisterScriptInvocations(this); + + // When an object is modified, we might need to update its extended physics parameters + BaseScene.EventManager.OnSceneObjectPartUpdated += EventManager_OnSceneObjectPartUpdated; + } + + public Type ReplaceableInterface { get { return null; } } + + #endregion // INonSharedRegionModule + + // Event generated when some property of a prim changes. + private void EventManager_OnSceneObjectPartUpdated(SceneObjectPart sop, bool isFullUpdate) + { + } + + [ScriptConstant] + public static int PHYS_CENTER_OF_MASS = 1 << 0; + + [ScriptConstant] + public static int PHYS_LINKSET_TYPE_CONSTRAINT = 1; + [ScriptConstant] + public static int PHYS_LINKSET_TYPE_COMPOUND = 2; + [ScriptConstant] + public static int PHYS_LINKSET_TYPE_MANUAL = 3; + + [ScriptInvocation] + public string physGetEngineType(UUID hostID, UUID scriptID) + { + string ret = string.Empty; + + if (BaseScene.PhysicsScene != null) + { + ret = BaseScene.PhysicsScene.EngineType; + } + + return ret; + } + + [ScriptInvocation] + public void physSetLinksetType(UUID hostID, UUID scriptID, int linksetType) + { + } +} +} -- cgit v1.1 From 1b55a9d81e66972312fdc801d17da697466f9ed4 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 8 Feb 2013 15:25:57 -0800 Subject: BulletSim: fix avatar bobbing or jiggling while stationary flying. Various comments and debugging message mods. --- .../Scripting/ExtendedPhysics/ExtendedPhysics.cs | 10 +++++++- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 29 ++++++++++++---------- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 4 +++ .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 6 ++--- .../Region/Physics/BulletSPlugin/BSPrimLinkable.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 2 +- 6 files changed, 34 insertions(+), 19 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs index aaa349f..6009dc5 100755 --- a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs +++ b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs @@ -77,13 +77,14 @@ public class ExtendedPhysics : INonSharedRegionModule m_log.ErrorFormat("{0} Initialization error: {0}", LogHeader, e); } - m_log.ErrorFormat("{0} module {1} enabled", LogHeader, (Enabled ? "is" : "is not")); + m_log.InfoFormat("{0} module {1} enabled", LogHeader, (Enabled ? "is" : "is not")); } public void Close() { if (BaseScene != null) { + BaseScene.EventManager.OnObjectAddedToScene -= EventManager_OnObjectAddedToScene; BaseScene.EventManager.OnSceneObjectPartUpdated -= EventManager_OnSceneObjectPartUpdated; BaseScene = null; } @@ -120,13 +121,20 @@ public class ExtendedPhysics : INonSharedRegionModule Comms.RegisterScriptInvocations(this); // When an object is modified, we might need to update its extended physics parameters + BaseScene.EventManager.OnObjectAddedToScene += EventManager_OnObjectAddedToScene; BaseScene.EventManager.OnSceneObjectPartUpdated += EventManager_OnSceneObjectPartUpdated; + } public Type ReplaceableInterface { get { return null; } } #endregion // INonSharedRegionModule + private void EventManager_OnObjectAddedToScene(SceneObjectGroup obj) + { + throw new NotImplementedException(); + } + // Event generated when some property of a prim changes. private void EventManager_OnSceneObjectPartUpdated(SceneObjectPart sop, bool isFullUpdate) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 0afc437..6a995a2 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -140,7 +140,7 @@ public sealed class BSCharacter : BSPhysObject ZeroMotion(true); ForcePosition = _position; - // Set the velocity and compute the proper friction + // Set the velocity _velocityMotor.Reset(); _velocityMotor.SetTarget(_velocity); _velocityMotor.SetCurrent(_velocity); @@ -214,25 +214,28 @@ public sealed class BSCharacter : BSPhysObject _velocityMotor.Step(timeStep); // If we're not supposed to be moving, make sure things are zero. - if (_velocityMotor.ErrorIsZero() && _velocityMotor.TargetValue == OMV.Vector3.Zero && IsColliding) + if (_velocityMotor.ErrorIsZero() && _velocityMotor.TargetValue == OMV.Vector3.Zero) { // The avatar shouldn't be moving _velocityMotor.Zero(); - // If we are colliding with a stationary object, presume we're standing and don't move around - if (!ColliderIsMoving) + if (IsColliding) { - DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", LocalID); - ZeroMotion(true /* inTaintTime */); - } + // If we are colliding with a stationary object, presume we're standing and don't move around + if (!ColliderIsMoving) + { + DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", LocalID); + ZeroMotion(true /* inTaintTime */); + } - // Standing has more friction on the ground - if (_currentFriction != BSParam.AvatarStandingFriction) - { - _currentFriction = BSParam.AvatarStandingFriction; - PhysicsScene.PE.SetFriction(PhysBody, _currentFriction); + // Standing has more friction on the ground + if (_currentFriction != BSParam.AvatarStandingFriction) + { + _currentFriction = BSParam.AvatarStandingFriction; + PhysicsScene.PE.SetFriction(PhysBody, _currentFriction); + } } - DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1}", LocalID, _velocityMotor.TargetValue); + DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1},colliding={2}", LocalID, _velocityMotor.TargetValue, IsColliding); } else { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 8e69db3..e35311f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -71,6 +71,10 @@ public abstract class BSLinkset ret = new BSLinksetCompound(physScene, parent); break; } + if (ret == null) + { + physScene.Logger.ErrorFormat("[BULLETSIM LINKSET] Factory could not create linkset. Parent name={1}, ID={2}", parent.Name, parent.LocalID); + } return ret; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index e1d269a..de69fa0 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -290,13 +290,13 @@ public abstract class BSPhysObject : PhysicsActor CollisionAccumulation++; // For movement tests, remember if we are colliding with an object that is moving. - ColliderIsMoving = collidee != null ? collidee.RawVelocity != OMV.Vector3.Zero : false; + ColliderIsMoving = collidee != null ? (collidee.RawVelocity != OMV.Vector3.Zero) : false; // If someone has subscribed for collision events log the collision so it will be reported up if (SubscribedEvents()) { CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); - DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5}", - LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth); + DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5},colliderMoving={6}", + LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth, ColliderIsMoving); ret = true; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs index fd66d1c..9898562 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs @@ -160,8 +160,8 @@ public class BSPrimLinkable : BSPrimDisplaced // TODO: this will have to change when linksets are articulated. base.UpdateProperties(entprop); } + // The linkset might like to know about changing locations Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this); - } public override bool Collide(uint collidingWith, BSPhysObject collidee, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index e506d22..05722b8 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -463,7 +463,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters if (!m_initialized) return null; - DetailLog("{0},AddPrimShape,call", localID); + DetailLog("{0},BSScene.AddPrimShape,call", localID); BSPhysObject prim = new BSPrimLinkable(localID, primName, this, position, size, rotation, pbs, isPhysical); lock (PhysObjects) PhysObjects.Add(localID, prim); -- cgit v1.1 From 222040f1ec0d85b06de8271fd7eabc7dd0a2f7d4 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 8 Feb 2013 15:36:10 -0800 Subject: BulletSim: Change BSCharacter to use new base Density and Friction variables rather than own local varaibles. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 26 +++++++++------------- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 2 +- 2 files changed, 12 insertions(+), 16 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 6a995a2..f781aea 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -45,7 +45,6 @@ public sealed class BSCharacter : BSPhysObject private bool _selected; private OMV.Vector3 _position; private float _mass; - private float _avatarDensity; private float _avatarVolume; private OMV.Vector3 _force; private OMV.Vector3 _velocity; @@ -63,9 +62,6 @@ public sealed class BSCharacter : BSPhysObject private bool _kinematic; private float _buoyancy; - // The friction and velocity of the avatar is modified depending on whether walking or not. - private float _currentFriction; // the friction currently being used (changed by setVelocity). - private BSVMotor _velocityMotor; private OMV.Vector3 _PIDTarget; @@ -86,8 +82,8 @@ public sealed class BSCharacter : BSPhysObject _orientation = OMV.Quaternion.Identity; _velocity = OMV.Vector3.Zero; _buoyancy = ComputeBuoyancyFromFlying(isFlying); - _currentFriction = BSParam.AvatarStandingFriction; - _avatarDensity = BSParam.AvatarDensity; + Friction = BSParam.AvatarStandingFriction; + Density = BSParam.AvatarDensity; // Old versions of ScenePresence passed only the height. If width and/or depth are zero, // replace with the default values. @@ -104,7 +100,7 @@ public sealed class BSCharacter : BSPhysObject SetupMovementMotor(); DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}", - LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass); + LocalID, _size, Scale, Density, _avatarVolume, RawMass); // do actual creation in taint time PhysicsScene.TaintedObject("BSCharacter.create", delegate() @@ -229,10 +225,10 @@ public sealed class BSCharacter : BSPhysObject } // Standing has more friction on the ground - if (_currentFriction != BSParam.AvatarStandingFriction) + if (Friction != BSParam.AvatarStandingFriction) { - _currentFriction = BSParam.AvatarStandingFriction; - PhysicsScene.PE.SetFriction(PhysBody, _currentFriction); + Friction = BSParam.AvatarStandingFriction; + PhysicsScene.PE.SetFriction(PhysBody, Friction); } } DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1},colliding={2}", LocalID, _velocityMotor.TargetValue, IsColliding); @@ -241,11 +237,11 @@ public sealed class BSCharacter : BSPhysObject { OMV.Vector3 stepVelocity = _velocityMotor.CurrentValue; - if (_currentFriction != BSParam.AvatarFriction) + if (Friction != BSParam.AvatarFriction) { // Probably starting up walking. Set friction to moving friction. - _currentFriction = BSParam.AvatarFriction; - PhysicsScene.PE.SetFriction(PhysBody, _currentFriction); + Friction = BSParam.AvatarFriction; + PhysicsScene.PE.SetFriction(PhysBody, Friction); } // If falling, we keep the world's downward vector no matter what the other axis specify. @@ -345,7 +341,7 @@ public sealed class BSCharacter : BSPhysObject Scale = ComputeAvatarScale(_size); ComputeAvatarVolumeAndMass(); DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}", - LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass); + LocalID, _size, Scale, Density, _avatarVolume, RawMass); PhysicsScene.TaintedObject("BSCharacter.setSize", delegate() { @@ -873,7 +869,7 @@ public sealed class BSCharacter : BSPhysObject * Math.Min(Size.X, Size.Y) / 2 * Size.Y / 2f // plus the volume of the capsule end caps ); - _mass = _avatarDensity * _avatarVolume; + _mass = Density * _avatarVolume; } // The physics engine says that properties have updated. Update same and inform diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 601c78c..6cb7434 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -424,7 +424,7 @@ public static class BSParam (s) => { return AvatarFriction; }, (s,p,l,v) => { AvatarFriction = v; } ), new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", - 10.0f, + 0.95f, (s,cf,p,v) => { AvatarStandingFriction = cf.GetFloat(p, v); }, (s) => { return AvatarStandingFriction; }, (s,p,l,v) => { AvatarStandingFriction = v; } ), -- cgit v1.1 From 4808b8ee380d32c1b63654f9c0170a5f07b46bd0 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 8 Feb 2013 16:27:44 -0800 Subject: BulletSim: add parameter to set global contact breaking threshold. Update DLLs and SOs for setting same. --- OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs | 1 + OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 6 ++++++ 2 files changed, 7 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index 5e06c1e..7ab86d2 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs @@ -183,6 +183,7 @@ public struct ConfigurationParameters public float shouldEnableFrictionCaching; public float numberOfSolverIterations; public float useSingleSidedMeshes; + public float globalContactBreakingThreshold; public float physicsLoggingFrames; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 6cb7434..3e0b4bc 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -87,6 +87,7 @@ public static class BSParam public static float NumberOfSolverIterations; public static bool UseSingleSidedMeshes { get { return UseSingleSidedMeshesF != ConfigurationParameters.numericFalse; } } public static float UseSingleSidedMeshesF; + public static float GlobalContactBreakingThreshold; // Avatar parameters public static float AvatarFriction { get; private set; } @@ -570,6 +571,11 @@ public static class BSParam (s,cf,p,v) => { UseSingleSidedMeshesF = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, (s) => { return UseSingleSidedMeshesF; }, (s,p,l,v) => { UseSingleSidedMeshesF = v; s.UnmanagedParams[0].useSingleSidedMeshes = v; } ), + new ParameterDefn("GlobalContactBreakingThreshold", "Amount of shape radius before breaking a collision contact (0 says Bullet default (0.2))", + 0f, + (s,cf,p,v) => { GlobalContactBreakingThreshold = cf.GetFloat(p, v); }, + (s) => { return GlobalContactBreakingThreshold; }, + (s,p,l,v) => { GlobalContactBreakingThreshold = v; s.UnmanagedParams[0].globalContactBreakingThreshold = v; } ), new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", (float)BSLinkset.LinksetImplementation.Compound, -- cgit v1.1 From a8bc08ebe6523a2e66bb2e1d1d226d3159eba30c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 9 Feb 2013 01:10:53 +0000 Subject: Change TestDestroyStore() and TestJsonRemoveValue() to reflect the fact that the return values have changed. --- .../Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index ca88d1a..af97ac7 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -144,8 +144,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests int dsrv = (int)InvokeOp("JsonDestroyStore", fakeStoreId); - // XXX: Current returns 'true' even though no such store existed. Need to ask if this is best behaviour. - Assert.That(dsrv, Is.EqualTo(1)); + Assert.That(dsrv, Is.EqualTo(0)); } [Test] @@ -211,9 +210,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests // Test remove of non-existing value int fakeValueRemove = (int)InvokeOp("JsonRemoveValue", storeId, "Hello"); - - // XXX: Is this the best response to removing a value that isn't there? - Assert.That(fakeValueRemove, Is.EqualTo(1)); + Assert.That(fakeValueRemove, Is.EqualTo(0)); // Test get from non-existing store UUID fakeStoreId = TestHelpers.ParseTail(0x500); -- cgit v1.1 From 7bb82c8f2ed987410342c1367dde24b695593eec Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Fri, 8 Feb 2013 22:43:15 -0800 Subject: Make JsonStore path parsing more robust. Should fix the invalid path problem. --- .../Scripting/JsonStore/JsonStore.cs | 68 +++++++++++++++------- .../Scripting/JsonStore/JsonStoreScriptModule.cs | 12 +++- 2 files changed, 59 insertions(+), 21 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs index 5c89717..3d715cc 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs @@ -81,7 +81,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore protected static Regex m_ParsePassFour = new Regex("\\.+"); // expression used to validate the full path, this is canonical representation - protected static Regex m_ValidatePath = new Regex("^\\.(({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])\\.)+$"); + protected static Regex m_ValidatePath = new Regex("^\\.(({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])\\.)*$"); // expression used to match path components protected static Regex m_PathComponent = new Regex("\\.({[^}]+}|\\[[0-9]+\\]|\\[\\+\\]+)"); @@ -107,9 +107,17 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - public static string CanonicalPathExpression(string path) + public static bool CanonicalPathExpression(string ipath, out string opath) { - return PathExpressionToKey(ParsePathExpression(path)); + Stack path; + if (! ParsePathExpression(ipath,out path)) + { + opath = ""; + return false; + } + + opath = PathExpressionToKey(path); + return true; } // ----------------------------------------------------------------- @@ -139,7 +147,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore // ----------------------------------------------------------------- public bool TestPath(string expr, bool useJson) { - Stack path = ParsePathExpression(expr); + Stack path; + if (! ParsePathExpression(expr,out path)) + return false; + OSD result = ProcessPathExpression(ValueStore,path); if (result == null) @@ -158,7 +169,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore // ----------------------------------------------------------------- public bool GetValue(string expr, out string value, bool useJson) { - Stack path = ParsePathExpression(expr); + Stack path; + if (! ParsePathExpression(expr,out path)) + { + value = ""; + return false; + } + OSD result = ProcessPathExpression(ValueStore,path); return ConvertOutputValue(result,out value,useJson); } @@ -192,7 +209,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore // ----------------------------------------------------------------- public bool TakeValue(string expr, bool useJson, TakeValueCallback cback) { - Stack path = ParsePathExpression(expr); + Stack path; + if (! ParsePathExpression(expr,out path)) + return false; + string pexpr = PathExpressionToKey(path); OSD result = ProcessPathExpression(ValueStore,path); @@ -223,7 +243,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore // ----------------------------------------------------------------- public bool ReadValue(string expr, bool useJson, TakeValueCallback cback) { - Stack path = ParsePathExpression(expr); + Stack path; + if (! ParsePathExpression(expr,out path)) + return false; + string pexpr = PathExpressionToKey(path); OSD result = ProcessPathExpression(ValueStore,path); @@ -253,7 +276,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore // ----------------------------------------------------------------- protected bool SetValueFromExpression(string expr, OSD ovalue) { - Stack path = ParsePathExpression(expr); + Stack path; + if (! ParsePathExpression(expr,out path)) + return false; + if (path.Count == 0) { ValueStore = ovalue; @@ -399,34 +425,36 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// use a stack because we process the path in inverse order later /// // ----------------------------------------------------------------- - protected static Stack ParsePathExpression(string path) + protected static bool ParsePathExpression(string expr, out Stack path) { - Stack m_path = new Stack(); + path = new Stack(); // add front and rear separators - path = "." + path + "."; + expr = "." + expr + "."; - // add separators for quoted paths - path = m_ParsePassOne.Replace(path,".$0.",-1,0); + // add separators for quoted exprs + expr = m_ParsePassOne.Replace(expr,".$0.",-1,0); // add separators for array references - path = m_ParsePassTwo.Replace(path,".$0.",-1,0); + expr = m_ParsePassTwo.Replace(expr,".$0.",-1,0); // add quotes to bare identifier - path = m_ParsePassThree.Replace(path,".{$1}",-1,0); + expr = m_ParsePassThree.Replace(expr,".{$1}",-1,0); // remove extra separators - path = m_ParsePassFour.Replace(path,".",-1,0); + expr = m_ParsePassFour.Replace(expr,".",-1,0); // validate the results (catches extra quote characters for example) - if (m_ValidatePath.IsMatch(path)) + if (m_ValidatePath.IsMatch(expr)) { - MatchCollection matches = m_PathComponent.Matches(path,0); + MatchCollection matches = m_PathComponent.Matches(expr,0); foreach (Match match in matches) - m_path.Push(match.Groups[1].Value); + path.Push(match.Groups[1].Value); + + return true; } - return m_path; + return false; } // ----------------------------------------------------------------- diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index d75cd32..e436304 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs @@ -301,7 +301,16 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore [ScriptInvocation] public string JsonList2Path(UUID hostID, UUID scriptID, object[] pathlist) { - return JsonStore.CanonicalPathExpression(ConvertList2Path(pathlist)); + string ipath = ConvertList2Path(pathlist); + string opath; + + if (JsonStore.CanonicalPathExpression(ipath,out opath)) + return opath; + + // This won't parse if passed to the other routines as opposed to + // returning an empty string which is a valid path and would overwrite + // the entire store + return "**INVALID**"; } // ----------------------------------------------------------------- @@ -421,6 +430,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore // ----------------------------------------------------------------- protected void GenerateRuntimeError(string msg) { + m_log.InfoFormat("[JsonStore] runtime error: {0}",msg); throw new Exception("JsonStore Runtime Error: " + msg); } -- cgit v1.1 From adedd70c352581bc447452f5835c10853c77bea8 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Sun, 10 Feb 2013 13:01:33 -0500 Subject: Fix teleport/telehub issue: Fix bug that allowed only login access to regions with mis-configured telehubs. Administrators now have teleport access when there exists a mis-configured telehub in the region. Estate owners are now placed at region center in the absence of spawnpoints instead of being denied access. Grid Gods are unrestricted. All others are denied access to the region until spawnpoints are assigned to the telehub object. --- OpenSim/Region/Framework/Scenes/Scene.cs | 9 +++++++-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 11 ++++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index de3978c..9b17b7f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -5506,8 +5506,13 @@ namespace OpenSim.Region.Framework.Scenes if (banned) { - reason = "No suitable landing point found"; - return false; + if(Permissions.IsAdministrator(agentID) == false || Permissions.IsGridGod(agentID) == false) + { + reason = "No suitable landing point found"; + return false; + } + reason = "Administrative access only"; + return true; } } } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 6e41774..30bd715 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -4021,6 +4021,7 @@ namespace OpenSim.Region.Framework.Scenes (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0) { + if (GodLevel < 200 && ((!m_scene.Permissions.IsGod(m_uuid) && !m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) || @@ -4029,7 +4030,14 @@ namespace OpenSim.Region.Framework.Scenes { SpawnPoint[] spawnPoints = m_scene.RegionInfo.RegionSettings.SpawnPoints().ToArray(); if (spawnPoints.Length == 0) + { + if(m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) + { + pos.X = 128.0f; + pos.Y = 128.0f; + } return; + } int index; bool selected = false; @@ -4049,7 +4057,8 @@ namespace OpenSim.Region.Framework.Scenes // SpawnPoint sp = spawnPoints[index]; ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y); - if (land == null || land.IsEitherBannedOrRestricted(UUID)) + if (spawnPoints.Length == 0) + return; if (land == null || land.IsEitherBannedOrRestricted(UUID)) selected = false; else selected = true; -- cgit v1.1 From 7524bd5a7ce332a9c63587423c79d6988e4c2896 Mon Sep 17 00:00:00 2001 From: Allen Kerensky Date: Sat, 9 Feb 2013 15:06:42 -0600 Subject: Additional ThreadPool worker and IOCP thread startup logic Signed-off-by: BlueWall --- OpenSim/Region/Application/Application.cs | 45 ++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs index 0f90d37..c3e7ec2 100644 --- a/OpenSim/Region/Application/Application.cs +++ b/OpenSim/Region/Application/Application.cs @@ -102,17 +102,50 @@ namespace OpenSim m_log.InfoFormat( "[OPENSIM MAIN]: Environment variable MONO_THREADS_PER_CPU is {0}", monoThreadsPerCpu ?? "unset"); - // Increase the number of IOCP threads available. Mono defaults to a tragically low number + // Verify the Threadpool allocates or uses enough worker and IO completion threads + // .NET 2.0 workerthreads default to 50 * numcores + // .NET 3.0 workerthreads defaults to 250 * numcores + // .NET 4.0 workerthreads are dynamic based on bitness and OS resources + // Max IO Completion threads are 1000 on all 3 CLRs. + int workerThreadsMin = 500; + int workerThreadsMax = 1000; // may need further adjustment to match other CLR + int iocpThreadsMin = 1000; + int iocpThreadsMax = 2000; // may need further adjustment to match other CLR int workerThreads, iocpThreads; System.Threading.ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads); m_log.InfoFormat("[OPENSIM MAIN]: Runtime gave us {0} worker threads and {1} IOCP threads", workerThreads, iocpThreads); - if (workerThreads < 500 || iocpThreads < 1000) + if (workerThreads < workerThreadsMin) { - workerThreads = 500; - iocpThreads = 1000; - m_log.Info("[OPENSIM MAIN]: Bumping up to 500 worker threads and 1000 IOCP threads"); - System.Threading.ThreadPool.SetMaxThreads(workerThreads, iocpThreads); + workerThreads = workerThreadsMin; + m_log.InfoFormat("[OPENSIM MAIN]: Bumping up to worker threads to {0}",workerThreads); } + if (workerThreads > workerThreadsMax) + { + workerThreads = workerThreadsMax; + m_log.InfoFormat("[OPENSIM MAIN]: Limiting worker threads to {0}",workerThreads); + } + // Increase the number of IOCP threads available. + // Mono defaults to a tragically low number (24 on 6-core / 8GB Fedora 17) + if (iocpThreads < iocpThreadsMin) + { + iocpThreads = iocpThreadsMin; + m_log.InfoFormat("[OPENSIM MAIN]: Bumping up IO completion threads to {0}",iocpThreads); + } + // Make sure we don't overallocate IOCP threads and thrash system resources + if ( iocpThreads > iocpThreadsMax ) + { + iocpThreads = iocpThreadsMax; + m_log.InfoFormat("[OPENSIM MAIN]: Limiting IO completion threads to {0}",iocpThreads); + } + // set the resulting worker and IO completion thread counts back to ThreadPool + if ( System.Threading.ThreadPool.SetMaxThreads(workerThreads, iocpThreads) ) + { + m_log.InfoFormat("[OPENSIM MAIN]: Threadpool set to {0} worker threads and {1} IO completion threads", workerThreads, iocpThreads); + } + else + { + m_log.Info("[OPENSIM MAIN]: Threadpool reconfiguration failed, runtime defaults still in effect."); + } // Check if the system is compatible with OpenSimulator. // Ensures that the minimum system requirements are met -- cgit v1.1 From 6f3dcf58b8f47922b68993cfdd9cdbd5b4ae36d8 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 10 Feb 2013 20:00:39 +0000 Subject: Fix code to check for no spawn points. Possibly a merge artefact? --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 30bd715..70e3952 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -4046,6 +4046,8 @@ namespace OpenSim.Region.Framework.Scenes { case "random": + if (spawnPoints.Length == 0) + return; do { index = Util.RandomClass.Next(spawnPoints.Length - 1); @@ -4057,8 +4059,8 @@ namespace OpenSim.Region.Framework.Scenes // SpawnPoint sp = spawnPoints[index]; ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y); - if (spawnPoints.Length == 0) - return; if (land == null || land.IsEitherBannedOrRestricted(UUID)) + + if (land == null || land.IsEitherBannedOrRestricted(UUID)) selected = false; else selected = true; -- cgit v1.1 From c72c1898644319b3b0ddedc0b0a65f6b8c678db9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 11 Feb 2013 22:16:07 +0000 Subject: Add test to try reading notecard into an invalid path in TestJsonReadNotecard() regression test --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index af97ac7..e91c02d 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -357,8 +357,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests 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("")); @@ -367,27 +366,24 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests } { - // Read notecard to new multi-component path + // Read notecard to new multi-component path. This should not work. 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 + // Read notecard to existing multi-component path. This should work 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("")); @@ -396,6 +392,16 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests } { + // Read notecard to invalid path. This should not work. + UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'make' : { 'it' : 'so' } }"); + UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "/", notecardName); + Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); + + string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); + Assert.That(value, Is.EqualTo("")); + } + + { // Try read notecard to fake store. UUID fakeStoreId = TestHelpers.ParseTail(0x500); UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, fakeStoreId, "", notecardName); -- cgit v1.1 From cbb8d82c7d37019f32c6d8166de53c75c29e27a5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 11 Feb 2013 22:28:50 +0000 Subject: Add section to TestJsonSetValue() to test attempted set of value where the penultimate section of path does not exist --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 31 ++++++++++++++++------ 1 file changed, 23 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index e91c02d..2af3afc 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -244,18 +244,33 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests TestHelpers.InMethod(); // TestHelpers.EnableLogging(); - UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); - int result = (int)InvokeOp("JsonSetValue", storeId, "Fun", "Times"); - Assert.That(result, Is.EqualTo(1)); + int result = (int)InvokeOp("JsonSetValue", storeId, "Fun", "Times"); + Assert.That(result, Is.EqualTo(1)); - string value = (string)InvokeOp("JsonGetValue", storeId, "Fun"); - Assert.That(value, Is.EqualTo("Times")); + string value = (string)InvokeOp("JsonGetValue", storeId, "Fun"); + Assert.That(value, Is.EqualTo("Times")); + } + + // Test setting to location that does not exist. This should fail. + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); + + int result = (int)InvokeOp("JsonSetValue", storeId, "Fun.Circus", "Times"); + Assert.That(result, Is.EqualTo(0)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Circus"); + Assert.That(value, Is.EqualTo("")); + } // Test with fake store - UUID fakeStoreId = TestHelpers.ParseTail(0x500); - int fakeStoreValueSet = (int)InvokeOp("JsonSetValue", fakeStoreId, "Hello", "World"); - Assert.That(fakeStoreValueSet, Is.EqualTo(0)); + { + UUID fakeStoreId = TestHelpers.ParseTail(0x500); + int fakeStoreValueSet = (int)InvokeOp("JsonSetValue", fakeStoreId, "Hello", "World"); + Assert.That(fakeStoreValueSet, Is.EqualTo(0)); + } } /// -- cgit v1.1 From 8fcfd8224165908284b729935a5bf61d07545958 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 11 Feb 2013 22:44:25 +0000 Subject: Extend TestJsonTestPath() for non-terminating section of path (i.e. one that does not point to a value/leaf) --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 28 +++++++++++++++------- 1 file changed, 20 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 2af3afc..98d8ff6 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -224,18 +224,30 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests TestHelpers.InMethod(); // TestHelpers.EnableLogging(); - UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }"); + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }"); - int result = (int)InvokeOp("JsonTestPath", storeId, "Hello"); - Assert.That(result, Is.EqualTo(1)); + { + int result = (int)InvokeOp("JsonTestPath", storeId, "Hello.World"); + Assert.That(result, Is.EqualTo(1)); + } + + // Test for path which does not resolve to a value. + { + int result = (int)InvokeOp("JsonTestPath", storeId, "Hello"); + Assert.That(result, Is.EqualTo(0)); + } - int result2 = (int)InvokeOp("JsonTestPath", storeId, "foo"); - Assert.That(result2, Is.EqualTo(0)); + { + int result2 = (int)InvokeOp("JsonTestPath", storeId, "foo"); + Assert.That(result2, Is.EqualTo(0)); + } // Test with fake store - UUID fakeStoreId = TestHelpers.ParseTail(0x500); - int fakeStoreValueRemove = (int)InvokeOp("JsonTestPath", fakeStoreId, "Hello"); - Assert.That(fakeStoreValueRemove, Is.EqualTo(0)); + { + UUID fakeStoreId = TestHelpers.ParseTail(0x500); + int fakeStoreValueRemove = (int)InvokeOp("JsonTestPath", fakeStoreId, "Hello"); + Assert.That(fakeStoreValueRemove, Is.EqualTo(0)); + } } [Test] -- cgit v1.1 From 9d001e40e79b17a8b5eb4316f1f3525afd1b6b96 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 11 Feb 2013 22:56:43 +0000 Subject: Add section to TestJsonGetValue() to test call on a sub-tree --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 30 +++++++++++++++------- 1 file changed, 21 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 98d8ff6..a2d065c 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -153,19 +153,31 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests TestHelpers.InMethod(); // TestHelpers.EnableLogging(); - UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }"); + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Two' } }"); + + { + string value = (string)InvokeOp("JsonGetValue", storeId, "Hello.World"); + Assert.That(value, Is.EqualTo("Two")); + } - string value = (string)InvokeOp("JsonGetValue", storeId, "Hello"); - Assert.That(value, Is.EqualTo("World")); + // Test get of path section instead of leaf + { + string value = (string)InvokeOp("JsonGetValue", storeId, "Hello"); + Assert.That(value, Is.EqualTo("")); + } // Test get of non-existing value - string fakeValueGet = (string)InvokeOp("JsonGetValue", storeId, "foo"); - Assert.That(fakeValueGet, Is.EqualTo("")); + { + string fakeValueGet = (string)InvokeOp("JsonGetValue", storeId, "foo"); + Assert.That(fakeValueGet, Is.EqualTo("")); + } // Test get from non-existing store - UUID fakeStoreId = TestHelpers.ParseTail(0x500); - string fakeStoreValueGet = (string)InvokeOp("JsonGetValue", fakeStoreId, "Hello"); - Assert.That(fakeStoreValueGet, Is.EqualTo("")); + { + UUID fakeStoreId = TestHelpers.ParseTail(0x500); + string fakeStoreValueGet = (string)InvokeOp("JsonGetValue", fakeStoreId, "Hello"); + Assert.That(fakeStoreValueGet, Is.EqualTo("")); + } } // [Test] @@ -432,7 +444,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests // 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)); + Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); string value = (string)InvokeOp("JsonGetValue", fakeStoreId, "Hello"); Assert.That(value, Is.EqualTo("")); -- cgit v1.1 From 6924bd21f48a4c2540ebd8316e966367157e97c7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 11 Feb 2013 23:10:07 +0000 Subject: Add regression TestJsonTestPathJson() --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index a2d065c..de42e74 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -263,6 +263,38 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests } [Test] + public void TestJsonTestPathJson() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }"); + + { + int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello.World"); + Assert.That(result, Is.EqualTo(1)); + } + + // Test for path which does not resolve to a value. + { + int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello"); + Assert.That(result, Is.EqualTo(1)); + } + + { + int result2 = (int)InvokeOp("JsonTestPathJson", storeId, "foo"); + Assert.That(result2, Is.EqualTo(0)); + } + + // Test with fake store + { + UUID fakeStoreId = TestHelpers.ParseTail(0x500); + int fakeStoreValueRemove = (int)InvokeOp("JsonTestPathJson", fakeStoreId, "Hello"); + Assert.That(fakeStoreValueRemove, Is.EqualTo(0)); + } + } + + [Test] public void TestJsonSetValue() { TestHelpers.InMethod(); -- cgit v1.1 From d55974bcb7e0dc2931c9ca18e4bbe85fb0ef5440 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 11 Feb 2013 23:47:49 +0000 Subject: Add regression TestJsonGetValueJson() --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 33 ++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index de42e74..ddbfa45 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -180,6 +180,39 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests } } + [Test] + public void TestJsonGetValueJson() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Two' } }"); + + { + string value = (string)InvokeOp("JsonGetValueJson", storeId, "Hello.World"); + Assert.That(value, Is.EqualTo("'Two'")); + } + + // Test get of path section instead of leaf + { + string value = (string)InvokeOp("JsonGetValueJson", storeId, "Hello"); + Assert.That(value, Is.EqualTo("{\"World\":\"Two\"}")); + } + + // Test get of non-existing value + { + string fakeValueGet = (string)InvokeOp("JsonGetValueJson", storeId, "foo"); + Assert.That(fakeValueGet, Is.EqualTo("")); + } + + // Test get from non-existing store + { + UUID fakeStoreId = TestHelpers.ParseTail(0x500); + string fakeStoreValueGet = (string)InvokeOp("JsonGetValueJson", fakeStoreId, "Hello"); + Assert.That(fakeStoreValueGet, Is.EqualTo("")); + } + } + // [Test] // public void TestJsonTakeValue() // { -- cgit v1.1 From 586def0bcc3bad5ff1e92ff24bbd41a0d2ab4c52 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 12 Feb 2013 01:27:38 +0000 Subject: Add regression TestJsonSetValueJson() The part to test setting of single leaf-node string tokens is currently commented out. See http://opensimulator.org/mantis/view.php?id=6540 --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 58 ++++++++++++++++++++++ 1 file changed, 58 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index ddbfa45..717484c 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -362,6 +362,64 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests } } + [Test] + public void TestJsonSetValueJson() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + // Single quoted token case +// { +// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); +// +// int result = (int)InvokeOp("JsonSetValueJson", storeId, "Fun", "'Times'"); +// Assert.That(result, Is.EqualTo(1)); +// +// string value = (string)InvokeOp("JsonGetValue", storeId, "Fun"); +// Assert.That(value, Is.EqualTo("Times")); +// } + + // Sub-tree case + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); + + int result = (int)InvokeOp("JsonSetValueJson", storeId, "Fun", "{ 'Filled' : 'Times' }"); + Assert.That(result, Is.EqualTo(1)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Filled"); + Assert.That(value, Is.EqualTo("Times")); + } + + // If setting single strings in JsonSetValueJson, these must be single quoted tokens, not bare strings. + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); + + int result = (int)InvokeOp("JsonSetValueJson", storeId, "Fun", "Times"); + Assert.That(result, Is.EqualTo(0)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "Fun"); + Assert.That(value, Is.EqualTo("")); + } + + // Test setting to location that does not exist. This should fail. + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); + + int result = (int)InvokeOp("JsonSetValueJson", storeId, "Fun.Circus", "'Times'"); + Assert.That(result, Is.EqualTo(0)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Circus"); + Assert.That(value, Is.EqualTo("")); + } + + // Test with fake store + { + UUID fakeStoreId = TestHelpers.ParseTail(0x500); + int fakeStoreValueSet = (int)InvokeOp("JsonSetValueJson", fakeStoreId, "Hello", "'World'"); + Assert.That(fakeStoreValueSet, Is.EqualTo(0)); + } + } + /// /// Test for writing json to a notecard /// -- cgit v1.1 From d3b2cdc2b41833a338101a7f05eaa6f8d4dd5ef1 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Mon, 11 Feb 2013 19:55:10 -0800 Subject: Fix handling of string values in JsonSetValueJson(). There are some oddities with empty strings: the Json serializer treats them as default values and does not return them in serialized hashes. --- .../Scripting/JsonStore/JsonStore.cs | 32 +++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs index 3d715cc..82a4da7 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs @@ -198,7 +198,37 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore // ----------------------------------------------------------------- public bool SetValue(string expr, string value, bool useJson) { - OSD ovalue = useJson ? OSDParser.DeserializeJson(value) : new OSDString(value); + OSD ovalue; + + // One note of caution... if you use an empty string in the + // structure it will be assumed to be a default value and will + // not be seialized in the json + + if (useJson) + { + // There doesn't appear to be a good way to determine if the + // value is valid Json other than to let the parser crash + try + { + ovalue = OSDParser.DeserializeJson(value); + } + catch (Exception e) + { + if (value.StartsWith("'") && value.EndsWith("'")) + { + ovalue = new OSDString(value.Substring(1,value.Length - 2)); + } + else + { + return false; + } + } + } + else + { + ovalue = new OSDString(value); + } + return SetValueFromExpression(expr,ovalue); } -- cgit v1.1 From 4b8c22ecfaf573b26e1b8f65cb8c95c39c3f519b Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Tue, 12 Feb 2013 11:10:17 -0800 Subject: Adds the parameter for OSD serialization to encode default values. This makes the JsonStore get/set operations symmetric. --- .../Region/OptionalModules/Scripting/JsonStore/JsonStore.cs | 11 +++++++---- .../OptionalModules/Scripting/JsonStore/JsonStoreModule.cs | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs index 82a4da7..3bad06c 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs @@ -131,15 +131,18 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore m_TakeStore = new List(); m_ReadStore = new List(); } - + public JsonStore(string value) : this() { + // This is going to throw an exception if the value is not + // a valid JSON chunk. Calling routines should catch the + // exception and handle it appropriately if (String.IsNullOrEmpty(value)) ValueStore = new OSDMap(); else ValueStore = OSDParser.DeserializeJson(value); } - + // ----------------------------------------------------------------- /// /// @@ -574,14 +577,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore // The path pointed to an intermediate hash structure if (result.Type == OSDType.Map) { - value = OSDParser.SerializeJsonString(result as OSDMap); + value = OSDParser.SerializeJsonString(result as OSDMap,true); return true; } // The path pointed to an intermediate hash structure if (result.Type == OSDType.Array) { - value = OSDParser.SerializeJsonString(result as OSDArray); + value = OSDParser.SerializeJsonString(result as OSDArray,true); return true; } diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs index f1ce856..cc13661 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs @@ -227,7 +227,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } catch (Exception e) { - m_log.Error(string.Format("[JsonStore]: Unable to initialize store from {0}", value), e); + m_log.ErrorFormat("[JsonStore]: Unable to initialize store from {0}", value); return false; } -- cgit v1.1 From 058d477ce7cfb9ddc4f5508368141b5d74ba91e3 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 12 Feb 2013 20:51:36 +0000 Subject: Re-enable subtest for single quoted token in TestJsonSetValueJson() This is in response to the resolution of http://opensimulator.org/mantis/view.php?id=6540 --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 717484c..012a528 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -369,15 +369,15 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests // TestHelpers.EnableLogging(); // Single quoted token case -// { -// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); -// -// int result = (int)InvokeOp("JsonSetValueJson", storeId, "Fun", "'Times'"); -// Assert.That(result, Is.EqualTo(1)); -// -// string value = (string)InvokeOp("JsonGetValue", storeId, "Fun"); -// Assert.That(value, Is.EqualTo("Times")); -// } + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); + + int result = (int)InvokeOp("JsonSetValueJson", storeId, "Fun", "'Times'"); + Assert.That(result, Is.EqualTo(1)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "Fun"); + Assert.That(value, Is.EqualTo("Times")); + } // Sub-tree case { -- cgit v1.1 From a82bd5678ec14ea45f7ddcf54e4dd0af43b64c8c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 12 Feb 2013 21:34:12 +0000 Subject: Use an integer when specifying the XWorkItem wait rather than a TimeSpan to avoid a Windows casting issue in SmartThreadPool for large TimeSpans. TimeSpan.Milliseconds is an int64. However, STP casts this to an int (32-bit). If TimeSpan.MaxValue is given then the casting results in an invalid value for the SDK WaitHandle.WaitAll() call. This was causing the co-op script termination regression tests to fail on Windows but not Mono 2.10.8 (which is perhaps not strict in the negative values that it accepts). Solution here is to use the int millisecondsTimeout STP call rather than the TimeSpan one. This also allows us to more clearly specify Timeout.Infinite rather than TimeSpan.MaxValue Thanks to Teravus for this spot. --- OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs | 7 ++++++- OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 4 ++-- OpenSim/Region/ScriptEngine/XEngine/XWorkItem.cs | 6 +++++- 3 files changed, 13 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index f68612c..35ae44c 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs @@ -52,7 +52,12 @@ namespace OpenSim.Region.ScriptEngine.Interfaces { bool Cancel(); void Abort(); - bool Wait(TimeSpan t); + + /// + /// Wait for the work item to complete. + /// + /// The number of milliseconds to wait. Must be >= -1 (Timeout.Infinite). + bool Wait(int t); } /// diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 669cc37..bf19a42 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -595,7 +595,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance if (!m_coopTermination) { // If we're not co-operative terminating then try and wait for the event to complete before stopping - if (workItem.Wait(new TimeSpan((long)timeout * 100000))) + if (workItem.Wait(timeout)) return true; } else @@ -610,7 +610,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance // For now, we will wait forever since the event should always cleanly terminate once LSL loop // checking is implemented. May want to allow a shorter timeout option later. - if (workItem.Wait(TimeSpan.MaxValue)) + if (workItem.Wait(Timeout.Infinite)) { if (DebugLevel >= 1) m_log.DebugFormat( diff --git a/OpenSim/Region/ScriptEngine/XEngine/XWorkItem.cs b/OpenSim/Region/ScriptEngine/XEngine/XWorkItem.cs index 2ac5c31..8dd7677 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XWorkItem.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XWorkItem.cs @@ -57,8 +57,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine wr.Abort(); } - public bool Wait(TimeSpan t) + public bool Wait(int t) { + // We use the integer version of WaitAll because the current version of SmartThreadPool has a bug with the + // TimeSpan version. The number of milliseconds in TimeSpan is an int64 so when STP casts it down to an + // int (32-bit) we can end up with bad values. This occurs on Windows though curious not on Mono 2.10.8 + // (or very likely other versions of Mono at least up until 3.0.3). return SmartThreadPool.WaitAll(new IWorkItemResult[] {wr}, t, false); } } -- cgit v1.1 From 992ef9e971112af34590e971b0ccf5d48db513b2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 12 Feb 2013 23:00:24 +0000 Subject: Extend TestJsonCreateStore() with a one key input and an input with raw number values --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 012a528..eb4bc22 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -115,8 +115,26 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests TestHelpers.InMethod(); // TestHelpers.EnableLogging(); - UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); - Assert.That(storeId, Is.Not.EqualTo(UUID.Zero)); + // Test blank store + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + Assert.That(storeId, Is.Not.EqualTo(UUID.Zero)); + } + + // Test single element store + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }"); + Assert.That(storeId, Is.Not.EqualTo(UUID.Zero)); + } + + // Test with an integer value + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 42.15 }"); + Assert.That(storeId, Is.Not.EqualTo(UUID.Zero)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "Hello"); + Assert.That(value, Is.EqualTo("42.15")); + } } [Test] -- cgit v1.1 From fb903ff49089d5fd7a56aa2401528c3e7cf1800c Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 10 Feb 2013 09:51:34 -0800 Subject: BulletSim: More work on center-of-mass. Remove linksetinfo and rely on simulator to update info. --- .../Region/Physics/BulletSPlugin/BSApiTemplate.cs | 7 +- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 3 + .../Physics/BulletSPlugin/BSLinksetCompound.cs | 150 ++++++++++----------- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 31 +++-- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 4 +- .../Physics/BulletSPlugin/BSPrimDisplaced.cs | 85 ++++++++---- .../Region/Physics/BulletSPlugin/BSPrimLinkable.cs | 4 +- 8 files changed, 162 insertions(+), 124 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index 7ab86d2..3f83ef0 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs @@ -225,9 +225,10 @@ public enum CollisionFlags : uint CF_DISABLE_VISUALIZE_OBJECT = 1 << 5, CF_DISABLE_SPU_COLLISION_PROCESS = 1 << 6, // Following used by BulletSim to control collisions and updates - BS_SUBSCRIBE_COLLISION_EVENTS = 1 << 10, - BS_FLOATS_ON_WATER = 1 << 11, - BS_VEHICLE_COLLISIONS = 1 << 12, + BS_SUBSCRIBE_COLLISION_EVENTS = 1 << 10, // return collision events from unmanaged to managed + BS_FLOATS_ON_WATER = 1 << 11, // the object should float at water level + BS_VEHICLE_COLLISIONS = 1 << 12, // return collisions for vehicle ground checking + BS_RETURN_ROOT_COMPOUND_SHAPE = 1 << 13, // return the pos/rot of the root shape in a compound shape BS_NONE = 0, BS_ALL = 0xFFFFFFFF }; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index f781aea..04fb05b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -274,7 +274,7 @@ public sealed class BSCharacter : BSPhysObject // This test is done if moving forward, not flying and is colliding with something. // DetailLog("{0},BSCharacter.WalkUpStairs,IsColliding={1},flying={2},targSpeed={3},collisions={4}", // LocalID, IsColliding, Flying, TargetSpeed, CollisionsLastTick.Count); - if (IsColliding && !Flying && TargetSpeed > 0.1f /* && ForwardSpeed < 0.1f */) + if (IsColliding && !Flying && TargetVelocitySpeed > 0.1f /* && ForwardSpeed < 0.1f */) { // The range near the character's feet where we will consider stairs float nearFeetHeightMin = RawPosition.Z - (Size.Z / 2f) + 0.05f; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index e35311f..4ece1eb 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -127,6 +127,8 @@ public abstract class BSLinkset m_children = new HashSet(); LinksetMass = parent.RawMass; Rebuilding = false; + + parent.ClearDisplacement(); } // Link to a linkset where the child knows the parent. @@ -280,6 +282,7 @@ public abstract class BSLinkset return mass; } + // Computes linkset's center of mass in world coordinates. protected virtual OMV.Vector3 ComputeLinksetCenterOfMass() { OMV.Vector3 com; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 36bae9b..1f66b56 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -93,7 +93,8 @@ public sealed class BSLinksetCompound : BSLinkset { private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]"; - public BSLinksetCompound(BSScene scene, BSPrimLinkable parent) : base(scene, parent) + public BSLinksetCompound(BSScene scene, BSPrimLinkable parent) + : base(scene, parent) { } @@ -217,59 +218,45 @@ public sealed class BSLinksetCompound : BSLinkset // and that is caused by us updating the object. if ((whichUpdated & ~(UpdatedProperties.Position | UpdatedProperties.Orientation)) == 0) { - // Gather the child info. It might not be there if the linkset is in transition. - BSLinksetCompoundInfo lsi = updated.LinksetInfo as BSLinksetCompoundInfo; - if (lsi != null) - { - // Since the child moved or rotationed, it needs a new relative position within the linkset - BSLinksetCompoundInfo newLsi = new BSLinksetCompoundInfo(lsi.Index, LinksetRoot, updated, OMV.Vector3.Zero); - updated.LinksetInfo = newLsi; - // Find the physical instance of the child - if (LinksetRoot.PhysShape.HasPhysicalShape && PhysicsScene.PE.IsCompound(LinksetRoot.PhysShape)) + if (LinksetRoot.PhysShape.HasPhysicalShape && PhysicsScene.PE.IsCompound(LinksetRoot.PhysShape)) + { + // It is possible that the linkset is still under construction and the child is not yet + // inserted into the compound shape. A rebuild of the linkset in a pre-step action will + // build the whole thing with the new position or rotation. + // The index must be checked because Bullet references the child array but does no validity + // checking of the child index passed. + int numLinksetChildren = PhysicsScene.PE.GetNumberOfCompoundChildren(LinksetRoot.PhysShape); + if (updated.LinksetChildIndex < numLinksetChildren) { - // It is possible that the linkset is still under construction and the child is not yet - // inserted into the compound shape. A rebuild of the linkset in a pre-step action will - // build the whole thing with the new position or rotation. - // The index must be checked because Bullet references the child array but does no validity - // checking of the child index passed. - int numLinksetChildren = PhysicsScene.PE.GetNumberOfCompoundChildren(LinksetRoot.PhysShape); - if (lsi.Index < numLinksetChildren) + BulletShape linksetChildShape = PhysicsScene.PE.GetChildShapeFromCompoundShapeIndex(LinksetRoot.PhysShape, updated.LinksetChildIndex); + if (linksetChildShape.HasPhysicalShape) { - BulletShape linksetChildShape = PhysicsScene.PE.GetChildShapeFromCompoundShapeIndex(LinksetRoot.PhysShape, lsi.Index); - if (linksetChildShape.HasPhysicalShape) - { - // Found the child shape within the compound shape - PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, lsi.Index, - newLsi.OffsetFromCenterOfMass, - newLsi.OffsetRot, - true /* shouldRecalculateLocalAabb */); - updatedChild = true; - DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1},newLsi={2}", - updated.LocalID, whichUpdated, newLsi); - } - else // DEBUG DEBUG - { // DEBUG DEBUG - DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noChildShape,shape={1}", - updated.LocalID, linksetChildShape); - } // DEBUG DEBUG + // Found the child shape within the compound shape + PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, updated.LinksetChildIndex, + updated.RawPosition - LinksetRoot.RawPosition, + updated.RawOrientation * OMV.Quaternion.Inverse(LinksetRoot.RawOrientation), + true /* shouldRecalculateLocalAabb */); + updatedChild = true; + DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1},pos={2},rot={3}", + updated.LocalID, whichUpdated, updated.RawPosition, updated.RawOrientation); } else // DEBUG DEBUG { // DEBUG DEBUG - // the child is not yet in the compound shape. This is non-fatal. - DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,childNotInCompoundShape,numChildren={1},index={2}", - updated.LocalID, numLinksetChildren, lsi.Index); + DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noChildShape,shape={1}", + updated.LocalID, linksetChildShape); } // DEBUG DEBUG } else // DEBUG DEBUG { // DEBUG DEBUG - DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noBodyOrNotCompound", updated.LocalID); + // the child is not yet in the compound shape. This is non-fatal. + DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,childNotInCompoundShape,numChildren={1},index={2}", + updated.LocalID, numLinksetChildren, updated.LinksetChildIndex); } // DEBUG DEBUG } else // DEBUG DEBUG { // DEBUG DEBUG - DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noLinkSetInfo,rootPhysShape={1}", - updated.LocalID, LinksetRoot.PhysShape); + DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noBodyOrNotCompound", updated.LocalID); } // DEBUG DEBUG if (!updatedChild) @@ -379,6 +366,8 @@ public sealed class BSLinksetCompound : BSLinkset // Safe to call even if the child is not really in the linkset. protected override void RemoveChildFromLinkset(BSPrimLinkable child) { + child.ClearDisplacement(); + if (m_children.Remove(child)) { DetailLog("{0},BSLinksetCompound.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}", @@ -410,7 +399,7 @@ public sealed class BSLinksetCompound : BSLinkset // Constraint linksets are rebuilt every time. // Note that this works for rebuilding just the root after a linkset is taken apart. // Called at taint time!! - private bool disableCOM = true; // DEBUG DEBUG: disable until we get this debugged + private bool disableCOM = false; // DEBUG DEBUG: disable until we get this debugged private void RecomputeLinksetCompound() { try @@ -424,30 +413,31 @@ public sealed class BSLinksetCompound : BSLinkset // The center of mass for the linkset is the geometric center of the group. // Compute a displacement for each component so it is relative to the center-of-mass. // Bullet presumes an object's origin (relative <0,0,0>) is its center-of-mass - OMV.Vector3 centerOfMass; - OMV.Vector3 centerDisplacement = OMV.Vector3.Zero; - if (disableCOM) // DEBUG DEBUG - { // DEBUG DEBUG - centerOfMass = LinksetRoot.RawPosition; // DEBUG DEBUG - // LinksetRoot.PositionDisplacement = OMV.Vector3.Zero; - } // DEBUG DEBUG - else + OMV.Vector3 centerOfMassW = LinksetRoot.RawPosition; + if (!disableCOM) // DEBUG DEBUG { - centerOfMass = ComputeLinksetCenterOfMass(); - // 'centerDisplacement' is the value to *add* to all the shape offsets - centerDisplacement = LinksetRoot.RawPosition - centerOfMass; - - // Since we're displacing the center of the shape, we need to move the body in the world - // LinksetRoot.PositionDisplacement = centerDisplacement; - - // This causes the root prim position to be set properly based on the new PositionDisplacement - LinksetRoot.ForcePosition = LinksetRoot.RawPosition; - // Update the local transform for the root child shape so it is offset from the <0,0,0> which is COM - PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, -centerDisplacement, OMV.Quaternion.Identity, false); - DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}", - LinksetRoot.LocalID, centerOfMass, LinksetRoot.RawPosition, centerDisplacement); + // Compute a center-of-mass in world coordinates. + centerOfMassW = ComputeLinksetCenterOfMass(); } + OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); + + // 'centerDisplacement' is the value to subtract from children to give physical offset position + OMV.Vector3 centerDisplacement = (centerOfMassW - LinksetRoot.RawPosition) * invRootOrientation; + LinksetRoot.SetEffectiveCenterOfMassW(centerDisplacement); + + // This causes the physical position of the root prim to be offset to accomodate for the displacements + LinksetRoot.ForcePosition = LinksetRoot.RawPosition; + + // Update the local transform for the root child shape so it is offset from the <0,0,0> which is COM + PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, + -centerDisplacement, + LinksetRoot.RawOrientation, + false /* shouldRecalculateLocalAabb */); + + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}", + LinksetRoot.LocalID, centerOfMassW, LinksetRoot.RawPosition, centerDisplacement); + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); @@ -455,29 +445,20 @@ public sealed class BSLinksetCompound : BSLinkset int memberIndex = 1; ForEachMember(delegate(BSPrimLinkable cPrim) { - if (!IsRoot(cPrim)) + if (IsRoot(cPrim)) { - // Compute the displacement of the child from the root of the linkset. - // This info is saved in the child prim so the relationship does not - // change over time and the new child position can be computed - // when the linkset is being disassembled (the linkset may have moved). - BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; - if (lci == null) - { - lci = new BSLinksetCompoundInfo(memberIndex, LinksetRoot, cPrim, centerDisplacement); - cPrim.LinksetInfo = lci; - DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); - } - - DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},lci={3}", - LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci); + cPrim.LinksetChildIndex = 0; + } + else + { + cPrim.LinksetChildIndex = memberIndex; if (cPrim.PhysShape.isNativeShape) { // A native shape is turned into a hull collision shape because native // shapes are not shared so we have to hullify it so it will be tracked // and freed at the correct time. This also solves the scaling problem - // (native shapes scaled but hull/meshes are assumed to not be). + // (native shapes scale but hull/meshes are assumed to not be). // TODO: decide of the native shape can just be used in the compound shape. // Use call to CreateGeomNonSpecial(). BulletShape saveShape = cPrim.PhysShape; @@ -486,7 +467,10 @@ public sealed class BSLinksetCompound : BSLinkset PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); BulletShape newShape = cPrim.PhysShape; cPrim.PhysShape = saveShape; - PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetFromCenterOfMass, lci.OffsetRot); + + OMV.Vector3 offsetPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation - centerDisplacement; + OMV.Quaternion offsetRot = cPrim.RawOrientation * invRootOrientation; + PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, offsetPos, offsetRot); } else { @@ -498,9 +482,10 @@ public sealed class BSLinksetCompound : BSLinkset PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); } - PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetFromCenterOfMass, lci.OffsetRot); + OMV.Vector3 offsetPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation - centerDisplacement; + OMV.Quaternion offsetRot = cPrim.RawOrientation * invRootOrientation; + PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, offsetPos, offsetRot); } - lci.Index = memberIndex; memberIndex++; } return false; // 'false' says to move onto the next child in the list @@ -509,6 +494,9 @@ public sealed class BSLinksetCompound : BSLinkset // With all of the linkset packed into the root prim, it has the mass of everyone. LinksetMass = ComputeLinksetMass(); LinksetRoot.UpdatePhysicalMassProperties(LinksetMass, true); + + // Enable the physical position updator to return the position and rotation of the root shape + PhysicsScene.PE.AddToCollisionFlags(LinksetRoot.PhysBody, CollisionFlags.BS_RETURN_ROOT_COMPOUND_SHAPE); } finally { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index de69fa0..8ebb532 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -136,6 +136,7 @@ public abstract class BSPhysObject : PhysicsActor // The objects base shape information. Null if not a prim type shape. public PrimitiveBaseShape BaseShape { get; protected set; } + // Some types of objects have preferred physical representations. // Returns SHAPE_UNKNOWN if there is no preference. public virtual BSPhysicsShapeType PreferredPhysicalShape @@ -150,15 +151,17 @@ public abstract class BSPhysObject : PhysicsActor public EntityProperties LastEntityProperties { get; set; } public virtual OMV.Vector3 Scale { get; set; } - public abstract bool IsSolid { get; } - public abstract bool IsStatic { get; } - public abstract bool IsSelected { get; } // It can be confusing for an actor to know if it should move or update an object // depeneding on the setting of 'selected', 'physical, ... // This flag is the true test -- if true, the object is being acted on in the physical world public abstract bool IsPhysicallyActive { get; } + // Detailed state of the object. + public abstract bool IsSolid { get; } + public abstract bool IsStatic { get; } + public abstract bool IsSelected { get; } + // Materialness public MaterialAttributes.Material Material { get; private set; } public override void SetMaterial(int material) @@ -185,14 +188,6 @@ public abstract class BSPhysObject : PhysicsActor public abstract OMV.Quaternion RawOrientation { get; set; } public abstract OMV.Quaternion ForceOrientation { get; set; } - public virtual float TargetSpeed - { - get - { - OMV.Vector3 characterOrientedVelocity = TargetVelocity * OMV.Quaternion.Inverse(OMV.Quaternion.Normalize(RawOrientation)); - return characterOrientedVelocity.X; - } - } public abstract OMV.Vector3 RawVelocity { get; set; } public abstract OMV.Vector3 ForceVelocity { get; set; } @@ -202,6 +197,7 @@ public abstract class BSPhysObject : PhysicsActor public virtual bool ForceBodyShapeRebuild(bool inTaintTime) { return false; } + // The current velocity forward public virtual float ForwardSpeed { get @@ -210,6 +206,19 @@ public abstract class BSPhysObject : PhysicsActor return characterOrientedVelocity.X; } } + // The forward speed we are trying to achieve (TargetVelocity) + public virtual float TargetVelocitySpeed + { + get + { + OMV.Vector3 characterOrientedVelocity = TargetVelocity * OMV.Quaternion.Inverse(OMV.Quaternion.Normalize(RawOrientation)); + return characterOrientedVelocity.X; + } + } + + // The user can optionally set the center of mass. The user's setting will override any + // computed center-of-mass (like in linksets). + public OMV.Vector3? UserSetCenterOfMass { get; set; } #region Collisions diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index cf7aa0f..a76f8b9 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -442,7 +442,7 @@ public class BSPrim : BSPhysObject RegisterPreStepAction("BSPrim.setForce", LocalID, delegate(float timeStep) { - if (!IsPhysicallyActive) + if (!IsPhysicallyActive || _force == OMV.Vector3.Zero) { UnRegisterPreStepAction("BSPrim.setForce", LocalID); return; @@ -647,7 +647,7 @@ public class BSPrim : BSPhysObject RegisterPreStepAction("BSPrim.setTorque", LocalID, delegate(float timeStep) { - if (!IsPhysicallyActive) + if (!IsPhysicallyActive || _torque == OMV.Vector3.Zero) { UnRegisterPreStepAction("BSPrim.setTorque", LocalID); return; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs index 6401308..b9f2cca 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs @@ -44,72 +44,107 @@ namespace OpenSim.Region.Physics.BulletSPlugin { public class BSPrimDisplaced : BSPrim { - // 'Position' and 'Orientation' is what the simulator thinks the positions of the prim is. - // Because Bullet needs the zero coordinate to be the center of mass of the linkset, - // sometimes it is necessary to displace the position the physics engine thinks - // the position is. PositionDisplacement must be added and removed from the - // position as the simulator position is stored and fetched from the physics - // engine. Similar to OrientationDisplacement. + // The purpose of this module is to do any mapping between what the simulator thinks + // the prim position and orientation is and what the physical position/orientation. + // This difference happens because Bullet assumes the center-of-mass is the <0,0,0> + // of the prim/linkset. The simulator tracks the location of the prim/linkset by + // the location of the root prim. So, if center-of-mass is anywhere but the origin + // of the root prim, the physical origin is displaced from the simulator origin. + // + // This routine works by capturing the Force* setting of position/orientation/... and + // adjusting the simulator values (being set) into the physical values. + // The conversion is also done in the opposite direction (physical origin -> simulator origin). + // + // The updateParameter call is also captured and the values from the physics engine + // are converted into simulator origin values before being passed to the base + // class. + public virtual OMV.Vector3 PositionDisplacement { get; set; } public virtual OMV.Quaternion OrientationDisplacement { get; set; } - public virtual OMV.Vector3 CenterOfMassLocation { get; set; } - public virtual OMV.Vector3 GeometricCenterLocation { get; set; } public BSPrimDisplaced(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) : base(localID, primName, parent_scene, pos, size, rotation, pbs, pisPhysical) { - CenterOfMassLocation = RawPosition; - GeometricCenterLocation = RawPosition; + ClearDisplacement(); } - public override Vector3 ForcePosition + public void ClearDisplacement() + { + PositionDisplacement = OMV.Vector3.Zero; + OrientationDisplacement = OMV.Quaternion.Identity; + } + + // Set this sets and computes the displacement from the passed prim to the center-of-mass. + // A user set value for center-of-mass overrides whatever might be passed in here. + // The displacement is in local coordinates (relative to root prim in linkset oriented coordinates). + public virtual void SetEffectiveCenterOfMassW(Vector3 centerOfMassDisplacement) { - get + Vector3 comDisp; + if (UserSetCenterOfMass.HasValue) + comDisp = (OMV.Vector3)UserSetCenterOfMass; + else + comDisp = centerOfMassDisplacement; + + if (comDisp == Vector3.Zero) { - return base.ForcePosition; + // If there is no diplacement. Things get reset. + PositionDisplacement = OMV.Vector3.Zero; + OrientationDisplacement = OMV.Quaternion.Identity; } - set + else { - base.ForcePosition = value; - CenterOfMassLocation = RawPosition; - GeometricCenterLocation = RawPosition; + // Remember the displacement from root as well as the origional rotation of the + // new center-of-mass. + PositionDisplacement = comDisp; + OrientationDisplacement = OMV.Quaternion.Identity; } } - public override Quaternion ForceOrientation + public override Vector3 ForcePosition { - get + get { return base.ForcePosition; } + set { - return base.ForceOrientation; + if (PositionDisplacement != OMV.Vector3.Zero) + base.ForcePosition = value - (PositionDisplacement * RawOrientation); + else + base.ForcePosition = value; } + } + + public override Quaternion ForceOrientation + { + get { return base.ForceOrientation; } set { base.ForceOrientation = value; } } + // TODO: decide if this is the right place for these variables. + // Somehow incorporate the optional settability by the user. // Is this used? public override OMV.Vector3 CenterOfMass { - get { return CenterOfMassLocation; } + get { return RawPosition; } } // Is this used? public override OMV.Vector3 GeometricCenter { - get { return GeometricCenterLocation; } + get { return RawPosition; } } - public override void UpdateProperties(EntityProperties entprop) { // Undo any center-of-mass displacement that might have been done. - if (PositionDisplacement != OMV.Vector3.Zero) + if (PositionDisplacement != OMV.Vector3.Zero || OrientationDisplacement != OMV.Quaternion.Identity) { // Correct for any rotation around the center-of-mass // TODO!!! - entprop.Position -= PositionDisplacement; + entprop.Position = entprop.Position + (PositionDisplacement * entprop.Rotation); + entprop.Rotation = something; } base.UpdateProperties(entprop); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs index 9898562..96f9762 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs @@ -38,6 +38,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin public class BSPrimLinkable : BSPrimDisplaced { public BSLinkset Linkset { get; set; } + // The index of this child prim. + public int LinksetChildIndex { get; set; } + public BSLinksetInfo LinksetInfo { get; set; } public BSPrimLinkable(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, @@ -90,7 +93,6 @@ public class BSPrimLinkable : BSPrimDisplaced DetailLog("{0},BSPrimLinkset.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ", LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren); return; - base.delink(); } // When simulator changes position, this might be moving a child of the linkset. -- cgit v1.1 From 0194a3d890b95c8a29fcdf130c378e3a8a629c77 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 12 Feb 2013 15:45:44 -0800 Subject: BulletSim: fix density since the simulator/viewer track density in a funny unit that is 100 times real density (default 1000). Fix avatar drifting slowly when stationary flying. Fix for physical prims getting corrected for being under terrain when it was just its geometric center that was below terrain. Add PreUpdatePropertyAction allowing plugable modifiction of phys parameters returned from Bullet. Fix an exception setting GravityMultiplier on initialization. Update DLLs and SOs for good measure (no functional change). --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 13 ++++- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 19 ++++--- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 17 ++++-- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 66 ++++++++++++++++++++-- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 55 +++++++++++++++++- .../Physics/BulletSPlugin/BSPrimDisplaced.cs | 2 +- .../Region/Physics/BulletSPlugin/BSPrimLinkable.cs | 3 +- 7 files changed, 150 insertions(+), 25 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 04fb05b..8dca7c6 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -83,7 +83,7 @@ public sealed class BSCharacter : BSPhysObject _velocity = OMV.Vector3.Zero; _buoyancy = ComputeBuoyancyFromFlying(isFlying); Friction = BSParam.AvatarStandingFriction; - Density = BSParam.AvatarDensity; + Density = BSParam.AvatarDensity / BSParam.DensityScaleFactor; // Old versions of ScenePresence passed only the height. If width and/or depth are zero, // replace with the default values. @@ -231,6 +231,15 @@ public sealed class BSCharacter : BSPhysObject PhysicsScene.PE.SetFriction(PhysBody, Friction); } } + else + { + if (Flying) + { + // Flying and not collising and velocity nearly zero. + ZeroMotion(true /* inTaintTime */); + } + } + DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1},colliding={2}", LocalID, _velocityMotor.TargetValue, IsColliding); } else @@ -869,7 +878,7 @@ public sealed class BSCharacter : BSPhysObject * Math.Min(Size.X, Size.Y) / 2 * Size.Y / 2f // plus the volume of the capsule end caps ); - _mass = Density * _avatarVolume; + _mass = Density * BSParam.DensityScaleFactor * _avatarVolume; } // The physics engine says that properties have updated. Update same and inform diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 1f66b56..4ce58c7 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -399,7 +399,7 @@ public sealed class BSLinksetCompound : BSLinkset // Constraint linksets are rebuilt every time. // Note that this works for rebuilding just the root after a linkset is taken apart. // Called at taint time!! - private bool disableCOM = false; // DEBUG DEBUG: disable until we get this debugged + private bool disableCOM = true; // DEBUG DEBUG: disable until we get this debugged private void RecomputeLinksetCompound() { try @@ -430,10 +430,10 @@ public sealed class BSLinksetCompound : BSLinkset LinksetRoot.ForcePosition = LinksetRoot.RawPosition; // Update the local transform for the root child shape so it is offset from the <0,0,0> which is COM - PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, - -centerDisplacement, - LinksetRoot.RawOrientation, - false /* shouldRecalculateLocalAabb */); + PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0 /* childIndex */, + -centerDisplacement, + OMV.Quaternion.Identity, // LinksetRoot.RawOrientation, + false /* shouldRecalculateLocalAabb (is done later after linkset built) */); DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}", LinksetRoot.LocalID, centerOfMassW, LinksetRoot.RawPosition, centerDisplacement); @@ -463,7 +463,6 @@ public sealed class BSLinksetCompound : BSLinkset // Use call to CreateGeomNonSpecial(). BulletShape saveShape = cPrim.PhysShape; cPrim.PhysShape.Clear(); // Don't let the create free the child's shape - // PhysicsScene.Shapes.CreateGeomNonSpecial(true, cPrim, null); PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); BulletShape newShape = cPrim.PhysShape; cPrim.PhysShape = saveShape; @@ -471,6 +470,8 @@ public sealed class BSLinksetCompound : BSLinkset OMV.Vector3 offsetPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation - centerDisplacement; OMV.Quaternion offsetRot = cPrim.RawOrientation * invRootOrientation; PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, offsetPos, offsetRot); + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addNative,indx={1},rShape={2},cShape={3},offPos={4},offRot={5}", + LinksetRoot.LocalID, memberIndex, LinksetRoot.PhysShape, newShape, offsetPos, offsetRot); } else { @@ -484,7 +485,10 @@ public sealed class BSLinksetCompound : BSLinkset } OMV.Vector3 offsetPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation - centerDisplacement; OMV.Quaternion offsetRot = cPrim.RawOrientation * invRootOrientation; - PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, offsetPos, offsetRot); + PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, offsetPos, offsetRot); + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addNonNative,indx={1},rShape={2},cShape={3},offPos={4},offRot={5}", + LinksetRoot.LocalID, memberIndex, LinksetRoot.PhysShape, cPrim.PhysShape, offsetPos, offsetRot); + } memberIndex++; } @@ -503,6 +507,7 @@ public sealed class BSLinksetCompound : BSLinkset Rebuilding = false; } + // See that the Aabb surrounds the new shape PhysicsScene.PE.RecalculateCompoundShapeLocalAabb(LinksetRoot.PhysShape); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 3e0b4bc..329169f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -49,6 +49,7 @@ public static class BSParam public static float MaxLinearVelocity { get; private set; } public static float MaxAngularVelocity { get; private set; } public static float MaxAddForceMagnitude { get; private set; } + public static float DensityScaleFactor { get; private set; } public static float LinearDamping { get; private set; } public static float AngularDamping { get; private set; } @@ -281,29 +282,35 @@ public static class BSParam new ParameterDefn("MinObjectMass", "Minimum object mass (0.0001)", 0.0001f, (s,cf,p,v) => { MinimumObjectMass = cf.GetFloat(p, v); }, - (s) => { return (float)MinimumObjectMass; }, + (s) => { return MinimumObjectMass; }, (s,p,l,v) => { MinimumObjectMass = v; } ), new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)", 10000.01f, (s,cf,p,v) => { MaximumObjectMass = cf.GetFloat(p, v); }, - (s) => { return (float)MaximumObjectMass; }, + (s) => { return MaximumObjectMass; }, (s,p,l,v) => { MaximumObjectMass = v; } ), new ParameterDefn("MaxLinearVelocity", "Maximum velocity magnitude that can be assigned to an object", 1000.0f, (s,cf,p,v) => { MaxLinearVelocity = cf.GetFloat(p, v); }, - (s) => { return (float)MaxLinearVelocity; }, + (s) => { return MaxLinearVelocity; }, (s,p,l,v) => { MaxLinearVelocity = v; } ), new ParameterDefn("MaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to an object", 1000.0f, (s,cf,p,v) => { MaxAngularVelocity = cf.GetFloat(p, v); }, - (s) => { return (float)MaxAngularVelocity; }, + (s) => { return MaxAngularVelocity; }, (s,p,l,v) => { MaxAngularVelocity = v; } ), // LL documentation says thie number should be 20f for llApplyImpulse and 200f for llRezObject new ParameterDefn("MaxAddForceMagnitude", "Maximum force that can be applied by llApplyImpulse (SL says 20f)", 20000.0f, (s,cf,p,v) => { MaxAddForceMagnitude = cf.GetFloat(p, v); }, - (s) => { return (float)MaxAddForceMagnitude; }, + (s) => { return MaxAddForceMagnitude; }, (s,p,l,v) => { MaxAddForceMagnitude = v; } ), + // Density is passed around as 100kg/m3. This scales that to 1kg/m3. + new ParameterDefn("DensityScaleFactor", "Conversion for simulator/viewer density (100kg/m3) to physical density (1kg/m3)", + 0.01f, + (s,cf,p,v) => { DensityScaleFactor = cf.GetFloat(p, v); }, + (s) => { return DensityScaleFactor; }, + (s,p,l,v) => { DensityScaleFactor = v; } ), new ParameterDefn("PID_D", "Derivitive factor for motion smoothing", 2200f, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 8ebb532..f953c1e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -99,6 +99,9 @@ public abstract class BSPhysObject : PhysicsActor CollisionAccumulation = 0; ColliderIsMoving = false; CollisionScore = 0; + + // All axis free. + LockedAxis = LockedAxisFree; } // Tell the object to clean up. @@ -172,7 +175,8 @@ public abstract class BSPhysObject : PhysicsActor MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false); Friction = matAttrib.friction; Restitution = matAttrib.restitution; - Density = matAttrib.density; + Density = matAttrib.density / BSParam.DensityScaleFactor; + DetailLog("{0},{1}.SetMaterial,Mat={2},frict={3},rest={4},den={5}", LocalID, TypeName, Material, Friction, Restitution, Density); } // Stop all physical motion. @@ -220,6 +224,9 @@ public abstract class BSPhysObject : PhysicsActor // computed center-of-mass (like in linksets). public OMV.Vector3? UserSetCenterOfMass { get; set; } + public OMV.Vector3 LockedAxis { get; set; } // zero means locked. one means free. + public readonly OMV.Vector3 LockedAxisFree = new OMV.Vector3(1f, 1f, 1f); // All axis are free + #region Collisions // Requested number of milliseconds between collision events. Zero means disabled. @@ -416,9 +423,7 @@ public abstract class BSPhysObject : PhysicsActor { // Clean out any existing action UnRegisterPreStepAction(op, id); - RegisteredPrestepActions[identifier] = actn; - PhysicsScene.BeforeStep += actn; } DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier); @@ -464,9 +469,7 @@ public abstract class BSPhysObject : PhysicsActor { // Clean out any existing action UnRegisterPostStepAction(op, id); - RegisteredPoststepActions[identifier] = actn; - PhysicsScene.AfterStep += actn; } DetailLog("{0},BSPhysObject.RegisterPostStepAction,id={1}", LocalID, identifier); @@ -503,7 +506,58 @@ public abstract class BSPhysObject : PhysicsActor } DetailLog("{0},BSPhysObject.UnRegisterAllPostStepActions,", LocalID); } - + + // When an update to the physical properties happens, this event is fired to let + // different actors to modify the update before it is passed around + public delegate void PreUpdatePropertyAction(ref EntityProperties entprop); + public event PreUpdatePropertyAction OnPreUpdateProperty; + protected void TriggerPreUpdatePropertyAction(ref EntityProperties entprop) + { + PreUpdatePropertyAction actions = OnPreUpdateProperty; + if (actions != null) + actions(ref entprop); + } + + private Dictionary RegisteredPreUpdatePropertyActions = new Dictionary(); + public void RegisterPreUpdatePropertyAction(string identifier, PreUpdatePropertyAction actn) + { + lock (RegisteredPreUpdatePropertyActions) + { + // Clean out any existing action + UnRegisterPreUpdatePropertyAction(identifier); + RegisteredPreUpdatePropertyActions[identifier] = actn; + OnPreUpdateProperty += actn; + } + DetailLog("{0},BSPhysObject.RegisterPreUpdatePropertyAction,id={1}", LocalID, identifier); + } + public bool UnRegisterPreUpdatePropertyAction(string identifier) + { + bool removed = false; + lock (RegisteredPreUpdatePropertyActions) + { + if (RegisteredPreUpdatePropertyActions.ContainsKey(identifier)) + { + OnPreUpdateProperty -= RegisteredPreUpdatePropertyActions[identifier]; + RegisteredPreUpdatePropertyActions.Remove(identifier); + removed = true; + } + } + DetailLog("{0},BSPhysObject.UnRegisterPreUpdatePropertyAction,id={1},removed={2}", LocalID, identifier, removed); + return removed; + } + public void UnRegisterAllPreUpdatePropertyActions() + { + lock (RegisteredPreUpdatePropertyActions) + { + foreach (KeyValuePair kvp in RegisteredPreUpdatePropertyActions) + { + OnPreUpdateProperty -= kvp.Value; + } + RegisteredPreUpdatePropertyActions.Clear(); + } + DetailLog("{0},BSPhysObject.UnRegisterAllPreUpdatePropertyAction,", LocalID); + } + #endregion // Per Simulation Step actions // High performance detailed logging routine used by the physical objects. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index a76f8b9..0323b0d 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -242,6 +242,45 @@ public class BSPrim : BSPhysObject public override void LockAngularMotion(OMV.Vector3 axis) { DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis); + + OMV.Vector3 locking = new OMV.Vector3(1f, 1f, 1f); + if (axis.X != 1) locking.X = 0f; + if (axis.Y != 1) locking.Y = 0f; + if (axis.Z != 1) locking.Z = 0f; + LockedAxis = locking; + + /* Not implemented yet + if (LockedAxis != LockedAxisFree) + { + // Something is locked so start the thingy that keeps that axis from changing + RegisterPreUpdatePropertyAction("BSPrim.LockAngularMotion", delegate(ref EntityProperties entprop) + { + if (LockedAxis != LockedAxisFree) + { + if (IsPhysicallyActive) + { + // Bullet can lock axis but it only works for global axis. + // Check if this prim is aligned on global axis and use Bullet's + // system if so. + + ForceOrientation = entprop.Rotation; + ForceRotationalVelocity = entprop.RotationalVelocity; + } + } + else + { + UnRegisterPreUpdatePropertyAction("BSPrim.LockAngularMotion"); + } + + }); + } + else + { + // Everything seems unlocked + UnRegisterPreUpdatePropertyAction("BSPrim.LockAngularMotion"); + } + */ + return; } @@ -311,7 +350,8 @@ public class BSPrim : BSPhysObject float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition); OMV.Vector3 upForce = OMV.Vector3.Zero; - if (RawPosition.Z < terrainHeight) + float approxSize = Math.Max(Size.X, Math.Max(Size.Y, Size.Z)); + if ((RawPosition.Z + approxSize / 2f) < terrainHeight) { DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, RawPosition, terrainHeight); float targetHeight = terrainHeight + (Size.Z / 2f); @@ -576,6 +616,8 @@ public class BSPrim : BSPhysObject } } } + // The simulator/viewer keep density as 100kg/m3. + // Remember to use BSParam.DensityScaleFactor to create the physical density. public override float Density { get { return base.Density; } @@ -1569,7 +1611,8 @@ public class BSPrim : BSPhysObject profileEnd = 1.0f - (float)BaseShape.ProfileEnd * 2.0e-5f; volume *= (profileEnd - profileBegin); - returnMass = Density * volume; + returnMass = Density * BSParam.DensityScaleFactor * volume; + DetailLog("{0},BSPrim.CalculateMass,den={1},vol={2},mass={3}", LocalID, Density, volume, returnMass); returnMass = Util.Clamp(returnMass, BSParam.MinimumObjectMass, BSParam.MaximumObjectMass); @@ -1607,6 +1650,8 @@ public class BSPrim : BSPhysObject // the world that things have changed. public override void UpdateProperties(EntityProperties entprop) { + TriggerPreUpdatePropertyAction(ref entprop); + // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet // TODO: handle physics introduced by Bullet with computed vehicle physics. if (VehicleController.IsActive) @@ -1619,7 +1664,11 @@ public class BSPrim : BSPhysObject // Assign directly to the local variables so the normal set actions do not happen _position = entprop.Position; _orientation = entprop.Rotation; - _velocity = entprop.Velocity; + // _velocity = entprop.Velocity; + // DEBUG DEBUG DEBUG -- smooth velocity changes a bit. The simulator seems to be + // very sensitive to velocity changes. + if (!entprop.Velocity.ApproxEquals(_velocity, 0.1f)) + _velocity = entprop.Velocity; _acceleration = entprop.Acceleration; _rotationalVelocity = entprop.RotationalVelocity; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs index b9f2cca..f1c3b5c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs @@ -144,7 +144,7 @@ public class BSPrimDisplaced : BSPrim // Correct for any rotation around the center-of-mass // TODO!!! entprop.Position = entprop.Position + (PositionDisplacement * entprop.Rotation); - entprop.Rotation = something; + // entprop.Rotation = something; } base.UpdateProperties(entprop); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs index 96f9762..d65d407 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs @@ -135,7 +135,8 @@ public class BSPrimLinkable : BSPrimDisplaced // When going from non-physical to physical, this re-enables the constraints that // had been automatically disabled when the mass was set to zero. // For compound based linksets, this enables and disables interactions of the children. - Linkset.Refresh(this); + if (Linkset != null) // null can happen during initialization + Linkset.Refresh(this); } protected override void MakeDynamic(bool makeStatic) -- cgit v1.1 From 4b797f2ead3052ca24ff36948f4bfb4e28bbb638 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 13 Feb 2013 00:12:20 +0000 Subject: Extend TestJsonRemoveValue() with tests for non-penultimate nodes and arrays --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 70 ++++++++++++++++++---- 1 file changed, 57 insertions(+), 13 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index eb4bc22..bba727d 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -260,25 +260,69 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests TestHelpers.InMethod(); // TestHelpers.EnableLogging(); - UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }"); + // Test remove of node in object pointing to a string + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }"); + + int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello"); + Assert.That(returnValue, Is.EqualTo(1)); + + int result = (int)InvokeOp("JsonTestPath", storeId, "Hello"); + Assert.That(result, Is.EqualTo(0)); + + string returnValue2 = (string)InvokeOp("JsonGetValue", storeId, "Hello"); + Assert.That(returnValue2, Is.EqualTo("")); + } + + // Test remove of node in object pointing to another object + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Wally' } }"); + + int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello"); + Assert.That(returnValue, Is.EqualTo(1)); + + int result = (int)InvokeOp("JsonTestPath", storeId, "Hello"); + Assert.That(result, Is.EqualTo(0)); - int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello"); - Assert.That(returnValue, Is.EqualTo(1)); + string returnValue2 = (string)InvokeOp("JsonGetValueJson", storeId, "Hello"); + Assert.That(returnValue2, Is.EqualTo("")); + } - int result = (int)InvokeOp("JsonTestPath", storeId, "Hello"); - Assert.That(result, Is.EqualTo(0)); + // Test remove of node in an array + { + UUID storeId + = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : [ 'value1', 'value2' ] }"); - string returnValue2 = (string)InvokeOp("JsonGetValue", storeId, "Hello"); - Assert.That(returnValue2, Is.EqualTo("")); + int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello[0]"); + Assert.That(returnValue, Is.EqualTo(1)); + + int result = (int)InvokeOp("JsonTestPath", storeId, "Hello[0]"); + Assert.That(result, Is.EqualTo(1)); + + result = (int)InvokeOp("JsonTestPath", storeId, "Hello[1]"); + Assert.That(result, Is.EqualTo(0)); + + string stringReturnValue = (string)InvokeOp("JsonGetValue", storeId, "Hello[0]"); + Assert.That(stringReturnValue, Is.EqualTo("value2")); + + stringReturnValue = (string)InvokeOp("JsonGetValueJson", storeId, "Hello[1]"); + Assert.That(stringReturnValue, Is.EqualTo("")); + } // Test remove of non-existing value - int fakeValueRemove = (int)InvokeOp("JsonRemoveValue", storeId, "Hello"); - Assert.That(fakeValueRemove, Is.EqualTo(0)); + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }"); - // Test get from non-existing store - UUID fakeStoreId = TestHelpers.ParseTail(0x500); - int fakeStoreValueRemove = (int)InvokeOp("JsonRemoveValue", fakeStoreId, "Hello"); - Assert.That(fakeStoreValueRemove, Is.EqualTo(0)); + int fakeValueRemove = (int)InvokeOp("JsonRemoveValue", storeId, "Cheese"); + Assert.That(fakeValueRemove, Is.EqualTo(0)); + } + + { + // Test get from non-existing store + UUID fakeStoreId = TestHelpers.ParseTail(0x500); + int fakeStoreValueRemove = (int)InvokeOp("JsonRemoveValue", fakeStoreId, "Hello"); + Assert.That(fakeStoreValueRemove, Is.EqualTo(0)); + } } [Test] -- cgit v1.1 From 70e641c70828bc0b726e4962a40efc90c54a5420 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 13 Feb 2013 00:51:45 +0000 Subject: Add test for array as root element in TestJsonCreateStore() --- .../Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index bba727d..9721b8d 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -135,6 +135,15 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests string value = (string)InvokeOp("JsonGetValue", storeId, "Hello"); Assert.That(value, Is.EqualTo("42.15")); } + + // Test with an array as the root node + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "[ 'one', 'two', 'three' ]"); + Assert.That(storeId, Is.Not.EqualTo(UUID.Zero)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "[1]"); + Assert.That(value, Is.EqualTo("two")); + } } [Test] -- cgit v1.1 From b1a165a39ad5aef2b55e367aa7ff984374016ba7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 13 Feb 2013 01:25:30 +0000 Subject: Extend JsonTestSetValue() with tests for escaping brackets, periods and unbalanced braces from paths The sub-tests that are commented out are currently those which fail unexpectedly based on my understanding of the path syntax --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 73 +++++++++++++++++++++- 1 file changed, 71 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 9721b8d..71983b3 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -405,7 +405,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests // TestHelpers.EnableLogging(); { - UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); int result = (int)InvokeOp("JsonSetValue", storeId, "Fun", "Times"); Assert.That(result, Is.EqualTo(1)); @@ -414,9 +414,78 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests Assert.That(value, Is.EqualTo("Times")); } + // Commented out as this currently unexpectedly fails. + // Test setting a key containing periods. +// { +// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); +// +// int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun.Circus}", "Times"); +// Assert.That(result, Is.EqualTo(1)); +// +// string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun.Circus}"); +// Assert.That(value, Is.EqualTo("Times")); +// } + + // Test setting a key containing empty brackets + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + + int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[]Circus}", "Times"); + Assert.That(result, Is.EqualTo(1)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[]Circus}"); + Assert.That(value, Is.EqualTo("Times")); + } + + // Commented out as this currently unexpectedly fails. +// // Test setting a key containing brackets with an integer +// { +// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); +// +// int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[0]Circus}", "Times"); +// Assert.That(result, Is.EqualTo(1)); +// +// string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[]Circus}"); +// Assert.That(value, Is.EqualTo("Times")); +// } + + // Commented out as this currently unexpectedly fails. +// // Test setting a key containing unbalanced } +// { +// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); +// +// int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun}Circus}", "Times"); +// Assert.That(result, Is.EqualTo(1)); +// +// string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun}Circus}"); +// Assert.That(value, Is.EqualTo("Times")); +// } + + // Test setting a key containing unbalanced { + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + + int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun{Circus}", "Times"); + Assert.That(result, Is.EqualTo(1)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun{Circus}"); + Assert.That(value, Is.EqualTo("Times")); + } + + // Test setting a key containing balanced {}. This should fail. + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + + int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun{Filled}Circus}", "Times"); + Assert.That(result, Is.EqualTo(0)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun{Filled}Circus}"); + Assert.That(value, Is.EqualTo("")); + } + // Test setting to location that does not exist. This should fail. { - UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); int result = (int)InvokeOp("JsonSetValue", storeId, "Fun.Circus", "Times"); Assert.That(result, Is.EqualTo(0)); -- cgit v1.1 From 5557b523fdae64e0017cbf5285331f71fe046961 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 13 Feb 2013 01:38:33 +0000 Subject: Add more sub-tests to TestJsonSetValue for paths containing []{} without {} delineation. As expected, values are not set and the set call returns FALSE (0). As a reminder, these tests are not currently running on jenkins continuous integration as the functionality is only available on .net 4 (mono 2.8 and later). --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 91 ++++++++++++++++++++-- 1 file changed, 86 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 71983b3..f25f290 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -415,7 +415,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests } // Commented out as this currently unexpectedly fails. - // Test setting a key containing periods. + // Test setting a key containing periods with delineation // { // UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); // @@ -426,7 +426,64 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests // Assert.That(value, Is.EqualTo("Times")); // } - // Test setting a key containing empty brackets + // *** Test [] *** + + // Test setting a key containing unbalanced ] without delineation. Expecting failure + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + + int result = (int)InvokeOp("JsonSetValue", storeId, "Fun]Circus", "Times"); + Assert.That(result, Is.EqualTo(0)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "Fun]Circus"); + Assert.That(value, Is.EqualTo("")); + } + + // Test setting a key containing unbalanced [ without delineation. Expecting failure + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + + int result = (int)InvokeOp("JsonSetValue", storeId, "Fun[Circus", "Times"); + Assert.That(result, Is.EqualTo(0)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "Fun[Circus"); + Assert.That(value, Is.EqualTo("")); + } + + // Test setting a key containing unbalanced [] without delineation. Expecting failure + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + + int result = (int)InvokeOp("JsonSetValue", storeId, "Fun[]Circus", "Times"); + Assert.That(result, Is.EqualTo(0)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "Fun[]Circus"); + Assert.That(value, Is.EqualTo("")); + } + + // Test setting a key containing unbalanced ] with delineation + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + + int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun]Circus}", "Times"); + Assert.That(result, Is.EqualTo(1)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun]Circus}"); + Assert.That(value, Is.EqualTo("Times")); + } + + // Test setting a key containing unbalanced [ with delineation + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + + int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[Circus}", "Times"); + Assert.That(result, Is.EqualTo(1)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[Circus}"); + Assert.That(value, Is.EqualTo("Times")); + } + + // Test setting a key containing empty balanced [] with delineation { UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); @@ -438,7 +495,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests } // Commented out as this currently unexpectedly fails. -// // Test setting a key containing brackets with an integer +// // Test setting a key containing brackets around an integer with delineation // { // UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); // @@ -449,6 +506,30 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests // Assert.That(value, Is.EqualTo("Times")); // } + // *** Test {} *** + + // Test setting a key containing unbalanced } without delineation. Expecting failure (?) + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + + int result = (int)InvokeOp("JsonSetValue", storeId, "Fun}Circus", "Times"); + Assert.That(result, Is.EqualTo(0)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "Fun}Circus"); + Assert.That(value, Is.EqualTo("")); + } + + // Test setting a key containing unbalanced { without delineation. Expecting failure (?) + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + + int result = (int)InvokeOp("JsonSetValue", storeId, "Fun{Circus", "Times"); + Assert.That(result, Is.EqualTo(0)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "Fun}Circus"); + Assert.That(value, Is.EqualTo("")); + } + // Commented out as this currently unexpectedly fails. // // Test setting a key containing unbalanced } // { @@ -461,7 +542,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests // Assert.That(value, Is.EqualTo("Times")); // } - // Test setting a key containing unbalanced { + // Test setting a key containing unbalanced { with delineation { UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); @@ -472,7 +553,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests Assert.That(value, Is.EqualTo("Times")); } - // Test setting a key containing balanced {}. This should fail. + // Test setting a key containing balanced {} with delineation. This should fail. { UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); -- cgit v1.1 From c2bfdaa026b02b1a6f41745464e7934e166ab35f Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 13 Feb 2013 01:52:25 +0000 Subject: Make the sim features module register it's interface so it can be used --- OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs index 191bccf..8f38737 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs @@ -94,6 +94,8 @@ namespace OpenSim.Region.ClientStack.Linden { m_scene = s; m_scene.EventManager.OnRegisterCaps += RegisterCaps; + + m_scene.RegisterModuleInterface(this); } public void RemoveRegion(Scene s) -- cgit v1.1 From 708c3f8b864812abc1c9642f65bc284d4bd3f074 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Tue, 12 Feb 2013 23:21:49 -0800 Subject: Make path parsing more robust in the JsonStore. --- .../OptionalModules/Scripting/JsonStore/JsonStore.cs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs index 3bad06c..f7625fb 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs @@ -68,14 +68,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore protected List m_TakeStore; protected List m_ReadStore; - // add separators for quoted paths - protected static Regex m_ParsePassOne = new Regex("{[^}]+}"); - - // add separators for array references - protected static Regex m_ParsePassTwo = new Regex("(\\[[0-9]+\\]|\\[\\+\\])"); + // add separators for quoted paths and array references + protected static Regex m_ParsePassOne = new Regex("({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])"); // add quotes to bare identifiers which are limited to alphabetic characters - protected static Regex m_ParsePassThree = new Regex("\\.([a-zA-Z]+)"); + protected static Regex m_ParsePassThree = new Regex("(? // ----------------------------------------------------------------- + public JsonStoreNodeType PathType(string expr) + { + Stack path; + if (! ParsePathExpression(expr,out path)) + return JsonStoreNodeType.Undefined; + + OSD result = ProcessPathExpression(ValueStore,path); + + if (result == null) + return JsonStoreNodeType.Undefined; + + if (result is OSDMap) + return JsonStoreNodeType.Object; + + if (result is OSDArray) + return JsonStoreNodeType.Array; + + if (OSDBaseType(result.Type)) + return JsonStoreNodeType.Value; + + return JsonStoreNodeType.Undefined; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- public bool TestPath(string expr, bool useJson) { Stack path; @@ -167,6 +195,27 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- + public int ArrayLength(string expr) + { + Stack path; + if (! ParsePathExpression(expr,out path)) + return -1; + + OSD result = ProcessPathExpression(ValueStore,path); + if (result != null && result.Type == OSDType.Array) + { + OSDArray arr = result as OSDArray; + return arr.Count; + } + + return -1; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- public bool GetValue(string expr, out string value, bool useJson) { Stack path; diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs index cc13661..eec86ef 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs @@ -270,6 +270,38 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- + public JsonStoreNodeType PathType(UUID storeID, string path) + { + if (! m_enabled) return JsonStoreNodeType.Undefined; + + JsonStore map = null; + lock (m_JsonValueStore) + { + if (! m_JsonValueStore.TryGetValue(storeID,out map)) + { + m_log.InfoFormat("[JsonStore] Missing store {0}",storeID); + return JsonStoreNodeType.Undefined; + } + } + + try + { + lock (map) + return map.PathType(path); + } + catch (Exception e) + { + m_log.Error(string.Format("[JsonStore]: Path test failed for {0} in {1}", path, storeID), e); + } + + return JsonStoreNodeType.Undefined; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- public bool TestPath(UUID storeID, string path, bool useJson) { if (! m_enabled) return false; @@ -375,6 +407,37 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- + public int ArrayLength(UUID storeID, string path) + { + if (! m_enabled) return -1; + + JsonStore map = null; + lock (m_JsonValueStore) + { + if (! m_JsonValueStore.TryGetValue(storeID,out map)) + return -1; + } + + try + { + lock (map) + { + return map.ArrayLength(path); + } + } + catch (Exception e) + { + m_log.Error("[JsonStore]: unable to retrieve value", e); + } + + return -1; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- public bool GetValue(UUID storeID, string path, bool useJson, out string value) { value = String.Empty; diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index e436304..3955bff 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs @@ -167,7 +167,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore try { m_comms.RegisterScriptInvocations(this); - + m_comms.RegisterConstants(this); + // m_comms.RegisterScriptInvocation(this, "JsonCreateStore"); // m_comms.RegisterScriptInvocation(this, "JsonAttachObjectStore"); // m_comms.RegisterScriptInvocation(this, "JsonDestroyStore"); @@ -214,6 +215,22 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore #endregion +#region ScriptConstantInteface + + [ScriptConstant] + public static readonly int JSONTYPEUNDEF = (int)JsonStoreNodeType.Undefined; + + [ScriptConstant] + public static readonly int JSONTYPEOBJECT = (int)JsonStoreNodeType.Object; + + [ScriptConstant] + public static readonly int JSONTYPEARRAY = (int)JsonStoreNodeType.Array; + + [ScriptConstant] + public static readonly int JSONTYPEVALUE = (int)JsonStoreNodeType.Value; + +#endregion + #region ScriptInvocationInteface // ----------------------------------------------------------------- /// @@ -319,6 +336,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// // ----------------------------------------------------------------- [ScriptInvocation] + public int JsonPathType(UUID hostID, UUID scriptID, UUID storeID, string path) + { + return (int)m_store.PathType(storeID,path); + } + + [ScriptInvocation] public int JsonTestPath(UUID hostID, UUID scriptID, UUID storeID, string path) { return m_store.TestPath(storeID,path,false) ? 1 : 0; @@ -364,6 +387,17 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// // ----------------------------------------------------------------- [ScriptInvocation] + public int JsonArrayLength(UUID hostID, UUID scriptID, UUID storeID, string path) + { + return m_store.ArrayLength(storeID,path); + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + [ScriptInvocation] public string JsonGetValue(UUID hostID, UUID scriptID, UUID storeID, string path) { string value = String.Empty; -- cgit v1.1 From 69d0e168fb2b945ffcd1fb005abd0192d1eb8876 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Feb 2013 00:19:28 +0000 Subject: Fix a very unlikely-to-occur NullReferenceException race condition in llPushObject() where the code assumed that the physics actor it null-checked would still be null when it invoked a method on it --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index be6ac0a..96f650e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4479,6 +4479,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } } + if (pushAllowed) { float distance = (PusheePos - m_host.AbsolutePosition).Length(); @@ -4507,17 +4508,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api applied_linear_impulse *= scaling_factor; } + if (pusheeIsAvatar) { if (pusheeav != null) { - if (pusheeav.PhysicsActor != null) + PhysicsActor pa = pusheeav.PhysicsActor; + + if (pa != null) { if (local != 0) { applied_linear_impulse *= m_host.GetWorldRotation(); } - pusheeav.PhysicsActor.AddForce(applied_linear_impulse, true); + + pa.AddForce(applied_linear_impulse, true); } } } -- cgit v1.1 From ef662fc959c7943e55c548c50c6b160d12e5c095 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 14 Feb 2013 08:40:15 +0100 Subject: Add an event and some logic to allow customizing Simulator Features by avatar --- .../Linden/Caps/SimulatorFeaturesModule.cs | 25 ++++++++++++++++++---- .../Interfaces/ISimulatorFeaturesModule.cs | 6 +++++- 2 files changed, 26 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs index 8f38737..6ef8815 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs @@ -59,6 +59,8 @@ namespace OpenSim.Region.ClientStack.Linden // private static readonly ILog m_log = // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + public event SimulatorFeaturesRequestDelegate OnSimulatorFeaturesRequest; + private Scene m_scene; /// @@ -158,7 +160,7 @@ namespace OpenSim.Region.ClientStack.Linden IRequestHandler reqHandler = new RestHTTPHandler( "GET", "/CAPS/" + UUID.Random(), - HandleSimulatorFeaturesRequest, "SimulatorFeatures", agentID.ToString()); + x => { return HandleSimulatorFeaturesRequest(x, agentID); }, "SimulatorFeatures", agentID.ToString()); caps.RegisterHandler("SimulatorFeatures", reqHandler); } @@ -187,18 +189,33 @@ namespace OpenSim.Region.ClientStack.Linden return new OSDMap(m_features); } - private Hashtable HandleSimulatorFeaturesRequest(Hashtable mDhttpMethod) + private OSDMap DeepCopy() + { + // This isn't the cheapest way of doing this but the rate + // of occurrence is low (on sim entry only) and it's a sure + // way to get a true deep copy. + OSD copy = OSDParser.DeserializeLLSDXml(OSDParser.SerializeLLSDXmlString(m_features)); + + return (OSDMap)copy; + } + + private Hashtable HandleSimulatorFeaturesRequest(Hashtable mDhttpMethod, UUID agentID) { // m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: SimulatorFeatures request"); + OSDMap copy = DeepCopy(); + + SimulatorFeaturesRequestDelegate handlerOnSimulatorFeaturesRequest = OnSimulatorFeaturesRequest; + if (handlerOnSimulatorFeaturesRequest != null) + handlerOnSimulatorFeaturesRequest(agentID, ref copy); + //Send back data Hashtable responsedata = new Hashtable(); responsedata["int_response_code"] = 200; responsedata["content_type"] = "text/plain"; responsedata["keepalive"] = false; - lock (m_features) - responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(m_features); + responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(copy); return responsedata; } diff --git a/OpenSim/Region/Framework/Interfaces/ISimulatorFeaturesModule.cs b/OpenSim/Region/Framework/Interfaces/ISimulatorFeaturesModule.cs index 8cef14e..6effcc1 100644 --- a/OpenSim/Region/Framework/Interfaces/ISimulatorFeaturesModule.cs +++ b/OpenSim/Region/Framework/Interfaces/ISimulatorFeaturesModule.cs @@ -26,18 +26,22 @@ */ using System; +using OpenMetaverse; using OpenMetaverse.StructuredData; namespace OpenSim.Region.Framework.Interfaces { + public delegate void SimulatorFeaturesRequestDelegate(UUID agentID, ref OSDMap features); + /// /// Add remove or retrieve Simulator Features that will be given to a viewer via the SimulatorFeatures capability. /// public interface ISimulatorFeaturesModule { + event SimulatorFeaturesRequestDelegate OnSimulatorFeaturesRequest; void AddFeature(string name, OSD value); bool RemoveFeature(string name); bool TryGetFeature(string name, out OSD value); OSDMap GetFeatures(); } -} \ No newline at end of file +} -- cgit v1.1 From 5920abbf8d1b1770c03bc6232f1afe0551b4a331 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 14 Feb 2013 09:48:11 -0800 Subject: Add EventManager events triggered when a SOP is added or removed from the physical scene. Invocations added in SceneObjectPart. --- OpenSim/Region/Framework/Scenes/EventManager.cs | 55 ++++++++++++++++++++++ OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 + 2 files changed, 57 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 9ee1520..59d0148 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -791,6 +791,19 @@ namespace OpenSim.Region.Framework.Scenes public delegate void ObjectBeingRemovedFromScene(SceneObjectGroup obj); /// + /// Triggered when an object is placed into the physical scene (PhysicsActor created). + /// + public event Action OnObjectAddedToPhysicalScene; + /// + /// Triggered when an object is removed from the physical scene (PhysicsActor destroyed). + /// + /// + /// Note: this is triggered just before the PhysicsActor is removed from the + /// physics engine so the receiver can do any necessary cleanup before its destruction. + /// + public event Action OnObjectRemovedFromPhysicalScene; + + /// /// Triggered when an object is removed from the scene. /// /// @@ -1516,6 +1529,48 @@ namespace OpenSim.Region.Framework.Scenes } } + public void TriggerObjectAddedToPhysicalScene(SceneObjectPart obj) + { + Action handler = OnObjectAddedToPhysicalScene; + if (handler != null) + { + foreach (Action d in handler.GetInvocationList()) + { + try + { + d(obj); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[EVENT MANAGER]: Delegate for TriggerObjectAddedToPhysicalScene failed - continuing. {0} {1}", + e.Message, e.StackTrace); + } + } + } + } + + public void TriggerObjectRemovedFromPhysicalScene(SceneObjectPart obj) + { + Action handler = OnObjectRemovedFromPhysicalScene; + if (handler != null) + { + foreach (Action d in handler.GetInvocationList()) + { + try + { + d(obj); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[EVENT MANAGER]: Delegate for TriggerObjectRemovedFromPhysicalScene failed - continuing. {0} {1}", + e.Message, e.StackTrace); + } + } + } + } + public void TriggerShutdown() { Action handlerShutdown = OnShutdown; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 9b29973..cce8b21 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4316,6 +4316,7 @@ namespace OpenSim.Region.Framework.Scenes } PhysActor = pa; + ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this); } /// @@ -4328,6 +4329,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void RemoveFromPhysics() { + ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this); ParentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); PhysActor = null; } -- cgit v1.1 From a52dfd43b6c7f5b1893bf027d949c7cc15c233b3 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Feb 2013 21:03:07 +0000 Subject: Make new JsonStore script constants separated with underscores, to be consistent with existing LSL/OSSL, etc script constants. Agreed with cmickeyb --- .../Scripting/JsonStore/JsonStoreScriptModule.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index 3955bff..669d752 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs @@ -215,19 +215,19 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore #endregion -#region ScriptConstantInteface +#region ScriptConstantsInterface [ScriptConstant] - public static readonly int JSONTYPEUNDEF = (int)JsonStoreNodeType.Undefined; + public static readonly int JSON_TYPE_UNDEF = (int)JsonStoreNodeType.Undefined; [ScriptConstant] - public static readonly int JSONTYPEOBJECT = (int)JsonStoreNodeType.Object; + public static readonly int JSON_TYPE_OBJECT = (int)JsonStoreNodeType.Object; [ScriptConstant] - public static readonly int JSONTYPEARRAY = (int)JsonStoreNodeType.Array; + public static readonly int JSON_TYPE_ARRAY = (int)JsonStoreNodeType.Array; [ScriptConstant] - public static readonly int JSONTYPEVALUE = (int)JsonStoreNodeType.Value; + public static readonly int JSON_TYPE_VALUE = (int)JsonStoreNodeType.Value; #endregion -- cgit v1.1 From edb99dcc19d20980ab8fc1a0a272017855e1f266 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Feb 2013 21:11:58 +0000 Subject: Rename new JsonScript functions JsonPathType() -> JsonGetPathType() and JsonArrayLength() -> JsonGetArrayLength() This is for consistentency with the verb:noun naming approach existing json script functions and other script functions. Corresponding c# methods also changed since verb:noun is also the .net c# method naming guideline (as used by OpenSimulator) and for consistency with script functions. As agreed with cmickeyb --- OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs | 4 ++-- .../Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs | 4 ++-- .../OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs index d7907e3..b40d24f 100644 --- a/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs @@ -49,7 +49,7 @@ namespace OpenSim.Region.Framework.Interfaces bool CreateStore(string value, ref UUID result); bool DestroyStore(UUID storeID); - JsonStoreNodeType PathType(UUID storeID, string path); + JsonStoreNodeType GetPathType(UUID storeID, string path); bool TestStore(UUID storeID); bool TestPath(UUID storeID, string path, bool useJson); @@ -60,6 +60,6 @@ namespace OpenSim.Region.Framework.Interfaces void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback); void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback); - int ArrayLength(UUID storeID, string path); + int GetArrayLength(UUID storeID, string path); } } diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs index eec86ef..fb35068 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs @@ -270,7 +270,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - public JsonStoreNodeType PathType(UUID storeID, string path) + public JsonStoreNodeType GetPathType(UUID storeID, string path) { if (! m_enabled) return JsonStoreNodeType.Undefined; @@ -407,7 +407,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - public int ArrayLength(UUID storeID, string path) + public int GetArrayLength(UUID storeID, string path) { if (! m_enabled) return -1; diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index 669d752..1ed7df7 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs @@ -336,9 +336,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// // ----------------------------------------------------------------- [ScriptInvocation] - public int JsonPathType(UUID hostID, UUID scriptID, UUID storeID, string path) + public int JsonGetPathType(UUID hostID, UUID scriptID, UUID storeID, string path) { - return (int)m_store.PathType(storeID,path); + return (int)m_store.GetPathType(storeID,path); } [ScriptInvocation] @@ -387,9 +387,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// // ----------------------------------------------------------------- [ScriptInvocation] - public int JsonArrayLength(UUID hostID, UUID scriptID, UUID storeID, string path) + public int JsonGetArrayLength(UUID hostID, UUID scriptID, UUID storeID, string path) { - return m_store.ArrayLength(storeID,path); + return m_store.GetArrayLength(storeID,path); } // ----------------------------------------------------------------- -- cgit v1.1 From 0ad07eb44d38fd1b57ef40c5aaf073663bc0694c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Feb 2013 21:29:35 +0000 Subject: minor: remove some mono compiler warnings --- .../Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs | 2 +- .../Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs index d1ad74f..b67c0df 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs @@ -42,7 +42,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction public class AssetTransactionModule : INonSharedRegionModule, IAgentAssetTransactions { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected Scene m_Scene; private bool m_dumpAssetsToFile = false; diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs index d36f65a..37131b9 100644 --- a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs +++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs @@ -44,7 +44,7 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DAExampleModule [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DAExampleModule")] public class DAExampleModule : INonSharedRegionModule { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly bool ENABLED = false; // enable for testing -- cgit v1.1 From 6fe771f27e08f516a93ba7c04010a3157841b061 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Feb 2013 21:31:34 +0000 Subject: Add regression TestJsonGetPathType() --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 47 ++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index f25f290..e5555d6 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -399,6 +399,53 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests } [Test] + public void TestJsonGetPathType() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : [ 'one', 2 ] } }"); + + { + int result = (int)InvokeOp("JsonGetPathType", storeId, "."); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_OBJECT)); + } + + { + int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_OBJECT)); + } + + { + int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello.World"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_ARRAY)); + } + + { + int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello.World[0]"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_VALUE)); + } + + { + int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello.World[1]"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_VALUE)); + } + + // Test for non-existant path + { + int result = (int)InvokeOp("JsonGetPathType", storeId, "foo"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_UNDEF)); + } + + // Test for non-existant store + { + UUID fakeStoreId = TestHelpers.ParseTail(0x500); + int result = (int)InvokeOp("JsonGetPathType", fakeStoreId, "."); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_UNDEF)); + } + } + + [Test] public void TestJsonSetValue() { TestHelpers.InMethod(); -- cgit v1.1 From 13d4f6f747d3432f7b7d2f3e1d383dcdce91c01b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Feb 2013 21:34:57 +0000 Subject: Add regression TestGetArrayLength() --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 33 ++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index e5555d6..a457c7b 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -399,6 +399,39 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests } [Test] + public void TestGetArrayLength() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : [ 'one', 2 ] } }"); + + { + int result = (int)InvokeOp("JsonGetArrayLength", storeId, "Hello.World"); + Assert.That(result, Is.EqualTo(2)); + } + + // Test path which is not an array + { + int result = (int)InvokeOp("JsonGetArrayLength", storeId, "Hello"); + Assert.That(result, Is.EqualTo(-1)); + } + + // Test fake path + { + int result = (int)InvokeOp("JsonGetArrayLength", storeId, "foo"); + Assert.That(result, Is.EqualTo(-1)); + } + + // Test fake store + { + UUID fakeStoreId = TestHelpers.ParseTail(0x500); + int result = (int)InvokeOp("JsonGetArrayLength", fakeStoreId, "Hello.World"); + Assert.That(result, Is.EqualTo(-1)); + } + } + + [Test] public void TestJsonGetPathType() { TestHelpers.InMethod(); -- cgit v1.1 From 71862f34b6e97e19fceefd9ccb813ce09ef0a0c3 Mon Sep 17 00:00:00 2001 From: teravus Date: Thu, 14 Feb 2013 18:52:11 -0500 Subject: * Handle null check on configs in module startup so that the the code can be run on 'stop on handled and unhandled null reference exceptions' mode without pausing during startup a bunch of times. I don't think exceptions were really meant for replacing a single if statement... --- .../Framework/Statistics/Logging/BinaryLoggingModule.cs | 2 +- .../Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs index fb74cc6..f3436d1 100644 --- a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs @@ -57,7 +57,7 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging try { IConfig statConfig = source.Configs["Statistics.Binary"]; - if (statConfig.Contains("enabled") && statConfig.GetBoolean("enabled")) + if (statConfig != null && statConfig.Contains("enabled") && statConfig.GetBoolean("enabled")) { if (statConfig.Contains("collect_region_stats")) { diff --git a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs index 385f5ad..cbffca7 100644 --- a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs @@ -111,13 +111,15 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC m_rpcPending = new Dictionary(); m_rpcPendingResponses = new Dictionary(); m_pendingSRDResponses = new Dictionary(); - - try - { - m_remoteDataPort = config.Configs["XMLRPC"].GetInt("XmlRpcPort", m_remoteDataPort); - } - catch (Exception) + if (config.Configs["XMLRPC"] != null) { + try + { + m_remoteDataPort = config.Configs["XMLRPC"].GetInt("XmlRpcPort", m_remoteDataPort); + } + catch (Exception) + { + } } } -- cgit v1.1 From cc40517863a9a32d3c5af1293623c4466c736c13 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 15 Feb 2013 00:27:30 +0000 Subject: Add regression TestJsonList2Path() --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 29 ++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index a457c7b..68eed1d 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -53,6 +53,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests private Scene m_scene; private MockScriptEngine m_engine; private ScriptModuleCommsModule m_smcm; + private JsonStoreScriptModule m_jssm; [TestFixtureSetUp] public void FixtureInit() @@ -82,10 +83,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests m_engine = new MockScriptEngine(); m_smcm = new ScriptModuleCommsModule(); JsonStoreModule jsm = new JsonStoreModule(); - JsonStoreScriptModule jssm = new JsonStoreScriptModule(); + m_jssm = new JsonStoreScriptModule(); m_scene = new SceneHelpers().SetupScene(); - SceneHelpers.SetupSceneModules(m_scene, configSource, m_engine, m_smcm, jsm, jssm); + SceneHelpers.SetupSceneModules(m_scene, configSource, m_engine, m_smcm, jsm, m_jssm); try { @@ -479,6 +480,30 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests } [Test] + public void TestJsonList2Path() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + // Invoking these methods directly since I just couldn't get comms module invocation to work for some reason + // - some confusion with the methods that take a params object[] invocation. + { + string result = m_jssm.JsonList2Path(UUID.Zero, UUID.Zero, new object[] { "foo" }); + Assert.That(result, Is.EqualTo("{foo}")); + } + + { + string result = m_jssm.JsonList2Path(UUID.Zero, UUID.Zero, new object[] { "foo", "bar" }); + Assert.That(result, Is.EqualTo("{foo}.{bar}")); + } + + { + string result = m_jssm.JsonList2Path(UUID.Zero, UUID.Zero, new object[] { "foo", 1, "bar" }); + Assert.That(result, Is.EqualTo("{foo}.[1].{bar}")); + } + } + + [Test] public void TestJsonSetValue() { TestHelpers.InMethod(); -- cgit v1.1 From 0b2608d8f4c715acf693565d57d2919dda4d7f18 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 15 Feb 2013 00:32:20 +0000 Subject: Comment out regression TestJsonTestPath and TestJsonTestPathJson as these will go away soon --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 124 ++++++++++----------- 1 file changed, 62 insertions(+), 62 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 68eed1d..1c4737b 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -335,69 +335,69 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests } } - [Test] - public void TestJsonTestPath() - { - TestHelpers.InMethod(); -// TestHelpers.EnableLogging(); - - UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }"); - - { - int result = (int)InvokeOp("JsonTestPath", storeId, "Hello.World"); - Assert.That(result, Is.EqualTo(1)); - } - - // Test for path which does not resolve to a value. - { - int result = (int)InvokeOp("JsonTestPath", storeId, "Hello"); - Assert.That(result, Is.EqualTo(0)); - } - - { - int result2 = (int)InvokeOp("JsonTestPath", storeId, "foo"); - Assert.That(result2, Is.EqualTo(0)); - } - - // Test with fake store - { - UUID fakeStoreId = TestHelpers.ParseTail(0x500); - int fakeStoreValueRemove = (int)InvokeOp("JsonTestPath", fakeStoreId, "Hello"); - Assert.That(fakeStoreValueRemove, Is.EqualTo(0)); - } - } - - [Test] - public void TestJsonTestPathJson() - { - TestHelpers.InMethod(); -// TestHelpers.EnableLogging(); - - UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }"); - - { - int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello.World"); - Assert.That(result, Is.EqualTo(1)); - } - - // Test for path which does not resolve to a value. - { - int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello"); - Assert.That(result, Is.EqualTo(1)); - } - - { - int result2 = (int)InvokeOp("JsonTestPathJson", storeId, "foo"); - Assert.That(result2, Is.EqualTo(0)); - } +// [Test] +// public void TestJsonTestPath() +// { +// TestHelpers.InMethod(); +//// TestHelpers.EnableLogging(); +// +// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }"); +// +// { +// int result = (int)InvokeOp("JsonTestPath", storeId, "Hello.World"); +// Assert.That(result, Is.EqualTo(1)); +// } +// +// // Test for path which does not resolve to a value. +// { +// int result = (int)InvokeOp("JsonTestPath", storeId, "Hello"); +// Assert.That(result, Is.EqualTo(0)); +// } +// +// { +// int result2 = (int)InvokeOp("JsonTestPath", storeId, "foo"); +// Assert.That(result2, Is.EqualTo(0)); +// } +// +// // Test with fake store +// { +// UUID fakeStoreId = TestHelpers.ParseTail(0x500); +// int fakeStoreValueRemove = (int)InvokeOp("JsonTestPath", fakeStoreId, "Hello"); +// Assert.That(fakeStoreValueRemove, Is.EqualTo(0)); +// } +// } - // Test with fake store - { - UUID fakeStoreId = TestHelpers.ParseTail(0x500); - int fakeStoreValueRemove = (int)InvokeOp("JsonTestPathJson", fakeStoreId, "Hello"); - Assert.That(fakeStoreValueRemove, Is.EqualTo(0)); - } - } +// [Test] +// public void TestJsonTestPathJson() +// { +// TestHelpers.InMethod(); +//// TestHelpers.EnableLogging(); +// +// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }"); +// +// { +// int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello.World"); +// Assert.That(result, Is.EqualTo(1)); +// } +// +// // Test for path which does not resolve to a value. +// { +// int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello"); +// Assert.That(result, Is.EqualTo(1)); +// } +// +// { +// int result2 = (int)InvokeOp("JsonTestPathJson", storeId, "foo"); +// Assert.That(result2, Is.EqualTo(0)); +// } +// +// // Test with fake store +// { +// UUID fakeStoreId = TestHelpers.ParseTail(0x500); +// int fakeStoreValueRemove = (int)InvokeOp("JsonTestPathJson", fakeStoreId, "Hello"); +// Assert.That(fakeStoreValueRemove, Is.EqualTo(0)); +// } +// } [Test] public void TestGetArrayLength() -- cgit v1.1 From 61f18d15e1115275588e9e5a27f5d148ed762b4e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 15 Feb 2013 00:38:07 +0000 Subject: Rename JsonSetValueJson() -> JsonSetJson() and JsonGetValueJson() -> JsonGetJson() This is because JsonGetJson() is getting json from anywhere in the structure, not just values. Equally, JsonSetJson() is setting any type of json, not just json which represents a value. Agreed with cmickeyb --- .../Scripting/JsonStore/JsonStoreScriptModule.cs | 4 ++-- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 26 +++++++++++----------- 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index 1ed7df7..ef08c05 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs @@ -365,7 +365,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } [ScriptInvocation] - public int JsonSetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path, string value) + public int JsonSetJson(UUID hostID, UUID scriptID, UUID storeID, string path, string value) { return m_store.SetValue(storeID,path,value,true) ? 1 : 0; } @@ -406,7 +406,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } [ScriptInvocation] - public string JsonGetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) + public string JsonGetJson(UUID hostID, UUID scriptID, UUID storeID, string path) { string value = String.Empty; m_store.GetValue(storeID,path,true, out value); diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 1c4737b..ffa8250 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -209,7 +209,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests } [Test] - public void TestJsonGetValueJson() + public void TestJsonGetJson() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); @@ -217,26 +217,26 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Two' } }"); { - string value = (string)InvokeOp("JsonGetValueJson", storeId, "Hello.World"); + string value = (string)InvokeOp("JsonGetJson", storeId, "Hello.World"); Assert.That(value, Is.EqualTo("'Two'")); } // Test get of path section instead of leaf { - string value = (string)InvokeOp("JsonGetValueJson", storeId, "Hello"); + string value = (string)InvokeOp("JsonGetJson", storeId, "Hello"); Assert.That(value, Is.EqualTo("{\"World\":\"Two\"}")); } // Test get of non-existing value { - string fakeValueGet = (string)InvokeOp("JsonGetValueJson", storeId, "foo"); + string fakeValueGet = (string)InvokeOp("JsonGetJson", storeId, "foo"); Assert.That(fakeValueGet, Is.EqualTo("")); } // Test get from non-existing store { UUID fakeStoreId = TestHelpers.ParseTail(0x500); - string fakeStoreValueGet = (string)InvokeOp("JsonGetValueJson", fakeStoreId, "Hello"); + string fakeStoreValueGet = (string)InvokeOp("JsonGetJson", fakeStoreId, "Hello"); Assert.That(fakeStoreValueGet, Is.EqualTo("")); } } @@ -294,7 +294,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests int result = (int)InvokeOp("JsonTestPath", storeId, "Hello"); Assert.That(result, Is.EqualTo(0)); - string returnValue2 = (string)InvokeOp("JsonGetValueJson", storeId, "Hello"); + string returnValue2 = (string)InvokeOp("JsonGetJson", storeId, "Hello"); Assert.That(returnValue2, Is.EqualTo("")); } @@ -315,7 +315,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests string stringReturnValue = (string)InvokeOp("JsonGetValue", storeId, "Hello[0]"); Assert.That(stringReturnValue, Is.EqualTo("value2")); - stringReturnValue = (string)InvokeOp("JsonGetValueJson", storeId, "Hello[1]"); + stringReturnValue = (string)InvokeOp("JsonGetJson", storeId, "Hello[1]"); Assert.That(stringReturnValue, Is.EqualTo("")); } @@ -689,7 +689,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests } [Test] - public void TestJsonSetValueJson() + public void TestJsonSetJson() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); @@ -698,7 +698,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests { UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); - int result = (int)InvokeOp("JsonSetValueJson", storeId, "Fun", "'Times'"); + int result = (int)InvokeOp("JsonSetJson", storeId, "Fun", "'Times'"); Assert.That(result, Is.EqualTo(1)); string value = (string)InvokeOp("JsonGetValue", storeId, "Fun"); @@ -709,7 +709,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests { UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); - int result = (int)InvokeOp("JsonSetValueJson", storeId, "Fun", "{ 'Filled' : 'Times' }"); + int result = (int)InvokeOp("JsonSetJson", storeId, "Fun", "{ 'Filled' : 'Times' }"); Assert.That(result, Is.EqualTo(1)); string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Filled"); @@ -720,7 +720,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests { UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); - int result = (int)InvokeOp("JsonSetValueJson", storeId, "Fun", "Times"); + int result = (int)InvokeOp("JsonSetJson", storeId, "Fun", "Times"); Assert.That(result, Is.EqualTo(0)); string value = (string)InvokeOp("JsonGetValue", storeId, "Fun"); @@ -731,7 +731,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests { UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); - int result = (int)InvokeOp("JsonSetValueJson", storeId, "Fun.Circus", "'Times'"); + int result = (int)InvokeOp("JsonSetJson", storeId, "Fun.Circus", "'Times'"); Assert.That(result, Is.EqualTo(0)); string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Circus"); @@ -741,7 +741,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests // Test with fake store { UUID fakeStoreId = TestHelpers.ParseTail(0x500); - int fakeStoreValueSet = (int)InvokeOp("JsonSetValueJson", fakeStoreId, "Hello", "'World'"); + int fakeStoreValueSet = (int)InvokeOp("JsonSetJson", fakeStoreId, "Hello", "'World'"); Assert.That(fakeStoreValueSet, Is.EqualTo(0)); } } -- cgit v1.1 From 8d5fe5c22232e23b414531b07c5a8b343bb4b886 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 15 Feb 2013 01:00:49 +0000 Subject: Enable one sub-test in TestJsonSetValue() which now works (using identifier with embedded .). Need to look further at other still commented tests. Still need to check coverage against some of Mic's scripts. --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 30 ++++++++++------------ 1 file changed, 13 insertions(+), 17 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index ffa8250..3d9ad16 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -519,17 +519,16 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests Assert.That(value, Is.EqualTo("Times")); } - // Commented out as this currently unexpectedly fails. // Test setting a key containing periods with delineation -// { -// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); -// -// int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun.Circus}", "Times"); -// Assert.That(result, Is.EqualTo(1)); -// -// string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun.Circus}"); -// Assert.That(value, Is.EqualTo("Times")); -// } + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + + int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun.Circus}", "Times"); + Assert.That(result, Is.EqualTo(1)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun.Circus}"); + Assert.That(value, Is.EqualTo("Times")); + } // *** Test [] *** @@ -599,7 +598,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests Assert.That(value, Is.EqualTo("Times")); } - // Commented out as this currently unexpectedly fails. +// // Commented out as this currently unexpectedly fails. // // Test setting a key containing brackets around an integer with delineation // { // UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); @@ -607,7 +606,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests // int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[0]Circus}", "Times"); // Assert.That(result, Is.EqualTo(1)); // -// string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[]Circus}"); +// string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[0]Circus}"); // Assert.That(value, Is.EqualTo("Times")); // } @@ -635,16 +634,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests Assert.That(value, Is.EqualTo("")); } - // Commented out as this currently unexpectedly fails. +// // Commented out as this currently unexpectedly fails. // // Test setting a key containing unbalanced } // { // UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); // // int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun}Circus}", "Times"); -// Assert.That(result, Is.EqualTo(1)); -// -// string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun}Circus}"); -// Assert.That(value, Is.EqualTo("Times")); +// Assert.That(result, Is.EqualTo(0)); // } // Test setting a key containing unbalanced { with delineation -- cgit v1.1 From e9cc22fea48a6d80fccbd624fd9710dfa3830980 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 16 Feb 2013 00:26:21 +0000 Subject: Add regression test TestSaveNonRootFolderToIar --- .../Archiver/InventoryArchiveReadRequest.cs | 4 +- .../Inventory/Archiver/InventoryArchiveUtils.cs | 86 ++++++++++++++++++++-- .../Archiver/InventoryArchiveWriteRequest.cs | 2 +- .../Archiver/Tests/InventoryArchiverTests.cs | 84 ++++++++++++++++++++- .../Avatar/Inventory/Archiver/Tests/PathTests.cs | 30 ++++---- .../Tests/InventoryAccessModuleTests.cs | 4 +- .../CoreModules/World/Archiver/AssetsRequest.cs | 2 + .../Scenes/Tests/SceneObjectDeRezTests.cs | 2 +- .../Framework/Scenes/Tests/TaskInventoryTests.cs | 2 +- .../Framework/Scenes/Tests/UserInventoryTests.cs | 6 +- 10 files changed, 188 insertions(+), 34 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs index ecbd07f..98285e9 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs @@ -161,7 +161,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver string filePath = "ERROR"; List folderCandidates - = InventoryArchiveUtils.FindFolderByPath( + = InventoryArchiveUtils.FindFoldersByPath( m_scene.InventoryService, m_userInfo.PrincipalID, m_invPath); if (folderCandidates.Count == 0) @@ -296,7 +296,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver // iar name and try to find that instead. string plainPath = ArchiveConstants.ExtractPlainPathFromIarPath(archivePath); List folderCandidates - = InventoryArchiveUtils.FindFolderByPath( + = InventoryArchiveUtils.FindFoldersByPath( m_scene.InventoryService, m_userInfo.PrincipalID, plainPath); if (folderCandidates.Count != 0) diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs index 0d90a15..dbaf2aa 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs @@ -52,13 +52,82 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// /// Find a folder given a PATH_DELIMITER delimited path starting from a user's root folder /// + /// + /// This method does not handle paths that contain multiple delimitors + /// + /// FIXME: We have no way of distinguishing folders with the same path /// + /// FIXME: Delimitors which occur in names themselves are not currently escapable. + /// + /// + /// Inventory service to query + /// + /// + /// User id to search + /// + /// + /// The path to the required folder. + /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned. + /// + /// The folder found. Please note that if there are multiple folders with the same name then an + /// unspecified one will be returned. If no such folder eixsts then null is returned + public static InventoryFolderBase FindFolderByPath( + IInventoryService inventoryService, UUID userId, string path) + { + List folders = FindFoldersByPath(inventoryService, userId, path); + + if (folders.Count == 0) + return null; + else + return folders[0]; + } + + /// + /// Find a folder given a PATH_DELIMITER delimited path starting from a given folder + /// + /// /// This method does not handle paths that contain multiple delimitors /// /// FIXME: We have no way of distinguishing folders with the same path /// /// FIXME: Delimitors which occur in names themselves are not currently escapable. + /// + /// + /// Inventory service to query + /// + /// + /// The folder from which the path starts + /// + /// + /// The path to the required folder. + /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned. + /// + /// The folder found. Please note that if there are multiple folders with the same name then an + /// unspecified one will be returned. If no such folder eixsts then null is returned + public static InventoryFolderBase FindFolderByPath( + IInventoryService inventoryService, InventoryFolderBase startFolder, string path) + { + if (null == startFolder) + return null; + + List folders = FindFoldersByPath(inventoryService, startFolder, path); + + if (folders.Count == 0) + return null; + else + return folders[0]; + } + + /// + /// Find a set of folders given a PATH_DELIMITER delimited path starting from a user's root folder + /// + /// + /// This method does not handle paths that contain multiple delimitors + /// + /// FIXME: We have no way of distinguishing folders with the same path /// + /// FIXME: Delimitors which occur in names themselves are not currently escapable. + /// /// /// Inventory service to query /// @@ -70,7 +139,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned. /// /// An empty list if the folder is not found, otherwise a list of all folders that match the name - public static List FindFolderByPath( + public static List FindFoldersByPath( IInventoryService inventoryService, UUID userId, string path) { InventoryFolderBase rootFolder = inventoryService.GetRootFolder(userId); @@ -78,19 +147,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver if (null == rootFolder) return new List(); - return FindFolderByPath(inventoryService, rootFolder, path); + return FindFoldersByPath(inventoryService, rootFolder, path); } /// - /// Find a folder given a PATH_DELIMITER delimited path starting from this folder + /// Find a set of folders given a PATH_DELIMITER delimited path starting from this folder /// - /// + /// /// This method does not handle paths that contain multiple delimitors /// /// FIXME: We have no way of distinguishing folders with the same path. /// /// FIXME: Delimitors which occur in names themselves are not currently escapable. - /// + /// /// /// Inventory service to query /// @@ -102,7 +171,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned. /// /// An empty list if the folder is not found, otherwise a list of all folders that match the name - public static List FindFolderByPath( + public static List FindFoldersByPath( IInventoryService inventoryService, InventoryFolderBase startFolder, string path) { List foundFolders = new List(); @@ -133,12 +202,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID); +// m_log.DebugFormat( +// "Found {0} folders in {1} for {2}", contents.Folders.Count, startFolder.Name, startFolder.Owner); + foreach (InventoryFolderBase folder in contents.Folders) { if (folder.Name == components[0]) { if (components.Length > 1) - foundFolders.AddRange(FindFolderByPath(inventoryService, folder, components[1])); + foundFolders.AddRange(FindFoldersByPath(inventoryService, folder, components[1])); else foundFolders.Add(folder); } diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index 4c85637..d703498 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs @@ -289,7 +289,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver { m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER)); List candidateFolders - = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, rootFolder, m_invPath); + = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, rootFolder, m_invPath); if (candidateFolders.Count > 0) inventoryFolder = candidateFolders[0]; } diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs index 06f6e49..38254e5 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs @@ -121,6 +121,86 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests Assert.That(iarr.ControlFileLoaded, Is.True); } + + [Test] + public void TestSaveNonRootFolderToIar() + { + TestHelpers.InMethod(); + TestHelpers.EnableLogging(); + + string userFirstName = "Jock"; + string userLastName = "Stirrup"; + string userPassword = "troll"; + UUID userId = TestHelpers.ParseTail(0x20); + + UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword); + + // Create base folder + InventoryFolderBase f1 + = UserInventoryHelpers.CreateInventoryFolder(m_scene.InventoryService, userId, "f1", true); + + // Create item1 + SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(1, userId, "My Little Dog Object", 0x5); + InventoryItemBase i1 = UserInventoryHelpers.AddInventoryItem(m_scene, so1, 0x50, 0x60, "f1"); + + // Create embedded folder + InventoryFolderBase f1_1 + = UserInventoryHelpers.CreateInventoryFolder(m_scene.InventoryService, userId, "f1/f1.1", true); + + // Create embedded item + SceneObjectGroup so1_1 = SceneHelpers.CreateSceneObject(1, userId, "My Little Cat Object", 0x6); + InventoryItemBase i2 = UserInventoryHelpers.AddInventoryItem(m_scene, so1_1, 0x500, 0x600, "f1/f1.1"); + + MemoryStream archiveWriteStream = new MemoryStream(); + m_archiverModule.OnInventoryArchiveSaved += SaveCompleted; + + mre.Reset(); + m_archiverModule.ArchiveInventory( + Guid.NewGuid(), userFirstName, userLastName, "f1", userPassword, archiveWriteStream); + mre.WaitOne(60000, false); + + // Test created iar + byte[] archive = archiveWriteStream.ToArray(); + MemoryStream archiveReadStream = new MemoryStream(archive); + TarArchiveReader tar = new TarArchiveReader(archiveReadStream); + +// InventoryArchiveUtils. + bool gotf1 = false, gotf1_1 = false, gotso1 = false, gotso2 = false; + + string f1FileName + = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, InventoryArchiveWriteRequest.CreateArchiveFolderName(f1)); + string f1_1FileName + = string.Format("{0}{1}", f1FileName, InventoryArchiveWriteRequest.CreateArchiveFolderName(f1_1)); + string so1FileName + = string.Format("{0}{1}", f1FileName, InventoryArchiveWriteRequest.CreateArchiveItemName(i1)); + string so2FileName + = string.Format("{0}{1}", f1_1FileName, InventoryArchiveWriteRequest.CreateArchiveItemName(i2)); + + string filePath; + TarArchiveReader.TarEntryType tarEntryType; + + while (tar.ReadEntry(out filePath, out tarEntryType) != null) + { +// Console.WriteLine("Got {0}", filePath); + + if (filePath == f1FileName) + gotf1 = true; + else if (filePath == f1_1FileName) + gotf1_1 = true; + else if (filePath == so1FileName) + gotso1 = true; + else if (filePath == so2FileName) + gotso2 = true; + } + +// Assert.That(gotControlFile, Is.True, "No control file in archive"); + Assert.That(gotf1, Is.True); + Assert.That(gotf1_1, Is.True); + Assert.That(gotso1, Is.True); + Assert.That(gotso2, Is.True); + + // TODO: Test presence of more files and contents of files. + } /// /// Test saving a single inventory item to an IAR @@ -155,7 +235,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests item1.AssetID = asset1.FullID; item1.ID = item1Id; InventoryFolderBase objsFolder - = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, userId, "Objects")[0]; + = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, userId, "Objects")[0]; item1.Folder = objsFolder.ID; m_scene.AddInventoryItem(item1); @@ -250,7 +330,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests item1.AssetID = asset1.FullID; item1.ID = item1Id; InventoryFolderBase objsFolder - = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, userId, "Objects")[0]; + = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, userId, "Objects")[0]; item1.Folder = objsFolder.ID; m_scene.AddInventoryItem(item1); diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs index 6eb3605..1871576 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs @@ -101,7 +101,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests item1.AssetID = asset1.FullID; item1.ID = item1Id; InventoryFolderBase objsFolder - = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, userId, "Objects")[0]; + = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, userId, "Objects")[0]; item1.Folder = objsFolder.ID; scene.AddInventoryItem(item1); @@ -193,7 +193,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); // Now try loading to a root child folder - UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xA"); + UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xA", false); MemoryStream archiveReadStream = new MemoryStream(m_iarStream.ToArray()); archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xA", "meowfood", archiveReadStream); @@ -202,7 +202,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests Assert.That(foundItem2, Is.Not.Null, "Didn't find loaded item 2"); // Now try loading to a more deeply nested folder - UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC"); + UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC", false); archiveReadStream = new MemoryStream(archiveReadStream.ToArray()); archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xB/xC", "meowfood", archiveReadStream); @@ -287,7 +287,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests item1.AssetID = asset1.FullID; item1.ID = item1Id; InventoryFolderBase objsFolder - = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, userId, "Objects")[0]; + = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, userId, "Objects")[0]; item1.Folder = objsFolder.ID; scene.AddInventoryItem(item1); @@ -351,12 +351,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests foldersCreated, nodesLoaded); List folder1Candidates - = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1Name); + = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1Name); Assert.That(folder1Candidates.Count, Is.EqualTo(1)); InventoryFolderBase folder1 = folder1Candidates[0]; List folder2aCandidates - = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1, folder2aName); + = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1, folder2aName); Assert.That(folder2aCandidates.Count, Is.EqualTo(1)); } @@ -368,17 +368,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests foldersCreated, nodesLoaded); List folder1Candidates - = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1Name); + = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1Name); Assert.That(folder1Candidates.Count, Is.EqualTo(1)); InventoryFolderBase folder1 = folder1Candidates[0]; List folder2aCandidates - = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1, folder2aName); + = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1, folder2aName); Assert.That(folder2aCandidates.Count, Is.EqualTo(1)); List folder2bCandidates - = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1, folder2bName); + = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1, folder2bName); Assert.That(folder2bCandidates.Count, Is.EqualTo(1)); } } @@ -401,7 +401,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests InventoryFolderBase folder1 = UserInventoryHelpers.CreateInventoryFolder( - scene.InventoryService, ua1.PrincipalID, folder1ExistingName); + scene.InventoryService, ua1.PrincipalID, folder1ExistingName, false); string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random()); string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random()); @@ -414,7 +414,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests new Dictionary(), new HashSet()); List folder1PostCandidates - = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); + = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); Assert.That(folder1PostCandidates.Count, Is.EqualTo(2)); // FIXME: Temporarily, we're going to do something messy to make sure we pick up the created folder. @@ -430,7 +430,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests // Assert.That(folder1Post.ID, Is.EqualTo(folder1.ID)); List folder2PostCandidates - = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1Post, "b"); + = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1Post, "b"); Assert.That(folder2PostCandidates.Count, Is.EqualTo(1)); } @@ -452,7 +452,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests InventoryFolderBase folder1 = UserInventoryHelpers.CreateInventoryFolder( - scene.InventoryService, ua1.PrincipalID, folder1ExistingName); + scene.InventoryService, ua1.PrincipalID, folder1ExistingName, false); string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random()); string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random()); @@ -465,12 +465,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests new Dictionary(), new HashSet()); List folder1PostCandidates - = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); + = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); Assert.That(folder1PostCandidates.Count, Is.EqualTo(1)); Assert.That(folder1PostCandidates[0].ID, Is.EqualTo(folder1.ID)); List folder2PostCandidates - = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1PostCandidates[0], "b"); + = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1PostCandidates[0], "b"); Assert.That(folder2PostCandidates.Count, Is.EqualTo(1)); } } diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs index ac25a93..ad1a0e1 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs @@ -109,7 +109,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests item1.AssetID = asset1.FullID; item1.ID = item1Id; InventoryFolderBase objsFolder - = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, m_userId, "Objects")[0]; + = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, m_userId, "Objects")[0]; item1.Folder = objsFolder.ID; m_scene.AddInventoryItem(item1); @@ -159,7 +159,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests item1.AssetID = asset1.FullID; item1.ID = item1Id; InventoryFolderBase objsFolder - = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, m_userId, "Objects")[0]; + = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, m_userId, "Objects")[0]; item1.Folder = objsFolder.ID; m_scene.AddInventoryItem(item1); diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs index b22bcf9..9600023 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs @@ -156,6 +156,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver foreach (KeyValuePair kvp in m_uuids) { +// m_log.DebugFormat("[ARCHIVER]: Requesting asset {0}", kvp.Key); + // m_assetService.Get(kvp.Key.ToString(), kvp.Value, PreAssetRequestCallback); AssetBase asset = m_assetService.Get(kvp.Key.ToString()); PreAssetRequestCallback(kvp.Key.ToString(), kvp.Value, asset); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs index c1522e7..52ad538 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs @@ -164,7 +164,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests UserAccount ua = UserAccountHelpers.CreateUserWithInventory(scene, agentId); InventoryFolderBase folder1 - = UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, ua.PrincipalID, "folder1"); + = UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, ua.PrincipalID, "folder1", false); IClientAPI client = SceneHelpers.AddScenePresence(scene, agentId).ControllingClient; scene.DeRezObjects(client, new List() { so.LocalId }, UUID.Zero, DeRezAction.Take, folder1.ID); diff --git a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs index 0b461f5..df819ec 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs @@ -133,7 +133,7 @@ namespace OpenSim.Region.Framework.Tests scene, sop1, "ncItem", TestHelpers.ParseTail(0x800), TestHelpers.ParseTail(0x900)); InventoryFolderBase folder - = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, user1.PrincipalID, "Objects")[0]; + = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, user1.PrincipalID, "Objects")[0]; // Perform test scene.MoveTaskInventoryItem(user1.PrincipalID, folder.ID, sop1, sopItem1.ItemID); diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs index 9457ebb..e50b4da 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs @@ -64,7 +64,7 @@ namespace OpenSim.Region.Framework.Tests Scene scene = new SceneHelpers().SetupScene(); UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001)); - UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, foldersName); + UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, foldersName, false); List oneFolder = UserInventoryHelpers.GetInventoryFolders(scene.InventoryService, user1.PrincipalID, foldersName); @@ -73,7 +73,7 @@ namespace OpenSim.Region.Framework.Tests InventoryFolderBase firstRetrievedFolder = oneFolder[0]; Assert.That(firstRetrievedFolder.Name, Is.EqualTo(foldersName)); - UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, foldersName); + UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, foldersName, false); List twoFolders = UserInventoryHelpers.GetInventoryFolders(scene.InventoryService, user1.PrincipalID, foldersName); @@ -121,7 +121,7 @@ namespace OpenSim.Region.Framework.Tests UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001)); UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1002)); InventoryFolderBase folder1 - = UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, "folder1"); + = UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, "folder1", false); scene.GiveInventoryFolder(user2.PrincipalID, user1.PrincipalID, folder1.ID, UUID.Zero); -- cgit v1.1 From d54d31807af8b5e2b85897d0bb744d9d34055dff Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 16 Feb 2013 00:49:06 +0000 Subject: Make it so that "load iar / ..." does not save the 'root' "My Inventory" folder. Really "My Inventory" is just the name of the root, it isn't a folder in its own right. This also makes it more intuitive for users to save whole inventory iars for backup/later restoration, as they don't need to remember to use /* /* will still work and this is a special case just for the root If you want to save only the contents of other folders (rather than the folder itself), you still need to specify something like a/b/* Added a regression test for this case. --- .../Archiver/InventoryArchiveWriteRequest.cs | 6 +++ .../Archiver/Tests/InventoryArchiverTests.cs | 55 +++++++++++++++++++++- 2 files changed, 60 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index d703498..4ec8ae7 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs @@ -272,6 +272,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver saveFolderContentsOnly = true; maxComponentIndex--; } + else if (maxComponentIndex == -1) + { + // If the user has just specified "/", then don't save the root "My Inventory" folder. This is + // more intuitive then requiring the user to specify "/*" for this. + saveFolderContentsOnly = true; + } m_invPath = String.Empty; for (int i = 0; i <= maxComponentIndex; i++) diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs index 38254e5..7ff29e5 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs @@ -123,10 +123,63 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests } [Test] + public void TestSaveRootFolderToIar() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + string userFirstName = "Jock"; + string userLastName = "Stirrup"; + string userPassword = "troll"; + UUID userId = TestHelpers.ParseTail(0x20); + + UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword); + + MemoryStream archiveWriteStream = new MemoryStream(); + m_archiverModule.OnInventoryArchiveSaved += SaveCompleted; + + mre.Reset(); + m_archiverModule.ArchiveInventory( + Guid.NewGuid(), userFirstName, userLastName, "/", userPassword, archiveWriteStream); + mre.WaitOne(60000, false); + + // Test created iar + byte[] archive = archiveWriteStream.ToArray(); + MemoryStream archiveReadStream = new MemoryStream(archive); + TarArchiveReader tar = new TarArchiveReader(archiveReadStream); + +// InventoryArchiveUtils. + bool gotObjectsFolder = false; + + string objectsFolderName + = string.Format( + "{0}{1}", + ArchiveConstants.INVENTORY_PATH, + InventoryArchiveWriteRequest.CreateArchiveFolderName( + UserInventoryHelpers.GetInventoryFolder(m_scene.InventoryService, userId, "Objects"))); + + string filePath; + TarArchiveReader.TarEntryType tarEntryType; + + while (tar.ReadEntry(out filePath, out tarEntryType) != null) + { +// Console.WriteLine("Got {0}", filePath); + + // Lazily, we only bother to look for the system objects folder created when we call CreateUserWithInventory() + // XXX: But really we need to stop all that stuff being created in tests or check for such folders + // more thoroughly + if (filePath == objectsFolderName) + gotObjectsFolder = true; + } + + Assert.That(gotObjectsFolder, Is.True); + } + + [Test] public void TestSaveNonRootFolderToIar() { TestHelpers.InMethod(); - TestHelpers.EnableLogging(); +// TestHelpers.EnableLogging(); string userFirstName = "Jock"; string userLastName = "Stirrup"; -- cgit v1.1 From 7d7736dc738c92261bbdcbe2873fd669f51219ce Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 16 Feb 2013 01:57:42 +0000 Subject: Separate IAR tests into separate files for load/save/loadpath tests --- .../Tests/InventoryArchiveLoadPathTests.cs | 362 ++++++++++++++ .../Archiver/Tests/InventoryArchiveLoadTests.cs | 194 ++++++++ .../Archiver/Tests/InventoryArchiveSaveTests.cs | 424 ++++++++++++++++ .../Archiver/Tests/InventoryArchiverTests.cs | 550 --------------------- .../Avatar/Inventory/Archiver/Tests/PathTests.cs | 477 ------------------ 5 files changed, 980 insertions(+), 1027 deletions(-) create mode 100644 OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs create mode 100644 OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs create mode 100644 OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs delete mode 100644 OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs delete mode 100644 OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs new file mode 100644 index 0000000..95f562e --- /dev/null +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs @@ -0,0 +1,362 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Threading; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Data; +using OpenSim.Framework; +using OpenSim.Framework.Serialization; +using OpenSim.Framework.Serialization.External; +using OpenSim.Framework.Communications; +using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; +using OpenSim.Region.CoreModules.World.Serialiser; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Scenes.Serialization; +using OpenSim.Services.Interfaces; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests +{ + [TestFixture] + public class InventoryArchiveLoadPathTests : InventoryArchiveTestCase + { + /// + /// Test loading an IAR to various different inventory paths. + /// + [Test] + public void TestLoadIarToInventoryPaths() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + SerialiserModule serialiserModule = new SerialiserModule(); + InventoryArchiverModule archiverModule = new InventoryArchiverModule(); + + // Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene + Scene scene = new SceneHelpers().SetupScene(); + + SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); + + UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "meowfood"); + UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire"); + + archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream); + InventoryItemBase foundItem1 + = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); + + Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); + + // Now try loading to a root child folder + UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xA", false); + MemoryStream archiveReadStream = new MemoryStream(m_iarStream.ToArray()); + archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xA", "meowfood", archiveReadStream); + + InventoryItemBase foundItem2 + = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, "xA/" + m_item1Name); + Assert.That(foundItem2, Is.Not.Null, "Didn't find loaded item 2"); + + // Now try loading to a more deeply nested folder + UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC", false); + archiveReadStream = new MemoryStream(archiveReadStream.ToArray()); + archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xB/xC", "meowfood", archiveReadStream); + + InventoryItemBase foundItem3 + = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC/" + m_item1Name); + Assert.That(foundItem3, Is.Not.Null, "Didn't find loaded item 3"); + } + + /// + /// Test that things work when the load path specified starts with a slash + /// + [Test] + public void TestLoadIarPathStartsWithSlash() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + SerialiserModule serialiserModule = new SerialiserModule(); + InventoryArchiverModule archiverModule = new InventoryArchiverModule(); + Scene scene = new SceneHelpers().SetupScene(); + SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); + + UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "password"); + archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/Objects", "password", m_iarStream); + + InventoryItemBase foundItem1 + = InventoryArchiveUtils.FindItemByPath( + scene.InventoryService, m_uaMT.PrincipalID, "/Objects/" + m_item1Name); + + Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1 in TestLoadIarFolderStartsWithSlash()"); + } + + [Test] + public void TestLoadIarPathWithEscapedChars() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + string itemName = "You & you are a mean/man/"; + string humanEscapedItemName = @"You & you are a mean\/man\/"; + string userPassword = "meowfood"; + + InventoryArchiverModule archiverModule = new InventoryArchiverModule(); + + Scene scene = new SceneHelpers().SetupScene(); + SceneHelpers.SetupSceneModules(scene, archiverModule); + + // Create user + string userFirstName = "Jock"; + string userLastName = "Stirrup"; + UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020"); + UserAccountHelpers.CreateUserWithInventory(scene, userFirstName, userLastName, userId, "meowfood"); + + // Create asset + SceneObjectGroup object1; + SceneObjectPart part1; + { + string partName = "part name"; + UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); + PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere(); + Vector3 groupPosition = new Vector3(10, 20, 30); + Quaternion rotationOffset = new Quaternion(20, 30, 40, 50); + Vector3 offsetPosition = new Vector3(5, 10, 15); + + part1 + = new SceneObjectPart( + ownerId, shape, groupPosition, rotationOffset, offsetPosition); + part1.Name = partName; + + object1 = new SceneObjectGroup(part1); + scene.AddNewSceneObject(object1, false); + } + + UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); + AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); + scene.AssetService.Store(asset1); + + // Create item + UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080"); + InventoryItemBase item1 = new InventoryItemBase(); + item1.Name = itemName; + item1.AssetID = asset1.FullID; + item1.ID = item1Id; + InventoryFolderBase objsFolder + = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, userId, "Objects")[0]; + item1.Folder = objsFolder.ID; + scene.AddInventoryItem(item1); + + MemoryStream archiveWriteStream = new MemoryStream(); + archiverModule.OnInventoryArchiveSaved += SaveCompleted; + + mre.Reset(); + archiverModule.ArchiveInventory( + Guid.NewGuid(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream); + mre.WaitOne(60000, false); + + // LOAD ITEM + MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); + + archiverModule.DearchiveInventory(userFirstName, userLastName, "Scripts", userPassword, archiveReadStream); + + InventoryItemBase foundItem1 + = InventoryArchiveUtils.FindItemByPath( + scene.InventoryService, userId, "Scripts/Objects/" + humanEscapedItemName); + + Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); +// Assert.That( +// foundItem1.CreatorId, Is.EqualTo(userUuid), +// "Loaded item non-uuid creator doesn't match that of the loading user"); + Assert.That( + foundItem1.Name, Is.EqualTo(itemName), + "Loaded item name doesn't match saved name"); + } + + /// + /// Test replication of an archive path to the user's inventory. + /// + [Test] + public void TestNewIarPath() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + Scene scene = new SceneHelpers().SetupScene(); + UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); + + Dictionary foldersCreated = new Dictionary(); + HashSet nodesLoaded = new HashSet(); + + string folder1Name = "1"; + string folder2aName = "2a"; + string folder2bName = "2b"; + + string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1Name, UUID.Random()); + string folder2aArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2aName, UUID.Random()); + string folder2bArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2bName, UUID.Random()); + + string iarPath1 = string.Join("", new string[] { folder1ArchiveName, folder2aArchiveName }); + string iarPath2 = string.Join("", new string[] { folder1ArchiveName, folder2bArchiveName }); + + { + // Test replication of path1 + new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false) + .ReplicateArchivePathToUserInventory( + iarPath1, scene.InventoryService.GetRootFolder(ua1.PrincipalID), + foldersCreated, nodesLoaded); + + List folder1Candidates + = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1Name); + Assert.That(folder1Candidates.Count, Is.EqualTo(1)); + + InventoryFolderBase folder1 = folder1Candidates[0]; + List folder2aCandidates + = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1, folder2aName); + Assert.That(folder2aCandidates.Count, Is.EqualTo(1)); + } + + { + // Test replication of path2 + new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false) + .ReplicateArchivePathToUserInventory( + iarPath2, scene.InventoryService.GetRootFolder(ua1.PrincipalID), + foldersCreated, nodesLoaded); + + List folder1Candidates + = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1Name); + Assert.That(folder1Candidates.Count, Is.EqualTo(1)); + + InventoryFolderBase folder1 = folder1Candidates[0]; + + List folder2aCandidates + = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1, folder2aName); + Assert.That(folder2aCandidates.Count, Is.EqualTo(1)); + + List folder2bCandidates + = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1, folder2bName); + Assert.That(folder2bCandidates.Count, Is.EqualTo(1)); + } + } + + /// + /// Test replication of a partly existing archive path to the user's inventory. This should create + /// a duplicate path without the merge option. + /// + [Test] + public void TestPartExistingIarPath() + { + TestHelpers.InMethod(); + //log4net.Config.XmlConfigurator.Configure(); + + Scene scene = new SceneHelpers().SetupScene(); + UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); + + string folder1ExistingName = "a"; + string folder2Name = "b"; + + InventoryFolderBase folder1 + = UserInventoryHelpers.CreateInventoryFolder( + scene.InventoryService, ua1.PrincipalID, folder1ExistingName, false); + + string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random()); + string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random()); + + string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName }); + + new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false) + .ReplicateArchivePathToUserInventory( + itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), + new Dictionary(), new HashSet()); + + List folder1PostCandidates + = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); + Assert.That(folder1PostCandidates.Count, Is.EqualTo(2)); + + // FIXME: Temporarily, we're going to do something messy to make sure we pick up the created folder. + InventoryFolderBase folder1Post = null; + foreach (InventoryFolderBase folder in folder1PostCandidates) + { + if (folder.ID != folder1.ID) + { + folder1Post = folder; + break; + } + } +// Assert.That(folder1Post.ID, Is.EqualTo(folder1.ID)); + + List folder2PostCandidates + = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1Post, "b"); + Assert.That(folder2PostCandidates.Count, Is.EqualTo(1)); + } + + /// + /// Test replication of a partly existing archive path to the user's inventory. This should create + /// a merged path. + /// + [Test] + public void TestMergeIarPath() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + Scene scene = new SceneHelpers().SetupScene(); + UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); + + string folder1ExistingName = "a"; + string folder2Name = "b"; + + InventoryFolderBase folder1 + = UserInventoryHelpers.CreateInventoryFolder( + scene.InventoryService, ua1.PrincipalID, folder1ExistingName, false); + + string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random()); + string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random()); + + string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName }); + + new InventoryArchiveReadRequest(scene, ua1, folder1ExistingName, (Stream)null, true) + .ReplicateArchivePathToUserInventory( + itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), + new Dictionary(), new HashSet()); + + List folder1PostCandidates + = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); + Assert.That(folder1PostCandidates.Count, Is.EqualTo(1)); + Assert.That(folder1PostCandidates[0].ID, Is.EqualTo(folder1.ID)); + + List folder2PostCandidates + = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1PostCandidates[0], "b"); + Assert.That(folder2PostCandidates.Count, Is.EqualTo(1)); + } + } +} + diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs new file mode 100644 index 0000000..1b521fc --- /dev/null +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs @@ -0,0 +1,194 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Threading; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Data; +using OpenSim.Framework; +using OpenSim.Framework.Serialization; +using OpenSim.Framework.Serialization.External; +using OpenSim.Framework.Communications; +using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; +using OpenSim.Region.CoreModules.World.Serialiser; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Scenes.Serialization; +using OpenSim.Services.Interfaces; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests +{ + [TestFixture] + public class InventoryArchiveLoadTests : InventoryArchiveTestCase + { + protected TestScene m_scene; + protected InventoryArchiverModule m_archiverModule; + + [SetUp] + public override void SetUp() + { + base.SetUp(); + + SerialiserModule serialiserModule = new SerialiserModule(); + m_archiverModule = new InventoryArchiverModule(); + + m_scene = new SceneHelpers().SetupScene(); + SceneHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule); + } + + [Test] + public void TestLoadCoalesecedItem() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "password"); + m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "password", m_iarStream); + + InventoryItemBase coaItem + = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_coaItemName); + + Assert.That(coaItem, Is.Not.Null, "Didn't find loaded item 1"); + + string assetXml = AssetHelpers.ReadAssetAsString(m_scene.AssetService, coaItem.AssetID); + + CoalescedSceneObjects coa; + bool readResult = CoalescedSceneObjectsSerializer.TryFromXml(assetXml, out coa); + + Assert.That(readResult, Is.True); + Assert.That(coa.Count, Is.EqualTo(2)); + + List coaObjects = coa.Objects; + Assert.That(coaObjects[0].UUID, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000120"))); + Assert.That(coaObjects[0].AbsolutePosition, Is.EqualTo(new Vector3(15, 30, 45))); + + Assert.That(coaObjects[1].UUID, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000140"))); + Assert.That(coaObjects[1].AbsolutePosition, Is.EqualTo(new Vector3(25, 50, 75))); + } + + /// + /// Test case where a creator account exists for the creator UUID embedded in item metadata and serialized + /// objects. + /// + [Test] + public void TestLoadIarCreatorAccountPresent() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "meowfood"); + + m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "meowfood", m_iarStream); + InventoryItemBase foundItem1 + = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_item1Name); + + Assert.That( + foundItem1.CreatorId, Is.EqualTo(m_uaLL1.PrincipalID.ToString()), + "Loaded item non-uuid creator doesn't match original"); + Assert.That( + foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL1.PrincipalID), + "Loaded item uuid creator doesn't match original"); + Assert.That(foundItem1.Owner, Is.EqualTo(m_uaLL1.PrincipalID), + "Loaded item owner doesn't match inventory reciever"); + + AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); + string xmlData = Utils.BytesToString(asset1.Data); + SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); + + Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL1.PrincipalID)); + } + +// /// +// /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where +// /// an account exists with the same name as the creator, though not the same id. +// /// +// [Test] +// public void TestLoadIarV0_1SameNameCreator() +// { +// TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); +// +// UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood"); +// UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire"); +// +// m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream); +// InventoryItemBase foundItem1 +// = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); +// +// Assert.That( +// foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()), +// "Loaded item non-uuid creator doesn't match original"); +// Assert.That( +// foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID), +// "Loaded item uuid creator doesn't match original"); +// Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID), +// "Loaded item owner doesn't match inventory reciever"); +// +// AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); +// string xmlData = Utils.BytesToString(asset1.Data); +// SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); +// +// Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID)); +// } + + /// + /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where + /// the creator or an account with the creator's name does not exist within the system. + /// + [Test] + public void TestLoadIarV0_1AbsentCreator() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "password"); + m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "password", m_iarStream); + + InventoryItemBase foundItem1 + = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); + + Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); + Assert.That( + foundItem1.CreatorId, Is.EqualTo(m_uaMT.PrincipalID.ToString()), + "Loaded item non-uuid creator doesn't match that of the loading user"); + Assert.That( + foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaMT.PrincipalID), + "Loaded item uuid creator doesn't match that of the loading user"); + + AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); + string xmlData = Utils.BytesToString(asset1.Data); + SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); + + Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaMT.PrincipalID)); + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs new file mode 100644 index 0000000..5e7e24c --- /dev/null +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs @@ -0,0 +1,424 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Threading; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Data; +using OpenSim.Framework; +using OpenSim.Framework.Serialization; +using OpenSim.Framework.Serialization.External; +using OpenSim.Framework.Communications; +using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; +using OpenSim.Region.CoreModules.World.Serialiser; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Scenes.Serialization; +using OpenSim.Services.Interfaces; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests +{ + [TestFixture] + public class InventoryArchiveSaveTests : InventoryArchiveTestCase + { + protected TestScene m_scene; + protected InventoryArchiverModule m_archiverModule; + + [SetUp] + public override void SetUp() + { + base.SetUp(); + + SerialiserModule serialiserModule = new SerialiserModule(); + m_archiverModule = new InventoryArchiverModule(); + + m_scene = new SceneHelpers().SetupScene(); + SceneHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule); + } + + /// + /// Test that the IAR has the required files in the right order. + /// + /// + /// At the moment, the only thing that matters is that the control file is the very first one. + /// + [Test] + public void TestOrder() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + MemoryStream archiveReadStream = new MemoryStream(m_iarStreamBytes); + TarArchiveReader tar = new TarArchiveReader(archiveReadStream); + string filePath; + TarArchiveReader.TarEntryType tarEntryType; + + byte[] data = tar.ReadEntry(out filePath, out tarEntryType); + Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH)); + + InventoryArchiveReadRequest iarr + = new InventoryArchiveReadRequest(null, null, null, (Stream)null, false); + iarr.LoadControlFile(filePath, data); + + Assert.That(iarr.ControlFileLoaded, Is.True); + } + + [Test] + public void TestSaveRootFolderToIar() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + string userFirstName = "Jock"; + string userLastName = "Stirrup"; + string userPassword = "troll"; + UUID userId = TestHelpers.ParseTail(0x20); + + UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword); + + MemoryStream archiveWriteStream = new MemoryStream(); + m_archiverModule.OnInventoryArchiveSaved += SaveCompleted; + + mre.Reset(); + m_archiverModule.ArchiveInventory( + Guid.NewGuid(), userFirstName, userLastName, "/", userPassword, archiveWriteStream); + mre.WaitOne(60000, false); + + // Test created iar + byte[] archive = archiveWriteStream.ToArray(); + MemoryStream archiveReadStream = new MemoryStream(archive); + TarArchiveReader tar = new TarArchiveReader(archiveReadStream); + +// InventoryArchiveUtils. + bool gotObjectsFolder = false; + + string objectsFolderName + = string.Format( + "{0}{1}", + ArchiveConstants.INVENTORY_PATH, + InventoryArchiveWriteRequest.CreateArchiveFolderName( + UserInventoryHelpers.GetInventoryFolder(m_scene.InventoryService, userId, "Objects"))); + + string filePath; + TarArchiveReader.TarEntryType tarEntryType; + + while (tar.ReadEntry(out filePath, out tarEntryType) != null) + { +// Console.WriteLine("Got {0}", filePath); + + // Lazily, we only bother to look for the system objects folder created when we call CreateUserWithInventory() + // XXX: But really we need to stop all that stuff being created in tests or check for such folders + // more thoroughly + if (filePath == objectsFolderName) + gotObjectsFolder = true; + } + + Assert.That(gotObjectsFolder, Is.True); + } + + [Test] + public void TestSaveNonRootFolderToIar() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + string userFirstName = "Jock"; + string userLastName = "Stirrup"; + string userPassword = "troll"; + UUID userId = TestHelpers.ParseTail(0x20); + + UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword); + + // Create base folder + InventoryFolderBase f1 + = UserInventoryHelpers.CreateInventoryFolder(m_scene.InventoryService, userId, "f1", true); + + // Create item1 + SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(1, userId, "My Little Dog Object", 0x5); + InventoryItemBase i1 = UserInventoryHelpers.AddInventoryItem(m_scene, so1, 0x50, 0x60, "f1"); + + // Create embedded folder + InventoryFolderBase f1_1 + = UserInventoryHelpers.CreateInventoryFolder(m_scene.InventoryService, userId, "f1/f1.1", true); + + // Create embedded item + SceneObjectGroup so1_1 = SceneHelpers.CreateSceneObject(1, userId, "My Little Cat Object", 0x6); + InventoryItemBase i2 = UserInventoryHelpers.AddInventoryItem(m_scene, so1_1, 0x500, 0x600, "f1/f1.1"); + + MemoryStream archiveWriteStream = new MemoryStream(); + m_archiverModule.OnInventoryArchiveSaved += SaveCompleted; + + mre.Reset(); + m_archiverModule.ArchiveInventory( + Guid.NewGuid(), userFirstName, userLastName, "f1", userPassword, archiveWriteStream); + mre.WaitOne(60000, false); + + // Test created iar + byte[] archive = archiveWriteStream.ToArray(); + MemoryStream archiveReadStream = new MemoryStream(archive); + TarArchiveReader tar = new TarArchiveReader(archiveReadStream); + +// InventoryArchiveUtils. + bool gotf1 = false, gotf1_1 = false, gotso1 = false, gotso2 = false; + + string f1FileName + = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, InventoryArchiveWriteRequest.CreateArchiveFolderName(f1)); + string f1_1FileName + = string.Format("{0}{1}", f1FileName, InventoryArchiveWriteRequest.CreateArchiveFolderName(f1_1)); + string so1FileName + = string.Format("{0}{1}", f1FileName, InventoryArchiveWriteRequest.CreateArchiveItemName(i1)); + string so2FileName + = string.Format("{0}{1}", f1_1FileName, InventoryArchiveWriteRequest.CreateArchiveItemName(i2)); + + string filePath; + TarArchiveReader.TarEntryType tarEntryType; + + while (tar.ReadEntry(out filePath, out tarEntryType) != null) + { +// Console.WriteLine("Got {0}", filePath); + + if (filePath == f1FileName) + gotf1 = true; + else if (filePath == f1_1FileName) + gotf1_1 = true; + else if (filePath == so1FileName) + gotso1 = true; + else if (filePath == so2FileName) + gotso2 = true; + } + +// Assert.That(gotControlFile, Is.True, "No control file in archive"); + Assert.That(gotf1, Is.True); + Assert.That(gotf1_1, Is.True); + Assert.That(gotso1, Is.True); + Assert.That(gotso2, Is.True); + + // TODO: Test presence of more files and contents of files. + } + + /// + /// Test saving a single inventory item to an IAR + /// (subject to change since there is no fixed format yet). + /// + [Test] + public void TestSaveItemToIar() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + // Create user + string userFirstName = "Jock"; + string userLastName = "Stirrup"; + string userPassword = "troll"; + UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020"); + UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword); + + // Create asset + UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); + SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50); + + UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); + AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); + m_scene.AssetService.Store(asset1); + + // Create item + UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080"); + string item1Name = "My Little Dog"; + InventoryItemBase item1 = new InventoryItemBase(); + item1.Name = item1Name; + item1.AssetID = asset1.FullID; + item1.ID = item1Id; + InventoryFolderBase objsFolder + = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, userId, "Objects")[0]; + item1.Folder = objsFolder.ID; + m_scene.AddInventoryItem(item1); + + MemoryStream archiveWriteStream = new MemoryStream(); + m_archiverModule.OnInventoryArchiveSaved += SaveCompleted; + + mre.Reset(); + m_archiverModule.ArchiveInventory( + Guid.NewGuid(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream); + mre.WaitOne(60000, false); + + byte[] archive = archiveWriteStream.ToArray(); + MemoryStream archiveReadStream = new MemoryStream(archive); + TarArchiveReader tar = new TarArchiveReader(archiveReadStream); + + //bool gotControlFile = false; + bool gotObject1File = false; + //bool gotObject2File = false; + string expectedObject1FileName = InventoryArchiveWriteRequest.CreateArchiveItemName(item1); + string expectedObject1FilePath = string.Format( + "{0}{1}", + ArchiveConstants.INVENTORY_PATH, + expectedObject1FileName); + + string filePath; + TarArchiveReader.TarEntryType tarEntryType; + +// Console.WriteLine("Reading archive"); + + while (tar.ReadEntry(out filePath, out tarEntryType) != null) + { + Console.WriteLine("Got {0}", filePath); + +// if (ArchiveConstants.CONTROL_FILE_PATH == filePath) +// { +// gotControlFile = true; +// } + + if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH) && filePath.EndsWith(".xml")) + { +// string fileName = filePath.Remove(0, "Objects/".Length); +// +// if (fileName.StartsWith(part1.Name)) +// { + Assert.That(expectedObject1FilePath, Is.EqualTo(filePath)); + gotObject1File = true; +// } +// else if (fileName.StartsWith(part2.Name)) +// { +// Assert.That(fileName, Is.EqualTo(expectedObject2FileName)); +// gotObject2File = true; +// } + } + } + +// Assert.That(gotControlFile, Is.True, "No control file in archive"); + Assert.That(gotObject1File, Is.True, "No item1 file in archive"); +// Assert.That(gotObject2File, Is.True, "No object2 file in archive"); + + // TODO: Test presence of more files and contents of files. + } + + /// + /// Test saving a single inventory item to an IAR without its asset + /// + [Test] + public void TestSaveItemToIarNoAssets() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + // Create user + string userFirstName = "Jock"; + string userLastName = "Stirrup"; + string userPassword = "troll"; + UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020"); + UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword); + + // Create asset + UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); + SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50); + + UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); + AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); + m_scene.AssetService.Store(asset1); + + // Create item + UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080"); + string item1Name = "My Little Dog"; + InventoryItemBase item1 = new InventoryItemBase(); + item1.Name = item1Name; + item1.AssetID = asset1.FullID; + item1.ID = item1Id; + InventoryFolderBase objsFolder + = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, userId, "Objects")[0]; + item1.Folder = objsFolder.ID; + m_scene.AddInventoryItem(item1); + + MemoryStream archiveWriteStream = new MemoryStream(); + + Dictionary options = new Dictionary(); + options.Add("noassets", true); + + // When we're not saving assets, archiving is being done synchronously. + m_archiverModule.ArchiveInventory( + Guid.NewGuid(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream, options); + + byte[] archive = archiveWriteStream.ToArray(); + MemoryStream archiveReadStream = new MemoryStream(archive); + TarArchiveReader tar = new TarArchiveReader(archiveReadStream); + + //bool gotControlFile = false; + bool gotObject1File = false; + //bool gotObject2File = false; + string expectedObject1FileName = InventoryArchiveWriteRequest.CreateArchiveItemName(item1); + string expectedObject1FilePath = string.Format( + "{0}{1}", + ArchiveConstants.INVENTORY_PATH, + expectedObject1FileName); + + string filePath; + TarArchiveReader.TarEntryType tarEntryType; + +// Console.WriteLine("Reading archive"); + + while (tar.ReadEntry(out filePath, out tarEntryType) != null) + { + Console.WriteLine("Got {0}", filePath); + +// if (ArchiveConstants.CONTROL_FILE_PATH == filePath) +// { +// gotControlFile = true; +// } + + if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH) && filePath.EndsWith(".xml")) + { +// string fileName = filePath.Remove(0, "Objects/".Length); +// +// if (fileName.StartsWith(part1.Name)) +// { + Assert.That(expectedObject1FilePath, Is.EqualTo(filePath)); + gotObject1File = true; +// } +// else if (fileName.StartsWith(part2.Name)) +// { +// Assert.That(fileName, Is.EqualTo(expectedObject2FileName)); +// gotObject2File = true; +// } + } + else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH)) + { + Assert.Fail("Found asset path in TestSaveItemToIarNoAssets()"); + } + } + +// Assert.That(gotControlFile, Is.True, "No control file in archive"); + Assert.That(gotObject1File, Is.True, "No item1 file in archive"); +// Assert.That(gotObject2File, Is.True, "No object2 file in archive"); + + // TODO: Test presence of more files and contents of files. + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs deleted file mode 100644 index 7ff29e5..0000000 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ /dev/null @@ -1,550 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using System.Threading; -using NUnit.Framework; -using OpenMetaverse; -using OpenSim.Data; -using OpenSim.Framework; -using OpenSim.Framework.Serialization; -using OpenSim.Framework.Serialization.External; -using OpenSim.Framework.Communications; -using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; -using OpenSim.Region.CoreModules.World.Serialiser; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.Framework.Scenes.Serialization; -using OpenSim.Services.Interfaces; -using OpenSim.Tests.Common; -using OpenSim.Tests.Common.Mock; - -namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests -{ - [TestFixture] - public class InventoryArchiverTests : InventoryArchiveTestCase - { - protected TestScene m_scene; - protected InventoryArchiverModule m_archiverModule; - - [SetUp] - public override void SetUp() - { - base.SetUp(); - - SerialiserModule serialiserModule = new SerialiserModule(); - m_archiverModule = new InventoryArchiverModule(); - - m_scene = new SceneHelpers().SetupScene(); - SceneHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule); - } - - [Test] - public void TestLoadCoalesecedItem() - { - TestHelpers.InMethod(); -// TestHelpers.EnableLogging(); - - UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "password"); - m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "password", m_iarStream); - - InventoryItemBase coaItem - = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_coaItemName); - - Assert.That(coaItem, Is.Not.Null, "Didn't find loaded item 1"); - - string assetXml = AssetHelpers.ReadAssetAsString(m_scene.AssetService, coaItem.AssetID); - - CoalescedSceneObjects coa; - bool readResult = CoalescedSceneObjectsSerializer.TryFromXml(assetXml, out coa); - - Assert.That(readResult, Is.True); - Assert.That(coa.Count, Is.EqualTo(2)); - - List coaObjects = coa.Objects; - Assert.That(coaObjects[0].UUID, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000120"))); - Assert.That(coaObjects[0].AbsolutePosition, Is.EqualTo(new Vector3(15, 30, 45))); - - Assert.That(coaObjects[1].UUID, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000140"))); - Assert.That(coaObjects[1].AbsolutePosition, Is.EqualTo(new Vector3(25, 50, 75))); - } - - /// - /// Test that the IAR has the required files in the right order. - /// - /// - /// At the moment, the only thing that matters is that the control file is the very first one. - /// - [Test] - public void TestOrder() - { - TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); - - MemoryStream archiveReadStream = new MemoryStream(m_iarStreamBytes); - TarArchiveReader tar = new TarArchiveReader(archiveReadStream); - string filePath; - TarArchiveReader.TarEntryType tarEntryType; - - byte[] data = tar.ReadEntry(out filePath, out tarEntryType); - Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH)); - - InventoryArchiveReadRequest iarr - = new InventoryArchiveReadRequest(null, null, null, (Stream)null, false); - iarr.LoadControlFile(filePath, data); - - Assert.That(iarr.ControlFileLoaded, Is.True); - } - - [Test] - public void TestSaveRootFolderToIar() - { - TestHelpers.InMethod(); -// TestHelpers.EnableLogging(); - - string userFirstName = "Jock"; - string userLastName = "Stirrup"; - string userPassword = "troll"; - UUID userId = TestHelpers.ParseTail(0x20); - - UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword); - - MemoryStream archiveWriteStream = new MemoryStream(); - m_archiverModule.OnInventoryArchiveSaved += SaveCompleted; - - mre.Reset(); - m_archiverModule.ArchiveInventory( - Guid.NewGuid(), userFirstName, userLastName, "/", userPassword, archiveWriteStream); - mre.WaitOne(60000, false); - - // Test created iar - byte[] archive = archiveWriteStream.ToArray(); - MemoryStream archiveReadStream = new MemoryStream(archive); - TarArchiveReader tar = new TarArchiveReader(archiveReadStream); - -// InventoryArchiveUtils. - bool gotObjectsFolder = false; - - string objectsFolderName - = string.Format( - "{0}{1}", - ArchiveConstants.INVENTORY_PATH, - InventoryArchiveWriteRequest.CreateArchiveFolderName( - UserInventoryHelpers.GetInventoryFolder(m_scene.InventoryService, userId, "Objects"))); - - string filePath; - TarArchiveReader.TarEntryType tarEntryType; - - while (tar.ReadEntry(out filePath, out tarEntryType) != null) - { -// Console.WriteLine("Got {0}", filePath); - - // Lazily, we only bother to look for the system objects folder created when we call CreateUserWithInventory() - // XXX: But really we need to stop all that stuff being created in tests or check for such folders - // more thoroughly - if (filePath == objectsFolderName) - gotObjectsFolder = true; - } - - Assert.That(gotObjectsFolder, Is.True); - } - - [Test] - public void TestSaveNonRootFolderToIar() - { - TestHelpers.InMethod(); -// TestHelpers.EnableLogging(); - - string userFirstName = "Jock"; - string userLastName = "Stirrup"; - string userPassword = "troll"; - UUID userId = TestHelpers.ParseTail(0x20); - - UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword); - - // Create base folder - InventoryFolderBase f1 - = UserInventoryHelpers.CreateInventoryFolder(m_scene.InventoryService, userId, "f1", true); - - // Create item1 - SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(1, userId, "My Little Dog Object", 0x5); - InventoryItemBase i1 = UserInventoryHelpers.AddInventoryItem(m_scene, so1, 0x50, 0x60, "f1"); - - // Create embedded folder - InventoryFolderBase f1_1 - = UserInventoryHelpers.CreateInventoryFolder(m_scene.InventoryService, userId, "f1/f1.1", true); - - // Create embedded item - SceneObjectGroup so1_1 = SceneHelpers.CreateSceneObject(1, userId, "My Little Cat Object", 0x6); - InventoryItemBase i2 = UserInventoryHelpers.AddInventoryItem(m_scene, so1_1, 0x500, 0x600, "f1/f1.1"); - - MemoryStream archiveWriteStream = new MemoryStream(); - m_archiverModule.OnInventoryArchiveSaved += SaveCompleted; - - mre.Reset(); - m_archiverModule.ArchiveInventory( - Guid.NewGuid(), userFirstName, userLastName, "f1", userPassword, archiveWriteStream); - mre.WaitOne(60000, false); - - // Test created iar - byte[] archive = archiveWriteStream.ToArray(); - MemoryStream archiveReadStream = new MemoryStream(archive); - TarArchiveReader tar = new TarArchiveReader(archiveReadStream); - -// InventoryArchiveUtils. - bool gotf1 = false, gotf1_1 = false, gotso1 = false, gotso2 = false; - - string f1FileName - = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, InventoryArchiveWriteRequest.CreateArchiveFolderName(f1)); - string f1_1FileName - = string.Format("{0}{1}", f1FileName, InventoryArchiveWriteRequest.CreateArchiveFolderName(f1_1)); - string so1FileName - = string.Format("{0}{1}", f1FileName, InventoryArchiveWriteRequest.CreateArchiveItemName(i1)); - string so2FileName - = string.Format("{0}{1}", f1_1FileName, InventoryArchiveWriteRequest.CreateArchiveItemName(i2)); - - string filePath; - TarArchiveReader.TarEntryType tarEntryType; - - while (tar.ReadEntry(out filePath, out tarEntryType) != null) - { -// Console.WriteLine("Got {0}", filePath); - - if (filePath == f1FileName) - gotf1 = true; - else if (filePath == f1_1FileName) - gotf1_1 = true; - else if (filePath == so1FileName) - gotso1 = true; - else if (filePath == so2FileName) - gotso2 = true; - } - -// Assert.That(gotControlFile, Is.True, "No control file in archive"); - Assert.That(gotf1, Is.True); - Assert.That(gotf1_1, Is.True); - Assert.That(gotso1, Is.True); - Assert.That(gotso2, Is.True); - - // TODO: Test presence of more files and contents of files. - } - - /// - /// Test saving a single inventory item to an IAR - /// (subject to change since there is no fixed format yet). - /// - [Test] - public void TestSaveItemToIar() - { - TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); - - // Create user - string userFirstName = "Jock"; - string userLastName = "Stirrup"; - string userPassword = "troll"; - UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020"); - UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword); - - // Create asset - UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); - SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50); - - UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); - AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); - m_scene.AssetService.Store(asset1); - - // Create item - UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080"); - string item1Name = "My Little Dog"; - InventoryItemBase item1 = new InventoryItemBase(); - item1.Name = item1Name; - item1.AssetID = asset1.FullID; - item1.ID = item1Id; - InventoryFolderBase objsFolder - = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, userId, "Objects")[0]; - item1.Folder = objsFolder.ID; - m_scene.AddInventoryItem(item1); - - MemoryStream archiveWriteStream = new MemoryStream(); - m_archiverModule.OnInventoryArchiveSaved += SaveCompleted; - - mre.Reset(); - m_archiverModule.ArchiveInventory( - Guid.NewGuid(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream); - mre.WaitOne(60000, false); - - byte[] archive = archiveWriteStream.ToArray(); - MemoryStream archiveReadStream = new MemoryStream(archive); - TarArchiveReader tar = new TarArchiveReader(archiveReadStream); - - //bool gotControlFile = false; - bool gotObject1File = false; - //bool gotObject2File = false; - string expectedObject1FileName = InventoryArchiveWriteRequest.CreateArchiveItemName(item1); - string expectedObject1FilePath = string.Format( - "{0}{1}", - ArchiveConstants.INVENTORY_PATH, - expectedObject1FileName); - - string filePath; - TarArchiveReader.TarEntryType tarEntryType; - -// Console.WriteLine("Reading archive"); - - while (tar.ReadEntry(out filePath, out tarEntryType) != null) - { - Console.WriteLine("Got {0}", filePath); - -// if (ArchiveConstants.CONTROL_FILE_PATH == filePath) -// { -// gotControlFile = true; -// } - - if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH) && filePath.EndsWith(".xml")) - { -// string fileName = filePath.Remove(0, "Objects/".Length); -// -// if (fileName.StartsWith(part1.Name)) -// { - Assert.That(expectedObject1FilePath, Is.EqualTo(filePath)); - gotObject1File = true; -// } -// else if (fileName.StartsWith(part2.Name)) -// { -// Assert.That(fileName, Is.EqualTo(expectedObject2FileName)); -// gotObject2File = true; -// } - } - } - -// Assert.That(gotControlFile, Is.True, "No control file in archive"); - Assert.That(gotObject1File, Is.True, "No item1 file in archive"); -// Assert.That(gotObject2File, Is.True, "No object2 file in archive"); - - // TODO: Test presence of more files and contents of files. - } - - /// - /// Test saving a single inventory item to an IAR without its asset - /// - [Test] - public void TestSaveItemToIarNoAssets() - { - TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); - - // Create user - string userFirstName = "Jock"; - string userLastName = "Stirrup"; - string userPassword = "troll"; - UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020"); - UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword); - - // Create asset - UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); - SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50); - - UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); - AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); - m_scene.AssetService.Store(asset1); - - // Create item - UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080"); - string item1Name = "My Little Dog"; - InventoryItemBase item1 = new InventoryItemBase(); - item1.Name = item1Name; - item1.AssetID = asset1.FullID; - item1.ID = item1Id; - InventoryFolderBase objsFolder - = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, userId, "Objects")[0]; - item1.Folder = objsFolder.ID; - m_scene.AddInventoryItem(item1); - - MemoryStream archiveWriteStream = new MemoryStream(); - - Dictionary options = new Dictionary(); - options.Add("noassets", true); - - // When we're not saving assets, archiving is being done synchronously. - m_archiverModule.ArchiveInventory( - Guid.NewGuid(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream, options); - - byte[] archive = archiveWriteStream.ToArray(); - MemoryStream archiveReadStream = new MemoryStream(archive); - TarArchiveReader tar = new TarArchiveReader(archiveReadStream); - - //bool gotControlFile = false; - bool gotObject1File = false; - //bool gotObject2File = false; - string expectedObject1FileName = InventoryArchiveWriteRequest.CreateArchiveItemName(item1); - string expectedObject1FilePath = string.Format( - "{0}{1}", - ArchiveConstants.INVENTORY_PATH, - expectedObject1FileName); - - string filePath; - TarArchiveReader.TarEntryType tarEntryType; - -// Console.WriteLine("Reading archive"); - - while (tar.ReadEntry(out filePath, out tarEntryType) != null) - { - Console.WriteLine("Got {0}", filePath); - -// if (ArchiveConstants.CONTROL_FILE_PATH == filePath) -// { -// gotControlFile = true; -// } - - if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH) && filePath.EndsWith(".xml")) - { -// string fileName = filePath.Remove(0, "Objects/".Length); -// -// if (fileName.StartsWith(part1.Name)) -// { - Assert.That(expectedObject1FilePath, Is.EqualTo(filePath)); - gotObject1File = true; -// } -// else if (fileName.StartsWith(part2.Name)) -// { -// Assert.That(fileName, Is.EqualTo(expectedObject2FileName)); -// gotObject2File = true; -// } - } - else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH)) - { - Assert.Fail("Found asset path in TestSaveItemToIarNoAssets()"); - } - } - -// Assert.That(gotControlFile, Is.True, "No control file in archive"); - Assert.That(gotObject1File, Is.True, "No item1 file in archive"); -// Assert.That(gotObject2File, Is.True, "No object2 file in archive"); - - // TODO: Test presence of more files and contents of files. - } - - /// - /// Test case where a creator account exists for the creator UUID embedded in item metadata and serialized - /// objects. - /// - [Test] - public void TestLoadIarCreatorAccountPresent() - { - TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); - - UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "meowfood"); - - m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "meowfood", m_iarStream); - InventoryItemBase foundItem1 - = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_item1Name); - - Assert.That( - foundItem1.CreatorId, Is.EqualTo(m_uaLL1.PrincipalID.ToString()), - "Loaded item non-uuid creator doesn't match original"); - Assert.That( - foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL1.PrincipalID), - "Loaded item uuid creator doesn't match original"); - Assert.That(foundItem1.Owner, Is.EqualTo(m_uaLL1.PrincipalID), - "Loaded item owner doesn't match inventory reciever"); - - AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); - string xmlData = Utils.BytesToString(asset1.Data); - SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); - - Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL1.PrincipalID)); - } - -// /// -// /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where -// /// an account exists with the same name as the creator, though not the same id. -// /// -// [Test] -// public void TestLoadIarV0_1SameNameCreator() -// { -// TestHelpers.InMethod(); -// TestHelpers.EnableLogging(); -// -// UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood"); -// UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire"); -// -// m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream); -// InventoryItemBase foundItem1 -// = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); -// -// Assert.That( -// foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()), -// "Loaded item non-uuid creator doesn't match original"); -// Assert.That( -// foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID), -// "Loaded item uuid creator doesn't match original"); -// Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID), -// "Loaded item owner doesn't match inventory reciever"); -// -// AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); -// string xmlData = Utils.BytesToString(asset1.Data); -// SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); -// -// Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID)); -// } - - /// - /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where - /// the creator or an account with the creator's name does not exist within the system. - /// - [Test] - public void TestLoadIarV0_1AbsentCreator() - { - TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); - - UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "password"); - m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "password", m_iarStream); - - InventoryItemBase foundItem1 - = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); - - Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); - Assert.That( - foundItem1.CreatorId, Is.EqualTo(m_uaMT.PrincipalID.ToString()), - "Loaded item non-uuid creator doesn't match that of the loading user"); - Assert.That( - foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaMT.PrincipalID), - "Loaded item uuid creator doesn't match that of the loading user"); - - AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); - string xmlData = Utils.BytesToString(asset1.Data); - SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); - - Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaMT.PrincipalID)); - } - } -} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs deleted file mode 100644 index 1871576..0000000 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs +++ /dev/null @@ -1,477 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using System.Threading; -using NUnit.Framework; -using OpenMetaverse; -using OpenSim.Data; -using OpenSim.Framework; -using OpenSim.Framework.Serialization; -using OpenSim.Framework.Serialization.External; -using OpenSim.Framework.Communications; -using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; -using OpenSim.Region.CoreModules.World.Serialiser; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.Framework.Scenes.Serialization; -using OpenSim.Services.Interfaces; -using OpenSim.Tests.Common; -using OpenSim.Tests.Common.Mock; - -namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests -{ - [TestFixture] - public class PathTests : InventoryArchiveTestCase - { - /// - /// Test saving an inventory path to a V0.1 OpenSim Inventory Archive - /// (subject to change since there is no fixed format yet). - /// - [Test] - public void TestSavePathToIarV0_1() - { - TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); - - InventoryArchiverModule archiverModule = new InventoryArchiverModule(); - - Scene scene = new SceneHelpers().SetupScene(); - SceneHelpers.SetupSceneModules(scene, archiverModule); - - // Create user - string userFirstName = "Jock"; - string userLastName = "Stirrup"; - string userPassword = "troll"; - UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020"); - UserAccountHelpers.CreateUserWithInventory(scene, userFirstName, userLastName, userId, userPassword); - - // Create asset - SceneObjectGroup object1; - SceneObjectPart part1; - { - string partName = "My Little Dog Object"; - UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); - PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere(); - Vector3 groupPosition = new Vector3(10, 20, 30); - Quaternion rotationOffset = new Quaternion(20, 30, 40, 50); - Vector3 offsetPosition = new Vector3(5, 10, 15); - - part1 = new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, offsetPosition); - part1.Name = partName; - - object1 = new SceneObjectGroup(part1); - scene.AddNewSceneObject(object1, false); - } - - UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); - AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); - scene.AssetService.Store(asset1); - - // Create item - UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080"); - InventoryItemBase item1 = new InventoryItemBase(); - item1.Name = "My Little Dog"; - item1.AssetID = asset1.FullID; - item1.ID = item1Id; - InventoryFolderBase objsFolder - = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, userId, "Objects")[0]; - item1.Folder = objsFolder.ID; - scene.AddInventoryItem(item1); - - MemoryStream archiveWriteStream = new MemoryStream(); - archiverModule.OnInventoryArchiveSaved += SaveCompleted; - - // Test saving a particular path - mre.Reset(); - archiverModule.ArchiveInventory( - Guid.NewGuid(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream); - mre.WaitOne(60000, false); - - byte[] archive = archiveWriteStream.ToArray(); - MemoryStream archiveReadStream = new MemoryStream(archive); - TarArchiveReader tar = new TarArchiveReader(archiveReadStream); - - //bool gotControlFile = false; - bool gotObject1File = false; - //bool gotObject2File = false; - string expectedObject1FileName = InventoryArchiveWriteRequest.CreateArchiveItemName(item1); - string expectedObject1FilePath = string.Format( - "{0}{1}{2}", - ArchiveConstants.INVENTORY_PATH, - InventoryArchiveWriteRequest.CreateArchiveFolderName(objsFolder), - expectedObject1FileName); - - string filePath; - TarArchiveReader.TarEntryType tarEntryType; - -// Console.WriteLine("Reading archive"); - - while (tar.ReadEntry(out filePath, out tarEntryType) != null) - { -// Console.WriteLine("Got {0}", filePath); - -// if (ArchiveConstants.CONTROL_FILE_PATH == filePath) -// { -// gotControlFile = true; -// } - - if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH) && filePath.EndsWith(".xml")) - { -// string fileName = filePath.Remove(0, "Objects/".Length); -// -// if (fileName.StartsWith(part1.Name)) -// { - Assert.That(expectedObject1FilePath, Is.EqualTo(filePath)); - gotObject1File = true; -// } -// else if (fileName.StartsWith(part2.Name)) -// { -// Assert.That(fileName, Is.EqualTo(expectedObject2FileName)); -// gotObject2File = true; -// } - } - } - -// Assert.That(gotControlFile, Is.True, "No control file in archive"); - Assert.That(gotObject1File, Is.True, "No item1 file in archive"); -// Assert.That(gotObject2File, Is.True, "No object2 file in archive"); - - // TODO: Test presence of more files and contents of files. - } - - /// - /// Test loading an IAR to various different inventory paths. - /// - [Test] - public void TestLoadIarToInventoryPaths() - { - TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); - - SerialiserModule serialiserModule = new SerialiserModule(); - InventoryArchiverModule archiverModule = new InventoryArchiverModule(); - - // Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene - Scene scene = new SceneHelpers().SetupScene(); - - SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); - - UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "meowfood"); - UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire"); - - archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream); - InventoryItemBase foundItem1 - = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); - - Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); - - // Now try loading to a root child folder - UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xA", false); - MemoryStream archiveReadStream = new MemoryStream(m_iarStream.ToArray()); - archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xA", "meowfood", archiveReadStream); - - InventoryItemBase foundItem2 - = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, "xA/" + m_item1Name); - Assert.That(foundItem2, Is.Not.Null, "Didn't find loaded item 2"); - - // Now try loading to a more deeply nested folder - UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC", false); - archiveReadStream = new MemoryStream(archiveReadStream.ToArray()); - archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xB/xC", "meowfood", archiveReadStream); - - InventoryItemBase foundItem3 - = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC/" + m_item1Name); - Assert.That(foundItem3, Is.Not.Null, "Didn't find loaded item 3"); - } - - /// - /// Test that things work when the load path specified starts with a slash - /// - [Test] - public void TestLoadIarPathStartsWithSlash() - { - TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); - - SerialiserModule serialiserModule = new SerialiserModule(); - InventoryArchiverModule archiverModule = new InventoryArchiverModule(); - Scene scene = new SceneHelpers().SetupScene(); - SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); - - UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "password"); - archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/Objects", "password", m_iarStream); - - InventoryItemBase foundItem1 - = InventoryArchiveUtils.FindItemByPath( - scene.InventoryService, m_uaMT.PrincipalID, "/Objects/" + m_item1Name); - - Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1 in TestLoadIarFolderStartsWithSlash()"); - } - - [Test] - public void TestLoadIarPathWithEscapedChars() - { - TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); - - string itemName = "You & you are a mean/man/"; - string humanEscapedItemName = @"You & you are a mean\/man\/"; - string userPassword = "meowfood"; - - InventoryArchiverModule archiverModule = new InventoryArchiverModule(); - - Scene scene = new SceneHelpers().SetupScene(); - SceneHelpers.SetupSceneModules(scene, archiverModule); - - // Create user - string userFirstName = "Jock"; - string userLastName = "Stirrup"; - UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020"); - UserAccountHelpers.CreateUserWithInventory(scene, userFirstName, userLastName, userId, "meowfood"); - - // Create asset - SceneObjectGroup object1; - SceneObjectPart part1; - { - string partName = "part name"; - UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); - PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere(); - Vector3 groupPosition = new Vector3(10, 20, 30); - Quaternion rotationOffset = new Quaternion(20, 30, 40, 50); - Vector3 offsetPosition = new Vector3(5, 10, 15); - - part1 - = new SceneObjectPart( - ownerId, shape, groupPosition, rotationOffset, offsetPosition); - part1.Name = partName; - - object1 = new SceneObjectGroup(part1); - scene.AddNewSceneObject(object1, false); - } - - UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); - AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); - scene.AssetService.Store(asset1); - - // Create item - UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080"); - InventoryItemBase item1 = new InventoryItemBase(); - item1.Name = itemName; - item1.AssetID = asset1.FullID; - item1.ID = item1Id; - InventoryFolderBase objsFolder - = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, userId, "Objects")[0]; - item1.Folder = objsFolder.ID; - scene.AddInventoryItem(item1); - - MemoryStream archiveWriteStream = new MemoryStream(); - archiverModule.OnInventoryArchiveSaved += SaveCompleted; - - mre.Reset(); - archiverModule.ArchiveInventory( - Guid.NewGuid(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream); - mre.WaitOne(60000, false); - - // LOAD ITEM - MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); - - archiverModule.DearchiveInventory(userFirstName, userLastName, "Scripts", userPassword, archiveReadStream); - - InventoryItemBase foundItem1 - = InventoryArchiveUtils.FindItemByPath( - scene.InventoryService, userId, "Scripts/Objects/" + humanEscapedItemName); - - Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); -// Assert.That( -// foundItem1.CreatorId, Is.EqualTo(userUuid), -// "Loaded item non-uuid creator doesn't match that of the loading user"); - Assert.That( - foundItem1.Name, Is.EqualTo(itemName), - "Loaded item name doesn't match saved name"); - } - - /// - /// Test replication of an archive path to the user's inventory. - /// - [Test] - public void TestNewIarPath() - { - TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); - - Scene scene = new SceneHelpers().SetupScene(); - UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); - - Dictionary foldersCreated = new Dictionary(); - HashSet nodesLoaded = new HashSet(); - - string folder1Name = "1"; - string folder2aName = "2a"; - string folder2bName = "2b"; - - string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1Name, UUID.Random()); - string folder2aArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2aName, UUID.Random()); - string folder2bArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2bName, UUID.Random()); - - string iarPath1 = string.Join("", new string[] { folder1ArchiveName, folder2aArchiveName }); - string iarPath2 = string.Join("", new string[] { folder1ArchiveName, folder2bArchiveName }); - - { - // Test replication of path1 - new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false) - .ReplicateArchivePathToUserInventory( - iarPath1, scene.InventoryService.GetRootFolder(ua1.PrincipalID), - foldersCreated, nodesLoaded); - - List folder1Candidates - = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1Name); - Assert.That(folder1Candidates.Count, Is.EqualTo(1)); - - InventoryFolderBase folder1 = folder1Candidates[0]; - List folder2aCandidates - = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1, folder2aName); - Assert.That(folder2aCandidates.Count, Is.EqualTo(1)); - } - - { - // Test replication of path2 - new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false) - .ReplicateArchivePathToUserInventory( - iarPath2, scene.InventoryService.GetRootFolder(ua1.PrincipalID), - foldersCreated, nodesLoaded); - - List folder1Candidates - = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1Name); - Assert.That(folder1Candidates.Count, Is.EqualTo(1)); - - InventoryFolderBase folder1 = folder1Candidates[0]; - - List folder2aCandidates - = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1, folder2aName); - Assert.That(folder2aCandidates.Count, Is.EqualTo(1)); - - List folder2bCandidates - = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1, folder2bName); - Assert.That(folder2bCandidates.Count, Is.EqualTo(1)); - } - } - - /// - /// Test replication of a partly existing archive path to the user's inventory. This should create - /// a duplicate path without the merge option. - /// - [Test] - public void TestPartExistingIarPath() - { - TestHelpers.InMethod(); - //log4net.Config.XmlConfigurator.Configure(); - - Scene scene = new SceneHelpers().SetupScene(); - UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); - - string folder1ExistingName = "a"; - string folder2Name = "b"; - - InventoryFolderBase folder1 - = UserInventoryHelpers.CreateInventoryFolder( - scene.InventoryService, ua1.PrincipalID, folder1ExistingName, false); - - string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random()); - string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random()); - - string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName }); - - new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false) - .ReplicateArchivePathToUserInventory( - itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), - new Dictionary(), new HashSet()); - - List folder1PostCandidates - = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); - Assert.That(folder1PostCandidates.Count, Is.EqualTo(2)); - - // FIXME: Temporarily, we're going to do something messy to make sure we pick up the created folder. - InventoryFolderBase folder1Post = null; - foreach (InventoryFolderBase folder in folder1PostCandidates) - { - if (folder.ID != folder1.ID) - { - folder1Post = folder; - break; - } - } -// Assert.That(folder1Post.ID, Is.EqualTo(folder1.ID)); - - List folder2PostCandidates - = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1Post, "b"); - Assert.That(folder2PostCandidates.Count, Is.EqualTo(1)); - } - - /// - /// Test replication of a partly existing archive path to the user's inventory. This should create - /// a merged path. - /// - [Test] - public void TestMergeIarPath() - { - TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); - - Scene scene = new SceneHelpers().SetupScene(); - UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); - - string folder1ExistingName = "a"; - string folder2Name = "b"; - - InventoryFolderBase folder1 - = UserInventoryHelpers.CreateInventoryFolder( - scene.InventoryService, ua1.PrincipalID, folder1ExistingName, false); - - string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random()); - string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random()); - - string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName }); - - new InventoryArchiveReadRequest(scene, ua1, folder1ExistingName, (Stream)null, true) - .ReplicateArchivePathToUserInventory( - itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), - new Dictionary(), new HashSet()); - - List folder1PostCandidates - = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); - Assert.That(folder1PostCandidates.Count, Is.EqualTo(1)); - Assert.That(folder1PostCandidates[0].ID, Is.EqualTo(folder1.ID)); - - List folder2PostCandidates - = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1PostCandidates[0], "b"); - Assert.That(folder2PostCandidates.Count, Is.EqualTo(1)); - } - } -} \ No newline at end of file -- cgit v1.1 From 3108d18ffb2fc4d2b10eac696842335b25aaf088 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 16 Feb 2013 05:09:27 +0100 Subject: Fix shape parameters sent for meshes tosupport the full number of faces --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index bd4a2d1..a187190 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -3802,6 +3802,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP part.Shape.LightEntry = false; } } + + if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh)) + { + // Ensure that mesh has at least 8 valid faces + part.Shape.ProfileBegin = 12500; + part.Shape.ProfileEnd = 0; + part.Shape.ProfileHollow = 27500; + } } #region UpdateFlags to packet type conversion -- cgit v1.1 From e549c2922ab2af6c4fbe08c3492918a5d5f4ba61 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 16 Feb 2013 19:28:38 -0800 Subject: BulletSim: fix physical object appearing to slowly float off when they stop moving. --- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 0323b0d..4bb2a9e 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -1667,7 +1667,7 @@ public class BSPrim : BSPhysObject // _velocity = entprop.Velocity; // DEBUG DEBUG DEBUG -- smooth velocity changes a bit. The simulator seems to be // very sensitive to velocity changes. - if (!entprop.Velocity.ApproxEquals(_velocity, 0.1f)) + if (entprop.Velocity == OMV.Vector3.Zero || !entprop.Velocity.ApproxEquals(_velocity, 0.1f)) _velocity = entprop.Velocity; _acceleration = entprop.Acceleration; _rotationalVelocity = entprop.RotationalVelocity; -- cgit v1.1 From 6560d80fa856fb73c51a7ccd37f720c25b12d42d Mon Sep 17 00:00:00 2001 From: teravus Date: Sat, 16 Feb 2013 22:54:37 -0500 Subject: * Fix walking to via autopilot. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 70e3952..9c1d2b6 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1847,7 +1847,11 @@ namespace OpenSim.Region.Framework.Scenes // Get terrain height for sub-region in a megaregion if necessary int X = (int)((m_scene.RegionInfo.RegionLocX * Constants.RegionSize) + pos.X); int Y = (int)((m_scene.RegionInfo.RegionLocY * Constants.RegionSize) + pos.Y); - UUID target_regionID = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, X, Y).RegionID; + GridRegion target_region = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, X, Y); + // If X and Y is NaN, target_region will be null + if (target_region == null) + return; + UUID target_regionID = target_region.RegionID; Scene targetScene = m_scene; if (!SceneManager.Instance.TryGetScene(target_regionID, out targetScene)) -- cgit v1.1 From 885b45b112607e3edf12838cf01cfefa6da884ae Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 16 Feb 2013 22:14:38 -0800 Subject: BulletSim: rework parameter setting for different types of values (like vectors or quaternions). --- OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs | 4 +- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 6 +- .../Physics/BulletSPlugin/BSLinksetConstraints.cs | 4 +- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 674 ++++++++++----------- OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 54 +- 5 files changed, 348 insertions(+), 394 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs index 39e62dd..15fa52b 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs @@ -1133,8 +1133,8 @@ private sealed class BulletConstraintXNA : BulletConstraint p.numberOfSolverIterations = o[0].numberOfSolverIterations; p.linksetImplementation = BSParam.LinksetImplementation; - p.linkConstraintUseFrameOffset = BSParam.LinkConstraintUseFrameOffset; - p.linkConstraintEnableTransMotor = BSParam.LinkConstraintEnableTransMotor; + p.linkConstraintUseFrameOffset = BSParam.NumericBool(BSParam.LinkConstraintUseFrameOffset); + p.linkConstraintEnableTransMotor = BSParam.NumericBool(BSParam.LinkConstraintEnableTransMotor); p.linkConstraintTransMotorMaxVel = BSParam.LinkConstraintTransMotorMaxVel; p.linkConstraintTransMotorMaxForce = BSParam.LinkConstraintTransMotorMaxForce; p.linkConstraintERP = BSParam.LinkConstraintERP; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 41d353a..e6933f9 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -144,7 +144,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin enableAngularVerticalAttraction = true; enableAngularDeflection = false; enableAngularBanking = false; - if (BSParam.VehicleDebuggingEnabled != ConfigurationParameters.numericFalse) + if (BSParam.VehicleDebuggingEnabled) { enableAngularVerticalAttraction = true; enableAngularDeflection = false; @@ -607,8 +607,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle. // Maybe compute linear and angular factor and damping from params. PhysicsScene.PE.SetAngularDamping(Prim.PhysBody, BSParam.VehicleAngularDamping); - PhysicsScene.PE.SetLinearFactor(Prim.PhysBody, BSParam.VehicleLinearFactorV); - PhysicsScene.PE.SetAngularFactorV(Prim.PhysBody, BSParam.VehicleAngularFactorV); + PhysicsScene.PE.SetLinearFactor(Prim.PhysBody, BSParam.VehicleLinearFactor); + PhysicsScene.PE.SetAngularFactorV(Prim.PhysBody, BSParam.VehicleAngularFactor); // Vehicles report collision events so we know when it's on the ground PhysicsScene.PE.AddToCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index cc814d1..6d252ca 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -223,8 +223,8 @@ public sealed class BSLinksetConstraints : BSLinkset constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); // tweek the constraint to increase stability - constrain.UseFrameOffset(BSParam.BoolNumeric(BSParam.LinkConstraintUseFrameOffset)); - constrain.TranslationalLimitMotor(BSParam.BoolNumeric(BSParam.LinkConstraintEnableTransMotor), + constrain.UseFrameOffset(BSParam.LinkConstraintUseFrameOffset); + constrain.TranslationalLimitMotor(BSParam.LinkConstraintEnableTransMotor, BSParam.LinkConstraintTransMotorMaxVel, BSParam.LinkConstraintTransMotorMaxForce); constrain.SetCFMAndERP(BSParam.LinkConstraintCFM, BSParam.LinkConstraintERP); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 329169f..c2a9671 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -37,6 +37,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin { public static class BSParam { + private static string LogHeader = "[BULLETSIM PARAMETERS]"; + // Level of Detail values kept as float because that's what the Meshmerizer wants public static float MeshLOD { get; private set; } public static float MeshCircularLOD { get; private set; } @@ -80,14 +82,13 @@ public static class BSParam // Physics Engine operation public static float MaxPersistantManifoldPoolSize; public static float MaxCollisionAlgorithmPoolSize; - public static float ShouldDisableContactPoolDynamicAllocation; - public static float ShouldForceUpdateAllAabbs; - public static float ShouldRandomizeSolverOrder; - public static float ShouldSplitSimulationIslands; - public static float ShouldEnableFrictionCaching; + public static bool ShouldDisableContactPoolDynamicAllocation; + public static bool ShouldForceUpdateAllAabbs; + public static bool ShouldRandomizeSolverOrder; + public static bool ShouldSplitSimulationIslands; + public static bool ShouldEnableFrictionCaching; public static float NumberOfSolverIterations; - public static bool UseSingleSidedMeshes { get { return UseSingleSidedMeshesF != ConfigurationParameters.numericFalse; } } - public static float UseSingleSidedMeshesF; + public static bool UseSingleSidedMeshes; public static float GlobalContactBreakingThreshold; // Avatar parameters @@ -112,16 +113,14 @@ public static class BSParam public static float VehicleAngularDamping { get; private set; } public static float VehicleFriction { get; private set; } public static float VehicleRestitution { get; private set; } - public static float VehicleLinearFactor { get; private set; } - public static Vector3 VehicleLinearFactorV { get; private set; } - public static float VehicleAngularFactor { get; private set; } - public static Vector3 VehicleAngularFactorV { get; private set; } + public static Vector3 VehicleLinearFactor { get; private set; } + public static Vector3 VehicleAngularFactor { get; private set; } public static float VehicleGroundGravityFudge { get; private set; } - public static float VehicleDebuggingEnabled { get; private set; } + public static bool VehicleDebuggingEnabled { get; private set; } public static float LinksetImplementation { get; private set; } - public static float LinkConstraintUseFrameOffset { get; private set; } - public static float LinkConstraintEnableTransMotor { get; private set; } + public static bool LinkConstraintUseFrameOffset { get; private set; } + public static bool LinkConstraintEnableTransMotor { get; private set; } public static float LinkConstraintTransMotorMaxVel { get; private set; } public static float LinkConstraintTransMotorMaxForce { get; private set; } public static float LinkConstraintERP { get; private set; } @@ -141,40 +140,106 @@ public static class BSParam public const float MinRestitution = 0f; public const float MaxRestitution = 1f; - // =========================================================================== - public delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val); - public delegate float ParamGet(BSScene scene); - public delegate void ParamSet(BSScene scene, string paramName, uint localID, float val); - public delegate void SetOnObject(BSScene scene, BSPhysObject obj, float val); + // ===================================================================================== + // ===================================================================================== - public struct ParameterDefn + // Base parameter definition that gets and sets parameter values via a string + public abstract class ParameterDefnBase { public string name; // string name of the parameter public string desc; // a short description of what the parameter means - public float defaultValue; // default value if not specified anywhere else - public ParamUser userParam; // get the value from the configuration file - public ParamGet getter; // return the current value stored for this parameter - public ParamSet setter; // set the current value for this parameter - public SetOnObject onObject; // set the value on an object in the physical domain - public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s) + public ParameterDefnBase(string pName, string pDesc) + { + name = pName; + desc = pDesc; + } + // Set the parameter value to the default + public abstract void AssignDefault(BSScene s); + // Get the value as a string + public abstract string GetValue(BSScene s); + // Set the value to this string value + public abstract void SetValue(BSScene s, string valAsString); + // set the value on a particular object (usually sets in physics engine) + public abstract void SetOnObject(BSScene s, BSPhysObject obj); + public abstract bool HasSetOnObject { get; } + } + + // Specific parameter definition for a parameter of a specific type. + public delegate T PGetValue(BSScene s); + public delegate void PSetValue(BSScene s, T val); + public delegate void PSetOnObject(BSScene scene, BSPhysObject obj); + public sealed class ParameterDefn : ParameterDefnBase + { + T defaultValue; + PSetValue setter; + PGetValue getter; + PSetOnObject objectSet; + public ParameterDefn(string pName, string pDesc, T pDefault, PGetValue pGetter, PSetValue pSetter) + : base(pName, pDesc) + { + defaultValue = pDefault; + setter = pSetter; + getter = pGetter; + objectSet = null; + } + public ParameterDefn(string pName, string pDesc, T pDefault, PGetValue pGetter, PSetValue pSetter, PSetOnObject pObjSetter) + : base(pName, pDesc) + { + defaultValue = pDefault; + setter = pSetter; + getter = pGetter; + objectSet = pObjSetter; + } + public override void AssignDefault(BSScene s) + { + setter(s, defaultValue); + } + public override string GetValue(BSScene s) + { + return String.Format("{0}", getter(s)); + } + public override void SetValue(BSScene s, string valAsString) { - name = n; - desc = d; - defaultValue = v; - userParam = u; - getter = g; - setter = s; - onObject = null; + // Get the generic type of the setter + Type genericType = setter.GetType().GetGenericArguments()[0]; + // Find the 'Parse' method on that type + System.Reflection.MethodInfo parser = null; + try + { + parser = genericType.GetMethod("Parse", new Type[] { typeof(String) } ); + } + catch (Exception e) + { + s.Logger.ErrorFormat("{0} Exception getting parser for type '{1}': {2}", LogHeader, genericType, e); + parser = null; + } + if (parser != null) + { + // Parse the input string + try + { + T setValue = (T)parser.Invoke(genericType, new Object[] { valAsString }); + setter(s, setValue); + // s.Logger.DebugFormat("{0} Parameter {1} = {2}", LogHeader, name, setValue); + } + catch + { + s.Logger.ErrorFormat("{0} Failed parsing parameter value '{1}' as type '{2}'", LogHeader, valAsString, genericType); + } + } + else + { + s.Logger.ErrorFormat("{0} Could not find parameter parser for type '{1}'", LogHeader, genericType); + } + } + public override bool HasSetOnObject + { + get { return objectSet != null; } } - public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s, SetOnObject o) + public override void SetOnObject(BSScene s, BSPhysObject obj) { - name = n; - desc = d; - defaultValue = v; - userParam = u; - getter = g; - setter = s; - onObject = o; + if (objectSet != null) + objectSet(s, obj); } } @@ -184,462 +249,375 @@ public static class BSParam // location somewhere in the program and make an entry in this table with the // getters and setters. // It is easiest to find an existing definition and copy it. - // Parameter values are floats. Booleans are converted to a floating value. // - // A ParameterDefn() takes the following parameters: + // A ParameterDefn() takes the following parameters: // -- the text name of the parameter. This is used for console input and ini file. // -- a short text description of the parameter. This shows up in the console listing. - // -- a default value (float) - // -- a delegate for fetching the parameter from the ini file. - // Should handle fetching the right type from the ini file and converting it. - // -- a delegate for getting the value as a float - // -- a delegate for setting the value from a float + // -- a default value + // -- a delegate for getting the value + // -- a delegate for setting the value // -- an optional delegate to update the value in the world. Most often used to // push the new value to an in-world object. // // The single letter parameters for the delegates are: // s = BSScene // o = BSPhysObject - // p = string parameter name - // l = localID of referenced object // v = value (float) - // cf = parameter configuration class (for fetching values from ini file) - private static ParameterDefn[] ParameterDefinitions = + private static ParameterDefnBase[] ParameterDefinitions = { - new ParameterDefn("MeshSculptedPrim", "Whether to create meshes for sculpties", - ConfigurationParameters.numericTrue, - (s,cf,p,v) => { ShouldMeshSculptedPrim = cf.GetBoolean(p, BSParam.BoolNumeric(v)); }, - (s) => { return BSParam.NumericBool(ShouldMeshSculptedPrim); }, - (s,p,l,v) => { ShouldMeshSculptedPrim = BSParam.BoolNumeric(v); } ), - new ParameterDefn("ForceSimplePrimMeshing", "If true, only use primitive meshes for objects", - ConfigurationParameters.numericFalse, - (s,cf,p,v) => { ShouldForceSimplePrimMeshing = cf.GetBoolean(p, BSParam.BoolNumeric(v)); }, - (s) => { return BSParam.NumericBool(ShouldForceSimplePrimMeshing); }, - (s,p,l,v) => { ShouldForceSimplePrimMeshing = BSParam.BoolNumeric(v); } ), - new ParameterDefn("UseHullsForPhysicalObjects", "If true, create hulls for physical objects", - ConfigurationParameters.numericTrue, - (s,cf,p,v) => { ShouldUseHullsForPhysicalObjects = cf.GetBoolean(p, BSParam.BoolNumeric(v)); }, - (s) => { return BSParam.NumericBool(ShouldUseHullsForPhysicalObjects); }, - (s,p,l,v) => { ShouldUseHullsForPhysicalObjects = BSParam.BoolNumeric(v); } ), - new ParameterDefn("ShouldRemoveZeroWidthTriangles", "If true, remove degenerate triangles from meshes", - ConfigurationParameters.numericTrue, - (s,cf,p,v) => { ShouldRemoveZeroWidthTriangles = cf.GetBoolean(p, BSParam.BoolNumeric(v)); }, - (s) => { return BSParam.NumericBool(ShouldRemoveZeroWidthTriangles); }, - (s,p,l,v) => { ShouldRemoveZeroWidthTriangles = BSParam.BoolNumeric(v); } ), - - new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", + new ParameterDefn("MeshSculptedPrim", "Whether to create meshes for sculpties", + true, + (s) => { return ShouldMeshSculptedPrim; }, + (s,v) => { ShouldMeshSculptedPrim = v; } ), + new ParameterDefn("ForceSimplePrimMeshing", "If true, only use primitive meshes for objects", + false, + (s) => { return ShouldForceSimplePrimMeshing; }, + (s,v) => { ShouldForceSimplePrimMeshing = v; } ), + new ParameterDefn("UseHullsForPhysicalObjects", "If true, create hulls for physical objects", + true, + (s) => { return ShouldUseHullsForPhysicalObjects; }, + (s,v) => { ShouldUseHullsForPhysicalObjects = v; } ), + new ParameterDefn("ShouldRemoveZeroWidthTriangles", "If true, remove degenerate triangles from meshes", + true, + (s) => { return ShouldRemoveZeroWidthTriangles; }, + (s,v) => { ShouldRemoveZeroWidthTriangles = v; } ), + + new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", 32f, - (s,cf,p,v) => { MeshLOD = (float)cf.GetInt(p, (int)v); }, (s) => { return MeshLOD; }, - (s,p,l,v) => { MeshLOD = v; } ), - new ParameterDefn("MeshLevelOfDetailCircular", "Level of detail for prims with circular cuts or shapes", + (s,v) => { MeshLOD = v; } ), + new ParameterDefn("MeshLevelOfDetailCircular", "Level of detail for prims with circular cuts or shapes", 32f, - (s,cf,p,v) => { MeshCircularLOD = (float)cf.GetInt(p, (int)v); }, (s) => { return MeshCircularLOD; }, - (s,p,l,v) => { MeshCircularLOD = v; } ), - new ParameterDefn("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD", + (s,v) => { MeshCircularLOD = v; } ), + new ParameterDefn("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD", 10f, - (s,cf,p,v) => { MeshMegaPrimThreshold = (float)cf.GetInt(p, (int)v); }, (s) => { return MeshMegaPrimThreshold; }, - (s,p,l,v) => { MeshMegaPrimThreshold = v; } ), - new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters", + (s,v) => { MeshMegaPrimThreshold = v; } ), + new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters", 32f, - (s,cf,p,v) => { MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); }, (s) => { return MeshMegaPrimLOD; }, - (s,p,l,v) => { MeshMegaPrimLOD = v; } ), - new ParameterDefn("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)", + (s,v) => { MeshMegaPrimLOD = v; } ), + new ParameterDefn("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)", 32f, - (s,cf,p,v) => { SculptLOD = (float)cf.GetInt(p, (int)v); }, (s) => { return SculptLOD; }, - (s,p,l,v) => { SculptLOD = v; } ), + (s,v) => { SculptLOD = v; } ), - new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps", - 10f, - (s,cf,p,v) => { s.m_maxSubSteps = cf.GetInt(p, (int)v); }, - (s) => { return (float)s.m_maxSubSteps; }, - (s,p,l,v) => { s.m_maxSubSteps = (int)v; } ), - new ParameterDefn("FixedTimeStep", "In simulation step, seconds of one substep (1/60)", + new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps", + 10, + (s) => { return s.m_maxSubSteps; }, + (s,v) => { s.m_maxSubSteps = (int)v; } ), + new ParameterDefn("FixedTimeStep", "In simulation step, seconds of one substep (1/60)", 1f / 60f, - (s,cf,p,v) => { s.m_fixedTimeStep = cf.GetFloat(p, v); }, - (s) => { return (float)s.m_fixedTimeStep; }, - (s,p,l,v) => { s.m_fixedTimeStep = v; } ), - new ParameterDefn("NominalFrameRate", "The base frame rate we claim", + (s) => { return s.m_fixedTimeStep; }, + (s,v) => { s.m_fixedTimeStep = v; } ), + new ParameterDefn("NominalFrameRate", "The base frame rate we claim", 55f, - (s,cf,p,v) => { s.NominalFrameRate = cf.GetInt(p, (int)v); }, - (s) => { return (float)s.NominalFrameRate; }, - (s,p,l,v) => { s.NominalFrameRate = (int)v; } ), - new ParameterDefn("MaxCollisionsPerFrame", "Max collisions returned at end of each frame", - 2048f, - (s,cf,p,v) => { s.m_maxCollisionsPerFrame = cf.GetInt(p, (int)v); }, - (s) => { return (float)s.m_maxCollisionsPerFrame; }, - (s,p,l,v) => { s.m_maxCollisionsPerFrame = (int)v; } ), - new ParameterDefn("MaxUpdatesPerFrame", "Max updates returned at end of each frame", - 8000f, - (s,cf,p,v) => { s.m_maxUpdatesPerFrame = cf.GetInt(p, (int)v); }, - (s) => { return (float)s.m_maxUpdatesPerFrame; }, - (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ), - - new ParameterDefn("MinObjectMass", "Minimum object mass (0.0001)", + (s) => { return s.NominalFrameRate; }, + (s,v) => { s.NominalFrameRate = (int)v; } ), + new ParameterDefn("MaxCollisionsPerFrame", "Max collisions returned at end of each frame", + 2048, + (s) => { return s.m_maxCollisionsPerFrame; }, + (s,v) => { s.m_maxCollisionsPerFrame = (int)v; } ), + new ParameterDefn("MaxUpdatesPerFrame", "Max updates returned at end of each frame", + 8000, + (s) => { return s.m_maxUpdatesPerFrame; }, + (s,v) => { s.m_maxUpdatesPerFrame = (int)v; } ), + + new ParameterDefn("MinObjectMass", "Minimum object mass (0.0001)", 0.0001f, - (s,cf,p,v) => { MinimumObjectMass = cf.GetFloat(p, v); }, (s) => { return MinimumObjectMass; }, - (s,p,l,v) => { MinimumObjectMass = v; } ), - new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)", + (s,v) => { MinimumObjectMass = v; } ), + new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)", 10000.01f, - (s,cf,p,v) => { MaximumObjectMass = cf.GetFloat(p, v); }, (s) => { return MaximumObjectMass; }, - (s,p,l,v) => { MaximumObjectMass = v; } ), - new ParameterDefn("MaxLinearVelocity", "Maximum velocity magnitude that can be assigned to an object", + (s,v) => { MaximumObjectMass = v; } ), + new ParameterDefn("MaxLinearVelocity", "Maximum velocity magnitude that can be assigned to an object", 1000.0f, - (s,cf,p,v) => { MaxLinearVelocity = cf.GetFloat(p, v); }, (s) => { return MaxLinearVelocity; }, - (s,p,l,v) => { MaxLinearVelocity = v; } ), - new ParameterDefn("MaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to an object", + (s,v) => { MaxLinearVelocity = v; } ), + new ParameterDefn("MaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to an object", 1000.0f, - (s,cf,p,v) => { MaxAngularVelocity = cf.GetFloat(p, v); }, (s) => { return MaxAngularVelocity; }, - (s,p,l,v) => { MaxAngularVelocity = v; } ), + (s,v) => { MaxAngularVelocity = v; } ), // LL documentation says thie number should be 20f for llApplyImpulse and 200f for llRezObject - new ParameterDefn("MaxAddForceMagnitude", "Maximum force that can be applied by llApplyImpulse (SL says 20f)", + new ParameterDefn("MaxAddForceMagnitude", "Maximum force that can be applied by llApplyImpulse (SL says 20f)", 20000.0f, - (s,cf,p,v) => { MaxAddForceMagnitude = cf.GetFloat(p, v); }, (s) => { return MaxAddForceMagnitude; }, - (s,p,l,v) => { MaxAddForceMagnitude = v; } ), + (s,v) => { MaxAddForceMagnitude = v; } ), // Density is passed around as 100kg/m3. This scales that to 1kg/m3. - new ParameterDefn("DensityScaleFactor", "Conversion for simulator/viewer density (100kg/m3) to physical density (1kg/m3)", + new ParameterDefn("DensityScaleFactor", "Conversion for simulator/viewer density (100kg/m3) to physical density (1kg/m3)", 0.01f, - (s,cf,p,v) => { DensityScaleFactor = cf.GetFloat(p, v); }, (s) => { return DensityScaleFactor; }, - (s,p,l,v) => { DensityScaleFactor = v; } ), + (s,v) => { DensityScaleFactor = v; } ), - new ParameterDefn("PID_D", "Derivitive factor for motion smoothing", + new ParameterDefn("PID_D", "Derivitive factor for motion smoothing", 2200f, - (s,cf,p,v) => { PID_D = cf.GetFloat(p, v); }, (s) => { return (float)PID_D; }, - (s,p,l,v) => { PID_D = v; } ), - new ParameterDefn("PID_P", "Parameteric factor for motion smoothing", + (s,v) => { PID_D = v; } ), + new ParameterDefn("PID_P", "Parameteric factor for motion smoothing", 900f, - (s,cf,p,v) => { PID_P = cf.GetFloat(p, v); }, (s) => { return (float)PID_P; }, - (s,p,l,v) => { PID_P = v; } ), + (s,v) => { PID_P = v; } ), - new ParameterDefn("DefaultFriction", "Friction factor used on new objects", + new ParameterDefn("DefaultFriction", "Friction factor used on new objects", 0.2f, - (s,cf,p,v) => { DefaultFriction = cf.GetFloat(p, v); }, (s) => { return DefaultFriction; }, - (s,p,l,v) => { DefaultFriction = v; s.UnmanagedParams[0].defaultFriction = v; } ), - new ParameterDefn("DefaultDensity", "Density for new objects" , + (s,v) => { DefaultFriction = v; s.UnmanagedParams[0].defaultFriction = v; } ), + new ParameterDefn("DefaultDensity", "Density for new objects" , 10.000006836f, // Aluminum g/cm3 - (s,cf,p,v) => { DefaultDensity = cf.GetFloat(p, v); }, (s) => { return DefaultDensity; }, - (s,p,l,v) => { DefaultDensity = v; s.UnmanagedParams[0].defaultDensity = v; } ), - new ParameterDefn("DefaultRestitution", "Bouncyness of an object" , + (s,v) => { DefaultDensity = v; s.UnmanagedParams[0].defaultDensity = v; } ), + new ParameterDefn("DefaultRestitution", "Bouncyness of an object" , 0f, - (s,cf,p,v) => { DefaultRestitution = cf.GetFloat(p, v); }, (s) => { return DefaultRestitution; }, - (s,p,l,v) => { DefaultRestitution = v; s.UnmanagedParams[0].defaultRestitution = v; } ), - new ParameterDefn("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!)", + (s,v) => { DefaultRestitution = v; s.UnmanagedParams[0].defaultRestitution = v; } ), + new ParameterDefn("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!)", 0.04f, - (s,cf,p,v) => { CollisionMargin = cf.GetFloat(p, v); }, (s) => { return CollisionMargin; }, - (s,p,l,v) => { CollisionMargin = v; s.UnmanagedParams[0].collisionMargin = v; } ), - new ParameterDefn("Gravity", "Vertical force of gravity (negative means down)", + (s,v) => { CollisionMargin = v; s.UnmanagedParams[0].collisionMargin = v; } ), + new ParameterDefn("Gravity", "Vertical force of gravity (negative means down)", -9.80665f, - (s,cf,p,v) => { Gravity = cf.GetFloat(p, v); }, (s) => { return Gravity; }, - (s,p,l,v) => { Gravity = v; s.UnmanagedParams[0].gravity = v; }, - (s,o,v) => { s.PE.SetGravity(o.PhysBody, new Vector3(0f,0f,v)); } ), + (s,v) => { Gravity = v; s.UnmanagedParams[0].gravity = v; }, + (s,o) => { s.PE.SetGravity(o.PhysBody, new Vector3(0f,0f,Gravity)); } ), - new ParameterDefn("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)", + new ParameterDefn("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)", 0f, - (s,cf,p,v) => { LinearDamping = cf.GetFloat(p, v); }, (s) => { return LinearDamping; }, - (s,p,l,v) => { LinearDamping = v; }, - (s,o,v) => { s.PE.SetDamping(o.PhysBody, v, AngularDamping); } ), - new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)", + (s,v) => { LinearDamping = v; }, + (s,o) => { s.PE.SetDamping(o.PhysBody, LinearDamping, AngularDamping); } ), + new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)", 0f, - (s,cf,p,v) => { AngularDamping = cf.GetFloat(p, v); }, (s) => { return AngularDamping; }, - (s,p,l,v) => { AngularDamping = v; }, - (s,o,v) => { s.PE.SetDamping(o.PhysBody, LinearDamping, v); } ), - new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static", + (s,v) => { AngularDamping = v; }, + (s,o) => { s.PE.SetDamping(o.PhysBody, LinearDamping, AngularDamping); } ), + new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static", 0.2f, - (s,cf,p,v) => { DeactivationTime = cf.GetFloat(p, v); }, (s) => { return DeactivationTime; }, - (s,p,l,v) => { DeactivationTime = v; }, - (s,o,v) => { s.PE.SetDeactivationTime(o.PhysBody, v); } ), - new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static", + (s,v) => { DeactivationTime = v; }, + (s,o) => { s.PE.SetDeactivationTime(o.PhysBody, DeactivationTime); } ), + new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static", 0.8f, - (s,cf,p,v) => { LinearSleepingThreshold = cf.GetFloat(p, v); }, (s) => { return LinearSleepingThreshold; }, - (s,p,l,v) => { LinearSleepingThreshold = v;}, - (s,o,v) => { s.PE.SetSleepingThresholds(o.PhysBody, v, v); } ), - new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static", + (s,v) => { LinearSleepingThreshold = v;}, + (s,o) => { s.PE.SetSleepingThresholds(o.PhysBody, LinearSleepingThreshold, AngularSleepingThreshold); } ), + new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static", 1.0f, - (s,cf,p,v) => { AngularSleepingThreshold = cf.GetFloat(p, v); }, (s) => { return AngularSleepingThreshold; }, - (s,p,l,v) => { AngularSleepingThreshold = v;}, - (s,o,v) => { s.PE.SetSleepingThresholds(o.PhysBody, v, v); } ), - new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" , + (s,v) => { AngularSleepingThreshold = v;}, + (s,o) => { s.PE.SetSleepingThresholds(o.PhysBody, LinearSleepingThreshold, AngularSleepingThreshold); } ), + new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" , 0.0f, // set to zero to disable - (s,cf,p,v) => { CcdMotionThreshold = cf.GetFloat(p, v); }, (s) => { return CcdMotionThreshold; }, - (s,p,l,v) => { CcdMotionThreshold = v;}, - (s,o,v) => { s.PE.SetCcdMotionThreshold(o.PhysBody, v); } ), - new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" , + (s,v) => { CcdMotionThreshold = v;}, + (s,o) => { s.PE.SetCcdMotionThreshold(o.PhysBody, CcdMotionThreshold); } ), + new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" , 0.2f, - (s,cf,p,v) => { CcdSweptSphereRadius = cf.GetFloat(p, v); }, (s) => { return CcdSweptSphereRadius; }, - (s,p,l,v) => { CcdSweptSphereRadius = v;}, - (s,o,v) => { s.PE.SetCcdSweptSphereRadius(o.PhysBody, v); } ), - new ParameterDefn("ContactProcessingThreshold", "Distance above which contacts can be discarded (0 means no discard)" , + (s,v) => { CcdSweptSphereRadius = v;}, + (s,o) => { s.PE.SetCcdSweptSphereRadius(o.PhysBody, CcdSweptSphereRadius); } ), + new ParameterDefn("ContactProcessingThreshold", "Distance above which contacts can be discarded (0 means no discard)" , 0.0f, - (s,cf,p,v) => { ContactProcessingThreshold = cf.GetFloat(p, v); }, (s) => { return ContactProcessingThreshold; }, - (s,p,l,v) => { ContactProcessingThreshold = v;}, - (s,o,v) => { s.PE.SetContactProcessingThreshold(o.PhysBody, v); } ), + (s,v) => { ContactProcessingThreshold = v;}, + (s,o) => { s.PE.SetContactProcessingThreshold(o.PhysBody, ContactProcessingThreshold); } ), - new ParameterDefn("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)", + new ParameterDefn("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)", (float)BSTerrainPhys.TerrainImplementation.Mesh, - (s,cf,p,v) => { TerrainImplementation = cf.GetFloat(p,v); }, (s) => { return TerrainImplementation; }, - (s,p,l,v) => { TerrainImplementation = v; } ), - new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" , + (s,v) => { TerrainImplementation = v; } ), + new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" , 0.3f, - (s,cf,p,v) => { TerrainFriction = cf.GetFloat(p, v); }, (s) => { return TerrainFriction; }, - (s,p,l,v) => { TerrainFriction = v; /* TODO: set on real terrain */} ), - new ParameterDefn("TerrainHitFraction", "Distance to measure hit collisions" , + (s,v) => { TerrainFriction = v; /* TODO: set on real terrain */} ), + new ParameterDefn("TerrainHitFraction", "Distance to measure hit collisions" , 0.8f, - (s,cf,p,v) => { TerrainHitFraction = cf.GetFloat(p, v); }, (s) => { return TerrainHitFraction; }, - (s,p,l,v) => { TerrainHitFraction = v; /* TODO: set on real terrain */ } ), - new ParameterDefn("TerrainRestitution", "Bouncyness" , + (s,v) => { TerrainHitFraction = v; /* TODO: set on real terrain */ } ), + new ParameterDefn("TerrainRestitution", "Bouncyness" , 0f, - (s,cf,p,v) => { TerrainRestitution = cf.GetFloat(p, v); }, (s) => { return TerrainRestitution; }, - (s,p,l,v) => { TerrainRestitution = v; /* TODO: set on real terrain */ } ), - new ParameterDefn("TerrainCollisionMargin", "Margin where collision checking starts" , + (s,v) => { TerrainRestitution = v; /* TODO: set on real terrain */ } ), + new ParameterDefn("TerrainCollisionMargin", "Margin where collision checking starts" , 0.08f, - (s,cf,p,v) => { TerrainCollisionMargin = cf.GetFloat(p, v); }, (s) => { return TerrainCollisionMargin; }, - (s,p,l,v) => { TerrainCollisionMargin = v; /* TODO: set on real terrain */ } ), + (s,v) => { TerrainCollisionMargin = v; /* TODO: set on real terrain */ } ), - new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.", + new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.", 0.2f, - (s,cf,p,v) => { AvatarFriction = cf.GetFloat(p, v); }, (s) => { return AvatarFriction; }, - (s,p,l,v) => { AvatarFriction = v; } ), - new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", + (s,v) => { AvatarFriction = v; } ), + new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", 0.95f, - (s,cf,p,v) => { AvatarStandingFriction = cf.GetFloat(p, v); }, (s) => { return AvatarStandingFriction; }, - (s,p,l,v) => { AvatarStandingFriction = v; } ), - new ParameterDefn("AvatarAlwaysRunFactor", "Speed multiplier if avatar is set to always run", + (s,v) => { AvatarStandingFriction = v; } ), + new ParameterDefn("AvatarAlwaysRunFactor", "Speed multiplier if avatar is set to always run", 1.3f, - (s,cf,p,v) => { AvatarAlwaysRunFactor = cf.GetFloat(p, v); }, (s) => { return AvatarAlwaysRunFactor; }, - (s,p,l,v) => { AvatarAlwaysRunFactor = v; } ), - new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.", + (s,v) => { AvatarAlwaysRunFactor = v; } ), + new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.", 3.5f, - (s,cf,p,v) => { AvatarDensity = cf.GetFloat(p, v); }, (s) => { return AvatarDensity; }, - (s,p,l,v) => { AvatarDensity = v; } ), - new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.", + (s,v) => { AvatarDensity = v; } ), + new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.", 0f, - (s,cf,p,v) => { AvatarRestitution = cf.GetFloat(p, v); }, (s) => { return AvatarRestitution; }, - (s,p,l,v) => { AvatarRestitution = v; } ), - new ParameterDefn("AvatarCapsuleWidth", "The distance between the sides of the avatar capsule", + (s,v) => { AvatarRestitution = v; } ), + new ParameterDefn("AvatarCapsuleWidth", "The distance between the sides of the avatar capsule", 0.6f, - (s,cf,p,v) => { AvatarCapsuleWidth = cf.GetFloat(p, v); }, (s) => { return AvatarCapsuleWidth; }, - (s,p,l,v) => { AvatarCapsuleWidth = v; } ), - new ParameterDefn("AvatarCapsuleDepth", "The distance between the front and back of the avatar capsule", + (s,v) => { AvatarCapsuleWidth = v; } ), + new ParameterDefn("AvatarCapsuleDepth", "The distance between the front and back of the avatar capsule", 0.45f, - (s,cf,p,v) => { AvatarCapsuleDepth = cf.GetFloat(p, v); }, (s) => { return AvatarCapsuleDepth; }, - (s,p,l,v) => { AvatarCapsuleDepth = v; } ), - new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar", + (s,v) => { AvatarCapsuleDepth = v; } ), + new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar", 1.5f, - (s,cf,p,v) => { AvatarCapsuleHeight = cf.GetFloat(p, v); }, (s) => { return AvatarCapsuleHeight; }, - (s,p,l,v) => { AvatarCapsuleHeight = v; } ), - new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", + (s,v) => { AvatarCapsuleHeight = v; } ), + new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", 0.1f, - (s,cf,p,v) => { AvatarContactProcessingThreshold = cf.GetFloat(p, v); }, (s) => { return AvatarContactProcessingThreshold; }, - (s,p,l,v) => { AvatarContactProcessingThreshold = v; } ), - new ParameterDefn("AvatarStepHeight", "Height of a step obstacle to consider step correction", + (s,v) => { AvatarContactProcessingThreshold = v; } ), + new ParameterDefn("AvatarStepHeight", "Height of a step obstacle to consider step correction", 0.3f, - (s,cf,p,v) => { AvatarStepHeight = cf.GetFloat(p, v); }, (s) => { return AvatarStepHeight; }, - (s,p,l,v) => { AvatarStepHeight = v; } ), - new ParameterDefn("AvatarStepApproachFactor", "Factor to control angle of approach to step (0=straight on)", + (s,v) => { AvatarStepHeight = v; } ), + new ParameterDefn("AvatarStepApproachFactor", "Factor to control angle of approach to step (0=straight on)", 0.6f, - (s,cf,p,v) => { AvatarStepApproachFactor = cf.GetFloat(p, v); }, (s) => { return AvatarStepApproachFactor; }, - (s,p,l,v) => { AvatarStepApproachFactor = v; } ), - new ParameterDefn("AvatarStepForceFactor", "Controls the amount of force up applied to step up onto a step", + (s,v) => { AvatarStepApproachFactor = v; } ), + new ParameterDefn("AvatarStepForceFactor", "Controls the amount of force up applied to step up onto a step", 2.0f, - (s,cf,p,v) => { AvatarStepForceFactor = cf.GetFloat(p, v); }, (s) => { return AvatarStepForceFactor; }, - (s,p,l,v) => { AvatarStepForceFactor = v; } ), + (s,v) => { AvatarStepForceFactor = v; } ), - new ParameterDefn("VehicleMaxLinearVelocity", "Maximum velocity magnitude that can be assigned to a vehicle", + new ParameterDefn("VehicleMaxLinearVelocity", "Maximum velocity magnitude that can be assigned to a vehicle", 1000.0f, - (s,cf,p,v) => { VehicleMaxLinearVelocity = cf.GetFloat(p, v); }, (s) => { return (float)VehicleMaxLinearVelocity; }, - (s,p,l,v) => { VehicleMaxLinearVelocity = v; VehicleMaxLinearVelocitySq = v * v; } ), - new ParameterDefn("VehicleMaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to a vehicle", + (s,v) => { VehicleMaxLinearVelocity = v; VehicleMaxLinearVelocitySq = v * v; } ), + new ParameterDefn("VehicleMaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to a vehicle", 12.0f, - (s,cf,p,v) => { VehicleMaxAngularVelocity = cf.GetFloat(p, v); }, (s) => { return (float)VehicleMaxAngularVelocity; }, - (s,p,l,v) => { VehicleMaxAngularVelocity = v; VehicleMaxAngularVelocitySq = v * v; } ), - new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", + (s,v) => { VehicleMaxAngularVelocity = v; VehicleMaxAngularVelocitySq = v * v; } ), + new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", 0.0f, - (s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); }, (s) => { return VehicleAngularDamping; }, - (s,p,l,v) => { VehicleAngularDamping = v; } ), - new ParameterDefn("VehicleLinearFactor", "Fraction of physical linear changes applied to vehicle (0.0 - 1.0)", - 1.0f, - (s,cf,p,v) => { VehicleLinearFactor = cf.GetFloat(p, v); }, + (s,v) => { VehicleAngularDamping = v; } ), + new ParameterDefn("VehicleLinearFactor", "Fraction of physical linear changes applied to vehicle (<0,0,0> to <1,1,1>)", + new Vector3(1f, 1f, 1f), (s) => { return VehicleLinearFactor; }, - (s,p,l,v) => { VehicleLinearFactor = v; VehicleLinearFactorV = new Vector3(v, v, v); } ), - new ParameterDefn("VehicleAngularFactor", "Fraction of physical angular changes applied to vehicle (0.0 - 1.0)", - 1.0f, - (s,cf,p,v) => { VehicleAngularFactor = cf.GetFloat(p, v); }, + (s,v) => { VehicleLinearFactor = v; } ), + new ParameterDefn("VehicleAngularFactor", "Fraction of physical angular changes applied to vehicle (<0,0,0> to <1,1,1>)", + new Vector3(1f, 1f, 1f), (s) => { return VehicleAngularFactor; }, - (s,p,l,v) => { VehicleAngularFactor = v; VehicleAngularFactorV = new Vector3(v, v, v); } ), - new ParameterDefn("VehicleFriction", "Friction of vehicle on the ground (0.0 - 1.0)", + (s,v) => { VehicleAngularFactor = v; } ), + new ParameterDefn("VehicleFriction", "Friction of vehicle on the ground (0.0 - 1.0)", 0.0f, - (s,cf,p,v) => { VehicleFriction = cf.GetFloat(p, v); }, (s) => { return VehicleFriction; }, - (s,p,l,v) => { VehicleFriction = v; } ), - new ParameterDefn("VehicleRestitution", "Bouncyness factor for vehicles (0.0 - 1.0)", + (s,v) => { VehicleFriction = v; } ), + new ParameterDefn("VehicleRestitution", "Bouncyness factor for vehicles (0.0 - 1.0)", 0.0f, - (s,cf,p,v) => { VehicleRestitution = cf.GetFloat(p, v); }, (s) => { return VehicleRestitution; }, - (s,p,l,v) => { VehicleRestitution = v; } ), - new ParameterDefn("VehicleGroundGravityFudge", "Factor to multiple gravity if a ground vehicle is probably on the ground (0.0 - 1.0)", + (s,v) => { VehicleRestitution = v; } ), + new ParameterDefn("VehicleGroundGravityFudge", "Factor to multiple gravity if a ground vehicle is probably on the ground (0.0 - 1.0)", 0.2f, - (s,cf,p,v) => { VehicleGroundGravityFudge = cf.GetFloat(p, v); }, (s) => { return VehicleGroundGravityFudge; }, - (s,p,l,v) => { VehicleGroundGravityFudge = v; } ), - new ParameterDefn("VehicleDebuggingEnable", "Turn on/off vehicle debugging", - ConfigurationParameters.numericFalse, - (s,cf,p,v) => { VehicleDebuggingEnabled = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s,v) => { VehicleGroundGravityFudge = v; } ), + new ParameterDefn("VehicleDebuggingEnable", "Turn on/off vehicle debugging", + false, (s) => { return VehicleDebuggingEnabled; }, - (s,p,l,v) => { VehicleDebuggingEnabled = v; } ), + (s,v) => { VehicleDebuggingEnabled = v; } ), - new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", + new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", 0f, - (s,cf,p,v) => { MaxPersistantManifoldPoolSize = cf.GetFloat(p, v); }, (s) => { return MaxPersistantManifoldPoolSize; }, - (s,p,l,v) => { MaxPersistantManifoldPoolSize = v; s.UnmanagedParams[0].maxPersistantManifoldPoolSize = v; } ), - new ParameterDefn("MaxCollisionAlgorithmPoolSize", "Number of collisions pooled (0 means default of 4096)", + (s,v) => { MaxPersistantManifoldPoolSize = v; s.UnmanagedParams[0].maxPersistantManifoldPoolSize = v; } ), + new ParameterDefn("MaxCollisionAlgorithmPoolSize", "Number of collisions pooled (0 means default of 4096)", 0f, - (s,cf,p,v) => { MaxCollisionAlgorithmPoolSize = cf.GetFloat(p, v); }, (s) => { return MaxCollisionAlgorithmPoolSize; }, - (s,p,l,v) => { MaxCollisionAlgorithmPoolSize = v; s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = v; } ), - new ParameterDefn("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count", - ConfigurationParameters.numericFalse, - (s,cf,p,v) => { ShouldDisableContactPoolDynamicAllocation = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s,v) => { MaxCollisionAlgorithmPoolSize = v; s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = v; } ), + new ParameterDefn("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count", + false, (s) => { return ShouldDisableContactPoolDynamicAllocation; }, - (s,p,l,v) => { ShouldDisableContactPoolDynamicAllocation = v; s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = v; } ), - new ParameterDefn("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step", - ConfigurationParameters.numericFalse, - (s,cf,p,v) => { ShouldForceUpdateAllAabbs = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s,v) => { ShouldDisableContactPoolDynamicAllocation = v; + s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = NumericBool(v); } ), + new ParameterDefn("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step", + false, (s) => { return ShouldForceUpdateAllAabbs; }, - (s,p,l,v) => { ShouldForceUpdateAllAabbs = v; s.UnmanagedParams[0].shouldForceUpdateAllAabbs = v; } ), - new ParameterDefn("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction", - ConfigurationParameters.numericTrue, - (s,cf,p,v) => { ShouldRandomizeSolverOrder = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s,v) => { ShouldForceUpdateAllAabbs = v; s.UnmanagedParams[0].shouldForceUpdateAllAabbs = NumericBool(v); } ), + new ParameterDefn("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction", + true, (s) => { return ShouldRandomizeSolverOrder; }, - (s,p,l,v) => { ShouldRandomizeSolverOrder = v; s.UnmanagedParams[0].shouldRandomizeSolverOrder = v; } ), - new ParameterDefn("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands", - ConfigurationParameters.numericTrue, - (s,cf,p,v) => { ShouldSplitSimulationIslands = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s,v) => { ShouldRandomizeSolverOrder = v; s.UnmanagedParams[0].shouldRandomizeSolverOrder = NumericBool(v); } ), + new ParameterDefn("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands", + true, (s) => { return ShouldSplitSimulationIslands; }, - (s,p,l,v) => { ShouldSplitSimulationIslands = v; s.UnmanagedParams[0].shouldSplitSimulationIslands = v; } ), - new ParameterDefn("ShouldEnableFrictionCaching", "Enable friction computation caching", - ConfigurationParameters.numericTrue, - (s,cf,p,v) => { ShouldEnableFrictionCaching = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s,v) => { ShouldSplitSimulationIslands = v; s.UnmanagedParams[0].shouldSplitSimulationIslands = NumericBool(v); } ), + new ParameterDefn("ShouldEnableFrictionCaching", "Enable friction computation caching", + true, (s) => { return ShouldEnableFrictionCaching; }, - (s,p,l,v) => { ShouldEnableFrictionCaching = v; s.UnmanagedParams[0].shouldEnableFrictionCaching = v; } ), - new ParameterDefn("NumberOfSolverIterations", "Number of internal iterations (0 means default)", + (s,v) => { ShouldEnableFrictionCaching = v; s.UnmanagedParams[0].shouldEnableFrictionCaching = NumericBool(v); } ), + new ParameterDefn("NumberOfSolverIterations", "Number of internal iterations (0 means default)", 0f, // zero says use Bullet default - (s,cf,p,v) => { NumberOfSolverIterations = cf.GetFloat(p, v); }, (s) => { return NumberOfSolverIterations; }, - (s,p,l,v) => { NumberOfSolverIterations = v; s.UnmanagedParams[0].numberOfSolverIterations = v; } ), - new ParameterDefn("UseSingleSidedMeshes", "Whether to compute collisions based on single sided meshes.", - ConfigurationParameters.numericTrue, - (s,cf,p,v) => { UseSingleSidedMeshesF = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, - (s) => { return UseSingleSidedMeshesF; }, - (s,p,l,v) => { UseSingleSidedMeshesF = v; s.UnmanagedParams[0].useSingleSidedMeshes = v; } ), - new ParameterDefn("GlobalContactBreakingThreshold", "Amount of shape radius before breaking a collision contact (0 says Bullet default (0.2))", + (s,v) => { NumberOfSolverIterations = v; s.UnmanagedParams[0].numberOfSolverIterations = v; } ), + new ParameterDefn("UseSingleSidedMeshes", "Whether to compute collisions based on single sided meshes.", + true, + (s) => { return UseSingleSidedMeshes; }, + (s,v) => { UseSingleSidedMeshes = v; s.UnmanagedParams[0].useSingleSidedMeshes = NumericBool(v); } ), + new ParameterDefn("GlobalContactBreakingThreshold", "Amount of shape radius before breaking a collision contact (0 says Bullet default (0.2))", 0f, - (s,cf,p,v) => { GlobalContactBreakingThreshold = cf.GetFloat(p, v); }, (s) => { return GlobalContactBreakingThreshold; }, - (s,p,l,v) => { GlobalContactBreakingThreshold = v; s.UnmanagedParams[0].globalContactBreakingThreshold = v; } ), + (s,v) => { GlobalContactBreakingThreshold = v; s.UnmanagedParams[0].globalContactBreakingThreshold = v; } ), - new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", + new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", (float)BSLinkset.LinksetImplementation.Compound, - (s,cf,p,v) => { LinksetImplementation = cf.GetFloat(p,v); }, (s) => { return LinksetImplementation; }, - (s,p,l,v) => { LinksetImplementation = v; } ), - new ParameterDefn("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.", - ConfigurationParameters.numericFalse, - (s,cf,p,v) => { LinkConstraintUseFrameOffset = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s,v) => { LinksetImplementation = v; } ), + new ParameterDefn("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.", + false, (s) => { return LinkConstraintUseFrameOffset; }, - (s,p,l,v) => { LinkConstraintUseFrameOffset = v; } ), - new ParameterDefn("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints", - ConfigurationParameters.numericTrue, - (s,cf,p,v) => { LinkConstraintEnableTransMotor = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); }, + (s,v) => { LinkConstraintUseFrameOffset = v; } ), + new ParameterDefn("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints", + true, (s) => { return LinkConstraintEnableTransMotor; }, - (s,p,l,v) => { LinkConstraintEnableTransMotor = v; } ), - new ParameterDefn("LinkConstraintTransMotorMaxVel", "Maximum velocity to be applied by translational motor in linkset constraints", + (s,v) => { LinkConstraintEnableTransMotor = v; } ), + new ParameterDefn("LinkConstraintTransMotorMaxVel", "Maximum velocity to be applied by translational motor in linkset constraints", 5.0f, - (s,cf,p,v) => { LinkConstraintTransMotorMaxVel = cf.GetFloat(p, v); }, (s) => { return LinkConstraintTransMotorMaxVel; }, - (s,p,l,v) => { LinkConstraintTransMotorMaxVel = v; } ), - new ParameterDefn("LinkConstraintTransMotorMaxForce", "Maximum force to be applied by translational motor in linkset constraints", + (s,v) => { LinkConstraintTransMotorMaxVel = v; } ), + new ParameterDefn("LinkConstraintTransMotorMaxForce", "Maximum force to be applied by translational motor in linkset constraints", 0.1f, - (s,cf,p,v) => { LinkConstraintTransMotorMaxForce = cf.GetFloat(p, v); }, (s) => { return LinkConstraintTransMotorMaxForce; }, - (s,p,l,v) => { LinkConstraintTransMotorMaxForce = v; } ), - new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1", + (s,v) => { LinkConstraintTransMotorMaxForce = v; } ), + new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1", 0.1f, - (s,cf,p,v) => { LinkConstraintCFM = cf.GetFloat(p, v); }, (s) => { return LinkConstraintCFM; }, - (s,p,l,v) => { LinkConstraintCFM = v; } ), - new ParameterDefn("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2", + (s,v) => { LinkConstraintCFM = v; } ), + new ParameterDefn("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2", 0.1f, - (s,cf,p,v) => { LinkConstraintERP = cf.GetFloat(p, v); }, (s) => { return LinkConstraintERP; }, - (s,p,l,v) => { LinkConstraintERP = v; } ), - new ParameterDefn("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)", + (s,v) => { LinkConstraintERP = v; } ), + new ParameterDefn("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)", 40, - (s,cf,p,v) => { LinkConstraintSolverIterations = cf.GetFloat(p, v); }, (s) => { return LinkConstraintSolverIterations; }, - (s,p,l,v) => { LinkConstraintSolverIterations = v; } ), + (s,v) => { LinkConstraintSolverIterations = v; } ), - new ParameterDefn("PhysicsMetricFrames", "Frames between outputting detailed phys metrics. (0 is off)", - 0f, - (s,cf,p,v) => { s.PhysicsMetricDumpFrames = cf.GetFloat(p, (int)v); }, - (s) => { return (float)s.PhysicsMetricDumpFrames; }, - (s,p,l,v) => { s.PhysicsMetricDumpFrames = (int)v; } ), - new ParameterDefn("ResetBroadphasePool", "Setting this is any value resets the broadphase collision pool", + new ParameterDefn("PhysicsMetricFrames", "Frames between outputting detailed phys metrics. (0 is off)", + 0, + (s) => { return s.PhysicsMetricDumpFrames; }, + (s,v) => { s.PhysicsMetricDumpFrames = v; } ), + new ParameterDefn("ResetBroadphasePool", "Setting this is any value resets the broadphase collision pool", 0f, - (s,cf,p,v) => { ; }, (s) => { return 0f; }, - (s,p,l,v) => { BSParam.ResetBroadphasePoolTainted(s, v); } ), - new ParameterDefn("ResetConstraintSolver", "Setting this is any value resets the constraint solver", + (s,v) => { BSParam.ResetBroadphasePoolTainted(s, v); } ), + new ParameterDefn("ResetConstraintSolver", "Setting this is any value resets the constraint solver", 0f, - (s,cf,p,v) => { ; }, (s) => { return 0f; }, - (s,p,l,v) => { BSParam.ResetConstraintSolverTainted(s, v); } ), + (s,v) => { BSParam.ResetConstraintSolverTainted(s, v); } ), }; // Convert a boolean to our numeric true and false values @@ -658,13 +636,13 @@ public static class BSParam // ParameterDefn structure. // Case does not matter as names are compared after converting to lower case. // Returns 'false' if the parameter is not found. - internal static bool TryGetParameter(string paramName, out ParameterDefn defn) + internal static bool TryGetParameter(string paramName, out ParameterDefnBase defn) { bool ret = false; - ParameterDefn foundDefn = new ParameterDefn(); + ParameterDefnBase foundDefn = null; string pName = paramName.ToLower(); - foreach (ParameterDefn parm in ParameterDefinitions) + foreach (ParameterDefnBase parm in ParameterDefinitions) { if (pName == parm.name.ToLower()) { @@ -680,18 +658,18 @@ public static class BSParam // Pass through the settable parameters and set the default values internal static void SetParameterDefaultValues(BSScene physicsScene) { - foreach (ParameterDefn parm in ParameterDefinitions) + foreach (ParameterDefnBase parm in ParameterDefinitions) { - parm.setter(physicsScene, parm.name, PhysParameterEntry.APPLY_TO_NONE, parm.defaultValue); + parm.AssignDefault(physicsScene); } } // Get user set values out of the ini file. internal static void SetParameterConfigurationValues(BSScene physicsScene, IConfig cfg) { - foreach (ParameterDefn parm in ParameterDefinitions) + foreach (ParameterDefnBase parm in ParameterDefinitions) { - parm.userParam(physicsScene, cfg, parm.name, parm.defaultValue); + parm.SetValue(physicsScene, cfg.GetString(parm.name, parm.GetValue(physicsScene))); } } @@ -706,11 +684,11 @@ public static class BSParam List entries = new List(); for (int ii = 0; ii < ParameterDefinitions.Length; ii++) { - ParameterDefn pd = ParameterDefinitions[ii]; + ParameterDefnBase pd = ParameterDefinitions[ii]; entries.Add(new PhysParameterEntry(pd.name, pd.desc)); } - // make the list alphabetical for estetic reasons + // make the list alphabetical for ease of finding anything entries.Sort((ppe1, ppe2) => { return ppe1.name.CompareTo(ppe2.name); }); SettableParameters = entries.ToArray(); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 05722b8..e6aefd5 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -161,7 +161,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters private int m_physicsLoggingFileMinutes; private bool m_physicsLoggingDoFlush; private bool m_physicsPhysicalDumpEnabled; - public float PhysicsMetricDumpFrames { get; set; } + public int PhysicsMetricDumpFrames { get; set; } // 'true' of the vehicle code is to log lots of details public bool VehicleLoggingEnabled { get; private set; } public bool VehiclePhysicalLoggingEnabled { get; private set; } @@ -542,7 +542,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters collidersCount = 0; } - if ((m_simulationStep % PhysicsMetricDumpFrames) == 0) + if (PhysicsMetricDumpFrames != 0 && ((m_simulationStep % PhysicsMetricDumpFrames) == 0)) PE.DumpPhysicsStatistics(World); // Get a value for 'now' so all the collision and update routines don't have to get their own. @@ -880,38 +880,14 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters { bool ret = false; - float valf = 0f; - if (val.ToLower() == "true") - { - valf = PhysParameterEntry.NUMERIC_TRUE; - } - else - { - if (val.ToLower() == "false") - { - valf = PhysParameterEntry.NUMERIC_FALSE; - } - else - { - try - { - valf = float.Parse(val); - } - catch - { - valf = 0f; - } - } - } - - BSParam.ParameterDefn theParam; + BSParam.ParameterDefnBase theParam; if (BSParam.TryGetParameter(parm, out theParam)) { // Set the value in the C# code - theParam.setter(this, parm, localID, valf); + theParam.SetValue(this, val); // Optionally set the parameter in the unmanaged code - if (theParam.onObject != null) + if (theParam.HasSetOnObject) { // update all the localIDs specified // If the local ID is APPLY_TO_NONE, just change the default value @@ -923,16 +899,16 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters case PhysParameterEntry.APPLY_TO_NONE: // This will cause a call into the physical world if some operation is specified (SetOnObject). objectIDs.Add(TERRAIN_ID); - TaintedUpdateParameter(parm, objectIDs, valf); + TaintedUpdateParameter(parm, objectIDs, val); break; case PhysParameterEntry.APPLY_TO_ALL: lock (PhysObjects) objectIDs = new List(PhysObjects.Keys); - TaintedUpdateParameter(parm, objectIDs, valf); + TaintedUpdateParameter(parm, objectIDs, val); break; default: // setting only one localID objectIDs.Add(localID); - TaintedUpdateParameter(parm, objectIDs, valf); + TaintedUpdateParameter(parm, objectIDs, val); break; } } @@ -943,22 +919,22 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters } // schedule the actual updating of the paramter to when the phys engine is not busy - private void TaintedUpdateParameter(string parm, List lIDs, float val) + private void TaintedUpdateParameter(string parm, List lIDs, string val) { - float xval = val; + string xval = val; List xlIDs = lIDs; string xparm = parm; TaintedObject("BSScene.UpdateParameterSet", delegate() { - BSParam.ParameterDefn thisParam; + BSParam.ParameterDefnBase thisParam; if (BSParam.TryGetParameter(xparm, out thisParam)) { - if (thisParam.onObject != null) + if (thisParam.HasSetOnObject) { foreach (uint lID in xlIDs) { BSPhysObject theObject = null; if (PhysObjects.TryGetValue(lID, out theObject)) - thisParam.onObject(this, theObject, xval); + thisParam.SetOnObject(this, theObject); } } } @@ -971,10 +947,10 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters { string val = String.Empty; bool ret = false; - BSParam.ParameterDefn theParam; + BSParam.ParameterDefnBase theParam; if (BSParam.TryGetParameter(parm, out theParam)) { - val = theParam.getter(this).ToString(); + val = theParam.GetValue(this); ret = true; } value = val; -- cgit v1.1 From 1d7276235ace0ed6b7701efa36a7fd7f1b552bab Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 17 Feb 2013 20:07:04 -0800 Subject: BulletSim: add calls for creating all the different Bullet constraint types. Updated the DLLs and SOs and code for BulletXNA to create the types. All the detailed control calls are not all in place yet. --- OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | 102 +++++++++ OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs | 227 +++++++++++++++++---- .../Region/Physics/BulletSPlugin/BSApiTemplate.cs | 27 +++ .../Physics/BulletSPlugin/BSConstraint6Dof.cs | 16 ++ .../BulletSPlugin/BSConstraintCollection.cs | 13 +- 5 files changed, 338 insertions(+), 47 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs index ae54499..3a27d2c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs @@ -438,6 +438,28 @@ public override BulletConstraint Create6DofConstraintToPoint(BulletWorld world, joinPoint, useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); } +public override BulletConstraint Create6DofConstraintFixed(BulletWorld world, BulletBody obj1, + Vector3 frameInBloc, Quaternion frameInBrot, + bool useLinearReferenceFrameB, bool disableCollisionsBetweenLinkedBodies) +{ + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletBodyUnman bodyu1 = obj1 as BulletBodyUnman; + return new BulletConstraintUnman(BSAPICPP.Create6DofConstraintFixed2(worldu.ptr, bodyu1.ptr, + frameInBloc, frameInBrot, useLinearReferenceFrameB, disableCollisionsBetweenLinkedBodies)); +} + +public override BulletConstraint Create6DofSpringConstraint(BulletWorld world, BulletBody obj1, BulletBody obj2, + Vector3 frame1loc, Quaternion frame1rot, + Vector3 frame2loc, Quaternion frame2rot, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) +{ + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletBodyUnman bodyu1 = obj1 as BulletBodyUnman; + BulletBodyUnman bodyu2 = obj2 as BulletBodyUnman; + return new BulletConstraintUnman(BSAPICPP.Create6DofSpringConstraint2(worldu.ptr, bodyu1.ptr, bodyu2.ptr, frame1loc, frame1rot, + frame2loc, frame2rot, useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); +} + public override BulletConstraint CreateHingeConstraint(BulletWorld world, BulletBody obj1, BulletBody obj2, Vector3 pivotinA, Vector3 pivotinB, Vector3 axisInA, Vector3 axisInB, @@ -450,6 +472,52 @@ public override BulletConstraint CreateHingeConstraint(BulletWorld world, Bullet pivotinA, pivotinB, axisInA, axisInB, useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); } +public override BulletConstraint CreateSliderConstraint(BulletWorld world, BulletBody obj1, BulletBody obj2, + Vector3 frame1loc, Quaternion frame1rot, + Vector3 frame2loc, Quaternion frame2rot, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) +{ + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletBodyUnman bodyu1 = obj1 as BulletBodyUnman; + BulletBodyUnman bodyu2 = obj2 as BulletBodyUnman; + return new BulletConstraintUnman(BSAPICPP.CreateSliderConstraint2(worldu.ptr, bodyu1.ptr, bodyu2.ptr, frame1loc, frame1rot, + frame2loc, frame2rot, useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); +} + +public override BulletConstraint CreateConeTwistConstraint(BulletWorld world, BulletBody obj1, BulletBody obj2, + Vector3 frame1loc, Quaternion frame1rot, + Vector3 frame2loc, Quaternion frame2rot, + bool disableCollisionsBetweenLinkedBodies) +{ + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletBodyUnman bodyu1 = obj1 as BulletBodyUnman; + BulletBodyUnman bodyu2 = obj2 as BulletBodyUnman; + return new BulletConstraintUnman(BSAPICPP.CreateConeTwistConstraint2(worldu.ptr, bodyu1.ptr, bodyu2.ptr, frame1loc, frame1rot, + frame2loc, frame2rot, disableCollisionsBetweenLinkedBodies)); +} + +public override BulletConstraint CreateGearConstraint(BulletWorld world, BulletBody obj1, BulletBody obj2, + Vector3 axisInA, Vector3 axisInB, + float ratio, bool disableCollisionsBetweenLinkedBodies) +{ + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletBodyUnman bodyu1 = obj1 as BulletBodyUnman; + BulletBodyUnman bodyu2 = obj2 as BulletBodyUnman; + return new BulletConstraintUnman(BSAPICPP.CreateGearConstraint2(worldu.ptr, bodyu1.ptr, bodyu2.ptr, axisInA, axisInB, + ratio, disableCollisionsBetweenLinkedBodies)); +} + +public override BulletConstraint CreatePoint2PointConstraint(BulletWorld world, BulletBody obj1, BulletBody obj2, + Vector3 pivotInA, Vector3 pivotInB, + bool disableCollisionsBetweenLinkedBodies) +{ + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletBodyUnman bodyu1 = obj1 as BulletBodyUnman; + BulletBodyUnman bodyu2 = obj2 as BulletBodyUnman; + return new BulletConstraintUnman(BSAPICPP.CreatePoint2PointConstraint2(worldu.ptr, bodyu1.ptr, bodyu2.ptr, pivotInA, pivotInB, + disableCollisionsBetweenLinkedBodies)); +} + public override void SetConstraintEnable(BulletConstraint constrain, float numericTrueFalse) { BulletConstraintUnman constrainu = constrain as BulletConstraintUnman; @@ -1426,12 +1494,46 @@ public static extern IntPtr Create6DofConstraintToPoint2(IntPtr world, IntPtr ob bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr Create6DofConstraintFixed2(IntPtr world, IntPtr obj1, + Vector3 frameInBloc, Quaternion frameInBrot, + bool useLinearReferenceFrameB, bool disableCollisionsBetweenLinkedBodies); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr Create6DofSpringConstraint2(IntPtr world, IntPtr obj1, IntPtr obj2, + Vector3 frame1loc, Quaternion frame1rot, + Vector3 frame2loc, Quaternion frame2rot, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern IntPtr CreateHingeConstraint2(IntPtr world, IntPtr obj1, IntPtr obj2, Vector3 pivotinA, Vector3 pivotinB, Vector3 axisInA, Vector3 axisInB, bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateSliderConstraint2(IntPtr world, IntPtr obj1, IntPtr obj2, + Vector3 frameInAloc, Quaternion frameInArot, + Vector3 frameInBloc, Quaternion frameInBrot, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateConeTwistConstraint2(IntPtr world, IntPtr obj1, IntPtr obj2, + Vector3 frameInAloc, Quaternion frameInArot, + Vector3 frameInBloc, Quaternion frameInBrot, + bool disableCollisionsBetweenLinkedBodies); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateGearConstraint2(IntPtr world, IntPtr obj1, IntPtr obj2, + Vector3 axisInA, Vector3 axisInB, + float ratio, bool disableCollisionsBetweenLinkedBodies); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreatePoint2PointConstraint2(IntPtr world, IntPtr obj1, IntPtr obj2, + Vector3 pivotInA, Vector3 pivotInB, + bool disableCollisionsBetweenLinkedBodies); + + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern void SetConstraintEnable2(IntPtr constrain, float numericTrueFalse); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs index 15fa52b..6fc10e9 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs @@ -559,8 +559,9 @@ private sealed class BulletConstraintXNA : BulletConstraint } - //BulletSimAPI.Create6DofConstraint(m_world.ptr, m_body1.ptr, m_body2.ptr,frame1, frame1rot,frame2, frame2rot,useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); - public override BulletConstraint Create6DofConstraint(BulletWorld pWorld, BulletBody pBody1, BulletBody pBody2, Vector3 pframe1, Quaternion pframe1rot, Vector3 pframe2, Quaternion pframe2rot, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies) + public override BulletConstraint Create6DofConstraint(BulletWorld pWorld, BulletBody pBody1, BulletBody pBody2, + Vector3 pframe1, Quaternion pframe1rot, Vector3 pframe2, Quaternion pframe2rot, + bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies) { DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; @@ -584,7 +585,24 @@ private sealed class BulletConstraintXNA : BulletConstraint return new BulletConstraintXNA(consttr); } - + public override BulletConstraint Create6DofConstraintFixed(BulletWorld pWorld, BulletBody pBody1, + Vector3 pframe1, Quaternion pframe1rot, + bool pUseLinearReferenceFrameB, bool pdisableCollisionsBetweenLinkedBodies) + { + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; + RigidBody body1 = (pBody1 as BulletBodyXNA).rigidBody; + IndexedVector3 frame1v = new IndexedVector3(pframe1.X, pframe1.Y, pframe1.Z); + IndexedQuaternion frame1rot = new IndexedQuaternion(pframe1rot.X, pframe1rot.Y, pframe1rot.Z, pframe1rot.W); + IndexedMatrix frame1 = IndexedMatrix.CreateFromQuaternion(frame1rot); + frame1._origin = frame1v; + + Generic6DofConstraint consttr = new Generic6DofConstraint(body1, ref frame1, pUseLinearReferenceFrameB); + consttr.CalculateTransforms(); + world.AddConstraint(consttr,pdisableCollisionsBetweenLinkedBodies); + + return new BulletConstraintXNA(consttr); + } + /// /// /// @@ -1443,129 +1461,130 @@ private sealed class BulletConstraintXNA : BulletConstraint public BSPhysicsShapeType BSShapeTypeFromBroadPhaseNativeType(BroadphaseNativeTypes pin) { + BSPhysicsShapeType ret = BSPhysicsShapeType.SHAPE_UNKNOWN; switch (pin) { case BroadphaseNativeTypes.BOX_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_BOX; + ret = BSPhysicsShapeType.SHAPE_BOX; break; case BroadphaseNativeTypes.TRIANGLE_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_UNKNOWN; + ret = BSPhysicsShapeType.SHAPE_UNKNOWN; break; case BroadphaseNativeTypes.TETRAHEDRAL_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_UNKNOWN; + ret = BSPhysicsShapeType.SHAPE_UNKNOWN; break; case BroadphaseNativeTypes.CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_MESH; + ret = BSPhysicsShapeType.SHAPE_MESH; break; case BroadphaseNativeTypes.CONVEX_HULL_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_HULL; + ret = BSPhysicsShapeType.SHAPE_HULL; break; case BroadphaseNativeTypes.CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_UNKNOWN; + ret = BSPhysicsShapeType.SHAPE_UNKNOWN; break; case BroadphaseNativeTypes.CUSTOM_POLYHEDRAL_SHAPE_TYPE: - return BSPhysicsShapeType.SHAPE_UNKNOWN; + ret = BSPhysicsShapeType.SHAPE_UNKNOWN; break; //implicit convex shapes case BroadphaseNativeTypes.IMPLICIT_CONVEX_SHAPES_START_HERE: - return BSPhysicsShapeType.SHAPE_UNKNOWN; + ret = BSPhysicsShapeType.SHAPE_UNKNOWN; break; case BroadphaseNativeTypes.SPHERE_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_SPHERE; + ret = BSPhysicsShapeType.SHAPE_SPHERE; break; case BroadphaseNativeTypes.MULTI_SPHERE_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_UNKNOWN; + ret = BSPhysicsShapeType.SHAPE_UNKNOWN; break; case BroadphaseNativeTypes.CAPSULE_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_CAPSULE; + ret = BSPhysicsShapeType.SHAPE_CAPSULE; break; case BroadphaseNativeTypes.CONE_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_CONE; + ret = BSPhysicsShapeType.SHAPE_CONE; break; case BroadphaseNativeTypes.CONVEX_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_UNKNOWN; + ret = BSPhysicsShapeType.SHAPE_UNKNOWN; break; case BroadphaseNativeTypes.CYLINDER_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_CYLINDER; + ret = BSPhysicsShapeType.SHAPE_CYLINDER; break; case BroadphaseNativeTypes.UNIFORM_SCALING_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_UNKNOWN; + ret = BSPhysicsShapeType.SHAPE_UNKNOWN; break; case BroadphaseNativeTypes.MINKOWSKI_SUM_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_UNKNOWN; + ret = BSPhysicsShapeType.SHAPE_UNKNOWN; break; case BroadphaseNativeTypes.MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_UNKNOWN; + ret = BSPhysicsShapeType.SHAPE_UNKNOWN; break; case BroadphaseNativeTypes.BOX_2D_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_UNKNOWN; + ret = BSPhysicsShapeType.SHAPE_UNKNOWN; break; case BroadphaseNativeTypes.CONVEX_2D_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_UNKNOWN; + ret = BSPhysicsShapeType.SHAPE_UNKNOWN; break; case BroadphaseNativeTypes.CUSTOM_CONVEX_SHAPE_TYPE: - return BSPhysicsShapeType.SHAPE_UNKNOWN; + ret = BSPhysicsShapeType.SHAPE_UNKNOWN; break; //concave shape case BroadphaseNativeTypes.CONCAVE_SHAPES_START_HERE: - return BSPhysicsShapeType.SHAPE_UNKNOWN; + ret = BSPhysicsShapeType.SHAPE_UNKNOWN; break; //keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy! case BroadphaseNativeTypes.TRIANGLE_MESH_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_MESH; + ret = BSPhysicsShapeType.SHAPE_MESH; break; case BroadphaseNativeTypes.SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_MESH; + ret = BSPhysicsShapeType.SHAPE_MESH; break; ///used for demo integration FAST/Swift collision library and Bullet case BroadphaseNativeTypes.FAST_CONCAVE_MESH_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_MESH; + ret = BSPhysicsShapeType.SHAPE_MESH; break; //terrain case BroadphaseNativeTypes.TERRAIN_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_HEIGHTMAP; + ret = BSPhysicsShapeType.SHAPE_HEIGHTMAP; break; ///Used for GIMPACT Trimesh integration case BroadphaseNativeTypes.GIMPACT_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_MESH; + ret = BSPhysicsShapeType.SHAPE_MESH; break; ///Multimaterial mesh case BroadphaseNativeTypes.MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_MESH; + ret = BSPhysicsShapeType.SHAPE_MESH; break; case BroadphaseNativeTypes.EMPTY_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_UNKNOWN; + ret = BSPhysicsShapeType.SHAPE_UNKNOWN; break; case BroadphaseNativeTypes.STATIC_PLANE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_GROUNDPLANE; + ret = BSPhysicsShapeType.SHAPE_GROUNDPLANE; break; case BroadphaseNativeTypes.CUSTOM_CONCAVE_SHAPE_TYPE: - return BSPhysicsShapeType.SHAPE_UNKNOWN; + ret = BSPhysicsShapeType.SHAPE_UNKNOWN; break; case BroadphaseNativeTypes.CONCAVE_SHAPES_END_HERE: - return BSPhysicsShapeType.SHAPE_UNKNOWN; + ret = BSPhysicsShapeType.SHAPE_UNKNOWN; break; case BroadphaseNativeTypes.COMPOUND_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_COMPOUND; + ret = BSPhysicsShapeType.SHAPE_COMPOUND; break; case BroadphaseNativeTypes.SOFTBODY_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_MESH; + ret = BSPhysicsShapeType.SHAPE_MESH; break; case BroadphaseNativeTypes.HFFLUID_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_UNKNOWN; + ret = BSPhysicsShapeType.SHAPE_UNKNOWN; break; case BroadphaseNativeTypes.HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_UNKNOWN; + ret = BSPhysicsShapeType.SHAPE_UNKNOWN; break; case BroadphaseNativeTypes.INVALID_SHAPE_PROXYTYPE: - return BSPhysicsShapeType.SHAPE_UNKNOWN; + ret = BSPhysicsShapeType.SHAPE_UNKNOWN; break; } - return BSPhysicsShapeType.SHAPE_UNKNOWN; + return ret; } public override void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape) { /* TODO */ } @@ -1579,7 +1598,39 @@ private sealed class BulletConstraintXNA : BulletConstraint return new BulletShapeXNA(m_planeshape, BSPhysicsShapeType.SHAPE_GROUNDPLANE); } - public override BulletConstraint CreateHingeConstraint(BulletWorld pWorld, BulletBody pBody1, BulletBody pBody2, Vector3 ppivotInA, Vector3 ppivotInB, Vector3 paxisInA, Vector3 paxisInB, bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies) + public override BulletConstraint Create6DofSpringConstraint(BulletWorld pWorld, BulletBody pBody1, BulletBody pBody2, + Vector3 pframe1, Quaternion pframe1rot, Vector3 pframe2, Quaternion pframe2rot, + bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies) + + { + Generic6DofSpringConstraint constrain = null; + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; + RigidBody body1 = (pBody1 as BulletBodyXNA).rigidBody; + RigidBody body2 = (pBody2 as BulletBodyXNA).rigidBody; + if (body1 != null && body2 != null) + { + IndexedVector3 frame1v = new IndexedVector3(pframe1.X, pframe1.Y, pframe1.Z); + IndexedQuaternion frame1rot = new IndexedQuaternion(pframe1rot.X, pframe1rot.Y, pframe1rot.Z, pframe1rot.W); + IndexedMatrix frame1 = IndexedMatrix.CreateFromQuaternion(frame1rot); + frame1._origin = frame1v; + + IndexedVector3 frame2v = new IndexedVector3(pframe2.X, pframe2.Y, pframe2.Z); + IndexedQuaternion frame2rot = new IndexedQuaternion(pframe2rot.X, pframe2rot.Y, pframe2rot.Z, pframe2rot.W); + IndexedMatrix frame2 = IndexedMatrix.CreateFromQuaternion(frame2rot); + frame2._origin = frame1v; + + constrain = new Generic6DofSpringConstraint(body1, body2, ref frame1, ref frame2, puseLinearReferenceFrameA); + world.AddConstraint(constrain, pdisableCollisionsBetweenLinkedBodies); + + constrain.CalculateTransforms(); + } + + return new BulletConstraintXNA(constrain); + } + + public override BulletConstraint CreateHingeConstraint(BulletWorld pWorld, BulletBody pBody1, BulletBody pBody2, + Vector3 ppivotInA, Vector3 ppivotInB, Vector3 paxisInA, Vector3 paxisInB, + bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies) { HingeConstraint constrain = null; DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; @@ -1591,6 +1642,100 @@ private sealed class BulletConstraintXNA : BulletConstraint IndexedVector3 pivotInB = new IndexedVector3(ppivotInB.X, ppivotInB.Y, ppivotInB.Z); IndexedVector3 axisInA = new IndexedVector3(paxisInA.X, paxisInA.Y, paxisInA.Z); IndexedVector3 axisInB = new IndexedVector3(paxisInB.X, paxisInB.Y, paxisInB.Z); + constrain = new HingeConstraint(rb1, rb2, ref pivotInA, ref pivotInB, ref axisInA, ref axisInB, puseLinearReferenceFrameA); + world.AddConstraint(constrain, pdisableCollisionsBetweenLinkedBodies); + } + return new BulletConstraintXNA(constrain); + } + + public override BulletConstraint CreateSliderConstraint(BulletWorld pWorld, BulletBody pBody1, BulletBody pBody2, + Vector3 pframe1, Quaternion pframe1rot, + Vector3 pframe2, Quaternion pframe2rot, + bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies) + { + SliderConstraint constrain = null; + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; + RigidBody rb1 = (pBody1 as BulletBodyXNA).rigidBody; + RigidBody rb2 = (pBody2 as BulletBodyXNA).rigidBody; + if (rb1 != null && rb2 != null) + { + IndexedVector3 frame1v = new IndexedVector3(pframe1.X, pframe1.Y, pframe1.Z); + IndexedQuaternion frame1rot = new IndexedQuaternion(pframe1rot.X, pframe1rot.Y, pframe1rot.Z, pframe1rot.W); + IndexedMatrix frame1 = IndexedMatrix.CreateFromQuaternion(frame1rot); + frame1._origin = frame1v; + + IndexedVector3 frame2v = new IndexedVector3(pframe2.X, pframe2.Y, pframe2.Z); + IndexedQuaternion frame2rot = new IndexedQuaternion(pframe2rot.X, pframe2rot.Y, pframe2rot.Z, pframe2rot.W); + IndexedMatrix frame2 = IndexedMatrix.CreateFromQuaternion(frame2rot); + frame2._origin = frame1v; + + constrain = new SliderConstraint(rb1, rb2, ref frame1, ref frame2, puseLinearReferenceFrameA); + world.AddConstraint(constrain, pdisableCollisionsBetweenLinkedBodies); + } + return new BulletConstraintXNA(constrain); + } + + public override BulletConstraint CreateConeTwistConstraint(BulletWorld pWorld, BulletBody pBody1, BulletBody pBody2, + Vector3 pframe1, Quaternion pframe1rot, + Vector3 pframe2, Quaternion pframe2rot, + bool pdisableCollisionsBetweenLinkedBodies) + { + ConeTwistConstraint constrain = null; + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; + RigidBody rb1 = (pBody1 as BulletBodyXNA).rigidBody; + RigidBody rb2 = (pBody2 as BulletBodyXNA).rigidBody; + if (rb1 != null && rb2 != null) + { + IndexedVector3 frame1v = new IndexedVector3(pframe1.X, pframe1.Y, pframe1.Z); + IndexedQuaternion frame1rot = new IndexedQuaternion(pframe1rot.X, pframe1rot.Y, pframe1rot.Z, pframe1rot.W); + IndexedMatrix frame1 = IndexedMatrix.CreateFromQuaternion(frame1rot); + frame1._origin = frame1v; + + IndexedVector3 frame2v = new IndexedVector3(pframe2.X, pframe2.Y, pframe2.Z); + IndexedQuaternion frame2rot = new IndexedQuaternion(pframe2rot.X, pframe2rot.Y, pframe2rot.Z, pframe2rot.W); + IndexedMatrix frame2 = IndexedMatrix.CreateFromQuaternion(frame2rot); + frame2._origin = frame1v; + + constrain = new ConeTwistConstraint(rb1, rb2, ref frame1, ref frame2); + world.AddConstraint(constrain, pdisableCollisionsBetweenLinkedBodies); + } + return new BulletConstraintXNA(constrain); + } + + public override BulletConstraint CreateGearConstraint(BulletWorld pWorld, BulletBody pBody1, BulletBody pBody2, + Vector3 paxisInA, Vector3 paxisInB, + float pratio, bool pdisableCollisionsBetweenLinkedBodies) + { + Generic6DofConstraint constrain = null; + /* BulletXNA does not have a gear constraint + GearConstraint constrain = null; + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; + RigidBody rb1 = (pBody1 as BulletBodyXNA).rigidBody; + RigidBody rb2 = (pBody2 as BulletBodyXNA).rigidBody; + if (rb1 != null && rb2 != null) + { + IndexedVector3 axis1 = new IndexedVector3(paxisInA.X, paxisInA.Y, paxisInA.Z); + IndexedVector3 axis2 = new IndexedVector3(paxisInB.X, paxisInB.Y, paxisInB.Z); + constrain = new GearConstraint(rb1, rb2, ref axis1, ref axis2, pratio); + world.AddConstraint(constrain, pdisableCollisionsBetweenLinkedBodies); + } + */ + return new BulletConstraintXNA(constrain); + } + + public override BulletConstraint CreatePoint2PointConstraint(BulletWorld pWorld, BulletBody pBody1, BulletBody pBody2, + Vector3 ppivotInA, Vector3 ppivotInB, + bool pdisableCollisionsBetweenLinkedBodies) + { + Point2PointConstraint constrain = null; + DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; + RigidBody rb1 = (pBody1 as BulletBodyXNA).rigidBody; + RigidBody rb2 = (pBody2 as BulletBodyXNA).rigidBody; + if (rb1 != null && rb2 != null) + { + IndexedVector3 pivotInA = new IndexedVector3(ppivotInA.X, ppivotInA.Y, ppivotInA.Z); + IndexedVector3 pivotInB = new IndexedVector3(ppivotInB.X, ppivotInB.Y, ppivotInB.Z); + constrain = new Point2PointConstraint(rb1, rb2, ref pivotInA, ref pivotInB); world.AddConstraint(constrain, pdisableCollisionsBetweenLinkedBodies); } return new BulletConstraintXNA(constrain); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index 3f83ef0..5765b0d 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs @@ -365,11 +365,38 @@ public abstract BulletConstraint Create6DofConstraintToPoint(BulletWorld world, Vector3 joinPoint, bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); +public abstract BulletConstraint Create6DofConstraintFixed(BulletWorld world, BulletBody obj1, + Vector3 frameInBloc, Quaternion frameInBrot, + bool useLinearReferenceFrameB, bool disableCollisionsBetweenLinkedBodies); + +public abstract BulletConstraint Create6DofSpringConstraint(BulletWorld world, BulletBody obj1, BulletBody obj2, + Vector3 frame1loc, Quaternion frame1rot, + Vector3 frame2loc, Quaternion frame2rot, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); + public abstract BulletConstraint CreateHingeConstraint(BulletWorld world, BulletBody obj1, BulletBody obj2, Vector3 pivotinA, Vector3 pivotinB, Vector3 axisInA, Vector3 axisInB, bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); +public abstract BulletConstraint CreateSliderConstraint(BulletWorld world, BulletBody obj1, BulletBody obj2, + Vector3 frameInAloc, Quaternion frameInArot, + Vector3 frameInBloc, Quaternion frameInBrot, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies); + +public abstract BulletConstraint CreateConeTwistConstraint(BulletWorld world, BulletBody obj1, BulletBody obj2, + Vector3 frameInAloc, Quaternion frameInArot, + Vector3 frameInBloc, Quaternion frameInBrot, + bool disableCollisionsBetweenLinkedBodies); + +public abstract BulletConstraint CreateGearConstraint(BulletWorld world, BulletBody obj1, BulletBody obj2, + Vector3 axisInA, Vector3 axisInB, + float ratio, bool disableCollisionsBetweenLinkedBodies); + +public abstract BulletConstraint CreatePoint2PointConstraint(BulletWorld world, BulletBody obj1, BulletBody obj2, + Vector3 pivotInA, Vector3 pivotInB, + bool disableCollisionsBetweenLinkedBodies); + public abstract void SetConstraintEnable(BulletConstraint constrain, float numericTrueFalse); public abstract void SetConstraintNumSolverIterations(BulletConstraint constrain, float iterations); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs index ecb1b32..476a0e5 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs @@ -57,6 +57,7 @@ public sealed class BSConstraint6Dof : BSConstraint obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString); } + // 6 Dof constraint based on a midpoint between the two constrained bodies public BSConstraint6Dof(BulletWorld world, BulletBody obj1, BulletBody obj2, Vector3 joinPoint, bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) @@ -94,6 +95,21 @@ public sealed class BSConstraint6Dof : BSConstraint } } + // A 6 Dof constraint that is fixed in the world and constrained to a on-the-fly created static object + public BSConstraint6Dof(BulletWorld world, BulletBody obj1, Vector3 frameInBloc, Quaternion frameInBrot, + bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) + : base(world) + { + m_body1 = obj1; + m_body2 = obj1; // Look out for confusion down the road + m_constraint = PhysicsScene.PE.Create6DofConstraintFixed(m_world, m_body1, + frameInBloc, frameInBrot, + useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies); + m_enabled = true; + world.physicsScene.DetailLog("{0},BS6DofConstraint,createFixed,wID={1},rID={2},rBody={3}", + BSScene.DetailLogZero, world.worldID, obj1.ID, obj1.AddrString); + } + public bool SetFrames(Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot) { bool ret = false; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs index 2aeff25..5c8d94e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs @@ -117,8 +117,7 @@ public sealed class BSConstraintCollection : IDisposable if (this.TryGetConstraint(body1, body2, out constrain)) { // remove the constraint from our collection - RemoveAndDestroyConstraint(constrain); - ret = true; + ret = RemoveAndDestroyConstraint(constrain); } } @@ -126,17 +125,19 @@ public sealed class BSConstraintCollection : IDisposable } // The constraint MUST exist in the collection + // Could be called if the constraint was previously removed. + // Return 'true' if the constraint was actually removed and disposed. public bool RemoveAndDestroyConstraint(BSConstraint constrain) { + bool removed = false; lock (m_constraints) { // remove the constraint from our collection - m_constraints.Remove(constrain); + removed = m_constraints.Remove(constrain); } - // tell the engine that all its structures need to be freed + // Dispose() is safe to call multiple times constrain.Dispose(); - // we destroyed something - return true; + return removed; } // Remove all constraints that reference the passed body. -- cgit v1.1 From 26421294f644b224234e874210bbfd2a1aabf451 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 17 Feb 2013 20:11:40 -0800 Subject: BulletSim: experimental lock axis code using constraints. Not enabled by default. Like more debugging is needed. --- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 4 +- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 92 +++++++++++++++++----- 2 files changed, 74 insertions(+), 22 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 4ce58c7..e05562a 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -485,8 +485,8 @@ public sealed class BSLinksetCompound : BSLinkset } OMV.Vector3 offsetPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation - centerDisplacement; OMV.Quaternion offsetRot = cPrim.RawOrientation * invRootOrientation; - PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, offsetPos, offsetRot); - DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addNonNative,indx={1},rShape={2},cShape={3},offPos={4},offRot={5}", + PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, offsetPos, offsetRot); + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addNonNative,indx={1},rShape={2},cShape={3},offPos={4},offRot={5}", LinksetRoot.LocalID, memberIndex, LinksetRoot.PhysShape, cPrim.PhysShape, offsetPos, offsetRot); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 4bb2a9e..4d61ad2 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -239,50 +239,98 @@ public class BSPrim : BSPhysObject }); } + bool TryExperimentalLockAxisCode = false; + BSConstraint LockAxisConstraint = null; public override void LockAngularMotion(OMV.Vector3 axis) { DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis); + // "1" means free, "0" means locked OMV.Vector3 locking = new OMV.Vector3(1f, 1f, 1f); if (axis.X != 1) locking.X = 0f; if (axis.Y != 1) locking.Y = 0f; if (axis.Z != 1) locking.Z = 0f; LockedAxis = locking; - /* Not implemented yet - if (LockedAxis != LockedAxisFree) + if (TryExperimentalLockAxisCode && LockedAxis != LockedAxisFree) { - // Something is locked so start the thingy that keeps that axis from changing - RegisterPreUpdatePropertyAction("BSPrim.LockAngularMotion", delegate(ref EntityProperties entprop) + // Lock that axis by creating a 6DOF constraint that has one end in the world and + // the other in the object. + // http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=20817 + // http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=26380 + + PhysicsScene.TaintedObject("BSPrim.LockAngularMotion", delegate() { - if (LockedAxis != LockedAxisFree) + CleanUpLockAxisPhysicals(true /* inTaintTime */); + + BSConstraint6Dof axisConstrainer = new BSConstraint6Dof(PhysicsScene.World, PhysBody, + OMV.Vector3.Zero, OMV.Quaternion.Inverse(RawOrientation), + true /* useLinearReferenceFrameB */, true /* disableCollisionsBetweenLinkedBodies */); + LockAxisConstraint = axisConstrainer; + PhysicsScene.Constraints.AddConstraint(LockAxisConstraint); + + // The constraint is tied to the world and oriented to the prim. + + // Free to move linearly + OMV.Vector3 linearLow = OMV.Vector3.Zero; + OMV.Vector3 linearHigh = PhysicsScene.TerrainManager.DefaultRegionSize; + axisConstrainer.SetLinearLimits(linearLow, linearHigh); + + // Angular with some axis locked + float f2PI = (float)Math.PI * 2f; + OMV.Vector3 angularLow = new OMV.Vector3(-f2PI, -f2PI, -f2PI); + OMV.Vector3 angularHigh = new OMV.Vector3(f2PI, f2PI, f2PI); + if (LockedAxis.X != 1f) { - if (IsPhysicallyActive) - { - // Bullet can lock axis but it only works for global axis. - // Check if this prim is aligned on global axis and use Bullet's - // system if so. - - ForceOrientation = entprop.Rotation; - ForceRotationalVelocity = entprop.RotationalVelocity; - } + angularLow.X = 0f; + angularHigh.X = 0f; } - else + if (LockedAxis.Y != 1f) { - UnRegisterPreUpdatePropertyAction("BSPrim.LockAngularMotion"); + angularLow.Y = 0f; + angularHigh.Y = 0f; } + if (LockedAxis.Z != 1f) + { + angularLow.Z = 0f; + angularHigh.Z = 0f; + } + axisConstrainer.SetAngularLimits(angularLow, angularHigh); + + DetailLog("{0},BSPrim.LockAngularMotion,create,linLow={1},linHi={2},angLow={3},angHi={4}", + LocalID, linearLow, linearHigh, angularLow, angularHigh); + + // Constants from one of the posts mentioned above and used in Bullet's ConstraintDemo. + axisConstrainer.TranslationalLimitMotor(true /* enable */, 5.0f, 0.1f); + axisConstrainer.RecomputeConstraintVariables(RawMass); }); } else { // Everything seems unlocked - UnRegisterPreUpdatePropertyAction("BSPrim.LockAngularMotion"); + CleanUpLockAxisPhysicals(false /* inTaintTime */); } - */ return; } + // Get rid of any constraint built for LockAxis + // Most often the constraint is removed when the constraint collection is cleaned for this prim. + private void CleanUpLockAxisPhysicals(bool inTaintTime) + { + if (LockAxisConstraint != null) + { + PhysicsScene.TaintedObject(inTaintTime, "BSPrim.CleanUpLockAxisPhysicals", delegate() + { + if (LockAxisConstraint != null) + { + PhysicsScene.Constraints.RemoveAndDestroyConstraint(LockAxisConstraint); + LockAxisConstraint = null; + DetailLog("{0},BSPrim.CleanUpLockAxisPhysicals,destroyingConstraint", LocalID); + } + }); + } + } public override OMV.Vector3 RawPosition { @@ -762,6 +810,7 @@ public class BSPrim : BSPhysObject SetObjectDynamic(true); // whether phys-to-static or static-to-phys, the object is not moving. ZeroMotion(true); + }); } } @@ -885,6 +934,8 @@ public class BSPrim : BSPhysObject // For good measure, make sure the transform is set through to the motion state ForcePosition = _position; + ForceVelocity = _velocity; + ForceRotationalVelocity = _rotationalVelocity; // A dynamic object has mass UpdatePhysicalMassProperties(RawMass, false); @@ -1064,8 +1115,8 @@ public class BSPrim : BSPhysObject _buoyancy = value; // DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); // Force the recalculation of the various inertia,etc variables in the object - DetailLog("{0},BSPrim.ForceBuoyancy,buoy={1},mass={2}", LocalID, _buoyancy, _mass); - UpdatePhysicalMassProperties(_mass, true); + UpdatePhysicalMassProperties(RawMass, true); + DetailLog("{0},BSPrim.ForceBuoyancy,buoy={1},mass={2},grav={3}", LocalID, _buoyancy, RawMass, Gravity); ActivateIfPhysical(false); } } @@ -1303,6 +1354,7 @@ public class BSPrim : BSPhysObject { if (PhysBody.HasPhysicalBody) { + DetailLog("{0},BSPrim.AddAngularForce,taint,angForce={1}", LocalID, angForce); PhysicsScene.PE.ApplyTorque(PhysBody, angForce); ActivateIfPhysical(false); } -- cgit v1.1 From 050ef1dc4e9c6e2a8afe353343e19d8ae0ff72ee Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 18 Feb 2013 22:59:29 +0000 Subject: minor: Rename regression test method TestGetArrayLength() -> JsonTestGetArrayLength() to match others --- .../Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 3d9ad16..db82d4b 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -400,7 +400,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests // } [Test] - public void TestGetArrayLength() + public void TestJsonGetArrayLength() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); -- cgit v1.1 From 26dca1adc32e834e9debf47e66625fa36e7f3ace Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 19 Feb 2013 23:53:30 +0000 Subject: Convert JsonTestPath() use in json regression tests to JsonGetPathType() instead --- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index db82d4b..b64dbd4 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -158,8 +158,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests Assert.That(dsrv, Is.EqualTo(1)); - int tprv = (int)InvokeOp("JsonTestPath", storeId, "Hello"); - Assert.That(tprv, Is.EqualTo(0)); + int tprv = (int)InvokeOp("JsonGetPathType", storeId, "Hello"); + Assert.That(tprv, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_UNDEF)); } [Test] @@ -277,8 +277,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello"); Assert.That(returnValue, Is.EqualTo(1)); - int result = (int)InvokeOp("JsonTestPath", storeId, "Hello"); - Assert.That(result, Is.EqualTo(0)); + int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_UNDEF)); string returnValue2 = (string)InvokeOp("JsonGetValue", storeId, "Hello"); Assert.That(returnValue2, Is.EqualTo("")); @@ -291,8 +291,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello"); Assert.That(returnValue, Is.EqualTo(1)); - int result = (int)InvokeOp("JsonTestPath", storeId, "Hello"); - Assert.That(result, Is.EqualTo(0)); + int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_UNDEF)); string returnValue2 = (string)InvokeOp("JsonGetJson", storeId, "Hello"); Assert.That(returnValue2, Is.EqualTo("")); @@ -306,11 +306,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello[0]"); Assert.That(returnValue, Is.EqualTo(1)); - int result = (int)InvokeOp("JsonTestPath", storeId, "Hello[0]"); - Assert.That(result, Is.EqualTo(1)); + int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello[0]"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_VALUE)); - result = (int)InvokeOp("JsonTestPath", storeId, "Hello[1]"); - Assert.That(result, Is.EqualTo(0)); + result = (int)InvokeOp("JsonGetPathType", storeId, "Hello[1]"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_UNDEF)); string stringReturnValue = (string)InvokeOp("JsonGetValue", storeId, "Hello[0]"); Assert.That(stringReturnValue, Is.EqualTo("value2")); -- cgit v1.1 From 8a6f2432fc0c57645cb395578f373474548975e9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 20 Feb 2013 00:01:20 +0000 Subject: minor: remove some mono compiler warnings in OpenSim.Region.ClientStack.Linden.Caps.dll --- OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 2 +- OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index 1af61db..20df8a6 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -912,7 +912,7 @@ namespace OpenSim.Region.ClientStack.Linden string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { - OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request); +// OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request); OSDMap resp = new OSDMap(); OSDMap accessPrefs = new OSDMap(); diff --git a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs index 17c7270..69dd76f 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs @@ -56,8 +56,8 @@ namespace OpenSim.Region.ClientStack.Linden [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RegionConsoleModule")] public class RegionConsoleModule : INonSharedRegionModule, IRegionConsole { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = +// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene; private IEventQueue m_eventQueue; @@ -157,8 +157,8 @@ namespace OpenSim.Region.ClientStack.Linden public class ConsoleHandler : BaseStreamHandler { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = +// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private RegionConsoleModule m_consoleModule; private UUID m_agentID; -- cgit v1.1 From 4779f7d7d5ce0e284d9ed15104389f8479b11545 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 19 Feb 2013 17:14:55 -0800 Subject: Deleted all AssemblyFileVersion directives --- OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/DataSnapshot/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/Framework/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs | 2 +- .../Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/RegionCombinerModule/Properties/AssemblyInfo.cs | 2 +- .../ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs | 2 +- OpenSim/Region/UserStatistics/Properties/AssemblyInfo.cs | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs b/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs index d29a001..595d01a 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs @@ -30,4 +30,4 @@ using System.Runtime.InteropServices; // Revision // [assembly: AssemblyVersion("0.7.6.*")] -[assembly: AssemblyFileVersion("1.0.0.0")] + diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs b/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs index 8f9dad3..98ef72f 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs @@ -30,4 +30,4 @@ using System.Runtime.InteropServices; // Revision // [assembly: AssemblyVersion("0.7.6.*")] -[assembly: AssemblyFileVersion("1.0.0.0")] + diff --git a/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs b/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs index f6353f9..bfe0383 100644 --- a/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs @@ -31,7 +31,7 @@ using Mono.Addins; // Revision // [assembly: AssemblyVersion("0.7.6.*")] -[assembly: AssemblyFileVersion("1.0.0.0")] + [assembly: Addin("OpenSim.Region.CoreModules", "0.1")] [assembly: AddinDependency("OpenSim", "0.5")] diff --git a/OpenSim/Region/DataSnapshot/Properties/AssemblyInfo.cs b/OpenSim/Region/DataSnapshot/Properties/AssemblyInfo.cs index 0f083c7..0e7df07 100644 --- a/OpenSim/Region/DataSnapshot/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/DataSnapshot/Properties/AssemblyInfo.cs @@ -30,4 +30,4 @@ using System.Runtime.InteropServices; // Revision // [assembly: AssemblyVersion("0.7.6.*")] -[assembly: AssemblyFileVersion("1.0.0.0")] + diff --git a/OpenSim/Region/Framework/Properties/AssemblyInfo.cs b/OpenSim/Region/Framework/Properties/AssemblyInfo.cs index 2a5828e..167c248 100644 --- a/OpenSim/Region/Framework/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/Framework/Properties/AssemblyInfo.cs @@ -30,4 +30,4 @@ using System.Runtime.InteropServices; // Revision // [assembly: AssemblyVersion("0.7.6.*")] -[assembly: AssemblyFileVersion("1.0.0.0")] + diff --git a/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs b/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs index 0065531..70bda72 100644 --- a/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs @@ -31,7 +31,7 @@ using Mono.Addins; // Revision // [assembly: AssemblyVersion("0.7.6.*")] -[assembly: AssemblyFileVersion("1.0.0.0")] + [assembly: Addin("OpenSim.Region.OptionalModules", "0.1")] [assembly: AddinDependency("OpenSim", "0.5")] diff --git a/OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs b/OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs index d240c71..02b03a8 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs @@ -30,4 +30,4 @@ using System.Runtime.InteropServices; // Revision // [assembly: AssemblyVersion("0.7.6.*")] -[assembly: AssemblyFileVersion("1.0.0.0")] + diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs index cafd7f4..f611b9a 100644 --- a/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs @@ -33,4 +33,4 @@ using System.Runtime.InteropServices; // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("0.7.6.*")] -[assembly: AssemblyFileVersion("1.0.0.0")] + diff --git a/OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs b/OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs index bd70296..3de061a 100644 --- a/OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs @@ -30,4 +30,4 @@ using System.Runtime.InteropServices; // Revision // [assembly: AssemblyVersion("0.7.6.*")] -[assembly: AssemblyFileVersion("1.0.0.0")] + diff --git a/OpenSim/Region/RegionCombinerModule/Properties/AssemblyInfo.cs b/OpenSim/Region/RegionCombinerModule/Properties/AssemblyInfo.cs index ca945b5..86a3101 100644 --- a/OpenSim/Region/RegionCombinerModule/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/RegionCombinerModule/Properties/AssemblyInfo.cs @@ -30,4 +30,4 @@ using System.Runtime.InteropServices; // Revision // [assembly: AssemblyVersion("0.7.6.*")] -[assembly: AssemblyFileVersion("1.0.0.0")] + diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs index 3c01eec..6d218a6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs @@ -30,4 +30,4 @@ using System.Runtime.InteropServices; // Revision // [assembly: AssemblyVersion("0.7.6.*")] -[assembly: AssemblyFileVersion("1.0.0.0")] + diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs index fd37753..5b5c4fd 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs @@ -30,4 +30,4 @@ using System.Runtime.InteropServices; // Revision // [assembly: AssemblyVersion("0.7.6.*")] -[assembly: AssemblyFileVersion("1.0.0.0")] + diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs index 74747a2..48964b6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs @@ -30,4 +30,4 @@ using System.Runtime.InteropServices; // Revision // [assembly: AssemblyVersion("0.7.6.*")] -[assembly: AssemblyFileVersion("1.0.0.0")] + diff --git a/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs index a887171..f0640da 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs @@ -30,4 +30,4 @@ using System.Runtime.InteropServices; // Revision // [assembly: AssemblyVersion("0.7.6.*")] -[assembly: AssemblyFileVersion("1.0.0.0")] + diff --git a/OpenSim/Region/UserStatistics/Properties/AssemblyInfo.cs b/OpenSim/Region/UserStatistics/Properties/AssemblyInfo.cs index caa6d4e..1fff12a 100644 --- a/OpenSim/Region/UserStatistics/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/UserStatistics/Properties/AssemblyInfo.cs @@ -30,4 +30,4 @@ using System.Runtime.InteropServices; // Revision // [assembly: AssemblyVersion("0.7.6.*")] -[assembly: AssemblyFileVersion("1.0.0.0")] + -- cgit v1.1 From 903b40b47e53cc131b57919e8a8a83db3cb36f96 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Tue, 19 Feb 2013 22:53:46 -0800 Subject: Fix the JsonStore path set problem justincc found earlier today and remove the deprecated TestPath functions. --- .../Framework/Interfaces/IJsonStoreModule.cs | 1 - .../Scripting/JsonStore/JsonStore.cs | 28 ++-------------- .../Scripting/JsonStore/JsonStoreModule.cs | 32 ------------------ .../Scripting/JsonStore/JsonStoreScriptModule.cs | 38 ---------------------- 4 files changed, 3 insertions(+), 96 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs index b40d24f..345f01b 100644 --- a/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs @@ -51,7 +51,6 @@ namespace OpenSim.Region.Framework.Interfaces JsonStoreNodeType GetPathType(UUID storeID, string path); bool TestStore(UUID storeID); - bool TestPath(UUID storeID, string path, bool useJson); bool SetValue(UUID storeID, string path, string value, bool useJson); bool RemoveValue(UUID storeID, string path); diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs index ca3989a..40adba1 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs @@ -84,11 +84,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore protected static Regex m_PathComponent = new Regex("\\.({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])"); // extract the internals of an array reference - protected static Regex m_SimpleArrayPattern = new Regex("\\[([0-9]+)\\]"); - protected static Regex m_ArrayPattern = new Regex("\\[([0-9]+|\\+)\\]"); + protected static Regex m_SimpleArrayPattern = new Regex("^\\[([0-9]+)\\]$"); + protected static Regex m_ArrayPattern = new Regex("^\\[([0-9]+|\\+)\\]$"); // extract the internals of a has reference - protected static Regex m_HashPattern = new Regex("{([^}]+)}"); + protected static Regex m_HashPattern = new Regex("^{([^}]+)}$"); // ----------------------------------------------------------------- /// @@ -173,28 +173,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - public bool TestPath(string expr, bool useJson) - { - Stack path; - if (! ParsePathExpression(expr,out path)) - return false; - - OSD result = ProcessPathExpression(ValueStore,path); - - if (result == null) - return false; - - if (useJson || OSDBaseType(result.Type)) - return true; - - return false; - } - - // ----------------------------------------------------------------- - /// - /// - /// - // ----------------------------------------------------------------- public int ArrayLength(string expr) { Stack path; diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs index fb35068..e78a2f4 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs @@ -302,38 +302,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - public bool TestPath(UUID storeID, string path, bool useJson) - { - if (! m_enabled) return false; - - JsonStore map = null; - lock (m_JsonValueStore) - { - if (! m_JsonValueStore.TryGetValue(storeID,out map)) - { - m_log.InfoFormat("[JsonStore] Missing store {0}",storeID); - return false; - } - } - - try - { - lock (map) - return map.TestPath(path,useJson); - } - catch (Exception e) - { - m_log.Error(string.Format("[JsonStore]: Path test failed for {0} in {1}", path, storeID), e); - } - - return false; - } - - // ----------------------------------------------------------------- - /// - /// - /// - // ----------------------------------------------------------------- public bool SetValue(UUID storeID, string path, string value, bool useJson) { if (! m_enabled) return false; diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index ef08c05..e13eb56 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs @@ -168,32 +168,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore { m_comms.RegisterScriptInvocations(this); m_comms.RegisterConstants(this); - - // m_comms.RegisterScriptInvocation(this, "JsonCreateStore"); - // m_comms.RegisterScriptInvocation(this, "JsonAttachObjectStore"); - // m_comms.RegisterScriptInvocation(this, "JsonDestroyStore"); - // m_comms.RegisterScriptInvocation(this, "JsonTestStore"); - - // m_comms.RegisterScriptInvocation(this, "JsonReadNotecard"); - // m_comms.RegisterScriptInvocation(this, "JsonWriteNotecard"); - - // m_comms.RegisterScriptInvocation(this, "JsonTestPathList"); - // m_comms.RegisterScriptInvocation(this, "JsonTestPath"); - // m_comms.RegisterScriptInvocation(this, "JsonTestPathJson"); - - // m_comms.RegisterScriptInvocation(this, "JsonGetValue"); - // m_comms.RegisterScriptInvocation(this, "JsonGetValueJson"); - - // m_comms.RegisterScriptInvocation(this, "JsonTakeValue"); - // m_comms.RegisterScriptInvocation(this, "JsonTakeValueJson"); - - // m_comms.RegisterScriptInvocation(this, "JsonReadValue"); - // m_comms.RegisterScriptInvocation(this, "JsonReadValueJson"); - - // m_comms.RegisterScriptInvocation(this, "JsonSetValue"); - // m_comms.RegisterScriptInvocation(this, "JsonSetValueJson"); - - // m_comms.RegisterScriptInvocation(this, "JsonRemoveValue"); } catch (Exception e) { @@ -341,18 +315,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore return (int)m_store.GetPathType(storeID,path); } - [ScriptInvocation] - public int JsonTestPath(UUID hostID, UUID scriptID, UUID storeID, string path) - { - return m_store.TestPath(storeID,path,false) ? 1 : 0; - } - - [ScriptInvocation] - public int JsonTestPathJson(UUID hostID, UUID scriptID, UUID storeID, string path) - { - return m_store.TestPath(storeID,path,true) ? 1 : 0; - } - // ----------------------------------------------------------------- /// /// -- cgit v1.1 From a671c06ee59e17a6ae7be9740e8e045ae9ac224c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 20 Feb 2013 22:09:33 +0000 Subject: Correct mistake in parsing 'show object pos' and similar pos commands where the 'to' text would be treat as the end vector rather than discarded. Before this, the commands still work but the help text is wrong - one has to leave out the 'to' in stating the vectors --- .../CoreModules/World/Objects/Commands/ObjectCommandsModule.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs index 9fc2daf..28db407 100644 --- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs @@ -416,7 +416,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands if (!ConsoleUtil.TryParseConsoleMinVector(rawConsoleStartVector, out startVector)) { - m_console.OutputFormat("Error: Start vector {0} does not have a valid format", rawConsoleStartVector); + m_console.OutputFormat("Error: Start vector '{0}' does not have a valid format", rawConsoleStartVector); return; } @@ -425,7 +425,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands if (!ConsoleUtil.TryParseConsoleMaxVector(rawConsoleEndVector, out endVector)) { - m_console.OutputFormat("Error: End vector {0} does not have a valid format", rawConsoleEndVector); + m_console.OutputFormat("Error: End vector '{0}' does not have a valid format", rawConsoleEndVector); return; } @@ -896,17 +896,17 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands if (!ConsoleUtil.TryParseConsoleMinVector(rawConsoleStartVector, out startVector)) { - m_console.OutputFormat("Error: Start vector {0} does not have a valid format", rawConsoleStartVector); + m_console.OutputFormat("Error: Start vector '{0}' does not have a valid format", rawConsoleStartVector); endVector = Vector3.Zero; return false; } - string rawConsoleEndVector = rawComponents.Skip(1).Take(1).Single(); + string rawConsoleEndVector = rawComponents.Skip(2).Take(1).Single(); if (!ConsoleUtil.TryParseConsoleMaxVector(rawConsoleEndVector, out endVector)) { - m_console.OutputFormat("Error: End vector {0} does not have a valid format", rawConsoleEndVector); + m_console.OutputFormat("Error: End vector '{0}' does not have a valid format", rawConsoleEndVector); return false; } -- cgit v1.1 From 16bb40229b84cff5f2543591464256907855cb2a Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 20 Feb 2013 14:10:32 -0800 Subject: Add flush after write feature to LogWriter --- .../CoreModules/Framework/Statistics/Logging/LogWriter.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs index fd8d5e3..3c8e0ef 100755 --- a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs +++ b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs @@ -52,6 +52,7 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging private TimeSpan m_logFileLife; private DateTime m_logFileEndTime; private Object m_logFileWriteLock = new Object(); + private bool m_flushWrite; // set externally when debugging. If let 'null', this does not write any error messages. public ILog ErrorLogger = null; @@ -73,7 +74,9 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging /// The directory to create the log file in. May be 'null' for default. /// The characters that begin the log file name. May be 'null' for default. /// Maximum age of a log file in minutes. If zero, will set default. - public LogWriter(string dir, string headr, int maxFileTime) + /// Whether to do a flush after every log write. Best left off but + /// if one is looking for a crash, this is a good thing to turn on. + public LogWriter(string dir, string headr, int maxFileTime, bool flushWrite) { m_logDirectory = dir == null ? "." : dir; @@ -86,8 +89,14 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging m_logFileLife = new TimeSpan(0, m_logMaxFileTimeMin, 0); m_logFileEndTime = DateTime.Now + m_logFileLife; + m_flushWrite = flushWrite; + Enabled = true; } + // Constructor that assumes flushWrite is off. + public LogWriter(string dir, string headr, int maxFileTime) : this(dir, headr, maxFileTime, false) + { + } public void Dispose() { @@ -153,6 +162,8 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging buff.Append(line); buff.Append("\r\n"); m_logFile.Write(buff.ToString()); + if (m_flushWrite) + m_logFile.Flush(); } } } -- cgit v1.1 From 681653ca130eaf15c62aae6fd1a7c5276036a0e9 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 20 Feb 2013 14:11:02 -0800 Subject: Add a method to IStatsCollector for returning stats as an OSDMap. Extend implementors of IStatsCollector to return an OSDMap of stats. Update UserStatsCollector and AssetStatsCollector to return both string and OSDMap data (as well as console format). --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index a187190..5675870 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -12138,6 +12138,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP return String.Empty; } + public OSDMap OReport(string uptime, string version) + { + return new OSDMap(); + } + /// /// Make an asset request to the asset service in response to a client request. /// -- cgit v1.1 From efb5da0aa672551a8a68e16066f3dd3991f75da4 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 21 Feb 2013 08:52:11 -0800 Subject: BulletSim: add OutOfBounds logic and some position sanity checking to eliminate some of the "cannot find terrain height" warning messages. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 7 ++-- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 43 ++++++++++++++-------- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 27 ++++++++++++-- .../Physics/BulletSPlugin/BSShapeCollection.cs | 2 +- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 22 ++++++----- 5 files changed, 68 insertions(+), 33 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 8dca7c6..1f186c3 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -443,6 +443,7 @@ public sealed class BSCharacter : BSPhysObject PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate() { DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); + PositionSanityCheck(); ForcePosition = _position; }); } @@ -456,7 +457,6 @@ public sealed class BSCharacter : BSPhysObject _position = value; if (PhysBody.HasPhysicalBody) { - PositionSanityCheck(); PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); } } @@ -512,9 +512,8 @@ public sealed class BSCharacter : BSPhysObject // just assign to "Position" because of potential call loops. PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.PositionSanityCheck", delegate() { - DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); - if (PhysBody.HasPhysicalBody) - PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); + DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); + ForcePosition = _position; }); ret = true; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index c2a9671..dc57b67 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -46,6 +46,8 @@ public static class BSParam public static float MeshMegaPrimThreshold { get; private set; } public static float SculptLOD { get; private set; } + public static int CrossingFailuresBeforeOutOfBounds { get; private set; } + public static float MinimumObjectMass { get; private set; } public static float MaximumObjectMass { get; private set; } public static float MaxLinearVelocity { get; private set; } @@ -73,23 +75,23 @@ public static class BSParam public static float TerrainRestitution { get; private set; } public static float TerrainCollisionMargin { get; private set; } - public static float DefaultFriction; - public static float DefaultDensity; - public static float DefaultRestitution; - public static float CollisionMargin; - public static float Gravity; + public static float DefaultFriction { get; private set; } + public static float DefaultDensity { get; private set; } + public static float DefaultRestitution { get; private set; } + public static float CollisionMargin { get; private set; } + public static float Gravity { get; private set; } // Physics Engine operation - public static float MaxPersistantManifoldPoolSize; - public static float MaxCollisionAlgorithmPoolSize; - public static bool ShouldDisableContactPoolDynamicAllocation; - public static bool ShouldForceUpdateAllAabbs; - public static bool ShouldRandomizeSolverOrder; - public static bool ShouldSplitSimulationIslands; - public static bool ShouldEnableFrictionCaching; - public static float NumberOfSolverIterations; - public static bool UseSingleSidedMeshes; - public static float GlobalContactBreakingThreshold; + public static float MaxPersistantManifoldPoolSize { get; private set; } + public static float MaxCollisionAlgorithmPoolSize { get; private set; } + public static bool ShouldDisableContactPoolDynamicAllocation { get; private set; } + public static bool ShouldForceUpdateAllAabbs { get; private set; } + public static bool ShouldRandomizeSolverOrder { get; private set; } + public static bool ShouldSplitSimulationIslands { get; private set; } + public static bool ShouldEnableFrictionCaching { get; private set; } + public static float NumberOfSolverIterations { get; private set; } + public static bool UseSingleSidedMeshes { get; private set; } + public static float GlobalContactBreakingThreshold { get; private set; } // Avatar parameters public static float AvatarFriction { get; private set; } @@ -118,6 +120,7 @@ public static class BSParam public static float VehicleGroundGravityFudge { get; private set; } public static bool VehicleDebuggingEnabled { get; private set; } + // Linkset implementation parameters public static float LinksetImplementation { get; private set; } public static bool LinkConstraintUseFrameOffset { get; private set; } public static bool LinkConstraintEnableTransMotor { get; private set; } @@ -282,6 +285,11 @@ public static class BSParam (s) => { return ShouldRemoveZeroWidthTriangles; }, (s,v) => { ShouldRemoveZeroWidthTriangles = v; } ), + new ParameterDefn("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions", + 5, + (s) => { return CrossingFailuresBeforeOutOfBounds; }, + (s,v) => { CrossingFailuresBeforeOutOfBounds = v; } ), + new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", 32f, (s) => { return MeshLOD; }, @@ -695,6 +703,10 @@ public static class BSParam } } + // ===================================================================== + // ===================================================================== + // There are parameters that, when set, cause things to happen in the physics engine. + // This causes the broadphase collision cache to be cleared. private static void ResetBroadphasePoolTainted(BSScene pPhysScene, float v) { BSScene physScene = pPhysScene; @@ -704,6 +716,7 @@ public static class BSParam }); } + // This causes the constraint solver cache to be cleared and reset. private static void ResetConstraintSolverTainted(BSScene pPhysScene, float v) { BSScene physScene = pPhysScene; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 4d61ad2..4dff927 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -70,6 +70,8 @@ public class BSPrim : BSPhysObject private bool _kinematic; private float _buoyancy; + private int CrossingFailures { get; set; } + public BSDynamics VehicleController { get; private set; } private BSVMotor _targetMotor; @@ -197,7 +199,20 @@ public class BSPrim : BSPhysObject { get { return _isSelected; } } - public override void CrossingFailure() { return; } + + public override void CrossingFailure() + { + CrossingFailures++; + if (CrossingFailures > BSParam.CrossingFailuresBeforeOutOfBounds) + { + base.RaiseOutOfBounds(RawPosition); + } + else if (CrossingFailures == BSParam.CrossingFailuresBeforeOutOfBounds) + { + m_log.WarnFormat("{0} Too many crossing failures for {1}", LogHeader, Name); + } + return; + } // link me to the specified parent public override void link(PhysicsActor obj) { @@ -1123,7 +1138,11 @@ public class BSPrim : BSPhysObject // Used for MoveTo public override OMV.Vector3 PIDTarget { - set { _PIDTarget = value; } + set + { + // TODO: add a sanity check -- don't move more than a region or something like that. + _PIDTarget = value; + } } public override float PIDTau { set { _PIDTau = value; } @@ -1177,7 +1196,9 @@ public class BSPrim : BSPhysObject } else { - ForcePosition = movePosition; + _position = movePosition; + PositionSanityCheck(true /* intaintTime */); + ForcePosition = _position; } DetailLog("{0},BSPrim.PIDTarget,move,fromPos={1},movePos={2}", LocalID, origPosition, movePosition); }); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 15747c9..219372b 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -568,7 +568,7 @@ public sealed class BSShapeCollection : IDisposable { newShape = PhysicsScene.PE.BuildCapsuleShape(PhysicsScene.World, 1f, 1f, prim.Scale); - if (DDetail) DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); + if (DDetail) DetailLog("{0},BSShapeCollection.BuildPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); } else { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index bda7c47..49718c4 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -1,17 +1,16 @@ CURRENT PRIORITIES ================================================= -One sided meshes? Should terrain be built into a closed shape? - When meshes get partially wedged into the terrain, they cannot push themselves out. - It is possible that Bullet processes collisions whether entering or leaving a mesh. - Ref: http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4869 Deleting a linkset while standing on the root will leave the physical shape of the root behind. Not sure if it is because standing on it. Done with large prim linksets. -Terrain detail: double terrain mesh detail Vehicle angular vertical attraction vehicle angular banking Center-of-gravity Vehicle angular deflection Preferred orientation angular correction fix +Enable vehicle border crossings (at least as poorly as ODE) + Terrain skirts + Avatar created in previous region and not new region when crossing border + Vehicle recreated in new sim at small Z value (offset from root value?) (DONE) when should angular and linear motor targets be zeroed? when selected? Need a vehicle.clear()? Or an 'else' in prestep if not physical. Teravus llMoveToTarget script debug @@ -26,14 +25,16 @@ Avatar movement flying into a wall doesn't stop avatar who keeps appearing to move through the obstacle (DONE) walking up stairs is not calibrated correctly (stairs out of Kepler cabin) avatar capsule rotation completed (NOT DONE - Bullet's capsule shape is not the solution) -Enable vehicle border crossings (at least as poorly as ODE) - Terrain skirts - Avatar created in previous region and not new region when crossing border - Vehicle recreated in new sim at small Z value (offset from root value?) (DONE) Vehicle script tuning/debugging Avanti speed script Weapon shooter script -Add material densities to the material types +Move material definitions (friction, ...) into simulator. +Add material densities to the material types. +Terrain detail: double terrain mesh detail +One sided meshes? Should terrain be built into a closed shape? + When meshes get partially wedged into the terrain, they cannot push themselves out. + It is possible that Bullet processes collisions whether entering or leaving a mesh. + Ref: http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4869 VEHICLES TODO LIST: ================================================= @@ -65,6 +66,7 @@ Vehicle attributes are not restored when a vehicle is rezzed on region creation GENERAL TODO LIST: ================================================= +Add a sanity check for PIDTarget location. Level-of-detail for mesh creation. Prims with circular interiors require lod of 32. Is much saved with lower LODs? At the moment, all set to 32. Collisions are inconsistant: arrows are supposed to hit and report collision. Often don't. -- cgit v1.1 From 9de670c550fd6847c2c14413d2c956f446b958f0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 21 Feb 2013 23:08:50 +0000 Subject: minor: Change summary in "show appearance" console command to "incomplete" rather than "corrupt" Corrupt is misleading - it implies textures were uploaded but are not j2k valid. The actual situation is that at least one required baked texture is not present. --- OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | 2 +- .../Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index ce79f07..00d1fd8 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -693,7 +693,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory } bool bakedTextureValid = m_scene.AvatarFactory.ValidateBakedTextureCache(sp); - outputAction("{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt"); + outputAction("{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "incomplete"); } } } diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index d718a2f..fa35f0f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -222,7 +222,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance { bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(sp); MainConsole.Instance.OutputFormat( - "{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt"); + "{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "incomplete"); } ); } -- cgit v1.1 From e515cdddec435e97e9ed4722de08ee410e94a7e6 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 21 Feb 2013 17:26:19 -0800 Subject: Simplification of HG configs: HomeURI and GatekeeperURI now are defined as default under [Startup]. They can then be overwritten in the other sections (but probably shouldn't). I kept the existing code for backwards compatibility, so this should not cause any breaks from people's current configurations. But people should move to have these 2 vars under [Startup] -- see OpenSim.ini.example and Robust.HG.ini.example. And yes, both names now end with "URI" for consistency. --- OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs | 4 +++- .../Framework/InventoryAccess/HGInventoryAccessModule.cs | 9 ++++----- OpenSim/Region/DataSnapshot/DataSnapshotManager.cs | 13 ++++++++++--- .../ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 12 ++++++++++-- 4 files changed, 27 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs index 232a4fe..784a788 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs @@ -65,7 +65,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure { m_Enabled = true; - m_ThisGridURL = config.Configs["Messaging"].GetString("Gatekeeper", string.Empty); + m_ThisGridURL = Util.GetConfigVarWithDefaultSection(config, "GatekeeperURI", "Messaging"); + // Legacy. Remove soon! + m_ThisGridURL = config.Configs["Messaging"].GetString("Gatekeeper", m_ThisGridURL); m_log.DebugFormat("[LURE MODULE]: {0} enabled", Name); } } diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs index 964efda..c439ea8 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs @@ -88,12 +88,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"]; if (thisModuleConfig != null) { - // legacy configuration [obsolete] - m_HomeURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty); - // preferred - m_HomeURI = thisModuleConfig.GetString("HomeURI", m_HomeURI); + m_HomeURI = Util.GetConfigVarWithDefaultSection(source, "HomeURI", "HGInventoryAccessModule"); m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true); - m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", string.Empty); + m_ThisGatekeeper = Util.GetConfigVarWithDefaultSection(source, "GatekeeperURI", "HGInventoryAccessModule"); + // Legacy. Renove soon! + m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", m_ThisGatekeeper); m_RestrictInventoryAccessAbroad = thisModuleConfig.GetBoolean("RestrictInventoryAccessAbroad", true); } else diff --git a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs index 5e62f23..13d9d31 100644 --- a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs +++ b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs @@ -113,9 +113,16 @@ namespace OpenSim.Region.DataSnapshot try { m_enabled = config.Configs["DataSnapshot"].GetBoolean("index_sims", m_enabled); - IConfig conf = config.Configs["GridService"]; - if (conf != null) - m_gridinfo.Add("gatekeeperURL", conf.GetString("Gatekeeper", String.Empty)); + string gatekeeper = Util.GetConfigVarWithDefaultSection(config, "GatekeeperURI", "GridService"); + // Legacy. Remove soon! + if (string.IsNullOrEmpty(gatekeeper)) + { + IConfig conf = config.Configs["GridService"]; + if (conf != null) + gatekeeper = conf.GetString("Gatekeeper", gatekeeper); + } + if (!string.IsNullOrEmpty(gatekeeper)) + m_gridinfo.Add("gatekeeperURL", gatekeeper); m_gridinfo.Add( "name", config.Configs["DataSnapshot"].GetString("gridname", "the lost continent of hippo")); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 1426070..0334169 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2137,9 +2137,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api CheckThreatLevel(ThreatLevel.Moderate, "osGetGridHomeURI"); m_host.AddScriptLPS(1); - string HomeURI = String.Empty; IConfigSource config = m_ScriptEngine.ConfigSource; + string HomeURI = Util.GetConfigVarWithDefaultSection(config, "HomeURI", string.Empty); + if (!string.IsNullOrEmpty(HomeURI)) + return HomeURI; + + // Legacy. Remove soon! if (config.Configs["LoginService"] != null) HomeURI = config.Configs["LoginService"].GetString("SRV_HomeURI", HomeURI); @@ -2154,9 +2158,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api CheckThreatLevel(ThreatLevel.Moderate, "osGetGridGatekeeperURI"); m_host.AddScriptLPS(1); - string gatekeeperURI = String.Empty; IConfigSource config = m_ScriptEngine.ConfigSource; + string gatekeeperURI = Util.GetConfigVarWithDefaultSection(config, "GatekeeperURI", string.Empty); + + if (!string.IsNullOrEmpty(gatekeeperURI)) + return gatekeeperURI; + // Legacy. Remove soon! if (config.Configs["GridService"] != null) gatekeeperURI = config.Configs["GridService"].GetString("Gatekeeper", gatekeeperURI); -- cgit v1.1 From ccb7cce8190f50024ebf25369d95e7267376f28b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 22 Feb 2013 21:59:00 +0000 Subject: Make reset of EntityTransferStateMachine for an avatar transfer always happen despite unexpected exceptions. This means that if such an exception does occur, the region does not need to be reset before that user can teleport from it again. This is all Oren's code from his patch in http://opensimulator.org/mantis/view.php?id=6374 but I've chosen to split it in two. --- .../EntityTransfer/EntityTransferModule.cs | 123 ++++++++++++++------- 1 file changed, 81 insertions(+), 42 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 3cb1901..07c3666 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -179,13 +179,24 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (!sp.Scene.Permissions.CanTeleport(sp.UUID)) return; - // Reset animations; the viewer does that in teleports. - sp.Animator.ResetAnimations(); - string destinationRegionName = "(not found)"; + // Record that this agent is in transit so that we can prevent simultaneous requests and do later detection + // of whether the destination region completes the teleport. + if (!m_entityTransferStateMachine.SetInTransit(sp.UUID)) + { + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2}@{3} - agent is already in transit.", + sp.Name, sp.UUID, position, regionHandle); + + return; + } + try { + // Reset animations; the viewer does that in teleports. + sp.Animator.ResetAnimations(); + if (regionHandle == sp.Scene.RegionInfo.RegionHandle) { destinationRegionName = sp.Scene.RegionInfo.RegionName; @@ -194,12 +205,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } else // Another region possibly in another simulator { - GridRegion finalDestination; - TeleportAgentToDifferentRegion( - sp, regionHandle, position, lookAt, teleportFlags, out finalDestination); - - if (finalDestination != null) - destinationRegionName = finalDestination.RegionName; + GridRegion finalDestination = null; + try + { + TeleportAgentToDifferentRegion( + sp, regionHandle, position, lookAt, teleportFlags, out finalDestination); + } + finally + { + if (finalDestination != null) + destinationRegionName = finalDestination.RegionName; + } } } catch (Exception e) @@ -209,11 +225,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, destinationRegionName, e.Message, e.StackTrace); - // Make sure that we clear the in-transit flag so that future teleport attempts don't always fail. - m_entityTransferStateMachine.ResetFromTransit(sp.UUID); - sp.ControllingClient.SendTeleportFailed("Internal error"); } + finally + { + m_entityTransferStateMachine.ResetFromTransit(sp.UUID); + } } /// @@ -229,15 +246,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: Teleport for {0} to {1} within {2}", sp.Name, position, sp.Scene.RegionInfo.RegionName); - if (!m_entityTransferStateMachine.SetInTransit(sp.UUID)) - { - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Ignoring within region teleport request of {0} {1} to {2} - agent is already in transit.", - sp.Name, sp.UUID, position); - - return; - } - // Teleport within the same region if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) { @@ -282,7 +290,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); - m_entityTransferStateMachine.ResetFromTransit(sp.UUID); } /// @@ -336,7 +343,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // // This is it // - DoTeleport(sp, reg, finalDestination, position, lookAt, teleportFlags); + DoTeleportInternal(sp, reg, finalDestination, position, lookAt, teleportFlags); // // // @@ -391,6 +398,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer && Math.Abs(sourceRegion.RegionLocY - destRegion.RegionCoordY) <= MaxTransferDistance; } + /// + /// Wraps DoTeleportInternal() and manages the transfer state. + /// public void DoTeleport( ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags) @@ -405,12 +415,37 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } + + try + { + DoTeleportInternal(sp, reg, finalDestination, position, lookAt, teleportFlags); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[ENTITY TRANSFER MODULE]: Exception on teleport of {0} from {1}@{2} to {3}@{4}: {5}{6}", + sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, finalDestination.RegionName, + e.Message, e.StackTrace); - if (reg == null || finalDestination == null) + sp.ControllingClient.SendTeleportFailed("Internal error"); + } + finally { - sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); m_entityTransferStateMachine.ResetFromTransit(sp.UUID); + } + } + /// + /// Teleports the agent to another region. + /// This method doesn't manage the transfer state; the caller must do that. + /// + private void DoTeleportInternal( + ScenePresence sp, GridRegion reg, GridRegion finalDestination, + Vector3 position, Vector3 lookAt, uint teleportFlags) + { + if (reg == null || finalDestination == null) + { + sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); return; } @@ -430,8 +465,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY, MaxTransferDistance)); - m_entityTransferStateMachine.ResetFromTransit(sp.UUID); - return; } @@ -450,7 +483,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (endPoint.Address == null) { sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); - m_entityTransferStateMachine.ResetFromTransit(sp.UUID); return; } @@ -472,7 +504,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) { sp.ControllingClient.SendTeleportFailed(reason); - m_entityTransferStateMachine.ResetFromTransit(sp.UUID); m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}", @@ -528,7 +559,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) { sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason)); - m_entityTransferStateMachine.ResetFromTransit(sp.UUID); m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}", @@ -629,7 +659,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); - Fail(sp, finalDestination, logout); + Fail(sp, finalDestination, logout); return; } @@ -682,8 +712,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", // sp.UUID); // } - - m_entityTransferStateMachine.ResetFromTransit(sp.UUID); } protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout) @@ -703,8 +731,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer Scene.SimulationService.CloseAgent(finalDestination, sp.UUID); sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); - - m_entityTransferStateMachine.ResetFromTransit(sp.UUID); } protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) @@ -1133,16 +1159,24 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (neighbourRegion == null) return agent; - try + if (!m_entityTransferStateMachine.SetInTransit(agent.UUID)) { - m_entityTransferStateMachine.SetInTransit(agent.UUID); + m_log.ErrorFormat( + "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2} - agent is already in transit", + agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName); + return agent; + } + bool transitWasReset = false; + + try + { ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); - + m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}", agent.Firstname, agent.Lastname, neighbourx, neighboury, version); - + Scene m_scene = agent.Scene; if (!agent.ValidateAttachments()) @@ -1155,7 +1189,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer agent.RemoveFromPhysicalScene(); - AgentData cAgent = new AgentData(); + AgentData cAgent = new AgentData(); agent.CopyTo(cAgent); cAgent.Position = pos; if (isFlying) @@ -1174,7 +1208,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer ReInstantiateScripts(agent); agent.AddToPhysicalScene(isFlying); - m_entityTransferStateMachine.ResetFromTransit(agent.UUID); return agent; } @@ -1222,6 +1255,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // FIXME: Possibly this should occur lower down after other commands to close other agents, // but not sure yet what the side effects would be. m_entityTransferStateMachine.ResetFromTransit(agent.UUID); + transitWasReset = true; // now we have a child agent in this region. Request all interesting data about other (root) agents agent.SendOtherAgentsAvatarDataToMe(); @@ -1261,6 +1295,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. } + finally + { + if (!transitWasReset) + m_entityTransferStateMachine.ResetFromTransit(agent.UUID); + } return agent; } @@ -2083,4 +2122,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #endregion } -} \ No newline at end of file +} -- cgit v1.1 From a93f06eb88489f822d903249377ce8cbdd991fb0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 22 Feb 2013 23:08:14 +0000 Subject: minor: Add doc to ScenePresence.IsInTransit to make it clear that this is set only for region crossing and not teleport, etc. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 9c1d2b6..39a885c 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -657,6 +657,12 @@ namespace OpenSim.Region.Framework.Scenes private bool m_inTransit; + /// + /// This signals whether the presence is in transit between neighbouring regions. + /// + /// + /// It is not set when the presence is teleporting or logging in/out directly to a region. + /// public bool IsInTransit { get { return m_inTransit; } -- cgit v1.1 From 0e8289cd002b1947e172d1bfc77fdd0b16d92ffb Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 22 Feb 2013 15:57:33 -0800 Subject: Added new Util function for reading config vars that's more generic than the one I added yesterday -- this is for helping move config vars out of [Startup] --- OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs | 2 +- .../Framework/InventoryAccess/HGInventoryAccessModule.cs | 7 ++++--- OpenSim/Region/DataSnapshot/DataSnapshotManager.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 4 ++-- 4 files changed, 8 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs index 784a788..22cdc80 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs @@ -65,7 +65,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure { m_Enabled = true; - m_ThisGridURL = Util.GetConfigVarWithDefaultSection(config, "GatekeeperURI", "Messaging"); + m_ThisGridURL = Util.GetConfigVarFromSections(config, "GatekeeperURI", new string[] {"Startup", "Messaging"}); // Legacy. Remove soon! m_ThisGridURL = config.Configs["Messaging"].GetString("Gatekeeper", m_ThisGridURL); m_log.DebugFormat("[LURE MODULE]: {0} enabled", Name); diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs index c439ea8..4f6b92e 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs @@ -88,11 +88,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"]; if (thisModuleConfig != null) { - m_HomeURI = Util.GetConfigVarWithDefaultSection(source, "HomeURI", "HGInventoryAccessModule"); - m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true); - m_ThisGatekeeper = Util.GetConfigVarWithDefaultSection(source, "GatekeeperURI", "HGInventoryAccessModule"); + m_HomeURI = Util.GetConfigVarFromSections(source, "HomeURI", new string[] {"Startup", "HGInventoryAccessModule"}); + m_ThisGatekeeper = Util.GetConfigVarFromSections(source, "GatekeeperURI", new string[] {"Startup", "HGInventoryAccessModule"}); // Legacy. Renove soon! m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", m_ThisGatekeeper); + + m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true); m_RestrictInventoryAccessAbroad = thisModuleConfig.GetBoolean("RestrictInventoryAccessAbroad", true); } else diff --git a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs index 13d9d31..e8bf194 100644 --- a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs +++ b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs @@ -113,7 +113,7 @@ namespace OpenSim.Region.DataSnapshot try { m_enabled = config.Configs["DataSnapshot"].GetBoolean("index_sims", m_enabled); - string gatekeeper = Util.GetConfigVarWithDefaultSection(config, "GatekeeperURI", "GridService"); + string gatekeeper = Util.GetConfigVarFromSections(config, "GatekeeperURI", new string[] {"Startup", "GridService"}); // Legacy. Remove soon! if (string.IsNullOrEmpty(gatekeeper)) { diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 0334169..d356f8c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2138,7 +2138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); IConfigSource config = m_ScriptEngine.ConfigSource; - string HomeURI = Util.GetConfigVarWithDefaultSection(config, "HomeURI", string.Empty); + string HomeURI = Util.GetConfigVarFromSections(config, "HomeURI", new string[]{"Startup"}); if (!string.IsNullOrEmpty(HomeURI)) return HomeURI; @@ -2159,7 +2159,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); IConfigSource config = m_ScriptEngine.ConfigSource; - string gatekeeperURI = Util.GetConfigVarWithDefaultSection(config, "GatekeeperURI", string.Empty); + string gatekeeperURI = Util.GetConfigVarFromSections(config, "GatekeeperURI", new string[] {"Startup"}); if (!string.IsNullOrEmpty(gatekeeperURI)) return gatekeeperURI; -- cgit v1.1 From ee18db027c67d3ea9b905f4d07bd5a2ec8fdf65f Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 23 Feb 2013 21:00:05 +0000 Subject: Make sure state machine is reset if crossing is aborted --- .../CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 6f18e1c..6cfd332 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1132,10 +1132,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer bool isFlying, string version) { if (!CrossAgentToNewRegionPrep(agent, neighbourRegion)) + { + m_entityTransferStateMachine.ResetFromTransit(agent.UUID); return agent; + } if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying)) + { + m_entityTransferStateMachine.ResetFromTransit(agent.UUID); return agent; + } CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version); return agent; -- cgit v1.1 From 8e67ad25b07c6e934e7df86b3baffa2ab85145c1 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 23 Feb 2013 16:49:02 -0800 Subject: Addition of ServerStats shared region module which collects and registers server wide statistics (CPU%, network bytes sent, ...) with StatsManager. --- .../Framework/Monitoring/ServerStats.cs | 438 +++++++++++++++++++++ 1 file changed, 438 insertions(+) create mode 100644 OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs b/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs new file mode 100644 index 0000000..8f60c8d --- /dev/null +++ b/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs @@ -0,0 +1,438 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Net.NetworkInformation; +using System.Text; +using System.Threading; + +using log4net; +using Mono.Addins; +using Nini.Config; + +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Framework.Monitoring; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +using OpenMetaverse.StructuredData; + +namespace OpenSim.Region.OptionalModules.Framework.Monitoring +{ +[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ServerStatistics")] +public class ServerStats : ISharedRegionModule +{ + private readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + private readonly string LogHeader = "[SERVER STATS]"; + + public bool Enabled = false; + private static Dictionary RegisteredStats = new Dictionary(); + + public readonly string CategoryServer = "server"; + + public readonly string ContainerProcessor = "processor"; + public readonly string ContainerMemory = "memory"; + public readonly string ContainerNetwork = "network"; + public readonly string ContainerProcess = "process"; + + + readonly int performanceCounterSampleInterval = 500; + int lastperformanceCounterSampleTime = 0; + + private class PerfCounterControl + { + public PerformanceCounter perfCounter; + public int lastFetch; + public string name; + public PerfCounterControl(PerformanceCounter pPc) + : this(pPc, String.Empty) + { + } + public PerfCounterControl(PerformanceCounter pPc, string pName) + { + perfCounter = pPc; + lastFetch = 0; + name = pName; + } + } + + PerfCounterControl processorPercentPerfCounter = null; + + PerfCounterControl processThreadCountPerfCounter = null; + PerfCounterControl processVirtualBytesPerfCounter = null; + PerfCounterControl processWorkingSetPerfCounter = null; + + PerfCounterControl dotNETCLRMemoryAllocatedBytesPerSecPerfCounter = null; + PerfCounterControl dotNETCLRMemoryGen0HeapSizePerfCounter = null; + PerfCounterControl dotNETCLRMemoryGen1HeapSizePerfCounter = null; + PerfCounterControl dotNETCLRMemoryGen2HeapSizePerfCounter = null; + + PerfCounterControl dotNETCLRLaTTotalContentionsPerfCounter = null; + PerfCounterControl dotNETCLRLaTContentionsPerSecPerfCounter = null; + PerfCounterControl dotNETCLRLaTLogicalThreadsPerfCounter = null; + PerfCounterControl dotNETCLRLaTPhysicalThreadsPerfCounter = null; + + #region ISharedRegionModule + // IRegionModuleBase.Name + public string Name { get { return "Server Stats"; } } + // IRegionModuleBase.ReplaceableInterface + public Type ReplaceableInterface { get { return null; } } + // IRegionModuleBase.Initialize + public void Initialise(IConfigSource source) + { + IConfig cnfg = source.Configs["Statistics"]; + + if (cnfg != null) + Enabled = cnfg.GetBoolean("Enabled", true); + } + // IRegionModuleBase.Close + public void Close() + { + if (RegisteredStats.Count > 0) + { + foreach (Stat stat in RegisteredStats.Values) + { + StatsManager.DeregisterStat(stat); + stat.Dispose(); + } + RegisteredStats.Clear(); + } + } + // IRegionModuleBase.AddRegion + public void AddRegion(Scene scene) + { + } + // IRegionModuleBase.RemoveRegion + public void RemoveRegion(Scene scene) + { + } + // IRegionModuleBase.RegionLoaded + public void RegionLoaded(Scene scene) + { + } + // ISharedRegionModule.PostInitialize + public void PostInitialise() + { + if (RegisteredStats.Count == 0) + { + RegisterServerStats(); + } + } + #endregion ISharedRegionModule + + public void RegisterServerStats() + { + lastperformanceCounterSampleTime = Util.EnvironmentTickCount(); + PerformanceCounter tempPC; + Stat tempStat; + string tempName; + + try + { + tempName = "CPU_Percent"; + tempPC = new PerformanceCounter("Processor", "% Processor Time", "_Total"); + processorPercentPerfCounter = new PerfCounterControl(tempPC); + // A long time bug in mono is that CPU percent is reported as CPU percent idle. Windows reports CPU percent busy. + tempStat = new Stat(tempName, tempName, "", "percent", CategoryServer, ContainerProcessor, + StatType.Pull, (s) => { GetNextValue(s, processorPercentPerfCounter, Util.IsWindows() ? 1 : -1); }, + StatVerbosity.Info); + StatsManager.RegisterStat(tempStat); + RegisteredStats.Add(tempName, tempStat); + + /* Performance counters are not the way to go. Ick. Find another way. + tempName = "Thread_Count"; + tempPC = new PerformanceCounter("Process", "Thread Count", AppDomain.CurrentDomain.FriendlyName); + processThreadCountPerfCounter = new PerfCounterControl(tempPC); + tempStat = new Stat("Thread_Count", "Thread_Count", "", "threads", CategoryServer, ContainerProcess, + StatType.Pull, (s) => { GetNextValue(s, processThreadCountPerfCounter); }, StatVerbosity.Info); + StatsManager.RegisterStat(tempStat); + RegisteredStats.Add(tempName, tempStat); + + tempName = "Virtual_Bytes"; + tempPC = new PerformanceCounter("Process", "Virtual Bytes", AppDomain.CurrentDomain.FriendlyName); + processVirtualBytesPerfCounter = new PerfCounterControl(tempPC); + tempStat = new Stat("Virtual_Bytes", "Virtual_Bytes", "", "MB", CategoryServer, ContainerProcess, + StatType.Pull, (s) => { GetNextValue(s, processVirtualBytesPerfCounter, 1024.0*1024.0); }, StatVerbosity.Info); + StatsManager.RegisterStat(tempStat); + RegisteredStats.Add(tempName, tempStat); + + tempName = "Working_Set"; + tempPC = new PerformanceCounter("Process", "Working Set", AppDomain.CurrentDomain.FriendlyName); + processWorkingSetPerfCounter = new PerfCounterControl(tempPC); + tempStat = new Stat("Working_Set", "Working_Set", "", "MB", CategoryServer, ContainerProcess, + StatType.Pull, (s) => { GetNextValue(s, processWorkingSetPerfCounter, 1024.0*1024.0); }, StatVerbosity.Info); + StatsManager.RegisterStat(tempStat); + RegisteredStats.Add(tempName, tempStat); + */ + } + catch (Exception e) + { + m_log.ErrorFormat("{0} Exception creating 'Process': {1}", LogHeader, e); + } + + try + { + /* The ".NET CLR *" categories aren't working for me. + tempName = ""Bytes_Allocated_Per_Sec"; + tempPC = new PerformanceCounter(".NET CLR Memory", "Allocated Bytes/sec", AppDomain.CurrentDomain.FriendlyName); + dotNETCLRMemoryAllocatedBytesPerSecPerfCounter = new PerfCounterControl(tempPC, tempStat); + tempStat = new Stat(tempName, tempName, "", "bytes/sec", ServerCategory, MemoryContainer, + StatType.Pull, (s) => { GetNextValue(s, dotNETCLRMemoryAllocatedBytesPerSecPerfCounter); }, StatVerbosity.Info); + StatsManager.RegisterStat(tempStat); + RegisteredStats.Add(tempName, tempStat); + + tempName = "Gen_0_Heap_Size"; + tempPC = new PerformanceCounter(".NET CLR Memory", "Gen 0 heap size", AppDomain.CurrentDomain.FriendlyName); + dotNETCLRMemoryGen0HeapSizePerfCounter = new PerfCounterControl(tempPC, tempStat); + tempStat = new Stat("Gen_0_Heap_Size", "Gen_0_Heap_Size", "", "bytes", ServerCategory, MemoryContainer, + StatType.Pull, (s) => { GetNextValue(s, dotNETCLRMemoryGen0HeapSizePerfCounter); }, StatVerbosity.Info); + StatsManager.RegisterStat(tempStat); + RegisteredStats.Add(tempName, tempStat); + + tempName = "Gen_1_Heap_Size"; + tempPC = new PerformanceCounter(".NET CLR Memory", "Gen 1 heap size", AppDomain.CurrentDomain.FriendlyName); + dotNETCLRMemoryGen1HeapSizePerfCounter = new PerfCounterControl(tempPC, tempStat); + tempStat = new Stat("Gen_1_Heap_Size", "Gen_1_Heap_Size", "", "bytes", ServerCategory, MemoryContainer, + StatType.Pull, (s) => { GetNextValue(s, dotNETCLRMemoryGen1HeapSizePerfCounter); }, StatVerbosity.Info); + StatsManager.RegisterStat(tempStat); + RegisteredStats.Add(tempName, tempStat); + + tempName = "Gen_2_Heap_Size"; + tempPC = new PerformanceCounter(".NET CLR Memory", "Gen 2 heap size", AppDomain.CurrentDomain.FriendlyName); + dotNETCLRMemoryGen2HeapSizePerfCounter = new PerfCounterControl(tempPC, tempStat); + tempStat = new Stat("Gen_2_Heap_Size", "Gen_2_Heap_Size", "", "bytes", ServerCategory, MemoryContainer, + StatType.Pull, (s) => { GetNextValue(s, dotNETCLRMemoryGen2HeapSizePerfCounter); }, StatVerbosity.Info); + StatsManager.RegisterStat(tempStat); + RegisteredStats.Add(tempName, tempStat); + + tempName = "Total_Lock_Contentions"; + tempPC = new PerformanceCounter(".NET CLR LocksAndThreads", "Total # of Contentions"); + dotNETCLRLaTTotalContentionsPerfCounter = new PerfCounterControl(tempPC, tempStat); + tempStat = new Stat("Total_Lock_Contentions", "Total_Lock_Contentions", "", "contentions", ServerCategory, ProcessContainer, + StatType.Pull, (s) => { GetNextValue(s, dotNETCLRLaTTotalContentionsPerfCounter); }, StatVerbosity.Info); + StatsManager.RegisterStat(tempStat); + RegisteredStats.Add(tempName, tempStat); + + tempName = "Lock_Contentions"; + tempPC = new PerformanceCounter(".NET CLR LocksAndThreads", "Contention Rate / sec"); + dotNETCLRLaTContentionsPerSecPerfCounter = new PerfCounterControl(tempPC, tempStat); + tempStat = new Stat("Lock_Contentions", "Lock_Contentions", "", "contentions/sec", ServerCategory, ProcessContainer, + StatType.Pull, (s) => { GetNextValue(s, dotNETCLRLaTContentionsPerSecPerfCounter); }, StatVerbosity.Info); + StatsManager.RegisterStat(tempStat); + RegisteredStats.Add(tempName, tempStat); + + tempName = "Logical_Threads"; + tempPC = new PerformanceCounter(".NET CLR LocksAndThreads", "# of current logical Threads"); + dotNETCLRLaTLogicalThreadsPerfCounter = new PerfCounterControl(tempPC, tempStat); + tempStat = new Stat("Logicial_Threads", "Logicial_Threads", "", "threads", ServerCategory, ProcessContainer, + StatType.Pull, (s) => { GetNextValue(s, dotNETCLRLaTLogicalThreadsPerfCounter); }, StatVerbosity.Info); + StatsManager.RegisterStat(tempStat); + RegisteredStats.Add(tempName, tempStat); + + tempName = "Physical_Threads"; + tempPC = new PerformanceCounter(".NET CLR LocksAndThreads", "# of current physical Threads"); + dotNETCLRLaTPhysicalThreadsPerfCounter = new PerfCounterControl(tempPC, tempStat); + tempStat = new Stat("Physical_Threads", "Physical_Threads", "", "threads", ServerCategory, ProcessContainer, + StatType.Pull, (s) => { GetNextValue(s, dotNETCLRLaTPhysicalThreadsPerfCounter); }, StatVerbosity.Info); + StatsManager.RegisterStat(tempStat); + RegisteredStats.Add(tempName, tempStat); + */ + } + catch (Exception e) + { + m_log.ErrorFormat("{0} Exception creating '.NET CLR Memory': {1}", LogHeader, e); + } + + try + { + IEnumerable nics = NetworkInterface.GetAllNetworkInterfaces(); + // IEnumerable nics = NetworkInterface.GetAllNetworkInterfaces().Where( + // (network) => network.NetworkInterfaceType == NetworkInterfaceType.Ethernet); + // IEnumerable nics = NetworkInterface.GetAllNetworkInterfaces().Where( + // (network) => network.OperationalStatus == OperationalStatus.Up); + + foreach (NetworkInterface nic in nics) + { + if (nic.OperationalStatus != OperationalStatus.Up || nic.NetworkInterfaceType != NetworkInterfaceType.Ethernet) + continue; + + if (nic.Supports(NetworkInterfaceComponent.IPv4)) + { + IPv4InterfaceStatistics nicStats = nic.GetIPv4Statistics(); + if (nicStats != null) + { + tempName = "Bytes_Rcvd/" + nic.Name; + tempStat = new Stat(tempName, tempName, nic.Name, "KB", CategoryServer, ContainerNetwork, + StatType.Pull, (s) => { LookupNic(s, (ns) => { return ns.BytesReceived; }, 1024.0); }, StatVerbosity.Info); + StatsManager.RegisterStat(tempStat); + RegisteredStats.Add(tempName, tempStat); + + tempName = "Bytes_Sent/" + nic.Name; + tempStat = new Stat(tempName, tempName, nic.Name, "KB", CategoryServer, ContainerNetwork, + StatType.Pull, (s) => { LookupNic(s, (ns) => { return ns.BytesSent; }, 1024.0); }, StatVerbosity.Info); + StatsManager.RegisterStat(tempStat); + RegisteredStats.Add(tempName, tempStat); + + tempName = "Total_Bytes/" + nic.Name; + tempStat = new Stat(tempName, tempName, nic.Name, "KB", CategoryServer, ContainerNetwork, + StatType.Pull, (s) => { LookupNic(s, (ns) => { return ns.BytesSent + ns.BytesReceived; }, 1024.0); }, StatVerbosity.Info); + StatsManager.RegisterStat(tempStat); + RegisteredStats.Add(tempName, tempStat); + } + } + } + } + catch (Exception e) + { + m_log.ErrorFormat("{0} Exception creating 'Network Interface': {1}", LogHeader, e); + } + + tempName = "Process_Memory"; + tempStat = new Stat(tempName, tempName, "", "MB", CategoryServer, ContainerMemory, + StatType.Pull, (s) => { s.Value = Process.GetCurrentProcess().WorkingSet64 / 1024d / 1024d; }, StatVerbosity.Info); + StatsManager.RegisterStat(tempStat); + RegisteredStats.Add(tempName, tempStat); + + tempName = "Object_Memory"; + tempStat = new Stat(tempName, tempName, "", "MB", CategoryServer, ContainerMemory, + StatType.Pull, (s) => { s.Value = GC.GetTotalMemory(false) / 1024d / 1024d; }, StatVerbosity.Info); + StatsManager.RegisterStat(tempStat); + RegisteredStats.Add(tempName, tempStat); + + tempName = "Last_Memory_Churn"; + tempStat = new Stat(tempName, tempName, "", "MB/sec", CategoryServer, ContainerMemory, + StatType.Pull, (s) => { s.Value = Math.Round(MemoryWatchdog.LastMemoryChurn * 1000d / 1024d / 1024d, 3); }, StatVerbosity.Info); + StatsManager.RegisterStat(tempStat); + RegisteredStats.Add(tempName, tempStat); + + tempName = "Average_Memory_Churn"; + tempStat = new Stat(tempName, tempName, "", "MB/sec", CategoryServer, ContainerMemory, + StatType.Pull, (s) => { s.Value = Math.Round(MemoryWatchdog.AverageMemoryChurn * 1000d / 1024d / 1024d, 3); }, StatVerbosity.Info); + StatsManager.RegisterStat(tempStat); + RegisteredStats.Add(tempName, tempStat); + + } + + // Notes on performance counters: + // "How To Read Performance Counters": http://blogs.msdn.com/b/bclteam/archive/2006/06/02/618156.aspx + // "How to get the CPU Usage in C#": http://stackoverflow.com/questions/278071/how-to-get-the-cpu-usage-in-c + // "Mono Performance Counters": http://www.mono-project.com/Mono_Performance_Counters + private delegate double PerfCounterNextValue(); + private void GetNextValue(Stat stat, PerfCounterControl perfControl) + { + GetNextValue(stat, perfControl, 1.0); + } + private void GetNextValue(Stat stat, PerfCounterControl perfControl, double factor) + { + if (Util.EnvironmentTickCountSubtract(perfControl.lastFetch) > performanceCounterSampleInterval) + { + if (perfControl != null && perfControl.perfCounter != null) + { + try + { + // Kludge for factor to run double duty. If -1, subtract the value from one + if (factor == -1) + stat.Value = 1 - perfControl.perfCounter.NextValue(); + else + stat.Value = perfControl.perfCounter.NextValue() / factor; + } + catch (Exception e) + { + m_log.ErrorFormat("{0} Exception on NextValue fetching {1}: {2}", LogHeader, stat.Name, e); + } + perfControl.lastFetch = Util.EnvironmentTickCount(); + } + } + } + + private delegate double GetIPv4StatValue(IPv4InterfaceStatistics interfaceStat); + private void LookupNic(Stat stat, GetIPv4StatValue getter, double factor) + { + // Get the one nic that has the name of this stat + IEnumerable nics = NetworkInterface.GetAllNetworkInterfaces().Where( + (network) => network.Name == stat.Description); + try + { + foreach (NetworkInterface nic in nics) + { + IPv4InterfaceStatistics intrStats = nic.GetIPv4Statistics(); + if (intrStats != null) + stat.Value = Math.Round(getter(intrStats) / factor, 3); + break; + } + } + catch + { + // There are times interfaces go away so we just won't update the stat for this + m_log.ErrorFormat("{0} Exception fetching stat on interface '{1}'", LogHeader, stat.Description); + } + } +} + +public class ServerStatsAggregator : Stat +{ + public ServerStatsAggregator( + string shortName, + string name, + string description, + string unitName, + string category, + string container + ) + : base( + shortName, + name, + description, + unitName, + category, + container, + StatType.Push, + MeasuresOfInterest.None, + null, + StatVerbosity.Info) + { + } + public override string ToConsoleString() + { + StringBuilder sb = new StringBuilder(); + + return sb.ToString(); + } + + public override OSDMap ToOSDMap() + { + OSDMap ret = new OSDMap(); + + return ret; + } +} + +} -- cgit v1.1 From b2495c9a1e79fe8d3ec23f87d6c8177302e77b01 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 24 Feb 2013 07:43:01 -0800 Subject: Streamline stat registration code in ServerStats. Remove most of the usage of ProcessCounters which tend to fail oddly and are not supported everywhere. --- .../Framework/Monitoring/ServerStats.cs | 210 +++++---------------- 1 file changed, 50 insertions(+), 160 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs b/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs index 8f60c8d..a3d2436 100644 --- a/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs +++ b/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs @@ -63,6 +63,7 @@ public class ServerStats : ISharedRegionModule public readonly string ContainerNetwork = "network"; public readonly string ContainerProcess = "process"; + public string NetworkInterfaceTypes = "Ethernet"; readonly int performanceCounterSampleInterval = 500; int lastperformanceCounterSampleTime = 0; @@ -86,20 +87,6 @@ public class ServerStats : ISharedRegionModule PerfCounterControl processorPercentPerfCounter = null; - PerfCounterControl processThreadCountPerfCounter = null; - PerfCounterControl processVirtualBytesPerfCounter = null; - PerfCounterControl processWorkingSetPerfCounter = null; - - PerfCounterControl dotNETCLRMemoryAllocatedBytesPerSecPerfCounter = null; - PerfCounterControl dotNETCLRMemoryGen0HeapSizePerfCounter = null; - PerfCounterControl dotNETCLRMemoryGen1HeapSizePerfCounter = null; - PerfCounterControl dotNETCLRMemoryGen2HeapSizePerfCounter = null; - - PerfCounterControl dotNETCLRLaTTotalContentionsPerfCounter = null; - PerfCounterControl dotNETCLRLaTContentionsPerSecPerfCounter = null; - PerfCounterControl dotNETCLRLaTLogicalThreadsPerfCounter = null; - PerfCounterControl dotNETCLRLaTPhysicalThreadsPerfCounter = null; - #region ISharedRegionModule // IRegionModuleBase.Name public string Name { get { return "Server Stats"; } } @@ -108,10 +95,15 @@ public class ServerStats : ISharedRegionModule // IRegionModuleBase.Initialize public void Initialise(IConfigSource source) { - IConfig cnfg = source.Configs["Statistics"]; + IConfig cfg = source.Configs["Monitoring"]; + + if (cfg != null) + Enabled = cfg.GetBoolean("ServerStatsEnabled", true); - if (cnfg != null) - Enabled = cnfg.GetBoolean("Enabled", true); + if (Enabled) + { + NetworkInterfaceTypes = cfg.GetString("NetworkInterfaceTypes", "Ethernet"); + } } // IRegionModuleBase.Close public void Close() @@ -148,6 +140,13 @@ public class ServerStats : ISharedRegionModule } #endregion ISharedRegionModule + private void MakeStat(string pName, string pUnit, string pContainer, Action act) + { + Stat stat = new Stat(pName, pName, "", pUnit, CategoryServer, pContainer, StatType.Pull, act, StatVerbosity.Info); + StatsManager.RegisterStat(stat); + RegisteredStats.Add(pName, stat); + } + public void RegisterServerStats() { lastperformanceCounterSampleTime = Util.EnvironmentTickCount(); @@ -157,7 +156,7 @@ public class ServerStats : ISharedRegionModule try { - tempName = "CPU_Percent"; + tempName = "CPUPercent"; tempPC = new PerformanceCounter("Processor", "% Processor Time", "_Total"); processorPercentPerfCounter = new PerfCounterControl(tempPC); // A long time bug in mono is that CPU percent is reported as CPU percent idle. Windows reports CPU percent busy. @@ -167,31 +166,17 @@ public class ServerStats : ISharedRegionModule StatsManager.RegisterStat(tempStat); RegisteredStats.Add(tempName, tempStat); - /* Performance counters are not the way to go. Ick. Find another way. - tempName = "Thread_Count"; - tempPC = new PerformanceCounter("Process", "Thread Count", AppDomain.CurrentDomain.FriendlyName); - processThreadCountPerfCounter = new PerfCounterControl(tempPC); - tempStat = new Stat("Thread_Count", "Thread_Count", "", "threads", CategoryServer, ContainerProcess, - StatType.Pull, (s) => { GetNextValue(s, processThreadCountPerfCounter); }, StatVerbosity.Info); - StatsManager.RegisterStat(tempStat); - RegisteredStats.Add(tempName, tempStat); + MakeStat("TotalProcessorTime", "sec", ContainerProcessor, + (s) => { s.Value = Process.GetCurrentProcess().TotalProcessorTime.TotalSeconds; }); - tempName = "Virtual_Bytes"; - tempPC = new PerformanceCounter("Process", "Virtual Bytes", AppDomain.CurrentDomain.FriendlyName); - processVirtualBytesPerfCounter = new PerfCounterControl(tempPC); - tempStat = new Stat("Virtual_Bytes", "Virtual_Bytes", "", "MB", CategoryServer, ContainerProcess, - StatType.Pull, (s) => { GetNextValue(s, processVirtualBytesPerfCounter, 1024.0*1024.0); }, StatVerbosity.Info); - StatsManager.RegisterStat(tempStat); - RegisteredStats.Add(tempName, tempStat); + MakeStat("UserProcessorTime", "sec", ContainerProcessor, + (s) => { s.Value = Process.GetCurrentProcess().UserProcessorTime.TotalSeconds; }); - tempName = "Working_Set"; - tempPC = new PerformanceCounter("Process", "Working Set", AppDomain.CurrentDomain.FriendlyName); - processWorkingSetPerfCounter = new PerfCounterControl(tempPC); - tempStat = new Stat("Working_Set", "Working_Set", "", "MB", CategoryServer, ContainerProcess, - StatType.Pull, (s) => { GetNextValue(s, processWorkingSetPerfCounter, 1024.0*1024.0); }, StatVerbosity.Info); - StatsManager.RegisterStat(tempStat); - RegisteredStats.Add(tempName, tempStat); - */ + MakeStat("PrivilegedProcessorTime", "sec", ContainerProcessor, + (s) => { s.Value = Process.GetCurrentProcess().PrivilegedProcessorTime.TotalSeconds; }); + + MakeStat("Threads", "threads", ContainerProcessor, + (s) => { s.Value = Process.GetCurrentProcess().Threads.Count; }); } catch (Exception e) { @@ -200,112 +185,33 @@ public class ServerStats : ISharedRegionModule try { - /* The ".NET CLR *" categories aren't working for me. - tempName = ""Bytes_Allocated_Per_Sec"; - tempPC = new PerformanceCounter(".NET CLR Memory", "Allocated Bytes/sec", AppDomain.CurrentDomain.FriendlyName); - dotNETCLRMemoryAllocatedBytesPerSecPerfCounter = new PerfCounterControl(tempPC, tempStat); - tempStat = new Stat(tempName, tempName, "", "bytes/sec", ServerCategory, MemoryContainer, - StatType.Pull, (s) => { GetNextValue(s, dotNETCLRMemoryAllocatedBytesPerSecPerfCounter); }, StatVerbosity.Info); - StatsManager.RegisterStat(tempStat); - RegisteredStats.Add(tempName, tempStat); - - tempName = "Gen_0_Heap_Size"; - tempPC = new PerformanceCounter(".NET CLR Memory", "Gen 0 heap size", AppDomain.CurrentDomain.FriendlyName); - dotNETCLRMemoryGen0HeapSizePerfCounter = new PerfCounterControl(tempPC, tempStat); - tempStat = new Stat("Gen_0_Heap_Size", "Gen_0_Heap_Size", "", "bytes", ServerCategory, MemoryContainer, - StatType.Pull, (s) => { GetNextValue(s, dotNETCLRMemoryGen0HeapSizePerfCounter); }, StatVerbosity.Info); - StatsManager.RegisterStat(tempStat); - RegisteredStats.Add(tempName, tempStat); - - tempName = "Gen_1_Heap_Size"; - tempPC = new PerformanceCounter(".NET CLR Memory", "Gen 1 heap size", AppDomain.CurrentDomain.FriendlyName); - dotNETCLRMemoryGen1HeapSizePerfCounter = new PerfCounterControl(tempPC, tempStat); - tempStat = new Stat("Gen_1_Heap_Size", "Gen_1_Heap_Size", "", "bytes", ServerCategory, MemoryContainer, - StatType.Pull, (s) => { GetNextValue(s, dotNETCLRMemoryGen1HeapSizePerfCounter); }, StatVerbosity.Info); - StatsManager.RegisterStat(tempStat); - RegisteredStats.Add(tempName, tempStat); - - tempName = "Gen_2_Heap_Size"; - tempPC = new PerformanceCounter(".NET CLR Memory", "Gen 2 heap size", AppDomain.CurrentDomain.FriendlyName); - dotNETCLRMemoryGen2HeapSizePerfCounter = new PerfCounterControl(tempPC, tempStat); - tempStat = new Stat("Gen_2_Heap_Size", "Gen_2_Heap_Size", "", "bytes", ServerCategory, MemoryContainer, - StatType.Pull, (s) => { GetNextValue(s, dotNETCLRMemoryGen2HeapSizePerfCounter); }, StatVerbosity.Info); - StatsManager.RegisterStat(tempStat); - RegisteredStats.Add(tempName, tempStat); - - tempName = "Total_Lock_Contentions"; - tempPC = new PerformanceCounter(".NET CLR LocksAndThreads", "Total # of Contentions"); - dotNETCLRLaTTotalContentionsPerfCounter = new PerfCounterControl(tempPC, tempStat); - tempStat = new Stat("Total_Lock_Contentions", "Total_Lock_Contentions", "", "contentions", ServerCategory, ProcessContainer, - StatType.Pull, (s) => { GetNextValue(s, dotNETCLRLaTTotalContentionsPerfCounter); }, StatVerbosity.Info); - StatsManager.RegisterStat(tempStat); - RegisteredStats.Add(tempName, tempStat); - - tempName = "Lock_Contentions"; - tempPC = new PerformanceCounter(".NET CLR LocksAndThreads", "Contention Rate / sec"); - dotNETCLRLaTContentionsPerSecPerfCounter = new PerfCounterControl(tempPC, tempStat); - tempStat = new Stat("Lock_Contentions", "Lock_Contentions", "", "contentions/sec", ServerCategory, ProcessContainer, - StatType.Pull, (s) => { GetNextValue(s, dotNETCLRLaTContentionsPerSecPerfCounter); }, StatVerbosity.Info); - StatsManager.RegisterStat(tempStat); - RegisteredStats.Add(tempName, tempStat); - - tempName = "Logical_Threads"; - tempPC = new PerformanceCounter(".NET CLR LocksAndThreads", "# of current logical Threads"); - dotNETCLRLaTLogicalThreadsPerfCounter = new PerfCounterControl(tempPC, tempStat); - tempStat = new Stat("Logicial_Threads", "Logicial_Threads", "", "threads", ServerCategory, ProcessContainer, - StatType.Pull, (s) => { GetNextValue(s, dotNETCLRLaTLogicalThreadsPerfCounter); }, StatVerbosity.Info); - StatsManager.RegisterStat(tempStat); - RegisteredStats.Add(tempName, tempStat); - - tempName = "Physical_Threads"; - tempPC = new PerformanceCounter(".NET CLR LocksAndThreads", "# of current physical Threads"); - dotNETCLRLaTPhysicalThreadsPerfCounter = new PerfCounterControl(tempPC, tempStat); - tempStat = new Stat("Physical_Threads", "Physical_Threads", "", "threads", ServerCategory, ProcessContainer, - StatType.Pull, (s) => { GetNextValue(s, dotNETCLRLaTPhysicalThreadsPerfCounter); }, StatVerbosity.Info); - StatsManager.RegisterStat(tempStat); - RegisteredStats.Add(tempName, tempStat); - */ - } - catch (Exception e) - { - m_log.ErrorFormat("{0} Exception creating '.NET CLR Memory': {1}", LogHeader, e); - } + List okInterfaceTypes = new List(NetworkInterfaceTypes.Split(',')); - try - { IEnumerable nics = NetworkInterface.GetAllNetworkInterfaces(); - // IEnumerable nics = NetworkInterface.GetAllNetworkInterfaces().Where( - // (network) => network.NetworkInterfaceType == NetworkInterfaceType.Ethernet); - // IEnumerable nics = NetworkInterface.GetAllNetworkInterfaces().Where( - // (network) => network.OperationalStatus == OperationalStatus.Up); - foreach (NetworkInterface nic in nics) { - if (nic.OperationalStatus != OperationalStatus.Up || nic.NetworkInterfaceType != NetworkInterfaceType.Ethernet) + if (nic.OperationalStatus != OperationalStatus.Up) + continue; + + string nicInterfaceType = nic.NetworkInterfaceType.ToString(); + if (!okInterfaceTypes.Contains(nicInterfaceType)) + { + m_log.DebugFormat("{0} Not including stats for network interface '{1}' of type '{2}'. To include, add to [Monitoring]NetworkInterfaceTypes='Ethernet,Loopback'", + LogHeader, nic.Name, nicInterfaceType); continue; + } if (nic.Supports(NetworkInterfaceComponent.IPv4)) { IPv4InterfaceStatistics nicStats = nic.GetIPv4Statistics(); if (nicStats != null) { - tempName = "Bytes_Rcvd/" + nic.Name; - tempStat = new Stat(tempName, tempName, nic.Name, "KB", CategoryServer, ContainerNetwork, - StatType.Pull, (s) => { LookupNic(s, (ns) => { return ns.BytesReceived; }, 1024.0); }, StatVerbosity.Info); - StatsManager.RegisterStat(tempStat); - RegisteredStats.Add(tempName, tempStat); - - tempName = "Bytes_Sent/" + nic.Name; - tempStat = new Stat(tempName, tempName, nic.Name, "KB", CategoryServer, ContainerNetwork, - StatType.Pull, (s) => { LookupNic(s, (ns) => { return ns.BytesSent; }, 1024.0); }, StatVerbosity.Info); - StatsManager.RegisterStat(tempStat); - RegisteredStats.Add(tempName, tempStat); - - tempName = "Total_Bytes/" + nic.Name; - tempStat = new Stat(tempName, tempName, nic.Name, "KB", CategoryServer, ContainerNetwork, - StatType.Pull, (s) => { LookupNic(s, (ns) => { return ns.BytesSent + ns.BytesReceived; }, 1024.0); }, StatVerbosity.Info); - StatsManager.RegisterStat(tempStat); - RegisteredStats.Add(tempName, tempStat); + MakeStat("BytesRcvd/" + nic.Name, "KB", ContainerNetwork, + (s) => { LookupNic(s, (ns) => { return ns.BytesReceived; }, 1024.0); }); + MakeStat("BytesSent/" + nic.Name, "KB", ContainerNetwork, + (s) => { LookupNic(s, (ns) => { return ns.BytesSent; }, 1024.0); }); + MakeStat("TotalBytes/" + nic.Name, "KB", ContainerNetwork, + (s) => { LookupNic(s, (ns) => { return ns.BytesSent + ns.BytesReceived; }, 1024.0); }); } } } @@ -315,30 +221,14 @@ public class ServerStats : ISharedRegionModule m_log.ErrorFormat("{0} Exception creating 'Network Interface': {1}", LogHeader, e); } - tempName = "Process_Memory"; - tempStat = new Stat(tempName, tempName, "", "MB", CategoryServer, ContainerMemory, - StatType.Pull, (s) => { s.Value = Process.GetCurrentProcess().WorkingSet64 / 1024d / 1024d; }, StatVerbosity.Info); - StatsManager.RegisterStat(tempStat); - RegisteredStats.Add(tempName, tempStat); - - tempName = "Object_Memory"; - tempStat = new Stat(tempName, tempName, "", "MB", CategoryServer, ContainerMemory, - StatType.Pull, (s) => { s.Value = GC.GetTotalMemory(false) / 1024d / 1024d; }, StatVerbosity.Info); - StatsManager.RegisterStat(tempStat); - RegisteredStats.Add(tempName, tempStat); - - tempName = "Last_Memory_Churn"; - tempStat = new Stat(tempName, tempName, "", "MB/sec", CategoryServer, ContainerMemory, - StatType.Pull, (s) => { s.Value = Math.Round(MemoryWatchdog.LastMemoryChurn * 1000d / 1024d / 1024d, 3); }, StatVerbosity.Info); - StatsManager.RegisterStat(tempStat); - RegisteredStats.Add(tempName, tempStat); - - tempName = "Average_Memory_Churn"; - tempStat = new Stat(tempName, tempName, "", "MB/sec", CategoryServer, ContainerMemory, - StatType.Pull, (s) => { s.Value = Math.Round(MemoryWatchdog.AverageMemoryChurn * 1000d / 1024d / 1024d, 3); }, StatVerbosity.Info); - StatsManager.RegisterStat(tempStat); - RegisteredStats.Add(tempName, tempStat); - + MakeStat("ProcessMemory", "MB", ContainerMemory, + (s) => { s.Value = Process.GetCurrentProcess().WorkingSet64 / 1024d / 1024d; }); + MakeStat("ObjectMemory", "MB", ContainerMemory, + (s) => { s.Value = GC.GetTotalMemory(false) / 1024d / 1024d; }); + MakeStat("LastMemoryChurn", "MB/sec", ContainerMemory, + (s) => { s.Value = Math.Round(MemoryWatchdog.LastMemoryChurn * 1000d / 1024d / 1024d, 3); }); + MakeStat("AverageMemoryChurn", "MB/sec", ContainerMemory, + (s) => { s.Value = Math.Round(MemoryWatchdog.AverageMemoryChurn * 1000d / 1024d / 1024d, 3); }); } // Notes on performance counters: -- cgit v1.1 From aa538fe36f92a7c047c9db8c98514de83cb5c3e7 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 24 Feb 2013 07:45:37 -0800 Subject: Add StatsManager registration for region specific stats as collected by MonitorModule. Left existing functionality (command line and HTTP fetch) and just added StatsManager registration. --- .../Framework/Monitoring/MonitorModule.cs | 48 +++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs index d84460a..4c9ee06 100644 --- a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs @@ -33,6 +33,7 @@ using log4net; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; +using OpenSim.Framework.Monitoring; using OpenSim.Framework.Servers; using OpenSim.Region.CoreModules.Framework.Monitoring.Alerts; using OpenSim.Region.CoreModules.Framework.Monitoring.Monitors; @@ -100,6 +101,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring "/monitorstats/" + Uri.EscapeDataString(m_scene.RegionInfo.RegionName), StatsPage); AddMonitors(); + RegisterStatsManagerRegionStatistics(); } public void RemoveRegion(Scene scene) @@ -109,6 +111,9 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring MainServer.Instance.RemoveHTTPHandler("GET", "/monitorstats/" + m_scene.RegionInfo.RegionID); MainServer.Instance.RemoveHTTPHandler("GET", "/monitorstats/" + Uri.EscapeDataString(m_scene.RegionInfo.RegionName)); + + UnRegisterStatsManagerRegionStatistics(); + m_scene = null; } @@ -399,6 +404,47 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring { m_log.Error("[Monitor] " + reporter.Name + " for " + m_scene.RegionInfo.RegionName + " reports " + reason + " (Fatal: " + fatal + ")"); } + + private List registeredStats = new List(); + private void MakeStat(string pName, string pUnitName, Action act) + { + Stat tempStat = new Stat(pName, pName, pName, pUnitName, "scene", m_scene.RegionInfo.RegionName, StatType.Pull, act, StatVerbosity.Info); + StatsManager.RegisterStat(tempStat); + registeredStats.Add(tempStat); + } + private void RegisterStatsManagerRegionStatistics() + { + string regionName = m_scene.RegionInfo.RegionName; + + MakeStat("RootAgents", "avatars", (s) => { s.Value = m_scene.SceneGraph.GetRootAgentCount(); }); + MakeStat("ChildAgents", "avatars", (s) => { s.Value = m_scene.SceneGraph.GetChildAgentCount(); }); + MakeStat("TotalPrims", "objects", (s) => { s.Value = m_scene.SceneGraph.GetTotalObjectsCount(); }); + MakeStat("ActivePrims", "objects", (s) => { s.Value = m_scene.SceneGraph.GetActiveObjectsCount(); }); + MakeStat("ActiveScripts", "scripts", (s) => { s.Value = m_scene.SceneGraph.GetActiveScriptsCount(); }); + + MakeStat("TimeDilation", "sec/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[0]; }); + MakeStat("SimFPS", "fps", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[1]; }); + MakeStat("PhysicsFPS", "fps", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[2]; }); + MakeStat("AgentUpdates", "updates/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[3]; }); + MakeStat("FrameTime", "ms/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[8]; }); + MakeStat("NetTime", "ms/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[9]; }); + MakeStat("OtherTime", "ms/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[12]; }); + MakeStat("PhysicsTime", "ms/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[10]; }); + MakeStat("AgentTime", "ms/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[16]; }); + MakeStat("ImageTime", "ms/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[11]; }); + MakeStat("ScriptLines", "lines/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[20]; }); + MakeStat("SimSpareMS", "ms/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[21]; }); + } + + private void UnRegisterStatsManagerRegionStatistics() + { + foreach (Stat stat in registeredStats) + { + StatsManager.DeregisterStat(stat); + stat.Dispose(); + } + registeredStats.Clear(); + } } -} +} \ No newline at end of file -- cgit v1.1 From d0cb4fc3262df2afe2ef34396c7960f7afee6b89 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 25 Feb 2013 23:04:38 +0000 Subject: Move map related settings from [Startup] to a new [Map] section in OpenSim.ini Existing map settings in [Startup] will continue to work, and if present will override anything in [Map] However, the proper place for such settings would now be [Map] This is to reduce the use of [Startup] as a bag for non-generic settings which should really go in sections, in common with other settings. This commit also extends Diva's previous work to allow a default setting to be given when looking at multiple sections for settings. --- .../CoreModules/Hypergrid/HGWorldMapModule.cs | 4 ++-- .../CoreModules/World/LegacyMap/MapImageModule.cs | 24 +++++++++------------- .../World/Warp3DMap/Warp3DImageModule.cs | 20 ++++++++---------- .../CoreModules/World/WorldMap/WorldMapModule.cs | 9 +++++--- OpenSim/Region/Framework/Scenes/Scene.cs | 11 ++++++++-- 5 files changed, 35 insertions(+), 33 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs index e0921ad..c4255b9 100644 --- a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs +++ b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs @@ -52,8 +52,8 @@ namespace OpenSim.Region.CoreModules.Hypergrid public override void Initialise(IConfigSource config) { - IConfig startupConfig = config.Configs["Startup"]; - if (startupConfig.GetString("WorldMapModule", "WorldMap") == "HGWorldMap") + if (Util.GetConfigVarFromSections( + config, "WorldMapModule", new string[] { "Map", "Startup" }, "WorldMap") == "HGWorldMap") m_Enabled = true; } diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs index e7065dc..40638f8 100644 --- a/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs +++ b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs @@ -80,17 +80,14 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap bool generateMaptiles = true; Bitmap mapbmp; - try - { - IConfig startupConfig = m_config.Configs["Startup"]; - drawPrimVolume = startupConfig.GetBoolean("DrawPrimOnMapTile", drawPrimVolume); - textureTerrain = startupConfig.GetBoolean("TextureOnMapTile", textureTerrain); - generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", generateMaptiles); - } - catch - { - m_log.Warn("[MAPTILE]: Failed to load StartupConfig"); - } + string[] configSections = new string[] { "Map", "Startup" }; + + drawPrimVolume + = Util.GetConfigVarFromSections(m_config, "DrawPrimOnMapTile", configSections, drawPrimVolume); + textureTerrain + = Util.GetConfigVarFromSections(m_config, "TextureOnMapTile", configSections, textureTerrain); + generateMaptiles + = Util.GetConfigVarFromSections(m_config, "GenerateMaptiles", configSections, generateMaptiles); if (generateMaptiles) { @@ -148,9 +145,8 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap { m_config = source; - IConfig startupConfig = m_config.Configs["Startup"]; - if (startupConfig.GetString("MapImageModule", "MapImageModule") != - "MapImageModule") + if (Util.GetConfigVarFromSections( + m_config, "MapImageModule", new string[] { "Startup", "Map" }, "MapImageModule") != "MapImageModule") return; m_Enabled = true; diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs index 5e0dfa7..ed2b06a 100644 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs +++ b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs @@ -71,8 +71,8 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap { m_config = source; - IConfig startupConfig = m_config.Configs["Startup"]; - if (startupConfig.GetString("MapImageModule", "MapImageModule") != "Warp3DImageModule") + if (Util.GetConfigVarFromSections( + m_config, "MapImageModule", new string[] { "Startup", "Map" }, "MapImageModule") != "Warp3DImageModule") return; m_Enabled = true; @@ -143,16 +143,12 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap bool drawPrimVolume = true; bool textureTerrain = true; - try - { - IConfig startupConfig = m_config.Configs["Startup"]; - drawPrimVolume = startupConfig.GetBoolean("DrawPrimOnMapTile", drawPrimVolume); - textureTerrain = startupConfig.GetBoolean("TextureOnMapTile", textureTerrain); - } - catch - { - m_log.Warn("[WARP 3D IMAGE MODULE]: Failed to load StartupConfig"); - } + string[] configSections = new string[] { "Map", "Startup" }; + + drawPrimVolume + = Util.GetConfigVarFromSections(m_config, "DrawPrimOnMapTile", configSections, drawPrimVolume); + textureTerrain + = Util.GetConfigVarFromSections(m_config, "TextureOnMapTile", configSections, textureTerrain); m_colors.Clear(); diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index e2f525c..912d50a 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -86,11 +86,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap #region INonSharedRegionModule Members public virtual void Initialise (IConfigSource config) { - IConfig startupConfig = config.Configs["Startup"]; - if (startupConfig.GetString("WorldMapModule", "WorldMap") == "WorldMap") + string[] configSections = new string[] { "Map", "Startup" }; + + if (Util.GetConfigVarFromSections( + config, "WorldMapModule", configSections, "WorldMap") == "WorldMap") m_Enabled = true; - blacklistTimeout = startupConfig.GetInt("BlacklistTimeout", 10*60) * 1000; + blacklistTimeout + = Util.GetConfigVarFromSections(config, "BlacklistTimeout", configSections, 10 * 60) * 1000; } public virtual void AddRegion (Scene scene) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 9b17b7f..5b61538 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -897,7 +897,11 @@ namespace OpenSim.Region.Framework.Scenes m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); - m_generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", true); + string[] possibleMapConfigSections = new string[] { "Map", "Startup" }; + + m_generateMaptiles + = Util.GetConfigVarFromSections(config, "GenerateMaptiles", possibleMapConfigSections, true); + if (m_generateMaptiles) { int maptileRefresh = startupConfig.GetInt("MaptileRefresh", 0); @@ -911,7 +915,10 @@ namespace OpenSim.Region.Framework.Scenes } else { - string tile = startupConfig.GetString("MaptileStaticUUID", UUID.Zero.ToString()); + string tile + = Util.GetConfigVarFromSections( + config, "MaptileStaticUUID", possibleMapConfigSections, UUID.Zero.ToString()); + UUID tileID; if (tile != UUID.Zero.ToString() && UUID.TryParse(tile, out tileID)) -- cgit v1.1 From 2b53f08386baddeda7e0fa19a3072477c2829080 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 25 Feb 2013 21:58:00 -0800 Subject: BulletSim: tweeks to make avatar jump work better. --- OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 1f186c3..f442ca2 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -204,7 +204,7 @@ public sealed class BSCharacter : BSPhysObject // move. Thus, the velocity cannot be forced to zero. The problem is that small velocity // errors can creap in and the avatar will slowly float off in some direction. // So, the problem is that, when an avatar is standing, we cannot tell creaping error - // from real pushing.OMV.Vector3.Zero; + // from real pushing. // The code below keeps setting the velocity to zero hoping the world will keep pushing. _velocityMotor.Step(timeStep); @@ -254,9 +254,11 @@ public sealed class BSCharacter : BSPhysObject } // If falling, we keep the world's downward vector no matter what the other axis specify. + // The check for _velocity.Z < 0 makes jumping work (temporary upward force). if (!Flying && !IsColliding) { - stepVelocity.Z = _velocity.Z; + if (_velocity.Z < 0) + stepVelocity.Z = _velocity.Z; // DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity); } @@ -512,7 +514,7 @@ public sealed class BSCharacter : BSPhysObject // just assign to "Position" because of potential call loops. PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.PositionSanityCheck", delegate() { - DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); + DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); ForcePosition = _position; }); ret = true; @@ -572,7 +574,7 @@ public sealed class BSCharacter : BSPhysObject m_targetVelocity = value; OMV.Vector3 targetVel = value; if (_setAlwaysRun) - targetVel *= BSParam.AvatarAlwaysRunFactor; + targetVel *= new OMV.Vector3(BSParam.AvatarAlwaysRunFactor, BSParam.AvatarAlwaysRunFactor, 0f); PhysicsScene.TaintedObject("BSCharacter.setTargetVelocity", delegate() { -- cgit v1.1 From bf9132e1c7a1ddaf291101f60f43c0cbd0f53662 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 26 Feb 2013 11:32:01 -0800 Subject: BulletSim: fix crash around race condition when a mesh asset cannot be fetched. Update TODO list. --- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 2 +- OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 4dff927..8f660c4 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -470,7 +470,7 @@ public class BSPrim : BSPhysObject // Note that this does not change _mass! public override void UpdatePhysicalMassProperties(float physMass, bool inWorld) { - if (PhysBody.HasPhysicalBody) + if (PhysBody.HasPhysicalBody && PhysShape.HasPhysicalShape) { if (IsStatic) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 49718c4..4dc16f4 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -1,5 +1,12 @@ CURRENT PRIORITIES ================================================= +Use the HACD convex hull routine in Bullet rather than the C# version. + Speed up hullifying large meshes. +Enable vehicle border crossings (at least as poorly as ODE) + Terrain skirts + Avatar created in previous region and not new region when crossing border + Vehicle recreated in new sim at small Z value (offset from root value?) (DONE) +Lock axis Deleting a linkset while standing on the root will leave the physical shape of the root behind. Not sure if it is because standing on it. Done with large prim linksets. Vehicle angular vertical attraction @@ -7,16 +14,11 @@ vehicle angular banking Center-of-gravity Vehicle angular deflection Preferred orientation angular correction fix -Enable vehicle border crossings (at least as poorly as ODE) - Terrain skirts - Avatar created in previous region and not new region when crossing border - Vehicle recreated in new sim at small Z value (offset from root value?) (DONE) when should angular and linear motor targets be zeroed? when selected? Need a vehicle.clear()? Or an 'else' in prestep if not physical. Teravus llMoveToTarget script debug Mixing of hover, buoyancy/gravity, moveToTarget, into one force Setting hover height to zero disables hover even if hover flags are on (from SL wiki) -Nebadon vehicles turning funny in arena limitMotorUp calibration (more down?) llRotLookAt llLookAt @@ -66,6 +68,8 @@ Vehicle attributes are not restored when a vehicle is rezzed on region creation GENERAL TODO LIST: ================================================= +Resitution of a prim works on another prim but not on terrain. + The dropped prim doesn't bounce properly on the terrain. Add a sanity check for PIDTarget location. Level-of-detail for mesh creation. Prims with circular interiors require lod of 32. Is much saved with lower LODs? At the moment, all set to 32. @@ -163,7 +167,6 @@ Create tests for different interface components Have test objects/scripts measure themselves and turn color if correct/bad Test functions in SL and calibrate correctness there Create auto rezzer and tracker to run through the tests -Use the HACD convex hull routine in Bullet rather than the C# version. Do we need to do convex hulls all the time? Can complex meshes be left meshes? There is some problem with meshes and collisions Hulls are not as detailed as meshes. Hulled vehicles insides are different shape. @@ -334,4 +337,5 @@ Child movement in linkset (don't rebuild linkset) (DONE 20130122)) Avatar standing on a moving object should start to move with the object. (DONE 20130125) Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE. Verify that angular motion specified around Z moves in the vehicle coordinates. - DONE 20130120: BulletSim properly applies force in vehicle relative coordinates. \ No newline at end of file + DONE 20130120: BulletSim properly applies force in vehicle relative coordinates. +Nebadon vehicles turning funny in arena (DONE) \ No newline at end of file -- cgit v1.1 From b8a7c8b26f3005eed5b161c37509b06b1d604967 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 26 Feb 2013 23:36:36 +0000 Subject: Add regression test for llRequestUrl() --- .../CoreModules/Scripting/LSLHttp/UrlModule.cs | 37 ++++++++++++---------- .../Region/Framework/Interfaces/IScriptModule.cs | 11 +++++++ .../Shared/Api/Implementation/LSL_Api.cs | 1 + 3 files changed, 33 insertions(+), 16 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index be617a5..79e633f 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -122,15 +122,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp /// private int m_TotalUrls = 100; - private uint https_port = 0; + private uint m_HttpsPort = 0; private IHttpServer m_HttpServer = null; private IHttpServer m_HttpsServer = null; - private string m_ExternalHostNameForLSL = ""; - public string ExternalHostNameForLSL - { - get { return m_ExternalHostNameForLSL; } - } + public string ExternalHostNameForLSL { get; private set; } public Type ReplaceableInterface { @@ -144,11 +140,20 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp public void Initialise(IConfigSource config) { - m_ExternalHostNameForLSL = config.Configs["Network"].GetString("ExternalHostNameForLSL", System.Environment.MachineName); - bool ssl_enabled = config.Configs["Network"].GetBoolean("https_listener",false); + IConfig networkConfig = config.Configs["Network"]; + + if (networkConfig != null) + { + ExternalHostNameForLSL = config.Configs["Network"].GetString("ExternalHostNameForLSL", null); + + bool ssl_enabled = config.Configs["Network"].GetBoolean("https_listener", false); + + if (ssl_enabled) + m_HttpsPort = (uint)config.Configs["Network"].GetInt("https_port", (int)m_HttpsPort); + } - if (ssl_enabled) - https_port = (uint) config.Configs["Network"].GetInt("https_port",0); + if (ExternalHostNameForLSL == null) + ExternalHostNameForLSL = System.Environment.MachineName; IConfig llFunctionsConfig = config.Configs["LL-Functions"]; @@ -169,9 +174,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp m_HttpServer = MainServer.Instance; // // We can use the https if it is enabled - if (https_port > 0) + if (m_HttpsPort > 0) { - m_HttpsServer = MainServer.GetHttpServer(https_port); + m_HttpsServer = MainServer.GetHttpServer(m_HttpsPort); } } @@ -209,7 +214,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); return urlcode; } - string url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString() + "/"; + string url = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString() + "/"; UrlData urlData = new UrlData(); urlData.hostID = host.UUID; @@ -254,7 +259,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); return urlcode; } - string url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString() + "/"; + string url = "https://" + ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString() + "/"; UrlData urlData = new UrlData(); urlData.hostID = host.UUID; @@ -579,9 +584,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp string url; if (is_ssl) - url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp; + url = "https://" + ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp; else - url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp; + url = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp; // Avoid a race - the request URL may have been released via llRequestUrl() whilst this // request was being processed. diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs index 143af48..ced4e91 100644 --- a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs @@ -52,7 +52,18 @@ namespace OpenSim.Region.Framework.Interfaces string GetXMLState(UUID itemID); bool SetXMLState(UUID itemID, string xml); + /// + /// Post a script event to a single script. + /// + /// true if the post suceeded, false if it did not + /// The item ID of the script. + /// The name of the event. + /// + /// The arguments of the event. These are in the order in which they appear. + /// e.g. for http_request this will be an object array of key request_id, string method, string body + /// bool PostScriptEvent(UUID itemID, string name, Object[] args); + bool PostObjectEvent(UUID itemID, string name, Object[] args); /// diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 96f650e..6a31568 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -9423,6 +9423,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return UUID.Zero.ToString(); } } + public LSL_String llRequestURL() { m_host.AddScriptLPS(1); -- cgit v1.1 From 80c19b7cac52a57fd04966169c657400aeee3de8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 27 Feb 2013 00:21:02 +0000 Subject: Make sure we dispose of WebResponse, StreamReader and Stream in various places where we were not already. --- .../Scripting/VectorRender/VectorRenderModule.cs | 16 +++++--- .../CoreModules/World/WorldMap/WorldMapModule.cs | 30 +++++++------- .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 21 ++++++---- .../Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 12 +++--- .../XmlRpcGroupsServicesConnectorModule.cs | 46 +++++++++++++--------- 5 files changed, 71 insertions(+), 54 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs index 689e8a7..f04fabe 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs @@ -838,13 +838,17 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender try { WebRequest request = HttpWebRequest.Create(url); -//Ckrinke: Comment out for now as 'str' is unused. Bring it back into play later when it is used. -//Ckrinke Stream str = null; - HttpWebResponse response = (HttpWebResponse)(request).GetResponse(); - if (response.StatusCode == HttpStatusCode.OK) + + using (HttpWebResponse response = (HttpWebResponse)(request).GetResponse()) { - Bitmap image = new Bitmap(response.GetResponseStream()); - return image; + if (response.StatusCode == HttpStatusCode.OK) + { + using (Stream s = response.GetResponseStream()) + { + Bitmap image = new Bitmap(s); + return image; + } + } } } catch { } diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 912d50a..c50ab64 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -868,20 +868,22 @@ namespace OpenSim.Region.CoreModules.World.WorldMap } string response_mapItems_reply = null; - { // get the response - StreamReader sr = null; + { try { - WebResponse webResponse = mapitemsrequest.GetResponse(); - if (webResponse != null) - { - sr = new StreamReader(webResponse.GetResponseStream()); - response_mapItems_reply = sr.ReadToEnd().Trim(); - } - else + using (WebResponse webResponse = mapitemsrequest.GetResponse()) { - return new OSDMap(); - } + if (webResponse != null) + { + using (Stream s = webResponse.GetResponseStream()) + using (StreamReader sr = new StreamReader(s)) + response_mapItems_reply = sr.ReadToEnd().Trim(); + } + else + { + return new OSDMap(); + } + } } catch (WebException) { @@ -908,11 +910,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap return responseMap; } - finally - { - if (sr != null) - sr.Close(); - } OSD rezResponse = null; try @@ -926,6 +923,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap { m_log.InfoFormat("[WORLD MAP]: exception on parse of RequestMapItems reply from {0}: {1}", httpserver, ex.Message); responseMap["connect"] = OSD.FromBoolean(false); + lock (m_blacklistedregions) { if (!m_blacklistedregions.ContainsKey(regionhandle)) diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 37ab35a..ef1b92e 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -551,13 +551,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice reqStream.Close(); } - HttpWebResponse fwdrsp = (HttpWebResponse)forwardreq.GetResponse(); - Encoding encoding = Util.UTF8; - StreamReader fwdresponsestream = new StreamReader(fwdrsp.GetResponseStream(), encoding); - fwdresponsestr = fwdresponsestream.ReadToEnd(); - fwdresponsecontenttype = fwdrsp.ContentType; - fwdresponsecode = (int)fwdrsp.StatusCode; - fwdresponsestream.Close(); + using (HttpWebResponse fwdrsp = (HttpWebResponse)forwardreq.GetResponse()) + { + Encoding encoding = Util.UTF8; + + using (Stream s = fwdrsp.GetResponseStream()) + { + using (StreamReader fwdresponsestream = new StreamReader(s)) + { + fwdresponsestr = fwdresponsestream.ReadToEnd(); + fwdresponsecontenttype = fwdrsp.ContentType; + fwdresponsecode = (int)fwdrsp.StatusCode; + } + } + } response["content_type"] = fwdresponsecontenttype; response["str_response_string"] = fwdresponsestr; diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index 881807a..cb69411 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -1116,18 +1116,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice // Otherwise prepare the request m_log.DebugFormat("[VivoxVoice] Sending request <{0}>", requrl); - HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requrl); - HttpWebResponse rsp = null; + HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requrl); // We are sending just parameters, no content req.ContentLength = 0; // Send request and retrieve the response - rsp = (HttpWebResponse)req.GetResponse(); - - XmlTextReader rdr = new XmlTextReader(rsp.GetResponseStream()); - doc.Load(rdr); - rdr.Close(); + using (HttpWebResponse rsp = (HttpWebResponse)req.GetResponse()) + using (Stream s = rsp.GetResponseStream()) + using (XmlTextReader rdr = new XmlTextReader(s)) + doc.Load(rdr); } catch (Exception e) { diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 1101851..71b24ac 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -1146,28 +1146,38 @@ namespace Nwc.XmlRpc request.AllowWriteStreamBuffering = true; request.KeepAlive = !_disableKeepAlive; - Stream stream = request.GetRequestStream(); - XmlTextWriter xml = new XmlTextWriter(stream, Encoding.ASCII); - _serializer.Serialize(xml, this); - xml.Flush(); - xml.Close(); - - HttpWebResponse response = (HttpWebResponse)request.GetResponse(); - StreamReader input = new StreamReader(response.GetResponseStream()); - - string inputXml = input.ReadToEnd(); - XmlRpcResponse resp; - try + using (Stream stream = request.GetRequestStream()) { - resp = (XmlRpcResponse)_deserializer.Deserialize(inputXml); + using (XmlTextWriter xml = new XmlTextWriter(stream, Encoding.ASCII)) + { + _serializer.Serialize(xml, this); + xml.Flush(); + } } - catch (Exception e) + + XmlRpcResponse resp; + + using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { - RequestResponse = inputXml; - throw e; + using (Stream s = response.GetResponseStream()) + { + using (StreamReader input = new StreamReader(s)) + { + string inputXml = input.ReadToEnd(); + + try + { + resp = (XmlRpcResponse)_deserializer.Deserialize(inputXml); + } + catch (Exception e) + { + RequestResponse = inputXml; + throw e; + } + } + } } - input.Close(); - response.Close(); + return resp; } } -- cgit v1.1 From 59bd099b0385cc79bba751e168ef26c923c9f003 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 27 Feb 2013 20:12:58 +0000 Subject: Add regression test for llReleaseUrl() (and for llRequestUrl) Forgot to add file for llRequestUrl() test in commit b8a7c8b --- .../CoreModules/Scripting/LSLHttp/UrlModule.cs | 25 ++- .../ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs | 250 +++++++++++++++++++++ 2 files changed, 266 insertions(+), 9 deletions(-) create mode 100644 OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index 79e633f..c9cd412 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -117,17 +117,22 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp /// private Dictionary m_UrlMap = new Dictionary(); - /// - /// Maximum number of external urls that can be set up by this module. - /// - private int m_TotalUrls = 100; - private uint m_HttpsPort = 0; private IHttpServer m_HttpServer = null; private IHttpServer m_HttpsServer = null; public string ExternalHostNameForLSL { get; private set; } + /// + /// The default maximum number of urls + /// + public const int DefaultTotalUrls = 100; + + /// + /// Maximum number of external urls that can be set up by this module. + /// + public int TotalUrls { get; set; } + public Type ReplaceableInterface { get { return null; } @@ -158,7 +163,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp IConfig llFunctionsConfig = config.Configs["LL-Functions"]; if (llFunctionsConfig != null) - m_TotalUrls = llFunctionsConfig.GetInt("max_external_urls_per_simulator", m_TotalUrls); + TotalUrls = llFunctionsConfig.GetInt("max_external_urls_per_simulator", DefaultTotalUrls); + else + TotalUrls = DefaultTotalUrls; } public void PostInitialise() @@ -209,7 +216,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp lock (m_UrlMap) { - if (m_UrlMap.Count >= m_TotalUrls) + if (m_UrlMap.Count >= TotalUrls) { engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); return urlcode; @@ -254,7 +261,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp lock (m_UrlMap) { - if (m_UrlMap.Count >= m_TotalUrls) + if (m_UrlMap.Count >= TotalUrls) { engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); return urlcode; @@ -382,7 +389,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp public int GetFreeUrls() { lock (m_UrlMap) - return m_TotalUrls - m_UrlMap.Count; + return TotalUrls - m_UrlMap.Count; } public void ScriptRemoved(UUID itemID) diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs new file mode 100644 index 0000000..b0baa1c --- /dev/null +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs @@ -0,0 +1,250 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Reflection; +using System.Text; +using log4net; +using Nini.Config; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Region.CoreModules.Scripting.LSLHttp; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.ScriptEngine.Shared; +using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; +using OpenSim.Services.Interfaces; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Region.ScriptEngine.Shared.Tests +{ + /// + /// Tests for HTTP related functions in LSL + /// + [TestFixture] + public class LSL_ApiHttpTests : OpenSimTestCase + { + private Scene m_scene; + private MockScriptEngine m_engine; + private UrlModule m_urlModule; + + private TaskInventoryItem m_scriptItem; + private LSL_Api m_lslApi; + + [TestFixtureSetUp] + public void TestFixtureSetUp() + { + // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread. + Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest; + } + + [TestFixtureTearDown] + public void TestFixureTearDown() + { + // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple + // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression + // tests really shouldn't). + Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; + } + + [SetUp] + public override void SetUp() + { + base.SetUp(); + + // This is an unfortunate bit of clean up we have to do because MainServer manages things through static + // variables and the VM is not restarted between tests. + uint port = 9999; + MainServer.RemoveHttpServer(port); + + BaseHttpServer server = new BaseHttpServer(port, false, 0, ""); + MainServer.AddHttpServer(server); + MainServer.Instance = server; + + server.Start(); + + m_engine = new MockScriptEngine(); + m_urlModule = new UrlModule(); + + m_scene = new SceneHelpers().SetupScene(); + SceneHelpers.SetupSceneModules(m_scene, new IniConfigSource(), m_engine, m_urlModule); + + SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); + m_scriptItem = TaskInventoryHelpers.AddScript(m_scene, so.RootPart); + + // This is disconnected from the actual script - the mock engine does not set up any LSL_Api atm. + // Possibly this could be done and we could obtain it directly from the MockScriptEngine. + m_lslApi = new LSL_Api(); + m_lslApi.Initialize(m_engine, so.RootPart, m_scriptItem, null); + } + + [TearDown] + public void TearDown() + { + MainServer.Instance.Stop(); + } + + [Test] + public void TestLlReleaseUrl() + { + TestHelpers.InMethod(); + + m_lslApi.llRequestURL(); + string returnedUri = m_engine.PostedEvents[m_scriptItem.ItemID][0].Params[2].ToString(); + + { + // Check that the initial number of URLs is correct + Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls - 1)); + } + + { + // Check releasing a non-url + m_lslApi.llReleaseURL("GARBAGE"); + Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls - 1)); + } + + { + // Check releasing a non-existing url + m_lslApi.llReleaseURL("http://example.com"); + Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls - 1)); + } + + { + // Check URL release + m_lslApi.llReleaseURL(returnedUri); + Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls)); + + HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(returnedUri); + + bool gotExpectedException = false; + + try + { + using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse()) + {} + } + catch (WebException e) + { + using (HttpWebResponse response = (HttpWebResponse)e.Response) + gotExpectedException = response.StatusCode == HttpStatusCode.NotFound; + } + + Assert.That(gotExpectedException, Is.True); + } + + { + // Check releasing the same URL again + m_lslApi.llReleaseURL(returnedUri); + Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls)); + } + } + + [Test] + public void TestLlRequestUrl() + { + TestHelpers.InMethod(); + + string requestId = m_lslApi.llRequestURL(); + Assert.That(requestId, Is.Not.EqualTo(UUID.Zero.ToString())); + string returnedUri; + + { + // Check that URL is correctly set up + Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls - 1)); + + Assert.That(m_engine.PostedEvents.ContainsKey(m_scriptItem.ItemID)); + + List events = m_engine.PostedEvents[m_scriptItem.ItemID]; + Assert.That(events.Count, Is.EqualTo(1)); + EventParams eventParams = events[0]; + Assert.That(eventParams.EventName, Is.EqualTo("http_request")); + + UUID returnKey; + string rawReturnKey = eventParams.Params[0].ToString(); + string method = eventParams.Params[1].ToString(); + returnedUri = eventParams.Params[2].ToString(); + + Assert.That(UUID.TryParse(rawReturnKey, out returnKey), Is.True); + Assert.That(method, Is.EqualTo(ScriptBaseClass.URL_REQUEST_GRANTED)); + Assert.That(Uri.IsWellFormedUriString(returnedUri, UriKind.Absolute), Is.True); + } + + { + // Check that request to URL works. + string testResponse = "Hello World"; + + m_engine.ClearPostedEvents(); + m_engine.PostEventHook + += (itemId, evp) => m_lslApi.llHTTPResponse(evp.Params[0].ToString(), 200, testResponse); + +// Console.WriteLine("Trying {0}", returnedUri); + HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(returnedUri); + + AssertHttpResponse(returnedUri, testResponse); + + Assert.That(m_engine.PostedEvents.ContainsKey(m_scriptItem.ItemID)); + + List events = m_engine.PostedEvents[m_scriptItem.ItemID]; + Assert.That(events.Count, Is.EqualTo(1)); + EventParams eventParams = events[0]; + Assert.That(eventParams.EventName, Is.EqualTo("http_request")); + + UUID returnKey; + string rawReturnKey = eventParams.Params[0].ToString(); + string method = eventParams.Params[1].ToString(); + string body = eventParams.Params[2].ToString(); + + Assert.That(UUID.TryParse(rawReturnKey, out returnKey), Is.True); + Assert.That(method, Is.EqualTo("GET")); + Assert.That(body, Is.EqualTo("")); + } + } + + private void AssertHttpResponse(string uri, string expectedResponse) + { + HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri); + + using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse()) + { + using (Stream stream = webResponse.GetResponseStream()) + { + using (StreamReader reader = new StreamReader(stream)) + { + Assert.That(reader.ReadToEnd(), Is.EqualTo(expectedResponse)); + } + } + } + } + } +} \ No newline at end of file -- cgit v1.1 From 61ba02e95fbce86b64fca39451b8b4f395bec0c9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 27 Feb 2013 20:38:10 +0000 Subject: minor: remove some mono compiler warnings in script regression tests --- .../Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs | 1 - OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs index 7ea30bf1..ac822c6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs @@ -443,7 +443,6 @@ default string itemName = "TestNoStop"; SceneObjectPart partWhereRezzed = CreateScript(script, itemName, userId); - TaskInventoryItem rezzedItem = partWhereRezzed.Inventory.GetInventoryItem(itemName); // Wait for the script to start the event before we try stopping it. m_chatEvent.WaitOne(60000); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs index 1f8a6e5..74f010e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs @@ -222,7 +222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests // Store an avatar with a different height from default in a notecard. UUID userId = TestHelpers.ParseTail(0x1); float firstHeight = 1.9f; - float secondHeight = 2.1f; +// float secondHeight = 2.1f; string firstAppearanceNcName = "appearanceNc1"; string secondAppearanceNcName = "appearanceNc2"; -- cgit v1.1 From 647cb278c714f86c945a449bfecc901982d96687 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 27 Feb 2013 22:25:03 +0000 Subject: Get "show modules" console command to show modules in alphabetical order, and group shared and non-shared modules together This is to make it easier to tell if a region has a certain module active or not --- OpenSim/Region/Application/OpenSim.cs | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index c4731a3..20e00e3 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -30,6 +30,7 @@ using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Linq; using System.Reflection; using System.Text; using System.Text.RegularExpressions; @@ -809,15 +810,27 @@ namespace OpenSim case "modules": SceneManager.ForEachScene( - delegate(Scene scene) { - MainConsole.Instance.Output("Loaded region modules in" + scene.RegionInfo.RegionName + " are:"); - foreach (IRegionModuleBase module in scene.RegionModules.Values) + scene => { - Type type = module.GetType().GetInterface("ISharedRegionModule"); - string module_type = type != null ? "Shared" : "Non-Shared"; - MainConsole.Instance.OutputFormat("New Region Module ({0}): {1}", module_type, module.Name); + MainConsole.Instance.OutputFormat("Loaded region modules in {0} are:", scene.Name); + + List sharedModules = new List(); + List nonSharedModules = new List(); + + foreach (IRegionModuleBase module in scene.RegionModules.Values) + { + if (module.GetType().GetInterface("ISharedRegionModule") != null) + nonSharedModules.Add(module); + else + sharedModules.Add(module); + } + + foreach (IRegionModuleBase module in sharedModules.OrderBy(m => m.Name)) + MainConsole.Instance.OutputFormat("New Region Module (Shared): {0}", module.Name); + + foreach (IRegionModuleBase module in sharedModules.OrderBy(m => m.Name)) + MainConsole.Instance.OutputFormat("New Region Module (Non-Shared): {0}", module.Name); } - } ); MainConsole.Instance.Output(""); -- cgit v1.1 From 0e8ec5649ec5929927760368226ac5c584dc4a4e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 27 Feb 2013 22:31:47 +0000 Subject: Get "show modules" console command to obey selected command line region/s --- OpenSim/Region/Application/OpenSim.cs | 2 +- OpenSim/Region/Application/OpenSimBase.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneManager.cs | 27 ++++++++++--------------- 3 files changed, 13 insertions(+), 18 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 20e00e3..4075edb 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -809,7 +809,7 @@ namespace OpenSim break; case "modules": - SceneManager.ForEachScene( + SceneManager.ForEachSelectedScene( scene => { MainConsole.Instance.OutputFormat("Loaded region modules in {0} are:", scene.Name); diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index 3c8e199..c555915 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -668,7 +668,7 @@ namespace OpenSim // listenIP = IPAddress.Parse("0.0.0.0"); uint port = (uint) regionInfo.InternalEndPoint.Port; - IClientNetworkServer clientNetworkServer; + if (m_autoCreateClientStack) { clientNetworkServers = m_clientStackManager.CreateServers( diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs index 1e2e973..780bd01 100644 --- a/OpenSim/Region/Framework/Scenes/SceneManager.cs +++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs @@ -331,35 +331,30 @@ namespace OpenSim.Region.Framework.Scenes public void SendCommandToPluginModules(string[] cmdparams) { - ForEachCurrentScene(delegate(Scene scene) { scene.SendCommandToPlugins(cmdparams); }); + ForEachSelectedScene(delegate(Scene scene) { scene.SendCommandToPlugins(cmdparams); }); } public void SetBypassPermissionsOnCurrentScene(bool bypassPermissions) { - ForEachCurrentScene(delegate(Scene scene) { scene.Permissions.SetBypassPermissions(bypassPermissions); }); + ForEachSelectedScene(delegate(Scene scene) { scene.Permissions.SetBypassPermissions(bypassPermissions); }); } - private void ForEachCurrentScene(Action func) + public void ForEachSelectedScene(Action func) { if (CurrentScene == null) - { - lock (m_localScenes) - m_localScenes.ForEach(func); - } + ForEachScene(func); else - { func(CurrentScene); - } } public void RestartCurrentScene() { - ForEachCurrentScene(delegate(Scene scene) { scene.RestartNow(); }); + ForEachSelectedScene(delegate(Scene scene) { scene.RestartNow(); }); } public void BackupCurrentScene() { - ForEachCurrentScene(delegate(Scene scene) { scene.Backup(true); }); + ForEachSelectedScene(delegate(Scene scene) { scene.Backup(true); }); } public bool TrySetCurrentScene(string regionName) @@ -490,7 +485,7 @@ namespace OpenSim.Region.Framework.Scenes /// Name of avatar to debug public void SetDebugPacketLevelOnCurrentScene(int newDebug, string name) { - ForEachCurrentScene(scene => + ForEachSelectedScene(scene => scene.ForEachScenePresence(sp => { if (name == null || sp.Name == name) @@ -509,7 +504,7 @@ namespace OpenSim.Region.Framework.Scenes { List avatars = new List(); - ForEachCurrentScene( + ForEachSelectedScene( delegate(Scene scene) { scene.ForEachRootScenePresence(delegate(ScenePresence scenePresence) @@ -526,7 +521,7 @@ namespace OpenSim.Region.Framework.Scenes { List presences = new List(); - ForEachCurrentScene(delegate(Scene scene) + ForEachSelectedScene(delegate(Scene scene) { scene.ForEachScenePresence(delegate(ScenePresence sp) { @@ -555,12 +550,12 @@ namespace OpenSim.Region.Framework.Scenes public void ForceCurrentSceneClientUpdate() { - ForEachCurrentScene(delegate(Scene scene) { scene.ForceClientUpdate(); }); + ForEachSelectedScene(delegate(Scene scene) { scene.ForceClientUpdate(); }); } public void HandleEditCommandOnCurrentScene(string[] cmdparams) { - ForEachCurrentScene(delegate(Scene scene) { scene.HandleEditCommand(cmdparams); }); + ForEachSelectedScene(delegate(Scene scene) { scene.HandleEditCommand(cmdparams); }); } public bool TryGetScenePresence(UUID avatarId, out ScenePresence avatar) -- cgit v1.1 From b892411575f2a42bf1ca3c326815942f905e79ff Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 27 Feb 2013 22:54:51 +0000 Subject: Add comment to example region modules about need to add Assembly annotation if adding modules to a DLL which does not already have this --- .../Example/BareBonesNonShared/BareBonesNonSharedModule.cs | 5 +++++ .../OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs | 5 +++++ 2 files changed, 10 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs b/OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs index 7d37135..ad2fc7a 100644 --- a/OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs +++ b/OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs @@ -33,6 +33,11 @@ using Nini.Config; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +// You will need to uncomment this line if you are adding a region module to some other assembly which does not already +// specify its assembly. Otherwise, the region modules in the assembly will not be picked up when OpenSimulator scans +// the available DLLs +//[assembly: Addin("MyModule", "1.0")] + namespace OpenSim.Region.OptionalModules.Example.BareBonesNonShared { /// diff --git a/OpenSim/Region/OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs b/OpenSim/Region/OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs index 781fe95..bb9cbb7 100644 --- a/OpenSim/Region/OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs +++ b/OpenSim/Region/OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs @@ -33,6 +33,11 @@ using Nini.Config; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +// You will need to uncomment this line if you are adding a region module to some other assembly which does not already +// specify its assembly. Otherwise, the region modules in the assembly will not be picked up when OpenSimulator scans +// the available DLLs +//[assembly: Addin("MyModule", "1.0")] + namespace OpenSim.Region.OptionalModules.Example.BareBonesShared { /// -- cgit v1.1 From f1010d7b152b68e2961b40482006221e28e976af Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 27 Feb 2013 20:49:41 -0800 Subject: Moved the HG default variables out of [Startup] and into their own section [Hypergrid] in *Common.ini.example. Backwards compatible for now. --- OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs | 2 +- .../CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs | 4 ++-- OpenSim/Region/DataSnapshot/DataSnapshotManager.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs index 22cdc80..c646d94 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs @@ -65,7 +65,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure { m_Enabled = true; - m_ThisGridURL = Util.GetConfigVarFromSections(config, "GatekeeperURI", new string[] {"Startup", "Messaging"}); + m_ThisGridURL = Util.GetConfigVarFromSections(config, "GatekeeperURI", new string[] { "Startup", "Hypergrid", "Messaging" }); // Legacy. Remove soon! m_ThisGridURL = config.Configs["Messaging"].GetString("Gatekeeper", m_ThisGridURL); m_log.DebugFormat("[LURE MODULE]: {0} enabled", Name); diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs index 4f6b92e..31fccea 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs @@ -88,8 +88,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"]; if (thisModuleConfig != null) { - m_HomeURI = Util.GetConfigVarFromSections(source, "HomeURI", new string[] {"Startup", "HGInventoryAccessModule"}); - m_ThisGatekeeper = Util.GetConfigVarFromSections(source, "GatekeeperURI", new string[] {"Startup", "HGInventoryAccessModule"}); + m_HomeURI = Util.GetConfigVarFromSections(source, "HomeURI", new string[] { "Startup", "Hypergrid", "HGInventoryAccessModule" }); + m_ThisGatekeeper = Util.GetConfigVarFromSections(source, "GatekeeperURI", new string[] { "Startup", "Hypergrid", "HGInventoryAccessModule" }); // Legacy. Renove soon! m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", m_ThisGatekeeper); diff --git a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs index e8bf194..61dbfa5 100644 --- a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs +++ b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs @@ -113,7 +113,7 @@ namespace OpenSim.Region.DataSnapshot try { m_enabled = config.Configs["DataSnapshot"].GetBoolean("index_sims", m_enabled); - string gatekeeper = Util.GetConfigVarFromSections(config, "GatekeeperURI", new string[] {"Startup", "GridService"}); + string gatekeeper = Util.GetConfigVarFromSections(config, "GatekeeperURI", new string[] { "Startup", "Hypergrid", "GridService" }); // Legacy. Remove soon! if (string.IsNullOrEmpty(gatekeeper)) { diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index d356f8c..e81b4ae 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2138,7 +2138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); IConfigSource config = m_ScriptEngine.ConfigSource; - string HomeURI = Util.GetConfigVarFromSections(config, "HomeURI", new string[]{"Startup"}); + string HomeURI = Util.GetConfigVarFromSections(config, "HomeURI", new string[] { "Startup", "Hypergrid" }); if (!string.IsNullOrEmpty(HomeURI)) return HomeURI; @@ -2159,7 +2159,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); IConfigSource config = m_ScriptEngine.ConfigSource; - string gatekeeperURI = Util.GetConfigVarFromSections(config, "GatekeeperURI", new string[] {"Startup"}); + string gatekeeperURI = Util.GetConfigVarFromSections(config, "GatekeeperURI", new string[] { "Startup", "Hypergrid" }); if (!string.IsNullOrEmpty(gatekeeperURI)) return gatekeeperURI; -- cgit v1.1 From bb447581795cb622e88a071d3050370c64ace946 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 27 Feb 2013 20:59:16 -0800 Subject: Switched to using the other Util function with a default value. --- OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs | 3 ++- .../Framework/InventoryAccess/HGInventoryAccessModule.cs | 6 ++++-- OpenSim/Region/DataSnapshot/DataSnapshotManager.cs | 3 ++- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 6 ++++-- 4 files changed, 12 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs index c646d94..6c9fd86 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs @@ -65,7 +65,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure { m_Enabled = true; - m_ThisGridURL = Util.GetConfigVarFromSections(config, "GatekeeperURI", new string[] { "Startup", "Hypergrid", "Messaging" }); + m_ThisGridURL = Util.GetConfigVarFromSections(config, "GatekeeperURI", + new string[] { "Startup", "Hypergrid", "Messaging" }, String.Empty); // Legacy. Remove soon! m_ThisGridURL = config.Configs["Messaging"].GetString("Gatekeeper", m_ThisGridURL); m_log.DebugFormat("[LURE MODULE]: {0} enabled", Name); diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs index 31fccea..b2b628d 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs @@ -88,8 +88,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"]; if (thisModuleConfig != null) { - m_HomeURI = Util.GetConfigVarFromSections(source, "HomeURI", new string[] { "Startup", "Hypergrid", "HGInventoryAccessModule" }); - m_ThisGatekeeper = Util.GetConfigVarFromSections(source, "GatekeeperURI", new string[] { "Startup", "Hypergrid", "HGInventoryAccessModule" }); + m_HomeURI = Util.GetConfigVarFromSections(source, "HomeURI", + new string[] { "Startup", "Hypergrid", "HGInventoryAccessModule" }, String.Empty); + m_ThisGatekeeper = Util.GetConfigVarFromSections(source, "GatekeeperURI", + new string[] { "Startup", "Hypergrid", "HGInventoryAccessModule" }, String.Empty); // Legacy. Renove soon! m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", m_ThisGatekeeper); diff --git a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs index 61dbfa5..32017a8 100644 --- a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs +++ b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs @@ -113,7 +113,8 @@ namespace OpenSim.Region.DataSnapshot try { m_enabled = config.Configs["DataSnapshot"].GetBoolean("index_sims", m_enabled); - string gatekeeper = Util.GetConfigVarFromSections(config, "GatekeeperURI", new string[] { "Startup", "Hypergrid", "GridService" }); + string gatekeeper = Util.GetConfigVarFromSections(config, "GatekeeperURI", + new string[] { "Startup", "Hypergrid", "GridService" }, String.Empty); // Legacy. Remove soon! if (string.IsNullOrEmpty(gatekeeper)) { diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index e81b4ae..48c6b50 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2138,7 +2138,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); IConfigSource config = m_ScriptEngine.ConfigSource; - string HomeURI = Util.GetConfigVarFromSections(config, "HomeURI", new string[] { "Startup", "Hypergrid" }); + string HomeURI = Util.GetConfigVarFromSections(config, "HomeURI", + new string[] { "Startup", "Hypergrid" }, String.Empty); if (!string.IsNullOrEmpty(HomeURI)) return HomeURI; @@ -2159,7 +2160,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); IConfigSource config = m_ScriptEngine.ConfigSource; - string gatekeeperURI = Util.GetConfigVarFromSections(config, "GatekeeperURI", new string[] { "Startup", "Hypergrid" }); + string gatekeeperURI = Util.GetConfigVarFromSections(config, "GatekeeperURI", + new string[] { "Startup", "Hypergrid" }, String.Empty); if (!string.IsNullOrEmpty(gatekeeperURI)) return gatekeeperURI; -- cgit v1.1 From 3cc3a8e5bf4653157adb51ac2839448189428a14 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 27 Feb 2013 21:12:27 -0800 Subject: Removed duplicate 'using' statement. --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs index 2fe6948..d0922aa 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs @@ -29,7 +29,6 @@ using System; using System.Reflection; using System.Collections; using System.Collections.Generic; -using System.Reflection; using System.Runtime.Remoting.Lifetime; using System.Threading; using log4net; -- cgit v1.1 From 14684116f8ef23892b71ef16759224a536ac27bf Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Feb 2013 20:57:03 +0000 Subject: Add regression tests for llGetNotecardLine() --- .../Framework/Scenes/Tests/TaskInventoryTests.cs | 4 +- .../Shared/Tests/LSL_ApiLinkingTests.cs | 4 +- .../Shared/Tests/LSL_ApiNotecardTests.cs | 270 +++++++++++++++++++++ .../Shared/Tests/OSSL_ApiAttachmentTests.cs | 2 +- 4 files changed, 275 insertions(+), 5 deletions(-) create mode 100644 OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiNotecardTests.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs index df819ec..6e0ea7d 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs @@ -130,7 +130,7 @@ namespace OpenSim.Region.Framework.Tests SceneObjectPart sop1 = sog1.RootPart; TaskInventoryItem sopItem1 = TaskInventoryHelpers.AddNotecard( - scene, sop1, "ncItem", TestHelpers.ParseTail(0x800), TestHelpers.ParseTail(0x900)); + scene, sop1, "ncItem", TestHelpers.ParseTail(0x800), TestHelpers.ParseTail(0x900), "Hello World!"); InventoryFolderBase folder = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, user1.PrincipalID, "Objects")[0]; @@ -162,7 +162,7 @@ namespace OpenSim.Region.Framework.Tests SceneObjectPart sop1 = sog1.RootPart; TaskInventoryItem sopItem1 = TaskInventoryHelpers.AddNotecard( - scene, sop1, "ncItem", TestHelpers.ParseTail(0x800), TestHelpers.ParseTail(0x900)); + scene, sop1, "ncItem", TestHelpers.ParseTail(0x800), TestHelpers.ParseTail(0x900), "Hello World!"); // Perform test scene.MoveTaskInventoryItem(user1.PrincipalID, UUID.Zero, sop1, sopItem1.ItemID); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs index 5b57bbe..ac9f93b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs @@ -93,7 +93,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests // FIXME: This should really be a script item (with accompanying script) TaskInventoryItem grp1Item = TaskInventoryHelpers.AddNotecard( - m_scene, grp1.RootPart, "ncItem", TestHelpers.ParseTail(0x800), TestHelpers.ParseTail(0x900)); + m_scene, grp1.RootPart, "ncItem", TestHelpers.ParseTail(0x800), TestHelpers.ParseTail(0x900), "Hello World!"); grp1Item.PermsMask |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; SceneObjectGroup grp2 = SceneHelpers.CreateSceneObject(2, ownerId, "grp2-", 0x20); @@ -127,7 +127,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests // FIXME: This should really be a script item (with accompanying script) TaskInventoryItem grp1Item = TaskInventoryHelpers.AddNotecard( - m_scene, grp1.RootPart, "ncItem", TestHelpers.ParseTail(0x800), TestHelpers.ParseTail(0x900)); + m_scene, grp1.RootPart, "ncItem", TestHelpers.ParseTail(0x800), TestHelpers.ParseTail(0x900), "Hello World!"); grp1Item.PermsMask |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiNotecardTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiNotecardTests.cs new file mode 100644 index 0000000..c92bcdb --- /dev/null +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiNotecardTests.cs @@ -0,0 +1,270 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Reflection; +using System.Text; +using log4net; +using Nini.Config; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Region.CoreModules.Scripting.LSLHttp; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.ScriptEngine.Shared; +using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; +using OpenSim.Services.Interfaces; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Region.ScriptEngine.Shared.Tests +{ + /// + /// Tests for notecard related functions in LSL + /// + [TestFixture] + public class LSL_ApiNotecardTests : OpenSimTestCase + { + private Scene m_scene; + private MockScriptEngine m_engine; + + private SceneObjectGroup m_so; + private TaskInventoryItem m_scriptItem; + private LSL_Api m_lslApi; + + [TestFixtureSetUp] + public void TestFixtureSetUp() + { + // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread. + Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest; + } + + [TestFixtureTearDown] + public void TestFixureTearDown() + { + // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple + // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression + // tests really shouldn't). + Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; + } + + [SetUp] + public override void SetUp() + { + base.SetUp(); + + m_engine = new MockScriptEngine(); + + m_scene = new SceneHelpers().SetupScene(); + SceneHelpers.SetupSceneModules(m_scene, new IniConfigSource(), m_engine); + + m_so = SceneHelpers.AddSceneObject(m_scene); + m_scriptItem = TaskInventoryHelpers.AddScript(m_scene, m_so.RootPart); + + // This is disconnected from the actual script - the mock engine does not set up any LSL_Api atm. + // Possibly this could be done and we could obtain it directly from the MockScriptEngine. + m_lslApi = new LSL_Api(); + m_lslApi.Initialize(m_engine, m_so.RootPart, m_scriptItem, null); + } + + [Test] + public void TestLlGetNotecardLine() + { + TestHelpers.InMethod(); + + string[] ncLines = { "One", "Two", "Three" }; + + TaskInventoryItem ncItem + = TaskInventoryHelpers.AddNotecard(m_scene, m_so.RootPart, "nc", "1", "10", string.Join("\n", ncLines)); + + AssertValidNotecardLine(ncItem.Name, 0, ncLines[0]); + AssertValidNotecardLine(ncItem.Name, 2, ncLines[2]); + AssertValidNotecardLine(ncItem.Name, 3, ScriptBaseClass.EOF); + AssertValidNotecardLine(ncItem.Name, 4, ScriptBaseClass.EOF); + + // XXX: Is this correct or do we really expect no dataserver event to fire at all? + AssertValidNotecardLine(ncItem.Name, -1, ""); + AssertValidNotecardLine(ncItem.Name, -2, ""); + } + + [Test] + public void TestLlGetNotecardLine_NoNotecard() + { + TestHelpers.InMethod(); + + AssertInValidNotecardLine("nc", 0); + } + + [Test] + public void TestLlGetNotecardLine_NotANotecard() + { + TestHelpers.InMethod(); + + TaskInventoryItem ncItem = TaskInventoryHelpers.AddScript(m_scene, m_so.RootPart, "nc1", "Not important"); + + AssertInValidNotecardLine(ncItem.Name, 0); + } + + private void AssertValidNotecardLine(string ncName, int lineNumber, string assertLine) + { + string key = m_lslApi.llGetNotecardLine(ncName, lineNumber); + Assert.That(key, Is.Not.EqualTo(UUID.Zero.ToString())); + + Assert.That(m_engine.PostedEvents.Count, Is.EqualTo(1)); + Assert.That(m_engine.PostedEvents.ContainsKey(m_scriptItem.ItemID)); + + List events = m_engine.PostedEvents[m_scriptItem.ItemID]; + Assert.That(events.Count, Is.EqualTo(1)); + EventParams eventParams = events[0]; + + Assert.That(eventParams.EventName, Is.EqualTo("dataserver")); + Assert.That(eventParams.Params[0].ToString(), Is.EqualTo(key)); + Assert.That(eventParams.Params[1].ToString(), Is.EqualTo(assertLine)); + + m_engine.ClearPostedEvents(); + } + + private void AssertInValidNotecardLine(string ncName, int lineNumber) + { + string key = m_lslApi.llGetNotecardLine(ncName, lineNumber); + Assert.That(key, Is.EqualTo(UUID.Zero.ToString())); + + Assert.That(m_engine.PostedEvents.Count, Is.EqualTo(0)); + } + +// [Test] +// public void TestLlReleaseUrl() +// { +// TestHelpers.InMethod(); +// +// m_lslApi.llRequestURL(); +// string returnedUri = m_engine.PostedEvents[m_scriptItem.ItemID][0].Params[2].ToString(); +// +// { +// // Check that the initial number of URLs is correct +// Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls - 1)); +// } +// +// { +// // Check releasing a non-url +// m_lslApi.llReleaseURL("GARBAGE"); +// Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls - 1)); +// } +// +// { +// // Check releasing a non-existing url +// m_lslApi.llReleaseURL("http://example.com"); +// Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls - 1)); +// } +// +// { +// // Check URL release +// m_lslApi.llReleaseURL(returnedUri); +// Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls)); +// +// HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(returnedUri); +// +// bool gotExpectedException = false; +// +// try +// { +// using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse()) +// {} +// } +// catch (WebException e) +// { +// using (HttpWebResponse response = (HttpWebResponse)e.Response) +// gotExpectedException = response.StatusCode == HttpStatusCode.NotFound; +// } +// +// Assert.That(gotExpectedException, Is.True); +// } +// +// { +// // Check releasing the same URL again +// m_lslApi.llReleaseURL(returnedUri); +// Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls)); +// } +// } +// +// [Test] +// public void TestLlRequestUrl() +// { +// TestHelpers.InMethod(); +// +// string requestId = m_lslApi.llRequestURL(); +// Assert.That(requestId, Is.Not.EqualTo(UUID.Zero.ToString())); +// string returnedUri; +// +// { +// // Check that URL is correctly set up +// Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls - 1)); +// +// Assert.That(m_engine.PostedEvents.ContainsKey(m_scriptItem.ItemID)); +// +// List events = m_engine.PostedEvents[m_scriptItem.ItemID]; +// Assert.That(events.Count, Is.EqualTo(1)); +// EventParams eventParams = events[0]; +// Assert.That(eventParams.EventName, Is.EqualTo("http_request")); +// +// UUID returnKey; +// string rawReturnKey = eventParams.Params[0].ToString(); +// string method = eventParams.Params[1].ToString(); +// returnedUri = eventParams.Params[2].ToString(); +// +// Assert.That(UUID.TryParse(rawReturnKey, out returnKey), Is.True); +// Assert.That(method, Is.EqualTo(ScriptBaseClass.URL_REQUEST_GRANTED)); +// Assert.That(Uri.IsWellFormedUriString(returnedUri, UriKind.Absolute), Is.True); +// } +// +// { +// // Check that request to URL works. +// string testResponse = "Hello World"; +// +// m_engine.ClearPostedEvents(); +// m_engine.PostEventHook +// += (itemId, evp) => m_lslApi.llHTTPResponse(evp.Params[0].ToString(), 200, testResponse); +// +//// Console.WriteLine("Trying {0}", returnedUri); +// HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(returnedUri); +// +// AssertHttpResponse(returnedUri, testResponse); +// +// Assert.That(m_engine.PostedEvents.ContainsKey(m_scriptItem.ItemID)); +// +// List events = m_engine.PostedEvents[m_scriptItem.ItemID]; +// Assert.That(events.Count, Is.EqualTo(1)); +// EventParams eventParams = events[0]; +// Assert.That(eventParams.EventName, Is.EqualTo("http_request")); +// +// UUID returnKey; +// string rawReturnKey = eventParams.Params[0].ToString(); +// string method = eventParams.Params[1].ToString(); +// string body = eventParams.Params[2].ToString(); +// +// Assert.That(UUID.TryParse(rawReturnKey, out returnKey), Is.True); +// Assert.That(method, Is.EqualTo("GET")); +// Assert.That(body, Is.EqualTo("")); +// } +// } +// +// private void AssertHttpResponse(string uri, string expectedResponse) +// { +// HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri); +// +// using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse()) +// { +// using (Stream stream = webResponse.GetResponseStream()) +// { +// using (StreamReader reader = new StreamReader(stream)) +// { +// Assert.That(reader.ReadToEnd(), Is.EqualTo(expectedResponse)); +// } +// } +// } +// } + } +} \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs index b2803a1..e422f5b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs @@ -151,7 +151,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests // Create an object embedded inside the first TaskInventoryHelpers.AddNotecard( - m_scene, inWorldObj.RootPart, taskInvObjItemName, taskInvObjItemId, TestHelpers.ParseTail(0x900)); + m_scene, inWorldObj.RootPart, taskInvObjItemName, taskInvObjItemId, TestHelpers.ParseTail(0x900), "Hello World!"); bool exceptionCaught = false; -- cgit v1.1 From a523ed1e4d4c8e9c4366fddaaf6a67fe35a9859f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Feb 2013 21:15:14 +0000 Subject: Fix bug where simultaneous calls by different scripts to llGetNotecardLine() or llGetNumberOfNotecardLines() would sometimes not trigger a dataserver event. This was because the notecard asset ID was being used as the request identifier. Now using a random ID, in common with other code using the DataServer --- .../Shared/Api/Implementation/LSL_Api.cs | 26 ++++++++++++---------- 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 6a31568..ec24dc2 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -10806,14 +10806,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return UUID.Zero.ToString(); } + string reqIdentifier = UUID.Random().ToString(); + // was: UUID tid = tid = AsyncCommands. - UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, assetID.ToString()); + UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, reqIdentifier); if (NotecardCache.IsCached(assetID)) { - AsyncCommands. - DataserverPlugin.DataserverReply(assetID.ToString(), - NotecardCache.GetLines(assetID).ToString()); + AsyncCommands.DataserverPlugin.DataserverReply(reqIdentifier, NotecardCache.GetLines(assetID).ToString()); + ScriptSleep(100); return tid.ToString(); } @@ -10829,9 +10830,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api string data = Encoding.UTF8.GetString(a.Data); //m_log.Debug(data); NotecardCache.Cache(id, data); - AsyncCommands. - DataserverPlugin.DataserverReply(id.ToString(), - NotecardCache.GetLines(id).ToString()); + AsyncCommands.DataserverPlugin.DataserverReply(reqIdentifier, NotecardCache.GetLines(id).ToString()); }); ScriptSleep(100); @@ -10860,13 +10859,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return UUID.Zero.ToString(); } + string reqIdentifier = UUID.Random().ToString(); + // was: UUID tid = tid = AsyncCommands. - UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, assetID.ToString()); + UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, reqIdentifier); if (NotecardCache.IsCached(assetID)) { - AsyncCommands.DataserverPlugin.DataserverReply(assetID.ToString(), - NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax)); + AsyncCommands.DataserverPlugin.DataserverReply( + reqIdentifier, NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax)); + ScriptSleep(100); return tid.ToString(); } @@ -10882,8 +10884,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api string data = Encoding.UTF8.GetString(a.Data); //m_log.Debug(data); NotecardCache.Cache(id, data); - AsyncCommands.DataserverPlugin.DataserverReply(id.ToString(), - NotecardCache.GetLine(id, line, m_notecardLineReadCharsMax)); + AsyncCommands.DataserverPlugin.DataserverReply( + reqIdentifier, NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax)); }); ScriptSleep(100); -- cgit v1.1 From 239a8da74e87bb22bb9107a0341829ff99bbd3fe Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Feb 2013 21:19:23 +0000 Subject: Fix potential concurrency issue since the LSL notecard cache was not being checked for expiry under lock --- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index ec24dc2..ab087af 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -11689,7 +11689,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public static void Cache(UUID assetID, string text) { - CacheCheck(); + CheckCache(); lock (m_Notecards) { @@ -11774,14 +11774,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return line; } - public static void CacheCheck() + public static void CheckCache() { - foreach (UUID key in new List(m_Notecards.Keys)) + lock (m_Notecards) { - Notecard nc = m_Notecards[key]; - if (nc.lastRef.AddSeconds(30) < DateTime.Now) - m_Notecards.Remove(key); + foreach (UUID key in new List(m_Notecards.Keys)) + { + Notecard nc = m_Notecards[key]; + if (nc.lastRef.AddSeconds(30) < DateTime.Now) + m_Notecards.Remove(key); + } } } } -} +} \ No newline at end of file -- cgit v1.1 From ea3e0ef8a362a103fd70f17cfc3ea76a20fac5ab Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 28 Feb 2013 14:20:07 -0800 Subject: Bug fix in DataSnapshot, where a var was being used before being initialized. --- OpenSim/Region/DataSnapshot/DataSnapshotManager.cs | 34 ++++++++++------------ 1 file changed, 15 insertions(+), 19 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs index 32017a8..dd48dd5 100644 --- a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs +++ b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs @@ -148,8 +148,6 @@ namespace OpenSim.Region.DataSnapshot return; } - if (m_enabled) - m_snapStore = new SnapshotStore(m_snapsDir, m_gridinfo, m_listener_port, m_hostname); } } @@ -163,8 +161,22 @@ namespace OpenSim.Region.DataSnapshot m_log.DebugFormat("[DATASNAPSHOT]: Module added to Scene {0}.", scene.RegionInfo.RegionName); - m_snapStore.AddScene(scene); + if (!m_servicesNotified) + { + m_hostname = scene.RegionInfo.ExternalHostName; + m_snapStore = new SnapshotStore(m_snapsDir, m_gridinfo, m_listener_port, m_hostname); + + //Hand it the first scene, assuming that all scenes have the same BaseHTTPServer + new DataRequestHandler(scene, this); + + if (m_dataServices != "" && m_dataServices != "noservices") + NotifyDataServices(m_dataServices, "online"); + + m_servicesNotified = true; + } + m_scenes.Add(scene); + m_snapStore.AddScene(scene); Assembly currentasm = Assembly.GetExecutingAssembly(); @@ -189,22 +201,6 @@ namespace OpenSim.Region.DataSnapshot } } - // Must be done here because on shared modules, PostInitialise() will run - // BEFORE any scenes are registered. There is no "all scenes have been loaded" - // kind of callback because scenes may be created dynamically, so we cannot - // have that info, ever. - if (!m_servicesNotified) - { - //Hand it the first scene, assuming that all scenes have the same BaseHTTPServer - new DataRequestHandler(m_scenes[0], this); - - m_hostname = m_scenes[0].RegionInfo.ExternalHostName; - - if (m_dataServices != "" && m_dataServices != "noservices") - NotifyDataServices(m_dataServices, "online"); - - m_servicesNotified = true; - } } public void RemoveRegion(Scene scene) -- cgit v1.1 From faf96f5c854a9f928797f170b07c32236a7559e3 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Feb 2013 23:59:26 +0000 Subject: minor: Log location in which simulator/robust was started. Useful information for system debugging, especially if logging and ini files locations have been changed from defaults. --- OpenSim/Region/Application/OpenSimBase.cs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index c555915..137bd81 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -134,6 +134,10 @@ namespace OpenSim /// public OpenSimBase(IConfigSource configSource) : base() { + // FIXME: This should be done down in ServerBase but we need to sort out and refactor the log4net + // XmlConfigurator calls first accross servers. + m_log.InfoFormat("[SERVER BASE]: Starting in {0}", m_startupDirectory); + LoadConfigSettings(configSource); } -- cgit v1.1 From 1c740798b45dddb3e056b2e281fe98de6bf35143 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 1 Mar 2013 08:52:06 -0800 Subject: BulletSim: add parameters, code cleanup around checking and enforcing maximum velocity and angular velocity values for prims. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 4 +- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 20 ++++++--- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 47 +++++++++++++++++++--- 3 files changed, 57 insertions(+), 14 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index e6933f9..235cefc 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -961,13 +961,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ================================================================== // Clamp high or low velocities float newVelocityLengthSq = VehicleVelocity.LengthSquared(); - if (newVelocityLengthSq > BSParam.VehicleMaxLinearVelocitySq) + if (newVelocityLengthSq > BSParam.VehicleMaxLinearVelocitySquared) { Vector3 origVelW = VehicleVelocity; // DEBUG DEBUG VehicleVelocity /= VehicleVelocity.Length(); VehicleVelocity *= BSParam.VehicleMaxLinearVelocity; VDetailLog("{0}, MoveLinear,clampMax,origVelW={1},lenSq={2},maxVelSq={3},,newVelW={4}", - Prim.LocalID, origVelW, newVelocityLengthSq, BSParam.VehicleMaxLinearVelocitySq, VehicleVelocity); + Prim.LocalID, origVelW, newVelocityLengthSq, BSParam.VehicleMaxLinearVelocitySquared, VehicleVelocity); } else if (newVelocityLengthSq < 0.001f) VehicleVelocity = Vector3.Zero; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index dc57b67..fa58109 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -47,12 +47,16 @@ public static class BSParam public static float SculptLOD { get; private set; } public static int CrossingFailuresBeforeOutOfBounds { get; private set; } + public static float UpdateVelocityChangeThreshold { get; private set; } public static float MinimumObjectMass { get; private set; } public static float MaximumObjectMass { get; private set; } public static float MaxLinearVelocity { get; private set; } + public static float MaxLinearVelocitySquared { get; private set; } public static float MaxAngularVelocity { get; private set; } + public static float MaxAngularVelocitySquared { get; private set; } public static float MaxAddForceMagnitude { get; private set; } + public static float MaxAddForceMagnitudeSquared { get; private set; } public static float DensityScaleFactor { get; private set; } public static float LinearDamping { get; private set; } @@ -109,7 +113,7 @@ public static class BSParam // Vehicle parameters public static float VehicleMaxLinearVelocity { get; private set; } - public static float VehicleMaxLinearVelocitySq { get; private set; } + public static float VehicleMaxLinearVelocitySquared { get; private set; } public static float VehicleMaxAngularVelocity { get; private set; } public static float VehicleMaxAngularVelocitySq { get; private set; } public static float VehicleAngularDamping { get; private set; } @@ -265,7 +269,7 @@ public static class BSParam // The single letter parameters for the delegates are: // s = BSScene // o = BSPhysObject - // v = value (float) + // v = value (appropriate type) private static ParameterDefnBase[] ParameterDefinitions = { new ParameterDefn("MeshSculptedPrim", "Whether to create meshes for sculpties", @@ -289,6 +293,10 @@ public static class BSParam 5, (s) => { return CrossingFailuresBeforeOutOfBounds; }, (s,v) => { CrossingFailuresBeforeOutOfBounds = v; } ), + new ParameterDefn("UpdateVelocityChangeThreshold", "Change in updated velocity required before reporting change to simulator", + 0.1f, + (s) => { return UpdateVelocityChangeThreshold; }, + (s,v) => { UpdateVelocityChangeThreshold = v; } ), new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", 32f, @@ -343,16 +351,16 @@ public static class BSParam new ParameterDefn("MaxLinearVelocity", "Maximum velocity magnitude that can be assigned to an object", 1000.0f, (s) => { return MaxLinearVelocity; }, - (s,v) => { MaxLinearVelocity = v; } ), + (s,v) => { MaxLinearVelocity = v; MaxLinearVelocitySquared = v * v; } ), new ParameterDefn("MaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to an object", 1000.0f, (s) => { return MaxAngularVelocity; }, - (s,v) => { MaxAngularVelocity = v; } ), + (s,v) => { MaxAngularVelocity = v; MaxAngularVelocitySquared = v * v; } ), // LL documentation says thie number should be 20f for llApplyImpulse and 200f for llRezObject new ParameterDefn("MaxAddForceMagnitude", "Maximum force that can be applied by llApplyImpulse (SL says 20f)", 20000.0f, (s) => { return MaxAddForceMagnitude; }, - (s,v) => { MaxAddForceMagnitude = v; } ), + (s,v) => { MaxAddForceMagnitude = v; MaxAddForceMagnitudeSquared = v * v; } ), // Density is passed around as 100kg/m3. This scales that to 1kg/m3. new ParameterDefn("DensityScaleFactor", "Conversion for simulator/viewer density (100kg/m3) to physical density (1kg/m3)", 0.01f, @@ -505,7 +513,7 @@ public static class BSParam new ParameterDefn("VehicleMaxLinearVelocity", "Maximum velocity magnitude that can be assigned to a vehicle", 1000.0f, (s) => { return (float)VehicleMaxLinearVelocity; }, - (s,v) => { VehicleMaxLinearVelocity = v; VehicleMaxLinearVelocitySq = v * v; } ), + (s,v) => { VehicleMaxLinearVelocity = v; VehicleMaxLinearVelocitySquared = v * v; } ), new ParameterDefn("VehicleMaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to a vehicle", 12.0f, (s) => { return (float)VehicleMaxAngularVelocity; }, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 8f660c4..a465613 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -108,6 +108,9 @@ public class BSPrim : BSPhysObject // do the actual object creation at taint time PhysicsScene.TaintedObject("BSPrim.create", delegate() { + // Make sure the object is being created with some sanity. + ExtremeSanityCheck(true /* inTaintTime */); + CreateGeomAndObject(true); CurrentCollisionFlags = PhysicsScene.PE.GetCollisionFlags(PhysBody); @@ -450,6 +453,38 @@ public class BSPrim : BSPhysObject return ret; } + // Occasionally things will fly off and really get lost. + // Find the wanderers and bring them back. + // Return 'true' if some parameter need some sanity. + private bool ExtremeSanityCheck(bool inTaintTime) + { + bool ret = false; + + uint wayOutThere = Constants.RegionSize * Constants.RegionSize; + // There have been instances of objects getting thrown way out of bounds and crashing + // the border crossing code. + if ( _position.X < -Constants.RegionSize || _position.X > wayOutThere + || _position.Y < -Constants.RegionSize || _position.Y > wayOutThere + || _position.Z < -Constants.RegionSize || _position.Z > wayOutThere) + { + _position = new OMV.Vector3(10, 10, 50); + ZeroMotion(inTaintTime); + ret = true; + } + if (_velocity.LengthSquared() > BSParam.MaxLinearVelocity) + { + _velocity = Util.ClampV(_velocity, BSParam.MaxLinearVelocity); + ret = true; + } + if (_rotationalVelocity.LengthSquared() > BSParam.MaxAngularVelocitySquared) + { + _rotationalVelocity = Util.ClampV(_rotationalVelocity, BSParam.MaxAngularVelocity); + ret = true; + } + + return ret; + } + // Return the effective mass of the object. // The definition of this call is to return the mass of the prim. // If the simulator cares about the mass of the linkset, it will sum it itself. @@ -585,12 +620,12 @@ public class BSPrim : BSPhysObject if (VehicleController.Type == Vehicle.TYPE_NONE) { UnRegisterPreStepAction("BSPrim.Vehicle", LocalID); - PhysicsScene.AfterStep -= VehicleController.PostStep; + UnRegisterPostStepAction("BSPrim.Vehicle", LocalID); } else { RegisterPreStepAction("BSPrim.Vehicle", LocalID, VehicleController.Step); - PhysicsScene.AfterStep += VehicleController.PostStep; + RegisterPostStepAction("BSPrim.Vehicle", LocalID, VehicleController.PostStep); } }); } @@ -732,7 +767,7 @@ public class BSPrim : BSPhysObject set { PhysicsScene.AssertInTaintTime("BSPrim.ForceVelocity"); - _velocity = value; + _velocity = Util.ClampV(value, BSParam.MaxLinearVelocity); if (PhysBody.HasPhysicalBody) { DetailLog("{0},BSPrim.ForceVelocity,taint,vel={1}", LocalID, _velocity); @@ -1098,7 +1133,7 @@ public class BSPrim : BSPhysObject return _rotationalVelocity; } set { - _rotationalVelocity = value; + _rotationalVelocity = Util.ClampV(value, BSParam.MaxAngularVelocity); if (PhysBody.HasPhysicalBody) { DetailLog("{0},BSPrim.ForceRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); @@ -1230,6 +1265,7 @@ public class BSPrim : BSPhysObject RegisterPreStepAction("BSPrim.Hover", LocalID, delegate(float timeStep) { + // Don't do hovering while the object is selected. if (!IsPhysicallyActive) return; @@ -1737,10 +1773,9 @@ public class BSPrim : BSPhysObject // Assign directly to the local variables so the normal set actions do not happen _position = entprop.Position; _orientation = entprop.Rotation; - // _velocity = entprop.Velocity; // DEBUG DEBUG DEBUG -- smooth velocity changes a bit. The simulator seems to be // very sensitive to velocity changes. - if (entprop.Velocity == OMV.Vector3.Zero || !entprop.Velocity.ApproxEquals(_velocity, 0.1f)) + if (entprop.Velocity == OMV.Vector3.Zero || !entprop.Velocity.ApproxEquals(_velocity, BSParam.UpdateVelocityChangeThreshold)) _velocity = entprop.Velocity; _acceleration = entprop.Acceleration; _rotationalVelocity = entprop.RotationalVelocity; -- cgit v1.1 From 326634a0b38fc21fd52a7bfb0c89a0d4c13f0dae Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 1 Mar 2013 09:43:40 -0800 Subject: BulletSim: more things into the TODO list. --- OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 4dc16f4..8a15abe 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -9,6 +9,9 @@ Enable vehicle border crossings (at least as poorly as ODE) Lock axis Deleting a linkset while standing on the root will leave the physical shape of the root behind. Not sure if it is because standing on it. Done with large prim linksets. +Linkset child rotations. + Nebadon spiral tube has middle sections which are rotated wrong. + Select linked spiral tube. Delink and note where the middle section ends up. Vehicle angular vertical attraction vehicle angular banking Center-of-gravity @@ -68,6 +71,8 @@ Vehicle attributes are not restored when a vehicle is rezzed on region creation GENERAL TODO LIST: ================================================= +Explore btGImpactMeshShape as alternative to convex hulls for simplified physical objects. + Regular triangle meshes don't do physical collisions. Resitution of a prim works on another prim but not on terrain. The dropped prim doesn't bounce properly on the terrain. Add a sanity check for PIDTarget location. @@ -338,4 +343,4 @@ Avatar standing on a moving object should start to move with the object. (DONE 2 Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE. Verify that angular motion specified around Z moves in the vehicle coordinates. DONE 20130120: BulletSim properly applies force in vehicle relative coordinates. -Nebadon vehicles turning funny in arena (DONE) \ No newline at end of file +Nebadon vehicles turning funny in arena (DONE) -- cgit v1.1 From c851ebcd8c65d1cf371379bf75d98f544b54ac7a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 1 Mar 2013 21:47:17 +0000 Subject: Add the Mono AddinDependency attribute to the example region modules. It turns out this is required to get Mono.Addins to pick up plugin DLLs --- .../Example/BareBonesNonShared/BareBonesNonSharedModule.cs | 3 ++- .../OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs b/OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs index ad2fc7a..0615036 100644 --- a/OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs +++ b/OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs @@ -33,10 +33,11 @@ using Nini.Config; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -// You will need to uncomment this line if you are adding a region module to some other assembly which does not already +// You will need to uncomment these lines if you are adding a region module to some other assembly which does not already // specify its assembly. Otherwise, the region modules in the assembly will not be picked up when OpenSimulator scans // the available DLLs //[assembly: Addin("MyModule", "1.0")] +//[assembly: AddinDependency("OpenSim", "0.5")] namespace OpenSim.Region.OptionalModules.Example.BareBonesNonShared { diff --git a/OpenSim/Region/OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs b/OpenSim/Region/OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs index bb9cbb7..811a263 100644 --- a/OpenSim/Region/OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs +++ b/OpenSim/Region/OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs @@ -33,10 +33,11 @@ using Nini.Config; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -// You will need to uncomment this line if you are adding a region module to some other assembly which does not already +// You will need to uncomment these lines if you are adding a region module to some other assembly which does not already // specify its assembly. Otherwise, the region modules in the assembly will not be picked up when OpenSimulator scans // the available DLLs //[assembly: Addin("MyModule", "1.0")] +//[assembly: AddinDependency("OpenSim", "0.5")] namespace OpenSim.Region.OptionalModules.Example.BareBonesShared { -- cgit v1.1 From 20530ee66723faa78ab8cf93c096fa4626c3c701 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 1 Mar 2013 15:24:22 -0800 Subject: Moved permissions config vars out of [Startup] into [Permissions]. Backwards compatible ([Startup] still being looked up), but please update your configs sometime soon. --- .../World/Permissions/PermissionsModule.cs | 54 +++++++++++++--------- .../PrimLimitsModule/PrimLimitsModule.cs | 5 +- 2 files changed, 36 insertions(+), 23 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index ddaa227..121fb2a 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -156,9 +156,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions public void Initialise(IConfigSource config) { - IConfig myConfig = config.Configs["Startup"]; - - string permissionModules = myConfig.GetString("permissionmodules", "DefaultPermissionsModule"); + string permissionModules = Util.GetConfigVarFromSections(config, "permissionmodules", + new string[] { "Startup", "Permissions" }, "DefaultPermissionsModule"); List modules = new List(permissionModules.Split(',')); @@ -167,26 +166,34 @@ namespace OpenSim.Region.CoreModules.World.Permissions m_Enabled = true; - m_allowGridGods = myConfig.GetBoolean("allow_grid_gods", false); - m_bypassPermissions = !myConfig.GetBoolean("serverside_object_permissions", true); - m_propagatePermissions = myConfig.GetBoolean("propagate_permissions", true); - m_RegionOwnerIsGod = myConfig.GetBoolean("region_owner_is_god", true); - m_RegionManagerIsGod = myConfig.GetBoolean("region_manager_is_god", false); - m_ParcelOwnerIsGod = myConfig.GetBoolean("parcel_owner_is_god", true); - - m_SimpleBuildPermissions = myConfig.GetBoolean("simple_build_permissions", false); + m_allowGridGods = Util.GetConfigVarFromSections(config, "allow_grid_gods", + new string[] { "Startup", "Permissions" }, false); + m_bypassPermissions = !Util.GetConfigVarFromSections(config, "serverside_object_permissions", + new string[] { "Startup", "Permissions" }, true); + m_propagatePermissions = Util.GetConfigVarFromSections(config, "propagate_permissions", + new string[] { "Startup", "Permissions" }, true); + m_RegionOwnerIsGod = Util.GetConfigVarFromSections(config, "region_owner_is_god", + new string[] { "Startup", "Permissions" }, true); + m_RegionManagerIsGod = Util.GetConfigVarFromSections(config, "region_manager_is_god", + new string[] { "Startup", "Permissions" }, false); + m_ParcelOwnerIsGod = Util.GetConfigVarFromSections(config, "parcel_owner_is_god", + new string[] { "Startup", "Permissions" }, true); + + m_SimpleBuildPermissions = Util.GetConfigVarFromSections(config, "simple_build_permissions", + new string[] { "Startup", "Permissions" }, false); m_allowedScriptCreators - = ParseUserSetConfigSetting(myConfig, "allowed_script_creators", m_allowedScriptCreators); + = ParseUserSetConfigSetting(config, "allowed_script_creators", m_allowedScriptCreators); m_allowedScriptEditors - = ParseUserSetConfigSetting(myConfig, "allowed_script_editors", m_allowedScriptEditors); + = ParseUserSetConfigSetting(config, "allowed_script_editors", m_allowedScriptEditors); if (m_bypassPermissions) m_log.Info("[PERMISSIONS]: serverside_object_permissions = false in ini file so disabling all region service permission checks"); else m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks"); - string grant = myConfig.GetString("GrantLSL", ""); + string grant = Util.GetConfigVarFromSections(config, "GrantLSL", + new string[] { "Startup", "Permissions" }, string.Empty); if (grant.Length > 0) { foreach (string uuidl in grant.Split(',')) @@ -196,7 +203,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions } } - grant = myConfig.GetString("GrantCS", ""); + grant = Util.GetConfigVarFromSections(config, "GrantCS", + new string[] { "Startup", "Permissions" }, string.Empty); if (grant.Length > 0) { foreach (string uuidl in grant.Split(',')) @@ -206,7 +214,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions } } - grant = myConfig.GetString("GrantVB", ""); + grant = Util.GetConfigVarFromSections(config, "GrantVB", + new string[] { "Startup", "Permissions" }, string.Empty); if (grant.Length > 0) { foreach (string uuidl in grant.Split(',')) @@ -216,7 +225,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions } } - grant = myConfig.GetString("GrantJS", ""); + grant = Util.GetConfigVarFromSections(config, "GrantJS", + new string[] { "Startup", "Permissions" }, string.Empty); if (grant.Length > 0) { foreach (string uuidl in grant.Split(',')) @@ -226,7 +236,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions } } - grant = myConfig.GetString("GrantYP", ""); + grant = Util.GetConfigVarFromSections(config, "GrantYP", + new string[] { "Startup", "Permissions" }, string.Empty); if (grant.Length > 0) { foreach (string uuidl in grant.Split(',')) @@ -464,11 +475,12 @@ namespace OpenSim.Region.CoreModules.World.Permissions /// /// The default value for this attribute /// The parsed value - private static UserSet ParseUserSetConfigSetting(IConfig config, string settingName, UserSet defaultValue) + private static UserSet ParseUserSetConfigSetting(IConfigSource config, string settingName, UserSet defaultValue) { UserSet userSet = defaultValue; - - string rawSetting = config.GetString(settingName, defaultValue.ToString()); + + string rawSetting = Util.GetConfigVarFromSections(config, settingName, + new string[] {"Startup", "Permissions"}, defaultValue.ToString()); // Temporary measure to allow 'gods' to be specified in config for consistency's sake. In the long term // this should disappear. diff --git a/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs b/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs index c1957e2..a6d43f1 100644 --- a/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs +++ b/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs @@ -57,9 +57,10 @@ namespace OpenSim.Region.OptionalModules public void Initialise(IConfigSource config) { - IConfig myConfig = config.Configs["Startup"]; + //IConfig myConfig = config.Configs["Startup"]; - string permissionModules = myConfig.GetString("permissionmodules", "DefaultPermissionsModule"); + string permissionModules = Util.GetConfigVarFromSections(config, "permissionmodules", + new string[] { "Startup", "Permissions" }, "DefaultPermissionsModule"); List modules=new List(permissionModules.Split(',')); -- cgit v1.1 From 1a98ce5f6480c65ae30db933941f1a0184b5bc84 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 2 Mar 2013 01:06:08 +0000 Subject: minor: Quieten down the parts of the WebSocketEcho module logging for now where it tells us it is added/loaded/removed from regions --- .../Example/WebSocketEchoTest/WebSocketEchoModule.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Example/WebSocketEchoTest/WebSocketEchoModule.cs b/OpenSim/Region/OptionalModules/Example/WebSocketEchoTest/WebSocketEchoModule.cs index 112ba4e..5bf0ed4 100644 --- a/OpenSim/Region/OptionalModules/Example/WebSocketEchoTest/WebSocketEchoModule.cs +++ b/OpenSim/Region/OptionalModules/Example/WebSocketEchoTest/WebSocketEchoModule.cs @@ -45,6 +45,7 @@ namespace OpenSim.Region.OptionalModules.WebSocketEchoModule public class WebSocketEchoModule : ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private bool enabled; public string Name { get { return "WebSocketEchoModule"; } } @@ -55,9 +56,9 @@ namespace OpenSim.Region.OptionalModules.WebSocketEchoModule public void Initialise(IConfigSource pConfig) { - enabled =(pConfig.Configs["WebSocketEcho"] != null); - if (enabled) - m_log.DebugFormat("[WebSocketEchoModule]: INITIALIZED MODULE"); + enabled = (pConfig.Configs["WebSocketEcho"] != null); +// if (enabled) +// m_log.DebugFormat("[WebSocketEchoModule]: INITIALIZED MODULE"); } /// @@ -158,17 +159,17 @@ namespace OpenSim.Region.OptionalModules.WebSocketEchoModule public void AddRegion(Scene scene) { - m_log.DebugFormat("[WebSocketEchoModule]: REGION {0} ADDED", scene.RegionInfo.RegionName); +// m_log.DebugFormat("[WebSocketEchoModule]: REGION {0} ADDED", scene.RegionInfo.RegionName); } public void RemoveRegion(Scene scene) { - m_log.DebugFormat("[WebSocketEchoModule]: REGION {0} REMOVED", scene.RegionInfo.RegionName); +// m_log.DebugFormat("[WebSocketEchoModule]: REGION {0} REMOVED", scene.RegionInfo.RegionName); } public void RegionLoaded(Scene scene) { - m_log.DebugFormat("[WebSocketEchoModule]: REGION {0} LOADED", scene.RegionInfo.RegionName); +// m_log.DebugFormat("[WebSocketEchoModule]: REGION {0} LOADED", scene.RegionInfo.RegionName); } } } \ No newline at end of file -- cgit v1.1 From 1bc8692a999f4e80b90b9a1eb7c7428b2e74214e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 2 Mar 2013 01:43:54 +0000 Subject: Move AllowedClients and BannedClients section to new [AccessControl] section in OpenSim.ini from [Startup] This change also corrects the setting names - they were actually wrong (though the text in {} was correct). If there are settings in [Startup] they will continue to be used and anything there will override settings in [AccessControl] --- OpenSim/Region/Framework/Scenes/Scene.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 5b61538..14dac7a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -932,7 +932,12 @@ namespace OpenSim.Region.Framework.Scenes } } - string grant = startupConfig.GetString("AllowedClients", String.Empty); + string[] possibleAccessControlConfigSections = new string[] { "AccessControl", "Startup" }; + + string grant + = Util.GetConfigVarFromSections( + config, "AllowedClients", possibleAccessControlConfigSections, ""); + if (grant.Length > 0) { foreach (string viewer in grant.Split('|')) @@ -941,7 +946,10 @@ namespace OpenSim.Region.Framework.Scenes } } - grant = startupConfig.GetString("BannedClients", String.Empty); + grant + = Util.GetConfigVarFromSections( + config, "BannedClients", possibleAccessControlConfigSections, ""); + if (grant.Length > 0) { foreach (string viewer in grant.Split('|')) -- cgit v1.1 From b0985f7019d7fc9ea6bb32c4f1d174e6f635c9e3 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 2 Mar 2013 17:53:57 -0800 Subject: Fixed typos in TempAttachmentsModule. No changes. --- .../Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs index d7fb272..1e7bc02 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs @@ -76,7 +76,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments if (m_console != null) { - m_console.AddCommand("TempATtachModule", false, "set auto_grant_attach_perms", "set auto_grant_attach_perms true|false", "Allow objects owned by the region owner os estate managers to obtain attach permissions without asking the user", SetAutoGrantAttachPerms); + m_console.AddCommand("TempAttachModule", false, "set auto_grant_attach_perms", "set auto_grant_attach_perms true|false", "Allow objects owned by the region owner or estate managers to obtain attach permissions without asking the user", SetAutoGrantAttachPerms); } } else -- cgit v1.1 From fa9f4ef1baca14ed4ee20712219932f1e6e09990 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 4 Mar 2013 23:20:00 +0000 Subject: Fix issue in the mesh upload flag module where the ID of the last agent to request the capability was always used instead of the original requesting agent for each cap. Should address http://opensimulator.org/mantis/view.php?id=6556 --- .../Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs index 33b1f77..45d33cd 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs @@ -57,7 +57,6 @@ namespace OpenSim.Region.ClientStack.Linden public bool Enabled { get; private set; } private Scene m_scene; - private UUID m_agentID; #region ISharedRegionModule Members @@ -118,25 +117,26 @@ namespace OpenSim.Region.ClientStack.Linden public void RegisterCaps(UUID agentID, Caps caps) { IRequestHandler reqHandler - = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), MeshUploadFlag, "MeshUploadFlag", agentID.ToString()); + = new RestHTTPHandler( + "GET", "/CAPS/" + UUID.Random(), ht => MeshUploadFlag(ht, agentID), "MeshUploadFlag", agentID.ToString()); caps.RegisterHandler("MeshUploadFlag", reqHandler); - m_agentID = agentID; + } - private Hashtable MeshUploadFlag(Hashtable mDhttpMethod) + private Hashtable MeshUploadFlag(Hashtable mDhttpMethod, UUID agentID) { // m_log.DebugFormat("[MESH UPLOAD FLAG MODULE]: MeshUploadFlag request"); OSDMap data = new OSDMap(); - ScenePresence sp = m_scene.GetScenePresence(m_agentID); + ScenePresence sp = m_scene.GetScenePresence(agentID); data["username"] = sp.Firstname + "." + sp.Lastname; data["display_name_next_update"] = new OSDDate(DateTime.Now); data["legacy_first_name"] = sp.Firstname; data["mesh_upload_status"] = "valid"; data["display_name"] = sp.Firstname + " " + sp.Lastname; data["legacy_last_name"] = sp.Lastname; - data["id"] = m_agentID; + data["id"] = agentID; data["is_display_name_default"] = true; //Send back data -- cgit v1.1 From 7556b42d7a208e3e7dfc23550293bad243533328 Mon Sep 17 00:00:00 2001 From: teravus Date: Mon, 4 Mar 2013 21:26:26 -0500 Subject: * Update LibOMV to f8f8e616b37a7ea22b7922b2331999bc06725bf9 * Add zero length blocks to the new packet blocks to remain compatible with older viewers and avoid a NullRef when _packets_.cs calls the Length parameter.. which adds up the Length property all of the blocks. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 5675870..6742d99 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -790,7 +790,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP handshake.RegionInfo3.ColoName = Utils.EmptyBytes; handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType); handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes; - + handshake.RegionInfo4 = new RegionHandshakePacket.RegionInfo4Block[0]; + OutPacket(handshake, ThrottleOutPacketType.Task); } @@ -3571,6 +3572,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP avp.Sender.IsTrial = false; avp.Sender.ID = agentID; + avp.AppearanceData = new AvatarAppearancePacket.AppearanceDataBlock[0]; //m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString()); OutPacket(avp, ThrottleOutPacketType.Task); } @@ -4192,7 +4194,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP pack.Stat = stats.StatsBlock; pack.Header.Reliable = false; - + pack.RegionInfo = new SimStatsPacket.RegionInfoBlock[0]; OutPacket(pack, ThrottleOutPacketType.Task); } -- cgit v1.1 From ccd6f443e1092cb410f565e921f7cf4dd8cd2dac Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 5 Mar 2013 23:47:36 +0000 Subject: Get attachment script state before taking sp.AttachmentsSyncLock() to avoid race conditions between closing agents and scripts that may be doing attachment manipulation. This is in an effort to resolve http://opensimulator.org/mantis/view.php?id=6557 --- .../Avatar/Attachments/AttachmentsModule.cs | 301 +++++++++++---------- 1 file changed, 161 insertions(+), 140 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 8a3eeaa..3ccf9f4 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -241,12 +241,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); + List attachments = sp.GetAttachments(); + + if (attachments.Count <= 0) + return; + + Dictionary scriptStates = new Dictionary(); + + foreach (SceneObjectGroup so in attachments) + { + // Scripts MUST be snapshotted before the object is + // removed from the scene because doing otherwise will + // clobber the run flag + // This must be done outside the sp.AttachmentSyncLock so that there is no risk of a deadlock from + // scripts performing attachment operations at the same time. Getting object states stops the scripts. + scriptStates[so] = PrepareScriptInstanceForSave(so, false); + } + lock (sp.AttachmentsSyncLock) { - foreach (SceneObjectGroup so in sp.GetAttachments()) - { - UpdateDetachedObject(sp, so); - } + foreach (SceneObjectGroup so in attachments) + UpdateDetachedObject(sp, so, scriptStates[so]); sp.ClearAttachments(); } @@ -285,32 +300,40 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp) { - lock (sp.AttachmentsSyncLock) - { // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", // group.Name, group.LocalId, sp.Name, attachmentPt, silent); - if (group.GetSittingAvatarsCount() != 0) - { + if (group.GetSittingAvatarsCount() != 0) + { // m_log.WarnFormat( // "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since {4} avatars are still sitting on it", // group.Name, group.LocalId, sp.Name, attachmentPt, group.GetSittingAvatarsCount()); - - return false; - } - - if (sp.GetAttachments(attachmentPt).Contains(group)) - { - // m_log.WarnFormat( - // "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", - // group.Name, group.LocalId, sp.Name, AttachmentPt); - - return false; - } - + + return false; + } + + if (sp.GetAttachments(attachmentPt).Contains(group)) + { +// m_log.WarnFormat( +// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", +// group.Name, group.LocalId, sp.Name, AttachmentPt); + + return false; + } + + // Remove any previous attachments + List existingAttachments = sp.GetAttachments(attachmentPt); + string existingAttachmentScriptState = null; + + // At the moment we can only deal with a single attachment + if (existingAttachments.Count != 0 && existingAttachments[0].FromItemID != UUID.Zero) + DetachSingleAttachmentToInv(sp, group); + + lock (sp.AttachmentsSyncLock) + { Vector3 attachPos = group.AbsolutePosition; - + // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should // be removed when that functionality is implemented in opensim attachmentPt &= 0x7f; @@ -322,14 +345,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { attachPos = Vector3.Zero; } - + // AttachmentPt 0 means the client chose to 'wear' the attachment. if (attachmentPt == 0) { // Check object for stored attachment point attachmentPt = group.AttachmentPoint; } - + // if we still didn't find a suitable attachment point....... if (attachmentPt == 0) { @@ -337,13 +360,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments attachmentPt = (uint)AttachmentPoint.LeftHand; attachPos = Vector3.Zero; } - + group.AttachmentPoint = attachmentPt; group.AbsolutePosition = attachPos; if (sp.PresenceType != PresenceType.Npc) UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp); - + AttachToAgent(sp, group, attachmentPt, attachPos, silent); } @@ -352,21 +375,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp) { - // Remove any previous attachments - List attachments = sp.GetAttachments(attachmentPt); - - // At the moment we can only deal with a single attachment - if (attachments.Count != 0) - { - if (attachments[0].FromItemID != UUID.Zero) - DetachSingleAttachmentToInvInternal(sp, attachments[0]); - // Error logging commented because UUID.Zero now means temp attachment -// else -// m_log.WarnFormat( -// "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!", -// attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name); - } - // Add the new attachment to inventory if we don't already have it. if (!temp) { @@ -426,12 +434,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return; // m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name); - lock (sp.AttachmentsSyncLock) + + foreach (KeyValuePair rez in rezlist) { - foreach (KeyValuePair rez in rezlist) - { - RezSingleAttachmentFromInventory(sp, rez.Key, rez.Value); - } + RezSingleAttachmentFromInventory(sp, rez.Key, rez.Value); } } @@ -511,25 +517,33 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments public void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup so) { + if (so.AttachedAvatar != sp.UUID) + { + m_log.WarnFormat( + "[ATTACHMENTS MODULE]: Tried to detach object {0} from {1} {2} but attached avatar id was {3} in {4}", + so.Name, sp.Name, sp.UUID, so.AttachedAvatar, m_scene.RegionInfo.RegionName); + + return; + } + + // Scripts MUST be snapshotted before the object is + // removed from the scene because doing otherwise will + // clobber the run flag + // This must be done outside the sp.AttachmentSyncLock so that there is no risk of a deadlock from + // scripts performing attachment operations at the same time. Getting object states stops the scripts. + string scriptedState = PrepareScriptInstanceForSave(so, true); + lock (sp.AttachmentsSyncLock) { // Save avatar attachment information // m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID); - if (so.AttachedAvatar != sp.UUID) - { - m_log.WarnFormat( - "[ATTACHMENTS MODULE]: Tried to detach object {0} from {1} {2} but attached avatar id was {3} in {4}", - so.Name, sp.Name, sp.UUID, so.AttachedAvatar, m_scene.RegionInfo.RegionName); - - return; - } - bool changed = sp.Appearance.DetachAttachment(so.FromItemID); if (changed && m_scene.AvatarFactory != null) m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); - DetachSingleAttachmentToInvInternal(sp, so); + sp.RemoveAttachment(so); + UpdateDetachedObject(sp, so, scriptedState); } } @@ -739,8 +753,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return newItem; } - private string GetObjectScriptStates(SceneObjectGroup grp) + /// + /// Prepares the script instance for save. + /// + /// + /// This involves triggering the detach event and getting the script state (which also stops the script) + /// This MUST be done outside sp.AttachmentsSyncLock, since otherwise there is a chance of deadlock if a + /// running script is performing attachment operations. + /// + /// + /// The script state ready for persistence. + /// + /// + /// + /// + /// If true, then fire the script event before we save its state. + /// + private string PrepareScriptInstanceForSave(SceneObjectGroup grp, bool fireDetachEvent) { + if (fireDetachEvent) + m_scene.EventManager.TriggerOnAttach(grp.LocalId, grp.FromItemID, UUID.Zero); + using (StringWriter sw = new StringWriter()) { using (XmlTextWriter writer = new XmlTextWriter(sw)) @@ -752,7 +785,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } } - private void UpdateDetachedObject(IScenePresence sp, SceneObjectGroup so) + private void UpdateDetachedObject(IScenePresence sp, SceneObjectGroup so, string scriptedState) { // Don't save attachments for HG visitors, it // messes up their inventory. When a HG visitor logs @@ -765,11 +798,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments && (m_scene.UserManagementModule == null || m_scene.UserManagementModule.IsLocalGridUser(sp.UUID)); - // Scripts MUST be snapshotted before the object is - // removed from the scene because doing otherwise will - // clobber the run flag - string scriptedState = GetObjectScriptStates(so); - // Remove the object from the scene so no more updates // are sent. Doing this before the below changes will ensure // updates can't cause "HUD artefacts" @@ -793,91 +821,87 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments so.RemoveScriptInstances(true); } - private void DetachSingleAttachmentToInvInternal(IScenePresence sp, SceneObjectGroup so) - { - // m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name); - - m_scene.EventManager.TriggerOnAttach(so.LocalId, so.FromItemID, UUID.Zero); - sp.RemoveAttachment(so); - - UpdateDetachedObject(sp, so); - } - private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt) { if (m_invAccessModule == null) return null; - lock (sp.AttachmentsSyncLock) + SceneObjectGroup objatt; + + if (itemID != UUID.Zero) + objatt = m_invAccessModule.RezObject(sp.ControllingClient, + itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, + false, false, sp.UUID, true); + else + objatt = m_invAccessModule.RezObject(sp.ControllingClient, + null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, + false, false, sp.UUID, true); + + if (objatt == null) { - SceneObjectGroup objatt; + m_log.WarnFormat( + "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", + itemID, sp.Name, attachmentPt); - if (itemID != UUID.Zero) - objatt = m_invAccessModule.RezObject(sp.ControllingClient, - itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, - false, false, sp.UUID, true); - else - objatt = m_invAccessModule.RezObject(sp.ControllingClient, - null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, - false, false, sp.UUID, true); + return null; + } - if (objatt != null) - { + // Remove any previous attachments + List attachments = sp.GetAttachments(attachmentPt); + string previousAttachmentScriptedState = null; + + // At the moment we can only deal with a single attachment + if (attachments.Count != 0) + DetachSingleAttachmentToInv(sp, attachments[0]); + + lock (sp.AttachmentsSyncLock) + { // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}", // objatt.Name, sp.Name, attachmentPt, m_scene.Name); - // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. - objatt.HasGroupChanged = false; - bool tainted = false; - if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) - tainted = true; - - // FIXME: Detect whether it's really likely for AttachObject to throw an exception in the normal - // course of events. If not, then it's probably not worth trying to recover the situation - // since this is more likely to trigger further exceptions and confuse later debugging. If - // exceptions can be thrown in expected error conditions (not NREs) then make this consistent - // since other normal error conditions will simply return false instead. - // This will throw if the attachment fails - try - { - AttachObjectInternal(sp, objatt, attachmentPt, false, false); - } - catch (Exception e) - { - m_log.ErrorFormat( - "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}", - objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); - - // Make sure the object doesn't stick around and bail - sp.RemoveAttachment(objatt); - m_scene.DeleteSceneObject(objatt, false); - return null; - } + // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. + objatt.HasGroupChanged = false; + bool tainted = false; + if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) + tainted = true; + + // FIXME: Detect whether it's really likely for AttachObject to throw an exception in the normal + // course of events. If not, then it's probably not worth trying to recover the situation + // since this is more likely to trigger further exceptions and confuse later debugging. If + // exceptions can be thrown in expected error conditions (not NREs) then make this consistent + // since other normal error conditions will simply return false instead. + // This will throw if the attachment fails + try + { + AttachObjectInternal(sp, objatt, attachmentPt, false, false); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}", + objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); - if (tainted) - objatt.HasGroupChanged = true; + // Make sure the object doesn't stick around and bail + sp.RemoveAttachment(objatt); + m_scene.DeleteSceneObject(objatt, false); + return null; + } - // Fire after attach, so we don't get messy perms dialogs - // 4 == AttachedRez - objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); - objatt.ResumeScripts(); + if (tainted) + objatt.HasGroupChanged = true; - // Do this last so that event listeners have access to all the effects of the attachment - m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID); + // Fire after attach, so we don't get messy perms dialogs + // 4 == AttachedRez + objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); + objatt.ResumeScripts(); - return objatt; - } - else - { - m_log.WarnFormat( - "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", - itemID, sp.Name, attachmentPt); - } - } + // Do this last so that event listeners have access to all the effects of the attachment + m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID); - return null; + return objatt; + } } /// @@ -1027,17 +1051,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); if (sp != null) { - lock (sp.AttachmentsSyncLock) + List attachments = sp.GetAttachments(); + + foreach (SceneObjectGroup group in attachments) { - List attachments = sp.GetAttachments(); - - foreach (SceneObjectGroup group in attachments) + if (group.FromItemID == itemID && group.FromItemID != UUID.Zero) { - if (group.FromItemID == itemID && group.FromItemID != UUID.Zero) - { - DetachSingleAttachmentToInv(sp, group); - return; - } + DetachSingleAttachmentToInv(sp, group); + return; } } } @@ -1055,4 +1076,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments #endregion } -} +} \ No newline at end of file -- cgit v1.1 From b272b91317b1fd6c01aee57a0086a26dc233b03e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 5 Mar 2013 23:59:39 +0000 Subject: minor: Fix mono compiler warning in MonitorModule --- OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs | 2 -- 1 file changed, 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs index 4c9ee06..64feec1 100644 --- a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs @@ -414,8 +414,6 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring } private void RegisterStatsManagerRegionStatistics() { - string regionName = m_scene.RegionInfo.RegionName; - MakeStat("RootAgents", "avatars", (s) => { s.Value = m_scene.SceneGraph.GetRootAgentCount(); }); MakeStat("ChildAgents", "avatars", (s) => { s.Value = m_scene.SceneGraph.GetChildAgentCount(); }); MakeStat("TotalPrims", "objects", (s) => { s.Value = m_scene.SceneGraph.GetTotalObjectsCount(); }); -- cgit v1.1 From a9f380d1241b765d5bf278b5dcf6ab91f0015e85 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 6 Mar 2013 00:22:58 +0000 Subject: Fix bug in osGetPrimitiveParams() so that it works for prims with the same owner as the script and not ones with different owners. Addresses http://opensimulator.org/mantis/view.php?id=6560 --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index ab087af..dd7ee24 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -10920,7 +10920,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api LSL_List result = new LSL_List(); - if (obj != null && obj.OwnerID != m_host.OwnerID) + if (obj != null && obj.OwnerID == m_host.OwnerID) { LSL_List remaining = GetPrimParams(obj, rules, ref result); -- cgit v1.1 From 30e06b0742512caf08d1ab67505f9ab381dae9f5 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Tue, 5 Mar 2013 20:32:06 -0800 Subject: Convert doubles passed back through the MOD interface into LSL_Floats --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs index d0922aa..21bae27 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs @@ -266,6 +266,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { llist[i] = new LSL_Float((float)result[i]); } + else if (result[i] is double) + { + llist[i] = new LSL_Float((double)result[i]); + } else if (result[i] is UUID) { llist[i] = new LSL_Key(result[i].ToString()); -- cgit v1.1 From 9875e840f7e71f0b253c0b2aa90d47edc9c77b64 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Tue, 5 Mar 2013 20:33:17 -0800 Subject: Per discussions with justincc... split the JsonStore type functions into one for node type and one for value type. Define and export constants for both nodes and values. --- .../Framework/Interfaces/IJsonStoreModule.cs | 14 +++++- .../Scripting/JsonStore/JsonStore.cs | 39 ++++++++++++++++- .../Scripting/JsonStore/JsonStoreModule.cs | 36 +++++++++++++++- .../Scripting/JsonStore/JsonStoreScriptModule.cs | 39 ++++++++++++++--- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 50 +++++++++++----------- 5 files changed, 143 insertions(+), 35 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs index 345f01b..b67312e 100644 --- a/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs @@ -41,6 +41,16 @@ namespace OpenSim.Region.Framework.Interfaces Value = 3 } + public enum JsonStoreValueType + { + Undefined = 0, + Boolean = 1, + Integer = 2, + Float = 3, + String = 4, + UUID = 5 + } + public delegate void TakeValueCallback(string s); public interface IJsonStoreModule @@ -49,7 +59,9 @@ namespace OpenSim.Region.Framework.Interfaces bool CreateStore(string value, ref UUID result); bool DestroyStore(UUID storeID); - JsonStoreNodeType GetPathType(UUID storeID, string path); + JsonStoreNodeType GetNodeType(UUID storeID, string path); + JsonStoreValueType GetValueType(UUID storeID, string path); + bool TestStore(UUID storeID); bool SetValue(UUID storeID, string path, string value, bool useJson); diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs index 40adba1..e498c6a 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs @@ -145,7 +145,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - public JsonStoreNodeType PathType(string expr) + public JsonStoreNodeType GetNodeType(string expr) { Stack path; if (! ParsePathExpression(expr,out path)) @@ -173,6 +173,43 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- + public JsonStoreValueType GetValueType(string expr) + { + Stack path; + if (! ParsePathExpression(expr,out path)) + return JsonStoreValueType.Undefined; + + OSD result = ProcessPathExpression(ValueStore,path); + + if (result == null) + return JsonStoreValueType.Undefined; + + if (result is OSDMap) + return JsonStoreValueType.Undefined; + + if (result is OSDArray) + return JsonStoreValueType.Undefined; + + if (result is OSDBoolean) + return JsonStoreValueType.Boolean; + + if (result is OSDInteger) + return JsonStoreValueType.Integer; + + if (result is OSDReal) + return JsonStoreValueType.Float; + + if (result is OSDString) + return JsonStoreValueType.String; + + return JsonStoreValueType.Undefined; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- public int ArrayLength(string expr) { Stack path; diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs index e78a2f4..5fbfcc5 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs @@ -270,7 +270,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - public JsonStoreNodeType GetPathType(UUID storeID, string path) + public JsonStoreNodeType GetNodeType(UUID storeID, string path) { if (! m_enabled) return JsonStoreNodeType.Undefined; @@ -287,7 +287,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore try { lock (map) - return map.PathType(path); + return map.GetNodeType(path); } catch (Exception e) { @@ -302,6 +302,38 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- + public JsonStoreValueType GetValueType(UUID storeID, string path) + { + if (! m_enabled) return JsonStoreValueType.Undefined; + + JsonStore map = null; + lock (m_JsonValueStore) + { + if (! m_JsonValueStore.TryGetValue(storeID,out map)) + { + m_log.InfoFormat("[JsonStore] Missing store {0}",storeID); + return JsonStoreValueType.Undefined; + } + } + + try + { + lock (map) + return map.GetValueType(path); + } + catch (Exception e) + { + m_log.Error(string.Format("[JsonStore]: Path test failed for {0} in {1}", path, storeID), e); + } + + return JsonStoreValueType.Undefined; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- public bool SetValue(UUID storeID, string path, string value, bool useJson) { if (! m_enabled) return false; diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index e13eb56..4a754a9 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs @@ -192,16 +192,32 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore #region ScriptConstantsInterface [ScriptConstant] - public static readonly int JSON_TYPE_UNDEF = (int)JsonStoreNodeType.Undefined; + public static readonly int JSON_NODETYPE_UNDEF = (int)JsonStoreNodeType.Undefined; [ScriptConstant] - public static readonly int JSON_TYPE_OBJECT = (int)JsonStoreNodeType.Object; + public static readonly int JSON_NODETYPE_OBJECT = (int)JsonStoreNodeType.Object; [ScriptConstant] - public static readonly int JSON_TYPE_ARRAY = (int)JsonStoreNodeType.Array; + public static readonly int JSON_NODETYPE_ARRAY = (int)JsonStoreNodeType.Array; [ScriptConstant] - public static readonly int JSON_TYPE_VALUE = (int)JsonStoreNodeType.Value; + public static readonly int JSON_NODETYPE_VALUE = (int)JsonStoreNodeType.Value; + + [ScriptConstant] + public static readonly int JSON_VALUETYPE_UNDEF = (int)JsonStoreValueType.Undefined; + + [ScriptConstant] + public static readonly int JSON_VALUETYPE_BOOLEAN = (int)JsonStoreValueType.Boolean; + + [ScriptConstant] + public static readonly int JSON_VALUETYPE_INTEGER = (int)JsonStoreValueType.Integer; + + [ScriptConstant] + public static readonly int JSON_VALUETYPE_FLOAT = (int)JsonStoreValueType.Float; + + [ScriptConstant] + public static readonly int JSON_VALUETYPE_STRING = (int)JsonStoreValueType.String; + #endregion @@ -310,9 +326,20 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// // ----------------------------------------------------------------- [ScriptInvocation] - public int JsonGetPathType(UUID hostID, UUID scriptID, UUID storeID, string path) + public int JsonGetNodeType(UUID hostID, UUID scriptID, UUID storeID, string path) + { + return (int)m_store.GetNodeType(storeID,path); + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + [ScriptInvocation] + public int JsonGetValueType(UUID hostID, UUID scriptID, UUID storeID, string path) { - return (int)m_store.GetPathType(storeID,path); + return (int)m_store.GetValueType(storeID,path); } // ----------------------------------------------------------------- diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index b64dbd4..bfa9937 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs @@ -158,8 +158,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests Assert.That(dsrv, Is.EqualTo(1)); - int tprv = (int)InvokeOp("JsonGetPathType", storeId, "Hello"); - Assert.That(tprv, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_UNDEF)); + int tprv = (int)InvokeOp("JsonGetNodeType", storeId, "Hello"); + Assert.That(tprv, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF)); } [Test] @@ -277,8 +277,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello"); Assert.That(returnValue, Is.EqualTo(1)); - int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello"); - Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_UNDEF)); + int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF)); string returnValue2 = (string)InvokeOp("JsonGetValue", storeId, "Hello"); Assert.That(returnValue2, Is.EqualTo("")); @@ -291,8 +291,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello"); Assert.That(returnValue, Is.EqualTo(1)); - int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello"); - Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_UNDEF)); + int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF)); string returnValue2 = (string)InvokeOp("JsonGetJson", storeId, "Hello"); Assert.That(returnValue2, Is.EqualTo("")); @@ -306,11 +306,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello[0]"); Assert.That(returnValue, Is.EqualTo(1)); - int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello[0]"); - Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_VALUE)); + int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello[0]"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_VALUE)); - result = (int)InvokeOp("JsonGetPathType", storeId, "Hello[1]"); - Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_UNDEF)); + result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello[1]"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF)); string stringReturnValue = (string)InvokeOp("JsonGetValue", storeId, "Hello[0]"); Assert.That(stringReturnValue, Is.EqualTo("value2")); @@ -433,7 +433,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests } [Test] - public void TestJsonGetPathType() + public void TestJsonGetNodeType() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); @@ -441,41 +441,41 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : [ 'one', 2 ] } }"); { - int result = (int)InvokeOp("JsonGetPathType", storeId, "."); - Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_OBJECT)); + int result = (int)InvokeOp("JsonGetNodeType", storeId, "."); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_OBJECT)); } { - int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello"); - Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_OBJECT)); + int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_OBJECT)); } { - int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello.World"); - Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_ARRAY)); + int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello.World"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_ARRAY)); } { - int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello.World[0]"); - Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_VALUE)); + int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello.World[0]"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_VALUE)); } { - int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello.World[1]"); - Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_VALUE)); + int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello.World[1]"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_VALUE)); } // Test for non-existant path { - int result = (int)InvokeOp("JsonGetPathType", storeId, "foo"); - Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_UNDEF)); + int result = (int)InvokeOp("JsonGetNodeType", storeId, "foo"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF)); } // Test for non-existant store { UUID fakeStoreId = TestHelpers.ParseTail(0x500); - int result = (int)InvokeOp("JsonGetPathType", fakeStoreId, "."); - Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_UNDEF)); + int result = (int)InvokeOp("JsonGetNodeType", fakeStoreId, "."); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF)); } } -- cgit v1.1 From 8960418e7d51a0f861e7b4cb800f007d76862c9c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 6 Mar 2013 21:37:53 +0000 Subject: Add regression test for presence crossing between regions on the same simulator. Unlike a much earlier commented out version of this test, this is done in synchronous mode. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 37 +++--- .../Scenes/Tests/ScenePresenceAgentTests.cs | 103 --------------- .../Scenes/Tests/ScenePresenceCrossingTests.cs | 140 +++++++++++++++++++++ .../BasicPhysicsPlugin/BasicPhysicsScene.cs | 9 +- 4 files changed, 166 insertions(+), 123 deletions(-) create mode 100644 OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 39a885c..a7c7539 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1613,32 +1613,28 @@ namespace OpenSim.Region.Framework.Scenes bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); - //m_log.Debug("[CONTROL]: " +flags); // Applies a satisfying roll effect to the avatar when flying. - if (((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) != 0) && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0)) + if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) != 0 && (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0) { - - ApplyFlyingRoll(FLY_ROLL_RADIANS_PER_UPDATE, ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0), ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0)); - - + ApplyFlyingRoll( + FLY_ROLL_RADIANS_PER_UPDATE, + (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0, + (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0); } - else if (((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) != 0) && - ((flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)) + else if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) != 0 && + (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0) { - ApplyFlyingRoll(-FLY_ROLL_RADIANS_PER_UPDATE, ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0), ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0)); - - + ApplyFlyingRoll( + -FLY_ROLL_RADIANS_PER_UPDATE, + (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0, + (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0); } else { if (m_AngularVelocity.Z != 0) - m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_UPDATE); - - } - - - + m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_UPDATE); + } if (Flying && IsColliding && controlland) { @@ -2400,7 +2396,8 @@ namespace OpenSim.Region.Framework.Scenes /// The vector in which to move. This is relative to the rotation argument public void AddNewMovement(Vector3 vec) { -// m_log.DebugFormat("[SCENE PRESENCE]: Adding new movement {0} for {1}", vec, Name); +// m_log.DebugFormat( +// "[SCENE PRESENCE]: Adding new movement {0} with rotation {1} for {2}", vec, Rotation, Name); Vector3 direc = vec * Rotation; direc.Normalize(); @@ -2420,6 +2417,8 @@ namespace OpenSim.Region.Framework.Scenes direc *= 0.03f * 128f * SpeedModifier; +// m_log.DebugFormat("[SCENE PRESENCE]: Force to apply before modification was {0} for {1}", direc, Name); + if (PhysicsActor != null) { if (Flying) @@ -2453,6 +2452,8 @@ namespace OpenSim.Region.Framework.Scenes } } +// m_log.DebugFormat("[SCENE PRESENCE]: Setting force to apply to {0} for {1}", direc, Name); + // TODO: Add the force instead of only setting it to support multiple forces per frame? m_forceToApply = direc; } diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs index 5faf131..bbfbbfc 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs @@ -289,108 +289,5 @@ namespace OpenSim.Region.Framework.Scenes.Tests // // Assert.That(presence, Is.Null, "presence is not null"); // } - - // I'm commenting this test because it does not represent - // crossings. The Thread.Sleep's in here are not meaningful mocks, - // and they sometimes fail in panda. - // We need to talk in order to develop a test - // that really tests region crossings. There are 3 async components, - // but things are synchronous among them. So there should be - // 3 threads in here. - //[Test] -// public void T021_TestCrossToNewRegion() -// { -// TestHelpers.InMethod(); -// -// scene.RegisterRegionWithGrid(); -// scene2.RegisterRegionWithGrid(); -// -// // Adding child agent to region 1001 -// string reason; -// scene2.NewUserConnection(acd1,0, out reason); -// scene2.AddNewClient(testclient, PresenceType.User); -// -// ScenePresence presence = scene.GetScenePresence(agent1); -// presence.MakeRootAgent(new Vector3(0,unchecked(Constants.RegionSize-1),0), true); -// -// ScenePresence presence2 = scene2.GetScenePresence(agent1); -// -// // Adding neighbour region caps info to presence2 -// -// string cap = presence.ControllingClient.RequestClientInfo().CapsPath; -// presence2.AddNeighbourRegion(region1, cap); -// -// Assert.That(presence.IsChildAgent, Is.False, "Did not start root in origin region."); -// Assert.That(presence2.IsChildAgent, Is.True, "Is not a child on destination region."); -// -// // Cross to x+1 -// presence.AbsolutePosition = new Vector3(Constants.RegionSize+1,3,100); -// presence.Update(); -// -// EventWaitHandle wh = new EventWaitHandle (false, EventResetMode.AutoReset, "Crossing"); -// -// // Mimicking communication between client and server, by waiting OK from client -// // sent by TestClient.CrossRegion call. Originally, this is network comm. -// if (!wh.WaitOne(5000,false)) -// { -// presence.Update(); -// if (!wh.WaitOne(8000,false)) -// throw new ArgumentException("1 - Timeout waiting for signal/variable."); -// } -// -// // This is a TestClient specific method that fires OnCompleteMovementToRegion event, which -// // would normally be fired after receiving the reply packet from comm. done on the last line. -// testclient.CompleteMovement(); -// -// // Crossings are asynchronous -// int timer = 10; -// -// // Make sure cross hasn't already finished -// if (!presence.IsInTransit && !presence.IsChildAgent) -// { -// // If not and not in transit yet, give it some more time -// Thread.Sleep(5000); -// } -// -// // Enough time, should at least be in transit by now. -// while (presence.IsInTransit && timer > 0) -// { -// Thread.Sleep(1000); -// timer-=1; -// } -// -// Assert.That(timer,Is.GreaterThan(0),"Timed out waiting to cross 2->1."); -// Assert.That(presence.IsChildAgent, Is.True, "Did not complete region cross as expected."); -// Assert.That(presence2.IsChildAgent, Is.False, "Did not receive root status after receiving agent."); -// -// // Cross Back -// presence2.AbsolutePosition = new Vector3(-10, 3, 100); -// presence2.Update(); -// -// if (!wh.WaitOne(5000,false)) -// { -// presence2.Update(); -// if (!wh.WaitOne(8000,false)) -// throw new ArgumentException("2 - Timeout waiting for signal/variable."); -// } -// testclient.CompleteMovement(); -// -// if (!presence2.IsInTransit && !presence2.IsChildAgent) -// { -// // If not and not in transit yet, give it some more time -// Thread.Sleep(5000); -// } -// -// // Enough time, should at least be in transit by now. -// while (presence2.IsInTransit && timer > 0) -// { -// Thread.Sleep(1000); -// timer-=1; -// } -// -// Assert.That(timer,Is.GreaterThan(0),"Timed out waiting to cross 1->2."); -// Assert.That(presence2.IsChildAgent, Is.True, "Did not return from region as expected."); -// Assert.That(presence.IsChildAgent, Is.False, "Presence was not made root in old region again."); -// } } } \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs new file mode 100644 index 0000000..ef9fff5 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs @@ -0,0 +1,140 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Reflection; +using Nini.Config; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Servers; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.CoreModules.Framework; +using OpenSim.Region.CoreModules.Framework.EntityTransfer; +using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Region.Framework.Scenes.Tests +{ + [TestFixture] + public class ScenePresenceCrossingTests : OpenSimTestCase + { + [TestFixtureSetUp] + public void FixtureInit() + { + // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread. + Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest; + } + + [TestFixtureTearDown] + public void TearDown() + { + // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple + // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression + // tests really shouldn't). + Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; + } + + [Test] + public void TestCrossOnSameSimulator() + { + TestHelpers.InMethod(); + TestHelpers.EnableLogging(); + + UUID userId = TestHelpers.ParseTail(0x1); + + EntityTransferModule etmA = new EntityTransferModule(); + EntityTransferModule etmB = new EntityTransferModule(); + LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); + + IConfigSource config = new IniConfigSource(); + IConfig modulesConfig = config.AddConfig("Modules"); + modulesConfig.Set("EntityTransferModule", etmA.Name); + modulesConfig.Set("SimulationServices", lscm.Name); + IConfig entityTransferConfig = config.AddConfig("EntityTransfer"); + + // In order to run a single threaded regression test we do not want the entity transfer module waiting + // for a callback from the destination scene before removing its avatar data. +// entityTransferConfig.Set("wait_for_callback", false); + + SceneHelpers sh = new SceneHelpers(); + TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); + TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1000, 999); + + SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); + SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA); + SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB); + + ScenePresence originalSp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager); + originalSp.AbsolutePosition = new Vector3(128, 32, 10); + +// originalSp.Flying = true; + +// Console.WriteLine("First pos {0}", originalSp.AbsolutePosition); + + AgentUpdateArgs moveArgs = new AgentUpdateArgs(); + //moveArgs.BodyRotation = Quaternion.CreateFromEulers(Vector3.Zero); + moveArgs.BodyRotation = Quaternion.CreateFromEulers(new Vector3(0, 0, (float)-(Math.PI / 2))); + moveArgs.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS; + + originalSp.HandleAgentUpdate(originalSp.ControllingClient, moveArgs); + + sceneA.Update(1); + +// Console.WriteLine("Second pos {0}", originalSp.AbsolutePosition); + + // FIXME: This is a sufficient number of updates to for the presence to reach the northern border. + // But really we want to do this in a more robust way. + for (int i = 0; i < 100; i++) + { + sceneA.Update(1); +// Console.WriteLine("Pos {0}", originalSp.AbsolutePosition); + } + + // sceneA should now only have a child agent + ScenePresence spAfterCrossSceneA = sceneA.GetScenePresence(originalSp.UUID); + Assert.That(spAfterCrossSceneA.IsChildAgent, Is.True); + + ScenePresence spAfterCrossSceneB = sceneB.GetScenePresence(originalSp.UUID); + + // Agent remains a child until the client triggers complete movement + Assert.That(spAfterCrossSceneB.IsChildAgent, Is.True); + + TestClient sceneBTc = ((TestClient)spAfterCrossSceneB.ControllingClient); + + bool receivedCompleteMovement = false; + sceneBTc.OnReceivedMoveAgentIntoRegion += (ri, pos, look) => receivedCompleteMovement = true; + + sceneBTc.CompleteMovement(); + + Assert.That(receivedCompleteMovement, Is.True); + Assert.That(spAfterCrossSceneB.IsChildAgent, Is.False); + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs index c4b9117..0816b7b 100644 --- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs @@ -102,6 +102,8 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin public override float Simulate(float timeStep) { +// Console.WriteLine("Simulating"); + float fps = 0; for (int i = 0; i < _actors.Count; ++i) { @@ -109,8 +111,11 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin Vector3 actorPosition = actor.Position; Vector3 actorVelocity = actor.Velocity; - actorPosition.X += actor.Velocity.X*timeStep; - actorPosition.Y += actor.Velocity.Y*timeStep; +// Console.WriteLine( +// "Processing actor {0}, starting pos {1}, starting vel {2}", i, actorPosition, actorVelocity); + + actorPosition.X += actor.Velocity.X * timeStep; + actorPosition.Y += actor.Velocity.Y * timeStep; if (actor.Position.Y < 0) { -- cgit v1.1 From f954c53ddb009009e386a4046857cc20d0fd656c Mon Sep 17 00:00:00 2001 From: teravus Date: Wed, 6 Mar 2013 17:02:53 -0500 Subject: * Separate two if trees that got merged into one if tree with borked logic. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 27 ++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 7cab841..e22cf47 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4574,7 +4574,8 @@ namespace OpenSim.Region.Framework.Scenes if (ParentGroup.RootPart == this) AngularVelocity = new Vector3(0, 0, 0); } - else if (SetVD != wasVD) + + else { if (ParentGroup.Scene.CollidablePrims) { @@ -4620,9 +4621,31 @@ namespace OpenSim.Region.Framework.Scenes UpdatePhysicsSubscribedEvents(); } } - + if (SetVD) + { + // If the above logic worked (this is urgent candidate to unit tests!) + // we now have a physicsactor. + // Defensive programming calls for a check here. + // Better would be throwing an exception that could be catched by a unit test as the internal + // logic should make sure, this Physactor is always here. + if (pa != null) + { + pa.SetVolumeDetect(1); + AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active + VolumeDetectActive = true; + } // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString()); + } + else if (SetVD != wasVD) + { + // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like + // (mumbles, well, at least if you have infinte CPU powers :-)) + if (pa != null) + pa.SetVolumeDetect(0); + RemFlag(PrimFlags.Phantom); + VolumeDetectActive = false; + } // and last in case we have a new actor and not building if (ParentGroup != null) -- cgit v1.1 From 5751ecde5250484fe8e4b79ef38bfbf441e3dead Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 6 Mar 2013 23:06:00 +0000 Subject: Add code for testing event queue messages recevied on region cross. This is currently disabled pending an improvement in the test code to properly add avatars when an event queue module is present. --- .../EntityTransfer/EntityTransferModule.cs | 5 ++++ .../Simulation/LocalSimulationConnector.cs | 9 +++++--- .../Scenes/Tests/ScenePresenceCrossingTests.cs | 27 ++++++++++++++++++---- 3 files changed, 33 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 07c3666..01b1668 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1206,6 +1206,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // region doesn't take it m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); + m_log.WarnFormat( + "[ENTITY TRANSFER MODULE]: Region {0} would not accept update for agent {1} on cross attempt. Returning to original region.", + neighbourRegion.RegionName, agent.Name); + ReInstantiateScripts(agent); agent.AddToPhysicalScene(isFlying); @@ -1225,6 +1229,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer neighbourRegion.RegionHandle); return agent; } + // No turning back agent.IsChildAgent = true; diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs index 3c18074..a413546 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs @@ -219,12 +219,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation { // m_log.DebugFormat( // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", -// s.RegionInfo.RegionName, destination.RegionHandle); +// destination.RegionName, destination.RegionID); return m_scenes[destination.RegionID].IncomingChildAgentDataUpdate(cAgentData); } -// m_log.DebugFormat("[LOCAL COMMS]: Did not find region {0} for ChildAgentUpdate", regionHandle); +// m_log.DebugFormat( +// "[LOCAL COMMS]: Did not find region {0} {1} for ChildAgentUpdate", +// destination.RegionName, destination.RegionID); + return false; } @@ -239,7 +242,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation // note that we really don't need the GridRegion for this call foreach (Scene s in m_scenes.Values) { - //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); +// m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); s.IncomingChildAgentDataUpdate(cAgentData); } diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs index ef9fff5..81a2fcc 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs @@ -26,6 +26,7 @@ */ using System; +using System.Collections.Generic; using System.Reflection; using Nini.Config; using NUnit.Framework; @@ -65,10 +66,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests public void TestCrossOnSameSimulator() { TestHelpers.InMethod(); - TestHelpers.EnableLogging(); +// TestHelpers.EnableLogging(); UUID userId = TestHelpers.ParseTail(0x1); +// TestEventQueueGetModule eqmA = new TestEventQueueGetModule(); EntityTransferModule etmA = new EntityTransferModule(); EntityTransferModule etmB = new EntityTransferModule(); LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); @@ -77,7 +79,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests IConfig modulesConfig = config.AddConfig("Modules"); modulesConfig.Set("EntityTransferModule", etmA.Name); modulesConfig.Set("SimulationServices", lscm.Name); - IConfig entityTransferConfig = config.AddConfig("EntityTransfer"); +// IConfig entityTransferConfig = config.AddConfig("EntityTransfer"); // In order to run a single threaded regression test we do not want the entity transfer module waiting // for a callback from the destination scene before removing its avatar data. @@ -89,6 +91,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA); +// SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA, eqmA); SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB); ScenePresence originalSp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager); @@ -98,6 +101,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests // Console.WriteLine("First pos {0}", originalSp.AbsolutePosition); +// eqmA.ClearEvents(); + AgentUpdateArgs moveArgs = new AgentUpdateArgs(); //moveArgs.BodyRotation = Quaternion.CreateFromEulers(Vector3.Zero); moveArgs.BodyRotation = Quaternion.CreateFromEulers(new Vector3(0, 0, (float)-(Math.PI / 2))); @@ -117,6 +122,18 @@ namespace OpenSim.Region.Framework.Scenes.Tests // Console.WriteLine("Pos {0}", originalSp.AbsolutePosition); } + // Need to sort processing of EnableSimulator message on adding scene presences before we can test eqm + // messages +// Dictionary> eqmEvents = eqmA.Events; +// +// Assert.That(eqmEvents.Count, Is.EqualTo(1)); +// Assert.That(eqmEvents.ContainsKey(originalSp.UUID), Is.True); +// +// List spEqmEvents = eqmEvents[originalSp.UUID]; +// +// Assert.That(spEqmEvents.Count, Is.EqualTo(1)); +// Assert.That(spEqmEvents[0].Name, Is.EqualTo("CrossRegion")); + // sceneA should now only have a child agent ScenePresence spAfterCrossSceneA = sceneA.GetScenePresence(originalSp.UUID); Assert.That(spAfterCrossSceneA.IsChildAgent, Is.True); @@ -128,12 +145,12 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestClient sceneBTc = ((TestClient)spAfterCrossSceneB.ControllingClient); - bool receivedCompleteMovement = false; - sceneBTc.OnReceivedMoveAgentIntoRegion += (ri, pos, look) => receivedCompleteMovement = true; + int agentMovementCompleteReceived = 0; + sceneBTc.OnReceivedMoveAgentIntoRegion += (ri, pos, look) => agentMovementCompleteReceived++; sceneBTc.CompleteMovement(); - Assert.That(receivedCompleteMovement, Is.True); + Assert.That(agentMovementCompleteReceived, Is.EqualTo(1)); Assert.That(spAfterCrossSceneB.IsChildAgent, Is.False); } } -- cgit v1.1 From 6706e189d5b1c04e4931c96b1a9c233f3606b71a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 6 Mar 2013 23:11:32 +0000 Subject: minor: remove some completely unused string local vars added recently in commit 984faf2 --- OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 2 -- 1 file changed, 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 3ccf9f4..b6a7481 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -324,7 +324,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // Remove any previous attachments List existingAttachments = sp.GetAttachments(attachmentPt); - string existingAttachmentScriptState = null; // At the moment we can only deal with a single attachment if (existingAttachments.Count != 0 && existingAttachments[0].FromItemID != UUID.Zero) @@ -849,7 +848,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // Remove any previous attachments List attachments = sp.GetAttachments(attachmentPt); - string previousAttachmentScriptedState = null; // At the moment we can only deal with a single attachment if (attachments.Count != 0) -- cgit v1.1 From 33dab49d22002b9d24b2c286d662dca1755ace30 Mon Sep 17 00:00:00 2001 From: teravus Date: Thu, 7 Mar 2013 19:19:36 -0500 Subject: * Just another one of those new packet blocks causing a null ref. Defaulting to zero length array..... --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 6742d99..bae7952 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -4581,7 +4581,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP rinfopack.AgentData = new RegionInfoPacket.AgentDataBlock(); rinfopack.AgentData.AgentID = AgentId; rinfopack.AgentData.SessionID = SessionId; - + rinfopack.RegionInfo3 = new RegionInfoPacket.RegionInfo3Block[0]; OutPacket(rinfopack, ThrottleOutPacketType.Task); } -- cgit v1.1 From 5097437e1174d19d3dcb68e936581e60e4ef49cc Mon Sep 17 00:00:00 2001 From: teravus Date: Fri, 8 Mar 2013 19:32:47 -0500 Subject: * Apparently, sometimes texture entries come in from the wire with no default texture defined.. so apply better fallback protection against that. The net result is clients will have their selected textures set when they would have previously had an ignored exception. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index cce8b21..3e9a6fa 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4503,8 +4503,25 @@ namespace OpenSim.Region.Framework.Scenes Changed changeFlags = 0; + Primitive.TextureEntryFace fallbackNewFace = newTex.DefaultTexture; + Primitive.TextureEntryFace fallbackOldFace = oldTex.DefaultTexture; + + // On Incoming packets, sometimes newText.DefaultTexture is null. The assumption is that all + // other prim-sides are set, but apparently that's not always the case. Lets assume packet/data corruption at this point. + if (fallbackNewFace == null) + { + fallbackNewFace = new Primitive.TextureEntry(Util.BLANK_TEXTURE_UUID).CreateFace(0); + newTex.DefaultTexture = fallbackNewFace; + } + if (fallbackOldFace == null) + { + fallbackOldFace = new Primitive.TextureEntry(Util.BLANK_TEXTURE_UUID).CreateFace(0); + oldTex.DefaultTexture = fallbackOldFace; + } + for (int i = 0 ; i < GetNumberOfSides(); i++) { + Primitive.TextureEntryFace newFace = newTex.DefaultTexture; Primitive.TextureEntryFace oldFace = oldTex.DefaultTexture; -- cgit v1.1 From 1120bcf123b5aa159e966a80254794f6af66f2a3 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 9 Mar 2013 14:15:14 -0800 Subject: BulletSim: remove the ability for avatars to fly off the edge of regions when there are no region neighbors. Add some terrain location processing routines to support above. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 29 +++--- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 5 ++ .../Physics/BulletSPlugin/BSTerrainManager.cs | 100 +++++++++++++++++++-- .../Region/Physics/BulletSPlugin/BSTerrainMesh.cs | 6 +- 4 files changed, 117 insertions(+), 23 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index f442ca2..e208d3a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -205,7 +205,7 @@ public sealed class BSCharacter : BSPhysObject // errors can creap in and the avatar will slowly float off in some direction. // So, the problem is that, when an avatar is standing, we cannot tell creaping error // from real pushing. - // The code below keeps setting the velocity to zero hoping the world will keep pushing. + // The code below uses whether the collider is static or moving to decide whether to zero motion. _velocityMotor.Step(timeStep); @@ -244,6 +244,7 @@ public sealed class BSCharacter : BSPhysObject } else { + // Supposed to be moving. OMV.Vector3 stepVelocity = _velocityMotor.CurrentValue; if (Friction != BSParam.AvatarFriction) @@ -276,8 +277,8 @@ public sealed class BSCharacter : BSPhysObject }); } - // Decide of the character is colliding with a low object and compute a force to pop the - // avatar up so it has a chance of walking up and over the low object. + // Decide if the character is colliding with a low object and compute a force to pop the + // avatar up so it can walk up and over the low objects. private OMV.Vector3 WalkUpStairs() { OMV.Vector3 ret = OMV.Vector3.Zero; @@ -476,17 +477,19 @@ public sealed class BSCharacter : BSPhysObject if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition)) { // The character is out of the known/simulated area. - // Upper levels of code will handle the transition to other areas so, for - // the time, we just ignore the position. - return ret; + // Force the avatar position to be within known. ScenePresence will use the position + // plus the velocity to decide if the avatar is moving out of the region. + RawPosition = PhysicsScene.TerrainManager.ClampPositionIntoKnownTerrain(RawPosition); + DetailLog("{0},BSCharacter.PositionSanityCheck,notWithinKnownTerrain,clampedPos={1}", LocalID, RawPosition); + return true; } // If below the ground, move the avatar up float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition); if (Position.Z < terrainHeight) { - DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); - _position.Z = terrainHeight + 2.0f; + DetailLog("{0},BSCharacter.PositionSanityCheck,adjustForUnderGround,pos={1},terrain={2}", LocalID, _position, terrainHeight); + _position.Z = terrainHeight + BSParam.AvatarBelowGroundUpCorrectionMeters; ret = true; } if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) @@ -806,14 +809,7 @@ public sealed class BSCharacter : BSPhysObject private void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { if (force.IsFinite()) { - float magnitude = force.Length(); - if (magnitude > BSParam.MaxAddForceMagnitude) - { - // Force has a limit - force = force / magnitude * BSParam.MaxAddForceMagnitude; - } - - OMV.Vector3 addForce = force; + OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude); // DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce); PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.AddForce", delegate() @@ -902,6 +898,7 @@ public sealed class BSCharacter : BSPhysObject // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. if (PositionSanityCheck(true)) { + DetailLog("{0},BSCharacter.UpdateProperties,updatePosForSanity,pos={1}", LocalID, _position); entprop.Position = _position; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index fa58109..2af8468 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -107,6 +107,7 @@ public static class BSParam public static float AvatarCapsuleDepth { get; private set; } public static float AvatarCapsuleHeight { get; private set; } public static float AvatarContactProcessingThreshold { get; private set; } + public static float AvatarBelowGroundUpCorrectionMeters { get; private set; } public static float AvatarStepHeight { get; private set; } public static float AvatarStepApproachFactor { get; private set; } public static float AvatarStepForceFactor { get; private set; } @@ -497,6 +498,10 @@ public static class BSParam 0.1f, (s) => { return AvatarContactProcessingThreshold; }, (s,v) => { AvatarContactProcessingThreshold = v; } ), + new ParameterDefn("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground", + 1.0f, + (s) => { return AvatarBelowGroundUpCorrectionMeters; }, + (s,v) => { AvatarBelowGroundUpCorrectionMeters = v; } ), new ParameterDefn("AvatarStepHeight", "Height of a step obstacle to consider step correction", 0.3f, (s) => { return AvatarStepHeight; }, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index 2e9db39..e8040d8 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -337,6 +337,54 @@ public sealed class BSTerrainManager : IDisposable return GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ); } + // Return a new position that is over known terrain if the position is outside our terrain. + public Vector3 ClampPositionIntoKnownTerrain(Vector3 pPos) + { + Vector3 ret = pPos; + + // Can't do this function if we don't know about any terrain. + if (m_terrains.Count == 0) + return ret; + + int loopPrevention = 5; + Vector3 terrainBaseXYZ; + BSTerrainPhys physTerrain; + while (!GetTerrainPhysicalAtXYZ(ret, out physTerrain, out terrainBaseXYZ)) + { + // The passed position is not within a known terrain area. + + // First, base addresses are never negative so correct for that possible problem. + if (ret.X < 0f || ret.Y < 0f) + { + if (ret.X < 0f) + ret.X = 0f; + if (ret.Y < 0f) + ret.Y = 0f; + DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,zeroingNegXorY,oldPos={1},newPos={2}", + BSScene.DetailLogZero, pPos, ret); + } + else + { + // Must be off the top of a region. Find an adjacent region to move into. + Vector3 adjacentTerrainBase = FindAdjacentTerrainBase(terrainBaseXYZ); + + ret.X = Math.Min(ret.X, adjacentTerrainBase.X + DefaultRegionSize.X); + ret.Y = Math.Min(ret.Y, adjacentTerrainBase.Y + DefaultRegionSize.Y); + DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,findingAdjacentRegion,adjacentRegBase={1},oldPos={2},newPos={3}", + BSScene.DetailLogZero, adjacentTerrainBase, pPos, ret); + } + if (loopPrevention-- < 0f) + { + // The 'while' is a little dangerous so this prevents looping forever if the + // mapping of the terrains ever gets messed up (like nothing at <0,0>) or + // the list of terrains is in transition. + DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,suppressingFindAdjacentRegionLoop", BSScene.DetailLogZero); + break; + } + } + return ret; + } + // Given an X and Y, find the height of the terrain. // Since we could be handling multiple terrains for a mega-region, // the base of the region is calcuated assuming all regions are @@ -400,18 +448,60 @@ public sealed class BSTerrainManager : IDisposable // the descriptor class and the 'base' fo the addresses therein. private bool GetTerrainPhysicalAtXYZ(Vector3 pos, out BSTerrainPhys outPhysTerrain, out Vector3 outTerrainBase) { - int offsetX = ((int)(pos.X / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X; - int offsetY = ((int)(pos.Y / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y; - Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f); + bool ret = false; + + Vector3 terrainBaseXYZ = Vector3.Zero; + if (pos.X < 0f || pos.Y < 0f) + { + // We don't handle negative addresses so just make up a base that will not be found. + terrainBaseXYZ = new Vector3(-DefaultRegionSize.X, -DefaultRegionSize.Y, 0f); + } + else + { + int offsetX = ((int)(pos.X / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X; + int offsetY = ((int)(pos.Y / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y; + terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f); + } BSTerrainPhys physTerrain = null; lock (m_terrains) { - m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain); + ret = m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain); } outTerrainBase = terrainBaseXYZ; outPhysTerrain = physTerrain; - return (physTerrain != null); + return ret; + } + + // Given a terrain base, return a terrain base for a terrain that is closer to <0,0> than + // this one. Usually used to return an out of bounds object to a known place. + private Vector3 FindAdjacentTerrainBase(Vector3 pTerrainBase) + { + Vector3 ret = pTerrainBase; + ret.Z = 0f; + lock (m_terrains) + { + // Once down to the <0,0> region, we have to be done. + while (ret.X > 0f && ret.Y > 0f) + { + if (ret.X > 0f) + { + ret.X = Math.Max(0f, ret.X - DefaultRegionSize.X); + DetailLog("{0},BSTerrainManager.FindAdjacentTerrainBase,reducingX,terrainBase={1}", BSScene.DetailLogZero, ret); + if (m_terrains.ContainsKey(ret)) + break; + } + if (ret.Y > 0f) + { + ret.Y = Math.Max(0f, ret.Y - DefaultRegionSize.Y); + DetailLog("{0},BSTerrainManager.FindAdjacentTerrainBase,reducingY,terrainBase={1}", BSScene.DetailLogZero, ret); + if (m_terrains.ContainsKey(ret)) + break; + } + } + } + + return ret; } // Although no one seems to check this, I do support combining. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index d7e800d..57a5ff2 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs @@ -215,7 +215,8 @@ public sealed class BSTerrainMesh : BSTerrainPhys float magX = (float)sizeX / extentX; float magY = (float)sizeY / extentY; - physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2},extentBase={3},magX={4},magY={5}", + if (physicsScene != null) + physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2},extentBase={3},magX={4},magY={5}", BSScene.DetailLogZero, totalVertices, totalIndices, extentBase, magX, magY); float minHeight = float.MaxValue; // Note that sizeX+1 vertices are created since there is land between this and the next region. @@ -257,7 +258,8 @@ public sealed class BSTerrainMesh : BSTerrainPhys } catch (Exception e) { - physicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh. For={1}/{2}, e={3}", + if (physicsScene != null) + physicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh. For={1}/{2}, e={3}", LogHeader, physicsScene.RegionName, extentBase, e); } -- cgit v1.1 From e898a5fec5b78fe428ec10e1cd94cc717f5ac5a7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 11 Mar 2013 22:42:27 +0000 Subject: minor: Remove mono compiler warnings in EventQueueTests --- .../ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs index ed8ec16..141af8a 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs @@ -49,8 +49,10 @@ namespace OpenSim.Region.ClientStack.Linden.Tests private TestScene m_scene; [SetUp] - public void SetUp() + public override void SetUp() { + base.SetUp(); + uint port = 9999; uint sslPort = 9998; -- cgit v1.1 From be686f80a354103cd6630cd8f4e5fb40a4093549 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 11 Mar 2013 23:01:07 +0000 Subject: minor: Remove mono compiler warnings from LSL_ApiHttpTests --- OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs index b0baa1c..ab44e38 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs @@ -209,7 +209,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests += (itemId, evp) => m_lslApi.llHTTPResponse(evp.Params[0].ToString(), 200, testResponse); // Console.WriteLine("Trying {0}", returnedUri); - HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(returnedUri); AssertHttpResponse(returnedUri, testResponse); -- cgit v1.1 From 0c6268fe5606c197d99c81a5e84a84e667e28fe8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 11 Mar 2013 23:15:13 +0000 Subject: minor: remove mono compiler warning in SceneObjectUndoRedoTests --- OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs index 96973de..4883ae7 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs @@ -110,8 +110,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests Vector3 firstSize = new Vector3(2, 3, 4); Vector3 secondSize = new Vector3(5, 6, 7); - Vector3 thirdSize = new Vector3(8, 9, 10); - Vector3 fourthSize = new Vector3(11, 12, 13); +// Vector3 thirdSize = new Vector3(8, 9, 10); +// Vector3 fourthSize = new Vector3(11, 12, 13); Scene scene = new SceneHelpers().SetupScene(); scene.MaxUndoCount = 20; -- cgit v1.1 From c43d4b557267547d07f6c90dc7e335ce4f7e07be Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 12 Mar 2013 22:16:09 +0000 Subject: Improve teleport cancellation in some circumstances, though cancelling teleports is still not recommended. Previously, hitting the cancel button on a teleport would cancel on the client side but the request was ignored on the server side. Cancel would still work if the teleport failed in the early stages (e.g. because the destination never replied to early CreateAgent and UpdateAgent messages). But if the teleport still completed after a delay here or later on, the viewer would become confused (usual symptom appears to be avatar being unable to move/reteleport). This commit makes OpenSimulator obey cancellations which are received before it sends the TeleportFinish event queue message and does proper cleanup. But cancellations received after this (which can happen even though the cancel button is removed as this messages comes on a different thread) can still result in a frozen avatar. This looks extremely difficult and impossible to fix. I can replicate the same problem on the Linden Lab grid by hitting cancel immediately after a teleport starts (a teleport which would otherwise quickly succeed). --- .../EntityTransfer/EntityTransferModule.cs | 59 ++++++++-- .../EntityTransfer/EntityTransferStateMachine.cs | 124 ++++++++++++++++----- 2 files changed, 149 insertions(+), 34 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 01b1668..34f0924 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -148,6 +148,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected virtual void OnNewClient(IClientAPI client) { + client.OnTeleportCancel += OnClientCancelTeleport; client.OnTeleportHomeRequest += TeleportHome; client.OnTeleportLandmarkRequest += RequestTeleportLandmark; } @@ -168,6 +169,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #region Agent Teleports + private void OnClientCancelTeleport(IClientAPI client) + { + m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Cancelling); + + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Received teleport cancel request from {0} in {1}", client.Name, Scene.Name); + } + public void Teleport(ScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) { if (sp.Scene.Permissions.IsGridGod(sp.UUID)) @@ -567,6 +576,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } + if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling) + { + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request", + sp.Name, finalDestination.RegionName, sp.Scene.Name); + + return; + } + // Past this point we have to attempt clean up if the teleport fails, so update transfer state. m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); @@ -631,7 +649,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - sp.ControllingClient.SendTeleportProgress(teleportFlags | (uint)TeleportFlags.DisableCancel, "sending_dest"); + if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling) + { + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request", + sp.Name, finalDestination.RegionName, sp.Scene.Name); + + CleanupAbortedInterRegionTeleport(sp, finalDestination); + + return; + } m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", @@ -714,14 +741,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // } } - protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout) + /// + /// Clean up an inter-region teleport that did not complete, either because of simulator failure or cancellation. + /// + /// + /// All operations here must be idempotent so that we can call this method at any point in the teleport process + /// up until we send the TeleportFinish event quene event to the viewer. + /// + /// + /// + protected virtual void CleanupAbortedInterRegionTeleport(ScenePresence sp, GridRegion finalDestination) { m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); - // Client never contacted destination. Let's restore everything back - sp.ControllingClient.SendTeleportFailed("Problems connecting to destination."); - - // Fail. Reset it back sp.IsChildAgent = false; ReInstantiateScripts(sp); @@ -729,7 +761,20 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Finally, kill the agent we just created at the destination. Scene.SimulationService.CloseAgent(finalDestination, sp.UUID); + } + + /// + /// Signal that the inter-region teleport failed and perform cleanup. + /// + /// + /// + /// + protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout) + { + CleanupAbortedInterRegionTeleport(sp, finalDestination); + sp.ControllingClient.SendTeleportFailed( + string.Format("Problems connecting to destination {0}", finalDestination.RegionName)); sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); } @@ -2097,7 +2142,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public bool IsInTransit(UUID id) { - return m_entityTransferStateMachine.IsInTransit(id); + return m_entityTransferStateMachine.GetAgentTransferState(id) != null; } protected void ReInstantiateScripts(ScenePresence sp) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs index d0cab49..24d81d9 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs @@ -51,8 +51,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// This is a state machine. /// /// [Entry] => Preparing - /// Preparing => { Transferring || CleaningUp || [Exit] } - /// Transferring => { ReceivedAtDestination || CleaningUp } + /// Preparing => { Transferring || Cancelling || CleaningUp || [Exit] } + /// Transferring => { ReceivedAtDestination || Cancelling || CleaningUp } + /// Cancelling => CleaningUp /// ReceivedAtDestination => CleaningUp /// CleaningUp => [Exit] /// @@ -64,7 +65,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer Preparing, // The agent is being prepared for transfer Transferring, // The agent is in the process of being transferred to a destination ReceivedAtDestination, // The destination has notified us that the agent has been successfully received - CleaningUp // The agent is being changed to child/removed after a transfer + CleaningUp, // The agent is being changed to child/removed after a transfer + Cancelling // The user has cancelled the teleport but we have yet to act upon this. } /// @@ -115,42 +117,110 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// /// /// Illegal transitions will throw an Exception - internal void UpdateInTransit(UUID id, AgentTransferState newState) + internal bool UpdateInTransit(UUID id, AgentTransferState newState) { + bool transitionOkay = false; + + // We don't want to throw an exception on cancel since this can come it at any time. + bool failIfNotOkay = true; + + // Should be a failure message if failure is not okay. + string failureMessage = null; + + AgentTransferState? oldState = null; + lock (m_agentsInTransit) { // Illegal to try and update an agent that's not actually in transit. if (!m_agentsInTransit.ContainsKey(id)) - throw new Exception( - string.Format( - "Agent with ID {0} is not registered as in transit in {1}", - id, m_mod.Scene.RegionInfo.RegionName)); - - AgentTransferState oldState = m_agentsInTransit[id]; + { + if (newState != AgentTransferState.Cancelling) + failureMessage = string.Format( + "Agent with ID {0} is not registered as in transit in {1}", + id, m_mod.Scene.RegionInfo.RegionName); + else + failIfNotOkay = false; + } + else + { + oldState = m_agentsInTransit[id]; - bool transitionOkay = false; + if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp) + { + transitionOkay = true; + } + else if (newState == AgentTransferState.Transferring && oldState == AgentTransferState.Preparing) + { + transitionOkay = true; + } + else if (newState == AgentTransferState.ReceivedAtDestination && oldState == AgentTransferState.Transferring) + { + transitionOkay = true; + } + else + { + if (newState == AgentTransferState.Cancelling + && (oldState == AgentTransferState.Preparing || oldState == AgentTransferState.Transferring)) + { + transitionOkay = true; + } + else + { + failIfNotOkay = false; + } + } - if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp) - transitionOkay = true; - else if (newState == AgentTransferState.Transferring && oldState == AgentTransferState.Preparing) - transitionOkay = true; - else if (newState == AgentTransferState.ReceivedAtDestination && oldState == AgentTransferState.Transferring) - transitionOkay = true; + if (!transitionOkay) + failureMessage + = string.Format( + "Agent with ID {0} is not allowed to move from old transit state {1} to new state {2} in {3}", + id, oldState, newState, m_mod.Scene.RegionInfo.RegionName); + } if (transitionOkay) + { m_agentsInTransit[id] = newState; - else - throw new Exception( - string.Format( - "Agent with ID {0} is not allowed to move from old transit state {1} to new state {2} in {3}", - id, oldState, newState, m_mod.Scene.RegionInfo.RegionName)); + +// m_log.DebugFormat( +// "[ENTITY TRANSFER STATE MACHINE]: Changed agent with id {0} from state {1} to {2} in {3}", +// id, oldState, newState, m_mod.Scene.Name); + } + else if (failIfNotOkay) + { + throw new Exception(failureMessage); + } +// else +// { +// if (oldState != null) +// m_log.DebugFormat( +// "[ENTITY TRANSFER STATE MACHINE]: Ignored change of agent with id {0} from state {1} to {2} in {3}", +// id, oldState, newState, m_mod.Scene.Name); +// else +// m_log.DebugFormat( +// "[ENTITY TRANSFER STATE MACHINE]: Ignored change of agent with id {0} to state {1} in {2} since agent not in transit", +// id, newState, m_mod.Scene.Name); +// } } + + return transitionOkay; } - internal bool IsInTransit(UUID id) + /// + /// Gets the current agent transfer state. + /// + /// Null if the agent is not in transit + /// + /// Identifier. + /// + internal AgentTransferState? GetAgentTransferState(UUID id) { lock (m_agentsInTransit) - return m_agentsInTransit.ContainsKey(id); + { + if (!m_agentsInTransit.ContainsKey(id)) + return null; + else + return m_agentsInTransit[id]; + } } /// @@ -203,14 +273,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer lock (m_agentsInTransit) { - if (!IsInTransit(id)) + AgentTransferState? currentState = GetAgentTransferState(id); + + if (currentState == null) throw new Exception( string.Format( "Asked to wait for destination callback for agent with ID {0} in {1} but agent is not in transit", id, m_mod.Scene.RegionInfo.RegionName)); - AgentTransferState currentState = m_agentsInTransit[id]; - if (currentState != AgentTransferState.Transferring && currentState != AgentTransferState.ReceivedAtDestination) throw new Exception( string.Format( -- cgit v1.1 From fb1211ad5ef86bf6a1b6170775f1ebb4adcb4cb7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 12 Mar 2013 23:01:27 +0000 Subject: Add DisableInterRegionTeleportCancellation option in [EntityTransfer] section of OpenSim.ini. False by default. This option allows the simulator to specify that the cancel button on inter-region teleports should never appear. This exists because sometimes cancellation will result in a stuck avatar requiring relog. It may be hard to prevent this due to the protocol design (the LL grid has the same issue) In small controlled grids where teleport failure is practically impossible it can be better to disable teleport cancellation entirely. --- .../EntityTransfer/EntityTransferModule.cs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 34f0924..9b1b69a 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -66,6 +66,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// public bool WaitForAgentArrivedAtDestination { get; set; } + /// + /// If true then we ask the viewer to disable teleport cancellation and ignore teleport requests. + /// + /// + /// This is useful in situations where teleport is very likely to always succeed and we want to avoid a + /// situation where avatars can be come 'stuck' due to a failed teleport cancellation. Unfortunately, the + /// nature of the teleport protocol makes it extremely difficult (maybe impossible) to make teleport + /// cancellation consistently suceed. + /// + public bool DisableInterRegionTeleportCancellation { get; set; } + protected bool m_Enabled = false; public Scene Scene { get; private set; } @@ -116,6 +127,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer IConfig transferConfig = source.Configs["EntityTransfer"]; if (transferConfig != null) { + DisableInterRegionTeleportCancellation + = transferConfig.GetBoolean("DisableInterRegionTeleportCancellation", false); + WaitForAgentArrivedAtDestination = transferConfig.GetBoolean("wait_for_callback", WaitForAgentArrivedAtDestinationDefault); @@ -148,9 +162,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected virtual void OnNewClient(IClientAPI client) { - client.OnTeleportCancel += OnClientCancelTeleport; client.OnTeleportHomeRequest += TeleportHome; client.OnTeleportLandmarkRequest += RequestTeleportLandmark; + + if (!DisableInterRegionTeleportCancellation) + client.OnTeleportCancel += OnClientCancelTeleport; } public virtual void Close() {} @@ -528,6 +544,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (sp.ParentID != (uint)0) sp.StandUp(); + if (DisableInterRegionTeleportCancellation) + teleportFlags |= (uint)TeleportFlags.DisableCancel; + // At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to // the viewer. However, it might mean that the viewer does not see the black teleport screen (untested). sp.ControllingClient.SendTeleportStart(teleportFlags); -- cgit v1.1 From 0d25be3f8162fc4e99cd5abdaceb425a1f7370fe Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 13 Mar 2013 00:19:37 +0000 Subject: Make C# scripts return correct error line and column numbers instead of failing because they have no linemap. Adapted fix from http://opensimulator.org/mantis/view.php?id=6571 Thanks Nickel Briand --- OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs index 9d20c9e..b71afe3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs @@ -662,13 +662,18 @@ namespace SecondLife { string severity = CompErr.IsWarning ? "Warning" : "Error"; - KeyValuePair lslPos; + KeyValuePair errorPos; // Show 5 errors max, but check entire list for errors if (severity == "Error") { - lslPos = FindErrorPosition(CompErr.Line, CompErr.Column, m_lineMaps[assembly]); + // C# scripts will not have a linemap since theres no line translation involved. + if (!m_lineMaps.ContainsKey(assembly)) + errorPos = new KeyValuePair(CompErr.Line, CompErr.Column); + else + errorPos = FindErrorPosition(CompErr.Line, CompErr.Column, m_lineMaps[assembly]); + string text = CompErr.ErrorText; // Use LSL type names @@ -678,7 +683,7 @@ namespace SecondLife // The Second Life viewer's script editor begins // countingn lines and columns at 0, so we subtract 1. errtext += String.Format("({0},{1}): {4} {2}: {3}\n", - lslPos.Key - 1, lslPos.Value - 1, + errorPos.Key - 1, errorPos.Value - 1, CompErr.ErrorNumber, text, severity); hadErrors = true; } -- cgit v1.1 From f8a4d95bdd2bff70a428d386edad1ca91e15c6c0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 13 Mar 2013 00:22:07 +0000 Subject: minor: Remove mono compiler warning in LLClientView --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index bae7952..7ea538c 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -7069,7 +7069,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (handlerUpdatePrimFlags != null) { - byte[] data = Pack.ToBytes(); +// byte[] data = Pack.ToBytes(); // 46,47,48 are special positions within the packet // This may change so perhaps we need a better way // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?) -- cgit v1.1 From b7216f4daffca6dad4049c84982beca6dca9b094 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 13 Mar 2013 00:46:17 +0000 Subject: minor: save some commented out log lines which will be useful again in future debugging of VectorRenderModule --- .../Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs index f04fabe..4cecd85 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs @@ -516,6 +516,9 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender foreach (string line in GetLines(data, dataDelim)) { string nextLine = line.Trim(); + +// m_log.DebugFormat("[VECTOR RENDER MODULE]: Processing line '{0}'", nextLine); + //replace with switch, or even better, do some proper parsing if (nextLine.StartsWith("MoveTo")) { @@ -829,6 +832,8 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender float y = Convert.ToSingle(yVal, CultureInfo.InvariantCulture); PointF point = new PointF(x, y); points[i / 2] = point; + +// m_log.DebugFormat("[VECTOR RENDER MODULE]: Got point {0}", points[i / 2]); } } } -- cgit v1.1 From 5c53660a7f055be9ed41f30893de673acac8a0f1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 13 Mar 2013 22:59:06 +0000 Subject: Add prototype dynamic objects map for scene object parts This allows region modules to add dynamic objects to SOPs rather than having to continually push and pull OSD dynamic attributes. This is to explore the original MOAP use case for dynamic attributes where it could be very awkward and possibly time-consuming to keep reconstructing MediaEntrys from stored DynamicAttributes. This commit adds a DOExampleModule to demonstrate/evolve this code. Dynamic objects involve no storage or persistence changes - the 'backing store' for any data that does need to be saved will remain the DAMap. DOExampleModule in this commit only attaches a fresh dynamic object. Actually constructing this from stored dynamic attributes and handling persistence is left for later. These changes should affect no existing functionality, though it may or may not reveal necessary changes in DAMap down the road. --- .../Framework/DynamicAttributes/DOExampleModule.cs | 117 +++++++++++++++++++++ OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 22 ++++ 2 files changed, 139 insertions(+) create mode 100644 OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs new file mode 100644 index 0000000..71bb3f0 --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs @@ -0,0 +1,117 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenMetaverse; +using OpenMetaverse.Packets; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Region.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.Framework.DynamicAttributes.DOExampleModule +{ + /// + /// Example module for experimenting with and demonstrating dynamic object ideas. + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DOExampleModule")] + public class DOExampleModule : INonSharedRegionModule + { + public class MyObject + { + public int Moves { get; set; } + } + + // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private static readonly bool ENABLED = false; // enable for testing + + private Scene m_scene; + private IDialogModule m_dialogMod; + + public string Name { get { return "DOExample Module"; } } + public Type ReplaceableInterface { get { return null; } } + + public void Initialise(IConfigSource source) {} + + public void AddRegion(Scene scene) + { + if (ENABLED) + { + m_scene = scene; + m_scene.EventManager.OnObjectAddedToScene += OnObjectAddedToScene; + m_scene.EventManager.OnSceneGroupMove += OnSceneGroupMove; + m_dialogMod = m_scene.RequestModuleInterface(); + } + } + + public void RemoveRegion(Scene scene) + { + if (ENABLED) + { + m_scene.EventManager.OnSceneGroupMove -= OnSceneGroupMove; + } + } + + public void RegionLoaded(Scene scene) {} + + public void Close() + { + RemoveRegion(m_scene); + } + + private void OnObjectAddedToScene(SceneObjectGroup so) + { + so.RootPart.DynObjs.Add(Name, new MyObject()); + } + + private bool OnSceneGroupMove(UUID groupId, Vector3 delta) + { + SceneObjectGroup so = m_scene.GetSceneObjectGroup(groupId); + + if (so == null) + return true; + + object rawObj = so.RootPart.DynObjs.Get(Name); + + if (rawObj != null) + { + MyObject myObj = (MyObject)rawObj; + + m_dialogMod.SendGeneralAlert(string.Format("{0} {1} moved {2} times", so.Name, so.UUID, ++myObj.Moves)); + } + + return true; + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 3e9a6fa..ee7c4f4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -129,6 +129,27 @@ namespace OpenSim.Region.Framework.Scenes /// Dynamic attributes can be created and deleted as required. /// public DAMap DynAttrs { get; set; } + + private DOMap m_dynObjs; + + /// + /// Dynamic objects that can be created and deleted as required. + /// + public DOMap DynObjs + { + get + { + if (m_dynObjs == null) + m_dynObjs = new DOMap(); + + return m_dynObjs; + } + + set + { + m_dynObjs = value; + } + } /// /// Is this a root part? @@ -348,6 +369,7 @@ namespace OpenSim.Region.Framework.Scenes Rezzed = DateTime.UtcNow; Description = String.Empty; DynAttrs = new DAMap(); + DynObjs = new DOMap(); // Prims currently only contain a single folder (Contents). From looking at the Second Life protocol, // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from -- cgit v1.1 From 48d41ef3076eb4c2a8c4a67d811630ab7b498469 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 13 Mar 2013 23:25:56 +0000 Subject: Remove unnecessary instation of DOMap() in SOP from commit 5c53660 since this is being done lazily --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index ee7c4f4..a8b63fe 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -369,7 +369,6 @@ namespace OpenSim.Region.Framework.Scenes Rezzed = DateTime.UtcNow; Description = String.Empty; DynAttrs = new DAMap(); - DynObjs = new DOMap(); // Prims currently only contain a single folder (Contents). From looking at the Second Life protocol, // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from -- cgit v1.1 From 43220afda2a69e7849c2ab9f98dcbd61a3da218b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 13 Mar 2013 23:42:14 +0000 Subject: Improve DAExampleModule to show current necessary locking to avoid race conditions with a serialization thread. --- .../Framework/DynamicAttributes/DAExampleModule.cs | 24 ++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs index 37131b9..f874495 100644 --- a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs +++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs @@ -85,19 +85,27 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DAExampleModule { OSDMap attrs = null; SceneObjectPart sop = m_scene.GetSceneObjectPart(groupId); + + if (sop == null) + return true; + if (!sop.DynAttrs.TryGetValue(Name, out attrs)) attrs = new OSDMap(); OSDInteger newValue; - - if (!attrs.ContainsKey("moves")) - newValue = new OSDInteger(1); - else - newValue = new OSDInteger(((OSDInteger)attrs["moves"]).AsInteger() + 1); - - attrs["moves"] = newValue; - sop.DynAttrs[Name] = attrs; + // We have to lock on the entire dynamic attributes map to avoid race conditions with serialization code. + lock (sop.DynAttrs) + { + if (!attrs.ContainsKey("moves")) + newValue = new OSDInteger(1); + else + newValue = new OSDInteger(attrs["moves"].AsInteger() + 1); + + attrs["moves"] = newValue; + + sop.DynAttrs[Name] = attrs; + } m_dialogMod.SendGeneralAlert(string.Format("{0} {1} moved {2} times", sop.Name, sop.UUID, newValue)); -- cgit v1.1 From e9c394fb4ed56ffb931a0161b8c6fdc929b38058 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 21:23:48 +0000 Subject: Make llGetObjectDetails() return the correct world rotation for a sitting avatar This addresses http://opensimulator.org/mantis/view.php?id=6567 This creates a ScenePresence.GetWorldRotation() with the same semantics as SOP.GetWorldRotation() SP.Rotation can't be used since it's relative to the sat upon prim if the avatar is sitting. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 40 +++++++++++++++++++--- .../Shared/Api/Implementation/LSL_Api.cs | 2 +- 2 files changed, 36 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index a7c7539..82bb759 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -559,16 +559,28 @@ namespace OpenSim.Region.Framework.Scenes private Quaternion m_bodyRot = Quaternion.Identity; + /// + /// The rotation of the avatar. + /// + /// + /// If the avatar is not sitting, this is with respect to the world + /// If the avatar is sitting, this is a with respect to the part that it's sitting upon (a local rotation). + /// If you always want the world rotation, use GetWorldRotation() + /// public Quaternion Rotation { - get { return m_bodyRot; } + get + { + return m_bodyRot; + } + set { m_bodyRot = value; + if (PhysicsActor != null) - { PhysicsActor.Orientation = m_bodyRot; - } + // m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); } } @@ -608,6 +620,26 @@ namespace OpenSim.Region.Framework.Scenes set { m_health = value; } } + /// + /// Gets the world rotation of this presence. + /// + /// + /// Unlike Rotation, this returns the world rotation no matter whether the avatar is sitting on a prim or not. + /// + /// + public Quaternion GetWorldRotation() + { + if (IsSatOnObject) + { + SceneObjectPart sitPart = ParentPart; + + if (sitPart != null) + return sitPart.GetWorldRotation() * Rotation; + } + + return Rotation; + } + public void AdjustKnownSeeds() { Dictionary seeds; @@ -709,8 +741,6 @@ namespace OpenSim.Region.Framework.Scenes #endregion - - #region Constructor(s) public ScenePresence( diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index dd7ee24..47f8758 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -10518,7 +10518,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); break; case ScriptBaseClass.OBJECT_ROT: - ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); + ret.Add(new LSL_Rotation(av.GetWorldRotation())); break; case ScriptBaseClass.OBJECT_VELOCITY: ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); -- cgit v1.1 From ad9bd3fe93e3d48b17ca28b3e036fe39991f2203 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 21:46:29 +0000 Subject: Fix sensors, llGetRootRotation(), llGet*Param() and other functions to use the world rotation if the avatar to which they are attached is sitting --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 4 ++-- .../Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 9 +++------ .../Shared/Api/Implementation/Plugins/SensorRepeat.cs | 4 ++-- 3 files changed, 7 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 47f8758..d88e416 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2174,7 +2174,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) q = avatar.CameraRotation; // Mouselook else - q = avatar.Rotation; // Currently infrequently updated so may be inaccurate + q = avatar.GetWorldRotation(); // Currently infrequently updated so may be inaccurate } else q = part.ParentGroup.GroupRotation; // Likely never get here but just in case @@ -7831,7 +7831,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) q = avatar.CameraRotation; // Mouselook else - q = avatar.Rotation; // Currently infrequently updated so may be inaccurate + q = avatar.GetWorldRotation(); // Currently infrequently updated so may be inaccurate else q = m_host.ParentGroup.GroupRotation; // Likely never get here but just in case } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 48c6b50..bd83f02 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2578,18 +2578,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { UUID npcId; if (!UUID.TryParse(npc.m_string, out npcId)) - return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W); + return new LSL_Rotation(Quaternion.Identity); if (!npcModule.CheckPermissions(npcId, m_host.OwnerID)) - return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W); + return new LSL_Rotation(Quaternion.Identity); ScenePresence sp = World.GetScenePresence(npcId); if (sp != null) - { - Quaternion rot = sp.Rotation; - return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W); - } + return new LSL_Rotation(sp.GetWorldRotation()); } return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs index dd45406..88ab515 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs @@ -353,7 +353,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins // Position of a sensor in a child prim attached to an avatar // will be still wrong. ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); - q = avatar.Rotation * q; + q = avatar.GetWorldRotation() * q; } LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); @@ -480,7 +480,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins // Position of a sensor in a child prim attached to an avatar // will be still wrong. ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); - q = avatar.Rotation * q; + q = avatar.GetWorldRotation() * q; } LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); -- cgit v1.1 From f84072827384f7ea7c50f77eab23c141cae6cd9e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 21:57:43 +0000 Subject: refactor: use cleaner LSL_Rotation quaternion constructor in LSL_Api.GetPartRot() --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index d88e416..854169b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2181,10 +2181,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } else q = part.ParentGroup.GroupRotation; // just the group rotation - return new LSL_Rotation(q.X, q.Y, q.Z, q.W); + + return new LSL_Rotation(q); } - q = part.GetWorldRotation(); - return new LSL_Rotation(q.X, q.Y, q.Z, q.W); + + return new LSL_Rotation(part.GetWorldRotation()); } public LSL_Rotation llGetLocalRot() -- cgit v1.1 From c3e081a5ca165b197fcb5c6e407f0174931c8f7c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 22:00:04 +0000 Subject: Fix minor race condition in llGetLocalRot() where inconsistent results could be returned if the prim was rotating during the call --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 854169b..c9d0d91 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2191,7 +2191,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Rotation llGetLocalRot() { m_host.AddScriptLPS(1); - return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); + + return new LSL_Rotation(m_host.RotationOffset); } public void llSetForce(LSL_Vector force, int local) -- cgit v1.1 From ffbbe29229c2122502a3c173bd40a870d2a3d631 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 22:01:24 +0000 Subject: refactor: Use LSL_Vector(Vector3) constructor in llGetTorque() --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index c9d0d91..e55e215 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2287,8 +2287,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector llGetTorque() { m_host.AddScriptLPS(1); - Vector3 torque = m_host.ParentGroup.GetTorque(); - return new LSL_Vector(torque.X,torque.Y,torque.Z); + + return new LSL_Vector(m_host.ParentGroup.GetTorque()); } public void llSetForceAndTorque(LSL_Vector force, LSL_Vector torque, int local) -- cgit v1.1 From 04e806036ff6fe9246f7c1ab91f162cb5168bb07 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 22:02:43 +0000 Subject: refactor: Use LSL_Vector(Vector3) constructor in llGetVel() --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index e55e215..aadfe72 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2314,7 +2314,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api vel = m_host.Velocity; } - return new LSL_Vector(vel.X, vel.Y, vel.Z); + return new LSL_Vector(vel); } public LSL_Vector llGetAccel() -- cgit v1.1 From 1774c631cb441458596f3adde3474518d883a7e6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 22:04:11 +0000 Subject: Fix minor race condition in llGetOmega() where a call whilst a prim was changing angular velocity could return inconsistent results --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index aadfe72..29bc9c7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2320,7 +2320,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector llGetAccel() { m_host.AddScriptLPS(1); - return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); + + return new LSL_Vector(m_host.Acceleration); } public LSL_Vector llGetOmega() -- cgit v1.1 From 895aa7346f5ba44055225cb4d11351f953ce458e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 22:07:07 +0000 Subject: Fix minor race condition in llGetOmega() where inconsistent results could be returned (accidentally stated that commit 1774c631 was this fix). Commit 1774c631 was actually a fix for a similar minor race condition in llGetAccel() --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 29bc9c7..d25f673 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2327,7 +2327,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector llGetOmega() { m_host.AddScriptLPS(1); - return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); + + return new LSL_Vector(m_host.AngularVelocity); } public LSL_Float llGetTimeOfDay() -- cgit v1.1 From ff6a16b46e334995bce589fe9c9f3854381ee167 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 22:09:05 +0000 Subject: Fix a minor race condition in llInstantMessage() where slightly wrong origin co-ordinates could be given for a fast moving prim --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index d25f673..267dc96 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3105,13 +3105,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api msg.ParentEstateID = 0; //ParentEstateID; msg.Position = new Vector3(m_host.AbsolutePosition); msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; + + Vector3 pos = m_host.AbsolutePosition; msg.binaryBucket = Util.StringToBytes256( "{0}/{1}/{2}/{3}", World.RegionInfo.RegionName, - (int)Math.Floor(m_host.AbsolutePosition.X), - (int)Math.Floor(m_host.AbsolutePosition.Y), - (int)Math.Floor(m_host.AbsolutePosition.Z)); + (int)Math.Floor(pos.X), + (int)Math.Floor(pos.Y), + (int)Math.Floor(pos.Z)); if (m_TransferModule != null) { -- cgit v1.1 From 7b85279dbaf3e73ed45ecafe6a373565643e9a9e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 22:14:32 +0000 Subject: refactor: Use LSL_Vector(Vector3) constructor in llGetCenterOfMass() --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 267dc96..aca0132 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4877,8 +4877,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector llGetCenterOfMass() { m_host.AddScriptLPS(1); - Vector3 center = m_host.GetCenterOfMass(); - return new LSL_Vector(center.X,center.Y,center.Z); + + return new LSL_Vector(m_host.GetCenterOfMass()); } public LSL_List llListSort(LSL_List src, int stride, int ascending) -- cgit v1.1 From 3c9bea1e3fbe0bb457bcc227d0420125c00ce832 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 22:22:10 +0000 Subject: Fix minor race conditions in llTeleportAgent(), llTeleportAgentGlobalCoords(), llEjectFromLand() and llOverMyLand() where the wrong parcel could be identified for very fast moving avatars. --- .../Shared/Api/Implementation/LSL_Api.cs | 35 +++++++++++++--------- 1 file changed, 21 insertions(+), 14 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index aca0132..8415feb 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4202,9 +4202,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (destination == String.Empty) destination = World.RegionInfo.RegionName; + Vector3 pos = presence.AbsolutePosition; + // agent must be over the owners land - if (m_host.OwnerID == World.LandChannel.GetLandObject( - presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) + if (m_host.OwnerID == World.LandChannel.GetLandObject(pos.X, pos.Y).LandData.OwnerID) { DoLLTeleport(presence, destination, targetPos, targetLookAt); } @@ -4234,9 +4235,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // agent must not be a god if (presence.GodLevel >= 200) return; + Vector3 pos = presence.AbsolutePosition; + // agent must be over the owners land - if (m_host.OwnerID == World.LandChannel.GetLandObject( - presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) + if (m_host.OwnerID == World.LandChannel.GetLandObject(pos.X, pos.Y).LandData.OwnerID) { World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); } @@ -5865,8 +5867,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ScenePresence presence = World.GetScenePresence(agentID); if (presence != null) { + Vector3 pos = presence.AbsolutePosition; + // agent must be over the owners land - ILandObject land = World.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y); + ILandObject land = World.LandChannel.GetLandObject(pos.X, pos.Y); if (land == null) return; @@ -5888,19 +5892,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ScenePresence presence = World.GetScenePresence(key); if (presence != null) // object is an avatar { - if (m_host.OwnerID - == World.LandChannel.GetLandObject( - presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) + Vector3 pos = presence.AbsolutePosition; + + if (m_host.OwnerID == World.LandChannel.GetLandObject(pos.X, pos.Y).LandData.OwnerID) return 1; } else // object is not an avatar { SceneObjectPart obj = World.GetSceneObjectPart(key); + if (obj != null) - if (m_host.OwnerID - == World.LandChannel.GetLandObject( - obj.AbsolutePosition.X, obj.AbsolutePosition.Y).LandData.OwnerID) + { + Vector3 pos = obj.AbsolutePosition; + + if (m_host.OwnerID == World.LandChannel.GetLandObject(pos.X, pos.Y).LandData.OwnerID) return 1; + } } } @@ -5979,7 +5986,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // or // if the object is owned by a person with estate access. - ILandObject parcel = World.LandChannel.GetLandObject(av.AbsolutePosition.X, av.AbsolutePosition.Y); + Vector3 pos = av.AbsolutePosition; + + ILandObject parcel = World.LandChannel.GetLandObject(pos.X, pos.Y); if (parcel != null) { if (m_host.OwnerID == parcel.LandData.OwnerID || @@ -5991,9 +6000,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } } - } - } public LSL_Vector llGroundSlope(LSL_Vector offset) -- cgit v1.1 From f8c24b2a61e9f927620fee8e06457f70ba6e2e82 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 22:26:37 +0000 Subject: minor: Reuse ground LSL_Vector in llGroundSlope() rather than creating a new one. --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 8415feb..6414f35 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -6006,6 +6006,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector llGroundSlope(LSL_Vector offset) { m_host.AddScriptLPS(1); + //Get the slope normal. This gives us the equation of the plane tangent to the slope. LSL_Vector vsn = llGroundNormal(offset); @@ -6016,7 +6017,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api vsl.Normalize(); //Normalization might be overkill here - return new LSL_Vector(vsl.X, vsl.Y, vsl.Z); + vsn.x = vsl.X; + vsn.y = vsl.Y; + vsn.z = vsl.Z; + + return vsn; } public LSL_Vector llGroundNormal(LSL_Vector offset) -- cgit v1.1 From e6eb9146756a9c49aef018cdfd403c10c2bc82d6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 22:28:40 +0000 Subject: refactor: use LSL_Vector(Vector3) constructor in llGroundNormal() --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 6414f35..6aae784 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -6071,7 +6071,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api //I believe the crossproduct of two normalized vectors is a normalized vector so //this normalization may be overkill - return new LSL_Vector(vsn.X, vsn.Y, vsn.Z); + return new LSL_Vector(vsn); } public LSL_Vector llGroundContour(LSL_Vector offset) -- cgit v1.1 From e7603f98b7353a2d1603094d206ad6f80b837371 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 22:31:07 +0000 Subject: Fix minor race conditions in detecting current parcel for llAddToLandPassList(), llSetParcelMusicURL() and llGetParcelMusicURL() for moving prims --- .../Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 6aae784..f95ecb4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -6571,7 +6571,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); UUID key; - ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); + Vector3 pos = m_host.AbsolutePosition; + + ILandObject land = World.LandChannel.GetLandObject(pos.X, pos.Y); if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) { int expires = 0; @@ -7800,7 +7802,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); + Vector3 pos = m_host.AbsolutePosition; + ILandObject land = World.LandChannel.GetLandObject(pos.X, pos.Y); if (land.LandData.OwnerID != m_host.OwnerID) return; @@ -7814,7 +7817,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); + Vector3 pos = m_host.AbsolutePosition; + ILandObject land = World.LandChannel.GetLandObject(pos.X, pos.Y); if (land.LandData.OwnerID != m_host.OwnerID) return String.Empty; -- cgit v1.1 From dd6f1fc637f0efb44e0aadf7424314993f100a32 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 22:33:44 +0000 Subject: Fix minor race condition in llGetRootPosition() where inconsistent results could be returned for moving prims --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index f95ecb4..559744f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -7829,8 +7829,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector llGetRootPosition() { m_host.AddScriptLPS(1); - return new LSL_Vector(m_host.ParentGroup.AbsolutePosition.X, m_host.ParentGroup.AbsolutePosition.Y, - m_host.ParentGroup.AbsolutePosition.Z); + + return new LSL_Vector(m_host.ParentGroup.AbsolutePosition); } /// -- cgit v1.1 From a6f8638174dde7c32bef4659164a71b47c1c6c71 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 22:34:48 +0000 Subject: refactor: use LSL_Rotation(Quaternion) constructor in lLGetRootRotation() --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 559744f..19eec71 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -7859,7 +7859,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } else q = m_host.ParentGroup.GroupRotation; // just the group rotation - return new LSL_Rotation(q.X, q.Y, q.Z, q.W); + + return new LSL_Rotation(q); } public LSL_String llGetObjectDesc() -- cgit v1.1 From b23009e480cee996d2d2808b22ea4dfd76a45e03 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 22:35:41 +0000 Subject: Fix minor race condition in llGetGeometricCenter() if this was changing whilst the function was called. --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 19eec71..deaaa8a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -7967,7 +7967,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector llGetGeometricCenter() { - return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); + return new LSL_Vector(m_host.GetGeometricCenter()); } public LSL_List llGetPrimitiveParams(LSL_List rules) -- cgit v1.1 From 2a81eb8d45b4c2b1866479eec1bc906d0d6cf1a7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 22:42:11 +0000 Subject: Fix minor race conditions in LSL_Api.GetPrimParams() for PRIM_POSITION, PRIM_SIZE and PRIM_ROT_LOCAL This function is used by all the various ll*Params() and os*Params() functions --- .../Shared/Api/Implementation/LSL_Api.cs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index deaaa8a..8d5eea3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -8054,23 +8054,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api break; case (int)ScriptBaseClass.PRIM_POSITION: - LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, - part.AbsolutePosition.Y, - part.AbsolutePosition.Z); + LSL_Vector v = new LSL_Vector(part.AbsolutePosition); + // For some reason, the part.AbsolutePosition.* values do not change if the // linkset is rotated; they always reflect the child prim's world position // as though the linkset is unrotated. This is incompatible behavior with SL's // implementation, so will break scripts imported from there (not to mention it // makes it more difficult to determine a child prim's actual inworld position). - if (part.ParentID != 0) - v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition(); + if (!part.IsRoot) + { + LSL_Vector rootPos = new LSL_Vector(m_host.ParentGroup.AbsolutePosition); + v = ((v - rootPos) * llGetRootRotation()) + rootPos; + } + res.Add(v); break; case (int)ScriptBaseClass.PRIM_SIZE: - res.Add(new LSL_Vector(part.Scale.X, - part.Scale.Y, - part.Scale.Z)); + res.Add(new LSL_Vector(part.Scale)); break; case (int)ScriptBaseClass.PRIM_ROTATION: @@ -8384,8 +8385,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api case (int)ScriptBaseClass.PRIM_DESC: res.Add(new LSL_String(part.Description)); break; - case (int)ScriptBaseClass.PRIM_ROT_LOCAL: - res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); + case (int)ScriptBaseClass.PRIM_ROT_LOCAL: + res.Add(new LSL_Rotation(part.RotationOffset)); break; case (int)ScriptBaseClass.PRIM_POS_LOCAL: res.Add(new LSL_Vector(GetPartLocalPos(part))); -- cgit v1.1 From d4b109b4c4c9bc548bfbfa4b0c6d021cfa38bee3 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 22:45:00 +0000 Subject: Fix minor race condition in llParcelMediaCommandList() where a parcel could be misidentified for a moving prim --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 8d5eea3..1b98bd8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -9595,7 +9595,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // according to the docs, this command only works if script owner and land owner are the same // lets add estate owners and gods, too, and use the generic permission check. - ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); + Vector3 pos = m_host.AbsolutePosition; + + ILandObject landObject = World.LandChannel.GetLandObject(pos.X, pos.Y); if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia)) return; bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)? -- cgit v1.1 From 114fd042ded4b2b5e27866810c7af05a6568fc87 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 22:46:27 +0000 Subject: Fix minor race condition in llGetCameraPos() where an inconsistent post could be returned for a moving camera --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 1b98bd8..b1134e7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -9916,21 +9916,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); if (m_item.PermsGranter == UUID.Zero) - return new LSL_Vector(); + return Vector3.Zero; if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) { ShoutError("No permissions to track the camera"); - return new LSL_Vector(); + return Vector3.Zero; } ScenePresence presence = World.GetScenePresence(m_host.OwnerID); if (presence != null) { - LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); + LSL_Vector pos = new LSL_Vector(presence.CameraPosition); return pos; } - return new LSL_Vector(); + + return Vector3.Zero; } public LSL_Rotation llGetCameraRot() -- cgit v1.1 From c09f4ff4834aa2064489ef5376e51352dcdc6966 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 22:49:08 +0000 Subject: Fix minor race condition in llGetCameraRot() where inconsistent information could be returned for a rotating camera --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index b1134e7..42f9c8d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -9939,21 +9939,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); if (m_item.PermsGranter == UUID.Zero) - return new LSL_Rotation(); + return Quaternion.Identity; if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) { ShoutError("No permissions to track the camera"); - return new LSL_Rotation(); + return Quaternion.Identity; } ScenePresence presence = World.GetScenePresence(m_host.OwnerID); if (presence != null) { - return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); + return new LSL_Rotation(presence.CameraRotation); } - return new LSL_Rotation(); + return Quaternion.Identity; } /// -- cgit v1.1 From c1115e4c2e8a35fee3287add748881f3718deba5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 22:56:26 +0000 Subject: Add ILandChannel.GetLandObject(Vector3 position) as this is a very common input to GetLandObject() This conforms to the existing ILandChannel.ParcelsNearPoint() method --- OpenSim/Region/CoreModules/World/Land/LandChannel.cs | 5 +++++ .../Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs | 5 +++++ 2 files changed, 10 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs index 7fc358d..73c592d 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs @@ -95,6 +95,11 @@ namespace OpenSim.Region.CoreModules.World.Land return null; } + public ILandObject GetLandObject(Vector3 position) + { + return GetLandObject(position.X, position.Y); + } + public ILandObject GetLandObject(int x, int y) { if (m_landManagementModule != null) diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs index a133e51..b4abc1d 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs @@ -68,6 +68,11 @@ public class RegionCombinerLargeLandChannel : ILandChannel RootRegionLandChannel.Clear(setupDefaultParcel); } + public ILandObject GetLandObject(Vector3 position) + { + return GetLandObject(position.X, position.Y); + } + public ILandObject GetLandObject(int x, int y) { //m_log.DebugFormat("[BIGLANDTESTINT]: <{0},{1}>", x, y); -- cgit v1.1 From ca99f418d8c09a9364d802d6cbd144c188c7b5cf Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 23:05:21 +0000 Subject: refactor: Use ILandChannel.GetLandObject(Vector3) in LSL_Api rather than having to continually take intermediate Vector3s to avoid race conditions --- .../Shared/Api/Implementation/LSL_Api.cs | 62 ++++++++-------------- 1 file changed, 21 insertions(+), 41 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 42f9c8d..9ab92c9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4176,13 +4176,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (presence != null) { // agent must be over the owners land - if (m_host.OwnerID == World.LandChannel.GetLandObject( - presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) + if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) { World.TeleportClientHome(agentId, presence.ControllingClient); } } } + ScriptSleep(5000); } @@ -4202,10 +4202,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (destination == String.Empty) destination = World.RegionInfo.RegionName; - Vector3 pos = presence.AbsolutePosition; - // agent must be over the owners land - if (m_host.OwnerID == World.LandChannel.GetLandObject(pos.X, pos.Y).LandData.OwnerID) + if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) { DoLLTeleport(presence, destination, targetPos, targetLookAt); } @@ -4235,10 +4233,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // agent must not be a god if (presence.GodLevel >= 200) return; - Vector3 pos = presence.AbsolutePosition; - // agent must be over the owners land - if (m_host.OwnerID == World.LandChannel.GetLandObject(pos.X, pos.Y).LandData.OwnerID) + if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) { World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); } @@ -4442,7 +4438,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { if (pushrestricted) { - ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos.X, PusheePos.Y); + ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos); // We didn't find the parcel but region is push restricted so assume it is NOT ok if (targetlandObj == null) @@ -4457,7 +4453,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } else { - ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos.X, PusheePos.Y); + ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos); if (targetlandObj == null) { // We didn't find the parcel but region isn't push restricted so assume it's ok @@ -5715,8 +5711,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID id = UUID.Zero; if (parcel || parcelOwned) { - pos = m_host.ParentGroup.RootPart.GetWorldPosition(); - land = World.LandChannel.GetLandObject(pos.X, pos.Y); + land = World.LandChannel.GetLandObject(m_host.ParentGroup.RootPart.GetWorldPosition()); if (land == null) { id = UUID.Zero; @@ -5742,8 +5737,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { if (!regionWide) { - pos = ssp.AbsolutePosition; - land = World.LandChannel.GetLandObject(pos.X, pos.Y); + land = World.LandChannel.GetLandObject(ssp.AbsolutePosition); if (land != null) { if (parcelOwned && land.LandData.OwnerID == id || @@ -5867,10 +5861,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ScenePresence presence = World.GetScenePresence(agentID); if (presence != null) { - Vector3 pos = presence.AbsolutePosition; - // agent must be over the owners land - ILandObject land = World.LandChannel.GetLandObject(pos.X, pos.Y); + ILandObject land = World.LandChannel.GetLandObject(presence.AbsolutePosition); if (land == null) return; @@ -5892,9 +5884,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ScenePresence presence = World.GetScenePresence(key); if (presence != null) // object is an avatar { - Vector3 pos = presence.AbsolutePosition; - - if (m_host.OwnerID == World.LandChannel.GetLandObject(pos.X, pos.Y).LandData.OwnerID) + if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) return 1; } else // object is not an avatar @@ -5903,9 +5893,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (obj != null) { - Vector3 pos = obj.AbsolutePosition; - - if (m_host.OwnerID == World.LandChannel.GetLandObject(pos.X, pos.Y).LandData.OwnerID) + if (m_host.OwnerID == World.LandChannel.GetLandObject(obj.AbsolutePosition).LandData.OwnerID) return 1; } } @@ -5985,10 +5973,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // if the land is group owned and the object is group owned by the same group // or // if the object is owned by a person with estate access. - - Vector3 pos = av.AbsolutePosition; - - ILandObject parcel = World.LandChannel.GetLandObject(pos.X, pos.Y); + ILandObject parcel = World.LandChannel.GetLandObject(av.AbsolutePosition); if (parcel != null) { if (m_host.OwnerID == parcel.LandData.OwnerID || @@ -6571,9 +6556,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); UUID key; - Vector3 pos = m_host.AbsolutePosition; + ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); - ILandObject land = World.LandChannel.GetLandObject(pos.X, pos.Y); if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) { int expires = 0; @@ -7802,8 +7786,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - Vector3 pos = m_host.AbsolutePosition; - ILandObject land = World.LandChannel.GetLandObject(pos.X, pos.Y); + ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); if (land.LandData.OwnerID != m_host.OwnerID) return; @@ -7817,8 +7800,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - Vector3 pos = m_host.AbsolutePosition; - ILandObject land = World.LandChannel.GetLandObject(pos.X, pos.Y); + ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); if (land.LandData.OwnerID != m_host.OwnerID) return String.Empty; @@ -9595,9 +9577,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // according to the docs, this command only works if script owner and land owner are the same // lets add estate owners and gods, too, and use the generic permission check. - Vector3 pos = m_host.AbsolutePosition; - - ILandObject landObject = World.LandChannel.GetLandObject(pos.X, pos.Y); + ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition); if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia)) return; bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)? @@ -10022,7 +10002,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); UUID key; - ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); + ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) { int expires = 0; @@ -10063,7 +10043,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); UUID key; - ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); + ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed)) { if (UUID.TryParse(avatar, out key)) @@ -10090,7 +10070,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); UUID key; - ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); + ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) { if (UUID.TryParse(avatar, out key)) @@ -10352,7 +10332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llResetLandBanList() { m_host.AddScriptLPS(1); - LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).LandData; + LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData; if (land.OwnerID == m_host.OwnerID) { foreach (LandAccessEntry entry in land.ParcelAccessList) @@ -10369,7 +10349,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llResetLandPassList() { m_host.AddScriptLPS(1); - LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).LandData; + LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData; if (land.OwnerID == m_host.OwnerID) { foreach (LandAccessEntry entry in land.ParcelAccessList) -- cgit v1.1 From f8dab4f93fda5aa63bb796adfe64187a7799a7af Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 23:06:54 +0000 Subject: refactor: Use LSL_Vector(Vector3) constructor in llCastRay() --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 9ab92c9..3885ba6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -11462,7 +11462,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api list.Add(new LSL_Integer(linkNum)); if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) - list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z)); + list.Add(new LSL_Vector(result.Normal)); values++; if (values >= count) -- cgit v1.1 From 55204ccde6099652652bbfa315abdd321e96a340 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 23:09:59 +0000 Subject: Fix minor race conditions in OSSL_Api functions where a parcel could be misidentified for moving prims. --- .../Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index bd83f02..dc03ee6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -363,7 +363,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api //OSSL only may be used if object is in the same group as the parcel if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("PARCEL_GROUP_MEMBER")) { - ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); + ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); if (land.LandData.GroupID == m_item.GroupID && land.LandData.GroupID != UUID.Zero) { @@ -374,7 +374,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api //Only Parcelowners may use the function if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("PARCEL_OWNER")) { - ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); + ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); if (land.LandData.OwnerID == ownerID) { @@ -1502,8 +1502,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); - ILandObject land - = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); + ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); if (land.LandData.OwnerID != m_host.OwnerID) return; @@ -1519,8 +1518,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); - ILandObject land - = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); + ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); if (land.LandData.OwnerID != m_host.OwnerID) { -- cgit v1.1 From 56b333f301cc66cf6417c0e4853f1b930e54dbb0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 23:12:58 +0000 Subject: minor: Use more compact libomv primitive constructors in osNpcGetPos() and osNpcGetRot() --- .../Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index dc03ee6..0ab2733 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2513,13 +2513,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ScenePresence sp = World.GetScenePresence(npcId); if (sp != null) - { - Vector3 pos = sp.AbsolutePosition; - return new LSL_Vector(pos.X, pos.Y, pos.Z); - } + return new LSL_Vector(sp.AbsolutePosition); } - return new LSL_Vector(0, 0, 0); + return Vector3.Zero; } public void osNpcMoveTo(LSL_Key npc, LSL_Vector pos) @@ -2587,7 +2584,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return new LSL_Rotation(sp.GetWorldRotation()); } - return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W); + return Quaternion.Identity; } public void osNpcSetRot(LSL_Key npc, LSL_Rotation rotation) -- cgit v1.1 From 0ea0f8aa83eac5ce826483785ac5398286876e17 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 23:16:39 +0000 Subject: Fix bug in osCauseHealing() if called with an avatar ID for an avatar that is not in the scene. --- .../Shared/Api/Implementation/OSSL_Api.cs | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 0ab2733..a6dca61 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -3014,20 +3014,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID avatarId = new UUID(avatar); ScenePresence presence = World.GetScenePresence(avatarId); - Vector3 pos = m_host.GetWorldPosition(); - bool result = World.ScriptDanger(m_host.LocalId, new Vector3((float)pos.X, (float)pos.Y, (float)pos.Z)); - if (result) + + if (presence != null && World.ScriptDanger(m_host.LocalId, m_host.GetWorldPosition())) { - if (presence != null) - { - float health = presence.Health; - health += (float)healing; - if (health >= 100) - { - health = 100; - } - presence.setHealthWithUpdate(health); - } + float health = presence.Health; + health += (float)healing; + + if (health >= 100) + health = 100; + + presence.setHealthWithUpdate(health); } } -- cgit v1.1 From 2fbc08d7dd30b16b3cf5198e175353ea49f08d91 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 23:19:18 +0000 Subject: refactor: minor cleanup in osGetAvatarList() --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index a6dca61..bf1b45b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -3100,8 +3100,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (avatar != null && avatar.UUID != m_host.OwnerID) { result.Add(new LSL_String(avatar.UUID.ToString())); - OpenMetaverse.Vector3 ap = avatar.AbsolutePosition; - result.Add(new LSL_Vector(ap.X, ap.Y, ap.Z)); + result.Add(new LSL_Vector(avatar.AbsolutePosition)); result.Add(new LSL_String(avatar.Name)); } }); -- cgit v1.1 From 12900ea84e699f84943009f2d3218fcf5013c6f9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 23:39:15 +0000 Subject: Log same environment information to Robust log as is already done for simulator logs, for debug purposes --- OpenSim/Region/Application/OpenSim.cs | 1 + OpenSim/Region/Application/OpenSimBase.cs | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 4075edb..11dd052 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -159,6 +159,7 @@ namespace OpenSim MainConsole.Instance = m_console; + LogEnvironmentInformation(); RegisterCommonAppenders(Config.Configs["Startup"]); RegisterConsoleCommands(); diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index 137bd81..c555915 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -134,10 +134,6 @@ namespace OpenSim /// public OpenSimBase(IConfigSource configSource) : base() { - // FIXME: This should be done down in ServerBase but we need to sort out and refactor the log4net - // XmlConfigurator calls first accross servers. - m_log.InfoFormat("[SERVER BASE]: Starting in {0}", m_startupDirectory); - LoadConfigSettings(configSource); } -- cgit v1.1 From 081271e1d7fbf18c918a676d17b40edc8b0b6bfb Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 14 Mar 2013 23:44:16 +0000 Subject: minor: remove mono compiler warnings in LSL_Api.cs --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 3885ba6..cf16571 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -5707,8 +5707,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } ILandObject land; - Vector3 pos; UUID id = UUID.Zero; + if (parcel || parcelOwned) { land = World.LandChannel.GetLandObject(m_host.ParentGroup.RootPart.GetWorldPosition()); @@ -11028,7 +11028,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api World.ForEachScenePresence(delegate(ScenePresence sp) { Vector3 ac = sp.AbsolutePosition - rayStart; - Vector3 bc = sp.AbsolutePosition - rayEnd; +// Vector3 bc = sp.AbsolutePosition - rayEnd; double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); @@ -11118,7 +11118,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api radius = Math.Abs(maxZ); radius = radius*1.413f; Vector3 ac = group.AbsolutePosition - rayStart; - Vector3 bc = group.AbsolutePosition - rayEnd; +// Vector3 bc = group.AbsolutePosition - rayEnd; double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); -- cgit v1.1 From e25ba116a337fe360145ad0a430ee5326d318859 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 15 Mar 2013 00:06:42 +0000 Subject: refactor: make llGetLinkName() and llGetLinkKey() use a common GetLinkEntity() method --- .../Shared/Api/Implementation/LSL_Api.cs | 164 ++++++++++----------- 1 file changed, 80 insertions(+), 84 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index cf16571..8adf4d9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -283,6 +283,80 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } + /// + /// Get a given link entity from a linkset (linked objects and any sitting avatars). + /// + /// + /// If there are any ScenePresence's in the linkset (i.e. because they are sat upon one of the prims), then + /// these are counted as extra entities that correspond to linknums beyond the number of prims in the linkset. + /// The ScenePresences receive linknums in the order in which they sat. + /// + /// + /// The link entity. null if not found. + /// + /// + /// Can be either a non-negative integer or ScriptBaseClass.LINK_THIS (-4). + /// If ScriptBaseClass.LINK_THIS then the entity containing the script is returned. + /// If the linkset has one entity and a linknum of zero is given, then the single entity is returned. If any + /// positive integer is given in this case then null is returned. + /// If the linkset has more than one entity and a linknum greater than zero but equal to or less than the number + /// of entities, then the entity which corresponds to that linknum is returned. + /// Otherwise, if a positive linknum is given which is greater than the number of entities in the linkset, then + /// null is returned. + /// + public ISceneEntity GetLinkEntity(int linknum) + { + if (linknum < 0) + { + if (linknum == ScriptBaseClass.LINK_THIS) + return m_host; + else + return null; + } + + int actualPrimCount = m_host.ParentGroup.PrimCount; + List sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars(); + int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count; + + // Special case for a single prim. In this case the linknum is zero. However, this will not match a single + // prim that has any avatars sat upon it (in which case the root prim is link 1). + if (linknum == 0) + { + if (actualPrimCount == 1 && sittingAvatarIds.Count == 0) + return m_host; + + return null; + } + // Special case to handle a single prim with sitting avatars. GetLinkPart() would only match zero but + // here we must match 1 (ScriptBaseClass.LINK_ROOT). + else if (linknum == ScriptBaseClass.LINK_ROOT && actualPrimCount == 1) + { + if (sittingAvatarIds.Count > 0) + return m_host.ParentGroup.RootPart; + else + return null; + } + else if (linknum <= adjustedPrimCount) + { + if (linknum <= actualPrimCount) + { + return m_host.ParentGroup.GetLinkNumPart(linknum); + } + else + { + ScenePresence sp = World.GetScenePresence(sittingAvatarIds[linknum - actualPrimCount - 1]); + if (sp != null) + return sp; + else + return null; + } + } + else + { + return null; + } + } + public List GetLinkParts(int linkType) { return GetLinkParts(m_host, linkType); @@ -3697,47 +3771,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - if (linknum < 0) - { - if (linknum == ScriptBaseClass.LINK_THIS) - return m_host.UUID.ToString(); - else - return ScriptBaseClass.NULL_KEY; - } - - int actualPrimCount = m_host.ParentGroup.PrimCount; - List sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars(); - int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count; + ISceneEntity entity = GetLinkEntity(linknum); - // Special case for a single prim. In this case the linknum is zero. However, this will not match a single - // prim that has any avatars sat upon it (in which case the root prim is link 1). - if (linknum == 0) - { - if (actualPrimCount == 1 && sittingAvatarIds.Count == 0) - return m_host.UUID.ToString(); - - return ScriptBaseClass.NULL_KEY; - } - // Special case to handle a single prim with sitting avatars. GetLinkPart() would only match zero but - // here we must match 1 (ScriptBaseClass.LINK_ROOT). - else if (linknum == 1 && actualPrimCount == 1) - { - if (sittingAvatarIds.Count > 0) - return m_host.ParentGroup.RootPart.UUID.ToString(); - else - return ScriptBaseClass.NULL_KEY; - } - else if (linknum <= adjustedPrimCount) - { - if (linknum <= actualPrimCount) - return m_host.ParentGroup.GetLinkNumPart(linknum).UUID.ToString(); - else - return sittingAvatarIds[linknum - actualPrimCount - 1].ToString(); - } + if (entity != null) + return entity.UUID.ToString(); else - { return ScriptBaseClass.NULL_KEY; - } } /// @@ -3783,55 +3822,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - if (linknum < 0) - { - if (linknum == ScriptBaseClass.LINK_THIS) - return m_host.Name; - else - return ScriptBaseClass.NULL_KEY; - } - - int actualPrimCount = m_host.ParentGroup.PrimCount; - List sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars(); - int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count; - - // Special case for a single prim. In this case the linknum is zero. However, this will not match a single - // prim that has any avatars sat upon it (in which case the root prim is link 1). - if (linknum == 0) - { - if (actualPrimCount == 1 && sittingAvatarIds.Count == 0) - return m_host.Name; + ISceneEntity entity = GetLinkEntity(linknum); - return ScriptBaseClass.NULL_KEY; - } - // Special case to handle a single prim with sitting avatars. GetLinkPart() would only match zero but - // here we must match 1 (ScriptBaseClass.LINK_ROOT). - else if (linknum == 1 && actualPrimCount == 1) - { - if (sittingAvatarIds.Count > 0) - return m_host.ParentGroup.RootPart.Name; - else - return ScriptBaseClass.NULL_KEY; - } - else if (linknum <= adjustedPrimCount) - { - if (linknum <= actualPrimCount) - { - return m_host.ParentGroup.GetLinkNumPart(linknum).Name; - } - else - { - ScenePresence sp = World.GetScenePresence(sittingAvatarIds[linknum - actualPrimCount - 1]); - if (sp != null) - return sp.Name; - else - return ScriptBaseClass.NULL_KEY; - } - } + if (entity != null) + return entity.Name; else - { return ScriptBaseClass.NULL_KEY; - } } public LSL_Integer llGetInventoryNumber(int type) -- cgit v1.1 From cb74186888d987ec353a257d677aa35b0dc63c0a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 15 Mar 2013 00:27:06 +0000 Subject: Add ParentGroup.HasGroupChanged = true setting to DAExampleModule as this is necessary to get attributes to save (though this probably happens anyway due to the prim move) --- .../Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs index f874495..854e00d 100644 --- a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs +++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs @@ -106,6 +106,8 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DAExampleModule sop.DynAttrs[Name] = attrs; } + + sop.ParentGroup.HasGroupChanged = true; m_dialogMod.SendGeneralAlert(string.Format("{0} {1} moved {2} times", sop.Name, sop.UUID, newValue)); -- cgit v1.1 From d3e76730bd8e89b684cb856bcb7192246f201c2a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 15 Mar 2013 00:49:35 +0000 Subject: Add example code to DOExampleModule to pull data from that previously saved by DAExampleModule when instantiating a dynamc object. --- .../Framework/DynamicAttributes/DAExampleModule.cs | 8 ++++--- .../Framework/DynamicAttributes/DOExampleModule.cs | 26 ++++++++++++++++++++-- 2 files changed, 29 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs index 854e00d..1f1568f 100644 --- a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs +++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs @@ -39,7 +39,7 @@ using OpenSim.Region.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -namespace OpenSim.Region.Framework.DynamicAttributes.DAExampleModule +namespace OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DAExampleModule")] public class DAExampleModule : INonSharedRegionModule @@ -48,6 +48,8 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DAExampleModule private static readonly bool ENABLED = false; // enable for testing + public const string DANamespace = "DAExample Module"; + protected Scene m_scene; protected IDialogModule m_dialogMod; @@ -89,7 +91,7 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DAExampleModule if (sop == null) return true; - if (!sop.DynAttrs.TryGetValue(Name, out attrs)) + if (!sop.DynAttrs.TryGetValue(DANamespace, out attrs)) attrs = new OSDMap(); OSDInteger newValue; @@ -104,7 +106,7 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DAExampleModule attrs["moves"] = newValue; - sop.DynAttrs[Name] = attrs; + sop.DynAttrs[DANamespace] = attrs; } sop.ParentGroup.HasGroupChanged = true; diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs index 71bb3f0..650aa35 100644 --- a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs +++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs @@ -36,6 +36,7 @@ using OpenMetaverse.Packets; using OpenMetaverse.StructuredData; using OpenSim.Framework; using OpenSim.Region.Framework; +using OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -50,9 +51,14 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DOExampleModule public class MyObject { public int Moves { get; set; } + + public MyObject(int moves) + { + Moves = moves; + } } - // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly bool ENABLED = false; // enable for testing @@ -92,7 +98,23 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DOExampleModule private void OnObjectAddedToScene(SceneObjectGroup so) { - so.RootPart.DynObjs.Add(Name, new MyObject()); + SceneObjectPart rootPart = so.RootPart; + + OSDMap attrs; + + int movesSoFar = 0; + +// Console.WriteLine("Here for {0}", so.Name); + + if (rootPart.DynAttrs.TryGetValue(DAExampleModule.DANamespace, out attrs)) + { + movesSoFar = attrs["moves"].AsInteger(); + + m_log.DebugFormat( + "[DO EXAMPLE MODULE]: Found saved moves {0} for {1} in {2}", movesSoFar, so.Name, m_scene.Name); + } + + rootPart.DynObjs.Add(Name, new MyObject(movesSoFar)); } private bool OnSceneGroupMove(UUID groupId, Vector3 delta) -- cgit v1.1 From c10c43d6f6b0a79848b9a655533c27ab58cd2993 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 15 Mar 2013 13:59:34 -0700 Subject: Fix server statistics always reporting zero for total network bytes in/out. Clean up some parameter code in Statistics.Binary. --- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 51 ++++++++++++++-------- .../Framework/Monitoring/ServerStats.cs | 41 ++++++++++------- 2 files changed, 58 insertions(+), 34 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index a7628d2..72516cd 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -278,25 +278,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_shouldCollectStats = false; if (config != null) { - if (config.Contains("enabled") && config.GetBoolean("enabled")) - { - if (config.Contains("collect_packet_headers")) - m_shouldCollectStats = config.GetBoolean("collect_packet_headers"); - if (config.Contains("packet_headers_period_seconds")) - { - binStatsMaxFilesize = TimeSpan.FromSeconds(config.GetInt("region_stats_period_seconds")); - } - if (config.Contains("stats_dir")) - { - binStatsDir = config.GetString("stats_dir"); - } - } - else - { - m_shouldCollectStats = false; - } - } - #endregion BinaryStats + m_shouldCollectStats = config.GetBoolean("Enabled", false); + binStatsMaxFilesize = TimeSpan.FromSeconds(config.GetInt("packet_headers_period_seconds", 300)); + binStatsDir = config.GetString("stats_dir", "."); + m_aggregatedBWStats = config.GetBoolean("aggregatedBWStats", false); + } + #endregion BinaryStats m_throttle = new TokenBucket(null, sceneThrottleBps); ThrottleRates = new ThrottleRates(configSource); @@ -1266,8 +1253,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP static object binStatsLogLock = new object(); static string binStatsDir = ""; + //for Aggregated In/Out BW logging + static bool m_aggregatedBWStats = false; + static long m_aggregatedBytesIn = 0; + static long m_aggregatedByestOut = 0; + static object aggBWStatsLock = new object(); + + public static long AggregatedLLUDPBytesIn + { + get { return m_aggregatedBytesIn; } + } + public static long AggregatedLLUDPBytesOut + { + get {return m_aggregatedByestOut;} + } + public static void LogPacketHeader(bool incoming, uint circuit, byte flags, PacketType packetType, ushort size) { + if (m_aggregatedBWStats) + { + lock (aggBWStatsLock) + { + if (incoming) + m_aggregatedBytesIn += size; + else + m_aggregatedByestOut += size; + } + } + if (!m_shouldCollectStats) return; // Binary logging format is TTTTTTTTCCCCFPPPSS, T=Time, C=Circuit, F=Flags, P=PacketType, S=size diff --git a/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs b/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs index a3d2436..6e74ce0 100644 --- a/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs +++ b/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs @@ -140,9 +140,12 @@ public class ServerStats : ISharedRegionModule } #endregion ISharedRegionModule - private void MakeStat(string pName, string pUnit, string pContainer, Action act) + private void MakeStat(string pName, string pDesc, string pUnit, string pContainer, Action act) { - Stat stat = new Stat(pName, pName, "", pUnit, CategoryServer, pContainer, StatType.Pull, act, StatVerbosity.Info); + string desc = pDesc; + if (desc == null) + desc = pName; + Stat stat = new Stat(pName, pName, desc, pUnit, CategoryServer, pContainer, StatType.Pull, act, StatVerbosity.Info); StatsManager.RegisterStat(stat); RegisteredStats.Add(pName, stat); } @@ -166,16 +169,16 @@ public class ServerStats : ISharedRegionModule StatsManager.RegisterStat(tempStat); RegisteredStats.Add(tempName, tempStat); - MakeStat("TotalProcessorTime", "sec", ContainerProcessor, + MakeStat("TotalProcessorTime", null, "sec", ContainerProcessor, (s) => { s.Value = Process.GetCurrentProcess().TotalProcessorTime.TotalSeconds; }); - MakeStat("UserProcessorTime", "sec", ContainerProcessor, + MakeStat("UserProcessorTime", null, "sec", ContainerProcessor, (s) => { s.Value = Process.GetCurrentProcess().UserProcessorTime.TotalSeconds; }); - MakeStat("PrivilegedProcessorTime", "sec", ContainerProcessor, + MakeStat("PrivilegedProcessorTime", null, "sec", ContainerProcessor, (s) => { s.Value = Process.GetCurrentProcess().PrivilegedProcessorTime.TotalSeconds; }); - MakeStat("Threads", "threads", ContainerProcessor, + MakeStat("Threads", null, "threads", ContainerProcessor, (s) => { s.Value = Process.GetCurrentProcess().Threads.Count; }); } catch (Exception e) @@ -196,8 +199,10 @@ public class ServerStats : ISharedRegionModule string nicInterfaceType = nic.NetworkInterfaceType.ToString(); if (!okInterfaceTypes.Contains(nicInterfaceType)) { - m_log.DebugFormat("{0} Not including stats for network interface '{1}' of type '{2}'. To include, add to [Monitoring]NetworkInterfaceTypes='Ethernet,Loopback'", + m_log.DebugFormat("{0} Not including stats for network interface '{1}' of type '{2}'.", LogHeader, nic.Name, nicInterfaceType); + m_log.DebugFormat("{0} To include, add to comma separated list in [Monitoring]NetworkInterfaceTypes={1}", + LogHeader, NetworkInterfaceTypes); continue; } @@ -206,14 +211,15 @@ public class ServerStats : ISharedRegionModule IPv4InterfaceStatistics nicStats = nic.GetIPv4Statistics(); if (nicStats != null) { - MakeStat("BytesRcvd/" + nic.Name, "KB", ContainerNetwork, + MakeStat("BytesRcvd/" + nic.Name, nic.Name, "KB", ContainerNetwork, (s) => { LookupNic(s, (ns) => { return ns.BytesReceived; }, 1024.0); }); - MakeStat("BytesSent/" + nic.Name, "KB", ContainerNetwork, + MakeStat("BytesSent/" + nic.Name, nic.Name, "KB", ContainerNetwork, (s) => { LookupNic(s, (ns) => { return ns.BytesSent; }, 1024.0); }); - MakeStat("TotalBytes/" + nic.Name, "KB", ContainerNetwork, + MakeStat("TotalBytes/" + nic.Name, nic.Name, "KB", ContainerNetwork, (s) => { LookupNic(s, (ns) => { return ns.BytesSent + ns.BytesReceived; }, 1024.0); }); } } + // TODO: add IPv6 (it may actually happen someday) } } catch (Exception e) @@ -221,13 +227,13 @@ public class ServerStats : ISharedRegionModule m_log.ErrorFormat("{0} Exception creating 'Network Interface': {1}", LogHeader, e); } - MakeStat("ProcessMemory", "MB", ContainerMemory, + MakeStat("ProcessMemory", null, "MB", ContainerMemory, (s) => { s.Value = Process.GetCurrentProcess().WorkingSet64 / 1024d / 1024d; }); - MakeStat("ObjectMemory", "MB", ContainerMemory, + MakeStat("ObjectMemory", null, "MB", ContainerMemory, (s) => { s.Value = GC.GetTotalMemory(false) / 1024d / 1024d; }); - MakeStat("LastMemoryChurn", "MB/sec", ContainerMemory, + MakeStat("LastMemoryChurn", null, "MB/sec", ContainerMemory, (s) => { s.Value = Math.Round(MemoryWatchdog.LastMemoryChurn * 1000d / 1024d / 1024d, 3); }); - MakeStat("AverageMemoryChurn", "MB/sec", ContainerMemory, + MakeStat("AverageMemoryChurn", null, "MB/sec", ContainerMemory, (s) => { s.Value = Math.Round(MemoryWatchdog.AverageMemoryChurn * 1000d / 1024d / 1024d, 3); }); } @@ -263,6 +269,8 @@ public class ServerStats : ISharedRegionModule } } + // Lookup the nic that goes with this stat and set the value by using a fetch action. + // Not sure about closure with delegates inside delegates. private delegate double GetIPv4StatValue(IPv4InterfaceStatistics interfaceStat); private void LookupNic(Stat stat, GetIPv4StatValue getter, double factor) { @@ -275,7 +283,10 @@ public class ServerStats : ISharedRegionModule { IPv4InterfaceStatistics intrStats = nic.GetIPv4Statistics(); if (intrStats != null) - stat.Value = Math.Round(getter(intrStats) / factor, 3); + { + double newVal = Math.Round(getter(intrStats) / factor, 3); + stat.Value = newVal; + } break; } } -- cgit v1.1 From 78b25094dce9bbc79848da1208c44f0d9ebe8c76 Mon Sep 17 00:00:00 2001 From: Vegaslon Date: Mon, 11 Mar 2013 19:08:38 -0400 Subject: BulletSim: Tweak vertical angular attraction to remove double VehicleOrientation application fixing the problem with the vertical attractor pushing vehicles nose first into ground when tilted on side. Signed-off-by: Robert Adams --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 235cefc..d347159 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -1335,7 +1335,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 unscaledContribVerticalErrorV = vertContributionV; // DEBUG DEBUG vertContributionV /= m_verticalAttractionTimescale; - VehicleRotationalVelocity += vertContributionV * VehicleOrientation; + VehicleRotationalVelocity += vertContributionV; VDetailLog("{0}, MoveAngular,verticalAttraction,,origRotVW={1},vertError={2},unscaledV={3},eff={4},ts={5},vertContribV={6}", Prim.LocalID, origRotVelW, verticalError, unscaledContribVerticalErrorV, -- cgit v1.1 From 7e5d5537815d5626387d8638da769192ab3c7ca8 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 15 Mar 2013 23:46:49 +0000 Subject: Make the LSL memory functions virtual so script engines can override them if they have different memory management. --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 8adf4d9..f07b645 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -6068,7 +6068,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return m_host.ParentGroup.AttachmentPoint; } - public LSL_Integer llGetFreeMemory() + public virtual LSL_Integer llGetFreeMemory() { m_host.AddScriptLPS(1); // Make scripts designed for LSO happy @@ -11560,7 +11560,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return 16384; } - public LSL_Integer llGetUsedMemory() + public virtual LSL_Integer llGetUsedMemory() { m_host.AddScriptLPS(1); // The value returned for LSO scripts in SL @@ -11790,4 +11790,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } } -} \ No newline at end of file +} -- cgit v1.1 From fc84ebb819b590099bbfa5bd357e886ce7460063 Mon Sep 17 00:00:00 2001 From: Vegaslon Date: Sat, 16 Mar 2013 17:16:01 -0400 Subject: BulletSim: Working Implementation of Angular Banking for Vehicles (Not SL Grade, Other features when implemented should slow it down for now be Strong with Vertical Angular attraction setting and conservative with Angular Velocity on X axis) Signed-off-by: Robert Adams --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 33 +++++++++++----------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index d347159..96eaa6b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -143,7 +143,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin { enableAngularVerticalAttraction = true; enableAngularDeflection = false; - enableAngularBanking = false; + enableAngularBanking = true; if (BSParam.VehicleDebuggingEnabled) { enableAngularVerticalAttraction = true; @@ -1280,11 +1280,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement // TODO: This is here because this is where ODE put it but documentation says it // is a linear effect. Where should this check go? - if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) - { - angularMotorContributionV.X = 0f; - angularMotorContributionV.Y = 0f; - } + //if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) + // { + // angularMotorContributionV.X = 0f; + // angularMotorContributionV.Y = 0f; + // } VehicleRotationalVelocity += angularMotorContributionV * VehicleOrientation; VDetailLog("{0}, MoveAngular,angularTurning,angularMotorContrib={1}", Prim.LocalID, angularMotorContributionV); @@ -1437,24 +1437,25 @@ namespace OpenSim.Region.Physics.BulletSPlugin // As the vehicle rolls to the right or left, the Y value will increase from // zero (straight up) to 1 or -1 (full tilt right or left) Vector3 rollComponents = Vector3.UnitZ * VehicleOrientation; - // Figure out the yaw value for this much roll. // Squared because that seems to give a good value - float yawAngle = (float)Math.Asin(rollComponents.Y * rollComponents.Y) * m_bankingEfficiency; - + // float yawAngle = (float)Math.Asin(rollComponents.X * rollComponents.X) * m_bankingEfficiency; + float yawAngle = m_angularMotorDirection.X * m_bankingEfficiency; // actual error = static turn error + dynamic turn error - float mixedYawAngle = yawAngle * (1f - m_bankingMix) + yawAngle * m_bankingMix * VehicleForwardSpeed; - - // TODO: the banking effect should not go to infinity but what to limit it to? - mixedYawAngle = ClampInRange(-20f, mixedYawAngle, 20f); + float mixedYawAngle =(yawAngle * (1f - m_bankingMix)) + ((yawAngle * m_bankingMix) * VehicleForwardSpeed); + // TODO: the banking effect should not go to infinity but what to limit it to? and what should happen when this is + // being added to a user defined yaw that is already PI*4? + mixedYawAngle = ClampInRange(-12, mixedYawAngle, 12); // Build the force vector to change rotation from what it is to what it should be bankingContributionV.Z = -mixedYawAngle; - // Don't do it all at once. - bankingContributionV /= m_bankingTimescale; + // Don't do it all at once. 60 becouse 1 second is too fast with most user defined roll as PI*4 + bankingContributionV /= m_bankingTimescale*60; - VehicleRotationalVelocity += bankingContributionV * VehicleOrientation; + //VehicleRotationalVelocity += bankingContributionV * VehicleOrientation; + VehicleRotationalVelocity += bankingContributionV; + VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},rollComp={3},yAng={4},mYAng={5},ret={6}", Prim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, bankingContributionV); -- cgit v1.1 From 464201b41d5f5fdd7c88ab5e95dd7b6fbae6d766 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 16 Mar 2013 15:34:07 -0700 Subject: BulletSim: add INI parameter for angular banking timescale fudge parameter. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 12 ++++++------ OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 7 ++++++- 2 files changed, 12 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 96eaa6b..38596fa 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -1437,21 +1437,21 @@ namespace OpenSim.Region.Physics.BulletSPlugin // As the vehicle rolls to the right or left, the Y value will increase from // zero (straight up) to 1 or -1 (full tilt right or left) Vector3 rollComponents = Vector3.UnitZ * VehicleOrientation; + // Figure out the yaw value for this much roll. - // Squared because that seems to give a good value - // float yawAngle = (float)Math.Asin(rollComponents.X * rollComponents.X) * m_bankingEfficiency; float yawAngle = m_angularMotorDirection.X * m_bankingEfficiency; // actual error = static turn error + dynamic turn error float mixedYawAngle =(yawAngle * (1f - m_bankingMix)) + ((yawAngle * m_bankingMix) * VehicleForwardSpeed); - // TODO: the banking effect should not go to infinity but what to limit it to? and what should happen when this is - // being added to a user defined yaw that is already PI*4? + + // TODO: the banking effect should not go to infinity but what to limit it to? + // And what should happen when this is being added to a user defined yaw that is already PI*4? mixedYawAngle = ClampInRange(-12, mixedYawAngle, 12); // Build the force vector to change rotation from what it is to what it should be bankingContributionV.Z = -mixedYawAngle; - // Don't do it all at once. 60 becouse 1 second is too fast with most user defined roll as PI*4 - bankingContributionV /= m_bankingTimescale*60; + // Don't do it all at once. Fudge because 1 second is too fast with most user defined roll as PI*4. + bankingContributionV /= m_bankingTimescale * BSParam.VehicleAngularBankingTimescaleFudge; //VehicleRotationalVelocity += bankingContributionV * VehicleOrientation; VehicleRotationalVelocity += bankingContributionV; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 2af8468..77bdacb 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -123,6 +123,7 @@ public static class BSParam public static Vector3 VehicleLinearFactor { get; private set; } public static Vector3 VehicleAngularFactor { get; private set; } public static float VehicleGroundGravityFudge { get; private set; } + public static float VehicleAngularBankingTimescaleFudge { get; private set; } public static bool VehicleDebuggingEnabled { get; private set; } // Linkset implementation parameters @@ -543,10 +544,14 @@ public static class BSParam 0.0f, (s) => { return VehicleRestitution; }, (s,v) => { VehicleRestitution = v; } ), - new ParameterDefn("VehicleGroundGravityFudge", "Factor to multiple gravity if a ground vehicle is probably on the ground (0.0 - 1.0)", + new ParameterDefn("VehicleGroundGravityFudge", "Factor to multiply gravity if a ground vehicle is probably on the ground (0.0 - 1.0)", 0.2f, (s) => { return VehicleGroundGravityFudge; }, (s,v) => { VehicleGroundGravityFudge = v; } ), + new ParameterDefn("VehicleAngularBankingTimescaleFudge", "Factor to multiple angular banking timescale. Tune to increase realism.", + 60.0f, + (s) => { return VehicleAngularBankingTimescaleFudge; }, + (s,v) => { VehicleAngularBankingTimescaleFudge = v; } ), new ParameterDefn("VehicleDebuggingEnable", "Turn on/off vehicle debugging", false, (s) => { return VehicleDebuggingEnabled; }, -- cgit v1.1 From a7a9a8a614549c7492e4954189e9f4df2473ca1e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 18 Mar 2013 20:42:08 +0000 Subject: Fix recent regression where an item worn to an attachment point that was already occupied did not remove the previous attachment (current behaviour) Regression was commit ccd6f4 (Tue Mar 5 23:47:36 2013) Added regression test for this case. --- .../Avatar/Attachments/AttachmentsModule.cs | 178 +++++++++++---------- .../Attachments/Tests/AttachmentsModuleTests.cs | 64 +++++++- 2 files changed, 153 insertions(+), 89 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index b6a7481..2092d6f 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -289,16 +289,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (!Enabled) return false; - if (AttachObjectInternal(sp, group, attachmentPt, silent, temp)) - { - m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID); - return true; - } - - return false; + return AttachObjectInternal(sp, group, attachmentPt, silent, temp, false); } - - private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp) + + /// + /// Internal method which actually does all the work for attaching an object. + /// + /// The object attached. + /// + /// The object to attach. + /// + /// + /// + /// If true then scripts are resumed on the attached object. + private bool AttachObjectInternal( + IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp, bool resumeScripts) { // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", @@ -322,44 +327,44 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return false; } + Vector3 attachPos = group.AbsolutePosition; + + // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should + // be removed when that functionality is implemented in opensim + attachmentPt &= 0x7f; + + // If the attachment point isn't the same as the one previously used + // set it's offset position = 0 so that it appears on the attachment point + // and not in a weird location somewhere unknown. + if (attachmentPt != 0 && attachmentPt != group.AttachmentPoint) + { + attachPos = Vector3.Zero; + } + + // AttachmentPt 0 means the client chose to 'wear' the attachment. + if (attachmentPt == 0) + { + // Check object for stored attachment point + attachmentPt = group.AttachmentPoint; + } + + // if we still didn't find a suitable attachment point....... + if (attachmentPt == 0) + { + // Stick it on left hand with Zero Offset from the attachment point. + attachmentPt = (uint)AttachmentPoint.LeftHand; + attachPos = Vector3.Zero; + } + // Remove any previous attachments List existingAttachments = sp.GetAttachments(attachmentPt); // At the moment we can only deal with a single attachment if (existingAttachments.Count != 0 && existingAttachments[0].FromItemID != UUID.Zero) - DetachSingleAttachmentToInv(sp, group); + DetachSingleAttachmentToInv(sp, existingAttachments[0]); lock (sp.AttachmentsSyncLock) { - Vector3 attachPos = group.AbsolutePosition; - - // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should - // be removed when that functionality is implemented in opensim - attachmentPt &= 0x7f; - - // If the attachment point isn't the same as the one previously used - // set it's offset position = 0 so that it appears on the attachment point - // and not in a weird location somewhere unknown. - if (attachmentPt != 0 && attachmentPt != group.AttachmentPoint) - { - attachPos = Vector3.Zero; - } - - // AttachmentPt 0 means the client chose to 'wear' the attachment. - if (attachmentPt == 0) - { - // Check object for stored attachment point - attachmentPt = group.AttachmentPoint; - } - - // if we still didn't find a suitable attachment point....... - if (attachmentPt == 0) - { - // Stick it on left hand with Zero Offset from the attachment point. - attachmentPt = (uint)AttachmentPoint.LeftHand; - attachPos = Vector3.Zero; - } - group.AttachmentPoint = attachmentPt; group.AbsolutePosition = attachPos; @@ -367,6 +372,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp); AttachToAgent(sp, group, attachmentPt, attachPos, silent); + + if (resumeScripts) + { + // Fire after attach, so we don't get messy perms dialogs + // 4 == AttachedRez + group.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); + group.ResumeScripts(); + } + + // Do this last so that event listeners have access to all the effects of the attachment + m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID); } return true; @@ -391,8 +407,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return null; // m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}", -// (AttachmentPoint)AttachmentPt, itemID, sp.Name); +// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2} in {3}", +// (AttachmentPoint)AttachmentPt, itemID, sp.Name, m_scene.Name); // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should // be removed when that functionality is implemented in opensim @@ -525,6 +541,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return; } +// m_log.DebugFormat( +// "[ATTACHMENTS MODULE]: Detaching object {0} {1} for {2} in {3}", +// so.Name, so.LocalId, sp.Name, m_scene.Name); + // Scripts MUST be snapshotted before the object is // removed from the scene because doing otherwise will // clobber the run flag @@ -846,60 +866,42 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return null; } - // Remove any previous attachments - List attachments = sp.GetAttachments(attachmentPt); - - // At the moment we can only deal with a single attachment - if (attachments.Count != 0) - DetachSingleAttachmentToInv(sp, attachments[0]); - - lock (sp.AttachmentsSyncLock) - { // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}", // objatt.Name, sp.Name, attachmentPt, m_scene.Name); - // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. - objatt.HasGroupChanged = false; - bool tainted = false; - if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) - tainted = true; - - // FIXME: Detect whether it's really likely for AttachObject to throw an exception in the normal - // course of events. If not, then it's probably not worth trying to recover the situation - // since this is more likely to trigger further exceptions and confuse later debugging. If - // exceptions can be thrown in expected error conditions (not NREs) then make this consistent - // since other normal error conditions will simply return false instead. - // This will throw if the attachment fails - try - { - AttachObjectInternal(sp, objatt, attachmentPt, false, false); - } - catch (Exception e) - { - m_log.ErrorFormat( - "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}", - objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); - - // Make sure the object doesn't stick around and bail - sp.RemoveAttachment(objatt); - m_scene.DeleteSceneObject(objatt, false); - return null; - } - - if (tainted) - objatt.HasGroupChanged = true; + // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. + objatt.HasGroupChanged = false; + bool tainted = false; + if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) + tainted = true; + + // FIXME: Detect whether it's really likely for AttachObject to throw an exception in the normal + // course of events. If not, then it's probably not worth trying to recover the situation + // since this is more likely to trigger further exceptions and confuse later debugging. If + // exceptions can be thrown in expected error conditions (not NREs) then make this consistent + // since other normal error conditions will simply return false instead. + // This will throw if the attachment fails + try + { + AttachObjectInternal(sp, objatt, attachmentPt, false, false, true); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}", + objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); - // Fire after attach, so we don't get messy perms dialogs - // 4 == AttachedRez - objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); - objatt.ResumeScripts(); + // Make sure the object doesn't stick around and bail + sp.RemoveAttachment(objatt); + m_scene.DeleteSceneObject(objatt, false); + return null; + } - // Do this last so that event listeners have access to all the effects of the attachment - m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID); + if (tainted) + objatt.HasGroupChanged = true; - return objatt; - } + return objatt; } /// diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 0ee01c7..624adcf 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -293,7 +293,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // Check appearance status Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); - Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); // Check events @@ -301,6 +300,69 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests } /// + /// Test wearing an attachment from inventory, as opposed to explicit choosing the rez point + /// + [Test] + public void TestWearAttachmentFromInventory() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + Scene scene = CreateTestScene(); + UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); + ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); + + InventoryItemBase attItem1 = CreateAttachmentItem(scene, ua1.PrincipalID, "att1", 0x10, 0x20); + InventoryItemBase attItem2 = CreateAttachmentItem(scene, ua1.PrincipalID, "att2", 0x11, 0x21); + + { + scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, attItem1.ID, (uint)AttachmentPoint.Default); + + // default attachment point is currently the left hand. + Assert.That(sp.HasAttachments(), Is.True); + List attachments = sp.GetAttachments(); + Assert.That(attachments.Count, Is.EqualTo(1)); + SceneObjectGroup attSo = attachments[0]; + Assert.That(attSo.Name, Is.EqualTo(attItem1.Name)); + Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand)); + Assert.That(attSo.IsAttachment); + + // Check appearance status + Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); + Assert.That(sp.Appearance.GetAttachpoint(attItem1.ID), Is.EqualTo((int)AttachmentPoint.LeftHand)); + Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); + + // Check events + Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); + } + + // Test wearing a second attachment at the same position + // Until multiple attachments at one point is implemented, this will remove the first attachment + // This test relies on both attachments having the same default attachment point (in this case LeftHand + // since none other has been set). + { + scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, attItem2.ID, (uint)AttachmentPoint.Default); + + // default attachment point is currently the left hand. + Assert.That(sp.HasAttachments(), Is.True); + List attachments = sp.GetAttachments(); + Assert.That(attachments.Count, Is.EqualTo(1)); + SceneObjectGroup attSo = attachments[0]; + Assert.That(attSo.Name, Is.EqualTo(attItem2.Name)); + Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand)); + Assert.That(attSo.IsAttachment); + + // Check appearance status + Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); + Assert.That(sp.Appearance.GetAttachpoint(attItem2.ID), Is.EqualTo((int)AttachmentPoint.LeftHand)); + Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); + + // Check events + Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3)); + } + } + + /// /// Test specific conditions associated with rezzing a scripted attachment from inventory. /// [Test] -- cgit v1.1 From 3611d33b00650ccc71994b331e4c6595f95d3131 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 18 Mar 2013 22:04:27 +0000 Subject: Improve rejection of any attempt to reattach an object that is already attached. This also adds/extends regression tests for wearing attachments directly for the scene and attempting to reattach/rewear already attached objects. --- .../Avatar/Attachments/AttachmentsModule.cs | 24 +-- .../Attachments/Tests/AttachmentsModuleTests.cs | 201 +++++++++++++++++++-- 2 files changed, 194 insertions(+), 31 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 2092d6f..1c28f49 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -305,6 +305,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments private bool AttachObjectInternal( IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp, bool resumeScripts) { + if (sp.GetAttachments().Contains(group)) + { +// m_log.WarnFormat( +// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", +// group.Name, group.LocalId, sp.Name, AttachmentPt); + + return false; + } + // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", // group.Name, group.LocalId, sp.Name, attachmentPt, silent); @@ -318,15 +327,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return false; } - if (sp.GetAttachments(attachmentPt).Contains(group)) - { -// m_log.WarnFormat( -// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", -// group.Name, group.LocalId, sp.Name, AttachmentPt); - - return false; - } - Vector3 attachPos = group.AbsolutePosition; // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should @@ -336,13 +336,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // If the attachment point isn't the same as the one previously used // set it's offset position = 0 so that it appears on the attachment point // and not in a weird location somewhere unknown. - if (attachmentPt != 0 && attachmentPt != group.AttachmentPoint) + if (attachmentPt != (uint)AttachmentPoint.Default && attachmentPt != group.AttachmentPoint) { attachPos = Vector3.Zero; } - // AttachmentPt 0 means the client chose to 'wear' the attachment. - if (attachmentPt == 0) + // AttachmentPt 0 (default) means the client chose to 'wear' the attachment. + if (attachmentPt == (uint)AttachmentPoint.Default) { // Check object for stored attachment point attachmentPt = group.AttachmentPoint; diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 624adcf..719a59c 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -228,6 +228,120 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); } + [Test] + public void TestWearAttachmentFromGround() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + Scene scene = CreateTestScene(); + UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); + ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1); + + SceneObjectGroup so2 = SceneHelpers.AddSceneObject(scene, "att2", sp.UUID); + + { + SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, "att1", sp.UUID); + + m_numberOfAttachEventsFired = 0; + scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Default, false, false); + + // Check status on scene presence + Assert.That(sp.HasAttachments(), Is.True); + List attachments = sp.GetAttachments(); + Assert.That(attachments.Count, Is.EqualTo(1)); + SceneObjectGroup attSo = attachments[0]; + Assert.That(attSo.Name, Is.EqualTo(so.Name)); + Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand)); + Assert.That(attSo.IsAttachment); + Assert.That(attSo.UsesPhysics, Is.False); + Assert.That(attSo.IsTemporary, Is.False); + + // Check item status + Assert.That( + sp.Appearance.GetAttachpoint(attSo.FromItemID), + Is.EqualTo((int)AttachmentPoint.LeftHand)); + + InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID)); + Assert.That(attachmentItem, Is.Not.Null); + Assert.That(attachmentItem.Name, Is.EqualTo(so.Name)); + + InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object); + Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID)); + + Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(2)); + + // Check events + Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); + } + + // Test wearing a different attachment from the ground. + { + scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, false); + + // Check status on scene presence + Assert.That(sp.HasAttachments(), Is.True); + List attachments = sp.GetAttachments(); + Assert.That(attachments.Count, Is.EqualTo(1)); + SceneObjectGroup attSo = attachments[0]; + Assert.That(attSo.Name, Is.EqualTo(so2.Name)); + Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand)); + Assert.That(attSo.IsAttachment); + Assert.That(attSo.UsesPhysics, Is.False); + Assert.That(attSo.IsTemporary, Is.False); + + // Check item status + Assert.That( + sp.Appearance.GetAttachpoint(attSo.FromItemID), + Is.EqualTo((int)AttachmentPoint.LeftHand)); + + InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID)); + Assert.That(attachmentItem, Is.Not.Null); + Assert.That(attachmentItem.Name, Is.EqualTo(so2.Name)); + + InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object); + Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID)); + + Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); + + // Check events + Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3)); + } + + // Test rewearing an already worn attachment from ground. Nothing should happen. + { + scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, false); + + // Check status on scene presence + Assert.That(sp.HasAttachments(), Is.True); + List attachments = sp.GetAttachments(); + Assert.That(attachments.Count, Is.EqualTo(1)); + SceneObjectGroup attSo = attachments[0]; + Assert.That(attSo.Name, Is.EqualTo(so2.Name)); + Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand)); + Assert.That(attSo.IsAttachment); + Assert.That(attSo.UsesPhysics, Is.False); + Assert.That(attSo.IsTemporary, Is.False); + + // Check item status + Assert.That( + sp.Appearance.GetAttachpoint(attSo.FromItemID), + Is.EqualTo((int)AttachmentPoint.LeftHand)); + + InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID)); + Assert.That(attachmentItem, Is.Not.Null); + Assert.That(attachmentItem.Name, Is.EqualTo(so2.Name)); + + InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object); + Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID)); + + Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); + + // Check events + Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3)); + } + } + /// /// Test that we do not attempt to attach an in-world object that someone else is sitting on. /// @@ -275,28 +389,54 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); - m_numberOfAttachEventsFired = 0; - scene.AttachmentsModule.RezSingleAttachmentFromInventory( - sp, attItem.ID, (uint)AttachmentPoint.Chest); + { + scene.AttachmentsModule.RezSingleAttachmentFromInventory( + sp, attItem.ID, (uint)AttachmentPoint.Chest); - // Check scene presence status - Assert.That(sp.HasAttachments(), Is.True); - List attachments = sp.GetAttachments(); - Assert.That(attachments.Count, Is.EqualTo(1)); - SceneObjectGroup attSo = attachments[0]; - Assert.That(attSo.Name, Is.EqualTo(attItem.Name)); - Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); - Assert.That(attSo.IsAttachment); - Assert.That(attSo.UsesPhysics, Is.False); - Assert.That(attSo.IsTemporary, Is.False); + // Check scene presence status + Assert.That(sp.HasAttachments(), Is.True); + List attachments = sp.GetAttachments(); + Assert.That(attachments.Count, Is.EqualTo(1)); + SceneObjectGroup attSo = attachments[0]; + Assert.That(attSo.Name, Is.EqualTo(attItem.Name)); + Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); + Assert.That(attSo.IsAttachment); + Assert.That(attSo.UsesPhysics, Is.False); + Assert.That(attSo.IsTemporary, Is.False); - // Check appearance status - Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); - Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); - Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); + // Check appearance status + Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); + Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); + Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); - // Check events - Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); + // Check events + Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); + } + + // Test attaching an already attached attachment + { + scene.AttachmentsModule.RezSingleAttachmentFromInventory( + sp, attItem.ID, (uint)AttachmentPoint.Chest); + + // Check scene presence status + Assert.That(sp.HasAttachments(), Is.True); + List attachments = sp.GetAttachments(); + Assert.That(attachments.Count, Is.EqualTo(1)); + SceneObjectGroup attSo = attachments[0]; + Assert.That(attSo.Name, Is.EqualTo(attItem.Name)); + Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); + Assert.That(attSo.IsAttachment); + Assert.That(attSo.UsesPhysics, Is.False); + Assert.That(attSo.IsTemporary, Is.False); + + // Check appearance status + Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); + Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); + Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); + + // Check events + Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); + } } /// @@ -316,6 +456,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests InventoryItemBase attItem2 = CreateAttachmentItem(scene, ua1.PrincipalID, "att2", 0x11, 0x21); { + m_numberOfAttachEventsFired = 0; scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, attItem1.ID, (uint)AttachmentPoint.Default); // default attachment point is currently the left hand. @@ -360,6 +501,28 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // Check events Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3)); } + + // Test wearing an already attached attachment + { + scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, attItem2.ID, (uint)AttachmentPoint.Default); + + // default attachment point is currently the left hand. + Assert.That(sp.HasAttachments(), Is.True); + List attachments = sp.GetAttachments(); + Assert.That(attachments.Count, Is.EqualTo(1)); + SceneObjectGroup attSo = attachments[0]; + Assert.That(attSo.Name, Is.EqualTo(attItem2.Name)); + Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand)); + Assert.That(attSo.IsAttachment); + + // Check appearance status + Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); + Assert.That(sp.Appearance.GetAttachpoint(attItem2.ID), Is.EqualTo((int)AttachmentPoint.LeftHand)); + Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); + + // Check events + Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3)); + } } /// -- cgit v1.1 From fcecfc81bbd6ee8ebfa2dc0585d92ebf899358c1 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 18 Mar 2013 22:56:03 +0000 Subject: Multiattach, part 1 Conflicts: OpenSim/Framework/AvatarAppearance.cs OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs OpenSim/Region/Framework/Scenes/Scene.cs OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs --- .../Avatar/Attachments/AttachmentsModule.cs | 58 +++++++++++----------- .../Attachments/Tests/AttachmentsModuleTests.cs | 6 +-- .../Framework/Interfaces/IAttachmentsModule.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.cs | 2 +- .../Avatar/Attachments/TempAttachmentsModule.cs | 2 +- .../Shared/Api/Implementation/LSL_Api.cs | 4 +- 6 files changed, 36 insertions(+), 38 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 8a3eeaa..f8fc483 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -221,9 +221,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // If we're an NPC then skip all the item checks and manipulations since we don't have an // inventory right now. if (sp.PresenceType == PresenceType.Npc) - RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p); + RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, true); else - RezSingleAttachmentFromInventory(sp, attach.ItemID, p); + RezSingleAttachmentFromInventory(sp, attach.ItemID, p | (uint)0x80); } catch (Exception e) { @@ -268,13 +268,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments sp.ClearAttachments(); } - - public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp) + + public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp, bool append) { if (!Enabled) return false; - if (AttachObjectInternal(sp, group, attachmentPt, silent, temp)) + if (AttachObjectInternal(sp, group, attachmentPt, silent, temp, append)) { m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID); return true; @@ -283,7 +283,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return false; } - private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp) + private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp, bool append) { lock (sp.AttachmentsSyncLock) { @@ -311,10 +311,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments Vector3 attachPos = group.AbsolutePosition; - // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should - // be removed when that functionality is implemented in opensim - attachmentPt &= 0x7f; - // If the attachment point isn't the same as the one previously used // set it's offset position = 0 so that it appears on the attachment point // and not in a weird location somewhere unknown. @@ -342,7 +338,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments group.AbsolutePosition = attachPos; if (sp.PresenceType != PresenceType.Npc) - UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp); + UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp, append); AttachToAgent(sp, group, attachmentPt, attachPos, silent); } @@ -350,21 +346,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return true; } - private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp) + private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp, bool append) { // Remove any previous attachments List attachments = sp.GetAttachments(attachmentPt); // At the moment we can only deal with a single attachment - if (attachments.Count != 0) + if (attachments.Count != 0 && !append) { if (attachments[0].FromItemID != UUID.Zero) DetachSingleAttachmentToInvInternal(sp, attachments[0]); - // Error logging commented because UUID.Zero now means temp attachment -// else -// m_log.WarnFormat( -// "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!", -// attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name); } // Add the new attachment to inventory if we don't already have it. @@ -374,7 +365,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (newAttachmentItemID == UUID.Zero) newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID; - ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group); + ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group, append); } } @@ -387,8 +378,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}", // (AttachmentPoint)AttachmentPt, itemID, sp.Name); - // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should - // be removed when that functionality is implemented in opensim + bool append = (AttachmentPt & 0x80) != 0; AttachmentPt &= 0x7f; // Viewer 2/3 sometimes asks to re-wear items that are already worn (and show up in it's inventory as such). @@ -417,7 +407,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return null; } - return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt); + return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, append); } public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List> rezlist) @@ -803,8 +793,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments UpdateDetachedObject(sp, so); } - private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( - IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt) + protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( + IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, bool append) { if (m_invAccessModule == null) return null; @@ -842,7 +832,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // This will throw if the attachment fails try { - AttachObjectInternal(sp, objatt, attachmentPt, false, false); + AttachObjectInternal(sp, objatt, attachmentPt, false, false, append); } catch (Exception e) { @@ -887,7 +877,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// /// /// - private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att) + private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att, bool append) { // m_log.DebugFormat( // "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", @@ -910,7 +900,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (item == null) return; - bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); + int attFlag = append ? 0x80 : 0; + bool changed = sp.Appearance.SetAttachment((int)AttachmentPt | attFlag, itemID, item.AssetID); if (changed && m_scene.AvatarFactory != null) { // m_log.DebugFormat( @@ -994,12 +985,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return; } - // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should - // be removed when that functionality is implemented in opensim + bool append = (AttachmentPt & 0x80) != 0; AttachmentPt &= 0x7f; // Calls attach with a Zero position - AttachObject(sp, part.ParentGroup, AttachmentPt, false, false); + if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, false, append)) + { +// m_log.Debug( +// "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId +// + ", AttachmentPoint: " + AttachmentPt); + + // Save avatar attachment information + m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId); + } } catch (Exception e) { diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 0ee01c7..f48bb6f 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -197,7 +197,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID); m_numberOfAttachEventsFired = 0; - scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false); + scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false); // Check status on scene presence Assert.That(sp.HasAttachments(), Is.True); @@ -254,7 +254,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests sp2.AbsolutePosition = new Vector3(0, 0, 0); sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero); - scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false); + scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false); Assert.That(sp.HasAttachments(), Is.False); Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); @@ -663,4 +663,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0)); } } -} \ No newline at end of file +} diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index 620ec22..46daab3 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -83,7 +83,7 @@ namespace OpenSim.Region.Framework.Interfaces /// /// /// true if the object was successfully attached, false otherwise - bool AttachObject(IScenePresence sp, SceneObjectGroup grp, uint AttachmentPt, bool silent, bool temp); + bool AttachObject(IScenePresence sp, SceneObjectGroup grp, uint AttachmentPt, bool silent, bool temp, bool append); /// /// Rez an attachment from user inventory and change inventory status to match. diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 14dac7a..3c91c5b 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2741,7 +2741,7 @@ namespace OpenSim.Region.Framework.Scenes RootPrim.RemFlag(PrimFlags.TemporaryOnRez); if (AttachmentsModule != null) - AttachmentsModule.AttachObject(sp, grp, 0, false, false); + AttachmentsModule.AttachObject(sp, grp, 0, false, false, true); } else { diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs index 1e7bc02..e9ddbbe 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs @@ -183,7 +183,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments hostPart.ParentGroup.RootPart.ScheduleFullUpdate(); } - return attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, true) ? 1 : 0; + return attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, true, true) ? 1 : 0; } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index ab087af..cf6f13e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2985,7 +2985,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; if (attachmentsModule != null) - return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); + return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, true); else return false; } @@ -11787,4 +11787,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } } -} \ No newline at end of file +} -- cgit v1.1 From e4a70b9f9aa9d454c9b57c85452eec7f9d0d13e9 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 5 Mar 2013 15:11:30 +0100 Subject: Limit each attachment point to 5 items as per spec --- .../CoreModules/Avatar/Attachments/AttachmentsModule.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index f8fc483..ed4506c 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -348,14 +348,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp, bool append) { - // Remove any previous attachments List attachments = sp.GetAttachments(attachmentPt); - // At the moment we can only deal with a single attachment - if (attachments.Count != 0 && !append) + // If we already have 5, remove the oldest until only 4 are left. Skip over temp ones + while (attachments.Count >= 5) { if (attachments[0].FromItemID != UUID.Zero) DetachSingleAttachmentToInvInternal(sp, attachments[0]); + attachments.RemoveAt(0); + } + + // If we're not appending, remove the rest as well + if (attachments.Count != 0 && !append) + { + foreach (SceneObjectGroup g in attachments) + { + if (g.FromItemID != UUID.Zero) + DetachSingleAttachmentToInvInternal(sp, g); + } } // Add the new attachment to inventory if we don't already have it. -- cgit v1.1 From 55ab6f015a6e6891aed6b882e546709ef89a1306 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 18 Mar 2013 23:48:03 +0000 Subject: Fix tests for multiattach --- OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 6 +++--- .../CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 2dea14d..d489821 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -289,7 +289,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (!Enabled) return false; - return AttachObjectInternal(sp, group, attachmentPt, silent, temp, append); + return AttachObjectInternal(sp, group, attachmentPt, silent, temp, true, append); } /// @@ -303,7 +303,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// /// If true then scripts are resumed on the attached object. private bool AttachObjectInternal( - IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp, bool resumeScripts) + IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp, bool resumeScripts, bool append) { if (group.GetSittingAvatarsCount() != 0) { @@ -889,7 +889,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // This will throw if the attachment fails try { - AttachObjectInternal(sp, objatt, attachmentPt, false, false, append); + AttachObjectInternal(sp, objatt, attachmentPt, false, false, true, append); } catch (Exception e) { diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 0c1df6a..4cd03da 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -244,7 +244,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, "att1", sp.UUID); m_numberOfAttachEventsFired = 0; - scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Default, false, false); + scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Default, false, false, false); // Check status on scene presence Assert.That(sp.HasAttachments(), Is.True); @@ -277,7 +277,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // Test wearing a different attachment from the ground. { - scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, false); + scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, false, false); // Check status on scene presence Assert.That(sp.HasAttachments(), Is.True); @@ -310,7 +310,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // Test rewearing an already worn attachment from ground. Nothing should happen. { - scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, false); + scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, false, false); // Check status on scene presence Assert.That(sp.HasAttachments(), Is.True); -- cgit v1.1 From 397379cd3f0d6ca0b17015b44af319440895970d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 19 Mar 2013 00:39:58 +0000 Subject: Process default attachment point in AttachObjectInternal before we check whether a worn object needs to displace an existing attachment on the same point if we are not using multi-attach. --- .../Avatar/Attachments/AttachmentsModule.cs | 54 +++++++++++----------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index d489821..72ba3cf 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -314,6 +314,33 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return false; } + Vector3 attachPos = group.AbsolutePosition; + // If the attachment point isn't the same as the one previously used + // set it's offset position = 0 so that it appears on the attachment point + // and not in a weird location somewhere unknown. + if (attachmentPt != (uint)AttachmentPoint.Default && attachmentPt != group.AttachmentPoint) + { + attachPos = Vector3.Zero; + } + + // AttachmentPt 0 means the client chose to 'wear' the attachment. + if (attachmentPt == (uint)AttachmentPoint.Default) + { + // Check object for stored attachment point + attachmentPt = group.AttachmentPoint; + } + + // if we still didn't find a suitable attachment point....... + if (attachmentPt == 0) + { + // Stick it on left hand with Zero Offset from the attachment point. + attachmentPt = (uint)AttachmentPoint.LeftHand; + attachPos = Vector3.Zero; + } + + group.AttachmentPoint = attachmentPt; + group.AbsolutePosition = attachPos; + List attachments = sp.GetAttachments(attachmentPt); if (attachments.Contains(group)) @@ -345,33 +372,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments lock (sp.AttachmentsSyncLock) { - Vector3 attachPos = group.AbsolutePosition; - // If the attachment point isn't the same as the one previously used - // set it's offset position = 0 so that it appears on the attachment point - // and not in a weird location somewhere unknown. - if (attachmentPt != 0 && attachmentPt != group.AttachmentPoint) - { - attachPos = Vector3.Zero; - } - - // AttachmentPt 0 means the client chose to 'wear' the attachment. - if (attachmentPt == 0) - { - // Check object for stored attachment point - attachmentPt = group.AttachmentPoint; - } - - // if we still didn't find a suitable attachment point....... - if (attachmentPt == 0) - { - // Stick it on left hand with Zero Offset from the attachment point. - attachmentPt = (uint)AttachmentPoint.LeftHand; - attachPos = Vector3.Zero; - } - - group.AttachmentPoint = attachmentPt; - group.AbsolutePosition = attachPos; - if (sp.PresenceType != PresenceType.Npc) UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp, append); -- cgit v1.1 From 566ab7ccf92c607fa06e38700c8094680eea704c Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 19 Mar 2013 01:19:33 +0000 Subject: Fix merge artefacts --- OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 6 +++--- .../CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 296f198..c94d152 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -304,7 +304,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (!Enabled) return false; - AttachObjectInternal(sp, group, attachmentPt, silent, useAttachData, temp, append); + return AttachObjectInternal(sp, group, attachmentPt, silent, useAttachData, temp, false, append); } /// @@ -317,7 +317,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// /// /// If true then scripts are resumed on the attached object. - private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp, bool append) + private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp, bool resumeScripts, bool append) { // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", @@ -917,7 +917,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments objatt.ResetOwnerChangeFlag(); } - AttachObjectInternal(sp, objatt, attachmentPt, false, true, false, append); + AttachObjectInternal(sp, objatt, attachmentPt, false, true, false, true, append); } catch (Exception e) { diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index da4bc83..dee8ce3 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -244,7 +244,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, "att1", sp.UUID); m_numberOfAttachEventsFired = 0; - scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Default, false, false); + scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Default, false, false, false, false); // Check status on scene presence Assert.That(sp.HasAttachments(), Is.True); @@ -277,7 +277,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // Test wearing a different attachment from the ground. { - scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, false); + scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, false, false, false); // Check status on scene presence Assert.That(sp.HasAttachments(), Is.True); @@ -310,7 +310,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // Test rewearing an already worn attachment from ground. Nothing should happen. { - scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, false); + scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, false, false, false); // Check status on scene presence Assert.That(sp.HasAttachments(), Is.True); -- cgit v1.1 From 8510f57ad48db5f97dacc2a9be63c64e62477d14 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 17 Mar 2013 18:44:09 -0700 Subject: BulletSim: add terrain contact processing threshold parameter. Initialize contact processing threshold for static object as well as mesh terrain. --- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 19 +++++++++++++++++++ OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 2 +- .../Region/Physics/BulletSPlugin/BSTerrainManager.cs | 1 + OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs | 2 ++ 4 files changed, 23 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 77bdacb..cb0d929 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -39,6 +39,20 @@ public static class BSParam { private static string LogHeader = "[BULLETSIM PARAMETERS]"; + // Tuning notes: + // From: http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=6575 + // Contact points can be added even if the distance is positive. The constraint solver can deal with + // contacts with positive distances as well as negative (penetration). Contact points are discarded + // if the distance exceeds a certain threshold. + // Bullet has a contact processing threshold and a contact breaking threshold. + // If the distance is larger than the contact breaking threshold, it will be removed after one frame. + // If the distance is larger than the contact processing threshold, the constraint solver will ignore it. + + // This is separate/independent from the collision margin. The collision margin increases the object a bit + // to improve collision detection performance and accuracy. + // =================== + // From: + // Level of Detail values kept as float because that's what the Meshmerizer wants public static float MeshLOD { get; private set; } public static float MeshCircularLOD { get; private set; } @@ -77,6 +91,7 @@ public static class BSParam public static float TerrainFriction { get; private set; } public static float TerrainHitFraction { get; private set; } public static float TerrainRestitution { get; private set; } + public static float TerrainContactProcessingThreshold { get; private set; } public static float TerrainCollisionMargin { get; private set; } public static float DefaultFriction { get; private set; } @@ -458,6 +473,10 @@ public static class BSParam 0f, (s) => { return TerrainRestitution; }, (s,v) => { TerrainRestitution = v; /* TODO: set on real terrain */ } ), + new ParameterDefn("TerrainContactProcessingThreshold", "Distance from terrain to stop processing collisions" , + 0.0f, + (s) => { return TerrainContactProcessingThreshold; }, + (s,v) => { TerrainContactProcessingThreshold = v; /* TODO: set on real terrain */ } ), new ParameterDefn("TerrainCollisionMargin", "Margin where collision checking starts" , 0.08f, (s) => { return TerrainCollisionMargin; }, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index a465613..2cbbe9a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -947,9 +947,9 @@ public class BSPrim : BSPhysObject ZeroMotion(true); // Set various physical properties so other object interact properly - MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false); PhysicsScene.PE.SetFriction(PhysBody, Friction); PhysicsScene.PE.SetRestitution(PhysBody, Restitution); + PhysicsScene.PE.SetContactProcessingThreshold(PhysBody, BSParam.ContactProcessingThreshold); // Mass is zero which disables a bunch of physics stuff in Bullet UpdatePhysicalMassProperties(0f, false); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index e8040d8..a60946d 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -263,6 +263,7 @@ public sealed class BSTerrainManager : IDisposable if (MegaRegionParentPhysicsScene == null) { + // This terrain is not part of the mega-region scheme. Create vanilla terrain. BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords); m_terrains.Add(terrainRegionBase, newTerrainPhys); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index 57a5ff2..c9a75ae 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs @@ -112,11 +112,13 @@ public sealed class BSTerrainMesh : BSTerrainPhys // Something is very messed up and a crash is in our future. return; } + physicsScene.PE.SetShapeCollisionMargin(m_terrainShape, BSParam.TerrainCollisionMargin); // Set current terrain attributes PhysicsScene.PE.SetFriction(m_terrainBody, BSParam.TerrainFriction); PhysicsScene.PE.SetHitFraction(m_terrainBody, BSParam.TerrainHitFraction); PhysicsScene.PE.SetRestitution(m_terrainBody, BSParam.TerrainRestitution); + PhysicsScene.PE.SetContactProcessingThreshold(m_terrainBody, BSParam.TerrainContactProcessingThreshold); PhysicsScene.PE.SetCollisionFlags(m_terrainBody, CollisionFlags.CF_STATIC_OBJECT); // Static objects are not very massive. -- cgit v1.1 From 8360223fedc5a5521878806f40bdb0c3244241cc Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 18 Mar 2013 23:58:21 -0700 Subject: BulletSim: code to generate a higher resolution terrain mesh. Parameter TerrainMeshMagnification controls number of vertices generated per heightmap point. Default is 3. --- OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | 4 +- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 5 +- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 5 + .../Region/Physics/BulletSPlugin/BSTerrainMesh.cs | 193 +++++++++++++++++++-- 4 files changed, 189 insertions(+), 18 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs index 3a27d2c..77ea3ed 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs @@ -286,7 +286,7 @@ public override void SetShapeCollisionMargin(BulletShape shape, float margin) { BulletShapeUnman shapeu = shape as BulletShapeUnman; if (shapeu != null && shapeu.HasPhysicalShape) - BSAPICPP.SetShapeCollisionMargin2(shapeu.ptr, margin); + BSAPICPP.SetShapeCollisionMargin(shapeu.ptr, margin); } public override BulletShape BuildCapsuleShape(BulletWorld world, float radius, float height, Vector3 scale) @@ -1420,7 +1420,7 @@ public static extern IntPtr BuildNativeShape2(IntPtr world, ShapeData shapeData) public static extern bool IsNativeShape2(IntPtr shape); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] -public static extern void SetShapeCollisionMargin2(IntPtr shape, float margin); +public static extern void SetShapeCollisionMargin(IntPtr shape, float margin); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern IntPtr BuildCapsuleShape2(IntPtr world, float radius, float height, Vector3 scale); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 38596fa..5549984 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -1201,8 +1201,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin VehicleAddForce(appliedGravity); - VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},collid={2},appliedForce={3}", - Prim.LocalID, m_VehicleGravity, Prim.IsColliding, appliedGravity); + VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},collid={2},fudge={3},mass={4},appliedForce={3}", + Prim.LocalID, m_VehicleGravity, + Prim.IsColliding, BSParam.VehicleGroundGravityFudge, m_vehicleMass, appliedGravity); } // ======================================================================= diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index cb0d929..4d89a88 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -88,6 +88,7 @@ public static class BSParam public static bool ShouldRemoveZeroWidthTriangles { get; private set; } public static float TerrainImplementation { get; private set; } + public static int TerrainMeshMagnification { get; private set; } public static float TerrainFriction { get; private set; } public static float TerrainHitFraction { get; private set; } public static float TerrainRestitution { get; private set; } @@ -461,6 +462,10 @@ public static class BSParam (float)BSTerrainPhys.TerrainImplementation.Mesh, (s) => { return TerrainImplementation; }, (s,v) => { TerrainImplementation = v; } ), + new ParameterDefn("TerrainMeshMagnification", "Number of times the 256x256 heightmap is multiplied to create the terrain mesh" , + 3, + (s) => { return TerrainMeshMagnification; }, + (s,v) => { TerrainMeshMagnification = v; } ), new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" , 0.3f, (s) => { return TerrainFriction; }, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index c9a75ae..a9cd8a1 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs @@ -76,11 +76,26 @@ public sealed class BSTerrainMesh : BSTerrainPhys m_sizeX = (int)(maxCoords.X - minCoords.X); m_sizeY = (int)(maxCoords.Y - minCoords.Y); - if (!BSTerrainMesh.ConvertHeightmapToMesh(PhysicsScene, initialMap, - m_sizeX, m_sizeY, - (float)m_sizeX, (float)m_sizeY, - Vector3.Zero, 1.0f, - out indicesCount, out indices, out verticesCount, out vertices)) + bool meshCreationSuccess = false; + if (BSParam.TerrainMeshMagnification == 1) + { + // If a magnification of one, use the old routine that is tried and true. + meshCreationSuccess = BSTerrainMesh.ConvertHeightmapToMesh(PhysicsScene, + initialMap, m_sizeX, m_sizeY, // input size + Vector3.Zero, // base for mesh + out indicesCount, out indices, out verticesCount, out vertices); + } + else + { + // Other magnifications use the newer routine + meshCreationSuccess = BSTerrainMesh.ConvertHeightmapToMesh2(PhysicsScene, + initialMap, m_sizeX, m_sizeY, // input size + BSParam.TerrainMeshMagnification, + physicsScene.TerrainManager.DefaultRegionSize, + Vector3.Zero, // base for mesh + out indicesCount, out indices, out verticesCount, out vertices); + } + if (!meshCreationSuccess) { // DISASTER!! PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedConversionOfHeightmap", ID); @@ -88,6 +103,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys // Something is very messed up and a crash is in our future. return; } + PhysicsScene.DetailLog("{0},BSTerrainMesh.create,meshed,indices={1},indSz={2},vertices={3},vertSz={4}", ID, indicesCount, indices.Length, verticesCount, vertices.Length); @@ -186,9 +202,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys // Return 'true' if successfully created. public static bool ConvertHeightmapToMesh( BSScene physicsScene, float[] heightMap, int sizeX, int sizeY, // parameters of incoming heightmap - float extentX, float extentY, // zero based range for output vertices Vector3 extentBase, // base to be added to all vertices - float magnification, // number of vertices to create between heightMap coords out int indicesCountO, out int[] indicesO, out int verticesCountO, out float[] verticesO) { @@ -209,17 +223,15 @@ public sealed class BSTerrainMesh : BSTerrainPhys // of the heightmap. try { - // One vertice per heightmap value plus the vertices off the top and bottom edge. + // One vertice per heightmap value plus the vertices off the side and bottom edge. int totalVertices = (sizeX + 1) * (sizeY + 1); vertices = new float[totalVertices * 3]; int totalIndices = sizeX * sizeY * 6; indices = new int[totalIndices]; - float magX = (float)sizeX / extentX; - float magY = (float)sizeY / extentY; if (physicsScene != null) - physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2},extentBase={3},magX={4},magY={5}", - BSScene.DetailLogZero, totalVertices, totalIndices, extentBase, magX, magY); + physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2},extentBase={3}", + BSScene.DetailLogZero, totalVertices, totalIndices, extentBase); float minHeight = float.MaxValue; // Note that sizeX+1 vertices are created since there is land between this and the next region. for (int yy = 0; yy <= sizeY; yy++) @@ -232,8 +244,8 @@ public sealed class BSTerrainMesh : BSTerrainPhys if (xx == sizeX) offset -= 1; float height = heightMap[offset]; minHeight = Math.Min(minHeight, height); - vertices[verticesCount + 0] = (float)xx * magX + extentBase.X; - vertices[verticesCount + 1] = (float)yy * magY + extentBase.Y; + vertices[verticesCount + 0] = (float)xx + extentBase.X; + vertices[verticesCount + 1] = (float)yy + extentBase.Y; vertices[verticesCount + 2] = height + extentBase.Z; verticesCount += 3; } @@ -272,5 +284,158 @@ public sealed class BSTerrainMesh : BSTerrainPhys return ret; } + + private class HeightMapGetter + { + private float[] m_heightMap; + private int m_sizeX; + private int m_sizeY; + public HeightMapGetter(float[] pHeightMap, int pSizeX, int pSizeY) + { + m_heightMap = pHeightMap; + m_sizeX = pSizeX; + m_sizeY = pSizeY; + } + // The heightmap is extended as an infinite plane at the last height + public float GetHeight(int xx, int yy) + { + int offset = 0; + // Extend the height with the height from the last row or column + if (yy >= m_sizeY) + if (xx >= m_sizeX) + offset = (m_sizeY - 1) * m_sizeX + (m_sizeX - 1); + else + offset = (m_sizeY - 1) * m_sizeX + xx; + else + if (xx >= m_sizeX) + offset = yy * m_sizeX + (m_sizeX - 1); + else + offset = yy * m_sizeX + xx; + + return m_heightMap[offset]; + } + } + + // Convert the passed heightmap to mesh information suitable for CreateMeshShape2(). + // Version that handles magnification. + // Return 'true' if successfully created. + public static bool ConvertHeightmapToMesh2( BSScene physicsScene, + float[] heightMap, int sizeX, int sizeY, // parameters of incoming heightmap + int magnification, // number of vertices per heighmap step + Vector3 extent, // dimensions of the output mesh + Vector3 extentBase, // base to be added to all vertices + out int indicesCountO, out int[] indicesO, + out int verticesCountO, out float[] verticesO) + { + bool ret = false; + + int indicesCount = 0; + int verticesCount = 0; + int[] indices = new int[0]; + float[] vertices = new float[0]; + + HeightMapGetter hmap = new HeightMapGetter(heightMap, sizeX, sizeY); + + // The vertices dimension of the output mesh + int meshX = sizeX * magnification; + int meshY = sizeY * magnification; + // The output size of one mesh step + float meshXStep = extent.X / meshX; + float meshYStep = extent.Y / meshY; + + // Create an array of vertices that is meshX+1 by meshY+1 (note the loop + // from zero to <= meshX). The triangle indices are then generated as two triangles + // per heightmap point. There are meshX by meshY of these squares. The extra row and + // column of vertices are used to complete the triangles of the last row and column + // of the heightmap. + try + { + // Vertices for the output heightmap plus one on the side and bottom to complete triangles + int totalVertices = (meshX + 1) * (meshY + 1); + vertices = new float[totalVertices * 3]; + int totalIndices = meshX * meshY * 6; + indices = new int[totalIndices]; + + if (physicsScene != null) + physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh2,inSize={1},outSize={2},totVert={3},totInd={4},extentBase={5}", + BSScene.DetailLogZero, new Vector2(sizeX, sizeY), new Vector2(meshX, meshY), + totalVertices, totalIndices, extentBase); + + float minHeight = float.MaxValue; + // Note that sizeX+1 vertices are created since there is land between this and the next region. + // Loop through the output vertices and compute the mediun height in between the input vertices + for (int yy = 0; yy <= meshY; yy++) + { + for (int xx = 0; xx <= meshX; xx++) // Hint: the "<=" means we go around sizeX + 1 times + { + float offsetY = (float)yy * (float)sizeY / (float)meshY; // The Y that is closest to the mesh point + int stepY = (int)offsetY; + float fractionalY = offsetY - (float)stepY; + float offsetX = (float)xx * (float)sizeX / (float)meshX; // The X that is closest to the mesh point + int stepX = (int)offsetX; + float fractionalX = offsetX - (float)stepX; + + // physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh2,xx={1},yy={2},offX={3},stepX={4},fractX={5},offY={6},stepY={7},fractY={8}", + // BSScene.DetailLogZero, xx, yy, offsetX, stepX, fractionalX, offsetY, stepY, fractionalY); + + // get the four corners of the heightmap square the mesh point is in + float heightUL = hmap.GetHeight(stepX , stepY ); + float heightUR = hmap.GetHeight(stepX + 1, stepY ); + float heightLL = hmap.GetHeight(stepX , stepY + 1); + float heightLR = hmap.GetHeight(stepX + 1, stepY + 1); + + // bilinear interplolation + float height = heightUL * (1 - fractionalX) * (1 - fractionalY) + + heightUR * fractionalX * (1 - fractionalY) + + heightLL * (1 - fractionalX) * fractionalY + + heightLR * fractionalX * fractionalY; + + // physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh2,heightUL={1},heightUR={2},heightLL={3},heightLR={4},heightMap={5}", + // BSScene.DetailLogZero, heightUL, heightUR, heightLL, heightLR, height); + + minHeight = Math.Min(minHeight, height); + + vertices[verticesCount + 0] = (float)xx * meshXStep + extentBase.X; + vertices[verticesCount + 1] = (float)yy * meshYStep + extentBase.Y; + vertices[verticesCount + 2] = height + extentBase.Z; + verticesCount += 3; + } + } + // The number of vertices generated + verticesCount /= 3; + + // Loop through all the heightmap squares and create indices for the two triangles for that square + for (int yy = 0; yy < meshY; yy++) + { + for (int xx = 0; xx < meshX; xx++) + { + int offset = yy * (meshX + 1) + xx; + // Each vertices is presumed to be the upper left corner of a box of two triangles + indices[indicesCount + 0] = offset; + indices[indicesCount + 1] = offset + 1; + indices[indicesCount + 2] = offset + meshX + 1; // accounting for the extra column + indices[indicesCount + 3] = offset + 1; + indices[indicesCount + 4] = offset + meshX + 2; + indices[indicesCount + 5] = offset + meshX + 1; + indicesCount += 6; + } + } + + ret = true; + } + catch (Exception e) + { + if (physicsScene != null) + physicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh. For={1}/{2}, e={3}", + LogHeader, physicsScene.RegionName, extentBase, e); + } + + indicesCountO = indicesCount; + indicesO = indices; + verticesCountO = verticesCount; + verticesO = vertices; + + return ret; + } } } -- cgit v1.1 From 1dd2d432f1b0221c6180f1367badbcc3d29c478d Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 19 Mar 2013 11:40:10 -0700 Subject: For those people collecting and comparing logfiles from servers scattered around the world, change LogWriter to use DateTime.UtcNow rather than DateTime.Now. --- OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs index 3c8e0ef..2fe9026 100755 --- a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs +++ b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs @@ -136,7 +136,7 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging { lock (m_logFileWriteLock) { - DateTime now = DateTime.Now; + DateTime now = DateTime.UtcNow; if (m_logFile == null || now > m_logFileEndTime) { if (m_logFile != null) -- cgit v1.1 From 364816421985c052521cf7b444e124760c0a1025 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 19 Mar 2013 21:44:18 +0000 Subject: Prevent multiple instances of the same item ID being appended to an AvatarAppearance It looks like this was happening when AttachmentsModule.RezAttachments was doing a secondary set of each attachment to update with the asset ID (initially they only have the inventory ID). However, with multi-attach this was appending a second copy of the same attachment rather than updating the data that was already there. This commit requires both simulator and service to be updated. --- .../CoreModules/Avatar/Attachments/AttachmentsModule.cs | 4 ++-- .../CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | 12 ++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 72ba3cf..ad17aa9 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -547,8 +547,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } // m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: Detaching object {0} {1} for {2} in {3}", -// so.Name, so.LocalId, sp.Name, m_scene.Name); +// "[ATTACHMENTS MODULE]: Detaching object {0} {1} (FromItemID {2}) for {3} in {4}", +// so.Name, so.LocalId, so.FromItemID, sp.Name, m_scene.Name); // Scripts MUST be snapshotted before the object is // removed from the scene because doing otherwise will diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 00d1fd8..ff5bf9f 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -326,7 +326,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory public void QueueAppearanceSave(UUID agentid) { - // m_log.WarnFormat("[AVFACTORY]: Queue appearance save for {0}", agentid); +// m_log.DebugFormat("[AVFACTORY]: Queueing appearance save for {0}", agentid); // 10000 ticks per millisecond, 1000 milliseconds per second long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000); @@ -529,7 +529,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory return; } - // m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid); +// m_log.DebugFormat("[AVFACTORY]: Saving appearance for avatar {0}", agentid); // This could take awhile since it needs to pull inventory // We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape @@ -538,6 +538,14 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // multiple save requests. SetAppearanceAssets(sp.UUID, sp.Appearance); +// List attachments = sp.Appearance.GetAttachments(); +// foreach (AvatarAttachment att in attachments) +// { +// m_log.DebugFormat( +// "[AVFACTORY]: For {0} saving attachment {1} at point {2}", +// sp.Name, att.ItemID, att.AttachPoint); +// } + m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); // Trigger this here because it's the final step in the set/queue/save process for appearance setting. -- cgit v1.1 From 90b9121e66934795ab2d59f149e9e65eadc09e75 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 19 Mar 2013 17:15:24 -0700 Subject: BulletSim: change 'degenerate mesh' message from Error to Debug because there seem to be lots of sculpties with this problem while the condition really doesn't change region operation. --- OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 219372b..b16bc10 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -685,7 +685,7 @@ public sealed class BSShapeCollection : IDisposable } else { - PhysicsScene.Logger.ErrorFormat("{0} All mesh triangles degenerate. Prim {1} at {2} in {3}", + PhysicsScene.Logger.DebugFormat("{0} All mesh triangles degenerate. Prim {1} at {2} in {3}", LogHeader, prim.PhysObjectName, prim.RawPosition, PhysicsScene.Name); } } -- cgit v1.1 From 3cb1c23554439dc1f9ea2911a27d16de986e2ffd Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 20 Mar 2013 01:46:50 +0000 Subject: Force a viewer object update for attachments at the end of the final Scene.CompleteMovement() in order to make all multi-attachments appear on the destination region. For some reason, sending updates before this will not have this effect. This may be something related to some viewers (e.g. LL 3.3.4) or something OpenSimulator isn't getting quite right. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 82bb759..6d96c93 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1326,6 +1326,15 @@ namespace OpenSim.Region.Framework.Scenes friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); } + // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region + // If we do it a little bit earlier (e.g. when converting the child to a root agent) then this does not work. + // This may be due to viewer code or it may be something we're not doing properly simulator side. + lock (m_attachments) + { + foreach (SceneObjectGroup sog in m_attachments) + sog.ScheduleGroupForFullUpdate(); + } + // m_log.DebugFormat( // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", // client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); -- cgit v1.1 From c0ff5635ba696d1701a6ce0356f247c69a7a52b9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 20 Mar 2013 02:00:56 +0000 Subject: Fix "show attachments" command probably broken in commit addab12 (Wed Jan 2 21:38:00 2013) This break was not connected with the recent attachment code changes. --- .../Avatar/Attachments/AttachmentsCommandModule.cs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs index d97e3b3..0333747 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs @@ -176,16 +176,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments // " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n", // attachmentObject.Name, attachmentObject.LocalId, attachmentObject.FromItemID, // (AttachmentPoint)attachmentObject.AttachmentPoint, attachmentObject.RootPart.AttachedPos); - ct.Rows.Add( - new ConsoleDisplayTableRow( - new List() - { - attachmentObject.Name, - attachmentObject.LocalId.ToString(), - attachmentObject.FromItemID.ToString(), - ((AttachmentPoint)attachmentObject.AttachmentPoint).ToString(), - attachmentObject.RootPart.AttachedPos.ToString() - })); + + ct.AddRow( + attachmentObject.Name, + attachmentObject.LocalId, + attachmentObject.FromItemID, + ((AttachmentPoint)attachmentObject.AttachmentPoint), + attachmentObject.RootPart.AttachedPos); // } } -- cgit v1.1 From 8de933ab07a0f9e8291d705a9a03d5b1ba60caa9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 20 Mar 2013 02:09:25 +0000 Subject: Insert a short delay on the simulator side rezzing of attachments in order to fix viewer 3 issues if its own rezzing actions on login collide with the simulator side actions. This resolves issues (at least in my tests with LL 3.3.4) where this can make attachments invisible until one zooms in on the avatar. This doesn't affect version 1 viewers since this delay is shorter than the login delay. This doesn't increase the login time since this part of the process was already being performed asynchronously. This may be a temporary solution. --- OpenSim/Region/Framework/Scenes/Scene.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 3c91c5b..89eca32 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2832,7 +2832,7 @@ namespace OpenSim.Region.Framework.Scenes sp.IsChildAgent = false; if (AttachmentsModule != null) - Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); }); + Util.FireAndForget(o => { Thread.Sleep(5000); AttachmentsModule.RezAttachments(sp); }); } } else -- cgit v1.1 From 36651bed71ce1011c376078943a4fef7e8a9ada6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 20 Mar 2013 23:01:16 +0000 Subject: On the later forms of teleport failure, tell the user if this was because viewer couldn't/didn't connect with destination or if destination didn't signal teleport completion. Also adds regression test for the case where the viewer couldn't connect with the destination region. Also refactoring of regression test support code associated with entity transfer in order to make this test possible and the code less obscure. --- .../Attachments/Tests/AttachmentsModuleTests.cs | 10 +- .../EntityTransfer/EntityTransferModule.cs | 36 +++--- .../Scenes/Tests/ScenePresenceCrossingTests.cs | 9 +- .../Scenes/Tests/ScenePresenceTeleportTests.cs | 135 +++++++++++++++++---- 4 files changed, 150 insertions(+), 40 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 4cd03da..c8c594d 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -829,7 +829,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule()); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1); - ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, ua1.PrincipalID, sh.SceneManager); + + AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); + TestClient tc = new TestClient(acd, sceneA, sh.SceneManager); + List destinationTestClients = new List(); + EntityTransferHelpers.SetUpInformClientOfNeighbour(tc, destinationTestClients); + + ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, tc, acd, sh.SceneManager); beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32); InventoryItemBase attItem = CreateAttachmentItem(sceneA, ua1.PrincipalID, "att", 0x10, 0x20); @@ -848,7 +854,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests teleportLookAt, (uint)TeleportFlags.ViaLocation); - ((TestClient)beforeTeleportSp.ControllingClient).CompleteTeleportClientSide(); + destinationTestClients[0].CompleteMovement(); // Check attachments have made it into sceneB ScenePresence afterTeleportSceneBSp = sceneB.GetScenePresence(ua1.PrincipalID); diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 9b1b69a..58a6654 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -517,12 +517,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName); -// if (!sp.ValidateAttachments()) -// { -// sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state"); -// return; -// } - string reason; string version; if (!Scene.SimulationService.QueryAccess( @@ -583,6 +577,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } // Let's create an agent there if one doesn't exist yet. + // NOTE: logout will always be false for a non-HG teleport. bool logout = false; if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) { @@ -625,11 +620,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (m_eqModule != null) { + // The EnableSimulator message makes the client establish a connection with the destination + // simulator by sending the initial UseCircuitCode UDP packet to the destination containing the + // correct circuit code. m_eqModule.EnableSimulator(destinationHandle, endPoint, sp.UUID); - // ES makes the client send a UseCircuitCode message to the destination, - // which triggers a bunch of things there. - // So let's wait + // XXX: Is this wait necessary? We will always end up waiting on UpdateAgent for the destination + // simulator to confirm that it has established communication with the viewer. Thread.Sleep(200); // At least on LL 3.3.4 for teleports between different regions on the same simulator this appears @@ -640,6 +637,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } else { + // XXX: This is a little misleading since we're information the client of its avatar destination, + // which may or may not be a neighbour region of the source region. This path is probably little + // used anyway (with EQ being the one used). But it is currently being used for test code. sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); } } @@ -657,14 +657,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); + // A common teleport failure occurs when we can send CreateAgent to the + // destination region but the viewer cannot establish the connection (e.g. due to network issues between + // the viewer and the destination). In this case, UpdateAgent timesout after 10 seconds, although then + // there's a further 10 second wait whilst we attempt to tell the destination to delete the agent in Fail(). if (!UpdateAgent(reg, finalDestination, agent, sp)) { - // Region doesn't take it m_log.WarnFormat( - "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Returning avatar to source region.", + "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.", sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); - Fail(sp, finalDestination, logout); + Fail(sp, finalDestination, logout, "Connection between viewer and destination region could not be established."); return; } @@ -705,7 +708,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); - Fail(sp, finalDestination, logout); + Fail(sp, finalDestination, logout, "Destination region did not signal teleport completion."); return; } @@ -788,12 +791,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// /// /// - protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout) + /// Human readable reason for teleport failure. Will be sent to client. + protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string reason) { CleanupAbortedInterRegionTeleport(sp, finalDestination); sp.ControllingClient.SendTeleportFailed( - string.Format("Problems connecting to destination {0}", finalDestination.RegionName)); + string.Format( + "Problems connecting to destination {0}, reason: {1}", finalDestination.RegionName, reason)); + sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); } diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs index 81a2fcc..b67b8b9 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs @@ -66,7 +66,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests public void TestCrossOnSameSimulator() { TestHelpers.InMethod(); -// TestHelpers.EnableLogging(); + TestHelpers.EnableLogging(); UUID userId = TestHelpers.ParseTail(0x1); @@ -94,7 +94,12 @@ namespace OpenSim.Region.Framework.Scenes.Tests // SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA, eqmA); SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB); - ScenePresence originalSp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager); + AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); + TestClient tc = new TestClient(acd, sceneA, sh.SceneManager); + List destinationTestClients = new List(); + EntityTransferHelpers.SetUpInformClientOfNeighbour(tc, destinationTestClients); + + ScenePresence originalSp = SceneHelpers.AddScenePresence(sceneA, tc, acd, sh.SceneManager); originalSp.AbsolutePosition = new Vector3(128, 32, 10); // originalSp.Flying = true; diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs index 8dd1f3d..d6bc313 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs @@ -26,7 +26,10 @@ */ using System; -using System.Reflection; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Text; using Nini.Config; using NUnit.Framework; using OpenMetaverse; @@ -40,8 +43,6 @@ using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; using OpenSim.Region.CoreModules.World.Permissions; using OpenSim.Tests.Common; using OpenSim.Tests.Common.Mock; -using System.IO; -using System.Text; namespace OpenSim.Region.Framework.Scenes.Tests { @@ -68,7 +69,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests } [Test] - public void TestSameRegionTeleport() + public void TestSameRegion() { TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); @@ -106,10 +107,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests } [Test] - public void TestSameSimulatorSeparatedRegionsTeleport() + public void TestSameSimulatorSeparatedRegions() { TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); +// TestHelpers.EnableLogging(); UUID userId = TestHelpers.ParseTail(0x1); @@ -141,9 +142,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager); sp.AbsolutePosition = new Vector3(30, 31, 32); - // XXX: A very nasty hack to tell the client about the destination scene without having to crank the whole - // UDP stack (?) -// ((TestClient)sp.ControllingClient).TeleportTargetScene = sceneB; + List destinationTestClients = new List(); + EntityTransferHelpers.SetUpInformClientOfNeighbour((TestClient)sp.ControllingClient, destinationTestClients); sceneA.RequestTeleportLocation( sp.ControllingClient, @@ -152,7 +152,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests teleportLookAt, (uint)TeleportFlags.ViaLocation); - ((TestClient)sp.ControllingClient).CompleteTeleportClientSide(); + // SetupInformClientOfNeighbour() will have handled the callback into the target scene to setup the child + // agent. This call will now complete the movement of the user into the destination and upgrade the agent + // from child to root. + destinationTestClients[0].CompleteMovement(); Assert.That(sceneA.GetScenePresence(userId), Is.Null); @@ -177,7 +180,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests /// Test teleport procedures when the target simulator returns false when queried about access. /// [Test] - public void TestSameSimulatorSeparatedRegionsQueryAccessFails() + public void TestSameSimulatorSeparatedRegions_DeniedOnQueryAccess() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); @@ -261,7 +264,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests /// Test teleport procedures when the target simulator create agent step is refused. /// [Test] - public void TestSameSimulatorSeparatedRegionsCreateAgentFails() + public void TestSameSimulatorSeparatedRegions_DeniedOnCreateAgent() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); @@ -333,13 +336,101 @@ namespace OpenSim.Region.Framework.Scenes.Tests // TestHelpers.DisableLogging(); } + /// + /// Test teleport when the destination region does not process (or does not receive) the connection attempt + /// from the viewer. + /// + /// + /// This could be quite a common case where the source region can connect to a remove destination region + /// (for CreateAgent) but the viewer cannot reach the destination region due to network issues. + /// [Test] - public void TestSameSimulatorNeighbouringRegionsTeleport() + public void TestSameSimulatorSeparatedRegions_DestinationDidNotProcessViewerConnection() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); UUID userId = TestHelpers.ParseTail(0x1); + Vector3 preTeleportPosition = new Vector3(30, 31, 32); + + EntityTransferModule etmA = new EntityTransferModule(); + EntityTransferModule etmB = new EntityTransferModule(); + + LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); + + IConfigSource config = new IniConfigSource(); + config.AddConfig("Modules"); + config.Configs["Modules"].Set("EntityTransferModule", etmA.Name); + config.Configs["Modules"].Set("SimulationServices", lscm.Name); + + config.AddConfig("EntityTransfer"); + + // In order to run a single threaded regression test we do not want the entity transfer module waiting + // for a callback from the destination scene before removing its avatar data. + config.Configs["EntityTransfer"].Set("wait_for_callback", false); + +// config.AddConfig("Startup"); +// config.Configs["Startup"].Set("serverside_object_permissions", true); + + SceneHelpers sh = new SceneHelpers(); + TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); + TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1002, 1000); + + SceneHelpers.SetupSceneModules(sceneA, config, etmA ); + + // We need to set up the permisions module on scene B so that our later use of agent limit to deny + // QueryAccess won't succeed anyway because administrators are always allowed in and the default + // IsAdministrator if no permissions module is present is true. + SceneHelpers.SetupSceneModules(sceneB, config, new object[] { new PermissionsModule(), etmB }); + + // Shared scene modules + SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); + + Vector3 teleportPosition = new Vector3(10, 11, 12); + Vector3 teleportLookAt = new Vector3(20, 21, 22); + + ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager); + sp.AbsolutePosition = preTeleportPosition; + + sceneA.RequestTeleportLocation( + sp.ControllingClient, + sceneB.RegionInfo.RegionHandle, + teleportPosition, + teleportLookAt, + (uint)TeleportFlags.ViaLocation); + + // FIXME: Not setting up InformClientOfNeighbour on the TestClient means that it does not initiate + // communication with the destination region. But this is a very non-obvious way of doing it - really we + // should be forced to expicitly set this up. + + Assert.That(sceneB.GetScenePresence(userId), Is.Null); + + ScenePresence sceneASp = sceneA.GetScenePresence(userId); + Assert.That(sceneASp, Is.Not.Null); + Assert.That(sceneASp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneA.RegionInfo.RegionName)); + Assert.That(sceneASp.AbsolutePosition, Is.EqualTo(preTeleportPosition)); + + Assert.That(sceneA.GetRootAgentCount(), Is.EqualTo(1)); + Assert.That(sceneA.GetChildAgentCount(), Is.EqualTo(0)); + Assert.That(sceneB.GetRootAgentCount(), Is.EqualTo(0)); + Assert.That(sceneB.GetChildAgentCount(), Is.EqualTo(0)); + + // TODO: Add assertions to check correct circuit details in both scenes. + + // Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera + // position instead). +// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt)); + +// TestHelpers.DisableLogging(); + } + + [Test] + public void TestSameSimulatorNeighbouringRegions() + { + TestHelpers.InMethod(); + TestHelpers.EnableLogging(); + + UUID userId = TestHelpers.ParseTail(0x1); EntityTransferModule etmA = new EntityTransferModule(); EntityTransferModule etmB = new EntityTransferModule(); @@ -366,10 +457,14 @@ namespace OpenSim.Region.Framework.Scenes.Tests Vector3 teleportPosition = new Vector3(10, 11, 12); Vector3 teleportLookAt = new Vector3(20, 21, 22); - ScenePresence originalSp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager); - originalSp.AbsolutePosition = new Vector3(30, 31, 32); + AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); + TestClient tc = new TestClient(acd, sceneA, sh.SceneManager); + List destinationTestClients = new List(); + EntityTransferHelpers.SetUpInformClientOfNeighbour(tc, destinationTestClients); + + ScenePresence beforeSceneASp = SceneHelpers.AddScenePresence(sceneA, tc, acd, sh.SceneManager); + beforeSceneASp.AbsolutePosition = new Vector3(30, 31, 32); - ScenePresence beforeSceneASp = sceneA.GetScenePresence(userId); Assert.That(beforeSceneASp, Is.Not.Null); Assert.That(beforeSceneASp.IsChildAgent, Is.False); @@ -377,10 +472,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(beforeSceneBSp, Is.Not.Null); Assert.That(beforeSceneBSp.IsChildAgent, Is.True); - // XXX: A very nasty hack to tell the client about the destination scene without having to crank the whole - // UDP stack (?) -// ((TestClient)beforeSceneASp.ControllingClient).TeleportTargetScene = sceneB; - + // In this case, we will not receieve a second InformClientOfNeighbour since the viewer already knows + // about the neighbour region it is teleporting to. sceneA.RequestTeleportLocation( beforeSceneASp.ControllingClient, sceneB.RegionInfo.RegionHandle, @@ -388,7 +481,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests teleportLookAt, (uint)TeleportFlags.ViaLocation); - ((TestClient)beforeSceneASp.ControllingClient).CompleteTeleportClientSide(); + destinationTestClients[0].CompleteMovement(); ScenePresence afterSceneASp = sceneA.GetScenePresence(userId); Assert.That(afterSceneASp, Is.Not.Null); -- cgit v1.1 From b1cd1d917e25e34c2efda65ab52164269863da87 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 20 Mar 2013 23:12:13 +0000 Subject: minor: don't bother with the pause before rezzing attachments if we are running regression tests (fire and forget calls launched on the same thread). Also adds code comments as to why this pause exists. --- OpenSim/Region/Framework/Scenes/Scene.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 89eca32..c9c0662 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2831,8 +2831,22 @@ namespace OpenSim.Region.Framework.Scenes // XXX: This is convoluted. sp.IsChildAgent = false; + // We leave a 5 second pause before attempting to rez attachments to avoid a clash with + // version 3 viewers that maybe doing their own attachment rezzing related to their current + // outfit folder on startup. If these operations do clash, then the symptoms are invisible + // attachments until one zooms in on the avatar. + // + // We do not pause if we are launching on the same thread anyway in order to avoid pointlessly + // delaying any attachment related regression tests. if (AttachmentsModule != null) - Util.FireAndForget(o => { Thread.Sleep(5000); AttachmentsModule.RezAttachments(sp); }); + Util.FireAndForget( + o => + { + if (Util.FireAndForgetMethod != FireAndForgetMethod.None) + Thread.Sleep(5000); + + AttachmentsModule.RezAttachments(sp); + }); } } else -- cgit v1.1 From 4de530af45c86a003676a10d6b037a5acec3646c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 20 Mar 2013 23:13:12 +0000 Subject: minor: disable logging on regression TestCrossOnSameSimulator() that I accidentally left on a few commits ago. --- OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs index b67b8b9..8775949 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs @@ -66,7 +66,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests public void TestCrossOnSameSimulator() { TestHelpers.InMethod(); - TestHelpers.EnableLogging(); +// TestHelpers.EnableLogging(); UUID userId = TestHelpers.ParseTail(0x1); -- cgit v1.1 From cc504eb0d136d6555ddae990a98592eaf123816a Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 21 Mar 2013 01:44:09 +0100 Subject: Fix SceneManager to use the new automatic property throughout. --- OpenSim/Region/Framework/Scenes/SceneManager.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs index c307f7a..c70342f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneManager.cs +++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs @@ -100,7 +100,6 @@ namespace OpenSim.Region.Framework.Scenes } private readonly DoubleDictionary m_localScenes = new DoubleDictionary(); - private Scene m_currentScene = null; public List Scenes { @@ -354,7 +353,7 @@ namespace OpenSim.Region.Framework.Scenes if (m_localScenes.TryGetValue(regionName, out s)) { - m_currentScene = s; + CurrentScene = s; return true; } @@ -370,7 +369,7 @@ namespace OpenSim.Region.Framework.Scenes if (m_localScenes.TryGetValue(regionID, out s)) { - m_currentScene = s; + CurrentScene = s; return true; } -- cgit v1.1 From 46c833810ccd9dd0c3273803e208dc85bb0860a9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 21 Mar 2013 00:46:08 +0000 Subject: On a teleport, lock m_agentsInTransit whilst we grab the value to check for completion just to be sure we're not using a thread cached version. --- .../Framework/EntityTransfer/EntityTransferStateMachine.cs | 9 ++++++++- .../Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs | 8 ++++---- 2 files changed, 12 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs index 24d81d9..7314727 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs @@ -292,8 +292,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // There should be no race condition here since no other code should be removing the agent transfer or // changing the state to another other than Transferring => ReceivedAtDestination. - while (m_agentsInTransit[id] != AgentTransferState.ReceivedAtDestination && count-- > 0) + + while (count-- > 0) { + lock (m_agentsInTransit) + { + if (m_agentsInTransit[id] == AgentTransferState.ReceivedAtDestination) + break; + } + // m_log.Debug(" >>> Waiting... " + count); Thread.Sleep(100); } diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs index d6bc313..de4458d 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs @@ -107,7 +107,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests } [Test] - public void TestSameSimulatorSeparatedRegions() + public void TestSameSimulatorIsolatedRegions() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); @@ -180,7 +180,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests /// Test teleport procedures when the target simulator returns false when queried about access. /// [Test] - public void TestSameSimulatorSeparatedRegions_DeniedOnQueryAccess() + public void TestSameSimulatorIsolatedRegions_DeniedOnQueryAccess() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); @@ -264,7 +264,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests /// Test teleport procedures when the target simulator create agent step is refused. /// [Test] - public void TestSameSimulatorSeparatedRegions_DeniedOnCreateAgent() + public void TestSameSimulatorIsolatedRegions_DeniedOnCreateAgent() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); @@ -345,7 +345,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests /// (for CreateAgent) but the viewer cannot reach the destination region due to network issues. /// [Test] - public void TestSameSimulatorSeparatedRegions_DestinationDidNotProcessViewerConnection() + public void TestSameSimulatorIsolatedRegions_DestinationDidNotProcessViewerConnection() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); -- cgit v1.1 From e23a0dcc5dd5f2869fe0da39452e075cec34199b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 21 Mar 2013 23:37:23 +0000 Subject: minor: On teleport, signal a child agent before we send the viewer TeleportFinish in order to avoid a theoretical race condition when teleporting to a neighbour. If we do this after TeleportFinish, then it's possible for a neighbour destination to request the source to create a child agent whilst its still treated as root. This closes the original presence which we don't really want to do. This is probably okay (albeit with warnings on the console) but afaics there's no reason not to move the child agent signal. --- .../Framework/EntityTransfer/EntityTransferModule.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 58a6654..82358d8 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -686,6 +686,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", capsPath, sp.Scene.RegionInfo.RegionName, sp.Name); + // We need to set this here to avoid an unlikely race condition when teleporting to a neighbour simulator, + // where that neighbour simulator could otherwise request a child agent create on the source which then + // closes our existing agent which is still signalled as root. + sp.IsChildAgent = true; + if (m_eqModule != null) { m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID); @@ -696,9 +701,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer teleportFlags, capsPath); } - // Let's set this to true tentatively. This does not trigger OnChildAgent - sp.IsChildAgent = true; - // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation // that the client contacted the destination before we close things here. @@ -731,8 +733,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Now let's make it officially a child agent sp.MakeChildAgent(); -// sp.Scene.CleanDroppedAttachments(); - // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) -- cgit v1.1 From 476a7d3eee1afc42ac501ac265d63f8fe52e27a6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 22 Mar 2013 00:03:10 +0000 Subject: Implement chat across region borders since we can tell if avatars in neighbouring regions are in range. --- OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs index 6d62ff0..9032dd4 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs @@ -240,7 +240,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat { // This should use ForEachClient, but clients don't have a position. // If camera is moved into client, then camera position can be used - s.ForEachRootScenePresence( + s.ForEachScenePresence( delegate(ScenePresence presence) { if (TrySendChatMessage( -- cgit v1.1 From 7471bc77757ce0b294d04f0eb552dbc5ea749793 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 22 Mar 2013 01:00:13 +0000 Subject: At strategic points in the teleport process, if the client has simultaneously logged out then do not continue. This aims to reduce any side effects if the process tries to complete after the client has logged back in (e.g. it was delayed due to a slow destination region response). This introduces a new Aborting entity transfer state which signals that the teleport should be stopped but no compensating actions performed. --- .../EntityTransfer/EntityTransferModule.cs | 59 ++++++++++++++++++++-- .../EntityTransfer/EntityTransferStateMachine.cs | 20 +++++--- 2 files changed, 69 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 82358d8..5713e88 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -167,6 +167,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (!DisableInterRegionTeleportCancellation) client.OnTeleportCancel += OnClientCancelTeleport; + + client.OnConnectionClosed += OnConnectionClosed; } public virtual void Close() {} @@ -185,6 +187,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #region Agent Teleports + private void OnConnectionClosed(IClientAPI client) + { + if (client.IsLoggingOut) + { + m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Aborting); + + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Aborted teleport request from {0} in {1} due to simultaneous logout", + client.Name, Scene.Name); + } + } + private void OnClientCancelTeleport(IClientAPI client) { m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Cancelling); @@ -590,6 +604,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } + Thread.Sleep(30000); + if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling) { m_log.DebugFormat( @@ -598,6 +614,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } + else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) + { + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.", + sp.Name, finalDestination.RegionName, sp.Scene.Name); + + return; + } // Past this point we have to attempt clean up if the teleport fails, so update transfer state. m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); @@ -657,12 +681,32 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); + // We will check for an abort before UpdateAgent since UpdateAgent will require an active viewer to + // establish th econnection to the destination which makes it return true. + if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) + { + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} before UpdateAgent", + sp.Name, finalDestination.RegionName, sp.Scene.Name); + + return; + } + // A common teleport failure occurs when we can send CreateAgent to the // destination region but the viewer cannot establish the connection (e.g. due to network issues between // the viewer and the destination). In this case, UpdateAgent timesout after 10 seconds, although then // there's a further 10 second wait whilst we attempt to tell the destination to delete the agent in Fail(). if (!UpdateAgent(reg, finalDestination, agent, sp)) { + if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) + { + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.", + sp.Name, finalDestination.RegionName, sp.Scene.Name); + + return; + } + m_log.WarnFormat( "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.", sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); @@ -677,7 +721,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request", sp.Name, finalDestination.RegionName, sp.Scene.Name); - CleanupAbortedInterRegionTeleport(sp, finalDestination); + CleanupFailedInterRegionTeleport(sp, finalDestination); return; } @@ -706,6 +750,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // that the client contacted the destination before we close things here. if (!m_entityTransferStateMachine.WaitForAgentArrivedAtDestination(sp.UUID)) { + if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) + { + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after WaitForAgentArrivedAtDestination due to previous client close.", + sp.Name, finalDestination.RegionName, sp.Scene.Name); + + return; + } + m_log.WarnFormat( "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); @@ -772,7 +825,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// /// /// - protected virtual void CleanupAbortedInterRegionTeleport(ScenePresence sp, GridRegion finalDestination) + protected virtual void CleanupFailedInterRegionTeleport(ScenePresence sp, GridRegion finalDestination) { m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); @@ -794,7 +847,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// Human readable reason for teleport failure. Will be sent to client. protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string reason) { - CleanupAbortedInterRegionTeleport(sp, finalDestination); + CleanupFailedInterRegionTeleport(sp, finalDestination); sp.ControllingClient.SendTeleportFailed( string.Format( diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs index 7314727..fc02916 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs @@ -51,11 +51,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// This is a state machine. /// /// [Entry] => Preparing - /// Preparing => { Transferring || Cancelling || CleaningUp || [Exit] } - /// Transferring => { ReceivedAtDestination || Cancelling || CleaningUp } - /// Cancelling => CleaningUp - /// ReceivedAtDestination => CleaningUp + /// Preparing => { Transferring || Cancelling || CleaningUp || Aborting || [Exit] } + /// Transferring => { ReceivedAtDestination || Cancelling || CleaningUp || Aborting } + /// Cancelling => CleaningUp || Aborting + /// ReceivedAtDestination => CleaningUp || Aborting /// CleaningUp => [Exit] + /// Aborting => [Exit] /// /// In other words, agents normally travel throwing Preparing => Transferring => ReceivedAtDestination => CleaningUp /// However, any state can transition to CleaningUp if the teleport has failed. @@ -66,7 +67,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer Transferring, // The agent is in the process of being transferred to a destination ReceivedAtDestination, // The destination has notified us that the agent has been successfully received CleaningUp, // The agent is being changed to child/removed after a transfer - Cancelling // The user has cancelled the teleport but we have yet to act upon this. + Cancelling, // The user has cancelled the teleport but we have yet to act upon this. + Aborting // The transfer is aborting. Unlike Cancelling, no compensating actions should be performed } /// @@ -134,7 +136,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Illegal to try and update an agent that's not actually in transit. if (!m_agentsInTransit.ContainsKey(id)) { - if (newState != AgentTransferState.Cancelling) + if (newState != AgentTransferState.Cancelling && newState != AgentTransferState.Aborting) failureMessage = string.Format( "Agent with ID {0} is not registered as in transit in {1}", id, m_mod.Scene.RegionInfo.RegionName); @@ -145,7 +147,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { oldState = m_agentsInTransit[id]; - if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp) + if (newState == AgentTransferState.Aborting) + { + transitionOkay = true; + } + else if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp) { transitionOkay = true; } -- cgit v1.1 From 1f17ef6d3ce8d3db22d4179cbbc1aee3503610ea Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 22 Mar 2013 01:06:56 +0000 Subject: Take out a testing sleep I accidentally left in the teleport code from last commit 7471bc7 --- .../Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 2 -- 1 file changed, 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 5713e88..26267e2 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -604,8 +604,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - Thread.Sleep(30000); - if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling) { m_log.DebugFormat( -- cgit v1.1 From c4d9a23f2666d0284f2e65d1ee757bc17c3f56ad Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 22 Mar 2013 01:42:47 +0000 Subject: Following on from 476a7d3e (which wasn't enough), make chat across regions on different simulators work. Also resolves an issue of multiple chatting if the originating simulators had more than one region and they were neighbours --- .../Region/CoreModules/Avatar/Chat/ChatModule.cs | 87 ++++++++-------------- 1 file changed, 31 insertions(+), 56 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs index 9032dd4..58f747b 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs @@ -50,7 +50,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat private int m_saydistance = 20; private int m_shoutdistance = 100; private int m_whisperdistance = 10; - private List m_scenes = new List(); internal object m_syncy = new object(); @@ -82,18 +81,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat public virtual void AddRegion(Scene scene) { - if (!m_enabled) return; + if (!m_enabled) + return; - lock (m_syncy) - { - if (!m_scenes.Contains(scene)) - { - m_scenes.Add(scene); - scene.EventManager.OnNewClient += OnNewClient; - scene.EventManager.OnChatFromWorld += OnChatFromWorld; - scene.EventManager.OnChatBroadcast += OnChatBroadcast; - } - } + scene.EventManager.OnNewClient += OnNewClient; + scene.EventManager.OnChatFromWorld += OnChatFromWorld; + scene.EventManager.OnChatBroadcast += OnChatBroadcast; m_log.InfoFormat("[CHAT]: Initialized for {0} w:{1} s:{2} S:{3}", scene.RegionInfo.RegionName, m_whisperdistance, m_saydistance, m_shoutdistance); @@ -105,18 +98,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat public virtual void RemoveRegion(Scene scene) { - if (!m_enabled) return; + if (!m_enabled) + return; - lock (m_syncy) - { - if (m_scenes.Contains(scene)) - { - scene.EventManager.OnNewClient -= OnNewClient; - scene.EventManager.OnChatFromWorld -= OnChatFromWorld; - scene.EventManager.OnChatBroadcast -= OnChatBroadcast; - m_scenes.Remove(scene); - } - } + scene.EventManager.OnNewClient -= OnNewClient; + scene.EventManager.OnChatFromWorld -= OnChatFromWorld; + scene.EventManager.OnChatBroadcast -= OnChatBroadcast; } public virtual void Close() @@ -191,7 +178,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat UUID ownerID = UUID.Zero; UUID targetID = c.TargetUUID; string message = c.Message; - IScene scene = c.Scene; + Scene scene = (Scene)c.Scene; Vector3 fromPos = c.Position; Vector3 regionPos = new Vector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); @@ -201,13 +188,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat switch (sourceType) { case ChatSourceType.Agent: - if (!(scene is Scene)) - { - m_log.WarnFormat("[CHAT]: scene {0} is not a Scene object, cannot obtain scene presence for {1}", - scene.RegionInfo.RegionName, c.Sender.AgentId); - return; - } - ScenePresence avatar = (scene as Scene).GetScenePresence(c.Sender.AgentId); + ScenePresence avatar = scene.GetScenePresence(c.Sender.AgentId); fromPos = avatar.AbsolutePosition; fromName = avatar.Name; fromID = c.Sender.AgentId; @@ -234,36 +215,33 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat HashSet receiverIDs = new HashSet(); - foreach (Scene s in m_scenes) + if (targetID == UUID.Zero) { - if (targetID == UUID.Zero) - { - // This should use ForEachClient, but clients don't have a position. - // If camera is moved into client, then camera position can be used - s.ForEachScenePresence( - delegate(ScenePresence presence) - { - if (TrySendChatMessage( - presence, fromPos, regionPos, fromID, ownerID, fromName, c.Type, message, sourceType, false)) - receiverIDs.Add(presence.UUID); - } - ); - } - else - { - // This is a send to a specific client eg from llRegionSayTo - // no need to check distance etc, jand send is as say - ScenePresence presence = s.GetScenePresence(targetID); - if (presence != null && !presence.IsChildAgent) + // This should use ForEachClient, but clients don't have a position. + // If camera is moved into client, then camera position can be used + scene.ForEachScenePresence( + delegate(ScenePresence presence) { if (TrySendChatMessage( - presence, fromPos, regionPos, fromID, ownerID, fromName, ChatTypeEnum.Say, message, sourceType, true)) + presence, fromPos, regionPos, fromID, ownerID, fromName, c.Type, message, sourceType, false)) receiverIDs.Add(presence.UUID); } + ); + } + else + { + // This is a send to a specific client eg from llRegionSayTo + // no need to check distance etc, jand send is as say + ScenePresence presence = scene.GetScenePresence(targetID); + if (presence != null && !presence.IsChildAgent) + { + if (TrySendChatMessage( + presence, fromPos, regionPos, fromID, ownerID, fromName, ChatTypeEnum.Say, message, sourceType, true)) + receiverIDs.Add(presence.UUID); } } - (scene as Scene).EventManager.TriggerOnChatToClients( + scene.EventManager.TriggerOnChatToClients( fromID, receiverIDs, message, c.Type, fromPos, fromName, sourceType, ChatAudibleLevel.Fully); } @@ -348,9 +326,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat UUID fromAgentID, UUID ownerID, string fromName, ChatTypeEnum type, string message, ChatSourceType src, bool ignoreDistance) { - // don't send stuff to child agents - if (presence.IsChildAgent) return false; - Vector3 fromRegionPos = fromPos + regionPos; Vector3 toRegionPos = presence.AbsolutePosition + new Vector3(presence.Scene.RegionInfo.RegionLocX * Constants.RegionSize, -- cgit v1.1 From 93206ef0fa6dffe93313455b3354ce3787e7262d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 23 Mar 2013 00:39:03 +0000 Subject: Add "show borders" command to show the borders of a region. This is relevant to mega-regions where the borders are very different to a regular region. Also adds some method doc and other code comments. --- .../EntityTransfer/EntityTransferModule.cs | 4 +++ OpenSim/Region/Framework/Scenes/Border.cs | 7 +++-- OpenSim/Region/Framework/Scenes/Scene.cs | 1 - OpenSim/Region/Framework/Scenes/ScenePresence.cs | 14 +++++++--- .../World/SceneCommands/SceneCommandsModule.cs | 31 ++++++++++++++++++++++ .../RegionCombinerModule/RegionCombinerModule.cs | 8 +++--- 6 files changed, 54 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 26267e2..136caad 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -994,6 +994,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { Scene scene = agent.Scene; Vector3 pos = agent.AbsolutePosition; + +// m_log.DebugFormat( +// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); + Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z); uint neighbourx = scene.RegionInfo.RegionLocX; uint neighboury = scene.RegionInfo.RegionLocY; diff --git a/OpenSim/Region/Framework/Scenes/Border.cs b/OpenSim/Region/Framework/Scenes/Border.cs index c6a6511..08c0c31 100644 --- a/OpenSim/Region/Framework/Scenes/Border.cs +++ b/OpenSim/Region/Framework/Scenes/Border.cs @@ -33,8 +33,7 @@ using OpenMetaverse; namespace OpenSim.Region.Framework.Scenes { public class Border - { - + { /// /// Line perpendicular to the Direction Cardinal. Z value is the /// @@ -81,6 +80,10 @@ namespace OpenSim.Region.Framework.Scenes TriggerRegionY = triggerRegionY; } + /// + /// Tests to see if the given position would cross this border. + /// + /// public bool TestCross(Vector3 position) { bool result = false; diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index c9c0662..e8f00a4 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2541,7 +2541,6 @@ namespace OpenSim.Region.Framework.Scenes } } - return null; } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 6d96c93..f7ae3a2 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -442,9 +442,9 @@ namespace OpenSim.Region.Framework.Scenes { m_pos = PhysicsActor.Position; - //m_log.DebugFormat( - // "[SCENE PRESENCE]: Set position {0} for {1} in {2} via getting AbsolutePosition!", - // m_pos, Name, Scene.RegionInfo.RegionName); +// m_log.DebugFormat( +// "[SCENE PRESENCE]: Set position of {0} in {1} to {2} via getting AbsolutePosition!", +// Name, Scene.Name, m_pos); } else { @@ -471,6 +471,9 @@ namespace OpenSim.Region.Framework.Scenes } set { +// m_log.DebugFormat("[SCENE PRESENCE]: Setting position of {0} in {1} to {2}", Name, Scene.Name, value); +// Util.PrintCallStack(); + if (PhysicsActor != null) { try @@ -878,6 +881,7 @@ namespace OpenSim.Region.Framework.Scenes // before the inventory is processed in MakeRootAgent. This fixes a race condition // related to the handling of attachments //m_scene.GetAvatarAppearance(ControllingClient, out Appearance); + if (m_scene.TestBorderCross(pos, Cardinals.E)) { Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); @@ -2909,6 +2913,10 @@ namespace OpenSim.Region.Framework.Scenes if (!IsInTransit) { +// m_log.DebugFormat( +// "[SCENE PRESENCE]: Testing border check for projected position {0} of {1} in {2}", +// pos2, Name, Scene.Name); + // Checks if where it's headed exists a region bool needsTransit = false; if (m_scene.TestBorderCross(pos2, Cardinals.W)) diff --git a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs index 5fb74b0..29b39e0 100644 --- a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs +++ b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs @@ -116,6 +116,37 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments + "If teleport is true then some extra teleport debug information is logged.\n" + "If updates is true then any frame which exceeds double the maximum desired frame time is logged.", HandleDebugSceneSetCommand); + + scene.AddCommand( + "Regions", + this, "show borders", "show borders", "Show border information for regions", HandleShowBordersCommand); + } + + private void HandleShowBordersCommand(string module, string[] args) + { + StringBuilder sb = new StringBuilder(); + sb.AppendFormat("Borders for {0}:\n", m_scene.Name); + + ConsoleDisplayTable cdt = new ConsoleDisplayTable(); + cdt.AddColumn("Cross Direction", 15); + cdt.AddColumn("Line", 34); + cdt.AddColumn("Trigger Region", 14); + + foreach (Border b in m_scene.NorthBorders) + cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY)); + + foreach (Border b in m_scene.EastBorders) + cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY)); + + foreach (Border b in m_scene.SouthBorders) + cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY)); + + foreach (Border b in m_scene.WestBorders) + cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY)); + + cdt.AddToStringBuilder(sb); + + MainConsole.Instance.Output(sb.ToString()); } private void HandleDebugSceneGetCommand(string module, string[] args) diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index 905540d..7127c73 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs @@ -415,18 +415,17 @@ namespace OpenSim.Region.RegionCombinerModule */ #endregion - // If we're one region over +x y + // If we're one region over +x y (i.e. root region is to the west) //xxx //xxy //xxx - if (rootConn.PosX + rootConn.XEnd >= newConn.PosX && rootConn.PosY >= newConn.PosY) { connectedYN = DoWorkForOneRegionOverPlusXY(rootConn, newConn, scene); break; } - // If we're one region over x +y + // If we're one region over x +y (i.e. root region is to the south) //xyx //xxx //xxx @@ -436,7 +435,7 @@ namespace OpenSim.Region.RegionCombinerModule break; } - // If we're one region over +x +y + // If we're one region over +x +y (i.e. root region is to the south-west) //xxy //xxx //xxx @@ -646,7 +645,6 @@ namespace OpenSim.Region.RegionCombinerModule { if (rootConn.RegionScene.EastBorders.Count == 1)// && conn.RegionScene.EastBorders.Count == 2) { - rootConn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; lock (rootConn.RegionScene.NorthBorders) -- cgit v1.1 From 01636ca90015561366130a3db9b19e4eb976b80a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 23 Mar 2013 00:47:59 +0000 Subject: Fix teleporting into the non-SW 256x256 corner of a megaregion, though currently with a 10 second delay before auto-reteleport to the correct location. This now does a check for border crossing (required to trigger the teleport) immediately in SP.MakeRootAgent(). If left any later, it looks like the physics scene changes the position and stops the cross happening. If done any earlier, nothing happens because the cross-code currently requires a PhysicsActor to be in place, thuogh it's probably not necessary for this case. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index f7ae3a2..f3b923f 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -925,6 +925,13 @@ namespace OpenSim.Region.Framework.Scenes AddToPhysicalScene(isFlying); + // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a + // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it + // since it requires a physics actor to be present. If it is left any later, then physics appears to reset + // the value to a negative position which does not trigger the border cross. + // This may not be the best location for this. + CheckForBorderCrossing(); + if (ForceFly) { Flying = true; -- cgit v1.1 From c341664c1b8ccf3bd7b81795b900b971a15ff318 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 24 Mar 2013 18:56:28 +0100 Subject: Phase 1 of implementing a transfer permission. Overwrite libOMV's PermissionMask with our own and add export permissions as well as a new definition for "All" as meaning "all conventional permissions" rather than "all possible permissions" --- .../Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 9 +++++---- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 8 +++++--- .../CoreModules/Agent/AssetTransaction/AssetXferUploader.cs | 5 +++-- .../CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | 1 + OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs | 1 + .../Framework/InventoryAccess/InventoryAccessModule.cs | 7 +++++-- OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs | 1 + OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs | 1 + .../Region/CoreModules/World/Objects/BuySell/BuySellModule.cs | 1 + .../Region/CoreModules/World/Permissions/PermissionsModule.cs | 1 + OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 7 ++++--- OpenSim/Region/Framework/Scenes/Scene.cs | 1 + OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs | 1 + OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 1 + OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 1 + OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 1 + .../OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs | 1 + .../OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs | 3 ++- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 1 + .../Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 5 +++-- 20 files changed, 40 insertions(+), 17 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index eadca9b..921d3bf 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -50,6 +50,7 @@ using OpenSim.Services.Interfaces; using Caps = OpenSim.Framework.Capabilities.Caps; using OSDArray = OpenMetaverse.StructuredData.OSDArray; using OSDMap = OpenMetaverse.StructuredData.OSDMap; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.ClientStack.Linden { @@ -830,9 +831,9 @@ namespace OpenSim.Region.ClientStack.Linden texitem.Folder = texturesFolder; texitem.CurrentPermissions - = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer); + = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Export); - texitem.BasePermissions = (uint)PermissionMask.All; + texitem.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export; texitem.EveryOnePermissions = 0; texitem.NextPermissions = (uint)PermissionMask.All; texitem.CreationDate = Util.UnixTimeSinceEpoch(); @@ -1097,9 +1098,9 @@ namespace OpenSim.Region.ClientStack.Linden else { item.CurrentPermissions - = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer); + = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Export); - item.BasePermissions = (uint)PermissionMask.All; + item.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export; item.EveryOnePermissions = 0; item.NextPermissions = (uint)PermissionMask.All; } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 5b2bad4..f8b9352 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -51,6 +51,7 @@ using RegionFlags = OpenMetaverse.RegionFlags; using Nini.Config; using System.IO; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.ClientStack.LindenUDP { @@ -1802,7 +1803,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item) { - const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All; + // Fudge this value. It's only needed to make the CRC anyway + const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff; FetchInventoryReplyPacket inventoryReply = (FetchInventoryReplyPacket)PacketPool.Instance.GetPacket(PacketType.FetchInventoryReply); // TODO: don't create new blocks if recycling an old packet @@ -2007,7 +2009,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP protected void SendBulkUpdateInventoryItem(InventoryItemBase item) { - const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All; + const uint FULL_MASK_PERMISSIONS = (uint)0x7ffffff; BulkUpdateInventoryPacket bulkUpdate = (BulkUpdateInventoryPacket)PacketPool.Instance.GetPacket(PacketType.BulkUpdateInventory); @@ -2066,7 +2068,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase) public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId) { - const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All; + const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff; UpdateCreateInventoryItemPacket InventoryReply = (UpdateCreateInventoryItemPacket)PacketPool.Instance.GetPacket( diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs index e13f479..ffff37d 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs @@ -34,6 +34,7 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.CoreModules.Agent.AssetTransaction { @@ -430,8 +431,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction item.AssetType = type; item.InvType = invType; item.Folder = InventFolder; - item.BasePermissions = 0x7fffffff; - item.CurrentPermissions = 0x7fffffff; + item.BasePermissions = (uint)(PermissionMask.All | PermissionMask.Export); + item.CurrentPermissions = item.BasePermissions; item.GroupPermissions=0; item.EveryOnePermissions=0; item.NextPermissions = nextPerm; diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 51fe1ea..bc79944 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -40,6 +40,7 @@ using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; using Mono.Addins; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory { diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs index 5ec0ea9..b44a5c9 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs @@ -36,6 +36,7 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; using Mono.Addins; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.CoreModules.Avatar.Friends { diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 6e5a4a5..5aad7f0 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -47,6 +47,7 @@ using OpenMetaverse; using log4net; using Nini.Config; using Mono.Addins; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.CoreModules.Framework.InventoryAccess { @@ -398,7 +399,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess objectGroup.RootPart.NextOwnerMask &= ((uint)PermissionMask.Copy | (uint)PermissionMask.Transfer | - (uint)PermissionMask.Modify); + (uint)PermissionMask.Modify | + (uint)PermissionMask.Export); objectGroup.RootPart.NextOwnerMask |= (uint)PermissionMask.Move; @@ -506,7 +508,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess InventoryItemBase item, SceneObjectGroup so, List objsForEffectivePermissions, IClientAPI remoteClient) { - uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move) | 7; + uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move | PermissionMask.Export) | 7; // For the porposes of inventory, an object is modify if the prims // are modify. This allows renaming an object that contains no // mod items. @@ -555,6 +557,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess (uint)PermissionMask.Transfer | (uint)PermissionMask.Modify | (uint)PermissionMask.Move | + (uint)PermissionMask.Export | 7); // Preserve folded permissions } diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs index ec22146..d07cff4 100644 --- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs @@ -43,6 +43,7 @@ using OpenMetaverse; using log4net; using Mono.Addins; using Nini.Config; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.CoreModules.Framework.Library { diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs index 367693d..a990898 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs @@ -44,6 +44,7 @@ using Ionic.Zlib; using GZipStream = Ionic.Zlib.GZipStream; using CompressionMode = Ionic.Zlib.CompressionMode; using OpenSim.Framework.Serialization.External; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.CoreModules.World.Archiver { diff --git a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs index eb4731c..28daf2f 100644 --- a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs @@ -38,6 +38,7 @@ using OpenSim.Region.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes.Serialization; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.CoreModules.World.Objects.BuySell { diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 121fb2a..79dd4a0 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -38,6 +38,7 @@ using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; using Mono.Addins; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.CoreModules.World.Permissions { diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index a9e1fc2..6a3fb24 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -39,6 +39,7 @@ using OpenSim.Region.Framework; using OpenSim.Framework.Client; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes.Serialization; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.Framework.Scenes { @@ -907,7 +908,7 @@ namespace OpenSim.Region.Framework.Scenes { CreateNewInventoryItem( remoteClient, creatorID, creatorData, folderID, name, description, flags, callbackID, asset, invType, - (uint)PermissionMask.All, (uint)PermissionMask.All, 0, nextOwnerMask, 0, creationDate, transationID); + (uint)PermissionMask.All | (uint)PermissionMask.Export, (uint)PermissionMask.All | (uint)PermissionMask.Export, 0, nextOwnerMask, 0, creationDate, transationID); } @@ -1036,8 +1037,8 @@ namespace OpenSim.Region.Framework.Scenes CreateNewInventoryItem( remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, name, description, 0, callbackID, asset, invType, - (uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All, - (uint)PermissionMask.All, (uint)PermissionMask.All, Util.UnixTimeSinceEpoch()); + (uint)PermissionMask.All | (uint)PermissionMask.Export, (uint)PermissionMask.All | (uint)PermissionMask.Export, (uint)PermissionMask.All, + (uint)PermissionMask.All | (uint)PermissionMask.Export, (uint)PermissionMask.All | (uint)PermissionMask.Export, Util.UnixTimeSinceEpoch()); } else { diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 6b031ae..357a94b 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -51,6 +51,7 @@ using OpenSim.Region.Physics.Manager; using Timer=System.Timers.Timer; using TPFlags = OpenSim.Framework.Constants.TeleportFlags; using GridRegion = OpenSim.Services.Interfaces.GridRegion; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.Framework.Scenes { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index 26524fb..f8624e7 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs @@ -34,6 +34,7 @@ using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using System.Collections.Generic; using System.Xml; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.Framework.Scenes { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 0f5d116..b109b4f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -41,6 +41,7 @@ using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Physics.Manager; using OpenSim.Region.Framework.Scenes.Serialization; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.Framework.Scenes { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index ffde415..9265805 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -43,6 +43,7 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes.Scripting; using OpenSim.Region.Framework.Scenes.Serialization; using OpenSim.Region.Physics.Manager; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.Framework.Scenes { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 3a9a146..d04d87b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -38,6 +38,7 @@ using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes.Scripting; using OpenSim.Region.Framework.Scenes.Serialization; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.Framework.Scenes { diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs index bed192a..8740f87 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs @@ -40,6 +40,7 @@ using OpenSim.Framework.Monitoring; using OpenSim.Region.ClientStack.LindenUDP; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.OptionalModules.Avatar.Attachments { diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index 4a754a9..1bb5aee 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs @@ -42,6 +42,7 @@ using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes.Scripting; using System.Collections.Generic; using System.Text.RegularExpressions; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.OptionalModules.Scripting.JsonStore { @@ -643,4 +644,4 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } } -} \ No newline at end of file +} diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 1fbfc52..f677cdf 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -71,6 +71,7 @@ using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; using System.Reflection; using Timer = System.Timers.Timer; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.ScriptEngine.Shared.Api { diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 234ba34..f4e4f44 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -62,6 +62,7 @@ using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.ScriptEngine.Shared.Api { @@ -1796,8 +1797,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api taskItem.InvType = (int)InventoryType.Notecard; taskItem.OwnerID = m_host.OwnerID; taskItem.CreatorID = m_host.OwnerID; - taskItem.BasePermissions = (uint)PermissionMask.All; - taskItem.CurrentPermissions = (uint)PermissionMask.All; + taskItem.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export; + taskItem.CurrentPermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export; taskItem.EveryonePermissions = 0; taskItem.NextPermissions = (uint)PermissionMask.All; taskItem.GroupID = m_host.GroupID; -- cgit v1.1 From 128c72a23437423d87cc9b10815f96d7362bddd1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 25 Mar 2013 21:24:21 +0000 Subject: Start recording inter-region teleport attempts, aborts, cancels and failures in statistics for monitoring/debugging purposes These are recorded as 'entitytransfer' stats as seen by the "show stats entitytransfer" console command. --- .../EntityTransfer/EntityTransferModule.cs | 119 +++++++++++++++++++-- 1 file changed, 109 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 136caad..4cf7645 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -33,6 +33,7 @@ using System.Threading; using OpenSim.Framework; using OpenSim.Framework.Capabilities; using OpenSim.Framework.Client; +using OpenSim.Framework.Monitoring; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Physics.Manager; @@ -77,6 +78,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// public bool DisableInterRegionTeleportCancellation { get; set; } + /// + /// Number of times inter-region teleport was attempted. + /// + private Stat m_interRegionTeleportAttempts; + + /// + /// Number of times inter-region teleport was aborted (due to simultaneous client logout). + /// + private Stat m_interRegionTeleportAborts; + + /// + /// Number of times inter-region teleport was successfully cancelled by the client. + /// + private Stat m_interRegionTeleportCancels; + + /// + /// Number of times inter-region teleport failed due to server/client/network problems (e.g. viewer failed to + /// connect with destination region). + /// + /// + /// This is not necessarily a problem for this simulator - in open-grid/hg conditions, viewer connectivity to + /// destination simulator is unknown. + /// + private Stat m_interRegionTeleportFailures; + protected bool m_Enabled = false; public Scene Scene { get; private set; } @@ -156,6 +182,60 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer Scene = scene; + m_interRegionTeleportAttempts = + new Stat( + "InterRegionTeleportAttempts", + "Number of inter-region teleports attempted.", + "This does not count attempts which failed due to pre-conditions (e.g. target simulator refused access).\n" + + "You can get successfully teleports by subtracting aborts, cancels and teleport failures from this figure.", + "", + "entitytransfer", + Scene.Name, + StatType.Push, + null, + StatVerbosity.Debug); + + m_interRegionTeleportAborts = + new Stat( + "InterRegionTeleportAborts", + "Number of inter-region teleports aborted due to client actions.", + "The chief action is simultaneous logout whilst teleporting.", + "", + "entitytransfer", + Scene.Name, + StatType.Push, + null, + StatVerbosity.Debug); + + m_interRegionTeleportCancels = + new Stat( + "InterRegionTeleportCancels", + "Number of inter-region teleports cancelled by the client.", + null, + "", + "entitytransfer", + Scene.Name, + StatType.Push, + null, + StatVerbosity.Debug); + + m_interRegionTeleportFailures = + new Stat( + "InterRegionTeleportFailures", + "Number of inter-region teleports that failed due to server/client/network issues.", + "This number may not be very helpful in open-grid/hg situations as the network connectivity/quality of destinations is uncontrollable.", + "", + "entitytransfer", + Scene.Name, + StatType.Push, + null, + StatVerbosity.Debug); + + StatsManager.RegisterStat(m_interRegionTeleportAttempts); + StatsManager.RegisterStat(m_interRegionTeleportAborts); + StatsManager.RegisterStat(m_interRegionTeleportCancels); + StatsManager.RegisterStat(m_interRegionTeleportFailures); + scene.RegisterModuleInterface(this); scene.EventManager.OnNewClient += OnNewClient; } @@ -173,7 +253,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public virtual void Close() {} - public virtual void RemoveRegion(Scene scene) {} + public virtual void RemoveRegion(Scene scene) + { + StatsManager.DeregisterStat(m_interRegionTeleportAttempts); + StatsManager.DeregisterStat(m_interRegionTeleportAborts); + StatsManager.DeregisterStat(m_interRegionTeleportCancels); + StatsManager.DeregisterStat(m_interRegionTeleportFailures); + } public virtual void RegionLoaded(Scene scene) { @@ -545,6 +631,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } + // Before this point, teleport 'failure' is due to checkable pre-conditions such as whether the target + // simulator can be found and is explicitly prepared to allow access. Therefore, we will not count these + // as server attempts. + m_interRegionTeleportAttempts.Value++; + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); // Fixing a bug where teleporting while sitting results in the avatar ending up removed from @@ -595,6 +686,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer bool logout = false; if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) { + m_interRegionTeleportFailures.Value++; + sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason)); m_log.DebugFormat( @@ -606,6 +699,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling) { + m_interRegionTeleportCancels.Value++; + m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request", sp.Name, finalDestination.RegionName, sp.Scene.Name); @@ -614,6 +709,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) { + m_interRegionTeleportAborts.Value++; + m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.", sp.Name, finalDestination.RegionName, sp.Scene.Name); @@ -683,6 +780,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // establish th econnection to the destination which makes it return true. if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) { + m_interRegionTeleportAborts.Value++; + m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} before UpdateAgent", sp.Name, finalDestination.RegionName, sp.Scene.Name); @@ -698,6 +797,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) { + m_interRegionTeleportAborts.Value++; + m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.", sp.Name, finalDestination.RegionName, sp.Scene.Name); @@ -715,6 +816,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling) { + m_interRegionTeleportCancels.Value++; + m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request", sp.Name, finalDestination.RegionName, sp.Scene.Name); @@ -750,6 +853,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) { + m_interRegionTeleportAborts.Value++; + m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after WaitForAgentArrivedAtDestination due to previous client close.", sp.Name, finalDestination.RegionName, sp.Scene.Name); @@ -762,6 +867,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); Fail(sp, finalDestination, logout, "Destination region did not signal teleport completion."); + return; } @@ -803,15 +909,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // now we have a child agent in this region. sp.Reset(); } - - // Commented pending deletion since this method no longer appears to do anything at all -// // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! -// if (sp.Scene.NeedSceneCacheClear(sp.UUID)) -// { -// m_log.DebugFormat( -// "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", -// sp.UUID); -// } } /// @@ -847,6 +944,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { CleanupFailedInterRegionTeleport(sp, finalDestination); + m_interRegionTeleportFailures.Value++; + sp.ControllingClient.SendTeleportFailed( string.Format( "Problems connecting to destination {0}, reason: {1}", finalDestination.RegionName, reason)); -- cgit v1.1 From f783b9169fbc0544ec6c634900cb34bf48c6b2a9 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 22 Mar 2013 16:50:56 -0700 Subject: BulletSim: parameterize C# HACD hull creation. Add feature of reducing max hull count for simple (non-cut prims) meshes. --- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 33 +++++++++++++ .../Physics/BulletSPlugin/BSShapeCollection.cs | 55 ++++++++++++++++------ 2 files changed, 74 insertions(+), 14 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 4d89a88..26d2d60 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -142,6 +142,14 @@ public static class BSParam public static float VehicleAngularBankingTimescaleFudge { get; private set; } public static bool VehicleDebuggingEnabled { get; private set; } + // Convex Hulls + public static int CSHullMaxDepthSplit { get; private set; } + public static int CSHullMaxDepthSplitForSimpleShapes { get; private set; } + public static float CSHullConcavityThresholdPercent { get; private set; } + public static float CSHullVolumeConservationThresholdPercent { get; private set; } + public static int CSHullMaxVertices { get; private set; } + public static float CSHullMaxSkinWidth { get; private set; } + // Linkset implementation parameters public static float LinksetImplementation { get; private set; } public static bool LinkConstraintUseFrameOffset { get; private set; } @@ -623,6 +631,31 @@ public static class BSParam (s) => { return GlobalContactBreakingThreshold; }, (s,v) => { GlobalContactBreakingThreshold = v; s.UnmanagedParams[0].globalContactBreakingThreshold = v; } ), + new ParameterDefn("CSHullMaxDepthSplit", "CS impl: max depth to split for hull. 1-10 but > 7 is iffy", + 7, + (s) => { return CSHullMaxDepthSplit; }, + (s,v) => { CSHullMaxDepthSplit = v; } ), + new ParameterDefn("CSHullMaxDepthSplitForSimpleShapes", "CS impl: max depth setting for simple prim shapes", + 2, + (s) => { return CSHullMaxDepthSplitForSimpleShapes; }, + (s,v) => { CSHullMaxDepthSplitForSimpleShapes = v; } ), + new ParameterDefn("CSHullConcavityThresholdPercent", "CS impl: concavity threshold percent (0-20)", + 5f, + (s) => { return CSHullConcavityThresholdPercent; }, + (s,v) => { CSHullConcavityThresholdPercent = v; } ), + new ParameterDefn("CSHullVolumeConservationThresholdPercent", "percent volume conservation to collapse hulls (0-30)", + 5f, + (s) => { return CSHullVolumeConservationThresholdPercent; }, + (s,v) => { CSHullVolumeConservationThresholdPercent = v; } ), + new ParameterDefn("CSHullMaxVertices", "CS impl: maximum number of vertices in output hulls. Keep < 50.", + 32, + (s) => { return CSHullMaxVertices; }, + (s,v) => { CSHullMaxVertices = v; } ), + new ParameterDefn("CSHullMaxSkinWidth", "CS impl: skin width to apply to output hulls.", + 0, + (s) => { return CSHullMaxSkinWidth; }, + (s,v) => { CSHullMaxSkinWidth = v; } ), + new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", (float)BSLinkset.LinksetImplementation.Compound, (s) => { return LinksetImplementation; }, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index b16bc10..457f204 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -447,17 +447,10 @@ public sealed class BSShapeCollection : IDisposable // If the prim attributes are simple, this could be a simple Bullet native shape if (!haveShape + && nativeShapePossible && pbs != null && !pbs.SculptEntry - && nativeShapePossible - && ((pbs.SculptEntry && !BSParam.ShouldMeshSculptedPrim) - || (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0 - && pbs.ProfileHollow == 0 - && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0 - && pbs.PathBegin == 0 && pbs.PathEnd == 0 - && pbs.PathTaperX == 0 && pbs.PathTaperY == 0 - && pbs.PathScaleX == 100 && pbs.PathScaleY == 100 - && pbs.PathShearX == 0 && pbs.PathShearY == 0) ) ) + && ((pbs.SculptEntry && !BSParam.ShouldMeshSculptedPrim) || PrimHasNoCuts(pbs)) ) { // Get the scale of any existing shape so we can see if the new shape is same native type and same size. OMV.Vector3 scaleOfExistingShape = OMV.Vector3.Zero; @@ -508,6 +501,18 @@ public sealed class BSShapeCollection : IDisposable return ret; } + // return 'true' if this shape description does not include any cutting or twisting. + private bool PrimHasNoCuts(PrimitiveBaseShape pbs) + { + return pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0 + && pbs.ProfileHollow == 0 + && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0 + && pbs.PathBegin == 0 && pbs.PathEnd == 0 + && pbs.PathTaperX == 0 && pbs.PathTaperY == 0 + && pbs.PathScaleX == 100 && pbs.PathScaleY == 100 + && pbs.PathShearX == 0 && pbs.PathShearY == 0; + } + // return 'true' if the prim's shape was changed. public bool CreateGeomMeshOrHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback) { @@ -518,7 +523,7 @@ public sealed class BSShapeCollection : IDisposable if (prim.IsPhysical && BSParam.ShouldUseHullsForPhysicalObjects) { // Update prim.BSShape to reference a hull of this shape. - ret = GetReferenceToHull(prim,shapeCallback); + ret = GetReferenceToHull(prim, shapeCallback); if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); } @@ -697,6 +702,7 @@ public sealed class BSShapeCollection : IDisposable // See that hull shape exists in the physical world and update prim.BSShape. // We could be creating the hull because scale changed or whatever. + // Return 'true' if a new hull was built. Otherwise, returning a shared hull instance. private bool GetReferenceToHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback) { BulletShape newShape; @@ -715,6 +721,7 @@ public sealed class BSShapeCollection : IDisposable DereferenceShape(prim.PhysShape, shapeCallback); newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, prim.BaseShape, prim.Size, lod); + // It might not have been created if we're waiting for an asset. newShape = VerifyMeshCreated(newShape, prim); ReferenceShape(newShape); @@ -733,14 +740,14 @@ public sealed class BSShapeCollection : IDisposable HullDesc hullDesc; if (Hulls.TryGetValue(newHullKey, out hullDesc)) { - // If the hull shape already is created, just use it. + // If the hull shape already has been created, just use the one shared instance. newShape = hullDesc.shape.Clone(); } else { - // Build a new hull in the physical world - // Pass true for physicalness as this creates some sort of bounding box which we don't need - IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false); + // Build a new hull in the physical world. + // Pass true for physicalness as this prevents the creation of bounding box which is not needed + IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */); if (meshData != null) { @@ -759,15 +766,35 @@ public sealed class BSShapeCollection : IDisposable convVertices.Add(new float3(vv.X, vv.Y, vv.Z)); } + uint maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplit; + if (BSParam.CSHullMaxDepthSplit != BSParam.CSHullMaxDepthSplitForSimpleShapes) + { + // Simple primitive shapes we know are convex so they are better implemented with + // fewer hulls. + // Check for simple shape (prim without cuts) and reduce split parameter if so. + if (PrimHasNoCuts(pbs)) + { + maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplitForSimpleShapes; + } + } + // setup and do convex hull conversion m_hulls = new List(); DecompDesc dcomp = new DecompDesc(); dcomp.mIndices = convIndices; dcomp.mVertices = convVertices; + dcomp.mDepth = maxDepthSplit; + dcomp.mCpercent = BSParam.CSHullConcavityThresholdPercent; + dcomp.mPpercent = BSParam.CSHullVolumeConservationThresholdPercent; + dcomp.mMaxVertices = (uint)BSParam.CSHullMaxVertices; + dcomp.mSkinWidth = BSParam.CSHullMaxSkinWidth; ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn); // create the hull into the _hulls variable convexBuilder.process(dcomp); + DetailLog("{0},BSShapeCollection.CreatePhysicalHull,key={1},inVert={2},inInd={3},split={4},hulls={5}", + BSScene.DetailLogZero, newHullKey, indices.GetLength(0), vertices.Count, maxDepthSplit, m_hulls.Count); + // Convert the vertices and indices for passing to unmanaged. // The hull information is passed as a large floating point array. // The format is: -- cgit v1.1 From 953090fd62c2f8647d0e04bc3890a04a7076dbad Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 23 Mar 2013 11:00:52 -0700 Subject: BulletSim: fix possible race condition where an prim's asset can be requested quicker than the asset fetcher returns and thus falsely reporting that an asset was not fetched and defaulting the assset to a bounding box. --- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 12 ++++++++---- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 2 +- .../Physics/BulletSPlugin/BSShapeCollection.cs | 21 +++++++++++++++------ 3 files changed, 24 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index f953c1e..6bb88c7 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -86,7 +86,7 @@ public abstract class BSPhysObject : PhysicsActor PhysBody = new BulletBody(localID); PhysShape = new BulletShape(); - LastAssetBuildFailed = false; + PrimAssetState = PrimAssetCondition.Unknown; // Default material type. Also sets Friction, Restitution and Density. SetMaterial((int)MaterialAttributes.Material.Wood); @@ -133,9 +133,13 @@ public abstract class BSPhysObject : PhysicsActor // Reference to the physical shape (btCollisionShape) of this object public BulletShape PhysShape; - // 'true' if the mesh's underlying asset failed to build. - // This will keep us from looping after the first time the build failed. - public bool LastAssetBuildFailed { get; set; } + // The physical representation of the prim might require an asset fetch. + // The asset state is first 'Unknown' then 'Waiting' then either 'Failed' or 'Fetched'. + public enum PrimAssetCondition + { + Unknown, Waiting, Failed, Fetched + } + public PrimAssetCondition PrimAssetState { get; set; } // The objects base shape information. Null if not a prim type shape. public PrimitiveBaseShape BaseShape { get; protected set; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 2cbbe9a..6a5461a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -155,7 +155,7 @@ public class BSPrim : BSPhysObject public override PrimitiveBaseShape Shape { set { BaseShape = value; - LastAssetBuildFailed = false; + PrimAssetState = PrimAssetCondition.Unknown; ForceBodyShapeRebuild(false); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 457f204..a6e20a8 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -930,11 +930,15 @@ public sealed class BSShapeCollection : IDisposable return newShape; // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset - if (prim.BaseShape.SculptEntry && !prim.LastAssetBuildFailed && prim.BaseShape.SculptTexture != OMV.UUID.Zero) + if (prim.BaseShape.SculptEntry + && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Failed + && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Waiting + && prim.BaseShape.SculptTexture != OMV.UUID.Zero + ) { - DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset,lastFailed={1}", prim.LocalID, prim.LastAssetBuildFailed); - // This will prevent looping through this code as we keep trying to get the failed shape - prim.LastAssetBuildFailed = true; + DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset", prim.LocalID); + // Multiple requestors will know we're waiting for this asset + prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Waiting; BSPhysObject xprim = prim; Util.FireAndForget(delegate @@ -945,7 +949,7 @@ public sealed class BSShapeCollection : IDisposable BSPhysObject yprim = xprim; // probably not necessary, but, just in case. assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset) { - bool assetFound = false; // DEBUG DEBUG + bool assetFound = false; string mismatchIDs = String.Empty; // DEBUG DEBUG if (asset != null && yprim.BaseShape.SculptEntry) { @@ -963,6 +967,10 @@ public sealed class BSShapeCollection : IDisposable mismatchIDs = yprim.BaseShape.SculptTexture.ToString() + "/" + asset.ID; } } + if (assetFound) + yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Fetched; + else + yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed; DetailLog("{0},BSShapeCollection,fetchAssetCallback,found={1},isSculpt={2},ids={3}", yprim.LocalID, assetFound, yprim.BaseShape.SculptEntry, mismatchIDs ); @@ -970,6 +978,7 @@ public sealed class BSShapeCollection : IDisposable } else { + xprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed; PhysicsScene.Logger.ErrorFormat("{0} Physical object requires asset but no asset provider. Name={1}", LogHeader, PhysicsScene.Name); } @@ -977,7 +986,7 @@ public sealed class BSShapeCollection : IDisposable } else { - if (prim.LastAssetBuildFailed) + if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Failed) { PhysicsScene.Logger.ErrorFormat("{0} Mesh failed to fetch asset. lID={1}, texture={2}", LogHeader, prim.LocalID, prim.BaseShape.SculptTexture); -- cgit v1.1 From c96a6f1de6d5e66dd2055365c26144d7a92f2fc5 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 23 Mar 2013 11:03:59 -0700 Subject: BulletSim: small tweaks and formatting in the parameter fetching code. --- OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 26d2d60..f3454c8 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -203,10 +203,10 @@ public static class BSParam public delegate void PSetOnObject(BSScene scene, BSPhysObject obj); public sealed class ParameterDefn : ParameterDefnBase { - T defaultValue; - PSetValue setter; - PGetValue getter; - PSetOnObject objectSet; + private T defaultValue; + private PSetValue setter; + private PGetValue getter; + private PSetOnObject objectSet; public ParameterDefn(string pName, string pDesc, T pDefault, PGetValue pGetter, PSetValue pSetter) : base(pName, pDesc) { @@ -223,13 +223,23 @@ public static class BSParam getter = pGetter; objectSet = pObjSetter; } + /* Wish I could simplify using this definition but CLR doesn't store references so closure around delegates of references won't work + public ParameterDefn(string pName, string pDesc, T pDefault, ref T loc) + : base(pName, pDesc) + { + defaultValue = pDefault; + setter = (s, v) => { loc = v; }; + getter = (s) => { return loc; }; + objectSet = null; + } + */ public override void AssignDefault(BSScene s) { setter(s, defaultValue); } public override string GetValue(BSScene s) { - return String.Format("{0}", getter(s)); + return getter(s).ToString(); } public override void SetValue(BSScene s, string valAsString) { @@ -252,6 +262,7 @@ public static class BSParam try { T setValue = (T)parser.Invoke(genericType, new Object[] { valAsString }); + // Store the parsed value setter(s, setValue); // s.Logger.DebugFormat("{0} Parameter {1} = {2}", LogHeader, name, setValue); } -- cgit v1.1 From 285dc554ece0b504cb549193096f84c9c0cfe89f Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 25 Mar 2013 15:19:55 -0700 Subject: BulletSim: new algorithm for vertical attraction which uses quaternion arithmetic to compute the shortest path between the current tilt and vertical. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 48 ++++++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 5549984..65df741 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -321,7 +321,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin } } - internal void ProcessTypeChange(Vehicle pType) + public void ProcessTypeChange(Vehicle pType) { VDetailLog("{0},ProcessTypeChange,type={1}", Prim.LocalID, pType); // Set Defaults For Type @@ -1301,14 +1301,52 @@ namespace OpenSim.Region.Physics.BulletSPlugin // efficiency of 1.0 will cause the spring to reach its equilibrium with exponential decay. public void ComputeAngularVerticalAttraction() { + // If vertical attaction timescale is reasonable if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff) { + // Possible solution derived from a discussion at: + // http://stackoverflow.com/questions/14939657/computing-vector-from-quaternion-works-computing-quaternion-from-vector-does-no + + // Create a rotation that is only the vehicle's rotation around Z + Vector3 currentEuler = Vector3.Zero; + VehicleOrientation.GetEulerAngles(out currentEuler.X, out currentEuler.Y, out currentEuler.Z); + Quaternion justZOrientation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, currentEuler.Z); + + // Create the axis that is perpendicular to the up vector and the rotated up vector. + Vector3 differenceAxis = Vector3.Cross(Vector3.UnitZ * justZOrientation, Vector3.UnitZ * VehicleOrientation); + // Compute the angle between those to vectors. + double differenceAngle = Math.Acos((double)Vector3.Dot(Vector3.UnitZ, Vector3.Normalize(Vector3.UnitZ * VehicleOrientation))); + // 'differenceAngle' is the angle to rotate and 'differenceAxis' is the plane to rotate in to get the vehicle vertical + + // Reduce the change by the time period it is to change in. Timestep is handled when velocity is applied. + // TODO: add 'efficiency'. + differenceAngle /= m_verticalAttractionTimescale; + + // Create the quaterian representing the correction angle + Quaternion correctionRotation = Quaternion.CreateFromAxisAngle(differenceAxis, (float)differenceAngle); + + // Turn that quaternion into Euler values to make it into velocities to apply. + Vector3 vertContributionV = Vector3.Zero; + correctionRotation.GetEulerAngles(out vertContributionV.X, out vertContributionV.Y, out vertContributionV.Z); + vertContributionV *= -1f; + + VehicleRotationalVelocity += vertContributionV; + + VDetailLog("{0}, MoveAngular,verticalAttraction,diffAxis={1},diffAng={2},corrRot={3},contrib={4}", + Prim.LocalID, + differenceAxis, + differenceAngle, + correctionRotation, + vertContributionV); + + // =================================================================== + /* Vector3 vertContributionV = Vector3.Zero; Vector3 origRotVelW = VehicleRotationalVelocity; // DEBUG DEBUG // Take a vector pointing up and convert it from world to vehicle relative coords. - Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; + Vector3 verticalError = Vector3.Normalize(Vector3.UnitZ * VehicleOrientation); // If vertical attraction correction is needed, the vector that was pointing up (UnitZ) // is now: @@ -1334,13 +1372,17 @@ namespace OpenSim.Region.Physics.BulletSPlugin // 'vertContrbution' is now the necessary angular correction to correct tilt in one second. // Correction happens over a number of seconds. Vector3 unscaledContribVerticalErrorV = vertContributionV; // DEBUG DEBUG + + // The correction happens over the user's time period vertContributionV /= m_verticalAttractionTimescale; - VehicleRotationalVelocity += vertContributionV; + // Rotate the vehicle rotation to the world coordinates. + VehicleRotationalVelocity += (vertContributionV * VehicleOrientation); VDetailLog("{0}, MoveAngular,verticalAttraction,,origRotVW={1},vertError={2},unscaledV={3},eff={4},ts={5},vertContribV={6}", Prim.LocalID, origRotVelW, verticalError, unscaledContribVerticalErrorV, m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContributionV); + */ } } -- cgit v1.1 From 5f4c4df227025c6b6156ce8238b56553dca4b5ae Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 26 Mar 2013 03:40:06 +0000 Subject: Phase 1 of implementing a transfer permission. Overwrite libOMV's PermissionMask with our own and add export permissions as well as a new definition for "All" as meaning "all conventional permissions" rather than "all possible permissions" --- .../Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 5 +++-- .../Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs | 1 + OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 8 +++++--- .../CoreModules/Agent/AssetTransaction/AssetXferUploader.cs | 5 +++-- .../CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | 1 + OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs | 1 + .../Framework/InventoryAccess/InventoryAccessModule.cs | 9 ++++++--- OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs | 1 + OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs | 1 + .../Region/CoreModules/World/Objects/BuySell/BuySellModule.cs | 1 + .../Region/CoreModules/World/Permissions/PermissionsModule.cs | 1 + OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 7 ++++--- OpenSim/Region/Framework/Scenes/Scene.cs | 1 + OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs | 1 + OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 1 + OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 1 + OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 1 + .../OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs | 1 + .../OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs | 3 ++- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 1 + .../Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 5 +++-- 21 files changed, 40 insertions(+), 16 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index 20df8a6..8752404 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -49,6 +49,7 @@ using OpenSim.Services.Interfaces; using Caps = OpenSim.Framework.Capabilities.Caps; using OSDArray = OpenMetaverse.StructuredData.OSDArray; using OSDMap = OpenMetaverse.StructuredData.OSDMap; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.ClientStack.Linden { @@ -705,9 +706,9 @@ namespace OpenSim.Region.ClientStack.Linden // If we set PermissionMask.All then when we rez the item the next permissions will replace the current // (owner) permissions. This becomes a problem if next permissions are changed. item.CurrentPermissions - = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer); + = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Export); - item.BasePermissions = (uint)PermissionMask.All; + item.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export; item.EveryOnePermissions = 0; item.NextPermissions = (uint)PermissionMask.All; item.CreationDate = Util.UnixTimeSinceEpoch(); diff --git a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs index 5529550..f69a0bb 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs @@ -44,6 +44,7 @@ using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; using Caps = OpenSim.Framework.Capabilities.Caps; using OpenSim.Framework.Capabilities; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.ClientStack.Linden { diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 7ea538c..110e50e 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -51,6 +51,7 @@ using RegionFlags = OpenMetaverse.RegionFlags; using Nini.Config; using System.IO; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.ClientStack.LindenUDP { @@ -1808,7 +1809,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item) { - const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All; + // Fudge this value. It's only needed to make the CRC anyway + const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff; FetchInventoryReplyPacket inventoryReply = (FetchInventoryReplyPacket)PacketPool.Instance.GetPacket(PacketType.FetchInventoryReply); // TODO: don't create new blocks if recycling an old packet @@ -2013,7 +2015,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP protected void SendBulkUpdateInventoryItem(InventoryItemBase item) { - const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All; + const uint FULL_MASK_PERMISSIONS = (uint)0x7ffffff; BulkUpdateInventoryPacket bulkUpdate = (BulkUpdateInventoryPacket)PacketPool.Instance.GetPacket(PacketType.BulkUpdateInventory); @@ -2067,7 +2069,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase) public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId) { - const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All; + const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff; UpdateCreateInventoryItemPacket InventoryReply = (UpdateCreateInventoryItemPacket)PacketPool.Instance.GetPacket( diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs index 11efe6d..5e772e6 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs @@ -33,6 +33,7 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.CoreModules.Agent.AssetTransaction { @@ -406,8 +407,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction item.AssetType = type; item.InvType = invType; item.Folder = InventFolder; - item.BasePermissions = 0x7fffffff; - item.CurrentPermissions = 0x7fffffff; + item.BasePermissions = (uint)(PermissionMask.All | PermissionMask.Export); + item.CurrentPermissions = item.BasePermissions; item.GroupPermissions=0; item.EveryOnePermissions=0; item.NextPermissions = nextPerm; diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index ff5bf9f..c7ac7c4 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -40,6 +40,7 @@ using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; using Mono.Addins; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory { diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs index 5ec0ea9..b44a5c9 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs @@ -36,6 +36,7 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; using Mono.Addins; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.CoreModules.Avatar.Friends { diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 8b7c16e..eaf4ce2 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -47,6 +47,7 @@ using OpenMetaverse; using log4net; using Nini.Config; using Mono.Addins; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.CoreModules.Framework.InventoryAccess { @@ -377,7 +378,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess objectGroup.RootPart.NextOwnerMask &= ((uint)PermissionMask.Copy | (uint)PermissionMask.Transfer | - (uint)PermissionMask.Modify); + (uint)PermissionMask.Modify | + (uint)PermissionMask.Export); objectGroup.RootPart.NextOwnerMask |= (uint)PermissionMask.Move; @@ -485,7 +487,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess InventoryItemBase item, SceneObjectGroup so, List objsForEffectivePermissions, IClientAPI remoteClient) { - uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move) | 7; + uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move | PermissionMask.Export) | 7; foreach (SceneObjectGroup grp in objsForEffectivePermissions) effectivePerms &= grp.GetEffectivePermissions(); effectivePerms |= (uint)PermissionMask.Move; @@ -525,6 +527,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess (uint)PermissionMask.Transfer | (uint)PermissionMask.Modify | (uint)PermissionMask.Move | + (uint)PermissionMask.Export | 7); // Preserve folded permissions } @@ -1150,4 +1153,4 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess #endregion } -} \ No newline at end of file +} diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs index ec22146..d07cff4 100644 --- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs @@ -43,6 +43,7 @@ using OpenMetaverse; using log4net; using Mono.Addins; using Nini.Config; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.CoreModules.Framework.Library { diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs index 367693d..a990898 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs @@ -44,6 +44,7 @@ using Ionic.Zlib; using GZipStream = Ionic.Zlib.GZipStream; using CompressionMode = Ionic.Zlib.CompressionMode; using OpenSim.Framework.Serialization.External; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.CoreModules.World.Archiver { diff --git a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs index 1e4f0a4..22a53a8 100644 --- a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs @@ -38,6 +38,7 @@ using OpenSim.Region.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes.Serialization; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.CoreModules.World.Objects.BuySell { diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 121fb2a..79dd4a0 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -38,6 +38,7 @@ using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; using Mono.Addins; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.CoreModules.World.Permissions { diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 6808017..2ce778d 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -39,6 +39,7 @@ using OpenSim.Region.Framework; using OpenSim.Framework.Client; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes.Serialization; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.Framework.Scenes { @@ -892,7 +893,7 @@ namespace OpenSim.Region.Framework.Scenes { CreateNewInventoryItem( remoteClient, creatorID, creatorData, folderID, name, description, flags, callbackID, asset, invType, - (uint)PermissionMask.All, (uint)PermissionMask.All, 0, nextOwnerMask, 0, creationDate); + (uint)PermissionMask.All | (uint)PermissionMask.Export, (uint)PermissionMask.All | (uint)PermissionMask.Export, 0, nextOwnerMask, 0, creationDate); } /// @@ -1010,8 +1011,8 @@ namespace OpenSim.Region.Framework.Scenes CreateNewInventoryItem( remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, name, description, 0, callbackID, asset, invType, - (uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All, - (uint)PermissionMask.All, (uint)PermissionMask.All, Util.UnixTimeSinceEpoch()); + (uint)PermissionMask.All | (uint)PermissionMask.Export, (uint)PermissionMask.All | (uint)PermissionMask.Export, (uint)PermissionMask.All, + (uint)PermissionMask.All | (uint)PermissionMask.Export, (uint)PermissionMask.All | (uint)PermissionMask.Export, Util.UnixTimeSinceEpoch()); } else { diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index e8f00a4..45cbdd5 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -51,6 +51,7 @@ using OpenSim.Region.Physics.Manager; using Timer=System.Timers.Timer; using TPFlags = OpenSim.Framework.Constants.TeleportFlags; using GridRegion = OpenSim.Services.Interfaces.GridRegion; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.Framework.Scenes { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index ddf5da0..dcb62f8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs @@ -34,6 +34,7 @@ using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using System.Collections.Generic; using System.Xml; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.Framework.Scenes { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 15795e5..0621e2a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -40,6 +40,7 @@ using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Physics.Manager; using OpenSim.Region.Framework.Scenes.Serialization; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.Framework.Scenes { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index a8b63fe..27325c5 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -43,6 +43,7 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes.Scripting; using OpenSim.Region.Framework.Scenes.Serialization; using OpenSim.Region.Physics.Manager; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.Framework.Scenes { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index db723fa..7dba7c8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -38,6 +38,7 @@ using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes.Scripting; using OpenSim.Region.Framework.Scenes.Serialization; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.Framework.Scenes { diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs index e9ddbbe..54c86ae 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs @@ -40,6 +40,7 @@ using OpenSim.Framework.Monitoring; using OpenSim.Region.ClientStack.LindenUDP; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.OptionalModules.Avatar.Attachments { diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index 4a754a9..1bb5aee 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs @@ -42,6 +42,7 @@ using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes.Scripting; using System.Collections.Generic; using System.Text.RegularExpressions; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.OptionalModules.Scripting.JsonStore { @@ -643,4 +644,4 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } } -} \ No newline at end of file +} diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index e1f0071..aab41f5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -67,6 +67,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; using System.Reflection; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.ScriptEngine.Shared.Api { diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index bf1b45b..415166a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -62,6 +62,7 @@ using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.ScriptEngine.Shared.Api { @@ -1787,8 +1788,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api taskItem.InvType = (int)InventoryType.Notecard; taskItem.OwnerID = m_host.OwnerID; taskItem.CreatorID = m_host.OwnerID; - taskItem.BasePermissions = (uint)PermissionMask.All; - taskItem.CurrentPermissions = (uint)PermissionMask.All; + taskItem.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export; + taskItem.CurrentPermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export; taskItem.EveryonePermissions = 0; taskItem.NextPermissions = (uint)PermissionMask.All; taskItem.GroupID = m_host.GroupID; -- cgit v1.1 From e82fab34d7377a7d9bfc223f093ac67b393677cc Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 26 Mar 2013 19:00:30 +0000 Subject: Implement a pref to turn on the simulator ExportSupported feature entry. This tells the viewer to enable the UI for export permissions. WARNING: If your inventory store contains invalid flags data, this will result in items becoming exportable! Don't turn this on in production until it's complete! --- OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs index 6ef8815..7d9f935 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs @@ -70,6 +70,7 @@ namespace OpenSim.Region.ClientStack.Linden private string m_MapImageServerURL = string.Empty; private string m_SearchURL = string.Empty; + private bool m_ExportSupported = false; #region ISharedRegionModule Members @@ -87,6 +88,8 @@ namespace OpenSim.Region.ClientStack.Linden } m_SearchURL = config.GetString("SearchServerURI", string.Empty); + + m_ExportSupported = config.GetBoolean("ExportSupported", m_ExportSupported); } AddDefaultFeatures(); @@ -152,6 +155,9 @@ namespace OpenSim.Region.ClientStack.Linden if (m_SearchURL != string.Empty) gridServicesMap["search"] = m_SearchURL; m_features["GridServices"] = gridServicesMap; + + if (m_ExportSupported) + m_features["ExportSupported"] = true; } } -- cgit v1.1 From 3f0f313a764213e928aeb57968efbdd0e4c851cd Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 26 Mar 2013 20:25:58 +0000 Subject: Make llGetLinkPrimitiveParams() and llGetPrimitiveParams() work for avatars in a linkset. llGetPrimitiveParams() works through PRIM_LINK_TARGET Setting via llSetLinkPrimitiveParams(), etc. not yet implemented --- .../Shared/Api/Implementation/LSL_Api.cs | 224 ++++++++++++++++++--- 1 file changed, 194 insertions(+), 30 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index e1f0071..bf3d8ab 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -5923,8 +5923,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } else { - agentSize = new LSL_Vector(0.45, 0.6, avatar.Appearance.AvatarHeight); + agentSize = GetAgentSize(avatar); } + return agentSize; } @@ -7948,61 +7949,224 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return new LSL_Vector(m_host.GetGeometricCenter()); } - public LSL_List llGetPrimitiveParams(LSL_List rules) + public LSL_List GetEntityParams(ISceneEntity entity, LSL_List rules) { - m_host.AddScriptLPS(1); - LSL_List result = new LSL_List(); + LSL_List remaining = null; - LSL_List remaining = GetPrimParams(m_host, rules, ref result); + while (true) + { + if (entity is SceneObjectPart) + remaining = GetPrimParams((SceneObjectPart)entity, rules, ref result); + else + remaining = GetAgentParams((ScenePresence)entity, rules, ref result); + + if (remaining == null || remaining.Length <= 2) + return result; - while (remaining != null && remaining.Length > 2) - { int linknumber = remaining.GetLSLIntegerItem(0); rules = remaining.GetSublist(1, -1); - List parts = GetLinkParts(linknumber); - - foreach (SceneObjectPart part in parts) - remaining = GetPrimParams(part, rules, ref result); + entity = GetLinkEntity(linknumber); } + } - return result; + public LSL_List llGetPrimitiveParams(LSL_List rules) + { + m_host.AddScriptLPS(1); + + return GetEntityParams(m_host, rules); } public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules) { m_host.AddScriptLPS(1); - List parts = GetLinkParts(linknumber); + return GetEntityParams(GetLinkEntity(linknumber), rules); + } - LSL_List res = new LSL_List(); - LSL_List remaining = null; + public LSL_Vector GetAgentSize(ScenePresence sp) + { + return new LSL_Vector(0.45, 0.6, sp.Appearance.AvatarHeight); + } - foreach (SceneObjectPart part in parts) + /// + /// Gets params for a seated avatar in a linkset. + /// + /// + /// + /// + /// + public LSL_List GetAgentParams(ScenePresence sp, LSL_List rules, ref LSL_List res) + { + int idx = 0; + while (idx < rules.Length) { - remaining = GetPrimParams(part, rules, ref res); - } + int code = (int)rules.GetLSLIntegerItem(idx++); + int remain = rules.Length-idx; - while (remaining != null && remaining.Length > 2) - { - linknumber = remaining.GetLSLIntegerItem(0); - rules = remaining.GetSublist(1, -1); - parts = GetLinkParts(linknumber); + switch (code) + { + case (int)ScriptBaseClass.PRIM_MATERIAL: + res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MATERIAL_FLESH)); + break; - foreach (SceneObjectPart part in parts) - remaining = GetPrimParams(part, rules, ref res); + case (int)ScriptBaseClass.PRIM_PHYSICS: + res.Add(ScriptBaseClass.FALSE); + break; + + case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: + res.Add(ScriptBaseClass.FALSE); + break; + + case (int)ScriptBaseClass.PRIM_PHANTOM: + res.Add(ScriptBaseClass.FALSE); + break; + + case (int)ScriptBaseClass.PRIM_POSITION: + res.Add(new LSL_Vector(sp.AbsolutePosition)); + break; + + case (int)ScriptBaseClass.PRIM_SIZE: + res.Add(GetAgentSize(sp)); + break; + + case (int)ScriptBaseClass.PRIM_ROTATION: + res.Add(sp.GetWorldRotation()); + break; + + case (int)ScriptBaseClass.PRIM_TYPE: + res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX)); + res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT)); + res.Add(new LSL_Vector(0, 1, 0)); + res.Add(new LSL_Float(0)); + res.Add(new LSL_Vector(0, 0, 0)); + res.Add(new LSL_Vector(1, 1, 0)); + res.Add(new LSL_Vector(0, 0, 0)); + break; + + case (int)ScriptBaseClass.PRIM_TEXTURE: + if (remain < 1) + return null; + + int face = (int)rules.GetLSLIntegerItem(idx++); + if (face > 21) + break; + + res.Add(new LSL_String("")); + res.Add(ScriptBaseClass.ZERO_VECTOR); + res.Add(ScriptBaseClass.ZERO_VECTOR); + res.Add(new LSL_Float(0)); + break; + + case (int)ScriptBaseClass.PRIM_COLOR: + if (remain < 1) + return null; + + face = (int)rules.GetLSLIntegerItem(idx++); + if (face > 21) + break; + + res.Add(ScriptBaseClass.ZERO_VECTOR); + res.Add(new LSL_Float(0)); + break; + + case (int)ScriptBaseClass.PRIM_BUMP_SHINY: + if (remain < 1) + return null; + + face = (int)rules.GetLSLIntegerItem(idx++); + if (face > 21) + break; + + res.Add(ScriptBaseClass.PRIM_SHINY_NONE); + res.Add(ScriptBaseClass.PRIM_BUMP_NONE); + break; + + case (int)ScriptBaseClass.PRIM_FULLBRIGHT: + if (remain < 1) + return null; + + face = (int)rules.GetLSLIntegerItem(idx++); + if (face > 21) + break; + + res.Add(ScriptBaseClass.FALSE); + break; + + case (int)ScriptBaseClass.PRIM_FLEXIBLE: + res.Add(ScriptBaseClass.FALSE); + res.Add(new LSL_Integer(0)); + res.Add(new LSL_Float(0)); + res.Add(new LSL_Float(0)); + res.Add(new LSL_Float(0)); + res.Add(new LSL_Float(0)); + res.Add(ScriptBaseClass.ZERO_VECTOR); + break; + + case (int)ScriptBaseClass.PRIM_TEXGEN: + if (remain < 1) + return null; + + face = (int)rules.GetLSLIntegerItem(idx++); + if (face > 21) + break; + + res.Add(ScriptBaseClass.PRIM_TEXGEN_DEFAULT); + break; + + case (int)ScriptBaseClass.PRIM_POINT_LIGHT: + res.Add(ScriptBaseClass.FALSE); + res.Add(ScriptBaseClass.ZERO_VECTOR); + res.Add(ScriptBaseClass.ZERO_VECTOR); + break; + + case (int)ScriptBaseClass.PRIM_GLOW: + if (remain < 1) + return null; + + face = (int)rules.GetLSLIntegerItem(idx++); + if (face > 21) + break; + + res.Add(new LSL_Float(0)); + break; + + case (int)ScriptBaseClass.PRIM_TEXT: + res.Add(new LSL_String("")); + res.Add(ScriptBaseClass.ZERO_VECTOR); + res.Add(new LSL_Float(1)); + break; + + case (int)ScriptBaseClass.PRIM_ROT_LOCAL: + res.Add(new LSL_Rotation(sp.Rotation)); + break; + + case (int)ScriptBaseClass.PRIM_POS_LOCAL: + res.Add(new LSL_Vector(sp.OffsetPosition)); + break; + + case (int)ScriptBaseClass.PRIM_SLICE: + res.Add(new LSL_Vector(0, 1, 0)); + break; + + case (int)ScriptBaseClass.PRIM_LINK_TARGET: + if(remain < 3) + return null; + + return rules.GetSublist(idx, -1); + } } - return res; + return null; } public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res) { - int idx=0; + int idx = 0; while (idx < rules.Length) { - int code=(int)rules.GetLSLIntegerItem(idx++); - int remain=rules.Length-idx; + int code = (int)rules.GetLSLIntegerItem(idx++); + int remain = rules.Length-idx; switch (code) { @@ -8245,7 +8409,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (remain < 1) return null; - face=(int)rules.GetLSLIntegerItem(idx++); + face = (int)rules.GetLSLIntegerItem(idx++); tex = part.Shape.Textures; if (face == ScriptBaseClass.ALL_SIDES) -- cgit v1.1 From abde0d4efb897581df2a6a7be591de2224611b90 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 26 Mar 2013 15:02:10 -0700 Subject: BulletSim: prevent asset fetching loop when the fetched asset fails to mesh. Check for the case where the fetched mesh asset fails meshing (degenerate triangles or no physical mesh). In this case, the asset is marked 'failed' and BulletSim doesn't keep trying to fetch over-and-over trying to get a good asset. --- .../Physics/BulletSPlugin/BSShapeCollection.cs | 116 ++++++++++++--------- 1 file changed, 64 insertions(+), 52 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index a6e20a8..b6ac23d 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -929,67 +929,79 @@ public sealed class BSShapeCollection : IDisposable if (newShape.HasPhysicalShape) return newShape; - // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset - if (prim.BaseShape.SculptEntry - && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Failed - && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Waiting - && prim.BaseShape.SculptTexture != OMV.UUID.Zero - ) + // VerifyMeshCreated is called after trying to create the mesh. If we think the asset had been + // fetched but we end up here again, the meshing of the asset must have failed. + // Prevent trying to keep fetching the mesh by declaring failure. + if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) { - DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset", prim.LocalID); - // Multiple requestors will know we're waiting for this asset - prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Waiting; + prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed; + PhysicsScene.Logger.WarnFormat("{0} Fetched asset would not mesh. {1}, texture={2}", + LogHeader, prim.PhysObjectName, prim.BaseShape.SculptTexture); + } + else + { + // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset + if (prim.BaseShape.SculptEntry + && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Failed + && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Waiting + && prim.BaseShape.SculptTexture != OMV.UUID.Zero + ) + { + DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset", prim.LocalID); + // Multiple requestors will know we're waiting for this asset + prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Waiting; - BSPhysObject xprim = prim; - Util.FireAndForget(delegate - { - RequestAssetDelegate assetProvider = PhysicsScene.RequestAssetMethod; - if (assetProvider != null) + BSPhysObject xprim = prim; + Util.FireAndForget(delegate { - BSPhysObject yprim = xprim; // probably not necessary, but, just in case. - assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset) + RequestAssetDelegate assetProvider = PhysicsScene.RequestAssetMethod; + if (assetProvider != null) { - bool assetFound = false; - string mismatchIDs = String.Empty; // DEBUG DEBUG - if (asset != null && yprim.BaseShape.SculptEntry) + BSPhysObject yprim = xprim; // probably not necessary, but, just in case. + assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset) { - if (yprim.BaseShape.SculptTexture.ToString() == asset.ID) + bool assetFound = false; + string mismatchIDs = String.Empty; // DEBUG DEBUG + if (asset != null && yprim.BaseShape.SculptEntry) { - yprim.BaseShape.SculptData = asset.Data; - // This will cause the prim to see that the filler shape is not the right - // one and try again to build the object. - // No race condition with the normal shape setting since the rebuild is at taint time. - yprim.ForceBodyShapeRebuild(false /* inTaintTime */); - assetFound = true; + if (yprim.BaseShape.SculptTexture.ToString() == asset.ID) + { + yprim.BaseShape.SculptData = asset.Data; + // This will cause the prim to see that the filler shape is not the right + // one and try again to build the object. + // No race condition with the normal shape setting since the rebuild is at taint time. + yprim.ForceBodyShapeRebuild(false /* inTaintTime */); + assetFound = true; + } + else + { + mismatchIDs = yprim.BaseShape.SculptTexture.ToString() + "/" + asset.ID; + } } + if (assetFound) + yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Fetched; else - { - mismatchIDs = yprim.BaseShape.SculptTexture.ToString() + "/" + asset.ID; - } - } - if (assetFound) - yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Fetched; - else - yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed; - DetailLog("{0},BSShapeCollection,fetchAssetCallback,found={1},isSculpt={2},ids={3}", - yprim.LocalID, assetFound, yprim.BaseShape.SculptEntry, mismatchIDs ); - - }); - } - else - { - xprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed; - PhysicsScene.Logger.ErrorFormat("{0} Physical object requires asset but no asset provider. Name={1}", - LogHeader, PhysicsScene.Name); - } - }); - } - else - { - if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Failed) + yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed; + DetailLog("{0},BSShapeCollection,fetchAssetCallback,found={1},isSculpt={2},ids={3}", + yprim.LocalID, assetFound, yprim.BaseShape.SculptEntry, mismatchIDs ); + + }); + } + else + { + xprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed; + PhysicsScene.Logger.ErrorFormat("{0} Physical object requires asset but no asset provider. Name={1}", + LogHeader, PhysicsScene.Name); + } + }); + } + else { - PhysicsScene.Logger.ErrorFormat("{0} Mesh failed to fetch asset. lID={1}, texture={2}", - LogHeader, prim.LocalID, prim.BaseShape.SculptTexture); + if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Failed) + { + PhysicsScene.Logger.WarnFormat("{0} Mesh failed to fetch asset. obj={1}, texture={2}", + LogHeader, prim.PhysObjectName, prim.BaseShape.SculptTexture); + } } } -- cgit v1.1 From dd7d7683c914f5b16d8b87434bccea3fe74d9bab Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Mar 2013 00:12:48 +0000 Subject: Fix problem with megaregions where teleporting into a different region which already had a child agent would stop the eq working for the agent in the new region. This was because the calculation as to whether a new agent was needed in the receiving region did not take megaregions into account, unlike the original calculation when the user first teleported into the region. This meant that on teleport, entity transfer would create a new CAP but this would be ignored by the viewer and receiving region, meaning that the EQ could no longer be used. This would prevent subsequent teleport, amongst other things. Currently, regions up to 512m from a megaregion are considered neighbours. --- .../EntityTransfer/EntityTransferModule.cs | 45 +++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 4cf7645..8af236e 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -727,6 +727,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer IClientIPEndpoint ipepClient; if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) { + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for incoming agent {3} from {4}", + finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name); + //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); #region IP Translation for NAT // Uses ipepClient above @@ -1001,7 +1005,46 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected virtual bool NeedsNewAgent(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY) { - return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY); + Border[] northBorders = Scene.NorthBorders.ToArray(); + Border[] southBorders = Scene.SouthBorders.ToArray(); + Border[] eastBorders = Scene.EastBorders.ToArray(); + Border[] westBorders = Scene.WestBorders.ToArray(); + + // Leaving this as a "megaregions" computation vs "non-megaregions" computation; it isn't + // clear what should be done with a "far view" given that megaregions already extended the + // view to include everything in the megaregion + if (northBorders.Length > 1 || southBorders.Length > 1 || eastBorders.Length > 1 || westBorders.Length > 1) + { + Vector2 extent = Vector2.Zero; + for (int i = 0; i < eastBorders.Length; i++) + { + extent.X = (eastBorders[i].BorderLine.Z > extent.X) ? eastBorders[i].BorderLine.Z : extent.X; + } + for (int i = 0; i < northBorders.Length; i++) + { + extent.Y = (northBorders[i].BorderLine.Z > extent.Y) ? northBorders[i].BorderLine.Z : extent.Y; + } + + // Loss of fraction on purpose + extent.X = ((int)extent.X / (int)Constants.RegionSize) + 1; + extent.Y = ((int)extent.Y / (int)Constants.RegionSize) + 1; + + uint startX = oldRegionX - 1; + uint startY = oldRegionY - 1; + + uint endX = oldRegionX + (uint)extent.X; + uint endY = oldRegionY + (uint)extent.Y; + + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Megaregion view of {0} is from {1},{2} to {3},{4} with new agent check for {5},{6}", + Scene.Name, startX, startY, endX, endY, newRegionX, newRegionY); + + return !(newRegionX >= startX && newRegionX <= endX && newRegionY >= startY && newRegionY <= endY); + } + else + { + return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY); + } } protected virtual bool NeedsClosing(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg) -- cgit v1.1 From cfb20f09a967ede0a64e7151c3430f74362aec99 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Mar 2013 00:57:43 +0000 Subject: refactor: combine the checks for megaregion view range into a single place. --- .../EntityTransfer/EntityTransferModule.cs | 102 ++++++++++----------- 1 file changed, 51 insertions(+), 51 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 8af236e..f5ffef2 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -117,6 +117,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer new ExpiringCache>(); private IEventQueue m_eqModule; + private IRegionCombinerModule m_regionCombinerModule; #region ISharedRegionModule @@ -267,6 +268,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; m_eqModule = Scene.RequestModuleInterface(); + m_regionCombinerModule = Scene.RequestModuleInterface(); } #endregion @@ -1005,41 +1007,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected virtual bool NeedsNewAgent(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY) { - Border[] northBorders = Scene.NorthBorders.ToArray(); - Border[] southBorders = Scene.SouthBorders.ToArray(); - Border[] eastBorders = Scene.EastBorders.ToArray(); - Border[] westBorders = Scene.WestBorders.ToArray(); - - // Leaving this as a "megaregions" computation vs "non-megaregions" computation; it isn't - // clear what should be done with a "far view" given that megaregions already extended the - // view to include everything in the megaregion - if (northBorders.Length > 1 || southBorders.Length > 1 || eastBorders.Length > 1 || westBorders.Length > 1) + if (m_regionCombinerModule != null && m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID)) { - Vector2 extent = Vector2.Zero; - for (int i = 0; i < eastBorders.Length; i++) - { - extent.X = (eastBorders[i].BorderLine.Z > extent.X) ? eastBorders[i].BorderLine.Z : extent.X; - } - for (int i = 0; i < northBorders.Length; i++) - { - extent.Y = (northBorders[i].BorderLine.Z > extent.Y) ? northBorders[i].BorderLine.Z : extent.Y; - } - - // Loss of fraction on purpose - extent.X = ((int)extent.X / (int)Constants.RegionSize) + 1; - extent.Y = ((int)extent.Y / (int)Constants.RegionSize) + 1; - - uint startX = oldRegionX - 1; - uint startY = oldRegionY - 1; - - uint endX = oldRegionX + (uint)extent.X; - uint endY = oldRegionY + (uint)extent.Y; + Vector2 swCorner, neCorner; + GetMegaregionViewRange(out swCorner, out neCorner); m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Megaregion view of {0} is from {1},{2} to {3},{4} with new agent check for {5},{6}", - Scene.Name, startX, startY, endX, endY, newRegionX, newRegionY); + "[ENTITY TRANSFER MODULE]: Megaregion view of {0} is from {1} to {2} with new agent check for {3},{4}", + Scene.Name, swCorner, neCorner, newRegionX, newRegionY); - return !(newRegionX >= startX && newRegionX <= endX && newRegionY >= startY && newRegionY <= endY); + return !(newRegionX >= swCorner.X && newRegionX <= neCorner.X && newRegionY >= swCorner.Y && newRegionY <= neCorner.Y); } else { @@ -1903,6 +1880,37 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } /// + /// Gets the range considered in view of this megaregion (assuming this is a megaregion). + /// + /// Expressed in 256m units + /// + /// + private void GetMegaregionViewRange(out Vector2 swCorner, out Vector2 neCorner) + { + Border[] northBorders = Scene.NorthBorders.ToArray(); + Border[] eastBorders = Scene.EastBorders.ToArray(); + + Vector2 extent = Vector2.Zero; + for (int i = 0; i < eastBorders.Length; i++) + { + extent.X = (eastBorders[i].BorderLine.Z > extent.X) ? eastBorders[i].BorderLine.Z : extent.X; + } + for (int i = 0; i < northBorders.Length; i++) + { + extent.Y = (northBorders[i].BorderLine.Z > extent.Y) ? northBorders[i].BorderLine.Z : extent.Y; + } + + // Loss of fraction on purpose + extent.X = ((int)extent.X / (int)Constants.RegionSize) + 1; + extent.Y = ((int)extent.Y / (int)Constants.RegionSize) + 1; + + swCorner.X = Scene.RegionInfo.RegionLocX - 1; + swCorner.Y = Scene.RegionInfo.RegionLocY - 1; + neCorner.X = Scene.RegionInfo.RegionLocX + extent.X; + neCorner.Y = Scene.RegionInfo.RegionLocY + extent.Y; + } + + /// /// Return the list of regions that are considered to be neighbours to the given scene. /// /// @@ -1922,8 +1930,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Leaving this as a "megaregions" computation vs "non-megaregions" computation; it isn't // clear what should be done with a "far view" given that megaregions already extended the // view to include everything in the megaregion - if (northBorders.Length <= 1 && southBorders.Length <= 1 && eastBorders.Length <= 1 && westBorders.Length <= 1) + if (m_regionCombinerModule == null || !m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID)) { + Console.WriteLine("NOT MEGA"); int dd = avatar.DrawDistance < Constants.RegionSize ? (int)Constants.RegionSize : (int)avatar.DrawDistance; int startX = (int)pRegionLocX * (int)Constants.RegionSize - dd + (int)(Constants.RegionSize/2); @@ -1940,27 +1949,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } else { - Vector2 extent = Vector2.Zero; - for (int i = 0; i < eastBorders.Length; i++) - { - extent.X = (eastBorders[i].BorderLine.Z > extent.X) ? eastBorders[i].BorderLine.Z : extent.X; - } - for (int i = 0; i < northBorders.Length; i++) - { - extent.Y = (northBorders[i].BorderLine.Z > extent.Y) ? northBorders[i].BorderLine.Z : extent.Y; - } - - // Loss of fraction on purpose - extent.X = ((int)extent.X / (int)Constants.RegionSize) + 1; - extent.Y = ((int)extent.Y / (int)Constants.RegionSize) + 1; - - int startX = (int)(pRegionLocX - 1) * (int)Constants.RegionSize; - int startY = (int)(pRegionLocY - 1) * (int)Constants.RegionSize; + Console.WriteLine("MEGA"); + Vector2 swCorner, neCorner; + GetMegaregionViewRange(out swCorner, out neCorner); - int endX = ((int)pRegionLocX + (int)extent.X) * (int)Constants.RegionSize; - int endY = ((int)pRegionLocY + (int)extent.Y) * (int)Constants.RegionSize; + List neighbours + = pScene.GridService.GetRegionRange( + m_regionInfo.ScopeID, + (int)swCorner.X * (int)Constants.RegionSize, + (int)neCorner.X * (int)Constants.RegionSize, + (int)swCorner.Y * (int)Constants.RegionSize, + (int)neCorner.Y * (int)Constants.RegionSize); - List neighbours = pScene.GridService.GetRegionRange(m_regionInfo.ScopeID, startX, endX, startY, endY); neighbours.RemoveAll(delegate(GridRegion r) { return r.RegionID == m_regionInfo.RegionID; }); return neighbours; -- cgit v1.1 From f32027f3b53e8ad4f0b9fed0fee65a7e46ec91b0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Mar 2013 01:08:47 +0000 Subject: Remove some Console.WriteLines accidentally left in last commit cfb20f09 --- .../Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 2 -- 1 file changed, 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index f5ffef2..dc6a2a0 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1932,7 +1932,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // view to include everything in the megaregion if (m_regionCombinerModule == null || !m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID)) { - Console.WriteLine("NOT MEGA"); int dd = avatar.DrawDistance < Constants.RegionSize ? (int)Constants.RegionSize : (int)avatar.DrawDistance; int startX = (int)pRegionLocX * (int)Constants.RegionSize - dd + (int)(Constants.RegionSize/2); @@ -1949,7 +1948,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } else { - Console.WriteLine("MEGA"); Vector2 swCorner, neCorner; GetMegaregionViewRange(out swCorner, out neCorner); -- cgit v1.1 From 876d0d310f3c7248a4a6fc29d8babe55a7b1e570 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Mar 2013 01:36:34 +0000 Subject: Add "show eq" console command to show numbers of messages in agent event queues. For debugging purposes. --- .../Linden/Caps/EventQueue/EventQueueGetModule.cs | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index 3cc3950..624378e 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -97,6 +97,14 @@ namespace OpenSim.Region.ClientStack.Linden + " >= 1 - turns on outgoing event logging\n" + " >= 2 - turns on poll notification", HandleDebugEq); + + MainConsole.Instance.Commands.AddCommand( + "Debug", + false, + "show eq", + "show eq", + "Show contents of event queues for logged in avatars. Used for debugging.", + HandleShowEq); } public void RemoveRegion(Scene scene) @@ -148,6 +156,21 @@ namespace OpenSim.Region.ClientStack.Linden } } + protected void HandleShowEq(string module, string[] args) + { + MainConsole.Instance.OutputFormat("For scene {0}", m_scene.Name); + + lock (queues) + { + foreach (KeyValuePair> kvp in queues) + { + MainConsole.Instance.OutputFormat( + "For agent {0} there are {1} messages queued for send.", + kvp.Key, kvp.Value.Count); + } + } + } + /// /// Always returns a valid queue /// -- cgit v1.1 From b5b01e5bb59656078012c12146ea6f9e71589d43 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Mar 2013 01:37:52 +0000 Subject: Make HGLureModule track god like lures as well as normal lures, to see if this fixes issues where second megaregion auto-teleport hangs on black teleport screen when HG is active. --- OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs index 6c9fd86..a34f2d2 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs @@ -154,7 +154,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure void OnIncomingInstantMessage(GridInstantMessage im) { - if (im.dialog == (byte)InstantMessageDialog.RequestTeleport) + if (im.dialog == (byte)InstantMessageDialog.RequestTeleport + || im.dialog == (byte)InstantMessageDialog.GodLikeRequestTeleport) { UUID sessionID = new UUID(im.imSessionID); -- cgit v1.1 From 617637c788045f5776d21fc4ce246f3a8d6ecfb8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Mar 2013 01:41:23 +0000 Subject: minor: Fix usage error message for "debug eq" console command --- .../Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index 624378e..c7d4283 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -146,7 +146,7 @@ namespace OpenSim.Region.ClientStack.Linden if (!(args.Length == 3 && int.TryParse(args[2], out debugLevel))) { - MainConsole.Instance.OutputFormat("Usage: debug eq [0|1]"); + MainConsole.Instance.OutputFormat("Usage: debug eq [0|1|2]"); } else { -- cgit v1.1 From 506d5e41bf3fff8acb78002e565eab96beede370 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Mar 2013 01:54:11 +0000 Subject: On the North and East sides of a megaregion, only consider regions within 256m to be neighbours rather than regions up to 512 distant. This looks like an off-by-one bug since the view distance was already only 256 on the west and south sides. This reduces the number of child agents being logged into regions neighbouring a megaregion. --- .../CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index dc6a2a0..8da76df 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1901,8 +1901,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } // Loss of fraction on purpose - extent.X = ((int)extent.X / (int)Constants.RegionSize) + 1; - extent.Y = ((int)extent.Y / (int)Constants.RegionSize) + 1; + extent.X = ((int)extent.X / (int)Constants.RegionSize); + extent.Y = ((int)extent.Y / (int)Constants.RegionSize); swCorner.X = Scene.RegionInfo.RegionLocX - 1; swCorner.Y = Scene.RegionInfo.RegionLocY - 1; -- cgit v1.1 From b05ed4ffa693f3481f97a197de7e582492dc7271 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Mar 2013 02:17:32 +0000 Subject: Instead of going via GodLikeRequestTeleport, auto-teleport the agent directly in a megaregion, in the same manner at the "teleport user" console command. This is to bypass an issue with the HGLureModule which stops the auto-teleport from happening. --- OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs | 2 +- .../Framework/EntityTransfer/EntityTransferModule.cs | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs index e4b0cfa..7f4606b 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs @@ -165,7 +165,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure (uint)presence.AbsolutePosition.Y, (uint)Math.Ceiling(presence.AbsolutePosition.Z)); - m_log.DebugFormat("TP invite with message {0}", message); + m_log.DebugFormat("TP invite with message {0}, type {1}", message, lureType); GridInstantMessage m = new GridInstantMessage(scene, client.AgentId, client.FirstName+" "+client.LastName, targetid, diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 8da76df..8a16943 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -379,8 +379,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer Vector3 emergencyPos = new Vector3(128, 128, 128); m_log.WarnFormat( - "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", - position, sp.Name, sp.UUID, emergencyPos); + "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2} in {3}. Substituting {4}", + position, sp.Name, sp.UUID, Scene.Name, emergencyPos); position = emergencyPos; } @@ -1346,7 +1346,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer Scene initiatingScene) { Thread.Sleep(10000); - + + agent.Scene.RequestTeleportLocation( + agent.ControllingClient, + Utils.UIntsToLong(regionX * (uint)Constants.RegionSize, regionY * (uint)Constants.RegionSize), + position, + agent.Lookat, + (uint)Constants.TeleportFlags.ViaLocation); + + /* IMessageTransferModule im = initiatingScene.RequestModuleInterface(); if (im != null) { @@ -1381,6 +1389,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer }); } + */ } private void InformClientToInitiateTeleportToLocationCompleted(IAsyncResult iar) -- cgit v1.1 From d9c049fd9f1a78d73931f6aaa4cf9e6c512ba576 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Mar 2013 02:20:43 +0000 Subject: Fix a bug in HGEntityTransferModule to call base.RemoveRegion() when a region is removed rather than base.AddRegion() --- .../CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index b188741..33ea063 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -199,7 +199,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public override void RemoveRegion(Scene scene) { - base.AddRegion(scene); + base.RemoveRegion(scene); if (m_Enabled) scene.UnregisterModuleInterface(this); -- cgit v1.1 From afd0d6af0710375bf566ef5a6fcf00e7d1c5ca0f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Mar 2013 02:23:09 +0000 Subject: minor: Only try to deregister stats in EntityTransferModule.RemoveRegion() if module was enabled. --- .../Framework/EntityTransfer/EntityTransferModule.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 8a16943..f351da6 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -256,10 +256,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public virtual void RemoveRegion(Scene scene) { - StatsManager.DeregisterStat(m_interRegionTeleportAttempts); - StatsManager.DeregisterStat(m_interRegionTeleportAborts); - StatsManager.DeregisterStat(m_interRegionTeleportCancels); - StatsManager.DeregisterStat(m_interRegionTeleportFailures); + if (m_Enabled) + { + StatsManager.DeregisterStat(m_interRegionTeleportAttempts); + StatsManager.DeregisterStat(m_interRegionTeleportAborts); + StatsManager.DeregisterStat(m_interRegionTeleportCancels); + StatsManager.DeregisterStat(m_interRegionTeleportFailures); + } } public virtual void RegionLoaded(Scene scene) -- cgit v1.1 From 9ca54d00d8b1ca6181392d027077e82e64c53c3d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Mar 2013 02:29:34 +0000 Subject: Add back a log message when we attempt a megaregion auto-reteleport --- .../CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index f351da6..035632b 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1350,6 +1350,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { Thread.Sleep(10000); + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Auto-reteleporting {0} to correct megaregion location {1},{2},{3} from {4}", + agent.Name, regionX, regionY, position, initiatingScene.Name); + agent.Scene.RequestTeleportLocation( agent.ControllingClient, Utils.UIntsToLong(regionX * (uint)Constants.RegionSize, regionY * (uint)Constants.RegionSize), -- cgit v1.1 From 3f9b274180acb4499b878e9acad461811f11eb1f Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 27 Mar 2013 16:59:13 -0700 Subject: BulletSim: tweaks to terrain boundry computation. No functional changes. --- .../Physics/BulletSPlugin/BSTerrainManager.cs | 50 +++++++++++++--------- 1 file changed, 29 insertions(+), 21 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index a60946d..d4aecbc 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -343,37 +343,35 @@ public sealed class BSTerrainManager : IDisposable { Vector3 ret = pPos; + // First, base addresses are never negative so correct for that possible problem. + if (ret.X < 0f || ret.Y < 0f) + { + ret.X = Util.Clamp(ret.X, 0f, 1000000f); + ret.Y = Util.Clamp(ret.Y, 0f, 1000000f); + DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,zeroingNegXorY,oldPos={1},newPos={2}", + BSScene.DetailLogZero, pPos, ret); + } + // Can't do this function if we don't know about any terrain. if (m_terrains.Count == 0) return ret; - int loopPrevention = 5; + int loopPrevention = 10; Vector3 terrainBaseXYZ; BSTerrainPhys physTerrain; while (!GetTerrainPhysicalAtXYZ(ret, out physTerrain, out terrainBaseXYZ)) { // The passed position is not within a known terrain area. + // NOTE that GetTerrainPhysicalAtXYZ will set 'terrainBaseXYZ' to the base of the unfound region. - // First, base addresses are never negative so correct for that possible problem. - if (ret.X < 0f || ret.Y < 0f) - { - if (ret.X < 0f) - ret.X = 0f; - if (ret.Y < 0f) - ret.Y = 0f; - DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,zeroingNegXorY,oldPos={1},newPos={2}", - BSScene.DetailLogZero, pPos, ret); - } - else - { - // Must be off the top of a region. Find an adjacent region to move into. - Vector3 adjacentTerrainBase = FindAdjacentTerrainBase(terrainBaseXYZ); + // Must be off the top of a region. Find an adjacent region to move into. + Vector3 adjacentTerrainBase = FindAdjacentTerrainBase(terrainBaseXYZ); + + ret.X = Math.Min(ret.X, adjacentTerrainBase.X + (ret.X % DefaultRegionSize.X)); + ret.Y = Math.Min(ret.Y, adjacentTerrainBase.Y + (ret.X % DefaultRegionSize.Y)); + DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,findingAdjacentRegion,adjacentRegBase={1},oldPos={2},newPos={3}", + BSScene.DetailLogZero, adjacentTerrainBase, pPos, ret); - ret.X = Math.Min(ret.X, adjacentTerrainBase.X + DefaultRegionSize.X); - ret.Y = Math.Min(ret.Y, adjacentTerrainBase.Y + DefaultRegionSize.Y); - DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,findingAdjacentRegion,adjacentRegBase={1},oldPos={2},newPos={3}", - BSScene.DetailLogZero, adjacentTerrainBase, pPos, ret); - } if (loopPrevention-- < 0f) { // The 'while' is a little dangerous so this prevents looping forever if the @@ -383,6 +381,7 @@ public sealed class BSTerrainManager : IDisposable break; } } + return ret; } @@ -479,11 +478,20 @@ public sealed class BSTerrainManager : IDisposable private Vector3 FindAdjacentTerrainBase(Vector3 pTerrainBase) { Vector3 ret = pTerrainBase; + + // Can't do this function if we don't know about any terrain. + if (m_terrains.Count == 0) + return ret; + + // Just some sanity + ret.X = Util.Clamp(ret.X, 0f, 1000000f); + ret.Y = Util.Clamp(ret.Y, 0f, 1000000f); ret.Z = 0f; + lock (m_terrains) { // Once down to the <0,0> region, we have to be done. - while (ret.X > 0f && ret.Y > 0f) + while (ret.X > 0f || ret.Y > 0f) { if (ret.X > 0f) { -- cgit v1.1 From 6a9630d2bdc27ed702936f4c44e6978f728a9ef0 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 28 Mar 2013 10:56:21 -0700 Subject: BulletSim: fix race condition when creating very large mega-regions. The symptom was exceptions while creating physical terrain. Reduce default terrain mesh magnification to 2 from 3 because the higher resolution uses a lot of memory and doesn't solve the terrain smoothness for vehicles. Added comments here and there and improved some debugging log messages. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 4 +-- .../Region/Physics/BulletSPlugin/BSMaterials.cs | 3 ++ OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 2 +- .../Physics/BulletSPlugin/BSTerrainManager.cs | 38 ++++++++++++++-------- .../Region/Physics/BulletSPlugin/BSTerrainMesh.cs | 10 +++--- 5 files changed, 35 insertions(+), 22 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index e208d3a..90c2d9c 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -479,7 +479,7 @@ public sealed class BSCharacter : BSPhysObject // The character is out of the known/simulated area. // Force the avatar position to be within known. ScenePresence will use the position // plus the velocity to decide if the avatar is moving out of the region. - RawPosition = PhysicsScene.TerrainManager.ClampPositionIntoKnownTerrain(RawPosition); + RawPosition = PhysicsScene.TerrainManager.ClampPositionIntoKnownTerrain(RawPosition); DetailLog("{0},BSCharacter.PositionSanityCheck,notWithinKnownTerrain,clampedPos={1}", LocalID, RawPosition); return true; } @@ -898,7 +898,7 @@ public sealed class BSCharacter : BSPhysObject // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. if (PositionSanityCheck(true)) { - DetailLog("{0},BSCharacter.UpdateProperties,updatePosForSanity,pos={1}", LocalID, _position); + DetailLog("{0},BSCharacter.UpdateProperties,updatePosForSanity,pos={1}", LocalID, _position); entprop.Position = _position; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs index 92d62ff..ee77d6e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs @@ -180,11 +180,14 @@ public static class BSMaterials // Use reflection to set the value in the attribute structure. private static void SetAttributeValue(int matType, string attribName, float val) { + // Get the current attribute values for this material MaterialAttributes thisAttrib = Attributes[matType]; + // Find the field for the passed attribute name (eg, find field named 'friction') FieldInfo fieldInfo = thisAttrib.GetType().GetField(attribName.ToLower()); if (fieldInfo != null) { fieldInfo.SetValue(thisAttrib, val); + // Copy new attributes back to array -- since MaterialAttributes is 'struct', passed by value, not reference. Attributes[matType] = thisAttrib; } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index f3454c8..385ed9e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -482,7 +482,7 @@ public static class BSParam (s) => { return TerrainImplementation; }, (s,v) => { TerrainImplementation = v; } ), new ParameterDefn("TerrainMeshMagnification", "Number of times the 256x256 heightmap is multiplied to create the terrain mesh" , - 3, + 2, (s) => { return TerrainMeshMagnification; }, (s,v) => { TerrainMeshMagnification = v; } ), new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" , diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index d4aecbc..b2fb835 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -132,6 +132,7 @@ public sealed class BSTerrainManager : IDisposable // safe to call Bullet in real time. We hope no one is moving prims around yet. public void CreateInitialGroundPlaneAndTerrain() { + DetailLog("{0},BSTerrainManager.CreateInitialGroundPlaneAndTerrain,region={1}", BSScene.DetailLogZero, PhysicsScene.RegionName); // The ground plane is here to catch things that are trying to drop to negative infinity BulletShape groundPlaneShape = PhysicsScene.PE.CreateGroundPlaneShape(BSScene.GROUNDPLANE_ID, 1f, BSParam.TerrainCollisionMargin); m_groundPlane = PhysicsScene.PE.CreateBodyWithDefaultMotionState(groundPlaneShape, @@ -145,14 +146,18 @@ public sealed class BSTerrainManager : IDisposable m_groundPlane.collisionType = CollisionType.Groundplane; m_groundPlane.ApplyCollisionMask(PhysicsScene); - // Build an initial terrain and put it in the world. This quickly gets replaced by the real region terrain. BSTerrainPhys initialTerrain = new BSTerrainHeightmap(PhysicsScene, Vector3.Zero, BSScene.TERRAIN_ID, DefaultRegionSize); - m_terrains.Add(Vector3.Zero, initialTerrain); + lock (m_terrains) + { + // Build an initial terrain and put it in the world. This quickly gets replaced by the real region terrain. + m_terrains.Add(Vector3.Zero, initialTerrain); + } } // Release all the terrain structures we might have allocated public void ReleaseGroundPlaneAndTerrain() { + DetailLog("{0},BSTerrainManager.ReleaseGroundPlaneAndTerrain,region={1}", BSScene.DetailLogZero, PhysicsScene.RegionName); if (m_groundPlane.HasPhysicalBody) { if (PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, m_groundPlane)) @@ -193,11 +198,16 @@ public sealed class BSTerrainManager : IDisposable // the terrain is added to our parent if (MegaRegionParentPhysicsScene is BSScene) { - DetailLog("{0},SetTerrain.ToParent,offset={1},worldMax={2}", - BSScene.DetailLogZero, m_worldOffset, m_worldMax); - ((BSScene)MegaRegionParentPhysicsScene).TerrainManager.UpdateTerrain( - BSScene.CHILDTERRAIN_ID, localHeightMap, - m_worldOffset, m_worldOffset + DefaultRegionSize, true); + DetailLog("{0},SetTerrain.ToParent,offset={1},worldMax={2}", BSScene.DetailLogZero, m_worldOffset, m_worldMax); + // This looks really odd but this region is passing its terrain to its mega-region root region + // and the creation of the terrain must happen on the root region's taint thread and not + // my taint thread. + ((BSScene)MegaRegionParentPhysicsScene).PostTaintObject("TerrainManager.SetTerrain.Mega-" + m_worldOffset.ToString(), 0, delegate() + { + ((BSScene)MegaRegionParentPhysicsScene).TerrainManager.UpdateTerrain( + BSScene.CHILDTERRAIN_ID, localHeightMap, + m_worldOffset, m_worldOffset + DefaultRegionSize, true /* inTaintTime */); + }); } } else @@ -206,16 +216,16 @@ public sealed class BSTerrainManager : IDisposable DetailLog("{0},SetTerrain.Existing", BSScene.DetailLogZero); UpdateTerrain(BSScene.TERRAIN_ID, localHeightMap, - m_worldOffset, m_worldOffset + DefaultRegionSize, true); + m_worldOffset, m_worldOffset + DefaultRegionSize, true /* inTaintTime */); } }); } - // If called with no mapInfo for the terrain, this will create a new mapInfo and terrain + // If called for terrain has has not been previously allocated, a new terrain will be built // based on the passed information. The 'id' should be either the terrain id or // BSScene.CHILDTERRAIN_ID. If the latter, a new child terrain ID will be allocated and used. // The latter feature is for creating child terrains for mega-regions. - // If called with a mapInfo in m_heightMaps and there is an existing terrain body, a new + // If there is an existing terrain body, a new // terrain shape is created and added to the body. // This call is most often used to update the heightMap and parameters of the terrain. // (The above does suggest that some simplification/refactoring is in order.) @@ -223,8 +233,8 @@ public sealed class BSTerrainManager : IDisposable private void UpdateTerrain(uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords, bool inTaintTime) { - DetailLog("{0},BSTerrainManager.UpdateTerrain,call,minC={1},maxC={2},inTaintTime={3}", - BSScene.DetailLogZero, minCoords, maxCoords, inTaintTime); + DetailLog("{0},BSTerrainManager.UpdateTerrain,call,id={1},minC={2},maxC={3},inTaintTime={4}", + BSScene.DetailLogZero, id, minCoords, maxCoords, inTaintTime); // Find high and low points of passed heightmap. // The min and max passed in is usually the area objects can be in (maximum @@ -253,7 +263,7 @@ public sealed class BSTerrainManager : IDisposable if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys)) { // There is already a terrain in this spot. Free the old and build the new. - DetailLog("{0},UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}", + DetailLog("{0},BSTErrainManager.UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}", BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords); // Remove old terrain from the collection @@ -292,7 +302,7 @@ public sealed class BSTerrainManager : IDisposable if (newTerrainID >= BSScene.CHILDTERRAIN_ID) newTerrainID = ++m_terrainCount; - DetailLog("{0},UpdateTerrain:NewTerrain,taint,newID={1},minCoord={2},maxCoord={3}", + DetailLog("{0},BSTerrainManager.UpdateTerrain:NewTerrain,taint,newID={1},minCoord={2},maxCoord={3}", BSScene.DetailLogZero, newTerrainID, minCoords, minCoords); BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords); m_terrains.Add(terrainRegionBase, newTerrainPhys); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index a9cd8a1..2ce1513 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs @@ -98,20 +98,20 @@ public sealed class BSTerrainMesh : BSTerrainPhys if (!meshCreationSuccess) { // DISASTER!! - PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedConversionOfHeightmap", ID); + PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedConversionOfHeightmap,id={1}", BSScene.DetailLogZero, ID); PhysicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh! base={1}", LogHeader, TerrainBase); // Something is very messed up and a crash is in our future. return; } - PhysicsScene.DetailLog("{0},BSTerrainMesh.create,meshed,indices={1},indSz={2},vertices={3},vertSz={4}", - ID, indicesCount, indices.Length, verticesCount, vertices.Length); + PhysicsScene.DetailLog("{0},BSTerrainMesh.create,meshed,id={1},indices={2},indSz={3},vertices={4},vertSz={5}", + BSScene.DetailLogZero, ID, indicesCount, indices.Length, verticesCount, vertices.Length); m_terrainShape = PhysicsScene.PE.CreateMeshShape(PhysicsScene.World, indicesCount, indices, verticesCount, vertices); if (!m_terrainShape.HasPhysicalShape) { // DISASTER!! - PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape", ID); + PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape,id={1}", BSScene.DetailLogZero, ID); PhysicsScene.Logger.ErrorFormat("{0} Failed creation of terrain mesh! base={1}", LogHeader, TerrainBase); // Something is very messed up and a crash is in our future. return; @@ -151,7 +151,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys if (BSParam.UseSingleSidedMeshes) { - PhysicsScene.DetailLog("{0},BSTerrainMesh.settingCustomMaterial", id); + PhysicsScene.DetailLog("{0},BSTerrainMesh.settingCustomMaterial,id={1}", BSScene.DetailLogZero, id); PhysicsScene.PE.AddToCollisionFlags(m_terrainBody, CollisionFlags.CF_CUSTOM_MATERIAL_CALLBACK); } -- cgit v1.1 From c2093ccce16cd5210c8e0759f23b5b4bd205b7af Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Mar 2013 22:07:58 +0000 Subject: Move the simulator-side RezAttachments call on login to SP.MakeRootAgent with the other attachments code, using TeleportFlags.ViaLogin check to fire if necessary. This is to simplify the code (no tricky 'wasChild' signalling required) and to reduce the risk of a thread clash between simulator-side attaching (necessary for v1 viewers) and the viewer-side attaching the v3 viewers perform. --- .../Avatar/Attachments/AttachmentsModule.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.cs | 28 --------------- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 41 ++++++++++++++++------ 3 files changed, 32 insertions(+), 39 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index ad17aa9..a46834c 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -197,7 +197,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return; } -// m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0}", sp.Name); +// m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0} from simulator-side", sp.Name); List attachments = sp.Appearance.GetAttachments(); foreach (AvatarAttachment attach in attachments) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 45cbdd5..0ac4027 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2820,34 +2820,6 @@ namespace OpenSim.Region.Framework.Scenes m_eventManager.TriggerOnNewPresence(sp); sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags; - - // The first agent upon login is a root agent by design. - // For this agent we will have to rez the attachments. - // All other AddNewClient calls find aCircuit.child to be true. - if (aCircuit.child == false) - { - // We have to set SP to be a root agent here so that SP.MakeRootAgent() will later not try to - // start the scripts again (since this is done in RezAttachments()). - // XXX: This is convoluted. - sp.IsChildAgent = false; - - // We leave a 5 second pause before attempting to rez attachments to avoid a clash with - // version 3 viewers that maybe doing their own attachment rezzing related to their current - // outfit folder on startup. If these operations do clash, then the symptoms are invisible - // attachments until one zooms in on the avatar. - // - // We do not pause if we are launching on the same thread anyway in order to avoid pointlessly - // delaying any attachment related regression tests. - if (AttachmentsModule != null) - Util.FireAndForget( - o => - { - if (Util.FireAndForgetMethod != FireAndForgetMethod.None) - Thread.Sleep(5000); - - AttachmentsModule.RezAttachments(sp); - }); - } } else { diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index f3b923f..4fb9a1b 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -866,7 +866,6 @@ namespace OpenSim.Region.Framework.Scenes //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); - bool wasChild = IsChildAgent; IsChildAgent = false; IGroupsModule gm = m_scene.RequestModuleInterface(); @@ -952,18 +951,40 @@ namespace OpenSim.Region.Framework.Scenes // and it has already rezzed the attachments and started their scripts. // We do the following only for non-login agents, because their scripts // haven't started yet. - lock (m_attachments) + if ((TeleportFlags & TeleportFlags.ViaLogin) != 0) + { + // We leave a 5 second pause before attempting to rez attachments to avoid a clash with + // version 3 viewers that maybe doing their own attachment rezzing related to their current + // outfit folder on startup. If these operations do clash, then the symptoms are invisible + // attachments until one zooms in on the avatar. + // + // We do not pause if we are launching on the same thread anyway in order to avoid pointlessly + // delaying any attachment related regression tests. + if (Scene.AttachmentsModule != null) + Util.FireAndForget( + o => + { + if (Util.FireAndForgetMethod != FireAndForgetMethod.None) + System.Threading.Thread.Sleep(5000); + + Scene.AttachmentsModule.RezAttachments(this); + }); + } + else { - if (wasChild && HasAttachments()) + lock (m_attachments) { - m_log.DebugFormat( - "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); - - // Resume scripts - foreach (SceneObjectGroup sog in m_attachments) + if (HasAttachments()) { - sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); - sog.ResumeScripts(); + m_log.DebugFormat( + "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); + + // Resume scripts + foreach (SceneObjectGroup sog in m_attachments) + { + sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); + sog.ResumeScripts(); + } } } } -- cgit v1.1 From 3b377f16b29a6395d73af1cc987cb9abf9935376 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Mar 2013 22:44:59 +0000 Subject: Fix regression tests by making a new NPC always trigger simulator side attachment code when created. Regression from previous commit c2093ccc. Failed because NPCs don't set the ViaLogin flag --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 4fb9a1b..3a1e758 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -951,7 +951,7 @@ namespace OpenSim.Region.Framework.Scenes // and it has already rezzed the attachments and started their scripts. // We do the following only for non-login agents, because their scripts // haven't started yet. - if ((TeleportFlags & TeleportFlags.ViaLogin) != 0) + if (PresenceType == PresenceType.Npc || (TeleportFlags & TeleportFlags.ViaLogin) != 0) { // We leave a 5 second pause before attempting to rez attachments to avoid a clash with // version 3 viewers that maybe doing their own attachment rezzing related to their current @@ -964,7 +964,7 @@ namespace OpenSim.Region.Framework.Scenes Util.FireAndForget( o => { - if (Util.FireAndForgetMethod != FireAndForgetMethod.None) + if (PresenceType != PresenceType.Npc && Util.FireAndForgetMethod != FireAndForgetMethod.None) System.Threading.Thread.Sleep(5000); Scene.AttachmentsModule.RezAttachments(this); -- cgit v1.1 From 4ad9b275302ee109937512963eab095ff542a0c7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Mar 2013 22:51:59 +0000 Subject: If the viewer has already rezzed any attachments itself, then ignore the simulator-side rez attachments call. This is a further effort to reduce v3 viewer race conditions where this call may clash with the viewer signalling attachment wearing from its current outfit folder. --- .../CoreModules/Avatar/Attachments/AttachmentsModule.cs | 14 ++++++++++---- OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs | 4 ++++ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 12 +++++------- 3 files changed, 19 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index a46834c..55c5422 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -182,10 +182,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } } - /// - /// RezAttachments. This should only be called upon login on the first region. - /// Attachment rezzings on crossings and TPs are done in a different way. - /// public void RezAttachments(IScenePresence sp) { if (!Enabled) @@ -194,9 +190,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (null == sp.Appearance) { m_log.WarnFormat("[ATTACHMENTS MODULE]: Appearance has not been initialized for agent {0}", sp.UUID); + return; } + if (sp.GetAttachments().Count > 0) + { +// m_log.DebugFormat( +// "[ATTACHMENTS MODULE]: Not doing simulator-side attachment rez for {0} in {1} as their viewer has already rezzed attachments", +// m_scene.Name, sp.Name); + + return; + } + // m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0} from simulator-side", sp.Name); List attachments = sp.Appearance.GetAttachments(); diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index 46daab3..156a09d 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -53,6 +53,10 @@ namespace OpenSim.Region.Framework.Interfaces /// RezAttachments. This should only be called upon login on the first region. /// Attachment rezzings on crossings and TPs are done in a different way. /// + /// + /// This is only actually necessary for viewers which do not have a current outfit folder (these viewers make + /// their own attachment calls on login) and agents which have attachments but no viewer (e.g. NPCs). + /// /// void RezAttachments(IScenePresence sp); diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 3a1e758..fcb2f6d 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -953,13 +953,11 @@ namespace OpenSim.Region.Framework.Scenes // haven't started yet. if (PresenceType == PresenceType.Npc || (TeleportFlags & TeleportFlags.ViaLogin) != 0) { - // We leave a 5 second pause before attempting to rez attachments to avoid a clash with - // version 3 viewers that maybe doing their own attachment rezzing related to their current - // outfit folder on startup. If these operations do clash, then the symptoms are invisible - // attachments until one zooms in on the avatar. - // - // We do not pause if we are launching on the same thread anyway in order to avoid pointlessly - // delaying any attachment related regression tests. + // Viewers which have a current outfit folder will actually rez their own attachments. However, + // viewers without (e.g. v1 viewers) will not, so we still need to make this call. + // + // However, we leave a 5 second pause to try and avoid a clash with viewers that are rezzing + // attachments themselves. This should then mean that this call ends up doing nothing. if (Scene.AttachmentsModule != null) Util.FireAndForget( o => -- cgit v1.1 From 03e421bf3d796bf3498f4f3311c59ce04fb1fea1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Mar 2013 22:55:13 +0000 Subject: minor: comment out unused Scene.AgentCrossing() to reduce code complexity --- OpenSim/Region/Framework/Scenes/Scene.cs | 54 ++++++++++++++++---------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 0ac4027..5337835 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -4103,33 +4103,33 @@ namespace OpenSim.Region.Framework.Scenes // } // } - /// - /// Triggered when an agent crosses into this sim. Also happens on initial login. - /// - /// - /// - /// - public virtual void AgentCrossing(UUID agentID, Vector3 position, bool isFlying) - { - ScenePresence presence = GetScenePresence(agentID); - if (presence != null) - { - try - { - presence.MakeRootAgent(position, isFlying); - } - catch (Exception e) - { - m_log.ErrorFormat("[SCENE]: Unable to do agent crossing, exception {0}{1}", e.Message, e.StackTrace); - } - } - else - { - m_log.ErrorFormat( - "[SCENE]: Could not find presence for agent {0} crossing into scene {1}", - agentID, RegionInfo.RegionName); - } - } +// /// +// /// Triggered when an agent crosses into this sim. Also happens on initial login. +// /// +// /// +// /// +// /// +// public virtual void AgentCrossing(UUID agentID, Vector3 position, bool isFlying) +// { +// ScenePresence presence = GetScenePresence(agentID); +// if (presence != null) +// { +// try +// { +// presence.MakeRootAgent(position, isFlying); +// } +// catch (Exception e) +// { +// m_log.ErrorFormat("[SCENE]: Unable to do agent crossing, exception {0}{1}", e.Message, e.StackTrace); +// } +// } +// else +// { +// m_log.ErrorFormat( +// "[SCENE]: Could not find presence for agent {0} crossing into scene {1}", +// agentID, RegionInfo.RegionName); +// } +// } /// /// We've got an update about an agent that sees into this region, -- cgit v1.1 From feffc8081dc5ab2889a7ea4b96b2befaed0c3f95 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Mar 2013 22:56:30 +0000 Subject: minor: remove some mono compiler warnings from EntityTransferModule --- .../CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 5 ----- 1 file changed, 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 035632b..764c982 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1938,11 +1938,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer Scene pScene = avatar.Scene; RegionInfo m_regionInfo = pScene.RegionInfo; - Border[] northBorders = pScene.NorthBorders.ToArray(); - Border[] southBorders = pScene.SouthBorders.ToArray(); - Border[] eastBorders = pScene.EastBorders.ToArray(); - Border[] westBorders = pScene.WestBorders.ToArray(); - // Leaving this as a "megaregions" computation vs "non-megaregions" computation; it isn't // clear what should be done with a "far view" given that megaregions already extended the // view to include everything in the megaregion -- cgit v1.1 From 2b142f2f9e888d5cb7317cc51c12ac7152c54459 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Mar 2013 23:09:35 +0000 Subject: Add "debug attachments" console command to allow highly verbose attachment logging to be switched on and off. Default is off. --- .../Avatar/Attachments/AttachmentsModule.cs | 170 +++++++++++++-------- 1 file changed, 109 insertions(+), 61 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 55c5422..c78f5b3 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -48,6 +48,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { #region INonSharedRegionModule private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public int DebugLevel { get; set; } private Scene m_scene; private IInventoryAccessModule m_invAccessModule; @@ -79,11 +81,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments m_scene.EventManager.OnNewClient += SubscribeToClientEvents; m_scene.EventManager.OnStartScript += (localID, itemID) => HandleScriptStateChange(localID, true); m_scene.EventManager.OnStopScript += (localID, itemID) => HandleScriptStateChange(localID, false); + + MainConsole.Instance.Commands.AddCommand( + "Debug", + false, + "debug attachments", + "debug attachments [0|1]", + "Turn on attachments debugging\n" + + " <= 0 - turns off debugging\n" + + " >= 1 - turns on attachment message logging\n", + HandleDebugAttachments); } // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI } + private void HandleDebugAttachments(string module, string[] args) + { + int debugLevel; + + if (!(args.Length == 3 && int.TryParse(args[2], out debugLevel))) + { + MainConsole.Instance.OutputFormat("Usage: debug attachments [0|1]"); + } + else + { + DebugLevel = debugLevel; + MainConsole.Instance.OutputFormat( + "Set event queue debug level to {0} in {1}", DebugLevel, m_scene.Name); + } + } + /// /// Listen for client triggered running state changes so that we can persist the script's object if necessary. /// @@ -196,14 +224,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (sp.GetAttachments().Count > 0) { -// m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: Not doing simulator-side attachment rez for {0} in {1} as their viewer has already rezzed attachments", -// m_scene.Name, sp.Name); + if (DebugLevel > 0) + m_log.DebugFormat( + "[ATTACHMENTS MODULE]: Not doing simulator-side attachment rez for {0} in {1} as their viewer has already rezzed attachments", + m_scene.Name, sp.Name); return; } -// m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0} from simulator-side", sp.Name); + if (DebugLevel > 0) + m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0} from simulator-side", sp.Name); List attachments = sp.Appearance.GetAttachments(); foreach (AvatarAttachment attach in attachments) @@ -245,7 +275,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (!Enabled) return; -// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); + if (DebugLevel > 0) + m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); List attachments = sp.GetAttachments(); @@ -278,9 +309,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (!Enabled) return; -// m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}", -// m_scene.RegionInfo.RegionName, sp.Name, silent); + if (DebugLevel > 0) + m_log.DebugFormat( + "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}", + m_scene.RegionInfo.RegionName, sp.Name, silent); foreach (SceneObjectGroup sop in sp.GetAttachments()) { @@ -313,9 +345,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { if (group.GetSittingAvatarsCount() != 0) { -// m_log.WarnFormat( -// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since {4} avatars are still sitting on it", -// group.Name, group.LocalId, sp.Name, attachmentPt, group.GetSittingAvatarsCount()); + if (DebugLevel > 0) + m_log.WarnFormat( + "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since {4} avatars are still sitting on it", + group.Name, group.LocalId, sp.Name, attachmentPt, group.GetSittingAvatarsCount()); return false; } @@ -351,9 +384,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (attachments.Contains(group)) { -// m_log.WarnFormat( -// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", -// group.Name, group.LocalId, sp.Name, AttachmentPt); + if (DebugLevel > 0) + m_log.WarnFormat( + "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", + group.Name, group.LocalId, sp.Name, attachmentPt); return false; } @@ -418,9 +452,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (!Enabled) return null; -// m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2} in {3}", -// (AttachmentPoint)AttachmentPt, itemID, sp.Name, m_scene.Name); + if (DebugLevel > 0) + m_log.DebugFormat( + "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2} in {3}", + (AttachmentPoint)AttachmentPt, itemID, sp.Name, m_scene.Name); bool append = (AttachmentPt & 0x80) != 0; AttachmentPt &= 0x7f; @@ -444,9 +479,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // if (sp.Appearance.GetAttachmentForItem(itemID) != null) if (alreadyOn) { -// m_log.WarnFormat( -// "[ATTACHMENTS MODULE]: Ignoring request by {0} to wear item {1} at {2} since it is already worn", -// sp.Name, itemID, AttachmentPt); + if (DebugLevel > 0) + m_log.DebugFormat( + "[ATTACHMENTS MODULE]: Ignoring request by {0} to wear item {1} at {2} since it is already worn", + sp.Name, itemID, AttachmentPt); return null; } @@ -459,7 +495,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (!Enabled) return; - // m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name); + if (DebugLevel > 0) + m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name); foreach (KeyValuePair rez in rezlist) { @@ -477,9 +514,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (!Enabled) return; -// m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}", -// sp.UUID, soLocalId); + if (DebugLevel > 0) + m_log.DebugFormat( + "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}", + sp.UUID, soLocalId); SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId); @@ -495,9 +533,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (inventoryID == UUID.Zero) return; -// m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}", -// so.Name, so.LocalId, inventoryID); + if (DebugLevel > 0) + m_log.DebugFormat( + "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}", + so.Name, so.LocalId, inventoryID); lock (sp.AttachmentsSyncLock) { @@ -552,9 +591,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return; } -// m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: Detaching object {0} {1} (FromItemID {2}) for {3} in {4}", -// so.Name, so.LocalId, so.FromItemID, sp.Name, m_scene.Name); + if (DebugLevel > 0) + m_log.DebugFormat( + "[ATTACHMENTS MODULE]: Detaching object {0} {1} (FromItemID {2}) for {3} in {4}", + so.Name, so.LocalId, so.FromItemID, sp.Name, m_scene.Name); // Scripts MUST be snapshotted before the object is // removed from the scene because doing otherwise will @@ -680,12 +720,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments grp.HasGroupChanged = false; // Prevent it being saved over and over } -// else -// { -// m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}", -// grp.UUID, grp.AttachmentPoint); -// } + else if (DebugLevel > 0) + { + m_log.DebugFormat( + "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}", + grp.UUID, grp.AttachmentPoint); + } } /// @@ -703,9 +743,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments private void AttachToAgent( IScenePresence sp, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) { -// m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", -// so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); + if (DebugLevel > 0) + m_log.DebugFormat( + "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", + so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); so.DetachFromBackup(); @@ -730,9 +771,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { if (so.HasPrivateAttachmentPoint) { -// m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: Killing private HUD {0} for avatars other than {1} at attachment point {2}", -// so.Name, sp.Name, so.AttachmentPoint); + if (DebugLevel > 0) + m_log.DebugFormat( + "[ATTACHMENTS MODULE]: Killing private HUD {0} for avatars other than {1} at attachment point {2}", + so.Name, sp.Name, so.AttachmentPoint); // As this scene object can now only be seen by the attaching avatar, tell everybody else in the // scene that it's no longer in their awareness. @@ -766,9 +808,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (m_invAccessModule == null) return null; - // m_log.DebugFormat( - // "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}", - // grp.Name, grp.LocalId, remoteClient.Name); + if (DebugLevel > 0) + m_log.DebugFormat( + "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}", + grp.Name, grp.LocalId, sp.Name); InventoryItemBase newItem = m_invAccessModule.CopyToInventory( @@ -877,9 +920,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return null; } -// m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}", -// objatt.Name, sp.Name, attachmentPt, m_scene.Name); + if (DebugLevel > 0) + m_log.DebugFormat( + "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}", + objatt.Name, sp.Name, attachmentPt, m_scene.Name); // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. objatt.HasGroupChanged = false; @@ -949,9 +993,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments bool changed = sp.Appearance.SetAttachment((int)AttachmentPt | attFlag, itemID, item.AssetID); if (changed && m_scene.AvatarFactory != null) { -// m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: Queueing appearance save for {0}, attachment {1} point {2} in ShowAttachInUserInventory()", -// sp.Name, att.Name, AttachmentPt); + if (DebugLevel > 0) + m_log.DebugFormat( + "[ATTACHMENTS MODULE]: Queueing appearance save for {0}, attachment {1} point {2} in ShowAttachInUserInventory()", + sp.Name, att.Name, AttachmentPt); m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); } @@ -966,9 +1011,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (!Enabled) return null; - // m_log.DebugFormat( - // "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}", - // (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name); + if (DebugLevel > 0) + m_log.DebugFormat( + "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}", + (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name); ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); @@ -999,9 +1045,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments private void Client_OnObjectAttach(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) { -// m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", -// objectLocalID, remoteClient.Name, AttachmentPt, silent); + if (DebugLevel > 0) + m_log.DebugFormat( + "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", + objectLocalID, remoteClient.Name, AttachmentPt, silent); if (!Enabled) return; @@ -1036,9 +1083,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // Calls attach with a Zero position if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, false, append)) { -// m_log.Debug( -// "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId -// + ", AttachmentPoint: " + AttachmentPt); + if (DebugLevel > 0) + m_log.Debug( + "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId + + ", AttachmentPoint: " + AttachmentPt); // Save avatar attachment information m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId); @@ -1095,4 +1143,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments #endregion } -} +} \ No newline at end of file -- cgit v1.1 From c92654fb43f303da8e1623f9fff8a404aad72374 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Mar 2013 23:57:35 +0000 Subject: Stop attempts to update/add existing attachments in user inventory when teleporting between regions. This appears to resolve issues on teleport where attachments disappear or become labelled as invalid within user inventory. --- .../Avatar/Attachments/AttachmentsModule.cs | 31 +++++++++++----------- .../Attachments/Tests/AttachmentsModuleTests.cs | 10 +++---- .../Framework/Interfaces/IAttachmentsModule.cs | 6 +++-- .../Avatar/Attachments/TempAttachmentsModule.cs | 2 +- 4 files changed, 25 insertions(+), 24 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index c78f5b3..b7f4303 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -322,12 +322,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments sp.ClearAttachments(); } - public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp, bool append) + public bool AttachObject( + IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool addToInventory, bool append) { if (!Enabled) return false; - return AttachObjectInternal(sp, group, attachmentPt, silent, temp, true, append); + return AttachObjectInternal(sp, group, attachmentPt, silent, addToInventory, true, append); } /// @@ -338,10 +339,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// The object to attach. /// /// - /// + /// If true then add object to user inventory. /// If true then scripts are resumed on the attached object. + /// Append to attachment point rather than replace. private bool AttachObjectInternal( - IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp, bool resumeScripts, bool append) + IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool addToInventory, bool resumeScripts, bool append) { if (group.GetSittingAvatarsCount() != 0) { @@ -412,8 +414,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments lock (sp.AttachmentsSyncLock) { - if (sp.PresenceType != PresenceType.Npc) - UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp, append); + if (addToInventory && sp.PresenceType != PresenceType.Npc) + UpdateUserInventoryWithAttachment(sp, group, attachmentPt, append); AttachToAgent(sp, group, attachmentPt, attachPos, silent); @@ -432,19 +434,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return true; } - private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp, bool append) + private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool append) { List attachments = sp.GetAttachments(attachmentPt); // Add the new attachment to inventory if we don't already have it. - if (!temp) - { - UUID newAttachmentItemID = group.FromItemID; - if (newAttachmentItemID == UUID.Zero) - newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID; + UUID newAttachmentItemID = group.FromItemID; + if (newAttachmentItemID == UUID.Zero) + newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID; - ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group, append); - } + ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group, append); } public SceneObjectGroup RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) @@ -939,7 +938,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // This will throw if the attachment fails try { - AttachObjectInternal(sp, objatt, attachmentPt, false, false, true, append); + AttachObjectInternal(sp, objatt, attachmentPt, false, true, true, append); } catch (Exception e) { @@ -1081,7 +1080,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments AttachmentPt &= 0x7f; // Calls attach with a Zero position - if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, false, append)) + if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true, append)) { if (DebugLevel > 0) m_log.Debug( diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index c8c594d..6e4262e 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -197,7 +197,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID); m_numberOfAttachEventsFired = 0; - scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false); + scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, true, false); // Check status on scene presence Assert.That(sp.HasAttachments(), Is.True); @@ -244,7 +244,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, "att1", sp.UUID); m_numberOfAttachEventsFired = 0; - scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Default, false, false, false); + scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Default, false, true, false); // Check status on scene presence Assert.That(sp.HasAttachments(), Is.True); @@ -277,7 +277,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // Test wearing a different attachment from the ground. { - scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, false, false); + scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, true, false); // Check status on scene presence Assert.That(sp.HasAttachments(), Is.True); @@ -310,7 +310,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // Test rewearing an already worn attachment from ground. Nothing should happen. { - scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, false, false); + scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, true, false); // Check status on scene presence Assert.That(sp.HasAttachments(), Is.True); @@ -368,7 +368,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests sp2.AbsolutePosition = new Vector3(0, 0, 0); sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero); - scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false); + scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, true, false); Assert.That(sp.HasAttachments(), Is.False); Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index 156a09d..d9901bd 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -80,14 +80,16 @@ namespace OpenSim.Region.Framework.Interfaces void DeleteAttachmentsFromScene(IScenePresence sp, bool silent); /// - /// Attach an object to an avatar + /// Attach an object to an avatar. /// /// /// /// /// + /// If true then add object to user inventory + /// Append to attachment point rather than replace. /// true if the object was successfully attached, false otherwise - bool AttachObject(IScenePresence sp, SceneObjectGroup grp, uint AttachmentPt, bool silent, bool temp, bool append); + bool AttachObject(IScenePresence sp, SceneObjectGroup grp, uint AttachmentPt, bool silent, bool addToInventory, bool append); /// /// Rez an attachment from user inventory and change inventory status to match. diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs index 54c86ae..535bf67 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs @@ -184,7 +184,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments hostPart.ParentGroup.RootPart.ScheduleFullUpdate(); } - return attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, true, true) ? 1 : 0; + return attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, false, true) ? 1 : 0; } } } -- cgit v1.1 From 285bd3abc87aced43efa9519a5760d9dae3f50d9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 29 Mar 2013 00:49:55 +0000 Subject: Eliminate code which tries to restart attachment scripts in ScenePresence.MakeRootAgent(), since this is already done in AttachmentsModule --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index fcb2f6d..6591fef 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -968,24 +968,6 @@ namespace OpenSim.Region.Framework.Scenes Scene.AttachmentsModule.RezAttachments(this); }); } - else - { - lock (m_attachments) - { - if (HasAttachments()) - { - m_log.DebugFormat( - "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); - - // Resume scripts - foreach (SceneObjectGroup sog in m_attachments) - { - sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); - sog.ResumeScripts(); - } - } - } - } // send the animations of the other presences to me m_scene.ForEachRootScenePresence(delegate(ScenePresence presence) -- cgit v1.1 From d87ddf50fcd674fbd9aa8b8556bf57f2d285a3ba Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 29 Mar 2013 01:16:29 +0000 Subject: Try eliminating the pause before auto-reteleporting for a megaregion now that we're telepoting in a different way. On my own system, I can now eliminate the pause entirely and the reteleport happens whilst the teleport screen is still up. Trying this change to see if this is true for other people. --- .../Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 764c982..495b0a0 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1348,7 +1348,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public void InformClientToInitiateTeleportToLocationAsync(ScenePresence agent, uint regionX, uint regionY, Vector3 position, Scene initiatingScene) { - Thread.Sleep(10000); +// Thread.Sleep(10000); m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Auto-reteleporting {0} to correct megaregion location {1},{2},{3} from {4}", -- cgit v1.1 From 4dfffa1df325c4b27a79e995585696cc20b6d905 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 29 Mar 2013 01:31:37 +0000 Subject: Add Location (relative), Rotation (Relative) and Rotation (World) to "show part" and other related console commands --- .../Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs index 28db407..e434b2e 100644 --- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs @@ -597,6 +597,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands cdl.AddRow("LightFalloff", s.LightFalloff); cdl.AddRow("LightIntensity", s.LightIntensity); cdl.AddRow("LightRadius", s.LightRadius); + cdl.AddRow("Location (relative)", sop.RelativePosition); cdl.AddRow("Media", string.Format("{0} entries", s.Media != null ? s.Media.Count.ToString() : "n/a")); cdl.AddRow("PathBegin", s.PathBegin); cdl.AddRow("PathEnd", s.PathEnd); @@ -619,6 +620,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands cdl.AddRow("ProjectionFocus", s.ProjectionFocus); cdl.AddRow("ProjectionFOV", s.ProjectionFOV); cdl.AddRow("ProjectionTextureUUID", s.ProjectionTextureUUID); + cdl.AddRow("Rotation (Relative)", sop.RotationOffset); + cdl.AddRow("Rotation (World)", sop.GetWorldRotation()); cdl.AddRow("Scale", s.Scale); cdl.AddRow( "SculptData", -- cgit v1.1 From e89bcf4f773d95492b168376599f7530a6044e8f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 29 Mar 2013 01:34:31 +0000 Subject: Revert "Try eliminating the pause before auto-reteleporting for a megaregion now that we're telepoting in a different way." Unfortunately fails on Nebadon's system right now. Needs investigation. May put in a temproary option for experimentation soon. This reverts commit d87ddf50fcd674fbd9aa8b8556bf57f2d285a3ba. --- .../Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 495b0a0..764c982 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1348,7 +1348,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public void InformClientToInitiateTeleportToLocationAsync(ScenePresence agent, uint regionX, uint regionY, Vector3 position, Scene initiatingScene) { -// Thread.Sleep(10000); + Thread.Sleep(10000); m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Auto-reteleporting {0} to correct megaregion location {1},{2},{3} from {4}", -- cgit v1.1 From 23ae4c0a4d813763bcc39db7693850a21727d7f2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 29 Mar 2013 02:21:38 +0000 Subject: Fix bug where CHANGED_REGION and/or CHANGED_TELEPORT weren't firing for scripts in attachments. This was because the script resumption in AttachmentsModule was firing the attach event instead. Had to reinstate the code in 285bd3a do we can resume the scripts there instead, though the bug existed before its removal. This is to resolve http://opensimulator.org/mantis/view.php?id=6578 --- .../Avatar/Attachments/AttachmentsModule.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.cs | 5 ++++- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 4 ++++ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 22 ++++++++++++++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index b7f4303..29a6478 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -328,7 +328,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (!Enabled) return false; - return AttachObjectInternal(sp, group, attachmentPt, silent, addToInventory, true, append); + return AttachObjectInternal(sp, group, attachmentPt, silent, addToInventory, false, append); } /// diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 5337835..911a3e4 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2739,7 +2739,10 @@ namespace OpenSim.Region.Framework.Scenes // "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition); RootPrim.RemFlag(PrimFlags.TemporaryOnRez); - + + // We must currently not resume scripts at this stage since AttachmentsModule does not have the + // information that this is due to a teleport/border cross rather than an ordinary attachment. + // We currently do this in Scene.MakeRootAgent() instead. if (AttachmentsModule != null) AttachmentsModule.AttachObject(sp, grp, 0, false, false, true); } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 27325c5..847df03 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3203,6 +3203,10 @@ namespace OpenSim.Region.Framework.Scenes /// public void SetScriptEvents(UUID scriptid, int events) { +// m_log.DebugFormat( +// "[SCENE OBJECT PART]: Set script events for script with id {0} on {1}/{2} to {3} in {4}", +// scriptid, Name, ParentGroup.Name, events, ParentGroup.Scene.Name); + // scriptEvents oldparts; lock (m_scriptEvents) { diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 6591fef..4930a39 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -968,6 +968,28 @@ namespace OpenSim.Region.Framework.Scenes Scene.AttachmentsModule.RezAttachments(this); }); } + else + { + // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT + // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently + // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are + // not transporting the required data. + lock (m_attachments) + { + if (HasAttachments()) + { + m_log.DebugFormat( + "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); + + // Resume scripts + foreach (SceneObjectGroup sog in m_attachments) + { + sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); + sog.ResumeScripts(); + } + } + } + } // send the animations of the other presences to me m_scene.ForEachRootScenePresence(delegate(ScenePresence presence) -- cgit v1.1 From 023faa227ef72a3701dc5fbfc46ab5f831c54953 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 29 Mar 2013 23:10:28 +0000 Subject: Check viewer 2/3 attachment calls against avatar appearance attachment data rather than actually attached objects By checking against the grid's Avatar data, we can ignore viewer side attachments but still initiate these calls simulator-side. Initiating simulator-side is always necessary for version 1 viewers. This is a further commit to resolve http://opensimulator.org/mantis/view.php?id=6581 --- .../Avatar/Attachments/AttachmentsModule.cs | 36 ++++++++++------------ .../Attachments/Tests/AttachmentsModuleTests.cs | 6 ++-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 7 ++--- 3 files changed, 23 insertions(+), 26 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 29a6478..4b53ee0 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -256,10 +256,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { // If we're an NPC then skip all the item checks and manipulations since we don't have an // inventory right now. - if (sp.PresenceType == PresenceType.Npc) - RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, true); - else - RezSingleAttachmentFromInventory(sp, attach.ItemID, p | (uint)0x80); + RezSingleAttachmentFromInventoryInternal( + sp, sp.PresenceType == PresenceType.Npc ? UUID.Zero : attach.ItemID, attach.AssetID, p | (uint)0x80); } catch (Exception e) { @@ -456,26 +454,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2} in {3}", (AttachmentPoint)AttachmentPt, itemID, sp.Name, m_scene.Name); - bool append = (AttachmentPt & 0x80) != 0; - AttachmentPt &= 0x7f; - - // Viewer 2/3 sometimes asks to re-wear items that are already worn (and show up in it's inventory as such). - // This often happens during login - not sure the exact reason. - // For now, we will ignore the request. Unfortunately, this means that we need to dig through all the - // ScenePresence attachments. We can't use the data in AvatarAppearance because that's present at login - // before anything has actually been attached. + // We check the attachments in the avatar appearance here rather than the objects attached to the + // ScenePresence itself so that we can ignore calls by viewer 2/3 to attach objects on startup. We are + // already doing this in ScenePresence.MakeRootAgent(). Simulator-side attaching needs to be done + // because pre-outfit folder viewers (most version 1 viewers) require it. bool alreadyOn = false; - List existingAttachments = sp.GetAttachments(); - foreach (SceneObjectGroup so in existingAttachments) + List existingAttachments = sp.Appearance.GetAttachments(); + foreach (AvatarAttachment existingAttachment in existingAttachments) { - if (so.FromItemID == itemID) + if (existingAttachment.ItemID == itemID) { alreadyOn = true; break; } } -// if (sp.Appearance.GetAttachmentForItem(itemID) != null) if (alreadyOn) { if (DebugLevel > 0) @@ -486,7 +479,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return null; } - return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, append); + return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt); } public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List> rezlist) @@ -495,7 +488,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return; if (DebugLevel > 0) - m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name); + m_log.DebugFormat( + "[ATTACHMENTS MODULE]: Rezzing {0} attachments from inventory for {1} in {2}", + rezlist.Count, sp.Name, m_scene.Name); foreach (KeyValuePair rez in rezlist) { @@ -894,11 +889,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( - IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, bool append) + IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt) { if (m_invAccessModule == null) return null; + bool append = (attachmentPt & 0x80) != 0; + attachmentPt &= 0x7f; + SceneObjectGroup objatt; if (itemID != UUID.Zero) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 6e4262e..25444e5 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -130,7 +130,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests config.AddConfig("Modules"); config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); - modules.Add(new AttachmentsModule()); + AttachmentsModule attMod = new AttachmentsModule(); + attMod.DebugLevel = 1; + modules.Add(attMod); modules.Add(new BasicInventoryAccessModule()); } @@ -728,7 +730,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests public void TestRezAttachmentsOnAvatarEntrance() { TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); +// TestHelpers.EnableLogging(); Scene scene = CreateTestScene(); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 4930a39..215a689 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -955,15 +955,12 @@ namespace OpenSim.Region.Framework.Scenes { // Viewers which have a current outfit folder will actually rez their own attachments. However, // viewers without (e.g. v1 viewers) will not, so we still need to make this call. - // - // However, we leave a 5 second pause to try and avoid a clash with viewers that are rezzing - // attachments themselves. This should then mean that this call ends up doing nothing. if (Scene.AttachmentsModule != null) Util.FireAndForget( o => { - if (PresenceType != PresenceType.Npc && Util.FireAndForgetMethod != FireAndForgetMethod.None) - System.Threading.Thread.Sleep(5000); +// if (PresenceType != PresenceType.Npc && Util.FireAndForgetMethod != FireAndForgetMethod.None) +// System.Threading.Thread.Sleep(7000); Scene.AttachmentsModule.RezAttachments(this); }); -- cgit v1.1 From cbc9ae898c474295567532c668644d09b698d59b Mon Sep 17 00:00:00 2001 From: Kevin Cozens Date: Wed, 27 Mar 2013 17:26:17 -0400 Subject: Added missing functionality (mainly custom headers) to llHTTPRequest. --- .../Scripting/HttpRequest/ScriptsHttpRequests.cs | 73 +++++++-- .../Region/Framework/Interfaces/IHttpRequests.cs | 3 + .../Shared/Api/Implementation/LSL_Api.cs | 169 +++++++++++++++------ .../Shared/Api/Runtime/LSL_Constants.cs | 15 +- 4 files changed, 195 insertions(+), 65 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs index a676971..c2e37c4 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs @@ -187,6 +187,45 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest case (int)HttpRequestConstants.HTTP_VERIFY_CERT: htc.HttpVerifyCert = (int.Parse(parms[i + 1]) != 0); break; + + case (int)HttpRequestConstants.HTTP_VERBOSE_THROTTLE: + + // TODO implement me + break; + + case (int)HttpRequestConstants.HTTP_CUSTOM_HEADER: + //Parameters are in pairs and custom header takes + //arguments in pairs so adjust for header marker. + ++i; + + //Maximum of 8 headers are allowed based on the + //Second Life documentation for llHTTPRequest. + for (int count = 1; count <= 8; ++count) + { + //Not enough parameters remaining for a header? + if (parms.Length - i < 2) + break; + + //Have we reached the end of the list of headers? + //End is marked by a string with a single digit. + //We already know we have at least one parameter + //so it is safe to do this check at top of loop. + if (Char.IsDigit(parms[i][0])) + break; + + if (htc.HttpCustomHeaders == null) + htc.HttpCustomHeaders = new List(); + + htc.HttpCustomHeaders.Add(parms[i]); + htc.HttpCustomHeaders.Add(parms[i+1]); + + i += 2; + } + break; + + case (int)HttpRequestConstants.HTTP_PRAGMA_NO_CACHE: + htc.HttpPragmaNoCache = (int.Parse(parms[i + 1]) != 0); + break; } } } @@ -328,9 +367,12 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest // public const int HTTP_METHOD = 0; // public const int HTTP_MIMETYPE = 1; // public const int HTTP_VERIFY_CERT = 3; + // public const int HTTP_VERBOSE_THROTTLE = 4; + // public const int HTTP_CUSTOM_HEADER = 5; + // public const int HTTP_PRAGMA_NO_CACHE = 6; private bool _finished; public bool Finished - { + { get { return _finished; } } // public int HttpBodyMaxLen = 2048; // not implemented @@ -340,11 +382,14 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest public string HttpMIMEType = "text/plain;charset=utf-8"; public int HttpTimeout; public bool HttpVerifyCert = true; + //public bool HttpVerboseThrottle = true; // not implemented + public List HttpCustomHeaders = null; + public bool HttpPragmaNoCache = true; private Thread httpThread; // Request info private UUID _itemID; - public UUID ItemID + public UUID ItemID { get { return _itemID; } set { _itemID = value; } @@ -360,7 +405,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest public string proxyexcepts; public string OutboundBody; private UUID _reqID; - public UUID ReqID + public UUID ReqID { get { return _reqID; } set { _reqID = value; } @@ -401,7 +446,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest Request.Method = HttpMethod; Request.ContentType = HttpMIMEType; - if(!HttpVerifyCert) + if (!HttpVerifyCert) { // We could hijack Connection Group Name to identify // a desired security exception. But at the moment we'll use a dummy header instead. @@ -412,14 +457,24 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest // { // Request.ConnectionGroupName="Verify"; // } - if (proxyurl != null && proxyurl.Length > 0) + if (!HttpPragmaNoCache) + { + Request.Headers.Add("Pragma", "no-cache"); + } + if (HttpCustomHeaders != null) { - if (proxyexcepts != null && proxyexcepts.Length > 0) + for (int i = 0; i < HttpCustomHeaders.Count; i += 2) + Request.Headers.Add(HttpCustomHeaders[i], + HttpCustomHeaders[i+1]); + } + if (proxyurl != null && proxyurl.Length > 0) + { + if (proxyexcepts != null && proxyexcepts.Length > 0) { string[] elist = proxyexcepts.Split(';'); Request.Proxy = new WebProxy(proxyurl, true, elist); - } - else + } + else { Request.Proxy = new WebProxy(proxyurl, true); } @@ -432,7 +487,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest Request.Headers[entry.Key] = entry.Value; // Encode outbound data - if (OutboundBody.Length > 0) + if (OutboundBody.Length > 0) { byte[] data = Util.UTF8.GetBytes(OutboundBody); diff --git a/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs b/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs index de0f2a3..eb6c5ac 100644 --- a/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs +++ b/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs @@ -36,6 +36,9 @@ namespace OpenSim.Region.Framework.Interfaces HTTP_MIMETYPE = 1, HTTP_BODY_MAXLENGTH = 2, HTTP_VERIFY_CERT = 3, + HTTP_VERBOSE_THROTTLE = 4, + HTTP_CUSTOM_HEADER = 5, + HTTP_PRAGMA_NO_CACHE = 6 } public interface IHttpRequestModule diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index bf84b16..969243c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -67,6 +67,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; using System.Reflection; +using System.Linq; using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.ScriptEngine.Shared.Api @@ -92,8 +93,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// /// Used for script sleeps when we are using co-operative script termination. /// - /// null if co-operative script termination is not active - WaitHandle m_coopSleepHandle; + /// null if co-operative script termination is not active + WaitHandle m_coopSleepHandle; /// /// The item that hosts this script @@ -119,6 +120,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. protected ISoundModule m_SoundModule = null; + //An array of HTTP/1.1 headers that are not allowed to be used + //as custom headers by llHTTPRequest. + private string[] HttpStandardHeaders = + { + "Accept", "Accept-Charset", "Accept-Encoding", "Accept-Language", + "Accept-Ranges", "Age", "Allow", "Authorization", "Cache-Control", + "Connection", "Content-Encoding", "Content-Language", + "Content-Length", "Content-Location", "Content-MD5", + "Content-Range", "Content-Type", "Date", "ETag", "Expect", + "Expires", "From", "Host", "If-Match", "If-Modified-Since", + "If-None-Match", "If-Range", "If-Unmodified-Since", "Last-Modified", + "Location", "Max-Forwards", "Pragma", "Proxy-Authenticate", + "Proxy-Authorization", "Range", "Referer", "Retry-After", "Server", + "TE", "Trailer", "Transfer-Encoding", "Upgrade", "User-Agent", + "Vary", "Via", "Warning", "WWW-Authenticate" + }; + public void Initialize( IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) { @@ -303,7 +321,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// If the linkset has more than one entity and a linknum greater than zero but equal to or less than the number /// of entities, then the entity which corresponds to that linknum is returned. /// Otherwise, if a positive linknum is given which is greater than the number of entities in the linkset, then - /// null is returned. + /// null is returned. /// public ISceneEntity GetLinkEntity(int linknum) { @@ -1557,7 +1575,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (tex.FaceTextures[i] != null) { tex.FaceTextures[i].Shiny = sval; - tex.FaceTextures[i].Bump = bump;; + tex.FaceTextures[i].Bump = bump; } tex.DefaultTexture.Shiny = sval; tex.DefaultTexture.Bump = bump; @@ -1666,7 +1684,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f); tex.DefaultTexture.RGBA = texcolor; } - + part.UpdateTextureEntry(tex.GetBytes()); return; } @@ -1787,7 +1805,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api rgb.x = texcolor.R; rgb.y = texcolor.G; rgb.z = texcolor.B; - + return rgb; } else @@ -1819,12 +1837,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { UUID textureID = new UUID(); - textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture); - if (textureID == UUID.Zero) - { - if (!UUID.TryParse(texture, out textureID)) - return; - } + textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture); + if (textureID == UUID.Zero) + { + if (!UUID.TryParse(texture, out textureID)) + return; + } Primitive.TextureEntry tex = part.Shape.Textures; @@ -2021,7 +2039,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // IF YOU GET REGION CROSSINGS WORKING WITH THIS FUNCTION, REPLACE THE WORKAROUND. // // This workaround is to prevent silent failure of this function. - // According to the specification on the SL Wiki, providing a position outside of the + // According to the specification on the SL Wiki, providing a position outside of the if (pos.x < 0 || pos.x > Constants.RegionSize || pos.y < 0 || pos.y > Constants.RegionSize) { return 0; @@ -2230,7 +2248,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { return llGetRootRotation(); } - + m_host.AddScriptLPS(1); Quaternion q = m_host.GetWorldRotation(); return new LSL_Rotation(q.X, q.Y, q.Z, q.W); @@ -2919,7 +2937,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // we need to convert from a vector describing // the angles of rotation in radians into rotation value LSL_Rotation rot = llEuler2Rot(angle); - + // Per discussion with Melanie, for non-physical objects llLookAt appears to simply // set the rotation of the object, copy that behavior PhysicsActor pa = m_host.PhysActor; @@ -2996,7 +3014,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!UUID.TryParse(id, out objectID)) objectID = UUID.Zero; - + if (objectID == UUID.Zero && name == "") return; @@ -3182,19 +3200,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; Vector3 pos = m_host.AbsolutePosition; - msg.binaryBucket + msg.binaryBucket = Util.StringToBytes256( - "{0}/{1}/{2}/{3}", - World.RegionInfo.RegionName, - (int)Math.Floor(pos.X), - (int)Math.Floor(pos.Y), + "{0}/{1}/{2}/{3}", + World.RegionInfo.RegionName, + (int)Math.Floor(pos.X), + (int)Math.Floor(pos.Y), (int)Math.Floor(pos.Z)); if (m_TransferModule != null) { m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); } - + ScriptSleep(2000); } @@ -3319,7 +3337,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llRotLookAt(LSL_Rotation target, double strength, double damping) { m_host.AddScriptLPS(1); - + // Per discussion with Melanie, for non-physical objects llLookAt appears to simply // set the rotation of the object, copy that behavior PhysicsActor pa = m_host.PhysActor; @@ -4313,7 +4331,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llCollisionSound(string impact_sound, double impact_volume) { m_host.AddScriptLPS(1); - + // TODO: Parameter check logic required. m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound); m_host.CollisionSoundVolume = (float)impact_volume; @@ -5008,7 +5026,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // SL spits out an empty string for types other than key & string // At the time of patching, LSL_Key is currently LSL_String, // so the OR check may be a little redundant, but it's being done - // for completion and should LSL_Key ever be implemented + // for completion and should LSL_Key ever be implemented // as it's own struct else if (!(src.Data[index] is LSL_String || src.Data[index] is LSL_Key)) @@ -5144,8 +5162,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - return string.Join(", ", - (new List(src.Data)).ConvertAll(o => + return string.Join(", ", + (new List(src.Data)).ConvertAll(o => { return o.ToString(); }).ToArray()); @@ -6188,7 +6206,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api SetParticleSystem(m_host, rules); } - private void SetParticleSystem(SceneObjectPart part, LSL_List rules) + private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { if (rules.Length == 0) { @@ -6425,7 +6443,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.OwnerID, m_host.Name, destID, (byte)InstantMessageDialog.TaskInventoryOffered, false, string.Format("'{0}'", category), -// We won't go so far as to add a SLURL, but this is the format used by LL as of 2012-10-06 +// We won't go so far as to add a SLURL, but this is the format used by LL as of 2012-10-06 // false, string.Format("'{0}' ( http://slurl.com/secondlife/{1}/{2}/{3}/{4} )", category, World.Name, (int)pos.X, (int)pos.Y, (int)pos.Z), folderID, false, pos, bucket, false); @@ -6540,12 +6558,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_String llAvatarOnLinkSitTarget(int linknum) { m_host.AddScriptLPS(1); - if(linknum == ScriptBaseClass.LINK_SET || + if(linknum == ScriptBaseClass.LINK_SET || linknum == ScriptBaseClass.LINK_ALL_CHILDREN || linknum == ScriptBaseClass.LINK_ALL_OTHERS) return UUID.Zero.ToString(); - + List parts = GetLinkParts(linknum); - if (parts.Count == 0) return UUID.Zero.ToString(); + if (parts.Count == 0) return UUID.Zero.ToString(); return parts[0].SitTargetAvatar.ToString(); } @@ -6922,7 +6940,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api hollow = 0.70f; } } - // Otherwise, hollow is limited to 95%. + // Otherwise, hollow is limited to 95%. else { if (hollow > 0.95f) @@ -7956,8 +7974,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api LSL_List remaining = null; while (true) - { - if (entity is SceneObjectPart) + { + if (entity is SceneObjectPart) remaining = GetPrimParams((SceneObjectPart)entity, rules, ref result); else remaining = GetAgentParams((ScenePresence)entity, rules, ref result); @@ -8138,7 +8156,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api res.Add(new LSL_Float(1)); break; - case (int)ScriptBaseClass.PRIM_ROT_LOCAL: + case (int)ScriptBaseClass.PRIM_ROT_LOCAL: res.Add(new LSL_Rotation(sp.Rotation)); break; @@ -8282,16 +8300,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0)); // float revolutions - res.Add(new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d); + res.Add(new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d); // Slightly inaccurate, because an unsigned byte is being used to represent - // the entire range of floating-point values from 1.0 through 4.0 (which is how + // the entire range of floating-point values from 1.0 through 4.0 (which is how // SL does it). // - // Using these formulas to store and retrieve PathRevolutions, it is not - // possible to use all values between 1.00 and 4.00. For instance, you can't + // Using these formulas to store and retrieve PathRevolutions, it is not + // possible to use all values between 1.00 and 4.00. For instance, you can't // represent 1.10. You can represent 1.09 and 1.11, but not 1.10. So, if you // use llSetPrimitiveParams to set revolutions to 1.10 and then retreive them - // with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar + // with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar // behavior in the viewer as you cannot set 1.10. The viewer jumps to 1.11. // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value // such as 1.10. So, SL must store and retreive the actual user input rather @@ -8528,7 +8546,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api case (int)ScriptBaseClass.PRIM_DESC: res.Add(new LSL_String(part.Description)); break; - case (int)ScriptBaseClass.PRIM_ROT_LOCAL: + case (int)ScriptBaseClass.PRIM_ROT_LOCAL: res.Add(new LSL_Rotation(part.RotationOffset)); break; case (int)ScriptBaseClass.PRIM_POS_LOCAL: @@ -10415,9 +10433,60 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api IHttpRequestModule httpScriptMod = m_ScriptEngine.World.RequestModuleInterface(); List param = new List(); - foreach (object o in parameters.Data) + bool ok; + Int32 flag; + + for (int i = 0; i < parameters.Data.Length; i += 2) { - param.Add(o.ToString()); + ok = Int32.TryParse(parameters.Data[i].ToString(), out flag); + if (!ok || flag < 0 || + flag > (int)HttpRequestConstants.HTTP_PRAGMA_NO_CACHE) + { + throw new ScriptException("Parameter " + i.ToString() + " is an invalid flag"); + } + + param.Add(parameters.Data[i].ToString()); //Add parameter flag + + if (flag != (int)HttpRequestConstants.HTTP_CUSTOM_HEADER) + { + param.Add(parameters.Data[i+1].ToString()); //Add parameter value + } + else + { + //Parameters are in pairs and custom header takes + //arguments in pairs so adjust for header marker. + ++i; + + //Maximum of 8 headers are allowed based on the + //Second Life documentation for llHTTPRequest. + for (int count = 1; count <= 8; ++count) + { + //Enough parameters remaining for (another) header? + if (parameters.Data.Length - i < 2) + { + //There must be at least one name/value pair for custom header + if (count == 1) + throw new ScriptException("Missing name/value for custom header at parameter " + i.ToString()); + break; + } + + if (HttpStandardHeaders.Contains(parameters.Data[i].ToString(), StringComparer.OrdinalIgnoreCase)) + throw new ScriptException("Name is invalid as a custom header at parameter " + i.ToString()); + + param.Add(parameters.Data[i].ToString()); + param.Add(parameters.Data[i+1].ToString()); + + //Have we reached the end of the list of headers? + //End is marked by a string with a single digit. + if (i+2 >= parameters.Data.Length || + Char.IsDigit(parameters.Data[i].ToString()[0])) + { + break; + } + + i += 2; + } + } } Vector3 position = m_host.AbsolutePosition; @@ -10527,12 +10596,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide) { m_host.AddScriptLPS(1); - + ILandObject lo = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y); if (lo == null) return 0; - + IPrimCounts pc = lo.PrimCounts; if (sim_wide != ScriptBaseClass.FALSE) @@ -10562,7 +10631,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api else if (category == ScriptBaseClass.PARCEL_COUNT_TEMP) return 0; // counts not implemented yet } - + return 0; } @@ -10905,7 +10974,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return ret; } } - + return new LSL_List(); } @@ -11282,7 +11351,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // Vector3 bc = group.AbsolutePosition - rayEnd; double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); - + // Too far off ray, don't bother if (d > radius) return; @@ -11611,7 +11680,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api else { ScenePresence sp = World.GetScenePresence(result.ConsumerID); - /// It it a boy? a girl? + /// It it a boy? a girl? if (sp != null) itemID = sp.UUID; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index bd66ba3..dc5ef13 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -355,6 +355,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int HTTP_MIMETYPE = 1; public const int HTTP_BODY_MAXLENGTH = 2; public const int HTTP_VERIFY_CERT = 3; + public const int HTTP_VERBOSE_THROTTLE = 4; + public const int HTTP_CUSTOM_HEADER = 5; + public const int HTTP_PRAGMA_NO_CACHE = 6; public const int PRIM_MATERIAL = 2; public const int PRIM_PHYSICS = 3; @@ -635,7 +638,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int TOUCH_INVALID_FACE = -1; public static readonly vector TOUCH_INVALID_TEXCOORD = new vector(-1.0, -1.0, 0.0); public static readonly vector TOUCH_INVALID_VECTOR = ZERO_VECTOR; - + // constants for llGetPrimMediaParams/llSetPrimMediaParams public const int PRIM_MEDIA_ALT_IMAGE_ENABLE = 0; public const int PRIM_MEDIA_CONTROLS = 1; @@ -652,15 +655,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int PRIM_MEDIA_WHITELIST = 12; public const int PRIM_MEDIA_PERMS_INTERACT = 13; public const int PRIM_MEDIA_PERMS_CONTROL = 14; - + public const int PRIM_MEDIA_CONTROLS_STANDARD = 0; public const int PRIM_MEDIA_CONTROLS_MINI = 1; - + public const int PRIM_MEDIA_PERM_NONE = 0; public const int PRIM_MEDIA_PERM_OWNER = 1; public const int PRIM_MEDIA_PERM_GROUP = 2; public const int PRIM_MEDIA_PERM_ANYONE = 4; - + public const int PRIM_PHYSICS_SHAPE_TYPE = 30; public const int PRIM_PHYSICS_SHAPE_PRIM = 0; public const int PRIM_PHYSICS_SHAPE_CONVEX = 2; @@ -688,7 +691,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const string TEXTURE_PLYWOOD = "89556747-24cb-43ed-920b-47caed15465f"; public const string TEXTURE_TRANSPARENT = "8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"; public const string TEXTURE_MEDIA = "8b5fec65-8d8d-9dc5-cda8-8fdf2716e361"; - + // Constants for osGetRegionStats public const int STATS_TIME_DILATION = 0; public const int STATS_SIM_FPS = 1; @@ -741,7 +744,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public static readonly LSLInteger RC_GET_ROOT_KEY = 2; public static readonly LSLInteger RC_GET_LINK_NUM = 4; - public static readonly LSLInteger RCERR_UNKNOWN = -1; + public static readonly LSLInteger RCERR_UNKNOWN = -1; public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; -- cgit v1.1 From 76629289f001ef4bd0bac204e0f46907ebe5df5e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 29 Mar 2013 23:59:21 +0000 Subject: refactor: move the append magic number processing for attachments back up into RezSingleAttachmentFromInventory from RezSingleAttachmentFromInventoryInternal() done in commit 023faa2 --- .../CoreModules/Avatar/Attachments/AttachmentsModule.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 4b53ee0..eec7ee5 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -257,7 +257,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // If we're an NPC then skip all the item checks and manipulations since we don't have an // inventory right now. RezSingleAttachmentFromInventoryInternal( - sp, sp.PresenceType == PresenceType.Npc ? UUID.Zero : attach.ItemID, attach.AssetID, p | (uint)0x80); + sp, sp.PresenceType == PresenceType.Npc ? UUID.Zero : attach.ItemID, attach.AssetID, p, true); } catch (Exception e) { @@ -479,7 +479,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return null; } - return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt); + bool append = (AttachmentPt & 0x80) != 0; + AttachmentPt &= 0x7f; + + return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, append); } public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List> rezlist) @@ -889,14 +892,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( - IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt) + IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, bool append) { if (m_invAccessModule == null) return null; - bool append = (attachmentPt & 0x80) != 0; - attachmentPt &= 0x7f; - SceneObjectGroup objatt; if (itemID != UUID.Zero) -- cgit v1.1 From f8785b5f4720a0da7993ce6014e46cb8aaad308a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 30 Mar 2013 00:29:52 +0000 Subject: refactor: rename ETM.InformClientToInitateTeleportToLocationDelegate to InformClientToInitiateTeleportToLocationDelegate to correct spelling and bring into line with other ETM Initiate methods --- .../Framework/EntityTransfer/EntityTransferModule.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 764c982..3e69bf2 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1159,7 +1159,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; agent.ControllingClient.SendAgentAlertMessage( String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); - InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); + InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); return true; } } @@ -1182,7 +1182,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; agent.ControllingClient.SendAgentAlertMessage( String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); - InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); + InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); return true; } @@ -1213,7 +1213,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; agent.ControllingClient.SendAgentAlertMessage( String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); - InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); + InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); return true; } } @@ -1243,7 +1243,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; agent.ControllingClient.SendAgentAlertMessage( String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); - InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); + InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); return true; } } @@ -1330,16 +1330,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } - public delegate void InformClientToInitateTeleportToLocationDelegate(ScenePresence agent, uint regionX, uint regionY, + public delegate void InformClientToInitiateTeleportToLocationDelegate(ScenePresence agent, uint regionX, uint regionY, Vector3 position, Scene initiatingScene); - private void InformClientToInitateTeleportToLocation(ScenePresence agent, uint regionX, uint regionY, Vector3 position, Scene initiatingScene) + private void InformClientToInitiateTeleportToLocation(ScenePresence agent, uint regionX, uint regionY, Vector3 position, Scene initiatingScene) { // This assumes that we know what our neighbours are. - InformClientToInitateTeleportToLocationDelegate d = InformClientToInitiateTeleportToLocationAsync; + InformClientToInitiateTeleportToLocationDelegate d = InformClientToInitiateTeleportToLocationAsync; d.BeginInvoke(agent, regionX, regionY, position, initiatingScene, InformClientToInitiateTeleportToLocationCompleted, d); @@ -1401,8 +1401,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer private void InformClientToInitiateTeleportToLocationCompleted(IAsyncResult iar) { - InformClientToInitateTeleportToLocationDelegate icon = - (InformClientToInitateTeleportToLocationDelegate)iar.AsyncState; + InformClientToInitiateTeleportToLocationDelegate icon = + (InformClientToInitiateTeleportToLocationDelegate)iar.AsyncState; icon.EndInvoke(iar); } -- cgit v1.1 From 9fee431cc8a054dd4d6b20392cbefd0a0f8343f1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 30 Mar 2013 01:21:16 +0000 Subject: In the flotasm asset cache, if we get a request for a file that we're actively writing, simply return null instead of first logging an exception. --- .../Region/CoreModules/Asset/FlotsamAssetCache.cs | 52 +++++++++++----------- 1 file changed, 27 insertions(+), 25 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index 3cba9b4..2afe065 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -341,11 +341,35 @@ namespace OpenSim.Region.CoreModules.Asset /// /// An asset retrieved from the file cache. null if there was a problem retrieving an asset. private AssetBase GetFromFileCache(string id) - { - AssetBase asset = null; - + { string filename = GetFileName(id); +#if WAIT_ON_INPROGRESS_REQUESTS + // Check if we're already downloading this asset. If so, try to wait for it to + // download. + if (m_WaitOnInprogressTimeout > 0) + { + m_RequestsForInprogress++; + + ManualResetEvent waitEvent; + if (m_CurrentlyWriting.TryGetValue(filename, out waitEvent)) + { + waitEvent.WaitOne(m_WaitOnInprogressTimeout); + return Get(id); + } + } +#else + // Track how often we have the problem that an asset is requested while + // it is still being downloaded by a previous request. + if (m_CurrentlyWriting.Contains(filename)) + { + m_RequestsForInprogress++; + return null; + } +#endif + + AssetBase asset = null; + if (File.Exists(filename)) { FileStream stream = null; @@ -383,28 +407,6 @@ namespace OpenSim.Region.CoreModules.Asset } } -#if WAIT_ON_INPROGRESS_REQUESTS - // Check if we're already downloading this asset. If so, try to wait for it to - // download. - if (m_WaitOnInprogressTimeout > 0) - { - m_RequestsForInprogress++; - - ManualResetEvent waitEvent; - if (m_CurrentlyWriting.TryGetValue(filename, out waitEvent)) - { - waitEvent.WaitOne(m_WaitOnInprogressTimeout); - return Get(id); - } - } -#else - // Track how often we have the problem that an asset is requested while - // it is still being downloaded by a previous request. - if (m_CurrentlyWriting.Contains(filename)) - { - m_RequestsForInprogress++; - } -#endif return asset; } -- cgit v1.1 From 4bf9c4bbb833f8ecbd0757b333da76ffaea14bc7 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 31 Mar 2013 20:25:32 +0200 Subject: Export permission, part two. Setting export perms for textures and clothing works. Setting perms for prims also works but they don't propagate correctly yet. NOT FOR PRODUCTIN USE. Your database will need to be updated before you can use this! --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 46 ++++++++++++++++++++-- .../Region/Framework/Scenes/SceneObjectGroup.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 29 ++++++++++---- 3 files changed, 66 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 6a3fb24..d2e41f8 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -413,18 +413,57 @@ namespace OpenSim.Region.Framework.Scenes if (itemUpd.NextPermissions != 0) // Use this to determine validity. Can never be 0 if valid { + // Create a set of base permissions that will not include export if the user + // is not allowed to change the export flag. + bool denyExportChange = false; + + m_log.InfoFormat("[XXX]: B: {0} O: {1} E: {2}", itemUpd.BasePermissions, itemUpd.CurrentPermissions, itemUpd.EveryOnePermissions); + + // If the user is not the creator or doesn't have "E" in both "B" and "O", deny setting export + if ((item.BasePermissions & (uint)(PermissionMask.All | PermissionMask.Export)) != (uint)(PermissionMask.All | PermissionMask.Export) || (item.CurrentPermissions & (uint)PermissionMask.Export) == 0 || item.CreatorIdAsUuid != item.Owner) + denyExportChange = true; + + m_log.InfoFormat("[XXX]: Deny Export Update {0}", denyExportChange); + + // If it is already set, force it set and also force full perm + // else prevent setting it. It can and should never be set unless + // set in base, so the condition above is valid + if (denyExportChange) + { + // If we are not allowed to change it, then force it to the + // original item's setting and if it was on, also force full perm + if ((item.EveryOnePermissions & (uint)PermissionMask.Export) != 0) + { + itemUpd.NextPermissions = (uint)(PermissionMask.All); + itemUpd.EveryOnePermissions |= (uint)PermissionMask.Export; + } + else + { + itemUpd.EveryOnePermissions &= ~(uint)PermissionMask.Export; + } + } + else + { + // If the new state is exportable, force full perm + if ((itemUpd.EveryOnePermissions & (uint)PermissionMask.Export) != 0) + { + m_log.InfoFormat("[XXX]: Force full perm"); + itemUpd.NextPermissions = (uint)(PermissionMask.All); + } + } + if (item.NextPermissions != (itemUpd.NextPermissions & item.BasePermissions)) item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner; item.NextPermissions = itemUpd.NextPermissions & item.BasePermissions; + if (item.EveryOnePermissions != (itemUpd.EveryOnePermissions & item.BasePermissions)) item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteEveryone; item.EveryOnePermissions = itemUpd.EveryOnePermissions & item.BasePermissions; + if (item.GroupPermissions != (itemUpd.GroupPermissions & item.BasePermissions)) item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteGroup; - -// m_log.DebugFormat("[USER INVENTORY]: item.Flags {0}", item.Flags); - item.GroupPermissions = itemUpd.GroupPermissions & item.BasePermissions; + item.GroupID = itemUpd.GroupID; item.GroupOwned = itemUpd.GroupOwned; item.CreationDate = itemUpd.CreationDate; @@ -446,6 +485,7 @@ namespace OpenSim.Region.Framework.Scenes item.SaleType = itemUpd.SaleType; InventoryService.UpdateItem(item); + remoteClient.SendBulkUpdateInventory(item); } if (UUID.Zero != transactionID) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index b109b4f..69fb6df 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3468,7 +3468,7 @@ namespace OpenSim.Region.Framework.Scenes public void AdjustChildPrimPermissions() { - uint newOwnerMask = (uint)PermissionMask.All & 0xfffffff8; // Mask folded bits + uint newOwnerMask = (uint)(PermissionMask.All | PermissionMask.Export) & 0xfffffff8; // Mask folded bits uint foldedPerms = RootPart.OwnerMask & 3; ForEachPart(part => diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 9265805..c2f0792 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -470,8 +470,8 @@ namespace OpenSim.Region.Framework.Scenes private uint _category; private Int32 _creationDate; private uint _parentID = 0; - private uint _baseMask = (uint)PermissionMask.All; - private uint _ownerMask = (uint)PermissionMask.All; + private uint _baseMask = (uint)(PermissionMask.All | PermissionMask.Export); + private uint _ownerMask = (uint)(PermissionMask.All | PermissionMask.Export); private uint _groupMask = (uint)PermissionMask.None; private uint _everyoneMask = (uint)PermissionMask.None; private uint _nextOwnerMask = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer); @@ -4319,10 +4319,10 @@ namespace OpenSim.Region.Framework.Scenes public void TrimPermissions() { - BaseMask &= (uint)PermissionMask.All; - OwnerMask &= (uint)PermissionMask.All; + BaseMask &= (uint)(PermissionMask.All | PermissionMask.Export); + OwnerMask &= (uint)(PermissionMask.All | PermissionMask.Export); GroupMask &= (uint)PermissionMask.All; - EveryoneMask &= (uint)PermissionMask.All; + EveryoneMask &= (uint)(PermissionMask.All | PermissionMask.Export); NextOwnerMask &= (uint)PermissionMask.All; } @@ -4425,10 +4425,22 @@ namespace OpenSim.Region.Framework.Scenes baseMask; break; case 8: + // Trying to set export permissions - extra checks + if (set && (mask & (uint)PermissionMask.Export) != 0) + { + if ((OwnerMask & (uint)PermissionMask.Export) == 0 || (BaseMask & (uint)PermissionMask.Export) == 0 || (NextOwnerMask & (uint)PermissionMask.All) != (uint)PermissionMask.All) + mask &= ~(uint)PermissionMask.Export; + } EveryoneMask = ApplyMask(EveryoneMask, set, mask) & baseMask; break; case 16: + // Force full perm if export + if ((EveryoneMask & (uint)PermissionMask.Export) != 0) + { + NextOwnerMask = (uint)PermissionMask.All; + break; + } NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) & baseMask; // Prevent the client from creating no copy, no transfer @@ -5225,9 +5237,12 @@ namespace OpenSim.Region.Framework.Scenes public void ApplyNextOwnerPermissions() { - BaseMask &= NextOwnerMask; + // Export needs to be preserved in the base and everyone + // mask, but removed in the owner mask as a next owner + // can never change the export status + BaseMask &= NextOwnerMask | (uint)PermissionMask.Export; OwnerMask &= NextOwnerMask; - EveryoneMask &= NextOwnerMask; + EveryoneMask &= NextOwnerMask | (uint)PermissionMask.Export; Inventory.ApplyNextOwnerPermissions(); } -- cgit v1.1 From 6571e7ead276027e5ed86cb1fc9d1b47ddae2e6e Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 22 Apr 2013 22:24:41 +0200 Subject: Allow callers to set the invoice parameter for GenericMessage --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 14 ++++++++++++-- .../CoreModules/World/LightShare/LightShareModule.cs | 4 ++-- .../Agent/InternetRelayClientView/Server/IRCClientView.cs | 4 ++-- OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs | 4 ++-- 4 files changed, 18 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index f8b9352..4979be8 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -903,9 +903,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - public void SendGenericMessage(string method, List message) + public void SendGenericMessage(string method, UUID invoice, List message) { GenericMessagePacket gmp = new GenericMessagePacket(); + + gmp.AgentData.AgentID = AgentId; + gmp.AgentData.SessionID = m_sessionId; + gmp.AgentData.TransactionID = invoice; + gmp.MethodData.Method = Util.StringToBytes256(method); gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count]; int i = 0; @@ -918,9 +923,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(gmp, ThrottleOutPacketType.Task); } - public void SendGenericMessage(string method, List message) + public void SendGenericMessage(string method, UUID invoice, List message) { GenericMessagePacket gmp = new GenericMessagePacket(); + + gmp.AgentData.AgentID = AgentId; + gmp.AgentData.SessionID = m_sessionId; + gmp.AgentData.TransactionID = invoice; + gmp.MethodData.Method = Util.StringToBytes256(method); gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count]; int i = 0; diff --git a/OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs b/OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs index 6f92ef6..f13d648 100644 --- a/OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs +++ b/OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs @@ -198,12 +198,12 @@ namespace OpenSim.Region.CoreModules.World.LightShare if (m_scene.RegionInfo.WindlightSettings.valid) { List param = compileWindlightSettings(wl); - client.SendGenericMessage("Windlight", param); + client.SendGenericMessage("Windlight", UUID.Random(), param); } else { List param = new List(); - client.SendGenericMessage("WindlightReset", param); + client.SendGenericMessage("WindlightReset", UUID.Random(), param); } } } diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 5ac4e27..686c605 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -976,12 +976,12 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server // TODO } - public void SendGenericMessage(string method, List message) + public void SendGenericMessage(string method, UUID invoice, List message) { } - public void SendGenericMessage(string method, List message) + public void SendGenericMessage(string method, UUID invoice, List message) { } diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index d665126..7918c22 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -630,12 +630,12 @@ namespace OpenSim.Region.OptionalModules.World.NPC } - public void SendGenericMessage(string method, List message) + public void SendGenericMessage(string method, UUID invoice, List message) { } - public void SendGenericMessage(string method, List message) + public void SendGenericMessage(string method, UUID invoice, List message) { } -- cgit v1.1 From 51e05dcb5be80bc93061443072fd5587f83052e6 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 25 Apr 2013 01:37:18 +0200 Subject: Gods module cleanup --- OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs index 9fa9be1..d2e71a7 100644 --- a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs @@ -67,9 +67,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods protected Scene m_scene; protected IDialogModule m_dialogModule; - protected Dictionary m_capsDict = - new Dictionary(); - protected IDialogModule DialogModule { get @@ -91,7 +88,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods m_scene.RegisterModuleInterface(this); m_scene.EventManager.OnNewClient += SubscribeToClientEvents; m_scene.EventManager.OnRegisterCaps += OnRegisterCaps; - m_scene.EventManager.OnClientClosed += OnClientClosed; scene.EventManager.OnIncomingInstantMessage += OnIncomingInstantMessage; } @@ -127,15 +123,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods client.OnRequestGodlikePowers -= RequestGodlikePowers; } - private void OnClientClosed(UUID agentID, Scene scene) - { - m_capsDict.Remove(agentID); - } - private void OnRegisterCaps(UUID agentID, Caps caps) { string uri = "/CAPS/" + UUID.Random(); - m_capsDict[agentID] = uri; caps.RegisterHandler("UntrustedSimulatorMessage", new RestStreamHandler("POST", uri, -- cgit v1.1 From e39156c6569b10d48b0005b271f103387e16f527 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 25 Apr 2013 01:38:21 +0200 Subject: Send 503 when throttling textures --- .../ClientStack/Linden/Caps/GetTextureModule.cs | 34 +++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs index d4dbfb9..a42c96c 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs @@ -56,6 +56,7 @@ namespace OpenSim.Region.ClientStack.Linden public PollServiceTextureEventArgs thepoll; public UUID reqID; public Hashtable request; + public bool send503; } public class aPollResponse @@ -244,7 +245,19 @@ namespace OpenSim.Region.ClientStack.Linden reqinfo.thepoll = this; reqinfo.reqID = x; reqinfo.request = y; + reqinfo.send503 = false; + lock (responses) + { + if (responses.Count > 0) + { + if (m_queue.Count >= 4) + { + // Never allow more than 4 fetches to wait + reqinfo.send503 = true; + } + } + } m_queue.Enqueue(reqinfo); }; @@ -276,6 +289,22 @@ namespace OpenSim.Region.ClientStack.Linden UUID requestID = requestinfo.reqID; + if (requestinfo.send503) + { + response = new Hashtable(); + + response["int_response_code"] = 503; + response["str_response_string"] = "Throttled"; + response["content_type"] = "text/plain"; + response["keepalive"] = false; + response["reusecontext"] = false; + + lock (responses) + responses[requestID] = new aPollResponse() {bytes = 0, response = response}; + + return; + } + // If the avatar is gone, don't bother to get the texture if (m_scene.GetScenePresence(Id) == null) { @@ -385,6 +414,9 @@ namespace OpenSim.Region.ClientStack.Linden GetTextureModule.aPollResponse response; if (responses.TryGetValue(key, out response)) { + // This is any error response + if (response.bytes == 0) + return true; // Normal if (BytesSent + response.bytes <= ThrottleBytes) @@ -411,12 +443,12 @@ namespace OpenSim.Region.ClientStack.Linden return haskey; } + public void ProcessTime() { PassTime(); } - private void PassTime() { currenttime = Util.EnvironmentTickCount(); -- cgit v1.1 From 3934b779b811cc0c6331127f03212d9bbcdc2ce9 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 25 Apr 2013 01:39:22 +0200 Subject: Adding the dynamic menu module which allows registering new menu options in compliant viewers --- .../Framework/Interfaces/IDynamicMenuModule.cs | 57 +++++ .../ViewerSupport/DynamicMenuModule.cs | 282 +++++++++++++++++++++ 2 files changed, 339 insertions(+) create mode 100644 OpenSim/Region/Framework/Interfaces/IDynamicMenuModule.cs create mode 100644 OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Interfaces/IDynamicMenuModule.cs b/OpenSim/Region/Framework/Interfaces/IDynamicMenuModule.cs new file mode 100644 index 0000000..08b71e4 --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IDynamicMenuModule.cs @@ -0,0 +1,57 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System.Collections.Generic; +using OpenMetaverse; +using OpenSim.Framework; + +namespace OpenSim.Region.Framework.Interfaces +{ + public enum InsertLocation : int + { + Agent = 1, + World = 2, + Tools = 3, + Advanced = 4, + Admin = 5 + } + + public enum UserMode : int + { + Normal = 0, + God = 3 + } + + public delegate void CustomMenuHandler(string action, UUID agentID, List selection); + + public interface IDynamicMenuModule + { + void AddMenuItem(UUID agentID, string title, InsertLocation location, UserMode mode, CustomMenuHandler handler); + void AddMenuItem(string title, InsertLocation location, UserMode mode, CustomMenuHandler handler); + void RemoveMenuItem(string action); + } +} diff --git a/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs new file mode 100644 index 0000000..917911f --- /dev/null +++ b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs @@ -0,0 +1,282 @@ +// ****************************************************************** +// Copyright (c) 2008, 2009 Melanie Thielker +// +// All rights reserved +// + +using System; +using System.IO; +using System.Reflection; +using System.Text; +using System.Collections.Generic; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenSim; +using OpenSim.Region; +using OpenSim.Region.Framework; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Framework; +//using OpenSim.Framework.Capabilities; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Servers.HttpServer; +using Nini.Config; +using log4net; +using Mono.Addins; +using Caps = OpenSim.Framework.Capabilities.Caps; +using OSDMap = OpenMetaverse.StructuredData.OSDMap; + +namespace OpenSim.Region.OptionalModules.ViewerSupport +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DynamicMenu")] + public class DynamicMenuModule : INonSharedRegionModule, IDynamicMenuModule + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private class MenuItemData + { + public string Title; + public UUID AgentID; + public InsertLocation Location; + public UserMode Mode; + public CustomMenuHandler Handler; + } + + private Dictionary> m_menuItems = + new Dictionary>(); + + private Scene m_scene; + + public string Name + { + get { return "DynamicMenuModule"; } + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void Initialise(IConfigSource config) + { + } + + public void Close() + { + } + + public void AddRegion(Scene scene) + { + m_scene = scene; + scene.EventManager.OnRegisterCaps += OnRegisterCaps; + m_scene.RegisterModuleInterface(this); + } + + public void RegionLoaded(Scene scene) + { + ISimulatorFeaturesModule featuresModule = m_scene.RequestModuleInterface(); + + if (featuresModule != null) + featuresModule.OnSimulatorFeaturesRequest += OnSimulatorFeaturesRequest; + } + + public void RemoveRegion(Scene scene) + { + } + + private void OnSimulatorFeaturesRequest(UUID agentID, ref OSDMap features) + { + OSD menus = new OSDMap(); + if (features.ContainsKey("menus")) + menus = features["menus"]; + + OSDMap agent = new OSDMap(); + OSDMap world = new OSDMap(); + OSDMap tools = new OSDMap(); + OSDMap advanced = new OSDMap(); + OSDMap admin = new OSDMap(); + if (((OSDMap)menus).ContainsKey("agent")) + agent = (OSDMap)((OSDMap)menus)["agent"]; + if (((OSDMap)menus).ContainsKey("world")) + world = (OSDMap)((OSDMap)menus)["world"]; + if (((OSDMap)menus).ContainsKey("tools")) + tools = (OSDMap)((OSDMap)menus)["tools"]; + if (((OSDMap)menus).ContainsKey("advanced")) + advanced = (OSDMap)((OSDMap)menus)["advanced"]; + if (((OSDMap)menus).ContainsKey("admin")) + admin = (OSDMap)((OSDMap)menus)["admin"]; + + if (m_menuItems.ContainsKey(UUID.Zero)) + { + foreach (MenuItemData d in m_menuItems[UUID.Zero]) + { + if (d.Mode == UserMode.God && (!m_scene.Permissions.IsGod(agentID))) + continue; + + OSDMap loc = null; + switch (d.Location) + { + case InsertLocation.Agent: + loc = agent; + break; + case InsertLocation.World: + loc = world; + break; + case InsertLocation.Tools: + loc = tools; + break; + case InsertLocation.Advanced: + loc = advanced; + break; + case InsertLocation.Admin: + loc = admin; + break; + } + + if (loc == null) + continue; + + loc[d.Title] = OSD.FromString(d.Title); + } + } + + if (m_menuItems.ContainsKey(agentID)) + { + foreach (MenuItemData d in m_menuItems[agentID]) + { + if (d.Mode == UserMode.God && (!m_scene.Permissions.IsGod(agentID))) + continue; + + OSDMap loc = null; + switch (d.Location) + { + case InsertLocation.Agent: + loc = agent; + break; + case InsertLocation.World: + loc = world; + break; + case InsertLocation.Tools: + loc = tools; + break; + case InsertLocation.Advanced: + loc = advanced; + break; + case InsertLocation.Admin: + loc = admin; + break; + } + + if (loc == null) + continue; + + loc[d.Title] = OSD.FromString(d.Title); + } + } + + + ((OSDMap)menus)["agent"] = agent; + ((OSDMap)menus)["world"] = world; + ((OSDMap)menus)["tools"] = tools; + ((OSDMap)menus)["advanced"] = advanced; + ((OSDMap)menus)["admin"] = admin; + + features["menus"] = menus; + } + + private void OnRegisterCaps(UUID agentID, Caps caps) + { + string capUrl = "/CAPS/" + UUID.Random() + "/"; + + capUrl = "/CAPS/" + UUID.Random() + "/"; + caps.RegisterHandler("CustomMenuAction", new MenuActionHandler(capUrl, "CustomMenuAction", agentID, this, m_scene)); + } + + internal void HandleMenuSelection(string action, UUID agentID, List selection) + { + if (m_menuItems.ContainsKey(agentID)) + { + foreach (MenuItemData d in m_menuItems[agentID]) + { + if (d.Title == action) + d.Handler(action, agentID, selection); + } + } + + if (m_menuItems.ContainsKey(UUID.Zero)) + { + foreach (MenuItemData d in m_menuItems[UUID.Zero]) + { + if (d.Title == action) + d.Handler(action, agentID, selection); + } + } + } + + public void AddMenuItem(string title, InsertLocation location, UserMode mode, CustomMenuHandler handler) + { + AddMenuItem(UUID.Zero, title, location, mode, handler); + } + + public void AddMenuItem(UUID agentID, string title, InsertLocation location, UserMode mode, CustomMenuHandler handler) + { + if (!m_menuItems.ContainsKey(agentID)) + m_menuItems[agentID] = new List(); + + m_menuItems[agentID].Add(new MenuItemData() { Title = title, AgentID = agentID, Location = location, Mode = mode, Handler = handler }); + } + + public void RemoveMenuItem(string action) + { + foreach (KeyValuePair> kvp in m_menuItems) + { + List pendingDeletes = new List(); + foreach (MenuItemData d in kvp.Value) + { + if (d.Title == action) + pendingDeletes.Add(d); + } + + foreach (MenuItemData d in pendingDeletes) + kvp.Value.Remove(d); + } + } + } + + public class MenuActionHandler : BaseStreamHandler + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private UUID m_agentID; + private Scene m_scene; + private DynamicMenuModule m_module; + + public MenuActionHandler(string path, string name, UUID agentID, DynamicMenuModule module, Scene scene) + :base("POST", path, name, agentID.ToString()) + { + m_agentID = agentID; + m_scene = scene; + m_module = module; + } + + public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + { + StreamReader reader = new StreamReader(request); + string requestBody = reader.ReadToEnd(); + + OSD osd = OSDParser.DeserializeLLSDXml(requestBody); + + string action = ((OSDMap)osd)["action"].AsString(); + OSDArray selection = (OSDArray)((OSDMap)osd)["selection"]; + List sel = new List(); + for (int i = 0 ; i < selection.Count ; i++) + sel.Add(selection[i].AsUInteger()); + + Util.FireAndForget(x => { m_module.HandleMenuSelection(action, m_agentID, sel); }); + + Encoding encoding = Encoding.UTF8; + return encoding.GetBytes(OSDParser.SerializeLLSDXmlString(new OSD())); + } + } +} -- cgit v1.1 From 2093d87e20956b9b6bad34668ae230fdafeeaeda Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 24 Apr 2013 19:00:41 -0700 Subject: Make the kicked user's avie truly disappear when it's god-kicked. --- OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs index d2e71a7..fa8c3f3 100644 --- a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs @@ -278,8 +278,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods if (sp.IsChildAgent) return; sp.ControllingClient.Kick(reason); - sp.MakeChildAgent(); - sp.ControllingClient.Close(); + sp.Scene.IncomingCloseAgent(sp.UUID, true); } private void OnIncomingInstantMessage(GridInstantMessage msg) -- cgit v1.1 From 40036ca05f3a34ef7f0728ed52878068a66bc502 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 25 Apr 2013 21:35:18 +0100 Subject: Change EconomyDataRequest signature to use an IClientAPI rather than UUID. This is needed because recent LL viewer codebases call this earlier in login when the client is not yet established in the sim and can't be found by UUID. Sending the reply requires having the IClientAPI. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 2 +- .../World/MoneyModule/SampleMoneyModule.cs | 17 ++++++----------- 2 files changed, 7 insertions(+), 12 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 4979be8..98160c9 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -9860,7 +9860,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP EconomyDataRequest handlerEconomoyDataRequest = OnEconomyDataRequest; if (handlerEconomoyDataRequest != null) { - handlerEconomoyDataRequest(AgentId); + handlerEconomoyDataRequest(this); } return true; } diff --git a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs index 57d9217..be020e4 100644 --- a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs +++ b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs @@ -688,19 +688,14 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule /// Event called Economy Data Request handler. /// /// - public void EconomyDataRequestHandler(UUID agentId) + public void EconomyDataRequestHandler(IClientAPI user) { - IClientAPI user = LocateClientObject(agentId); + Scene s = LocateSceneClientIn(user.AgentId); - if (user != null) - { - Scene s = LocateSceneClientIn(user.AgentId); - - user.SendEconomyData(EnergyEfficiency, s.RegionInfo.ObjectCapacity, ObjectCount, PriceEnergyUnit, PriceGroupCreate, - PriceObjectClaim, PriceObjectRent, PriceObjectScaleFactor, PriceParcelClaim, PriceParcelClaimFactor, - PriceParcelRent, PricePublicObjectDecay, PricePublicObjectDelete, PriceRentLight, PriceUpload, - TeleportMinPrice, TeleportPriceExponent); - } + user.SendEconomyData(EnergyEfficiency, s.RegionInfo.ObjectCapacity, ObjectCount, PriceEnergyUnit, PriceGroupCreate, + PriceObjectClaim, PriceObjectRent, PriceObjectScaleFactor, PriceParcelClaim, PriceParcelClaimFactor, + PriceParcelRent, PricePublicObjectDecay, PricePublicObjectDelete, PriceRentLight, PriceUpload, + TeleportMinPrice, TeleportPriceExponent); } private void ValidateLandBuy(Object osender, EventManager.LandBuyArgs e) -- cgit v1.1 From 3fcac2ba7b7aa64a7fbd26e451f49933b0859527 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 27 Apr 2013 01:20:03 +0200 Subject: Controller module for dynamic floaters (WIP) --- .../Framework/Interfaces/IDynamicFloaterModule.cs | 51 +++++ .../ViewerSupport/DynamicFloaterModule.cs | 228 +++++++++++++++++++++ 2 files changed, 279 insertions(+) create mode 100644 OpenSim/Region/Framework/Interfaces/IDynamicFloaterModule.cs create mode 100644 OpenSim/Region/OptionalModules/ViewerSupport/DynamicFloaterModule.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Interfaces/IDynamicFloaterModule.cs b/OpenSim/Region/Framework/Interfaces/IDynamicFloaterModule.cs new file mode 100644 index 0000000..5e633e6 --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IDynamicFloaterModule.cs @@ -0,0 +1,51 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System.Collections.Generic; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.Framework.Interfaces +{ + public delegate bool HandlerDelegate(IClientAPI client, FloaterData data, string[] msg); + + public abstract class FloaterData + { + public abstract int Channel { get; } + public abstract string FloaterName { get; } + public virtual string XmlName { get; set; } + public virtual HandlerDelegate Handler { get; set; } + } + + + public interface IDynamicFloaterModule + { + void DoUserFloater(UUID agentID, FloaterData dialogData, string configuration); + void FloaterControl(ScenePresence sp, FloaterData d, string msg); + } +} diff --git a/OpenSim/Region/OptionalModules/ViewerSupport/DynamicFloaterModule.cs b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicFloaterModule.cs new file mode 100644 index 0000000..7919fef --- /dev/null +++ b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicFloaterModule.cs @@ -0,0 +1,228 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.IO; +using System.Reflection; +using System.Text; +using System.Collections.Generic; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenSim; +using OpenSim.Region; +using OpenSim.Region.Framework; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Framework; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Servers.HttpServer; +using Nini.Config; +using log4net; +using Mono.Addins; +using Caps = OpenSim.Framework.Capabilities.Caps; +using OSDMap = OpenMetaverse.StructuredData.OSDMap; + +namespace OpenSim.Region.OptionalModules.ViewerSupport +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DynamicFloater")] + public class DynamicFloaterModule : INonSharedRegionModule, IDynamicFloaterModule + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Scene m_scene; + + private Dictionary> m_floaters = new Dictionary>(); + + public string Name + { + get { return "DynamicFloaterModule"; } + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void Initialise(IConfigSource config) + { + } + + public void Close() + { + } + + public void AddRegion(Scene scene) + { + m_scene = scene; + scene.EventManager.OnNewClient += OnNewClient; + scene.EventManager.OnClientClosed += OnClientClosed; + m_scene.RegisterModuleInterface(this); + } + + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + } + + private void OnNewClient(IClientAPI client) + { + client.OnChatFromClient += OnChatFromClient; + } + + private void OnClientClosed(UUID agentID, Scene scene) + { + m_floaters.Remove(agentID); + } + + private void SendToClient(ScenePresence sp, string msg) + { + sp.ControllingClient.SendChatMessage(msg, + (byte)ChatTypeEnum.Owner, + sp.AbsolutePosition, + "Server", + UUID.Zero, + UUID.Zero, + (byte)ChatSourceType.Object, + (byte)ChatAudibleLevel.Fully); + } + + public void DoUserFloater(UUID agentID, FloaterData dialogData, string configuration) + { + ScenePresence sp = m_scene.GetScenePresence(agentID); + if (sp == null || sp.IsChildAgent) + return; + + if (!m_floaters.ContainsKey(agentID)) + m_floaters[agentID] = new Dictionary(); + + m_floaters[agentID].Add(dialogData.Channel, dialogData); + + string xml; + using (FileStream fs = File.Open(dialogData.XmlName + ".xml", FileMode.Open)) + { + using (StreamReader sr = new StreamReader(fs)) + xml = sr.ReadToEnd().Replace("\n", ""); + } + + List xparts = new List(); + + while (xml.Length > 0) + { + string x = xml; + if (x.Length > 600) + { + x = x.Substring(0, 600); + xml = xml.Substring(600); + } + else + { + xml = String.Empty; + } + + xparts.Add(x); + } + + for (int i = 0 ; i < xparts.Count ; i++) + SendToClient(sp, String.Format("># floater {2} create {0}/{1} " + xparts[i], i + 1, xparts.Count, dialogData.FloaterName)); + + SendToClient(sp, String.Format("># floater {0} {{notify:1}} {{channel: {1}}} {{node:cancel {{notify:1}}}} {{node:ok {{notify:1}}}} {2}", dialogData.FloaterName, (uint)dialogData.Channel, configuration)); + } + + private void OnChatFromClient(object sender, OSChatMessage msg) + { + if (msg.Sender == null) + return; + + //m_log.DebugFormat("chan {0} msg {1}", msg.Channel, msg.Message); + + IClientAPI client = msg.Sender; + + if (!m_floaters.ContainsKey(client.AgentId)) + return; + + string[] parts = msg.Message.Split(new char[] {':'}); + if (parts.Length == 0) + return; + + ScenePresence sp = m_scene.GetScenePresence(client.AgentId); + if (sp == null || sp.IsChildAgent) + return; + + Dictionary d = m_floaters[client.AgentId]; + + // Work around a viewer bug - VALUE from any + // dialog can appear on this channel and needs to + // be dispatched to ALL open dialogs for the user + if (msg.Channel == 427169570) + { + if (parts[0] == "VALUE") + { + foreach (FloaterData dd in d.Values) + { + if(dd.Handler(client, dd, parts)) + { + m_floaters[client.AgentId].Remove(dd.Channel); + SendToClient(sp, String.Format("># floater {0} destroy", dd.FloaterName)); + break; + } + } + } + return; + } + + if (!d.ContainsKey(msg.Channel)) + return; + + FloaterData data = d[msg.Channel]; + + if (parts[0] == "NOTIFY") + { + if (parts[1] == "cancel" || parts[1] == data.FloaterName) + { + m_floaters[client.AgentId].Remove(data.Channel); + SendToClient(sp, String.Format("># floater {0} destroy", data.FloaterName)); + } + } + + if (data.Handler(client, data, parts)) + { + m_floaters[client.AgentId].Remove(data.Channel); + SendToClient(sp, String.Format("># floater {0} destroy", data.FloaterName)); + } + } + + public void FloaterControl(ScenePresence sp, FloaterData d, string msg) + { + string sendData = String.Format("># floater {0} {1}", d.FloaterName, msg); + SendToClient(sp, sendData); + + } + } +} -- cgit v1.1