aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorMelanie2013-10-04 20:03:12 +0100
committerMelanie2013-10-04 20:03:12 +0100
commit75c68fa29e3a2fed81c883e7925bf161e968639f (patch)
tree13ba69e6818f634018a5954d38750cf48128b7f8 /OpenSim
parentMerge branch 'avination-current' into careminster (diff)
parentminor: Disable logging left active on regression test TestSameSimulatorIsolat... (diff)
downloadopensim-SC-75c68fa29e3a2fed81c883e7925bf161e968639f.zip
opensim-SC-75c68fa29e3a2fed81c883e7925bf161e968639f.tar.gz
opensim-SC-75c68fa29e3a2fed81c883e7925bf161e968639f.tar.bz2
opensim-SC-75c68fa29e3a2fed81c883e7925bf161e968639f.tar.xz
Merge branch 'master' into careminster
Conflicts: OpenSim/Data/MySQL/MySQLSimulationData.cs OpenSim/Data/MySQL/Resources/RegionStore.migrations OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs OpenSim/Region/Framework/Scenes/Scene.cs OpenSim/Region/Framework/Scenes/ScenePresence.cs OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Data/MSSQL/MSSQLSimulationData.cs17
-rw-r--r--OpenSim/Data/MSSQL/Resources/RegionStore.migrations12
-rw-r--r--OpenSim/Data/MySQL/MySQLSimulationData.cs29
-rw-r--r--OpenSim/Data/MySQL/Resources/RegionStore.migrations17
-rw-r--r--OpenSim/Data/SQLite/Resources/RegionStore.migrations12
-rw-r--r--OpenSim/Data/SQLite/SQLiteSimulationData.cs16
-rw-r--r--OpenSim/Framework/IScene.cs14
-rw-r--r--OpenSim/Framework/PrimitiveBaseShape.cs11
-rw-r--r--OpenSim/Framework/RegionSettings.cs2
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs16
-rw-r--r--OpenSim/Region/Application/ConfigurationLoader.cs4
-rw-r--r--OpenSim/Region/Application/OpenSim.cs56
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs1
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs57
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs3
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs74
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs39
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs9
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs18
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs18
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs68
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs8
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs27
-rw-r--r--OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs10
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs10
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs93
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneBase.cs16
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs20
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs63
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs14
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs88
-rw-r--r--OpenSim/Region/Framework/Scenes/UuidGatherer.cs15
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs2
-rwxr-xr-xOpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs335
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs20
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs91
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs221
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs4
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs40
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs41
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs6
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs25
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSConstraintConeTwist.cs54
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSConstraintSlider.cs55
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSConstraintSpring.cs103
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs43
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs31
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs494
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSParam.cs25
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs21
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs91
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs94
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs71
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs10
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiObjectTests.cs399
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs238
-rw-r--r--OpenSim/Tests/Common/Helpers/EntityTransferHelpers.cs4
-rw-r--r--OpenSim/Tests/Common/Helpers/SceneHelpers.cs2
70 files changed, 2748 insertions, 673 deletions
diff --git a/OpenSim/Data/MSSQL/MSSQLSimulationData.cs b/OpenSim/Data/MSSQL/MSSQLSimulationData.cs
index bc5beeb..0d09be6 100644
--- a/OpenSim/Data/MSSQL/MSSQLSimulationData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLSimulationData.cs
@@ -351,7 +351,7 @@ IF EXISTS (SELECT UUID FROM prims WHERE UUID = @UUID)
351 ScriptAccessPin = @ScriptAccessPin, AllowedDrop = @AllowedDrop, DieAtEdge = @DieAtEdge, SalePrice = @SalePrice, 351 ScriptAccessPin = @ScriptAccessPin, AllowedDrop = @AllowedDrop, DieAtEdge = @DieAtEdge, SalePrice = @SalePrice,
352 SaleType = @SaleType, ColorR = @ColorR, ColorG = @ColorG, ColorB = @ColorB, ColorA = @ColorA, ParticleSystem = @ParticleSystem, 352 SaleType = @SaleType, ColorR = @ColorR, ColorG = @ColorG, ColorB = @ColorB, ColorA = @ColorA, ParticleSystem = @ParticleSystem,
353 ClickAction = @ClickAction, Material = @Material, CollisionSound = @CollisionSound, CollisionSoundVolume = @CollisionSoundVolume, PassTouches = @PassTouches, 353 ClickAction = @ClickAction, Material = @Material, CollisionSound = @CollisionSound, CollisionSoundVolume = @CollisionSoundVolume, PassTouches = @PassTouches,
354 LinkNumber = @LinkNumber, MediaURL = @MediaURL, DynAttrs = @DynAttrs, 354 LinkNumber = @LinkNumber, MediaURL = @MediaURL, AttachedPosX = @AttachedPosX, AttachedPosY = @AttachedPosY, AttachedPosZ = @AttachedPosZ, DynAttrs = @DynAttrs,
355 PhysicsShapeType = @PhysicsShapeType, Density = @Density, GravityModifier = @GravityModifier, Friction = @Friction, Restitution = @Restitution 355 PhysicsShapeType = @PhysicsShapeType, Density = @Density, GravityModifier = @GravityModifier, Friction = @Friction, Restitution = @Restitution
356 WHERE UUID = @UUID 356 WHERE UUID = @UUID
357 END 357 END
@@ -367,7 +367,7 @@ ELSE
367 PayPrice, PayButton1, PayButton2, PayButton3, PayButton4, LoopedSound, LoopedSoundGain, TextureAnimation, OmegaX, 367 PayPrice, PayButton1, PayButton2, PayButton3, PayButton4, LoopedSound, LoopedSoundGain, TextureAnimation, OmegaX,
368 OmegaY, OmegaZ, CameraEyeOffsetX, CameraEyeOffsetY, CameraEyeOffsetZ, CameraAtOffsetX, CameraAtOffsetY, CameraAtOffsetZ, 368 OmegaY, OmegaZ, CameraEyeOffsetX, CameraEyeOffsetY, CameraEyeOffsetZ, CameraAtOffsetX, CameraAtOffsetY, CameraAtOffsetZ,
369 ForceMouselook, ScriptAccessPin, AllowedDrop, DieAtEdge, SalePrice, SaleType, ColorR, ColorG, ColorB, ColorA, 369 ForceMouselook, ScriptAccessPin, AllowedDrop, DieAtEdge, SalePrice, SaleType, ColorR, ColorG, ColorB, ColorA,
370 ParticleSystem, ClickAction, Material, CollisionSound, CollisionSoundVolume, PassTouches, LinkNumber, MediaURL, DynAttrs, 370 ParticleSystem, ClickAction, Material, CollisionSound, CollisionSoundVolume, PassTouches, LinkNumber, MediaURL, AttachedPosX, AttachedPosY, AttachedPosZ, DynAttrs,
371 PhysicsShapeType, Density, GravityModifier, Friction, Restitution 371 PhysicsShapeType, Density, GravityModifier, Friction, Restitution
372 ) VALUES ( 372 ) VALUES (
373 @UUID, @CreationDate, @Name, @Text, @Description, @SitName, @TouchName, @ObjectFlags, @OwnerMask, @NextOwnerMask, @GroupMask, 373 @UUID, @CreationDate, @Name, @Text, @Description, @SitName, @TouchName, @ObjectFlags, @OwnerMask, @NextOwnerMask, @GroupMask,
@@ -378,7 +378,7 @@ ELSE
378 @PayPrice, @PayButton1, @PayButton2, @PayButton3, @PayButton4, @LoopedSound, @LoopedSoundGain, @TextureAnimation, @OmegaX, 378 @PayPrice, @PayButton1, @PayButton2, @PayButton3, @PayButton4, @LoopedSound, @LoopedSoundGain, @TextureAnimation, @OmegaX,
379 @OmegaY, @OmegaZ, @CameraEyeOffsetX, @CameraEyeOffsetY, @CameraEyeOffsetZ, @CameraAtOffsetX, @CameraAtOffsetY, @CameraAtOffsetZ, 379 @OmegaY, @OmegaZ, @CameraEyeOffsetX, @CameraEyeOffsetY, @CameraEyeOffsetZ, @CameraAtOffsetX, @CameraAtOffsetY, @CameraAtOffsetZ,
380 @ForceMouselook, @ScriptAccessPin, @AllowedDrop, @DieAtEdge, @SalePrice, @SaleType, @ColorR, @ColorG, @ColorB, @ColorA, 380 @ForceMouselook, @ScriptAccessPin, @AllowedDrop, @DieAtEdge, @SalePrice, @SaleType, @ColorR, @ColorG, @ColorB, @ColorA,
381 @ParticleSystem, @ClickAction, @Material, @CollisionSound, @CollisionSoundVolume, @PassTouches, @LinkNumber, @MediaURL, @DynAttrs, 381 @ParticleSystem, @ClickAction, @Material, @CollisionSound, @CollisionSoundVolume, @PassTouches, @LinkNumber, @MediaURL, @AttachedPosX, @AttachedPosY, @AttachedPosZ, @DynAttrs,
382 @PhysicsShapeType, @Density, @GravityModifier, @Friction, @Restitution 382 @PhysicsShapeType, @Density, @GravityModifier, @Friction, @Restitution
383 ) 383 )
384 END"; 384 END";
@@ -1695,6 +1695,12 @@ VALUES
1695 if (!(primRow["MediaURL"] is System.DBNull)) 1695 if (!(primRow["MediaURL"] is System.DBNull))
1696 prim.MediaUrl = (string)primRow["MediaURL"]; 1696 prim.MediaUrl = (string)primRow["MediaURL"];
1697 1697
1698 if (!(primRow["AttachedPosX"] is System.DBNull))
1699 prim.AttachedPos = new Vector3(
1700 Convert.ToSingle(primRow["AttachedPosX"]),
1701 Convert.ToSingle(primRow["AttachedPosY"]),
1702 Convert.ToSingle(primRow["AttachedPosZ"]));
1703
1698 if (!(primRow["DynAttrs"] is System.DBNull)) 1704 if (!(primRow["DynAttrs"] is System.DBNull))
1699 prim.DynAttrs = DAMap.FromXml((string)primRow["DynAttrs"]); 1705 prim.DynAttrs = DAMap.FromXml((string)primRow["DynAttrs"]);
1700 else 1706 else
@@ -2099,7 +2105,10 @@ VALUES
2099 parameters.Add(_Database.CreateParameter("PassTouches", 0)); 2105 parameters.Add(_Database.CreateParameter("PassTouches", 0));
2100 parameters.Add(_Database.CreateParameter("LinkNumber", prim.LinkNum)); 2106 parameters.Add(_Database.CreateParameter("LinkNumber", prim.LinkNum));
2101 parameters.Add(_Database.CreateParameter("MediaURL", prim.MediaUrl)); 2107 parameters.Add(_Database.CreateParameter("MediaURL", prim.MediaUrl));
2102 2108 parameters.Add(_Database.CreateParameter("AttachedPosX", prim.AttachedPos.X));
2109 parameters.Add(_Database.CreateParameter("AttachedPosY", prim.AttachedPos.Y));
2110 parameters.Add(_Database.CreateParameter("AttachedPosZ", prim.AttachedPos.Z));
2111
2103 if (prim.DynAttrs.CountNamespaces > 0) 2112 if (prim.DynAttrs.CountNamespaces > 0)
2104 parameters.Add(_Database.CreateParameter("DynAttrs", prim.DynAttrs.ToXml())); 2113 parameters.Add(_Database.CreateParameter("DynAttrs", prim.DynAttrs.ToXml()));
2105 else 2114 else
diff --git a/OpenSim/Data/MSSQL/Resources/RegionStore.migrations b/OpenSim/Data/MSSQL/Resources/RegionStore.migrations
index 4549801..bb89884 100644
--- a/OpenSim/Data/MSSQL/Resources/RegionStore.migrations
+++ b/OpenSim/Data/MSSQL/Resources/RegionStore.migrations
@@ -1168,3 +1168,15 @@ ALTER TABLE prims ADD `Friction` double NOT NULL default '0.6';
1168ALTER TABLE prims ADD `Restitution` double NOT NULL default '0.5'; 1168ALTER TABLE prims ADD `Restitution` double NOT NULL default '0.5';
1169 1169
1170COMMIT 1170COMMIT
1171
1172:VERSION 40 #---------------- Save Attachment info
1173
1174BEGIN TRANSACTION
1175
1176ALTER TABLE prims ADD AttachedPosX float(53) default 0.0;
1177ALTER TABLE prims ADD AttachedPosY float(53) default 0.0;
1178ALTER TABLE prims ADD AttachedPosZ float(53) default 0.0;
1179ALTER TABLE primshapes ADD LastAttachPoint int not null default 0;
1180
1181COMMIT
1182
diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs
index feacbb2..1b3e81e 100644
--- a/OpenSim/Data/MySQL/MySQLSimulationData.cs
+++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs
@@ -174,7 +174,8 @@ namespace OpenSim.Data.MySQL
174 "CollisionSound, CollisionSoundVolume, " + 174 "CollisionSound, CollisionSoundVolume, " +
175 "PassTouches, " + 175 "PassTouches, " +
176 "PassCollisions, " + 176 "PassCollisions, " +
177 "LinkNumber, MediaURL, KeyframeMotion, " + 177 "LinkNumber, MediaURL, KeyframeMotion, AttachedPosX, " +
178 "AttachedPosY, AttachedPosZ, " +
178 "PhysicsShapeType, Density, GravityModifier, " + 179 "PhysicsShapeType, Density, GravityModifier, " +
179 "Friction, Restitution, Vehicle, DynAttrs " + 180 "Friction, Restitution, Vehicle, DynAttrs " +
180 ") values (" + "?UUID, " + 181 ") values (" + "?UUID, " +
@@ -209,7 +210,8 @@ namespace OpenSim.Data.MySQL
209 "?ColorB, ?ColorA, ?ParticleSystem, " + 210 "?ColorB, ?ColorA, ?ParticleSystem, " +
210 "?ClickAction, ?Material, ?CollisionSound, " + 211 "?ClickAction, ?Material, ?CollisionSound, " +
211 "?CollisionSoundVolume, ?PassTouches, ?PassCollisions, " + 212 "?CollisionSoundVolume, ?PassTouches, ?PassCollisions, " +
212 "?LinkNumber, ?MediaURL, ?KeyframeMotion, " + 213 "?LinkNumber, ?MediaURL, ?KeyframeMotion, ?AttachedPosX, " +
214 "?AttachedPosY, ?AttachedPosZ, " +
213 "?PhysicsShapeType, ?Density, ?GravityModifier, " + 215 "?PhysicsShapeType, ?Density, ?GravityModifier, " +
214 "?Friction, ?Restitution, ?Vehicle, ?DynAttrs)"; 216 "?Friction, ?Restitution, ?Vehicle, ?DynAttrs)";
215 217
@@ -228,7 +230,7 @@ namespace OpenSim.Data.MySQL
228 "PathTaperX, PathTaperY, PathTwist, " + 230 "PathTaperX, PathTaperY, PathTwist, " +
229 "PathTwistBegin, ProfileBegin, ProfileEnd, " + 231 "PathTwistBegin, ProfileBegin, ProfileEnd, " +
230 "ProfileCurve, ProfileHollow, Texture, " + 232 "ProfileCurve, ProfileHollow, Texture, " +
231 "ExtraParams, State, Media) " + 233 "ExtraParams, State, LastAttachPoint, Media) " +
232 "values (?UUID, " + 234 "values (?UUID, " +
233 "?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " + 235 "?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " +
234 "?PCode, ?PathBegin, ?PathEnd, " + 236 "?PCode, ?PathBegin, ?PathEnd, " +
@@ -240,7 +242,7 @@ namespace OpenSim.Data.MySQL
240 "?PathTwistBegin, ?ProfileBegin, " + 242 "?PathTwistBegin, ?ProfileBegin, " +
241 "?ProfileEnd, ?ProfileCurve, " + 243 "?ProfileEnd, ?ProfileCurve, " +
242 "?ProfileHollow, ?Texture, ?ExtraParams, " + 244 "?ProfileHollow, ?Texture, ?ExtraParams, " +
243 "?State, ?Media)"; 245 "?State, ?LastAttachPoint, ?Media)";
244 246
245 FillShapeCommand(cmd, prim); 247 FillShapeCommand(cmd, prim);
246 248
@@ -1320,7 +1322,16 @@ namespace OpenSim.Data.MySQL
1320 1322
1321 if (!(row["MediaURL"] is System.DBNull)) 1323 if (!(row["MediaURL"] is System.DBNull))
1322 prim.MediaUrl = (string)row["MediaURL"]; 1324 prim.MediaUrl = (string)row["MediaURL"];
1323 1325
1326 if (!(row["AttachedPosX"] is System.DBNull))
1327 {
1328 prim.AttachedPos = new Vector3(
1329 (float)(double)row["AttachedPosX"],
1330 (float)(double)row["AttachedPosY"],
1331 (float)(double)row["AttachedPosZ"]
1332 );
1333 }
1334
1324 if (!(row["DynAttrs"] is System.DBNull)) 1335 if (!(row["DynAttrs"] is System.DBNull))
1325 prim.DynAttrs = DAMap.FromXml((string)row["DynAttrs"]); 1336 prim.DynAttrs = DAMap.FromXml((string)row["DynAttrs"]);
1326 else 1337 else
@@ -1719,6 +1730,12 @@ namespace OpenSim.Data.MySQL
1719 1730
1720 cmd.Parameters.AddWithValue("LinkNumber", prim.LinkNum); 1731 cmd.Parameters.AddWithValue("LinkNumber", prim.LinkNum);
1721 cmd.Parameters.AddWithValue("MediaURL", prim.MediaUrl); 1732 cmd.Parameters.AddWithValue("MediaURL", prim.MediaUrl);
1733 if (prim.AttachedPos != null)
1734 {
1735 cmd.Parameters.AddWithValue("AttachedPosX", (double)prim.AttachedPos.X);
1736 cmd.Parameters.AddWithValue("AttachedPosY", (double)prim.AttachedPos.Y);
1737 cmd.Parameters.AddWithValue("AttachedPosZ", (double)prim.AttachedPos.Z);
1738 }
1722 1739
1723 if (prim.KeyframeMotion != null) 1740 if (prim.KeyframeMotion != null)
1724 cmd.Parameters.AddWithValue("KeyframeMotion", prim.KeyframeMotion.Serialize()); 1741 cmd.Parameters.AddWithValue("KeyframeMotion", prim.KeyframeMotion.Serialize());
@@ -1932,6 +1949,7 @@ namespace OpenSim.Data.MySQL
1932 s.ExtraParams = (byte[])row["ExtraParams"]; 1949 s.ExtraParams = (byte[])row["ExtraParams"];
1933 1950
1934 s.State = (byte)(int)row["State"]; 1951 s.State = (byte)(int)row["State"];
1952 s.LastAttachPoint = (byte)(int)row["LastAttachPoint"];
1935 1953
1936 if (!(row["Media"] is System.DBNull)) 1954 if (!(row["Media"] is System.DBNull))
1937 s.Media = PrimitiveBaseShape.MediaList.FromXml((string)row["Media"]); 1955 s.Media = PrimitiveBaseShape.MediaList.FromXml((string)row["Media"]);
@@ -1978,6 +1996,7 @@ namespace OpenSim.Data.MySQL
1978 cmd.Parameters.AddWithValue("Texture", s.TextureEntry); 1996 cmd.Parameters.AddWithValue("Texture", s.TextureEntry);
1979 cmd.Parameters.AddWithValue("ExtraParams", s.ExtraParams); 1997 cmd.Parameters.AddWithValue("ExtraParams", s.ExtraParams);
1980 cmd.Parameters.AddWithValue("State", s.State); 1998 cmd.Parameters.AddWithValue("State", s.State);
1999 cmd.Parameters.AddWithValue("LastAttachPoint", s.LastAttachPoint);
1981 cmd.Parameters.AddWithValue("Media", null == s.Media ? null : s.Media.ToXml()); 2000 cmd.Parameters.AddWithValue("Media", null == s.Media ? null : s.Media.ToXml());
1982 } 2001 }
1983 2002
diff --git a/OpenSim/Data/MySQL/Resources/RegionStore.migrations b/OpenSim/Data/MySQL/Resources/RegionStore.migrations
index bda1b6a..c2e3afe 100644
--- a/OpenSim/Data/MySQL/Resources/RegionStore.migrations
+++ b/OpenSim/Data/MySQL/Resources/RegionStore.migrations
@@ -922,3 +922,20 @@ ALTER TABLE prims ADD COLUMN `Friction` double NOT NULL default '0.6';
922ALTER TABLE prims ADD COLUMN `Restitution` double NOT NULL default '0.5'; 922ALTER TABLE prims ADD COLUMN `Restitution` double NOT NULL default '0.5';
923 923
924COMMIT; 924COMMIT;
925
926:VERSION 48 #---------------- Keyframes
927
928BEGIN;
929
930ALTER TABLE prims ADD COLUMN `KeyframeMotion` blob;
931
932COMMIT;
933
934:VERSION 49 #--------------------- Save attachment info
935
936BEGIN;
937ALTER TABLE prims ADD COLUMN AttachedPosX double default 0;
938ALTER TABLE prims ADD COLUMN AttachedPosY double default 0;
939ALTER TABLE prims ADD COLUMN AttachedPosZ double default 0;
940ALTER TABLE primshapes ADD COLUMN LastAttachPoint int(4) not null default '0';
941COMMIT;
diff --git a/OpenSim/Data/SQLite/Resources/RegionStore.migrations b/OpenSim/Data/SQLite/Resources/RegionStore.migrations
index bff039d..901068f 100644
--- a/OpenSim/Data/SQLite/Resources/RegionStore.migrations
+++ b/OpenSim/Data/SQLite/Resources/RegionStore.migrations
@@ -600,3 +600,15 @@ BEGIN;
600ALTER TABLE prims ADD COLUMN `KeyframeMotion` blob; 600ALTER TABLE prims ADD COLUMN `KeyframeMotion` blob;
601 601
602COMMIT; 602COMMIT;
603
604:VERSION 30 #---------------- Save Attachment info
605
606BEGIN;
607
608ALTER TABLE prims ADD COLUMN AttachedPosX double default '0';
609ALTER TABLE prims ADD COLUMN AttachedPosY double default '0';
610ALTER TABLE prims ADD COLUMN AttachedPosZ double default '0';
611ALTER TABLE primshapes ADD COLUMN LastAttachPoint int not null default '0';
612
613COMMIT;
614
diff --git a/OpenSim/Data/SQLite/SQLiteSimulationData.cs b/OpenSim/Data/SQLite/SQLiteSimulationData.cs
index 52502b3..4d6a80a 100644
--- a/OpenSim/Data/SQLite/SQLiteSimulationData.cs
+++ b/OpenSim/Data/SQLite/SQLiteSimulationData.cs
@@ -1236,6 +1236,10 @@ namespace OpenSim.Data.SQLite
1236 1236
1237 createCol(prims, "MediaURL", typeof(String)); 1237 createCol(prims, "MediaURL", typeof(String));
1238 1238
1239 createCol(prims, "AttachedPosX", typeof(Double));
1240 createCol(prims, "AttachedPosY", typeof(Double));
1241 createCol(prims, "AttachedPosZ", typeof(Double));
1242
1239 createCol(prims, "DynAttrs", typeof(String)); 1243 createCol(prims, "DynAttrs", typeof(String));
1240 1244
1241 createCol(prims, "PhysicsShapeType", typeof(Byte)); 1245 createCol(prims, "PhysicsShapeType", typeof(Byte));
@@ -1724,6 +1728,12 @@ namespace OpenSim.Data.SQLite
1724 prim.MediaUrl = (string)row["MediaURL"]; 1728 prim.MediaUrl = (string)row["MediaURL"];
1725 } 1729 }
1726 1730
1731 prim.AttachedPos = new Vector3(
1732 Convert.ToSingle(row["AttachedPosX"]),
1733 Convert.ToSingle(row["AttachedPosY"]),
1734 Convert.ToSingle(row["AttachedPosZ"])
1735 );
1736
1727 if (!(row["DynAttrs"] is System.DBNull)) 1737 if (!(row["DynAttrs"] is System.DBNull))
1728 { 1738 {
1729 //m_log.DebugFormat("[SQLITE]: DynAttrs type [{0}]", row["DynAttrs"].GetType()); 1739 //m_log.DebugFormat("[SQLITE]: DynAttrs type [{0}]", row["DynAttrs"].GetType());
@@ -2176,6 +2186,10 @@ namespace OpenSim.Data.SQLite
2176 2186
2177 row["MediaURL"] = prim.MediaUrl; 2187 row["MediaURL"] = prim.MediaUrl;
2178 2188
2189 row["AttachedPosX"] = prim.AttachedPos.X;
2190 row["AttachedPosY"] = prim.AttachedPos.Y;
2191 row["AttachedPosZ"] = prim.AttachedPos.Z;
2192
2179 if (prim.DynAttrs.CountNamespaces > 0) 2193 if (prim.DynAttrs.CountNamespaces > 0)
2180 row["DynAttrs"] = prim.DynAttrs.ToXml(); 2194 row["DynAttrs"] = prim.DynAttrs.ToXml();
2181 else 2195 else
@@ -2444,6 +2458,7 @@ namespace OpenSim.Data.SQLite
2444 s.ProfileCurve = Convert.ToByte(row["ProfileCurve"]); 2458 s.ProfileCurve = Convert.ToByte(row["ProfileCurve"]);
2445 s.ProfileHollow = Convert.ToUInt16(row["ProfileHollow"]); 2459 s.ProfileHollow = Convert.ToUInt16(row["ProfileHollow"]);
2446 s.State = Convert.ToByte(row["State"]); 2460 s.State = Convert.ToByte(row["State"]);
2461 s.LastAttachPoint = Convert.ToByte(row["LastAttachPoint"]);
2447 2462
2448 byte[] textureEntry = (byte[])row["Texture"]; 2463 byte[] textureEntry = (byte[])row["Texture"];
2449 s.TextureEntry = textureEntry; 2464 s.TextureEntry = textureEntry;
@@ -2493,6 +2508,7 @@ namespace OpenSim.Data.SQLite
2493 row["ProfileCurve"] = s.ProfileCurve; 2508 row["ProfileCurve"] = s.ProfileCurve;
2494 row["ProfileHollow"] = s.ProfileHollow; 2509 row["ProfileHollow"] = s.ProfileHollow;
2495 row["State"] = s.State; 2510 row["State"] = s.State;
2511 row["LastAttachPoint"] = s.LastAttachPoint;
2496 2512
2497 row["Texture"] = s.TextureEntry; 2513 row["Texture"] = s.TextureEntry;
2498 row["ExtraParams"] = s.ExtraParams; 2514 row["ExtraParams"] = s.ExtraParams;
diff --git a/OpenSim/Framework/IScene.cs b/OpenSim/Framework/IScene.cs
index 8164f41..e1b6d1e 100644
--- a/OpenSim/Framework/IScene.cs
+++ b/OpenSim/Framework/IScene.cs
@@ -86,24 +86,26 @@ namespace OpenSim.Framework
86 event restart OnRestart; 86 event restart OnRestart;
87 87
88 /// <summary> 88 /// <summary>
89 /// Add a new client and create a presence for it. All clients except initial login clients will starts off as a child agent 89 /// Add a new agent with an attached client. All agents except initial login clients will starts off as a child agent
90 /// - the later agent crossing will promote it to a root agent. 90 /// - the later agent crossing will promote it to a root agent.
91 /// </summary> 91 /// </summary>
92 /// <param name="client"></param> 92 /// <param name="client"></param>
93 /// <param name="type">The type of agent to add.</param> 93 /// <param name="type">The type of agent to add.</param>
94 /// <returns> 94 /// <returns>
95 /// The scene agent if the new client was added or if an agent that already existed.</returns> 95 /// The scene agent if the new client was added or if an agent that already existed.</returns>
96 ISceneAgent AddNewClient(IClientAPI client, PresenceType type); 96 ISceneAgent AddNewAgent(IClientAPI client, PresenceType type);
97 97
98 /// <summary> 98 /// <summary>
99 /// Remove the given client from the scene. 99 /// Tell a single agent to disconnect from the region.
100 /// </summary> 100 /// </summary>
101 /// <param name="agentID"></param> 101 /// <param name="agentID"></param>
102 /// <param name="closeChildAgents">Close the neighbour child agents associated with this client.</param> 102 /// <param name="force">
103 void RemoveClient(UUID agentID, bool closeChildAgents); 103 /// Force the agent to close even if it might be in the middle of some other operation. You do not want to
104 /// force unless you are absolutely sure that the agent is dead and a normal close is not working.
105 /// </param>
106 bool CloseAgent(UUID agentID, bool force);
104 107
105 void Restart(); 108 void Restart();
106 //RegionInfo OtherRegionUp(RegionInfo thisRegion);
107 109
108 string GetSimulatorVersion(); 110 string GetSimulatorVersion();
109 111
diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs
index df928dc..6a12a45 100644
--- a/OpenSim/Framework/PrimitiveBaseShape.cs
+++ b/OpenSim/Framework/PrimitiveBaseShape.cs
@@ -105,6 +105,7 @@ namespace OpenSim.Framework
105 private ushort _profileHollow; 105 private ushort _profileHollow;
106 private Vector3 _scale; 106 private Vector3 _scale;
107 private byte _state; 107 private byte _state;
108 private byte _lastattach;
108 private ProfileShape _profileShape; 109 private ProfileShape _profileShape;
109 private HollowShape _hollowShape; 110 private HollowShape _hollowShape;
110 111
@@ -207,6 +208,7 @@ namespace OpenSim.Framework
207 PCode = (byte)prim.PrimData.PCode; 208 PCode = (byte)prim.PrimData.PCode;
208 209
209 State = prim.PrimData.State; 210 State = prim.PrimData.State;
211 LastAttachPoint = prim.PrimData.State;
210 PathBegin = Primitive.PackBeginCut(prim.PrimData.PathBegin); 212 PathBegin = Primitive.PackBeginCut(prim.PrimData.PathBegin);
211 PathEnd = Primitive.PackEndCut(prim.PrimData.PathEnd); 213 PathEnd = Primitive.PackEndCut(prim.PrimData.PathEnd);
212 PathScaleX = Primitive.PackPathScale(prim.PrimData.PathScaleX); 214 PathScaleX = Primitive.PackPathScale(prim.PrimData.PathScaleX);
@@ -583,6 +585,15 @@ namespace OpenSim.Framework
583 } 585 }
584 } 586 }
585 587
588 public byte LastAttachPoint {
589 get {
590 return _lastattach;
591 }
592 set {
593 _lastattach = value;
594 }
595 }
596
586 public ProfileShape ProfileShape { 597 public ProfileShape ProfileShape {
587 get { 598 get {
588 return _profileShape; 599 return _profileShape;
diff --git a/OpenSim/Framework/RegionSettings.cs b/OpenSim/Framework/RegionSettings.cs
index 47a2780..2c6529d 100644
--- a/OpenSim/Framework/RegionSettings.cs
+++ b/OpenSim/Framework/RegionSettings.cs
@@ -200,7 +200,7 @@ namespace OpenSim.Framework
200 set { m_ObjectBonus = value; } 200 set { m_ObjectBonus = value; }
201 } 201 }
202 202
203 private int m_Maturity = 1; 203 private int m_Maturity = 0;
204 204
205 public int Maturity 205 public int Maturity
206 { 206 {
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index f4b4156..ed733cf 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -1057,7 +1057,21 @@ namespace OpenSim.Framework.Servers.HttpServer
1057 } 1057 }
1058 1058
1059 response.ContentType = "text/xml"; 1059 response.ContentType = "text/xml";
1060 responseString = XmlRpcResponseSerializer.Singleton.Serialize(xmlRpcResponse); 1060 using (MemoryStream outs = new MemoryStream())
1061 {
1062 using (XmlTextWriter writer = new XmlTextWriter(outs, Encoding.UTF8))
1063 {
1064 writer.Formatting = Formatting.None;
1065 XmlRpcResponseSerializer.Singleton.Serialize(writer, xmlRpcResponse);
1066 writer.Flush();
1067 outs.Flush();
1068 outs.Position = 0;
1069 using (StreamReader sr = new StreamReader(outs))
1070 {
1071 responseString = sr.ReadToEnd();
1072 }
1073 }
1074 }
1061 } 1075 }
1062 else 1076 else
1063 { 1077 {
diff --git a/OpenSim/Region/Application/ConfigurationLoader.cs b/OpenSim/Region/Application/ConfigurationLoader.cs
index bc7ecb7..010ae5a 100644
--- a/OpenSim/Region/Application/ConfigurationLoader.cs
+++ b/OpenSim/Region/Application/ConfigurationLoader.cs
@@ -203,10 +203,10 @@ namespace OpenSim
203 m_config.Source.Merge(envConfigSource); 203 m_config.Source.Merge(envConfigSource);
204 } 204 }
205 205
206 ReadConfigSettings();
207
208 m_config.Source.ExpandKeyValues(); 206 m_config.Source.ExpandKeyValues();
209 207
208 ReadConfigSettings();
209
210 return m_config; 210 return m_config;
211 } 211 }
212 212
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index a18a6fe..20f6af5 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -237,27 +237,33 @@ namespace OpenSim
237 237
238 m_console.Commands.AddCommand("General", false, "change region", 238 m_console.Commands.AddCommand("General", false, "change region",
239 "change region <region name>", 239 "change region <region name>",
240 "Change current console region", ChangeSelectedRegion); 240 "Change current console region",
241 ChangeSelectedRegion);
241 242
242 m_console.Commands.AddCommand("Archiving", false, "save xml", 243 m_console.Commands.AddCommand("Archiving", false, "save xml",
243 "save xml", 244 "save xml",
244 "Save a region's data in XML format", SaveXml); 245 "Save a region's data in XML format",
246 SaveXml);
245 247
246 m_console.Commands.AddCommand("Archiving", false, "save xml2", 248 m_console.Commands.AddCommand("Archiving", false, "save xml2",
247 "save xml2", 249 "save xml2",
248 "Save a region's data in XML2 format", SaveXml2); 250 "Save a region's data in XML2 format",
251 SaveXml2);
249 252
250 m_console.Commands.AddCommand("Archiving", false, "load xml", 253 m_console.Commands.AddCommand("Archiving", false, "load xml",
251 "load xml [-newIDs [<x> <y> <z>]]", 254 "load xml [-newIDs [<x> <y> <z>]]",
252 "Load a region's data from XML format", LoadXml); 255 "Load a region's data from XML format",
256 LoadXml);
253 257
254 m_console.Commands.AddCommand("Archiving", false, "load xml2", 258 m_console.Commands.AddCommand("Archiving", false, "load xml2",
255 "load xml2", 259 "load xml2",
256 "Load a region's data from XML2 format", LoadXml2); 260 "Load a region's data from XML2 format",
261 LoadXml2);
257 262
258 m_console.Commands.AddCommand("Archiving", false, "save prims xml2", 263 m_console.Commands.AddCommand("Archiving", false, "save prims xml2",
259 "save prims xml2 [<prim name> <file name>]", 264 "save prims xml2 [<prim name> <file name>]",
260 "Save named prim to XML2", SavePrimsXml2); 265 "Save named prim to XML2",
266 SavePrimsXml2);
261 267
262 m_console.Commands.AddCommand("Archiving", false, "load oar", 268 m_console.Commands.AddCommand("Archiving", false, "load oar",
263 "load oar [--merge] [--skip-assets] [<OAR path>]", 269 "load oar [--merge] [--skip-assets] [<OAR path>]",
@@ -287,7 +293,8 @@ namespace OpenSim
287 293
288 m_console.Commands.AddCommand("Objects", false, "edit scale", 294 m_console.Commands.AddCommand("Objects", false, "edit scale",
289 "edit scale <name> <x> <y> <z>", 295 "edit scale <name> <x> <y> <z>",
290 "Change the scale of a named prim", HandleEditScale); 296 "Change the scale of a named prim",
297 HandleEditScale);
291 298
292 m_console.Commands.AddCommand("Users", false, "kick user", 299 m_console.Commands.AddCommand("Users", false, "kick user",
293 "kick user <first> <last> [--force] [message]", 300 "kick user <first> <last> [--force] [message]",
@@ -305,31 +312,38 @@ namespace OpenSim
305 312
306 m_console.Commands.AddCommand("Comms", false, "show connections", 313 m_console.Commands.AddCommand("Comms", false, "show connections",
307 "show connections", 314 "show connections",
308 "Show connection data", HandleShow); 315 "Show connection data",
316 HandleShow);
309 317
310 m_console.Commands.AddCommand("Comms", false, "show circuits", 318 m_console.Commands.AddCommand("Comms", false, "show circuits",
311 "show circuits", 319 "show circuits",
312 "Show agent circuit data", HandleShow); 320 "Show agent circuit data",
321 HandleShow);
313 322
314 m_console.Commands.AddCommand("Comms", false, "show pending-objects", 323 m_console.Commands.AddCommand("Comms", false, "show pending-objects",
315 "show pending-objects", 324 "show pending-objects",
316 "Show # of objects on the pending queues of all scene viewers", HandleShow); 325 "Show # of objects on the pending queues of all scene viewers",
326 HandleShow);
317 327
318 m_console.Commands.AddCommand("General", false, "show modules", 328 m_console.Commands.AddCommand("General", false, "show modules",
319 "show modules", 329 "show modules",
320 "Show module data", HandleShow); 330 "Show module data",
331 HandleShow);
321 332
322 m_console.Commands.AddCommand("Regions", false, "show regions", 333 m_console.Commands.AddCommand("Regions", false, "show regions",
323 "show regions", 334 "show regions",
324 "Show region data", HandleShow); 335 "Show region data",
336 HandleShow);
325 337
326 m_console.Commands.AddCommand("Regions", false, "show ratings", 338 m_console.Commands.AddCommand("Regions", false, "show ratings",
327 "show ratings", 339 "show ratings",
328 "Show rating data", HandleShow); 340 "Show rating data",
341 HandleShow);
329 342
330 m_console.Commands.AddCommand("Objects", false, "backup", 343 m_console.Commands.AddCommand("Objects", false, "backup",
331 "backup", 344 "backup",
332 "Persist currently unsaved object changes immediately instead of waiting for the normal persistence call.", RunCommand); 345 "Persist currently unsaved object changes immediately instead of waiting for the normal persistence call.",
346 RunCommand);
333 347
334 m_console.Commands.AddCommand("Regions", false, "create region", 348 m_console.Commands.AddCommand("Regions", false, "create region",
335 "create region [\"region name\"] <region_file.ini>", 349 "create region [\"region name\"] <region_file.ini>",
@@ -342,19 +356,23 @@ namespace OpenSim
342 356
343 m_console.Commands.AddCommand("Regions", false, "restart", 357 m_console.Commands.AddCommand("Regions", false, "restart",
344 "restart", 358 "restart",
345 "Restart all sims in this instance", RunCommand); 359 "Restart all sims in this instance",
360 RunCommand);
346 361
347 m_console.Commands.AddCommand("General", false, "command-script", 362 m_console.Commands.AddCommand("General", false, "command-script",
348 "command-script <script>", 363 "command-script <script>",
349 "Run a command script from file", RunCommand); 364 "Run a command script from file",
365 RunCommand);
350 366
351 m_console.Commands.AddCommand("Regions", false, "remove-region", 367 m_console.Commands.AddCommand("Regions", false, "remove-region",
352 "remove-region <name>", 368 "remove-region <name>",
353 "Remove a region from this simulator", RunCommand); 369 "Remove a region from this simulator",
370 RunCommand);
354 371
355 m_console.Commands.AddCommand("Regions", false, "delete-region", 372 m_console.Commands.AddCommand("Regions", false, "delete-region",
356 "delete-region <name>", 373 "delete-region <name>",
357 "Delete a region from disk", RunCommand); 374 "Delete a region from disk",
375 RunCommand);
358 } 376 }
359 377
360 protected override void ShutdownSpecific() 378 protected override void ShutdownSpecific()
@@ -434,7 +452,7 @@ namespace OpenSim
434 else 452 else
435 presence.ControllingClient.Kick("\nYou have been logged out by an administrator.\n"); 453 presence.ControllingClient.Kick("\nYou have been logged out by an administrator.\n");
436 454
437 presence.Scene.IncomingCloseAgent(presence.UUID, force); 455 presence.Scene.CloseAgent(presence.UUID, force);
438 break; 456 break;
439 } 457 }
440 } 458 }
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
index b3b0b8a..9e24bce 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
@@ -96,7 +96,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
96 UUID spId = TestHelpers.ParseTail(0x1); 96 UUID spId = TestHelpers.ParseTail(0x1);
97 97
98 SceneHelpers.AddScenePresence(m_scene, spId); 98 SceneHelpers.AddScenePresence(m_scene, spId);
99 m_scene.IncomingCloseAgent(spId, false); 99 m_scene.CloseAgent(spId, false);
100 100
101 // TODO: Add more assertions for the other aspects of event queues 101 // TODO: Add more assertions for the other aspects of event queues
102 Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0)); 102 Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0));
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs
index 92805e2..94f8bc1 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs
@@ -155,6 +155,7 @@ namespace OpenSim.Region.ClientStack.Linden
155 Quaternion rotation = Quaternion.Identity; 155 Quaternion rotation = Quaternion.Identity;
156 Vector3 scale = Vector3.Zero; 156 Vector3 scale = Vector3.Zero;
157 int state = 0; 157 int state = 0;
158 int lastattach = 0;
158 159
159 if (r.Type != OSDType.Map) // not a proper req 160 if (r.Type != OSDType.Map) // not a proper req
160 return responsedata; 161 return responsedata;
@@ -224,6 +225,7 @@ namespace OpenSim.Region.ClientStack.Linden
224 225
225 ray_target_id = ObjMap["RayTargetId"].AsUUID(); 226 ray_target_id = ObjMap["RayTargetId"].AsUUID();
226 state = ObjMap["State"].AsInteger(); 227 state = ObjMap["State"].AsInteger();
228 lastattach = ObjMap["LastAttachPoint"].AsInteger();
227 try 229 try
228 { 230 {
229 ray_end = ((OSDArray)ObjMap["RayEnd"]).AsVector3(); 231 ray_end = ((OSDArray)ObjMap["RayEnd"]).AsVector3();
@@ -290,6 +292,7 @@ namespace OpenSim.Region.ClientStack.Linden
290 292
291 //session_id = rm["session_id"].AsUUID(); 293 //session_id = rm["session_id"].AsUUID();
292 state = rm["state"].AsInteger(); 294 state = rm["state"].AsInteger();
295 lastattach = rm["last_attach_point"].AsInteger();
293 try 296 try
294 { 297 {
295 ray_end = ((OSDArray)rm["ray_end"]).AsVector3(); 298 ray_end = ((OSDArray)rm["ray_end"]).AsVector3();
@@ -331,6 +334,7 @@ namespace OpenSim.Region.ClientStack.Linden
331 pbs.ProfileEnd = (ushort)profile_end; 334 pbs.ProfileEnd = (ushort)profile_end;
332 pbs.Scale = scale; 335 pbs.Scale = scale;
333 pbs.State = (byte)state; 336 pbs.State = (byte)state;
337 pbs.LastAttachPoint = (byte)lastattach;
334 338
335 SceneObjectGroup obj = null; ; 339 SceneObjectGroup obj = null; ;
336 340
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
index 55a503e..769fe28 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
@@ -277,6 +277,7 @@ namespace OpenSim.Region.ClientStack.Linden
277 pbs.ProfileEnd = (ushort) obj.ProfileEnd; 277 pbs.ProfileEnd = (ushort) obj.ProfileEnd;
278 pbs.Scale = obj.Scale; 278 pbs.Scale = obj.Scale;
279 pbs.State = (byte) 0; 279 pbs.State = (byte) 0;
280 pbs.LastAttachPoint = (byte) 0;
280 SceneObjectPart prim = new SceneObjectPart(); 281 SceneObjectPart prim = new SceneObjectPart();
281 prim.UUID = UUID.Random(); 282 prim.UUID = UUID.Random();
282 prim.CreatorID = AgentId; 283 prim.CreatorID = AgentId;
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
index f816ad3..6fc35cd 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
@@ -116,7 +116,7 @@ namespace OpenSim.Region.ClientStack.Linden
116 m_scene.EventManager.OnRegisterCaps -= RegisterCaps; 116 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
117 117
118 foreach (Thread t in m_workerThreads) 118 foreach (Thread t in m_workerThreads)
119 Watchdog.AbortThread(t.ManagedThreadId); 119 Watchdog.AbortThread(t.ManagedThreadId);
120 120
121 m_scene = null; 121 m_scene = null;
122 } 122 }
@@ -298,36 +298,49 @@ namespace OpenSim.Region.ClientStack.Linden
298 requestinfo.request["body"].ToString(), String.Empty, String.Empty, null, null); 298 requestinfo.request["body"].ToString(), String.Empty, String.Empty, null, null);
299 299
300 lock (responses) 300 lock (responses)
301 responses[requestID] = response; 301 responses[requestID] = response;
302 } 302 }
303 } 303 }
304 304
305 private void RegisterCaps(UUID agentID, Caps caps) 305 private void RegisterCaps(UUID agentID, Caps caps)
306 { 306 {
307 if (m_fetchInventoryDescendents2Url == "") 307 RegisterFetchDescendentsCap(agentID, caps, "FetchInventoryDescendents2", m_fetchInventoryDescendents2Url);
308 }
309
310 private void RegisterFetchDescendentsCap(UUID agentID, Caps caps, string capName, string url)
311 {
312 string capUrl;
313
314 // disable the cap clause
315 if (url == "")
316 {
308 return; 317 return;
318 }
319 // handled by the simulator
320 else if (url == "localhost")
321 {
322 capUrl = "/CAPS/" + UUID.Random() + "/";
309 323
310 // Register this as a poll service 324 // Register this as a poll service
311 PollServiceInventoryEventArgs args 325 PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(m_scene, capUrl, agentID);
312 = new PollServiceInventoryEventArgs(m_scene, "/CAPS/" + UUID.Random() + "/", agentID); 326 args.Type = PollServiceEventArgs.EventType.Inventory;
313 args.Type = PollServiceEventArgs.EventType.Inventory;
314 327
315 caps.RegisterPollHandler("FetchInventoryDescendents2", args); 328 caps.RegisterPollHandler(capName, args);
329 }
330 // external handler
331 else
332 {
333 capUrl = url;
334 IExternalCapsModule handler = m_scene.RequestModuleInterface<IExternalCapsModule>();
335 if (handler != null)
336 handler.RegisterExternalUserCapsHandler(agentID,caps,capName,capUrl);
337 else
338 caps.RegisterHandler(capName, capUrl);
339 }
316 340
317// MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args); 341 // m_log.DebugFormat(
318// 342 // "[FETCH INVENTORY DESCENDENTS2 MODULE]: Registered capability {0} at {1} in region {2} for {3}",
319// string hostName = m_scene.RegionInfo.ExternalHostName; 343 // capName, capUrl, m_scene.RegionInfo.RegionName, agentID);
320// uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
321// string protocol = "http";
322//
323// if (MainServer.Instance.UseSSL)
324// {
325// hostName = MainServer.Instance.SSLCommonName;
326// port = MainServer.Instance.SSLPort;
327// protocol = "https";
328// }
329//
330// caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
331 } 344 }
332 345
333// private void DeregisterCaps(UUID agentID, Caps caps) 346// private void DeregisterCaps(UUID agentID, Caps caps)
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 36edd0b..51cc2bf 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -783,7 +783,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
783 783
784 public virtual void Start() 784 public virtual void Start()
785 { 785 {
786 m_scene.AddNewClient(this, PresenceType.User); 786 m_scene.AddNewAgent(this, PresenceType.User);
787 787
788 RefreshGroupMembership(); 788 RefreshGroupMembership();
789 } 789 }
@@ -12548,6 +12548,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12548 12548
12549 shape.PCode = addPacket.ObjectData.PCode; 12549 shape.PCode = addPacket.ObjectData.PCode;
12550 shape.State = addPacket.ObjectData.State; 12550 shape.State = addPacket.ObjectData.State;
12551 shape.LastAttachPoint = addPacket.ObjectData.State;
12551 shape.PathBegin = addPacket.ObjectData.PathBegin; 12552 shape.PathBegin = addPacket.ObjectData.PathBegin;
12552 shape.PathEnd = addPacket.ObjectData.PathEnd; 12553 shape.PathEnd = addPacket.ObjectData.PathEnd;
12553 shape.PathScaleX = addPacket.ObjectData.PathScaleX; 12554 shape.PathScaleX = addPacket.ObjectData.PathScaleX;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index ad3f715..01981dd 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -1764,32 +1764,76 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1764 endPoint = (IPEndPoint)array[0]; 1764 endPoint = (IPEndPoint)array[0];
1765 CompleteAgentMovementPacket packet = (CompleteAgentMovementPacket)array[1]; 1765 CompleteAgentMovementPacket packet = (CompleteAgentMovementPacket)array[1];
1766 1766
1767 m_log.DebugFormat(
1768 "[LLUDPSERVER]: Handling CompleteAgentMovement request from {0} in {1}", endPoint, m_scene.Name);
1769
1767 // Determine which agent this packet came from 1770 // Determine which agent this packet came from
1768 int count = 20; 1771 // We need to wait here because in when using the OpenSimulator V2 teleport protocol to travel to a destination
1769 bool ready = false; 1772 // simulator with no existing child presence, the viewer (at least LL 3.3.4) will send UseCircuitCode
1770 while (!ready && count-- > 0) 1773 // and then CompleteAgentMovement immediately without waiting for an ack. As we are now handling these
1774 // packets asynchronously, we need to account for this thread proceeding more quickly than the
1775 // UseCircuitCode thread.
1776 int count = 40;
1777 while (count-- > 0)
1771 { 1778 {
1772 if (m_scene.TryGetClient(endPoint, out client) && client.IsActive && client.SceneAgent != null) 1779 if (m_scene.TryGetClient(endPoint, out client))
1773 { 1780 {
1774 LLClientView llClientView = (LLClientView)client; 1781 if (!client.IsActive)
1775 LLUDPClient udpClient = llClientView.UDPClient; 1782 {
1776 if (udpClient != null && udpClient.IsConnected) 1783 // This check exists to catch a condition where the client has been closed by another thread
1777 ready = true; 1784 // but has not yet been removed from the client manager (and possibly a new connection has
1785 // not yet been established).
1786 m_log.DebugFormat(
1787 "[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client is not active yet. Waiting.",
1788 endPoint, client.Name, m_scene.Name);
1789 }
1790 else if (client.SceneAgent == null)
1791 {
1792 // This check exists to catch a condition where the new client has been added to the client
1793 // manager but the SceneAgent has not yet been set in Scene.AddNewAgent(). If we are too
1794 // eager, then the new ScenePresence may not have registered a listener for this messsage
1795 // before we try to process it.
1796 // XXX: A better long term fix may be to add the SceneAgent before the client is added to
1797 // the client manager
1798 m_log.DebugFormat(
1799 "[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client SceneAgent not set yet. Waiting.",
1800 endPoint, client.Name, m_scene.Name);
1801 }
1778 else 1802 else
1779 { 1803 {
1780 m_log.Debug("[LLUDPSERVER]: Received a CompleteMovementIntoRegion in " + m_scene.RegionInfo.RegionName + " (not ready yet)"); 1804 break;
1781 Thread.Sleep(200);
1782 } 1805 }
1783 } 1806 }
1784 else 1807 else
1785 { 1808 {
1786 m_log.Debug("[LLUDPSERVER]: Received a CompleteMovementIntoRegion in " + m_scene.RegionInfo.RegionName + " (not ready yet)"); 1809 m_log.DebugFormat(
1787 Thread.Sleep(200); 1810 "[LLUDPSERVER]: Received a CompleteAgentMovement from {0} in {1} but no client exists yet. Waiting.",
1811 endPoint, m_scene.Name);
1788 } 1812 }
1813
1814 Thread.Sleep(200);
1789 } 1815 }
1790 1816
1791 if (client == null) 1817 if (client == null)
1818 {
1819 m_log.DebugFormat(
1820 "[LLUDPSERVER]: No client found for CompleteAgentMovement from {0} in {1} after wait. Dropping.",
1821 endPoint, m_scene.Name);
1822
1823 return;
1824 }
1825 else if (!client.IsActive || client.SceneAgent == null)
1826 {
1827 // This check exists to catch a condition where the client has been closed by another thread
1828 // but has not yet been removed from the client manager.
1829 // The packet could be simply ignored but it is useful to know if this condition occurred for other debugging
1830 // purposes.
1831 m_log.DebugFormat(
1832 "[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client is not active after wait. Dropping.",
1833 endPoint, client.Name, m_scene.Name);
1834
1792 return; 1835 return;
1836 }
1793 1837
1794 IncomingPacket incomingPacket1; 1838 IncomingPacket incomingPacket1;
1795 1839
@@ -1810,7 +1854,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1810 catch (Exception e) 1854 catch (Exception e)
1811 { 1855 {
1812 m_log.ErrorFormat( 1856 m_log.ErrorFormat(
1813 "[LLUDPSERVER]: CompleteMovementIntoRegion handling from endpoint {0}, client {1} {2} failed. Exception {3}{4}", 1857 "[LLUDPSERVER]: CompleteAgentMovement handling from endpoint {0}, client {1} {2} failed. Exception {3}{4}",
1814 endPoint != null ? endPoint.ToString() : "n/a", 1858 endPoint != null ? endPoint.ToString() : "n/a",
1815 client != null ? client.Name : "unknown", 1859 client != null ? client.Name : "unknown",
1816 client != null ? client.AgentId.ToString() : "unknown", 1860 client != null ? client.AgentId.ToString() : "unknown",
@@ -1921,7 +1965,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1921 client.Kick("Simulator logged you out due to connection timeout."); 1965 client.Kick("Simulator logged you out due to connection timeout.");
1922 } 1966 }
1923 1967
1924 m_scene.IncomingCloseAgent(client.AgentId, true); 1968 m_scene.CloseAgent(client.AgentId, true);
1925 } 1969 }
1926 1970
1927 private void IncomingPacketHandler() 1971 private void IncomingPacketHandler()
@@ -2264,7 +2308,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2264 if (!client.IsLoggingOut) 2308 if (!client.IsLoggingOut)
2265 { 2309 {
2266 client.IsLoggingOut = true; 2310 client.IsLoggingOut = true;
2267 m_scene.IncomingCloseAgent(client.AgentId, false); 2311 m_scene.CloseAgent(client.AgentId, false);
2268 } 2312 }
2269 } 2313 }
2270 } 2314 }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 48c5b37..881e768 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -291,7 +291,16 @@ namespace OpenMetaverse
291 m_log.Warn("[UDPBASE]: Salvaged the UDP listener on port " + m_udpPort); 291 m_log.Warn("[UDPBASE]: Salvaged the UDP listener on port " + m_udpPort);
292 } 292 }
293 } 293 }
294 catch (ObjectDisposedException) { } 294 catch (ObjectDisposedException e)
295 {
296 m_log.Error(
297 string.Format("[UDPBASE]: Error processing UDP begin receive {0}. Exception ", UdpReceives), e);
298 }
299 catch (Exception e)
300 {
301 m_log.Error(
302 string.Format("[UDPBASE]: Error processing UDP begin receive {0}. Exception ", UdpReceives), e);
303 }
295 } 304 }
296 } 305 }
297 306
@@ -308,12 +317,12 @@ namespace OpenMetaverse
308 if (m_asyncPacketHandling) 317 if (m_asyncPacketHandling)
309 AsyncBeginReceive(); 318 AsyncBeginReceive();
310 319
311 // get the buffer that was created in AsyncBeginReceive
312 // this is the received data
313 UDPPacketBuffer buffer = (UDPPacketBuffer)iar.AsyncState;
314
315 try 320 try
316 { 321 {
322 // get the buffer that was created in AsyncBeginReceive
323 // this is the received data
324 UDPPacketBuffer buffer = (UDPPacketBuffer)iar.AsyncState;
325
317 int startTick = Util.EnvironmentTickCount(); 326 int startTick = Util.EnvironmentTickCount();
318 327
319 // get the length of data actually read from the socket, store it with the 328 // get the length of data actually read from the socket, store it with the
@@ -341,8 +350,24 @@ namespace OpenMetaverse
341 m_currentReceiveTimeSamples++; 350 m_currentReceiveTimeSamples++;
342 } 351 }
343 } 352 }
344 catch (SocketException) { } 353 catch (SocketException se)
345 catch (ObjectDisposedException) { } 354 {
355 m_log.Error(
356 string.Format(
357 "[UDPBASE]: Error processing UDP end receive {0}, socket error code {1}. Exception ",
358 UdpReceives, se.ErrorCode),
359 se);
360 }
361 catch (ObjectDisposedException e)
362 {
363 m_log.Error(
364 string.Format("[UDPBASE]: Error processing UDP end receive {0}. Exception ", UdpReceives), e);
365 }
366 catch (Exception e)
367 {
368 m_log.Error(
369 string.Format("[UDPBASE]: Error processing UDP end receive {0}. Exception ", UdpReceives), e);
370 }
346 finally 371 finally
347 { 372 {
348// if (UsePools) 373// if (UsePools)
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs
index 119a677..e2178e5 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs
@@ -52,17 +52,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
52 public override void Update(int frames) {} 52 public override void Update(int frames) {}
53 public override void LoadWorldMap() {} 53 public override void LoadWorldMap() {}
54 54
55 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type) 55 public override ISceneAgent AddNewAgent(IClientAPI client, PresenceType type)
56 { 56 {
57 client.OnObjectName += RecordObjectNameCall; 57 client.OnObjectName += RecordObjectNameCall;
58 58
59 // FIXME 59 // FIXME
60 return null; 60 return null;
61 } 61 }
62 62
63 public override void RemoveClient(UUID agentID, bool someReason) {} 63 public override bool CloseAgent(UUID agentID, bool force) { return true; }
64// public override void CloseAllAgents(uint circuitcode) {} 64
65 public override bool CheckClient(UUID clientId, IPEndPoint endPoint) { return true; } 65 public override bool CheckClient(UUID clientId, IPEndPoint endPoint) { return true; }
66
66 public override void OtherRegionUp(GridRegion otherRegion) { } 67 public override void OtherRegionUp(GridRegion otherRegion) { }
67 68
68 public override bool TryGetScenePresence(UUID uuid, out ScenePresence sp) { sp = null; return false; } 69 public override bool TryGetScenePresence(UUID uuid, out ScenePresence sp) { sp = null; return false; }
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 95cc6b7..81a7278 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -482,13 +482,28 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
482 attachPos = Vector3.Zero; 482 attachPos = Vector3.Zero;
483 } 483 }
484 484
485 // AttachmentPt 0 (default) means the client chose to 'wear' the attachment. 485 // if the attachment point is the same as previous, make sure we get the saved
486 // position info.
487 if (attachmentPt != 0 && attachmentPt == group.RootPart.Shape.LastAttachPoint)
488 {
489 attachPos = group.RootPart.AttachedPos;
490 }
491
492 // AttachmentPt 0 means the client chose to 'wear' the attachment.
486 if (attachmentPt == (uint)AttachmentPoint.Default) 493 if (attachmentPt == (uint)AttachmentPoint.Default)
487 { 494 {
488 // Check object for stored attachment point 495 // Check object for stored attachment point
489 attachmentPt = group.AttachmentPoint; 496 attachmentPt = group.AttachmentPoint;
490 } 497 }
491 498
499 // if we didn't find an attach point, look for where it was last attached
500 if (attachmentPt == 0)
501 {
502 attachmentPt = (uint)group.RootPart.Shape.LastAttachPoint;
503 attachPos = group.RootPart.AttachedPos;
504 group.HasGroupChanged = true;
505 }
506
492 // if we still didn't find a suitable attachment point....... 507 // if we still didn't find a suitable attachment point.......
493 if (attachmentPt == 0) 508 if (attachmentPt == 0)
494 { 509 {
@@ -684,6 +699,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
684 so.ClearPartAttachmentData(); 699 so.ClearPartAttachmentData();
685 rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive,false); 700 rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive,false);
686 so.HasGroupChanged = true; 701 so.HasGroupChanged = true;
702 so.RootPart.Shape.LastAttachPoint = (byte)so.AttachmentPoint;
687 rootPart.Rezzed = DateTime.Now; 703 rootPart.Rezzed = DateTime.Now;
688 rootPart.RemFlag(PrimFlags.TemporaryOnRez); 704 rootPart.RemFlag(PrimFlags.TemporaryOnRez);
689 so.AttachToBackup(); 705 so.AttachToBackup();
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index 62acd78..f023e77 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -719,7 +719,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
719 SceneObjectGroup rezzedAtt = presence.GetAttachments()[0]; 719 SceneObjectGroup rezzedAtt = presence.GetAttachments()[0];
720 720
721 m_numberOfAttachEventsFired = 0; 721 m_numberOfAttachEventsFired = 0;
722 scene.IncomingCloseAgent(presence.UUID, false); 722 scene.CloseAgent(presence.UUID, false);
723 723
724 // Check that we can't retrieve this attachment from the scene. 724 // Check that we can't retrieve this attachment from the scene.
725 Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null); 725 Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null);
diff --git a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
index 6b14fa6..adb838c 100644
--- a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
@@ -276,7 +276,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
276 if (sp.IsChildAgent) 276 if (sp.IsChildAgent)
277 return; 277 return;
278 sp.ControllingClient.Kick(reason); 278 sp.ControllingClient.Kick(reason);
279 sp.Scene.IncomingCloseAgent(sp.UUID, true); 279 sp.Scene.CloseAgent(sp.UUID, true);
280 } 280 }
281 281
282 private void OnIncomingInstantMessage(GridInstantMessage msg) 282 private void OnIncomingInstantMessage(GridInstantMessage msg)
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
index e285f21..03aaaac 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
@@ -149,8 +149,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
149 private void OnInstantMessage(IClientAPI client, GridInstantMessage im) 149 private void OnInstantMessage(IClientAPI client, GridInstantMessage im)
150 { 150 {
151// m_log.DebugFormat( 151// m_log.DebugFormat(
152// "[INVENTORY TRANSFER]: {0} IM type received from {1}", 152// "[INVENTORY TRANSFER]: {0} IM type received from client {1}. From={2} ({3}), To={4}",
153// (InstantMessageDialog)im.dialog, client.Name); 153// (InstantMessageDialog)im.dialog, client.Name,
154// im.fromAgentID, im.fromAgentName, im.toAgentID);
154 155
155 Scene scene = FindClientScene(client.AgentId); 156 Scene scene = FindClientScene(client.AgentId);
156 157
@@ -467,9 +468,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
467 /// <summary> 468 /// <summary>
468 /// 469 ///
469 /// </summary> 470 /// </summary>
470 /// <param name="msg"></param> 471 /// <param name="im"></param>
471 private void OnGridInstantMessage(GridInstantMessage im) 472 private void OnGridInstantMessage(GridInstantMessage im)
472 { 473 {
474 // Check if it's a type of message that we should handle
475 if (!((im.dialog == (byte) InstantMessageDialog.InventoryOffered)
476 || (im.dialog == (byte) InstantMessageDialog.InventoryAccepted)
477 || (im.dialog == (byte) InstantMessageDialog.InventoryDeclined)
478 || (im.dialog == (byte) InstantMessageDialog.TaskInventoryDeclined)))
479 return;
480
481 m_log.DebugFormat(
482 "[INVENTORY TRANSFER]: {0} IM type received from grid. From={1} ({2}), To={3}",
483 (InstantMessageDialog)im.dialog, im.fromAgentID, im.fromAgentName, im.toAgentID);
484
473 // Check if this is ours to handle 485 // Check if this is ours to handle
474 // 486 //
475 Scene scene = FindClientScene(new UUID(im.toAgentID)); 487 Scene scene = FindClientScene(new UUID(im.toAgentID));
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
index 0c64f19..c517a30 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
165 (uint)presence.AbsolutePosition.Y, 165 (uint)presence.AbsolutePosition.Y,
166 (uint)presence.AbsolutePosition.Z + 2); 166 (uint)presence.AbsolutePosition.Z + 2);
167 167
168 m_log.DebugFormat("TP invite with message {0}, type {1}", message, lureType); 168 m_log.DebugFormat("[LURE MODULE]: TP invite with message {0}, type {1}", message, lureType);
169 169
170 GridInstantMessage m; 170 GridInstantMessage m;
171 171
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index ed14c12..ef5239a 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -56,6 +56,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
56 public const int DefaultMaxTransferDistance = 4095; 56 public const int DefaultMaxTransferDistance = 4095;
57 public const bool WaitForAgentArrivedAtDestinationDefault = true; 57 public const bool WaitForAgentArrivedAtDestinationDefault = true;
58 58
59 public string OutgoingTransferVersionName { get; set; }
60
61 /// <summary>
62 /// Determine the maximum entity transfer version we will use for teleports.
63 /// </summary>
64 public float MaxOutgoingTransferVersion { get; set; }
65
59 /// <summary> 66 /// <summary>
60 /// The maximum distance, in standard region units (256m) that an agent is allowed to transfer. 67 /// The maximum distance, in standard region units (256m) that an agent is allowed to transfer.
61 /// </summary> 68 /// </summary>
@@ -151,9 +158,39 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
151 /// <param name="source"></param> 158 /// <param name="source"></param>
152 protected virtual void InitialiseCommon(IConfigSource source) 159 protected virtual void InitialiseCommon(IConfigSource source)
153 { 160 {
161 string transferVersionName = "SIMULATION";
162 float maxTransferVersion = 0.2f;
163
154 IConfig transferConfig = source.Configs["EntityTransfer"]; 164 IConfig transferConfig = source.Configs["EntityTransfer"];
155 if (transferConfig != null) 165 if (transferConfig != null)
156 { 166 {
167 string rawVersion
168 = transferConfig.GetString(
169 "MaxOutgoingTransferVersion",
170 string.Format("{0}/{1}", transferVersionName, maxTransferVersion));
171
172 string[] rawVersionComponents = rawVersion.Split(new char[] { '/' });
173
174 bool versionValid = false;
175
176 if (rawVersionComponents.Length >= 2)
177 versionValid = float.TryParse(rawVersionComponents[1], out maxTransferVersion);
178
179 if (!versionValid)
180 {
181 m_log.ErrorFormat(
182 "[ENTITY TRANSFER MODULE]: MaxOutgoingTransferVersion {0} is invalid, using {1}",
183 rawVersion, string.Format("{0}/{1}", transferVersionName, maxTransferVersion));
184 }
185 else
186 {
187 transferVersionName = rawVersionComponents[0];
188
189 m_log.InfoFormat(
190 "[ENTITY TRANSFER MODULE]: MaxOutgoingTransferVersion set to {0}",
191 string.Format("{0}/{1}", transferVersionName, maxTransferVersion));
192 }
193
157 DisableInterRegionTeleportCancellation 194 DisableInterRegionTeleportCancellation
158 = transferConfig.GetBoolean("DisableInterRegionTeleportCancellation", false); 195 = transferConfig.GetBoolean("DisableInterRegionTeleportCancellation", false);
159 196
@@ -167,6 +204,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
167 MaxTransferDistance = DefaultMaxTransferDistance; 204 MaxTransferDistance = DefaultMaxTransferDistance;
168 } 205 }
169 206
207 OutgoingTransferVersionName = transferVersionName;
208 MaxOutgoingTransferVersion = maxTransferVersion;
209
170 m_entityTransferStateMachine = new EntityTransferStateMachine(this); 210 m_entityTransferStateMachine = new EntityTransferStateMachine(this);
171 211
172 m_Enabled = true; 212 m_Enabled = true;
@@ -522,6 +562,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
522 /// </returns> 562 /// </returns>
523 private bool IsWithinMaxTeleportDistance(RegionInfo sourceRegion, GridRegion destRegion) 563 private bool IsWithinMaxTeleportDistance(RegionInfo sourceRegion, GridRegion destRegion)
524 { 564 {
565 if(MaxTransferDistance == 0)
566 return true;
567
525// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Source co-ords are x={0} y={1}", curRegionX, curRegionY); 568// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Source co-ords are x={0} y={1}", curRegionX, curRegionY);
526// 569//
527// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final dest is x={0} y={1} {2}@{3}", 570// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final dest is x={0} y={1} {2}@{3}",
@@ -623,7 +666,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
623 if (!sp.ValidateAttachments()) 666 if (!sp.ValidateAttachments())
624 m_log.DebugFormat( 667 m_log.DebugFormat(
625 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", 668 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.",
626 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName); 669 sp.Name, sp.Scene.Name, finalDestination.RegionName);
627 670
628 string reason; 671 string reason;
629 string version; 672 string version;
@@ -634,7 +677,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
634 677
635 m_log.DebugFormat( 678 m_log.DebugFormat(
636 "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}", 679 "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}",
637 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); 680 sp.Name, sp.Scene.Name, finalDestination.RegionName, reason);
638 681
639 return; 682 return;
640 } 683 }
@@ -644,7 +687,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
644 // as server attempts. 687 // as server attempts.
645 m_interRegionTeleportAttempts.Value++; 688 m_interRegionTeleportAttempts.Value++;
646 689
647 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); 690 m_log.DebugFormat(
691 "[ENTITY TRANSFER MODULE]: {0} max transfer version is {1}/{2}, {3} max version is {4}",
692 sp.Scene.Name, OutgoingTransferVersionName, MaxOutgoingTransferVersion, finalDestination.RegionName, version);
648 693
649 // Fixing a bug where teleporting while sitting results in the avatar ending up removed from 694 // Fixing a bug where teleporting while sitting results in the avatar ending up removed from
650 // both regions 695 // both regions
@@ -691,7 +736,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
691 agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); 736 agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
692 } 737 }
693 738
694 if (version.Equals("SIMULATION/0.2")) 739 // We're going to fallback to V1 if the destination gives us anything smaller than 0.2 or we're forcing
740 // use of the earlier protocol
741 float versionNumber = 0.1f;
742 string[] versionComponents = version.Split(new char[] { '/' });
743 if (versionComponents.Length >= 2)
744 float.TryParse(versionComponents[1], out versionNumber);
745
746 if (versionNumber == 0.2f && MaxOutgoingTransferVersion >= versionNumber)
695 TransferAgent_V2(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason); 747 TransferAgent_V2(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason);
696 else 748 else
697 TransferAgent_V1(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason); 749 TransferAgent_V1(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason);
@@ -925,7 +977,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
925 977
926 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) 978 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
927 { 979 {
928 if (!sp.Scene.IncomingPreCloseAgent(sp)) 980 if (!sp.Scene.IncomingPreCloseClient(sp))
929 return; 981 return;
930 982
931 // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before 983 // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before
@@ -936,7 +988,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
936 // an agent cannot teleport back to this region if it has teleported away. 988 // an agent cannot teleport back to this region if it has teleported away.
937 Thread.Sleep(2000); 989 Thread.Sleep(2000);
938 990
939 sp.Scene.IncomingCloseAgent(sp.UUID, false); 991 sp.Scene.CloseAgent(sp.UUID, false);
940 } 992 }
941 else 993 else
942 { 994 {
@@ -1090,7 +1142,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1090 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone 1142 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
1091 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) 1143 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
1092 { 1144 {
1093 if (!sp.Scene.IncomingPreCloseAgent(sp)) 1145 if (!sp.Scene.IncomingPreCloseClient(sp))
1094 return; 1146 return;
1095 1147
1096 // RED ALERT!!!! 1148 // RED ALERT!!!!
@@ -1107,7 +1159,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1107 m_log.DebugFormat( 1159 m_log.DebugFormat(
1108 "[ENTITY TRANSFER MODULE]: Closing agent {0} in {1} after teleport", sp.Name, Scene.Name); 1160 "[ENTITY TRANSFER MODULE]: Closing agent {0} in {1} after teleport", sp.Name, Scene.Name);
1109 1161
1110 sp.Scene.IncomingCloseAgent(sp.UUID, false); 1162 sp.Scene.CloseAgent(sp.UUID, false);
1111 } 1163 }
1112 else 1164 else
1113 { 1165 {
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index 1cf1884..74b834a 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -181,7 +181,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
181 if (aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI")) 181 if (aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
182 { 182 {
183 string url = aCircuit.ServiceURLs["AssetServerURI"].ToString(); 183 string url = aCircuit.ServiceURLs["AssetServerURI"].ToString();
184 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Incoming attachement {0} for HG user {1} with asset server {2}", so.Name, so.AttachedAvatar, url); 184 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Incoming attachment {0} for HG user {1} with asset server {2}", so.Name, so.AttachedAvatar, url);
185 Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>(); 185 Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>();
186 HGUuidGatherer uuidGatherer = new HGUuidGatherer(Scene.AssetService, url); 186 HGUuidGatherer uuidGatherer = new HGUuidGatherer(Scene.AssetService, url);
187 uuidGatherer.GatherAssetUuids(so, ids); 187 uuidGatherer.GatherAssetUuids(so, ids);
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index 89bb037..3feeb13 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -906,6 +906,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
906 m_log.Debug("[INVENTORY ACCESS MODULE]: Object has UUID.Zero! Position 3"); 906 m_log.Debug("[INVENTORY ACCESS MODULE]: Object has UUID.Zero! Position 3");
907 } 907 }
908 908
909 // if this was previously an attachment and is now being rezzed,
910 // save the old attachment info.
911 if (group.IsAttachment == false && group.RootPart.Shape.State != 0)
912 {
913 group.RootPart.AttachedPos = group.AbsolutePosition;
914 group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint;
915 }
916
909 foreach (SceneObjectPart part in group.Parts) 917 foreach (SceneObjectPart part in group.Parts)
910 { 918 {
911 // Make the rezzer the owner, as this is not necessarily set correctly in the serialized asset. 919 // Make the rezzer the owner, as this is not necessarily set correctly in the serialized asset.
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index 8c983e6..d3926cc 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -178,17 +178,20 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
178 m_ServiceThrottle.Enqueue("name", uuid.ToString(), delegate 178 m_ServiceThrottle.Enqueue("name", uuid.ToString(), delegate
179 { 179 {
180 //m_log.DebugFormat("[YYY]: Name request {0}", uuid); 180 //m_log.DebugFormat("[YYY]: Name request {0}", uuid);
181 bool foundRealName = TryGetUserNames(uuid, names);
182
183 if (names.Length == 2)
184 {
185 if (!foundRealName)
186 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Sending {0} {1} for {2} to {3} since no bound name found", names[0], names[1], uuid, client.Name);
187 181
182 // As least upto September 2013, clients permanently cache UUID -> Name bindings. Some clients
183 // appear to clear this when the user asks it to clear the cache, but others may not.
184 //
185 // So to avoid clients
186 // (particularly Hypergrid clients) permanently binding "Unknown User" to a given UUID, we will
187 // instead drop the request entirely.
188 if (TryGetUserNames(uuid, names))
188 client.SendNameReply(uuid, names[0], names[1]); 189 client.SendNameReply(uuid, names[0], names[1]);
189 } 190// else
191// m_log.DebugFormat(
192// "[USER MANAGEMENT MODULE]: No bound name for {0} found, ignoring request from {1}",
193// uuid, client.Name);
190 }); 194 });
191
192 } 195 }
193 } 196 }
194 197
@@ -391,7 +394,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
391 } 394 }
392 395
393 names[0] = "Unknown"; 396 names[0] = "Unknown";
394 names[1] = "UserUMMTGUN8"; 397 names[1] = "UserUMMTGUN9";
395 398
396 return false; 399 return false;
397 } 400 }
@@ -539,7 +542,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
539 AddUser(uuid, homeURL + ";" + first + " " + last); 542 AddUser(uuid, homeURL + ";" + first + " " + last);
540 } 543 }
541 544
542 public void AddUser (UUID id, string creatorData) 545 public void AddUser(UUID id, string creatorData)
543 { 546 {
544 //m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData); 547 //m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData);
545 548
@@ -599,6 +602,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
599 user.LastName = "@unknown"; 602 user.LastName = "@unknown";
600 } 603 }
601 } 604 }
605
602 if (parts.Length >= 2) 606 if (parts.Length >= 2)
603 user.FirstName = parts[1].Replace(' ', '.'); 607 user.FirstName = parts[1].Replace(' ', '.');
604 } 608 }
@@ -611,7 +615,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
611 user.FirstName = "Unknown"; 615 user.FirstName = "Unknown";
612 user.LastName = "UserUMMAU4"; 616 user.LastName = "UserUMMAU4";
613 } 617 }
614 618
615 AddUserInternal(user); 619 AddUserInternal(user);
616 } 620 }
617 } 621 }
@@ -639,6 +643,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
639 643
640 protected void Init() 644 protected void Init()
641 { 645 {
646 AddUser(UUID.Zero, "Unknown", "User");
642 RegisterConsoleCmds(); 647 RegisterConsoleCmds();
643 } 648 }
644 649
diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
index f196973..8946b5c 100644
--- a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
@@ -129,7 +129,7 @@ namespace OpenSim.Region.CoreModules.Hypergrid
129 b.Access = 254; // means 'simulator is offline'. We need this because the viewer ignores 255's 129 b.Access = 254; // means 'simulator is offline'. We need this because the viewer ignores 255's
130 } 130 }
131 131
132 m_log.DebugFormat("[HG MAP]: Reseting {0} blocks", mapBlocks.Count); 132 m_log.DebugFormat("[HG MAP]: Resetting {0} blocks", mapBlocks.Count);
133 sp.ControllingClient.SendMapBlock(mapBlocks, 0); 133 sp.ControllingClient.SendMapBlock(mapBlocks, 0);
134 m_SeenMapBlocks.Remove(clientID); 134 m_SeenMapBlocks.Remove(clientID);
135 } 135 }
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
index a9aa73c..3be80eb 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
@@ -94,7 +94,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
94 throw new Exception(string.Format("Invalid ConnectorProtocolVersion {0}", ServiceVersion)); 94 throw new Exception(string.Format("Invalid ConnectorProtocolVersion {0}", ServiceVersion));
95 95
96 m_log.InfoFormat( 96 m_log.InfoFormat(
97 "[LOCAL SIMULATION CONNECTOR]: Initialzied with connector protocol version {0}", ServiceVersion); 97 "[LOCAL SIMULATION CONNECTOR]: Initialized with connector protocol version {0}", ServiceVersion);
98 } 98 }
99 } 99 }
100 100
@@ -235,7 +235,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
235// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", 235// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
236// destination.RegionName, destination.RegionID); 236// destination.RegionName, destination.RegionID);
237 237
238 return m_scenes[destination.RegionID].IncomingChildAgentDataUpdate(cAgentData); 238 return m_scenes[destination.RegionID].IncomingUpdateChildAgent(cAgentData);
239 } 239 }
240 240
241// m_log.DebugFormat( 241// m_log.DebugFormat(
@@ -245,7 +245,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
245 return false; 245 return false;
246 } 246 }
247 247
248 public bool UpdateAgent(GridRegion destination, AgentPosition cAgentData) 248 public bool UpdateAgent(GridRegion destination, AgentPosition agentPosition)
249 { 249 {
250 if (destination == null) 250 if (destination == null)
251 return false; 251 return false;
@@ -257,7 +257,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
257 foreach (Scene s in m_scenes.Values) 257 foreach (Scene s in m_scenes.Values)
258 { 258 {
259// m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); 259// m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate");
260 s.IncomingChildAgentDataUpdate(cAgentData); 260 s.IncomingUpdateChildAgent(agentPosition);
261 } 261 }
262 262
263 //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); 263 //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate");
@@ -311,7 +311,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
311// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", 311// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
312// s.RegionInfo.RegionName, destination.RegionHandle); 312// s.RegionInfo.RegionName, destination.RegionHandle);
313 313
314 m_scenes[destination.RegionID].IncomingCloseAgent(id, false, auth_token); 314 m_scenes[destination.RegionID].CloseAgent(id, false, auth_token);
315 return true; 315 return true;
316 } 316 }
317 //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); 317 //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent");
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index 1808fdd..487aa09 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
@@ -572,7 +572,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
572 if (!Scene.TeleportClientHome(user, s.ControllingClient)) 572 if (!Scene.TeleportClientHome(user, s.ControllingClient))
573 { 573 {
574 s.ControllingClient.Kick("Your access to the region was revoked and TP home failed - you have been logged out."); 574 s.ControllingClient.Kick("Your access to the region was revoked and TP home failed - you have been logged out.");
575 Scene.IncomingCloseAgent(s.UUID, false); 575 Scene.CloseAgent(s.UUID, false);
576 } 576 }
577 } 577 }
578 } 578 }
@@ -807,7 +807,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
807 if (!Scene.TeleportClientHome(prey, s.ControllingClient)) 807 if (!Scene.TeleportClientHome(prey, s.ControllingClient))
808 { 808 {
809 s.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out."); 809 s.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out.");
810 Scene.IncomingCloseAgent(s.UUID, false); 810 Scene.CloseAgent(s.UUID, false);
811 } 811 }
812 } 812 }
813 } 813 }
@@ -830,7 +830,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
830 if (!Scene.TeleportClientHome(p.UUID, p.ControllingClient)) 830 if (!Scene.TeleportClientHome(p.UUID, p.ControllingClient))
831 { 831 {
832 p.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out."); 832 p.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out.");
833 Scene.IncomingCloseAgent(p.UUID, false); 833 Scene.CloseAgent(p.UUID, false);
834 } 834 }
835 } 835 }
836 } 836 }
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 6e8eb91..7f06e82 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -148,7 +148,7 @@ namespace OpenSim.Region.Framework.Scenes
148 /// Triggered when a new presence is added to the scene 148 /// Triggered when a new presence is added to the scene
149 /// </summary> 149 /// </summary>
150 /// <remarks> 150 /// <remarks>
151 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.AddNewClient"/> which is used by both 151 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.AddNewAgent"/> which is used by both
152 /// <see cref="OpenSim.Framework.PresenceType.User">users</see> and <see cref="OpenSim.Framework.PresenceType.Npc">NPCs</see> 152 /// <see cref="OpenSim.Framework.PresenceType.User">users</see> and <see cref="OpenSim.Framework.PresenceType.Npc">NPCs</see>
153 /// </remarks> 153 /// </remarks>
154 public event OnNewPresenceDelegate OnNewPresence; 154 public event OnNewPresenceDelegate OnNewPresence;
@@ -159,7 +159,7 @@ namespace OpenSim.Region.Framework.Scenes
159 /// Triggered when a presence is removed from the scene 159 /// Triggered when a presence is removed from the scene
160 /// </summary> 160 /// </summary>
161 /// <remarks> 161 /// <remarks>
162 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.AddNewClient"/> which is used by both 162 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.AddNewAgent"/> which is used by both
163 /// <see cref="OpenSim.Framework.PresenceType.User">users</see> and <see cref="OpenSim.Framework.PresenceType.Npc">NPCs</see> 163 /// <see cref="OpenSim.Framework.PresenceType.User">users</see> and <see cref="OpenSim.Framework.PresenceType.Npc">NPCs</see>
164 /// 164 ///
165 /// Triggered under per-agent lock. So if you want to perform any long-running operations, please 165 /// Triggered under per-agent lock. So if you want to perform any long-running operations, please
@@ -1107,7 +1107,7 @@ namespace OpenSim.Region.Framework.Scenes
1107 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.ProcessMoneyTransferRequest"/> 1107 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.ProcessMoneyTransferRequest"/>
1108 /// via <see cref="OpenSim.Region.Framework.Scenes.Scene.SubscribeToClientGridEvents"/> 1108 /// via <see cref="OpenSim.Region.Framework.Scenes.Scene.SubscribeToClientGridEvents"/>
1109 /// via <see cref="OpenSim.Region.Framework.Scenes.Scene.SubscribeToClientEvents"/> 1109 /// via <see cref="OpenSim.Region.Framework.Scenes.Scene.SubscribeToClientEvents"/>
1110 /// via <see cref="OpenSim.Region.Framework.Scenes.Scene.AddNewClient"/> 1110 /// via <see cref="OpenSim.Region.Framework.Scenes.Scene.AddNewAgent"/>
1111 /// </remarks> 1111 /// </remarks>
1112 public event MoneyTransferEvent OnMoneyTransfer; 1112 public event MoneyTransferEvent OnMoneyTransfer;
1113 1113
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 4337b5a..659bde9 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -507,6 +507,9 @@ namespace OpenSim.Region.Framework.Scenes
507 // This MAY be problematic, if it is, another solution 507 // This MAY be problematic, if it is, another solution
508 // needs to be found. If inventory item flags are updated 508 // needs to be found. If inventory item flags are updated
509 // the viewer's notion of the item needs to be refreshed. 509 // the viewer's notion of the item needs to be refreshed.
510 //
511 // In other situations we cannot send out a bulk update here, since this will cause editing of clothing to start
512 // failing frequently. Possibly this is a race with a separate transaction that uploads the asset.
510 if (sendUpdate) 513 if (sendUpdate)
511 remoteClient.SendBulkUpdateInventory(item); 514 remoteClient.SendBulkUpdateInventory(item);
512 } 515 }
@@ -2393,6 +2396,13 @@ namespace OpenSim.Region.Framework.Scenes
2393 sourcePart.Inventory.RemoveInventoryItem(item.ItemID); 2396 sourcePart.Inventory.RemoveInventoryItem(item.ItemID);
2394 } 2397 }
2395 2398
2399
2400 if (group.IsAttachment == false && group.RootPart.Shape.State != 0)
2401 {
2402 group.RootPart.AttachedPos = group.AbsolutePosition;
2403 group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint;
2404 }
2405
2396 group.FromPartID = sourcePart.UUID; 2406 group.FromPartID = sourcePart.UUID;
2397 AddNewSceneObject(group, true, pos, rot, vel); 2407 AddNewSceneObject(group, true, pos, rot, vel);
2398 2408
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index d6d2df4..21036d8 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -751,6 +751,7 @@ namespace OpenSim.Region.Framework.Scenes
751 m_config = config; 751 m_config = config;
752 MinFrameTime = 0.089f; 752 MinFrameTime = 0.089f;
753 MinMaintenanceTime = 1; 753 MinMaintenanceTime = 1;
754 SeeIntoRegion = true;
754 755
755 Random random = new Random(); 756 Random random = new Random();
756 757
@@ -863,6 +864,7 @@ namespace OpenSim.Region.Framework.Scenes
863 //Animation states 864 //Animation states
864 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); 865 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
865 866
867 SeeIntoRegion = startupConfig.GetBoolean("see_into_region", SeeIntoRegion);
866 868
867 MaxUndoCount = startupConfig.GetInt("MaxPrimUndos", 20); 869 MaxUndoCount = startupConfig.GetInt("MaxPrimUndos", 20);
868 870
@@ -1338,7 +1340,7 @@ namespace OpenSim.Region.Framework.Scenes
1338 Thread.Sleep(500); 1340 Thread.Sleep(500);
1339 1341
1340 // Stop all client threads. 1342 // Stop all client threads.
1341 ForEachScenePresence(delegate(ScenePresence avatar) { IncomingCloseAgent(avatar.UUID, false); }); 1343 ForEachScenePresence(delegate(ScenePresence avatar) { CloseAgent(avatar.UUID, false); });
1342 1344
1343 m_log.Debug("[SCENE]: TriggerSceneShuttingDown"); 1345 m_log.Debug("[SCENE]: TriggerSceneShuttingDown");
1344 EventManager.TriggerSceneShuttingDown(this); 1346 EventManager.TriggerSceneShuttingDown(this);
@@ -2953,7 +2955,7 @@ namespace OpenSim.Region.Framework.Scenes
2953 2955
2954 #region Add/Remove Avatar Methods 2956 #region Add/Remove Avatar Methods
2955 2957
2956 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type) 2958 public override ISceneAgent AddNewAgent(IClientAPI client, PresenceType type)
2957 { 2959 {
2958 ScenePresence sp; 2960 ScenePresence sp;
2959 bool vialogin; 2961 bool vialogin;
@@ -2961,7 +2963,7 @@ namespace OpenSim.Region.Framework.Scenes
2961 2963
2962 // Validation occurs in LLUDPServer 2964 // Validation occurs in LLUDPServer
2963 // 2965 //
2964 // XXX: A race condition exists here where two simultaneous calls to AddNewClient can interfere with 2966 // XXX: A race condition exists here where two simultaneous calls to AddNewAgent can interfere with
2965 // each other. In practice, this does not currently occur in the code. 2967 // each other. In practice, this does not currently occur in the code.
2966 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode); 2968 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode);
2967 2969
@@ -2969,9 +2971,9 @@ namespace OpenSim.Region.Framework.Scenes
2969 // and a simultaneous one that removes it (as can happen if the client is closed at a particular point 2971 // and a simultaneous one that removes it (as can happen if the client is closed at a particular point
2970 // whilst connecting). 2972 // whilst connecting).
2971 // 2973 //
2972 // It would be easier to lock across all NewUserConnection(), AddNewClient() and 2974 // It would be easier to lock across all NewUserConnection(), AddNewAgent() and
2973 // RemoveClient() calls for all agents, but this would allow a slow call (e.g. because of slow service 2975 // RemoveClient() calls for all agents, but this would allow a slow call (e.g. because of slow service
2974 // response in some module listening to AddNewClient()) from holding up unrelated agent calls. 2976 // response in some module listening to AddNewAgent()) from holding up unrelated agent calls.
2975 // 2977 //
2976 // In practice, the lock (this) in LLUDPServer.AddNewClient() currently lock across all 2978 // In practice, the lock (this) in LLUDPServer.AddNewClient() currently lock across all
2977 // AddNewClient() operations (though not other ops). 2979 // AddNewClient() operations (though not other ops).
@@ -2988,7 +2990,7 @@ namespace OpenSim.Region.Framework.Scenes
2988 2990
2989 // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this 2991 // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this
2990 // could occur if a viewer crashes and relogs before the old client is kicked out. But this could cause 2992 // could occur if a viewer crashes and relogs before the old client is kicked out. But this could cause
2991 // other problems, and possible the code calling AddNewClient() should ensure that no client is already 2993 // other problems, and possibly the code calling AddNewAgent() should ensure that no client is already
2992 // connected. 2994 // connected.
2993 if (sp == null) 2995 if (sp == null)
2994 { 2996 {
@@ -3021,6 +3023,9 @@ namespace OpenSim.Region.Framework.Scenes
3021 3023
3022 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the 3024 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the
3023 // client is for a root or child agent. 3025 // client is for a root or child agent.
3026 // XXX: This may be better set for a new client before that client is added to the client manager.
3027 // But need to know what happens in the case where a ScenePresence is already present (and if this
3028 // actually occurs).
3024 client.SceneAgent = sp; 3029 client.SceneAgent = sp;
3025 3030
3026 // This is currently also being done earlier in NewUserConnection for real users to see if this 3031 // This is currently also being done earlier in NewUserConnection for real users to see if this
@@ -3130,7 +3135,7 @@ namespace OpenSim.Region.Framework.Scenes
3130 { 3135 {
3131 PresenceService.LogoutAgent(sp.ControllingClient.SessionId); 3136 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
3132 3137
3133 IncomingCloseAgent(sp.UUID, false); 3138 CloseAgent(sp.UUID, false);
3134 } 3139 }
3135 3140
3136 // BANG! SLASH! 3141 // BANG! SLASH!
@@ -3554,7 +3559,7 @@ namespace OpenSim.Region.Framework.Scenes
3554 /// <param name='closeChildAgents'> 3559 /// <param name='closeChildAgents'>
3555 /// Close the neighbour child agents associated with this client. 3560 /// Close the neighbour child agents associated with this client.
3556 /// </param> 3561 /// </param>
3557 public override void RemoveClient(UUID agentID, bool closeChildAgents) 3562 public void RemoveClient(UUID agentID, bool closeChildAgents)
3558 { 3563 {
3559 AgentCircuitData acd = m_authenticateHandler.GetAgentCircuitData(agentID); 3564 AgentCircuitData acd = m_authenticateHandler.GetAgentCircuitData(agentID);
3560 3565
@@ -3940,7 +3945,7 @@ namespace OpenSim.Region.Framework.Scenes
3940 sp.Name, sp.UUID, RegionInfo.RegionName); 3945 sp.Name, sp.UUID, RegionInfo.RegionName);
3941 3946
3942 if (sp.ControllingClient != null) 3947 if (sp.ControllingClient != null)
3943 IncomingCloseAgent(sp.UUID, true); 3948 CloseAgent(sp.UUID, true);
3944 3949
3945 sp = null; 3950 sp = null;
3946 } 3951 }
@@ -4024,19 +4029,6 @@ namespace OpenSim.Region.Framework.Scenes
4024 // Let the SP know how we got here. This has a lot of interesting 4029 // Let the SP know how we got here. This has a lot of interesting
4025 // uses down the line. 4030 // uses down the line.
4026 sp.TeleportFlags = (TPFlags)teleportFlags; 4031 sp.TeleportFlags = (TPFlags)teleportFlags;
4027
4028 // We must carry out a further authorization check if there's an
4029 // attempt to make a child agent into a root agent, since SeeIntoRegion may have allowed a child
4030 // agent to login to a region where a full avatar would not be allowed.
4031 //
4032 // We determine whether this is a CreateAgent for a future non-child agent by inspecting
4033 // TeleportFlags, which will be default for a child connection. This relies on input from the source
4034 // region.
4035 if (sp.TeleportFlags != TPFlags.Default)
4036 {
4037 if (!AuthorizeUser(acd, false, out reason))
4038 return false;
4039 }
4040 4032
4041 if (sp.IsChildAgent) 4033 if (sp.IsChildAgent)
4042 { 4034 {
@@ -4469,7 +4461,7 @@ namespace OpenSim.Region.Framework.Scenes
4469 /// <param name="cAgentData">Agent that contains all of the relevant things about an agent. 4461 /// <param name="cAgentData">Agent that contains all of the relevant things about an agent.
4470 /// Appearance, animations, position, etc.</param> 4462 /// Appearance, animations, position, etc.</param>
4471 /// <returns>true if we handled it.</returns> 4463 /// <returns>true if we handled it.</returns>
4472 public virtual bool IncomingChildAgentDataUpdate(AgentData cAgentData) 4464 public virtual bool IncomingUpdateChildAgent(AgentData cAgentData)
4473 { 4465 {
4474 m_log.DebugFormat( 4466 m_log.DebugFormat(
4475 "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName); 4467 "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName);
@@ -4487,7 +4479,7 @@ namespace OpenSim.Region.Framework.Scenes
4487 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); 4479 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2);
4488 if (nearestParcel == null) 4480 if (nearestParcel == null)
4489 { 4481 {
4490 m_log.DebugFormat( 4482 m_log.InfoFormat(
4491 "[SCENE]: Denying root agent entry to {0} in {1}: no allowed parcel", 4483 "[SCENE]: Denying root agent entry to {0} in {1}: no allowed parcel",
4492 cAgentData.AgentID, RegionInfo.RegionName); 4484 cAgentData.AgentID, RegionInfo.RegionName);
4493 4485
@@ -4497,7 +4489,7 @@ namespace OpenSim.Region.Framework.Scenes
4497 // We have to wait until the viewer contacts this region 4489 // We have to wait until the viewer contacts this region
4498 // after receiving the EnableSimulator HTTP Event Queue message (for the v1 teleport protocol) 4490 // after receiving the EnableSimulator HTTP Event Queue message (for the v1 teleport protocol)
4499 // or TeleportFinish (for the v2 teleport protocol). This triggers the viewer to send 4491 // or TeleportFinish (for the v2 teleport protocol). This triggers the viewer to send
4500 // a UseCircuitCode packet which in turn calls AddNewClient which finally creates the ScenePresence. 4492 // a UseCircuitCode packet which in turn calls AddNewAgent which finally creates the ScenePresence.
4501 ScenePresence sp = WaitGetScenePresence(cAgentData.AgentID); 4493 ScenePresence sp = WaitGetScenePresence(cAgentData.AgentID);
4502 4494
4503 if (sp != null) 4495 if (sp != null)
@@ -4512,7 +4504,7 @@ namespace OpenSim.Region.Framework.Scenes
4512 sp.UUID, sp.ControllingClient.SessionId, cAgentData.SessionID)); 4504 sp.UUID, sp.ControllingClient.SessionId, cAgentData.SessionID));
4513 } 4505 }
4514 4506
4515 sp.ChildAgentDataUpdate(cAgentData); 4507 sp.UpdateChildAgent(cAgentData);
4516 4508
4517 int ntimes = 20; 4509 int ntimes = 20;
4518 if (cAgentData.SenderWantsToWaitForRoot) 4510 if (cAgentData.SenderWantsToWaitForRoot)
@@ -4520,9 +4512,14 @@ namespace OpenSim.Region.Framework.Scenes
4520 while (sp.IsChildAgent && ntimes-- > 0) 4512 while (sp.IsChildAgent && ntimes-- > 0)
4521 Thread.Sleep(1000); 4513 Thread.Sleep(1000);
4522 4514
4523 m_log.DebugFormat( 4515 if (sp.IsChildAgent)
4524 "[SCENE]: Found presence {0} {1} {2} in {3} after {4} waits", 4516 m_log.WarnFormat(
4525 sp.Name, sp.UUID, sp.IsChildAgent ? "child" : "root", Name, 20 - ntimes); 4517 "[SCENE]: Found presence {0} {1} unexpectedly still child in {2}",
4518 sp.Name, sp.UUID, Name);
4519 else
4520 m_log.InfoFormat(
4521 "[SCENE]: Found presence {0} {1} as root in {2} after {3} waits",
4522 sp.Name, sp.UUID, Name, 20 - ntimes);
4526 4523
4527 if (sp.IsChildAgent) 4524 if (sp.IsChildAgent)
4528 return false; 4525 return false;
@@ -4540,7 +4537,7 @@ namespace OpenSim.Region.Framework.Scenes
4540 /// </summary> 4537 /// </summary>
4541 /// <param name="cAgentData">AgentPosition that contains agent positional data so we can know what to send</param> 4538 /// <param name="cAgentData">AgentPosition that contains agent positional data so we can know what to send</param>
4542 /// <returns>true if we handled it.</returns> 4539 /// <returns>true if we handled it.</returns>
4543 public virtual bool IncomingChildAgentDataUpdate(AgentPosition cAgentData) 4540 public virtual bool IncomingUpdateChildAgent(AgentPosition cAgentData)
4544 { 4541 {
4545 //m_log.Debug(" XXX Scene IncomingChildAgentDataUpdate POSITION in " + RegionInfo.RegionName); 4542 //m_log.Debug(" XXX Scene IncomingChildAgentDataUpdate POSITION in " + RegionInfo.RegionName);
4546 ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID); 4543 ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID);
@@ -4560,7 +4557,7 @@ namespace OpenSim.Region.Framework.Scenes
4560 uint tRegionX = RegionInfo.RegionLocX; 4557 uint tRegionX = RegionInfo.RegionLocX;
4561 uint tRegionY = RegionInfo.RegionLocY; 4558 uint tRegionY = RegionInfo.RegionLocY;
4562 //Send Data to ScenePresence 4559 //Send Data to ScenePresence
4563 childAgentUpdate.ChildAgentDataUpdate(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY); 4560 childAgentUpdate.UpdateChildAgent(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY);
4564 // Not Implemented: 4561 // Not Implemented:
4565 //TODO: Do we need to pass the message on to one of our neighbors? 4562 //TODO: Do we need to pass the message on to one of our neighbors?
4566 } 4563 }
@@ -4610,7 +4607,7 @@ namespace OpenSim.Region.Framework.Scenes
4610 /// <param name="force"></param> 4607 /// <param name="force"></param>
4611 /// <param name="auth_token"></param> 4608 /// <param name="auth_token"></param>
4612 /// <returns></returns> 4609 /// <returns></returns>
4613 public bool IncomingCloseAgent(UUID agentID, bool force, string auth_token) 4610 public bool CloseAgent(UUID agentID, bool force, string auth_token)
4614 { 4611 {
4615 //m_log.DebugFormat("[SCENE]: Processing incoming close agent {0} in region {1} with auth_token {2}", agentID, RegionInfo.RegionName, auth_token); 4612 //m_log.DebugFormat("[SCENE]: Processing incoming close agent {0} in region {1} with auth_token {2}", agentID, RegionInfo.RegionName, auth_token);
4616 4613
@@ -4628,7 +4625,7 @@ namespace OpenSim.Region.Framework.Scenes
4628 4625
4629 if (acd.SessionID.ToString() == auth_token) 4626 if (acd.SessionID.ToString() == auth_token)
4630 { 4627 {
4631 return IncomingCloseAgent(agentID, force); 4628 return CloseAgent(agentID, force);
4632 } 4629 }
4633 else 4630 else
4634 { 4631 {
@@ -4640,27 +4637,27 @@ namespace OpenSim.Region.Framework.Scenes
4640 return false; 4637 return false;
4641 } 4638 }
4642 4639
4643 public bool IncomingCloseAgent(UUID agentID) 4640// public bool IncomingCloseAgent(UUID agentID)
4644 { 4641// {
4645 return IncomingCloseAgent(agentID, false); 4642// return IncomingCloseAgent(agentID, false);
4646 } 4643// }
4647 4644
4648 public bool IncomingCloseChildAgent(UUID agentID) 4645// public bool IncomingCloseChildAgent(UUID agentID)
4649 { 4646// {
4650 return IncomingCloseAgent(agentID, true); 4647// return IncomingCloseAgent(agentID, true);
4651 } 4648// }
4652 4649
4653 /// <summary> 4650 /// <summary>
4654 /// Tell a single agent to prepare to close. 4651 /// Tell a single client to prepare to close.
4655 /// </summary> 4652 /// </summary>
4656 /// <remarks> 4653 /// <remarks>
4657 /// This should only be called if we may close the agent but there will be some delay in so doing. Meant for 4654 /// This should only be called if we may close the client but there will be some delay in so doing. Meant for
4658 /// internal use - other callers should almost certainly called IncomingCloseAgent(). 4655 /// internal use - other callers should almost certainly called CloseClient().
4659 /// </remarks> 4656 /// </remarks>
4660 /// <param name="sp"></param> 4657 /// <param name="sp"></param>
4661 /// <returns>true if pre-close state notification was successful. false if the agent 4658 /// <returns>true if pre-close state notification was successful. false if the agent
4662 /// was not in a state where it could transition to pre-close.</returns> 4659 /// was not in a state where it could transition to pre-close.</returns>
4663 public bool IncomingPreCloseAgent(ScenePresence sp) 4660 public bool IncomingPreCloseClient(ScenePresence sp)
4664 { 4661 {
4665 lock (m_removeClientLock) 4662 lock (m_removeClientLock)
4666 { 4663 {
@@ -4702,7 +4699,7 @@ namespace OpenSim.Region.Framework.Scenes
4702 /// Force the agent to close even if it might be in the middle of some other operation. You do not want to 4699 /// Force the agent to close even if it might be in the middle of some other operation. You do not want to
4703 /// force unless you are absolutely sure that the agent is dead and a normal close is not working. 4700 /// force unless you are absolutely sure that the agent is dead and a normal close is not working.
4704 /// </param> 4701 /// </param>
4705 public bool IncomingCloseAgent(UUID agentID, bool force) 4702 public override bool CloseAgent(UUID agentID, bool force)
4706 { 4703 {
4707 ScenePresence sp; 4704 ScenePresence sp;
4708 4705
@@ -4713,7 +4710,7 @@ namespace OpenSim.Region.Framework.Scenes
4713 if (sp == null) 4710 if (sp == null)
4714 { 4711 {
4715 m_log.DebugFormat( 4712 m_log.DebugFormat(
4716 "[SCENE]: Called IncomingCloseAgent() with agent ID {0} but no such presence is in {1}", 4713 "[SCENE]: Called CloseClient() with agent ID {0} but no such presence is in {1}",
4717 agentID, Name); 4714 agentID, Name);
4718 4715
4719 return false; 4716 return false;
@@ -4722,7 +4719,7 @@ namespace OpenSim.Region.Framework.Scenes
4722 if (sp.LifecycleState != ScenePresenceState.Running && sp.LifecycleState != ScenePresenceState.PreRemove) 4719 if (sp.LifecycleState != ScenePresenceState.Running && sp.LifecycleState != ScenePresenceState.PreRemove)
4723 { 4720 {
4724 m_log.DebugFormat( 4721 m_log.DebugFormat(
4725 "[SCENE]: Called IncomingCloseAgent() for {0} in {1} but presence is already in state {2}", 4722 "[SCENE]: Called CloseClient() for {0} in {1} but presence is already in state {2}",
4726 sp.Name, Name, sp.LifecycleState); 4723 sp.Name, Name, sp.LifecycleState);
4727 4724
4728 return false; 4725 return false;
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs
index 1dac676..9354a88 100644
--- a/OpenSim/Region/Framework/Scenes/SceneBase.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs
@@ -217,21 +217,9 @@ namespace OpenSim.Region.Framework.Scenes
217 217
218 #region Add/Remove Agent/Avatar 218 #region Add/Remove Agent/Avatar
219 219
220 public abstract ISceneAgent AddNewClient(IClientAPI client, PresenceType type); 220 public abstract ISceneAgent AddNewAgent(IClientAPI client, PresenceType type);
221 221
222 /// <summary> 222 public abstract bool CloseAgent(UUID agentID, bool force);
223 /// Remove the given client from the scene.
224 /// </summary>
225 /// <remarks>
226 /// Only clientstack code should call this directly. All other code should call IncomingCloseAgent() instead
227 /// to properly operate the state machine and avoid race conditions with other close requests (such as directly
228 /// from viewers).
229 /// </remarks>
230 /// <param name='agentID'>ID of agent to close</param>
231 /// <param name='closeChildAgents'>
232 /// Close the neighbour child agents associated with this client.
233 /// </param>
234 public abstract void RemoveClient(UUID agentID, bool closeChildAgents);
235 223
236 public bool TryGetScenePresence(UUID agentID, out object scenePresence) 224 public bool TryGetScenePresence(UUID agentID, out object scenePresence)
237 { 225 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index cf03d7c..66b42a1 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -2960,6 +2960,26 @@ namespace OpenSim.Region.Framework.Scenes
2960 //ParentGroup.RootPart.m_groupPosition = newpos; 2960 //ParentGroup.RootPart.m_groupPosition = newpos;
2961 } 2961 }
2962 2962
2963 if (pa != null && ParentID != 0 && ParentGroup != null)
2964 {
2965 // Special case where a child object is requesting property updates.
2966 // This happens when linksets are modified to use flexible links rather than
2967 // the default links.
2968 // The simulator code presumes that child parts are only modified by scripts
2969 // so the logic for changing position/rotation/etc does not take into
2970 // account the physical object actually moving.
2971 // This code updates the offset position and rotation of the child and then
2972 // lets the update code push the update to the viewer.
2973 // Since physics engines do not normally generate this event for linkset children,
2974 // this code will not be active unless you have a specially configured
2975 // physics engine.
2976 Quaternion invRootRotation = Quaternion.Normalize(Quaternion.Inverse(ParentGroup.RootPart.RotationOffset));
2977 m_offsetPosition = pa.Position - m_groupPosition;
2978 RotationOffset = pa.Orientation * invRootRotation;
2979 // m_log.DebugFormat("{0} PhysicsRequestingTerseUpdate child: pos={1}, rot={2}, offPos={3}, offRot={4}",
2980 // "[SCENE OBJECT PART]", pa.Position, pa.Orientation, m_offsetPosition, RotationOffset);
2981 }
2982
2963 ScheduleTerseUpdate(); 2983 ScheduleTerseUpdate();
2964 } 2984 }
2965 2985
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 183d8d1..9f330fd 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -320,7 +320,21 @@ namespace OpenSim.Region.Framework.Scenes
320 /// </summary> 320 /// </summary>
321 private string m_callbackURI; 321 private string m_callbackURI;
322 322
323 public UUID m_originRegionID; 323 /// <summary>
324 /// Records the region from which this presence originated, if not from login.
325 /// </summary>
326 /// <remarks>
327 /// Also acts as a signal in the teleport V2 process to release UpdateAgent after a viewer has triggered
328 /// CompleteMovement and made the previous child agent a root agent.
329 /// </remarks>
330 private UUID m_originRegionID;
331
332 /// <summary>
333 /// This object is used as a lock before accessing m_originRegionID to make sure that every thread is seeing
334 /// the very latest value and not using some cached version. Cannot make m_originRegionID itself volatite as
335 /// it is a value type.
336 /// </summary>
337 private object m_originRegionIDAccessLock = new object();
324 338
325 /// <summary> 339 /// <summary>
326 /// Used by the entity transfer module to signal when the presence should not be closed because a subsequent 340 /// Used by the entity transfer module to signal when the presence should not be closed because a subsequent
@@ -975,11 +989,11 @@ namespace OpenSim.Region.Framework.Scenes
975 /// This method is on the critical path for transferring an avatar from one region to another. Delay here 989 /// This method is on the critical path for transferring an avatar from one region to another. Delay here
976 /// delays that crossing. 990 /// delays that crossing.
977 /// </summary> 991 /// </summary>
978 public void MakeRootAgent(Vector3 pos, bool isFlying) 992 private void MakeRootAgent(Vector3 pos, bool isFlying)
979 { 993 {
980 m_log.InfoFormat( 994// m_log.InfoFormat(
981 "[SCENE]: Upgrading child to root agent for {0} in {1}", 995// "[SCENE]: Upgrading child to root agent for {0} in {1}",
982 Name, m_scene.RegionInfo.RegionName); 996// Name, m_scene.RegionInfo.RegionName);
983 997
984 if (ParentUUID != UUID.Zero) 998 if (ParentUUID != UUID.Zero)
985 { 999 {
@@ -1545,15 +1559,26 @@ namespace OpenSim.Region.Framework.Scenes
1545 1559
1546 private bool WaitForUpdateAgent(IClientAPI client) 1560 private bool WaitForUpdateAgent(IClientAPI client)
1547 { 1561 {
1548 // Before UpdateAgent, m_originRegionID is UUID.Zero; after, it's non-Zero 1562 // Before the source region executes UpdateAgent
1563 // (which triggers Scene.IncomingUpdateChildAgent(AgentData cAgentData) here in the destination,
1564 // m_originRegionID is UUID.Zero; after, it's non-Zero. The CompleteMovement sequence initiated from the
1565 // viewer (in turn triggered by the source region sending it a TeleportFinish event) waits until it's non-zero
1549 int count = 50; 1566 int count = 50;
1550 while (m_originRegionID.Equals(UUID.Zero) && count-- > 0) 1567 UUID originID;
1568
1569 lock (m_originRegionIDAccessLock)
1570 originID = m_originRegionID;
1571
1572 while (originID.Equals(UUID.Zero) && count-- > 0)
1551 { 1573 {
1574 lock (m_originRegionIDAccessLock)
1575 originID = m_originRegionID;
1576
1552 m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting for update in {1}", client.Name, Scene.Name); 1577 m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting for update in {1}", client.Name, Scene.Name);
1553 Thread.Sleep(200); 1578 Thread.Sleep(200);
1554 } 1579 }
1555 1580
1556 if (m_originRegionID.Equals(UUID.Zero)) 1581 if (originID.Equals(UUID.Zero))
1557 { 1582 {
1558 // Movement into region will fail 1583 // Movement into region will fail
1559 m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} never arrived in {1}", client.Name, Scene.Name); 1584 m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} never arrived in {1}", client.Name, Scene.Name);
@@ -1576,9 +1601,9 @@ namespace OpenSim.Region.Framework.Scenes
1576 { 1601 {
1577// DateTime startTime = DateTime.Now; 1602// DateTime startTime = DateTime.Now;
1578 1603
1579 m_log.DebugFormat( 1604 m_log.InfoFormat(
1580 "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}", 1605 "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}",
1581 client.Name, Scene.RegionInfo.RegionName, AbsolutePosition); 1606 client.Name, Scene.Name, AbsolutePosition);
1582 1607
1583 // Make sure it's not a login agent. We don't want to wait for updates during login 1608 // Make sure it's not a login agent. We don't want to wait for updates during login
1584 if (PresenceType != PresenceType.Npc && (m_teleportFlags & TeleportFlags.ViaLogin) == 0) 1609 if (PresenceType != PresenceType.Npc && (m_teleportFlags & TeleportFlags.ViaLogin) == 0)
@@ -1633,7 +1658,12 @@ namespace OpenSim.Region.Framework.Scenes
1633 "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}", 1658 "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}",
1634 client.Name, client.AgentId, m_callbackURI); 1659 client.Name, client.AgentId, m_callbackURI);
1635 1660
1636 Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); 1661 UUID originID;
1662
1663 lock (m_originRegionIDAccessLock)
1664 originID = m_originRegionID;
1665
1666 Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI);
1637 m_callbackURI = null; 1667 m_callbackURI = null;
1638 } 1668 }
1639// else 1669// else
@@ -3089,7 +3119,7 @@ namespace OpenSim.Region.Framework.Scenes
3089 // If we are using the the cached appearance then send it out to everyone 3119 // If we are using the the cached appearance then send it out to everyone
3090 if (cachedappearance) 3120 if (cachedappearance)
3091 { 3121 {
3092 m_log.DebugFormat("[SCENE PRESENCE]: baked textures are in the cache for {0}", Name); 3122 m_log.DebugFormat("[SCENE PRESENCE]: Baked textures are in the cache for {0} in {1}", Name, m_scene.Name);
3093 3123
3094 // If the avatars baked textures are all in the cache, then we have a 3124 // If the avatars baked textures are all in the cache, then we have a
3095 // complete appearance... send it out, if not, then we'll send it when 3125 // complete appearance... send it out, if not, then we'll send it when
@@ -3553,7 +3583,7 @@ namespace OpenSim.Region.Framework.Scenes
3553 3583
3554 #region Child Agent Updates 3584 #region Child Agent Updates
3555 3585
3556 public void ChildAgentDataUpdate(AgentData cAgentData) 3586 public void UpdateChildAgent(AgentData cAgentData)
3557 { 3587 {
3558// m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); 3588// m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName);
3559 if (!IsChildAgent) 3589 if (!IsChildAgent)
@@ -3563,15 +3593,17 @@ namespace OpenSim.Region.Framework.Scenes
3563 } 3593 }
3564 3594
3565 private static Vector3 marker = new Vector3(-1f, -1f, -1f); 3595 private static Vector3 marker = new Vector3(-1f, -1f, -1f);
3596
3566 private void RaiseUpdateThrottles() 3597 private void RaiseUpdateThrottles()
3567 { 3598 {
3568 m_scene.EventManager.TriggerThrottleUpdate(this); 3599 m_scene.EventManager.TriggerThrottleUpdate(this);
3569 } 3600 }
3601
3570 /// <summary> 3602 /// <summary>
3571 /// This updates important decision making data about a child agent 3603 /// This updates important decision making data about a child agent
3572 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region 3604 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region
3573 /// </summary> 3605 /// </summary>
3574 public void ChildAgentDataUpdate(AgentPosition cAgentData, uint tRegionX, uint tRegionY, uint rRegionX, uint rRegionY) 3606 public void UpdateChildAgent(AgentPosition cAgentData, uint tRegionX, uint tRegionY, uint rRegionX, uint rRegionY)
3575 { 3607 {
3576 if (!IsChildAgent) 3608 if (!IsChildAgent)
3577 return; 3609 return;
@@ -3679,7 +3711,8 @@ namespace OpenSim.Region.Framework.Scenes
3679 3711
3680 private void CopyFrom(AgentData cAgent) 3712 private void CopyFrom(AgentData cAgent)
3681 { 3713 {
3682 m_originRegionID = cAgent.RegionID; 3714 lock (m_originRegionIDAccessLock)
3715 m_originRegionID = cAgent.RegionID;
3683 3716
3684 m_callbackURI = cAgent.CallbackURI; 3717 m_callbackURI = cAgent.CallbackURI;
3685// m_log.DebugFormat( 3718// m_log.DebugFormat(
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index 68918d3..bc51b32 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -365,6 +365,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
365 m_SOPXmlProcessors.Add("CollisionSound", ProcessCollisionSound); 365 m_SOPXmlProcessors.Add("CollisionSound", ProcessCollisionSound);
366 m_SOPXmlProcessors.Add("CollisionSoundVolume", ProcessCollisionSoundVolume); 366 m_SOPXmlProcessors.Add("CollisionSoundVolume", ProcessCollisionSoundVolume);
367 m_SOPXmlProcessors.Add("MediaUrl", ProcessMediaUrl); 367 m_SOPXmlProcessors.Add("MediaUrl", ProcessMediaUrl);
368 m_SOPXmlProcessors.Add("AttachedPos", ProcessAttachedPos);
368 m_SOPXmlProcessors.Add("DynAttrs", ProcessDynAttrs); 369 m_SOPXmlProcessors.Add("DynAttrs", ProcessDynAttrs);
369 m_SOPXmlProcessors.Add("TextureAnimation", ProcessTextureAnimation); 370 m_SOPXmlProcessors.Add("TextureAnimation", ProcessTextureAnimation);
370 m_SOPXmlProcessors.Add("ParticleSystem", ProcessParticleSystem); 371 m_SOPXmlProcessors.Add("ParticleSystem", ProcessParticleSystem);
@@ -443,6 +444,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
443 m_ShapeXmlProcessors.Add("ProfileEnd", ProcessShpProfileEnd); 444 m_ShapeXmlProcessors.Add("ProfileEnd", ProcessShpProfileEnd);
444 m_ShapeXmlProcessors.Add("ProfileHollow", ProcessShpProfileHollow); 445 m_ShapeXmlProcessors.Add("ProfileHollow", ProcessShpProfileHollow);
445 m_ShapeXmlProcessors.Add("Scale", ProcessShpScale); 446 m_ShapeXmlProcessors.Add("Scale", ProcessShpScale);
447 m_ShapeXmlProcessors.Add("LastAttachPoint", ProcessShpLastAttach);
446 m_ShapeXmlProcessors.Add("State", ProcessShpState); 448 m_ShapeXmlProcessors.Add("State", ProcessShpState);
447 m_ShapeXmlProcessors.Add("ProfileShape", ProcessShpProfileShape); 449 m_ShapeXmlProcessors.Add("ProfileShape", ProcessShpProfileShape);
448 m_ShapeXmlProcessors.Add("HollowShape", ProcessShpHollowShape); 450 m_ShapeXmlProcessors.Add("HollowShape", ProcessShpHollowShape);
@@ -798,6 +800,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
798 obj.MediaUrl = reader.ReadElementContentAsString("MediaUrl", String.Empty); 800 obj.MediaUrl = reader.ReadElementContentAsString("MediaUrl", String.Empty);
799 } 801 }
800 802
803 private static void ProcessAttachedPos(SceneObjectPart obj, XmlTextReader reader)
804 {
805 obj.AttachedPos = Util.ReadVector(reader, "AttachedPos");
806 }
807
801 private static void ProcessDynAttrs(SceneObjectPart obj, XmlTextReader reader) 808 private static void ProcessDynAttrs(SceneObjectPart obj, XmlTextReader reader)
802 { 809 {
803 obj.DynAttrs.ReadXml(reader); 810 obj.DynAttrs.ReadXml(reader);
@@ -1099,6 +1106,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1099 shp.State = (byte)reader.ReadElementContentAsInt("State", String.Empty); 1106 shp.State = (byte)reader.ReadElementContentAsInt("State", String.Empty);
1100 } 1107 }
1101 1108
1109 private static void ProcessShpLastAttach(PrimitiveBaseShape shp, XmlTextReader reader)
1110 {
1111 shp.LastAttachPoint = (byte)reader.ReadElementContentAsInt("LastAttachPoint", String.Empty);
1112 }
1113
1102 private static void ProcessShpProfileShape(PrimitiveBaseShape shp, XmlTextReader reader) 1114 private static void ProcessShpProfileShape(PrimitiveBaseShape shp, XmlTextReader reader)
1103 { 1115 {
1104 shp.ProfileShape = Util.ReadEnum<ProfileShape>(reader, "ProfileShape"); 1116 shp.ProfileShape = Util.ReadEnum<ProfileShape>(reader, "ProfileShape");
@@ -1345,6 +1357,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1345 writer.WriteElementString("CollisionSoundVolume", sop.CollisionSoundVolume.ToString()); 1357 writer.WriteElementString("CollisionSoundVolume", sop.CollisionSoundVolume.ToString());
1346 if (sop.MediaUrl != null) 1358 if (sop.MediaUrl != null)
1347 writer.WriteElementString("MediaUrl", sop.MediaUrl.ToString()); 1359 writer.WriteElementString("MediaUrl", sop.MediaUrl.ToString());
1360 WriteVector(writer, "AttachedPos", sop.AttachedPos);
1348 1361
1349 if (sop.DynAttrs.CountNamespaces > 0) 1362 if (sop.DynAttrs.CountNamespaces > 0)
1350 { 1363 {
@@ -1539,6 +1552,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1539 writer.WriteElementString("ProfileEnd", shp.ProfileEnd.ToString()); 1552 writer.WriteElementString("ProfileEnd", shp.ProfileEnd.ToString());
1540 writer.WriteElementString("ProfileHollow", shp.ProfileHollow.ToString()); 1553 writer.WriteElementString("ProfileHollow", shp.ProfileHollow.ToString());
1541 writer.WriteElementString("State", shp.State.ToString()); 1554 writer.WriteElementString("State", shp.State.ToString());
1555 writer.WriteElementString("LastAttachPoint", shp.LastAttachPoint.ToString());
1542 1556
1543 WriteFlags(writer, "ProfileShape", shp.ProfileShape.ToString(), options); 1557 WriteFlags(writer, "ProfileShape", shp.ProfileShape.ToString(), options);
1544 WriteFlags(writer, "HollowShape", shp.HollowShape.ToString(), options); 1558 WriteFlags(writer, "HollowShape", shp.HollowShape.ToString(), options);
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
index bbe34d2..d1aeaee 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
@@ -146,7 +146,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
146 } 146 }
147 147
148 [Test] 148 [Test]
149 public void TestCloseAgent() 149 public void TestCloseClient()
150 { 150 {
151 TestHelpers.InMethod(); 151 TestHelpers.InMethod();
152// TestHelpers.EnableLogging(); 152// TestHelpers.EnableLogging();
@@ -154,7 +154,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
154 TestScene scene = new SceneHelpers().SetupScene(); 154 TestScene scene = new SceneHelpers().SetupScene();
155 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); 155 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
156 156
157 scene.IncomingCloseAgent(sp.UUID, false); 157 scene.CloseAgent(sp.UUID, false);
158 158
159 Assert.That(scene.GetScenePresence(sp.UUID), Is.Null); 159 Assert.That(scene.GetScenePresence(sp.UUID), Is.Null);
160 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null); 160 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null);
@@ -200,7 +200,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
200 // *** This is the second stage, where the client established a child agent/scene presence using the 200 // *** This is the second stage, where the client established a child agent/scene presence using the
201 // circuit code given to the scene in stage 1 *** 201 // circuit code given to the scene in stage 1 ***
202 TestClient client = new TestClient(acd, scene); 202 TestClient client = new TestClient(acd, scene);
203 scene.AddNewClient(client, PresenceType.User); 203 scene.AddNewAgent(client, PresenceType.User);
204 204
205 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(agentId), Is.Not.Null); 205 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(agentId), Is.Not.Null);
206 Assert.That(scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(1)); 206 Assert.That(scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(1));
@@ -279,7 +279,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
279// string reason; 279// string reason;
280// scene.NewUserConnection(agent, (uint)TeleportFlags.ViaLogin, out reason); 280// scene.NewUserConnection(agent, (uint)TeleportFlags.ViaLogin, out reason);
281// testclient = new TestClient(agent, scene); 281// testclient = new TestClient(agent, scene);
282// scene.AddNewClient(testclient); 282// scene.AddNewAgent(testclient);
283// 283//
284// ScenePresence presence = scene.GetScenePresence(agent1); 284// ScenePresence presence = scene.GetScenePresence(agent1);
285// 285//
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs
index 4ae7a8e..9fa0a71 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs
@@ -79,8 +79,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests
79 79
80 // TODO: Need to add tests for other ICapabiltiesModule methods. 80 // TODO: Need to add tests for other ICapabiltiesModule methods.
81 81
82 scene.IncomingCloseAgent(sp.UUID, false); 82// scene.IncomingCloseAgent(sp.UUID, false);
83 //Assert.That(capsMod.GetCapsForUser(spUuid), Is.Null); 83// //Assert.That(capsMod.GetCapsForUser(spUuid), Is.Null);
84 scene.CloseAgent(sp.UUID, false);
85// Assert.That(capsMod.GetCapsForUser(spUuid), Is.Null);
84 86
85 // TODO: Need to add tests for other ICapabiltiesModule methods. 87 // TODO: Need to add tests for other ICapabiltiesModule methods.
86 } 88 }
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs
index 12a778b..b806a97 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs
@@ -38,6 +38,7 @@ using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.CoreModules.Framework; 38using OpenSim.Region.CoreModules.Framework;
39using OpenSim.Region.CoreModules.Framework.EntityTransfer; 39using OpenSim.Region.CoreModules.Framework.EntityTransfer;
40using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; 40using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
41using OpenSim.Region.CoreModules.World.Permissions;
41using OpenSim.Tests.Common; 42using OpenSim.Tests.Common;
42using OpenSim.Tests.Common.Mock; 43using OpenSim.Tests.Common.Mock;
43 44
@@ -159,5 +160,90 @@ namespace OpenSim.Region.Framework.Scenes.Tests
159 Assert.That(agentMovementCompleteReceived, Is.EqualTo(1)); 160 Assert.That(agentMovementCompleteReceived, Is.EqualTo(1));
160 Assert.That(spAfterCrossSceneB.IsChildAgent, Is.False); 161 Assert.That(spAfterCrossSceneB.IsChildAgent, Is.False);
161 } 162 }
163
164 /// <summary>
165 /// Test a cross attempt where the user can see into the neighbour but does not have permission to become
166 /// root there.
167 /// </summary>
168 [Test]
169 public void TestCrossOnSameSimulatorNoRootDestPerm()
170 {
171 TestHelpers.InMethod();
172// TestHelpers.EnableLogging();
173
174 UUID userId = TestHelpers.ParseTail(0x1);
175
176 EntityTransferModule etmA = new EntityTransferModule();
177 EntityTransferModule etmB = new EntityTransferModule();
178 LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
179
180 IConfigSource config = new IniConfigSource();
181 IConfig modulesConfig = config.AddConfig("Modules");
182 modulesConfig.Set("EntityTransferModule", etmA.Name);
183 modulesConfig.Set("SimulationServices", lscm.Name);
184
185 SceneHelpers sh = new SceneHelpers();
186 TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000);
187 TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1000, 999);
188
189 SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
190 SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA);
191
192 // We need to set up the permisions module on scene B so that our later use of agent limit to deny
193 // QueryAccess won't succeed anyway because administrators are always allowed in and the default
194 // IsAdministrator if no permissions module is present is true.
195// SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), new PermissionsModule(), etmB);
196
197 AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
198 TestClient tc = new TestClient(acd, sceneA);
199 List<TestClient> destinationTestClients = new List<TestClient>();
200 EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients);
201
202 // Make sure sceneB will not accept this avatar.
203 sceneB.RegionInfo.EstateSettings.PublicAccess = false;
204
205 ScenePresence originalSp = SceneHelpers.AddScenePresence(sceneA, tc, acd);
206 originalSp.AbsolutePosition = new Vector3(128, 32, 10);
207
208 AgentUpdateArgs moveArgs = new AgentUpdateArgs();
209 //moveArgs.BodyRotation = Quaternion.CreateFromEulers(Vector3.Zero);
210 moveArgs.BodyRotation = Quaternion.CreateFromEulers(new Vector3(0, 0, (float)-(Math.PI / 2)));
211 moveArgs.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS;
212 moveArgs.SessionID = acd.SessionID;
213
214 originalSp.HandleAgentUpdate(originalSp.ControllingClient, moveArgs);
215
216 sceneA.Update(1);
217
218// Console.WriteLine("Second pos {0}", originalSp.AbsolutePosition);
219
220 // FIXME: This is a sufficient number of updates to for the presence to reach the northern border.
221 // But really we want to do this in a more robust way.
222 for (int i = 0; i < 100; i++)
223 {
224 sceneA.Update(1);
225// Console.WriteLine("Pos {0}", originalSp.AbsolutePosition);
226 }
227
228 // sceneA agent should still be root
229 ScenePresence spAfterCrossSceneA = sceneA.GetScenePresence(originalSp.UUID);
230 Assert.That(spAfterCrossSceneA.IsChildAgent, Is.False);
231
232 ScenePresence spAfterCrossSceneB = sceneB.GetScenePresence(originalSp.UUID);
233
234 // sceneB agent should also still be root
235 Assert.That(spAfterCrossSceneB.IsChildAgent, Is.True);
236
237 // sceneB should ignore unauthorized attempt to upgrade agent to root
238 TestClient sceneBTc = ((TestClient)spAfterCrossSceneB.ControllingClient);
239
240 int agentMovementCompleteReceived = 0;
241 sceneBTc.OnReceivedMoveAgentIntoRegion += (ri, pos, look) => agentMovementCompleteReceived++;
242
243 sceneBTc.CompleteMovement();
244
245 Assert.That(agentMovementCompleteReceived, Is.EqualTo(0));
246 Assert.That(spAfterCrossSceneB.IsChildAgent, Is.True);
247 }
162 } 248 }
163} \ No newline at end of file 249}
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
index e60a025..84e410f 100644
--- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
+++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
@@ -168,7 +168,20 @@ namespace OpenSim.Region.Framework.Scenes
168 // If the prim is a sculpt then preserve this information too 168 // If the prim is a sculpt then preserve this information too
169 if (part.Shape.SculptTexture != UUID.Zero) 169 if (part.Shape.SculptTexture != UUID.Zero)
170 assetUuids[part.Shape.SculptTexture] = AssetType.Texture; 170 assetUuids[part.Shape.SculptTexture] = AssetType.Texture;
171 171
172 if (part.Shape.ProjectionTextureUUID != UUID.Zero)
173 assetUuids[part.Shape.ProjectionTextureUUID] = AssetType.Texture;
174
175 if (part.CollisionSound != UUID.Zero)
176 assetUuids[part.CollisionSound] = AssetType.Sound;
177
178 if (part.ParticleSystem.Length > 0)
179 {
180 Primitive.ParticleSystem ps = new Primitive.ParticleSystem(part.ParticleSystem, 0);
181 if (ps.Texture != UUID.Zero)
182 assetUuids[ps.Texture] = AssetType.Texture;
183 }
184
172 TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 185 TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
173 186
174 // Now analyze this prim's inventory items to preserve all the uuids that they reference 187 // Now analyze this prim's inventory items to preserve all the uuids that they reference
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index a96c8b4..373ed41 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -908,7 +908,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
908 908
909 public void Start() 909 public void Start()
910 { 910 {
911 m_scene.AddNewClient(this, PresenceType.User); 911 m_scene.AddNewAgent(this, PresenceType.User);
912 912
913 // Mimicking LLClientView which gets always set appearance from client. 913 // Mimicking LLClientView which gets always set appearance from client.
914 AvatarAppearance appearance; 914 AvatarAppearance appearance;
diff --git a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs
index d1d318c..9daf9d7 100755
--- a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs
@@ -29,12 +29,14 @@ using System.Collections.Generic;
29using System.Linq; 29using System.Linq;
30using System.Reflection; 30using System.Reflection;
31using System.Text; 31using System.Text;
32using System.Threading;
32 33
33using OpenSim.Framework; 34using OpenSim.Framework;
34using OpenSim.Region.CoreModules; 35using OpenSim.Region.CoreModules;
35using OpenSim.Region.Framework; 36using OpenSim.Region.Framework;
36using OpenSim.Region.Framework.Interfaces; 37using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes; 38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Region.Physics.Manager;
38 40
39using Mono.Addins; 41using Mono.Addins;
40using Nini.Config; 42using Nini.Config;
@@ -60,6 +62,10 @@ public class ExtendedPhysics : INonSharedRegionModule
60 // Per prim functions. See BSPrim. 62 // Per prim functions. See BSPrim.
61 public const string PhysFunctGetLinksetType = "BulletSim.GetLinksetType"; 63 public const string PhysFunctGetLinksetType = "BulletSim.GetLinksetType";
62 public const string PhysFunctSetLinksetType = "BulletSim.SetLinksetType"; 64 public const string PhysFunctSetLinksetType = "BulletSim.SetLinksetType";
65 public const string PhysFunctChangeLinkFixed = "BulletSim.ChangeLinkFixed";
66 public const string PhysFunctChangeLinkType = "BulletSim.ChangeLinkType";
67 public const string PhysFunctGetLinkType = "BulletSim.GetLinkType";
68 public const string PhysFunctChangeLinkParams = "BulletSim.ChangeLinkParams";
63 69
64 // ============================================================= 70 // =============================================================
65 71
@@ -155,7 +161,7 @@ public class ExtendedPhysics : INonSharedRegionModule
155 } 161 }
156 162
157 [ScriptConstant] 163 [ScriptConstant]
158 public static int PHYS_CENTER_OF_MASS = 1 << 0; 164 public const int PHYS_CENTER_OF_MASS = 1 << 0;
159 165
160 [ScriptInvocation] 166 [ScriptInvocation]
161 public string physGetEngineType(UUID hostID, UUID scriptID) 167 public string physGetEngineType(UUID hostID, UUID scriptID)
@@ -171,11 +177,11 @@ public class ExtendedPhysics : INonSharedRegionModule
171 } 177 }
172 178
173 [ScriptConstant] 179 [ScriptConstant]
174 public static int PHYS_LINKSET_TYPE_CONSTRAINT = 0; 180 public const int PHYS_LINKSET_TYPE_CONSTRAINT = 0;
175 [ScriptConstant] 181 [ScriptConstant]
176 public static int PHYS_LINKSET_TYPE_COMPOUND = 1; 182 public const int PHYS_LINKSET_TYPE_COMPOUND = 1;
177 [ScriptConstant] 183 [ScriptConstant]
178 public static int PHYS_LINKSET_TYPE_MANUAL = 2; 184 public const int PHYS_LINKSET_TYPE_MANUAL = 2;
179 185
180 [ScriptInvocation] 186 [ScriptInvocation]
181 public int physSetLinksetType(UUID hostID, UUID scriptID, int linksetType) 187 public int physSetLinksetType(UUID hostID, UUID scriptID, int linksetType)
@@ -195,10 +201,38 @@ public class ExtendedPhysics : INonSharedRegionModule
195 201
196 if (rootPart != null) 202 if (rootPart != null)
197 { 203 {
198 Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor; 204 PhysicsActor rootPhysActor = rootPart.PhysActor;
199 if (rootPhysActor != null) 205 if (rootPhysActor != null)
200 { 206 {
201 ret = (int)rootPhysActor.Extension(PhysFunctSetLinksetType, linksetType); 207 if (rootPhysActor.IsPhysical)
208 {
209 // Change a physical linkset by making non-physical, waiting for one heartbeat so all
210 // the prim and linkset state is updated, changing the type and making the
211 // linkset physical again.
212 containingGroup.ScriptSetPhysicsStatus(false);
213 Thread.Sleep(150); // longer than one heartbeat tick
214
215 // A kludge for the moment.
216 // Since compound linksets move the children but don't generate position updates to the
217 // simulator, it is possible for compound linkset children to have out-of-sync simulator
218 // and physical positions. The following causes the simulator to push the real child positions
219 // down into the physics engine to get everything synced.
220 containingGroup.UpdateGroupPosition(containingGroup.AbsolutePosition);
221 containingGroup.UpdateGroupRotationR(containingGroup.GroupRotation);
222
223 object[] parms2 = { rootPhysActor, null, linksetType };
224 ret = MakeIntError(rootPhysActor.Extension(PhysFunctSetLinksetType, parms2));
225 Thread.Sleep(150); // longer than one heartbeat tick
226
227 containingGroup.ScriptSetPhysicsStatus(true);
228 }
229 else
230 {
231 // Non-physical linksets don't have a physical instantiation so there is no state to
232 // worry about being updated.
233 object[] parms2 = { rootPhysActor, null, linksetType };
234 ret = MakeIntError(rootPhysActor.Extension(PhysFunctSetLinksetType, parms2));
235 }
202 } 236 }
203 else 237 else
204 { 238 {
@@ -223,7 +257,6 @@ public class ExtendedPhysics : INonSharedRegionModule
223 public int physGetLinksetType(UUID hostID, UUID scriptID) 257 public int physGetLinksetType(UUID hostID, UUID scriptID)
224 { 258 {
225 int ret = -1; 259 int ret = -1;
226
227 if (!Enabled) return ret; 260 if (!Enabled) return ret;
228 261
229 // The part that is requesting the change. 262 // The part that is requesting the change.
@@ -237,10 +270,11 @@ public class ExtendedPhysics : INonSharedRegionModule
237 270
238 if (rootPart != null) 271 if (rootPart != null)
239 { 272 {
240 Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor; 273 PhysicsActor rootPhysActor = rootPart.PhysActor;
241 if (rootPhysActor != null) 274 if (rootPhysActor != null)
242 { 275 {
243 ret = (int)rootPhysActor.Extension(PhysFunctGetLinksetType); 276 object[] parms2 = { rootPhysActor, null };
277 ret = MakeIntError(rootPhysActor.Extension(PhysFunctGetLinksetType, parms2));
244 } 278 }
245 else 279 else
246 { 280 {
@@ -260,5 +294,288 @@ public class ExtendedPhysics : INonSharedRegionModule
260 } 294 }
261 return ret; 295 return ret;
262 } 296 }
297
298 [ScriptConstant]
299 public const int PHYS_LINK_TYPE_FIXED = 1234;
300 [ScriptConstant]
301 public const int PHYS_LINK_TYPE_HINGE = 4;
302 [ScriptConstant]
303 public const int PHYS_LINK_TYPE_SPRING = 9;
304 [ScriptConstant]
305 public const int PHYS_LINK_TYPE_6DOF = 6;
306 [ScriptConstant]
307 public const int PHYS_LINK_TYPE_SLIDER = 7;
308
309 // physChangeLinkType(integer linkNum, integer typeCode)
310 [ScriptInvocation]
311 public int physChangeLinkType(UUID hostID, UUID scriptID, int linkNum, int typeCode)
312 {
313 int ret = -1;
314 if (!Enabled) return ret;
315
316 PhysicsActor rootPhysActor;
317 PhysicsActor childPhysActor;
318
319 if (GetRootAndChildPhysActors(hostID, linkNum, out rootPhysActor, out childPhysActor))
320 {
321 object[] parms2 = { rootPhysActor, childPhysActor, typeCode };
322 ret = MakeIntError(rootPhysActor.Extension(PhysFunctChangeLinkType, parms2));
323 }
324
325 return ret;
326 }
327
328 // physGetLinkType(integer linkNum)
329 [ScriptInvocation]
330 public int physGetLinkType(UUID hostID, UUID scriptID, int linkNum)
331 {
332 int ret = -1;
333 if (!Enabled) return ret;
334
335 PhysicsActor rootPhysActor;
336 PhysicsActor childPhysActor;
337
338 if (GetRootAndChildPhysActors(hostID, linkNum, out rootPhysActor, out childPhysActor))
339 {
340 object[] parms2 = { rootPhysActor, childPhysActor };
341 ret = MakeIntError(rootPhysActor.Extension(PhysFunctGetLinkType, parms2));
342 }
343
344 return ret;
345 }
346
347 // physChangeLinkFixed(integer linkNum)
348 // Change the link between the root and the linkNum into a fixed, static physical connection.
349 [ScriptInvocation]
350 public int physChangeLinkFixed(UUID hostID, UUID scriptID, int linkNum)
351 {
352 int ret = -1;
353 if (!Enabled) return ret;
354
355 PhysicsActor rootPhysActor;
356 PhysicsActor childPhysActor;
357
358 if (GetRootAndChildPhysActors(hostID, linkNum, out rootPhysActor, out childPhysActor))
359 {
360 object[] parms2 = { rootPhysActor, childPhysActor , PHYS_LINK_TYPE_FIXED };
361 ret = MakeIntError(rootPhysActor.Extension(PhysFunctChangeLinkType, parms2));
362 }
363
364 return ret;
365 }
366
367 // Code for specifying params.
368 // The choice if 14400 is arbitrary and only serves to catch parameter code misuse.
369 public const int PHYS_PARAM_MIN = 14401;
370
371 [ScriptConstant]
372 public const int PHYS_PARAM_FRAMEINA_LOC = 14401;
373 [ScriptConstant]
374 public const int PHYS_PARAM_FRAMEINA_ROT = 14402;
375 [ScriptConstant]
376 public const int PHYS_PARAM_FRAMEINB_LOC = 14403;
377 [ScriptConstant]
378 public const int PHYS_PARAM_FRAMEINB_ROT = 14404;
379 [ScriptConstant]
380 public const int PHYS_PARAM_LINEAR_LIMIT_LOW = 14405;
381 [ScriptConstant]
382 public const int PHYS_PARAM_LINEAR_LIMIT_HIGH = 14406;
383 [ScriptConstant]
384 public const int PHYS_PARAM_ANGULAR_LIMIT_LOW = 14407;
385 [ScriptConstant]
386 public const int PHYS_PARAM_ANGULAR_LIMIT_HIGH = 14408;
387 [ScriptConstant]
388 public const int PHYS_PARAM_USE_FRAME_OFFSET = 14409;
389 [ScriptConstant]
390 public const int PHYS_PARAM_ENABLE_TRANSMOTOR = 14410;
391 [ScriptConstant]
392 public const int PHYS_PARAM_TRANSMOTOR_MAXVEL = 14411;
393 [ScriptConstant]
394 public const int PHYS_PARAM_TRANSMOTOR_MAXFORCE = 14412;
395 [ScriptConstant]
396 public const int PHYS_PARAM_CFM = 14413;
397 [ScriptConstant]
398 public const int PHYS_PARAM_ERP = 14414;
399 [ScriptConstant]
400 public const int PHYS_PARAM_SOLVER_ITERATIONS = 14415;
401 [ScriptConstant]
402 public const int PHYS_PARAM_SPRING_AXIS_ENABLE = 14416;
403 [ScriptConstant]
404 public const int PHYS_PARAM_SPRING_DAMPING = 14417;
405 [ScriptConstant]
406 public const int PHYS_PARAM_SPRING_STIFFNESS = 14418;
407 [ScriptConstant]
408 public const int PHYS_PARAM_LINK_TYPE = 14419;
409 [ScriptConstant]
410 public const int PHYS_PARAM_USE_LINEAR_FRAMEA = 14420;
411 [ScriptConstant]
412 public const int PHYS_PARAM_SPRING_EQUILIBRIUM_POINT = 14421;
413
414 public const int PHYS_PARAM_MAX = 14421;
415
416 // Used when specifying a parameter that has settings for the three linear and three angular axis
417 [ScriptConstant]
418 public const int PHYS_AXIS_ALL = -1;
419 [ScriptConstant]
420 public const int PHYS_AXIS_LINEAR_ALL = -2;
421 [ScriptConstant]
422 public const int PHYS_AXIS_ANGULAR_ALL = -3;
423 [ScriptConstant]
424 public const int PHYS_AXIS_LINEAR_X = 0;
425 [ScriptConstant]
426 public const int PHYS_AXIS_LINEAR_Y = 1;
427 [ScriptConstant]
428 public const int PHYS_AXIS_LINEAR_Z = 2;
429 [ScriptConstant]
430 public const int PHYS_AXIS_ANGULAR_X = 3;
431 [ScriptConstant]
432 public const int PHYS_AXIS_ANGULAR_Y = 4;
433 [ScriptConstant]
434 public const int PHYS_AXIS_ANGULAR_Z = 5;
435
436 // physChangeLinkParams(integer linkNum, [ PHYS_PARAM_*, value, PHYS_PARAM_*, value, ...])
437 [ScriptInvocation]
438 public int physChangeLinkParams(UUID hostID, UUID scriptID, int linkNum, object[] parms)
439 {
440 int ret = -1;
441 if (!Enabled) return ret;
442
443 PhysicsActor rootPhysActor;
444 PhysicsActor childPhysActor;
445
446 if (GetRootAndChildPhysActors(hostID, linkNum, out rootPhysActor, out childPhysActor))
447 {
448 object[] parms2 = AddToBeginningOfArray(rootPhysActor, childPhysActor, parms);
449 ret = MakeIntError(rootPhysActor.Extension(PhysFunctChangeLinkParams, parms2));
450 }
451
452 return ret;
453 }
454
455 private bool GetRootPhysActor(UUID hostID, out PhysicsActor rootPhysActor)
456 {
457 SceneObjectGroup containingGroup;
458 SceneObjectPart rootPart;
459 return GetRootPhysActor(hostID, out containingGroup, out rootPart, out rootPhysActor);
460 }
461
462 private bool GetRootPhysActor(UUID hostID, out SceneObjectGroup containingGroup, out SceneObjectPart rootPart, out PhysicsActor rootPhysActor)
463 {
464 bool ret = false;
465 rootPhysActor = null;
466 containingGroup = null;
467 rootPart = null;
468
469 SceneObjectPart requestingPart;
470
471 requestingPart = BaseScene.GetSceneObjectPart(hostID);
472 if (requestingPart != null)
473 {
474 // The type is is always on the root of a linkset.
475 containingGroup = requestingPart.ParentGroup;
476 if (containingGroup != null && !containingGroup.IsDeleted)
477 {
478 rootPart = containingGroup.RootPart;
479 if (rootPart != null)
480 {
481 rootPhysActor = rootPart.PhysActor;
482 if (rootPhysActor != null)
483 {
484 ret = true;
485 }
486 else
487 {
488 m_log.WarnFormat("{0} GetRootAndChildPhysActors: Root part does not have a physics actor. rootName={1}, hostID={2}",
489 LogHeader, rootPart.Name, hostID);
490 }
491 }
492 else
493 {
494 m_log.WarnFormat("{0} GetRootAndChildPhysActors: Root part does not exist. RequestingPartName={1}, hostID={2}",
495 LogHeader, requestingPart.Name, hostID);
496 }
497 }
498 else
499 {
500 m_log.WarnFormat("{0} GetRootAndChildPhysActors: Containing group missing or deleted. hostID={1}", LogHeader, hostID);
501 }
502 }
503 else
504 {
505 m_log.WarnFormat("{0} GetRootAndChildPhysActors: cannot find script object in scene. hostID={1}", LogHeader, hostID);
506 }
507
508 return ret;
509 }
510
511 // Find the root and child PhysActors based on the linkNum.
512 // Return 'true' if both are found and returned.
513 private bool GetRootAndChildPhysActors(UUID hostID, int linkNum, out PhysicsActor rootPhysActor, out PhysicsActor childPhysActor)
514 {
515 bool ret = false;
516 rootPhysActor = null;
517 childPhysActor = null;
518
519 SceneObjectGroup containingGroup;
520 SceneObjectPart rootPart;
521
522 if (GetRootPhysActor(hostID, out containingGroup, out rootPart, out rootPhysActor))
523 {
524 SceneObjectPart linkPart = containingGroup.GetLinkNumPart(linkNum);
525 if (linkPart != null)
526 {
527 childPhysActor = linkPart.PhysActor;
528 if (childPhysActor != null)
529 {
530 ret = true;
531 }
532 else
533 {
534 m_log.WarnFormat("{0} GetRootAndChildPhysActors: Link part has no physical actor. rootName={1}, hostID={2}, linknum={3}",
535 LogHeader, rootPart.Name, hostID, linkNum);
536 }
537 }
538 else
539 {
540 m_log.WarnFormat("{0} GetRootAndChildPhysActors: Could not find linknum part. rootName={1}, hostID={2}, linknum={3}",
541 LogHeader, rootPart.Name, hostID, linkNum);
542 }
543 }
544 else
545 {
546 m_log.WarnFormat("{0} GetRootAndChildPhysActors: Root part does not have a physics actor. rootName={1}, hostID={2}",
547 LogHeader, rootPart.Name, hostID);
548 }
549
550 return ret;
551 }
552
553 // Return an array of objects with the passed object as the first object of a new array
554 private object[] AddToBeginningOfArray(object firstOne, object secondOne, object[] prevArray)
555 {
556 object[] newArray = new object[2 + prevArray.Length];
557 newArray[0] = firstOne;
558 newArray[1] = secondOne;
559 prevArray.CopyTo(newArray, 2);
560 return newArray;
561 }
562
563 // Extension() returns an object. Convert that object into the integer error we expect to return.
564 private int MakeIntError(object extensionRet)
565 {
566 int ret = -1;
567 if (extensionRet != null)
568 {
569 try
570 {
571 ret = (int)extensionRet;
572 }
573 catch
574 {
575 ret = -1;
576 }
577 }
578 return ret;
579 }
263} 580}
264} 581}
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
index 78fe096..9ec4740 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
@@ -176,7 +176,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
176 lock (m_avatars) 176 lock (m_avatars)
177 { 177 {
178 scene.AuthenticateHandler.AddNewCircuit(npcAvatar.CircuitCode, acd); 178 scene.AuthenticateHandler.AddNewCircuit(npcAvatar.CircuitCode, acd);
179 scene.AddNewClient(npcAvatar, PresenceType.Npc); 179 scene.AddNewAgent(npcAvatar, PresenceType.Npc);
180 180
181 ScenePresence sp; 181 ScenePresence sp;
182 if (scene.TryGetScenePresence(npcAvatar.AgentId, out sp)) 182 if (scene.TryGetScenePresence(npcAvatar.AgentId, out sp))
@@ -207,8 +207,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC
207 if (scene.TryGetScenePresence(agentID, out sp)) 207 if (scene.TryGetScenePresence(agentID, out sp))
208 { 208 {
209// m_log.DebugFormat( 209// m_log.DebugFormat(
210// "[NPC MODULE]: Moving {0} to {1} in {2}, noFly {3}, landAtTarget {4}", 210// "[NPC MODULE]: Moving {0} to {1} in {2}, noFly {3}, landAtTarget {4}",
211// sp.Name, pos, scene.RegionInfo.RegionName, noFly, landAtTarget); 211// sp.Name, pos, scene.RegionInfo.RegionName,
212// noFly, landAtTarget);
212 213
213 sp.MoveToTarget(pos, noFly, landAtTarget); 214 sp.MoveToTarget(pos, noFly, landAtTarget);
214 sp.SetAlwaysRun = running; 215 sp.SetAlwaysRun = running;
@@ -285,9 +286,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
285 ScenePresence sp; 286 ScenePresence sp;
286 if (scene.TryGetScenePresence(agentID, out sp)) 287 if (scene.TryGetScenePresence(agentID, out sp))
287 { 288 {
288 sp.HandleAgentRequestSit(m_avatars[agentID], agentID, 289 sp.HandleAgentRequestSit(m_avatars[agentID], agentID, partID, Vector3.Zero);
289 partID, Vector3.Zero);
290 //sp.HandleAgentSit(m_avatars[agentID], agentID);
291 290
292 return true; 291 return true;
293 } 292 }
@@ -378,11 +377,14 @@ namespace OpenSim.Region.OptionalModules.World.NPC
378 agentID, av.Name); 377 agentID, av.Name);
379 */ 378 */
380 379
381 scene.IncomingCloseAgent(agentID, false); 380 scene.CloseAgent(agentID, false);
382// scene.RemoveClient(agentID, false); 381
383 m_avatars.Remove(agentID); 382 m_avatars.Remove(agentID);
384 383
385// m_log.DebugFormat("[NPC MODULE]: Removed NPC {0} {1}", agentID, av.Name); 384 /*
385 m_log.DebugFormat("[NPC MODULE]: Removed NPC {0} {1}",
386 agentID, av.Name);
387 */
386 return true; 388 return true;
387 } 389 }
388 } 390 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs
index 12a0c17..3bd81d4 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs
@@ -596,6 +596,60 @@ public override bool SetBreakingImpulseThreshold(BulletConstraint constrain, flo
596 return BSAPICPP.SetBreakingImpulseThreshold2(constrainu.ptr, threshold); 596 return BSAPICPP.SetBreakingImpulseThreshold2(constrainu.ptr, threshold);
597} 597}
598 598
599public override bool HingeSetLimits(BulletConstraint constrain, float low, float high, float softness, float bias, float relaxation)
600{
601 BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
602 return BSAPICPP.HingeSetLimits2(constrainu.ptr, low, high, softness, bias, relaxation);
603}
604
605public override bool SpringEnable(BulletConstraint constrain, int index, float numericTrueFalse)
606{
607 BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
608 return BSAPICPP.ConstraintSpringEnable2(constrainu.ptr, index, numericTrueFalse);
609}
610
611public override bool SpringSetEquilibriumPoint(BulletConstraint constrain, int index, float equilibriumPoint)
612{
613 BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
614 return BSAPICPP.ConstraintSpringSetEquilibriumPoint2(constrainu.ptr, index, equilibriumPoint);
615}
616
617public override bool SpringSetStiffness(BulletConstraint constrain, int index, float stiffnesss)
618{
619 BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
620 return BSAPICPP.ConstraintSpringSetStiffness2(constrainu.ptr, index, stiffnesss);
621}
622
623public override bool SpringSetDamping(BulletConstraint constrain, int index, float damping)
624{
625 BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
626 return BSAPICPP.ConstraintSpringSetDamping2(constrainu.ptr, index, damping);
627}
628
629public override bool SliderSetLimits(BulletConstraint constrain, int lowerUpper, int linAng, float val)
630{
631 BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
632 return BSAPICPP.SliderSetLimits2(constrainu.ptr, lowerUpper, linAng, val);
633}
634
635public override bool SliderSet(BulletConstraint constrain, int softRestDamp, int dirLimOrtho, int linAng, float val)
636{
637 BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
638 return BSAPICPP.SliderSet2(constrainu.ptr, softRestDamp, dirLimOrtho, linAng, val);
639}
640
641public override bool SliderMotorEnable(BulletConstraint constrain, int linAng, float numericTrueFalse)
642{
643 BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
644 return BSAPICPP.SliderMotorEnable2(constrainu.ptr, linAng, numericTrueFalse);
645}
646
647public override bool SliderMotor(BulletConstraint constrain, int forceVel, int linAng, float val)
648{
649 BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
650 return BSAPICPP.SliderMotor2(constrainu.ptr, forceVel, linAng, val);
651}
652
599public override bool CalculateTransforms(BulletConstraint constrain) 653public override bool CalculateTransforms(BulletConstraint constrain)
600{ 654{
601 BulletConstraintUnman constrainu = constrain as BulletConstraintUnman; 655 BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
@@ -671,6 +725,13 @@ public override bool RemoveObjectFromWorld(BulletWorld world, BulletBody obj)
671 return BSAPICPP.RemoveObjectFromWorld2(worldu.ptr, bodyu.ptr); 725 return BSAPICPP.RemoveObjectFromWorld2(worldu.ptr, bodyu.ptr);
672} 726}
673 727
728public override bool ClearCollisionProxyCache(BulletWorld world, BulletBody obj)
729{
730 BulletWorldUnman worldu = world as BulletWorldUnman;
731 BulletBodyUnman bodyu = obj as BulletBodyUnman;
732 return BSAPICPP.ClearCollisionProxyCache2(worldu.ptr, bodyu.ptr);
733}
734
674public override bool AddConstraintToWorld(BulletWorld world, BulletConstraint constrain, bool disableCollisionsBetweenLinkedObjects) 735public override bool AddConstraintToWorld(BulletWorld world, BulletConstraint constrain, bool disableCollisionsBetweenLinkedObjects)
675{ 736{
676 BulletWorldUnman worldu = world as BulletWorldUnman; 737 BulletWorldUnman worldu = world as BulletWorldUnman;
@@ -1601,6 +1662,33 @@ public static extern bool TranslationalLimitMotor2(IntPtr constrain, float enabl
1601public static extern bool SetBreakingImpulseThreshold2(IntPtr constrain, float threshold); 1662public static extern bool SetBreakingImpulseThreshold2(IntPtr constrain, float threshold);
1602 1663
1603[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1664[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1665public static extern bool HingeSetLimits2(IntPtr constrain, float low, float high, float softness, float bias, float relaxation);
1666
1667[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1668public static extern bool ConstraintSpringEnable2(IntPtr constrain, int index, float numericTrueFalse);
1669
1670[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1671public static extern bool ConstraintSpringSetEquilibriumPoint2(IntPtr constrain, int index, float equilibriumPoint);
1672
1673[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1674public static extern bool ConstraintSpringSetStiffness2(IntPtr constrain, int index, float stiffness);
1675
1676[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1677public static extern bool ConstraintSpringSetDamping2(IntPtr constrain, int index, float damping);
1678
1679[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1680public static extern bool SliderSetLimits2(IntPtr constrain, int lowerUpper, int linAng, float val);
1681
1682[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1683public static extern bool SliderSet2(IntPtr constrain, int softRestDamp, int dirLimOrtho, int linAng, float val);
1684
1685[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1686public static extern bool SliderMotorEnable2(IntPtr constrain, int linAng, float numericTrueFalse);
1687
1688[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1689public static extern bool SliderMotor2(IntPtr constrain, int forceVel, int linAng, float val);
1690
1691[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1604public static extern bool CalculateTransforms2(IntPtr constrain); 1692public static extern bool CalculateTransforms2(IntPtr constrain);
1605 1693
1606[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1694[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
@@ -1632,6 +1720,9 @@ public static extern bool AddObjectToWorld2(IntPtr world, IntPtr obj);
1632public static extern bool RemoveObjectFromWorld2(IntPtr world, IntPtr obj); 1720public static extern bool RemoveObjectFromWorld2(IntPtr world, IntPtr obj);
1633 1721
1634[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1722[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1723public static extern bool ClearCollisionProxyCache2(IntPtr world, IntPtr obj);
1724
1725[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1635public static extern bool AddConstraintToWorld2(IntPtr world, IntPtr constrain, bool disableCollisionsBetweenLinkedObjects); 1726public static extern bool AddConstraintToWorld2(IntPtr world, IntPtr constrain, bool disableCollisionsBetweenLinkedObjects);
1636 1727
1637[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1728[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs
index 2a820be..17ebed2 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs
@@ -169,6 +169,19 @@ private sealed class BulletConstraintXNA : BulletConstraint
169 return true; 169 return true;
170 } 170 }
171 171
172 public override bool ClearCollisionProxyCache(BulletWorld pWorld, BulletBody pBody)
173 {
174 DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
175 RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
176 CollisionObject collisionObject = ((BulletBodyXNA)pBody).body;
177 if (body != null && collisionObject != null && collisionObject.GetBroadphaseHandle() != null)
178 {
179 world.RemoveCollisionObject(collisionObject);
180 world.AddCollisionObject(collisionObject);
181 }
182 return true;
183 }
184
172 public override bool AddConstraintToWorld(BulletWorld pWorld, BulletConstraint pConstraint, bool pDisableCollisionsBetweenLinkedObjects) 185 public override bool AddConstraintToWorld(BulletWorld pWorld, BulletConstraint pConstraint, bool pDisableCollisionsBetweenLinkedObjects)
173 { 186 {
174 DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; 187 DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
@@ -752,6 +765,214 @@ private sealed class BulletConstraintXNA : BulletConstraint
752 constraint.SetBreakingImpulseThreshold(threshold); 765 constraint.SetBreakingImpulseThreshold(threshold);
753 return true; 766 return true;
754 } 767 }
768 public override bool HingeSetLimits(BulletConstraint pConstraint, float low, float high, float softness, float bias, float relaxation)
769 {
770 HingeConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as HingeConstraint;
771 if (softness == HINGE_NOT_SPECIFIED)
772 constraint.SetLimit(low, high);
773 else
774 constraint.SetLimit(low, high, softness, bias, relaxation);
775 return true;
776 }
777 public override bool SpringEnable(BulletConstraint pConstraint, int index, float numericTrueFalse)
778 {
779 Generic6DofSpringConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofSpringConstraint;
780 constraint.EnableSpring(index, (numericTrueFalse == 0f ? false : true));
781 return true;
782 }
783
784 public override bool SpringSetEquilibriumPoint(BulletConstraint pConstraint, int index, float equilibriumPoint)
785 {
786 Generic6DofSpringConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofSpringConstraint;
787 if (index == SPRING_NOT_SPECIFIED)
788 {
789 constraint.SetEquilibriumPoint();
790 }
791 else
792 {
793 if (equilibriumPoint == SPRING_NOT_SPECIFIED)
794 constraint.SetEquilibriumPoint(index);
795 else
796 constraint.SetEquilibriumPoint(index, equilibriumPoint);
797 }
798 return true;
799 }
800
801 public override bool SpringSetStiffness(BulletConstraint pConstraint, int index, float stiffness)
802 {
803 Generic6DofSpringConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofSpringConstraint;
804 constraint.SetStiffness(index, stiffness);
805 return true;
806 }
807
808 public override bool SpringSetDamping(BulletConstraint pConstraint, int index, float damping)
809 {
810 Generic6DofSpringConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofSpringConstraint;
811 constraint.SetDamping(index, damping);
812 return true;
813 }
814
815 public override bool SliderSetLimits(BulletConstraint pConstraint, int lowerUpper, int linAng, float val)
816 {
817 SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint;
818 switch (lowerUpper)
819 {
820 case SLIDER_LOWER_LIMIT:
821 switch (linAng)
822 {
823 case SLIDER_LINEAR:
824 constraint.SetLowerLinLimit(val);
825 break;
826 case SLIDER_ANGULAR:
827 constraint.SetLowerAngLimit(val);
828 break;
829 }
830 break;
831 case SLIDER_UPPER_LIMIT:
832 switch (linAng)
833 {
834 case SLIDER_LINEAR:
835 constraint.SetUpperLinLimit(val);
836 break;
837 case SLIDER_ANGULAR:
838 constraint.SetUpperAngLimit(val);
839 break;
840 }
841 break;
842 }
843 return true;
844 }
845 public override bool SliderSet(BulletConstraint pConstraint, int softRestDamp, int dirLimOrtho, int linAng, float val)
846 {
847 SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint;
848 switch (softRestDamp)
849 {
850 case SLIDER_SET_SOFTNESS:
851 switch (dirLimOrtho)
852 {
853 case SLIDER_SET_DIRECTION:
854 switch (linAng)
855 {
856 case SLIDER_LINEAR: constraint.SetSoftnessDirLin(val); break;
857 case SLIDER_ANGULAR: constraint.SetSoftnessDirAng(val); break;
858 }
859 break;
860 case SLIDER_SET_LIMIT:
861 switch (linAng)
862 {
863 case SLIDER_LINEAR: constraint.SetSoftnessLimLin(val); break;
864 case SLIDER_ANGULAR: constraint.SetSoftnessLimAng(val); break;
865 }
866 break;
867 case SLIDER_SET_ORTHO:
868 switch (linAng)
869 {
870 case SLIDER_LINEAR: constraint.SetSoftnessOrthoLin(val); break;
871 case SLIDER_ANGULAR: constraint.SetSoftnessOrthoAng(val); break;
872 }
873 break;
874 }
875 break;
876 case SLIDER_SET_RESTITUTION:
877 switch (dirLimOrtho)
878 {
879 case SLIDER_SET_DIRECTION:
880 switch (linAng)
881 {
882 case SLIDER_LINEAR: constraint.SetRestitutionDirLin(val); break;
883 case SLIDER_ANGULAR: constraint.SetRestitutionDirAng(val); break;
884 }
885 break;
886 case SLIDER_SET_LIMIT:
887 switch (linAng)
888 {
889 case SLIDER_LINEAR: constraint.SetRestitutionLimLin(val); break;
890 case SLIDER_ANGULAR: constraint.SetRestitutionLimAng(val); break;
891 }
892 break;
893 case SLIDER_SET_ORTHO:
894 switch (linAng)
895 {
896 case SLIDER_LINEAR: constraint.SetRestitutionOrthoLin(val); break;
897 case SLIDER_ANGULAR: constraint.SetRestitutionOrthoAng(val); break;
898 }
899 break;
900 }
901 break;
902 case SLIDER_SET_DAMPING:
903 switch (dirLimOrtho)
904 {
905 case SLIDER_SET_DIRECTION:
906 switch (linAng)
907 {
908 case SLIDER_LINEAR: constraint.SetDampingDirLin(val); break;
909 case SLIDER_ANGULAR: constraint.SetDampingDirAng(val); break;
910 }
911 break;
912 case SLIDER_SET_LIMIT:
913 switch (linAng)
914 {
915 case SLIDER_LINEAR: constraint.SetDampingLimLin(val); break;
916 case SLIDER_ANGULAR: constraint.SetDampingLimAng(val); break;
917 }
918 break;
919 case SLIDER_SET_ORTHO:
920 switch (linAng)
921 {
922 case SLIDER_LINEAR: constraint.SetDampingOrthoLin(val); break;
923 case SLIDER_ANGULAR: constraint.SetDampingOrthoAng(val); break;
924 }
925 break;
926 }
927 break;
928 }
929 return true;
930 }
931 public override bool SliderMotorEnable(BulletConstraint pConstraint, int linAng, float numericTrueFalse)
932 {
933 SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint;
934 switch (linAng)
935 {
936 case SLIDER_LINEAR:
937 constraint.SetPoweredLinMotor(numericTrueFalse == 0.0 ? false : true);
938 break;
939 case SLIDER_ANGULAR:
940 constraint.SetPoweredAngMotor(numericTrueFalse == 0.0 ? false : true);
941 break;
942 }
943 return true;
944 }
945 public override bool SliderMotor(BulletConstraint pConstraint, int forceVel, int linAng, float val)
946 {
947 SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint;
948 switch (forceVel)
949 {
950 case SLIDER_MOTOR_VELOCITY:
951 switch (linAng)
952 {
953 case SLIDER_LINEAR:
954 constraint.SetTargetLinMotorVelocity(val);
955 break;
956 case SLIDER_ANGULAR:
957 constraint.SetTargetAngMotorVelocity(val);
958 break;
959 }
960 break;
961 case SLIDER_MAX_MOTOR_FORCE:
962 switch (linAng)
963 {
964 case SLIDER_LINEAR:
965 constraint.SetMaxLinMotorForce(val);
966 break;
967 case SLIDER_ANGULAR:
968 constraint.SetMaxAngMotorForce(val);
969 break;
970 }
971 break;
972 }
973 return true;
974 }
975
755 //BulletSimAPI.SetAngularDamping(Prim.PhysBody.ptr, angularDamping); 976 //BulletSimAPI.SetAngularDamping(Prim.PhysBody.ptr, angularDamping);
756 public override void SetAngularDamping(BulletBody pBody, float angularDamping) 977 public override void SetAngularDamping(BulletBody pBody, float angularDamping)
757 { 978 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs
index 68bc1b9..1bcf879 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs
@@ -105,7 +105,7 @@ public class BSActorAvatarMove : BSActor
105 // into the movement motor. 105 // into the movement motor.
106 public void SetVelocityAndTarget(OMV.Vector3 vel, OMV.Vector3 targ, bool inTaintTime) 106 public void SetVelocityAndTarget(OMV.Vector3 vel, OMV.Vector3 targ, bool inTaintTime)
107 { 107 {
108 m_physicsScene.TaintedObject(inTaintTime, "BSActorAvatarMove.setVelocityAndTarget", delegate() 108 m_physicsScene.TaintedObject(inTaintTime, m_controllingPrim.LocalID, "BSActorAvatarMove.setVelocityAndTarget", delegate()
109 { 109 {
110 if (m_velocityMotor != null) 110 if (m_velocityMotor != null)
111 { 111 {
@@ -128,6 +128,7 @@ public class BSActorAvatarMove : BSActor
128 BSMotor.Infinite, // decay time scale 128 BSMotor.Infinite, // decay time scale
129 1f // efficiency 129 1f // efficiency
130 ); 130 );
131 m_velocityMotor.ErrorZeroThreshold = BSParam.AvatarStopZeroThreshold;
131 // _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages. 132 // _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
132 SetVelocityAndTarget(m_controllingPrim.RawVelocity, m_controllingPrim.TargetVelocity, true /* inTaintTime */); 133 SetVelocityAndTarget(m_controllingPrim.RawVelocity, m_controllingPrim.TargetVelocity, true /* inTaintTime */);
133 134
@@ -278,6 +279,7 @@ public class BSActorAvatarMove : BSActor
278 if (m_controllingPrim.IsStationary) 279 if (m_controllingPrim.IsStationary)
279 { 280 {
280 entprop.Position = m_controllingPrim.RawPosition; 281 entprop.Position = m_controllingPrim.RawPosition;
282 entprop.Velocity = OMV.Vector3.Zero;
281 m_physicsScene.PE.SetTranslation(m_controllingPrim.PhysBody, entprop.Position, entprop.Rotation); 283 m_physicsScene.PE.SetTranslation(m_controllingPrim.PhysBody, entprop.Position, entprop.Rotation);
282 } 284 }
283 285
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs
index 6cdc112..f7dd158 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs
@@ -43,7 +43,9 @@ public enum ConstraintType : int
43 SLIDER_CONSTRAINT_TYPE, 43 SLIDER_CONSTRAINT_TYPE,
44 CONTACT_CONSTRAINT_TYPE, 44 CONTACT_CONSTRAINT_TYPE,
45 D6_SPRING_CONSTRAINT_TYPE, 45 D6_SPRING_CONSTRAINT_TYPE,
46 MAX_CONSTRAINT_TYPE 46 MAX_CONSTRAINT_TYPE, // last type defined by Bullet
47 //
48 FIXED_CONSTRAINT_TYPE = 1234 // BulletSim constraint that is fixed and unmoving
47} 49}
48 50
49// =============================================================================== 51// ===============================================================================
@@ -290,7 +292,7 @@ public enum ConstraintParamAxis : int
290 AXIS_ANGULAR_X, 292 AXIS_ANGULAR_X,
291 AXIS_ANGULAR_Y, 293 AXIS_ANGULAR_Y,
292 AXIS_ANGULAR_Z, 294 AXIS_ANGULAR_Z,
293 AXIS_LINEAR_ALL = 20, // these last three added by BulletSim so we don't have to do zillions of calls 295 AXIS_LINEAR_ALL = 20, // added by BulletSim so we don't have to do zillions of calls
294 AXIS_ANGULAR_ALL, 296 AXIS_ANGULAR_ALL,
295 AXIS_ALL 297 AXIS_ALL
296}; 298};
@@ -441,6 +443,38 @@ public abstract bool TranslationalLimitMotor(BulletConstraint constrain, float e
441 443
442public abstract bool SetBreakingImpulseThreshold(BulletConstraint constrain, float threshold); 444public abstract bool SetBreakingImpulseThreshold(BulletConstraint constrain, float threshold);
443 445
446public const int HINGE_NOT_SPECIFIED = -1;
447public abstract bool HingeSetLimits(BulletConstraint constrain, float low, float high, float softness, float bias, float relaxation);
448
449public abstract bool SpringEnable(BulletConstraint constrain, int index, float numericTrueFalse);
450
451public const int SPRING_NOT_SPECIFIED = -1;
452public abstract bool SpringSetEquilibriumPoint(BulletConstraint constrain, int index, float equilibriumPoint);
453
454public abstract bool SpringSetStiffness(BulletConstraint constrain, int index, float stiffnesss);
455
456public abstract bool SpringSetDamping(BulletConstraint constrain, int index, float damping);
457
458public const int SLIDER_LOWER_LIMIT = 0;
459public const int SLIDER_UPPER_LIMIT = 1;
460public const int SLIDER_LINEAR = 2;
461public const int SLIDER_ANGULAR = 3;
462public abstract bool SliderSetLimits(BulletConstraint constrain, int lowerUpper, int linAng, float val);
463
464public const int SLIDER_SET_SOFTNESS = 4;
465public const int SLIDER_SET_RESTITUTION = 5;
466public const int SLIDER_SET_DAMPING = 6;
467public const int SLIDER_SET_DIRECTION = 7;
468public const int SLIDER_SET_LIMIT = 8;
469public const int SLIDER_SET_ORTHO = 9;
470public abstract bool SliderSet(BulletConstraint constrain, int softRestDamp, int dirLimOrtho, int linAng, float val);
471
472public abstract bool SliderMotorEnable(BulletConstraint constrain, int linAng, float numericTrueFalse);
473
474public const int SLIDER_MOTOR_VELOCITY = 10;
475public const int SLIDER_MAX_MOTOR_FORCE = 11;
476public abstract bool SliderMotor(BulletConstraint constrain, int forceVel, int linAng, float val);
477
444public abstract bool CalculateTransforms(BulletConstraint constrain); 478public abstract bool CalculateTransforms(BulletConstraint constrain);
445 479
446public abstract bool SetConstraintParam(BulletConstraint constrain, ConstraintParams paramIndex, float value, ConstraintParamAxis axis); 480public abstract bool SetConstraintParam(BulletConstraint constrain, ConstraintParams paramIndex, float value, ConstraintParamAxis axis);
@@ -464,6 +498,8 @@ public abstract bool AddObjectToWorld(BulletWorld world, BulletBody obj);
464 498
465public abstract bool RemoveObjectFromWorld(BulletWorld world, BulletBody obj); 499public abstract bool RemoveObjectFromWorld(BulletWorld world, BulletBody obj);
466 500
501public abstract bool ClearCollisionProxyCache(BulletWorld world, BulletBody obj);
502
467public abstract bool AddConstraintToWorld(BulletWorld world, BulletConstraint constrain, bool disableCollisionsBetweenLinkedObjects); 503public abstract bool AddConstraintToWorld(BulletWorld world, BulletConstraint constrain, bool disableCollisionsBetweenLinkedObjects);
468 504
469public abstract bool RemoveConstraintFromWorld(BulletWorld world, BulletConstraint constrain); 505public abstract bool RemoveConstraintFromWorld(BulletWorld world, BulletConstraint constrain);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 291dfcd..fc18960 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -93,7 +93,7 @@ public sealed class BSCharacter : BSPhysObject
93 LocalID, _size, Scale, Density, _avatarVolume, RawMass, pos); 93 LocalID, _size, Scale, Density, _avatarVolume, RawMass, pos);
94 94
95 // do actual creation in taint time 95 // do actual creation in taint time
96 PhysScene.TaintedObject("BSCharacter.create", delegate() 96 PhysScene.TaintedObject(LocalID, "BSCharacter.create", delegate()
97 { 97 {
98 DetailLog("{0},BSCharacter.create,taint", LocalID); 98 DetailLog("{0},BSCharacter.create,taint", LocalID);
99 // New body and shape into PhysBody and PhysShape 99 // New body and shape into PhysBody and PhysShape
@@ -121,7 +121,7 @@ public sealed class BSCharacter : BSPhysObject
121 base.Destroy(); 121 base.Destroy();
122 122
123 DetailLog("{0},BSCharacter.Destroy", LocalID); 123 DetailLog("{0},BSCharacter.Destroy", LocalID);
124 PhysScene.TaintedObject("BSCharacter.destroy", delegate() 124 PhysScene.TaintedObject(LocalID, "BSCharacter.destroy", delegate()
125 { 125 {
126 PhysScene.Shapes.DereferenceBody(PhysBody, null /* bodyCallback */); 126 PhysScene.Shapes.DereferenceBody(PhysBody, null /* bodyCallback */);
127 PhysBody.Clear(); 127 PhysBody.Clear();
@@ -209,7 +209,7 @@ public sealed class BSCharacter : BSPhysObject
209 DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}", 209 DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}",
210 LocalID, _size, Scale, Density, _avatarVolume, RawMass); 210 LocalID, _size, Scale, Density, _avatarVolume, RawMass);
211 211
212 PhysScene.TaintedObject("BSCharacter.setSize", delegate() 212 PhysScene.TaintedObject(LocalID, "BSCharacter.setSize", delegate()
213 { 213 {
214 if (PhysBody.HasPhysicalBody && PhysShape.physShapeInfo.HasPhysicalShape) 214 if (PhysBody.HasPhysicalBody && PhysShape.physShapeInfo.HasPhysicalShape)
215 { 215 {
@@ -257,7 +257,7 @@ public sealed class BSCharacter : BSPhysObject
257 _rotationalVelocity = OMV.Vector3.Zero; 257 _rotationalVelocity = OMV.Vector3.Zero;
258 258
259 // Zero some other properties directly into the physics engine 259 // Zero some other properties directly into the physics engine
260 PhysScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate() 260 PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.ZeroMotion", delegate()
261 { 261 {
262 if (PhysBody.HasPhysicalBody) 262 if (PhysBody.HasPhysicalBody)
263 PhysScene.PE.ClearAllForces(PhysBody); 263 PhysScene.PE.ClearAllForces(PhysBody);
@@ -267,7 +267,7 @@ public sealed class BSCharacter : BSPhysObject
267 { 267 {
268 _rotationalVelocity = OMV.Vector3.Zero; 268 _rotationalVelocity = OMV.Vector3.Zero;
269 269
270 PhysScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate() 270 PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.ZeroMotion", delegate()
271 { 271 {
272 if (PhysBody.HasPhysicalBody) 272 if (PhysBody.HasPhysicalBody)
273 { 273 {
@@ -291,7 +291,7 @@ public sealed class BSCharacter : BSPhysObject
291 set { 291 set {
292 RawPosition = value; 292 RawPosition = value;
293 293
294 PhysScene.TaintedObject("BSCharacter.setPosition", delegate() 294 PhysScene.TaintedObject(LocalID, "BSCharacter.setPosition", delegate()
295 { 295 {
296 DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, RawPosition, RawOrientation); 296 DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, RawPosition, RawOrientation);
297 PositionSanityCheck(); 297 PositionSanityCheck();
@@ -363,7 +363,7 @@ public sealed class BSCharacter : BSPhysObject
363 { 363 {
364 // The new position value must be pushed into the physics engine but we can't 364 // The new position value must be pushed into the physics engine but we can't
365 // just assign to "Position" because of potential call loops. 365 // just assign to "Position" because of potential call loops.
366 PhysScene.TaintedObject(inTaintTime, "BSCharacter.PositionSanityCheck", delegate() 366 PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.PositionSanityCheck", delegate()
367 { 367 {
368 DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, RawPosition, RawOrientation); 368 DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, RawPosition, RawOrientation);
369 ForcePosition = RawPosition; 369 ForcePosition = RawPosition;
@@ -390,7 +390,7 @@ public sealed class BSCharacter : BSPhysObject
390 set { 390 set {
391 RawForce = value; 391 RawForce = value;
392 // m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force); 392 // m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force);
393 PhysScene.TaintedObject("BSCharacter.SetForce", delegate() 393 PhysScene.TaintedObject(LocalID, "BSCharacter.SetForce", delegate()
394 { 394 {
395 DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, RawForce); 395 DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, RawForce);
396 if (PhysBody.HasPhysicalBody) 396 if (PhysBody.HasPhysicalBody)
@@ -438,7 +438,7 @@ public sealed class BSCharacter : BSPhysObject
438 set { 438 set {
439 RawVelocity = value; 439 RawVelocity = value;
440 // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, RawVelocity); 440 // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, RawVelocity);
441 PhysScene.TaintedObject("BSCharacter.setVelocity", delegate() 441 PhysScene.TaintedObject(LocalID, "BSCharacter.setVelocity", delegate()
442 { 442 {
443 if (m_moveActor != null) 443 if (m_moveActor != null)
444 m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, true /* inTaintTime */); 444 m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, true /* inTaintTime */);
@@ -480,7 +480,7 @@ public sealed class BSCharacter : BSPhysObject
480 if (RawOrientation != value) 480 if (RawOrientation != value)
481 { 481 {
482 RawOrientation = value; 482 RawOrientation = value;
483 PhysScene.TaintedObject("BSCharacter.setOrientation", delegate() 483 PhysScene.TaintedObject(LocalID, "BSCharacter.setOrientation", delegate()
484 { 484 {
485 // Bullet assumes we know what we are doing when forcing orientation 485 // Bullet assumes we know what we are doing when forcing orientation
486 // so it lets us go against all the rules and just compensates for them later. 486 // so it lets us go against all the rules and just compensates for them later.
@@ -560,7 +560,7 @@ public sealed class BSCharacter : BSPhysObject
560 public override bool FloatOnWater { 560 public override bool FloatOnWater {
561 set { 561 set {
562 _floatOnWater = value; 562 _floatOnWater = value;
563 PhysScene.TaintedObject("BSCharacter.setFloatOnWater", delegate() 563 PhysScene.TaintedObject(LocalID, "BSCharacter.setFloatOnWater", delegate()
564 { 564 {
565 if (PhysBody.HasPhysicalBody) 565 if (PhysBody.HasPhysicalBody)
566 { 566 {
@@ -588,7 +588,7 @@ public sealed class BSCharacter : BSPhysObject
588 public override float Buoyancy { 588 public override float Buoyancy {
589 get { return _buoyancy; } 589 get { return _buoyancy; }
590 set { _buoyancy = value; 590 set { _buoyancy = value;
591 PhysScene.TaintedObject("BSCharacter.setBuoyancy", delegate() 591 PhysScene.TaintedObject(LocalID, "BSCharacter.setBuoyancy", delegate()
592 { 592 {
593 DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy); 593 DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
594 ForceBuoyancy = _buoyancy; 594 ForceBuoyancy = _buoyancy;
@@ -633,7 +633,7 @@ public sealed class BSCharacter : BSPhysObject
633 OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude); 633 OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude);
634 // DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce); 634 // DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce);
635 635
636 PhysScene.TaintedObject(inTaintTime, "BSCharacter.AddForce", delegate() 636 PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.AddForce", delegate()
637 { 637 {
638 // Bullet adds this central force to the total force for this tick 638 // Bullet adds this central force to the total force for this tick
639 // DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce); 639 // DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce);
@@ -676,18 +676,20 @@ public sealed class BSCharacter : BSPhysObject
676 float heightAdjust = BSParam.AvatarHeightMidFudge; 676 float heightAdjust = BSParam.AvatarHeightMidFudge;
677 if (BSParam.AvatarHeightLowFudge != 0f || BSParam.AvatarHeightHighFudge != 0f) 677 if (BSParam.AvatarHeightLowFudge != 0f || BSParam.AvatarHeightHighFudge != 0f)
678 { 678 {
679 // An avatar is between 1.61 and 2.12 meters. Midpoint is 1.87m. 679 const float AVATAR_LOW = 1.1f;
680 // The "times 4" relies on the fact that the difference from the midpoint to the extremes is exactly 0.25 680 const float AVATAR_MID = 1.775f; // 1.87f
681 float midHeightOffset = size.Z - 1.87f; 681 const float AVATAR_HI = 2.45f;
682 // An avatar is between 1.1 and 2.45 meters. Midpoint is 1.775m.
683 float midHeightOffset = size.Z - AVATAR_MID;
682 if (midHeightOffset < 0f) 684 if (midHeightOffset < 0f)
683 { 685 {
684 // Small avatar. Add the adjustment based on the distance from midheight 686 // Small avatar. Add the adjustment based on the distance from midheight
685 heightAdjust += -1f * midHeightOffset * 4f * BSParam.AvatarHeightLowFudge; 687 heightAdjust += ((-1f * midHeightOffset) / (AVATAR_MID - AVATAR_LOW)) * BSParam.AvatarHeightLowFudge;
686 } 688 }
687 else 689 else
688 { 690 {
689 // Large avatar. Add the adjustment based on the distance from midheight 691 // Large avatar. Add the adjustment based on the distance from midheight
690 heightAdjust += midHeightOffset * 4f * BSParam.AvatarHeightHighFudge; 692 heightAdjust += ((midHeightOffset) / (AVATAR_HI - AVATAR_MID)) * BSParam.AvatarHeightHighFudge;
691 } 693 }
692 } 694 }
693 // The total scale height is the central cylindar plus the caps on the two ends. 695 // The total scale height is the central cylindar plus the caps on the two ends.
@@ -698,6 +700,9 @@ public sealed class BSCharacter : BSPhysObject
698 if (newScale.Z < 0) 700 if (newScale.Z < 0)
699 newScale.Z = 0.1f; 701 newScale.Z = 0.1f;
700 702
703 DetailLog("{0},BSCharacter.ComputerAvatarScale,size={1},lowF={2},midF={3},hiF={4},adj={5},newScale={6}",
704 LocalID, size, BSParam.AvatarHeightLowFudge, BSParam.AvatarHeightMidFudge, BSParam.AvatarHeightHighFudge, heightAdjust, newScale);
705
701 return newScale; 706 return newScale;
702 } 707 }
703 708
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
index 42b5c49..b47e9a8 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
@@ -64,7 +64,7 @@ public abstract class BSConstraint : IDisposable
64 { 64 {
65 bool success = PhysicsScene.PE.DestroyConstraint(m_world, m_constraint); 65 bool success = PhysicsScene.PE.DestroyConstraint(m_world, m_constraint);
66 m_world.physicsScene.DetailLog("{0},BSConstraint.Dispose,taint,id1={1},body1={2},id2={3},body2={4},success={5}", 66 m_world.physicsScene.DetailLog("{0},BSConstraint.Dispose,taint,id1={1},body1={2},id2={3},body2={4},success={5}",
67 BSScene.DetailLogZero, 67 m_body1.ID,
68 m_body1.ID, m_body1.AddrString, 68 m_body1.ID, m_body1.AddrString,
69 m_body2.ID, m_body2.AddrString, 69 m_body2.ID, m_body2.AddrString,
70 success); 70 success);
@@ -77,7 +77,10 @@ public abstract class BSConstraint : IDisposable
77 { 77 {
78 bool ret = false; 78 bool ret = false;
79 if (m_enabled) 79 if (m_enabled)
80 {
81 m_world.physicsScene.DetailLog("{0},BSConstraint.SetLinearLimits,taint,low={1},high={2}", m_body1.ID, low, high);
80 ret = PhysicsScene.PE.SetLinearLimits(m_constraint, low, high); 82 ret = PhysicsScene.PE.SetLinearLimits(m_constraint, low, high);
83 }
81 return ret; 84 return ret;
82 } 85 }
83 86
@@ -86,6 +89,7 @@ public abstract class BSConstraint : IDisposable
86 bool ret = false; 89 bool ret = false;
87 if (m_enabled) 90 if (m_enabled)
88 { 91 {
92 m_world.physicsScene.DetailLog("{0},BSConstraint.SetAngularLimits,taint,low={1},high={2}", m_body1.ID, low, high);
89 ret = PhysicsScene.PE.SetAngularLimits(m_constraint, low, high); 93 ret = PhysicsScene.PE.SetAngularLimits(m_constraint, low, high);
90 } 94 }
91 return ret; 95 return ret;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs
index d0949f5..7fcb75c 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs
@@ -32,12 +32,19 @@ using OpenMetaverse;
32namespace OpenSim.Region.Physics.BulletSPlugin 32namespace OpenSim.Region.Physics.BulletSPlugin
33{ 33{
34 34
35public sealed class BSConstraint6Dof : BSConstraint 35public class BSConstraint6Dof : BSConstraint
36{ 36{
37 private static string LogHeader = "[BULLETSIM 6DOF CONSTRAINT]"; 37 private static string LogHeader = "[BULLETSIM 6DOF CONSTRAINT]";
38 38
39 public override ConstraintType Type { get { return ConstraintType.D6_CONSTRAINT_TYPE; } } 39 public override ConstraintType Type { get { return ConstraintType.D6_CONSTRAINT_TYPE; } }
40 40
41 public BSConstraint6Dof(BulletWorld world, BulletBody obj1, BulletBody obj2) :base(world)
42 {
43 m_body1 = obj1;
44 m_body2 = obj2;
45 m_enabled = false;
46 }
47
41 // Create a btGeneric6DofConstraint 48 // Create a btGeneric6DofConstraint
42 public BSConstraint6Dof(BulletWorld world, BulletBody obj1, BulletBody obj2, 49 public BSConstraint6Dof(BulletWorld world, BulletBody obj1, BulletBody obj2,
43 Vector3 frame1, Quaternion frame1rot, 50 Vector3 frame1, Quaternion frame1rot,
@@ -52,9 +59,11 @@ public sealed class BSConstraint6Dof : BSConstraint
52 frame2, frame2rot, 59 frame2, frame2rot,
53 useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies); 60 useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
54 m_enabled = true; 61 m_enabled = true;
55 world.physicsScene.DetailLog("{0},BS6DofConstraint,createFrame,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}", 62 PhysicsScene.DetailLog("{0},BS6DofConstraint,create,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
56 BSScene.DetailLogZero, world.worldID, 63 m_body1.ID, world.worldID,
57 obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString); 64 obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString);
65 PhysicsScene.DetailLog("{0},BS6DofConstraint,create, f1Loc={1},f1Rot={2},f2Loc={3},f2Rot={4},usefA={5},disCol={6}",
66 m_body1.ID, frame1, frame1rot, frame2, frame2rot, useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
58 } 67 }
59 68
60 // 6 Dof constraint based on a midpoint between the two constrained bodies 69 // 6 Dof constraint based on a midpoint between the two constrained bodies
@@ -79,9 +88,11 @@ public sealed class BSConstraint6Dof : BSConstraint
79 m_constraint = PhysicsScene.PE.Create6DofConstraintToPoint(m_world, m_body1, m_body2, 88 m_constraint = PhysicsScene.PE.Create6DofConstraintToPoint(m_world, m_body1, m_body2,
80 joinPoint, 89 joinPoint,
81 useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies); 90 useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
91
82 PhysicsScene.DetailLog("{0},BS6DofConstraint,createMidPoint,wID={1}, csrt={2}, rID={3}, rBody={4}, cID={5}, cBody={6}", 92 PhysicsScene.DetailLog("{0},BS6DofConstraint,createMidPoint,wID={1}, csrt={2}, rID={3}, rBody={4}, cID={5}, cBody={6}",
83 BSScene.DetailLogZero, world.worldID, m_constraint.AddrString, 93 m_body1.ID, world.worldID, m_constraint.AddrString,
84 obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString); 94 obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString);
95
85 if (!m_constraint.HasPhysicalConstraint) 96 if (!m_constraint.HasPhysicalConstraint)
86 { 97 {
87 world.physicsScene.Logger.ErrorFormat("{0} Failed creation of 6Dof constraint. rootID={1}, childID={2}", 98 world.physicsScene.Logger.ErrorFormat("{0} Failed creation of 6Dof constraint. rootID={1}, childID={2}",
@@ -106,8 +117,10 @@ public sealed class BSConstraint6Dof : BSConstraint
106 frameInBloc, frameInBrot, 117 frameInBloc, frameInBrot,
107 useLinearReferenceFrameB, disableCollisionsBetweenLinkedBodies); 118 useLinearReferenceFrameB, disableCollisionsBetweenLinkedBodies);
108 m_enabled = true; 119 m_enabled = true;
109 world.physicsScene.DetailLog("{0},BS6DofConstraint,createFixed,wID={1},rID={2},rBody={3}", 120 PhysicsScene.DetailLog("{0},BS6DofConstraint,createFixed,wID={1},rID={2},rBody={3}",
110 BSScene.DetailLogZero, world.worldID, obj1.ID, obj1.AddrString); 121 m_body1.ID, world.worldID, obj1.ID, obj1.AddrString);
122 PhysicsScene.DetailLog("{0},BS6DofConstraint,createFixed, fBLoc={1},fBRot={2},usefA={3},disCol={4}",
123 m_body1.ID, frameInBloc, frameInBrot, useLinearReferenceFrameB, disableCollisionsBetweenLinkedBodies);
111 } 124 }
112 125
113 public bool SetFrames(Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot) 126 public bool SetFrames(Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintConeTwist.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintConeTwist.cs
new file mode 100755
index 0000000..7a76a9a
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintConeTwist.cs
@@ -0,0 +1,54 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyrightD
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using System.Collections.Generic;
29using System.Text;
30using OpenMetaverse;
31
32namespace OpenSim.Region.Physics.BulletSPlugin
33{
34
35public sealed class BSConstraintConeTwist : BSConstraint
36{
37 public override ConstraintType Type { get { return ConstraintType.CONETWIST_CONSTRAINT_TYPE; } }
38
39 public BSConstraintConeTwist(BulletWorld world, BulletBody obj1, BulletBody obj2,
40 Vector3 frameInAloc, Quaternion frameInArot,
41 Vector3 frameInBloc, Quaternion frameInBrot,
42 bool disableCollisionsBetweenLinkedBodies)
43 : base(world)
44 {
45 m_body1 = obj1;
46 m_body2 = obj2;
47 m_constraint = PhysicsScene.PE.CreateConeTwistConstraint(world, obj1, obj2,
48 frameInAloc, frameInArot, frameInBloc, frameInBrot,
49 disableCollisionsBetweenLinkedBodies);
50 m_enabled = true;
51 }
52}
53
54}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintSlider.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintSlider.cs
new file mode 100755
index 0000000..37cfa07
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintSlider.cs
@@ -0,0 +1,55 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyrightD
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using System.Collections.Generic;
29using System.Text;
30using OpenMetaverse;
31
32namespace OpenSim.Region.Physics.BulletSPlugin
33{
34
35public sealed class BSConstraintSlider : BSConstraint
36{
37 public override ConstraintType Type { get { return ConstraintType.SLIDER_CONSTRAINT_TYPE; } }
38
39 public BSConstraintSlider(BulletWorld world, BulletBody obj1, BulletBody obj2,
40 Vector3 frameInAloc, Quaternion frameInArot,
41 Vector3 frameInBloc, Quaternion frameInBrot,
42 bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)
43 : base(world)
44 {
45 m_body1 = obj1;
46 m_body2 = obj2;
47 m_constraint = PhysicsScene.PE.CreateSliderConstraint(world, obj1, obj2,
48 frameInAloc, frameInArot, frameInBloc, frameInBrot,
49 useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
50 m_enabled = true;
51 }
52
53}
54
55}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintSpring.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintSpring.cs
new file mode 100755
index 0000000..8e7ddff
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintSpring.cs
@@ -0,0 +1,103 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyrightD
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using System.Collections.Generic;
29using System.Text;
30using OpenMetaverse;
31
32namespace OpenSim.Region.Physics.BulletSPlugin
33{
34
35public sealed class BSConstraintSpring : BSConstraint6Dof
36{
37 public override ConstraintType Type { get { return ConstraintType.D6_SPRING_CONSTRAINT_TYPE; } }
38
39 public BSConstraintSpring(BulletWorld world, BulletBody obj1, BulletBody obj2,
40 Vector3 frame1Loc, Quaternion frame1Rot,
41 Vector3 frame2Loc, Quaternion frame2Rot,
42 bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)
43 :base(world, obj1, obj2)
44 {
45 m_constraint = PhysicsScene.PE.Create6DofSpringConstraint(world, obj1, obj2,
46 frame1Loc, frame1Rot, frame2Loc, frame2Rot,
47 useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
48 m_enabled = true;
49
50 PhysicsScene.DetailLog("{0},BSConstraintSpring,create,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
51 obj1.ID, world.worldID, obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString);
52 PhysicsScene.DetailLog("{0},BSConstraintSpring,create, f1Loc={1},f1Rot={2},f2Loc={3},f2Rot={4},usefA={5},disCol={6}",
53 m_body1.ID, frame1Loc, frame1Rot, frame2Loc, frame2Rot, useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
54 }
55
56 public bool SetAxisEnable(int pIndex, bool pAxisEnable)
57 {
58 PhysicsScene.DetailLog("{0},BSConstraintSpring.SetEnable,obj1ID={1},obj2ID={2},indx={3},enable={4}",
59 m_body1.ID, m_body1.ID, m_body2.ID, pIndex, pAxisEnable);
60 PhysicsScene.PE.SpringEnable(m_constraint, pIndex, BSParam.NumericBool(pAxisEnable));
61 return true;
62 }
63
64 public bool SetStiffness(int pIndex, float pStiffness)
65 {
66 PhysicsScene.DetailLog("{0},BSConstraintSpring.SetStiffness,obj1ID={1},obj2ID={2},indx={3},stiff={4}",
67 m_body1.ID, m_body1.ID, m_body2.ID, pIndex, pStiffness);
68 PhysicsScene.PE.SpringSetStiffness(m_constraint, pIndex, pStiffness);
69 return true;
70 }
71
72 public bool SetDamping(int pIndex, float pDamping)
73 {
74 PhysicsScene.DetailLog("{0},BSConstraintSpring.SetDamping,obj1ID={1},obj2ID={2},indx={3},damp={4}",
75 m_body1.ID, m_body1.ID, m_body2.ID, pIndex, pDamping);
76 PhysicsScene.PE.SpringSetDamping(m_constraint, pIndex, pDamping);
77 return true;
78 }
79
80 public bool SetEquilibriumPoint(int pIndex, float pEqPoint)
81 {
82 PhysicsScene.DetailLog("{0},BSConstraintSpring.SetEquilibriumPoint,obj1ID={1},obj2ID={2},indx={3},eqPoint={4}",
83 m_body1.ID, m_body1.ID, m_body2.ID, pIndex, pEqPoint);
84 PhysicsScene.PE.SpringSetEquilibriumPoint(m_constraint, pIndex, pEqPoint);
85 return true;
86 }
87
88 public bool SetEquilibriumPoint(Vector3 linearEq, Vector3 angularEq)
89 {
90 PhysicsScene.DetailLog("{0},BSConstraintSpring.SetEquilibriumPoint,obj1ID={1},obj2ID={2},linearEq={3},angularEq={4}",
91 m_body1.ID, m_body1.ID, m_body2.ID, linearEq, angularEq);
92 PhysicsScene.PE.SpringSetEquilibriumPoint(m_constraint, 0, linearEq.X);
93 PhysicsScene.PE.SpringSetEquilibriumPoint(m_constraint, 1, linearEq.Y);
94 PhysicsScene.PE.SpringSetEquilibriumPoint(m_constraint, 2, linearEq.Z);
95 PhysicsScene.PE.SpringSetEquilibriumPoint(m_constraint, 3, angularEq.X);
96 PhysicsScene.PE.SpringSetEquilibriumPoint(m_constraint, 4, angularEq.Y);
97 PhysicsScene.PE.SpringSetEquilibriumPoint(m_constraint, 5, angularEq.Z);
98 return true;
99 }
100
101}
102
103} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index 3afd52e..77f69a5 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -77,6 +77,10 @@ public abstract class BSLinkset
77 { 77 {
78 member = pMember; 78 member = pMember;
79 } 79 }
80 public virtual void ResetLink() { }
81 public virtual void SetLinkParameters(BSConstraint constrain) { }
82 // Returns 'true' if physical property updates from the child should be reported to the simulator
83 public virtual bool ShouldUpdateChildProperties() { return false; }
80 } 84 }
81 85
82 public LinksetImplementation LinksetImpl { get; protected set; } 86 public LinksetImplementation LinksetImpl { get; protected set; }
@@ -148,7 +152,7 @@ public abstract class BSLinkset
148 // Returns a new linkset for the child which is a linkset of one (just the 152 // Returns a new linkset for the child which is a linkset of one (just the
149 // orphened child). 153 // orphened child).
150 // Called at runtime. 154 // Called at runtime.
151 public BSLinkset RemoveMeFromLinkset(BSPrimLinkable child) 155 public BSLinkset RemoveMeFromLinkset(BSPrimLinkable child, bool inTaintTime)
152 { 156 {
153 lock (m_linksetActivityLock) 157 lock (m_linksetActivityLock)
154 { 158 {
@@ -157,7 +161,7 @@ public abstract class BSLinkset
157 // Cannot remove the root from a linkset. 161 // Cannot remove the root from a linkset.
158 return this; 162 return this;
159 } 163 }
160 RemoveChildFromLinkset(child); 164 RemoveChildFromLinkset(child, inTaintTime);
161 LinksetMass = ComputeLinksetMass(); 165 LinksetMass = ComputeLinksetMass();
162 } 166 }
163 167
@@ -205,6 +209,17 @@ public abstract class BSLinkset
205 return ret; 209 return ret;
206 } 210 }
207 211
212 public bool TryGetLinkInfo(BSPrimLinkable child, out BSLinkInfo foundInfo)
213 {
214 bool ret = false;
215 BSLinkInfo found = null;
216 lock (m_linksetActivityLock)
217 {
218 ret = m_children.TryGetValue(child, out found);
219 }
220 foundInfo = found;
221 return ret;
222 }
208 // Perform an action on each member of the linkset including root prim. 223 // Perform an action on each member of the linkset including root prim.
209 // Depends on the action on whether this should be done at taint time. 224 // Depends on the action on whether this should be done at taint time.
210 public delegate bool ForEachLinkInfoAction(BSLinkInfo obj); 225 public delegate bool ForEachLinkInfoAction(BSLinkInfo obj);
@@ -222,6 +237,21 @@ public abstract class BSLinkset
222 return ret; 237 return ret;
223 } 238 }
224 239
240 // Check the type of the link and return 'true' if the link is flexible and the
241 // updates from the child should be sent to the simulator so things change.
242 public virtual bool ShouldReportPropertyUpdates(BSPrimLinkable child)
243 {
244 bool ret = false;
245
246 BSLinkInfo linkInfo;
247 if (m_children.TryGetValue(child, out linkInfo))
248 {
249 ret = linkInfo.ShouldUpdateChildProperties();
250 }
251
252 return ret;
253 }
254
225 // Called after a simulation step to post a collision with this object. 255 // Called after a simulation step to post a collision with this object.
226 // Return 'true' if linkset processed the collision. 'false' says the linkset didn't have 256 // Return 'true' if linkset processed the collision. 'false' says the linkset didn't have
227 // anything to add for the collision and it should be passed through normal processing. 257 // anything to add for the collision and it should be passed through normal processing.
@@ -255,7 +285,7 @@ public abstract class BSLinkset
255 285
256 // I am the root of a linkset and one of my children is being removed. 286 // I am the root of a linkset and one of my children is being removed.
257 // Safe to call even if the child is not really in my linkset. 287 // Safe to call even if the child is not really in my linkset.
258 protected abstract void RemoveChildFromLinkset(BSPrimLinkable child); 288 protected abstract void RemoveChildFromLinkset(BSPrimLinkable child, bool inTaintTime);
259 289
260 // When physical properties are changed the linkset needs to recalculate 290 // When physical properties are changed the linkset needs to recalculate
261 // its internal properties. 291 // its internal properties.
@@ -430,6 +460,13 @@ public abstract class BSLinkset
430 return com; 460 return com;
431 } 461 }
432 462
463 #region Extension
464 public virtual object Extension(string pFunct, params object[] pParams)
465 {
466 return null;
467 }
468 #endregion // Extension
469
433 // Invoke the detailed logger and output something if it's enabled. 470 // Invoke the detailed logger and output something if it's enabled.
434 protected void DetailLog(string msg, params Object[] args) 471 protected void DetailLog(string msg, params Object[] args)
435 { 472 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
index 085d195..8f12189 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
@@ -90,10 +90,9 @@ public sealed class BSLinksetCompound : BSLinkset
90 // its internal properties. 90 // its internal properties.
91 public override void Refresh(BSPrimLinkable requestor) 91 public override void Refresh(BSPrimLinkable requestor)
92 { 92 {
93 base.Refresh(requestor);
94
95 // Something changed so do the rebuilding thing 93 // Something changed so do the rebuilding thing
96 // ScheduleRebuild(); 94 ScheduleRebuild(requestor);
95 base.Refresh(requestor);
97 } 96 }
98 97
99 // Schedule a refresh to happen after all the other taint processing. 98 // Schedule a refresh to happen after all the other taint processing.
@@ -127,7 +126,7 @@ public sealed class BSLinksetCompound : BSLinkset
127 if (IsRoot(child)) 126 if (IsRoot(child))
128 { 127 {
129 // The root is going dynamic. Rebuild the linkset so parts and mass get computed properly. 128 // The root is going dynamic. Rebuild the linkset so parts and mass get computed properly.
130 ScheduleRebuild(LinksetRoot); 129 Refresh(LinksetRoot);
131 } 130 }
132 return ret; 131 return ret;
133 } 132 }
@@ -144,7 +143,7 @@ public sealed class BSLinksetCompound : BSLinkset
144 if (IsRoot(child)) 143 if (IsRoot(child))
145 { 144 {
146 // Schedule a rebuild to verify that the root shape is set to the real shape. 145 // Schedule a rebuild to verify that the root shape is set to the real shape.
147 ScheduleRebuild(LinksetRoot); 146 Refresh(LinksetRoot);
148 } 147 }
149 return ret; 148 return ret;
150 } 149 }
@@ -227,7 +226,7 @@ public sealed class BSLinksetCompound : BSLinkset
227 // there will already be a rebuild scheduled. 226 // there will already be a rebuild scheduled.
228 DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild.schedulingRebuild,whichUpdated={1}", 227 DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild.schedulingRebuild,whichUpdated={1}",
229 updated.LocalID, whichUpdated); 228 updated.LocalID, whichUpdated);
230 ScheduleRebuild(updated); 229 Refresh(updated);
231 } 230 }
232 } 231 }
233 } 232 }
@@ -242,10 +241,10 @@ public sealed class BSLinksetCompound : BSLinkset
242 { 241 {
243 bool ret = false; 242 bool ret = false;
244 243
245 DetailLog("{0},BSLinksetCompound.RemoveBodyDependencies,refreshIfChild,rID={1},rBody={2},isRoot={3}", 244 DetailLog("{0},BSLinksetCompound.RemoveDependencies,refreshIfChild,rID={1},rBody={2},isRoot={3}",
246 child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody, IsRoot(child)); 245 child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody, IsRoot(child));
247 246
248 ScheduleRebuild(child); 247 Refresh(child);
249 248
250 return ret; 249 return ret;
251 } 250 }
@@ -263,14 +262,14 @@ public sealed class BSLinksetCompound : BSLinkset
263 DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); 262 DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID);
264 263
265 // Rebuild the compound shape with the new child shape included 264 // Rebuild the compound shape with the new child shape included
266 ScheduleRebuild(child); 265 Refresh(child);
267 } 266 }
268 return; 267 return;
269 } 268 }
270 269
271 // Remove the specified child from the linkset. 270 // Remove the specified child from the linkset.
272 // Safe to call even if the child is not really in the linkset. 271 // Safe to call even if the child is not really in the linkset.
273 protected override void RemoveChildFromLinkset(BSPrimLinkable child) 272 protected override void RemoveChildFromLinkset(BSPrimLinkable child, bool inTaintTime)
274 { 273 {
275 child.ClearDisplacement(); 274 child.ClearDisplacement();
276 275
@@ -282,17 +281,17 @@ public sealed class BSLinksetCompound : BSLinkset
282 child.LocalID, child.PhysBody.AddrString); 281 child.LocalID, child.PhysBody.AddrString);
283 282
284 // Cause the child's body to be rebuilt and thus restored to normal operation 283 // Cause the child's body to be rebuilt and thus restored to normal operation
285 child.ForceBodyShapeRebuild(false); 284 child.ForceBodyShapeRebuild(inTaintTime);
286 285
287 if (!HasAnyChildren) 286 if (!HasAnyChildren)
288 { 287 {
289 // The linkset is now empty. The root needs rebuilding. 288 // The linkset is now empty. The root needs rebuilding.
290 LinksetRoot.ForceBodyShapeRebuild(false); 289 LinksetRoot.ForceBodyShapeRebuild(inTaintTime);
291 } 290 }
292 else 291 else
293 { 292 {
294 // Rebuild the compound shape with the child removed 293 // Rebuild the compound shape with the child removed
295 ScheduleRebuild(LinksetRoot); 294 Refresh(LinksetRoot);
296 } 295 }
297 } 296 }
298 return; 297 return;
@@ -318,10 +317,10 @@ public sealed class BSLinksetCompound : BSLinkset
318 // being destructed and going non-physical. 317 // being destructed and going non-physical.
319 LinksetRoot.ForceBodyShapeRebuild(true); 318 LinksetRoot.ForceBodyShapeRebuild(true);
320 319
321 // There is no reason to build all this physical stuff for a non-physical linkset. 320 // There is no reason to build all this physical stuff for a non-physical or empty linkset.
322 if (!LinksetRoot.IsPhysicallyActive) 321 if (!LinksetRoot.IsPhysicallyActive || !HasAnyChildren)
323 { 322 {
324 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,notPhysical", LinksetRoot.LocalID); 323 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,notPhysicalOrNoChildren", LinksetRoot.LocalID);
325 return; // Note the 'finally' clause at the botton which will get executed. 324 return; // Note the 'finally' clause at the botton which will get executed.
326 } 325 }
327 326
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
index 4bac222..aaf92c8 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -28,6 +28,8 @@ using System;
28using System.Collections.Generic; 28using System.Collections.Generic;
29using System.Text; 29using System.Text;
30 30
31using OpenSim.Region.OptionalModules.Scripting;
32
31using OMV = OpenMetaverse; 33using OMV = OpenMetaverse;
32 34
33namespace OpenSim.Region.Physics.BulletSPlugin 35namespace OpenSim.Region.Physics.BulletSPlugin
@@ -51,18 +53,32 @@ public sealed class BSLinksetConstraints : BSLinkset
51 public float cfm; 53 public float cfm;
52 public float erp; 54 public float erp;
53 public float solverIterations; 55 public float solverIterations;
56 //
57 public OMV.Vector3 frameInAloc;
58 public OMV.Quaternion frameInArot;
59 public OMV.Vector3 frameInBloc;
60 public OMV.Quaternion frameInBrot;
61 public bool useLinearReferenceFrameA;
62 // Spring
63 public bool[] springAxisEnable;
64 public float[] springDamping;
65 public float[] springStiffness;
66 public OMV.Vector3 springLinearEquilibriumPoint;
67 public OMV.Vector3 springAngularEquilibriumPoint;
54 68
55 public BSLinkInfoConstraint(BSPrimLinkable pMember) 69 public BSLinkInfoConstraint(BSPrimLinkable pMember)
56 : base(pMember) 70 : base(pMember)
57 { 71 {
58 constraint = null; 72 constraint = null;
59 ResetToFixedConstraint(); 73 ResetLink();
74 member.PhysScene.DetailLog("{0},BSLinkInfoConstraint.creation", member.LocalID);
60 } 75 }
61 76
62 // Set all the parameters for this constraint to a fixed, non-movable constraint. 77 // Set all the parameters for this constraint to a fixed, non-movable constraint.
63 public void ResetToFixedConstraint() 78 public override void ResetLink()
64 { 79 {
65 constraintType = ConstraintType.D6_CONSTRAINT_TYPE; 80 // constraintType = ConstraintType.D6_CONSTRAINT_TYPE;
81 constraintType = ConstraintType.FIXED_CONSTRAINT_TYPE;
66 linearLimitLow = OMV.Vector3.Zero; 82 linearLimitLow = OMV.Vector3.Zero;
67 linearLimitHigh = OMV.Vector3.Zero; 83 linearLimitHigh = OMV.Vector3.Zero;
68 angularLimitLow = OMV.Vector3.Zero; 84 angularLimitLow = OMV.Vector3.Zero;
@@ -74,17 +90,37 @@ public sealed class BSLinksetConstraints : BSLinkset
74 cfm = BSParam.LinkConstraintCFM; 90 cfm = BSParam.LinkConstraintCFM;
75 erp = BSParam.LinkConstraintERP; 91 erp = BSParam.LinkConstraintERP;
76 solverIterations = BSParam.LinkConstraintSolverIterations; 92 solverIterations = BSParam.LinkConstraintSolverIterations;
93 frameInAloc = OMV.Vector3.Zero;
94 frameInArot = OMV.Quaternion.Identity;
95 frameInBloc = OMV.Vector3.Zero;
96 frameInBrot = OMV.Quaternion.Identity;
97 useLinearReferenceFrameA = true;
98 springAxisEnable = new bool[6];
99 springDamping = new float[6];
100 springStiffness = new float[6];
101 for (int ii = 0; ii < springAxisEnable.Length; ii++)
102 {
103 springAxisEnable[ii] = false;
104 springDamping[ii] = BSAPITemplate.SPRING_NOT_SPECIFIED;
105 springStiffness[ii] = BSAPITemplate.SPRING_NOT_SPECIFIED;
106 }
107 springLinearEquilibriumPoint = OMV.Vector3.Zero;
108 springAngularEquilibriumPoint = OMV.Vector3.Zero;
109 member.PhysScene.DetailLog("{0},BSLinkInfoConstraint.ResetLink", member.LocalID);
77 } 110 }
78 111
79 // Given a constraint, apply the current constraint parameters to same. 112 // Given a constraint, apply the current constraint parameters to same.
80 public void SetConstraintParameters(BSConstraint constrain) 113 public override void SetLinkParameters(BSConstraint constrain)
81 { 114 {
115 member.PhysScene.DetailLog("{0},BSLinkInfoConstraint.SetLinkParameters,type={1}", member.LocalID, constraintType);
82 switch (constraintType) 116 switch (constraintType)
83 { 117 {
118 case ConstraintType.FIXED_CONSTRAINT_TYPE:
84 case ConstraintType.D6_CONSTRAINT_TYPE: 119 case ConstraintType.D6_CONSTRAINT_TYPE:
85 BSConstraint6Dof constrain6dof = constrain as BSConstraint6Dof; 120 BSConstraint6Dof constrain6dof = constrain as BSConstraint6Dof;
86 if (constrain6dof != null) 121 if (constrain6dof != null)
87 { 122 {
123 // NOTE: D6_SPRING_CONSTRAINT_TYPE should be updated if you change any of this code.
88 // zero linear and angular limits makes the objects unable to move in relation to each other 124 // zero linear and angular limits makes the objects unable to move in relation to each other
89 constrain6dof.SetLinearLimits(linearLimitLow, linearLimitHigh); 125 constrain6dof.SetLinearLimits(linearLimitLow, linearLimitHigh);
90 constrain6dof.SetAngularLimits(angularLimitLow, angularLimitHigh); 126 constrain6dof.SetAngularLimits(angularLimitLow, angularLimitHigh);
@@ -99,10 +135,55 @@ public sealed class BSLinksetConstraints : BSLinkset
99 } 135 }
100 } 136 }
101 break; 137 break;
138 case ConstraintType.D6_SPRING_CONSTRAINT_TYPE:
139 BSConstraintSpring constrainSpring = constrain as BSConstraintSpring;
140 if (constrainSpring != null)
141 {
142 // zero linear and angular limits makes the objects unable to move in relation to each other
143 constrainSpring.SetLinearLimits(linearLimitLow, linearLimitHigh);
144 constrainSpring.SetAngularLimits(angularLimitLow, angularLimitHigh);
145
146 // tweek the constraint to increase stability
147 constrainSpring.UseFrameOffset(useFrameOffset);
148 constrainSpring.TranslationalLimitMotor(enableTransMotor, transMotorMaxVel, transMotorMaxForce);
149 constrainSpring.SetCFMAndERP(cfm, erp);
150 if (solverIterations != 0f)
151 {
152 constrainSpring.SetSolverIterations(solverIterations);
153 }
154 for (int ii = 0; ii < springAxisEnable.Length; ii++)
155 {
156 constrainSpring.SetAxisEnable(ii, springAxisEnable[ii]);
157 if (springDamping[ii] != BSAPITemplate.SPRING_NOT_SPECIFIED)
158 constrainSpring.SetDamping(ii, springDamping[ii]);
159 if (springStiffness[ii] != BSAPITemplate.SPRING_NOT_SPECIFIED)
160 constrainSpring.SetStiffness(ii, springStiffness[ii]);
161 }
162 constrainSpring.CalculateTransforms();
163
164 if (springLinearEquilibriumPoint != OMV.Vector3.Zero)
165 constrainSpring.SetEquilibriumPoint(springLinearEquilibriumPoint, springAngularEquilibriumPoint);
166 else
167 constrainSpring.SetEquilibriumPoint(BSAPITemplate.SPRING_NOT_SPECIFIED, BSAPITemplate.SPRING_NOT_SPECIFIED);
168 }
169 break;
102 default: 170 default:
103 break; 171 break;
104 } 172 }
105 } 173 }
174
175 // Return 'true' if the property updates from the physics engine should be reported
176 // to the simulator.
177 // If the constraint is fixed, we don't need to report as the simulator and viewer will
178 // report the right things.
179 public override bool ShouldUpdateChildProperties()
180 {
181 bool ret = true;
182 if (constraintType == ConstraintType.FIXED_CONSTRAINT_TYPE)
183 ret = false;
184
185 return ret;
186 }
106 } 187 }
107 188
108 public BSLinksetConstraints(BSScene scene, BSPrimLinkable parent) : base(scene, parent) 189 public BSLinksetConstraints(BSScene scene, BSPrimLinkable parent) : base(scene, parent)
@@ -110,12 +191,15 @@ public sealed class BSLinksetConstraints : BSLinkset
110 LinksetImpl = LinksetImplementation.Constraint; 191 LinksetImpl = LinksetImplementation.Constraint;
111 } 192 }
112 193
194 private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINT]";
195
113 // When physical properties are changed the linkset needs to recalculate 196 // When physical properties are changed the linkset needs to recalculate
114 // its internal properties. 197 // its internal properties.
115 // This is queued in the 'post taint' queue so the 198 // This is queued in the 'post taint' queue so the
116 // refresh will happen once after all the other taints are applied. 199 // refresh will happen once after all the other taints are applied.
117 public override void Refresh(BSPrimLinkable requestor) 200 public override void Refresh(BSPrimLinkable requestor)
118 { 201 {
202 ScheduleRebuild(requestor);
119 base.Refresh(requestor); 203 base.Refresh(requestor);
120 204
121 } 205 }
@@ -132,10 +216,16 @@ public sealed class BSLinksetConstraints : BSLinkset
132 { 216 {
133 // Queue to happen after all the other taint processing 217 // Queue to happen after all the other taint processing
134 m_physicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate() 218 m_physicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate()
219 {
220 if (HasAnyChildren)
135 { 221 {
136 if (HasAnyChildren) 222 // Constraints that have not been changed are not rebuild but make sure
137 RecomputeLinksetConstraints(); 223 // the constraint of the requestor is rebuilt.
138 }); 224 PhysicallyUnlinkAChildFromRoot(LinksetRoot, requestor);
225 // Rebuild the linkset and all its constraints.
226 RecomputeLinksetConstraints();
227 }
228 });
139 } 229 }
140 } 230 }
141 231
@@ -152,7 +242,7 @@ public sealed class BSLinksetConstraints : BSLinkset
152 if (IsRoot(child)) 242 if (IsRoot(child))
153 { 243 {
154 // The root is going dynamic. Rebuild the linkset so parts and mass get computed properly. 244 // The root is going dynamic. Rebuild the linkset so parts and mass get computed properly.
155 ScheduleRebuild(LinksetRoot); 245 Refresh(LinksetRoot);
156 } 246 }
157 return ret; 247 return ret;
158 } 248 }
@@ -171,7 +261,7 @@ public sealed class BSLinksetConstraints : BSLinkset
171 if (IsRoot(child)) 261 if (IsRoot(child))
172 { 262 {
173 // Schedule a rebuild to verify that the root shape is set to the real shape. 263 // Schedule a rebuild to verify that the root shape is set to the real shape.
174 ScheduleRebuild(LinksetRoot); 264 Refresh(LinksetRoot);
175 } 265 }
176 return ret; 266 return ret;
177 } 267 }
@@ -199,7 +289,7 @@ public sealed class BSLinksetConstraints : BSLinkset
199 // Just undo all the constraints for this linkset. Rebuild at the end of the step. 289 // Just undo all the constraints for this linkset. Rebuild at the end of the step.
200 ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot); 290 ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot);
201 // Cause the constraints, et al to be rebuilt before the next simulation step. 291 // Cause the constraints, et al to be rebuilt before the next simulation step.
202 ScheduleRebuild(LinksetRoot); 292 Refresh(LinksetRoot);
203 } 293 }
204 return ret; 294 return ret;
205 } 295 }
@@ -217,14 +307,14 @@ public sealed class BSLinksetConstraints : BSLinkset
217 DetailLog("{0},BSLinksetConstraints.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); 307 DetailLog("{0},BSLinksetConstraints.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID);
218 308
219 // Cause constraints and assorted properties to be recomputed before the next simulation step. 309 // Cause constraints and assorted properties to be recomputed before the next simulation step.
220 ScheduleRebuild(LinksetRoot); 310 Refresh(LinksetRoot);
221 } 311 }
222 return; 312 return;
223 } 313 }
224 314
225 // Remove the specified child from the linkset. 315 // Remove the specified child from the linkset.
226 // Safe to call even if the child is not really in my linkset. 316 // Safe to call even if the child is not really in my linkset.
227 protected override void RemoveChildFromLinkset(BSPrimLinkable child) 317 protected override void RemoveChildFromLinkset(BSPrimLinkable child, bool inTaintTime)
228 { 318 {
229 if (m_children.Remove(child)) 319 if (m_children.Remove(child))
230 { 320 {
@@ -236,12 +326,12 @@ public sealed class BSLinksetConstraints : BSLinkset
236 rootx.LocalID, rootx.PhysBody.AddrString, 326 rootx.LocalID, rootx.PhysBody.AddrString,
237 childx.LocalID, childx.PhysBody.AddrString); 327 childx.LocalID, childx.PhysBody.AddrString);
238 328
239 m_physicsScene.TaintedObject("BSLinksetConstraints.RemoveChildFromLinkset", delegate() 329 m_physicsScene.TaintedObject(inTaintTime, childx.LocalID, "BSLinksetConstraints.RemoveChildFromLinkset", delegate()
240 { 330 {
241 PhysicallyUnlinkAChildFromRoot(rootx, childx); 331 PhysicallyUnlinkAChildFromRoot(rootx, childx);
242 }); 332 });
243 // See that the linkset parameters are recomputed at the end of the taint time. 333 // See that the linkset parameters are recomputed at the end of the taint time.
244 ScheduleRebuild(LinksetRoot); 334 Refresh(LinksetRoot);
245 } 335 }
246 else 336 else
247 { 337 {
@@ -262,8 +352,8 @@ public sealed class BSLinksetConstraints : BSLinkset
262 // Create a static constraint between the two passed objects 352 // Create a static constraint between the two passed objects
263 private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSLinkInfo li) 353 private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSLinkInfo li)
264 { 354 {
265 BSLinkInfoConstraint liConstraint = li as BSLinkInfoConstraint; 355 BSLinkInfoConstraint linkInfo = li as BSLinkInfoConstraint;
266 if (liConstraint == null) 356 if (linkInfo == null)
267 return null; 357 return null;
268 358
269 // Zero motion for children so they don't interpolate 359 // Zero motion for children so they don't interpolate
@@ -271,27 +361,26 @@ public sealed class BSLinksetConstraints : BSLinkset
271 361
272 BSConstraint constrain = null; 362 BSConstraint constrain = null;
273 363
274 switch (liConstraint.constraintType) 364 switch (linkInfo.constraintType)
275 { 365 {
366 case ConstraintType.FIXED_CONSTRAINT_TYPE:
276 case ConstraintType.D6_CONSTRAINT_TYPE: 367 case ConstraintType.D6_CONSTRAINT_TYPE:
277 // Relative position normalized to the root prim 368 // Relative position normalized to the root prim
278 // Essentually a vector pointing from center of rootPrim to center of li.member 369 // Essentually a vector pointing from center of rootPrim to center of li.member
279 OMV.Vector3 childRelativePosition = liConstraint.member.Position - rootPrim.Position; 370 OMV.Vector3 childRelativePosition = linkInfo.member.Position - rootPrim.Position;
280 371
281 // real world coordinate of midpoint between the two objects 372 // real world coordinate of midpoint between the two objects
282 OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2); 373 OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2);
283 374
284 DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", 375 DetailLog("{0},BSLinksetConstraint.BuildConstraint,6Dof,rBody={1},cBody={2},rLoc={3},cLoc={4},midLoc={5}",
285 rootPrim.LocalID, 376 rootPrim.LocalID, rootPrim.PhysBody, linkInfo.member.PhysBody,
286 rootPrim.LocalID, rootPrim.PhysBody.AddrString, 377 rootPrim.Position, linkInfo.member.Position, midPoint);
287 liConstraint.member.LocalID, liConstraint.member.PhysBody.AddrString,
288 rootPrim.Position, liConstraint.member.Position, midPoint);
289 378
290 // create a constraint that allows no freedom of movement between the two objects 379 // create a constraint that allows no freedom of movement between the two objects
291 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 380 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
292 381
293 constrain = new BSConstraint6Dof( 382 constrain = new BSConstraint6Dof(
294 m_physicsScene.World, rootPrim.PhysBody, liConstraint.member.PhysBody, midPoint, true, true ); 383 m_physicsScene.World, rootPrim.PhysBody, linkInfo.member.PhysBody, midPoint, true, true );
295 384
296 /* NOTE: below is an attempt to build constraint with full frame computation, etc. 385 /* NOTE: below is an attempt to build constraint with full frame computation, etc.
297 * Using the midpoint is easier since it lets the Bullet code manipulate the transforms 386 * Using the midpoint is easier since it lets the Bullet code manipulate the transforms
@@ -320,11 +409,23 @@ public sealed class BSLinksetConstraints : BSLinkset
320 */ 409 */
321 410
322 break; 411 break;
412 case ConstraintType.D6_SPRING_CONSTRAINT_TYPE:
413 constrain = new BSConstraintSpring(m_physicsScene.World, rootPrim.PhysBody, linkInfo.member.PhysBody,
414 linkInfo.frameInAloc, linkInfo.frameInArot, linkInfo.frameInBloc, linkInfo.frameInBrot,
415 linkInfo.useLinearReferenceFrameA,
416 true /*disableCollisionsBetweenLinkedBodies*/);
417 DetailLog("{0},BSLinksetConstraint.BuildConstraint,spring,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6}",
418 rootPrim.LocalID,
419 rootPrim.LocalID, rootPrim.PhysBody.AddrString,
420 linkInfo.member.LocalID, linkInfo.member.PhysBody.AddrString,
421 rootPrim.Position, linkInfo.member.Position);
422
423 break;
323 default: 424 default:
324 break; 425 break;
325 } 426 }
326 427
327 liConstraint.SetConstraintParameters(constrain); 428 linkInfo.SetLinkParameters(constrain);
328 429
329 m_physicsScene.Constraints.AddConstraint(constrain); 430 m_physicsScene.Constraints.AddConstraint(constrain);
330 431
@@ -343,13 +444,22 @@ public sealed class BSLinksetConstraints : BSLinkset
343 rootPrim.LocalID, rootPrim.PhysBody.AddrString, 444 rootPrim.LocalID, rootPrim.PhysBody.AddrString,
344 childPrim.LocalID, childPrim.PhysBody.AddrString); 445 childPrim.LocalID, childPrim.PhysBody.AddrString);
345 446
346 // Find the constraint for this link and get rid of it from the overall collection and from my list 447 // If asked to unlink root from root, just remove all the constraints
347 if (m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody, childPrim.PhysBody)) 448 if (rootPrim == childPrim || childPrim == LinksetRoot)
348 { 449 {
349 // Make the child refresh its location 450 PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot);
350 m_physicsScene.PE.PushUpdate(childPrim.PhysBody);
351 ret = true; 451 ret = true;
352 } 452 }
453 else
454 {
455 // Find the constraint for this link and get rid of it from the overall collection and from my list
456 if (m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody, childPrim.PhysBody))
457 {
458 // Make the child refresh its location
459 m_physicsScene.PE.PushUpdate(childPrim.PhysBody);
460 ret = true;
461 }
462 }
353 463
354 return ret; 464 return ret;
355 } 465 }
@@ -382,9 +492,9 @@ public sealed class BSLinksetConstraints : BSLinkset
382 Rebuilding = true; 492 Rebuilding = true;
383 493
384 // There is no reason to build all this physical stuff for a non-physical linkset. 494 // There is no reason to build all this physical stuff for a non-physical linkset.
385 if (!LinksetRoot.IsPhysicallyActive) 495 if (!LinksetRoot.IsPhysicallyActive || !HasAnyChildren)
386 { 496 {
387 DetailLog("{0},BSLinksetConstraint.RecomputeLinksetCompound,notPhysical", LinksetRoot.LocalID); 497 DetailLog("{0},BSLinksetConstraint.RecomputeLinksetCompound,notPhysicalOrNoChildren", LinksetRoot.LocalID);
388 return; // Note the 'finally' clause at the botton which will get executed. 498 return; // Note the 'finally' clause at the botton which will get executed.
389 } 499 }
390 500
@@ -401,6 +511,7 @@ public sealed class BSLinksetConstraints : BSLinkset
401 // If constraint doesn't exist yet, create it. 511 // If constraint doesn't exist yet, create it.
402 constrain = BuildConstraint(LinksetRoot, li); 512 constrain = BuildConstraint(LinksetRoot, li);
403 } 513 }
514 li.SetLinkParameters(constrain);
404 constrain.RecomputeConstraintVariables(linksetMass); 515 constrain.RecomputeConstraintVariables(linksetMass);
405 516
406 // PhysicsScene.PE.DumpConstraint(PhysicsScene.World, constrain.Constraint); // DEBUG DEBUG 517 // PhysicsScene.PE.DumpConstraint(PhysicsScene.World, constrain.Constraint); // DEBUG DEBUG
@@ -412,5 +523,324 @@ public sealed class BSLinksetConstraints : BSLinkset
412 Rebuilding = false; 523 Rebuilding = false;
413 } 524 }
414 } 525 }
526
527 #region Extension
528 public override object Extension(string pFunct, params object[] pParams)
529 {
530 object ret = null;
531 switch (pFunct)
532 {
533 // pParams = [ BSPhysObject root, BSPhysObject child, integer linkType ]
534 case ExtendedPhysics.PhysFunctChangeLinkType:
535 if (pParams.Length > 2)
536 {
537 int requestedType = (int)pParams[2];
538 DetailLog("{0},BSLinksetConstraint.ChangeLinkType,requestedType={1}", LinksetRoot.LocalID, requestedType);
539 if (requestedType == (int)ConstraintType.FIXED_CONSTRAINT_TYPE
540 || requestedType == (int)ConstraintType.D6_CONSTRAINT_TYPE
541 || requestedType == (int)ConstraintType.D6_SPRING_CONSTRAINT_TYPE
542 || requestedType == (int)ConstraintType.HINGE_CONSTRAINT_TYPE
543 || requestedType == (int)ConstraintType.CONETWIST_CONSTRAINT_TYPE
544 || requestedType == (int)ConstraintType.SLIDER_CONSTRAINT_TYPE)
545 {
546 BSPrimLinkable child = pParams[1] as BSPrimLinkable;
547 if (child != null)
548 {
549 DetailLog("{0},BSLinksetConstraint.ChangeLinkType,rootID={1},childID={2},type={3}",
550 LinksetRoot.LocalID, LinksetRoot.LocalID, child.LocalID, requestedType);
551 m_physicsScene.TaintedObject(child.LocalID, "BSLinksetConstraint.PhysFunctChangeLinkType", delegate()
552 {
553 // Pick up all the constraints currently created.
554 RemoveDependencies(child);
555
556 BSLinkInfo linkInfo = null;
557 if (TryGetLinkInfo(child, out linkInfo))
558 {
559 BSLinkInfoConstraint linkInfoC = linkInfo as BSLinkInfoConstraint;
560 if (linkInfoC != null)
561 {
562 linkInfoC.constraintType = (ConstraintType)requestedType;
563 ret = (object)true;
564 DetailLog("{0},BSLinksetConstraint.ChangeLinkType,link={1},type={2}",
565 linkInfo.member.LocalID, linkInfo.member.LocalID, linkInfoC.constraintType);
566 }
567 else
568 {
569 DetailLog("{0},BSLinksetConstraint.ChangeLinkType,linkInfoNotConstraint,childID={1}", LinksetRoot.LocalID, child.LocalID);
570 }
571 }
572 else
573 {
574 DetailLog("{0},BSLinksetConstraint.ChangeLinkType,noLinkInfoForChild,childID={1}", LinksetRoot.LocalID, child.LocalID);
575 }
576 // Cause the whole linkset to be rebuilt in post-taint time.
577 Refresh(child);
578 });
579 }
580 else
581 {
582 DetailLog("{0},BSLinksetConstraint.SetLinkType,childNotBSPrimLinkable", LinksetRoot.LocalID);
583 }
584 }
585 else
586 {
587 DetailLog("{0},BSLinksetConstraint.SetLinkType,illegalRequestedType,reqested={1},spring={2}",
588 LinksetRoot.LocalID, requestedType, ((int)ConstraintType.D6_SPRING_CONSTRAINT_TYPE));
589 }
590 }
591 break;
592 // pParams = [ BSPhysObject root, BSPhysObject child ]
593 case ExtendedPhysics.PhysFunctGetLinkType:
594 if (pParams.Length > 0)
595 {
596 BSPrimLinkable child = pParams[1] as BSPrimLinkable;
597 if (child != null)
598 {
599 BSLinkInfo linkInfo = null;
600 if (TryGetLinkInfo(child, out linkInfo))
601 {
602 BSLinkInfoConstraint linkInfoC = linkInfo as BSLinkInfoConstraint;
603 if (linkInfoC != null)
604 {
605 ret = (object)(int)linkInfoC.constraintType;
606 DetailLog("{0},BSLinksetConstraint.GetLinkType,link={1},type={2}",
607 linkInfo.member.LocalID, linkInfo.member.LocalID, linkInfoC.constraintType);
608
609 }
610 }
611 }
612 }
613 break;
614 // pParams = [ BSPhysObject root, BSPhysObject child, int op, object opParams, int op, object opParams, ... ]
615 case ExtendedPhysics.PhysFunctChangeLinkParams:
616 // There should be two parameters: the childActor and a list of parameters to set
617 if (pParams.Length > 2)
618 {
619 BSPrimLinkable child = pParams[1] as BSPrimLinkable;
620 BSLinkInfo baseLinkInfo = null;
621 if (TryGetLinkInfo(child, out baseLinkInfo))
622 {
623 BSLinkInfoConstraint linkInfo = baseLinkInfo as BSLinkInfoConstraint;
624 if (linkInfo != null)
625 {
626 int valueInt;
627 float valueFloat;
628 bool valueBool;
629 OMV.Vector3 valueVector;
630 OMV.Vector3 valueVector2;
631 OMV.Quaternion valueQuaternion;
632 int axisLow, axisHigh;
633
634 int opIndex = 2;
635 while (opIndex < pParams.Length)
636 {
637 int thisOp = 0;
638 string errMsg = "";
639 try
640 {
641 thisOp = (int)pParams[opIndex];
642 DetailLog("{0},BSLinksetConstraint.ChangeLinkParams2,op={1},val={2}",
643 linkInfo.member.LocalID, thisOp, pParams[opIndex + 1]);
644 switch (thisOp)
645 {
646 case ExtendedPhysics.PHYS_PARAM_LINK_TYPE:
647 valueInt = (int)pParams[opIndex + 1];
648 ConstraintType valueType = (ConstraintType)valueInt;
649 if (valueType == ConstraintType.FIXED_CONSTRAINT_TYPE
650 || valueType == ConstraintType.D6_CONSTRAINT_TYPE
651 || valueType == ConstraintType.D6_SPRING_CONSTRAINT_TYPE
652 || valueType == ConstraintType.HINGE_CONSTRAINT_TYPE
653 || valueType == ConstraintType.CONETWIST_CONSTRAINT_TYPE
654 || valueType == ConstraintType.SLIDER_CONSTRAINT_TYPE)
655 {
656 linkInfo.constraintType = valueType;
657 }
658 opIndex += 2;
659 break;
660 case ExtendedPhysics.PHYS_PARAM_FRAMEINA_LOC:
661 errMsg = "PHYS_PARAM_FRAMEINA_LOC takes one parameter of type vector";
662 valueVector = (OMV.Vector3)pParams[opIndex + 1];
663 linkInfo.frameInAloc = valueVector;
664 opIndex += 2;
665 break;
666 case ExtendedPhysics.PHYS_PARAM_FRAMEINA_ROT:
667 errMsg = "PHYS_PARAM_FRAMEINA_ROT takes one parameter of type rotation";
668 valueQuaternion = (OMV.Quaternion)pParams[opIndex + 1];
669 linkInfo.frameInArot = valueQuaternion;
670 opIndex += 2;
671 break;
672 case ExtendedPhysics.PHYS_PARAM_FRAMEINB_LOC:
673 errMsg = "PHYS_PARAM_FRAMEINB_LOC takes one parameter of type vector";
674 valueVector = (OMV.Vector3)pParams[opIndex + 1];
675 linkInfo.frameInBloc = valueVector;
676 opIndex += 2;
677 break;
678 case ExtendedPhysics.PHYS_PARAM_FRAMEINB_ROT:
679 errMsg = "PHYS_PARAM_FRAMEINB_ROT takes one parameter of type rotation";
680 valueQuaternion = (OMV.Quaternion)pParams[opIndex + 1];
681 linkInfo.frameInBrot = valueQuaternion;
682 opIndex += 2;
683 break;
684 case ExtendedPhysics.PHYS_PARAM_LINEAR_LIMIT_LOW:
685 errMsg = "PHYS_PARAM_LINEAR_LIMIT_LOW takes one parameter of type vector";
686 valueVector = (OMV.Vector3)pParams[opIndex + 1];
687 linkInfo.linearLimitLow = valueVector;
688 opIndex += 2;
689 break;
690 case ExtendedPhysics.PHYS_PARAM_LINEAR_LIMIT_HIGH:
691 errMsg = "PHYS_PARAM_LINEAR_LIMIT_HIGH takes one parameter of type vector";
692 valueVector = (OMV.Vector3)pParams[opIndex + 1];
693 linkInfo.linearLimitHigh = valueVector;
694 opIndex += 2;
695 break;
696 case ExtendedPhysics.PHYS_PARAM_ANGULAR_LIMIT_LOW:
697 errMsg = "PHYS_PARAM_ANGULAR_LIMIT_LOW takes one parameter of type vector";
698 valueVector = (OMV.Vector3)pParams[opIndex + 1];
699 linkInfo.angularLimitLow = valueVector;
700 opIndex += 2;
701 break;
702 case ExtendedPhysics.PHYS_PARAM_ANGULAR_LIMIT_HIGH:
703 errMsg = "PHYS_PARAM_ANGULAR_LIMIT_HIGH takes one parameter of type vector";
704 valueVector = (OMV.Vector3)pParams[opIndex + 1];
705 linkInfo.angularLimitHigh = valueVector;
706 opIndex += 2;
707 break;
708 case ExtendedPhysics.PHYS_PARAM_USE_FRAME_OFFSET:
709 errMsg = "PHYS_PARAM_USE_FRAME_OFFSET takes one parameter of type integer (bool)";
710 valueBool = ((int)pParams[opIndex + 1]) != 0;
711 linkInfo.useFrameOffset = valueBool;
712 opIndex += 2;
713 break;
714 case ExtendedPhysics.PHYS_PARAM_ENABLE_TRANSMOTOR:
715 errMsg = "PHYS_PARAM_ENABLE_TRANSMOTOR takes one parameter of type integer (bool)";
716 valueBool = ((int)pParams[opIndex + 1]) != 0;
717 linkInfo.enableTransMotor = valueBool;
718 opIndex += 2;
719 break;
720 case ExtendedPhysics.PHYS_PARAM_TRANSMOTOR_MAXVEL:
721 errMsg = "PHYS_PARAM_TRANSMOTOR_MAXVEL takes one parameter of type float";
722 valueFloat = (float)pParams[opIndex + 1];
723 linkInfo.transMotorMaxVel = valueFloat;
724 opIndex += 2;
725 break;
726 case ExtendedPhysics.PHYS_PARAM_TRANSMOTOR_MAXFORCE:
727 errMsg = "PHYS_PARAM_TRANSMOTOR_MAXFORCE takes one parameter of type float";
728 valueFloat = (float)pParams[opIndex + 1];
729 linkInfo.transMotorMaxForce = valueFloat;
730 opIndex += 2;
731 break;
732 case ExtendedPhysics.PHYS_PARAM_CFM:
733 errMsg = "PHYS_PARAM_CFM takes one parameter of type float";
734 valueFloat = (float)pParams[opIndex + 1];
735 linkInfo.cfm = valueFloat;
736 opIndex += 2;
737 break;
738 case ExtendedPhysics.PHYS_PARAM_ERP:
739 errMsg = "PHYS_PARAM_ERP takes one parameter of type float";
740 valueFloat = (float)pParams[opIndex + 1];
741 linkInfo.erp = valueFloat;
742 opIndex += 2;
743 break;
744 case ExtendedPhysics.PHYS_PARAM_SOLVER_ITERATIONS:
745 errMsg = "PHYS_PARAM_SOLVER_ITERATIONS takes one parameter of type float";
746 valueFloat = (float)pParams[opIndex + 1];
747 linkInfo.solverIterations = valueFloat;
748 opIndex += 2;
749 break;
750 case ExtendedPhysics.PHYS_PARAM_SPRING_AXIS_ENABLE:
751 errMsg = "PHYS_PARAM_SPRING_AXIS_ENABLE takes two parameters of types integer and integer (bool)";
752 valueInt = (int)pParams[opIndex + 1];
753 valueBool = ((int)pParams[opIndex + 2]) != 0;
754 GetAxisRange(valueInt, out axisLow, out axisHigh);
755 for (int ii = axisLow; ii <= axisHigh; ii++)
756 linkInfo.springAxisEnable[ii] = valueBool;
757 opIndex += 3;
758 break;
759 case ExtendedPhysics.PHYS_PARAM_SPRING_DAMPING:
760 errMsg = "PHYS_PARAM_SPRING_DAMPING takes two parameters of types integer and float";
761 valueInt = (int)pParams[opIndex + 1];
762 valueFloat = (float)pParams[opIndex + 2];
763 GetAxisRange(valueInt, out axisLow, out axisHigh);
764 for (int ii = axisLow; ii <= axisHigh; ii++)
765 linkInfo.springDamping[ii] = valueFloat;
766 opIndex += 3;
767 break;
768 case ExtendedPhysics.PHYS_PARAM_SPRING_STIFFNESS:
769 errMsg = "PHYS_PARAM_SPRING_STIFFNESS takes two parameters of types integer and float";
770 valueInt = (int)pParams[opIndex + 1];
771 valueFloat = (float)pParams[opIndex + 2];
772 GetAxisRange(valueInt, out axisLow, out axisHigh);
773 for (int ii = axisLow; ii <= axisHigh; ii++)
774 linkInfo.springStiffness[ii] = valueFloat;
775 opIndex += 3;
776 break;
777 case ExtendedPhysics.PHYS_PARAM_SPRING_EQUILIBRIUM_POINT:
778 errMsg = "PHYS_PARAM_SPRING_EQUILIBRIUM_POINT takes two parameters of type vector";
779 valueVector = (OMV.Vector3)pParams[opIndex + 1];
780 valueVector2 = (OMV.Vector3)pParams[opIndex + 2];
781 linkInfo.springLinearEquilibriumPoint = valueVector;
782 linkInfo.springAngularEquilibriumPoint = valueVector2;
783 opIndex += 3;
784 break;
785 case ExtendedPhysics.PHYS_PARAM_USE_LINEAR_FRAMEA:
786 errMsg = "PHYS_PARAM_USE_LINEAR_FRAMEA takes one parameter of type integer (bool)";
787 valueBool = ((int)pParams[opIndex + 1]) != 0;
788 linkInfo.useLinearReferenceFrameA = valueBool;
789 opIndex += 2;
790 break;
791 default:
792 break;
793 }
794 }
795 catch (InvalidCastException e)
796 {
797 m_physicsScene.Logger.WarnFormat("{0} value of wrong type in physSetLinksetParams: {1}, err={2}",
798 LogHeader, errMsg, e);
799 }
800 catch (Exception e)
801 {
802 m_physicsScene.Logger.WarnFormat("{0} bad parameters in physSetLinksetParams: {1}", LogHeader, e);
803 }
804 }
805 }
806 // Something changed so a rebuild is in order
807 Refresh(child);
808 }
809 }
810 break;
811 default:
812 ret = base.Extension(pFunct, pParams);
813 break;
814 }
815 return ret;
816 }
817
818 // Bullet constraints keep some limit parameters for each linear and angular axis.
819 // Setting same is easier if there is an easy way to see all or types.
820 // This routine returns the array limits for the set of axis.
821 private void GetAxisRange(int rangeSpec, out int low, out int high)
822 {
823 switch (rangeSpec)
824 {
825 case ExtendedPhysics.PHYS_AXIS_LINEAR_ALL:
826 low = 0;
827 high = 2;
828 break;
829 case ExtendedPhysics.PHYS_AXIS_ANGULAR_ALL:
830 low = 3;
831 high = 5;
832 break;
833 case ExtendedPhysics.PHYS_AXIS_ALL:
834 low = 0;
835 high = 5;
836 break;
837 default:
838 low = high = rangeSpec;
839 break;
840 }
841 return;
842 }
843 #endregion // Extension
844
415} 845}
416} 846}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
index fcb892a..43aa63e 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
@@ -134,6 +134,7 @@ public static class BSParam
134 public static float AvatarHeightMidFudge { get; private set; } 134 public static float AvatarHeightMidFudge { get; private set; }
135 public static float AvatarHeightHighFudge { get; private set; } 135 public static float AvatarHeightHighFudge { get; private set; }
136 public static float AvatarContactProcessingThreshold { get; private set; } 136 public static float AvatarContactProcessingThreshold { get; private set; }
137 public static float AvatarStopZeroThreshold { get; private set; }
137 public static int AvatarJumpFrames { get; private set; } 138 public static int AvatarJumpFrames { get; private set; }
138 public static float AvatarBelowGroundUpCorrectionMeters { get; private set; } 139 public static float AvatarBelowGroundUpCorrectionMeters { get; private set; }
139 public static float AvatarStepHeight { get; private set; } 140 public static float AvatarStepHeight { get; private set; }
@@ -570,11 +571,13 @@ public static class BSParam
570 new ParameterDefn<float>("AvatarHeightLowFudge", "A fudge factor to make small avatars stand on the ground", 571 new ParameterDefn<float>("AvatarHeightLowFudge", "A fudge factor to make small avatars stand on the ground",
571 -0.2f ), 572 -0.2f ),
572 new ParameterDefn<float>("AvatarHeightMidFudge", "A fudge distance to adjust average sized avatars to be standing on ground", 573 new ParameterDefn<float>("AvatarHeightMidFudge", "A fudge distance to adjust average sized avatars to be standing on ground",
573 0.2f ), 574 0.1f ),
574 new ParameterDefn<float>("AvatarHeightHighFudge", "A fudge factor to make tall avatars stand on the ground", 575 new ParameterDefn<float>("AvatarHeightHighFudge", "A fudge factor to make tall avatars stand on the ground",
575 0.2f ), 576 0.1f ),
576 new ParameterDefn<float>("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", 577 new ParameterDefn<float>("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions",
577 0.1f ), 578 0.1f ),
579 new ParameterDefn<float>("AvatarStopZeroThreshold", "Movement velocity below which avatar is assumed to be stopped",
580 0.1f ),
578 new ParameterDefn<float>("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground", 581 new ParameterDefn<float>("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground",
579 1.0f ), 582 1.0f ),
580 new ParameterDefn<int>("AvatarJumpFrames", "Number of frames to allow jump forces. Changes jump height.", 583 new ParameterDefn<int>("AvatarJumpFrames", "Number of frames to allow jump forces. Changes jump height.",
@@ -683,21 +686,21 @@ public static class BSParam
683 0f ), 686 0f ),
684 687
685 new ParameterDefn<float>("BHullMaxVerticesPerHull", "Bullet impl: max number of vertices per created hull", 688 new ParameterDefn<float>("BHullMaxVerticesPerHull", "Bullet impl: max number of vertices per created hull",
686 100f ), 689 200f ),
687 new ParameterDefn<float>("BHullMinClusters", "Bullet impl: minimum number of hulls to create per mesh", 690 new ParameterDefn<float>("BHullMinClusters", "Bullet impl: minimum number of hulls to create per mesh",
688 2f ), 691 10f ),
689 new ParameterDefn<float>("BHullCompacityWeight", "Bullet impl: weight factor for how compact to make hulls", 692 new ParameterDefn<float>("BHullCompacityWeight", "Bullet impl: weight factor for how compact to make hulls",
690 0.1f ), 693 20f ),
691 new ParameterDefn<float>("BHullVolumeWeight", "Bullet impl: weight factor for volume in created hull", 694 new ParameterDefn<float>("BHullVolumeWeight", "Bullet impl: weight factor for volume in created hull",
692 0f ), 695 0.1f ),
693 new ParameterDefn<float>("BHullConcavity", "Bullet impl: weight factor for how convex a created hull can be", 696 new ParameterDefn<float>("BHullConcavity", "Bullet impl: weight factor for how convex a created hull can be",
694 100f ), 697 10f ),
695 new ParameterDefn<bool>("BHullAddExtraDistPoints", "Bullet impl: whether to add extra vertices for long distance vectors", 698 new ParameterDefn<bool>("BHullAddExtraDistPoints", "Bullet impl: whether to add extra vertices for long distance vectors",
696 false ), 699 true ),
697 new ParameterDefn<bool>("BHullAddNeighboursDistPoints", "Bullet impl: whether to add extra vertices between neighbor hulls", 700 new ParameterDefn<bool>("BHullAddNeighboursDistPoints", "Bullet impl: whether to add extra vertices between neighbor hulls",
698 false ), 701 true ),
699 new ParameterDefn<bool>("BHullAddFacesPoints", "Bullet impl: whether to add extra vertices to break up hull faces", 702 new ParameterDefn<bool>("BHullAddFacesPoints", "Bullet impl: whether to add extra vertices to break up hull faces",
700 false ), 703 true ),
701 new ParameterDefn<bool>("BHullShouldAdjustCollisionMargin", "Bullet impl: whether to shrink resulting hulls to account for collision margin", 704 new ParameterDefn<bool>("BHullShouldAdjustCollisionMargin", "Bullet impl: whether to shrink resulting hulls to account for collision margin",
702 false ), 705 false ),
703 706
@@ -826,7 +829,7 @@ public static class BSParam
826 private static void ResetConstraintSolverTainted(BSScene pPhysScene, float v) 829 private static void ResetConstraintSolverTainted(BSScene pPhysScene, float v)
827 { 830 {
828 BSScene physScene = pPhysScene; 831 BSScene physScene = pPhysScene;
829 physScene.TaintedObject("BSParam.ResetConstraintSolver", delegate() 832 physScene.TaintedObject(BSScene.DetailLogZero, "BSParam.ResetConstraintSolver", delegate()
830 { 833 {
831 physScene.PE.ResetConstraintSolver(physScene.World); 834 physScene.PE.ResetConstraintSolver(physScene.World);
832 }); 835 });
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index 9dc52d5..f89b376 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -121,7 +121,7 @@ public abstract class BSPhysObject : PhysicsActor
121 public virtual void Destroy() 121 public virtual void Destroy()
122 { 122 {
123 PhysicalActors.Enable(false); 123 PhysicalActors.Enable(false);
124 PhysScene.TaintedObject("BSPhysObject.Destroy", delegate() 124 PhysScene.TaintedObject(LocalID, "BSPhysObject.Destroy", delegate()
125 { 125 {
126 PhysicalActors.Dispose(); 126 PhysicalActors.Dispose();
127 }); 127 });
@@ -300,8 +300,19 @@ public abstract class BSPhysObject : PhysicsActor
300 // Called in taint-time!! 300 // Called in taint-time!!
301 public void ActivateIfPhysical(bool forceIt) 301 public void ActivateIfPhysical(bool forceIt)
302 { 302 {
303 if (IsPhysical && PhysBody.HasPhysicalBody) 303 if (PhysBody.HasPhysicalBody)
304 PhysScene.PE.Activate(PhysBody, forceIt); 304 {
305 if (IsPhysical)
306 {
307 // Physical objects might need activating
308 PhysScene.PE.Activate(PhysBody, forceIt);
309 }
310 else
311 {
312 // Clear the collision cache since we've changed some properties.
313 PhysScene.PE.ClearCollisionProxyCache(PhysScene.World, PhysBody);
314 }
315 }
305 } 316 }
306 317
307 // 'actors' act on the physical object to change or constrain its motion. These can range from 318 // 'actors' act on the physical object to change or constrain its motion. These can range from
@@ -509,7 +520,7 @@ public abstract class BSPhysObject : PhysicsActor
509 // make sure first collision happens 520 // make sure first collision happens
510 NextCollisionOkTime = Util.EnvironmentTickCountSubtract(SubscribedEventsMs); 521 NextCollisionOkTime = Util.EnvironmentTickCountSubtract(SubscribedEventsMs);
511 522
512 PhysScene.TaintedObject(TypeName+".SubscribeEvents", delegate() 523 PhysScene.TaintedObject(LocalID, TypeName+".SubscribeEvents", delegate()
513 { 524 {
514 if (PhysBody.HasPhysicalBody) 525 if (PhysBody.HasPhysicalBody)
515 CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 526 CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
@@ -524,7 +535,7 @@ public abstract class BSPhysObject : PhysicsActor
524 public override void UnSubscribeEvents() { 535 public override void UnSubscribeEvents() {
525 // DetailLog("{0},{1}.UnSubscribeEvents,unsubscribing", LocalID, TypeName); 536 // DetailLog("{0},{1}.UnSubscribeEvents,unsubscribing", LocalID, TypeName);
526 SubscribedEventsMs = 0; 537 SubscribedEventsMs = 0;
527 PhysScene.TaintedObject(TypeName+".UnSubscribeEvents", delegate() 538 PhysScene.TaintedObject(LocalID, TypeName+".UnSubscribeEvents", delegate()
528 { 539 {
529 // Make sure there is a body there because sometimes destruction happens in an un-ideal order. 540 // Make sure there is a body there because sometimes destruction happens in an un-ideal order.
530 if (PhysBody.HasPhysicalBody) 541 if (PhysBody.HasPhysicalBody)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index d5b999d..15b7090 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -41,7 +41,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
41 [Serializable] 41 [Serializable]
42public class BSPrim : BSPhysObject 42public class BSPrim : BSPhysObject
43{ 43{
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 44 protected static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 private static readonly string LogHeader = "[BULLETS PRIM]"; 45 private static readonly string LogHeader = "[BULLETS PRIM]";
46 46
47 // _size is what the user passed. Scale is what we pass to the physics engine with the mesh. 47 // _size is what the user passed. Scale is what we pass to the physics engine with the mesh.
@@ -102,7 +102,7 @@ public class BSPrim : BSPhysObject
102 102
103 // DetailLog("{0},BSPrim.constructor,call", LocalID); 103 // DetailLog("{0},BSPrim.constructor,call", LocalID);
104 // do the actual object creation at taint time 104 // do the actual object creation at taint time
105 PhysScene.TaintedObject("BSPrim.create", delegate() 105 PhysScene.TaintedObject(LocalID, "BSPrim.create", delegate()
106 { 106 {
107 // Make sure the object is being created with some sanity. 107 // Make sure the object is being created with some sanity.
108 ExtremeSanityCheck(true /* inTaintTime */); 108 ExtremeSanityCheck(true /* inTaintTime */);
@@ -126,7 +126,7 @@ public class BSPrim : BSPhysObject
126 // Undo any vehicle properties 126 // Undo any vehicle properties
127 this.VehicleType = (int)Vehicle.TYPE_NONE; 127 this.VehicleType = (int)Vehicle.TYPE_NONE;
128 128
129 PhysScene.TaintedObject("BSPrim.Destroy", delegate() 129 PhysScene.TaintedObject(LocalID, "BSPrim.Destroy", delegate()
130 { 130 {
131 DetailLog("{0},BSPrim.Destroy,taint,", LocalID); 131 DetailLog("{0},BSPrim.Destroy,taint,", LocalID);
132 // If there are physical body and shape, release my use of same. 132 // If there are physical body and shape, release my use of same.
@@ -161,7 +161,7 @@ public class BSPrim : BSPhysObject
161 } 161 }
162 public override bool ForceBodyShapeRebuild(bool inTaintTime) 162 public override bool ForceBodyShapeRebuild(bool inTaintTime)
163 { 163 {
164 PhysScene.TaintedObject(inTaintTime, "BSPrim.ForceBodyShapeRebuild", delegate() 164 PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ForceBodyShapeRebuild", delegate()
165 { 165 {
166 _mass = CalculateMass(); // changing the shape changes the mass 166 _mass = CalculateMass(); // changing the shape changes the mass
167 CreateGeomAndObject(true); 167 CreateGeomAndObject(true);
@@ -178,7 +178,7 @@ public class BSPrim : BSPhysObject
178 if (value != _isSelected) 178 if (value != _isSelected)
179 { 179 {
180 _isSelected = value; 180 _isSelected = value;
181 PhysScene.TaintedObject("BSPrim.setSelected", delegate() 181 PhysScene.TaintedObject(LocalID, "BSPrim.setSelected", delegate()
182 { 182 {
183 DetailLog("{0},BSPrim.selected,taint,selected={1}", LocalID, _isSelected); 183 DetailLog("{0},BSPrim.selected,taint,selected={1}", LocalID, _isSelected);
184 SetObjectDynamic(false); 184 SetObjectDynamic(false);
@@ -224,7 +224,7 @@ public class BSPrim : BSPhysObject
224 _rotationalVelocity = OMV.Vector3.Zero; 224 _rotationalVelocity = OMV.Vector3.Zero;
225 225
226 // Zero some other properties in the physics engine 226 // Zero some other properties in the physics engine
227 PhysScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate() 227 PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ZeroMotion", delegate()
228 { 228 {
229 if (PhysBody.HasPhysicalBody) 229 if (PhysBody.HasPhysicalBody)
230 PhysScene.PE.ClearAllForces(PhysBody); 230 PhysScene.PE.ClearAllForces(PhysBody);
@@ -234,7 +234,7 @@ public class BSPrim : BSPhysObject
234 { 234 {
235 _rotationalVelocity = OMV.Vector3.Zero; 235 _rotationalVelocity = OMV.Vector3.Zero;
236 // Zero some other properties in the physics engine 236 // Zero some other properties in the physics engine
237 PhysScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate() 237 PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ZeroMotion", delegate()
238 { 238 {
239 // DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity); 239 // DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity);
240 if (PhysBody.HasPhysicalBody) 240 if (PhysBody.HasPhysicalBody)
@@ -262,7 +262,7 @@ public class BSPrim : BSPhysObject
262 }); 262 });
263 263
264 // Update parameters so the new actor's Refresh() action is called at the right time. 264 // Update parameters so the new actor's Refresh() action is called at the right time.
265 PhysScene.TaintedObject("BSPrim.LockAngularMotion", delegate() 265 PhysScene.TaintedObject(LocalID, "BSPrim.LockAngularMotion", delegate()
266 { 266 {
267 UpdatePhysicalParameters(); 267 UpdatePhysicalParameters();
268 }); 268 });
@@ -287,7 +287,7 @@ public class BSPrim : BSPhysObject
287 RawPosition = value; 287 RawPosition = value;
288 PositionSanityCheck(false); 288 PositionSanityCheck(false);
289 289
290 PhysScene.TaintedObject("BSPrim.setPosition", delegate() 290 PhysScene.TaintedObject(LocalID, "BSPrim.setPosition", delegate()
291 { 291 {
292 DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, RawPosition, RawOrientation); 292 DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, RawPosition, RawOrientation);
293 ForcePosition = RawPosition; 293 ForcePosition = RawPosition;
@@ -531,7 +531,7 @@ public class BSPrim : BSPhysObject
531 set { 531 set {
532 Vehicle type = (Vehicle)value; 532 Vehicle type = (Vehicle)value;
533 533
534 PhysScene.TaintedObject("setVehicleType", delegate() 534 PhysScene.TaintedObject(LocalID, "setVehicleType", delegate()
535 { 535 {
536 // Some vehicle scripts change vehicle type on the fly as an easy way to 536 // Some vehicle scripts change vehicle type on the fly as an easy way to
537 // change all the parameters. Like a plane changing to CAR when on the 537 // change all the parameters. Like a plane changing to CAR when on the
@@ -561,7 +561,7 @@ public class BSPrim : BSPhysObject
561 } 561 }
562 public override void VehicleFloatParam(int param, float value) 562 public override void VehicleFloatParam(int param, float value)
563 { 563 {
564 PhysScene.TaintedObject("BSPrim.VehicleFloatParam", delegate() 564 PhysScene.TaintedObject(LocalID, "BSPrim.VehicleFloatParam", delegate()
565 { 565 {
566 BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */); 566 BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */);
567 if (vehicleActor != null) 567 if (vehicleActor != null)
@@ -573,7 +573,7 @@ public class BSPrim : BSPhysObject
573 } 573 }
574 public override void VehicleVectorParam(int param, OMV.Vector3 value) 574 public override void VehicleVectorParam(int param, OMV.Vector3 value)
575 { 575 {
576 PhysScene.TaintedObject("BSPrim.VehicleVectorParam", delegate() 576 PhysScene.TaintedObject(LocalID, "BSPrim.VehicleVectorParam", delegate()
577 { 577 {
578 BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */); 578 BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */);
579 if (vehicleActor != null) 579 if (vehicleActor != null)
@@ -585,7 +585,7 @@ public class BSPrim : BSPhysObject
585 } 585 }
586 public override void VehicleRotationParam(int param, OMV.Quaternion rotation) 586 public override void VehicleRotationParam(int param, OMV.Quaternion rotation)
587 { 587 {
588 PhysScene.TaintedObject("BSPrim.VehicleRotationParam", delegate() 588 PhysScene.TaintedObject(LocalID, "BSPrim.VehicleRotationParam", delegate()
589 { 589 {
590 BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */); 590 BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */);
591 if (vehicleActor != null) 591 if (vehicleActor != null)
@@ -597,7 +597,7 @@ public class BSPrim : BSPhysObject
597 } 597 }
598 public override void VehicleFlags(int param, bool remove) 598 public override void VehicleFlags(int param, bool remove)
599 { 599 {
600 PhysScene.TaintedObject("BSPrim.VehicleFlags", delegate() 600 PhysScene.TaintedObject(LocalID, "BSPrim.VehicleFlags", delegate()
601 { 601 {
602 BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */); 602 BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */);
603 if (vehicleActor != null) 603 if (vehicleActor != null)
@@ -613,7 +613,7 @@ public class BSPrim : BSPhysObject
613 if (_isVolumeDetect != newValue) 613 if (_isVolumeDetect != newValue)
614 { 614 {
615 _isVolumeDetect = newValue; 615 _isVolumeDetect = newValue;
616 PhysScene.TaintedObject("BSPrim.SetVolumeDetect", delegate() 616 PhysScene.TaintedObject(LocalID, "BSPrim.SetVolumeDetect", delegate()
617 { 617 {
618 // DetailLog("{0},setVolumeDetect,taint,volDetect={1}", LocalID, _isVolumeDetect); 618 // DetailLog("{0},setVolumeDetect,taint,volDetect={1}", LocalID, _isVolumeDetect);
619 SetObjectDynamic(true); 619 SetObjectDynamic(true);
@@ -628,7 +628,7 @@ public class BSPrim : BSPhysObject
628 public override void SetMaterial(int material) 628 public override void SetMaterial(int material)
629 { 629 {
630 base.SetMaterial(material); 630 base.SetMaterial(material);
631 PhysScene.TaintedObject("BSPrim.SetMaterial", delegate() 631 PhysScene.TaintedObject(LocalID, "BSPrim.SetMaterial", delegate()
632 { 632 {
633 UpdatePhysicalParameters(); 633 UpdatePhysicalParameters();
634 }); 634 });
@@ -641,7 +641,7 @@ public class BSPrim : BSPhysObject
641 if (base.Friction != value) 641 if (base.Friction != value)
642 { 642 {
643 base.Friction = value; 643 base.Friction = value;
644 PhysScene.TaintedObject("BSPrim.setFriction", delegate() 644 PhysScene.TaintedObject(LocalID, "BSPrim.setFriction", delegate()
645 { 645 {
646 UpdatePhysicalParameters(); 646 UpdatePhysicalParameters();
647 }); 647 });
@@ -656,7 +656,7 @@ public class BSPrim : BSPhysObject
656 if (base.Restitution != value) 656 if (base.Restitution != value)
657 { 657 {
658 base.Restitution = value; 658 base.Restitution = value;
659 PhysScene.TaintedObject("BSPrim.setRestitution", delegate() 659 PhysScene.TaintedObject(LocalID, "BSPrim.setRestitution", delegate()
660 { 660 {
661 UpdatePhysicalParameters(); 661 UpdatePhysicalParameters();
662 }); 662 });
@@ -673,7 +673,7 @@ public class BSPrim : BSPhysObject
673 if (base.Density != value) 673 if (base.Density != value)
674 { 674 {
675 base.Density = value; 675 base.Density = value;
676 PhysScene.TaintedObject("BSPrim.setDensity", delegate() 676 PhysScene.TaintedObject(LocalID, "BSPrim.setDensity", delegate()
677 { 677 {
678 UpdatePhysicalParameters(); 678 UpdatePhysicalParameters();
679 }); 679 });
@@ -688,7 +688,7 @@ public class BSPrim : BSPhysObject
688 if (base.GravModifier != value) 688 if (base.GravModifier != value)
689 { 689 {
690 base.GravModifier = value; 690 base.GravModifier = value;
691 PhysScene.TaintedObject("BSPrim.setGravityModifier", delegate() 691 PhysScene.TaintedObject(LocalID, "BSPrim.setGravityModifier", delegate()
692 { 692 {
693 UpdatePhysicalParameters(); 693 UpdatePhysicalParameters();
694 }); 694 });
@@ -699,7 +699,7 @@ public class BSPrim : BSPhysObject
699 get { return RawVelocity; } 699 get { return RawVelocity; }
700 set { 700 set {
701 RawVelocity = value; 701 RawVelocity = value;
702 PhysScene.TaintedObject("BSPrim.setVelocity", delegate() 702 PhysScene.TaintedObject(LocalID, "BSPrim.setVelocity", delegate()
703 { 703 {
704 // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, RawVelocity); 704 // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, RawVelocity);
705 ForceVelocity = RawVelocity; 705 ForceVelocity = RawVelocity;
@@ -745,7 +745,7 @@ public class BSPrim : BSPhysObject
745 return; 745 return;
746 RawOrientation = value; 746 RawOrientation = value;
747 747
748 PhysScene.TaintedObject("BSPrim.setOrientation", delegate() 748 PhysScene.TaintedObject(LocalID, "BSPrim.setOrientation", delegate()
749 { 749 {
750 ForceOrientation = RawOrientation; 750 ForceOrientation = RawOrientation;
751 }); 751 });
@@ -776,7 +776,7 @@ public class BSPrim : BSPhysObject
776 if (_isPhysical != value) 776 if (_isPhysical != value)
777 { 777 {
778 _isPhysical = value; 778 _isPhysical = value;
779 PhysScene.TaintedObject("BSPrim.setIsPhysical", delegate() 779 PhysScene.TaintedObject(LocalID, "BSPrim.setIsPhysical", delegate()
780 { 780 {
781 DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical); 781 DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical);
782 SetObjectDynamic(true); 782 SetObjectDynamic(true);
@@ -1020,7 +1020,7 @@ public class BSPrim : BSPhysObject
1020 public override bool FloatOnWater { 1020 public override bool FloatOnWater {
1021 set { 1021 set {
1022 _floatOnWater = value; 1022 _floatOnWater = value;
1023 PhysScene.TaintedObject("BSPrim.setFloatOnWater", delegate() 1023 PhysScene.TaintedObject(LocalID, "BSPrim.setFloatOnWater", delegate()
1024 { 1024 {
1025 if (_floatOnWater) 1025 if (_floatOnWater)
1026 CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER); 1026 CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER);
@@ -1037,7 +1037,7 @@ public class BSPrim : BSPhysObject
1037 _rotationalVelocity = value; 1037 _rotationalVelocity = value;
1038 Util.ClampV(_rotationalVelocity, BSParam.MaxAngularVelocity); 1038 Util.ClampV(_rotationalVelocity, BSParam.MaxAngularVelocity);
1039 // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); 1039 // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
1040 PhysScene.TaintedObject("BSPrim.setRotationalVelocity", delegate() 1040 PhysScene.TaintedObject(LocalID, "BSPrim.setRotationalVelocity", delegate()
1041 { 1041 {
1042 ForceRotationalVelocity = _rotationalVelocity; 1042 ForceRotationalVelocity = _rotationalVelocity;
1043 }); 1043 });
@@ -1068,7 +1068,7 @@ public class BSPrim : BSPhysObject
1068 get { return _buoyancy; } 1068 get { return _buoyancy; }
1069 set { 1069 set {
1070 _buoyancy = value; 1070 _buoyancy = value;
1071 PhysScene.TaintedObject("BSPrim.setBuoyancy", delegate() 1071 PhysScene.TaintedObject(LocalID, "BSPrim.setBuoyancy", delegate()
1072 { 1072 {
1073 ForceBuoyancy = _buoyancy; 1073 ForceBuoyancy = _buoyancy;
1074 }); 1074 });
@@ -1142,7 +1142,7 @@ public class BSPrim : BSPhysObject
1142 // DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); 1142 // DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce);
1143 1143
1144 OMV.Vector3 addForce = force; 1144 OMV.Vector3 addForce = force;
1145 PhysScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() 1145 PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.AddForce", delegate()
1146 { 1146 {
1147 // Bullet adds this central force to the total force for this tick. 1147 // Bullet adds this central force to the total force for this tick.
1148 // Deep down in Bullet: 1148 // Deep down in Bullet:
@@ -1172,7 +1172,7 @@ public class BSPrim : BSPhysObject
1172 OMV.Vector3 addImpulse = Util.ClampV(impulse, BSParam.MaxAddForceMagnitude); 1172 OMV.Vector3 addImpulse = Util.ClampV(impulse, BSParam.MaxAddForceMagnitude);
1173 // DetailLog("{0},BSPrim.addForceImpulse,call,impulse={1}", LocalID, impulse); 1173 // DetailLog("{0},BSPrim.addForceImpulse,call,impulse={1}", LocalID, impulse);
1174 1174
1175 PhysScene.TaintedObject(inTaintTime, "BSPrim.AddImpulse", delegate() 1175 PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.AddImpulse", delegate()
1176 { 1176 {
1177 // Bullet adds this impulse immediately to the velocity 1177 // Bullet adds this impulse immediately to the velocity
1178 DetailLog("{0},BSPrim.addForceImpulse,taint,impulseforce={1}", LocalID, addImpulse); 1178 DetailLog("{0},BSPrim.addForceImpulse,taint,impulseforce={1}", LocalID, addImpulse);
@@ -1197,7 +1197,7 @@ public class BSPrim : BSPhysObject
1197 if (force.IsFinite()) 1197 if (force.IsFinite())
1198 { 1198 {
1199 OMV.Vector3 angForce = force; 1199 OMV.Vector3 angForce = force;
1200 PhysScene.TaintedObject(inTaintTime, "BSPrim.AddAngularForce", delegate() 1200 PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.AddAngularForce", delegate()
1201 { 1201 {
1202 if (PhysBody.HasPhysicalBody) 1202 if (PhysBody.HasPhysicalBody)
1203 { 1203 {
@@ -1221,7 +1221,7 @@ public class BSPrim : BSPhysObject
1221 public void ApplyTorqueImpulse(OMV.Vector3 impulse, bool inTaintTime) 1221 public void ApplyTorqueImpulse(OMV.Vector3 impulse, bool inTaintTime)
1222 { 1222 {
1223 OMV.Vector3 applyImpulse = impulse; 1223 OMV.Vector3 applyImpulse = impulse;
1224 PhysScene.TaintedObject(inTaintTime, "BSPrim.ApplyTorqueImpulse", delegate() 1224 PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ApplyTorqueImpulse", delegate()
1225 { 1225 {
1226 if (PhysBody.HasPhysicalBody) 1226 if (PhysBody.HasPhysicalBody)
1227 { 1227 {
@@ -1552,39 +1552,10 @@ public class BSPrim : BSPhysObject
1552 #region Extension 1552 #region Extension
1553 public override object Extension(string pFunct, params object[] pParams) 1553 public override object Extension(string pFunct, params object[] pParams)
1554 { 1554 {
1555 DetailLog("{0} BSPrim.Extension,op={1}", LocalID, pFunct);
1555 object ret = null; 1556 object ret = null;
1556 switch (pFunct) 1557 switch (pFunct)
1557 { 1558 {
1558 case BSScene.PhysFunctGetLinksetType:
1559 {
1560 BSPrimLinkable myHandle = this as BSPrimLinkable;
1561 if (myHandle != null)
1562 {
1563 ret = (object)myHandle.LinksetType;
1564 }
1565 m_log.DebugFormat("{0} Extension.physGetLinksetType, type={1}", LogHeader, ret);
1566 break;
1567 }
1568 case BSScene.PhysFunctSetLinksetType:
1569 {
1570 if (pParams.Length > 0)
1571 {
1572 BSLinkset.LinksetImplementation linksetType = (BSLinkset.LinksetImplementation)pParams[0];
1573 BSPrimLinkable myHandle = this as BSPrimLinkable;
1574 if (myHandle != null && myHandle.Linkset.IsRoot(myHandle))
1575 {
1576 PhysScene.TaintedObject("BSPrim.PhysFunctSetLinksetType", delegate()
1577 {
1578 // Cause the linkset type to change
1579 m_log.DebugFormat("{0} Extension.physSetLinksetType, oldType={1}, newType={2}",
1580 LogHeader, myHandle.Linkset.LinksetImpl, linksetType);
1581 myHandle.ConvertLinkset(linksetType);
1582 });
1583 }
1584 ret = (object)(int)linksetType;
1585 }
1586 break;
1587 }
1588 default: 1559 default:
1589 ret = base.Extension(pFunct, pParams); 1560 ret = base.Extension(pFunct, pParams);
1590 break; 1561 break;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs
index 7179a6d..126b146 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs
@@ -30,6 +30,7 @@ using System.Linq;
30using System.Text; 30using System.Text;
31 31
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Region.OptionalModules.Scripting;
33 34
34using OMV = OpenMetaverse; 35using OMV = OpenMetaverse;
35 36
@@ -41,6 +42,8 @@ public class BSPrimLinkable : BSPrimDisplaced
41 // operations necessary for keeping the linkset created and, additionally, this 42 // operations necessary for keeping the linkset created and, additionally, this
42 // calls the linkset implementation for its creation and management. 43 // calls the linkset implementation for its creation and management.
43 44
45 private static readonly string LogHeader = "[BULLETS PRIMLINKABLE]";
46
44 // This adds the overrides for link() and delink() so the prim is linkable. 47 // This adds the overrides for link() and delink() so the prim is linkable.
45 48
46 public BSLinkset Linkset { get; set; } 49 public BSLinkset Linkset { get; set; }
@@ -58,15 +61,12 @@ public class BSPrimLinkable : BSPrimDisplaced
58 61
59 Linkset = BSLinkset.Factory(PhysScene, this); 62 Linkset = BSLinkset.Factory(PhysScene, this);
60 63
61 PhysScene.TaintedObject("BSPrimLinksetCompound.Refresh", delegate() 64 Linkset.Refresh(this);
62 {
63 Linkset.Refresh(this);
64 });
65 } 65 }
66 66
67 public override void Destroy() 67 public override void Destroy()
68 { 68 {
69 Linkset = Linkset.RemoveMeFromLinkset(this); 69 Linkset = Linkset.RemoveMeFromLinkset(this, false /* inTaintTime */);
70 base.Destroy(); 70 base.Destroy();
71 } 71 }
72 72
@@ -80,7 +80,7 @@ public class BSPrimLinkable : BSPrimDisplaced
80 80
81 Linkset = parent.Linkset.AddMeToLinkset(this); 81 Linkset = parent.Linkset.AddMeToLinkset(this);
82 82
83 DetailLog("{0},BSPrimLinkset.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}", 83 DetailLog("{0},BSPrimLinkable.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}",
84 LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren); 84 LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
85 } 85 }
86 return; 86 return;
@@ -94,9 +94,9 @@ public class BSPrimLinkable : BSPrimDisplaced
94 BSPhysObject parentBefore = Linkset.LinksetRoot; // DEBUG 94 BSPhysObject parentBefore = Linkset.LinksetRoot; // DEBUG
95 int childrenBefore = Linkset.NumberOfChildren; // DEBUG 95 int childrenBefore = Linkset.NumberOfChildren; // DEBUG
96 96
97 Linkset = Linkset.RemoveMeFromLinkset(this); 97 Linkset = Linkset.RemoveMeFromLinkset(this, false /* inTaintTime*/);
98 98
99 DetailLog("{0},BSPrimLinkset.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ", 99 DetailLog("{0},BSPrimLinkable.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ",
100 LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren); 100 LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
101 return; 101 return;
102 } 102 }
@@ -108,7 +108,7 @@ public class BSPrimLinkable : BSPrimDisplaced
108 set 108 set
109 { 109 {
110 base.Position = value; 110 base.Position = value;
111 PhysScene.TaintedObject("BSPrimLinkset.setPosition", delegate() 111 PhysScene.TaintedObject(LocalID, "BSPrimLinkable.setPosition", delegate()
112 { 112 {
113 Linkset.UpdateProperties(UpdatedProperties.Position, this); 113 Linkset.UpdateProperties(UpdatedProperties.Position, this);
114 }); 114 });
@@ -122,7 +122,7 @@ public class BSPrimLinkable : BSPrimDisplaced
122 set 122 set
123 { 123 {
124 base.Orientation = value; 124 base.Orientation = value;
125 PhysScene.TaintedObject("BSPrimLinkset.setOrientation", delegate() 125 PhysScene.TaintedObject(LocalID, "BSPrimLinkable.setOrientation", delegate()
126 { 126 {
127 Linkset.UpdateProperties(UpdatedProperties.Orientation, this); 127 Linkset.UpdateProperties(UpdatedProperties.Orientation, this);
128 }); 128 });
@@ -180,7 +180,7 @@ public class BSPrimLinkable : BSPrimDisplaced
180 // Do any filtering/modification needed for linksets. 180 // Do any filtering/modification needed for linksets.
181 public override void UpdateProperties(EntityProperties entprop) 181 public override void UpdateProperties(EntityProperties entprop)
182 { 182 {
183 if (Linkset.IsRoot(this)) 183 if (Linkset.IsRoot(this) || Linkset.ShouldReportPropertyUpdates(this))
184 { 184 {
185 // Properties are only updated for the roots of a linkset. 185 // Properties are only updated for the roots of a linkset.
186 // TODO: this will have to change when linksets are articulated. 186 // TODO: this will have to change when linksets are articulated.
@@ -240,6 +240,8 @@ public class BSPrimLinkable : BSPrimDisplaced
240 bool ret = false; 240 bool ret = false;
241 if (LinksetType != newType) 241 if (LinksetType != newType)
242 { 242 {
243 DetailLog("{0},BSPrimLinkable.ConvertLinkset,oldT={1},newT={2}", LocalID, LinksetType, newType);
244
243 // Set the implementation type first so the call to BSLinkset.Factory gets the new type. 245 // Set the implementation type first so the call to BSLinkset.Factory gets the new type.
244 this.LinksetType = newType; 246 this.LinksetType = newType;
245 247
@@ -263,7 +265,10 @@ public class BSPrimLinkable : BSPrimDisplaced
263 // Remove the children from the old linkset and add to the new (will be a new instance from the factory) 265 // Remove the children from the old linkset and add to the new (will be a new instance from the factory)
264 foreach (BSPrimLinkable child in children) 266 foreach (BSPrimLinkable child in children)
265 { 267 {
266 oldLinkset.RemoveMeFromLinkset(child); 268 oldLinkset.RemoveMeFromLinkset(child, true /*inTaintTime*/);
269 }
270 foreach (BSPrimLinkable child in children)
271 {
267 newLinkset.AddMeToLinkset(child); 272 newLinkset.AddMeToLinkset(child);
268 child.Linkset = newLinkset; 273 child.Linkset = newLinkset;
269 } 274 }
@@ -274,5 +279,70 @@ public class BSPrimLinkable : BSPrimDisplaced
274 } 279 }
275 return ret; 280 return ret;
276 } 281 }
282
283 #region Extension
284 public override object Extension(string pFunct, params object[] pParams)
285 {
286 DetailLog("{0} BSPrimLinkable.Extension,op={1},nParam={2}", LocalID, pFunct, pParams.Length);
287 object ret = null;
288 switch (pFunct)
289 {
290 // physGetLinksetType();
291 // pParams = [ BSPhysObject root, null ]
292 case ExtendedPhysics.PhysFunctGetLinksetType:
293 {
294 ret = (object)LinksetType;
295 DetailLog("{0},BSPrimLinkable.Extension.physGetLinksetType,type={1}", LocalID, ret);
296 break;
297 }
298 // physSetLinksetType(type);
299 // pParams = [ BSPhysObject root, null, integer type ]
300 case ExtendedPhysics.PhysFunctSetLinksetType:
301 {
302 if (pParams.Length > 2)
303 {
304 BSLinkset.LinksetImplementation linksetType = (BSLinkset.LinksetImplementation)pParams[2];
305 if (Linkset.IsRoot(this))
306 {
307 PhysScene.TaintedObject(LocalID, "BSPrim.PhysFunctSetLinksetType", delegate()
308 {
309 // Cause the linkset type to change
310 DetailLog("{0},BSPrimLinkable.Extension.physSetLinksetType, oldType={1},newType={2}",
311 LocalID, Linkset.LinksetImpl, linksetType);
312 ConvertLinkset(linksetType);
313 });
314 }
315 ret = (object)(int)linksetType;
316 }
317 break;
318 }
319 // physChangeLinkType(linknum, typeCode);
320 // pParams = [ BSPhysObject root, BSPhysObject child, integer linkType ]
321 case ExtendedPhysics.PhysFunctChangeLinkType:
322 {
323 ret = Linkset.Extension(pFunct, pParams);
324 break;
325 }
326 // physGetLinkType(linknum);
327 // pParams = [ BSPhysObject root, BSPhysObject child ]
328 case ExtendedPhysics.PhysFunctGetLinkType:
329 {
330 ret = Linkset.Extension(pFunct, pParams);
331 break;
332 }
333 // physChangeLinkParams(linknum, [code, value, code, value, ...]);
334 // pParams = [ BSPhysObject root, BSPhysObject child, object[] [ string op, object opParam, string op, object opParam, ... ] ]
335 case ExtendedPhysics.PhysFunctChangeLinkParams:
336 {
337 ret = Linkset.Extension(pFunct, pParams);
338 break;
339 }
340 default:
341 ret = base.Extension(pFunct, pParams);
342 break;
343 }
344 return ret;
345 }
346 #endregion // Extension
277} 347}
278} 348}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index c92c9b9..b3dfa41 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -157,12 +157,20 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
157 public delegate void TaintCallback(); 157 public delegate void TaintCallback();
158 private struct TaintCallbackEntry 158 private struct TaintCallbackEntry
159 { 159 {
160 public String originator;
160 public String ident; 161 public String ident;
161 public TaintCallback callback; 162 public TaintCallback callback;
162 public TaintCallbackEntry(string i, TaintCallback c) 163 public TaintCallbackEntry(string pIdent, TaintCallback pCallBack)
163 { 164 {
164 ident = i; 165 originator = BSScene.DetailLogZero;
165 callback = c; 166 ident = pIdent;
167 callback = pCallBack;
168 }
169 public TaintCallbackEntry(string pOrigin, string pIdent, TaintCallback pCallBack)
170 {
171 originator = pOrigin;
172 ident = pIdent;
173 callback = pCallBack;
166 } 174 }
167 } 175 }
168 private Object _taintLock = new Object(); // lock for using the next object 176 private Object _taintLock = new Object(); // lock for using the next object
@@ -867,18 +875,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
867 public override bool IsThreaded { get { return false; } } 875 public override bool IsThreaded { get { return false; } }
868 876
869 #region Extensions 877 #region Extensions
870 // =============================================================
871 // Per scene functions. See below.
872
873 // Per avatar functions. See BSCharacter.
874
875 // Per prim functions. See BSPrim.
876 public const string PhysFunctGetLinksetType = "BulletSim.GetLinksetType";
877 public const string PhysFunctSetLinksetType = "BulletSim.SetLinksetType";
878 // =============================================================
879
880 public override object Extension(string pFunct, params object[] pParams) 878 public override object Extension(string pFunct, params object[] pParams)
881 { 879 {
880 DetailLog("{0} BSScene.Extension,op={1}", DetailLogZero, pFunct);
882 return base.Extension(pFunct, pParams); 881 return base.Extension(pFunct, pParams);
883 } 882 }
884 #endregion // Extensions 883 #endregion // Extensions
@@ -897,26 +896,37 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
897 // Calls to the PhysicsActors can't directly call into the physics engine 896 // Calls to the PhysicsActors can't directly call into the physics engine
898 // because it might be busy. We delay changes to a known time. 897 // because it might be busy. We delay changes to a known time.
899 // We rely on C#'s closure to save and restore the context for the delegate. 898 // We rely on C#'s closure to save and restore the context for the delegate.
900 public void TaintedObject(String ident, TaintCallback callback) 899 public void TaintedObject(string pOriginator, string pIdent, TaintCallback pCallback)
901 { 900 {
902 if (!m_initialized) return; 901 TaintedObject(false /*inTaintTime*/, pOriginator, pIdent, pCallback);
903 902 }
904 lock (_taintLock) 903 public void TaintedObject(uint pOriginator, String pIdent, TaintCallback pCallback)
905 { 904 {
906 _taintOperations.Add(new TaintCallbackEntry(ident, callback)); 905 TaintedObject(false /*inTaintTime*/, m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback);
907 } 906 }
908 907 public void TaintedObject(bool inTaintTime, String pIdent, TaintCallback pCallback)
909 return; 908 {
909 TaintedObject(inTaintTime, BSScene.DetailLogZero, pIdent, pCallback);
910 }
911 public void TaintedObject(bool inTaintTime, uint pOriginator, String pIdent, TaintCallback pCallback)
912 {
913 TaintedObject(inTaintTime, m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback);
910 } 914 }
911
912 // Sometimes a potentially tainted operation can be used in and out of taint time. 915 // Sometimes a potentially tainted operation can be used in and out of taint time.
913 // This routine executes the command immediately if in taint-time otherwise it is queued. 916 // This routine executes the command immediately if in taint-time otherwise it is queued.
914 public void TaintedObject(bool inTaintTime, string ident, TaintCallback callback) 917 public void TaintedObject(bool inTaintTime, string pOriginator, string pIdent, TaintCallback pCallback)
915 { 918 {
919 if (!m_initialized) return;
920
916 if (inTaintTime) 921 if (inTaintTime)
917 callback(); 922 pCallback();
918 else 923 else
919 TaintedObject(ident, callback); 924 {
925 lock (_taintLock)
926 {
927 _taintOperations.Add(new TaintCallbackEntry(pOriginator, pIdent, pCallback));
928 }
929 }
920 } 930 }
921 931
922 private void TriggerPreStepEvent(float timeStep) 932 private void TriggerPreStepEvent(float timeStep)
@@ -960,7 +970,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
960 { 970 {
961 try 971 try
962 { 972 {
963 DetailLog("{0},BSScene.ProcessTaints,doTaint,id={1}", DetailLogZero, tcbe.ident); // DEBUG DEBUG DEBUG 973 DetailLog("{0},BSScene.ProcessTaints,doTaint,id={1}", tcbe.originator, tcbe.ident); // DEBUG DEBUG DEBUG
964 tcbe.callback(); 974 tcbe.callback();
965 } 975 }
966 catch (Exception e) 976 catch (Exception e)
@@ -977,10 +987,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
977 // will replace any previous operation by the same object. 987 // will replace any previous operation by the same object.
978 public void PostTaintObject(String ident, uint ID, TaintCallback callback) 988 public void PostTaintObject(String ident, uint ID, TaintCallback callback)
979 { 989 {
980 string uniqueIdent = ident + "-" + ID.ToString(); 990 string IDAsString = ID.ToString();
991 string uniqueIdent = ident + "-" + IDAsString;
981 lock (_taintLock) 992 lock (_taintLock)
982 { 993 {
983 _postTaintOperations[uniqueIdent] = new TaintCallbackEntry(uniqueIdent, callback); 994 _postTaintOperations[uniqueIdent] = new TaintCallbackEntry(IDAsString, uniqueIdent, callback);
984 } 995 }
985 996
986 return; 997 return;
@@ -1090,7 +1101,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
1090 string xval = val; 1101 string xval = val;
1091 List<uint> xlIDs = lIDs; 1102 List<uint> xlIDs = lIDs;
1092 string xparm = parm; 1103 string xparm = parm;
1093 TaintedObject("BSScene.UpdateParameterSet", delegate() { 1104 TaintedObject(DetailLogZero, "BSScene.UpdateParameterSet", delegate() {
1094 BSParam.ParameterDefnBase thisParam; 1105 BSParam.ParameterDefnBase thisParam;
1095 if (BSParam.TryGetParameter(xparm, out thisParam)) 1106 if (BSParam.TryGetParameter(xparm, out thisParam))
1096 { 1107 {
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index f05aaa9..8892b69 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -8900,8 +8900,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8900 int idx=0; 8900 int idx=0;
8901 while (idx < rules.Length) 8901 while (idx < rules.Length)
8902 { 8902 {
8903 int code=(int)rules.GetLSLIntegerItem(idx++); 8903 int code = (int)rules.GetLSLIntegerItem(idx++);
8904 int remain=rules.Length-idx; 8904 int remain = rules.Length - idx;
8905 8905
8906 switch (code) 8906 switch (code)
8907 { 8907 {
@@ -8974,7 +8974,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8974 break; 8974 break;
8975 8975
8976 case ScriptBaseClass.PRIM_TYPE_SCULPT: 8976 case ScriptBaseClass.PRIM_TYPE_SCULPT:
8977 res.Add(Shape.SculptTexture.ToString()); 8977 res.Add(new LSL_String(Shape.SculptTexture.ToString()));
8978 res.Add(new LSL_Integer(Shape.SculptType)); 8978 res.Add(new LSL_Integer(Shape.SculptType));
8979 break; 8979 break;
8980 8980
@@ -9316,7 +9316,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9316 )); 9316 ));
9317 break; 9317 break;
9318 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 9318 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9319 if(remain < 3) 9319
9320 // TODO: Should be issuing a runtime script warning in this case.
9321 if (remain < 2)
9320 return null; 9322 return null;
9321 9323
9322 return rules.GetSublist(idx, -1); 9324 return rules.GetSublist(idx, -1);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index f4e4f44..5c57971 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -3043,7 +3043,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3043 sp.ControllingClient.Kick(alert); 3043 sp.ControllingClient.Kick(alert);
3044 3044
3045 // ...and close on our side 3045 // ...and close on our side
3046 sp.Scene.IncomingCloseAgent(sp.UUID, false); 3046 sp.Scene.CloseAgent(sp.UUID, false);
3047 } 3047 }
3048 }); 3048 });
3049 } 3049 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiObjectTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiObjectTests.cs
new file mode 100644
index 0000000..ed61dc0
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiObjectTests.cs
@@ -0,0 +1,399 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Text;
32using log4net;
33using Nini.Config;
34using NUnit.Framework;
35using OpenMetaverse;
36using OpenMetaverse.Assets;
37using OpenMetaverse.StructuredData;
38using OpenSim.Framework;
39using OpenSim.Region.CoreModules.Avatar.AvatarFactory;
40using OpenSim.Region.OptionalModules.World.NPC;
41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Region.ScriptEngine.Shared;
43using OpenSim.Region.ScriptEngine.Shared.Api;
44using OpenSim.Region.ScriptEngine.Shared.Instance;
45using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
46using OpenSim.Services.Interfaces;
47using OpenSim.Tests.Common;
48using OpenSim.Tests.Common.Mock;
49using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
50using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
51
52namespace OpenSim.Region.ScriptEngine.Shared.Tests
53{
54 [TestFixture]
55 public class LSL_ApiObjectTests : OpenSimTestCase
56 {
57 private const double VECTOR_COMPONENT_ACCURACY = 0.0000005d;
58 private const float FLOAT_ACCURACY = 0.00005f;
59
60 protected Scene m_scene;
61 protected XEngine.XEngine m_engine;
62
63 [SetUp]
64 public override void SetUp()
65 {
66 base.SetUp();
67
68 IConfigSource initConfigSource = new IniConfigSource();
69 IConfig config = initConfigSource.AddConfig("XEngine");
70 config.Set("Enabled", "true");
71
72 m_scene = new SceneHelpers().SetupScene();
73 SceneHelpers.SetupSceneModules(m_scene, initConfigSource);
74
75 m_engine = new XEngine.XEngine();
76 m_engine.Initialise(initConfigSource);
77 m_engine.AddRegion(m_scene);
78 }
79
80 [Test]
81 public void TestllGetLinkPrimitiveParams()
82 {
83 TestHelpers.InMethod();
84 TestHelpers.EnableLogging();
85
86 UUID ownerId = TestHelpers.ParseTail(0x1);
87
88 SceneObjectGroup grp1 = SceneHelpers.CreateSceneObject(2, ownerId, "grp1-", 0x10);
89 grp1.AbsolutePosition = new Vector3(10, 11, 12);
90 m_scene.AddSceneObject(grp1);
91
92 LSL_Api apiGrp1 = new LSL_Api();
93 apiGrp1.Initialize(m_engine, grp1.RootPart, null, null);
94
95 // Check simple 1 prim case
96 {
97 LSL_List resList
98 = apiGrp1.llGetLinkPrimitiveParams(1, new LSL_List(new LSL_Integer(ScriptBaseClass.PRIM_ROTATION)));
99
100 Assert.That(resList.Length, Is.EqualTo(1));
101 }
102
103 // Check 2 prim case
104 {
105 LSL_List resList
106 = apiGrp1.llGetLinkPrimitiveParams(
107 1,
108 new LSL_List(
109 new LSL_Integer(ScriptBaseClass.PRIM_ROTATION),
110 new LSL_Integer(ScriptBaseClass.PRIM_LINK_TARGET),
111 new LSL_Integer(2),
112 new LSL_Integer(ScriptBaseClass.PRIM_ROTATION)));
113
114 Assert.That(resList.Length, Is.EqualTo(2));
115 }
116
117 // Check invalid parameters are ignored
118 {
119 LSL_List resList
120 = apiGrp1.llGetLinkPrimitiveParams(3, new LSL_List(new LSL_Integer(ScriptBaseClass.PRIM_ROTATION)));
121
122 Assert.That(resList.Length, Is.EqualTo(0));
123 }
124
125 // Check all parameters are ignored if an initial bad link is given
126 {
127 LSL_List resList
128 = apiGrp1.llGetLinkPrimitiveParams(
129 3,
130 new LSL_List(
131 new LSL_Integer(ScriptBaseClass.PRIM_ROTATION),
132 new LSL_Integer(ScriptBaseClass.PRIM_LINK_TARGET),
133 new LSL_Integer(1),
134 new LSL_Integer(ScriptBaseClass.PRIM_ROTATION)));
135
136 Assert.That(resList.Length, Is.EqualTo(0));
137 }
138
139 // Check only subsequent parameters are ignored when we hit the first bad link number
140 {
141 LSL_List resList
142 = apiGrp1.llGetLinkPrimitiveParams(
143 1,
144 new LSL_List(
145 new LSL_Integer(ScriptBaseClass.PRIM_ROTATION),
146 new LSL_Integer(ScriptBaseClass.PRIM_LINK_TARGET),
147 new LSL_Integer(3),
148 new LSL_Integer(ScriptBaseClass.PRIM_ROTATION)));
149
150 Assert.That(resList.Length, Is.EqualTo(1));
151 }
152 }
153
154 [Test]
155 // llSetPrimitiveParams and llGetPrimitiveParams test.
156 public void TestllSetPrimitiveParams()
157 {
158 TestHelpers.InMethod();
159
160 // Create Prim1.
161 Scene scene = new SceneHelpers().SetupScene();
162 string obj1Name = "Prim1";
163 UUID objUuid = new UUID("00000000-0000-0000-0000-000000000001");
164 SceneObjectPart part1 =
165 new SceneObjectPart(UUID.Zero, PrimitiveBaseShape.Default,
166 Vector3.Zero, Quaternion.Identity,
167 Vector3.Zero) { Name = obj1Name, UUID = objUuid };
168 Assert.That(scene.AddNewSceneObject(new SceneObjectGroup(part1), false), Is.True);
169
170 LSL_Api apiGrp1 = new LSL_Api();
171 apiGrp1.Initialize(m_engine, part1, null, null);
172
173 // Note that prim hollow check is passed with the other prim params in order to allow the
174 // specification of a different check value from the prim param. A cylinder, prism, sphere,
175 // torus or ring, with a hole shape of square, is limited to a hollow of 70%. Test 5 below
176 // specifies a value of 95% and checks to see if 70% was properly returned.
177
178 // Test a sphere.
179 CheckllSetPrimitiveParams(
180 apiGrp1,
181 "test 1", // Prim test identification string
182 new LSL_Types.Vector3(6.0d, 9.9d, 9.9d), // Prim size
183 ScriptBaseClass.PRIM_TYPE_SPHERE, // Prim type
184 ScriptBaseClass.PRIM_HOLE_DEFAULT, // Prim hole type
185 new LSL_Types.Vector3(0.0d, 0.075d, 0.0d), // Prim cut
186 0.80f, // Prim hollow
187 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist
188 new LSL_Types.Vector3(0.32d, 0.76d, 0.0d), // Prim dimple
189 0.80f); // Prim hollow check
190
191 // Test a prism.
192 CheckllSetPrimitiveParams(
193 apiGrp1,
194 "test 2", // Prim test identification string
195 new LSL_Types.Vector3(3.5d, 3.5d, 3.5d), // Prim size
196 ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type
197 ScriptBaseClass.PRIM_HOLE_CIRCLE, // Prim hole type
198 new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
199 0.90f, // Prim hollow
200 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist
201 new LSL_Types.Vector3(2.0d, 1.0d, 0.0d), // Prim taper
202 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
203 0.90f); // Prim hollow check
204
205 // Test a box.
206 CheckllSetPrimitiveParams(
207 apiGrp1,
208 "test 3", // Prim test identification string
209 new LSL_Types.Vector3(3.5d, 3.5d, 3.5d), // Prim size
210 ScriptBaseClass.PRIM_TYPE_BOX, // Prim type
211 ScriptBaseClass.PRIM_HOLE_TRIANGLE, // Prim hole type
212 new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
213 0.95f, // Prim hollow
214 new LSL_Types.Vector3(1.0d, 0.0d, 0.0d), // Prim twist
215 new LSL_Types.Vector3(1.0d, 1.0d, 0.0d), // Prim taper
216 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
217 0.95f); // Prim hollow check
218
219 // Test a tube.
220 CheckllSetPrimitiveParams(
221 apiGrp1,
222 "test 4", // Prim test identification string
223 new LSL_Types.Vector3(4.2d, 4.2d, 4.2d), // Prim size
224 ScriptBaseClass.PRIM_TYPE_TUBE, // Prim type
225 ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type
226 new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
227 0.00f, // Prim hollow
228 new LSL_Types.Vector3(1.0d, -1.0d, 0.0d), // Prim twist
229 new LSL_Types.Vector3(1.0d, 0.05d, 0.0d), // Prim hole size
230 // Expression for y selected to test precision problems during byte
231 // cast in SetPrimitiveShapeParams.
232 new LSL_Types.Vector3(0.0d, 0.35d + 0.1d, 0.0d), // Prim shear
233 new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim profile cut
234 // Expression for y selected to test precision problems during sbyte
235 // cast in SetPrimitiveShapeParams.
236 new LSL_Types.Vector3(-1.0d, 0.70d + 0.1d + 0.1d, 0.0d), // Prim taper
237 1.11f, // Prim revolutions
238 0.88f, // Prim radius
239 0.95f, // Prim skew
240 0.00f); // Prim hollow check
241
242 // Test a prism.
243 CheckllSetPrimitiveParams(
244 apiGrp1,
245 "test 5", // Prim test identification string
246 new LSL_Types.Vector3(3.5d, 3.5d, 3.5d), // Prim size
247 ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type
248 ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type
249 new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
250 0.95f, // Prim hollow
251 // Expression for x selected to test precision problems during sbyte
252 // cast in SetPrimitiveShapeBlockParams.
253 new LSL_Types.Vector3(0.7d + 0.2d, 0.0d, 0.0d), // Prim twist
254 // Expression for y selected to test precision problems during sbyte
255 // cast in SetPrimitiveShapeParams.
256 new LSL_Types.Vector3(2.0d, (1.3d + 0.1d), 0.0d), // Prim taper
257 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
258 0.70f); // Prim hollow check
259
260 // Test a sculpted prim.
261 CheckllSetPrimitiveParams(
262 apiGrp1,
263 "test 6", // Prim test identification string
264 new LSL_Types.Vector3(2.0d, 2.0d, 2.0d), // Prim size
265 ScriptBaseClass.PRIM_TYPE_SCULPT, // Prim type
266 "be293869-d0d9-0a69-5989-ad27f1946fd4", // Prim map
267 ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE); // Prim sculpt type
268 }
269
270 // Set prim params for a box, cylinder or prism and check results.
271 public void CheckllSetPrimitiveParams(LSL_Api api, string primTest,
272 LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut,
273 float primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primTaper, LSL_Types.Vector3 primShear,
274 float primHollowCheck)
275 {
276 // Set the prim params.
277 api.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
278 ScriptBaseClass.PRIM_TYPE, primType, primHoleType,
279 primCut, primHollow, primTwist, primTaper, primShear));
280
281 // Get params for prim to validate settings.
282 LSL_Types.list primParams =
283 api.llGetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, ScriptBaseClass.PRIM_TYPE));
284
285 // Validate settings.
286 CheckllSetPrimitiveParamsVector(primSize, api.llList2Vector(primParams, 0), primTest + " prim size");
287 Assert.AreEqual(primType, api.llList2Integer(primParams, 1),
288 "TestllSetPrimitiveParams " + primTest + " prim type check fail");
289 Assert.AreEqual(primHoleType, api.llList2Integer(primParams, 2),
290 "TestllSetPrimitiveParams " + primTest + " prim hole default check fail");
291 CheckllSetPrimitiveParamsVector(primCut, api.llList2Vector(primParams, 3), primTest + " prim cut");
292 Assert.AreEqual(primHollowCheck, api.llList2Float(primParams, 4), FLOAT_ACCURACY,
293 "TestllSetPrimitiveParams " + primTest + " prim hollow check fail");
294 CheckllSetPrimitiveParamsVector(primTwist, api.llList2Vector(primParams, 5), primTest + " prim twist");
295 CheckllSetPrimitiveParamsVector(primTaper, api.llList2Vector(primParams, 6), primTest + " prim taper");
296 CheckllSetPrimitiveParamsVector(primShear, api.llList2Vector(primParams, 7), primTest + " prim shear");
297 }
298
299 // Set prim params for a sphere and check results.
300 public void CheckllSetPrimitiveParams(LSL_Api api, string primTest,
301 LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut,
302 float primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primDimple, float primHollowCheck)
303 {
304 // Set the prim params.
305 api.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
306 ScriptBaseClass.PRIM_TYPE, primType, primHoleType,
307 primCut, primHollow, primTwist, primDimple));
308
309 // Get params for prim to validate settings.
310 LSL_Types.list primParams =
311 api.llGetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, ScriptBaseClass.PRIM_TYPE));
312
313 // Validate settings.
314 CheckllSetPrimitiveParamsVector(primSize, api.llList2Vector(primParams, 0), primTest + " prim size");
315 Assert.AreEqual(primType, api.llList2Integer(primParams, 1),
316 "TestllSetPrimitiveParams " + primTest + " prim type check fail");
317 Assert.AreEqual(primHoleType, api.llList2Integer(primParams, 2),
318 "TestllSetPrimitiveParams " + primTest + " prim hole default check fail");
319 CheckllSetPrimitiveParamsVector(primCut, api.llList2Vector(primParams, 3), primTest + " prim cut");
320 Assert.AreEqual(primHollowCheck, api.llList2Float(primParams, 4), FLOAT_ACCURACY,
321 "TestllSetPrimitiveParams " + primTest + " prim hollow check fail");
322 CheckllSetPrimitiveParamsVector(primTwist, api.llList2Vector(primParams, 5), primTest + " prim twist");
323 CheckllSetPrimitiveParamsVector(primDimple, api.llList2Vector(primParams, 6), primTest + " prim dimple");
324 }
325
326 // Set prim params for a torus, tube or ring and check results.
327 public void CheckllSetPrimitiveParams(LSL_Api api, string primTest,
328 LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut,
329 float primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primHoleSize,
330 LSL_Types.Vector3 primShear, LSL_Types.Vector3 primProfCut, LSL_Types.Vector3 primTaper,
331 float primRev, float primRadius, float primSkew, float primHollowCheck)
332 {
333 // Set the prim params.
334 api.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
335 ScriptBaseClass.PRIM_TYPE, primType, primHoleType,
336 primCut, primHollow, primTwist, primHoleSize, primShear, primProfCut,
337 primTaper, primRev, primRadius, primSkew));
338
339 // Get params for prim to validate settings.
340 LSL_Types.list primParams =
341 api.llGetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, ScriptBaseClass.PRIM_TYPE));
342
343 // Valdate settings.
344 CheckllSetPrimitiveParamsVector(primSize, api.llList2Vector(primParams, 0), primTest + " prim size");
345 Assert.AreEqual(primType, api.llList2Integer(primParams, 1),
346 "TestllSetPrimitiveParams " + primTest + " prim type check fail");
347 Assert.AreEqual(primHoleType, api.llList2Integer(primParams, 2),
348 "TestllSetPrimitiveParams " + primTest + " prim hole default check fail");
349 CheckllSetPrimitiveParamsVector(primCut, api.llList2Vector(primParams, 3), primTest + " prim cut");
350 Assert.AreEqual(primHollowCheck, api.llList2Float(primParams, 4), FLOAT_ACCURACY,
351 "TestllSetPrimitiveParams " + primTest + " prim hollow check fail");
352 CheckllSetPrimitiveParamsVector(primTwist, api.llList2Vector(primParams, 5), primTest + " prim twist");
353 CheckllSetPrimitiveParamsVector(primHoleSize, api.llList2Vector(primParams, 6), primTest + " prim hole size");
354 CheckllSetPrimitiveParamsVector(primShear, api.llList2Vector(primParams, 7), primTest + " prim shear");
355 CheckllSetPrimitiveParamsVector(primProfCut, api.llList2Vector(primParams, 8), primTest + " prim profile cut");
356 CheckllSetPrimitiveParamsVector(primTaper, api.llList2Vector(primParams, 9), primTest + " prim taper");
357 Assert.AreEqual(primRev, api.llList2Float(primParams, 10), FLOAT_ACCURACY,
358 "TestllSetPrimitiveParams " + primTest + " prim revolutions fail");
359 Assert.AreEqual(primRadius, api.llList2Float(primParams, 11), FLOAT_ACCURACY,
360 "TestllSetPrimitiveParams " + primTest + " prim radius fail");
361 Assert.AreEqual(primSkew, api.llList2Float(primParams, 12), FLOAT_ACCURACY,
362 "TestllSetPrimitiveParams " + primTest + " prim skew fail");
363 }
364
365 // Set prim params for a sculpted prim and check results.
366 public void CheckllSetPrimitiveParams(LSL_Api api, string primTest,
367 LSL_Types.Vector3 primSize, int primType, string primMap, int primSculptType)
368 {
369 // Set the prim params.
370 api.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
371 ScriptBaseClass.PRIM_TYPE, primType, primMap, primSculptType));
372
373 // Get params for prim to validate settings.
374 LSL_Types.list primParams =
375 api.llGetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, ScriptBaseClass.PRIM_TYPE));
376
377 // Validate settings.
378 CheckllSetPrimitiveParamsVector(primSize, api.llList2Vector(primParams, 0), primTest + " prim size");
379 Assert.AreEqual(primType, api.llList2Integer(primParams, 1),
380 "TestllSetPrimitiveParams " + primTest + " prim type check fail");
381 Assert.AreEqual(primMap, (string)api.llList2String(primParams, 2),
382 "TestllSetPrimitiveParams " + primTest + " prim map check fail");
383 Assert.AreEqual(primSculptType, api.llList2Integer(primParams, 3),
384 "TestllSetPrimitiveParams " + primTest + " prim type scuplt check fail");
385 }
386
387 public void CheckllSetPrimitiveParamsVector(LSL_Types.Vector3 vecCheck, LSL_Types.Vector3 vecReturned, string msg)
388 {
389 // Check each vector component against expected result.
390 Assert.AreEqual(vecCheck.x, vecReturned.x, VECTOR_COMPONENT_ACCURACY,
391 "TestllSetPrimitiveParams " + msg + " vector check fail on x component");
392 Assert.AreEqual(vecCheck.y, vecReturned.y, VECTOR_COMPONENT_ACCURACY,
393 "TestllSetPrimitiveParams " + msg + " vector check fail on y component");
394 Assert.AreEqual(vecCheck.z, vecReturned.z, VECTOR_COMPONENT_ACCURACY,
395 "TestllSetPrimitiveParams " + msg + " vector check fail on z component");
396 }
397
398 }
399} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
index e97ae06..7e3726a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
@@ -47,9 +47,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
47 [TestFixture, LongRunning] 47 [TestFixture, LongRunning]
48 public class LSL_ApiTest 48 public class LSL_ApiTest
49 { 49 {
50 private const double ANGLE_ACCURACY_IN_RADIANS = 1E-6;
51 private const double VECTOR_COMPONENT_ACCURACY = 0.0000005d; 50 private const double VECTOR_COMPONENT_ACCURACY = 0.0000005d;
52 private const float FLOAT_ACCURACY = 0.00005f; 51 private const double ANGLE_ACCURACY_IN_RADIANS = 1E-6;
53 private LSL_Api m_lslApi; 52 private LSL_Api m_lslApi;
54 53
55 [SetUp] 54 [SetUp]
@@ -255,241 +254,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
255 } 254 }
256 255
257 [Test] 256 [Test]
258 // llSetPrimitiveParams and llGetPrimitiveParams test.
259 public void TestllSetPrimitiveParams()
260 {
261 TestHelpers.InMethod();
262
263 // Create Prim1.
264 Scene scene = new SceneHelpers().SetupScene();
265 string obj1Name = "Prim1";
266 UUID objUuid = new UUID("00000000-0000-0000-0000-000000000001");
267 SceneObjectPart part1 =
268 new SceneObjectPart(UUID.Zero, PrimitiveBaseShape.Default,
269 Vector3.Zero, Quaternion.Identity,
270 Vector3.Zero) { Name = obj1Name, UUID = objUuid };
271 Assert.That(scene.AddNewSceneObject(new SceneObjectGroup(part1), false), Is.True);
272
273 // Note that prim hollow check is passed with the other prim params in order to allow the
274 // specification of a different check value from the prim param. A cylinder, prism, sphere,
275 // torus or ring, with a hole shape of square, is limited to a hollow of 70%. Test 5 below
276 // specifies a value of 95% and checks to see if 70% was properly returned.
277
278 // Test a sphere.
279 CheckllSetPrimitiveParams(
280 "test 1", // Prim test identification string
281 new LSL_Types.Vector3(6.0d, 9.9d, 9.9d), // Prim size
282 ScriptBaseClass.PRIM_TYPE_SPHERE, // Prim type
283 ScriptBaseClass.PRIM_HOLE_DEFAULT, // Prim hole type
284 new LSL_Types.Vector3(0.0d, 0.075d, 0.0d), // Prim cut
285 0.80f, // Prim hollow
286 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist
287 new LSL_Types.Vector3(0.32d, 0.76d, 0.0d), // Prim dimple
288 0.80f); // Prim hollow check
289
290 // Test a prism.
291 CheckllSetPrimitiveParams(
292 "test 2", // Prim test identification string
293 new LSL_Types.Vector3(3.5d, 3.5d, 3.5d), // Prim size
294 ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type
295 ScriptBaseClass.PRIM_HOLE_CIRCLE, // Prim hole type
296 new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
297 0.90f, // Prim hollow
298 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist
299 new LSL_Types.Vector3(2.0d, 1.0d, 0.0d), // Prim taper
300 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
301 0.90f); // Prim hollow check
302
303 // Test a box.
304 CheckllSetPrimitiveParams(
305 "test 3", // Prim test identification string
306 new LSL_Types.Vector3(3.5d, 3.5d, 3.5d), // Prim size
307 ScriptBaseClass.PRIM_TYPE_BOX, // Prim type
308 ScriptBaseClass.PRIM_HOLE_TRIANGLE, // Prim hole type
309 new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
310 0.95f, // Prim hollow
311 new LSL_Types.Vector3(1.0d, 0.0d, 0.0d), // Prim twist
312 new LSL_Types.Vector3(1.0d, 1.0d, 0.0d), // Prim taper
313 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
314 0.95f); // Prim hollow check
315
316 // Test a tube.
317 CheckllSetPrimitiveParams(
318 "test 4", // Prim test identification string
319 new LSL_Types.Vector3(4.2d, 4.2d, 4.2d), // Prim size
320 ScriptBaseClass.PRIM_TYPE_TUBE, // Prim type
321 ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type
322 new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
323 0.00f, // Prim hollow
324 new LSL_Types.Vector3(1.0d, -1.0d, 0.0d), // Prim twist
325 new LSL_Types.Vector3(1.0d, 0.05d, 0.0d), // Prim hole size
326 // Expression for y selected to test precision problems during byte
327 // cast in SetPrimitiveShapeParams.
328 new LSL_Types.Vector3(0.0d, 0.35d + 0.1d, 0.0d), // Prim shear
329 new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim profile cut
330 // Expression for y selected to test precision problems during sbyte
331 // cast in SetPrimitiveShapeParams.
332 new LSL_Types.Vector3(-1.0d, 0.70d + 0.1d + 0.1d, 0.0d), // Prim taper
333 1.11f, // Prim revolutions
334 0.88f, // Prim radius
335 0.95f, // Prim skew
336 0.00f); // Prim hollow check
337
338 // Test a prism.
339 CheckllSetPrimitiveParams(
340 "test 5", // Prim test identification string
341 new LSL_Types.Vector3(3.5d, 3.5d, 3.5d), // Prim size
342 ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type
343 ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type
344 new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
345 0.95f, // Prim hollow
346 // Expression for x selected to test precision problems during sbyte
347 // cast in SetPrimitiveShapeBlockParams.
348 new LSL_Types.Vector3(0.7d + 0.2d, 0.0d, 0.0d), // Prim twist
349 // Expression for y selected to test precision problems during sbyte
350 // cast in SetPrimitiveShapeParams.
351 new LSL_Types.Vector3(2.0d, (1.3d + 0.1d), 0.0d), // Prim taper
352 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
353 0.70f); // Prim hollow check
354
355 // Test a sculpted prim.
356 CheckllSetPrimitiveParams(
357 "test 6", // Prim test identification string
358 new LSL_Types.Vector3(2.0d, 2.0d, 2.0d), // Prim size
359 ScriptBaseClass.PRIM_TYPE_SCULPT, // Prim type
360 "be293869-d0d9-0a69-5989-ad27f1946fd4", // Prim map
361 ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE); // Prim sculpt type
362 }
363
364 // Set prim params for a box, cylinder or prism and check results.
365 public void CheckllSetPrimitiveParams(string primTest,
366 LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut,
367 float primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primTaper, LSL_Types.Vector3 primShear,
368 float primHollowCheck)
369 {
370 // Set the prim params.
371 m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
372 ScriptBaseClass.PRIM_TYPE, primType, primHoleType,
373 primCut, primHollow, primTwist, primTaper, primShear));
374
375 // Get params for prim to validate settings.
376 LSL_Types.list primParams =
377 m_lslApi.llGetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, ScriptBaseClass.PRIM_TYPE));
378
379 // Validate settings.
380 CheckllSetPrimitiveParamsVector(primSize, m_lslApi.llList2Vector(primParams, 0), primTest + " prim size");
381 Assert.AreEqual(primType, m_lslApi.llList2Integer(primParams, 1),
382 "TestllSetPrimitiveParams " + primTest + " prim type check fail");
383 Assert.AreEqual(primHoleType, m_lslApi.llList2Integer(primParams, 2),
384 "TestllSetPrimitiveParams " + primTest + " prim hole default check fail");
385 CheckllSetPrimitiveParamsVector(primCut, m_lslApi.llList2Vector(primParams, 3), primTest + " prim cut");
386 Assert.AreEqual(primHollowCheck, m_lslApi.llList2Float(primParams, 4), FLOAT_ACCURACY,
387 "TestllSetPrimitiveParams " + primTest + " prim hollow check fail");
388 CheckllSetPrimitiveParamsVector(primTwist, m_lslApi.llList2Vector(primParams, 5), primTest + " prim twist");
389 CheckllSetPrimitiveParamsVector(primTaper, m_lslApi.llList2Vector(primParams, 6), primTest + " prim taper");
390 CheckllSetPrimitiveParamsVector(primShear, m_lslApi.llList2Vector(primParams, 7), primTest + " prim shear");
391 }
392
393 // Set prim params for a sphere and check results.
394 public void CheckllSetPrimitiveParams(string primTest,
395 LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut,
396 float primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primDimple, float primHollowCheck)
397 {
398 // Set the prim params.
399 m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
400 ScriptBaseClass.PRIM_TYPE, primType, primHoleType,
401 primCut, primHollow, primTwist, primDimple));
402
403 // Get params for prim to validate settings.
404 LSL_Types.list primParams =
405 m_lslApi.llGetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, ScriptBaseClass.PRIM_TYPE));
406
407 // Validate settings.
408 CheckllSetPrimitiveParamsVector(primSize, m_lslApi.llList2Vector(primParams, 0), primTest + " prim size");
409 Assert.AreEqual(primType, m_lslApi.llList2Integer(primParams, 1),
410 "TestllSetPrimitiveParams " + primTest + " prim type check fail");
411 Assert.AreEqual(primHoleType, m_lslApi.llList2Integer(primParams, 2),
412 "TestllSetPrimitiveParams " + primTest + " prim hole default check fail");
413 CheckllSetPrimitiveParamsVector(primCut, m_lslApi.llList2Vector(primParams, 3), primTest + " prim cut");
414 Assert.AreEqual(primHollowCheck, m_lslApi.llList2Float(primParams, 4), FLOAT_ACCURACY,
415 "TestllSetPrimitiveParams " + primTest + " prim hollow check fail");
416 CheckllSetPrimitiveParamsVector(primTwist, m_lslApi.llList2Vector(primParams, 5), primTest + " prim twist");
417 CheckllSetPrimitiveParamsVector(primDimple, m_lslApi.llList2Vector(primParams, 6), primTest + " prim dimple");
418 }
419
420 // Set prim params for a torus, tube or ring and check results.
421 public void CheckllSetPrimitiveParams(string primTest,
422 LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut,
423 float primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primHoleSize,
424 LSL_Types.Vector3 primShear, LSL_Types.Vector3 primProfCut, LSL_Types.Vector3 primTaper,
425 float primRev, float primRadius, float primSkew, float primHollowCheck)
426 {
427 // Set the prim params.
428 m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
429 ScriptBaseClass.PRIM_TYPE, primType, primHoleType,
430 primCut, primHollow, primTwist, primHoleSize, primShear, primProfCut,
431 primTaper, primRev, primRadius, primSkew));
432
433 // Get params for prim to validate settings.
434 LSL_Types.list primParams =
435 m_lslApi.llGetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, ScriptBaseClass.PRIM_TYPE));
436
437 // Valdate settings.
438 CheckllSetPrimitiveParamsVector(primSize, m_lslApi.llList2Vector(primParams, 0), primTest + " prim size");
439 Assert.AreEqual(primType, m_lslApi.llList2Integer(primParams, 1),
440 "TestllSetPrimitiveParams " + primTest + " prim type check fail");
441 Assert.AreEqual(primHoleType, m_lslApi.llList2Integer(primParams, 2),
442 "TestllSetPrimitiveParams " + primTest + " prim hole default check fail");
443 CheckllSetPrimitiveParamsVector(primCut, m_lslApi.llList2Vector(primParams, 3), primTest + " prim cut");
444 Assert.AreEqual(primHollowCheck, m_lslApi.llList2Float(primParams, 4), FLOAT_ACCURACY,
445 "TestllSetPrimitiveParams " + primTest + " prim hollow check fail");
446 CheckllSetPrimitiveParamsVector(primTwist, m_lslApi.llList2Vector(primParams, 5), primTest + " prim twist");
447 CheckllSetPrimitiveParamsVector(primHoleSize, m_lslApi.llList2Vector(primParams, 6), primTest + " prim hole size");
448 CheckllSetPrimitiveParamsVector(primShear, m_lslApi.llList2Vector(primParams, 7), primTest + " prim shear");
449 CheckllSetPrimitiveParamsVector(primProfCut, m_lslApi.llList2Vector(primParams, 8), primTest + " prim profile cut");
450 CheckllSetPrimitiveParamsVector(primTaper, m_lslApi.llList2Vector(primParams, 9), primTest + " prim taper");
451 Assert.AreEqual(primRev, m_lslApi.llList2Float(primParams, 10), FLOAT_ACCURACY,
452 "TestllSetPrimitiveParams " + primTest + " prim revolutions fail");
453 Assert.AreEqual(primRadius, m_lslApi.llList2Float(primParams, 11), FLOAT_ACCURACY,
454 "TestllSetPrimitiveParams " + primTest + " prim radius fail");
455 Assert.AreEqual(primSkew, m_lslApi.llList2Float(primParams, 12), FLOAT_ACCURACY,
456 "TestllSetPrimitiveParams " + primTest + " prim skew fail");
457 }
458
459 // Set prim params for a sculpted prim and check results.
460 public void CheckllSetPrimitiveParams(string primTest,
461 LSL_Types.Vector3 primSize, int primType, string primMap, int primSculptType)
462 {
463 // Set the prim params.
464 m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
465 ScriptBaseClass.PRIM_TYPE, primType, primMap, primSculptType));
466
467 // Get params for prim to validate settings.
468 LSL_Types.list primParams =
469 m_lslApi.llGetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, ScriptBaseClass.PRIM_TYPE));
470
471 // Validate settings.
472 CheckllSetPrimitiveParamsVector(primSize, m_lslApi.llList2Vector(primParams, 0), primTest + " prim size");
473 Assert.AreEqual(primType, m_lslApi.llList2Integer(primParams, 1),
474 "TestllSetPrimitiveParams " + primTest + " prim type check fail");
475 Assert.AreEqual(primMap, (string)m_lslApi.llList2String(primParams, 2),
476 "TestllSetPrimitiveParams " + primTest + " prim map check fail");
477 Assert.AreEqual(primSculptType, m_lslApi.llList2Integer(primParams, 3),
478 "TestllSetPrimitiveParams " + primTest + " prim type scuplt check fail");
479 }
480
481 public void CheckllSetPrimitiveParamsVector(LSL_Types.Vector3 vecCheck, LSL_Types.Vector3 vecReturned, string msg)
482 {
483 // Check each vector component against expected result.
484 Assert.AreEqual(vecCheck.x, vecReturned.x, VECTOR_COMPONENT_ACCURACY,
485 "TestllSetPrimitiveParams " + msg + " vector check fail on x component");
486 Assert.AreEqual(vecCheck.y, vecReturned.y, VECTOR_COMPONENT_ACCURACY,
487 "TestllSetPrimitiveParams " + msg + " vector check fail on y component");
488 Assert.AreEqual(vecCheck.z, vecReturned.z, VECTOR_COMPONENT_ACCURACY,
489 "TestllSetPrimitiveParams " + msg + " vector check fail on z component");
490 }
491
492 [Test]
493 public void TestllVecNorm() 257 public void TestllVecNorm()
494 { 258 {
495 TestHelpers.InMethod(); 259 TestHelpers.InMethod();
diff --git a/OpenSim/Tests/Common/Helpers/EntityTransferHelpers.cs b/OpenSim/Tests/Common/Helpers/EntityTransferHelpers.cs
index ff6608d..52a17e7 100644
--- a/OpenSim/Tests/Common/Helpers/EntityTransferHelpers.cs
+++ b/OpenSim/Tests/Common/Helpers/EntityTransferHelpers.cs
@@ -84,7 +84,7 @@ namespace OpenSim.Tests.Common
84 84
85 TestClient neighbourTc = new TestClient(newAgent, neighbourScene); 85 TestClient neighbourTc = new TestClient(newAgent, neighbourScene);
86 neighbourTcs.Add(neighbourTc); 86 neighbourTcs.Add(neighbourTc);
87 neighbourScene.AddNewClient(neighbourTc, PresenceType.User); 87 neighbourScene.AddNewAgent(neighbourTc, PresenceType.User);
88 }; 88 };
89 } 89 }
90 90
@@ -119,7 +119,7 @@ namespace OpenSim.Tests.Common
119 119
120 TestClient destinationClient = new TestClient(newAgent, destinationScene); 120 TestClient destinationClient = new TestClient(newAgent, destinationScene);
121 destinationClients.Add(destinationClient); 121 destinationClients.Add(destinationClient);
122 destinationScene.AddNewClient(destinationClient, PresenceType.User); 122 destinationScene.AddNewAgent(destinationClient, PresenceType.User);
123 123
124 ThreadPool.UnsafeQueueUserWorkItem(o => destinationClient.CompleteMovement(), null); 124 ThreadPool.UnsafeQueueUserWorkItem(o => destinationClient.CompleteMovement(), null);
125 }; 125 };
diff --git a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs
index d9bb85e..4cdfe98 100644
--- a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs
+++ b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs
@@ -548,7 +548,7 @@ namespace OpenSim.Tests.Common
548 Console.WriteLine("NewUserConnection failed: " + reason); 548 Console.WriteLine("NewUserConnection failed: " + reason);
549 549
550 // Stage 2: add the new client as a child agent to the scene 550 // Stage 2: add the new client as a child agent to the scene
551 scene.AddNewClient(client, PresenceType.User); 551 scene.AddNewAgent(client, PresenceType.User);
552 552
553 return scene.GetScenePresence(client.AgentId); 553 return scene.GetScenePresence(client.AgentId);
554 } 554 }