aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS.txt3
-rw-r--r--OpenSim/ApplicationPlugins/Rest/Inventory/RestAppearanceServices.cs14
-rw-r--r--OpenSim/ApplicationPlugins/Rest/Inventory/tests/Remote.cs4
-rw-r--r--OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs45
-rw-r--r--OpenSim/Data/MSSQL/MSSQLMigration.cs2
-rw-r--r--OpenSim/Data/MSSQL/MSSQLSimulationData.cs15
-rw-r--r--OpenSim/Data/MSSQL/MSSQLXInventoryData.cs2
-rw-r--r--OpenSim/Data/MySQL/MySQLAssetData.cs9
-rw-r--r--OpenSim/Data/MySQL/MySQLSimulationData.cs17
-rw-r--r--OpenSim/Data/Null/NullRegionData.cs4
-rw-r--r--OpenSim/Data/SQLite/Resources/XInventoryStore.migrations4
-rw-r--r--OpenSim/Data/SQLite/SQLiteAssetData.cs8
-rw-r--r--OpenSim/Data/SQLite/SQLiteAuthenticationData.cs7
-rw-r--r--OpenSim/Data/SQLite/SQLiteEstateData.cs8
-rw-r--r--OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs10
-rw-r--r--OpenSim/Data/SQLite/SQLiteSimulationData.cs8
-rw-r--r--OpenSim/Data/SQLite/SQLiteXInventoryData.cs2
-rw-r--r--OpenSim/Data/Tests/AssetTests.cs6
-rw-r--r--OpenSim/Data/Tests/EstateTests.cs16
-rw-r--r--OpenSim/Data/Tests/InventoryTests.cs26
-rw-r--r--OpenSim/Data/Tests/RegionTests.cs46
-rw-r--r--OpenSim/Framework/AgentCircuitData.cs11
-rw-r--r--OpenSim/Framework/AvatarAppearance.cs76
-rw-r--r--OpenSim/Framework/AvatarAttachment.cs2
-rw-r--r--OpenSim/Framework/ChildAgentDataUpdate.cs4
-rw-r--r--OpenSim/Framework/IClientAPI.cs6
-rw-r--r--OpenSim/Framework/IScene.cs16
-rw-r--r--OpenSim/Framework/ISceneEntity.cs1
-rw-r--r--OpenSim/Framework/InventoryFolderImpl.cs8
-rw-r--r--OpenSim/Framework/PacketPool.cs17
-rw-r--r--OpenSim/Framework/PresenceType.cs (renamed from OpenSim/Framework/UndoStack.cs)77
-rw-r--r--OpenSim/Framework/PrimitiveBaseShape.cs61
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs112
-rw-r--r--OpenSim/Framework/Tests/AgentCircuitDataTest.cs2
-rw-r--r--OpenSim/Framework/Tests/AgentCircuitManagerTests.cs4
-rw-r--r--OpenSim/Framework/Tests/UtilTest.cs8
-rw-r--r--OpenSim/Framework/Util.cs40
-rw-r--r--OpenSim/Framework/WebUtil.cs24
-rw-r--r--OpenSim/Region/Application/Application.cs4
-rw-r--r--OpenSim/Region/Application/OpenSim.cs18
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs22
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs10
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs9
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs6
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs8
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs12
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs128
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs172
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs7
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs128
-rw-r--r--OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs16
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs513
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs274
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs222
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs120
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs12
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs10
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs22
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs36
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs20
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs71
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs868
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs14
-rw-r--r--OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs12
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs1
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs45
-rw-r--r--OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs87
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs25
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs17
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs20
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs81
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs8
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs10
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs1
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Access/AccessModule.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs18
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs50
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs52
-rw-r--r--OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs50
-rw-r--r--OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs12
-rw-r--r--OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs5
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs12
-rw-r--r--OpenSim/Region/CoreModules/World/Sound/SoundModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs11
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs221
-rw-r--r--OpenSim/Region/DataSnapshot/ObjectSnapshot.cs83
-rw-r--r--OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs6
-rw-r--r--OpenSim/Region/Examples/SimpleModule/RegionModule.cs2
-rw-r--r--OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs62
-rw-r--r--OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs25
-rw-r--r--OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs56
-rw-r--r--OpenSim/Region/Framework/Interfaces/INPCModule.cs73
-rw-r--r--OpenSim/Region/Framework/Interfaces/IScenePresence.cs88
-rw-r--r--OpenSim/Region/Framework/Interfaces/ISimulatorFeaturesModule.cs43
-rw-r--r--OpenSim/Region/Framework/Interfaces/IUserManagement.cs37
-rw-r--r--OpenSim/Region/Framework/Interfaces/IWorldComm.cs20
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs14
-rw-r--r--OpenSim/Region/Framework/Scenes/AsyncInventorySender.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/EntityBase.cs7
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs11
-rw-r--r--OpenSim/Region/Framework/Scenes/Prioritizer.cs12
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs45
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs308
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneBase.cs14
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs92
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneManager.cs233
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs796
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs952
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs11
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs577
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneViewer.cs5
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs53
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs172
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs22
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs16
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs28
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs104
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs66
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs (renamed from OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs)224
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs (renamed from OpenSim/Region/Framework/Scenes/Tests/StandaloneTeleportTests.cs)14
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs18
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs16
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/UndoState.cs245
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs8
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs6
-rw-r--r--OpenSim/Region/OptionalModules/Framework/Monitoring/MonitorServicesModule.cs119
-rwxr-xr-xOpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs277
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs5
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs4
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs16
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs187
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs108
-rw-r--r--OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs1
-rw-r--r--OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs12
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs451
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs951
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs68
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs1357
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs860
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs257
-rw-r--r--OpenSim/Region/Physics/ConvexDecompositionDotNet/CTri.cs341
-rw-r--r--OpenSim/Region/Physics/ConvexDecompositionDotNet/Concavity.cs233
-rw-r--r--OpenSim/Region/Physics/ConvexDecompositionDotNet/ConvexBuilder.cs411
-rw-r--r--OpenSim/Region/Physics/ConvexDecompositionDotNet/ConvexDecomposition.cs200
-rw-r--r--OpenSim/Region/Physics/ConvexDecompositionDotNet/ConvexResult.cs74
-rw-r--r--OpenSim/Region/Physics/ConvexDecompositionDotNet/HullClasses.cs171
-rw-r--r--OpenSim/Region/Physics/ConvexDecompositionDotNet/HullTriangle.cs99
-rw-r--r--OpenSim/Region/Physics/ConvexDecompositionDotNet/HullUtils.cs1868
-rw-r--r--OpenSim/Region/Physics/ConvexDecompositionDotNet/LICENSE.txt28
-rw-r--r--OpenSim/Region/Physics/ConvexDecompositionDotNet/Plane.cs99
-rw-r--r--OpenSim/Region/Physics/ConvexDecompositionDotNet/PlaneTri.cs211
-rw-r--r--OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs36
-rw-r--r--OpenSim/Region/Physics/ConvexDecompositionDotNet/Quaternion.cs209
-rw-r--r--OpenSim/Region/Physics/ConvexDecompositionDotNet/README.txt7
-rw-r--r--OpenSim/Region/Physics/ConvexDecompositionDotNet/SplitPlane.cs265
-rw-r--r--OpenSim/Region/Physics/ConvexDecompositionDotNet/VertexLookup.cs70
-rw-r--r--OpenSim/Region/Physics/ConvexDecompositionDotNet/float2.cs70
-rw-r--r--OpenSim/Region/Physics/ConvexDecompositionDotNet/float3.cs444
-rw-r--r--OpenSim/Region/Physics/ConvexDecompositionDotNet/float3x3.cs195
-rw-r--r--OpenSim/Region/Physics/ConvexDecompositionDotNet/float4.cs170
-rw-r--r--OpenSim/Region/Physics/ConvexDecompositionDotNet/float4x4.cs284
-rw-r--r--OpenSim/Region/Physics/ConvexDecompositionDotNet/int3.cs128
-rw-r--r--OpenSim/Region/Physics/ConvexDecompositionDotNet/int4.cs66
-rw-r--r--OpenSim/Region/Physics/Manager/IMesher.cs11
-rwxr-xr-xOpenSim/Region/Physics/Manager/IPhysicsParameters.cs73
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsScene.cs39
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs727
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODECharacter.cs18
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs303
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs92
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdeScene.cs834
-rw-r--r--OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs5
-rw-r--r--OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs11
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs601
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs5
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs593
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs13
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs6
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs13
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs5
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs45
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs6
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs31
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs232
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs229
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/EventManager.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs9
-rw-r--r--OpenSim/Server/Handlers/Authorization/AuthorizationServerPostHandler.cs2
-rw-r--r--OpenSim/Services/AssetService/AssetService.cs17
-rw-r--r--OpenSim/Services/AuthenticationService/WebkeyOrPasswordAuthenticationService.cs4
-rw-r--r--OpenSim/Services/AuthorizationService/AuthorizationService.cs5
-rw-r--r--OpenSim/Services/AvatarService/AvatarService.cs30
-rw-r--r--OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs56
-rw-r--r--OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs2
-rw-r--r--OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs71
-rw-r--r--OpenSim/Services/Connectors/MapImage/MapImageServiceConnector.cs1
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs2
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs4
-rw-r--r--OpenSim/Services/GridService/GridService.cs38
-rw-r--r--OpenSim/Services/HypergridService/HGInstantMessageService.cs17
-rw-r--r--OpenSim/Services/Interfaces/IAssetService.cs8
-rw-r--r--OpenSim/Services/Interfaces/IAuthorizationService.cs32
-rw-r--r--OpenSim/Services/Interfaces/IAvatarService.cs4
-rw-r--r--OpenSim/Services/Interfaces/IGridService.cs6
-rw-r--r--OpenSim/Services/InventoryService/LibraryService.cs9
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginResponse.cs19
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginService.cs8
-rw-r--r--OpenSim/Tests/Common/Helpers/AssetHelpers.cs6
-rw-r--r--OpenSim/Tests/Common/Helpers/SceneHelpers.cs (renamed from OpenSim/Tests/Common/Helpers/SceneSetupHelpers.cs)51
-rw-r--r--OpenSim/Tests/Common/Helpers/TaskInventoryHelpers.cs2
-rw-r--r--OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs8
-rw-r--r--OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs37
-rw-r--r--OpenSim/Tests/Common/Mock/TestClient.cs13
-rw-r--r--OpenSim/Tests/Common/TestHelpers.cs (renamed from OpenSim/Tests/Common/TestHelper.cs)2
-rw-r--r--Prebuild/src/Core/Targets/.NAntTarget.cs.swpbin49152 -> 0 bytes
-rw-r--r--Prebuild/src/Core/Targets/NAntTarget.cs5
-rw-r--r--ThirdPartyLicenses/ConvexDecompositionDotNet.txt28
-rwxr-xr-xbin/BulletSim-x86_64.dllbin0 -> 784384 bytes
-rwxr-xr-xbin/BulletSim.dllbin0 -> 676352 bytes
-rwxr-xr-xbin/HttpServer.dllbin102400 -> 0 bytes
-rw-r--r--bin/MXP.pdbbin382464 -> 0 bytes
-rw-r--r--bin/OpenSim.Region.OptionalModules.Tests.dll.config33
-rw-r--r--bin/OpenSim.ini.example43
-rw-r--r--bin/OpenSimDefaults.ini106
-rwxr-xr-xbin/Physics/OpenSim.Region.Physics.BulletSPlugin.dll.config6
-rwxr-xr-xbin/Prebuild.exebin228352 -> 228352 bytes
-rw-r--r--bin/Robust.HG.ini.example3
-rw-r--r--bin/Robust.ini.example3
-rw-r--r--bin/config-include/GridCommon.ini.example37
-rw-r--r--bin/config-include/StandaloneCommon.ini.example46
-rw-r--r--bin/inventory/AnimationsLibrary/AnimationsLibraryItems.xml6
-rw-r--r--bin/inventory/BodyPartsLibrary/BodyPartsLibraryItems.xml33
-rw-r--r--bin/inventory/ClothingLibrary/ClothingLibraryItems.xml14
-rw-r--r--bin/inventory/GesturesLibrary/GesturesLibraryItems.xml80
-rw-r--r--bin/inventory/LandmarksLibrary/LandmarksLibraryItems.xml4
-rw-r--r--bin/inventory/NotecardsLibrary/NotecardsLibraryItems.xml14
-rw-r--r--bin/inventory/ObjectsLibrary/ObjectsLibraryItems.xml4
-rw-r--r--bin/inventory/OpenSimLibrary/OpenSimLibrary.xml4
-rw-r--r--bin/inventory/PhotosLibrary/PhotosLibraryItems.xml4
-rw-r--r--bin/inventory/ScriptsLibrary/ScriptsLibraryItems.xml223
-rw-r--r--bin/inventory/SoundsLibrary/SoundsLibraryItems.xml4
-rw-r--r--bin/inventory/TexturesLibrary/TexturesLibraryItems.xml274
-rwxr-xr-xbin/libBulletSim-x86_64.sobin0 -> 2005396 bytes
-rwxr-xr-xbin/libBulletSim.sobin0 -> 1857855 bytes
-rw-r--r--bin/protobuf-net.pdbbin331264 -> 0 bytes
-rw-r--r--prebuild.xml91
267 files changed, 19194 insertions, 5446 deletions
diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt
index 5c1bdf1..2fe8b46 100644
--- a/CONTRIBUTORS.txt
+++ b/CONTRIBUTORS.txt
@@ -14,6 +14,7 @@ people that make the day to day of OpenSim happen.
14* Marck 14* Marck
15* Mic Bowman (Intel) 15* Mic Bowman (Intel)
16* BlueWall (James Hughes) 16* BlueWall (James Hughes)
17* Snoopy Pfeffer
17 18
18= Core Developers Following the White Rabbit = 19= Core Developers Following the White Rabbit =
19Core developers who have temporarily (we hope) gone chasing the white rabbit. 20Core developers who have temporarily (we hope) gone chasing the white rabbit.
@@ -112,6 +113,7 @@ what it is today.
112* mpallari 113* mpallari
113* MrMonkE 114* MrMonkE
114* Nebadon Izumi (Michael Cerquoni - http://OSgrid.org) 115* Nebadon Izumi (Michael Cerquoni - http://OSgrid.org)
116* Neil Canham
115* nornalbion 117* nornalbion
116* Omar Vera Ustariz (IBM) 118* Omar Vera Ustariz (IBM)
117* openlifegrid.com 119* openlifegrid.com
@@ -128,7 +130,6 @@ what it is today.
128* Salahzar Stenvaag 130* Salahzar Stenvaag
129* sempuki 131* sempuki
130* SignpostMarv 132* SignpostMarv
131* Snoopy
132* Strawberry Fride 133* Strawberry Fride
133* tglion 134* tglion
134* tlaukkan/Tommil (Tommi S. E. Laukkanen, Bubble Cloud) 135* tlaukkan/Tommil (Tommi S. E. Laukkanen, Bubble Cloud)
diff --git a/OpenSim/ApplicationPlugins/Rest/Inventory/RestAppearanceServices.cs b/OpenSim/ApplicationPlugins/Rest/Inventory/RestAppearanceServices.cs
index 0188eb7..3cda984 100644
--- a/OpenSim/ApplicationPlugins/Rest/Inventory/RestAppearanceServices.cs
+++ b/OpenSim/ApplicationPlugins/Rest/Inventory/RestAppearanceServices.cs
@@ -488,11 +488,11 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
488 rdata.userAppearance.AvatarHeight = (float) Convert.ToDouble(xml.Value); 488 rdata.userAppearance.AvatarHeight = (float) Convert.ToDouble(xml.Value);
489 indata = true; 489 indata = true;
490 } 490 }
491 if (xml.MoveToAttribute("Owner")) 491// if (xml.MoveToAttribute("Owner"))
492 { 492// {
493 rdata.userAppearance.Owner = (UUID)xml.Value; 493// rdata.userAppearance.Owner = (UUID)xml.Value;
494 indata = true; 494// indata = true;
495 } 495// }
496 if (xml.MoveToAttribute("Serial")) 496 if (xml.MoveToAttribute("Serial"))
497 { 497 {
498 rdata.userAppearance.Serial = Convert.ToInt32(xml.Value); 498 rdata.userAppearance.Serial = Convert.ToInt32(xml.Value);
@@ -747,8 +747,8 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
747 rdata.writer.WriteStartElement("Appearance"); 747 rdata.writer.WriteStartElement("Appearance");
748 748
749 rdata.writer.WriteAttributeString("Height", rdata.userAppearance.AvatarHeight.ToString()); 749 rdata.writer.WriteAttributeString("Height", rdata.userAppearance.AvatarHeight.ToString());
750 if (rdata.userAppearance.Owner != UUID.Zero) 750// if (rdata.userAppearance.Owner != UUID.Zero)
751 rdata.writer.WriteAttributeString("Owner", rdata.userAppearance.Owner.ToString()); 751// rdata.writer.WriteAttributeString("Owner", rdata.userAppearance.Owner.ToString());
752 rdata.writer.WriteAttributeString("Serial", rdata.userAppearance.Serial.ToString()); 752 rdata.writer.WriteAttributeString("Serial", rdata.userAppearance.Serial.ToString());
753 753
754/* 754/*
diff --git a/OpenSim/ApplicationPlugins/Rest/Inventory/tests/Remote.cs b/OpenSim/ApplicationPlugins/Rest/Inventory/tests/Remote.cs
index 4333ef1..1023108 100644
--- a/OpenSim/ApplicationPlugins/Rest/Inventory/tests/Remote.cs
+++ b/OpenSim/ApplicationPlugins/Rest/Inventory/tests/Remote.cs
@@ -168,8 +168,8 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests
168 float x = Convert.ToSingle(rdata.Parameters[PARM_MOVE_X]); 168 float x = Convert.ToSingle(rdata.Parameters[PARM_MOVE_X]);
169 float y = Convert.ToSingle(rdata.Parameters[PARM_MOVE_Y]); 169 float y = Convert.ToSingle(rdata.Parameters[PARM_MOVE_Y]);
170 float z = Convert.ToSingle(rdata.Parameters[PARM_MOVE_Z]); 170 float z = Convert.ToSingle(rdata.Parameters[PARM_MOVE_Z]);
171 Vector3 vector = new Vector3(x,y,z); 171 Vector3 vector = new Vector3(x, y, z);
172 presence.DoAutoPilot(0,vector,presence.ControllingClient); 172 presence.MoveToTarget(vector, false);
173 } 173 }
174 catch (Exception e) 174 catch (Exception e)
175 { 175 {
diff --git a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs
index c60abb1..720640e 100644
--- a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs
+++ b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs
@@ -57,7 +57,6 @@ namespace OpenSim.Capabilities.Handlers
57 57
58 public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap) 58 public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap)
59 { 59 {
60
61 Hashtable responsedata = new Hashtable(); 60 Hashtable responsedata = new Hashtable();
62 responsedata["int_response_code"] = 400; //501; //410; //404; 61 responsedata["int_response_code"] = 400; //501; //410; //404;
63 responsedata["content_type"] = "text/plain"; 62 responsedata["content_type"] = "text/plain";
@@ -69,7 +68,6 @@ namespace OpenSim.Capabilities.Handlers
69 if (request.ContainsKey("mesh_id")) 68 if (request.ContainsKey("mesh_id"))
70 meshStr = request["mesh_id"].ToString(); 69 meshStr = request["mesh_id"].ToString();
71 70
72
73 UUID meshID = UUID.Zero; 71 UUID meshID = UUID.Zero;
74 if (!String.IsNullOrEmpty(meshStr) && UUID.TryParse(meshStr, out meshID)) 72 if (!String.IsNullOrEmpty(meshStr) && UUID.TryParse(meshStr, out meshID))
75 { 73 {
@@ -82,12 +80,11 @@ namespace OpenSim.Capabilities.Handlers
82 return responsedata; 80 return responsedata;
83 } 81 }
84 82
85 AssetBase mesh; 83 AssetBase mesh = m_assetService.Get(meshID.ToString());
86 // Only try to fetch locally cached textures. Misses are redirected 84
87 mesh = m_assetService.GetCached(meshID.ToString());
88 if (mesh != null) 85 if (mesh != null)
89 { 86 {
90 if (mesh.Type == (SByte)AssetType.Mesh) 87 if (mesh.Type == (SByte)AssetType.Mesh)
91 { 88 {
92 responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); 89 responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
93 responsedata["content_type"] = "application/vnd.ll.mesh"; 90 responsedata["content_type"] = "application/vnd.ll.mesh";
@@ -105,39 +102,15 @@ namespace OpenSim.Capabilities.Handlers
105 } 102 }
106 else 103 else
107 { 104 {
108 mesh = m_assetService.Get(meshID.ToString()); 105 responsedata["int_response_code"] = 404; //501; //410; //404;
109 if (mesh != null) 106 responsedata["content_type"] = "text/plain";
110 { 107 responsedata["keepalive"] = false;
111 if (mesh.Type == (SByte)AssetType.Mesh) 108 responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!";
112 { 109 return responsedata;
113 responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
114 responsedata["content_type"] = "application/vnd.ll.mesh";
115 responsedata["int_response_code"] = 200;
116 }
117 // Optionally add additional mesh types here
118 else
119 {
120 responsedata["int_response_code"] = 404; //501; //410; //404;
121 responsedata["content_type"] = "text/plain";
122 responsedata["keepalive"] = false;
123 responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh.";
124 return responsedata;
125 }
126 }
127
128 else
129 {
130 responsedata["int_response_code"] = 404; //501; //410; //404;
131 responsedata["content_type"] = "text/plain";
132 responsedata["keepalive"] = false;
133 responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!";
134 return responsedata;
135 }
136 } 110 }
137
138 } 111 }
139 112
140 return responsedata; 113 return responsedata;
141 } 114 }
142 } 115 }
143} 116} \ No newline at end of file
diff --git a/OpenSim/Data/MSSQL/MSSQLMigration.cs b/OpenSim/Data/MSSQL/MSSQLMigration.cs
index 1aa96c7..c2fecef 100644
--- a/OpenSim/Data/MSSQL/MSSQLMigration.cs
+++ b/OpenSim/Data/MSSQL/MSSQLMigration.cs
@@ -88,7 +88,7 @@ namespace OpenSim.Data.MSSQL
88 cmd.ExecuteNonQuery(); 88 cmd.ExecuteNonQuery();
89 } 89 }
90 } 90 }
91 catch (Exception ex) 91 catch (Exception)
92 { 92 {
93 throw new Exception(sql); 93 throw new Exception(sql);
94 94
diff --git a/OpenSim/Data/MSSQL/MSSQLSimulationData.cs b/OpenSim/Data/MSSQL/MSSQLSimulationData.cs
index 78f80e1..bb59bba 100644
--- a/OpenSim/Data/MSSQL/MSSQLSimulationData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLSimulationData.cs
@@ -84,21 +84,6 @@ namespace OpenSim.Data.MSSQL
84 //New Migration settings 84 //New Migration settings
85 Migration m = new Migration(conn, Assembly, "RegionStore"); 85 Migration m = new Migration(conn, Assembly, "RegionStore");
86 m.Update(); 86 m.Update();
87
88 // Clean dropped attachments
89 //
90 try
91 {
92 using (SqlCommand cmd = conn.CreateCommand())
93 {
94 cmd.CommandText = "delete from prims where prims.UUID in (select UUID from primshapes where PCode = 9 and State <> 0); delete from primshapes where PCode = 9 and State <> 0";
95 cmd.ExecuteNonQuery();
96 }
97 }
98 catch (Exception ex)
99 {
100 _Log.Error("[REGION DB]: Error cleaning up dropped attachments: " + ex.Message);
101 }
102 } 87 }
103 } 88 }
104 89
diff --git a/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs b/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs
index 1f6994d..a1069c6 100644
--- a/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs
@@ -191,7 +191,7 @@ namespace OpenSim.Data.MSSQL
191 { 191 {
192 cmd.ExecuteNonQuery(); 192 cmd.ExecuteNonQuery();
193 } 193 }
194 catch (Exception e) 194 catch (Exception)
195 { 195 {
196 return false; 196 return false;
197 } 197 }
diff --git a/OpenSim/Data/MySQL/MySQLAssetData.cs b/OpenSim/Data/MySQL/MySQLAssetData.cs
index 94e2da4..a22dc0a 100644
--- a/OpenSim/Data/MySQL/MySQLAssetData.cs
+++ b/OpenSim/Data/MySQL/MySQLAssetData.cs
@@ -253,12 +253,14 @@ namespace OpenSim.Data.MySQL
253 } 253 }
254 254
255 /// <summary> 255 /// <summary>
256 /// check if the asset UUID exist in database 256 /// Check if the asset exists in the database
257 /// </summary> 257 /// </summary>
258 /// <param name="uuid">The asset UUID</param> 258 /// <param name="uuid">The asset UUID</param>
259 /// <returns>true if exist.</returns> 259 /// <returns>true if it exists, false otherwise.</returns>
260 override public bool ExistsAsset(UUID uuid) 260 override public bool ExistsAsset(UUID uuid)
261 { 261 {
262// m_log.DebugFormat("[ASSETS DB]: Checking for asset {0}", uuid);
263
262 bool assetExists = false; 264 bool assetExists = false;
263 265
264 lock (m_dbLock) 266 lock (m_dbLock)
@@ -275,7 +277,10 @@ namespace OpenSim.Data.MySQL
275 using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) 277 using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
276 { 278 {
277 if (dbReader.Read()) 279 if (dbReader.Read())
280 {
281// m_log.DebugFormat("[ASSETS DB]: Found asset {0}", uuid);
278 assetExists = true; 282 assetExists = true;
283 }
279 } 284 }
280 } 285 }
281 catch (Exception e) 286 catch (Exception e)
diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs
index cdaf5b7..b9228d1 100644
--- a/OpenSim/Data/MySQL/MySQLSimulationData.cs
+++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs
@@ -78,23 +78,6 @@ namespace OpenSim.Data.MySQL
78 // 78 //
79 Migration m = new Migration(dbcon, Assembly, "RegionStore"); 79 Migration m = new Migration(dbcon, Assembly, "RegionStore");
80 m.Update(); 80 m.Update();
81
82 // Clean dropped attachments
83 //
84 try
85 {
86 using (MySqlCommand cmd = dbcon.CreateCommand())
87 {
88 cmd.CommandText = "delete from prims, primshapes using prims " +
89 "left join primshapes on prims.uuid = primshapes.uuid " +
90 "where PCode = 9 and State <> 0";
91 ExecuteNonQuery(cmd);
92 }
93 }
94 catch (MySqlException ex)
95 {
96 m_log.Error("[REGION DB]: Error cleaning up dropped attachments: " + ex.Message);
97 }
98 } 81 }
99 } 82 }
100 83
diff --git a/OpenSim/Data/Null/NullRegionData.cs b/OpenSim/Data/Null/NullRegionData.cs
index 53e5207..9d09af7 100644
--- a/OpenSim/Data/Null/NullRegionData.cs
+++ b/OpenSim/Data/Null/NullRegionData.cs
@@ -40,7 +40,7 @@ namespace OpenSim.Data.Null
40 { 40 {
41 private static NullRegionData Instance = null; 41 private static NullRegionData Instance = null;
42 42
43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 43// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
44 44
45 Dictionary<UUID, RegionData> m_regionData = new Dictionary<UUID, RegionData>(); 45 Dictionary<UUID, RegionData> m_regionData = new Dictionary<UUID, RegionData>();
46 46
@@ -97,7 +97,7 @@ namespace OpenSim.Data.Null
97 97
98 foreach (RegionData r in m_regionData.Values) 98 foreach (RegionData r in m_regionData.Values)
99 { 99 {
100 m_log.DebugFormat("[NULL REGION DATA]: comparing {0} to {1}", cleanName, r.RegionName.ToLower()); 100// m_log.DebugFormat("[NULL REGION DATA]: comparing {0} to {1}", cleanName, r.RegionName.ToLower());
101 if (queryMatch(r.RegionName.ToLower())) 101 if (queryMatch(r.RegionName.ToLower()))
102 ret.Add(r); 102 ret.Add(r);
103 } 103 }
diff --git a/OpenSim/Data/SQLite/Resources/XInventoryStore.migrations b/OpenSim/Data/SQLite/Resources/XInventoryStore.migrations
index d5b3019..de44982 100644
--- a/OpenSim/Data/SQLite/Resources/XInventoryStore.migrations
+++ b/OpenSim/Data/SQLite/Resources/XInventoryStore.migrations
@@ -41,11 +41,9 @@ COMMIT;
41 41
42:VERSION 2 42:VERSION 2
43 43
44ATTACH 'inventoryStore.db' AS old;
45
46BEGIN TRANSACTION; 44BEGIN TRANSACTION;
47 45
48INSERT INTO inventoryfolders (folderName, type, version, folderID, agentID, parentFolderID) SELECT `name` AS folderName, `type` AS type, `version` AS version, `UUID` AS folderID, `agentID` AS agentID, `parentID` AS parentFolderID from old.inventoryfolders; 46INSERT INTO inventoryfolders (folderName, type, version, folderID, agentID, parentFolderID) SELECT `name` AS folderName, `type` AS type, `version` AS version, `UUID` AS folderID, `agentID` AS agentID, `parentID` AS parentFolderID from old.inventoryfolders;
49INSERT INTO inventoryitems (assetID, assetType, inventoryName, inventoryDescription, inventoryNextPermissions, inventoryCurrentPermissions, invType, creatorID, inventoryBasePermissions, inventoryEveryOnePermissions, salePrice, saleType, creationDate, groupID, groupOwned, flags, inventoryID, parentFolderID, avatarID, inventoryGroupPermissions) SELECT `assetID`, `assetType` AS assetType, `inventoryName` AS inventoryName, `inventoryDescription` AS inventoryDescription, `inventoryNextPermissions` AS inventoryNextPermissions, `inventoryCurrentPermissions` AS inventoryCurrentPermissions, `invType` AS invType, `creatorsID` AS creatorID, `inventoryBasePermissions` AS inventoryBasePermissions, `inventoryEveryOnePermissions` AS inventoryEveryOnePermissions, `salePrice` AS salePrice, `saleType` AS saleType, `creationDate` AS creationDate, `groupID` AS groupID, `groupOwned` AS groupOwned, `flags` AS flags, `UUID` AS inventoryID, `parentFolderID` AS parentFolderID, `avatarID` AS avatarID, `inventoryGroupPermissions` AS inventoryGroupPermissions FROM old.inventoryitems; 47INSERT INTO inventoryitems (assetID, assetType, inventoryName, inventoryDescription, inventoryNextPermissions, inventoryCurrentPermissions, invType, creatorID, inventoryBasePermissions, inventoryEveryOnePermissions, salePrice, saleType, creationDate, groupID, groupOwned, flags, inventoryID, parentFolderID, avatarID, inventoryGroupPermissions) SELECT `assetID`, `assetType` AS assetType, `inventoryName` AS inventoryName, `inventoryDescription` AS inventoryDescription, `inventoryNextPermissions` AS inventoryNextPermissions, `inventoryCurrentPermissions` AS inventoryCurrentPermissions, `invType` AS invType, `creatorsID` AS creatorID, `inventoryBasePermissions` AS inventoryBasePermissions, `inventoryEveryOnePermissions` AS inventoryEveryOnePermissions, `salePrice` AS salePrice, `saleType` AS saleType, `creationDate` AS creationDate, `groupID` AS groupID, `groupOwned` AS groupOwned, `flags` AS flags, `UUID` AS inventoryID, `parentFolderID` AS parentFolderID, `avatarID` AS avatarID, `inventoryGroupPermissions` AS inventoryGroupPermissions FROM old.inventoryitems;
50 48
51COMMIT; \ No newline at end of file 49COMMIT;
diff --git a/OpenSim/Data/SQLite/SQLiteAssetData.cs b/OpenSim/Data/SQLite/SQLiteAssetData.cs
index 9a4eb76..723544a 100644
--- a/OpenSim/Data/SQLite/SQLiteAssetData.cs
+++ b/OpenSim/Data/SQLite/SQLiteAssetData.cs
@@ -57,6 +57,11 @@ namespace OpenSim.Data.SQLite
57 57
58 private SqliteConnection m_conn; 58 private SqliteConnection m_conn;
59 59
60 protected virtual Assembly Assembly
61 {
62 get { return GetType().Assembly; }
63 }
64
60 override public void Dispose() 65 override public void Dispose()
61 { 66 {
62 if (m_conn != null) 67 if (m_conn != null)
@@ -83,8 +88,7 @@ namespace OpenSim.Data.SQLite
83 m_conn = new SqliteConnection(dbconnect); 88 m_conn = new SqliteConnection(dbconnect);
84 m_conn.Open(); 89 m_conn.Open();
85 90
86 Assembly assem = GetType().Assembly; 91 Migration m = new Migration(m_conn, Assembly, "AssetStore");
87 Migration m = new Migration(m_conn, assem, "AssetStore");
88 m.Update(); 92 m.Update();
89 93
90 return; 94 return;
diff --git a/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs b/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs
index c3b65bb..f51aa28 100644
--- a/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs
+++ b/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs
@@ -53,6 +53,11 @@ namespace OpenSim.Data.SQLite
53 protected static SqliteConnection m_Connection; 53 protected static SqliteConnection m_Connection;
54 private static bool m_initialized = false; 54 private static bool m_initialized = false;
55 55
56 protected virtual Assembly Assembly
57 {
58 get { return GetType().Assembly; }
59 }
60
56 public SQLiteAuthenticationData(string connectionString, string realm) 61 public SQLiteAuthenticationData(string connectionString, string realm)
57 : base(connectionString) 62 : base(connectionString)
58 { 63 {
@@ -63,7 +68,7 @@ namespace OpenSim.Data.SQLite
63 m_Connection = new SqliteConnection(connectionString); 68 m_Connection = new SqliteConnection(connectionString);
64 m_Connection.Open(); 69 m_Connection.Open();
65 70
66 Migration m = new Migration(m_Connection, GetType().Assembly, "AuthStore"); 71 Migration m = new Migration(m_Connection, Assembly, "AuthStore");
67 m.Update(); 72 m.Update();
68 73
69 m_initialized = true; 74 m_initialized = true;
diff --git a/OpenSim/Data/SQLite/SQLiteEstateData.cs b/OpenSim/Data/SQLite/SQLiteEstateData.cs
index 2f05a6e..65719a6 100644
--- a/OpenSim/Data/SQLite/SQLiteEstateData.cs
+++ b/OpenSim/Data/SQLite/SQLiteEstateData.cs
@@ -53,6 +53,11 @@ namespace OpenSim.Data.SQLite
53 private Dictionary<string, FieldInfo> m_FieldMap = 53 private Dictionary<string, FieldInfo> m_FieldMap =
54 new Dictionary<string, FieldInfo>(); 54 new Dictionary<string, FieldInfo>();
55 55
56 protected virtual Assembly Assembly
57 {
58 get { return GetType().Assembly; }
59 }
60
56 public SQLiteEstateStore() 61 public SQLiteEstateStore()
57 { 62 {
58 } 63 }
@@ -71,8 +76,7 @@ namespace OpenSim.Data.SQLite
71 m_connection = new SqliteConnection(m_connectionString); 76 m_connection = new SqliteConnection(m_connectionString);
72 m_connection.Open(); 77 m_connection.Open();
73 78
74 Assembly assem = GetType().Assembly; 79 Migration m = new Migration(m_connection, Assembly, "EstateStore");
75 Migration m = new Migration(m_connection, assem, "EstateStore");
76 m.Update(); 80 m.Update();
77 81
78 //m_connection.Close(); 82 //m_connection.Close();
diff --git a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs
index 0d7ae1f..4f977a8 100644
--- a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs
+++ b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs
@@ -55,6 +55,11 @@ namespace OpenSim.Data.SQLite
55 protected static SqliteConnection m_Connection; 55 protected static SqliteConnection m_Connection;
56 private static bool m_initialized; 56 private static bool m_initialized;
57 57
58 protected virtual Assembly Assembly
59 {
60 get { return GetType().Assembly; }
61 }
62
58 public SQLiteGenericTableHandler(string connectionString, 63 public SQLiteGenericTableHandler(string connectionString,
59 string realm, string storeName) : base(connectionString) 64 string realm, string storeName) : base(connectionString)
60 { 65 {
@@ -68,13 +73,12 @@ namespace OpenSim.Data.SQLite
68 73
69 if (storeName != String.Empty) 74 if (storeName != String.Empty)
70 { 75 {
71 Assembly assem = GetType().Assembly;
72 //SqliteConnection newConnection = 76 //SqliteConnection newConnection =
73 // (SqliteConnection)((ICloneable)m_Connection).Clone(); 77 // (SqliteConnection)((ICloneable)m_Connection).Clone();
74 //newConnection.Open(); 78 //newConnection.Open();
75 79
76 //Migration m = new Migration(newConnection, assem, storeName); 80 //Migration m = new Migration(newConnection, Assembly, storeName);
77 Migration m = new Migration(m_Connection, assem, storeName); 81 Migration m = new Migration(m_Connection, Assembly, storeName);
78 m.Update(); 82 m.Update();
79 //newConnection.Close(); 83 //newConnection.Close();
80 //newConnection.Dispose(); 84 //newConnection.Dispose();
diff --git a/OpenSim/Data/SQLite/SQLiteSimulationData.cs b/OpenSim/Data/SQLite/SQLiteSimulationData.cs
index 377c680..5618772 100644
--- a/OpenSim/Data/SQLite/SQLiteSimulationData.cs
+++ b/OpenSim/Data/SQLite/SQLiteSimulationData.cs
@@ -74,6 +74,11 @@ namespace OpenSim.Data.SQLite
74 74
75 private String m_connectionString; 75 private String m_connectionString;
76 76
77 protected virtual Assembly Assembly
78 {
79 get { return GetType().Assembly; }
80 }
81
77 public SQLiteSimulationData() 82 public SQLiteSimulationData()
78 { 83 {
79 } 84 }
@@ -132,8 +137,7 @@ namespace OpenSim.Data.SQLite
132 SqliteCommand regionSettingsSelectCmd = new SqliteCommand(regionSettingsSelect, m_conn); 137 SqliteCommand regionSettingsSelectCmd = new SqliteCommand(regionSettingsSelect, m_conn);
133 regionSettingsDa = new SqliteDataAdapter(regionSettingsSelectCmd); 138 regionSettingsDa = new SqliteDataAdapter(regionSettingsSelectCmd);
134 // This actually does the roll forward assembly stuff 139 // This actually does the roll forward assembly stuff
135 Assembly assem = GetType().Assembly; 140 Migration m = new Migration(m_conn, Assembly, "RegionStore");
136 Migration m = new Migration(m_conn, assem, "RegionStore");
137 m.Update(); 141 m.Update();
138 142
139 lock (ds) 143 lock (ds)
diff --git a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs
index 02edc30..16f9046 100644
--- a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs
+++ b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs
@@ -41,7 +41,7 @@ using OpenSim.Framework;
41namespace OpenSim.Data.SQLite 41namespace OpenSim.Data.SQLite
42{ 42{
43 /// <summary> 43 /// <summary>
44 /// A MySQL Interface for the Asset Server 44 /// A SQLite Interface for the Asset Server
45 /// </summary> 45 /// </summary>
46 public class SQLiteXInventoryData : IXInventoryData 46 public class SQLiteXInventoryData : IXInventoryData
47 { 47 {
diff --git a/OpenSim/Data/Tests/AssetTests.cs b/OpenSim/Data/Tests/AssetTests.cs
index b5ae244..1174e2f 100644
--- a/OpenSim/Data/Tests/AssetTests.cs
+++ b/OpenSim/Data/Tests/AssetTests.cs
@@ -106,7 +106,7 @@ namespace OpenSim.Data.Tests
106 [Test] 106 [Test]
107 public void T001_LoadEmpty() 107 public void T001_LoadEmpty()
108 { 108 {
109 TestHelper.InMethod(); 109 TestHelpers.InMethod();
110 110
111 Assert.That(m_db.ExistsAsset(uuid1), Is.False); 111 Assert.That(m_db.ExistsAsset(uuid1), Is.False);
112 Assert.That(m_db.ExistsAsset(uuid2), Is.False); 112 Assert.That(m_db.ExistsAsset(uuid2), Is.False);
@@ -116,7 +116,7 @@ namespace OpenSim.Data.Tests
116 [Test] 116 [Test]
117 public void T010_StoreReadVerifyAssets() 117 public void T010_StoreReadVerifyAssets()
118 { 118 {
119 TestHelper.InMethod(); 119 TestHelpers.InMethod();
120 120
121 AssetBase a1 = new AssetBase(uuid1, "asset one", (sbyte)AssetType.Texture, critter1.ToString()); 121 AssetBase a1 = new AssetBase(uuid1, "asset one", (sbyte)AssetType.Texture, critter1.ToString());
122 AssetBase a2 = new AssetBase(uuid2, "asset two", (sbyte)AssetType.Texture, critter2.ToString()); 122 AssetBase a2 = new AssetBase(uuid2, "asset two", (sbyte)AssetType.Texture, critter2.ToString());
@@ -183,7 +183,7 @@ namespace OpenSim.Data.Tests
183 [Test] 183 [Test]
184 public void T020_CheckForWeirdCreatorID() 184 public void T020_CheckForWeirdCreatorID()
185 { 185 {
186 TestHelper.InMethod(); 186 TestHelpers.InMethod();
187 187
188 // It is expected that eventually the CreatorID might be an arbitrary string (an URI) 188 // It is expected that eventually the CreatorID might be an arbitrary string (an URI)
189 // rather than a valid UUID (?). This test is to make sure that the database layer does not 189 // rather than a valid UUID (?). This test is to make sure that the database layer does not
diff --git a/OpenSim/Data/Tests/EstateTests.cs b/OpenSim/Data/Tests/EstateTests.cs
index 8d332da..3e47bcf 100644
--- a/OpenSim/Data/Tests/EstateTests.cs
+++ b/OpenSim/Data/Tests/EstateTests.cs
@@ -107,7 +107,7 @@ namespace OpenSim.Data.Tests
107 [Test] 107 [Test]
108 public void T010_EstateSettingsSimpleStorage_MinimumParameterSet() 108 public void T010_EstateSettingsSimpleStorage_MinimumParameterSet()
109 { 109 {
110 TestHelper.InMethod(); 110 TestHelpers.InMethod();
111 111
112 EstateSettingsSimpleStorage( 112 EstateSettingsSimpleStorage(
113 REGION_ID, 113 REGION_ID,
@@ -140,7 +140,7 @@ namespace OpenSim.Data.Tests
140 [Test] 140 [Test]
141 public void T011_EstateSettingsSimpleStorage_MaximumParameterSet() 141 public void T011_EstateSettingsSimpleStorage_MaximumParameterSet()
142 { 142 {
143 TestHelper.InMethod(); 143 TestHelpers.InMethod();
144 144
145 EstateSettingsSimpleStorage( 145 EstateSettingsSimpleStorage(
146 REGION_ID, 146 REGION_ID,
@@ -173,7 +173,7 @@ namespace OpenSim.Data.Tests
173 [Test] 173 [Test]
174 public void T012_EstateSettingsSimpleStorage_AccurateParameterSet() 174 public void T012_EstateSettingsSimpleStorage_AccurateParameterSet()
175 { 175 {
176 TestHelper.InMethod(); 176 TestHelpers.InMethod();
177 177
178 EstateSettingsSimpleStorage( 178 EstateSettingsSimpleStorage(
179 REGION_ID, 179 REGION_ID,
@@ -206,7 +206,7 @@ namespace OpenSim.Data.Tests
206 [Test] 206 [Test]
207 public void T012_EstateSettingsRandomStorage() 207 public void T012_EstateSettingsRandomStorage()
208 { 208 {
209 TestHelper.InMethod(); 209 TestHelpers.InMethod();
210 210
211 // Letting estate store generate rows to database for us 211 // Letting estate store generate rows to database for us
212 EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true); 212 EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true);
@@ -227,7 +227,7 @@ namespace OpenSim.Data.Tests
227 [Test] 227 [Test]
228 public void T020_EstateSettingsManagerList() 228 public void T020_EstateSettingsManagerList()
229 { 229 {
230 TestHelper.InMethod(); 230 TestHelpers.InMethod();
231 231
232 // Letting estate store generate rows to database for us 232 // Letting estate store generate rows to database for us
233 EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true); 233 EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true);
@@ -248,7 +248,7 @@ namespace OpenSim.Data.Tests
248 [Test] 248 [Test]
249 public void T021_EstateSettingsUserList() 249 public void T021_EstateSettingsUserList()
250 { 250 {
251 TestHelper.InMethod(); 251 TestHelpers.InMethod();
252 252
253 // Letting estate store generate rows to database for us 253 // Letting estate store generate rows to database for us
254 EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true); 254 EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true);
@@ -269,7 +269,7 @@ namespace OpenSim.Data.Tests
269 [Test] 269 [Test]
270 public void T022_EstateSettingsGroupList() 270 public void T022_EstateSettingsGroupList()
271 { 271 {
272 TestHelper.InMethod(); 272 TestHelpers.InMethod();
273 273
274 // Letting estate store generate rows to database for us 274 // Letting estate store generate rows to database for us
275 EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true); 275 EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true);
@@ -290,7 +290,7 @@ namespace OpenSim.Data.Tests
290 [Test] 290 [Test]
291 public void T022_EstateSettingsBanList() 291 public void T022_EstateSettingsBanList()
292 { 292 {
293 TestHelper.InMethod(); 293 TestHelpers.InMethod();
294 294
295 // Letting estate store generate rows to database for us 295 // Letting estate store generate rows to database for us
296 EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true); 296 EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true);
diff --git a/OpenSim/Data/Tests/InventoryTests.cs b/OpenSim/Data/Tests/InventoryTests.cs
index cf3bac1..5b6b61b 100644
--- a/OpenSim/Data/Tests/InventoryTests.cs
+++ b/OpenSim/Data/Tests/InventoryTests.cs
@@ -114,7 +114,7 @@ namespace OpenSim.Data.Tests
114 [Test] 114 [Test]
115 public void T001_LoadEmpty() 115 public void T001_LoadEmpty()
116 { 116 {
117 TestHelper.InMethod(); 117 TestHelpers.InMethod();
118 118
119 Assert.That(db.getInventoryFolder(zero), Is.Null); 119 Assert.That(db.getInventoryFolder(zero), Is.Null);
120 Assert.That(db.getInventoryFolder(folder1), Is.Null); 120 Assert.That(db.getInventoryFolder(folder1), Is.Null);
@@ -134,7 +134,7 @@ namespace OpenSim.Data.Tests
134 [Test] 134 [Test]
135 public void T010_FolderNonParent() 135 public void T010_FolderNonParent()
136 { 136 {
137 TestHelper.InMethod(); 137 TestHelpers.InMethod();
138 138
139 InventoryFolderBase f1 = NewFolder(folder2, folder1, owner1, name2); 139 InventoryFolderBase f1 = NewFolder(folder2, folder1, owner1, name2);
140 // the folder will go in 140 // the folder will go in
@@ -146,7 +146,7 @@ namespace OpenSim.Data.Tests
146 [Test] 146 [Test]
147 public void T011_FolderCreate() 147 public void T011_FolderCreate()
148 { 148 {
149 TestHelper.InMethod(); 149 TestHelpers.InMethod();
150 150
151 InventoryFolderBase f1 = NewFolder(folder1, zero, owner1, name1); 151 InventoryFolderBase f1 = NewFolder(folder1, zero, owner1, name1);
152 // TODO: this is probably wrong behavior, but is what we have 152 // TODO: this is probably wrong behavior, but is what we have
@@ -171,7 +171,7 @@ namespace OpenSim.Data.Tests
171 [Test] 171 [Test]
172 public void T012_FolderList() 172 public void T012_FolderList()
173 { 173 {
174 TestHelper.InMethod(); 174 TestHelpers.InMethod();
175 175
176 InventoryFolderBase f2 = NewFolder(folder3, folder1, owner1, name3); 176 InventoryFolderBase f2 = NewFolder(folder3, folder1, owner1, name3);
177 db.addInventoryFolder(f2); 177 db.addInventoryFolder(f2);
@@ -187,7 +187,7 @@ namespace OpenSim.Data.Tests
187 [Test] 187 [Test]
188 public void T013_FolderHierarchy() 188 public void T013_FolderHierarchy()
189 { 189 {
190 TestHelper.InMethod(); 190 TestHelpers.InMethod();
191 191
192 int n = db.getFolderHierarchy(zero).Count; // (for dbg - easier to see what's returned) 192 int n = db.getFolderHierarchy(zero).Count; // (for dbg - easier to see what's returned)
193 Assert.That(n, Is.EqualTo(0), "Assert.That(db.getFolderHierarchy(zero).Count, Is.EqualTo(0))"); 193 Assert.That(n, Is.EqualTo(0), "Assert.That(db.getFolderHierarchy(zero).Count, Is.EqualTo(0))");
@@ -202,7 +202,7 @@ namespace OpenSim.Data.Tests
202 [Test] 202 [Test]
203 public void T014_MoveFolder() 203 public void T014_MoveFolder()
204 { 204 {
205 TestHelper.InMethod(); 205 TestHelpers.InMethod();
206 206
207 InventoryFolderBase f2 = db.getInventoryFolder(folder2); 207 InventoryFolderBase f2 = db.getInventoryFolder(folder2);
208 f2.ParentID = folder3; 208 f2.ParentID = folder3;
@@ -218,7 +218,7 @@ namespace OpenSim.Data.Tests
218 [Test] 218 [Test]
219 public void T015_FolderHierarchy() 219 public void T015_FolderHierarchy()
220 { 220 {
221 TestHelper.InMethod(); 221 TestHelpers.InMethod();
222 222
223 Assert.That(db.getFolderHierarchy(zero).Count, Is.EqualTo(0), "Assert.That(db.getFolderHierarchy(zero).Count, Is.EqualTo(0))"); 223 Assert.That(db.getFolderHierarchy(zero).Count, Is.EqualTo(0), "Assert.That(db.getFolderHierarchy(zero).Count, Is.EqualTo(0))");
224 Assert.That(db.getFolderHierarchy(folder1).Count, Is.EqualTo(2), "Assert.That(db.getFolderHierarchy(folder1).Count, Is.EqualTo(2))"); 224 Assert.That(db.getFolderHierarchy(folder1).Count, Is.EqualTo(2), "Assert.That(db.getFolderHierarchy(folder1).Count, Is.EqualTo(2))");
@@ -231,7 +231,7 @@ namespace OpenSim.Data.Tests
231 [Test] 231 [Test]
232 public void T100_NoItems() 232 public void T100_NoItems()
233 { 233 {
234 TestHelper.InMethod(); 234 TestHelpers.InMethod();
235 235
236 Assert.That(db.getInventoryInFolder(zero).Count, Is.EqualTo(0), "Assert.That(db.getInventoryInFolder(zero).Count, Is.EqualTo(0))"); 236 Assert.That(db.getInventoryInFolder(zero).Count, Is.EqualTo(0), "Assert.That(db.getInventoryInFolder(zero).Count, Is.EqualTo(0))");
237 Assert.That(db.getInventoryInFolder(folder1).Count, Is.EqualTo(0), "Assert.That(db.getInventoryInFolder(folder1).Count, Is.EqualTo(0))"); 237 Assert.That(db.getInventoryInFolder(folder1).Count, Is.EqualTo(0), "Assert.That(db.getInventoryInFolder(folder1).Count, Is.EqualTo(0))");
@@ -245,7 +245,7 @@ namespace OpenSim.Data.Tests
245 [Test] 245 [Test]
246 public void T101_CreatItems() 246 public void T101_CreatItems()
247 { 247 {
248 TestHelper.InMethod(); 248 TestHelpers.InMethod();
249 249
250 db.addInventoryItem(NewItem(item1, folder3, owner1, iname1, asset1)); 250 db.addInventoryItem(NewItem(item1, folder3, owner1, iname1, asset1));
251 db.addInventoryItem(NewItem(item2, folder3, owner1, iname2, asset2)); 251 db.addInventoryItem(NewItem(item2, folder3, owner1, iname2, asset2));
@@ -256,7 +256,7 @@ namespace OpenSim.Data.Tests
256 [Test] 256 [Test]
257 public void T102_CompareItems() 257 public void T102_CompareItems()
258 { 258 {
259 TestHelper.InMethod(); 259 TestHelpers.InMethod();
260 260
261 InventoryItemBase i1 = db.getInventoryItem(item1); 261 InventoryItemBase i1 = db.getInventoryItem(item1);
262 InventoryItemBase i2 = db.getInventoryItem(item2); 262 InventoryItemBase i2 = db.getInventoryItem(item2);
@@ -275,7 +275,7 @@ namespace OpenSim.Data.Tests
275 [Test] 275 [Test]
276 public void T103_UpdateItem() 276 public void T103_UpdateItem()
277 { 277 {
278 TestHelper.InMethod(); 278 TestHelpers.InMethod();
279 279
280 // TODO: probably shouldn't have the ability to have an 280 // TODO: probably shouldn't have the ability to have an
281 // owner of an item in a folder not owned by the user 281 // owner of an item in a folder not owned by the user
@@ -295,7 +295,7 @@ namespace OpenSim.Data.Tests
295 [Test] 295 [Test]
296 public void T104_RandomUpdateItem() 296 public void T104_RandomUpdateItem()
297 { 297 {
298 TestHelper.InMethod(); 298 TestHelpers.InMethod();
299 299
300 PropertyScrambler<InventoryFolderBase> folderScrambler = 300 PropertyScrambler<InventoryFolderBase> folderScrambler =
301 new PropertyScrambler<InventoryFolderBase>() 301 new PropertyScrambler<InventoryFolderBase>()
@@ -354,7 +354,7 @@ namespace OpenSim.Data.Tests
354 [Test] 354 [Test]
355 public void T999_StillNull() 355 public void T999_StillNull()
356 { 356 {
357 TestHelper.InMethod(); 357 TestHelpers.InMethod();
358 358
359 // After all tests are run, these should still return no results 359 // After all tests are run, these should still return no results
360 Assert.That(db.getInventoryFolder(zero), Is.Null); 360 Assert.That(db.getInventoryFolder(zero), Is.Null);
diff --git a/OpenSim/Data/Tests/RegionTests.cs b/OpenSim/Data/Tests/RegionTests.cs
index 44cf1ab..cac8cac 100644
--- a/OpenSim/Data/Tests/RegionTests.cs
+++ b/OpenSim/Data/Tests/RegionTests.cs
@@ -151,7 +151,7 @@ namespace OpenSim.Data.Tests
151 [Test] 151 [Test]
152 public void T001_LoadEmpty() 152 public void T001_LoadEmpty()
153 { 153 {
154 TestHelper.InMethod(); 154 TestHelpers.InMethod();
155 155
156 List<SceneObjectGroup> objs = db.LoadObjects(region1); 156 List<SceneObjectGroup> objs = db.LoadObjects(region1);
157 List<SceneObjectGroup> objs3 = db.LoadObjects(region3); 157 List<SceneObjectGroup> objs3 = db.LoadObjects(region3);
@@ -169,7 +169,7 @@ namespace OpenSim.Data.Tests
169 [Test] 169 [Test]
170 public void T010_StoreSimpleObject() 170 public void T010_StoreSimpleObject()
171 { 171 {
172 TestHelper.InMethod(); 172 TestHelpers.InMethod();
173 173
174 SceneObjectGroup sog = NewSOG("object1", prim1, region1); 174 SceneObjectGroup sog = NewSOG("object1", prim1, region1);
175 SceneObjectGroup sog2 = NewSOG("object2", prim2, region1); 175 SceneObjectGroup sog2 = NewSOG("object2", prim2, region1);
@@ -204,7 +204,7 @@ namespace OpenSim.Data.Tests
204 [Test] 204 [Test]
205 public void T011_ObjectNames() 205 public void T011_ObjectNames()
206 { 206 {
207 TestHelper.InMethod(); 207 TestHelpers.InMethod();
208 208
209 List<SceneObjectGroup> objs = db.LoadObjects(region1); 209 List<SceneObjectGroup> objs = db.LoadObjects(region1);
210 foreach (SceneObjectGroup sog in objs) 210 foreach (SceneObjectGroup sog in objs)
@@ -218,7 +218,7 @@ namespace OpenSim.Data.Tests
218 [Test] 218 [Test]
219 public void T012_SceneParts() 219 public void T012_SceneParts()
220 { 220 {
221 TestHelper.InMethod(); 221 TestHelpers.InMethod();
222 222
223 UUID tmp0 = UUID.Random(); 223 UUID tmp0 = UUID.Random();
224 UUID tmp1 = UUID.Random(); 224 UUID tmp1 = UUID.Random();
@@ -253,7 +253,7 @@ namespace OpenSim.Data.Tests
253 [Test] 253 [Test]
254 public void T013_DatabasePersistency() 254 public void T013_DatabasePersistency()
255 { 255 {
256 TestHelper.InMethod(); 256 TestHelpers.InMethod();
257 257
258 // Sets all ScenePart parameters, stores and retrieves them, then check for consistency with initial data 258 // Sets all ScenePart parameters, stores and retrieves them, then check for consistency with initial data
259 // The commented Asserts are the ones that are unchangeable (when storing on the database, their "Set" values are ignored 259 // The commented Asserts are the ones that are unchangeable (when storing on the database, their "Set" values are ignored
@@ -304,9 +304,9 @@ namespace OpenSim.Data.Tests
304 regionInfo.RegionLocX = 0; 304 regionInfo.RegionLocX = 0;
305 regionInfo.RegionLocY = 0; 305 regionInfo.RegionLocY = 0;
306 306
307// Scene scene = new Scene(regionInfo);
308
309 SceneObjectPart sop = new SceneObjectPart(); 307 SceneObjectPart sop = new SceneObjectPart();
308 SceneObjectGroup sog = new SceneObjectGroup(sop);
309
310 sop.RegionHandle = regionh; 310 sop.RegionHandle = regionh;
311 sop.UUID = uuid; 311 sop.UUID = uuid;
312 sop.LocalId = localid; 312 sop.LocalId = localid;
@@ -373,8 +373,6 @@ namespace OpenSim.Data.Tests
373 373
374 // This is necessary or object will not be inserted in DB 374 // This is necessary or object will not be inserted in DB
375 sop.Flags = PrimFlags.None; 375 sop.Flags = PrimFlags.None;
376
377 SceneObjectGroup sog = new SceneObjectGroup(sop);
378 376
379 // Inserts group in DB 377 // Inserts group in DB
380 db.StoreObject(sog,region3); 378 db.StoreObject(sog,region3);
@@ -430,7 +428,7 @@ namespace OpenSim.Data.Tests
430 [Test] 428 [Test]
431 public void T014_UpdateObject() 429 public void T014_UpdateObject()
432 { 430 {
433 TestHelper.InMethod(); 431 TestHelpers.InMethod();
434 432
435 string text1 = "object1 text"; 433 string text1 = "object1 text";
436 SceneObjectGroup sog = FindSOG("object1", region1); 434 SceneObjectGroup sog = FindSOG("object1", region1);
@@ -540,7 +538,7 @@ namespace OpenSim.Data.Tests
540 [Test] 538 [Test]
541 public void T015_LargeSceneObjects() 539 public void T015_LargeSceneObjects()
542 { 540 {
543 TestHelper.InMethod(); 541 TestHelpers.InMethod();
544 542
545 UUID id = UUID.Random(); 543 UUID id = UUID.Random();
546 Dictionary<UUID, SceneObjectPart> mydic = new Dictionary<UUID, SceneObjectPart>(); 544 Dictionary<UUID, SceneObjectPart> mydic = new Dictionary<UUID, SceneObjectPart>();
@@ -587,7 +585,7 @@ namespace OpenSim.Data.Tests
587 //[Test] 585 //[Test]
588 public void T016_RandomSogWithSceneParts() 586 public void T016_RandomSogWithSceneParts()
589 { 587 {
590 TestHelper.InMethod(); 588 TestHelpers.InMethod();
591 589
592 PropertyScrambler<SceneObjectPart> scrambler = 590 PropertyScrambler<SceneObjectPart> scrambler =
593 new PropertyScrambler<SceneObjectPart>() 591 new PropertyScrambler<SceneObjectPart>()
@@ -663,7 +661,7 @@ namespace OpenSim.Data.Tests
663 [Test] 661 [Test]
664 public void T020_PrimInventoryEmpty() 662 public void T020_PrimInventoryEmpty()
665 { 663 {
666 TestHelper.InMethod(); 664 TestHelpers.InMethod();
667 665
668 SceneObjectGroup sog = GetMySOG("object1"); 666 SceneObjectGroup sog = GetMySOG("object1");
669 TaskInventoryItem t = sog.GetInventoryItem(sog.RootPart.LocalId, item1); 667 TaskInventoryItem t = sog.GetInventoryItem(sog.RootPart.LocalId, item1);
@@ -687,7 +685,7 @@ namespace OpenSim.Data.Tests
687 [Test] 685 [Test]
688 public void T021_PrimInventoryBasic() 686 public void T021_PrimInventoryBasic()
689 { 687 {
690 TestHelper.InMethod(); 688 TestHelpers.InMethod();
691 689
692 SceneObjectGroup sog = GetMySOG("object1"); 690 SceneObjectGroup sog = GetMySOG("object1");
693 InventoryItemBase i = NewItem(item1, zero, zero, itemname1, zero); 691 InventoryItemBase i = NewItem(item1, zero, zero, itemname1, zero);
@@ -727,7 +725,7 @@ namespace OpenSim.Data.Tests
727 [Test] 725 [Test]
728 public void T025_PrimInventoryPersistency() 726 public void T025_PrimInventoryPersistency()
729 { 727 {
730 TestHelper.InMethod(); 728 TestHelpers.InMethod();
731 729
732 InventoryItemBase i = new InventoryItemBase(); 730 InventoryItemBase i = new InventoryItemBase();
733 UUID id = UUID.Random(); 731 UUID id = UUID.Random();
@@ -800,7 +798,7 @@ namespace OpenSim.Data.Tests
800 [ExpectedException(typeof(ArgumentException))] 798 [ExpectedException(typeof(ArgumentException))]
801 public void T026_PrimInventoryMany() 799 public void T026_PrimInventoryMany()
802 { 800 {
803 TestHelper.InMethod(); 801 TestHelpers.InMethod();
804 802
805 UUID i1,i2,i3,i4; 803 UUID i1,i2,i3,i4;
806 i1 = UUID.Random(); 804 i1 = UUID.Random();
@@ -832,7 +830,7 @@ namespace OpenSim.Data.Tests
832 [Test] 830 [Test]
833 public void T052_RemoveObject() 831 public void T052_RemoveObject()
834 { 832 {
835 TestHelper.InMethod(); 833 TestHelpers.InMethod();
836 834
837 db.RemoveObject(prim1, region1); 835 db.RemoveObject(prim1, region1);
838 SceneObjectGroup sog = FindSOG("object1", region1); 836 SceneObjectGroup sog = FindSOG("object1", region1);
@@ -842,7 +840,7 @@ namespace OpenSim.Data.Tests
842 [Test] 840 [Test]
843 public void T100_DefaultRegionInfo() 841 public void T100_DefaultRegionInfo()
844 { 842 {
845 TestHelper.InMethod(); 843 TestHelpers.InMethod();
846 844
847 RegionSettings r1 = db.LoadRegionSettings(region1); 845 RegionSettings r1 = db.LoadRegionSettings(region1);
848 Assert.That(r1.RegionUUID, Is.EqualTo(region1), "Assert.That(r1.RegionUUID, Is.EqualTo(region1))"); 846 Assert.That(r1.RegionUUID, Is.EqualTo(region1), "Assert.That(r1.RegionUUID, Is.EqualTo(region1))");
@@ -854,7 +852,7 @@ namespace OpenSim.Data.Tests
854 [Test] 852 [Test]
855 public void T101_UpdateRegionInfo() 853 public void T101_UpdateRegionInfo()
856 { 854 {
857 TestHelper.InMethod(); 855 TestHelpers.InMethod();
858 856
859 int agentlimit = random.Next(); 857 int agentlimit = random.Next();
860 double objectbonus = random.Next(); 858 double objectbonus = random.Next();
@@ -960,7 +958,7 @@ namespace OpenSim.Data.Tests
960 [Test] 958 [Test]
961 public void T300_NoTerrain() 959 public void T300_NoTerrain()
962 { 960 {
963 TestHelper.InMethod(); 961 TestHelpers.InMethod();
964 962
965 Assert.That(db.LoadTerrain(zero), Is.Null); 963 Assert.That(db.LoadTerrain(zero), Is.Null);
966 Assert.That(db.LoadTerrain(region1), Is.Null); 964 Assert.That(db.LoadTerrain(region1), Is.Null);
@@ -971,7 +969,7 @@ namespace OpenSim.Data.Tests
971 [Test] 969 [Test]
972 public void T301_CreateTerrain() 970 public void T301_CreateTerrain()
973 { 971 {
974 TestHelper.InMethod(); 972 TestHelpers.InMethod();
975 973
976 double[,] t1 = GenTerrain(height1); 974 double[,] t1 = GenTerrain(height1);
977 db.StoreTerrain(t1, region1); 975 db.StoreTerrain(t1, region1);
@@ -985,7 +983,7 @@ namespace OpenSim.Data.Tests
985 [Test] 983 [Test]
986 public void T302_FetchTerrain() 984 public void T302_FetchTerrain()
987 { 985 {
988 TestHelper.InMethod(); 986 TestHelpers.InMethod();
989 987
990 double[,] baseterrain1 = GenTerrain(height1); 988 double[,] baseterrain1 = GenTerrain(height1);
991 double[,] baseterrain2 = GenTerrain(height2); 989 double[,] baseterrain2 = GenTerrain(height2);
@@ -997,7 +995,7 @@ namespace OpenSim.Data.Tests
997 [Test] 995 [Test]
998 public void T303_UpdateTerrain() 996 public void T303_UpdateTerrain()
999 { 997 {
1000 TestHelper.InMethod(); 998 TestHelpers.InMethod();
1001 999
1002 double[,] baseterrain1 = GenTerrain(height1); 1000 double[,] baseterrain1 = GenTerrain(height1);
1003 double[,] baseterrain2 = GenTerrain(height2); 1001 double[,] baseterrain2 = GenTerrain(height2);
@@ -1011,7 +1009,7 @@ namespace OpenSim.Data.Tests
1011 [Test] 1009 [Test]
1012 public void T400_EmptyLand() 1010 public void T400_EmptyLand()
1013 { 1011 {
1014 TestHelper.InMethod(); 1012 TestHelpers.InMethod();
1015 1013
1016 Assert.That(db.LoadLandObjects(zero).Count, Is.EqualTo(0), "Assert.That(db.LoadLandObjects(zero).Count, Is.EqualTo(0))"); 1014 Assert.That(db.LoadLandObjects(zero).Count, Is.EqualTo(0), "Assert.That(db.LoadLandObjects(zero).Count, Is.EqualTo(0))");
1017 Assert.That(db.LoadLandObjects(region1).Count, Is.EqualTo(0), "Assert.That(db.LoadLandObjects(region1).Count, Is.EqualTo(0))"); 1015 Assert.That(db.LoadLandObjects(region1).Count, Is.EqualTo(0), "Assert.That(db.LoadLandObjects(region1).Count, Is.EqualTo(0))");
diff --git a/OpenSim/Framework/AgentCircuitData.cs b/OpenSim/Framework/AgentCircuitData.cs
index 125910e..12c8ac0 100644
--- a/OpenSim/Framework/AgentCircuitData.cs
+++ b/OpenSim/Framework/AgentCircuitData.cs
@@ -296,11 +296,12 @@ namespace OpenSim.Framework
296 if (args["start_pos"] != null) 296 if (args["start_pos"] != null)
297 Vector3.TryParse(args["start_pos"].AsString(), out startpos); 297 Vector3.TryParse(args["start_pos"].AsString(), out startpos);
298 298
299 m_log.InfoFormat("[AGENTCIRCUITDATA] agentid={0}, child={1}, startpos={2}",AgentID,child,startpos.ToString()); 299 m_log.InfoFormat("[AGENTCIRCUITDATA]: agentid={0}, child={1}, startpos={2}", AgentID, child, startpos);
300 300
301 try { 301 try
302 {
302 // Unpack various appearance elements 303 // Unpack various appearance elements
303 Appearance = new AvatarAppearance(AgentID); 304 Appearance = new AvatarAppearance();
304 305
305 // Eventually this code should be deprecated, use full appearance 306 // Eventually this code should be deprecated, use full appearance
306 // packing in packed_appearance 307 // packing in packed_appearance
@@ -313,7 +314,9 @@ namespace OpenSim.Framework
313 m_log.InfoFormat("[AGENTCIRCUITDATA] unpacked appearance"); 314 m_log.InfoFormat("[AGENTCIRCUITDATA] unpacked appearance");
314 } 315 }
315 else 316 else
316 m_log.Warn("[AGENTCIRCUITDATA] failed to find a valid packed_appearance"); 317 {
318 m_log.Warn("[AGENTCIRCUITDATA]: failed to find a valid packed_appearance");
319 }
317 } 320 }
318 catch (Exception e) 321 catch (Exception e)
319 { 322 {
diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs
index c0bc47e..a68de57 100644
--- a/OpenSim/Framework/AvatarAppearance.cs
+++ b/OpenSim/Framework/AvatarAppearance.cs
@@ -47,7 +47,6 @@ namespace OpenSim.Framework
47 public readonly static int TEXTURE_COUNT = 21; 47 public readonly static int TEXTURE_COUNT = 21;
48 public readonly static byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; 48 public readonly static byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
49 49
50 protected UUID m_owner;
51 protected int m_serial = 0; 50 protected int m_serial = 0;
52 protected byte[] m_visualparams; 51 protected byte[] m_visualparams;
53 protected Primitive.TextureEntry m_texture; 52 protected Primitive.TextureEntry m_texture;
@@ -56,12 +55,6 @@ namespace OpenSim.Framework
56 protected float m_avatarHeight = 0; 55 protected float m_avatarHeight = 0;
57 protected float m_hipOffset = 0; 56 protected float m_hipOffset = 0;
58 57
59 public virtual UUID Owner
60 {
61 get { return m_owner; }
62 set { m_owner = value; }
63 }
64
65 public virtual int Serial 58 public virtual int Serial
66 { 59 {
67 get { return m_serial; } 60 get { return m_serial; }
@@ -77,7 +70,11 @@ namespace OpenSim.Framework
77 public virtual Primitive.TextureEntry Texture 70 public virtual Primitive.TextureEntry Texture
78 { 71 {
79 get { return m_texture; } 72 get { return m_texture; }
80 set { m_texture = value; } 73 set
74 {
75// m_log.DebugFormat("[AVATAR APPEARANCE]: Set TextureEntry to {0}", value);
76 m_texture = value;
77 }
81 } 78 }
82 79
83 public virtual AvatarWearable[] Wearables 80 public virtual AvatarWearable[] Wearables
@@ -97,38 +94,31 @@ namespace OpenSim.Framework
97 get { return m_hipOffset; } 94 get { return m_hipOffset; }
98 } 95 }
99 96
100 public AvatarAppearance() : this(UUID.Zero) {} 97 public AvatarAppearance()
101
102 public AvatarAppearance(UUID owner)
103 { 98 {
104// m_log.WarnFormat("[AVATAR APPEARANCE]: create empty appearance for {0}",owner); 99// m_log.WarnFormat("[AVATAR APPEARANCE]: create empty appearance");
105 100
106 m_serial = 0; 101 m_serial = 0;
107 m_owner = owner;
108
109 SetDefaultWearables(); 102 SetDefaultWearables();
110 SetDefaultTexture(); 103 SetDefaultTexture();
111 SetDefaultParams(); 104 SetDefaultParams();
112 SetHeight(); 105 SetHeight();
113
114 m_attachments = new Dictionary<int, List<AvatarAttachment>>(); 106 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
115 } 107 }
116 108
117 public AvatarAppearance(UUID avatarID, OSDMap map) 109 public AvatarAppearance(OSDMap map)
118 { 110 {
119// m_log.WarnFormat("[AVATAR APPEARANCE]: create appearance for {0} from OSDMap",avatarID); 111// m_log.WarnFormat("[AVATAR APPEARANCE]: create appearance from OSDMap");
120 112
121 m_owner = avatarID;
122 Unpack(map); 113 Unpack(map);
123 SetHeight(); 114 SetHeight();
124 } 115 }
125 116
126 public AvatarAppearance(UUID avatarID, AvatarWearable[] wearables, Primitive.TextureEntry textureEntry, byte[] visualParams) 117 public AvatarAppearance(AvatarWearable[] wearables, Primitive.TextureEntry textureEntry, byte[] visualParams)
127 { 118 {
128// m_log.WarnFormat("[AVATAR APPEARANCE] create initialized appearance for {0}",avatarID); 119// m_log.WarnFormat("[AVATAR APPEARANCE] create initialized appearance");
129 120
130 m_serial = 0; 121 m_serial = 0;
131 m_owner = avatarID;
132 122
133 if (wearables != null) 123 if (wearables != null)
134 m_wearables = wearables; 124 m_wearables = wearables;
@@ -161,24 +151,21 @@ namespace OpenSim.Framework
161 if (appearance == null) 151 if (appearance == null)
162 { 152 {
163 m_serial = 0; 153 m_serial = 0;
164 m_owner = UUID.Zero;
165
166 SetDefaultWearables(); 154 SetDefaultWearables();
167 SetDefaultTexture(); 155 SetDefaultTexture();
168 SetDefaultParams(); 156 SetDefaultParams();
169 SetHeight(); 157 SetHeight();
170
171 m_attachments = new Dictionary<int, List<AvatarAttachment>>(); 158 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
172 159
173 return; 160 return;
174 } 161 }
175 162
176 m_serial = appearance.Serial; 163 m_serial = appearance.Serial;
177 m_owner = appearance.Owner;
178 164
179 m_wearables = new AvatarWearable[AvatarWearable.MAX_WEARABLES]; 165 m_wearables = new AvatarWearable[AvatarWearable.MAX_WEARABLES];
180 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) 166 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
181 m_wearables[i] = new AvatarWearable(); 167 m_wearables[i] = new AvatarWearable();
168
182 if (copyWearables && (appearance.Wearables != null)) 169 if (copyWearables && (appearance.Wearables != null))
183 { 170 {
184 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) 171 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
@@ -196,6 +183,9 @@ namespace OpenSim.Framework
196 if (appearance.VisualParams != null) 183 if (appearance.VisualParams != null)
197 m_visualparams = (byte[])appearance.VisualParams.Clone(); 184 m_visualparams = (byte[])appearance.VisualParams.Clone();
198 185
186 m_avatarHeight = appearance.m_avatarHeight;
187 m_hipOffset = appearance.m_hipOffset;
188
199 // Copy the attachment, force append mode since that ensures consistency 189 // Copy the attachment, force append mode since that ensures consistency
200 m_attachments = new Dictionary<int, List<AvatarAttachment>>(); 190 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
201 foreach (AvatarAttachment attachment in appearance.GetAttachments()) 191 foreach (AvatarAttachment attachment in appearance.GetAttachments())
@@ -237,7 +227,6 @@ namespace OpenSim.Framework
237 { 227 {
238 m_serial = 0; 228 m_serial = 0;
239 229
240 SetDefaultParams();
241 SetDefaultTexture(); 230 SetDefaultTexture();
242 231
243 //for (int i = 0; i < BAKE_INDICES.Length; i++) 232 //for (int i = 0; i < BAKE_INDICES.Length; i++)
@@ -409,9 +398,11 @@ namespace OpenSim.Framework
409// DEBUG OFF 398// DEBUG OFF
410 399
411 /// <summary> 400 /// <summary>
412 /// Get a list of the attachments, note that there may be 401 /// Get a list of the attachments.
413 /// duplicate attachpoints
414 /// </summary> 402 /// </summary>
403 /// <remarks>
404 /// There may be duplicate attachpoints
405 /// </remarks>
415 public List<AvatarAttachment> GetAttachments() 406 public List<AvatarAttachment> GetAttachments()
416 { 407 {
417 lock (m_attachments) 408 lock (m_attachments)
@@ -447,17 +438,29 @@ namespace OpenSim.Framework
447 } 438 }
448 439
449 /// <summary> 440 /// <summary>
450 /// Add an attachment, if the attachpoint has the 441 /// Add an attachment
442 /// </summary>
443 /// <remarks>
444 /// If the attachpoint has the
451 /// 0x80 bit set then we assume this is an append 445 /// 0x80 bit set then we assume this is an append
452 /// operation otherwise we replace whatever is 446 /// operation otherwise we replace whatever is
453 /// currently attached at the attachpoint 447 /// currently attached at the attachpoint
448 /// </remarks>
449 /// <param name="attachpoint"></param>
450 /// <param name="item">If UUID.Zero, then an any attachment at the attachpoint is removed.</param>
451 /// <param name="asset"></param>
452 /// <returns>
454 /// return true if something actually changed 453 /// return true if something actually changed
455 /// </summary> 454 /// </returns>
456 public bool SetAttachment(int attachpoint, UUID item, UUID asset) 455 public bool SetAttachment(int attachpoint, UUID item, UUID asset)
457 { 456 {
458 if (attachpoint == 0) 457 if (attachpoint == 0)
459 return false; 458 return false;
460 459
460// m_log.DebugFormat(
461// "[AVATAR APPEARANCE]: Setting attachment at {0} with item ID {1}, asset ID {2}",
462// attachpoint, item, asset);
463
461 if (item == UUID.Zero) 464 if (item == UUID.Zero)
462 { 465 {
463 lock (m_attachments) 466 lock (m_attachments)
@@ -487,7 +490,7 @@ namespace OpenSim.Framework
487 } 490 }
488 else 491 else
489 { 492 {
490 ReplaceAttachment(new AvatarAttachment(attachpoint,item,asset)); 493 ReplaceAttachment(new AvatarAttachment(attachpoint,item, asset));
491 } 494 }
492 return true; 495 return true;
493 } 496 }
@@ -589,7 +592,7 @@ namespace OpenSim.Framework
589 /// </summary> 592 /// </summary>
590 public void Unpack(OSDMap data) 593 public void Unpack(OSDMap data)
591 { 594 {
592 if ((data != null) && (data["serial"] != null)) 595 if ((data != null) && (data["serial"] != null))
593 m_serial = data["serial"].AsInteger(); 596 m_serial = data["serial"].AsInteger();
594 if ((data != null) && (data["height"] != null)) 597 if ((data != null) && (data["height"] != null))
595 m_avatarHeight = (float)data["height"].AsReal(); 598 m_avatarHeight = (float)data["height"].AsReal();
@@ -647,7 +650,14 @@ namespace OpenSim.Framework
647 { 650 {
648 OSDArray attachs = (OSDArray)(data["attachments"]); 651 OSDArray attachs = (OSDArray)(data["attachments"]);
649 for (int i = 0; i < attachs.Count; i++) 652 for (int i = 0; i < attachs.Count; i++)
650 AppendAttachment(new AvatarAttachment((OSDMap)attachs[i])); 653 {
654 AvatarAttachment att = new AvatarAttachment((OSDMap)attachs[i]);
655 AppendAttachment(att);
656
657// m_log.DebugFormat(
658// "[AVATAR APPEARANCE]: Unpacked attachment itemID {0}, assetID {1}, point {2}",
659// att.ItemID, att.AssetID, att.AttachPoint);
660 }
651 } 661 }
652 } 662 }
653 catch (Exception e) 663 catch (Exception e)
diff --git a/OpenSim/Framework/AvatarAttachment.cs b/OpenSim/Framework/AvatarAttachment.cs
index c68d78d..07dd385 100644
--- a/OpenSim/Framework/AvatarAttachment.cs
+++ b/OpenSim/Framework/AvatarAttachment.cs
@@ -66,11 +66,11 @@ namespace OpenSim.Framework
66 return attachdata; 66 return attachdata;
67 } 67 }
68 68
69
70 public void Unpack(OSDMap args) 69 public void Unpack(OSDMap args)
71 { 70 {
72 if (args["point"] != null) 71 if (args["point"] != null)
73 AttachPoint = args["point"].AsInteger(); 72 AttachPoint = args["point"].AsInteger();
73
74 ItemID = (args["item"] != null) ? args["item"].AsUUID() : UUID.Zero; 74 ItemID = (args["item"] != null) ? args["item"].AsUUID() : UUID.Zero;
75 AssetID = (args["asset"] != null) ? args["asset"].AsUUID() : UUID.Zero; 75 AssetID = (args["asset"] != null) ? args["asset"].AsUUID() : UUID.Zero;
76 } 76 }
diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs
index 710a57d..613db1c 100644
--- a/OpenSim/Framework/ChildAgentDataUpdate.cs
+++ b/OpenSim/Framework/ChildAgentDataUpdate.cs
@@ -593,7 +593,7 @@ namespace OpenSim.Framework
593 // AgentTextures[i++] = o.AsUUID(); 593 // AgentTextures[i++] = o.AsUUID();
594 //} 594 //}
595 595
596 Appearance = new AvatarAppearance(AgentID); 596 Appearance = new AvatarAppearance();
597 597
598 // The code to unpack textures, visuals, wearables and attachments 598 // The code to unpack textures, visuals, wearables and attachments
599 // should be removed; packed appearance contains the full appearance 599 // should be removed; packed appearance contains the full appearance
@@ -635,7 +635,7 @@ namespace OpenSim.Framework
635 // end of code to remove 635 // end of code to remove
636 636
637 if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map) 637 if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map)
638 Appearance = new AvatarAppearance(AgentID,(OSDMap)args["packed_appearance"]); 638 Appearance = new AvatarAppearance((OSDMap)args["packed_appearance"]);
639 else 639 else
640 m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance"); 640 m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance");
641 641
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 80171b4..ee3d6b6 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -51,7 +51,7 @@ namespace OpenSim.Framework
51 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, 51 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
52 bool RezSelected, bool RemoveItem, UUID fromTaskID); 52 bool RezSelected, bool RemoveItem, UUID fromTaskID);
53 53
54 public delegate UUID RezSingleAttachmentFromInv(IClientAPI remoteClient, UUID itemID, uint AttachmentPt); 54 public delegate ISceneEntity RezSingleAttachmentFromInv(IClientAPI remoteClient, UUID itemID, uint AttachmentPt);
55 55
56 public delegate void RezMultipleAttachmentsFromInv(IClientAPI remoteClient, RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header, 56 public delegate void RezMultipleAttachmentsFromInv(IClientAPI remoteClient, RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header,
57 RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects); 57 RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects);
@@ -790,7 +790,7 @@ namespace OpenSim.Framework
790 event DeRezObject OnDeRezObject; 790 event DeRezObject OnDeRezObject;
791 event Action<IClientAPI> OnRegionHandShakeReply; 791 event Action<IClientAPI> OnRegionHandShakeReply;
792 event GenericCall1 OnRequestWearables; 792 event GenericCall1 OnRequestWearables;
793 event GenericCall1 OnCompleteMovementToRegion; 793 event Action<IClientAPI, bool> OnCompleteMovementToRegion;
794 event UpdateAgent OnPreAgentUpdate; 794 event UpdateAgent OnPreAgentUpdate;
795 event UpdateAgent OnAgentUpdate; 795 event UpdateAgent OnAgentUpdate;
796 event AgentRequestSit OnAgentRequestSit; 796 event AgentRequestSit OnAgentRequestSit;
@@ -940,7 +940,7 @@ namespace OpenSim.Framework
940 event ScriptReset OnScriptReset; 940 event ScriptReset OnScriptReset;
941 event GetScriptRunning OnGetScriptRunning; 941 event GetScriptRunning OnGetScriptRunning;
942 event SetScriptRunning OnSetScriptRunning; 942 event SetScriptRunning OnSetScriptRunning;
943 event UpdateVector OnAutoPilotGo; 943 event Action<Vector3, bool> OnAutoPilotGo;
944 944
945 event TerrainUnacked OnUnackedTerrain; 945 event TerrainUnacked OnUnackedTerrain;
946 event ActivateGesture OnActivateGesture; 946 event ActivateGesture OnActivateGesture;
diff --git a/OpenSim/Framework/IScene.cs b/OpenSim/Framework/IScene.cs
index 1298f26..8f7a2e5 100644
--- a/OpenSim/Framework/IScene.cs
+++ b/OpenSim/Framework/IScene.cs
@@ -70,8 +70,20 @@ namespace OpenSim.Framework
70 70
71 event restart OnRestart; 71 event restart OnRestart;
72 72
73 void AddNewClient(IClientAPI client); 73 /// <summary>
74 void RemoveClient(UUID agentID); 74 /// Register the new client with the scene. The client starts off as a child agent - the later agent crossing
75 /// will promote it to a root agent.
76 /// </summary>
77 /// <param name="client"></param>
78 /// <param name="type">The type of agent to add.</param>
79 void AddNewClient(IClientAPI client, PresenceType type);
80
81 /// <summary>
82 /// Remove the given client from the scene.
83 /// </summary>
84 /// <param name="agentID"></param>
85 /// <param name="closeChildAgents">Close the neighbour child agents associated with this client.</param>
86 void RemoveClient(UUID agentID, bool closeChildAgents);
75 87
76 void Restart(); 88 void Restart();
77 //RegionInfo OtherRegionUp(RegionInfo thisRegion); 89 //RegionInfo OtherRegionUp(RegionInfo thisRegion);
diff --git a/OpenSim/Framework/ISceneEntity.cs b/OpenSim/Framework/ISceneEntity.cs
index 5ac364f..c0ea302 100644
--- a/OpenSim/Framework/ISceneEntity.cs
+++ b/OpenSim/Framework/ISceneEntity.cs
@@ -31,6 +31,7 @@ namespace OpenSim.Framework
31{ 31{
32 public interface ISceneEntity 32 public interface ISceneEntity
33 { 33 {
34 string Name { get; set; }
34 UUID UUID { get; } 35 UUID UUID { get; }
35 uint LocalId { get; } 36 uint LocalId { get; }
36 Vector3 AbsolutePosition { get; } 37 Vector3 AbsolutePosition { get; }
diff --git a/OpenSim/Framework/InventoryFolderImpl.cs b/OpenSim/Framework/InventoryFolderImpl.cs
index 29c7682..139776b 100644
--- a/OpenSim/Framework/InventoryFolderImpl.cs
+++ b/OpenSim/Framework/InventoryFolderImpl.cs
@@ -27,13 +27,15 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection;
31using log4net;
30using OpenMetaverse; 32using OpenMetaverse;
31 33
32namespace OpenSim.Framework 34namespace OpenSim.Framework
33{ 35{
34 public class InventoryFolderImpl : InventoryFolderBase 36 public class InventoryFolderImpl : InventoryFolderBase
35 { 37 {
36 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 38// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
37 39
38 public static readonly string PATH_DELIMITER = "/"; 40 public static readonly string PATH_DELIMITER = "/";
39 41
@@ -402,6 +404,10 @@ namespace OpenSim.Framework
402 { 404 {
403 foreach (InventoryItemBase item in Items.Values) 405 foreach (InventoryItemBase item in Items.Values)
404 { 406 {
407// m_log.DebugFormat(
408// "[INVENTORY FOLDER IMPL]: Returning item {0} {1}, OwnerPermissions {2:X}",
409// item.Name, item.ID, item.CurrentPermissions);
410
405 itemList.Add(item); 411 itemList.Add(item);
406 } 412 }
407 } 413 }
diff --git a/OpenSim/Framework/PacketPool.cs b/OpenSim/Framework/PacketPool.cs
index 7e2860e..41d17c5 100644
--- a/OpenSim/Framework/PacketPool.cs
+++ b/OpenSim/Framework/PacketPool.cs
@@ -144,6 +144,7 @@ namespace OpenSim.Framework
144 m_log.WarnFormat("[PACKETPOOL]: Failed to get packet of type {0}", type); 144 m_log.WarnFormat("[PACKETPOOL]: Failed to get packet of type {0}", type);
145 else 145 else
146 packet.FromBytes(bytes, ref i, ref packetEnd, zeroBuffer); 146 packet.FromBytes(bytes, ref i, ref packetEnd, zeroBuffer);
147
147 return packet; 148 return packet;
148 } 149 }
149 150
@@ -160,19 +161,18 @@ namespace OpenSim.Framework
160 case PacketType.ObjectUpdate: 161 case PacketType.ObjectUpdate:
161 ObjectUpdatePacket oup = (ObjectUpdatePacket)packet; 162 ObjectUpdatePacket oup = (ObjectUpdatePacket)packet;
162 163
163 foreach (ObjectUpdatePacket.ObjectDataBlock oupod in 164 foreach (ObjectUpdatePacket.ObjectDataBlock oupod in oup.ObjectData)
164 oup.ObjectData)
165 ReturnDataBlock<ObjectUpdatePacket.ObjectDataBlock>(oupod); 165 ReturnDataBlock<ObjectUpdatePacket.ObjectDataBlock>(oupod);
166
166 oup.ObjectData = null; 167 oup.ObjectData = null;
167 break; 168 break;
168 169
169 case PacketType.ImprovedTerseObjectUpdate: 170 case PacketType.ImprovedTerseObjectUpdate:
170 ImprovedTerseObjectUpdatePacket itoup = 171 ImprovedTerseObjectUpdatePacket itoup = (ImprovedTerseObjectUpdatePacket)packet;
171 (ImprovedTerseObjectUpdatePacket)packet;
172 172
173 foreach (ImprovedTerseObjectUpdatePacket.ObjectDataBlock 173 foreach (ImprovedTerseObjectUpdatePacket.ObjectDataBlock itoupod in itoup.ObjectData)
174 itoupod in itoup.ObjectData)
175 ReturnDataBlock<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(itoupod); 174 ReturnDataBlock<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(itoupod);
175
176 itoup.ObjectData = null; 176 itoup.ObjectData = null;
177 break; 177 break;
178 } 178 }
@@ -194,6 +194,7 @@ namespace OpenSim.Framework
194 { 194 {
195 pool[type] = new Stack<Packet>(); 195 pool[type] = new Stack<Packet>();
196 } 196 }
197
197 if ((pool[type]).Count < 50) 198 if ((pool[type]).Count < 50)
198 { 199 {
199 (pool[type]).Push(packet); 200 (pool[type]).Push(packet);
@@ -223,6 +224,7 @@ namespace OpenSim.Framework
223 { 224 {
224 DataBlocks[typeof(T)] = new Stack<Object>(); 225 DataBlocks[typeof(T)] = new Stack<Object>();
225 } 226 }
227
226 return new T(); 228 return new T();
227 } 229 }
228 } 230 }
@@ -234,6 +236,9 @@ namespace OpenSim.Framework
234 236
235 lock (DataBlocks) 237 lock (DataBlocks)
236 { 238 {
239 if (!DataBlocks.ContainsKey(typeof(T)))
240 DataBlocks[typeof(T)] = new Stack<Object>();
241
237 if (DataBlocks[typeof(T)].Count < 50) 242 if (DataBlocks[typeof(T)].Count < 50)
238 DataBlocks[typeof(T)].Push(block); 243 DataBlocks[typeof(T)].Push(block);
239 } 244 }
diff --git a/OpenSim/Framework/UndoStack.cs b/OpenSim/Framework/PresenceType.cs
index 4cd779a..8c4c6e6 100644
--- a/OpenSim/Framework/UndoStack.cs
+++ b/OpenSim/Framework/PresenceType.cs
@@ -24,83 +24,16 @@
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 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. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27
28using System; 27using System;
29using System.Collections.Generic;
30 28
31namespace OpenSim.Framework 29namespace OpenSim.Framework
32{ 30{
33 /// <summary> 31 /// <summary>
34 /// Undo stack. Deletes entries beyond a certain capacity 32 /// Indicate the type of ScenePresence.
35 /// </summary> 33 /// </summary>
36 /// <typeparam name="T"></typeparam> 34 public enum PresenceType
37 [Serializable]
38 public class UndoStack<T>
39 { 35 {
40 private List<T> m_undolist; 36 User,
41 private int m_max; 37 Npc
42
43 public UndoStack(int capacity)
44 {
45 m_undolist = new List<T>();
46 m_max = capacity;
47 }
48
49 public bool IsFull
50 {
51 get { return m_undolist.Count >= m_max; }
52 }
53
54 public int Capacity
55 {
56 get { return m_max; }
57 }
58
59 public int Count
60 {
61 get
62 {
63 return m_undolist.Count;
64 }
65 }
66
67 public void Push(T item)
68 {
69 if (IsFull)
70 {
71 m_undolist.RemoveAt(0);
72 }
73 m_undolist.Add(item);
74 }
75
76 public T Pop()
77 {
78 if (m_undolist.Count > 0)
79 {
80 int ind = m_undolist.Count - 1;
81 T item = m_undolist[ind];
82 m_undolist.RemoveAt(ind);
83 return item;
84 }
85 else
86 throw new InvalidOperationException("Cannot pop from empty stack");
87 }
88
89 public T Peek()
90 {
91 if (m_undolist.Count > 0)
92 {
93 return m_undolist[m_undolist.Count - 1];
94 }
95 else
96 {
97 return default(T);
98 }
99 }
100
101 public void Clear()
102 {
103 m_undolist.Clear();
104 }
105 } 38 }
106} 39} \ No newline at end of file
diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs
index 83ddf95..9cfc7ed 100644
--- a/OpenSim/Framework/PrimitiveBaseShape.cs
+++ b/OpenSim/Framework/PrimitiveBaseShape.cs
@@ -879,6 +879,67 @@ namespace OpenSim.Framework
879 } 879 }
880 } 880 }
881 881
882 public ulong GetMeshKey(Vector3 size, float lod)
883 {
884 ulong hash = 5381;
885
886 hash = djb2(hash, this.PathCurve);
887 hash = djb2(hash, (byte)((byte)this.HollowShape | (byte)this.ProfileShape));
888 hash = djb2(hash, this.PathBegin);
889 hash = djb2(hash, this.PathEnd);
890 hash = djb2(hash, this.PathScaleX);
891 hash = djb2(hash, this.PathScaleY);
892 hash = djb2(hash, this.PathShearX);
893 hash = djb2(hash, this.PathShearY);
894 hash = djb2(hash, (byte)this.PathTwist);
895 hash = djb2(hash, (byte)this.PathTwistBegin);
896 hash = djb2(hash, (byte)this.PathRadiusOffset);
897 hash = djb2(hash, (byte)this.PathTaperX);
898 hash = djb2(hash, (byte)this.PathTaperY);
899 hash = djb2(hash, this.PathRevolutions);
900 hash = djb2(hash, (byte)this.PathSkew);
901 hash = djb2(hash, this.ProfileBegin);
902 hash = djb2(hash, this.ProfileEnd);
903 hash = djb2(hash, this.ProfileHollow);
904
905 // TODO: Separate scale out from the primitive shape data (after
906 // scaling is supported at the physics engine level)
907 byte[] scaleBytes = size.GetBytes();
908 for (int i = 0; i < scaleBytes.Length; i++)
909 hash = djb2(hash, scaleBytes[i]);
910
911 // Include LOD in hash, accounting for endianness
912 byte[] lodBytes = new byte[4];
913 Buffer.BlockCopy(BitConverter.GetBytes(lod), 0, lodBytes, 0, 4);
914 if (!BitConverter.IsLittleEndian)
915 {
916 Array.Reverse(lodBytes, 0, 4);
917 }
918 for (int i = 0; i < lodBytes.Length; i++)
919 hash = djb2(hash, lodBytes[i]);
920
921 // include sculpt UUID
922 if (this.SculptEntry)
923 {
924 scaleBytes = this.SculptTexture.GetBytes();
925 for (int i = 0; i < scaleBytes.Length; i++)
926 hash = djb2(hash, scaleBytes[i]);
927 }
928
929 return hash;
930 }
931
932 private ulong djb2(ulong hash, byte c)
933 {
934 return ((hash << 5) + hash) + (ulong)c;
935 }
936
937 private ulong djb2(ulong hash, ushort c)
938 {
939 hash = ((hash << 5) + hash) + (ulong)((byte)c);
940 return ((hash << 5) + hash) + (ulong)(c >> 8);
941 }
942
882 public byte[] ExtraParamsToBytes() 943 public byte[] ExtraParamsToBytes()
883 { 944 {
884// m_log.DebugFormat("[EXTRAPARAMS]: Called ExtraParamsToBytes()"); 945// m_log.DebugFormat("[EXTRAPARAMS]: Called ExtraParamsToBytes()");
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index 460f759..c0d65ac 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -56,7 +56,6 @@ namespace OpenSim.Framework.Servers.HttpServer
56 private volatile int NotSocketErrors = 0; 56 private volatile int NotSocketErrors = 0;
57 public volatile bool HTTPDRunning = false; 57 public volatile bool HTTPDRunning = false;
58 58
59 protected Thread m_workerThread;
60 // protected HttpListener m_httpListener; 59 // protected HttpListener m_httpListener;
61 protected CoolHTTPListener m_httpListener2; 60 protected CoolHTTPListener m_httpListener2;
62 protected Dictionary<string, XmlRpcMethod> m_rpcHandlers = new Dictionary<string, XmlRpcMethod>(); 61 protected Dictionary<string, XmlRpcMethod> m_rpcHandlers = new Dictionary<string, XmlRpcMethod>();
@@ -66,7 +65,6 @@ namespace OpenSim.Framework.Servers.HttpServer
66 protected Dictionary<string, IRequestHandler> m_streamHandlers = new Dictionary<string, IRequestHandler>(); 65 protected Dictionary<string, IRequestHandler> m_streamHandlers = new Dictionary<string, IRequestHandler>();
67 protected Dictionary<string, GenericHTTPMethod> m_HTTPHandlers = new Dictionary<string, GenericHTTPMethod>(); 66 protected Dictionary<string, GenericHTTPMethod> m_HTTPHandlers = new Dictionary<string, GenericHTTPMethod>();
68 protected Dictionary<string, IHttpAgentHandler> m_agentHandlers = new Dictionary<string, IHttpAgentHandler>(); 67 protected Dictionary<string, IHttpAgentHandler> m_agentHandlers = new Dictionary<string, IHttpAgentHandler>();
69
70 protected Dictionary<string, PollServiceEventArgs> m_pollHandlers = 68 protected Dictionary<string, PollServiceEventArgs> m_pollHandlers =
71 new Dictionary<string, PollServiceEventArgs>(); 69 new Dictionary<string, PollServiceEventArgs>();
72 70
@@ -155,7 +153,8 @@ namespace OpenSim.Framework.Servers.HttpServer
155 153
156 public List<string> GetStreamHandlerKeys() 154 public List<string> GetStreamHandlerKeys()
157 { 155 {
158 return new List<string>(m_streamHandlers.Keys); 156 lock (m_streamHandlers)
157 return new List<string>(m_streamHandlers.Keys);
159 } 158 }
160 159
161 private static string GetHandlerKey(string httpMethod, string path) 160 private static string GetHandlerKey(string httpMethod, string path)
@@ -196,7 +195,8 @@ namespace OpenSim.Framework.Servers.HttpServer
196 195
197 public List<string> GetXmlRpcHandlerKeys() 196 public List<string> GetXmlRpcHandlerKeys()
198 { 197 {
199 return new List<string>(m_rpcHandlers.Keys); 198 lock (m_rpcHandlers)
199 return new List<string>(m_rpcHandlers.Keys);
200 } 200 }
201 201
202 public bool AddHTTPHandler(string methodName, GenericHTTPMethod handler) 202 public bool AddHTTPHandler(string methodName, GenericHTTPMethod handler)
@@ -218,10 +218,10 @@ namespace OpenSim.Framework.Servers.HttpServer
218 218
219 public List<string> GetHTTPHandlerKeys() 219 public List<string> GetHTTPHandlerKeys()
220 { 220 {
221 return new List<string>(m_HTTPHandlers.Keys); 221 lock (m_HTTPHandlers)
222 return new List<string>(m_HTTPHandlers.Keys);
222 } 223 }
223 224
224
225 public bool AddPollServiceHTTPHandler(string methodName, GenericHTTPMethod handler, PollServiceEventArgs args) 225 public bool AddPollServiceHTTPHandler(string methodName, GenericHTTPMethod handler, PollServiceEventArgs args)
226 { 226 {
227 bool pollHandlerResult = false; 227 bool pollHandlerResult = false;
@@ -242,10 +242,10 @@ namespace OpenSim.Framework.Servers.HttpServer
242 242
243 public List<string> GetPollServiceHandlerKeys() 243 public List<string> GetPollServiceHandlerKeys()
244 { 244 {
245 return new List<string>(m_pollHandlers.Keys); 245 lock (m_pollHandlers)
246 return new List<string>(m_pollHandlers.Keys);
246 } 247 }
247 248
248
249 // Note that the agent string is provided simply to differentiate 249 // Note that the agent string is provided simply to differentiate
250 // the handlers - it is NOT required to be an actual agent header 250 // the handlers - it is NOT required to be an actual agent header
251 // value. 251 // value.
@@ -266,7 +266,8 @@ namespace OpenSim.Framework.Servers.HttpServer
266 266
267 public List<string> GetAgentHandlerKeys() 267 public List<string> GetAgentHandlerKeys()
268 { 268 {
269 return new List<string>(m_agentHandlers.Keys); 269 lock (m_agentHandlers)
270 return new List<string>(m_agentHandlers.Keys);
270 } 271 }
271 272
272 public bool AddLLSDHandler(string path, LLSDMethod handler) 273 public bool AddLLSDHandler(string path, LLSDMethod handler)
@@ -284,7 +285,8 @@ namespace OpenSim.Framework.Servers.HttpServer
284 285
285 public List<string> GetLLSDHandlerKeys() 286 public List<string> GetLLSDHandlerKeys()
286 { 287 {
287 return new List<string>(m_llsdHandlers.Keys); 288 lock (m_llsdHandlers)
289 return new List<string>(m_llsdHandlers.Keys);
288 } 290 }
289 291
290 public bool SetDefaultLLSDHandler(DefaultLLSDMethod handler) 292 public bool SetDefaultLLSDHandler(DefaultLLSDMethod handler)
@@ -404,14 +406,14 @@ namespace OpenSim.Framework.Servers.HttpServer
404 string requestMethod = request.HttpMethod; 406 string requestMethod = request.HttpMethod;
405 string uriString = request.RawUrl; 407 string uriString = request.RawUrl;
406 408
407 string reqnum = "unknown"; 409// string reqnum = "unknown";
408 int tickstart = Environment.TickCount; 410 int tickstart = Environment.TickCount;
409 411
410 try 412 try
411 { 413 {
412 // OpenSim.Framework.WebUtil.OSHeaderRequestID 414 // OpenSim.Framework.WebUtil.OSHeaderRequestID
413 if (request.Headers["opensim-request-id"] != null) 415// if (request.Headers["opensim-request-id"] != null)
414 reqnum = String.Format("{0}:{1}",request.RemoteIPEndPoint,request.Headers["opensim-request-id"]); 416// reqnum = String.Format("{0}:{1}",request.RemoteIPEndPoint,request.Headers["opensim-request-id"]);
415 //m_log.DebugFormat("[BASE HTTP SERVER]: <{0}> handle request for {1}",reqnum,request.RawUrl); 417 //m_log.DebugFormat("[BASE HTTP SERVER]: <{0}> handle request for {1}",reqnum,request.RawUrl);
416 418
417 Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US", true); 419 Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US", true);
@@ -746,7 +748,8 @@ namespace OpenSim.Framework.Servers.HttpServer
746 private bool TryGetAgentHandler(OSHttpRequest request, OSHttpResponse response, out IHttpAgentHandler agentHandler) 748 private bool TryGetAgentHandler(OSHttpRequest request, OSHttpResponse response, out IHttpAgentHandler agentHandler)
747 { 749 {
748 agentHandler = null; 750 agentHandler = null;
749 try 751
752 lock (m_agentHandlers)
750 { 753 {
751 foreach (IHttpAgentHandler handler in m_agentHandlers.Values) 754 foreach (IHttpAgentHandler handler in m_agentHandlers.Values)
752 { 755 {
@@ -757,9 +760,6 @@ namespace OpenSim.Framework.Servers.HttpServer
757 } 760 }
758 } 761 }
759 } 762 }
760 catch(KeyNotFoundException)
761 {
762 }
763 763
764 return false; 764 return false;
765 } 765 }
@@ -803,9 +803,12 @@ namespace OpenSim.Framework.Servers.HttpServer
803 803
804 XmlRpcMethod method; 804 XmlRpcMethod method;
805 bool methodWasFound; 805 bool methodWasFound;
806 bool keepAlive = false;
806 lock (m_rpcHandlers) 807 lock (m_rpcHandlers)
807 { 808 {
808 methodWasFound = m_rpcHandlers.TryGetValue(methodName, out method); 809 methodWasFound = m_rpcHandlers.TryGetValue(methodName, out method);
810 if (methodWasFound)
811 keepAlive = m_rpcHandlersKeepAlive[methodName];
809 } 812 }
810 813
811 if (methodWasFound) 814 if (methodWasFound)
@@ -824,7 +827,6 @@ namespace OpenSim.Framework.Servers.HttpServer
824 } 827 }
825 xmlRprcRequest.Params.Add(request.Headers.Get(xff)); // Param[3] 828 xmlRprcRequest.Params.Add(request.Headers.Get(xff)); // Param[3]
826 829
827
828 try 830 try
829 { 831 {
830 xmlRpcResponse = method(xmlRprcRequest, request.RemoteIPEndPoint); 832 xmlRpcResponse = method(xmlRprcRequest, request.RemoteIPEndPoint);
@@ -846,7 +848,7 @@ namespace OpenSim.Framework.Servers.HttpServer
846 } 848 }
847 849
848 // if the method wasn't found, we can't determine KeepAlive state anyway, so lets do it only here 850 // if the method wasn't found, we can't determine KeepAlive state anyway, so lets do it only here
849 response.KeepAlive = m_rpcHandlersKeepAlive[methodName]; 851 response.KeepAlive = keepAlive;
850 } 852 }
851 else 853 else
852 { 854 {
@@ -1106,7 +1108,6 @@ namespace OpenSim.Framework.Servers.HttpServer
1106 /// <returns>true if we have one, false if not</returns> 1108 /// <returns>true if we have one, false if not</returns>
1107 private bool DoWeHaveALLSDHandler(string path) 1109 private bool DoWeHaveALLSDHandler(string path)
1108 { 1110 {
1109
1110 string[] pathbase = path.Split('/'); 1111 string[] pathbase = path.Split('/');
1111 string searchquery = "/"; 1112 string searchquery = "/";
1112 1113
@@ -1122,14 +1123,12 @@ namespace OpenSim.Framework.Servers.HttpServer
1122 1123
1123 string bestMatch = null; 1124 string bestMatch = null;
1124 1125
1125 foreach (string pattern in m_llsdHandlers.Keys) 1126 lock (m_llsdHandlers)
1126 { 1127 {
1127 1128 foreach (string pattern in m_llsdHandlers.Keys)
1128 if (searchquery.StartsWith(pattern) && searchquery.Length >= pattern.Length)
1129 { 1129 {
1130 1130 if (searchquery.StartsWith(pattern) && searchquery.Length >= pattern.Length)
1131 bestMatch = pattern; 1131 bestMatch = pattern;
1132
1133 } 1132 }
1134 } 1133 }
1135 1134
@@ -1142,12 +1141,10 @@ namespace OpenSim.Framework.Servers.HttpServer
1142 1141
1143 if (String.IsNullOrEmpty(bestMatch)) 1142 if (String.IsNullOrEmpty(bestMatch))
1144 { 1143 {
1145
1146 return false; 1144 return false;
1147 } 1145 }
1148 else 1146 else
1149 { 1147 {
1150
1151 return true; 1148 return true;
1152 } 1149 }
1153 } 1150 }
@@ -1232,29 +1229,32 @@ namespace OpenSim.Framework.Servers.HttpServer
1232 1229
1233 string bestMatch = null; 1230 string bestMatch = null;
1234 1231
1235 foreach (string pattern in m_llsdHandlers.Keys) 1232 lock (m_llsdHandlers)
1236 { 1233 {
1237 if (searchquery.ToLower().StartsWith(pattern.ToLower())) 1234 foreach (string pattern in m_llsdHandlers.Keys)
1238 { 1235 {
1239 if (String.IsNullOrEmpty(bestMatch) || searchquery.Length > bestMatch.Length) 1236 if (searchquery.ToLower().StartsWith(pattern.ToLower()))
1240 { 1237 {
1241 // You have to specifically register for '/' and to get it, you must specificaly request it 1238 if (String.IsNullOrEmpty(bestMatch) || searchquery.Length > bestMatch.Length)
1242 // 1239 {
1243 if (pattern == "/" && searchquery == "/" || pattern != "/") 1240 // You have to specifically register for '/' and to get it, you must specificaly request it
1244 bestMatch = pattern; 1241 //
1242 if (pattern == "/" && searchquery == "/" || pattern != "/")
1243 bestMatch = pattern;
1244 }
1245 } 1245 }
1246 } 1246 }
1247 } 1247
1248 1248 if (String.IsNullOrEmpty(bestMatch))
1249 if (String.IsNullOrEmpty(bestMatch)) 1249 {
1250 { 1250 llsdHandler = null;
1251 llsdHandler = null; 1251 return false;
1252 return false; 1252 }
1253 } 1253 else
1254 else 1254 {
1255 { 1255 llsdHandler = m_llsdHandlers[bestMatch];
1256 llsdHandler = m_llsdHandlers[bestMatch]; 1256 return true;
1257 return true; 1257 }
1258 } 1258 }
1259 } 1259 }
1260 1260
@@ -1816,7 +1816,8 @@ namespace OpenSim.Framework.Servers.HttpServer
1816 1816
1817 //m_log.DebugFormat("[BASE HTTP SERVER]: Removing handler key {0}", handlerKey); 1817 //m_log.DebugFormat("[BASE HTTP SERVER]: Removing handler key {0}", handlerKey);
1818 1818
1819 lock (m_streamHandlers) m_streamHandlers.Remove(handlerKey); 1819 lock (m_streamHandlers)
1820 m_streamHandlers.Remove(handlerKey);
1820 } 1821 }
1821 1822
1822 public void RemoveHTTPHandler(string httpMethod, string path) 1823 public void RemoveHTTPHandler(string httpMethod, string path)
@@ -1848,17 +1849,16 @@ namespace OpenSim.Framework.Servers.HttpServer
1848 1849
1849 public bool RemoveAgentHandler(string agent, IHttpAgentHandler handler) 1850 public bool RemoveAgentHandler(string agent, IHttpAgentHandler handler)
1850 { 1851 {
1851 try 1852 lock (m_agentHandlers)
1852 { 1853 {
1853 if (handler == m_agentHandlers[agent]) 1854 IHttpAgentHandler foundHandler;
1855
1856 if (m_agentHandlers.TryGetValue(agent, out foundHandler) && foundHandler == handler)
1854 { 1857 {
1855 m_agentHandlers.Remove(agent); 1858 m_agentHandlers.Remove(agent);
1856 return true; 1859 return true;
1857 } 1860 }
1858 } 1861 }
1859 catch(KeyNotFoundException)
1860 {
1861 }
1862 1862
1863 return false; 1863 return false;
1864 } 1864 }
@@ -1876,18 +1876,16 @@ namespace OpenSim.Framework.Servers.HttpServer
1876 1876
1877 public bool RemoveLLSDHandler(string path, LLSDMethod handler) 1877 public bool RemoveLLSDHandler(string path, LLSDMethod handler)
1878 { 1878 {
1879 try 1879 lock (m_llsdHandlers)
1880 { 1880 {
1881 if (handler == m_llsdHandlers[path]) 1881 LLSDMethod foundHandler;
1882
1883 if (m_llsdHandlers.TryGetValue(path, out foundHandler) && foundHandler == handler)
1882 { 1884 {
1883 m_llsdHandlers.Remove(path); 1885 m_llsdHandlers.Remove(path);
1884 return true; 1886 return true;
1885 } 1887 }
1886 } 1888 }
1887 catch (KeyNotFoundException)
1888 {
1889 // This is an exception to prevent crashing because of invalid code
1890 }
1891 1889
1892 return false; 1890 return false;
1893 } 1891 }
diff --git a/OpenSim/Framework/Tests/AgentCircuitDataTest.cs b/OpenSim/Framework/Tests/AgentCircuitDataTest.cs
index 05d8469..0dce414 100644
--- a/OpenSim/Framework/Tests/AgentCircuitDataTest.cs
+++ b/OpenSim/Framework/Tests/AgentCircuitDataTest.cs
@@ -64,7 +64,7 @@ namespace OpenSim.Framework.Tests
64 SecureSessionId = UUID.Random(); 64 SecureSessionId = UUID.Random();
65 SessionId = UUID.Random(); 65 SessionId = UUID.Random();
66 66
67 AvAppearance = new AvatarAppearance(AgentId); 67 AvAppearance = new AvatarAppearance();
68 VisualParams = new byte[218]; 68 VisualParams = new byte[218];
69 69
70 //body 70 //body
diff --git a/OpenSim/Framework/Tests/AgentCircuitManagerTests.cs b/OpenSim/Framework/Tests/AgentCircuitManagerTests.cs
index 6c98897..9615f1b 100644
--- a/OpenSim/Framework/Tests/AgentCircuitManagerTests.cs
+++ b/OpenSim/Framework/Tests/AgentCircuitManagerTests.cs
@@ -68,7 +68,7 @@ namespace OpenSim.Framework.Tests
68 68
69 m_agentCircuitData1 = new AgentCircuitData(); 69 m_agentCircuitData1 = new AgentCircuitData();
70 m_agentCircuitData1.AgentID = AgentId1; 70 m_agentCircuitData1.AgentID = AgentId1;
71 m_agentCircuitData1.Appearance = new AvatarAppearance(AgentId1); 71 m_agentCircuitData1.Appearance = new AvatarAppearance();
72 m_agentCircuitData1.BaseFolder = BaseFolder; 72 m_agentCircuitData1.BaseFolder = BaseFolder;
73 m_agentCircuitData1.CapsPath = CapsPath; 73 m_agentCircuitData1.CapsPath = CapsPath;
74 m_agentCircuitData1.child = false; 74 m_agentCircuitData1.child = false;
@@ -83,7 +83,7 @@ namespace OpenSim.Framework.Tests
83 83
84 m_agentCircuitData2 = new AgentCircuitData(); 84 m_agentCircuitData2 = new AgentCircuitData();
85 m_agentCircuitData2.AgentID = AgentId2; 85 m_agentCircuitData2.AgentID = AgentId2;
86 m_agentCircuitData2.Appearance = new AvatarAppearance(AgentId2); 86 m_agentCircuitData2.Appearance = new AvatarAppearance();
87 m_agentCircuitData2.BaseFolder = BaseFolder; 87 m_agentCircuitData2.BaseFolder = BaseFolder;
88 m_agentCircuitData2.CapsPath = CapsPath; 88 m_agentCircuitData2.CapsPath = CapsPath;
89 m_agentCircuitData2.child = false; 89 m_agentCircuitData2.child = false;
diff --git a/OpenSim/Framework/Tests/UtilTest.cs b/OpenSim/Framework/Tests/UtilTest.cs
index 5eac411..c5a20e7 100644
--- a/OpenSim/Framework/Tests/UtilTest.cs
+++ b/OpenSim/Framework/Tests/UtilTest.cs
@@ -61,7 +61,7 @@ namespace OpenSim.Framework.Tests
61 "Magnitude of vector was incorrect."); 61 "Magnitude of vector was incorrect.");
62 62
63 TestDelegate d = delegate() { Util.GetNormalizedVector(v1); }; 63 TestDelegate d = delegate() { Util.GetNormalizedVector(v1); };
64 bool causesArgumentException = TestHelper.AssertThisDelegateCausesArgumentException(d); 64 bool causesArgumentException = TestHelpers.AssertThisDelegateCausesArgumentException(d);
65 Assert.That(causesArgumentException, Is.True, 65 Assert.That(causesArgumentException, Is.True,
66 "Getting magnitude of null vector did not cause argument exception."); 66 "Getting magnitude of null vector did not cause argument exception.");
67 67
@@ -94,12 +94,12 @@ namespace OpenSim.Framework.Tests
94 "Magnitude of vector was incorrect."); 94 "Magnitude of vector was incorrect.");
95 95
96 TestDelegate d = delegate() { Util.GetNormalizedVector(v1); }; 96 TestDelegate d = delegate() { Util.GetNormalizedVector(v1); };
97 bool causesArgumentException = TestHelper.AssertThisDelegateCausesArgumentException(d); 97 bool causesArgumentException = TestHelpers.AssertThisDelegateCausesArgumentException(d);
98 Assert.That(causesArgumentException, Is.True, 98 Assert.That(causesArgumentException, Is.True,
99 "Getting magnitude of null vector did not cause argument exception."); 99 "Getting magnitude of null vector did not cause argument exception.");
100 100
101 d = delegate() { Util.GetNormalizedVector(v2); }; 101 d = delegate() { Util.GetNormalizedVector(v2); };
102 causesArgumentException = TestHelper.AssertThisDelegateCausesArgumentException(d); 102 causesArgumentException = TestHelpers.AssertThisDelegateCausesArgumentException(d);
103 Assert.That(causesArgumentException, Is.True, 103 Assert.That(causesArgumentException, Is.True,
104 "Getting magnitude of null vector did not cause argument exception."); 104 "Getting magnitude of null vector did not cause argument exception.");
105 } 105 }
@@ -122,7 +122,7 @@ namespace OpenSim.Framework.Tests
122 "Magnitude of vector was incorrect."); 122 "Magnitude of vector was incorrect.");
123 123
124 TestDelegate d = delegate() { Util.GetNormalizedVector(v1); }; 124 TestDelegate d = delegate() { Util.GetNormalizedVector(v1); };
125 bool causesArgumentException = TestHelper.AssertThisDelegateCausesArgumentException(d); 125 bool causesArgumentException = TestHelpers.AssertThisDelegateCausesArgumentException(d);
126 Assert.That(causesArgumentException, Is.True, 126 Assert.That(causesArgumentException, Is.True,
127 "Getting magnitude of null vector did not cause argument exception."); 127 "Getting magnitude of null vector did not cause argument exception.");
128 128
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index b8b1039..2d58807 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -56,8 +56,13 @@ namespace OpenSim.Framework
56 /// <summary> 56 /// <summary>
57 /// The method used by Util.FireAndForget for asynchronously firing events 57 /// The method used by Util.FireAndForget for asynchronously firing events
58 /// </summary> 58 /// </summary>
59 /// <remarks>
60 /// None is used to execute the method in the same thread that made the call. It should only be used by regression
61 /// test code that relies on predictable event ordering.
62 /// </remarks>
59 public enum FireAndForgetMethod 63 public enum FireAndForgetMethod
60 { 64 {
65 None,
61 UnsafeQueueUserWorkItem, 66 UnsafeQueueUserWorkItem,
62 QueueUserWorkItem, 67 QueueUserWorkItem,
63 BeginInvoke, 68 BeginInvoke,
@@ -89,7 +94,8 @@ namespace OpenSim.Framework
89 public static readonly Regex UUIDPattern 94 public static readonly Regex UUIDPattern
90 = new Regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"); 95 = new Regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$");
91 96
92 public static FireAndForgetMethod FireAndForgetMethod = FireAndForgetMethod.SmartThreadPool; 97 public static FireAndForgetMethod DefaultFireAndForgetMethod = FireAndForgetMethod.SmartThreadPool;
98 public static FireAndForgetMethod FireAndForgetMethod = DefaultFireAndForgetMethod;
93 99
94 /// <summary> 100 /// <summary>
95 /// Gets the name of the directory where the current running executable 101 /// Gets the name of the directory where the current running executable
@@ -1511,25 +1517,47 @@ namespace OpenSim.Framework
1511 1517
1512 public static void FireAndForget(System.Threading.WaitCallback callback, object obj) 1518 public static void FireAndForget(System.Threading.WaitCallback callback, object obj)
1513 { 1519 {
1520 // When OpenSim interacts with a database or sends data over the wire, it must send this in en_US culture
1521 // so that we don't encounter problems where, for instance, data is saved with a culture that uses commas
1522 // for decimals places but is read by a culture that treats commas as number seperators.
1523 WaitCallback realCallback = delegate(object o)
1524 {
1525 Culture.SetCurrentCulture();
1526
1527 try
1528 {
1529 callback(o);
1530 }
1531 catch (Exception e)
1532 {
1533 m_log.ErrorFormat(
1534 "[UTIL]: Continuing after async_call_method thread terminated with exception {0}{1}",
1535 e.Message, e.StackTrace);
1536 }
1537 };
1538
1514 switch (FireAndForgetMethod) 1539 switch (FireAndForgetMethod)
1515 { 1540 {
1541 case FireAndForgetMethod.None:
1542 realCallback.Invoke(obj);
1543 break;
1516 case FireAndForgetMethod.UnsafeQueueUserWorkItem: 1544 case FireAndForgetMethod.UnsafeQueueUserWorkItem:
1517 ThreadPool.UnsafeQueueUserWorkItem(callback, obj); 1545 ThreadPool.UnsafeQueueUserWorkItem(realCallback, obj);
1518 break; 1546 break;
1519 case FireAndForgetMethod.QueueUserWorkItem: 1547 case FireAndForgetMethod.QueueUserWorkItem:
1520 ThreadPool.QueueUserWorkItem(callback, obj); 1548 ThreadPool.QueueUserWorkItem(realCallback, obj);
1521 break; 1549 break;
1522 case FireAndForgetMethod.BeginInvoke: 1550 case FireAndForgetMethod.BeginInvoke:
1523 FireAndForgetWrapper wrapper = FireAndForgetWrapper.Instance; 1551 FireAndForgetWrapper wrapper = FireAndForgetWrapper.Instance;
1524 wrapper.FireAndForget(callback, obj); 1552 wrapper.FireAndForget(realCallback, obj);
1525 break; 1553 break;
1526 case FireAndForgetMethod.SmartThreadPool: 1554 case FireAndForgetMethod.SmartThreadPool:
1527 if (m_ThreadPool == null) 1555 if (m_ThreadPool == null)
1528 m_ThreadPool = new SmartThreadPool(2000, 15, 2); 1556 m_ThreadPool = new SmartThreadPool(2000, 15, 2);
1529 m_ThreadPool.QueueWorkItem(SmartThreadPoolCallback, new object[] { callback, obj }); 1557 m_ThreadPool.QueueWorkItem(SmartThreadPoolCallback, new object[] { realCallback, obj });
1530 break; 1558 break;
1531 case FireAndForgetMethod.Thread: 1559 case FireAndForgetMethod.Thread:
1532 Thread thread = new Thread(delegate(object o) { callback(o); }); 1560 Thread thread = new Thread(delegate(object o) { realCallback(o); });
1533 thread.Start(obj); 1561 thread.Start(obj);
1534 break; 1562 break;
1535 default: 1563 default:
diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs
index 90ab982..971c0b7 100644
--- a/OpenSim/Framework/WebUtil.cs
+++ b/OpenSim/Framework/WebUtil.cs
@@ -908,15 +908,6 @@ namespace OpenSim.Framework
908 } 908 }
909 } 909 }
910 910
911 public class SynchronousRestObjectPoster
912 {
913 [Obsolete]
914 public static TResponse BeginPostObject<TRequest, TResponse>(string verb, string requestUrl, TRequest obj)
915 {
916 return SynchronousRestObjectRequester.MakeRequest<TRequest, TResponse>(verb, requestUrl, obj);
917 }
918 }
919
920 public class SynchronousRestObjectRequester 911 public class SynchronousRestObjectRequester
921 { 912 {
922 private static readonly ILog m_log = 913 private static readonly ILog m_log =
@@ -989,9 +980,6 @@ namespace OpenSim.Framework
989 { 980 {
990 using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse()) 981 using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
991 { 982 {
992 if (resp.StatusCode == HttpStatusCode.NotFound)
993 return deserial;
994
995 if (resp.ContentLength != 0) 983 if (resp.ContentLength != 0)
996 { 984 {
997 Stream respStream = resp.GetResponseStream(); 985 Stream respStream = resp.GetResponseStream();
@@ -1001,9 +989,19 @@ namespace OpenSim.Framework
1001 } 989 }
1002 else 990 else
1003 m_log.DebugFormat("[SynchronousRestObjectRequester]: Oops! no content found in response stream from {0} {1}", requestUrl, verb); 991 m_log.DebugFormat("[SynchronousRestObjectRequester]: Oops! no content found in response stream from {0} {1}", requestUrl, verb);
1004
1005 } 992 }
1006 } 993 }
994 catch (WebException e)
995 {
996 HttpWebResponse hwr = (HttpWebResponse)e.Response;
997
998 if (hwr != null && hwr.StatusCode == HttpStatusCode.NotFound)
999 return deserial;
1000 else
1001 m_log.ErrorFormat(
1002 "[SynchronousRestObjectRequester]: WebException {0} {1} {2} {3}",
1003 requestUrl, typeof(TResponse).ToString(), e.Message, e.StackTrace);
1004 }
1007 catch (System.InvalidOperationException) 1005 catch (System.InvalidOperationException)
1008 { 1006 {
1009 // This is what happens when there is invalid XML 1007 // This is what happens when there is invalid XML
diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs
index 3b261e7..c130038 100644
--- a/OpenSim/Region/Application/Application.cs
+++ b/OpenSim/Region/Application/Application.cs
@@ -73,6 +73,7 @@ namespace OpenSim
73 AppDomain.CurrentDomain.UnhandledException += 73 AppDomain.CurrentDomain.UnhandledException +=
74 new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 74 new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
75 75
76
76 // Add the arguments supplied when running the application to the configuration 77 // Add the arguments supplied when running the application to the configuration
77 ArgvConfigSource configSource = new ArgvConfigSource(args); 78 ArgvConfigSource configSource = new ArgvConfigSource(args);
78 79
@@ -91,6 +92,9 @@ namespace OpenSim
91 m_log.Info("[OPENSIM MAIN]: configured log4net using default OpenSim.exe.config"); 92 m_log.Info("[OPENSIM MAIN]: configured log4net using default OpenSim.exe.config");
92 } 93 }
93 94
95 m_log.DebugFormat(
96 "[OPENSIM MAIN]: System Locale is {0}", System.Threading.Thread.CurrentThread.CurrentCulture);
97
94 // Increase the number of IOCP threads available. Mono defaults to a tragically low number 98 // Increase the number of IOCP threads available. Mono defaults to a tragically low number
95 int workerThreads, iocpThreads; 99 int workerThreads, iocpThreads;
96 System.Threading.ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads); 100 System.Threading.ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads);
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index 86975c9..fae8be7 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -130,7 +130,9 @@ namespace OpenSim
130 //m_log.InfoFormat("[OPENSIM MAIN]: GC Latency Mode: {0}", GCSettings.LatencyMode.ToString()); 130 //m_log.InfoFormat("[OPENSIM MAIN]: GC Latency Mode: {0}", GCSettings.LatencyMode.ToString());
131 131
132 if (m_gui) // Driven by external GUI 132 if (m_gui) // Driven by external GUI
133 {
133 m_console = new CommandConsole("Region"); 134 m_console = new CommandConsole("Region");
135 }
134 else 136 else
135 { 137 {
136 switch (m_consoleType) 138 switch (m_consoleType)
@@ -547,6 +549,7 @@ namespace OpenSim
547 { 549 {
548 string regionName = string.Empty; 550 string regionName = string.Empty;
549 string regionFile = string.Empty; 551 string regionFile = string.Empty;
552
550 if (cmd.Length == 3) 553 if (cmd.Length == 3)
551 { 554 {
552 regionFile = cmd[2]; 555 regionFile = cmd[2];
@@ -556,14 +559,17 @@ namespace OpenSim
556 regionName = cmd[2]; 559 regionName = cmd[2];
557 regionFile = cmd[3]; 560 regionFile = cmd[3];
558 } 561 }
562
559 string extension = Path.GetExtension(regionFile).ToLower(); 563 string extension = Path.GetExtension(regionFile).ToLower();
560 bool isXml = extension.Equals(".xml"); 564 bool isXml = extension.Equals(".xml");
561 bool isIni = extension.Equals(".ini"); 565 bool isIni = extension.Equals(".ini");
566
562 if (!isXml && !isIni) 567 if (!isXml && !isIni)
563 { 568 {
564 MainConsole.Instance.Output("Usage: create region [\"region name\"] <region_file.ini>"); 569 MainConsole.Instance.Output("Usage: create region [\"region name\"] <region_file.ini>");
565 return; 570 return;
566 } 571 }
572
567 if (!Path.IsPathRooted(regionFile)) 573 if (!Path.IsPathRooted(regionFile))
568 { 574 {
569 string regionsDir = ConfigSource.Source.Configs["Startup"].GetString("regionload_regionsdir", "Regions").Trim(); 575 string regionsDir = ConfigSource.Source.Configs["Startup"].GetString("regionload_regionsdir", "Regions").Trim();
@@ -580,8 +586,18 @@ namespace OpenSim
580 regInfo = new RegionInfo(regionName, regionFile, false, ConfigSource.Source, regionName); 586 regInfo = new RegionInfo(regionName, regionFile, false, ConfigSource.Source, regionName);
581 } 587 }
582 588
583 IScene scene; 589 Scene existingScene;
590 if (SceneManager.TryGetScene(regInfo.RegionID, out existingScene))
591 {
592 MainConsole.Instance.OutputFormat(
593 "ERROR: Cannot create region {0} with ID {1}, this ID is already assigned to region {2}",
594 regInfo.RegionName, regInfo.RegionID, existingScene.RegionInfo.RegionName);
595
596 return;
597 }
598
584 PopulateRegionEstateInfo(regInfo); 599 PopulateRegionEstateInfo(regInfo);
600 IScene scene;
585 CreateRegion(regInfo, true, out scene); 601 CreateRegion(regInfo, true, out scene);
586 regInfo.EstateSettings.Save(); 602 regInfo.EstateSettings.Save();
587 } 603 }
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
index d3bb0bc..d1ce5df 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
@@ -136,7 +136,6 @@ namespace OpenSim.Region.ClientStack.Linden
136 TaskScriptUpdatedCall = m_Scene.CapsUpdateTaskInventoryScriptAsset; 136 TaskScriptUpdatedCall = m_Scene.CapsUpdateTaskInventoryScriptAsset;
137 CAPSFetchInventoryDescendents = m_Scene.HandleFetchInventoryDescendentsCAPS; 137 CAPSFetchInventoryDescendents = m_Scene.HandleFetchInventoryDescendentsCAPS;
138 GetClient = m_Scene.SceneContents.GetControllingClient; 138 GetClient = m_Scene.SceneContents.GetControllingClient;
139
140 } 139 }
141 140
142 /// <summary> 141 /// <summary>
@@ -232,7 +231,7 @@ namespace OpenSim.Region.ClientStack.Linden
232 public string SeedCapRequest(string request, string path, string param, 231 public string SeedCapRequest(string request, string path, string param,
233 OSHttpRequest httpRequest, OSHttpResponse httpResponse) 232 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
234 { 233 {
235 m_log.Debug("[CAPS]: Seed Caps Request in region: " + m_regionName); 234// m_log.Debug("[CAPS]: Seed Caps Request in region: " + m_regionName);
236 235
237 if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint)) 236 if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
238 { 237 {
@@ -331,14 +330,22 @@ namespace OpenSim.Region.ClientStack.Linden
331 } 330 }
332 } 331 }
333 332
333 /// <summary>
334 /// Handle a request from the client for a Uri to upload a baked texture.
335 /// </summary>
336 /// <param name="request"></param>
337 /// <param name="path"></param>
338 /// <param name="param"></param>
339 /// <param name="httpRequest"></param>
340 /// <param name="httpResponse"></param>
341 /// <returns>The upload response if the request is successful, null otherwise.</returns>
334 public string UploadBakedTexture(string request, string path, 342 public string UploadBakedTexture(string request, string path,
335 string param, OSHttpRequest httpRequest, 343 string param, OSHttpRequest httpRequest,
336 OSHttpResponse httpResponse) 344 OSHttpResponse httpResponse)
337 { 345 {
338 try 346 try
339 { 347 {
340 // m_log.Debug("[CAPS]: UploadBakedTexture Request in region: " + 348// m_log.Debug("[CAPS]: UploadBakedTexture Request in region: " + m_regionName);
341 // m_regionName);
342 349
343 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath; 350 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
344 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); 351 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
@@ -374,6 +381,11 @@ namespace OpenSim.Region.ClientStack.Linden
374 return null; 381 return null;
375 } 382 }
376 383
384 /// <summary>
385 /// Called when a baked texture has been successfully uploaded by a client.
386 /// </summary>
387 /// <param name="assetID"></param>
388 /// <param name="data"></param>
377 public void BakedTextureUploaded(UUID assetID, byte[] data) 389 public void BakedTextureUploaded(UUID assetID, byte[] data)
378 { 390 {
379 // m_log.WarnFormat("[CAPS]: Received baked texture {0}", assetID.ToString()); 391 // m_log.WarnFormat("[CAPS]: Received baked texture {0}", assetID.ToString());
@@ -687,7 +699,7 @@ namespace OpenSim.Region.ClientStack.Linden
687 item.CurrentPermissions = (uint)PermissionMask.All; 699 item.CurrentPermissions = (uint)PermissionMask.All;
688 item.BasePermissions = (uint)PermissionMask.All; 700 item.BasePermissions = (uint)PermissionMask.All;
689 item.EveryOnePermissions = 0; 701 item.EveryOnePermissions = 0;
690 item.NextPermissions = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer); 702 item.NextPermissions = (uint)PermissionMask.All;
691 item.CreationDate = Util.UnixTimeSinceEpoch(); 703 item.CreationDate = Util.UnixTimeSinceEpoch();
692 704
693 if (AddNewInventoryItem != null) 705 if (AddNewInventoryItem != null)
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs
index 14160ae..66b865f 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs
@@ -48,8 +48,8 @@ namespace OpenSim.Region.ClientStack.Linden
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
49 public class BunchOfCapsModule : INonSharedRegionModule 49 public class BunchOfCapsModule : INonSharedRegionModule
50 { 50 {
51 private static readonly ILog m_log = 51// private static readonly ILog m_log =
52 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 52// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53 53
54 private Scene m_Scene; 54 private Scene m_Scene;
55 55
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
index e0807ee..e7bd2e7 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
@@ -50,8 +50,8 @@ namespace OpenSim.Region.ClientStack.Linden
50 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 50 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
51 public class GetMeshModule : INonSharedRegionModule 51 public class GetMeshModule : INonSharedRegionModule
52 { 52 {
53 private static readonly ILog m_log = 53// private static readonly ILog m_log =
54 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55 55
56 private Scene m_scene; 56 private Scene m_scene;
57 private IAssetService m_AssetService; 57 private IAssetService m_AssetService;
@@ -113,12 +113,12 @@ namespace OpenSim.Region.ClientStack.Linden
113 113
114 public void RegisterCaps(UUID agentID, Caps caps) 114 public void RegisterCaps(UUID agentID, Caps caps)
115 { 115 {
116 UUID capID = UUID.Random(); 116// UUID capID = UUID.Random();
117 117
118 //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); 118 //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture));
119 if (m_URL == "localhost") 119 if (m_URL == "localhost")
120 { 120 {
121 m_log.InfoFormat("[GETMESH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); 121// m_log.DebugFormat("[GETMESH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
122 GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService); 122 GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService);
123 IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), 123 IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(),
124 delegate(Hashtable m_dhttpMethod) 124 delegate(Hashtable m_dhttpMethod)
@@ -130,7 +130,7 @@ namespace OpenSim.Region.ClientStack.Linden
130 } 130 }
131 else 131 else
132 { 132 {
133 m_log.InfoFormat("[GETMESH]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName); 133// m_log.DebugFormat("[GETMESH]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName);
134 caps.RegisterHandler("GetMesh", m_URL); 134 caps.RegisterHandler("GetMesh", m_URL);
135 } 135 }
136 } 136 }
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
index 35eedb4..fffcee2 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
@@ -54,8 +54,9 @@ namespace OpenSim.Region.ClientStack.Linden
54 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 54 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
55 public class GetTextureModule : INonSharedRegionModule 55 public class GetTextureModule : INonSharedRegionModule
56 { 56 {
57 private static readonly ILog m_log = 57// private static readonly ILog m_log =
58 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 58// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59
59 private Scene m_scene; 60 private Scene m_scene;
60 private IAssetService m_assetService; 61 private IAssetService m_assetService;
61 62
@@ -128,12 +129,12 @@ namespace OpenSim.Region.ClientStack.Linden
128 //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); 129 //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture));
129 if (m_URL == "localhost") 130 if (m_URL == "localhost")
130 { 131 {
131 m_log.InfoFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); 132// m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
132 caps.RegisterHandler("GetTexture", new GetTextureHandler("/CAPS/" + capID + "/", m_assetService)); 133 caps.RegisterHandler("GetTexture", new GetTextureHandler("/CAPS/" + capID + "/", m_assetService));
133 } 134 }
134 else 135 else
135 { 136 {
136 m_log.InfoFormat("[GETTEXTURE]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName); 137// m_log.DebugFormat("[GETTEXTURE]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName);
137 caps.RegisterHandler("GetTexture", m_URL); 138 caps.RegisterHandler("GetTexture", m_URL);
138 } 139 }
139 } 140 }
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs
index c9d7ae1..18c7eae 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs
@@ -48,8 +48,8 @@ namespace OpenSim.Region.ClientStack.Linden
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
49 public class MeshUploadFlagModule : INonSharedRegionModule 49 public class MeshUploadFlagModule : INonSharedRegionModule
50 { 50 {
51 private static readonly ILog m_log = 51// private static readonly ILog m_log =
52 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 52// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53 53
54 /// <summary> 54 /// <summary>
55 /// Is this module enabled? 55 /// Is this module enabled?
@@ -124,7 +124,7 @@ namespace OpenSim.Region.ClientStack.Linden
124 124
125 private Hashtable MeshUploadFlag(Hashtable mDhttpMethod) 125 private Hashtable MeshUploadFlag(Hashtable mDhttpMethod)
126 { 126 {
127 m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: MeshUploadFlag request"); 127// m_log.DebugFormat("[MESH UPLOAD FLAG MODULE]: MeshUploadFlag request");
128 128
129 OSDMap data = new OSDMap(); 129 OSDMap data = new OSDMap();
130 ScenePresence sp = m_scene.GetScenePresence(m_agentID); 130 ScenePresence sp = m_scene.GetScenePresence(m_agentID);
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
index b7e79cc..b2f04f9 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
@@ -160,8 +160,6 @@ namespace OpenSim.Region.ClientStack.Linden
160 } 160 }
161 } 161 }
162 // } 162 // }
163
164
165 163
166 string assetName = llsdRequest.name; 164 string assetName = llsdRequest.name;
167 string assetDes = llsdRequest.description; 165 string assetDes = llsdRequest.description;
@@ -208,12 +206,10 @@ namespace OpenSim.Region.ClientStack.Linden
208 return uploadResponse; 206 return uploadResponse;
209 } 207 }
210 208
211
212 public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID, 209 public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID,
213 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType, 210 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
214 string assetType,UUID AgentID) 211 string assetType,UUID AgentID)
215 { 212 {
216
217 sbyte assType = 0; 213 sbyte assType = 0;
218 sbyte inType = 0; 214 sbyte inType = 0;
219 215
@@ -266,10 +262,10 @@ namespace OpenSim.Region.ClientStack.Linden
266 item.CurrentPermissions = (uint)PermissionMask.All; 262 item.CurrentPermissions = (uint)PermissionMask.All;
267 item.BasePermissions = (uint)PermissionMask.All; 263 item.BasePermissions = (uint)PermissionMask.All;
268 item.EveryOnePermissions = 0; 264 item.EveryOnePermissions = 0;
269 item.NextPermissions = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer); 265 item.NextPermissions = (uint)PermissionMask.All;
270 item.CreationDate = Util.UnixTimeSinceEpoch(); 266 item.CreationDate = Util.UnixTimeSinceEpoch();
271 m_scene.AddInventoryItem(item); 267 m_scene.AddInventoryItem(item);
272 268
273 } 269 }
274 } 270 }
275} 271} \ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs
index 15139a3..1c47f0e 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs
@@ -322,8 +322,6 @@ namespace OpenSim.Region.ClientStack.Linden
322 rootpart.NextOwnerMask = next_owner_mask; 322 rootpart.NextOwnerMask = next_owner_mask;
323 rootpart.Material = (byte)material; 323 rootpart.Material = (byte)material;
324 324
325
326
327 m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor); 325 m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor);
328 326
329 responsedata["int_response_code"] = 200; //501; //410; //404; 327 responsedata["int_response_code"] = 200; //501; //410; //404;
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
index 15ed3b3..c07fc73 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
@@ -129,7 +129,7 @@ namespace OpenSim.Region.ClientStack.Linden
129 129
130 130
131 /// <summary> 131 /// <summary>
132 /// Parses ad request 132 /// Parses add request
133 /// </summary> 133 /// </summary>
134 /// <param name="request"></param> 134 /// <param name="request"></param>
135 /// <param name="AgentId"></param> 135 /// <param name="AgentId"></param>
@@ -312,11 +312,11 @@ namespace OpenSim.Region.ClientStack.Linden
312 primFace.RepeatV = face.ScaleT; 312 primFace.RepeatV = face.ScaleT;
313 primFace.TexMapType = (MappingType) (face.MediaFlags & 6); 313 primFace.TexMapType = (MappingType) (face.MediaFlags & 6);
314 } 314 }
315
315 pbs.TextureEntry = tmp.GetBytes(); 316 pbs.TextureEntry = tmp.GetBytes();
316 prim.Shape = pbs; 317 prim.Shape = pbs;
317 prim.Scale = obj.Scale; 318 prim.Scale = obj.Scale;
318 319
319
320 SceneObjectGroup grp = new SceneObjectGroup(); 320 SceneObjectGroup grp = new SceneObjectGroup();
321 321
322 grp.SetRootPart(prim); 322 grp.SetRootPart(prim);
@@ -330,7 +330,7 @@ namespace OpenSim.Region.ClientStack.Linden
330 grp.AbsolutePosition = obj.Position; 330 grp.AbsolutePosition = obj.Position;
331 prim.RotationOffset = obj.Rotation; 331 prim.RotationOffset = obj.Rotation;
332 332
333 grp.RootPart.IsAttachment = false; 333 grp.IsAttachment = false;
334 // Required for linking 334 // Required for linking
335 grp.RootPart.UpdateFlag = 0; 335 grp.RootPart.UpdateFlag = 0;
336 336
@@ -339,8 +339,8 @@ namespace OpenSim.Region.ClientStack.Linden
339 m_scene.AddSceneObject(grp); 339 m_scene.AddSceneObject(grp);
340 grp.AbsolutePosition = obj.Position; 340 grp.AbsolutePosition = obj.Position;
341 } 341 }
342
342 allparts[i] = grp; 343 allparts[i] = grp;
343
344 } 344 }
345 345
346 for (int j = 1; j < allparts.Length; j++) 346 for (int j = 1; j < allparts.Length; j++)
@@ -351,7 +351,9 @@ namespace OpenSim.Region.ClientStack.Linden
351 } 351 }
352 352
353 rootGroup.ScheduleGroupForFullUpdate(); 353 rootGroup.ScheduleGroupForFullUpdate();
354 pos = m_scene.GetNewRezLocation(Vector3.Zero, rootpos, UUID.Zero, rot, (byte)1, 1, true, allparts[0].GroupScale(), false); 354 pos
355 = m_scene.GetNewRezLocation(
356 Vector3.Zero, rootpos, UUID.Zero, rot, (byte)1, 1, true, allparts[0].GroupScale, false);
355 357
356 responsedata["int_response_code"] = 200; //501; //410; //404; 358 responsedata["int_response_code"] = 200; //501; //410; //404;
357 responsedata["content_type"] = "text/plain"; 359 responsedata["content_type"] = "text/plain";
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs
index 9f78948..1dd8938 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs
@@ -43,21 +43,29 @@ using Caps = OpenSim.Framework.Capabilities.Caps;
43namespace OpenSim.Region.ClientStack.Linden 43namespace OpenSim.Region.ClientStack.Linden
44{ 44{
45 /// <summary> 45 /// <summary>
46 /// SimulatorFeatures capability. This is required for uploading Mesh. 46 /// SimulatorFeatures capability.
47 /// </summary>
48 /// <remarks>
49 /// This is required for uploading Mesh.
47 /// Since is accepts an open-ended response, we also send more information 50 /// Since is accepts an open-ended response, we also send more information
48 /// for viewers that care to interpret it. 51 /// for viewers that care to interpret it.
49 /// 52 ///
50 /// NOTE: Part of this code was adapted from the Aurora project, specifically 53 /// NOTE: Part of this code was adapted from the Aurora project, specifically
51 /// the normal part of the response in the capability handler. 54 /// the normal part of the response in the capability handler.
52 /// </summary> 55 /// </remarks>
53 ///
54 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 56 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
55 public class SimulatorFeaturesModule : ISharedRegionModule 57 public class SimulatorFeaturesModule : ISharedRegionModule, ISimulatorFeaturesModule
56 { 58 {
57 private static readonly ILog m_log = 59// private static readonly ILog m_log =
58 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 60// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
61
59 private Scene m_scene; 62 private Scene m_scene;
60 63
64 /// <summary>
65 /// Simulator features
66 /// </summary>
67 private OSDMap m_features = new OSDMap();
68
61 private string m_MapImageServerURL = string.Empty; 69 private string m_MapImageServerURL = string.Empty;
62 private string m_SearchURL = string.Empty; 70 private string m_SearchURL = string.Empty;
63 71
@@ -66,18 +74,20 @@ namespace OpenSim.Region.ClientStack.Linden
66 public void Initialise(IConfigSource source) 74 public void Initialise(IConfigSource source)
67 { 75 {
68 IConfig config = source.Configs["SimulatorFeatures"]; 76 IConfig config = source.Configs["SimulatorFeatures"];
69 if (config == null) 77 if (config != null)
70 return;
71
72 m_MapImageServerURL = config.GetString("MapImageServerURI", string.Empty);
73 if (m_MapImageServerURL != string.Empty)
74 { 78 {
75 m_MapImageServerURL = m_MapImageServerURL.Trim(); 79 m_MapImageServerURL = config.GetString("MapImageServerURI", string.Empty);
76 if (!m_MapImageServerURL.EndsWith("/")) 80 if (m_MapImageServerURL != string.Empty)
77 m_MapImageServerURL = m_MapImageServerURL + "/"; 81 {
82 m_MapImageServerURL = m_MapImageServerURL.Trim();
83 if (!m_MapImageServerURL.EndsWith("/"))
84 m_MapImageServerURL = m_MapImageServerURL + "/";
85 }
86
87 m_SearchURL = config.GetString("SearchServerURI", string.Empty);
78 } 88 }
79 89
80 m_SearchURL = config.GetString("SearchServerURI", string.Empty); 90 AddDefaultFeatures();
81 } 91 }
82 92
83 public void AddRegion(Scene s) 93 public void AddRegion(Scene s)
@@ -110,43 +120,83 @@ namespace OpenSim.Region.ClientStack.Linden
110 120
111 #endregion 121 #endregion
112 122
123 /// <summary>
124 /// Add default features
125 /// </summary>
126 /// <remarks>
127 /// TODO: These should be added from other modules rather than hardcoded.
128 /// </remarks>
129 private void AddDefaultFeatures()
130 {
131 lock (m_features)
132 {
133 m_features["MeshRezEnabled"] = true;
134 m_features["MeshUploadEnabled"] = true;
135 m_features["MeshXferEnabled"] = true;
136 m_features["PhysicsMaterialsEnabled"] = true;
137
138 OSDMap typesMap = new OSDMap();
139 typesMap["convex"] = true;
140 typesMap["none"] = true;
141 typesMap["prim"] = true;
142 m_features["PhysicsShapeTypes"] = typesMap;
143
144 // Extra information for viewers that want to use it
145 OSDMap gridServicesMap = new OSDMap();
146 if (m_MapImageServerURL != string.Empty)
147 gridServicesMap["map-server-url"] = m_MapImageServerURL;
148 if (m_SearchURL != string.Empty)
149 gridServicesMap["search"] = m_SearchURL;
150 m_features["GridServices"] = gridServicesMap;
151 }
152 }
153
113 public void RegisterCaps(UUID agentID, Caps caps) 154 public void RegisterCaps(UUID agentID, Caps caps)
114 { 155 {
115 IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), SimulatorFeatures); 156 IRequestHandler reqHandler
157 = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), HandleSimulatorFeaturesRequest);
158
116 caps.RegisterHandler("SimulatorFeatures", reqHandler); 159 caps.RegisterHandler("SimulatorFeatures", reqHandler);
117 } 160 }
118 161
119 private Hashtable SimulatorFeatures(Hashtable mDhttpMethod) 162 public void AddFeature(string name, OSD value)
120 { 163 {
121 m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: SimulatorFeatures request"); 164 lock (m_features)
122 OSDMap data = new OSDMap(); 165 m_features[name] = value;
123 data["MeshRezEnabled"] = true; 166 }
124 data["MeshUploadEnabled"] = true; 167
125 data["MeshXferEnabled"] = true; 168 public bool RemoveFeature(string name)
126 data["PhysicsMaterialsEnabled"] = true; 169 {
127 170 lock (m_features)
128 OSDMap typesMap = new OSDMap(); 171 return m_features.Remove(name);
129 typesMap["convex"] = true; 172 }
130 typesMap["none"] = true; 173
131 typesMap["prim"] = true; 174 public bool TryGetFeature(string name, out OSD value)
132 data["PhysicsShapeTypes"] = typesMap; 175 {
133 176 lock (m_features)
134 // Extra information for viewers that want to use it 177 return m_features.TryGetValue(name, out value);
135 OSDMap gridServicesMap = new OSDMap(); 178 }
136 if (m_MapImageServerURL != string.Empty) 179
137 gridServicesMap["map-server-url"] = m_MapImageServerURL; 180 public OSDMap GetFeatures()
138 if (m_SearchURL != string.Empty) 181 {
139 gridServicesMap["search"] = m_SearchURL; 182 lock (m_features)
140 data["GridServices"] = gridServicesMap; 183 return new OSDMap(m_features);
184 }
185
186 private Hashtable HandleSimulatorFeaturesRequest(Hashtable mDhttpMethod)
187 {
188// m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: SimulatorFeatures request");
141 189
142 //Send back data 190 //Send back data
143 Hashtable responsedata = new Hashtable(); 191 Hashtable responsedata = new Hashtable();
144 responsedata["int_response_code"] = 200; 192 responsedata["int_response_code"] = 200;
145 responsedata["content_type"] = "text/plain"; 193 responsedata["content_type"] = "text/plain";
146 responsedata["keepalive"] = false; 194 responsedata["keepalive"] = false;
147 responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(data); 195
196 lock (m_features)
197 responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(m_features);
198
148 return responsedata; 199 return responsedata;
149 } 200 }
150
151 } 201 }
152} 202}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index d5419cc..5c94fba 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -90,7 +90,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
90 public event ObjectAttach OnObjectAttach; 90 public event ObjectAttach OnObjectAttach;
91 public event ObjectDeselect OnObjectDetach; 91 public event ObjectDeselect OnObjectDetach;
92 public event ObjectDrop OnObjectDrop; 92 public event ObjectDrop OnObjectDrop;
93 public event GenericCall1 OnCompleteMovementToRegion; 93 public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
94 public event UpdateAgent OnPreAgentUpdate; 94 public event UpdateAgent OnPreAgentUpdate;
95 public event UpdateAgent OnAgentUpdate; 95 public event UpdateAgent OnAgentUpdate;
96 public event AgentRequestSit OnAgentRequestSit; 96 public event AgentRequestSit OnAgentRequestSit;
@@ -232,7 +232,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
232 public event ScriptReset OnScriptReset; 232 public event ScriptReset OnScriptReset;
233 public event GetScriptRunning OnGetScriptRunning; 233 public event GetScriptRunning OnGetScriptRunning;
234 public event SetScriptRunning OnSetScriptRunning; 234 public event SetScriptRunning OnSetScriptRunning;
235 public event UpdateVector OnAutoPilotGo; 235 public event Action<Vector3, bool> OnAutoPilotGo;
236 public event TerrainUnacked OnUnackedTerrain; 236 public event TerrainUnacked OnUnackedTerrain;
237 public event ActivateGesture OnActivateGesture; 237 public event ActivateGesture OnActivateGesture;
238 public event DeactivateGesture OnDeactivateGesture; 238 public event DeactivateGesture OnDeactivateGesture;
@@ -534,7 +534,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
534 m_udpServer.Flush(m_udpClient); 534 m_udpServer.Flush(m_udpClient);
535 535
536 // Remove ourselves from the scene 536 // Remove ourselves from the scene
537 m_scene.RemoveClient(AgentId); 537 m_scene.RemoveClient(AgentId, true);
538 538
539 // We can't reach into other scenes and close the connection 539 // We can't reach into other scenes and close the connection
540 // We need to do this over grid communications 540 // We need to do this over grid communications
@@ -596,22 +596,42 @@ namespace OpenSim.Region.ClientStack.LindenUDP
596 return result; 596 return result;
597 } 597 }
598 598
599 /// <summary>
600 /// Add a handler for the given packet type.
601 /// </summary>
602 /// <remarks>The packet is handled on its own thread. If packets must be handled in the order in which thye
603 /// are received then please us ethe synchronous version of this method.</remarks>
604 /// <param name="packetType"></param>
605 /// <param name="handler"></param>
606 /// <returns>true if the handler was added. This is currently always the case.</returns>
599 public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler) 607 public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler)
600 { 608 {
601 return AddLocalPacketHandler(packetType, handler, true); 609 return AddLocalPacketHandler(packetType, handler, true);
602 } 610 }
603 611
604 public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler, bool async) 612 /// <summary>
613 /// Add a handler for the given packet type.
614 /// </summary>
615 /// <param name="packetType"></param>
616 /// <param name="handler"></param>
617 /// <param name="doAsync">
618 /// If true, when the packet is received it is handled on its own thread rather than on the main inward bound
619 /// packet handler thread. This vastly increases respnosiveness but some packets need to be handled
620 /// synchronously.
621 /// </param>
622 /// <returns>true if the handler was added. This is currently always the case.</returns>
623 public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler, bool doAsync)
605 { 624 {
606 bool result = false; 625 bool result = false;
607 lock (m_packetHandlers) 626 lock (m_packetHandlers)
608 { 627 {
609 if (!m_packetHandlers.ContainsKey(packetType)) 628 if (!m_packetHandlers.ContainsKey(packetType))
610 { 629 {
611 m_packetHandlers.Add(packetType, new PacketProcessor() { method = handler, Async = async }); 630 m_packetHandlers.Add(packetType, new PacketProcessor() { method = handler, Async = doAsync });
612 result = true; 631 result = true;
613 } 632 }
614 } 633 }
634
615 return result; 635 return result;
616 } 636 }
617 637
@@ -694,7 +714,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
694 714
695 public virtual void Start() 715 public virtual void Start()
696 { 716 {
697 m_scene.AddNewClient(this); 717 m_scene.AddNewClient(this, PresenceType.User);
698 718
699 RefreshGroupMembership(); 719 RefreshGroupMembership();
700 } 720 }
@@ -4800,7 +4820,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4800 { 4820 {
4801 SceneObjectPart part = (SceneObjectPart)entity; 4821 SceneObjectPart part = (SceneObjectPart)entity;
4802 4822
4803 attachPoint = part.AttachmentPoint; 4823 attachPoint = part.ParentGroup.AttachmentPoint;
4824
4825// m_log.DebugFormat(
4826// "[LLCLIENTVIEW]: Sending attachPoint {0} for {1} {2} to {3}",
4827// attachPoint, part.Name, part.LocalId, Name);
4828
4804 collisionPlane = Vector4.Zero; 4829 collisionPlane = Vector4.Zero;
4805 position = part.RelativePosition; 4830 position = part.RelativePosition;
4806 velocity = part.Velocity; 4831 velocity = part.Velocity;
@@ -4957,17 +4982,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4957 //update.JointType = 0; 4982 //update.JointType = 0;
4958 update.Material = data.Material; 4983 update.Material = data.Material;
4959 update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim 4984 update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim
4960 if (data.IsAttachment) 4985 if (data.ParentGroup.IsAttachment)
4961 { 4986 {
4962 update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.FromItemID); 4987 update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.FromItemID);
4963 update.State = (byte)((data.AttachmentPoint % 16) * 16 + (data.AttachmentPoint / 16)); 4988 update.State = (byte)((data.ParentGroup.AttachmentPoint % 16) * 16 + (data.ParentGroup.AttachmentPoint / 16));
4964 } 4989 }
4965 else 4990 else
4966 { 4991 {
4967 update.NameValue = Utils.EmptyBytes; 4992 update.NameValue = Utils.EmptyBytes;
4968 update.State = data.Shape.State; 4993
4994 // The root part state is the canonical state for all parts of the object. The other part states in the
4995 // case for attachments may contain conflicting values that can end up crashing the viewer.
4996 update.State = data.ParentGroup.RootPart.Shape.State;
4969 } 4997 }
4970 4998
4999// m_log.DebugFormat(
5000// "[LLCLIENTVIEW]: Sending state {0} for {1} {2} to {3}",
5001// update.State, data.Name, data.LocalId, Name);
5002
4971 update.ObjectData = objectData; 5003 update.ObjectData = objectData;
4972 update.ParentID = data.ParentID; 5004 update.ParentID = data.ParentID;
4973 update.PathBegin = data.Shape.PathBegin; 5005 update.PathBegin = data.Shape.PathBegin;
@@ -5311,6 +5343,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5311 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5343 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5312 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5344 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5313 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5345 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5346
5347 AddGenericPacketHandler("autopilot", HandleAutopilot);
5314 } 5348 }
5315 5349
5316 #region Packet Handlers 5350 #region Packet Handlers
@@ -5354,7 +5388,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5354 ); 5388 );
5355 } 5389 }
5356 else 5390 else
5391 {
5357 update = true; 5392 update = true;
5393 }
5358 5394
5359 // These should be ordered from most-likely to 5395 // These should be ordered from most-likely to
5360 // least likely to change. I've made an initial 5396 // least likely to change. I've made an initial
@@ -5362,6 +5398,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5362 5398
5363 if (update) 5399 if (update)
5364 { 5400 {
5401// m_log.DebugFormat("[LLCLIENTVIEW]: Triggered AgentUpdate for {0}", sener.Name);
5402
5365 AgentUpdateArgs arg = new AgentUpdateArgs(); 5403 AgentUpdateArgs arg = new AgentUpdateArgs();
5366 arg.AgentID = x.AgentID; 5404 arg.AgentID = x.AgentID;
5367 arg.BodyRotation = x.BodyRotation; 5405 arg.BodyRotation = x.BodyRotation;
@@ -6235,10 +6273,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6235 6273
6236 private bool HandleCompleteAgentMovement(IClientAPI sender, Packet Pack) 6274 private bool HandleCompleteAgentMovement(IClientAPI sender, Packet Pack)
6237 { 6275 {
6238 GenericCall1 handlerCompleteMovementToRegion = OnCompleteMovementToRegion; 6276 Action<IClientAPI, bool> handlerCompleteMovementToRegion = OnCompleteMovementToRegion;
6239 if (handlerCompleteMovementToRegion != null) 6277 if (handlerCompleteMovementToRegion != null)
6240 { 6278 {
6241 handlerCompleteMovementToRegion(sender); 6279 handlerCompleteMovementToRegion(sender, true);
6242 } 6280 }
6243 handlerCompleteMovementToRegion = null; 6281 handlerCompleteMovementToRegion = null;
6244 6282
@@ -11316,8 +11354,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11316 protected bool HandleMultipleObjUpdate(IClientAPI simClient, Packet packet) 11354 protected bool HandleMultipleObjUpdate(IClientAPI simClient, Packet packet)
11317 { 11355 {
11318 MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket)packet; 11356 MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket)packet;
11319 if (multipleupdate.AgentData.SessionID != SessionId) return false; 11357
11320 // m_log.Debug("new multi update packet " + multipleupdate.ToString()); 11358 if (multipleupdate.AgentData.SessionID != SessionId)
11359 return false;
11360
11361// m_log.DebugFormat(
11362// "[CLIENT]: Incoming MultipleObjectUpdatePacket contained {0} blocks", multipleupdate.ObjectData.Length);
11363
11321 Scene tScene = (Scene)m_scene; 11364 Scene tScene = (Scene)m_scene;
11322 11365
11323 for (int i = 0; i < multipleupdate.ObjectData.Length; i++) 11366 for (int i = 0; i < multipleupdate.ObjectData.Length; i++)
@@ -11338,7 +11381,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11338 } 11381 }
11339 else 11382 else
11340 { 11383 {
11341 // UUID partId = part.UUID; 11384// m_log.DebugFormat(
11385// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11386// i, block.Type, part.Name, part.LocalId);
11387
11388// // Do this once since fetch parts creates a new array.
11389// SceneObjectPart[] parts = part.ParentGroup.Parts;
11390// for (int j = 0; j < parts.Length; j++)
11391// {
11392// part.StoreUndoState();
11393// parts[j].IgnoreUndoUpdate = true;
11394// }
11395
11342 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11396 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation;
11343 11397
11344 switch (block.Type) 11398 switch (block.Type)
@@ -11353,6 +11407,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11353 handlerUpdatePrimSinglePosition(localId, pos1, this); 11407 handlerUpdatePrimSinglePosition(localId, pos1, this);
11354 } 11408 }
11355 break; 11409 break;
11410
11356 case 2: 11411 case 2:
11357 Quaternion rot1 = new Quaternion(block.Data, 0, true); 11412 Quaternion rot1 = new Quaternion(block.Data, 0, true);
11358 11413
@@ -11363,6 +11418,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11363 handlerUpdatePrimSingleRotation(localId, rot1, this); 11418 handlerUpdatePrimSingleRotation(localId, rot1, this);
11364 } 11419 }
11365 break; 11420 break;
11421
11366 case 3: 11422 case 3:
11367 Vector3 rotPos = new Vector3(block.Data, 0); 11423 Vector3 rotPos = new Vector3(block.Data, 0);
11368 Quaternion rot2 = new Quaternion(block.Data, 12, true); 11424 Quaternion rot2 = new Quaternion(block.Data, 12, true);
@@ -11375,6 +11431,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11375 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this); 11431 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11376 } 11432 }
11377 break; 11433 break;
11434
11378 case 4: 11435 case 4:
11379 case 20: 11436 case 20:
11380 Vector3 scale4 = new Vector3(block.Data, 0); 11437 Vector3 scale4 = new Vector3(block.Data, 0);
@@ -11386,8 +11443,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11386 handlerUpdatePrimScale(localId, scale4, this); 11443 handlerUpdatePrimScale(localId, scale4, this);
11387 } 11444 }
11388 break; 11445 break;
11389 case 5:
11390 11446
11447 case 5:
11391 Vector3 scale1 = new Vector3(block.Data, 12); 11448 Vector3 scale1 = new Vector3(block.Data, 12);
11392 Vector3 pos11 = new Vector3(block.Data, 0); 11449 Vector3 pos11 = new Vector3(block.Data, 0);
11393 11450
@@ -11404,6 +11461,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11404 } 11461 }
11405 } 11462 }
11406 break; 11463 break;
11464
11407 case 9: 11465 case 9:
11408 Vector3 pos2 = new Vector3(block.Data, 0); 11466 Vector3 pos2 = new Vector3(block.Data, 0);
11409 11467
@@ -11411,10 +11469,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11411 11469
11412 if (handlerUpdateVector != null) 11470 if (handlerUpdateVector != null)
11413 { 11471 {
11414
11415 handlerUpdateVector(localId, pos2, this); 11472 handlerUpdateVector(localId, pos2, this);
11416 } 11473 }
11417 break; 11474 break;
11475
11418 case 10: 11476 case 10:
11419 Quaternion rot3 = new Quaternion(block.Data, 0, true); 11477 Quaternion rot3 = new Quaternion(block.Data, 0, true);
11420 11478
@@ -11425,6 +11483,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11425 handlerUpdatePrimRotation(localId, rot3, this); 11483 handlerUpdatePrimRotation(localId, rot3, this);
11426 } 11484 }
11427 break; 11485 break;
11486
11428 case 11: 11487 case 11:
11429 Vector3 pos3 = new Vector3(block.Data, 0); 11488 Vector3 pos3 = new Vector3(block.Data, 0);
11430 Quaternion rot4 = new Quaternion(block.Data, 12, true); 11489 Quaternion rot4 = new Quaternion(block.Data, 12, true);
@@ -11448,6 +11507,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11448 handlerUpdatePrimGroupScale(localId, scale7, this); 11507 handlerUpdatePrimGroupScale(localId, scale7, this);
11449 } 11508 }
11450 break; 11509 break;
11510
11451 case 13: 11511 case 13:
11452 Vector3 scale2 = new Vector3(block.Data, 12); 11512 Vector3 scale2 = new Vector3(block.Data, 12);
11453 Vector3 pos4 = new Vector3(block.Data, 0); 11513 Vector3 pos4 = new Vector3(block.Data, 0);
@@ -11467,6 +11527,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11467 } 11527 }
11468 } 11528 }
11469 break; 11529 break;
11530
11470 case 29: 11531 case 29:
11471 Vector3 scale5 = new Vector3(block.Data, 12); 11532 Vector3 scale5 = new Vector3(block.Data, 12);
11472 Vector3 pos5 = new Vector3(block.Data, 0); 11533 Vector3 pos5 = new Vector3(block.Data, 0);
@@ -11475,6 +11536,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11475 if (handlerUpdatePrimGroupScale != null) 11536 if (handlerUpdatePrimGroupScale != null)
11476 { 11537 {
11477 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 11538 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11539 part.StoreUndoState(true);
11540 part.IgnoreUndoUpdate = true;
11478 handlerUpdatePrimGroupScale(localId, scale5, this); 11541 handlerUpdatePrimGroupScale(localId, scale5, this);
11479 handlerUpdateVector = OnUpdatePrimGroupPosition; 11542 handlerUpdateVector = OnUpdatePrimGroupPosition;
11480 11543
@@ -11482,8 +11545,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11482 { 11545 {
11483 handlerUpdateVector(localId, pos5, this); 11546 handlerUpdateVector(localId, pos5, this);
11484 } 11547 }
11548
11549 part.IgnoreUndoUpdate = false;
11485 } 11550 }
11551
11486 break; 11552 break;
11553
11487 case 21: 11554 case 21:
11488 Vector3 scale6 = new Vector3(block.Data, 12); 11555 Vector3 scale6 = new Vector3(block.Data, 12);
11489 Vector3 pos6 = new Vector3(block.Data, 0); 11556 Vector3 pos6 = new Vector3(block.Data, 0);
@@ -11491,6 +11558,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11491 handlerUpdatePrimScale = OnUpdatePrimScale; 11558 handlerUpdatePrimScale = OnUpdatePrimScale;
11492 if (handlerUpdatePrimScale != null) 11559 if (handlerUpdatePrimScale != null)
11493 { 11560 {
11561 part.StoreUndoState(false);
11562 part.IgnoreUndoUpdate = true;
11563
11494 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 11564 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11495 handlerUpdatePrimScale(localId, scale6, this); 11565 handlerUpdatePrimScale(localId, scale6, this);
11496 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11566 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition;
@@ -11498,15 +11568,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11498 { 11568 {
11499 handlerUpdatePrimSinglePosition(localId, pos6, this); 11569 handlerUpdatePrimSinglePosition(localId, pos6, this);
11500 } 11570 }
11571
11572 part.IgnoreUndoUpdate = false;
11501 } 11573 }
11502 break; 11574 break;
11575
11503 default: 11576 default:
11504 m_log.Debug("[CLIENT] MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 11577 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
11505 break; 11578 break;
11506 } 11579 }
11580
11581// for (int j = 0; j < parts.Length; j++)
11582// parts[j].IgnoreUndoUpdate = false;
11507 } 11583 }
11508 } 11584 }
11509 } 11585 }
11586
11510 return true; 11587 return true;
11511 } 11588 }
11512 11589
@@ -11666,55 +11743,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11666 return false; 11743 return false;
11667 } 11744 }
11668 11745
11669 /// <summary> 11746 protected void HandleAutopilot(Object sender, string method, List<String> args)
11670 /// Breaks down the genericMessagePacket into specific events
11671 /// </summary>
11672 /// <param name="gmMethod"></param>
11673 /// <param name="gmInvoice"></param>
11674 /// <param name="gmParams"></param>
11675 public void DecipherGenericMessage(string gmMethod, UUID gmInvoice, GenericMessagePacket.ParamListBlock[] gmParams)
11676 { 11747 {
11677 switch (gmMethod) 11748 float locx = 0;
11678 { 11749 float locy = 0;
11679 case "autopilot": 11750 float locz = 0;
11680 float locx; 11751 uint regionX = 0;
11681 float locy; 11752 uint regionY = 0;
11682 float locz;
11683
11684 try
11685 {
11686 uint regionX;
11687 uint regionY;
11688 Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY);
11689 locx = Convert.ToSingle(Utils.BytesToString(gmParams[0].Parameter)) - regionX;
11690 locy = Convert.ToSingle(Utils.BytesToString(gmParams[1].Parameter)) - regionY;
11691 locz = Convert.ToSingle(Utils.BytesToString(gmParams[2].Parameter));
11692 }
11693 catch (InvalidCastException)
11694 {
11695 m_log.Error("[CLIENT]: Invalid autopilot request");
11696 return;
11697 }
11698
11699 UpdateVector handlerAutoPilotGo = OnAutoPilotGo;
11700 if (handlerAutoPilotGo != null)
11701 {
11702 handlerAutoPilotGo(0, new Vector3(locx, locy, locz), this);
11703 }
11704 m_log.InfoFormat("[CLIENT]: Client Requests autopilot to position <{0},{1},{2}>", locx, locy, locz);
11705 11753
11754 Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out regionX, out regionY);
11755 locx = Convert.ToSingle(args[0]) - (float)regionX;
11756 locy = Convert.ToSingle(args[1]) - (float)regionY;
11757 locz = Convert.ToSingle(args[2]);
11706 11758
11707 break; 11759 Action<Vector3, bool> handlerAutoPilotGo = OnAutoPilotGo;
11708 default: 11760 if (handlerAutoPilotGo != null)
11709 m_log.Debug("[CLIENT]: Unknown Generic Message, Method: " + gmMethod + ". Invoice: " + gmInvoice + ". Dumping Params:"); 11761 handlerAutoPilotGo(new Vector3(locx, locy, locz), false);
11710 for (int hi = 0; hi < gmParams.Length; hi++)
11711 {
11712 Console.WriteLine(gmParams[hi].ToString());
11713 }
11714 //gmpack.MethodData.
11715 break;
11716
11717 }
11718 } 11762 }
11719 11763
11720 /// <summary> 11764 /// <summary>
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
index 29fd1a4..4c33db5 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
@@ -44,7 +44,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 private static Int32 m_counter = 0; 45 private static Int32 m_counter = 0;
46 46
47 private Int32 m_identifier; 47// private Int32 m_identifier;
48 48
49 /// <summary> 49 /// <summary>
50 /// Number of ticks (ms) per quantum, drip rate and max burst 50 /// Number of ticks (ms) per quantum, drip rate and max burst
@@ -173,7 +173,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
173 /// second. If zero, the bucket always remains full</param> 173 /// second. If zero, the bucket always remains full</param>
174 public TokenBucket(TokenBucket parent, Int64 dripRate) 174 public TokenBucket(TokenBucket parent, Int64 dripRate)
175 { 175 {
176 m_identifier = m_counter++; 176// m_identifier = m_counter++;
177 m_counter++;
177 178
178 Parent = parent; 179 Parent = parent;
179 RequestedDripRate = dripRate; 180 RequestedDripRate = dripRate;
@@ -320,7 +321,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
320 321
321 public class AdaptiveTokenBucket : TokenBucket 322 public class AdaptiveTokenBucket : TokenBucket
322 { 323 {
323 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 324// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
324 325
325 /// <summary> 326 /// <summary>
326 /// The minimum rate for flow control. Minimum drip rate is one 327 /// The minimum rate for flow control. Minimum drip rate is one
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index d85d727..a0648f7 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -316,6 +316,12 @@ namespace Flotsam.RegionModules.AssetCache
316 LogException(e); 316 LogException(e);
317 } 317 }
318 } 318 }
319 catch (Exception e)
320 {
321 m_log.ErrorFormat(
322 "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
323 asset.ID, e.Message, e.StackTrace);
324 }
319 } 325 }
320 326
321 public void Cache(AssetBase asset) 327 public void Cache(AssetBase asset)
@@ -368,13 +374,13 @@ namespace Flotsam.RegionModules.AssetCache
368 374
369 asset = (AssetBase)bformatter.Deserialize(stream); 375 asset = (AssetBase)bformatter.Deserialize(stream);
370 376
371 UpdateMemoryCache(id, asset);
372
373 m_DiskHits++; 377 m_DiskHits++;
374 } 378 }
375 catch (System.Runtime.Serialization.SerializationException e) 379 catch (System.Runtime.Serialization.SerializationException e)
376 { 380 {
377 LogException(e); 381 m_log.ErrorFormat(
382 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
383 filename, id, e.Message, e.StackTrace);
378 384
379 // If there was a problem deserializing the asset, the asset may 385 // If there was a problem deserializing the asset, the asset may
380 // either be corrupted OR was serialized under an old format 386 // either be corrupted OR was serialized under an old format
@@ -384,7 +390,9 @@ namespace Flotsam.RegionModules.AssetCache
384 } 390 }
385 catch (Exception e) 391 catch (Exception e)
386 { 392 {
387 LogException(e); 393 m_log.ErrorFormat(
394 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
395 filename, id, e.Message, e.StackTrace);
388 } 396 }
389 finally 397 finally
390 { 398 {
@@ -393,7 +401,6 @@ namespace Flotsam.RegionModules.AssetCache
393 } 401 }
394 } 402 }
395 403
396
397#if WAIT_ON_INPROGRESS_REQUESTS 404#if WAIT_ON_INPROGRESS_REQUESTS
398 // Check if we're already downloading this asset. If so, try to wait for it to 405 // Check if we're already downloading this asset. If so, try to wait for it to
399 // download. 406 // download.
@@ -416,7 +423,6 @@ namespace Flotsam.RegionModules.AssetCache
416 m_RequestsForInprogress++; 423 m_RequestsForInprogress++;
417 } 424 }
418#endif 425#endif
419
420 return asset; 426 return asset;
421 } 427 }
422 428
@@ -428,9 +434,15 @@ namespace Flotsam.RegionModules.AssetCache
428 434
429 if (m_MemoryCacheEnabled) 435 if (m_MemoryCacheEnabled)
430 asset = GetFromMemoryCache(id); 436 asset = GetFromMemoryCache(id);
431 else if (m_FileCacheEnabled) 437
438 if (asset == null && m_FileCacheEnabled)
439 {
432 asset = GetFromFileCache(id); 440 asset = GetFromFileCache(id);
433 441
442 if (m_MemoryCacheEnabled && asset != null)
443 UpdateMemoryCache(id, asset);
444 }
445
434 if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0)) 446 if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0))
435 { 447 {
436 m_HitRateFile = (double)m_DiskHits / m_Requests * 100.0; 448 m_HitRateFile = (double)m_DiskHits / m_Requests * 100.0;
@@ -445,7 +457,6 @@ namespace Flotsam.RegionModules.AssetCache
445 } 457 }
446 458
447 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} unnessesary requests due to requests for assets that are currently downloading.", m_RequestsForInprogress); 459 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} unnessesary requests due to requests for assets that are currently downloading.", m_RequestsForInprogress);
448
449 } 460 }
450 461
451 return asset; 462 return asset;
@@ -459,7 +470,7 @@ namespace Flotsam.RegionModules.AssetCache
459 public void Expire(string id) 470 public void Expire(string id)
460 { 471 {
461 if (m_LogLevel >= 2) 472 if (m_LogLevel >= 2)
462 m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Expiring Asset {0}.", id); 473 m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Expiring Asset {0}", id);
463 474
464 try 475 try
465 { 476 {
@@ -477,7 +488,9 @@ namespace Flotsam.RegionModules.AssetCache
477 } 488 }
478 catch (Exception e) 489 catch (Exception e)
479 { 490 {
480 LogException(e); 491 m_log.ErrorFormat(
492 "[FLOTSAM ASSET CACHE]: Failed to expire cached file {0}. Exception {1} {2}",
493 id, e.Message, e.StackTrace);
481 } 494 }
482 } 495 }
483 496
@@ -597,31 +610,59 @@ namespace Flotsam.RegionModules.AssetCache
597 610
598 try 611 try
599 { 612 {
600 if (!Directory.Exists(directory)) 613 try
601 { 614 {
602 Directory.CreateDirectory(directory); 615 if (!Directory.Exists(directory))
616 {
617 Directory.CreateDirectory(directory);
618 }
619
620 stream = File.Open(tempname, FileMode.Create);
621 BinaryFormatter bformatter = new BinaryFormatter();
622 bformatter.Serialize(stream, asset);
603 } 623 }
624 catch (IOException e)
625 {
626 m_log.ErrorFormat(
627 "[FLOTSAM ASSET CACHE]: Failed to write asset {0} to temporary location {1} (final {2}) on cache in {3}. Exception {4} {5}.",
628 asset.ID, tempname, filename, directory, e.Message, e.StackTrace);
604 629
605 stream = File.Open(tempname, FileMode.Create); 630 return;
606 BinaryFormatter bformatter = new BinaryFormatter(); 631 }
607 bformatter.Serialize(stream, asset); 632 finally
608 stream.Close(); 633 {
609 634 if (stream != null)
610 // Now that it's written, rename it so that it can be found. 635 stream.Close();
611 File.Move(tempname, filename); 636 }
612 637
613 if (m_LogLevel >= 2) 638 try
614 m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Cache Stored :: {0}", asset.ID); 639 {
615 } 640 // Now that it's written, rename it so that it can be found.
616 catch (Exception e) 641 //
617 { 642 // File.Copy(tempname, filename, true);
618 LogException(e); 643 // File.Delete(tempname);
644 //
645 // For a brief period, this was done as a separate copy and then temporary file delete operation to
646 // avoid an IOException caused by move if some competing thread had already written the file.
647 // However, this causes exceptions on Windows when other threads attempt to read a file
648 // which is still being copied. So instead, go back to moving the file and swallow any IOException.
649 //
650 // This situation occurs fairly rarely anyway. We assume in this that moves are atomic on the
651 // filesystem.
652 File.Move(tempname, filename);
653
654 if (m_LogLevel >= 2)
655 m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Cache Stored :: {0}", asset.ID);
656 }
657 catch (IOException)
658 {
659 // If we see an IOException here it's likely that some other competing thread has written the
660 // cache file first, so ignore. Other IOException errors (e.g. filesystem full) should be
661 // signally by the earlier temporary file writing code.
662 }
619 } 663 }
620 finally 664 finally
621 { 665 {
622 if (stream != null)
623 stream.Close();
624
625 // Even if the write fails with an exception, we need to make sure 666 // Even if the write fails with an exception, we need to make sure
626 // that we release the lock on that file, otherwise it'll never get 667 // that we release the lock on that file, otherwise it'll never get
627 // cached 668 // cached
@@ -635,22 +676,9 @@ namespace Flotsam.RegionModules.AssetCache
635 waitEvent.Set(); 676 waitEvent.Set();
636 } 677 }
637#else 678#else
638 if (m_CurrentlyWriting.Contains(filename)) 679 m_CurrentlyWriting.Remove(filename);
639 {
640 m_CurrentlyWriting.Remove(filename);
641 }
642#endif 680#endif
643 } 681 }
644
645 }
646 }
647
648 private static void LogException(Exception e)
649 {
650 string[] text = e.ToString().Split(new char[] { '\n' });
651 foreach (string t in text)
652 {
653 m_log.ErrorFormat("[FLOTSAM ASSET CACHE]: {0} ", t);
654 } 682 }
655 } 683 }
656 684
@@ -706,8 +734,7 @@ namespace Flotsam.RegionModules.AssetCache
706 s.ForEachSOG(delegate(SceneObjectGroup e) 734 s.ForEachSOG(delegate(SceneObjectGroup e)
707 { 735 {
708 gatherer.GatherAssetUuids(e, assets); 736 gatherer.GatherAssetUuids(e, assets);
709 } 737 });
710 );
711 } 738 }
712 739
713 foreach (UUID assetID in assets.Keys) 740 foreach (UUID assetID in assets.Keys)
@@ -740,7 +767,9 @@ namespace Flotsam.RegionModules.AssetCache
740 } 767 }
741 catch (Exception e) 768 catch (Exception e)
742 { 769 {
743 LogException(e); 770 m_log.ErrorFormat(
771 "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache directory {0} from {1}. Exception {2} {3}",
772 dir, m_CacheDirectory, e.Message, e.StackTrace);
744 } 773 }
745 } 774 }
746 775
@@ -752,7 +781,9 @@ namespace Flotsam.RegionModules.AssetCache
752 } 781 }
753 catch (Exception e) 782 catch (Exception e)
754 { 783 {
755 LogException(e); 784 m_log.ErrorFormat(
785 "[FLOTSAM ASSET CACHE]: Couldn't clear asset cache file {0} from {1}. Exception {1} {2}",
786 file, m_CacheDirectory, e.Message, e.StackTrace);
756 } 787 }
757 } 788 }
758 } 789 }
@@ -778,7 +809,7 @@ namespace Flotsam.RegionModules.AssetCache
778 809
779 foreach (string s in Directory.GetFiles(m_CacheDirectory, "*.fac")) 810 foreach (string s in Directory.GetFiles(m_CacheDirectory, "*.fac"))
780 { 811 {
781 m_log.Info("[FLOTSAM ASSET CACHE]: Deep Scans were performed on the following regions:"); 812 m_log.Info("[FLOTSAM ASSET CACHE]: Deep scans have previously been performed on the following regions:");
782 813
783 string RegionID = s.Remove(0,s.IndexOf("_")).Replace(".fac",""); 814 string RegionID = s.Remove(0,s.IndexOf("_")).Replace(".fac","");
784 DateTime RegionDeepScanTMStamp = File.GetLastWriteTime(s); 815 DateTime RegionDeepScanTMStamp = File.GetLastWriteTime(s);
@@ -849,7 +880,6 @@ namespace Flotsam.RegionModules.AssetCache
849 Util.FireAndForget(delegate { 880 Util.FireAndForget(delegate {
850 int assetsCached = CacheScenes(); 881 int assetsCached = CacheScenes();
851 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Completed Scene Caching, {0} assets found.", assetsCached); 882 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Completed Scene Caching, {0} assets found.", assetsCached);
852
853 }); 883 });
854 884
855 break; 885 break;
@@ -904,7 +934,6 @@ namespace Flotsam.RegionModules.AssetCache
904 934
905 #region IAssetService Members 935 #region IAssetService Members
906 936
907
908 public AssetMetadata GetMetadata(string id) 937 public AssetMetadata GetMetadata(string id)
909 { 938 {
910 AssetBase asset = Get(id); 939 AssetBase asset = Get(id);
@@ -934,7 +963,6 @@ namespace Flotsam.RegionModules.AssetCache
934 Cache(asset); 963 Cache(asset);
935 964
936 return asset.ID; 965 return asset.ID;
937
938 } 966 }
939 967
940 public bool UpdateContent(string id, byte[] data) 968 public bool UpdateContent(string id, byte[] data)
diff --git a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs
index 63b0c31..2ff1920 100644
--- a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs
+++ b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs
@@ -65,18 +65,18 @@ namespace OpenSim.Region.CoreModules.Asset.Tests
65 config.Configs["AssetCache"].Set("MemoryCacheEnabled", "true"); 65 config.Configs["AssetCache"].Set("MemoryCacheEnabled", "true");
66 66
67 m_cache = new FlotsamAssetCache(); 67 m_cache = new FlotsamAssetCache();
68 m_scene = SceneSetupHelpers.SetupScene(); 68 m_scene = SceneHelpers.SetupScene();
69 SceneSetupHelpers.SetupSceneModules(m_scene, config, m_cache); 69 SceneHelpers.SetupSceneModules(m_scene, config, m_cache);
70 } 70 }
71 71
72 [Test] 72 [Test]
73 public void TestCacheAsset() 73 public void TestCacheAsset()
74 { 74 {
75 TestHelper.InMethod(); 75 TestHelpers.InMethod();
76// log4net.Config.XmlConfigurator.Configure(); 76// log4net.Config.XmlConfigurator.Configure();
77 77
78 AssetBase asset = AssetHelpers.CreateAsset(); 78 AssetBase asset = AssetHelpers.CreateAsset();
79 asset.ID = TestHelper.ParseTail(0x1).ToString(); 79 asset.ID = TestHelpers.ParseTail(0x1).ToString();
80 80
81 // Check we don't get anything before the asset is put in the cache 81 // Check we don't get anything before the asset is put in the cache
82 AssetBase retrievedAsset = m_cache.Get(asset.ID.ToString()); 82 AssetBase retrievedAsset = m_cache.Get(asset.ID.ToString());
@@ -93,11 +93,11 @@ namespace OpenSim.Region.CoreModules.Asset.Tests
93 [Test] 93 [Test]
94 public void TestExpireAsset() 94 public void TestExpireAsset()
95 { 95 {
96 TestHelper.InMethod(); 96 TestHelpers.InMethod();
97// log4net.Config.XmlConfigurator.Configure(); 97// log4net.Config.XmlConfigurator.Configure();
98 98
99 AssetBase asset = AssetHelpers.CreateAsset(); 99 AssetBase asset = AssetHelpers.CreateAsset();
100 asset.ID = TestHelper.ParseTail(0x2).ToString(); 100 asset.ID = TestHelpers.ParseTail(0x2).ToString();
101 101
102 m_cache.Store(asset); 102 m_cache.Store(asset);
103 103
@@ -110,11 +110,11 @@ namespace OpenSim.Region.CoreModules.Asset.Tests
110 [Test] 110 [Test]
111 public void TestClearCache() 111 public void TestClearCache()
112 { 112 {
113 TestHelper.InMethod(); 113 TestHelpers.InMethod();
114// log4net.Config.XmlConfigurator.Configure(); 114// log4net.Config.XmlConfigurator.Configure();
115 115
116 AssetBase asset = AssetHelpers.CreateAsset(); 116 AssetBase asset = AssetHelpers.CreateAsset();
117 asset.ID = TestHelper.ParseTail(0x2).ToString(); 117 asset.ID = TestHelpers.ParseTail(0x2).ToString();
118 118
119 m_cache.Store(asset); 119 m_cache.Store(asset);
120 120
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 47476a9..8be0455 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -47,7 +47,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
47 { 47 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49 49
50 protected Scene m_scene = null; 50 private Scene m_scene;
51 private IDialogModule m_dialogModule;
51 52
52 public string Name { get { return "Attachments Module"; } } 53 public string Name { get { return "Attachments Module"; } }
53 public Type ReplaceableInterface { get { return null; } } 54 public Type ReplaceableInterface { get { return null; } }
@@ -57,6 +58,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
57 public void AddRegion(Scene scene) 58 public void AddRegion(Scene scene)
58 { 59 {
59 m_scene = scene; 60 m_scene = scene;
61 m_dialogModule = m_scene.RequestModuleInterface<IDialogModule>();
60 m_scene.RegisterModuleInterface<IAttachmentsModule>(this); 62 m_scene.RegisterModuleInterface<IAttachmentsModule>(this);
61 m_scene.EventManager.OnNewClient += SubscribeToClientEvents; 63 m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
62 // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI 64 // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI
@@ -81,7 +83,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
81 client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachmentsFromInventory; 83 client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachmentsFromInventory;
82 client.OnObjectAttach += AttachObject; 84 client.OnObjectAttach += AttachObject;
83 client.OnObjectDetach += DetachObject; 85 client.OnObjectDetach += DetachObject;
84 client.OnDetachAttachmentIntoInv += ShowDetachInUserInventory; 86 client.OnDetachAttachmentIntoInv += DetachSingleAttachmentToInv;
87 client.OnObjectDrop += DetachSingleAttachmentToGround;
85 } 88 }
86 89
87 public void UnsubscribeFromClientEvents(IClientAPI client) 90 public void UnsubscribeFromClientEvents(IClientAPI client)
@@ -90,7 +93,77 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
90 client.OnRezMultipleAttachmentsFromInv -= RezMultipleAttachmentsFromInventory; 93 client.OnRezMultipleAttachmentsFromInv -= RezMultipleAttachmentsFromInventory;
91 client.OnObjectAttach -= AttachObject; 94 client.OnObjectAttach -= AttachObject;
92 client.OnObjectDetach -= DetachObject; 95 client.OnObjectDetach -= DetachObject;
93 client.OnDetachAttachmentIntoInv -= ShowDetachInUserInventory; 96 client.OnDetachAttachmentIntoInv -= DetachSingleAttachmentToInv;
97 client.OnObjectDrop -= DetachSingleAttachmentToGround;
98 }
99
100 /// <summary>
101 /// RezAttachments. This should only be called upon login on the first region.
102 /// Attachment rezzings on crossings and TPs are done in a different way.
103 /// </summary>
104 public void RezAttachments(IScenePresence sp)
105 {
106 if (null == sp.Appearance)
107 {
108 m_log.WarnFormat("[ATTACHMENTS MODULE]: Appearance has not been initialized for agent {0}", sp.UUID);
109 return;
110 }
111
112 List<AvatarAttachment> attachments = sp.Appearance.GetAttachments();
113 foreach (AvatarAttachment attach in attachments)
114 {
115 uint p = (uint)attach.AttachPoint;
116
117// m_log.DebugFormat(
118// "[ATTACHMENTS MODULE]: Doing initial rez of attachment with itemID {0}, assetID {1}, point {2} for {3} in {4}",
119// attach.ItemID, attach.AssetID, p, sp.Name, m_scene.RegionInfo.RegionName);
120
121 // For some reason assetIDs are being written as Zero's in the DB -- need to track tat down
122 // But they're not used anyway, the item is being looked up for now, so let's proceed.
123 //if (UUID.Zero == assetID)
124 //{
125 // m_log.DebugFormat("[ATTACHMENT]: Cannot rez attachment in point {0} with itemID {1}", p, itemID);
126 // continue;
127 //}
128
129 try
130 {
131 // If we're an NPC then skip all the item checks and manipulations since we don't have an
132 // inventory right now.
133 if (sp.PresenceType == PresenceType.Npc)
134 RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p);
135 else
136 RezSingleAttachmentFromInventory(sp.ControllingClient, attach.ItemID, p);
137 }
138 catch (Exception e)
139 {
140 m_log.ErrorFormat("[ATTACHMENTS MODULE]: Unable to rez attachment: {0}{1}", e.Message, e.StackTrace);
141 }
142 }
143 }
144
145 public void SaveChangedAttachments(IScenePresence sp)
146 {
147 foreach (SceneObjectGroup grp in sp.GetAttachments())
148 {
149 if (grp.HasGroupChanged) // Resizer scripts?
150 {
151 grp.IsAttachment = false;
152 grp.AbsolutePosition = grp.RootPart.AttachedPos;
153 UpdateKnownItem(sp.ControllingClient, grp, grp.GetFromItemID(), grp.OwnerID);
154 grp.IsAttachment = true;
155 }
156 }
157 }
158
159 public void DeleteAttachmentsFromScene(IScenePresence sp, bool silent)
160 {
161 foreach (SceneObjectGroup sop in sp.GetAttachments())
162 {
163 sop.Scene.DeleteSceneObject(sop, silent);
164 }
165
166 sp.ClearAttachments();
94 } 167 }
95 168
96 /// <summary> 169 /// <summary>
@@ -102,10 +175,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
102 /// <param name="silent"></param> 175 /// <param name="silent"></param>
103 public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) 176 public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent)
104 { 177 {
105 m_log.Debug("[ATTACHMENTS MODULE]: Invoking AttachObject"); 178// m_log.DebugFormat(
179// "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})",
180// objectLocalID, remoteClient.Name, AttachmentPt, silent);
106 181
107 try 182 try
108 { 183 {
184 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
185
186 if (sp == null)
187 {
188 m_log.ErrorFormat(
189 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId);
190 return;
191 }
192
109 // If we can't take it, we can't attach it! 193 // If we can't take it, we can't attach it!
110 SceneObjectPart part = m_scene.GetSceneObjectPart(objectLocalID); 194 SceneObjectPart part = m_scene.GetSceneObjectPart(objectLocalID);
111 if (part == null) 195 if (part == null)
@@ -131,7 +215,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
131 AttachmentPt &= 0x7f; 215 AttachmentPt &= 0x7f;
132 216
133 // Calls attach with a Zero position 217 // Calls attach with a Zero position
134 if (AttachObject(remoteClient, part.ParentGroup, AttachmentPt, false)) 218 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false))
135 { 219 {
136 m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); 220 m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
137 221
@@ -144,73 +228,94 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
144 } 228 }
145 catch (Exception e) 229 catch (Exception e)
146 { 230 {
147 m_log.DebugFormat("[ATTACHMENTS MODULE]: exception upon Attach Object {0}", e); 231 m_log.ErrorFormat("[ATTACHMENTS MODULE]: exception upon Attach Object {0}{1}", e.Message, e.StackTrace);
148 } 232 }
149 } 233 }
150 234
151 public bool AttachObject(IClientAPI remoteClient, SceneObjectGroup group, uint AttachmentPt, bool silent) 235 public bool AttachObject(IClientAPI remoteClient, SceneObjectGroup group, uint AttachmentPt, bool silent)
152 { 236 {
237 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
238
239 if (sp == null)
240 {
241 m_log.ErrorFormat(
242 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId);
243 return false;
244 }
245
246 return AttachObject(sp, group, AttachmentPt, silent);
247 }
248
249 private bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent)
250 {
251// m_log.DebugFormat(
252// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})",
253// group.Name, group.LocalId, sp.Name, AttachmentPt, silent);
254
255 if (sp.GetAttachments(attachmentPt).Contains(group))
256 {
257// m_log.WarnFormat(
258// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
259// group.Name, group.LocalId, sp.Name, AttachmentPt);
260
261 return false;
262 }
263
153 Vector3 attachPos = group.AbsolutePosition; 264 Vector3 attachPos = group.AbsolutePosition;
154 265
155 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should 266 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
156 // be removed when that functionality is implemented in opensim 267 // be removed when that functionality is implemented in opensim
157 AttachmentPt &= 0x7f; 268 attachmentPt &= 0x7f;
158 269
159 // If the attachment point isn't the same as the one previously used 270 // If the attachment point isn't the same as the one previously used
160 // set it's offset position = 0 so that it appears on the attachment point 271 // set it's offset position = 0 so that it appears on the attachment point
161 // and not in a weird location somewhere unknown. 272 // and not in a weird location somewhere unknown.
162 if (AttachmentPt != 0 && AttachmentPt != (uint)group.GetAttachmentPoint()) 273 if (attachmentPt != 0 && attachmentPt != group.AttachmentPoint)
163 { 274 {
164 attachPos = Vector3.Zero; 275 attachPos = Vector3.Zero;
165 } 276 }
166 277
167 // AttachmentPt 0 means the client chose to 'wear' the attachment. 278 // AttachmentPt 0 means the client chose to 'wear' the attachment.
168 if (AttachmentPt == 0) 279 if (attachmentPt == 0)
169 { 280 {
170 // Check object for stored attachment point 281 // Check object for stored attachment point
171 AttachmentPt = (uint)group.GetAttachmentPoint(); 282 attachmentPt = group.AttachmentPoint;
172 } 283 }
173 284
174 // if we still didn't find a suitable attachment point....... 285 // if we still didn't find a suitable attachment point.......
175 if (AttachmentPt == 0) 286 if (attachmentPt == 0)
176 { 287 {
177 // Stick it on left hand with Zero Offset from the attachment point. 288 // Stick it on left hand with Zero Offset from the attachment point.
178 AttachmentPt = (uint)AttachmentPoint.LeftHand; 289 attachmentPt = (uint)AttachmentPoint.LeftHand;
179 attachPos = Vector3.Zero; 290 attachPos = Vector3.Zero;
180 } 291 }
181 292
182 group.SetAttachmentPoint((byte)AttachmentPt); 293 group.AttachmentPoint = attachmentPt;
183 group.AbsolutePosition = attachPos; 294 group.AbsolutePosition = attachPos;
184 295
185 // Remove any previous attachments 296 // Remove any previous attachments
186 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
187 UUID itemID = UUID.Zero; 297 UUID itemID = UUID.Zero;
188 if (sp != null)
189 {
190 foreach (SceneObjectGroup grp in sp.Attachments)
191 {
192 if (grp.GetAttachmentPoint() == (byte)AttachmentPt)
193 {
194 itemID = grp.GetFromItemID();
195 break;
196 }
197 }
198 if (itemID != UUID.Zero)
199 DetachSingleAttachmentToInv(itemID, remoteClient);
200 }
201 298
202 if (group.GetFromItemID() == UUID.Zero) 299 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
203 { 300
204 m_scene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemID); 301 // At the moment we can only deal with a single attachment
205 } 302 // We also don't want to do any of the inventory operations for an NPC.
206 else 303 if (sp.PresenceType != PresenceType.Npc)
207 { 304 {
305 if (attachments.Count != 0)
306 itemID = attachments[0].GetFromItemID();
307
308 if (itemID != UUID.Zero)
309 DetachSingleAttachmentToInv(itemID, sp);
310
208 itemID = group.GetFromItemID(); 311 itemID = group.GetFromItemID();
312 if (itemID == UUID.Zero)
313 itemID = AddSceneObjectAsAttachment(sp.ControllingClient, group).ID;
314
315 ShowAttachInUserInventory(sp, attachmentPt, itemID, group);
209 } 316 }
210 317
211 ShowAttachInUserInventory(remoteClient, AttachmentPt, itemID, group); 318 AttachToAgent(sp, group, attachmentPt, attachPos, silent);
212
213 AttachToAgent(sp, group, AttachmentPt, attachPos, silent);
214 319
215 return true; 320 return true;
216 } 321 }
@@ -226,12 +331,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
226 } 331 }
227 } 332 }
228 333
229 public UUID RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) 334 public ISceneEntity RezSingleAttachmentFromInventory(
335 IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
230 { 336 {
231 return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true); 337 return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true);
232 } 338 }
233 339
234 public UUID RezSingleAttachmentFromInventory( 340 public ISceneEntity RezSingleAttachmentFromInventory(
235 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus) 341 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus)
236 { 342 {
237 return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true, null); 343 return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true, null);
@@ -239,7 +345,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
239 345
240 public UUID RezSingleAttachmentFromInventory( 346 public UUID RezSingleAttachmentFromInventory(
241 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus, XmlDocument doc) 347 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus, XmlDocument doc)
348 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
349
242 { 350 {
351 if (sp == null) { m_log.ErrorFormat( "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezSingleAttachmentFromInventory()", remoteClient.Name, remoteClient.AgentId); return null; }
243 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should 352 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
244 // be removed when that functionality is implemented in opensim 353 // be removed when that functionality is implemented in opensim
245 AttachmentPt &= 0x7f; 354 AttachmentPt &= 0x7f;
@@ -249,15 +358,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
249 if (updateInventoryStatus) 358 if (updateInventoryStatus)
250 { 359 {
251 if (att == null) 360 if (att == null)
252 ShowDetachInUserInventory(itemID, remoteClient); 361 DetachSingleAttachmentToInv(itemID, sp.ControllingClient);
253 else 362 else
254 ShowAttachInUserInventory(att, remoteClient, itemID, AttachmentPt); 363 ShowAttachInUserInventory(att, sp, itemID, AttachmentPt);
255 } 364 }
256 365
257 if (null == att) 366 return att;
258 return UUID.Zero;
259 else
260 return att.UUID;
261 } 367 }
262 368
263 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 369 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
@@ -266,12 +372,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
266 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>(); 372 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
267 if (invAccess != null) 373 if (invAccess != null)
268 { 374 {
269 SceneObjectGroup objatt = invAccess.RezObject(remoteClient, 375 SceneObjectGroup objatt;
270 itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, 376
271 false, false, remoteClient.AgentId, true); 377 if (itemID != UUID.Zero)
378 objatt = invAccess.RezObject(sp.ControllingClient,
379 itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
380 false, false, sp.UUID, true);
381 else
382 objatt = invAccess.RezObject(sp.ControllingClient,
383 null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
384 false, false, sp.UUID, true);
272 385
273// m_log.DebugFormat( 386// m_log.DebugFormat(
274// "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}", 387// "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
275// objatt.Name, remoteClient.Name, AttachmentPt); 388// objatt.Name, remoteClient.Name, AttachmentPt);
276 389
277 if (objatt != null) 390 if (objatt != null)
@@ -281,17 +394,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
281 // since scripts aren't running yet. So, clear it here. 394 // since scripts aren't running yet. So, clear it here.
282 objatt.HasGroupChanged = false; 395 objatt.HasGroupChanged = false;
283 bool tainted = false; 396 bool tainted = false;
284 if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) 397 if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
285 tainted = true; 398 tainted = true;
286 399
287 // This will throw if the attachment fails 400 // This will throw if the attachment fails
288 try 401 try
289 { 402 {
290 AttachObject(remoteClient, objatt, AttachmentPt, false); 403 AttachObject(sp, objatt, attachmentPt, false);
291 } 404 }
292 catch 405 catch (Exception e)
293 { 406 {
407 m_log.ErrorFormat(
408 "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
409 objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
410
294 // Make sure the object doesn't stick around and bail 411 // Make sure the object doesn't stick around and bail
412 sp.RemoveAttachment(objatt);
295 m_scene.DeleteSceneObject(objatt, false); 413 m_scene.DeleteSceneObject(objatt, false);
296 return null; 414 return null;
297 } 415 }
@@ -311,13 +429,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
311 objatt.ResumeScripts(); 429 objatt.ResumeScripts();
312 430
313 // Do this last so that event listeners have access to all the effects of the attachment 431 // Do this last so that event listeners have access to all the effects of the attachment
314 //m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, remoteClient.AgentId); 432 m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID);
315 } 433 }
316 else 434 else
317 { 435 {
318 m_log.WarnFormat( 436 m_log.WarnFormat(
319 "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", 437 "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
320 itemID, remoteClient.Name, AttachmentPt); 438 itemID, sp.Name, attachmentPt);
321 } 439 }
322 440
323 return objatt; 441 return objatt;
@@ -330,31 +448,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
330 /// Update the user inventory to the attachment of an item 448 /// Update the user inventory to the attachment of an item
331 /// </summary> 449 /// </summary>
332 /// <param name="att"></param> 450 /// <param name="att"></param>
333 /// <param name="remoteClient"></param> 451 /// <param name="sp"></param>
334 /// <param name="itemID"></param> 452 /// <param name="itemID"></param>
335 /// <param name="AttachmentPt"></param> 453 /// <param name="attachmentPoint"></param>
336 /// <returns></returns> 454 /// <returns></returns>
337 protected UUID ShowAttachInUserInventory( 455 private UUID ShowAttachInUserInventory(
338 SceneObjectGroup att, IClientAPI remoteClient, UUID itemID, uint AttachmentPt) 456 SceneObjectGroup att, IScenePresence sp, UUID itemID, uint attachmentPoint)
339 { 457 {
340// m_log.DebugFormat( 458// m_log.DebugFormat(
341// "[ATTACHMENTS MODULE]: Updating inventory of {0} to show attachment of {1} (item ID {2})", 459// "[ATTACHMENTS MODULE]: Updating inventory of {0} to show attachment of {1} {2} (item ID {3}) at {4}",
342// remoteClient.Name, att.Name, itemID); 460// sp.Name, att.Name, att.LocalId, itemID, AttachmentPt);
343 461
344 if (!att.IsDeleted) 462 if (!att.IsDeleted)
345 AttachmentPt = att.RootPart.AttachmentPoint; 463 attachmentPoint = att.AttachmentPoint;
346 464
347 ScenePresence presence; 465 ScenePresence presence;
348 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) 466 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
349 { 467 {
350 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); 468 InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID);
351 if (m_scene.InventoryService != null) 469 if (m_scene.InventoryService != null)
352 item = m_scene.InventoryService.GetItem(item); 470 item = m_scene.InventoryService.GetItem(item);
353 471
354 bool changed = presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); 472 bool changed = sp.Appearance.SetAttachment((int)attachmentPoint, itemID, item.AssetID);
355 if (changed && m_scene.AvatarFactory != null) 473 if (changed && m_scene.AvatarFactory != null)
356 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); 474 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
357 }
358 475
359 return att.UUID; 476 return att.UUID;
360 } 477 }
@@ -362,12 +479,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
362 /// <summary> 479 /// <summary>
363 /// Update the user inventory to reflect an attachment 480 /// Update the user inventory to reflect an attachment
364 /// </summary> 481 /// </summary>
365 /// <param name="remoteClient"></param> 482 /// <param name="sp"></param>
366 /// <param name="AttachmentPt"></param> 483 /// <param name="AttachmentPt"></param>
367 /// <param name="itemID"></param> 484 /// <param name="itemID"></param>
368 /// <param name="att"></param> 485 /// <param name="att"></param>
369 protected void ShowAttachInUserInventory( 486 private void ShowAttachInUserInventory(
370 IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att) 487 IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att)
371 { 488 {
372// m_log.DebugFormat( 489// m_log.DebugFormat(
373// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", 490// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
@@ -390,23 +507,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
390 m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment for a prim without the rootpart!"); 507 m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment for a prim without the rootpart!");
391 return; 508 return;
392 } 509 }
510 InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID);
393 511
394 ScenePresence presence; 512
395 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) 513
396 { 514
397 // XXYY!! 515
398 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); 516
399 if (item == null) 517 item = m_scene.InventoryService.GetItem(item);
400 m_log.Error("[ATTACHMENT]: item == null"); 518 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID);
401 if (m_scene == null) 519 if (changed && m_scene.AvatarFactory != null)
402 m_log.Error("[ATTACHMENT]: m_scene == null"); 520 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
403 if (m_scene.InventoryService == null)
404 m_log.Error("[ATTACHMENT]: m_scene.InventoryService == null");
405 item = m_scene.InventoryService.GetItem(item);
406 bool changed = presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID);
407 if (changed && m_scene.AvatarFactory != null)
408 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
409 }
410 } 521 }
411 522
412 public void DetachObject(uint objectLocalID, IClientAPI remoteClient) 523 public void DetachObject(uint objectLocalID, IClientAPI remoteClient)
@@ -414,12 +525,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
414 SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); 525 SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID);
415 if (group != null) 526 if (group != null)
416 { 527 {
417 //group.DetachToGround(); 528 DetachSingleAttachmentToInv(group.GetFromItemID(), remoteClient);
418 ShowDetachInUserInventory(group.GetFromItemID(), remoteClient);
419 } 529 }
420 } 530 }
421 531
422 public void ShowDetachInUserInventory(UUID itemID, IClientAPI remoteClient) 532 public void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient)
423 { 533 {
424 ScenePresence presence; 534 ScenePresence presence;
425 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) 535 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
@@ -430,34 +540,44 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
430 bool changed = presence.Appearance.DetachAttachment(itemID); 540 bool changed = presence.Appearance.DetachAttachment(itemID);
431 if (changed && m_scene.AvatarFactory != null) 541 if (changed && m_scene.AvatarFactory != null)
432 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); 542 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
433 }
434 543
435 DetachSingleAttachmentToInv(itemID, remoteClient); 544 DetachSingleAttachmentToInv(itemID, presence);
545 }
436 } 546 }
437 547
438 public void DetachSingleAttachmentToGround(UUID itemID, IClientAPI remoteClient) 548 public void DetachSingleAttachmentToGround(uint soLocalId, IClientAPI remoteClient)
439 { 549 {
440 SceneObjectPart part = m_scene.GetSceneObjectPart(itemID); 550// m_log.DebugFormat(
441 if (part == null || part.ParentGroup == null) 551// "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}",
552// remoteClient.Name, sceneObjectID);
553
554 SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId);
555
556 if (so == null)
442 return; 557 return;
443 558
444 if (part.ParentGroup.RootPart.AttachedAvatar != remoteClient.AgentId) 559 if (so.AttachedAvatar != remoteClient.AgentId)
445 return; 560 return;
446 561
447 UUID inventoryID = part.ParentGroup.GetFromItemID(); 562 UUID inventoryID = so.GetFromItemID();
563
564// m_log.DebugFormat(
565// "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}",
566// so.Name, so.LocalId, inventoryID);
448 567
449 ScenePresence presence; 568 ScenePresence presence;
450 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) 569 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
451 { 570 {
452 if (!m_scene.Permissions.CanRezObject( 571 if (!m_scene.Permissions.CanRezObject(
453 part.ParentGroup.PrimCount, remoteClient.AgentId, presence.AbsolutePosition)) 572 so.PrimCount, remoteClient.AgentId, presence.AbsolutePosition))
454 return; 573 return;
455 574
456 bool changed = presence.Appearance.DetachAttachment(itemID); 575 bool changed = presence.Appearance.DetachAttachment(inventoryID);
457 if (changed && m_scene.AvatarFactory != null) 576 if (changed && m_scene.AvatarFactory != null)
458 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); 577 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
459 578
460 part.ParentGroup.DetachToGround(); 579 presence.RemoveAttachment(so);
580 DetachSceneObjectToGround(so, presence);
461 581
462 List<UUID> uuids = new List<UUID>(); 582 List<UUID> uuids = new List<UUID>();
463 uuids.Add(inventoryID); 583 uuids.Add(inventoryID);
@@ -465,12 +585,39 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
465 remoteClient.SendRemoveInventoryItem(inventoryID); 585 remoteClient.SendRemoveInventoryItem(inventoryID);
466 } 586 }
467 587
468 m_scene.EventManager.TriggerOnAttach(part.ParentGroup.LocalId, itemID, UUID.Zero); 588 m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero);
589 }
590
591 /// <summary>
592 /// Detach the given scene object to the ground.
593 /// </summary>
594 /// <remarks>
595 /// The caller has to take care of all the other work in updating avatar appearance, inventory, etc.
596 /// </remarks>
597 /// <param name="so">The scene object to detach.</param>
598 /// <param name="sp">The scene presence from which the scene object is being detached.</param>
599 private void DetachSceneObjectToGround(SceneObjectGroup so, ScenePresence sp)
600 {
601 SceneObjectPart rootPart = so.RootPart;
602
603 rootPart.FromItemID = UUID.Zero;
604 so.AbsolutePosition = sp.AbsolutePosition;
605 so.AttachedAvatar = UUID.Zero;
606 rootPart.SetParentLocalId(0);
607 so.ClearPartAttachmentData();
608 rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive, m_scene.m_physicalPrim);
609 so.HasGroupChanged = true;
610 rootPart.Rezzed = DateTime.Now;
611 rootPart.RemFlag(PrimFlags.TemporaryOnRez);
612 so.AttachToBackup();
613 m_scene.EventManager.TriggerParcelPrimCountTainted();
614 rootPart.ScheduleFullUpdate();
615 rootPart.ClearUndoState();
469 } 616 }
470 617
471 // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. 618 // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards.
472 // To LocalId or UUID, *THAT* is the question. How now Brown UUID?? 619 // To LocalId or UUID, *THAT* is the question. How now Brown UUID??
473 protected void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient) 620 private void DetachSingleAttachmentToInv(UUID itemID, IScenePresence sp)
474 { 621 {
475 if (itemID == UUID.Zero) // If this happened, someone made a mistake.... 622 if (itemID == UUID.Zero) // If this happened, someone made a mistake....
476 return; 623 return;
@@ -493,27 +640,55 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
493 group.DetachToInventoryPrep(); 640 group.DetachToInventoryPrep();
494 m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString()); 641 m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString());
495 642
496 // If an item contains scripts, it's always changed. 643 // Prepare sog for storage
497 // This ensures script state is saved on detach 644 group.AttachedAvatar = UUID.Zero;
498 foreach (SceneObjectPart p in group.Parts) 645
499 if (p.Inventory.ContainsScripts()) 646 group.ForEachPart(
500 group.HasGroupChanged = true; 647 delegate(SceneObjectPart part)
648 {
649 // If there are any scripts,
650 // then always trigger a new object and state persistence in UpdateKnownItem()
651 if (part.Inventory.ContainsScripts())
652 group.HasGroupChanged = true;
653 }
654 );
501 655
502 UpdateKnownItem(remoteClient, group, group.GetFromItemID(), group.OwnerID); 656 group.RootPart.SetParentLocalId(0);
657 group.IsAttachment = false;
658 group.AbsolutePosition = group.RootPart.AttachedPos;
659
660 UpdateKnownItem(sp.ControllingClient, group, group.GetFromItemID(), group.OwnerID);
503 m_scene.DeleteSceneObject(group, false); 661 m_scene.DeleteSceneObject(group, false);
662
504 return; 663 return;
505 } 664 }
506 } 665 }
507 } 666 }
508 } 667 }
509 668
669 public void UpdateAttachmentPosition(SceneObjectGroup sog, Vector3 pos)
670 {
671 // First we save the
672 // attachment point information, then we update the relative
673 // positioning. Then we have to mark the object as NOT an
674 // attachment. This is necessary in order to correctly save
675 // and retrieve GroupPosition information for the attachment.
676 // Finally, we restore the object's attachment status.
677 uint attachmentPoint = sog.AttachmentPoint;
678 sog.UpdateGroupPosition(pos);
679 sog.IsAttachment = false;
680 sog.AbsolutePosition = sog.RootPart.AttachedPos;
681 sog.AttachmentPoint = attachmentPoint;
682 sog.HasGroupChanged = true;
683 }
684
510 /// <summary> 685 /// <summary>
511 /// Update the attachment asset for the new sog details if they have changed. 686 /// Update the attachment asset for the new sog details if they have changed.
512 /// </summary> 687 /// </summary>
513 /// 688 /// <remarks>
514 /// This is essential for preserving attachment attributes such as permission. Unlike normal scene objects, 689 /// This is essential for preserving attachment attributes such as permission. Unlike normal scene objects,
515 /// these details are not stored on the region. 690 /// these details are not stored on the region.
516 /// 691 /// </remarks>
517 /// <param name="remoteClient"></param> 692 /// <param name="remoteClient"></param>
518 /// <param name="grp"></param> 693 /// <param name="grp"></param>
519 /// <param name="itemID"></param> 694 /// <param name="itemID"></param>
@@ -524,15 +699,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
524 { 699 {
525 if (!grp.HasGroupChanged) 700 if (!grp.HasGroupChanged)
526 { 701 {
527 m_log.WarnFormat("[ATTACHMENTS MODULE]: Save request for {0} which is unchanged", grp.UUID); 702 m_log.DebugFormat(
703 "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}",
704 grp.UUID, grp.AttachmentPoint);
705
528 return; 706 return;
529 } 707 }
530 708
531 m_log.DebugFormat( 709 m_log.DebugFormat(
532 "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", 710 "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}",
533 grp.UUID, grp.GetAttachmentPoint()); 711 grp.UUID, grp.AttachmentPoint);
534 712
535 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); 713 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp);
714
536 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); 715 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
537 item = m_scene.InventoryService.GetItem(item); 716 item = m_scene.InventoryService.GetItem(item);
538 717
@@ -564,20 +743,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
564 /// <summary> 743 /// <summary>
565 /// Attach this scene object to the given avatar. 744 /// Attach this scene object to the given avatar.
566 /// </summary> 745 /// </summary>
567 /// 746 /// <remarks>
568 /// This isn't publicly available since attachments should always perform the corresponding inventory 747 /// This isn't publicly available since attachments should always perform the corresponding inventory
569 /// operation (to show the attach in user inventory and update the asset with positional information). 748 /// operation (to show the attach in user inventory and update the asset with positional information).
570 /// 749 /// </remarks>
571 /// <param name="sp"></param> 750 /// <param name="sp"></param>
572 /// <param name="so"></param> 751 /// <param name="so"></param>
573 /// <param name="attachmentpoint"></param> 752 /// <param name="attachmentpoint"></param>
574 /// <param name="attachOffset"></param> 753 /// <param name="attachOffset"></param>
575 /// <param name="silent"></param> 754 /// <param name="silent"></param>
576 protected void AttachToAgent(ScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) 755 private void AttachToAgent(
756 IScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent)
577 { 757 {
578 758// m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}",
579 m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", Name, avatar.Name, 759// so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos);
580 attachmentpoint, attachOffset, so.RootPart.AttachedPos);
581 760
582 so.DetachFromBackup(); 761 so.DetachFromBackup();
583 762
@@ -585,12 +764,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
585 m_scene.DeleteFromStorage(so.UUID); 764 m_scene.DeleteFromStorage(so.UUID);
586 m_scene.EventManager.TriggerParcelPrimCountTainted(); 765 m_scene.EventManager.TriggerParcelPrimCountTainted();
587 766
588 so.RootPart.AttachedAvatar = avatar.UUID; 767 so.AttachedAvatar = avatar.UUID;
589
590 //Anakin Lohner bug #3839
591 SceneObjectPart[] parts = so.Parts;
592 for (int i = 0; i < parts.Length; i++)
593 parts[i].AttachedAvatar = avatar.UUID;
594 768
595 if (so.RootPart.PhysActor != null) 769 if (so.RootPart.PhysActor != null)
596 { 770 {
@@ -600,10 +774,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
600 774
601 so.AbsolutePosition = attachOffset; 775 so.AbsolutePosition = attachOffset;
602 so.RootPart.AttachedPos = attachOffset; 776 so.RootPart.AttachedPos = attachOffset;
603 so.RootPart.IsAttachment = true; 777 so.IsAttachment = true;
604
605 so.RootPart.SetParentLocalId(avatar.LocalId); 778 so.RootPart.SetParentLocalId(avatar.LocalId);
606 so.SetAttachmentPoint(Convert.ToByte(attachmentpoint)); 779 so.AttachmentPoint = attachmentpoint;
607 780
608 avatar.AddAttachment(so); 781 avatar.AddAttachment(so);
609 782
@@ -617,5 +790,97 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
617 // it get cleaned up 790 // it get cleaned up
618 so.RootPart.RemFlag(PrimFlags.TemporaryOnRez); 791 so.RootPart.RemFlag(PrimFlags.TemporaryOnRez);
619 } 792 }
793
794 /// <summary>
795 /// Add a scene object that was previously free in the scene as an attachment to an avatar.
796 /// </summary>
797 /// <param name="remoteClient"></param>
798 /// <param name="grp"></param>
799 /// <returns>The user inventory item created that holds the attachment.</returns>
800 private InventoryItemBase AddSceneObjectAsAttachment(IClientAPI remoteClient, SceneObjectGroup grp)
801 {
802// m_log.DebugFormat("[SCENE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2} {3} {4}", grp.Name, grp.LocalId, remoteClient.Name, remoteClient.AgentId, AgentId);
803
804 Vector3 inventoryStoredPosition = new Vector3
805 (((grp.AbsolutePosition.X > (int)Constants.RegionSize)
806 ? Constants.RegionSize - 6
807 : grp.AbsolutePosition.X)
808 ,
809 (grp.AbsolutePosition.Y > (int)Constants.RegionSize)
810 ? Constants.RegionSize - 6
811 : grp.AbsolutePosition.Y,
812 grp.AbsolutePosition.Z);
813
814 Vector3 originalPosition = grp.AbsolutePosition;
815
816 grp.AbsolutePosition = inventoryStoredPosition;
817
818 // If we're being called from a script, then trying to serialize that same script's state will not complete
819 // in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if
820 // the client/server crashes rather than logging out normally, the attachment's scripts will resume
821 // without state on relog. Arguably, this is what we want anyway.
822 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, false);
823
824 grp.AbsolutePosition = originalPosition;
825
826 AssetBase asset = m_scene.CreateAsset(
827 grp.GetPartName(grp.LocalId),
828 grp.GetPartDescription(grp.LocalId),
829 (sbyte)AssetType.Object,
830 Utils.StringToBytes(sceneObjectXml),
831 remoteClient.AgentId);
832
833 m_scene.AssetService.Store(asset);
834
835 InventoryItemBase item = new InventoryItemBase();
836 item.CreatorId = grp.RootPart.CreatorID.ToString();
837 item.CreatorData = grp.RootPart.CreatorData;
838 item.Owner = remoteClient.AgentId;
839 item.ID = UUID.Random();
840 item.AssetID = asset.FullID;
841 item.Description = asset.Description;
842 item.Name = asset.Name;
843 item.AssetType = asset.Type;
844 item.InvType = (int)InventoryType.Object;
845
846 InventoryFolderBase folder = m_scene.InventoryService.GetFolderForType(remoteClient.AgentId, AssetType.Object);
847 if (folder != null)
848 item.Folder = folder.ID;
849 else // oopsies
850 item.Folder = UUID.Zero;
851
852 if ((remoteClient.AgentId != grp.RootPart.OwnerID) && m_scene.Permissions.PropagatePermissions())
853 {
854 item.BasePermissions = grp.RootPart.NextOwnerMask;
855 item.CurrentPermissions = grp.RootPart.NextOwnerMask;
856 item.NextPermissions = grp.RootPart.NextOwnerMask;
857 item.EveryOnePermissions = grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask;
858 item.GroupPermissions = grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask;
859 }
860 else
861 {
862 item.BasePermissions = grp.RootPart.BaseMask;
863 item.CurrentPermissions = grp.RootPart.OwnerMask;
864 item.NextPermissions = grp.RootPart.NextOwnerMask;
865 item.EveryOnePermissions = grp.RootPart.EveryoneMask;
866 item.GroupPermissions = grp.RootPart.GroupMask;
867 }
868 item.CreationDate = Util.UnixTimeSinceEpoch();
869
870 // sets itemID so client can show item as 'attached' in inventory
871 grp.SetFromItemID(item.ID);
872
873 if (m_scene.AddInventoryItem(item))
874 {
875 remoteClient.SendInventoryItemCreateUpdate(item, 0);
876 }
877 else
878 {
879 if (m_dialogModule != null)
880 m_dialogModule.SendAlertToUser(remoteClient, "Operation failed");
881 }
882
883 return item;
884 }
620 } 885 }
621} 886}
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
new file mode 100644
index 0000000..363e258
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -0,0 +1,274 @@
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 System.Threading;
33using System.Timers;
34using Timer=System.Timers.Timer;
35using Nini.Config;
36using NUnit.Framework;
37using OpenMetaverse;
38using OpenSim.Framework;
39using OpenSim.Framework.Communications;
40using OpenSim.Region.CoreModules.Avatar.Attachments;
41using OpenSim.Region.CoreModules.Framework.InventoryAccess;
42using OpenSim.Region.CoreModules.World.Serialiser;
43using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
44using OpenSim.Region.Framework.Scenes;
45using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Tests.Common;
47using OpenSim.Tests.Common.Mock;
48
49namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
50{
51 /// <summary>
52 /// Attachment tests
53 /// </summary>
54 [TestFixture]
55 public class AttachmentsModuleTests
56 {
57 private Scene scene;
58 private AttachmentsModule m_attMod;
59 private ScenePresence m_presence;
60
61 [SetUp]
62 public void Init()
63 {
64 // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
65 Util.FireAndForgetMethod = FireAndForgetMethod.None;
66
67 IConfigSource config = new IniConfigSource();
68 config.AddConfig("Modules");
69 config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
70
71 scene = SceneHelpers.SetupScene();
72 m_attMod = new AttachmentsModule();
73 SceneHelpers.SetupSceneModules(scene, config, m_attMod, new BasicInventoryAccessModule());
74 }
75
76 [TearDown]
77 public void TearDown()
78 {
79 // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
80 // threads. Possibly, later tests should be rewritten not to worry about such things.
81 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
82 }
83
84 /// <summary>
85 /// Add the standard presence for a test.
86 /// </summary>
87 private void AddPresence()
88 {
89 UUID userId = TestHelpers.ParseTail(0x1);
90 UserAccountHelpers.CreateUserWithInventory(scene, userId);
91 m_presence = SceneHelpers.AddScenePresence(scene, userId);
92 }
93
94 [Test]
95 public void TestAddAttachmentFromGround()
96 {
97 TestHelpers.InMethod();
98// log4net.Config.XmlConfigurator.Configure();
99
100 AddPresence();
101 string attName = "att";
102
103 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName).ParentGroup;
104
105 m_attMod.AttachObject(m_presence.ControllingClient, so, (uint)AttachmentPoint.Chest, false);
106
107 // Check status on scene presence
108 Assert.That(m_presence.HasAttachments(), Is.True);
109 List<SceneObjectGroup> attachments = m_presence.GetAttachments();
110 Assert.That(attachments.Count, Is.EqualTo(1));
111 SceneObjectGroup attSo = attachments[0];
112 Assert.That(attSo.Name, Is.EqualTo(attName));
113 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
114 Assert.That(attSo.IsAttachment);
115 Assert.That(attSo.UsesPhysics, Is.False);
116 Assert.That(attSo.IsTemporary, Is.False);
117
118 // Check item status
119 Assert.That(m_presence.Appearance.GetAttachpoint(
120 attSo.GetFromItemID()), Is.EqualTo((int)AttachmentPoint.Chest));
121 }
122
123 [Test]
124 public void TestAddAttachmentFromInventory()
125 {
126 TestHelpers.InMethod();
127// log4net.Config.XmlConfigurator.Configure();
128
129 AddPresence();
130
131 UUID attItemId = TestHelpers.ParseTail(0x2);
132 UUID attAssetId = TestHelpers.ParseTail(0x3);
133 string attName = "att";
134
135 UserInventoryHelpers.CreateInventoryItem(
136 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
137
138 m_attMod.RezSingleAttachmentFromInventory(
139 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
140
141 // Check scene presence status
142 Assert.That(m_presence.HasAttachments(), Is.True);
143 List<SceneObjectGroup> attachments = m_presence.GetAttachments();
144 Assert.That(attachments.Count, Is.EqualTo(1));
145 SceneObjectGroup attSo = attachments[0];
146 Assert.That(attSo.Name, Is.EqualTo(attName));
147 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
148 Assert.That(attSo.IsAttachment);
149 Assert.That(attSo.UsesPhysics, Is.False);
150 Assert.That(attSo.IsTemporary, Is.False);
151
152 // Check appearance status
153 Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest));
154 }
155
156 [Test]
157 public void TestDetachAttachmentToGround()
158 {
159 TestHelpers.InMethod();
160// log4net.Config.XmlConfigurator.Configure();
161
162 AddPresence();
163
164 UUID attItemId = TestHelpers.ParseTail(0x2);
165 UUID attAssetId = TestHelpers.ParseTail(0x3);
166 string attName = "att";
167
168 UserInventoryHelpers.CreateInventoryItem(
169 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
170
171 ISceneEntity so = m_attMod.RezSingleAttachmentFromInventory(
172 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
173 m_attMod.DetachSingleAttachmentToGround(so.LocalId, m_presence.ControllingClient);
174
175 // Check scene presence status
176 Assert.That(m_presence.HasAttachments(), Is.False);
177 List<SceneObjectGroup> attachments = m_presence.GetAttachments();
178 Assert.That(attachments.Count, Is.EqualTo(0));
179
180 // Check appearance status
181 Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(0));
182
183 // Check item status
184 Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItemId)), Is.Null);
185
186 // Check object in scene
187 Assert.That(scene.GetSceneObjectGroup("att"), Is.Not.Null);
188 }
189
190 [Test]
191 public void TestDetachAttachmentToInventory()
192 {
193 TestHelpers.InMethod();
194// log4net.Config.XmlConfigurator.Configure();
195
196 AddPresence();
197
198 UUID attItemId = TestHelpers.ParseTail(0x2);
199 UUID attAssetId = TestHelpers.ParseTail(0x3);
200 string attName = "att";
201
202 UserInventoryHelpers.CreateInventoryItem(
203 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
204
205 m_attMod.RezSingleAttachmentFromInventory(
206 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
207 m_attMod.DetachSingleAttachmentToInv(attItemId, m_presence.ControllingClient);
208
209 // Check status on scene presence
210 Assert.That(m_presence.HasAttachments(), Is.False);
211 List<SceneObjectGroup> attachments = m_presence.GetAttachments();
212 Assert.That(attachments.Count, Is.EqualTo(0));
213
214 // Check item status
215 Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo(0));
216 }
217
218 [Test]
219 public void TestRezAttachmentsOnAvatarEntrance()
220 {
221 TestHelpers.InMethod();
222// log4net.Config.XmlConfigurator.Configure();
223
224 UUID userId = TestHelpers.ParseTail(0x1);
225 UUID attItemId = TestHelpers.ParseTail(0x2);
226 UUID attAssetId = TestHelpers.ParseTail(0x3);
227 string attName = "att";
228
229 UserAccountHelpers.CreateUserWithInventory(scene, userId);
230 InventoryItemBase attItem
231 = UserInventoryHelpers.CreateInventoryItem(
232 scene, attName, attItemId, attAssetId, userId, InventoryType.Object);
233
234 AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
235 acd.Appearance = new AvatarAppearance();
236 acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID);
237 ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd);
238
239 Assert.That(presence.HasAttachments(), Is.True);
240 List<SceneObjectGroup> attachments = presence.GetAttachments();
241
242 Assert.That(attachments.Count, Is.EqualTo(1));
243 SceneObjectGroup attSo = attachments[0];
244 Assert.That(attSo.Name, Is.EqualTo(attName));
245 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
246 Assert.That(attSo.IsAttachment);
247 Assert.That(attSo.UsesPhysics, Is.False);
248 Assert.That(attSo.IsTemporary, Is.False);
249 }
250
251 // I'm commenting this test because scene setup NEEDS InventoryService to
252 // be non-null
253 //[Test]
254// public void T032_CrossAttachments()
255// {
256// TestHelpers.InMethod();
257//
258// ScenePresence presence = scene.GetScenePresence(agent1);
259// ScenePresence presence2 = scene2.GetScenePresence(agent1);
260// presence2.AddAttachment(sog1);
261// presence2.AddAttachment(sog2);
262//
263// ISharedRegionModule serialiser = new SerialiserModule();
264// SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), serialiser);
265// SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), serialiser);
266//
267// Assert.That(presence.HasAttachments(), Is.False, "Presence has attachments before cross");
268//
269// //Assert.That(presence2.CrossAttachmentsIntoNewRegion(region1, true), Is.True, "Cross was not successful");
270// Assert.That(presence2.HasAttachments(), Is.False, "Presence2 objects were not deleted");
271// Assert.That(presence.HasAttachments(), Is.True, "Presence has not received new objects");
272// }
273 }
274} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index d02a305..b6a1564 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -104,7 +104,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
104 public void NewClient(IClientAPI client) 104 public void NewClient(IClientAPI client)
105 { 105 {
106 client.OnRequestWearables += SendWearables; 106 client.OnRequestWearables += SendWearables;
107 client.OnSetAppearance += SetAppearance; 107 client.OnSetAppearance += SetAppearanceFromClient;
108 client.OnAvatarNowWearing += AvatarIsWearing; 108 client.OnAvatarNowWearing += AvatarIsWearing;
109 } 109 }
110 110
@@ -116,16 +116,20 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
116 #endregion 116 #endregion
117 117
118 /// <summary> 118 /// <summary>
119 /// Check for the existence of the baked texture assets. Request a rebake 119 /// Check for the existence of the baked texture assets.
120 /// unless checkonly is true.
121 /// </summary> 120 /// </summary>
122 /// <param name="client"></param> 121 /// <param name="client"></param>
123 /// <param name="checkonly"></param>
124 public bool ValidateBakedTextureCache(IClientAPI client) 122 public bool ValidateBakedTextureCache(IClientAPI client)
125 { 123 {
126 return ValidateBakedTextureCache(client, true); 124 return ValidateBakedTextureCache(client, true);
127 } 125 }
128 126
127 /// <summary>
128 /// Check for the existence of the baked texture assets. Request a rebake
129 /// unless checkonly is true.
130 /// </summary>
131 /// <param name="client"></param>
132 /// <param name="checkonly"></param>
129 private bool ValidateBakedTextureCache(IClientAPI client, bool checkonly) 133 private bool ValidateBakedTextureCache(IClientAPI client, bool checkonly)
130 { 134 {
131 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 135 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
@@ -147,6 +151,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
147 if (face == null) 151 if (face == null)
148 continue; 152 continue;
149 153
154// m_log.DebugFormat(
155// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
156// face.TextureID, idx, client.Name, client.AgentId);
157
150 // if the texture is one of the "defaults" then skip it 158 // if the texture is one of the "defaults" then skip it
151 // this should probably be more intelligent (skirt texture doesnt matter 159 // this should probably be more intelligent (skirt texture doesnt matter
152 // if the avatar isnt wearing a skirt) but if any of the main baked 160 // if the avatar isnt wearing a skirt) but if any of the main baked
@@ -156,13 +164,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
156 164
157 defonly = false; // found a non-default texture reference 165 defonly = false; // found a non-default texture reference
158 166
159 if (! CheckBakedTextureAsset(client,face.TextureID,idx)) 167 if (!CheckBakedTextureAsset(client, face.TextureID, idx))
160 { 168 {
161 // the asset didn't exist if we are only checking, then we found a bad 169 // the asset didn't exist if we are only checking, then we found a bad
162 // one and we're done otherwise, ask for a rebake 170 // one and we're done otherwise, ask for a rebake
163 if (checkonly) return false; 171 if (checkonly)
172 return false;
164 173
165 m_log.InfoFormat("[AVFACTORY]: missing baked texture {0}, requesting rebake", face.TextureID); 174 m_log.InfoFormat("[AVFACTORY]: missing baked texture {0}, requesting rebake", face.TextureID);
175
166 client.SendRebakeAvatarTextures(face.TextureID); 176 client.SendRebakeAvatarTextures(face.TextureID);
167 } 177 }
168 } 178 }
@@ -174,16 +184,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
174 } 184 }
175 185
176 /// <summary> 186 /// <summary>
177 /// Set appearance data (textureentry and slider settings) received from the client 187 /// Set appearance data (texture asset IDs and slider settings) received from the client
178 /// </summary> 188 /// </summary>
189 /// <param name="client"></param>
179 /// <param name="texture"></param> 190 /// <param name="texture"></param>
180 /// <param name="visualParam"></param> 191 /// <param name="visualParam"></param>
181 public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams) 192 public void SetAppearanceFromClient(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams)
182 { 193 {
183 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 194 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
184 if (sp == null) 195 if (sp == null)
185 { 196 {
186 m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}",client.AgentId); 197 m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}", client.AgentId);
187 return; 198 return;
188 } 199 }
189 200
@@ -211,18 +222,18 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
211 changed = sp.Appearance.SetTextureEntries(textureEntry) || changed; 222 changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
212 223
213 m_log.InfoFormat("[AVFACTORY]: received texture update for {0}", client.AgentId); 224 m_log.InfoFormat("[AVFACTORY]: received texture update for {0}", client.AgentId);
214 Util.FireAndForget(delegate(object o) { ValidateBakedTextureCache(client,false); }); 225 Util.FireAndForget(delegate(object o) { ValidateBakedTextureCache(client, false); });
215 226
216 // This appears to be set only in the final stage of the appearance 227 // This appears to be set only in the final stage of the appearance
217 // update transaction. In theory, we should be able to do an immediate 228 // update transaction. In theory, we should be able to do an immediate
218 // appearance send and save here. 229 // appearance send and save here.
219 230
220 // save only if there were changes, send no matter what (doesn't hurt to send twice)
221 if (changed)
222 QueueAppearanceSave(client.AgentId);
223 QueueAppearanceSend(client.AgentId);
224 } 231 }
232 // save only if there were changes, send no matter what (doesn't hurt to send twice)
233 if (changed)
234 QueueAppearanceSave(client.AgentId);
225 235
236 QueueAppearanceSend(client.AgentId);
226 } 237 }
227 238
228 // m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString()); 239 // m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString());
@@ -246,6 +257,117 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
246 return true; 257 return true;
247 } 258 }
248 259
260 public Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(UUID agentId)
261 {
262 ScenePresence sp = m_scene.GetScenePresence(agentId);
263
264 if (sp == null)
265 return new Dictionary<BakeType, Primitive.TextureEntryFace>();
266
267 return GetBakedTextureFaces(sp);
268 }
269
270 private Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(ScenePresence sp)
271 {
272 if (sp.IsChildAgent)
273 return new Dictionary<BakeType, Primitive.TextureEntryFace>();
274
275 Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures
276 = new Dictionary<BakeType, Primitive.TextureEntryFace>();
277
278 AvatarAppearance appearance = sp.Appearance;
279 Primitive.TextureEntryFace[] faceTextures = appearance.Texture.FaceTextures;
280
281 foreach (int i in Enum.GetValues(typeof(BakeType)))
282 {
283 BakeType bakeType = (BakeType)i;
284
285 if (bakeType == BakeType.Unknown)
286 continue;
287
288// m_log.DebugFormat(
289// "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}",
290// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]);
291
292 int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType);
293 bakedTextures[bakeType] = faceTextures[ftIndex];
294 }
295
296 return bakedTextures;
297 }
298
299 public bool SaveBakedTextures(UUID agentId)
300 {
301 ScenePresence sp = m_scene.GetScenePresence(agentId);
302
303 if (sp == null)
304 return false;
305
306 m_log.DebugFormat(
307 "[AV FACTORY]: Permanently saving baked textures for {0} in {1}",
308 sp.Name, m_scene.RegionInfo.RegionName);
309
310 Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = GetBakedTextureFaces(sp);
311
312 if (bakedTextures.Count == 0)
313 return false;
314
315 foreach (BakeType bakeType in bakedTextures.Keys)
316 {
317 Primitive.TextureEntryFace bakedTextureFace = bakedTextures[bakeType];
318
319 if (bakedTextureFace == null)
320 {
321 m_log.WarnFormat(
322 "[AV FACTORY]: No texture ID set for {0} for {1} in {2} not found when trying to save permanently",
323 bakeType, sp.Name, m_scene.RegionInfo.RegionName);
324
325 continue;
326 }
327
328 AssetBase asset = m_scene.AssetService.Get(bakedTextureFace.TextureID.ToString());
329
330 if (asset != null)
331 {
332 asset.Temporary = false;
333 asset.Local = false;
334 m_scene.AssetService.Store(asset);
335 }
336 else
337 {
338 m_log.WarnFormat(
339 "[AV FACTORY]: Baked texture id {0} not found for bake {1} for avatar {2} in {3} when trying to save permanently",
340 bakedTextureFace.TextureID, bakeType, sp.Name, m_scene.RegionInfo.RegionName);
341 }
342 }
343
344// for (int i = 0; i < faceTextures.Length; i++)
345// {
346//// m_log.DebugFormat(
347//// "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}",
348//// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]);
349//
350// if (faceTextures[i] == null)
351// continue;
352//
353// AssetBase asset = m_scene.AssetService.Get(faceTextures[i].TextureID.ToString());
354//
355// if (asset != null)
356// {
357// asset.Temporary = false;
358// m_scene.AssetService.Store(asset);
359// }
360// else
361// {
362// m_log.WarnFormat(
363// "[AV FACTORY]: Baked texture {0} for {1} in {2} not found when trying to save permanently",
364// faceTextures[i].TextureID, sp.Name, m_scene.RegionInfo.RegionName);
365// }
366// }
367
368 return true;
369 }
370
249 #region UpdateAppearanceTimer 371 #region UpdateAppearanceTimer
250 372
251 /// <summary> 373 /// <summary>
@@ -278,26 +400,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
278 } 400 }
279 } 401 }
280 402
281 private void HandleAppearanceSend(UUID agentid) 403 private void SaveAppearance(UUID agentid)
282 { 404 {
283 ScenePresence sp = m_scene.GetScenePresence(agentid); 405 // We must set appearance parameters in the en_US culture in order to avoid issues where values are saved
284 if (sp == null) 406 // in a culture where decimal points are commas and then reloaded in a culture which just treats them as
285 { 407 // number seperators.
286 m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid); 408 Culture.SetCurrentCulture();
287 return;
288 }
289
290 // m_log.WarnFormat("[AVFACTORY]: Handle appearance send for {0}", agentid);
291 409
292 // Send the appearance to everyone in the scene
293 sp.SendAppearanceToAllOtherAgents();
294
295 // Send animations back to the avatar as well
296 sp.Animator.SendAnimPack();
297 }
298
299 private void HandleAppearanceSave(UUID agentid)
300 {
301 ScenePresence sp = m_scene.GetScenePresence(agentid); 410 ScenePresence sp = m_scene.GetScenePresence(agentid);
302 if (sp == null) 411 if (sp == null)
303 { 412 {
@@ -321,7 +430,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
321 { 430 {
322 if (kvp.Value < now) 431 if (kvp.Value < now)
323 { 432 {
324 Util.FireAndForget(delegate(object o) { HandleAppearanceSend(kvp.Key); }); 433 Util.FireAndForget(delegate(object o) { SendAppearance(kvp.Key); });
325 m_sendqueue.Remove(kvp.Key); 434 m_sendqueue.Remove(kvp.Key);
326 } 435 }
327 } 436 }
@@ -334,7 +443,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
334 { 443 {
335 if (kvp.Value < now) 444 if (kvp.Value < now)
336 { 445 {
337 Util.FireAndForget(delegate(object o) { HandleAppearanceSave(kvp.Key); }); 446 Util.FireAndForget(delegate(object o) { SaveAppearance(kvp.Key); });
338 m_savequeue.Remove(kvp.Key); 447 m_savequeue.Remove(kvp.Key);
339 } 448 }
340 } 449 }
@@ -380,11 +489,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
380 // m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId); 489 // m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId);
381 490
382 // we need to clean out the existing textures 491 // we need to clean out the existing textures
383 sp.Appearance.ResetAppearance(); 492 sp.Appearance.ResetAppearance();
384 493
385 // operate on a copy of the appearance so we don't have to lock anything 494 // operate on a copy of the appearance so we don't have to lock anything yet
386 AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false); 495 AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false);
387 496
388 foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) 497 foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
389 { 498 {
390 if (wear.Type < AvatarWearable.MAX_WEARABLES) 499 if (wear.Type < AvatarWearable.MAX_WEARABLES)
@@ -396,12 +505,37 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
396 // This could take awhile since it needs to pull inventory 505 // This could take awhile since it needs to pull inventory
397 SetAppearanceAssets(sp.UUID, ref avatAppearance); 506 SetAppearanceAssets(sp.UUID, ref avatAppearance);
398 507
399 // could get fancier with the locks here, but in the spirit of "last write wins" 508 lock (m_setAppearanceLock)
400 // this should work correctly, also, we don't need to send the appearance here 509 {
401 // since the "iswearing" will trigger a new set of visual param and baked texture changes 510 // Update only those fields that we have changed. This is important because the viewer
402 // when those complete, the new appearance will be sent 511 // often sends AvatarIsWearing and SetAppearance packets at once, and AvatarIsWearing
403 sp.Appearance = avatAppearance; 512 // shouldn't overwrite the changes made in SetAppearance.
404 QueueAppearanceSave(client.AgentId); 513 sp.Appearance.Wearables = avatAppearance.Wearables;
514 sp.Appearance.Texture = avatAppearance.Texture;
515
516 // We don't need to send the appearance here since the "iswearing" will trigger a new set
517 // of visual param and baked texture changes. When those complete, the new appearance will be sent
518
519 QueueAppearanceSave(client.AgentId);
520 }
521 }
522
523 public bool SendAppearance(UUID agentId)
524 {
525 ScenePresence sp = m_scene.GetScenePresence(agentId);
526 if (sp == null)
527 {
528 m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId);
529 return false;
530 }
531
532 // Send the appearance to everyone in the scene
533 sp.SendAppearanceToAllOtherAgents();
534
535 // Send animations back to the avatar as well
536 sp.Animator.SendAnimPack();
537
538 return true;
405 } 539 }
406 540
407 private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) 541 private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance)
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
new file mode 100644
index 0000000..7b2f14e
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
@@ -0,0 +1,120 @@
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 Nini.Config;
31using NUnit.Framework;
32using OpenMetaverse;
33using OpenSim.Framework;
34using OpenSim.Region.CoreModules.Asset;
35using OpenSim.Region.Framework.Scenes;
36using OpenSim.Tests.Common;
37using OpenSim.Tests.Common.Mock;
38
39namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
40{
41 [TestFixture]
42 public class AvatarFactoryModuleTests
43 {
44 /// <summary>
45 /// Only partial right now since we don't yet test that it's ended up in the avatar appearance service.
46 /// </summary>
47 [Test]
48 public void TestSetAppearance()
49 {
50 TestHelpers.InMethod();
51// log4net.Config.XmlConfigurator.Configure();
52
53 UUID userId = TestHelpers.ParseTail(0x1);
54
55 AvatarFactoryModule afm = new AvatarFactoryModule();
56 TestScene scene = SceneHelpers.SetupScene();
57 SceneHelpers.SetupSceneModules(scene, afm);
58 IClientAPI tc = SceneHelpers.AddScenePresence(scene, userId).ControllingClient;
59
60 byte[] visualParams = new byte[AvatarAppearance.VISUALPARAM_COUNT];
61 for (byte i = 0; i < visualParams.Length; i++)
62 visualParams[i] = i;
63
64 afm.SetAppearanceFromClient(tc, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams);
65
66 ScenePresence sp = scene.GetScenePresence(userId);
67
68 // TODO: Check baked texture
69 Assert.AreEqual(visualParams, sp.Appearance.VisualParams);
70 }
71
72 [Test]
73 public void TestSaveBakedTextures()
74 {
75 TestHelpers.InMethod();
76// log4net.Config.XmlConfigurator.Configure();
77
78 UUID userId = TestHelpers.ParseTail(0x1);
79 UUID eyesTextureId = TestHelpers.ParseTail(0x2);
80
81 // We need an asset cache because otherwise the LocalAssetServiceConnector will short-circuit directly
82 // to the AssetService, which will then store temporary and local assets permanently
83 CoreAssetCache assetCache = new CoreAssetCache();
84
85 AvatarFactoryModule afm = new AvatarFactoryModule();
86 TestScene scene = SceneHelpers.SetupScene(assetCache);
87 SceneHelpers.SetupSceneModules(scene, afm);
88 IClientAPI tc = SceneHelpers.AddScenePresence(scene, userId).ControllingClient;
89
90 // TODO: Use the actual BunchOfCaps functionality once we slot in the CapabilitiesModules
91 AssetBase uploadedAsset;
92 uploadedAsset = new AssetBase(eyesTextureId, "Baked Texture", (sbyte)AssetType.Texture, userId.ToString());
93 uploadedAsset.Data = new byte[] { 2 };
94 uploadedAsset.Temporary = true;
95 uploadedAsset.Local = true; // Local assets aren't persisted, non-local are
96 scene.AssetService.Store(uploadedAsset);
97
98 byte[] visualParams = new byte[AvatarAppearance.VISUALPARAM_COUNT];
99 for (byte i = 0; i < visualParams.Length; i++)
100 visualParams[i] = i;
101
102 Primitive.TextureEntry bakedTextureEntry = new Primitive.TextureEntry(TestHelpers.ParseTail(0x10));
103 uint eyesFaceIndex = (uint)AppearanceManager.BakeTypeToAgentTextureIndex(BakeType.Eyes);
104 Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex);
105 eyesFace.TextureID = eyesTextureId;
106
107 afm.SetAppearanceFromClient(tc, bakedTextureEntry, visualParams);
108 afm.SaveBakedTextures(userId);
109// Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = afm.GetBakedTextureFaces(userId);
110
111 // We should also inpsect the asset data store layer directly, but this is difficult to get at right now.
112 assetCache.Clear();
113
114 AssetBase eyesBake = scene.AssetService.Get(eyesTextureId.ToString());
115 Assert.That(eyesBake, Is.Not.Null);
116 Assert.That(eyesBake.Temporary, Is.False);
117 Assert.That(eyesBake.Local, Is.False);
118 }
119 }
120} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
index 1a0b914..d9dcee7 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
@@ -172,11 +172,15 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
172 private void RetrieveInstantMessages(IClientAPI client) 172 private void RetrieveInstantMessages(IClientAPI client)
173 { 173 {
174 if (m_RestURL == String.Empty) 174 if (m_RestURL == String.Empty)
175 {
175 return; 176 return;
177 }
178 else
179 {
180 m_log.DebugFormat("[OFFLINE MESSAGING]: Retrieving stored messages for {0}", client.AgentId);
176 181
177 m_log.DebugFormat("[OFFLINE MESSAGING] Retrieving stored messages for {0}", client.AgentId); 182 List<GridInstantMessage> msglist
178 183 = SynchronousRestObjectRequester.MakeRequest<UUID, List<GridInstantMessage>>(
179 List<GridInstantMessage> msglist = SynchronousRestObjectPoster.BeginPostObject<UUID, List<GridInstantMessage>>(
180 "POST", m_RestURL + "/RetrieveMessages/", client.AgentId); 184 "POST", m_RestURL + "/RetrieveMessages/", client.AgentId);
181 185
182 if (msglist != null) 186 if (msglist != null)
@@ -209,6 +213,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
209 im.dialog != (byte)InstantMessageDialog.GroupInvitation && 213 im.dialog != (byte)InstantMessageDialog.GroupInvitation &&
210 im.dialog != (byte)InstantMessageDialog.InventoryOffered) 214 im.dialog != (byte)InstantMessageDialog.InventoryOffered)
211 { 215 {
216 bool success = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>(
217 "POST", m_RestURL+"/SaveMessage/", im);
212 return; 218 return;
213 } 219 }
214 220
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs
index aadeedb..19ef571 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs
@@ -100,8 +100,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
100// log4net.Config.XmlConfigurator.Configure(); 100// log4net.Config.XmlConfigurator.Configure();
101 101
102 InventoryArchiverModule archiverModule = new InventoryArchiverModule(); 102 InventoryArchiverModule archiverModule = new InventoryArchiverModule();
103 Scene scene = SceneSetupHelpers.SetupScene(); 103 Scene scene = SceneHelpers.SetupScene();
104 SceneSetupHelpers.SetupSceneModules(scene, archiverModule); 104 SceneHelpers.SetupSceneModules(scene, archiverModule);
105 105
106 UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire"); 106 UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire");
107 107
@@ -109,7 +109,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
109 109
110 // Create scene object asset 110 // Create scene object asset
111 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); 111 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
112 SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, ownerId, "Ray Gun Object", 0x50); 112 SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, ownerId, "Ray Gun Object", 0x50);
113 113
114 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); 114 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
115 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); 115 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
@@ -127,10 +127,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
127 scene.AddInventoryItem(item1); 127 scene.AddInventoryItem(item1);
128 128
129 // Create coalesced objects asset 129 // Create coalesced objects asset
130 SceneObjectGroup cobj1 = SceneSetupHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object1", 0x120); 130 SceneObjectGroup cobj1 = SceneHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object1", 0x120);
131 cobj1.AbsolutePosition = new Vector3(15, 30, 45); 131 cobj1.AbsolutePosition = new Vector3(15, 30, 45);
132 132
133 SceneObjectGroup cobj2 = SceneSetupHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object2", 0x140); 133 SceneObjectGroup cobj2 = SceneHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object2", 0x140);
134 cobj2.AbsolutePosition = new Vector3(25, 50, 75); 134 cobj2.AbsolutePosition = new Vector3(25, 50, 75);
135 135
136 CoalescedSceneObjects coa = new CoalescedSceneObjects(m_uaLL1.PrincipalID, cobj1, cobj2); 136 CoalescedSceneObjects coa = new CoalescedSceneObjects(m_uaLL1.PrincipalID, cobj1, cobj2);
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
index ae3ab21..e409c8e 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
@@ -61,14 +61,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
61 SerialiserModule serialiserModule = new SerialiserModule(); 61 SerialiserModule serialiserModule = new SerialiserModule();
62 m_archiverModule = new InventoryArchiverModule(); 62 m_archiverModule = new InventoryArchiverModule();
63 63
64 m_scene = SceneSetupHelpers.SetupScene(); 64 m_scene = SceneHelpers.SetupScene();
65 SceneSetupHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule); 65 SceneHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule);
66 } 66 }
67 67
68 [Test] 68 [Test]
69 public void TestLoadCoalesecedItem() 69 public void TestLoadCoalesecedItem()
70 { 70 {
71 TestHelper.InMethod(); 71 TestHelpers.InMethod();
72// log4net.Config.XmlConfigurator.Configure(); 72// log4net.Config.XmlConfigurator.Configure();
73 73
74 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "password"); 74 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "password");
@@ -104,7 +104,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
104 [Test] 104 [Test]
105 public void TestOrder() 105 public void TestOrder()
106 { 106 {
107 TestHelper.InMethod(); 107 TestHelpers.InMethod();
108// log4net.Config.XmlConfigurator.Configure(); 108// log4net.Config.XmlConfigurator.Configure();
109 109
110 MemoryStream archiveReadStream = new MemoryStream(m_iarStreamBytes); 110 MemoryStream archiveReadStream = new MemoryStream(m_iarStreamBytes);
@@ -129,7 +129,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
129 [Test] 129 [Test]
130 public void TestSaveItemToIar() 130 public void TestSaveItemToIar()
131 { 131 {
132 TestHelper.InMethod(); 132 TestHelpers.InMethod();
133// log4net.Config.XmlConfigurator.Configure(); 133// log4net.Config.XmlConfigurator.Configure();
134 134
135 // Create user 135 // Create user
@@ -141,7 +141,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
141 141
142 // Create asset 142 // Create asset
143 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); 143 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
144 SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50); 144 SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50);
145 145
146 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); 146 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
147 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); 147 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
@@ -224,7 +224,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
224 [Test] 224 [Test]
225 public void TestSaveItemToIarNoAssets() 225 public void TestSaveItemToIarNoAssets()
226 { 226 {
227 TestHelper.InMethod(); 227 TestHelpers.InMethod();
228// log4net.Config.XmlConfigurator.Configure(); 228// log4net.Config.XmlConfigurator.Configure();
229 229
230 // Create user 230 // Create user
@@ -236,7 +236,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
236 236
237 // Create asset 237 // Create asset
238 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); 238 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
239 SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50); 239 SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50);
240 240
241 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); 241 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
242 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); 242 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
@@ -325,7 +325,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
325 [Test] 325 [Test]
326 public void TestLoadIarCreatorAccountPresent() 326 public void TestLoadIarCreatorAccountPresent()
327 { 327 {
328 TestHelper.InMethod(); 328 TestHelpers.InMethod();
329// log4net.Config.XmlConfigurator.Configure(); 329// log4net.Config.XmlConfigurator.Configure();
330 330
331 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "meowfood"); 331 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "meowfood");
@@ -357,7 +357,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
357 [Test] 357 [Test]
358 public void TestLoadIarV0_1SameNameCreator() 358 public void TestLoadIarV0_1SameNameCreator()
359 { 359 {
360 TestHelper.InMethod(); 360 TestHelpers.InMethod();
361// log4net.Config.XmlConfigurator.Configure(); 361// log4net.Config.XmlConfigurator.Configure();
362 362
363 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood"); 363 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood");
@@ -390,7 +390,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
390 [Test] 390 [Test]
391 public void TestLoadIarV0_1AbsentCreator() 391 public void TestLoadIarV0_1AbsentCreator()
392 { 392 {
393 TestHelper.InMethod(); 393 TestHelpers.InMethod();
394// log4net.Config.XmlConfigurator.Configure(); 394// log4net.Config.XmlConfigurator.Configure();
395 395
396 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "password"); 396 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "password");
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs
index 127d5f8..417c20c 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs
@@ -57,13 +57,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
57 [Test] 57 [Test]
58 public void TestSavePathToIarV0_1() 58 public void TestSavePathToIarV0_1()
59 { 59 {
60 TestHelper.InMethod(); 60 TestHelpers.InMethod();
61// log4net.Config.XmlConfigurator.Configure(); 61// log4net.Config.XmlConfigurator.Configure();
62 62
63 InventoryArchiverModule archiverModule = new InventoryArchiverModule(); 63 InventoryArchiverModule archiverModule = new InventoryArchiverModule();
64 64
65 Scene scene = SceneSetupHelpers.SetupScene(); 65 Scene scene = SceneHelpers.SetupScene();
66 SceneSetupHelpers.SetupSceneModules(scene, archiverModule); 66 SceneHelpers.SetupSceneModules(scene, archiverModule);
67 67
68 // Create user 68 // Create user
69 string userFirstName = "Jock"; 69 string userFirstName = "Jock";
@@ -172,16 +172,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
172 [Test] 172 [Test]
173 public void TestLoadIarToInventoryPaths() 173 public void TestLoadIarToInventoryPaths()
174 { 174 {
175 TestHelper.InMethod(); 175 TestHelpers.InMethod();
176// log4net.Config.XmlConfigurator.Configure(); 176// log4net.Config.XmlConfigurator.Configure();
177 177
178 SerialiserModule serialiserModule = new SerialiserModule(); 178 SerialiserModule serialiserModule = new SerialiserModule();
179 InventoryArchiverModule archiverModule = new InventoryArchiverModule(); 179 InventoryArchiverModule archiverModule = new InventoryArchiverModule();
180 180
181 // Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene 181 // Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene
182 Scene scene = SceneSetupHelpers.SetupScene(); 182 Scene scene = SceneHelpers.SetupScene();
183 183
184 SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); 184 SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
185 185
186 UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "meowfood"); 186 UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "meowfood");
187 UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire"); 187 UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire");
@@ -217,13 +217,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
217 [Test] 217 [Test]
218 public void TestLoadIarPathStartsWithSlash() 218 public void TestLoadIarPathStartsWithSlash()
219 { 219 {
220 TestHelper.InMethod(); 220 TestHelpers.InMethod();
221// log4net.Config.XmlConfigurator.Configure(); 221// log4net.Config.XmlConfigurator.Configure();
222 222
223 SerialiserModule serialiserModule = new SerialiserModule(); 223 SerialiserModule serialiserModule = new SerialiserModule();
224 InventoryArchiverModule archiverModule = new InventoryArchiverModule(); 224 InventoryArchiverModule archiverModule = new InventoryArchiverModule();
225 Scene scene = SceneSetupHelpers.SetupScene(); 225 Scene scene = SceneHelpers.SetupScene();
226 SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); 226 SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
227 227
228 UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "password"); 228 UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "password");
229 archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/Objects", "password", m_iarStream); 229 archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/Objects", "password", m_iarStream);
@@ -238,7 +238,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
238 [Test] 238 [Test]
239 public void TestLoadIarPathWithEscapedChars() 239 public void TestLoadIarPathWithEscapedChars()
240 { 240 {
241 TestHelper.InMethod(); 241 TestHelpers.InMethod();
242// log4net.Config.XmlConfigurator.Configure(); 242// log4net.Config.XmlConfigurator.Configure();
243 243
244 string itemName = "You & you are a mean/man/"; 244 string itemName = "You & you are a mean/man/";
@@ -247,8 +247,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
247 247
248 InventoryArchiverModule archiverModule = new InventoryArchiverModule(); 248 InventoryArchiverModule archiverModule = new InventoryArchiverModule();
249 249
250 Scene scene = SceneSetupHelpers.SetupScene(); 250 Scene scene = SceneHelpers.SetupScene();
251 SceneSetupHelpers.SetupSceneModules(scene, archiverModule); 251 SceneHelpers.SetupSceneModules(scene, archiverModule);
252 252
253 // Create user 253 // Create user
254 string userFirstName = "Jock"; 254 string userFirstName = "Jock";
@@ -323,10 +323,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
323 [Test] 323 [Test]
324 public void TestNewIarPath() 324 public void TestNewIarPath()
325 { 325 {
326 TestHelper.InMethod(); 326 TestHelpers.InMethod();
327// log4net.Config.XmlConfigurator.Configure(); 327// log4net.Config.XmlConfigurator.Configure();
328 328
329 Scene scene = SceneSetupHelpers.SetupScene(); 329 Scene scene = SceneHelpers.SetupScene();
330 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); 330 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene);
331 331
332 Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>(); 332 Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>();
@@ -390,10 +390,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
390 [Test] 390 [Test]
391 public void TestPartExistingIarPath() 391 public void TestPartExistingIarPath()
392 { 392 {
393 TestHelper.InMethod(); 393 TestHelpers.InMethod();
394 //log4net.Config.XmlConfigurator.Configure(); 394 //log4net.Config.XmlConfigurator.Configure();
395 395
396 Scene scene = SceneSetupHelpers.SetupScene(); 396 Scene scene = SceneHelpers.SetupScene();
397 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); 397 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene);
398 398
399 string folder1ExistingName = "a"; 399 string folder1ExistingName = "a";
@@ -441,10 +441,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
441 [Test] 441 [Test]
442 public void TestMergeIarPath() 442 public void TestMergeIarPath()
443 { 443 {
444 TestHelper.InMethod(); 444 TestHelpers.InMethod();
445// log4net.Config.XmlConfigurator.Configure(); 445// log4net.Config.XmlConfigurator.Configure();
446 446
447 Scene scene = SceneSetupHelpers.SetupScene(); 447 Scene scene = SceneHelpers.SetupScene();
448 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); 448 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene);
449 449
450 string folder1ExistingName = "a"; 450 string folder1ExistingName = "a";
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
index 528bc8d..120fd43 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
@@ -208,9 +208,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
208 Array.Copy(copyIDBytes, 0, im.binaryBucket, 1, copyIDBytes.Length); 208 Array.Copy(copyIDBytes, 0, im.binaryBucket, 1, copyIDBytes.Length);
209 209
210 if (user != null) 210 if (user != null)
211 {
212 user.ControllingClient.SendBulkUpdateInventory(folderCopy); 211 user.ControllingClient.SendBulkUpdateInventory(folderCopy);
213 }
214 212
215 // HACK!! 213 // HACK!!
216 im.imSessionID = folderID.Guid; 214 im.imSessionID = folderID.Guid;
@@ -240,9 +238,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
240 Array.Copy(copyID.GetBytes(), 0, im.binaryBucket, 1, 16); 238 Array.Copy(copyID.GetBytes(), 0, im.binaryBucket, 1, 16);
241 239
242 if (user != null) 240 if (user != null)
243 {
244 user.ControllingClient.SendBulkUpdateInventory(itemCopy); 241 user.ControllingClient.SendBulkUpdateInventory(itemCopy);
245 }
246 242
247 // HACK!! 243 // HACK!!
248 im.imSessionID = itemID.Guid; 244 im.imSessionID = itemID.Guid;
@@ -280,7 +276,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
280 else 276 else
281 { 277 {
282 if (m_TransferModule != null) 278 if (m_TransferModule != null)
283 m_TransferModule.SendInstantMessage(im, delegate(bool success) {}); 279 m_TransferModule.SendInstantMessage(im, delegate(bool success) {
280 // Send BulkUpdateInventory
281 IInventoryService invService = scene.InventoryService;
282 UUID inventoryEntityID = new UUID(im.imSessionID); // The inventory item /folder, back from it's trip
283
284 InventoryFolderBase folder = new InventoryFolderBase(inventoryEntityID, client.AgentId);
285 folder = invService.GetFolder(folder);
286
287 ScenePresence fromUser = scene.GetScenePresence(new UUID(im.fromAgentID));
288
289 // If the user has left the scene by the time the message comes back then we can't send
290 // them the update.
291 if (fromUser != null)
292 fromUser.ControllingClient.SendBulkUpdateInventory(folder);
293 });
284 } 294 }
285 } 295 }
286 else if (im.dialog == (byte) InstantMessageDialog.InventoryDeclined) 296 else if (im.dialog == (byte) InstantMessageDialog.InventoryDeclined)
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
index c82cfd2..d687e6a 100644
--- a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
@@ -196,7 +196,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
196 if (!(client.Scene is Scene)) 196 if (!(client.Scene is Scene))
197 return; 197 return;
198 198
199 Scene scene = (Scene)(client.Scene); 199// Scene scene = (Scene)(client.Scene);
200 200
201 GridInstantMessage im = null; 201 GridInstantMessage im = null;
202 if (m_PendingLures.TryGetValue(lureID, out im)) 202 if (m_PendingLures.TryGetValue(lureID, out im))
diff --git a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
index 079e1b6..dee0ad4 100644
--- a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
@@ -134,7 +134,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Profile
134 if (!(s is Scene)) 134 if (!(s is Scene))
135 return; 135 return;
136 136
137 Scene scene = (Scene)s; 137// Scene scene = (Scene)s;
138 138
139 string profileUrl = String.Empty; 139 string profileUrl = String.Empty;
140 string aboutText = String.Empty; 140 string aboutText = String.Empty;
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 90f0ca2..faccab2 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -209,7 +209,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
209 sp.TeleportFlags = (TeleportFlags)teleportFlags; 209 sp.TeleportFlags = (TeleportFlags)teleportFlags;
210 sp.Teleport(position); 210 sp.Teleport(position);
211 211
212 foreach (SceneObjectGroup grp in sp.Attachments) 212 foreach (SceneObjectGroup grp in sp.GetAttachments())
213 sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT); 213 sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT);
214 } 214 }
215 else // Another region possibly in another simulator 215 else // Another region possibly in another simulator
@@ -494,7 +494,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
494 // Now let's make it officially a child agent 494 // Now let's make it officially a child agent
495 sp.MakeChildAgent(); 495 sp.MakeChildAgent();
496 496
497 sp.Scene.CleanDroppedAttachments(); 497// sp.Scene.CleanDroppedAttachments();
498 498
499 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone 499 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
500 500
@@ -560,11 +560,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
560 560
561 protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout) 561 protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout)
562 { 562 {
563 foreach (SceneObjectGroup sop in sp.Attachments) 563 sp.Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, true);
564 {
565 sop.Scene.DeleteSceneObject(sop, true);
566 }
567 sp.Attachments.Clear();
568 } 564 }
569 565
570 protected void KillEntity(Scene scene, uint localID) 566 protected void KillEntity(Scene scene, uint localID)
@@ -1088,10 +1084,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1088 #endregion 1084 #endregion
1089 1085
1090 #region Enable Child Agent 1086 #region Enable Child Agent
1087
1091 /// <summary> 1088 /// <summary>
1092 /// This informs a single neighbouring region about agent "avatar". 1089 /// This informs a single neighbouring region about agent "avatar".
1093 /// Calls an asynchronous method to do so.. so it doesn't lag the sim. 1090 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
1094 /// </summary> 1091 /// </summary>
1092 /// <param name="sp"></param>
1093 /// <param name="region"></param>
1095 public void EnableChildAgent(ScenePresence sp, GridRegion region) 1094 public void EnableChildAgent(ScenePresence sp, GridRegion region)
1096 { 1095 {
1097 m_log.DebugFormat("[ENTITY TRANSFER]: Enabling child agent in new neighbour {0}", region.RegionName); 1096 m_log.DebugFormat("[ENTITY TRANSFER]: Enabling child agent in new neighbour {0}", region.RegionName);
@@ -1153,6 +1152,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1153 /// This informs all neighbouring regions about agent "avatar". 1152 /// This informs all neighbouring regions about agent "avatar".
1154 /// Calls an asynchronous method to do so.. so it doesn't lag the sim. 1153 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
1155 /// </summary> 1154 /// </summary>
1155 /// <param name="sp"></param>
1156 public void EnableChildAgents(ScenePresence sp) 1156 public void EnableChildAgents(ScenePresence sp)
1157 { 1157 {
1158 List<GridRegion> neighbours = new List<GridRegion>(); 1158 List<GridRegion> neighbours = new List<GridRegion>();
@@ -1340,7 +1340,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1340 Utils.LongToUInts(reg.RegionHandle, out x, out y); 1340 Utils.LongToUInts(reg.RegionHandle, out x, out y);
1341 x = x / Constants.RegionSize; 1341 x = x / Constants.RegionSize;
1342 y = y / Constants.RegionSize; 1342 y = y / Constants.RegionSize;
1343 m_log.Debug("[ENTITY TRANSFER MODULE]: Starting to inform client about neighbour " + x + ", " + y + "(" + endPoint.ToString() + ")"); 1343 m_log.Debug("[ENTITY TRANSFER MODULE]: Starting to inform client about neighbour " + x + ", " + y + "(" + endPoint + ")");
1344 1344
1345 string capsPath = reg.ServerURI + CapsUtil.GetCapsSeedPath(a.CapsPath); 1345 string capsPath = reg.ServerURI + CapsUtil.GetCapsSeedPath(a.CapsPath);
1346 1346
@@ -1786,34 +1786,33 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1786 1786
1787 protected bool CrossAttachmentsIntoNewRegion(GridRegion destination, ScenePresence sp, bool silent) 1787 protected bool CrossAttachmentsIntoNewRegion(GridRegion destination, ScenePresence sp, bool silent)
1788 { 1788 {
1789 List<SceneObjectGroup> m_attachments = sp.Attachments; 1789 List<SceneObjectGroup> m_attachments = sp.GetAttachments();
1790 lock (m_attachments) 1790
1791 // Validate
1792 foreach (SceneObjectGroup gobj in m_attachments)
1791 { 1793 {
1792 // Validate 1794 if (gobj == null || gobj.IsDeleted)
1793 foreach (SceneObjectGroup gobj in m_attachments) 1795 return false;
1794 { 1796 }
1795 if (gobj == null || gobj.IsDeleted)
1796 return false;
1797 }
1798 1797
1799 foreach (SceneObjectGroup gobj in m_attachments) 1798 foreach (SceneObjectGroup gobj in m_attachments)
1799 {
1800 // If the prim group is null then something must have happened to it!
1801 if (gobj != null)
1800 { 1802 {
1801 // If the prim group is null then something must have happened to it! 1803 // Set the parent localID to 0 so it transfers over properly.
1802 if (gobj != null && gobj.RootPart != null) 1804 gobj.RootPart.SetParentLocalId(0);
1803 { 1805 gobj.AbsolutePosition = gobj.RootPart.AttachedPos;
1804 // Set the parent localID to 0 so it transfers over properly. 1806 gobj.IsAttachment = false;
1805 gobj.RootPart.SetParentLocalId(0); 1807 //gobj.RootPart.LastOwnerID = gobj.GetFromAssetID();
1806 gobj.AbsolutePosition = gobj.RootPart.AttachedPos; 1808 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", gobj.UUID, destination.RegionName);
1807 gobj.RootPart.IsAttachment = false; 1809 CrossPrimGroupIntoNewRegion(destination, gobj, silent);
1808 //gobj.RootPart.LastOwnerID = gobj.GetFromAssetID();
1809 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", gobj.UUID, destination.RegionName);
1810 CrossPrimGroupIntoNewRegion(destination, gobj, silent);
1811 }
1812 } 1810 }
1813 m_attachments.Clear();
1814
1815 return true;
1816 } 1811 }
1812
1813 sp.ClearAttachments();
1814
1815 return true;
1817 } 1816 }
1818 1817
1819 #endregion 1818 #endregion
@@ -1862,7 +1861,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1862 int i = 0; 1861 int i = 0;
1863 if (sp.InTransitScriptStates.Count > 0) 1862 if (sp.InTransitScriptStates.Count > 0)
1864 { 1863 {
1865 sp.Attachments.ForEach(delegate(SceneObjectGroup sog) 1864 List<SceneObjectGroup> attachments = sp.GetAttachments();
1865
1866 foreach (SceneObjectGroup sog in attachments)
1866 { 1867 {
1867 if (i < sp.InTransitScriptStates.Count) 1868 if (i < sp.InTransitScriptStates.Count)
1868 { 1869 {
@@ -1871,8 +1872,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1871 sog.ResumeScripts(); 1872 sog.ResumeScripts();
1872 } 1873 }
1873 else 1874 else
1874 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: InTransitScriptStates.Count={0} smaller than Attachments.Count={1}", sp.InTransitScriptStates.Count, sp.Attachments.Count); 1875 m_log.ErrorFormat(
1875 }); 1876 "[ENTITY TRANSFER MODULE]: InTransitScriptStates.Count={0} smaller than Attachments.Count={1}",
1877 sp.InTransitScriptStates.Count, attachments.Count);
1878 }
1876 1879
1877 sp.InTransitScriptStates.Clear(); 1880 sp.InTransitScriptStates.Clear();
1878 } 1881 }
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index a98ce85..654e202 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -325,7 +325,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
325 } 325 }
326 } 326 }
327 327
328 // This is pethod scoped and will be returned. It will be the 328 // This is method scoped and will be returned. It will be the
329 // last created asset id 329 // last created asset id
330 UUID assetID = UUID.Zero; 330 UUID assetID = UUID.Zero;
331 331
@@ -354,9 +354,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
354 CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero); 354 CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero);
355 Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>(); 355 Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>();
356 356
357 Dictionary<UUID, string> xmlStrings =
358 new Dictionary<UUID, string>();
359
360 foreach (SceneObjectGroup objectGroup in objlist) 357 foreach (SceneObjectGroup objectGroup in objlist)
361 { 358 {
362 Vector3 inventoryStoredPosition = new Vector3 359 Vector3 inventoryStoredPosition = new Vector3
@@ -369,12 +366,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
369 : objectGroup.AbsolutePosition.Y, 366 : objectGroup.AbsolutePosition.Y,
370 objectGroup.AbsolutePosition.Z); 367 objectGroup.AbsolutePosition.Z);
371 368
372 Vector3 originalPosition = objectGroup.AbsolutePosition; 369 originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition;
373
374 // Restore attachment data after trip through the sim
375 if (objectGroup.RootPart.AttachPoint > 0)
376 inventoryStoredPosition = objectGroup.RootPart.AttachOffset;
377 objectGroup.RootPart.Shape.State = objectGroup.RootPart.AttachPoint;
378 370
379 objectGroup.AbsolutePosition = inventoryStoredPosition; 371 objectGroup.AbsolutePosition = inventoryStoredPosition;
380 372
@@ -388,60 +380,159 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
388 (uint)PermissionMask.Modify); 380 (uint)PermissionMask.Modify);
389 objectGroup.RootPart.NextOwnerMask |= 381 objectGroup.RootPart.NextOwnerMask |=
390 (uint)PermissionMask.Move; 382 (uint)PermissionMask.Move;
383
384 coa.Add(objectGroup);
385 }
391 386
392 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup); 387 string itemXml;
393 388
394 objectGroup.AbsolutePosition = originalPosition; 389 if (objlist.Count > 1)
390 itemXml = CoalescedSceneObjectsSerializer.ToXml(coa);
391 else
392 itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0]);
393
394 // Restore the position of each group now that it has been stored to inventory.
395 foreach (SceneObjectGroup objectGroup in objlist)
396 objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID];
395 397
396 xmlStrings[objectGroup.UUID] = sceneObjectXml; 398 InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID);
399 if (item == null)
400 return UUID.Zero;
401
402 // Can't know creator is the same, so null it in inventory
403 if (objlist.Count > 1)
404 {
405 item.CreatorId = UUID.Zero.ToString();
406 item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems;
397 } 407 }
408 else
409 {
410 item.CreatorId = objlist[0].RootPart.CreatorID.ToString();
411 item.SaleType = objlist[0].RootPart.ObjectSaleType;
412 item.SalePrice = objlist[0].RootPart.SalePrice;
413 }
398 414
399 string itemXml; 415 AssetBase asset = CreateAsset(
416 objlist[0].GetPartName(objlist[0].RootPart.LocalId),
417 objlist[0].GetPartDescription(objlist[0].RootPart.LocalId),
418 (sbyte)AssetType.Object,
419 Utils.StringToBytes(itemXml),
420 objlist[0].OwnerID.ToString());
421 m_Scene.AssetService.Store(asset);
422
423 item.AssetID = asset.FullID;
424 assetID = asset.FullID;
400 425
401 if (objlist.Count > 1) 426 if (DeRezAction.SaveToExistingUserInventoryItem == action)
402 { 427 {
403 float minX, minY, minZ; 428 m_Scene.InventoryService.UpdateItem(item);
404 float maxX, maxY, maxZ; 429 }
430 else
431 {
432 AddPermissions(item, objlist[0], objlist, remoteClient);
405 433
406 Vector3[] offsets = Scene.GetCombinedBoundingBox(objlist, 434 item.CreationDate = Util.UnixTimeSinceEpoch();
407 out minX, out maxX, out minY, out maxY, 435 item.Description = asset.Description;
408 out minZ, out maxZ); 436 item.Name = asset.Name;
437 item.AssetType = asset.Type;
409 438
410 // CreateWrapper 439 m_Scene.AddInventoryItem(item);
411 XmlDocument itemDoc = new XmlDocument();
412 XmlElement root = itemDoc.CreateElement("", "CoalescedObject", "");
413 itemDoc.AppendChild(root);
414 440
415 // Embed the offsets into the group XML 441 if (remoteClient != null && item.Owner == remoteClient.AgentId)
416 for ( int i = 0 ; i < objlist.Count ; i++ )
417 { 442 {
418 XmlDocument doc = new XmlDocument(); 443 remoteClient.SendInventoryItemCreateUpdate(item, 0);
419 SceneObjectGroup g = objlist[i]; 444 }
420 doc.LoadXml(xmlStrings[g.UUID]); 445 else
421 XmlElement e = (XmlElement)doc.SelectSingleNode("/SceneObjectGroup"); 446 {
422 e.SetAttribute("offsetx", offsets[i].X.ToString()); 447 ScenePresence notifyUser = m_Scene.GetScenePresence(item.Owner);
423 e.SetAttribute("offsety", offsets[i].Y.ToString()); 448 if (notifyUser != null)
424 e.SetAttribute("offsetz", offsets[i].Z.ToString()); 449 {
425 450 notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
426 XmlNode objectNode = itemDoc.ImportNode(e, true); 451 }
427 root.AppendChild(objectNode);
428 } 452 }
453 }
454
455 // This is a hook to do some per-asset post-processing for subclasses that need that
456 if (remoteClient != null)
457 ExportAsset(remoteClient.AgentId, assetID);
458
459 return assetID;
460 }
429 461
430 float sizeX = maxX - minX; 462 protected virtual void ExportAsset(UUID agentID, UUID assetID)
431 float sizeY = maxY - minY; 463 {
432 float sizeZ = maxZ - minZ; 464 // nothing to do here
465 }
433 466
434 root.SetAttribute("x", sizeX.ToString()); 467 /// <summary>
435 root.SetAttribute("y", sizeY.ToString()); 468 /// Add relevant permissions for an object to the item.
436 root.SetAttribute("z", sizeZ.ToString()); 469 /// </summary>
470 /// <param name="item"></param>
471 /// <param name="so"></param>
472 /// <param name="objsForEffectivePermissions"></param>
473 /// <param name="remoteClient"></param>
474 /// <returns></returns>
475 protected InventoryItemBase AddPermissions(
476 InventoryItemBase item, SceneObjectGroup so, List<SceneObjectGroup> objsForEffectivePermissions,
477 IClientAPI remoteClient)
478 {
479 uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move) | 7;
480 foreach (SceneObjectGroup grp in objsForEffectivePermissions)
481 effectivePerms &= grp.GetEffectivePermissions();
482 effectivePerms |= (uint)PermissionMask.Move;
437 483
438 itemXml = itemDoc.InnerXml; 484 if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions())
485 {
486 uint perms = effectivePerms;
487 uint nextPerms = (perms & 7) << 13;
488 if ((nextPerms & (uint)PermissionMask.Copy) == 0)
489 perms &= ~(uint)PermissionMask.Copy;
490 if ((nextPerms & (uint)PermissionMask.Transfer) == 0)
491 perms &= ~(uint)PermissionMask.Transfer;
492 if ((nextPerms & (uint)PermissionMask.Modify) == 0)
493 perms &= ~(uint)PermissionMask.Modify;
494
495 item.BasePermissions = perms & so.RootPart.NextOwnerMask;
496 item.CurrentPermissions = item.BasePermissions;
497 item.NextPermissions = perms & so.RootPart.NextOwnerMask;
498 item.EveryOnePermissions = so.RootPart.EveryoneMask & so.RootPart.NextOwnerMask;
499 item.GroupPermissions = so.RootPart.GroupMask & so.RootPart.NextOwnerMask;
500
501 // Magic number badness. Maybe this deserves an enum.
502 // bit 4 (16) is the "Slam" bit, it means treat as passed
503 // and apply next owner perms on rez
504 item.CurrentPermissions |= 16; // Slam!
439 } 505 }
440 else 506 else
441 { 507 {
442 itemXml = xmlStrings[objlist[0].UUID]; 508 item.BasePermissions = effectivePerms;
443 } 509 item.CurrentPermissions = effectivePerms;
510 item.NextPermissions = so.RootPart.NextOwnerMask & effectivePerms;
511 item.EveryOnePermissions = so.RootPart.EveryoneMask & effectivePerms;
512 item.GroupPermissions = so.RootPart.GroupMask & effectivePerms;
444 513
514 item.CurrentPermissions &=
515 ((uint)PermissionMask.Copy |
516 (uint)PermissionMask.Transfer |
517 (uint)PermissionMask.Modify |
518 (uint)PermissionMask.Move |
519 7); // Preserve folded permissions
520 }
521
522 return item;
523 }
524
525 /// <summary>
526 /// Create an item using details for the given scene object.
527 /// </summary>
528 /// <param name="action"></param>
529 /// <param name="remoteClient"></param>
530 /// <param name="so"></param>
531 /// <param name="folderID"></param>
532 /// <returns></returns>
533 protected InventoryItemBase CreateItemForObject(
534 DeRezAction action, IClientAPI remoteClient, SceneObjectGroup so, UUID folderID)
535 {
445 // Get the user info of the item destination 536 // Get the user info of the item destination
446 // 537 //
447 UUID userID = UUID.Zero; 538 UUID userID = UUID.Zero;
@@ -453,7 +544,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
453 // Saving changes requires a local user 544 // Saving changes requires a local user
454 // 545 //
455 if (remoteClient == null) 546 if (remoteClient == null)
456 return UUID.Zero; 547 return null;
457 548
458 userID = remoteClient.AgentId; 549 userID = remoteClient.AgentId;
459 } 550 }
@@ -461,13 +552,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
461 { 552 {
462 // All returns / deletes go to the object owner 553 // All returns / deletes go to the object owner
463 // 554 //
464 555 userID = so.RootPart.OwnerID;
465 userID = objlist[0].RootPart.OwnerID;
466 } 556 }
467 557
468 if (userID == UUID.Zero) // Can't proceed 558 if (userID == UUID.Zero) // Can't proceed
469 { 559 {
470 return UUID.Zero; 560 return null;
471 } 561 }
472 562
473 // If we're returning someone's item, it goes back to the 563 // If we're returning someone's item, it goes back to the
@@ -475,13 +565,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
475 // Delete is treated like return in this case 565 // Delete is treated like return in this case
476 // Deleting your own items makes them go to trash 566 // Deleting your own items makes them go to trash
477 // 567 //
478 568
479 InventoryFolderBase folder = null; 569 InventoryFolderBase folder = null;
480 InventoryItemBase item = null; 570 InventoryItemBase item = null;
481 571
482 if (DeRezAction.SaveToExistingUserInventoryItem == action) 572 if (DeRezAction.SaveToExistingUserInventoryItem == action)
483 { 573 {
484 item = new InventoryItemBase(objlist[0].RootPart.FromUserInventoryItemID, userID); 574 item = new InventoryItemBase(so.RootPart.FromUserInventoryItemID, userID);
485 item = m_Scene.InventoryService.GetItem(item); 575 item = m_Scene.InventoryService.GetItem(item);
486 576
487 //item = userInfo.RootFolder.FindItem( 577 //item = userInfo.RootFolder.FindItem(
@@ -491,8 +581,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
491 { 581 {
492 m_log.DebugFormat( 582 m_log.DebugFormat(
493 "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.", 583 "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.",
494 objlist[0].Name, objlist[0].UUID); 584 so.Name, so.UUID);
495 return UUID.Zero; 585
586 return null;
496 } 587 }
497 } 588 }
498 else 589 else
@@ -504,19 +595,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
504 // Deleting someone else's item 595 // Deleting someone else's item
505 // 596 //
506 if (remoteClient == null || 597 if (remoteClient == null ||
507 objlist[0].OwnerID != remoteClient.AgentId) 598 so.OwnerID != remoteClient.AgentId)
508 { 599 {
509
510 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); 600 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
511 } 601 }
512 else 602 else
513 { 603 {
514 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); 604 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder);
515 } 605 }
516 } 606 }
517 else if (action == DeRezAction.Return) 607 else if (action == DeRezAction.Return)
518 { 608 {
519
520 // Dump to lost + found unconditionally 609 // Dump to lost + found unconditionally
521 // 610 //
522 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); 611 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
@@ -532,8 +621,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
532 } 621 }
533 else 622 else
534 { 623 {
535 if (remoteClient == null || 624 if (remoteClient == null || so.OwnerID != remoteClient.AgentId)
536 objlist[0].OwnerID != remoteClient.AgentId)
537 { 625 {
538 // Taking copy of another person's item. Take to 626 // Taking copy of another person's item. Take to
539 // Objects folder. 627 // Objects folder.
@@ -554,9 +642,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
554 // 642 //
555 if (action == DeRezAction.Take || action == DeRezAction.TakeCopy) 643 if (action == DeRezAction.Take || action == DeRezAction.TakeCopy)
556 { 644 {
557 if (objlist[0].RootPart.FromFolderID != UUID.Zero && objlist[0].OwnerID == remoteClient.AgentId) 645 if (so.RootPart.FromFolderID != UUID.Zero)
558 { 646 {
559 InventoryFolderBase f = new InventoryFolderBase(objlist[0].RootPart.FromFolderID, userID); 647 InventoryFolderBase f = new InventoryFolderBase(so.RootPart.FromFolderID, userID);
560 folder = m_Scene.InventoryService.GetFolder(f); 648 folder = m_Scene.InventoryService.GetFolder(f);
561 } 649 }
562 } 650 }
@@ -567,380 +655,375 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
567 655
568 if (folder == null) // Nowhere to put it 656 if (folder == null) // Nowhere to put it
569 { 657 {
570 return UUID.Zero; 658 return null;
571 } 659 }
572 } 660 }
573 661
574 item = new InventoryItemBase(); 662 item = new InventoryItemBase();
575 // Can't know creator is the same, so null it in inventory
576 if (objlist.Count > 1)
577 {
578 item.CreatorId = UUID.Zero.ToString();
579 item.CreatorData = String.Empty;
580 }
581 else
582 {
583 item.CreatorId = objlist[0].RootPart.CreatorID.ToString();
584 item.CreatorData = objlist[0].RootPart.CreatorData;
585 }
586 item.ID = UUID.Random(); 663 item.ID = UUID.Random();
587 item.InvType = (int)InventoryType.Object; 664 item.InvType = (int)InventoryType.Object;
588 item.Folder = folder.ID; 665 item.Folder = folder.ID;
589 item.Owner = userID; 666 item.Owner = userID;
590 if (objlist.Count > 1) 667 }
668
669 return item;
670 }
671
672 public virtual SceneObjectGroup RezObject(
673 IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
674 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
675 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
676 {
677// m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID);
678 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
679 item = m_Scene.InventoryService.GetItem(item);
680
681 if (item == null)
682 {
683
684 return null;
685 }
686
687
688
689
690
691
692
693 item.Owner = remoteClient.AgentId;
694
695 return RezObject(
696 remoteClient, item, item.AssetID,
697 RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection,
698 RezSelected, RemoveItem, fromTaskID, attachment);
699 }
700
701 public virtual SceneObjectGroup RezObject(
702 IClientAPI remoteClient, InventoryItemBase item, UUID assetID, Vector3 RayEnd, Vector3 RayStart,
703 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
704 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
705 {
706 AssetBase rezAsset = m_Scene.AssetService.Get(assetID.ToString());
707
708 if (rezAsset == null)
709 {
710 if (item != null)
591 { 711 {
592 item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems; 712 m_log.WarnFormat(
713 "[InventoryAccessModule]: Could not find asset {0} for item {1} {2} for {3} in RezObject()",
714 assetID, item.Name, item.ID, remoteClient.Name);
593 } 715 }
594 else 716 else
595 { 717 {
596 item.SaleType = objlist[0].RootPart.ObjectSaleType; 718 m_log.WarnFormat(
597 item.SalePrice = objlist[0].RootPart.SalePrice; 719 "[InventoryAccessModule]: Could not find asset {0} for {1} in RezObject()",
720 assetID, remoteClient.Name);
598 } 721 }
722
723 return null;
599 } 724 }
600 725
601 AssetBase asset = CreateAsset( 726 SceneObjectGroup group = null;
602 objlist[0].GetPartName(objlist[0].RootPart.LocalId),
603 objlist[0].GetPartDescription(objlist[0].RootPart.LocalId),
604 (sbyte)AssetType.Object,
605 Utils.StringToBytes(itemXml),
606 objlist[0].OwnerID.ToString());
607 m_Scene.AssetService.Store(asset);
608 assetID = asset.FullID;
609 727
610 if (DeRezAction.SaveToExistingUserInventoryItem == action) 728 string xmlData = Utils.BytesToString(rezAsset.Data);
729 List<SceneObjectGroup> objlist =
730 new List<SceneObjectGroup>();
731 List<Vector3> veclist = new List<Vector3>();
732 byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0);
733 Vector3 pos;
734
735 XmlDocument doc = new XmlDocument();
736 doc.LoadXml(xmlData);
737 XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject");
738 if (e == null || attachment) // Single
611 { 739 {
612 item.AssetID = asset.FullID; 740 SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
613 m_Scene.InventoryService.UpdateItem(item); 741
742 objlist.Add(g);
743 veclist.Add(new Vector3(0, 0, 0));
744
745 float offsetHeight = 0;
746 pos = m_Scene.GetNewRezLocation(
747 RayStart, RayEnd, RayTargetID, Quaternion.Identity,
748 BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false);
749 pos.Z += offsetHeight;
614 } 750 }
615 else 751 else
616 { 752 {
617 item.AssetID = asset.FullID; 753 XmlElement coll = (XmlElement)e;
754 float bx = Convert.ToSingle(coll.GetAttribute("x"));
755 float by = Convert.ToSingle(coll.GetAttribute("y"));
756 float bz = Convert.ToSingle(coll.GetAttribute("z"));
757 Vector3 bbox = new Vector3(bx, by, bz);
618 758
619 uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move) | 7; 759 pos = m_Scene.GetNewRezLocation(RayStart, RayEnd,
620 foreach (SceneObjectGroup grp in objlist) 760 RayTargetID, Quaternion.Identity,
621 effectivePerms &= grp.GetEffectivePermissions(); 761 BypassRayCast, bRayEndIsIntersection, true,
622 effectivePerms |= (uint)PermissionMask.Move; 762 bbox, false);
623 763
624 if (remoteClient != null && (remoteClient.AgentId != objlist[0].RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) 764 pos -= bbox / 2;
625 { 765
626 uint perms = effectivePerms; 766 XmlNodeList groups = e.SelectNodes("SceneObjectGroup");
627 uint nextPerms = (perms & 7) << 13; 767 foreach (XmlNode n in groups)
628 if ((nextPerms & (uint)PermissionMask.Copy) == 0)
629 perms &= ~(uint)PermissionMask.Copy;
630 if ((nextPerms & (uint)PermissionMask.Transfer) == 0)
631 perms &= ~(uint)PermissionMask.Transfer;
632 if ((nextPerms & (uint)PermissionMask.Modify) == 0)
633 perms &= ~(uint)PermissionMask.Modify;
634
635 item.BasePermissions = perms & objlist[0].RootPart.NextOwnerMask;
636 item.CurrentPermissions = item.BasePermissions;
637 item.NextPermissions = perms & objlist[0].RootPart.NextOwnerMask;
638 item.EveryOnePermissions = objlist[0].RootPart.EveryoneMask & objlist[0].RootPart.NextOwnerMask;
639 item.GroupPermissions = objlist[0].RootPart.GroupMask & objlist[0].RootPart.NextOwnerMask;
640
641 item.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
642 }
643 else
644 { 768 {
645 item.BasePermissions = effectivePerms; 769 SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml);
646 item.CurrentPermissions = effectivePerms; 770
647 item.NextPermissions = objlist[0].RootPart.NextOwnerMask & effectivePerms; 771 objlist.Add(g);
648 item.EveryOnePermissions = objlist[0].RootPart.EveryoneMask & effectivePerms; 772 XmlElement el = (XmlElement)n;
649 item.GroupPermissions = objlist[0].RootPart.GroupMask & effectivePerms; 773
650 774 string rawX = el.GetAttribute("offsetx");
651 item.CurrentPermissions &= 775 string rawY = el.GetAttribute("offsety");
652 ((uint)PermissionMask.Copy | 776 string rawZ = el.GetAttribute("offsetz");
653 (uint)PermissionMask.Transfer | 777//
654 (uint)PermissionMask.Modify | 778// m_log.DebugFormat(
655 (uint)PermissionMask.Move | 779// "[INVENTORY ACCESS MODULE]: Converting coalesced object {0} offset <{1}, {2}, {3}>",
656 7); // Preserve folded permissions 780// g.Name, rawX, rawY, rawZ);
781
782 float x = Convert.ToSingle(rawX);
783 float y = Convert.ToSingle(rawY);
784 float z = Convert.ToSingle(rawZ);
785 veclist.Add(new Vector3(x, y, z));
657 } 786 }
787 }
658 788
659 item.CreationDate = Util.UnixTimeSinceEpoch(); 789 if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, attachment))
660 item.Description = asset.Description; 790 return null;
661 item.Name = asset.Name;
662 item.AssetType = asset.Type;
663 791
664 m_Scene.AddInventoryItem(item); 792 for (int i = 0; i < objlist.Count; i++)
793 {
794 group = objlist[i];
665 795
666 if (remoteClient != null && item.Owner == remoteClient.AgentId) 796// Vector3 storedPosition = group.AbsolutePosition;
797 if (group.UUID == UUID.Zero)
667 { 798 {
668 remoteClient.SendInventoryItemCreateUpdate(item, 0); 799 m_log.Debug("[InventoryAccessModule]: Object has UUID.Zero! Position 3");
669 } 800 }
670 else 801
802 if (!attachment)
671 { 803 {
672 ScenePresence notifyUser = m_Scene.GetScenePresence(item.Owner); 804 // If it's rezzed in world, select it. Much easier to
673 if (notifyUser != null) 805 // find small items.
806 //
807 foreach (SceneObjectPart part in group.Parts)
674 { 808 {
675 notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0); 809 part.CreateSelected = true;
676 } 810 }
677 } 811 }
812
813 group.ResetIDs();
814
815 if (attachment)
816 {
817 group.RootPart.Flags |= PrimFlags.Phantom;
818 group.IsAttachment = true;
819 }
820
821 // If we're rezzing an attachment then don't ask
822 // AddNewSceneObject() to update the client since
823 // we'll be doing that later on. Scheduling more than
824 // one full update during the attachment
825 // process causes some clients to fail to display the
826 // attachment properly.
827 m_Scene.AddNewSceneObject(group, true, false);
828
829 // if attachment we set it's asset id so object updates
830 // can reflect that, if not, we set it's position in world.
831 if (!attachment)
832 {
833 group.ScheduleGroupForFullUpdate();
834
835 group.AbsolutePosition = pos + veclist[i];
836 }
837
838 SceneObjectPart rootPart = group.RootPart;
839
840 group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
841
842 if (!attachment)
843 {
844 if (group.RootPart.Shape.PCode == (byte)PCode.Prim)
845 group.ClearPartAttachmentData();
846
847 // Fire on_rez
848 group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1);
849 rootPart.ParentGroup.ResumeScripts();
850
851 rootPart.ScheduleFullUpdate();
852 }
853
854// m_log.DebugFormat(
855// "[InventoryAccessModule]: Rezzed {0} {1} {2} for {3}",
856// group.Name, group.LocalId, group.UUID, remoteClient.Name);
678 } 857 }
679 858
680 // This is a hook to do some per-asset post-processing for subclasses that need that 859 group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
681 if (remoteClient != null) 860 // TODO: Remove the magic number badness
682 ExportAsset(remoteClient.AgentId, assetID); 861 if (item != null)
683 862 DoPostRezWhenFromItem(item, attachment);
684 return assetID;
685 }
686 863
687 protected virtual void ExportAsset(UUID agentID, UUID assetID) 864 if ((rootPart.OwnerID != item.Owner) ||
688 { 865 (item.CurrentPermissions & 16) != 0 || // Magic number
689 // nothing to do here 866 (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0)
867 {
868 //Need to kill the for sale here
869 rootPart.ObjectSaleType = 0;
870 rootPart.SalePrice = 10;
871
872 return group;
690 } 873 }
691 874
692 /// <summary> 875 /// <summary>
693 /// Rez an object into the scene from the user's inventory 876 /// Do pre-rez processing when the object comes from an item.
694 /// </summary> 877 /// </summary>
695 /// FIXME: It would be really nice if inventory access modules didn't also actually do the work of rezzing
696 /// things to the scene. The caller should be doing that, I think.
697 /// <param name="remoteClient"></param> 878 /// <param name="remoteClient"></param>
698 /// <param name="itemID"></param> 879 /// <param name="item"></param>
699 /// <param name="RayEnd"></param> 880 /// <param name="objlist"></param>
700 /// <param name="RayStart"></param> 881 /// <param name="pos"></param>
701 /// <param name="RayTargetID"></param> 882 /// <param name="isAttachment"></param>
702 /// <param name="BypassRayCast"></param> 883 /// <returns>true if we can processed with rezzing, false if we need to abort</returns>
703 /// <param name="RayEndIsIntersection"></param> 884 private bool DoPreRezWhenFromItem(
704 /// <param name="RezSelected"></param> 885 IClientAPI remoteClient, InventoryItemBase item, List<SceneObjectGroup> objlist, Vector3 pos, bool isAttachment)
705 /// <param name="RemoveItem"></param>
706 /// <param name="fromTaskID"></param>
707 /// <param name="attachment"></param>
708 /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful.</returns>
709 public virtual SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
710 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
711 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
712 { 886 {
713 // Work out position details 887 UUID fromUserInventoryItemId = UUID.Zero;
714 byte bRayEndIsIntersection = (byte)0;
715 888
716 if (RayEndIsIntersection) 889 // If we have permission to copy then link the rezzed object back to the user inventory
890 // item that it came from. This allows us to enable 'save object to inventory'
891 if (!m_Scene.Permissions.BypassPermissions())
717 { 892 {
718 bRayEndIsIntersection = (byte)1; 893 if ((item.CurrentPermissions & (uint)PermissionMask.Copy)
894 == (uint)PermissionMask.Copy && (item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
895 {
896 fromUserInventoryItemId = item.ID;
897 }
719 } 898 }
720 else 899 else
721 { 900 {
722 bRayEndIsIntersection = (byte)0; 901 if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
902 {
903 // Brave new fullperm world
904 fromUserInventoryItemId = item.ID;
905 }
723 } 906 }
724 907
725 Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f); 908 int primcount = 0;
909 foreach (SceneObjectGroup g in objlist)
910 primcount += g.PrimCount;
726 911
912 if (!m_Scene.Permissions.CanRezObject(
913 primcount, remoteClient.AgentId, pos)
914 && !isAttachment)
915 {
916 // The client operates in no fail mode. It will
917 // have already removed the item from the folder
918 // if it's no copy.
919 // Put it back if it's not an attachment
920 //
921 if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!isAttachment))
922 remoteClient.SendBulkUpdateInventory(item);
727 923
728 Vector3 pos = m_Scene.GetNewRezLocation( 924 return false;
729 RayStart, RayEnd, RayTargetID, Quaternion.Identity, 925 }
730 BypassRayCast, bRayEndIsIntersection, true, scale, false);
731
732 // Rez object
733 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
734 item = m_Scene.InventoryService.GetItem(item);
735 926
736 if (item != null) 927 for (int i = 0; i < objlist.Count; i++)
737 { 928 {
738 if (item.ID == UUID.Zero) 929 SceneObjectGroup so = objlist[i];
930 SceneObjectPart rootPart = so.RootPart;
931
932 // Since renaming the item in the inventory does not
933 // affect the name stored in the serialization, transfer
934 // the correct name from the inventory to the
935 // object itself before we rez.
936 //
937 // Only do these for the first object if we are rezzing a coalescence.
938 if (i == 0)
739 { 939 {
740 m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 1"); 940 rootPart.Name = item.Name;
941 rootPart.Description = item.Description;
942 rootPart.ObjectSaleType = item.SaleType;
943 rootPart.SalePrice = item.SalePrice;
741 } 944 }
742 item.Owner = remoteClient.AgentId;
743
744 AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString());
745
746 SceneObjectGroup group = null;
747 945
748 if (rezAsset != null) 946 rootPart.FromFolderID = item.Folder;
947
948 if ((rootPart.OwnerID != item.Owner) ||
949 (item.CurrentPermissions & 16) != 0)
749 { 950 {
750 UUID itemId = UUID.Zero; 951 //Need to kill the for sale here
751 952 rootPart.ObjectSaleType = 0;
752 // If we have permission to copy then link the rezzed object back to the user inventory 953 rootPart.SalePrice = 10;
753 // item that it came from. This allows us to enable 'save object to inventory' 954
754 if (!m_Scene.Permissions.BypassPermissions()) 955 if (m_Scene.Permissions.PropagatePermissions())
755 {
756 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy && (item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
757 {
758 itemId = item.ID;
759 }
760 }
761 else
762 { 956 {
763 if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) 957 foreach (SceneObjectPart part in so.Parts)
764 { 958 {
765 // Brave new fullperm world 959 if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
766 itemId = item.ID; 960 {
961 part.EveryoneMask = item.EveryOnePermissions;
962 part.NextOwnerMask = item.NextPermissions;
963 }
964 part.GroupMask = 0; // DO NOT propagate here
767 } 965 }
966
967 so.ApplyNextOwnerPermissions();
768 } 968 }
969 }
970
971 foreach (SceneObjectPart part in so.Parts)
972 {
973 part.FromUserInventoryItemID = fromUserInventoryItemId;
769 974
770 if (item.ID == UUID.Zero) 975 if ((part.OwnerID != item.Owner) ||
771 { 976 (item.CurrentPermissions & 16) != 0)
772 m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 2");
773 }
774
775 string xmlData = Utils.BytesToString(rezAsset.Data);
776 List<SceneObjectGroup> objlist =
777 new List<SceneObjectGroup>();
778 List<Vector3> veclist = new List<Vector3>();
779
780 XmlDocument doc = new XmlDocument();
781 doc.LoadXml(xmlData);
782 XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject");
783 if (e == null || attachment) // Single
784 { 977 {
785 SceneObjectGroup g = 978 part.LastOwnerID = part.OwnerID;
786 SceneObjectSerializer.FromOriginalXmlFormat( 979 part.OwnerID = item.Owner;
787 itemId, xmlData); 980 part.Inventory.ChangeInventoryOwner(item.Owner);
788 objlist.Add(g); 981 part.GroupMask = 0; // DO NOT propagate here
789 veclist.Add(new Vector3(0, 0, 0));
790
791 float offsetHeight = 0;
792 pos = m_Scene.GetNewRezLocation(
793 RayStart, RayEnd, RayTargetID, Quaternion.Identity,
794 BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false);
795 pos.Z += offsetHeight;
796 } 982 }
797 else 983 part.EveryoneMask = item.EveryOnePermissions;
798 { 984 part.NextOwnerMask = item.NextPermissions;
799 XmlElement coll = (XmlElement)e; 985 }
800 float bx = Convert.ToSingle(coll.GetAttribute("x")); 986
801 float by = Convert.ToSingle(coll.GetAttribute("y")); 987 rootPart.TrimPermissions();
802 float bz = Convert.ToSingle(coll.GetAttribute("z"));
803 Vector3 bbox = new Vector3(bx, by, bz);
804
805 pos = m_Scene.GetNewRezLocation(RayStart, RayEnd,
806 RayTargetID, Quaternion.Identity,
807 BypassRayCast, bRayEndIsIntersection, true,
808 bbox, false);
809
810 pos -= bbox / 2;
811 988
812 XmlNodeList groups = e.SelectNodes("SceneObjectGroup"); 989 if (isAttachment)
813 foreach (XmlNode n in groups) 990 so.SetFromItemID(item.ID);
814 { 991 }
815 SceneObjectGroup g =
816 SceneObjectSerializer.FromOriginalXmlFormat(
817 itemId, n.OuterXml);
818 objlist.Add(g);
819 XmlElement el = (XmlElement)n;
820 float x = Convert.ToSingle(el.GetAttribute("offsetx"));
821 float y = Convert.ToSingle(el.GetAttribute("offsety"));
822 float z = Convert.ToSingle(el.GetAttribute("offsetz"));
823 veclist.Add(new Vector3(x, y, z));
824 }
825 }
826 992
827 int primcount = 0; 993 return true;
828 foreach (SceneObjectGroup g in objlist) 994 }
829 primcount += g.PrimCount;
830 995
831 if (!m_Scene.Permissions.CanRezObject( 996 /// <summary>
832 primcount, remoteClient.AgentId, pos) 997 /// Do post-rez processing when the object comes from an item.
833 && !attachment) 998 /// </summary>
999 /// <param name="item"></param>
1000 /// <param name="isAttachment"></param>
1001 private void DoPostRezWhenFromItem(InventoryItemBase item, bool isAttachment)
1002 {
1003 if (!m_Scene.Permissions.BypassPermissions())
1004 {
1005 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1006 {
1007 // If this is done on attachments, no
1008 // copy ones will be lost, so avoid it
1009 //
1010 if (!isAttachment)
834 { 1011 {
835 // The client operates in no fail mode. It will 1012 List<UUID> uuids = new List<UUID>();
836 // have already removed the item from the folder 1013 uuids.Add(item.ID);
837 // if it's no copy. 1014 m_Scene.InventoryService.DeleteItems(item.Owner, uuids);
838 // Put it back if it's not an attachment
839 //
840 if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment))
841 remoteClient.SendBulkUpdateInventory(item);
842 return null;
843 } 1015 }
844 1016 }
845 for (int i = 0 ; i < objlist.Count ; i++ ) 1017 }
846 { 1018 if ((rootPart.OwnerID != item.Owner) ||
847 group = objlist[i];
848
849 Vector3 storedPosition = group.AbsolutePosition;
850 if (group.UUID == UUID.Zero)
851 {
852 m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 3");
853 }
854 group.RootPart.FromFolderID = item.Folder;
855
856 // If it's rezzed in world, select it. Much easier to
857 // find small items.
858 //
859 if (!attachment)
860 {
861 group.RootPart.CreateSelected = true;
862 foreach (SceneObjectPart child in group.Parts)
863 child.CreateSelected = true;
864 }
865
866 group.ResetIDs();
867
868 if (attachment)
869 {
870 group.RootPart.Flags |= PrimFlags.Phantom;
871 group.RootPart.IsAttachment = true;
872
873 // If we're rezzing an attachment then don't ask
874 // AddNewSceneObject() to update the client since
875 // we'll be doing that later on. Scheduling more
876 // than one full update during the attachment
877 // process causes some clients to fail to display
878 // the attachment properly.
879 // Also, don't persist attachments.
880 m_Scene.AddNewSceneObject(group, false, false);
881 }
882 else
883 {
884 m_Scene.AddNewSceneObject(group, true, false);
885 }
886
887 // if attachment we set it's asset id so object updates
888 // can reflect that, if not, we set it's position in world.
889 if (!attachment)
890 {
891 group.ScheduleGroupForFullUpdate();
892
893 group.AbsolutePosition = pos + veclist[i];
894 }
895 else
896 {
897 group.SetFromItemID(itemID);
898 }
899
900 SceneObjectPart rootPart = null;
901
902 try
903 {
904 rootPart = group.GetChildPart(group.UUID);
905 }
906 catch (NullReferenceException)
907 {
908 string isAttachment = "";
909
910 if (attachment)
911 isAttachment = " Object was an attachment";
912
913 m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment);
914 }
915
916 // Since renaming the item in the inventory does not
917 // affect the name stored in the serialization, transfer
918 // the correct name from the inventory to the
919 // object itself before we rez.
920 // On coalesced objects, do the first one
921 if (((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) || i == 0)
922 {
923 rootPart.Name = item.Name;
924 rootPart.Description = item.Description;
925 }
926 if ((item.Flags & (uint)InventoryItemFlags.ObjectSlamSale) != 0)
927 {
928 rootPart.ObjectSaleType = item.SaleType;
929 rootPart.SalePrice = item.SalePrice;
930 }
931
932 group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
933 // TODO: Remove the magic number badness
934
935 if ((rootPart.OwnerID != item.Owner) ||
936 (item.CurrentPermissions & 16) != 0 || // Magic number 1019 (item.CurrentPermissions & 16) != 0 || // Magic number
937 (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) 1020 (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0)
938 { 1021 {
939 //Need to kill the for sale here 1022 //Need to kill the for sale here
940 rootPart.ObjectSaleType = 0; 1023 rootPart.ObjectSaleType = 0;
941 rootPart.SalePrice = 10; 1024 rootPart.SalePrice = 10;
942 1025
943 if (m_Scene.Permissions.PropagatePermissions()) 1026 if (m_Scene.Permissions.PropagatePermissions())
944 { 1027 {
945 foreach (SceneObjectPart part in group.Parts) 1028 foreach (SceneObjectPart part in group.Parts)
946 { 1029 {
@@ -965,58 +1048,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
965 group.ApplyNextOwnerPermissions(); 1048 group.ApplyNextOwnerPermissions();
966 } 1049 }
967 } 1050 }
968 1051 foreach (SceneObjectPart part in group.Parts)
969 foreach (SceneObjectPart part in group.Parts) 1052 {
970 { 1053 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
971 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) 1054 part.EveryoneMask = item.EveryOnePermissions;
972 part.EveryoneMask = item.EveryOnePermissions; 1055 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
973 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) 1056 part.NextOwnerMask = item.NextPermissions;
974 part.NextOwnerMask = item.NextPermissions; 1057 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
975 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) 1058 part.GroupMask = item.GroupPermissions;
976 part.GroupMask = item.GroupPermissions;
977 }
978
979 rootPart.TrimPermissions();
980
981 if (!attachment)
982 {
983 if (group.RootPart.Shape.PCode == (byte)PCode.Prim)
984 {
985 // Save attachment data
986 group.RootPart.AttachPoint = group.RootPart.Shape.State;
987 group.RootPart.AttachOffset = storedPosition;
988
989 group.ClearPartAttachmentData();
990 }
991
992 // Fire on_rez
993 group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1);
994 rootPart.ParentGroup.ResumeScripts();
995
996 rootPart.ScheduleFullUpdate();
997 }
998 }
999
1000 if (!m_Scene.Permissions.BypassPermissions())
1001 {
1002 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1003 {
1004 // If this is done on attachments, no
1005 // copy ones will be lost, so avoid it
1006 //
1007 if (!attachment)
1008 {
1009 List<UUID> uuids = new List<UUID>();
1010 uuids.Add(item.ID);
1011 m_Scene.InventoryService.DeleteItems(item.Owner, uuids);
1012 }
1013 }
1014 }
1015 }
1016 return group;
1017 } 1059 }
1018
1019 return null;
1020 } 1060 }
1021 1061
1022 protected void AddUserData(SceneObjectGroup sog) 1062 protected void AddUserData(SceneObjectGroup sog)
@@ -1033,11 +1073,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
1033 public virtual bool CanGetAgentInventoryItem(IClientAPI remoteClient, UUID itemID, UUID requestID) 1073 public virtual bool CanGetAgentInventoryItem(IClientAPI remoteClient, UUID itemID, UUID requestID)
1034 { 1074 {
1035 InventoryItemBase assetRequestItem = GetItem(remoteClient.AgentId, itemID); 1075 InventoryItemBase assetRequestItem = GetItem(remoteClient.AgentId, itemID);
1076
1036 if (assetRequestItem == null) 1077 if (assetRequestItem == null)
1037 { 1078 {
1038 ILibraryService lib = m_Scene.RequestModuleInterface<ILibraryService>(); 1079 ILibraryService lib = m_Scene.RequestModuleInterface<ILibraryService>();
1080
1039 if (lib != null) 1081 if (lib != null)
1040 assetRequestItem = lib.LibraryRootFolder.FindItem(itemID); 1082 assetRequestItem = lib.LibraryRootFolder.FindItem(itemID);
1083
1041 if (assetRequestItem == null) 1084 if (assetRequestItem == null)
1042 return false; 1085 return false;
1043 } 1086 }
@@ -1068,6 +1111,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
1068 m_log.WarnFormat( 1111 m_log.WarnFormat(
1069 "[CLIENT]: {0} requested asset {1} from item {2} but this does not match item's asset {3}", 1112 "[CLIENT]: {0} requested asset {1} from item {2} but this does not match item's asset {3}",
1070 Name, requestID, itemID, assetRequestItem.AssetID); 1113 Name, requestID, itemID, assetRequestItem.AssetID);
1114
1071 return false; 1115 return false;
1072 } 1116 }
1073 1117
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
index 733ad25..e74310c 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
@@ -65,8 +65,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
65 config.AddConfig("Modules"); 65 config.AddConfig("Modules");
66 config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); 66 config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
67 67
68 m_scene = SceneSetupHelpers.SetupScene(); 68 m_scene = SceneHelpers.SetupScene();
69 SceneSetupHelpers.SetupSceneModules(m_scene, config, m_iam); 69 SceneHelpers.SetupSceneModules(m_scene, config, m_iam);
70 70
71 // Create user 71 // Create user
72 string userFirstName = "Jock"; 72 string userFirstName = "Jock";
@@ -82,14 +82,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
82 [Test] 82 [Test]
83 public void TestRezCoalescedObject() 83 public void TestRezCoalescedObject()
84 { 84 {
85 TestHelper.InMethod(); 85 TestHelpers.InMethod();
86// log4net.Config.XmlConfigurator.Configure(); 86// log4net.Config.XmlConfigurator.Configure();
87 87
88 // Create asset 88 // Create asset
89 SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, m_userId, "Object1", 0x20); 89 SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, m_userId, "Object1", 0x20);
90 object1.AbsolutePosition = new Vector3(15, 30, 45); 90 object1.AbsolutePosition = new Vector3(15, 30, 45);
91 91
92 SceneObjectGroup object2 = SceneSetupHelpers.CreateSceneObject(1, m_userId, "Object2", 0x40); 92 SceneObjectGroup object2 = SceneHelpers.CreateSceneObject(1, m_userId, "Object2", 0x40);
93 object2.AbsolutePosition = new Vector3(25, 50, 75); 93 object2.AbsolutePosition = new Vector3(25, 50, 75);
94 94
95 CoalescedSceneObjects coa = new CoalescedSceneObjects(m_userId, object1, object2); 95 CoalescedSceneObjects coa = new CoalescedSceneObjects(m_userId, object1, object2);
@@ -138,11 +138,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
138 [Test] 138 [Test]
139 public void TestRezObject() 139 public void TestRezObject()
140 { 140 {
141 TestHelper.InMethod(); 141 TestHelpers.InMethod();
142// log4net.Config.XmlConfigurator.Configure(); 142// log4net.Config.XmlConfigurator.Configure();
143 143
144 // Create asset 144 // Create asset
145 SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, m_userId, "My Little Dog Object", 0x40); 145 SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, m_userId, "My Little Dog Object", 0x40);
146 146
147 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); 147 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
148 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); 148 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
index d570608..3155ce7 100644
--- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
@@ -185,6 +185,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library
185 archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, "/", iarFileName, false); 185 archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, "/", iarFileName, false);
186 archread.Execute(); 186 archread.Execute();
187 } 187 }
188
188 foreach (InventoryNodeBase node in nodes) 189 foreach (InventoryNodeBase node in nodes)
189 FixPerms(node); 190 FixPerms(node);
190 } 191 }
@@ -197,18 +198,19 @@ namespace OpenSim.Region.CoreModules.Framework.Library
197 archread.Close(); 198 archread.Close();
198 } 199 }
199 } 200 }
200
201 } 201 }
202 202
203 private void FixPerms(InventoryNodeBase node) 203 private void FixPerms(InventoryNodeBase node)
204 { 204 {
205 m_log.DebugFormat("[LIBRARY MODULE]: Fixing perms for {0} {1}", node.Name, node.ID);
206
205 if (node is InventoryItemBase) 207 if (node is InventoryItemBase)
206 { 208 {
207 InventoryItemBase item = (InventoryItemBase)node; 209 InventoryItemBase item = (InventoryItemBase)node;
208 item.BasePermissions = 0x7FFFFFFF; 210 item.BasePermissions = (uint)PermissionMask.All;
209 item.EveryOnePermissions = 0x7FFFFFFF; 211 item.EveryOnePermissions = (uint)PermissionMask.All - (uint)PermissionMask.Modify;
210 item.CurrentPermissions = 0x7FFFFFFF; 212 item.CurrentPermissions = (uint)PermissionMask.All;
211 item.NextPermissions = 0x7FFFFFFF; 213 item.NextPermissions = (uint)PermissionMask.All;
212 } 214 }
213 } 215 }
214 216
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
index f15f8f6..b5cbcbb 100644
--- a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
@@ -68,7 +68,6 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
68 { 68 {
69 m_scene = scene; 69 m_scene = scene;
70 70
71
72 m_scene.AddCommand(this, "monitor report", 71 m_scene.AddCommand(this, "monitor report",
73 "monitor report", 72 "monitor report",
74 "Returns a variety of statistics about the current region and/or simulator", 73 "Returns a variety of statistics about the current region and/or simulator",
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index 27eb178..b0b35e4 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -186,7 +186,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
186 } 186 }
187 } 187 }
188 188
189
190 private string[] GetUserNames(UUID uuid) 189 private string[] GetUserNames(UUID uuid)
191 { 190 {
192 string[] returnstring = new string[2]; 191 string[] returnstring = new string[2];
@@ -292,6 +291,25 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
292 return userID.ToString(); 291 return userID.ToString();
293 } 292 }
294 293
294 public void AddUser(UUID uuid, string first, string last)
295 {
296 if (m_UserCache.ContainsKey(uuid))
297 return;
298
299 UserData user = new UserData();
300 user.Id = uuid;
301 user.FirstName = first;
302 user.LastName = last;
303 // user.ProfileURL = we should initialize this to the default
304
305 AddUserInternal(user);
306 }
307
308 public void AddUser(UUID uuid, string first, string last, string profileURL)
309 {
310 AddUser(uuid, profileURL + ";" + first + " " + last);
311 }
312
295 public void AddUser(UUID id, string creatorData) 313 public void AddUser(UUID id, string creatorData)
296 { 314 {
297 if (m_UserCache.ContainsKey(id)) 315 if (m_UserCache.ContainsKey(id))
@@ -299,18 +317,17 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
299 317
300// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, craetorData {1}", id, creatorData); 318// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, craetorData {1}", id, creatorData);
301 319
302 UserData user = new UserData();
303 user.Id = id;
304 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, id); 320 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, id);
305 321
306 if (account != null) 322 if (account != null)
307 { 323 {
308 user.FirstName = account.FirstName; 324 AddUser(id, account.FirstName, account.LastName);
309 user.LastName = account.LastName;
310 // user.ProfileURL = we should initialize this to the default
311 } 325 }
312 else 326 else
313 { 327 {
328 UserData user = new UserData();
329 user.Id = id;
330
314 if (creatorData != null && creatorData != string.Empty) 331 if (creatorData != null && creatorData != string.Empty)
315 { 332 {
316 //creatorData = <endpoint>;<name> 333 //creatorData = <endpoint>;<name>
@@ -338,17 +355,19 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
338 user.FirstName = "Unknown"; 355 user.FirstName = "Unknown";
339 user.LastName = "User"; 356 user.LastName = "User";
340 } 357 }
341 }
342 358
343 lock (m_UserCache) 359 AddUserInternal(user);
344 m_UserCache[id] = user; 360 }
345
346 //m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.HomeURL);
347 } 361 }
348 362
349 public void AddUser(UUID uuid, string first, string last, string profileURL) 363 void AddUserInternal(UserData user)
350 { 364 {
351 AddUser(uuid, profileURL + ";" + first + " " + last); 365 lock (m_UserCache)
366 m_UserCache[user.Id] = user;
367
368 m_log.DebugFormat(
369 "[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}",
370 user.Id, user.FirstName, user.LastName, user.HomeURL);
352 } 371 }
353 372
354 //public void AddUser(UUID uuid, string userData) 373 //public void AddUser(UUID uuid, string userData)
diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
index d647e71..b20a875 100644
--- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
@@ -282,6 +282,93 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
282 } 282 }
283 } 283 }
284 284
285 /// <summary>
286 /// Delivers the message to a scene entity.
287 /// </summary>
288 /// <param name='target'>
289 /// Target.
290 /// </param>
291 /// <param name='channel'>
292 /// Channel.
293 /// </param>
294 /// <param name='name'>
295 /// Name.
296 /// </param>
297 /// <param name='id'>
298 /// Identifier.
299 /// </param>
300 /// <param name='msg'>
301 /// Message.
302 /// </param>
303 public bool DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg, out string error)
304 {
305 error = null;
306 // Is id an avatar?
307 ScenePresence sp = m_scene.GetScenePresence(target);
308
309 if (sp != null)
310 {
311 // Send message to avatar
312 if (channel == 0)
313 {
314 m_scene.SimChatBroadcast(Utils.StringToBytes(msg), ChatTypeEnum.Owner, 0, pos, name, id, false);
315 }
316
317 List<SceneObjectGroup> attachments = sp.GetAttachments();
318
319 if (attachments.Count == 0)
320 return true;
321
322 // Get uuid of attachments
323 List<UUID> targets = new List<UUID>();
324 foreach (SceneObjectGroup sog in attachments)
325 {
326 targets.Add(sog.UUID);
327 }
328
329 // Need to check each attachment
330 foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg))
331 {
332 if (li.GetHostID().Equals(id))
333 continue;
334
335 if (m_scene.GetSceneObjectPart(li.GetHostID()) == null)
336 continue;
337
338 if (targets.Contains(li.GetHostID()))
339 QueueMessage(new ListenerInfo(li, name, id, msg));
340 }
341
342 return true;
343 }
344
345 // Need to toss an error here
346 if (channel == 0)
347 {
348 error = "Cannot use llRegionSayTo to message objects on channel 0";
349 return false;
350 }
351
352 foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg))
353 {
354 // Dont process if this message is from yourself!
355 if (li.GetHostID().Equals(id))
356 continue;
357
358 SceneObjectPart sPart = m_scene.GetSceneObjectPart(li.GetHostID());
359 if (sPart == null)
360 continue;
361
362 if ( li.GetHostID().Equals(target))
363 {
364 QueueMessage(new ListenerInfo(li, name, id, msg));
365 break;
366 }
367 }
368
369 return true;
370 }
371
285 protected void QueueMessage(ListenerInfo li) 372 protected void QueueMessage(ListenerInfo li)
286 { 373 {
287 lock (m_pending.SyncRoot) 374 lock (m_pending.SyncRoot)
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs
index b570155..e5af1f4 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs
@@ -48,7 +48,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.MapImage
48 private static bool m_Enabled = false; 48 private static bool m_Enabled = false;
49 49
50 private IConfigSource m_Config; 50 private IConfigSource m_Config;
51 bool m_Registered = false;
52 51
53 #region IRegionModule interface 52 #region IRegionModule interface
54 53
@@ -64,9 +63,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.MapImage
64 m_log.Info("[MAP SERVICE IN CONNECTOR]: MapImage Service In Connector enabled"); 63 m_log.Info("[MAP SERVICE IN CONNECTOR]: MapImage Service In Connector enabled");
65 new MapGetServiceConnector(m_Config, MainServer.Instance, "MapImageService"); 64 new MapGetServiceConnector(m_Config, MainServer.Instance, "MapImageService");
66 } 65 }
67
68 } 66 }
69
70 } 67 }
71 68
72 public void PostInitialise() 69 public void PostInitialise()
@@ -106,6 +103,5 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.MapImage
106 } 103 }
107 104
108 #endregion 105 #endregion
109
110 } 106 }
111} 107}
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs
index 51d1d59..cc5d061 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs
@@ -129,15 +129,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
129 m_Cache = null; 129 m_Cache = null;
130 } 130 }
131 131
132 m_log.InfoFormat("[LOCAL ASSET SERVICES CONNECTOR]: Enabled local assets for region {0}", scene.RegionInfo.RegionName); 132 m_log.DebugFormat(
133 "[LOCAL ASSET SERVICES CONNECTOR]: Enabled connector for region {0}", scene.RegionInfo.RegionName);
133 134
134 if (m_Cache != null) 135 if (m_Cache != null)
135 { 136 {
136 m_log.InfoFormat("[LOCAL ASSET SERVICES CONNECTOR]: Enabled asset caching for region {0}", scene.RegionInfo.RegionName); 137 m_log.DebugFormat(
138 "[LOCAL ASSET SERVICES CONNECTOR]: Enabled asset caching for region {0}",
139 scene.RegionInfo.RegionName);
137 } 140 }
138 else 141 else
139 { 142 {
140 // Short-circuit directly to storage layer 143 // Short-circuit directly to storage layer. This ends up storing temporary and local assets.
141 // 144 //
142 scene.UnregisterModuleInterface<IAssetService>(this); 145 scene.UnregisterModuleInterface<IAssetService>(this);
143 scene.RegisterModuleInterface<IAssetService>(m_AssetService); 146 scene.RegisterModuleInterface<IAssetService>(m_AssetService);
@@ -246,9 +249,21 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
246 m_Cache.Cache(asset); 249 m_Cache.Cache(asset);
247 250
248 if (asset.Temporary || asset.Local) 251 if (asset.Temporary || asset.Local)
252 {
253// m_log.DebugFormat(
254// "[LOCAL ASSET SERVICE CONNECTOR]: Returning asset {0} {1} without querying database since status Temporary = {2}, Local = {3}",
255// asset.Name, asset.ID, asset.Temporary, asset.Local);
256
249 return asset.ID; 257 return asset.ID;
250 258 }
251 return m_AssetService.Store(asset); 259 else
260 {
261// m_log.DebugFormat(
262// "[LOCAL ASSET SERVICE CONNECTOR]: Passing {0} {1} on to asset service for storage, status Temporary = {2}, Local = {3}",
263// asset.Name, asset.ID, asset.Temporary, asset.Local);
264
265 return m_AssetService.Store(asset);
266 }
252 } 267 }
253 268
254 public bool UpdateContent(string id, byte[] data) 269 public bool UpdateContent(string id, byte[] data)
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs
index 85a1ac3..18a7177 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs
@@ -39,8 +39,7 @@ using OpenMetaverse;
39 39
40namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization 40namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
41{ 41{
42 public class LocalAuthorizationServicesConnector : 42 public class LocalAuthorizationServicesConnector : ISharedRegionModule, IAuthorizationService
43 ISharedRegionModule, IAuthorizationService
44 { 43 {
45 private static readonly ILog m_log = 44 private static readonly ILog m_log =
46 LogManager.GetLogger( 45 LogManager.GetLogger(
@@ -127,15 +126,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
127 if (!m_Enabled) 126 if (!m_Enabled)
128 return; 127 return;
129 128
130 m_log.InfoFormat("[AUTHORIZATION CONNECTOR]: Enabled local authorization for region {0}", scene.RegionInfo.RegionName); 129 m_log.InfoFormat(
131 130 "[AUTHORIZATION CONNECTOR]: Enabled local authorization for region {0}",
132 131 scene.RegionInfo.RegionName);
133 } 132 }
134 133
135 public bool IsAuthorizedForRegion(string userID, string regionID, out string message) 134 public bool IsAuthorizedForRegion(
135 string userID, string firstName, string lastName, string regionID, out string message)
136 { 136 {
137 return m_AuthorizationService.IsAuthorizedForRegion(userID, regionID, out message); 137 return m_AuthorizationService.IsAuthorizedForRegion(userID, firstName, lastName, regionID, out message);
138 } 138 }
139
140 } 139 }
141} 140} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs
index 66994fa..003324f 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs
@@ -117,9 +117,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
117 117
118 } 118 }
119 119
120 public bool IsAuthorizedForRegion(string userID, string regionID, out string message) 120 public bool IsAuthorizedForRegion(
121 string userID, string firstName, string lastName, string regionID, out string message)
121 { 122 {
122 m_log.InfoFormat("[REMOTE AUTHORIZATION CONNECTOR]: IsAuthorizedForRegion checking {0} for region {1}", userID, regionID); 123 m_log.InfoFormat(
124 "[REMOTE AUTHORIZATION CONNECTOR]: IsAuthorizedForRegion checking {0} for region {1}", userID, regionID);
123 125
124 bool isAuthorized = true; 126 bool isAuthorized = true;
125 message = String.Empty; 127 message = String.Empty;
@@ -140,17 +142,19 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
140 if (scene != null) 142 if (scene != null)
141 { 143 {
142 UserAccount account = scene.UserAccountService.GetUserAccount(UUID.Zero, new UUID(userID)); 144 UserAccount account = scene.UserAccountService.GetUserAccount(UUID.Zero, new UUID(userID));
143 isAuthorized = IsAuthorizedForRegion(userID, account.FirstName, account.LastName, 145
144 account.Email, scene.RegionInfo.RegionName, regionID, out message); 146 isAuthorized
147 = IsAuthorizedForRegion(
148 userID, firstName, lastName, account.Email, scene.RegionInfo.RegionName, regionID, out message);
145 } 149 }
146 else 150 else
147 { 151 {
148 m_log.ErrorFormat("[REMOTE AUTHORIZATION CONNECTOR] IsAuthorizedForRegion, can't find scene to match region id of {0} ",regionID); 152 m_log.ErrorFormat(
153 "[REMOTE AUTHORIZATION CONNECTOR] IsAuthorizedForRegion, can't find scene to match region id of {0}",
154 regionID);
149 } 155 }
150 156
151
152 return isAuthorized; 157 return isAuthorized;
153
154 } 158 }
155 } 159 }
156} 160} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs
index 150a4d5..cd7d6bc 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs
@@ -55,19 +55,19 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests
55 config.Configs["Modules"].Set("GridServices", "LocalGridServicesConnector"); 55 config.Configs["Modules"].Set("GridServices", "LocalGridServicesConnector");
56 config.Configs["GridService"].Set("LocalServiceModule", "OpenSim.Services.GridService.dll:GridService"); 56 config.Configs["GridService"].Set("LocalServiceModule", "OpenSim.Services.GridService.dll:GridService");
57 config.Configs["GridService"].Set("StorageProvider", "OpenSim.Data.Null.dll"); 57 config.Configs["GridService"].Set("StorageProvider", "OpenSim.Data.Null.dll");
58 config.Configs["GridService"].Set("Region_Test_Region_1", "DefaultRegion"); 58 config.Configs["GridService"].Set("Region_Test_Region_1", "DefaultRegion");
59 config.Configs["GridService"].Set("Region_Test_Region_2", "FallbackRegion"); 59 config.Configs["GridService"].Set("Region_Test_Region_2", "FallbackRegion");
60 config.Configs["GridService"].Set("Region_Test_Region_3", "FallbackRegion"); 60 config.Configs["GridService"].Set("Region_Test_Region_3", "FallbackRegion");
61 config.Configs["GridService"].Set("Region_Other_Region_4", "FallbackRegion"); 61 config.Configs["GridService"].Set("Region_Other_Region_4", "FallbackRegion");
62 62
63 m_LocalConnector = new LocalGridServicesConnector(config); 63 m_LocalConnector = new LocalGridServicesConnector(config);
64 } 64 }
65 65
66 /// <summary> 66 /// <summary>
67 /// Test saving a V0.2 OpenSim Region Archive. 67 /// Test region registration.
68 /// </summary> 68 /// </summary>
69 [Test] 69 [Test]
70 public void TestRegisterRegionV0_2() 70 public void TestRegisterRegion()
71 { 71 {
72 SetUp(); 72 SetUp();
73 73
@@ -123,11 +123,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests
123 m_LocalConnector.RegisterRegion(UUID.Zero, r1); 123 m_LocalConnector.RegisterRegion(UUID.Zero, r1);
124 124
125 GridRegion result = m_LocalConnector.GetRegionByName(UUID.Zero, "Test"); 125 GridRegion result = m_LocalConnector.GetRegionByName(UUID.Zero, "Test");
126 Assert.IsNull(result, "Retrieved GetRegionByName \"Test\" is not null");
127
128 result = m_LocalConnector.GetRegionByName(UUID.Zero, "Test Region 1");
126 Assert.IsNotNull(result, "Retrieved GetRegionByName is null"); 129 Assert.IsNotNull(result, "Retrieved GetRegionByName is null");
127 Assert.That(result.RegionName, Is.EqualTo("Test Region 1"), "Retrieved region's name does not match"); 130 Assert.That(result.RegionName, Is.EqualTo("Test Region 1"), "Retrieved region's name does not match");
128 131
129 m_LocalConnector.RegisterRegion(UUID.Zero, r2); 132 m_LocalConnector.RegisterRegion(UUID.Zero, r2);
130 m_LocalConnector.RegisterRegion(UUID.Zero, r3); 133 m_LocalConnector.RegisterRegion(UUID.Zero, r3);
131 m_LocalConnector.RegisterRegion(UUID.Zero, r4); 134 m_LocalConnector.RegisterRegion(UUID.Zero, r4);
132 135
133 result = m_LocalConnector.GetRegionByUUID(UUID.Zero, new UUID(1)); 136 result = m_LocalConnector.GetRegionByUUID(UUID.Zero, new UUID(1));
@@ -152,38 +155,38 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests
152 Assert.IsNotNull(results, "Retrieved GetRegionRange collection is null"); 155 Assert.IsNotNull(results, "Retrieved GetRegionRange collection is null");
153 Assert.That(results.Count, Is.EqualTo(2), "Retrieved neighbour collection is not the number expected"); 156 Assert.That(results.Count, Is.EqualTo(2), "Retrieved neighbour collection is not the number expected");
154 157
155 results = m_LocalConnector.GetDefaultRegions(UUID.Zero); 158 results = m_LocalConnector.GetDefaultRegions(UUID.Zero);
156 Assert.IsNotNull(results, "Retrieved GetDefaultRegions collection is null"); 159 Assert.IsNotNull(results, "Retrieved GetDefaultRegions collection is null");
157 Assert.That(results.Count, Is.EqualTo(1), "Retrieved default regions collection has not the expected size"); 160 Assert.That(results.Count, Is.EqualTo(1), "Retrieved default regions collection has not the expected size");
158 Assert.That(results[0].RegionID, Is.EqualTo(new UUID(1)), "Retrieved default region's UUID does not match"); 161 Assert.That(results[0].RegionID, Is.EqualTo(new UUID(1)), "Retrieved default region's UUID does not match");
159 162
160 results = m_LocalConnector.GetFallbackRegions(UUID.Zero, r1.RegionLocX, r1.RegionLocY); 163 results = m_LocalConnector.GetFallbackRegions(UUID.Zero, r1.RegionLocX, r1.RegionLocY);
161 Assert.IsNotNull(results, "Retrieved GetFallbackRegions collection for region 1 is null"); 164 Assert.IsNotNull(results, "Retrieved GetFallbackRegions collection for region 1 is null");
162 Assert.That(results.Count, Is.EqualTo(3), "Retrieved fallback regions collection for region 1 has not the expected size"); 165 Assert.That(results.Count, Is.EqualTo(3), "Retrieved fallback regions collection for region 1 has not the expected size");
163 Assert.That(results[0].RegionID, Is.EqualTo(new UUID(2)), "Retrieved fallback regions for default region are not in the expected order 2-4-3"); 166 Assert.That(results[0].RegionID, Is.EqualTo(new UUID(2)), "Retrieved fallback regions for default region are not in the expected order 2-4-3");
164 Assert.That(results[1].RegionID, Is.EqualTo(new UUID(4)), "Retrieved fallback regions for default region are not in the expected order 2-4-3"); 167 Assert.That(results[1].RegionID, Is.EqualTo(new UUID(4)), "Retrieved fallback regions for default region are not in the expected order 2-4-3");
165 Assert.That(results[2].RegionID, Is.EqualTo(new UUID(3)), "Retrieved fallback regions for default region are not in the expected order 2-4-3"); 168 Assert.That(results[2].RegionID, Is.EqualTo(new UUID(3)), "Retrieved fallback regions for default region are not in the expected order 2-4-3");
166 169
167 results = m_LocalConnector.GetFallbackRegions(UUID.Zero, r2.RegionLocX, r2.RegionLocY); 170 results = m_LocalConnector.GetFallbackRegions(UUID.Zero, r2.RegionLocX, r2.RegionLocY);
168 Assert.IsNotNull(results, "Retrieved GetFallbackRegions collection for region 2 is null"); 171 Assert.IsNotNull(results, "Retrieved GetFallbackRegions collection for region 2 is null");
169 Assert.That(results.Count, Is.EqualTo(3), "Retrieved fallback regions collection for region 2 has not the expected size"); 172 Assert.That(results.Count, Is.EqualTo(3), "Retrieved fallback regions collection for region 2 has not the expected size");
170 Assert.That(results[0].RegionID, Is.EqualTo(new UUID(2)), "Retrieved fallback regions are not in the expected order 2-4-3"); 173 Assert.That(results[0].RegionID, Is.EqualTo(new UUID(2)), "Retrieved fallback regions are not in the expected order 2-4-3");
171 Assert.That(results[1].RegionID, Is.EqualTo(new UUID(4)), "Retrieved fallback regions are not in the expected order 2-4-3"); 174 Assert.That(results[1].RegionID, Is.EqualTo(new UUID(4)), "Retrieved fallback regions are not in the expected order 2-4-3");
172 Assert.That(results[2].RegionID, Is.EqualTo(new UUID(3)), "Retrieved fallback regions are not in the expected order 2-4-3"); 175 Assert.That(results[2].RegionID, Is.EqualTo(new UUID(3)), "Retrieved fallback regions are not in the expected order 2-4-3");
173 176
174 results = m_LocalConnector.GetFallbackRegions(UUID.Zero, r3.RegionLocX, r3.RegionLocY); 177 results = m_LocalConnector.GetFallbackRegions(UUID.Zero, r3.RegionLocX, r3.RegionLocY);
175 Assert.IsNotNull(results, "Retrieved GetFallbackRegions collection for region 3 is null"); 178 Assert.IsNotNull(results, "Retrieved GetFallbackRegions collection for region 3 is null");
176 Assert.That(results.Count, Is.EqualTo(3), "Retrieved fallback regions collection for region 3 has not the expected size"); 179 Assert.That(results.Count, Is.EqualTo(3), "Retrieved fallback regions collection for region 3 has not the expected size");
177 Assert.That(results[0].RegionID, Is.EqualTo(new UUID(3)), "Retrieved fallback regions are not in the expected order 3-4-2"); 180 Assert.That(results[0].RegionID, Is.EqualTo(new UUID(3)), "Retrieved fallback regions are not in the expected order 3-4-2");
178 Assert.That(results[1].RegionID, Is.EqualTo(new UUID(4)), "Retrieved fallback regions are not in the expected order 3-4-2"); 181 Assert.That(results[1].RegionID, Is.EqualTo(new UUID(4)), "Retrieved fallback regions are not in the expected order 3-4-2");
179 Assert.That(results[2].RegionID, Is.EqualTo(new UUID(2)), "Retrieved fallback regions are not in the expected order 3-4-2"); 182 Assert.That(results[2].RegionID, Is.EqualTo(new UUID(2)), "Retrieved fallback regions are not in the expected order 3-4-2");
180 183
181 results = m_LocalConnector.GetFallbackRegions(UUID.Zero, r4.RegionLocX, r4.RegionLocY); 184 results = m_LocalConnector.GetFallbackRegions(UUID.Zero, r4.RegionLocX, r4.RegionLocY);
182 Assert.IsNotNull(results, "Retrieved GetFallbackRegions collection for region 4 is null"); 185 Assert.IsNotNull(results, "Retrieved GetFallbackRegions collection for region 4 is null");
183 Assert.That(results.Count, Is.EqualTo(3), "Retrieved fallback regions collection for region 4 has not the expected size"); 186 Assert.That(results.Count, Is.EqualTo(3), "Retrieved fallback regions collection for region 4 has not the expected size");
184 Assert.That(results[0].RegionID, Is.EqualTo(new UUID(4)), "Retrieved fallback regions are not in the expected order 4-3-2"); 187 Assert.That(results[0].RegionID, Is.EqualTo(new UUID(4)), "Retrieved fallback regions are not in the expected order 4-3-2");
185 Assert.That(results[1].RegionID, Is.EqualTo(new UUID(3)), "Retrieved fallback regions are not in the expected order 4-3-2"); 188 Assert.That(results[1].RegionID, Is.EqualTo(new UUID(3)), "Retrieved fallback regions are not in the expected order 4-3-2");
186 Assert.That(results[2].RegionID, Is.EqualTo(new UUID(2)), "Retrieved fallback regions are not in the expected order 4-3-2"); 189 Assert.That(results[2].RegionID, Is.EqualTo(new UUID(2)), "Retrieved fallback regions are not in the expected order 4-3-2");
187 190
188 results = m_LocalConnector.GetHyperlinks(UUID.Zero); 191 results = m_LocalConnector.GetHyperlinks(UUID.Zero);
189 Assert.IsNotNull(results, "Retrieved GetHyperlinks list is null"); 192 Assert.IsNotNull(results, "Retrieved GetHyperlinks list is null");
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs
index 6543845..4cf62ec 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs
@@ -66,7 +66,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser
66 public void OnMakeRootAgent(ScenePresence sp) 66 public void OnMakeRootAgent(ScenePresence sp)
67 { 67 {
68// m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected root presence {0} in {1}", sp.UUID, sp.Scene.RegionInfo.RegionName); 68// m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected root presence {0} in {1}", sp.UUID, sp.Scene.RegionInfo.RegionName);
69 m_GridUserService.SetLastPosition(sp.UUID.ToString(), UUID.Zero, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); 69
70 if (sp.PresenceType != PresenceType.Npc)
71 m_GridUserService.SetLastPosition(
72 sp.UUID.ToString(), UUID.Zero, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
70 } 73 }
71 74
72 public void OnNewClient(IClientAPI client) 75 public void OnNewClient(IClientAPI client)
@@ -93,7 +96,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser
93 lookat = ((ScenePresence)sp).Lookat; 96 lookat = ((ScenePresence)sp).Lookat;
94 } 97 }
95 } 98 }
96 m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); 99
100// m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName);
97 m_GridUserService.LoggedOut(client.AgentId.ToString(), client.SessionId, client.Scene.RegionInfo.RegionID, position, lookat); 101 m_GridUserService.LoggedOut(client.AgentId.ToString(), client.SessionId, client.Scene.RegionInfo.RegionID, position, lookat);
98 } 102 }
99 103
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
index 698fd56..72ae3363 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
@@ -211,11 +211,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
211 return; 211 return;
212 } 212 }
213 } 213 }
214 else 214// else
215 { 215// {
216 m_log.DebugFormat("[HG INVENTORY CONNECTOR]: User {0} does not have InventoryServerURI. OH NOES!", userID); 216// m_log.DebugFormat("[HG INVENTORY CONNECTOR]: User {0} does not have InventoryServerURI. OH NOES!", userID);
217 return; 217// return;
218 } 218// }
219 } 219 }
220 } 220 }
221 if (sp == null) 221 if (sp == null)
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
index 0c57618..65e39c0 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
@@ -280,7 +280,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
280 { 280 {
281// m_log.DebugFormat("[LOCAL INVENTORY SERVICES CONNECTOR]: Requesting inventory item {0}", item.ID); 281// m_log.DebugFormat("[LOCAL INVENTORY SERVICES CONNECTOR]: Requesting inventory item {0}", item.ID);
282 282
283 UUID requestedItemId = item.ID; 283// UUID requestedItemId = item.ID;
284 284
285 item = m_InventoryService.GetItem(item); 285 item = m_InventoryService.GetItem(item);
286 286
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
index e224670..6d3ace9 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
@@ -61,7 +61,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
61 private bool m_enabled = false; 61 private bool m_enabled = false;
62 private IMapImageService m_MapService; 62 private IMapImageService m_MapService;
63 63
64 private string m_serverUrl = String.Empty;
65 private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>(); 64 private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
66 65
67 private int m_refreshtime = 0; 66 private int m_refreshtime = 0;
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs
index fa5b873..e2e383f 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs
@@ -39,7 +39,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
39{ 39{
40 public class PresenceDetector 40 public class PresenceDetector
41 { 41 {
42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 42// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43 43
44 private IPresenceService m_PresenceService; 44 private IPresenceService m_PresenceService;
45 private Scene m_aScene; 45 private Scene m_aScene;
@@ -94,7 +94,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
94 } 94 }
95 } 95 }
96 96
97 m_log.DebugFormat("[PRESENCE DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); 97// m_log.DebugFormat("[PRESENCE DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName);
98 m_PresenceService.LogoutAgent(client.SessionId); 98 m_PresenceService.LogoutAgent(client.SessionId);
99 } 99 }
100 100
diff --git a/OpenSim/Region/CoreModules/World/Access/AccessModule.cs b/OpenSim/Region/CoreModules/World/Access/AccessModule.cs
index c355b13..2399134 100644
--- a/OpenSim/Region/CoreModules/World/Access/AccessModule.cs
+++ b/OpenSim/Region/CoreModules/World/Access/AccessModule.cs
@@ -129,14 +129,12 @@ namespace OpenSim.Region.CoreModules.World
129 switch (cmd[1]) 129 switch (cmd[1])
130 { 130 {
131 case "enable": 131 case "enable":
132 if (scene.LoginsDisabled)
133 MainConsole.Instance.Output(String.Format("Enabling logins for region {0}", scene.RegionInfo.RegionName));
134 scene.LoginsDisabled = false; 132 scene.LoginsDisabled = false;
133 MainConsole.Instance.Output(String.Format("Logins are enabled for region {0}", scene.RegionInfo.RegionName));
135 break; 134 break;
136 case "disable": 135 case "disable":
137 if (!scene.LoginsDisabled)
138 MainConsole.Instance.Output(String.Format("Disabling logins for region {0}", scene.RegionInfo.RegionName));
139 scene.LoginsDisabled = true; 136 scene.LoginsDisabled = true;
137 MainConsole.Instance.Output(String.Format("Logins are disabled for region {0}", scene.RegionInfo.RegionName));
140 break; 138 break;
141 case "status": 139 case "status":
142 if (scene.LoginsDisabled) 140 if (scene.LoginsDisabled)
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
index 6ba3459..b185d9b 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
@@ -68,8 +68,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
68 SerialiserModule serialiserModule = new SerialiserModule(); 68 SerialiserModule serialiserModule = new SerialiserModule();
69 TerrainModule terrainModule = new TerrainModule(); 69 TerrainModule terrainModule = new TerrainModule();
70 70
71 m_scene = SceneSetupHelpers.SetupScene(); 71 m_scene = SceneHelpers.SetupScene();
72 SceneSetupHelpers.SetupSceneModules(m_scene, m_archiverModule, serialiserModule, terrainModule); 72 SceneHelpers.SetupSceneModules(m_scene, m_archiverModule, serialiserModule, terrainModule);
73 } 73 }
74 74
75 private void LoadCompleted(Guid requestId, string errorMessage) 75 private void LoadCompleted(Guid requestId, string errorMessage)
@@ -125,7 +125,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
125 [Test] 125 [Test]
126 public void TestSaveOar() 126 public void TestSaveOar()
127 { 127 {
128 TestHelper.InMethod(); 128 TestHelpers.InMethod();
129// log4net.Config.XmlConfigurator.Configure(); 129// log4net.Config.XmlConfigurator.Configure();
130 130
131 SceneObjectPart part1 = CreateSceneObjectPart1(); 131 SceneObjectPart part1 = CreateSceneObjectPart1();
@@ -217,7 +217,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
217 [Test] 217 [Test]
218 public void TestSaveOarNoAssets() 218 public void TestSaveOarNoAssets()
219 { 219 {
220 TestHelper.InMethod(); 220 TestHelpers.InMethod();
221// log4net.Config.XmlConfigurator.Configure(); 221// log4net.Config.XmlConfigurator.Configure();
222 222
223 SceneObjectPart part1 = CreateSceneObjectPart1(); 223 SceneObjectPart part1 = CreateSceneObjectPart1();
@@ -300,7 +300,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
300 [Test] 300 [Test]
301 public void TestLoadOar() 301 public void TestLoadOar()
302 { 302 {
303 TestHelper.InMethod(); 303 TestHelpers.InMethod();
304// log4net.Config.XmlConfigurator.Configure(); 304// log4net.Config.XmlConfigurator.Configure();
305 305
306 MemoryStream archiveWriteStream = new MemoryStream(); 306 MemoryStream archiveWriteStream = new MemoryStream();
@@ -409,7 +409,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
409 [Test] 409 [Test]
410 public void TestLoadOarRegionSettings() 410 public void TestLoadOarRegionSettings()
411 { 411 {
412 TestHelper.InMethod(); 412 TestHelpers.InMethod();
413 //log4net.Config.XmlConfigurator.Configure(); 413 //log4net.Config.XmlConfigurator.Configure();
414 414
415 MemoryStream archiveWriteStream = new MemoryStream(); 415 MemoryStream archiveWriteStream = new MemoryStream();
@@ -505,7 +505,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
505 //[Test] 505 //[Test]
506 public void TestMergeOar() 506 public void TestMergeOar()
507 { 507 {
508 TestHelper.InMethod(); 508 TestHelpers.InMethod();
509 //XmlConfigurator.Configure(); 509 //XmlConfigurator.Configure();
510 510
511 MemoryStream archiveWriteStream = new MemoryStream(); 511 MemoryStream archiveWriteStream = new MemoryStream();
@@ -524,8 +524,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
524 SerialiserModule serialiserModule = new SerialiserModule(); 524 SerialiserModule serialiserModule = new SerialiserModule();
525 TerrainModule terrainModule = new TerrainModule(); 525 TerrainModule terrainModule = new TerrainModule();
526 526
527 Scene scene = SceneSetupHelpers.SetupScene(); 527 Scene scene = SceneHelpers.SetupScene();
528 SceneSetupHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule); 528 SceneHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule);
529 529
530 m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false); 530 m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false);
531 531
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index b96f300..fb32288 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
@@ -875,41 +875,35 @@ namespace OpenSim.Region.CoreModules.World.Estate
875 SceneObjectPart prt = Scene.GetSceneObjectPart(obj); 875 SceneObjectPart prt = Scene.GetSceneObjectPart(obj);
876 if (prt != null) 876 if (prt != null)
877 { 877 {
878 if (prt.ParentGroup != null) 878 SceneObjectGroup sog = prt.ParentGroup;
879 LandStatReportItem lsri = new LandStatReportItem();
880 lsri.LocationX = sog.AbsolutePosition.X;
881 lsri.LocationY = sog.AbsolutePosition.Y;
882 lsri.LocationZ = sog.AbsolutePosition.Z;
883 lsri.Score = SceneData[obj];
884 lsri.TaskID = sog.UUID;
885 lsri.TaskLocalID = sog.LocalId;
886 lsri.TaskName = sog.GetPartName(obj);
887 lsri.OwnerName = "waiting";
888 lock (uuidNameLookupList)
889 uuidNameLookupList.Add(sog.OwnerID);
890
891 if (filter.Length != 0)
879 { 892 {
880 SceneObjectGroup sog = prt.ParentGroup; 893 if ((lsri.OwnerName.Contains(filter) || lsri.TaskName.Contains(filter)))
881 if (sog != null)
882 { 894 {
883 LandStatReportItem lsri = new LandStatReportItem(); 895 }
884 lsri.LocationX = sog.AbsolutePosition.X; 896 else
885 lsri.LocationY = sog.AbsolutePosition.Y; 897 {
886 lsri.LocationZ = sog.AbsolutePosition.Z; 898 continue;
887 lsri.Score = SceneData[obj];
888 lsri.TaskID = sog.UUID;
889 lsri.TaskLocalID = sog.LocalId;
890 lsri.TaskName = sog.GetPartName(obj);
891 lsri.OwnerName = "waiting";
892 lock (uuidNameLookupList)
893 uuidNameLookupList.Add(sog.OwnerID);
894
895 if (filter.Length != 0)
896 {
897 if ((lsri.OwnerName.Contains(filter) || lsri.TaskName.Contains(filter)))
898 {
899 }
900 else
901 {
902 continue;
903 }
904 }
905
906 SceneReport.Add(lsri);
907 } 899 }
908 } 900 }
909 }
910 901
902 SceneReport.Add(lsri);
903 }
911 } 904 }
912 } 905 }
906
913 remoteClient.SendLandStatReply(reportType, requestFlags, (uint)SceneReport.Count,SceneReport.ToArray()); 907 remoteClient.SendLandStatReply(reportType, requestFlags, (uint)SceneReport.Count,SceneReport.ToArray());
914 908
915 if (uuidNameLookupList.Count > 0) 909 if (uuidNameLookupList.Count > 0)
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index 4e7c76f..a3066e7 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -423,17 +423,49 @@ namespace OpenSim.Region.CoreModules.World.Land
423 SendLandUpdate(avatar, false); 423 SendLandUpdate(avatar, false);
424 } 424 }
425 425
426 public void EventManagerOnSignificantClientMovement(IClientAPI remote_client) 426 public void EventManagerOnSignificantClientMovement(ScenePresence clientAvatar)
427 { 427 {
428 ScenePresence clientAvatar = m_scene.GetScenePresence(remote_client.AgentId); 428 SendLandUpdate(clientAvatar);
429 429 SendOutNearestBanLine(clientAvatar.ControllingClient);
430 if (clientAvatar != null) 430 ILandObject parcel = GetLandObject(clientAvatar.AbsolutePosition.X, clientAvatar.AbsolutePosition.Y);
431 if (parcel != null)
431 { 432 {
432 SendLandUpdate(clientAvatar); 433 if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT &&
433 SendOutNearestBanLine(remote_client); 434 clientAvatar.sentMessageAboutRestrictedParcelFlyingDown)
434 ILandObject parcel = GetLandObject(clientAvatar.AbsolutePosition.X, clientAvatar.AbsolutePosition.Y); 435 {
435 if (parcel != null) 436 EventManagerOnAvatarEnteringNewParcel(clientAvatar, parcel.LandData.LocalID,
436 EnforceBans(parcel, clientAvatar); 437 m_scene.RegionInfo.RegionID);
438 //They are going under the safety line!
439 if (!parcel.IsBannedFromLand(clientAvatar.UUID))
440 {
441 clientAvatar.sentMessageAboutRestrictedParcelFlyingDown = false;
442 }
443 }
444 else if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT &&
445 parcel.IsBannedFromLand(clientAvatar.UUID))
446 {
447 //once we've sent the message once, keep going toward the target until we are done
448 if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId))
449 {
450 SendYouAreBannedNotice(clientAvatar);
451 ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar));
452 }
453 }
454 else if (parcel.IsRestrictedFromLand(clientAvatar.UUID))
455 {
456 //once we've sent the message once, keep going toward the target until we are done
457 if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId))
458 {
459 SendYouAreRestrictedNotice(clientAvatar);
460 ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar));
461 }
462 }
463 else
464 {
465 //when we are finally in a safe place, lets release the forced position lock
466 forcedPosition.Remove(clientAvatar.ControllingClient.AgentId);
467 }
468 EnforceBans(parcel, clientAvatar);
437 } 469 }
438 } 470 }
439 471
@@ -665,7 +697,7 @@ namespace OpenSim.Region.CoreModules.World.Land
665 // Corner case. If an autoreturn happens during sim startup 697 // Corner case. If an autoreturn happens during sim startup
666 // we will come here with the list uninitialized 698 // we will come here with the list uninitialized
667 // 699 //
668 int landId = m_landIDList[x, y]; 700// int landId = m_landIDList[x, y];
669 701
670// if (landId == 0) 702// if (landId == 0)
671// m_log.DebugFormat( 703// m_log.DebugFormat(
diff --git a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
index f466194..5122734 100644
--- a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
@@ -51,7 +51,7 @@ namespace OpenSim.Region.CoreModules.World.Land
51 51
52 public class PrimCountModule : IPrimCountModule, INonSharedRegionModule 52 public class PrimCountModule : IPrimCountModule, INonSharedRegionModule
53 { 53 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55 55
56 private Scene m_Scene; 56 private Scene m_Scene;
57 private Dictionary<UUID, PrimCounts> m_PrimCounts = 57 private Dictionary<UUID, PrimCounts> m_PrimCounts =
diff --git a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs
index a3aa38d..e553ffa 100644
--- a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs
+++ b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs
@@ -64,8 +64,8 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
64 { 64 {
65 m_pcm = new PrimCountModule(); 65 m_pcm = new PrimCountModule();
66 LandManagementModule lmm = new LandManagementModule(); 66 LandManagementModule lmm = new LandManagementModule();
67 m_scene = SceneSetupHelpers.SetupScene(); 67 m_scene = SceneHelpers.SetupScene();
68 SceneSetupHelpers.SetupSceneModules(m_scene, lmm, m_pcm); 68 SceneHelpers.SetupSceneModules(m_scene, lmm, m_pcm);
69 69
70 int xParcelDivider = (int)Constants.RegionSize - 1; 70 int xParcelDivider = (int)Constants.RegionSize - 1;
71 71
@@ -106,12 +106,12 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
106 [Test] 106 [Test]
107 public void TestAddOwnerObject() 107 public void TestAddOwnerObject()
108 { 108 {
109 TestHelper.InMethod(); 109 TestHelpers.InMethod();
110// log4net.Config.XmlConfigurator.Configure(); 110// log4net.Config.XmlConfigurator.Configure();
111 111
112 IPrimCounts pc = m_lo.PrimCounts; 112 IPrimCounts pc = m_lo.PrimCounts;
113 113
114 SceneObjectGroup sog = SceneSetupHelpers.CreateSceneObject(3, m_userId, "a", 0x01); 114 SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_userId, "a", 0x01);
115 m_scene.AddNewSceneObject(sog, false); 115 m_scene.AddNewSceneObject(sog, false);
116 116
117 Assert.That(pc.Owner, Is.EqualTo(3)); 117 Assert.That(pc.Owner, Is.EqualTo(3));
@@ -124,7 +124,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
124 Assert.That(pc.Simulator, Is.EqualTo(3)); 124 Assert.That(pc.Simulator, Is.EqualTo(3));
125 125
126 // Add a second object and retest 126 // Add a second object and retest
127 SceneObjectGroup sog2 = SceneSetupHelpers.CreateSceneObject(2, m_userId, "b", 0x10); 127 SceneObjectGroup sog2 = SceneHelpers.CreateSceneObject(2, m_userId, "b", 0x10);
128 m_scene.AddNewSceneObject(sog2, false); 128 m_scene.AddNewSceneObject(sog2, false);
129 129
130 Assert.That(pc.Owner, Is.EqualTo(5)); 130 Assert.That(pc.Owner, Is.EqualTo(5));
@@ -143,12 +143,12 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
143 [Test] 143 [Test]
144 public void TestCopyOwnerObject() 144 public void TestCopyOwnerObject()
145 { 145 {
146 TestHelper.InMethod(); 146 TestHelpers.InMethod();
147// log4net.Config.XmlConfigurator.Configure(); 147// log4net.Config.XmlConfigurator.Configure();
148 148
149 IPrimCounts pc = m_lo.PrimCounts; 149 IPrimCounts pc = m_lo.PrimCounts;
150 150
151 SceneObjectGroup sog = SceneSetupHelpers.CreateSceneObject(3, m_userId, "a", 0x01); 151 SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_userId, "a", 0x01);
152 m_scene.AddNewSceneObject(sog, false); 152 m_scene.AddNewSceneObject(sog, false);
153 m_scene.SceneGraph.DuplicateObject(sog.LocalId, Vector3.Zero, 0, m_userId, UUID.Zero, Quaternion.Identity); 153 m_scene.SceneGraph.DuplicateObject(sog.LocalId, Vector3.Zero, 0, m_userId, UUID.Zero, Quaternion.Identity);
154 154
@@ -169,12 +169,12 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
169 [Test] 169 [Test]
170 public void TestMoveOwnerObject() 170 public void TestMoveOwnerObject()
171 { 171 {
172 TestHelper.InMethod(); 172 TestHelpers.InMethod();
173// log4net.Config.XmlConfigurator.Configure(); 173// log4net.Config.XmlConfigurator.Configure();
174 174
175 SceneObjectGroup sog = SceneSetupHelpers.CreateSceneObject(3, m_userId, "a", 0x01); 175 SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_userId, "a", 0x01);
176 m_scene.AddNewSceneObject(sog, false); 176 m_scene.AddNewSceneObject(sog, false);
177 SceneObjectGroup sog2 = SceneSetupHelpers.CreateSceneObject(2, m_userId, "b", 0x10); 177 SceneObjectGroup sog2 = SceneHelpers.CreateSceneObject(2, m_userId, "b", 0x10);
178 m_scene.AddNewSceneObject(sog2, false); 178 m_scene.AddNewSceneObject(sog2, false);
179 179
180 // Move the first scene object to the eastern strip parcel 180 // Move the first scene object to the eastern strip parcel
@@ -230,13 +230,13 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
230 [Test] 230 [Test]
231 public void TestRemoveOwnerObject() 231 public void TestRemoveOwnerObject()
232 { 232 {
233 TestHelper.InMethod(); 233 TestHelpers.InMethod();
234// log4net.Config.XmlConfigurator.Configure(); 234// log4net.Config.XmlConfigurator.Configure();
235 235
236 IPrimCounts pc = m_lo.PrimCounts; 236 IPrimCounts pc = m_lo.PrimCounts;
237 237
238 m_scene.AddNewSceneObject(SceneSetupHelpers.CreateSceneObject(1, m_userId, "a", 0x1), false); 238 m_scene.AddNewSceneObject(SceneHelpers.CreateSceneObject(1, m_userId, "a", 0x1), false);
239 SceneObjectGroup sogToDelete = SceneSetupHelpers.CreateSceneObject(3, m_userId, "b", 0x10); 239 SceneObjectGroup sogToDelete = SceneHelpers.CreateSceneObject(3, m_userId, "b", 0x10);
240 m_scene.AddNewSceneObject(sogToDelete, false); 240 m_scene.AddNewSceneObject(sogToDelete, false);
241 m_scene.DeleteSceneObject(sogToDelete, false); 241 m_scene.DeleteSceneObject(sogToDelete, false);
242 242
@@ -253,14 +253,14 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
253 [Test] 253 [Test]
254 public void TestAddGroupObject() 254 public void TestAddGroupObject()
255 { 255 {
256 TestHelper.InMethod(); 256 TestHelpers.InMethod();
257// log4net.Config.XmlConfigurator.Configure(); 257// log4net.Config.XmlConfigurator.Configure();
258 258
259 m_lo.DeedToGroup(m_groupId); 259 m_lo.DeedToGroup(m_groupId);
260 260
261 IPrimCounts pc = m_lo.PrimCounts; 261 IPrimCounts pc = m_lo.PrimCounts;
262 262
263 SceneObjectGroup sog = SceneSetupHelpers.CreateSceneObject(3, m_otherUserId, "a", 0x01); 263 SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_otherUserId, "a", 0x01);
264 sog.GroupID = m_groupId; 264 sog.GroupID = m_groupId;
265 m_scene.AddNewSceneObject(sog, false); 265 m_scene.AddNewSceneObject(sog, false);
266 266
@@ -284,18 +284,18 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
284 [Test] 284 [Test]
285 public void TestRemoveGroupObject() 285 public void TestRemoveGroupObject()
286 { 286 {
287 TestHelper.InMethod(); 287 TestHelpers.InMethod();
288// log4net.Config.XmlConfigurator.Configure(); 288// log4net.Config.XmlConfigurator.Configure();
289 289
290 m_lo.DeedToGroup(m_groupId); 290 m_lo.DeedToGroup(m_groupId);
291 291
292 IPrimCounts pc = m_lo.PrimCounts; 292 IPrimCounts pc = m_lo.PrimCounts;
293 293
294 SceneObjectGroup sogToKeep = SceneSetupHelpers.CreateSceneObject(1, m_userId, "a", 0x1); 294 SceneObjectGroup sogToKeep = SceneHelpers.CreateSceneObject(1, m_userId, "a", 0x1);
295 sogToKeep.GroupID = m_groupId; 295 sogToKeep.GroupID = m_groupId;
296 m_scene.AddNewSceneObject(sogToKeep, false); 296 m_scene.AddNewSceneObject(sogToKeep, false);
297 297
298 SceneObjectGroup sogToDelete = SceneSetupHelpers.CreateSceneObject(3, m_userId, "b", 0x10); 298 SceneObjectGroup sogToDelete = SceneHelpers.CreateSceneObject(3, m_userId, "b", 0x10);
299 m_scene.AddNewSceneObject(sogToDelete, false); 299 m_scene.AddNewSceneObject(sogToDelete, false);
300 m_scene.DeleteSceneObject(sogToDelete, false); 300 m_scene.DeleteSceneObject(sogToDelete, false);
301 301
@@ -313,12 +313,12 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
313 [Test] 313 [Test]
314 public void TestAddOthersObject() 314 public void TestAddOthersObject()
315 { 315 {
316 TestHelper.InMethod(); 316 TestHelpers.InMethod();
317// log4net.Config.XmlConfigurator.Configure(); 317// log4net.Config.XmlConfigurator.Configure();
318 318
319 IPrimCounts pc = m_lo.PrimCounts; 319 IPrimCounts pc = m_lo.PrimCounts;
320 320
321 SceneObjectGroup sog = SceneSetupHelpers.CreateSceneObject(3, m_otherUserId, "a", 0x01); 321 SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_otherUserId, "a", 0x01);
322 m_scene.AddNewSceneObject(sog, false); 322 m_scene.AddNewSceneObject(sog, false);
323 323
324 Assert.That(pc.Owner, Is.EqualTo(0)); 324 Assert.That(pc.Owner, Is.EqualTo(0));
@@ -334,13 +334,13 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
334 [Test] 334 [Test]
335 public void TestRemoveOthersObject() 335 public void TestRemoveOthersObject()
336 { 336 {
337 TestHelper.InMethod(); 337 TestHelpers.InMethod();
338// log4net.Config.XmlConfigurator.Configure(); 338// log4net.Config.XmlConfigurator.Configure();
339 339
340 IPrimCounts pc = m_lo.PrimCounts; 340 IPrimCounts pc = m_lo.PrimCounts;
341 341
342 m_scene.AddNewSceneObject(SceneSetupHelpers.CreateSceneObject(1, m_otherUserId, "a", 0x1), false); 342 m_scene.AddNewSceneObject(SceneHelpers.CreateSceneObject(1, m_otherUserId, "a", 0x1), false);
343 SceneObjectGroup sogToDelete = SceneSetupHelpers.CreateSceneObject(3, m_otherUserId, "b", 0x10); 343 SceneObjectGroup sogToDelete = SceneHelpers.CreateSceneObject(3, m_otherUserId, "b", 0x10);
344 m_scene.AddNewSceneObject(sogToDelete, false); 344 m_scene.AddNewSceneObject(sogToDelete, false);
345 m_scene.DeleteSceneObject(sogToDelete, false); 345 m_scene.DeleteSceneObject(sogToDelete, false);
346 346
@@ -360,10 +360,10 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
360 [Test] 360 [Test]
361 public void TestTaint() 361 public void TestTaint()
362 { 362 {
363 TestHelper.InMethod(); 363 TestHelpers.InMethod();
364 IPrimCounts pc = m_lo.PrimCounts; 364 IPrimCounts pc = m_lo.PrimCounts;
365 365
366 SceneObjectGroup sog = SceneSetupHelpers.CreateSceneObject(3, m_userId, "a", 0x01); 366 SceneObjectGroup sog = SceneHelpers.CreateSceneObject(3, m_userId, "a", 0x01);
367 m_scene.AddNewSceneObject(sog, false); 367 m_scene.AddNewSceneObject(sog, false);
368 368
369 m_pcm.TaintPrimCount(); 369 m_pcm.TaintPrimCount();
diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs b/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs
index aa14054..1d2141e 100644
--- a/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs
+++ b/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs
@@ -173,7 +173,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap
173 private Bitmap fetchTexture(UUID id) 173 private Bitmap fetchTexture(UUID id)
174 { 174 {
175 AssetBase asset = m_scene.AssetService.Get(id.ToString()); 175 AssetBase asset = m_scene.AssetService.Get(id.ToString());
176 m_log.DebugFormat("Fetched texture {0}, found: {1}", id, asset != null); 176 m_log.DebugFormat("[TexturedMapTileRenderer]: Fetched texture {0}, found: {1}", id, asset != null);
177 if (asset == null) return null; 177 if (asset == null) return null;
178 178
179 ManagedImage managedImage; 179 ManagedImage managedImage;
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs
index d5b7082..4326606 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs
@@ -53,17 +53,17 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests
53 public void SetUp() 53 public void SetUp()
54 { 54 {
55 m_module = new MoapModule(); 55 m_module = new MoapModule();
56 m_scene = SceneSetupHelpers.SetupScene(); 56 m_scene = SceneHelpers.SetupScene();
57 SceneSetupHelpers.SetupSceneModules(m_scene, m_module); 57 SceneHelpers.SetupSceneModules(m_scene, m_module);
58 } 58 }
59 59
60 [Test] 60 [Test]
61 public void TestClearMediaUrl() 61 public void TestClearMediaUrl()
62 { 62 {
63 TestHelper.InMethod(); 63 TestHelpers.InMethod();
64// log4net.Config.XmlConfigurator.Configure(); 64// log4net.Config.XmlConfigurator.Configure();
65 65
66 SceneObjectPart part = SceneSetupHelpers.AddSceneObject(m_scene); 66 SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene);
67 MediaEntry me = new MediaEntry(); 67 MediaEntry me = new MediaEntry();
68 68
69 m_module.SetMediaEntry(part, 1, me); 69 m_module.SetMediaEntry(part, 1, me);
@@ -84,11 +84,11 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests
84 [Test] 84 [Test]
85 public void TestSetMediaUrl() 85 public void TestSetMediaUrl()
86 { 86 {
87 TestHelper.InMethod(); 87 TestHelpers.InMethod();
88 88
89 string homeUrl = "opensimulator.org"; 89 string homeUrl = "opensimulator.org";
90 90
91 SceneObjectPart part = SceneSetupHelpers.AddSceneObject(m_scene); 91 SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene);
92 MediaEntry me = new MediaEntry() { HomeURL = homeUrl }; 92 MediaEntry me = new MediaEntry() { HomeURL = homeUrl };
93 93
94 m_module.SetMediaEntry(part, 1, me); 94 m_module.SetMediaEntry(part, 1, me);
diff --git a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
index 516189f..49e3236 100644
--- a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
+++ b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
@@ -85,7 +85,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell
85 IClientAPI client, UUID agentID, UUID sessionID, uint localID, byte saleType, int salePrice) 85 IClientAPI client, UUID agentID, UUID sessionID, uint localID, byte saleType, int salePrice)
86 { 86 {
87 SceneObjectPart part = m_scene.GetSceneObjectPart(localID); 87 SceneObjectPart part = m_scene.GetSceneObjectPart(localID);
88 if (part == null || part.ParentGroup == null) 88 if (part == null)
89 return; 89 return;
90 90
91 if (part.ParentGroup.IsDeleted) 91 if (part.ParentGroup.IsDeleted)
@@ -111,9 +111,6 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell
111 if (part == null) 111 if (part == null)
112 return false; 112 return false;
113 113
114 if (part.ParentGroup == null)
115 return false;
116
117 SceneObjectGroup group = part.ParentGroup; 114 SceneObjectGroup group = part.ParentGroup;
118 115
119 switch (saleType) 116 switch (saleType)
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 2c7843f..afb641f 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -146,7 +146,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
146 = ParseUserSetConfigSetting(myConfig, "allowed_script_editors", m_allowedScriptEditors); 146 = ParseUserSetConfigSetting(myConfig, "allowed_script_editors", m_allowedScriptEditors);
147 147
148 if (m_bypassPermissions) 148 if (m_bypassPermissions)
149 m_log.Info("[PERMISSIONS]: serviceside_object_permissions = false in ini file so disabling all region service permission checks"); 149 m_log.Info("[PERMISSIONS]: serverside_object_permissions = false in ini file so disabling all region service permission checks");
150 else 150 else
151 m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks"); 151 m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks");
152 152
@@ -1131,7 +1131,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
1131 SceneObjectPart part = scene.GetSceneObjectPart(objectID); 1131 SceneObjectPart part = scene.GetSceneObjectPart(objectID);
1132 if (part.OwnerID != moverID) 1132 if (part.OwnerID != moverID)
1133 { 1133 {
1134 if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) 1134 if (!part.ParentGroup.IsDeleted)
1135 { 1135 {
1136 if (part.ParentGroup.IsAttachment) 1136 if (part.ParentGroup.IsAttachment)
1137 return false; 1137 return false;
diff --git a/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs b/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs
index 4f752ab..d5b585a 100644
--- a/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs
+++ b/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs
@@ -236,14 +236,14 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
236 public void Init() 236 public void Init()
237 { 237 {
238 m_serialiserModule = new SerialiserModule(); 238 m_serialiserModule = new SerialiserModule();
239 m_scene = SceneSetupHelpers.SetupScene(); 239 m_scene = SceneHelpers.SetupScene();
240 SceneSetupHelpers.SetupSceneModules(m_scene, m_serialiserModule); 240 SceneHelpers.SetupSceneModules(m_scene, m_serialiserModule);
241 } 241 }
242 242
243 [Test] 243 [Test]
244 public void TestDeserializeXml() 244 public void TestDeserializeXml()
245 { 245 {
246 TestHelper.InMethod(); 246 TestHelpers.InMethod();
247 //log4net.Config.XmlConfigurator.Configure(); 247 //log4net.Config.XmlConfigurator.Configure();
248 248
249 SceneObjectGroup so = SceneObjectSerializer.FromOriginalXmlFormat(xml); 249 SceneObjectGroup so = SceneObjectSerializer.FromOriginalXmlFormat(xml);
@@ -259,7 +259,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
259 [Test] 259 [Test]
260 public void TestSerializeXml() 260 public void TestSerializeXml()
261 { 261 {
262 TestHelper.InMethod(); 262 TestHelpers.InMethod();
263 //log4net.Config.XmlConfigurator.Configure(); 263 //log4net.Config.XmlConfigurator.Configure();
264 264
265 string rpName = "My Little Donkey"; 265 string rpName = "My Little Donkey";
@@ -334,7 +334,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
334 [Test] 334 [Test]
335 public void TestDeserializeXml2() 335 public void TestDeserializeXml2()
336 { 336 {
337 TestHelper.InMethod(); 337 TestHelpers.InMethod();
338 //log4net.Config.XmlConfigurator.Configure(); 338 //log4net.Config.XmlConfigurator.Configure();
339 339
340 SceneObjectGroup so = m_serialiserModule.DeserializeGroupFromXml2(xml2); 340 SceneObjectGroup so = m_serialiserModule.DeserializeGroupFromXml2(xml2);
@@ -350,7 +350,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
350 [Test] 350 [Test]
351 public void TestSerializeXml2() 351 public void TestSerializeXml2()
352 { 352 {
353 TestHelper.InMethod(); 353 TestHelpers.InMethod();
354 //log4net.Config.XmlConfigurator.Configure(); 354 //log4net.Config.XmlConfigurator.Configure();
355 355
356 string rpName = "My Little Pony"; 356 string rpName = "My Little Pony";
diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
index 09c0ebb..22ffcd6 100644
--- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
+++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
@@ -81,7 +81,7 @@ namespace OpenSim.Region.CoreModules.World.Sound
81 81
82 if (grp.IsAttachment) 82 if (grp.IsAttachment)
83 { 83 {
84 if (grp.GetAttachmentPoint() > 30) // HUD 84 if (grp.AttachmentPoint > 30) // HUD
85 { 85 {
86 if (sp.ControllingClient.AgentId != grp.OwnerID) 86 if (sp.ControllingClient.AgentId != grp.OwnerID)
87 return; 87 return;
@@ -115,7 +115,7 @@ namespace OpenSim.Region.CoreModules.World.Sound
115 { 115 {
116 SceneObjectGroup grp = part.ParentGroup; 116 SceneObjectGroup grp = part.ParentGroup;
117 117
118 if (grp.IsAttachment && grp.GetAttachmentPoint() > 30) 118 if (grp.IsAttachment && grp.AttachmentPoint > 30)
119 { 119 {
120 objectID = ownerID; 120 objectID = ownerID;
121 parentID = ownerID; 121 parentID = ownerID;
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
index 2da6458..a93ffaa 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -84,7 +84,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
84 private ITerrainChannel m_revert; 84 private ITerrainChannel m_revert;
85 private Scene m_scene; 85 private Scene m_scene;
86 private volatile bool m_tainted; 86 private volatile bool m_tainted;
87 private readonly UndoStack<LandUndoState> m_undo = new UndoStack<LandUndoState>(5); 87 private readonly Stack<LandUndoState> m_undo = new Stack<LandUndoState>(5);
88 88
89 #region ICommandableModule Members 89 #region ICommandableModule Members
90 90
diff --git a/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs b/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs
index c2ad7b8..ab8e1bf 100644
--- a/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs
+++ b/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs
@@ -100,15 +100,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Vegetation
100 { 100 {
101 case Tree.Cypress1: 101 case Tree.Cypress1:
102 case Tree.Cypress2: 102 case Tree.Cypress2:
103 tree.Scale = new Vector3(4, 4, 10); 103 tree.Scale *= new Vector3(8, 8, 20);
104 break; 104 break;
105 105
106 // case... other tree types 106 // case... other tree types
107 // tree.Scale = new Vector3(?, ?, ?); 107 // tree.Scale *= new Vector3(?, ?, ?);
108 // break; 108 // break;
109 109
110 default: 110 default:
111 tree.Scale = new Vector3(4, 4, 4); 111 tree.Scale *= new Vector3(8, 8, 8);
112 break; 112 break;
113 } 113 }
114 } 114 }
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
index ced2773..c13e9c6 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
@@ -96,16 +96,7 @@ m_log.DebugFormat("MAP NAME=({0})", mapName);
96 96
97 // try to fetch from GridServer 97 // try to fetch from GridServer
98 List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); 98 List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20);
99 if (regionInfos == null) 99 if (regionInfos.Count == 0)
100 {
101 m_log.Warn("[MAPSEARCHMODULE]: RequestNamedRegions returned null. Old gridserver?");
102 // service wasn't available; maybe still an old GridServer. Try the old API, though it will return only one region
103 regionInfos = new List<GridRegion>();
104 GridRegion info = m_scene.GridService.GetRegionByName(m_scene.RegionInfo.ScopeID, mapName);
105 if (info != null)
106 regionInfos.Add(info);
107 }
108 else if (regionInfos.Count == 0)
109 remoteClient.SendAlertMessage("Hyperlink could not be established."); 100 remoteClient.SendAlertMessage("Hyperlink could not be established.");
110 101
111 //m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions", mapName, regionInfos.Count); 102 //m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions", mapName, regionInfos.Count);
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index ca5529d9..21e3ecb 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -46,6 +46,7 @@ using OpenSim.Framework.Servers;
46using OpenSim.Framework.Servers.HttpServer; 46using OpenSim.Framework.Servers.HttpServer;
47using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
48using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.CoreModules.World.Land;
49using Caps=OpenSim.Framework.Capabilities.Caps; 50using Caps=OpenSim.Framework.Capabilities.Caps;
50using OSDArray=OpenMetaverse.StructuredData.OSDArray; 51using OSDArray=OpenMetaverse.StructuredData.OSDArray;
51using OSDMap=OpenMetaverse.StructuredData.OSDMap; 52using OSDMap=OpenMetaverse.StructuredData.OSDMap;
@@ -68,6 +69,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
68 protected Scene m_scene; 69 protected Scene m_scene;
69 private List<MapBlockData> cachedMapBlocks = new List<MapBlockData>(); 70 private List<MapBlockData> cachedMapBlocks = new List<MapBlockData>();
70 private int cachedTime = 0; 71 private int cachedTime = 0;
72 private int blacklistTimeout = 10*60*1000; // 10 minutes
71 private byte[] myMapImageJPEG; 73 private byte[] myMapImageJPEG;
72 protected volatile bool m_Enabled = false; 74 protected volatile bool m_Enabled = false;
73 private Dictionary<UUID, MapRequestState> m_openRequests = new Dictionary<UUID, MapRequestState>(); 75 private Dictionary<UUID, MapRequestState> m_openRequests = new Dictionary<UUID, MapRequestState>();
@@ -85,6 +87,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
85 IConfig startupConfig = config.Configs["Startup"]; 87 IConfig startupConfig = config.Configs["Startup"];
86 if (startupConfig.GetString("WorldMapModule", "WorldMap") == "WorldMap") 88 if (startupConfig.GetString("WorldMapModule", "WorldMap") == "WorldMap")
87 m_Enabled = true; 89 m_Enabled = true;
90
91 blacklistTimeout = startupConfig.GetInt("BlacklistTimeout", 10*60) * 1000;
88 } 92 }
89 93
90 public virtual void AddRegion (Scene scene) 94 public virtual void AddRegion (Scene scene)
@@ -159,11 +163,17 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
159 m_scene.EventManager.OnClientClosed += ClientLoggedOut; 163 m_scene.EventManager.OnClientClosed += ClientLoggedOut;
160 m_scene.EventManager.OnMakeChildAgent += MakeChildAgent; 164 m_scene.EventManager.OnMakeChildAgent += MakeChildAgent;
161 m_scene.EventManager.OnMakeRootAgent += MakeRootAgent; 165 m_scene.EventManager.OnMakeRootAgent += MakeRootAgent;
166 m_scene.EventManager.OnRegionUp += OnRegionUp;
167
168 StartThread(new object());
162 } 169 }
163 170
164 // this has to be called with a lock on m_scene 171 // this has to be called with a lock on m_scene
165 protected virtual void RemoveHandlers() 172 protected virtual void RemoveHandlers()
166 { 173 {
174 StopThread();
175
176 m_scene.EventManager.OnRegionUp -= OnRegionUp;
167 m_scene.EventManager.OnMakeRootAgent -= MakeRootAgent; 177 m_scene.EventManager.OnMakeRootAgent -= MakeRootAgent;
168 m_scene.EventManager.OnMakeChildAgent -= MakeChildAgent; 178 m_scene.EventManager.OnMakeChildAgent -= MakeChildAgent;
169 m_scene.EventManager.OnClientClosed -= ClientLoggedOut; 179 m_scene.EventManager.OnClientClosed -= ClientLoggedOut;
@@ -279,7 +289,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
279 /// <returns></returns> 289 /// <returns></returns>
280 public LLSDMapLayerResponse GetMapLayer(LLSDMapRequest mapReq) 290 public LLSDMapLayerResponse GetMapLayer(LLSDMapRequest mapReq)
281 { 291 {
282 m_log.Debug("[WORLD MAP]: MapLayer Request in region: " + m_scene.RegionInfo.RegionName); 292 m_log.DebugFormat("[WORLD MAP]: MapLayer Request in region: {0}", m_scene.RegionInfo.RegionName);
283 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); 293 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
284 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); 294 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
285 return mapResponse; 295 return mapResponse;
@@ -321,8 +331,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
321 lock (m_rootAgents) 331 lock (m_rootAgents)
322 { 332 {
323 m_rootAgents.Remove(AgentId); 333 m_rootAgents.Remove(AgentId);
324 if (m_rootAgents.Count == 0)
325 StopThread();
326 } 334 }
327 } 335 }
328 #endregion 336 #endregion
@@ -362,6 +370,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
362 public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags, 370 public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags,
363 uint EstateID, bool godlike, uint itemtype, ulong regionhandle) 371 uint EstateID, bool godlike, uint itemtype, ulong regionhandle)
364 { 372 {
373// m_log.DebugFormat("[WORLD MAP]: Handle MapItem request {0} {1}", regionhandle, itemtype);
374
365 lock (m_rootAgents) 375 lock (m_rootAgents)
366 { 376 {
367 if (!m_rootAgents.Contains(remoteClient.AgentId)) 377 if (!m_rootAgents.Contains(remoteClient.AgentId))
@@ -370,7 +380,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
370 uint xstart = 0; 380 uint xstart = 0;
371 uint ystart = 0; 381 uint ystart = 0;
372 Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out xstart, out ystart); 382 Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out xstart, out ystart);
373 if (itemtype == 6) // we only sevice 6 right now (avatar green dots) 383 if (itemtype == 6) // Service 6 right now (MAP_ITEM_AGENTS_LOCATION; green dots)
374 { 384 {
375 if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle) 385 if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle)
376 { 386 {
@@ -414,14 +424,57 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
414 // Remote Map Item Request 424 // Remote Map Item Request
415 425
416 // ensures that the blockingqueue doesn't get borked if the GetAgents() timing changes. 426 // ensures that the blockingqueue doesn't get borked if the GetAgents() timing changes.
417 // Note that we only start up a remote mapItem Request thread if there's users who could 427 RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle);
418 // be making requests 428 }
419 if (!threadrunning) 429 } else if (itemtype == 7) // Service 7 (MAP_ITEM_LAND_FOR_SALE)
430 {
431 if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle)
432 {
433 // Parcels
434 ILandChannel landChannel = m_scene.LandChannel;
435 List<ILandObject> parcels = landChannel.AllParcels();
436
437 // Local Map Item Request
438 List<mapItemReply> mapitems = new List<mapItemReply>();
439 mapItemReply mapitem = new mapItemReply();
440 if ((parcels != null) && (parcels.Count >= 1))
420 { 441 {
421 m_log.Warn("[WORLD MAP]: Starting new remote request thread manually. This means that AvatarEnteringParcel never fired! This needs to be fixed! Don't Mantis this, as the developers can see it in this message"); 442 foreach (ILandObject parcel_interface in parcels)
422 StartThread(new object()); 443 {
444 // Play it safe
445 if (!(parcel_interface is LandObject))
446 continue;
447
448 LandObject land = (LandObject)parcel_interface;
449 LandData parcel = land.LandData;
450
451 // Show land for sale
452 if ((parcel.Flags & (uint)ParcelFlags.ForSale) == (uint)ParcelFlags.ForSale)
453 {
454 Vector3 min = parcel.AABBMin;
455 Vector3 max = parcel.AABBMax;
456 float x = (min.X+max.X)/2;
457 float y = (min.Y+max.Y)/2;
458
459 mapitem = new mapItemReply();
460 mapitem.x = (uint)(xstart + x);
461 mapitem.y = (uint)(ystart + y);
462 // mapitem.z = (uint)m_scene.GetGroundHeight(x,y);
463 mapitem.id = UUID.Zero;
464 mapitem.name = parcel.Name;
465 mapitem.Extra = parcel.Area;
466 mapitem.Extra2 = parcel.SalePrice;
467 mapitems.Add(mapitem);
468 }
469 }
423 } 470 }
471 remoteClient.SendMapItemReply(mapitems.ToArray(), itemtype, flags);
472 }
473 else
474 {
475 // Remote Map Item Request
424 476
477 // ensures that the blockingqueue doesn't get borked if the GetAgents() timing changes.
425 RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle); 478 RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle);
426 } 479 }
427 } 480 }
@@ -542,6 +595,28 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
542 } 595 }
543 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags); 596 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags);
544 } 597 }
598
599 // Service 7 (MAP_ITEM_LAND_FOR_SALE)
600 uint itemtype = 7;
601
602 if (response.ContainsKey(itemtype.ToString()))
603 {
604 List<mapItemReply> returnitems = new List<mapItemReply>();
605 OSDArray itemarray = (OSDArray)response[itemtype.ToString()];
606 for (int i = 0; i < itemarray.Count; i++)
607 {
608 OSDMap mapitem = (OSDMap)itemarray[i];
609 mapItemReply mi = new mapItemReply();
610 mi.x = (uint)mapitem["X"].AsInteger();
611 mi.y = (uint)mapitem["Y"].AsInteger();
612 mi.id = mapitem["ID"].AsUUID();
613 mi.Extra = mapitem["Extra"].AsInteger();
614 mi.Extra2 = mapitem["Extra2"].AsInteger();
615 mi.name = mapitem["Name"].AsString();
616 returnitems.Add(mi);
617 }
618 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags);
619 }
545 } 620 }
546 } 621 }
547 } 622 }
@@ -589,12 +664,23 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
589 private OSDMap RequestMapItemsAsync(UUID id, uint flags, 664 private OSDMap RequestMapItemsAsync(UUID id, uint flags,
590 uint EstateID, bool godlike, uint itemtype, ulong regionhandle) 665 uint EstateID, bool godlike, uint itemtype, ulong regionhandle)
591 { 666 {
667// m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype);
668
592 string httpserver = ""; 669 string httpserver = "";
593 bool blacklisted = false; 670 bool blacklisted = false;
594 lock (m_blacklistedregions) 671 lock (m_blacklistedregions)
595 { 672 {
596 if (m_blacklistedregions.ContainsKey(regionhandle)) 673 if (m_blacklistedregions.ContainsKey(regionhandle))
597 blacklisted = true; 674 {
675 if (Environment.TickCount > (m_blacklistedregions[regionhandle] + blacklistTimeout))
676 {
677 m_log.DebugFormat("[WORLDMAP]: Unblock blacklisted region {0}", regionhandle);
678
679 m_blacklistedregions.Remove(regionhandle);
680 }
681 else
682 blacklisted = true;
683 }
598 } 684 }
599 685
600 if (blacklisted) 686 if (blacklisted)
@@ -636,7 +722,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
636 lock (m_blacklistedurls) 722 lock (m_blacklistedurls)
637 { 723 {
638 if (m_blacklistedurls.ContainsKey(httpserver)) 724 if (m_blacklistedurls.ContainsKey(httpserver))
639 blacklisted = true; 725 {
726 if (Environment.TickCount > (m_blacklistedurls[httpserver] + blacklistTimeout))
727 {
728 m_log.DebugFormat("[WORLDMAP]: Unblock blacklisted URL {0}", httpserver);
729
730 m_blacklistedurls.Remove(httpserver);
731 }
732 else
733 blacklisted = true;
734 }
640 } 735 }
641 736
642 // Can't find the http server 737 // Can't find the http server
@@ -682,7 +777,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
682 mapitemsrequest.ContentLength = buffer.Length; //Count bytes to send 777 mapitemsrequest.ContentLength = buffer.Length; //Count bytes to send
683 os = mapitemsrequest.GetRequestStream(); 778 os = mapitemsrequest.GetRequestStream();
684 os.Write(buffer, 0, buffer.Length); //Send it 779 os.Write(buffer, 0, buffer.Length); //Send it
685 os.Close();
686 //m_log.DebugFormat("[WORLD MAP]: Getting MapItems from {0}", httpserver); 780 //m_log.DebugFormat("[WORLD MAP]: Getting MapItems from {0}", httpserver);
687 } 781 }
688 catch (WebException ex) 782 catch (WebException ex)
@@ -705,6 +799,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
705 responseMap["connect"] = OSD.FromBoolean(false); 799 responseMap["connect"] = OSD.FromBoolean(false);
706 return responseMap; 800 return responseMap;
707 } 801 }
802 finally
803 {
804 if (os != null)
805 os.Close();
806 }
708 807
709 string response_mapItems_reply = null; 808 string response_mapItems_reply = null;
710 { // get the response 809 { // get the response
@@ -1060,6 +1159,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1060 1159
1061 Utils.LongToUInts(m_scene.RegionInfo.RegionHandle,out xstart,out ystart); 1160 Utils.LongToUInts(m_scene.RegionInfo.RegionHandle,out xstart,out ystart);
1062 1161
1162 // Service 6 (MAP_ITEM_AGENTS_LOCATION; green dots)
1163
1063 OSDMap responsemap = new OSDMap(); 1164 OSDMap responsemap = new OSDMap();
1064 int tc = Environment.TickCount; 1165 int tc = Environment.TickCount;
1065 if (m_scene.GetRootAgentCount() == 0) 1166 if (m_scene.GetRootAgentCount() == 0)
@@ -1092,6 +1193,60 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1092 }); 1193 });
1093 responsemap["6"] = responsearr; 1194 responsemap["6"] = responsearr;
1094 } 1195 }
1196
1197 // Service 7 (MAP_ITEM_LAND_FOR_SALE)
1198
1199 ILandChannel landChannel = m_scene.LandChannel;
1200 List<ILandObject> parcels = landChannel.AllParcels();
1201
1202 if ((parcels == null) || (parcels.Count == 0))
1203 {
1204 OSDMap responsemapdata = new OSDMap();
1205 responsemapdata["X"] = OSD.FromInteger((int)(xstart + 1));
1206 responsemapdata["Y"] = OSD.FromInteger((int)(ystart + 1));
1207 responsemapdata["ID"] = OSD.FromUUID(UUID.Zero);
1208 responsemapdata["Name"] = OSD.FromString("");
1209 responsemapdata["Extra"] = OSD.FromInteger(0);
1210 responsemapdata["Extra2"] = OSD.FromInteger(0);
1211 OSDArray responsearr = new OSDArray();
1212 responsearr.Add(responsemapdata);
1213
1214 responsemap["7"] = responsearr;
1215 }
1216 else
1217 {
1218 OSDArray responsearr = new OSDArray(m_scene.GetRootAgentCount());
1219 foreach (ILandObject parcel_interface in parcels)
1220 {
1221 // Play it safe
1222 if (!(parcel_interface is LandObject))
1223 continue;
1224
1225 LandObject land = (LandObject)parcel_interface;
1226 LandData parcel = land.LandData;
1227
1228 // Show land for sale
1229 if ((parcel.Flags & (uint)ParcelFlags.ForSale) == (uint)ParcelFlags.ForSale)
1230 {
1231 Vector3 min = parcel.AABBMin;
1232 Vector3 max = parcel.AABBMax;
1233 float x = (min.X+max.X)/2;
1234 float y = (min.Y+max.Y)/2;
1235
1236 OSDMap responsemapdata = new OSDMap();
1237 responsemapdata["X"] = OSD.FromInteger((int)(xstart + x));
1238 responsemapdata["Y"] = OSD.FromInteger((int)(ystart + y));
1239 // responsemapdata["Z"] = OSD.FromInteger((int)m_scene.GetGroundHeight(x,y));
1240 responsemapdata["ID"] = OSD.FromUUID(UUID.Zero);
1241 responsemapdata["Name"] = OSD.FromString(parcel.Name);
1242 responsemapdata["Extra"] = OSD.FromInteger(parcel.Area);
1243 responsemapdata["Extra2"] = OSD.FromInteger(parcel.SalePrice);
1244 responsearr.Add(responsemapdata);
1245 }
1246 }
1247 responsemap["7"] = responsearr;
1248 }
1249
1095 return responsemap; 1250 return responsemap;
1096 } 1251 }
1097 1252
@@ -1110,14 +1265,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1110 if (data == null) 1265 if (data == null)
1111 return; 1266 return;
1112 1267
1113 UUID lastMapRegionUUID = m_scene.RegionInfo.RegionSettings.TerrainImageID;
1114
1115 m_log.Debug("[WORLDMAP]: STORING MAPTILE IMAGE"); 1268 m_log.Debug("[WORLDMAP]: STORING MAPTILE IMAGE");
1116 1269
1117 m_scene.RegionInfo.RegionSettings.TerrainImageID = UUID.Random(); 1270 UUID terrainImageID = UUID.Random();
1118 1271
1119 AssetBase asset = new AssetBase( 1272 AssetBase asset = new AssetBase(
1120 m_scene.RegionInfo.RegionSettings.TerrainImageID, 1273 terrainImageID,
1121 "terrainImage_" + m_scene.RegionInfo.RegionID.ToString(), 1274 "terrainImage_" + m_scene.RegionInfo.RegionID.ToString(),
1122 (sbyte)AssetType.Texture, 1275 (sbyte)AssetType.Texture,
1123 m_scene.RegionInfo.RegionID.ToString()); 1276 m_scene.RegionInfo.RegionID.ToString());
@@ -1129,6 +1282,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1129 // Store the new one 1282 // Store the new one
1130 m_log.DebugFormat("[WORLDMAP]: Storing map tile {0}", asset.ID); 1283 m_log.DebugFormat("[WORLDMAP]: Storing map tile {0}", asset.ID);
1131 m_scene.AssetService.Store(asset); 1284 m_scene.AssetService.Store(asset);
1285
1286 // Switch to the new one
1287 UUID lastMapRegionUUID = m_scene.RegionInfo.RegionSettings.TerrainImageID;
1288 m_scene.RegionInfo.RegionSettings.TerrainImageID = terrainImageID;
1132 m_scene.RegionInfo.RegionSettings.Save(); 1289 m_scene.RegionInfo.RegionSettings.Save();
1133 1290
1134 // Delete the old one 1291 // Delete the old one
@@ -1138,12 +1295,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1138 1295
1139 private void MakeRootAgent(ScenePresence avatar) 1296 private void MakeRootAgent(ScenePresence avatar)
1140 { 1297 {
1141 // You may ask, why this is in a threadpool to start with..
1142 // The reason is so we don't cause the thread to freeze waiting
1143 // for the 1 second it costs to start a thread manually.
1144 if (!threadrunning)
1145 Util.FireAndForget(this.StartThread);
1146
1147 lock (m_rootAgents) 1298 lock (m_rootAgents)
1148 { 1299 {
1149 if (!m_rootAgents.Contains(avatar.UUID)) 1300 if (!m_rootAgents.Contains(avatar.UUID))
@@ -1158,8 +1309,30 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1158 lock (m_rootAgents) 1309 lock (m_rootAgents)
1159 { 1310 {
1160 m_rootAgents.Remove(avatar.UUID); 1311 m_rootAgents.Remove(avatar.UUID);
1161 if (m_rootAgents.Count == 0) 1312 }
1162 StopThread(); 1313 }
1314
1315 public void OnRegionUp(GridRegion otherRegion)
1316 {
1317 ulong regionhandle = otherRegion.RegionHandle;
1318 string httpserver = otherRegion.ServerURI + "MAP/MapItems/" + regionhandle.ToString();
1319
1320 lock (m_blacklistedregions)
1321 {
1322 if (!m_blacklistedregions.ContainsKey(regionhandle))
1323 m_blacklistedregions.Remove(regionhandle);
1324 }
1325
1326 lock (m_blacklistedurls)
1327 {
1328 if (m_blacklistedurls.ContainsKey(httpserver))
1329 m_blacklistedurls.Remove(httpserver);
1330 }
1331
1332 lock (m_cachedRegionMapItemsAddress)
1333 {
1334 if (!m_cachedRegionMapItemsAddress.ContainsKey(regionhandle))
1335 m_cachedRegionMapItemsAddress.Remove(regionhandle);
1163 } 1336 }
1164 } 1337 }
1165 1338
diff --git a/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs b/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs
index 5e75cae..0bb4044 100644
--- a/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs
+++ b/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs
@@ -118,59 +118,56 @@ namespace OpenSim.Region.DataSnapshot.Providers
118 { 118 {
119 SceneObjectPart m_rootPart = obj.RootPart; 119 SceneObjectPart m_rootPart = obj.RootPart;
120 120
121 if (m_rootPart != null) 121 ILandObject land = m_scene.LandChannel.GetLandObject(m_rootPart.AbsolutePosition.X, m_rootPart.AbsolutePosition.Y);
122 {
123 ILandObject land = m_scene.LandChannel.GetLandObject(m_rootPart.AbsolutePosition.X, m_rootPart.AbsolutePosition.Y);
124 122
125 XmlNode xmlobject = nodeFactory.CreateNode(XmlNodeType.Element, "object", ""); 123 XmlNode xmlobject = nodeFactory.CreateNode(XmlNodeType.Element, "object", "");
126 node = nodeFactory.CreateNode(XmlNodeType.Element, "uuid", ""); 124 node = nodeFactory.CreateNode(XmlNodeType.Element, "uuid", "");
127 node.InnerText = obj.UUID.ToString(); 125 node.InnerText = obj.UUID.ToString();
128 xmlobject.AppendChild(node); 126 xmlobject.AppendChild(node);
129 127
130 node = nodeFactory.CreateNode(XmlNodeType.Element, "title", ""); 128 node = nodeFactory.CreateNode(XmlNodeType.Element, "title", "");
131 node.InnerText = m_rootPart.Name; 129 node.InnerText = m_rootPart.Name;
132 xmlobject.AppendChild(node); 130 xmlobject.AppendChild(node);
133
134 node = nodeFactory.CreateNode(XmlNodeType.Element, "description", "");
135 node.InnerText = m_rootPart.Description;
136 xmlobject.AppendChild(node);
137 131
138 node = nodeFactory.CreateNode(XmlNodeType.Element, "flags", ""); 132 node = nodeFactory.CreateNode(XmlNodeType.Element, "description", "");
139 node.InnerText = String.Format("{0:x}", (uint)m_rootPart.Flags); 133 node.InnerText = m_rootPart.Description;
140 xmlobject.AppendChild(node); 134 xmlobject.AppendChild(node);
141 135
142 node = nodeFactory.CreateNode(XmlNodeType.Element, "regionuuid", ""); 136 node = nodeFactory.CreateNode(XmlNodeType.Element, "flags", "");
143 node.InnerText = m_scene.RegionInfo.RegionSettings.RegionUUID.ToString(); 137 node.InnerText = String.Format("{0:x}", (uint)m_rootPart.Flags);
144 xmlobject.AppendChild(node); 138 xmlobject.AppendChild(node);
145 139
146 if (land != null && land.LandData != null) 140 node = nodeFactory.CreateNode(XmlNodeType.Element, "regionuuid", "");
147 { 141 node.InnerText = m_scene.RegionInfo.RegionSettings.RegionUUID.ToString();
148 node = nodeFactory.CreateNode(XmlNodeType.Element, "parceluuid", ""); 142 xmlobject.AppendChild(node);
149 node.InnerText = land.LandData.GlobalID.ToString();
150 xmlobject.AppendChild(node);
151 }
152 else
153 {
154 // Something is wrong with this object. Let's not list it.
155 m_log.WarnFormat("[DATASNAPSHOT]: Bad data for object {0} ({1}) in region {2}", obj.Name, obj.UUID, m_scene.RegionInfo.RegionName);
156 continue;
157 }
158 143
159 node = nodeFactory.CreateNode(XmlNodeType.Element, "location", ""); 144 if (land != null && land.LandData != null)
160 Vector3 loc = obj.AbsolutePosition; 145 {
161 node.InnerText = loc.X.ToString() + "/" + loc.Y.ToString() + "/" + loc.Z.ToString(); 146 node = nodeFactory.CreateNode(XmlNodeType.Element, "parceluuid", "");
147 node.InnerText = land.LandData.GlobalID.ToString();
162 xmlobject.AppendChild(node); 148 xmlobject.AppendChild(node);
149 }
150 else
151 {
152 // Something is wrong with this object. Let's not list it.
153 m_log.WarnFormat("[DATASNAPSHOT]: Bad data for object {0} ({1}) in region {2}", obj.Name, obj.UUID, m_scene.RegionInfo.RegionName);
154 continue;
155 }
163 156
164 string bestImage = GuessImage(obj); 157 node = nodeFactory.CreateNode(XmlNodeType.Element, "location", "");
165 if (bestImage != string.Empty) 158 Vector3 loc = obj.AbsolutePosition;
166 { 159 node.InnerText = loc.X.ToString() + "/" + loc.Y.ToString() + "/" + loc.Z.ToString();
167 node = nodeFactory.CreateNode(XmlNodeType.Element, "image", ""); 160 xmlobject.AppendChild(node);
168 node.InnerText = bestImage;
169 xmlobject.AppendChild(node);
170 }
171 161
172 parent.AppendChild(xmlobject); 162 string bestImage = GuessImage(obj);
163 if (bestImage != string.Empty)
164 {
165 node = nodeFactory.CreateNode(XmlNodeType.Element, "image", "");
166 node.InnerText = bestImage;
167 xmlobject.AppendChild(node);
173 } 168 }
169
170 parent.AppendChild(xmlobject);
174 } 171 }
175 #pragma warning disable 0612 172 #pragma warning disable 0612
176 } 173 }
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
index 7e4fa71..3b740e2 100644
--- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
+++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
@@ -83,7 +83,7 @@ namespace OpenSim.Region.Examples.SimpleModule
83 public event DeRezObject OnDeRezObject; 83 public event DeRezObject OnDeRezObject;
84 public event Action<IClientAPI> OnRegionHandShakeReply; 84 public event Action<IClientAPI> OnRegionHandShakeReply;
85 public event GenericCall1 OnRequestWearables; 85 public event GenericCall1 OnRequestWearables;
86 public event GenericCall1 OnCompleteMovementToRegion; 86 public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
87 public event UpdateAgent OnPreAgentUpdate; 87 public event UpdateAgent OnPreAgentUpdate;
88 public event UpdateAgent OnAgentUpdate; 88 public event UpdateAgent OnAgentUpdate;
89 public event AgentRequestSit OnAgentRequestSit; 89 public event AgentRequestSit OnAgentRequestSit;
@@ -222,7 +222,7 @@ namespace OpenSim.Region.Examples.SimpleModule
222 public event ScriptReset OnScriptReset; 222 public event ScriptReset OnScriptReset;
223 public event GetScriptRunning OnGetScriptRunning; 223 public event GetScriptRunning OnGetScriptRunning;
224 public event SetScriptRunning OnSetScriptRunning; 224 public event SetScriptRunning OnSetScriptRunning;
225 public event UpdateVector OnAutoPilotGo; 225 public event Action<Vector3, bool> OnAutoPilotGo;
226 226
227 public event TerrainUnacked OnUnackedTerrain; 227 public event TerrainUnacked OnUnackedTerrain;
228 228
@@ -663,7 +663,7 @@ namespace OpenSim.Region.Examples.SimpleModule
663 663
664 if (OnCompleteMovementToRegion != null) 664 if (OnCompleteMovementToRegion != null)
665 { 665 {
666 OnCompleteMovementToRegion(this); 666 OnCompleteMovementToRegion(this, true);
667 } 667 }
668 } 668 }
669 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) 669 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID)
diff --git a/OpenSim/Region/Examples/SimpleModule/RegionModule.cs b/OpenSim/Region/Examples/SimpleModule/RegionModule.cs
index 088b818..3b8ce37 100644
--- a/OpenSim/Region/Examples/SimpleModule/RegionModule.cs
+++ b/OpenSim/Region/Examples/SimpleModule/RegionModule.cs
@@ -95,7 +95,7 @@ namespace OpenSim.Region.Examples.SimpleModule
95 for (int i = 0; i < 1; i++) 95 for (int i = 0; i < 1; i++)
96 { 96 {
97 MyNpcCharacter m_character = new MyNpcCharacter(m_scene); 97 MyNpcCharacter m_character = new MyNpcCharacter(m_scene);
98 m_scene.AddNewClient(m_character); 98 m_scene.AddNewClient(m_character, PresenceType.Npc);
99 m_scene.AgentCrossing(m_character.AgentId, Vector3.Zero, false); 99 m_scene.AgentCrossing(m_character.AgentId, Vector3.Zero, false);
100 } 100 }
101 101
diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
index 788f42b..6bbdd7d 100644
--- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
@@ -37,6 +37,27 @@ namespace OpenSim.Region.Framework.Interfaces
37 public interface IAttachmentsModule 37 public interface IAttachmentsModule
38 { 38 {
39 /// <summary> 39 /// <summary>
40 /// RezAttachments. This should only be called upon login on the first region.
41 /// Attachment rezzings on crossings and TPs are done in a different way.
42 /// </summary>
43 void RezAttachments(IScenePresence sp);
44
45 /// <summary>
46 /// Save the attachments that have change on this presence.
47 /// </summary>
48 /// <param name="sp"></param>
49 void SaveChangedAttachments(IScenePresence sp);
50
51 /// <summary>
52 /// Delete all the presence's attachments from the scene
53 /// </summary>
54 /// <param name="sp">
55 /// This is done when a root agent leaves/is demoted to child (for instance, on logout, teleport or region cross).
56 /// </param>
57 /// <param name="silent"></param>
58 void DeleteAttachmentsFromScene(IScenePresence sp, bool silent);
59
60 /// <summary>
40 /// Attach an object to an avatar from the world. 61 /// Attach an object to an avatar from the world.
41 /// </summary> 62 /// </summary>
42 /// <param name="controllingClient"></param> 63 /// <param name="controllingClient"></param>
@@ -48,13 +69,11 @@ namespace OpenSim.Region.Framework.Interfaces
48 IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent); 69 IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent);
49 70
50 /// <summary> 71 /// <summary>
51 /// Attach an object to an avatar. 72 /// Attach an object to an avatar
52 /// </summary> 73 /// </summary>
53 /// <param name="controllingClient"></param> 74 /// <param name="remoteClient"></param>
54 /// <param name="localID"></param> 75 /// <param name="grp"></param>
55 /// <param name="attachPoint"></param> 76 /// <param name="AttachmentPt"></param>
56 /// <param name="rot"></param>
57 /// <param name="attachPos"></param>
58 /// <param name="silent"></param> 77 /// <param name="silent"></param>
59 /// <returns>true if the object was successfully attached, false otherwise</returns> 78 /// <returns>true if the object was successfully attached, false otherwise</returns>
60 bool AttachObject( 79 bool AttachObject(
@@ -67,7 +86,7 @@ namespace OpenSim.Region.Framework.Interfaces
67 /// <param name="itemID"></param> 86 /// <param name="itemID"></param>
68 /// <param name="AttachmentPt"></param> 87 /// <param name="AttachmentPt"></param>
69 /// <returns>The scene object that was attached. Null if the scene object could not be found</returns> 88 /// <returns>The scene object that was attached. Null if the scene object could not be found</returns>
70 UUID RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt); 89 ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt);
71 90
72 /// <summary> 91 /// <summary>
73 /// Rez an attachment from user inventory 92 /// Rez an attachment from user inventory
@@ -80,7 +99,7 @@ namespace OpenSim.Region.Framework.Interfaces
80 /// False is required so that we don't attempt to update information when a user enters a scene with the 99 /// False is required so that we don't attempt to update information when a user enters a scene with the
81 /// attachment already correctly set up in inventory. 100 /// attachment already correctly set up in inventory.
82 /// <returns>The uuid of the scene object that was attached. Null if the scene object could not be found</returns> 101 /// <returns>The uuid of the scene object that was attached. Null if the scene object could not be found</returns>
83 UUID RezSingleAttachmentFromInventory( 102 ISceneEntity RezSingleAttachmentFromInventory(
84 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus); 103 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus);
85 104
86 // Same as above, but also load script states from a separate doc 105 // Same as above, but also load script states from a separate doc
@@ -101,9 +120,10 @@ namespace OpenSim.Region.Framework.Interfaces
101 /// <summary> 120 /// <summary>
102 /// Detach an object from the avatar. 121 /// Detach an object from the avatar.
103 /// </summary> 122 /// </summary>
104 /// 123 /// <remarks>
105 /// This method is called in response to a client's detach request, so we only update the information in 124 /// This method is called in response to a client's detach request, so we only update the information in
106 /// inventory 125 /// inventory
126 /// </remarks>
107 /// <param name="objectLocalID"></param> 127 /// <param name="objectLocalID"></param>
108 /// <param name="remoteClient"></param> 128 /// <param name="remoteClient"></param>
109 void DetachObject(uint objectLocalID, IClientAPI remoteClient); 129 void DetachObject(uint objectLocalID, IClientAPI remoteClient);
@@ -111,12 +131,12 @@ namespace OpenSim.Region.Framework.Interfaces
111 /// <summary> 131 /// <summary>
112 /// Detach the given item to the ground. 132 /// Detach the given item to the ground.
113 /// </summary> 133 /// </summary>
114 /// <param name="itemID"></param> 134 /// <param name="objectLocalID"></param>
115 /// <param name="remoteClient"></param> 135 /// <param name="remoteClient"></param>
116 void DetachSingleAttachmentToGround(UUID itemID, IClientAPI remoteClient); 136 void DetachSingleAttachmentToGround(uint objectLocalID, IClientAPI remoteClient);
117 137
118 /// <summary> 138 /// <summary>
119 /// Update the user inventory to show a detach. 139 /// Detach the given item so that it remains in the user's inventory.
120 /// </summary> 140 /// </summary>
121 /// <param name="itemID"> 141 /// <param name="itemID">
122 /// A <see cref="UUID"/> 142 /// A <see cref="UUID"/>
@@ -124,23 +144,15 @@ namespace OpenSim.Region.Framework.Interfaces
124 /// <param name="remoteClient"> 144 /// <param name="remoteClient">
125 /// A <see cref="IClientAPI"/> 145 /// A <see cref="IClientAPI"/>
126 /// </param> 146 /// </param>
127 void ShowDetachInUserInventory(UUID itemID, IClientAPI remoteClient); 147 void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient);
128 148
129 /// <summary> 149 /// <summary>
130 /// Update the user inventory with a changed attachment 150 /// Update the user inventory with a changed attachment
131 /// </summary> 151 /// </summary>
132 /// <param name="remoteClient"> 152 /// <param name="remoteClient"></param>
133 /// A <see cref="IClientAPI"/> 153 /// <param name="grp"></param>
134 /// </param> 154 /// <param name="itemID"></param>
135 /// <param name="grp"> 155 /// <param name="agentID"></param>
136 /// A <see cref="SceneObjectGroup"/>
137 /// </param>
138 /// <param name="itemID">
139 /// A <see cref="UUID"/>
140 /// </param>
141 /// <param name="agentID">
142 /// A <see cref="UUID"/>
143 /// </param>
144 void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID); 156 void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID);
145 } 157 }
146} 158}
diff --git a/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs b/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs
index d0e5609..4dbddf4 100644
--- a/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs
+++ b/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs
@@ -25,6 +25,7 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System.Collections.Generic;
28using OpenMetaverse; 29using OpenMetaverse;
29using OpenSim.Framework; 30using OpenSim.Framework;
30 31
@@ -32,6 +33,30 @@ namespace OpenSim.Region.Framework.Interfaces
32{ 33{
33 public interface IAvatarFactory 34 public interface IAvatarFactory
34 { 35 {
36 /// <summary>
37 /// Send the appearance of an avatar to others in the scene.
38 /// </summary>
39 /// <param name="agentId"></param>
40 /// <returns></returns>
41 bool SendAppearance(UUID agentId);
42
43 /// <summary>
44 /// Return the baked texture ids of the given agent.
45 /// </summary>
46 /// <param name="agentId"></param>
47 /// <returns>An empty list if this agent has no baked textures (e.g. because it's a child agent)</returns>
48 Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(UUID agentId);
49
50 /// <summary>
51 /// Save the baked textures for the given agent permanently in the asset database.
52 /// </summary>
53 /// <remarks>
54 /// This is used to preserve apperance textures for NPCs
55 /// </remarks>
56 /// <param name="agentId"></param>
57 /// <returns>true if a valid agent was found, false otherwise</returns>
58 bool SaveBakedTextures(UUID agentId);
59
35 bool ValidateBakedTextureCache(IClientAPI client); 60 bool ValidateBakedTextureCache(IClientAPI client);
36 void QueueAppearanceSend(UUID agentid); 61 void QueueAppearanceSend(UUID agentid);
37 void QueueAppearanceSave(UUID agentid); 62 void QueueAppearanceSave(UUID agentid);
diff --git a/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs b/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs
index da11e61..1904011 100644
--- a/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs
@@ -54,10 +54,58 @@ namespace OpenSim.Region.Framework.Interfaces
54 /// FIXME: This is not very useful. It would be far more useful to return a list of items instead. 54 /// FIXME: This is not very useful. It would be far more useful to return a list of items instead.
55 /// </returns> 55 /// </returns>
56 UUID CopyToInventory(DeRezAction action, UUID folderID, List<SceneObjectGroup> objectGroups, IClientAPI remoteClient); 56 UUID CopyToInventory(DeRezAction action, UUID folderID, List<SceneObjectGroup> objectGroups, IClientAPI remoteClient);
57 57
58 SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, 58 /// <summary>
59 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, 59 /// Rez an object into the scene from the user's inventory
60 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment); 60 /// </summary>
61 /// <remarks>
62 /// FIXME: It would be really nice if inventory access modules didn't also actually do the work of rezzing
63 /// things to the scene. The caller should be doing that, I think.
64 /// </remarks>
65 /// <param name="remoteClient"></param>
66 /// <param name="itemID"></param>
67 /// <param name="RayEnd"></param>
68 /// <param name="RayStart"></param>
69 /// <param name="RayTargetID"></param>
70 /// <param name="BypassRayCast"></param>
71 /// <param name="RayEndIsIntersection"></param>
72 /// <param name="RezSelected"></param>
73 /// <param name="RemoveItem"></param>
74 /// <param name="fromTaskID"></param>
75 /// <param name="attachment"></param>
76 /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful.</returns>
77 SceneObjectGroup RezObject(
78 IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
79 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
80 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment);
81
82 /// <summary>
83 /// Rez an object into the scene from the user's inventory
84 /// </summary>
85 /// <remarks>
86 /// FIXME: It would be really nice if inventory access modules didn't also actually do the work of rezzing
87 /// things to the scene. The caller should be doing that, I think.
88 /// </remarks>
89 /// <param name="remoteClient"></param>
90 /// <param name="item">
91 /// The item from which the object asset came. Can be null, in which case pre and post rez item adjustment and checks are not performed.
92 /// </param>
93 /// <param name="assetID">The asset id for the object to rez.</param>
94 /// <param name="RayEnd"></param>
95 /// <param name="RayStart"></param>
96 /// <param name="RayTargetID"></param>
97 /// <param name="BypassRayCast"></param>
98 /// <param name="RayEndIsIntersection"></param>
99 /// <param name="RezSelected"></param>
100 /// <param name="RemoveItem"></param>
101 /// <param name="fromTaskID"></param>
102 /// <param name="attachment"></param>
103 /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful.</returns>
104 SceneObjectGroup RezObject(
105 IClientAPI remoteClient, InventoryItemBase item, UUID assetID, Vector3 RayEnd, Vector3 RayStart,
106 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
107 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment);
108
61 void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver); 109 void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver);
62 110
63 /// <summary> 111 /// <summary>
diff --git a/OpenSim/Region/Framework/Interfaces/INPCModule.cs b/OpenSim/Region/Framework/Interfaces/INPCModule.cs
index 21a755f..5e5c4a1 100644
--- a/OpenSim/Region/Framework/Interfaces/INPCModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/INPCModule.cs
@@ -26,15 +26,80 @@
26 */ 26 */
27 27
28using OpenMetaverse; 28using OpenMetaverse;
29using OpenSim.Framework;
29using OpenSim.Region.Framework.Scenes; 30using OpenSim.Region.Framework.Scenes;
30 31
31namespace OpenSim.Region.Framework.Interfaces 32namespace OpenSim.Region.Framework.Interfaces
32{ 33{
33 public interface INPCModule 34 public interface INPCModule
34 { 35 {
35 UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, UUID cloneAppearanceFrom); 36 /// <summary>
36 void Autopilot(UUID agentID, Scene scene, Vector3 pos); 37 /// Create an NPC
37 void Say(UUID agentID, Scene scene, string text); 38 /// </summary>
38 void DeleteNPC(UUID agentID, Scene scene); 39 /// <param name="firstname"></param>
40 /// <param name="lastname"></param>
41 /// <param name="position"></param>
42 /// <param name="scene"></param>
43 /// <param name="appearance">The avatar appearance to use for the new NPC.</param>
44 /// <returns>The UUID of the ScenePresence created.</returns>
45 UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, AvatarAppearance appearance);
46
47 /// <summary>
48 /// Check if the agent is an NPC.
49 /// </summary>
50 /// <param name="agentID"></param>
51 /// <param name="scene"></param>
52 /// <returns>True if the agent is an NPC in the given scene. False otherwise.</returns>
53 bool IsNPC(UUID agentID, Scene scene);
54
55 /// <summary>
56 /// Set the appearance for an NPC.
57 /// </summary>
58 /// <param name="agentID"></param>
59 /// <param name="appearance"></param>
60 /// <param name="scene"></param>
61 /// <returns>True if the operation succeeded, false if there was no such agent or the agent was not an NPC</returns>
62 bool SetNPCAppearance(UUID agentID, AvatarAppearance appearance, Scene scene);
63
64 /// <summary>
65 /// Move an NPC to a target over time.
66 /// </summary>
67 /// <param name="agentID">The UUID of the NPC</param>
68 /// <param name="scene"></param>
69 /// <param name="pos"></param>
70 /// <param name="noFly">
71 /// If true, then the avatar will attempt to walk to the location even if it's up in the air.
72 /// This is to allow walking on prims.
73 /// </param>
74 /// <param name="landAtTarget">
75 /// If true and the avatar is flying when it reaches the target, land.
76 /// </param>
77 /// <returns>True if the operation succeeded, false if there was no such agent or the agent was not an NPC</returns>
78 bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos, bool noFly, bool landAtTarget);
79
80 /// <summary>
81 /// Stop the NPC's current movement.
82 /// </summary>
83 /// <param name="agentID">The UUID of the NPC</param>
84 /// <param name="scene"></param>
85 /// <returns>True if the operation succeeded, false if there was no such agent or the agent was not an NPC</returns>
86 bool StopMoveToTarget(UUID agentID, Scene scene);
87
88 /// <summary>
89 /// Get the NPC to say something.
90 /// </summary>
91 /// <param name="agentID">The UUID of the NPC</param>
92 /// <param name="scene"></param>
93 /// <param name="text"></param>
94 /// <returns>True if the operation succeeded, false if there was no such agent or the agent was not an NPC</returns>
95 bool Say(UUID agentID, Scene scene, string text);
96
97 /// <summary>
98 /// Delete an NPC.
99 /// </summary>
100 /// <param name="agentID">The UUID of the NPC</param>
101 /// <param name="scene"></param>
102 /// <returns>True if the operation succeeded, false if there was no such agent or the agent was not an NPC</returns>
103 bool DeleteNPC(UUID agentID, Scene scene);
39 } 104 }
40} \ No newline at end of file 105} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs
new file mode 100644
index 0000000..8913133
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs
@@ -0,0 +1,88 @@
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 OpenSim.Framework;
31using OpenSim.Region.Framework.Scenes;
32
33namespace OpenSim.Region.Framework.Interfaces
34{
35 /// <summary>
36 /// An agent in the scene.
37 /// </summary>
38 /// <remarks>
39 /// Interface is a work in progress. Please feel free to add other required properties and methods.
40 /// </remarks>
41 public interface IScenePresence : ISceneEntity
42 {
43 /// <value>
44 /// The client controlling this presence
45 /// </value>
46 IClientAPI ControllingClient { get; }
47
48 /// <summary>
49 /// What type of presence is this? User, NPC, etc.
50 /// </summary>
51 PresenceType PresenceType { get; }
52
53 /// <summary>
54 /// Avatar appearance data.
55 /// </summary>
56 /// <remarks>
57 // Because appearance setting is in a module, we actually need
58 // to give it access to our appearance directly, otherwise we
59 // get a synchronization issue.
60 /// </remarks>
61 AvatarAppearance Appearance { get; set; }
62
63 /// <summary>
64 /// The scene objects attached to this avatar.
65 /// </summary>
66 /// <returns>
67 /// A copy of the list.
68 /// </returns>
69 /// <remarks>
70 /// Do not change this list directly - use the attachments module.
71 /// </remarks>
72 List<SceneObjectGroup> GetAttachments();
73
74 /// <summary>
75 /// The scene objects attached to this avatar at a specific attachment point.
76 /// </summary>
77 /// <param name="attachmentPoint"></param>
78 /// <returns></returns>
79 List<SceneObjectGroup> GetAttachments(uint attachmentPoint);
80
81 bool HasAttachments();
82
83 // Don't use these methods directly. Instead, use the AttachmentsModule
84 void AddAttachment(SceneObjectGroup gobj);
85 void RemoveAttachment(SceneObjectGroup gobj);
86 void ClearAttachments();
87 }
88} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Interfaces/ISimulatorFeaturesModule.cs b/OpenSim/Region/Framework/Interfaces/ISimulatorFeaturesModule.cs
new file mode 100644
index 0000000..8cef14e
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/ISimulatorFeaturesModule.cs
@@ -0,0 +1,43 @@
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 OpenMetaverse.StructuredData;
30
31namespace OpenSim.Region.Framework.Interfaces
32{
33 /// <summary>
34 /// Add remove or retrieve Simulator Features that will be given to a viewer via the SimulatorFeatures capability.
35 /// </summary>
36 public interface ISimulatorFeaturesModule
37 {
38 void AddFeature(string name, OSD value);
39 bool RemoveFeature(string name);
40 bool TryGetFeature(string name, out OSD value);
41 OSDMap GetFeatures();
42 }
43} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
index 5d30aa8..c66e053 100644
--- a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
+++ b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
@@ -5,13 +5,48 @@ using OpenMetaverse;
5 5
6namespace OpenSim.Region.Framework.Interfaces 6namespace OpenSim.Region.Framework.Interfaces
7{ 7{
8 /// <summary>
9 /// This maintains the relationship between a UUID and a user name.
10 /// </summary>
8 public interface IUserManagement 11 public interface IUserManagement
9 { 12 {
10 string GetUserName(UUID uuid); 13 string GetUserName(UUID uuid);
11 string GetUserHomeURL(UUID uuid); 14 string GetUserHomeURL(UUID uuid);
12 string GetUserUUI(UUID uuid); 15 string GetUserUUI(UUID uuid);
13 string GetUserServerURL(UUID uuid, string serverType); 16 string GetUserServerURL(UUID uuid, string serverType);
14 void AddUser(UUID uuid, string userData); 17
18 /// <summary>
19 /// Add a user.
20 /// </summary>
21 /// <remarks>
22 /// If an account is found for the UUID, then the names in this will be used rather than any information
23 /// extracted from creatorData.
24 /// </remarks>
25 /// <param name="uuid"></param>
26 /// <param name="creatorData">The creator data for this user.</param>
27 void AddUser(UUID uuid, string creatorData);
28
29 /// <summary>
30 /// Add a user.
31 /// </summary>
32 /// <remarks>
33 /// The UUID is related to the name without any other checks being performed, such as user account presence.
34 /// </remarks>
35 /// <param name="uuid"></param>
36 /// <param name="firstName"></param>
37 /// <param name="lastName"></param>
38 void AddUser(UUID uuid, string firstName, string lastName);
39
40 /// <summary>
41 /// Add a user.
42 /// </summary>
43 /// <remarks>
44 /// The arguments apart from uuid are formed into a creatorData string and processing proceeds as for the
45 /// AddUser(UUID uuid, string creatorData) method.
46 /// </remarks>
47 /// <param name="uuid"></param>
48 /// <param name="firstName"></param>
49 /// <param name="profileURL"></param>
15 void AddUser(UUID uuid, string firstName, string lastName, string profileURL); 50 void AddUser(UUID uuid, string firstName, string lastName, string profileURL);
16 } 51 }
17} 52}
diff --git a/OpenSim/Region/Framework/Interfaces/IWorldComm.cs b/OpenSim/Region/Framework/Interfaces/IWorldComm.cs
index 8da99a0..dafbf30 100644
--- a/OpenSim/Region/Framework/Interfaces/IWorldComm.cs
+++ b/OpenSim/Region/Framework/Interfaces/IWorldComm.cs
@@ -81,6 +81,26 @@ namespace OpenSim.Region.Framework.Interfaces
81 void DeliverMessage(ChatTypeEnum type, int channel, string name, UUID id, string msg); 81 void DeliverMessage(ChatTypeEnum type, int channel, string name, UUID id, string msg);
82 82
83 /// <summary> 83 /// <summary>
84 /// Delivers the message to a specified object in the region.
85 /// </summary>
86 /// <param name='target'>
87 /// Target.
88 /// </param>
89 /// <param name='channel'>
90 /// Channel.
91 /// </param>
92 /// <param name='name'>
93 /// Name.
94 /// </param>
95 /// <param name='id'>
96 /// Identifier.
97 /// </param>
98 /// <param name='msg'>
99 /// Message.
100 /// </param>
101 bool DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg, out string error);
102
103 /// <summary>
84 /// Are there any listen events ready to be dispatched? 104 /// Are there any listen events ready to be dispatched?
85 /// </summary> 105 /// </summary>
86 /// <returns>boolean indication</returns> 106 /// <returns>boolean indication</returns>
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index 9c103cb..4925175 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -27,6 +27,8 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection;
31using log4net;
30using OpenMetaverse; 32using OpenMetaverse;
31using OpenSim.Framework; 33using OpenSim.Framework;
32using OpenSim.Region.Framework.Interfaces; 34using OpenSim.Region.Framework.Interfaces;
@@ -40,6 +42,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation
40 /// </summary> 42 /// </summary>
41 public class ScenePresenceAnimator 43 public class ScenePresenceAnimator
42 { 44 {
45// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46
43 public AnimationSet Animations 47 public AnimationSet Animations
44 { 48 {
45 get { return m_animations; } 49 get { return m_animations; }
@@ -79,6 +83,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation
79 if (m_scenePresence.IsChildAgent) 83 if (m_scenePresence.IsChildAgent)
80 return; 84 return;
81 85
86// m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Adding animation {0} for {1}", animID, m_scenePresence.Name);
87
82 if (m_animations.Add(animID, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, objectID)) 88 if (m_animations.Add(animID, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, objectID))
83 SendAnimPack(); 89 SendAnimPack();
84 } 90 }
@@ -93,6 +99,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation
93 if (animID == UUID.Zero) 99 if (animID == UUID.Zero)
94 return; 100 return;
95 101
102// m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Adding animation {0} {1} for {2}", animID, name, m_scenePresence.Name);
103
96 AddAnimation(animID, objectID); 104 AddAnimation(animID, objectID);
97 } 105 }
98 106
@@ -136,6 +144,10 @@ TrySetMovementAnimation("STAND");
136 if (m_animations.TrySetDefaultAnimation( 144 if (m_animations.TrySetDefaultAnimation(
137 anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID)) 145 anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID))
138 { 146 {
147// m_log.DebugFormat(
148// "[SCENE PRESENCE ANIMATOR]: Updating movement animation to {0} for {1}",
149// anim, m_scenePresence.Name);
150
139 // 16384 is CHANGED_ANIMATION 151 // 16384 is CHANGED_ANIMATION
140 m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { (int)Changed.ANIMATION}); 152 m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { (int)Changed.ANIMATION});
141 SendAnimPack(); 153 SendAnimPack();
@@ -353,7 +365,7 @@ TrySetMovementAnimation("STAND");
353/* This section removed, replaced by jumping section 365/* This section removed, replaced by jumping section
354 m_animTickFall = 0; 366 m_animTickFall = 0;
355 367
356 if (move.Z > 0f) 368 if (move.Z > 0.2f)
357 { 369 {
358 // Jumping 370 // Jumping
359 if (!jumping) 371 if (!jumping)
diff --git a/OpenSim/Region/Framework/Scenes/AsyncInventorySender.cs b/OpenSim/Region/Framework/Scenes/AsyncInventorySender.cs
index 06cd14b..9cb5674 100644
--- a/OpenSim/Region/Framework/Scenes/AsyncInventorySender.cs
+++ b/OpenSim/Region/Framework/Scenes/AsyncInventorySender.cs
@@ -70,7 +70,7 @@ namespace OpenSim.Region.Framework.Scenes
70 /// </remarks> 70 /// </remarks>
71 public class AsyncInventorySender 71 public class AsyncInventorySender
72 { 72 {
73 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 73// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
74 74
75 protected Scene m_scene; 75 protected Scene m_scene;
76 76
diff --git a/OpenSim/Region/Framework/Scenes/EntityBase.cs b/OpenSim/Region/Framework/Scenes/EntityBase.cs
index 6fd38e5..213431a 100644
--- a/OpenSim/Region/Framework/Scenes/EntityBase.cs
+++ b/OpenSim/Region/Framework/Scenes/EntityBase.cs
@@ -66,12 +66,7 @@ namespace OpenSim.Region.Framework.Scenes
66 /// <summary> 66 /// <summary>
67 /// Signals whether this entity was in a scene but has since been removed from it. 67 /// Signals whether this entity was in a scene but has since been removed from it.
68 /// </summary> 68 /// </summary>
69 public bool IsDeleted 69 public bool IsDeleted { get; protected internal set; }
70 {
71 get { return m_isDeleted; }
72 set { m_isDeleted = value; }
73 }
74 protected bool m_isDeleted;
75 70
76 protected Vector3 m_pos; 71 protected Vector3 m_pos;
77 72
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 3ec4e59..65c6a29 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -169,8 +169,7 @@ namespace OpenSim.Region.Framework.Scenes
169 public delegate void AvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID); 169 public delegate void AvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID);
170 public event AvatarEnteringNewParcel OnAvatarEnteringNewParcel; 170 public event AvatarEnteringNewParcel OnAvatarEnteringNewParcel;
171 171
172 public delegate void SignificantClientMovement(IClientAPI remote_client); 172 public event Action<ScenePresence> OnSignificantClientMovement;
173 public event SignificantClientMovement OnSignificantClientMovement;
174 173
175 public delegate void IncomingInstantMessage(GridInstantMessage message); 174 public delegate void IncomingInstantMessage(GridInstantMessage message);
176 public event IncomingInstantMessage OnIncomingInstantMessage; 175 public event IncomingInstantMessage OnIncomingInstantMessage;
@@ -1616,16 +1615,16 @@ namespace OpenSim.Region.Framework.Scenes
1616 } 1615 }
1617 } 1616 }
1618 1617
1619 public void TriggerSignificantClientMovement(IClientAPI client) 1618 public void TriggerSignificantClientMovement(ScenePresence presence)
1620 { 1619 {
1621 SignificantClientMovement handlerSignificantClientMovement = OnSignificantClientMovement; 1620 Action<ScenePresence> handlerSignificantClientMovement = OnSignificantClientMovement;
1622 if (handlerSignificantClientMovement != null) 1621 if (handlerSignificantClientMovement != null)
1623 { 1622 {
1624 foreach (SignificantClientMovement d in handlerSignificantClientMovement.GetInvocationList()) 1623 foreach (Action<ScenePresence> d in handlerSignificantClientMovement.GetInvocationList())
1625 { 1624 {
1626 try 1625 try
1627 { 1626 {
1628 d(client); 1627 d(presence);
1629 } 1628 }
1630 catch (Exception e) 1629 catch (Exception e)
1631 { 1630 {
diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs
index 657df15..0a34a4c 100644
--- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs
+++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs
@@ -116,14 +116,13 @@ namespace OpenSim.Region.Framework.Scenes
116 return priority; 116 return priority;
117 } 117 }
118 118
119
120 private uint GetPriorityByTime(IClientAPI client, ISceneEntity entity) 119 private uint GetPriorityByTime(IClientAPI client, ISceneEntity entity)
121 { 120 {
122 // And anything attached to this avatar gets top priority as well 121 // And anything attached to this avatar gets top priority as well
123 if (entity is SceneObjectPart) 122 if (entity is SceneObjectPart)
124 { 123 {
125 SceneObjectPart sop = (SceneObjectPart)entity; 124 SceneObjectPart sop = (SceneObjectPart)entity;
126 if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.RootPart.AttachedAvatar) 125 if (sop.ParentGroup.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar)
127 return 1; 126 return 1;
128 } 127 }
129 128
@@ -136,7 +135,7 @@ namespace OpenSim.Region.Framework.Scenes
136 if (entity is SceneObjectPart) 135 if (entity is SceneObjectPart)
137 { 136 {
138 SceneObjectPart sop = (SceneObjectPart)entity; 137 SceneObjectPart sop = (SceneObjectPart)entity;
139 if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.RootPart.AttachedAvatar) 138 if (sop.ParentGroup.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar)
140 return 1; 139 return 1;
141 } 140 }
142 141
@@ -149,7 +148,7 @@ namespace OpenSim.Region.Framework.Scenes
149 if (entity is SceneObjectPart) 148 if (entity is SceneObjectPart)
150 { 149 {
151 SceneObjectPart sop = (SceneObjectPart)entity; 150 SceneObjectPart sop = (SceneObjectPart)entity;
152 if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.RootPart.AttachedAvatar) 151 if (sop.ParentGroup.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar)
153 return 1; 152 return 1;
154 } 153 }
155 154
@@ -172,7 +171,7 @@ namespace OpenSim.Region.Framework.Scenes
172 if (entity is SceneObjectPart) 171 if (entity is SceneObjectPart)
173 { 172 {
174 // Attachments are high priority, 173 // Attachments are high priority,
175 if (((SceneObjectPart)entity).ParentGroup.RootPart.IsAttachment) 174 if (((SceneObjectPart)entity).ParentGroup.IsAttachment)
176 return 1; 175 return 1;
177 176
178 // Non physical prims are lower priority than physical prims 177 // Non physical prims are lower priority than physical prims
@@ -209,8 +208,7 @@ namespace OpenSim.Region.Framework.Scenes
209 if (entity is SceneObjectPart) 208 if (entity is SceneObjectPart)
210 { 209 {
211 SceneObjectGroup group = (entity as SceneObjectPart).ParentGroup; 210 SceneObjectGroup group = (entity as SceneObjectPart).ParentGroup;
212 if (group != null) 211 entityPos = group.AbsolutePosition;
213 entityPos = group.AbsolutePosition;
214 } 212 }
215 213
216 // Use the camera position for local agents and avatar position for remote agents 214 // Use the camera position for local agents and avatar position for remote agents
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index dbefb4a..89f3683 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -211,16 +211,10 @@ namespace OpenSim.Region.Framework.Scenes
211 211
212 // Retrieve group 212 // Retrieve group
213 SceneObjectPart part = GetSceneObjectPart(primId); 213 SceneObjectPart part = GetSceneObjectPart(primId);
214 SceneObjectGroup group = part.ParentGroup; 214 if (part == null)
215 if (null == group)
216 {
217 m_log.ErrorFormat(
218 "[PRIM INVENTORY]: " +
219 "Prim inventory update requested for item ID {0} in prim ID {1} but this prim does not exist",
220 itemId, primId);
221
222 return new ArrayList(); 215 return new ArrayList();
223 } 216
217 SceneObjectGroup group = part.ParentGroup;
224 218
225 // Retrieve item 219 // Retrieve item
226 TaskInventoryItem item = group.GetInventoryItem(part.LocalId, itemId); 220 TaskInventoryItem item = group.GetInventoryItem(part.LocalId, itemId);
@@ -709,7 +703,10 @@ namespace OpenSim.Region.Framework.Scenes
709 newName = item.Name; 703 newName = item.Name;
710 } 704 }
711 705
712 if (remoteClient.AgentId == oldAgentID || (LibraryService != null && LibraryService.LibraryRootFolder != null && oldAgentID == LibraryService.LibraryRootFolder.Owner)) 706 if (remoteClient.AgentId == oldAgentID
707 || (LibraryService != null
708 && LibraryService.LibraryRootFolder != null
709 && oldAgentID == LibraryService.LibraryRootFolder.Owner))
713 { 710 {
714 CreateNewInventoryItem( 711 CreateNewInventoryItem(
715 remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType, 712 remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType,
@@ -981,23 +978,14 @@ namespace OpenSim.Region.Framework.Scenes
981 if (item == null) 978 if (item == null)
982 return; 979 return;
983 980
984 if (item.Type == 10) 981 if (item.Type == 10)
985 {
986 part.RemoveScriptEvents(itemID);
987 EventManager.TriggerRemoveScript(localID, itemID);
988 }
989
990 group.RemoveInventoryItem(localID, itemID);
991 part.GetProperties(remoteClient);
992 }
993 else
994 { 982 {
995 m_log.ErrorFormat( 983 part.RemoveScriptEvents(itemID);
996 "[PRIM INVENTORY]: " + 984 EventManager.TriggerRemoveScript(localID, itemID);
997 "Removal of item {0} requested of prim {1} but this prim does not exist",
998 itemID,
999 localID);
1000 } 985 }
986
987 group.RemoveInventoryItem(localID, itemID);
988 part.GetProperties(remoteClient);
1001 } 989 }
1002 990
1003 private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId) 991 private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId)
@@ -1780,7 +1768,7 @@ namespace OpenSim.Region.Framework.Scenes
1780 } 1768 }
1781 1769
1782 // Already deleted by someone else 1770 // Already deleted by someone else
1783 if (part.ParentGroup == null || part.ParentGroup.IsDeleted) 1771 if (part.ParentGroup.IsDeleted)
1784 { 1772 {
1785 //Client still thinks the object exists, kill it 1773 //Client still thinks the object exists, kill it
1786 deleteIDs.Add(localID); 1774 deleteIDs.Add(localID);
@@ -2158,6 +2146,9 @@ namespace OpenSim.Region.Framework.Scenes
2158 foreach (uint localID in localIDs) 2146 foreach (uint localID in localIDs)
2159 { 2147 {
2160 SceneObjectPart part = GetSceneObjectPart(localID); 2148 SceneObjectPart part = GetSceneObjectPart(localID);
2149 if (part == null)
2150 continue;
2151
2161 if (!groups.Contains(part.ParentGroup)) 2152 if (!groups.Contains(part.ParentGroup))
2162 groups.Add(part.ParentGroup); 2153 groups.Add(part.ParentGroup);
2163 } 2154 }
@@ -2203,6 +2194,8 @@ namespace OpenSim.Region.Framework.Scenes
2203 foreach (uint localID in localIDs) 2194 foreach (uint localID in localIDs)
2204 { 2195 {
2205 SceneObjectPart part = GetSceneObjectPart(localID); 2196 SceneObjectPart part = GetSceneObjectPart(localID);
2197 if (part == null)
2198 continue;
2206 part.GetProperties(remoteClient); 2199 part.GetProperties(remoteClient);
2207 } 2200 }
2208 } 2201 }
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
index 9bef443..9da57a8 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -191,10 +191,6 @@ namespace OpenSim.Region.Framework.Scenes
191 if (part == null) 191 if (part == null)
192 return; 192 return;
193 193
194 // The prim is in the process of being deleted.
195 if (null == part.ParentGroup.RootPart)
196 return;
197
198 // A deselect packet contains all the local prims being deselected. However, since selection is still 194 // A deselect packet contains all the local prims being deselected. However, since selection is still
199 // group based we only want the root prim to trigger a full update - otherwise on objects with many prims 195 // group based we only want the root prim to trigger a full update - otherwise on objects with many prims
200 // we end up sending many duplicate ObjectUpdates 196 // we end up sending many duplicate ObjectUpdates
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index ec82cc3..26fe61d 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -635,6 +635,10 @@ namespace OpenSim.Region.Framework.Scenes
635 "delete object name <name>", 635 "delete object name <name>",
636 "Delete object by name", HandleDeleteObject); 636 "Delete object by name", HandleDeleteObject);
637 637
638 MainConsole.Instance.Commands.AddCommand("region", false, "delete object outside",
639 "delete object outside",
640 "Delete all objects outside boundaries", HandleDeleteObject);
641
638 //Bind Storage Manager functions to some land manager functions for this scene 642 //Bind Storage Manager functions to some land manager functions for this scene
639 EventManager.OnLandObjectAdded += 643 EventManager.OnLandObjectAdded +=
640 new EventManager.LandObjectAdded(simDataService.StoreLandObject); 644 new EventManager.LandObjectAdded(simDataService.StoreLandObject);
@@ -1703,20 +1707,20 @@ namespace OpenSim.Region.Framework.Scenes
1703 1707
1704 m_sceneGridService.SetScene(this); 1708 m_sceneGridService.SetScene(this);
1705 1709
1706 // If we generate maptiles internally at all, the maptile generator 1710 GridRegion region = new GridRegion(RegionInfo);
1707 // will register the region. If not, do it here 1711 string error = GridService.RegisterRegion(RegionInfo.ScopeID, region);
1708 if (m_generateMaptiles) 1712 if (error != String.Empty)
1709 { 1713 {
1710 RegenerateMaptile(null, null); 1714 throw new Exception(error);
1711 } 1715 }
1712 else 1716
1717 // Generate the maptile asynchronously, because sometimes it can be very slow and we
1718 // don't want this to delay starting the region.
1719 if (m_generateMaptiles)
1713 { 1720 {
1714 GridRegion region = new GridRegion(RegionInfo); 1721 Util.FireAndForget(delegate {
1715 string error = GridService.RegisterRegion(RegionInfo.ScopeID, region); 1722 RegenerateMaptile(null, null);
1716 if (error != String.Empty) 1723 });
1717 {
1718 throw new Exception(error);
1719 }
1720 } 1724 }
1721 } 1725 }
1722 1726
@@ -1757,6 +1761,7 @@ namespace OpenSim.Region.Framework.Scenes
1757 /// <summary> 1761 /// <summary>
1758 /// Loads the World's objects 1762 /// Loads the World's objects
1759 /// </summary> 1763 /// </summary>
1764 /// <param name="regionID"></param>
1760 public virtual void LoadPrimsFromStorage(UUID regionID) 1765 public virtual void LoadPrimsFromStorage(UUID regionID)
1761 { 1766 {
1762 LoadingPrims = true; 1767 LoadingPrims = true;
@@ -1769,20 +1774,13 @@ namespace OpenSim.Region.Framework.Scenes
1769 foreach (SceneObjectGroup group in PrimsFromDB) 1774 foreach (SceneObjectGroup group in PrimsFromDB)
1770 { 1775 {
1771 EventManager.TriggerOnSceneObjectLoaded(group); 1776 EventManager.TriggerOnSceneObjectLoaded(group);
1772
1773 if (group.RootPart == null)
1774 {
1775 m_log.ErrorFormat(
1776 "[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children",
1777 group.Parts == null ? 0 : group.PrimCount);
1778 }
1779
1780 AddRestoredSceneObject(group, true, true); 1777 AddRestoredSceneObject(group, true, true);
1781 SceneObjectPart rootPart = group.GetChildPart(group.UUID); 1778 SceneObjectPart rootPart = group.GetChildPart(group.UUID);
1782 rootPart.Flags &= ~PrimFlags.Scripted; 1779 rootPart.Flags &= ~PrimFlags.Scripted;
1783 rootPart.TrimPermissions(); 1780 rootPart.TrimPermissions();
1784 group.CheckSculptAndLoad(); 1781
1785 //rootPart.DoPhysicsPropertyUpdate(UsePhysics, true); 1782 // Don't do this here - it will get done later on when sculpt data is loaded.
1783// group.CheckSculptAndLoad();
1786 } 1784 }
1787 1785
1788 m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)"); 1786 m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)");
@@ -2643,10 +2641,11 @@ namespace OpenSim.Region.Framework.Scenes
2643 #region Add/Remove Avatar Methods 2641 #region Add/Remove Avatar Methods
2644 2642
2645 /// <summary> 2643 /// <summary>
2646 /// Adding a New Client and Create a Presence for it. 2644 /// Add a new client and create a child agent for it.
2647 /// </summary> 2645 /// </summary>
2648 /// <param name="client"></param> 2646 /// <param name="client"></param>
2649 public override void AddNewClient(IClientAPI client) 2647 /// <param name="type">The type of agent to add.</param>
2648 public override void AddNewClient(IClientAPI client, PresenceType type)
2650 { 2649 {
2651 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode); 2650 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode);
2652 bool vialogin = false; 2651 bool vialogin = false;
@@ -2667,7 +2666,7 @@ namespace OpenSim.Region.Framework.Scenes
2667 m_clientManager.Add(client); 2666 m_clientManager.Add(client);
2668 SubscribeToClientEvents(client); 2667 SubscribeToClientEvents(client);
2669 2668
2670 ScenePresence sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance); 2669 ScenePresence sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
2671 m_eventManager.TriggerOnNewPresence(sp); 2670 m_eventManager.TriggerOnNewPresence(sp);
2672 2671
2673 sp.TeleportFlags = (TeleportFlags)aCircuit.teleportFlags; 2672 sp.TeleportFlags = (TeleportFlags)aCircuit.teleportFlags;
@@ -2678,16 +2677,17 @@ namespace OpenSim.Region.Framework.Scenes
2678 if (aCircuit.child == false) 2677 if (aCircuit.child == false)
2679 { 2678 {
2680 sp.IsChildAgent = false; 2679 sp.IsChildAgent = false;
2681 Util.FireAndForget(delegate(object o) { sp.RezAttachments(); }); 2680 Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); });
2682 } 2681 }
2683 } 2682 }
2684 2683
2685 if (TryGetScenePresence(client.AgentId, out presence)) 2684 ScenePresence createdSp = GetScenePresence(client.AgentId);
2685 if (createdSp != null)
2686 { 2686 {
2687 m_LastLogin = Util.EnvironmentTickCount(); 2687 m_LastLogin = Util.EnvironmentTickCount();
2688 2688
2689 // Cache the user's name 2689 // Cache the user's name
2690 CacheUserName(aCircuit); 2690 CacheUserName(createdSp, aCircuit);
2691 2691
2692 EventManager.TriggerOnNewClient(client); 2692 EventManager.TriggerOnNewClient(client);
2693 if (vialogin) 2693 if (vialogin)
@@ -2702,28 +2702,41 @@ namespace OpenSim.Region.Framework.Scenes
2702 } 2702 }
2703 } 2703 }
2704 2704
2705 private void CacheUserName(AgentCircuitData aCircuit) 2705 /// <summary>
2706 /// Cache the user name for later use.
2707 /// </summary>
2708 /// <param name="sp"></param>
2709 /// <param name="aCircuit"></param>
2710 private void CacheUserName(ScenePresence sp, AgentCircuitData aCircuit)
2706 { 2711 {
2707 IUserManagement uMan = RequestModuleInterface<IUserManagement>(); 2712 IUserManagement uMan = RequestModuleInterface<IUserManagement>();
2708 if (uMan != null) 2713 if (uMan != null)
2709 { 2714 {
2710 string homeURL = string.Empty;
2711 string first = aCircuit.firstname, last = aCircuit.lastname; 2715 string first = aCircuit.firstname, last = aCircuit.lastname;
2712 2716
2713 if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) 2717 if (sp.PresenceType == PresenceType.Npc)
2714 homeURL = aCircuit.ServiceURLs["HomeURI"].ToString(); 2718 {
2715 2719 uMan.AddUser(aCircuit.AgentID, first, last);
2716 if (aCircuit.lastname.StartsWith("@")) 2720 }
2721 else
2717 { 2722 {
2718 string[] parts = aCircuit.firstname.Split('.'); 2723 string homeURL = string.Empty;
2719 if (parts.Length >= 2) 2724
2725 if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
2726 homeURL = aCircuit.ServiceURLs["HomeURI"].ToString();
2727
2728 if (aCircuit.lastname.StartsWith("@"))
2720 { 2729 {
2721 first = parts[0]; 2730 string[] parts = aCircuit.firstname.Split('.');
2722 last = parts[1]; 2731 if (parts.Length >= 2)
2732 {
2733 first = parts[0];
2734 last = parts[1];
2735 }
2723 } 2736 }
2724 }
2725 2737
2726 uMan.AddUser(aCircuit.AgentID, first, last, homeURL); 2738 uMan.AddUser(aCircuit.AgentID, first, last, homeURL);
2739 }
2727 } 2740 }
2728 } 2741 }
2729 2742
@@ -2821,12 +2834,14 @@ namespace OpenSim.Region.Framework.Scenes
2821 2834
2822 public virtual void SubscribeToClientPrimEvents(IClientAPI client) 2835 public virtual void SubscribeToClientPrimEvents(IClientAPI client)
2823 { 2836 {
2824 client.OnUpdatePrimGroupPosition += m_sceneGraph.UpdatePrimPosition; 2837 client.OnUpdatePrimGroupPosition += m_sceneGraph.UpdatePrimGroupPosition;
2825 client.OnUpdatePrimSinglePosition += m_sceneGraph.UpdatePrimSinglePosition; 2838 client.OnUpdatePrimSinglePosition += m_sceneGraph.UpdatePrimSinglePosition;
2826 client.OnUpdatePrimGroupRotation += m_sceneGraph.UpdatePrimRotation; 2839
2827 client.OnUpdatePrimGroupMouseRotation += m_sceneGraph.UpdatePrimRotation; 2840 client.OnUpdatePrimGroupRotation += m_sceneGraph.UpdatePrimGroupRotation;
2841 client.OnUpdatePrimGroupMouseRotation += m_sceneGraph.UpdatePrimGroupRotation;
2828 client.OnUpdatePrimSingleRotation += m_sceneGraph.UpdatePrimSingleRotation; 2842 client.OnUpdatePrimSingleRotation += m_sceneGraph.UpdatePrimSingleRotation;
2829 client.OnUpdatePrimSingleRotationPosition += m_sceneGraph.UpdatePrimSingleRotationPosition; 2843 client.OnUpdatePrimSingleRotationPosition += m_sceneGraph.UpdatePrimSingleRotationPosition;
2844
2830 client.OnUpdatePrimScale += m_sceneGraph.UpdatePrimScale; 2845 client.OnUpdatePrimScale += m_sceneGraph.UpdatePrimScale;
2831 client.OnUpdatePrimGroupScale += m_sceneGraph.UpdatePrimGroupScale; 2846 client.OnUpdatePrimGroupScale += m_sceneGraph.UpdatePrimGroupScale;
2832 client.OnUpdateExtraParams += m_sceneGraph.UpdateExtraParam; 2847 client.OnUpdateExtraParams += m_sceneGraph.UpdateExtraParam;
@@ -2856,7 +2871,6 @@ namespace OpenSim.Region.Framework.Scenes
2856 client.OnUndo += m_sceneGraph.HandleUndo; 2871 client.OnUndo += m_sceneGraph.HandleUndo;
2857 client.OnRedo += m_sceneGraph.HandleRedo; 2872 client.OnRedo += m_sceneGraph.HandleRedo;
2858 client.OnObjectDescription += m_sceneGraph.PrimDescription; 2873 client.OnObjectDescription += m_sceneGraph.PrimDescription;
2859 client.OnObjectDrop += m_sceneGraph.DropObject;
2860 client.OnObjectIncludeInSearch += m_sceneGraph.MakeObjectSearchable; 2874 client.OnObjectIncludeInSearch += m_sceneGraph.MakeObjectSearchable;
2861 client.OnObjectOwner += ObjectOwner; 2875 client.OnObjectOwner += ObjectOwner;
2862 } 2876 }
@@ -2949,12 +2963,14 @@ namespace OpenSim.Region.Framework.Scenes
2949 2963
2950 public virtual void UnSubscribeToClientPrimEvents(IClientAPI client) 2964 public virtual void UnSubscribeToClientPrimEvents(IClientAPI client)
2951 { 2965 {
2952 client.OnUpdatePrimGroupPosition -= m_sceneGraph.UpdatePrimPosition; 2966 client.OnUpdatePrimGroupPosition -= m_sceneGraph.UpdatePrimGroupPosition;
2953 client.OnUpdatePrimSinglePosition -= m_sceneGraph.UpdatePrimSinglePosition; 2967 client.OnUpdatePrimSinglePosition -= m_sceneGraph.UpdatePrimSinglePosition;
2954 client.OnUpdatePrimGroupRotation -= m_sceneGraph.UpdatePrimRotation; 2968
2955 client.OnUpdatePrimGroupMouseRotation -= m_sceneGraph.UpdatePrimRotation; 2969 client.OnUpdatePrimGroupRotation -= m_sceneGraph.UpdatePrimGroupRotation;
2970 client.OnUpdatePrimGroupMouseRotation -= m_sceneGraph.UpdatePrimGroupRotation;
2956 client.OnUpdatePrimSingleRotation -= m_sceneGraph.UpdatePrimSingleRotation; 2971 client.OnUpdatePrimSingleRotation -= m_sceneGraph.UpdatePrimSingleRotation;
2957 client.OnUpdatePrimSingleRotationPosition -= m_sceneGraph.UpdatePrimSingleRotationPosition; 2972 client.OnUpdatePrimSingleRotationPosition -= m_sceneGraph.UpdatePrimSingleRotationPosition;
2973
2958 client.OnUpdatePrimScale -= m_sceneGraph.UpdatePrimScale; 2974 client.OnUpdatePrimScale -= m_sceneGraph.UpdatePrimScale;
2959 client.OnUpdatePrimGroupScale -= m_sceneGraph.UpdatePrimGroupScale; 2975 client.OnUpdatePrimGroupScale -= m_sceneGraph.UpdatePrimGroupScale;
2960 client.OnUpdateExtraParams -= m_sceneGraph.UpdateExtraParam; 2976 client.OnUpdateExtraParams -= m_sceneGraph.UpdateExtraParam;
@@ -2982,7 +2998,6 @@ namespace OpenSim.Region.Framework.Scenes
2982 client.OnUndo -= m_sceneGraph.HandleUndo; 2998 client.OnUndo -= m_sceneGraph.HandleUndo;
2983 client.OnRedo -= m_sceneGraph.HandleRedo; 2999 client.OnRedo -= m_sceneGraph.HandleRedo;
2984 client.OnObjectDescription -= m_sceneGraph.PrimDescription; 3000 client.OnObjectDescription -= m_sceneGraph.PrimDescription;
2985 client.OnObjectDrop -= m_sceneGraph.DropObject;
2986 client.OnObjectIncludeInSearch -= m_sceneGraph.MakeObjectSearchable; 3001 client.OnObjectIncludeInSearch -= m_sceneGraph.MakeObjectSearchable;
2987 client.OnObjectOwner -= ObjectOwner; 3002 client.OnObjectOwner -= ObjectOwner;
2988 } 3003 }
@@ -3098,58 +3113,51 @@ namespace OpenSim.Region.Framework.Scenes
3098 Vector3 AXOrigin = new Vector3(RayStart.X, RayStart.Y, RayStart.Z); 3113 Vector3 AXOrigin = new Vector3(RayStart.X, RayStart.Y, RayStart.Z);
3099 Vector3 AXdirection = new Vector3(direction.X, direction.Y, direction.Z); 3114 Vector3 AXdirection = new Vector3(direction.X, direction.Y, direction.Z);
3100 3115
3101 if (target2.ParentGroup != null) 3116 pos = target2.AbsolutePosition;
3102 { 3117 //m_log.Info("[OBJECT_REZ]: TargetPos: " + pos.ToString() + ", RayStart: " + RayStart.ToString() + ", RayEnd: " + RayEnd.ToString() + ", Volume: " + Util.GetDistanceTo(RayStart,RayEnd).ToString() + ", mag1: " + Util.GetMagnitude(RayStart).ToString() + ", mag2: " + Util.GetMagnitude(RayEnd).ToString());
3103 pos = target2.AbsolutePosition;
3104 //m_log.Info("[OBJECT_REZ]: TargetPos: " + pos.ToString() + ", RayStart: " + RayStart.ToString() + ", RayEnd: " + RayEnd.ToString() + ", Volume: " + Util.GetDistanceTo(RayStart,RayEnd).ToString() + ", mag1: " + Util.GetMagnitude(RayStart).ToString() + ", mag2: " + Util.GetMagnitude(RayEnd).ToString());
3105 3118
3106 // TODO: Raytrace better here 3119 // TODO: Raytrace better here
3107 3120
3108 //EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection)); 3121 //EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection));
3109 Ray NewRay = new Ray(AXOrigin, AXdirection); 3122 Ray NewRay = new Ray(AXOrigin, AXdirection);
3110 3123
3111 // Ray Trace against target here 3124 // Ray Trace against target here
3112 EntityIntersection ei = target2.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, CopyCenters); 3125 EntityIntersection ei = target2.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, CopyCenters);
3113 3126
3114 // Un-comment out the following line to Get Raytrace results printed to the console. 3127 // Un-comment out the following line to Get Raytrace results printed to the console.
3115 //m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); 3128 //m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
3116 float ScaleOffset = 0.5f; 3129 float ScaleOffset = 0.5f;
3117 3130
3118 // If we hit something 3131 // If we hit something
3119 if (ei.HitTF) 3132 if (ei.HitTF)
3120 { 3133 {
3121 Vector3 scale = target.Scale; 3134 Vector3 scale = target.Scale;
3122 Vector3 scaleComponent = new Vector3(ei.AAfaceNormal.X, ei.AAfaceNormal.Y, ei.AAfaceNormal.Z); 3135 Vector3 scaleComponent = new Vector3(ei.AAfaceNormal.X, ei.AAfaceNormal.Y, ei.AAfaceNormal.Z);
3123 if (scaleComponent.X != 0) ScaleOffset = scale.X; 3136 if (scaleComponent.X != 0) ScaleOffset = scale.X;
3124 if (scaleComponent.Y != 0) ScaleOffset = scale.Y; 3137 if (scaleComponent.Y != 0) ScaleOffset = scale.Y;
3125 if (scaleComponent.Z != 0) ScaleOffset = scale.Z; 3138 if (scaleComponent.Z != 0) ScaleOffset = scale.Z;
3126 ScaleOffset = Math.Abs(ScaleOffset); 3139 ScaleOffset = Math.Abs(ScaleOffset);
3127 Vector3 intersectionpoint = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z); 3140 Vector3 intersectionpoint = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z);
3128 Vector3 normal = new Vector3(ei.normal.X, ei.normal.Y, ei.normal.Z); 3141 Vector3 normal = new Vector3(ei.normal.X, ei.normal.Y, ei.normal.Z);
3129 Vector3 offset = normal * (ScaleOffset / 2f); 3142 Vector3 offset = normal * (ScaleOffset / 2f);
3130 pos = intersectionpoint + offset; 3143 pos = intersectionpoint + offset;
3131 3144
3132 // stick in offset format from the original prim 3145 // stick in offset format from the original prim
3133 pos = pos - target.ParentGroup.AbsolutePosition; 3146 pos = pos - target.ParentGroup.AbsolutePosition;
3134 if (CopyRotates) 3147 if (CopyRotates)
3135 { 3148 {
3136 Quaternion worldRot = target2.GetWorldRotation(); 3149 Quaternion worldRot = target2.GetWorldRotation();
3137 3150
3138 // SceneObjectGroup obj = m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot); 3151 // SceneObjectGroup obj = m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot);
3139 m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot); 3152 m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot);
3140 //obj.Rotation = worldRot; 3153 //obj.Rotation = worldRot;
3141 //obj.UpdateGroupRotationR(worldRot); 3154 //obj.UpdateGroupRotationR(worldRot);
3142 } 3155 }
3143 else 3156 else
3144 { 3157 {
3145 m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID); 3158 m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID);
3146 }
3147 } 3159 }
3148
3149 return;
3150 } 3160 }
3151
3152 return;
3153 } 3161 }
3154 } 3162 }
3155 3163
@@ -3192,7 +3200,7 @@ namespace OpenSim.Region.Framework.Scenes
3192 if (aCircuit == null) 3200 if (aCircuit == null)
3193 { 3201 {
3194 m_log.DebugFormat("[APPEARANCE] Client did not supply a circuit. Non-Linden? Creating default appearance."); 3202 m_log.DebugFormat("[APPEARANCE] Client did not supply a circuit. Non-Linden? Creating default appearance.");
3195 appearance = new AvatarAppearance(client.AgentId); 3203 appearance = new AvatarAppearance();
3196 return; 3204 return;
3197 } 3205 }
3198 3206
@@ -3200,15 +3208,11 @@ namespace OpenSim.Region.Framework.Scenes
3200 if (appearance == null) 3208 if (appearance == null)
3201 { 3209 {
3202 m_log.DebugFormat("[APPEARANCE]: Appearance not found in {0}, returning default", RegionInfo.RegionName); 3210 m_log.DebugFormat("[APPEARANCE]: Appearance not found in {0}, returning default", RegionInfo.RegionName);
3203 appearance = new AvatarAppearance(client.AgentId); 3211 appearance = new AvatarAppearance();
3204 } 3212 }
3205 } 3213 }
3206 3214
3207 /// <summary> 3215 public override void RemoveClient(UUID agentID, bool closeChildAgents)
3208 /// Remove the given client from the scene.
3209 /// </summary>
3210 /// <param name="agentID"></param>
3211 public override void RemoveClient(UUID agentID)
3212 { 3216 {
3213 CheckHeartbeat(); 3217 CheckHeartbeat();
3214 bool childagentYN = false; 3218 bool childagentYN = false;
@@ -3229,15 +3233,17 @@ namespace OpenSim.Region.Framework.Scenes
3229 (childagentYN ? "child" : "root"), agentID, RegionInfo.RegionName); 3233 (childagentYN ? "child" : "root"), agentID, RegionInfo.RegionName);
3230 3234
3231 m_sceneGraph.removeUserCount(!childagentYN); 3235 m_sceneGraph.removeUserCount(!childagentYN);
3232 3236
3233 if (CapsModule != null) 3237 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop
3238 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI
3239 if (closeChildAgents && CapsModule != null)
3234 CapsModule.RemoveCaps(agentID); 3240 CapsModule.RemoveCaps(agentID);
3235 3241
3236 // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever 3242 // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
3237 // this method is doing is HORRIBLE!!! 3243 // this method is doing is HORRIBLE!!!
3238 avatar.Scene.NeedSceneCacheClear(avatar.UUID); 3244 avatar.Scene.NeedSceneCacheClear(avatar.UUID);
3239 3245
3240 if (!avatar.IsChildAgent) 3246 if (closeChildAgents && !avatar.IsChildAgent)
3241 { 3247 {
3242 //List<ulong> childknownRegions = new List<ulong>(); 3248 //List<ulong> childknownRegions = new List<ulong>();
3243 //List<ulong> ckn = avatar.KnownChildRegionHandles; 3249 //List<ulong> ckn = avatar.KnownChildRegionHandles;
@@ -3263,8 +3269,8 @@ namespace OpenSim.Region.Framework.Scenes
3263 m_eventManager.TriggerOnRemovePresence(agentID); 3269 m_eventManager.TriggerOnRemovePresence(agentID);
3264 m_log.Debug("[Scene] Finished OnRemovePresence"); 3270 m_log.Debug("[Scene] Finished OnRemovePresence");
3265 3271
3266 if (avatar != null && (!avatar.IsChildAgent)) 3272 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
3267 avatar.SaveChangedAttachments(); 3273 AttachmentsModule.SaveChangedAttachments(avatar);
3268 3274
3269 if (avatar != null && (!avatar.IsChildAgent)) 3275 if (avatar != null && (!avatar.IsChildAgent))
3270 avatar.SaveChangedAttachments(); 3276 avatar.SaveChangedAttachments();
@@ -3304,7 +3310,7 @@ namespace OpenSim.Region.Framework.Scenes
3304 } 3310 }
3305 m_log.Debug("[Scene] Done. Firing RemoveCircuit"); 3311 m_log.Debug("[Scene] Done. Firing RemoveCircuit");
3306 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); 3312 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode);
3307 CleanDroppedAttachments(); 3313// CleanDroppedAttachments();
3308 m_log.Debug("[Scene] The avatar has left the building"); 3314 m_log.Debug("[Scene] The avatar has left the building");
3309 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 3315 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
3310 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); 3316 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
@@ -3540,7 +3546,7 @@ namespace OpenSim.Region.Framework.Scenes
3540 3546
3541 if (vialogin) 3547 if (vialogin)
3542 { 3548 {
3543 CleanDroppedAttachments(); 3549// CleanDroppedAttachments();
3544 3550
3545 if (TestBorderCross(agent.startpos, Cardinals.E)) 3551 if (TestBorderCross(agent.startpos, Cardinals.E))
3546 { 3552 {
@@ -3699,11 +3705,12 @@ namespace OpenSim.Region.Framework.Scenes
3699 3705
3700 if (AuthorizationService != null) 3706 if (AuthorizationService != null)
3701 { 3707 {
3702 if (!AuthorizationService.IsAuthorizedForRegion(agentID.ToString(), RegionInfo.RegionID.ToString(),out reason)) 3708 if (!AuthorizationService.IsAuthorizedForRegion(
3709 agent.AgentID.ToString(), agent.firstname, agent.lastname, RegionInfo.RegionID.ToString(), out reason))
3703 { 3710 {
3704 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} at {1} because the user does not have access to the region", 3711 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} at {1} because the user does not have access to the region",
3705 agentID, RegionInfo.RegionName); 3712 agentID, RegionInfo.RegionName);
3706 //reason = String.Format("You are not currently on the access list for {0}",RegionInfo.RegionName); 3713
3707 return false; 3714 return false;
3708 } 3715 }
3709 } 3716 }
@@ -4033,8 +4040,11 @@ namespace OpenSim.Region.Framework.Scenes
4033 } 4040 }
4034 4041
4035 /// <summary> 4042 /// <summary>
4036 /// Tries to teleport agent to other region. 4043 /// Tries to teleport agent to another region.
4037 /// </summary> 4044 /// </summary>
4045 /// <remarks>
4046 /// The region name must exactly match that given.
4047 /// </remarks>
4038 /// <param name="remoteClient"></param> 4048 /// <param name="remoteClient"></param>
4039 /// <param name="regionName"></param> 4049 /// <param name="regionName"></param>
4040 /// <param name="position"></param> 4050 /// <param name="position"></param>
@@ -4043,15 +4053,16 @@ namespace OpenSim.Region.Framework.Scenes
4043 public void RequestTeleportLocation(IClientAPI remoteClient, string regionName, Vector3 position, 4053 public void RequestTeleportLocation(IClientAPI remoteClient, string regionName, Vector3 position,
4044 Vector3 lookat, uint teleportFlags) 4054 Vector3 lookat, uint teleportFlags)
4045 { 4055 {
4046 List<GridRegion> regions = GridService.GetRegionsByName(RegionInfo.ScopeID, regionName, 1); 4056 GridRegion region = GridService.GetRegionByName(RegionInfo.ScopeID, regionName);
4047 if (regions == null || regions.Count == 0) 4057
4058 if (region == null)
4048 { 4059 {
4049 // can't find the region: Tell viewer and abort 4060 // can't find the region: Tell viewer and abort
4050 remoteClient.SendTeleportFailed("The region '" + regionName + "' could not be found."); 4061 remoteClient.SendTeleportFailed("The region '" + regionName + "' could not be found.");
4051 return; 4062 return;
4052 } 4063 }
4053 4064
4054 RequestTeleportLocation(remoteClient, regions[0].RegionHandle, position, lookat, teleportFlags); 4065 RequestTeleportLocation(remoteClient, region.RegionHandle, position, lookat, teleportFlags);
4055 } 4066 }
4056 4067
4057 /// <summary> 4068 /// <summary>
@@ -4353,7 +4364,7 @@ namespace OpenSim.Region.Framework.Scenes
4353 // their scripts will actually run. 4364 // their scripts will actually run.
4354 // -- Leaf, Tue Aug 12 14:17:05 EDT 2008 4365 // -- Leaf, Tue Aug 12 14:17:05 EDT 2008
4355 SceneObjectPart parent = part.ParentGroup.RootPart; 4366 SceneObjectPart parent = part.ParentGroup.RootPart;
4356 if (parent != null && parent.IsAttachment) 4367 if (part.ParentGroup.IsAttachment)
4357 return ScriptDanger(parent, parent.GetWorldPosition()); 4368 return ScriptDanger(parent, parent.GetWorldPosition());
4358 else 4369 else
4359 return ScriptDanger(part, part.GetWorldPosition()); 4370 return ScriptDanger(part, part.GetWorldPosition());
@@ -5122,11 +5133,19 @@ namespace OpenSim.Region.Framework.Scenes
5122 5133
5123 private void HandleDeleteObject(string module, string[] cmd) 5134 private void HandleDeleteObject(string module, string[] cmd)
5124 { 5135 {
5125 if (cmd.Length < 4) 5136 if (cmd.Length < 3)
5126 return; 5137 return;
5127 5138
5128 string mode = cmd[2]; 5139 string mode = cmd[2];
5129 string o = cmd[3]; 5140 string o = "";
5141
5142 if (mode != "outside")
5143 {
5144 if (cmd.Length < 4)
5145 return;
5146
5147 o = cmd[3];
5148 }
5130 5149
5131 List<SceneObjectGroup> deletes = new List<SceneObjectGroup>(); 5150 List<SceneObjectGroup> deletes = new List<SceneObjectGroup>();
5132 5151
@@ -5168,10 +5187,35 @@ namespace OpenSim.Region.Framework.Scenes
5168 deletes.Add(g); 5187 deletes.Add(g);
5169 }); 5188 });
5170 break; 5189 break;
5190 case "outside":
5191 ForEachSOG(delegate (SceneObjectGroup g)
5192 {
5193 SceneObjectPart rootPart = g.RootPart;
5194 bool delete = false;
5195
5196 if (rootPart.GroupPosition.Z < 0.0 || rootPart.GroupPosition.Z > 10000.0)
5197 {
5198 delete = true;
5199 }
5200 else
5201 {
5202 ILandObject parcel = LandChannel.GetLandObject(rootPart.GroupPosition.X, rootPart.GroupPosition.Y);
5203
5204 if (parcel == null || parcel.LandData.Name == "NO LAND")
5205 delete = true;
5206 }
5207
5208 if (delete && !g.IsAttachment && !deletes.Contains(g))
5209 deletes.Add(g);
5210 });
5211 break;
5171 } 5212 }
5172 5213
5173 foreach (SceneObjectGroup g in deletes) 5214 foreach (SceneObjectGroup g in deletes)
5215 {
5216 m_log.InfoFormat("[SCENE]: Deleting object {0}", g.UUID);
5174 DeleteSceneObject(g, false); 5217 DeleteSceneObject(g, false);
5218 }
5175 } 5219 }
5176 5220
5177 private void HandleReloadEstate(string module, string[] cmd) 5221 private void HandleReloadEstate(string module, string[] cmd)
@@ -5268,10 +5312,40 @@ namespace OpenSim.Region.Framework.Scenes
5268 } 5312 }
5269 } 5313 }
5270 5314
5271 public void CleanDroppedAttachments() 5315// public void CleanDroppedAttachments()
5272 { 5316// {
5273 List<SceneObjectGroup> objectsToDelete = 5317// List<SceneObjectGroup> objectsToDelete =
5274 new List<SceneObjectGroup>(); 5318// new List<SceneObjectGroup>();
5319//
5320// lock (m_cleaningAttachments)
5321// {
5322// ForEachSOG(delegate (SceneObjectGroup grp)
5323// {
5324// if (grp.RootPart.Shape.PCode == 0 && grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp)))
5325// {
5326// UUID agentID = grp.OwnerID;
5327// if (agentID == UUID.Zero)
5328// {
5329// objectsToDelete.Add(grp);
5330// return;
5331// }
5332//
5333// ScenePresence sp = GetScenePresence(agentID);
5334// if (sp == null)
5335// {
5336// objectsToDelete.Add(grp);
5337// return;
5338// }
5339// }
5340// });
5341// }
5342//
5343// foreach (SceneObjectGroup grp in objectsToDelete)
5344// {
5345// m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID);
5346// DeleteSceneObject(grp, true);
5347// }
5348// }
5275 5349
5276 lock (m_cleaningAttachments) 5350 lock (m_cleaningAttachments)
5277 { 5351 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs
index f343bc8..bf861b8 100644
--- a/OpenSim/Region/Framework/Scenes/SceneBase.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs
@@ -177,18 +177,8 @@ namespace OpenSim.Region.Framework.Scenes
177 177
178 #region Add/Remove Agent/Avatar 178 #region Add/Remove Agent/Avatar
179 179
180 /// <summary> 180 public abstract void AddNewClient(IClientAPI client, PresenceType type);
181 /// Register the new client with the scene. The client starts off as a child agent - the later agent crossing 181 public abstract void RemoveClient(UUID agentID, bool closeChildAgents);
182 /// will promote it to a root agent during login.
183 /// </summary>
184 /// <param name="client"></param
185 public abstract void AddNewClient(IClientAPI client);
186
187 /// <summary>
188 /// Remove a client from the scene
189 /// </summary>
190 /// <param name="agentID"></param>
191 public abstract void RemoveClient(UUID agentID);
192 182
193 public bool TryGetScenePresence(UUID agentID, out object scenePresence) 183 public bool TryGetScenePresence(UUID agentID, out object scenePresence)
194 { 184 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 39d4a29..29edf13 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -403,7 +403,7 @@ namespace OpenSim.Region.Framework.Scenes
403 /// </returns> 403 /// </returns>
404 protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) 404 protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
405 { 405 {
406 if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero) 406 if (sceneObject == null || sceneObject.RootPart.UUID == UUID.Zero)
407 return false; 407 return false;
408 408
409 if (Entities.ContainsKey(sceneObject.UUID)) 409 if (Entities.ContainsKey(sceneObject.UUID))
@@ -613,13 +613,6 @@ namespace OpenSim.Region.Framework.Scenes
613 m_activeScripts += number; 613 m_activeScripts += number;
614 } 614 }
615 615
616 public void DropObject(uint objectLocalID, IClientAPI remoteClient)
617 {
618 SceneObjectGroup group = GetGroupByPrim(objectLocalID);
619 if (group != null)
620 m_parentScene.AttachmentsModule.DetachSingleAttachmentToGround(group.UUID, remoteClient);
621 }
622
623 protected internal void HandleUndo(IClientAPI remoteClient, UUID primId) 616 protected internal void HandleUndo(IClientAPI remoteClient, UUID primId)
624 { 617 {
625 if (primId != UUID.Zero) 618 if (primId != UUID.Zero)
@@ -629,11 +622,13 @@ namespace OpenSim.Region.Framework.Scenes
629 part.Undo(); 622 part.Undo();
630 } 623 }
631 } 624 }
625
632 protected internal void HandleRedo(IClientAPI remoteClient, UUID primId) 626 protected internal void HandleRedo(IClientAPI remoteClient, UUID primId)
633 { 627 {
634 if (primId != UUID.Zero) 628 if (primId != UUID.Zero)
635 { 629 {
636 SceneObjectPart part = m_parentScene.GetSceneObjectPart(primId); 630 SceneObjectPart part = m_parentScene.GetSceneObjectPart(primId);
631
637 if (part != null) 632 if (part != null)
638 part.Redo(); 633 part.Redo();
639 } 634 }
@@ -653,12 +648,13 @@ namespace OpenSim.Region.Framework.Scenes
653 } 648 }
654 } 649 }
655 650
656 protected internal ScenePresence CreateAndAddChildScenePresence(IClientAPI client, AvatarAppearance appearance) 651 protected internal ScenePresence CreateAndAddChildScenePresence(
652 IClientAPI client, AvatarAppearance appearance, PresenceType type)
657 { 653 {
658 ScenePresence newAvatar = null; 654 ScenePresence newAvatar = null;
659 655
660 // ScenePresence always defaults to child agent 656 // ScenePresence always defaults to child agent
661 newAvatar = new ScenePresence(client, m_parentScene, m_regInfo, appearance); 657 newAvatar = new ScenePresence(client, m_parentScene, m_regInfo, appearance, type);
662 658
663 AddScenePresence(newAvatar); 659 AddScenePresence(newAvatar);
664 660
@@ -1285,19 +1281,20 @@ namespace OpenSim.Region.Framework.Scenes
1285 #region Client Event handlers 1281 #region Client Event handlers
1286 1282
1287 /// <summary> 1283 /// <summary>
1288 /// 1284 /// Update the scale of an individual prim.
1289 /// </summary> 1285 /// </summary>
1290 /// <param name="localID"></param> 1286 /// <param name="localID"></param>
1291 /// <param name="scale"></param> 1287 /// <param name="scale"></param>
1292 /// <param name="remoteClient"></param> 1288 /// <param name="remoteClient"></param>
1293 protected internal void UpdatePrimScale(uint localID, Vector3 scale, IClientAPI remoteClient) 1289 protected internal void UpdatePrimScale(uint localID, Vector3 scale, IClientAPI remoteClient)
1294 { 1290 {
1295 SceneObjectGroup group = GetGroupByPrim(localID); 1291 SceneObjectPart part = GetSceneObjectPart(localID);
1296 if (group != null) 1292
1293 if (part != null)
1297 { 1294 {
1298 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) 1295 if (m_parentScene.Permissions.CanEditObject(part.ParentGroup.UUID, remoteClient.AgentId))
1299 { 1296 {
1300 group.Resize(scale, localID); 1297 part.Resize(scale);
1301 } 1298 }
1302 } 1299 }
1303 } 1300 }
@@ -1309,7 +1306,7 @@ namespace OpenSim.Region.Framework.Scenes
1309 { 1306 {
1310 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) 1307 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId))
1311 { 1308 {
1312 group.GroupResize(scale, localID); 1309 group.GroupResize(scale);
1313 } 1310 }
1314 } 1311 }
1315 } 1312 }
@@ -1363,19 +1360,18 @@ namespace OpenSim.Region.Framework.Scenes
1363 { 1360 {
1364 if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.AgentId)) 1361 if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.AgentId))
1365 { 1362 {
1366 group.UpdateSingleRotation(rot,pos, localID); 1363 group.UpdateSingleRotation(rot, pos, localID);
1367 } 1364 }
1368 } 1365 }
1369 } 1366 }
1370 1367
1371
1372 /// <summary> 1368 /// <summary>
1373 /// 1369 /// Update the rotation of a whole group.
1374 /// </summary> 1370 /// </summary>
1375 /// <param name="localID"></param> 1371 /// <param name="localID"></param>
1376 /// <param name="rot"></param> 1372 /// <param name="rot"></param>
1377 /// <param name="remoteClient"></param> 1373 /// <param name="remoteClient"></param>
1378 protected internal void UpdatePrimRotation(uint localID, Quaternion rot, IClientAPI remoteClient) 1374 protected internal void UpdatePrimGroupRotation(uint localID, Quaternion rot, IClientAPI remoteClient)
1379 { 1375 {
1380 SceneObjectGroup group = GetGroupByPrim(localID); 1376 SceneObjectGroup group = GetGroupByPrim(localID);
1381 if (group != null) 1377 if (group != null)
@@ -1394,7 +1390,7 @@ namespace OpenSim.Region.Framework.Scenes
1394 /// <param name="pos"></param> 1390 /// <param name="pos"></param>
1395 /// <param name="rot"></param> 1391 /// <param name="rot"></param>
1396 /// <param name="remoteClient"></param> 1392 /// <param name="remoteClient"></param>
1397 protected internal void UpdatePrimRotation(uint localID, Vector3 pos, Quaternion rot, IClientAPI remoteClient) 1393 protected internal void UpdatePrimGroupRotation(uint localID, Vector3 pos, Quaternion rot, IClientAPI remoteClient)
1398 { 1394 {
1399 SceneObjectGroup group = GetGroupByPrim(localID); 1395 SceneObjectGroup group = GetGroupByPrim(localID);
1400 if (group != null) 1396 if (group != null)
@@ -1425,12 +1421,12 @@ namespace OpenSim.Region.Framework.Scenes
1425 } 1421 }
1426 1422
1427 /// <summary> 1423 /// <summary>
1428 /// Update the position of the given part 1424 /// Update the position of the given group.
1429 /// </summary> 1425 /// </summary>
1430 /// <param name="localID"></param> 1426 /// <param name="localID"></param>
1431 /// <param name="pos"></param> 1427 /// <param name="pos"></param>
1432 /// <param name="remoteClient"></param> 1428 /// <param name="remoteClient"></param>
1433 public void UpdatePrimPosition(uint localID, Vector3 pos, IClientAPI remoteClient) 1429 public void UpdatePrimGroupPosition(uint localID, Vector3 pos, IClientAPI remoteClient)
1434 { 1430 {
1435 SceneObjectGroup group = GetGroupByPrim(localID); 1431 SceneObjectGroup group = GetGroupByPrim(localID);
1436 1432
@@ -1481,21 +1477,26 @@ namespace OpenSim.Region.Framework.Scenes
1481 } 1477 }
1482 1478
1483 /// <summary> 1479 /// <summary>
1484 /// 1480 /// Update the flags on a scene object. This covers properties such as phantom, physics and temporary.
1485 /// </summary> 1481 /// </summary>
1482 /// <remarks>
1483 /// This is currently handling the incoming call from the client stack (e.g. LLClientView).
1484 /// </remarks>
1486 /// <param name="localID"></param> 1485 /// <param name="localID"></param>
1487 /// <param name="packet"></param> 1486 /// <param name="UsePhysics"></param>
1487 /// <param name="SetTemporary"></param>
1488 /// <param name="SetPhantom"></param>
1488 /// <param name="remoteClient"></param> 1489 /// <param name="remoteClient"></param>
1489 /// This routine seems to get called when a user changes object settings in the viewer. 1490 protected internal void UpdatePrimFlags(
1490 /// If some one can confirm that, please change the comment according. 1491 uint localID, bool UsePhysics, bool SetTemporary, bool SetPhantom, IClientAPI remoteClient)
1491 protected internal void UpdatePrimFlags(uint localID, bool UsePhysics, bool IsTemporary, bool IsPhantom, IClientAPI remoteClient)
1492 { 1492 {
1493 SceneObjectGroup group = GetGroupByPrim(localID); 1493 SceneObjectGroup group = GetGroupByPrim(localID);
1494 if (group != null) 1494 if (group != null)
1495 { 1495 {
1496 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) 1496 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId))
1497 { 1497 {
1498 group.UpdatePrimFlags(localID, UsePhysics, IsTemporary, IsPhantom, false); // VolumeDetect can't be set via UI and will always be off when a change is made there 1498 // VolumeDetect can't be set via UI and will always be off when a change is made there
1499 group.UpdatePrimFlags(localID, UsePhysics, SetTemporary, SetPhantom, false);
1499 } 1500 }
1500 } 1501 }
1501 } 1502 }
@@ -1618,8 +1619,11 @@ namespace OpenSim.Region.Framework.Scenes
1618 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) 1619 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId))
1619 { 1620 {
1620 SceneObjectPart part = m_parentScene.GetSceneObjectPart(primLocalID); 1621 SceneObjectPart part = m_parentScene.GetSceneObjectPart(primLocalID);
1621 part.ClickAction = Convert.ToByte(clickAction); 1622 if (part != null)
1622 group.HasGroupChanged = true; 1623 {
1624 part.ClickAction = Convert.ToByte(clickAction);
1625 group.HasGroupChanged = true;
1626 }
1623 } 1627 }
1624 } 1628 }
1625 } 1629 }
@@ -1632,8 +1636,11 @@ namespace OpenSim.Region.Framework.Scenes
1632 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) 1636 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId))
1633 { 1637 {
1634 SceneObjectPart part = m_parentScene.GetSceneObjectPart(primLocalID); 1638 SceneObjectPart part = m_parentScene.GetSceneObjectPart(primLocalID);
1635 part.Material = Convert.ToByte(material); 1639 if (part != null)
1636 group.HasGroupChanged = true; 1640 {
1641 part.Material = Convert.ToByte(material);
1642 group.HasGroupChanged = true;
1643 }
1637 } 1644 }
1638 } 1645 }
1639 } 1646 }
@@ -1706,23 +1713,24 @@ namespace OpenSim.Region.Framework.Scenes
1706 parentGroup.areUpdatesSuspended = true; 1713 parentGroup.areUpdatesSuspended = true;
1707 1714
1708 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); 1715 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
1709 if (parentGroup != null) 1716
1717 // We do this in reverse to get the link order of the prims correct
1718 for (int i = children.Count - 1; i >= 0; i--)
1710 { 1719 {
1711 // We do this in reverse to get the link order of the prims correct 1720 SceneObjectGroup child = children[i].ParentGroup;
1712 for (int i = children.Count - 1; i >= 0; i--)
1713 {
1714 SceneObjectGroup child = children[i].ParentGroup;
1715 1721
1722 // Make sure no child prim is set for sale
1723 // So that, on delink, no prims are unwittingly
1724 // left for sale and sold off
1725
1716 if (child != null) 1726 if (child != null)
1717 { 1727 {
1728 child.RootPart.ObjectSaleType = 0;
1729 child.RootPart.SalePrice = 10;
1718 childGroups.Add(child); 1730 childGroups.Add(child);
1719 } 1731 }
1720 } 1732 }
1721 } 1733 }
1722 else
1723 {
1724 return; // parent is null so not in this region
1725 }
1726 1734
1727 foreach (SceneObjectGroup child in childGroups) 1735 foreach (SceneObjectGroup child in childGroups)
1728 { 1736 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs
index 86ba2aa..7fada4b 100644
--- a/OpenSim/Region/Framework/Scenes/SceneManager.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs
@@ -47,12 +47,18 @@ namespace OpenSim.Region.Framework.Scenes
47 47
48 public event RestartSim OnRestartSim; 48 public event RestartSim OnRestartSim;
49 49
50 private readonly List<Scene> m_localScenes; 50 private static SceneManager m_instance = null;
51 public static SceneManager Instance
52 {
53 get { return m_instance; }
54 }
55
56 private readonly List<Scene> m_localScenes = new List<Scene>();
51 private Scene m_currentScene = null; 57 private Scene m_currentScene = null;
52 58
53 public List<Scene> Scenes 59 public List<Scene> Scenes
54 { 60 {
55 get { return m_localScenes; } 61 get { return new List<Scene>(m_localScenes); }
56 } 62 }
57 63
58 public Scene CurrentScene 64 public Scene CurrentScene
@@ -66,13 +72,12 @@ namespace OpenSim.Region.Framework.Scenes
66 { 72 {
67 if (m_currentScene == null) 73 if (m_currentScene == null)
68 { 74 {
69 if (m_localScenes.Count > 0) 75 lock (m_localScenes)
70 { 76 {
71 return m_localScenes[0]; 77 if (m_localScenes.Count > 0)
72 } 78 return m_localScenes[0];
73 else 79 else
74 { 80 return null;
75 return null;
76 } 81 }
77 } 82 }
78 else 83 else
@@ -84,6 +89,7 @@ namespace OpenSim.Region.Framework.Scenes
84 89
85 public SceneManager() 90 public SceneManager()
86 { 91 {
92 m_instance = this;
87 m_localScenes = new List<Scene>(); 93 m_localScenes = new List<Scene>();
88 } 94 }
89 95
@@ -91,17 +97,21 @@ namespace OpenSim.Region.Framework.Scenes
91 { 97 {
92 // collect known shared modules in sharedModules 98 // collect known shared modules in sharedModules
93 Dictionary<string, IRegionModule> sharedModules = new Dictionary<string, IRegionModule>(); 99 Dictionary<string, IRegionModule> sharedModules = new Dictionary<string, IRegionModule>();
94 for (int i = 0; i < m_localScenes.Count; i++) 100
101 lock (m_localScenes)
95 { 102 {
96 // extract known shared modules from scene 103 for (int i = 0; i < m_localScenes.Count; i++)
97 foreach (string k in m_localScenes[i].Modules.Keys)
98 { 104 {
99 if (m_localScenes[i].Modules[k].IsSharedModule && 105 // extract known shared modules from scene
100 !sharedModules.ContainsKey(k)) 106 foreach (string k in m_localScenes[i].Modules.Keys)
101 sharedModules[k] = m_localScenes[i].Modules[k]; 107 {
108 if (m_localScenes[i].Modules[k].IsSharedModule &&
109 !sharedModules.ContainsKey(k))
110 sharedModules[k] = m_localScenes[i].Modules[k];
111 }
112 // close scene/region
113 m_localScenes[i].Close();
102 } 114 }
103 // close scene/region
104 m_localScenes[i].Close();
105 } 115 }
106 116
107 // all regions/scenes are now closed, we can now safely 117 // all regions/scenes are now closed, we can now safely
@@ -114,13 +124,16 @@ namespace OpenSim.Region.Framework.Scenes
114 124
115 public void Close(Scene cscene) 125 public void Close(Scene cscene)
116 { 126 {
117 if (m_localScenes.Contains(cscene)) 127 lock (m_localScenes)
118 { 128 {
119 for (int i = 0; i < m_localScenes.Count; i++) 129 if (m_localScenes.Contains(cscene))
120 { 130 {
121 if (m_localScenes[i].Equals(cscene)) 131 for (int i = 0; i < m_localScenes.Count; i++)
122 { 132 {
123 m_localScenes[i].Close(); 133 if (m_localScenes[i].Equals(cscene))
134 {
135 m_localScenes[i].Close();
136 }
124 } 137 }
125 } 138 }
126 } 139 }
@@ -129,27 +142,33 @@ namespace OpenSim.Region.Framework.Scenes
129 public void Add(Scene scene) 142 public void Add(Scene scene)
130 { 143 {
131 scene.OnRestart += HandleRestart; 144 scene.OnRestart += HandleRestart;
132 m_localScenes.Add(scene); 145
146 lock (m_localScenes)
147 m_localScenes.Add(scene);
133 } 148 }
134 149
135 public void HandleRestart(RegionInfo rdata) 150 public void HandleRestart(RegionInfo rdata)
136 { 151 {
137 m_log.Error("[SCENEMANAGER]: Got Restart message for region:" + rdata.RegionName + " Sending up to main"); 152 m_log.Error("[SCENEMANAGER]: Got Restart message for region:" + rdata.RegionName + " Sending up to main");
138 int RegionSceneElement = -1; 153 int RegionSceneElement = -1;
139 for (int i = 0; i < m_localScenes.Count; i++) 154
155 lock (m_localScenes)
140 { 156 {
141 if (rdata.RegionName == m_localScenes[i].RegionInfo.RegionName) 157 for (int i = 0; i < m_localScenes.Count; i++)
142 { 158 {
143 RegionSceneElement = i; 159 if (rdata.RegionName == m_localScenes[i].RegionInfo.RegionName)
160 {
161 RegionSceneElement = i;
162 }
144 } 163 }
145 }
146 164
147 // Now we make sure the region is no longer known about by the SceneManager 165 // Now we make sure the region is no longer known about by the SceneManager
148 // Prevents duplicates. 166 // Prevents duplicates.
149 167
150 if (RegionSceneElement >= 0) 168 if (RegionSceneElement >= 0)
151 { 169 {
152 m_localScenes.RemoveAt(RegionSceneElement); 170 m_localScenes.RemoveAt(RegionSceneElement);
171 }
153 } 172 }
154 173
155 // Send signal to main that we're restarting this sim. 174 // Send signal to main that we're restarting this sim.
@@ -160,28 +179,32 @@ namespace OpenSim.Region.Framework.Scenes
160 { 179 {
161 RegionInfo Result = null; 180 RegionInfo Result = null;
162 181
163 for (int i = 0; i < m_localScenes.Count; i++) 182 lock (m_localScenes)
164 {
165 if (m_localScenes[i].RegionInfo.RegionHandle == regionHandle)
166 {
167 // Inform other regions to tell their avatar about me
168 Result = m_localScenes[i].RegionInfo;
169 }
170 }
171 if (Result != null)
172 { 183 {
173 for (int i = 0; i < m_localScenes.Count; i++) 184 for (int i = 0; i < m_localScenes.Count; i++)
174 { 185 {
175 if (m_localScenes[i].RegionInfo.RegionHandle != regionHandle) 186 if (m_localScenes[i].RegionInfo.RegionHandle == regionHandle)
176 { 187 {
177 // Inform other regions to tell their avatar about me 188 // Inform other regions to tell their avatar about me
178 //m_localScenes[i].OtherRegionUp(Result); 189 Result = m_localScenes[i].RegionInfo;
179 } 190 }
180 } 191 }
181 } 192
182 else 193 if (Result != null)
183 { 194 {
184 m_log.Error("[REGION]: Unable to notify Other regions of this Region coming up"); 195 for (int i = 0; i < m_localScenes.Count; i++)
196 {
197 if (m_localScenes[i].RegionInfo.RegionHandle != regionHandle)
198 {
199 // Inform other regions to tell their avatar about me
200 //m_localScenes[i].OtherRegionUp(Result);
201 }
202 }
203 }
204 else
205 {
206 m_log.Error("[REGION]: Unable to notify Other regions of this Region coming up");
207 }
185 } 208 }
186 } 209 }
187 210
@@ -285,7 +308,8 @@ namespace OpenSim.Region.Framework.Scenes
285 { 308 {
286 if (m_currentScene == null) 309 if (m_currentScene == null)
287 { 310 {
288 m_localScenes.ForEach(func); 311 lock (m_localScenes)
312 m_localScenes.ForEach(func);
289 } 313 }
290 else 314 else
291 { 315 {
@@ -314,12 +338,15 @@ namespace OpenSim.Region.Framework.Scenes
314 } 338 }
315 else 339 else
316 { 340 {
317 foreach (Scene scene in m_localScenes) 341 lock (m_localScenes)
318 { 342 {
319 if (String.Compare(scene.RegionInfo.RegionName, regionName, true) == 0) 343 foreach (Scene scene in m_localScenes)
320 { 344 {
321 m_currentScene = scene; 345 if (String.Compare(scene.RegionInfo.RegionName, regionName, true) == 0)
322 return true; 346 {
347 m_currentScene = scene;
348 return true;
349 }
323 } 350 }
324 } 351 }
325 352
@@ -331,12 +358,15 @@ namespace OpenSim.Region.Framework.Scenes
331 { 358 {
332 m_log.Debug("Searching for Region: '" + regionID + "'"); 359 m_log.Debug("Searching for Region: '" + regionID + "'");
333 360
334 foreach (Scene scene in m_localScenes) 361 lock (m_localScenes)
335 { 362 {
336 if (scene.RegionInfo.RegionID == regionID) 363 foreach (Scene scene in m_localScenes)
337 { 364 {
338 m_currentScene = scene; 365 if (scene.RegionInfo.RegionID == regionID)
339 return true; 366 {
367 m_currentScene = scene;
368 return true;
369 }
340 } 370 }
341 } 371 }
342 372
@@ -345,26 +375,33 @@ namespace OpenSim.Region.Framework.Scenes
345 375
346 public bool TryGetScene(string regionName, out Scene scene) 376 public bool TryGetScene(string regionName, out Scene scene)
347 { 377 {
348 foreach (Scene mscene in m_localScenes) 378 lock (m_localScenes)
349 { 379 {
350 if (String.Compare(mscene.RegionInfo.RegionName, regionName, true) == 0) 380 foreach (Scene mscene in m_localScenes)
351 { 381 {
352 scene = mscene; 382 if (String.Compare(mscene.RegionInfo.RegionName, regionName, true) == 0)
353 return true; 383 {
384 scene = mscene;
385 return true;
386 }
354 } 387 }
355 } 388 }
389
356 scene = null; 390 scene = null;
357 return false; 391 return false;
358 } 392 }
359 393
360 public bool TryGetScene(UUID regionID, out Scene scene) 394 public bool TryGetScene(UUID regionID, out Scene scene)
361 { 395 {
362 foreach (Scene mscene in m_localScenes) 396 lock (m_localScenes)
363 { 397 {
364 if (mscene.RegionInfo.RegionID == regionID) 398 foreach (Scene mscene in m_localScenes)
365 { 399 {
366 scene = mscene; 400 if (mscene.RegionInfo.RegionID == regionID)
367 return true; 401 {
402 scene = mscene;
403 return true;
404 }
368 } 405 }
369 } 406 }
370 407
@@ -374,13 +411,16 @@ namespace OpenSim.Region.Framework.Scenes
374 411
375 public bool TryGetScene(uint locX, uint locY, out Scene scene) 412 public bool TryGetScene(uint locX, uint locY, out Scene scene)
376 { 413 {
377 foreach (Scene mscene in m_localScenes) 414 lock (m_localScenes)
378 { 415 {
379 if (mscene.RegionInfo.RegionLocX == locX && 416 foreach (Scene mscene in m_localScenes)
380 mscene.RegionInfo.RegionLocY == locY)
381 { 417 {
382 scene = mscene; 418 if (mscene.RegionInfo.RegionLocX == locX &&
383 return true; 419 mscene.RegionInfo.RegionLocY == locY)
420 {
421 scene = mscene;
422 return true;
423 }
384 } 424 }
385 } 425 }
386 426
@@ -390,13 +430,16 @@ namespace OpenSim.Region.Framework.Scenes
390 430
391 public bool TryGetScene(IPEndPoint ipEndPoint, out Scene scene) 431 public bool TryGetScene(IPEndPoint ipEndPoint, out Scene scene)
392 { 432 {
393 foreach (Scene mscene in m_localScenes) 433 lock (m_localScenes)
394 { 434 {
395 if ((mscene.RegionInfo.InternalEndPoint.Equals(ipEndPoint.Address)) && 435 foreach (Scene mscene in m_localScenes)
396 (mscene.RegionInfo.InternalEndPoint.Port == ipEndPoint.Port))
397 { 436 {
398 scene = mscene; 437 if ((mscene.RegionInfo.InternalEndPoint.Equals(ipEndPoint.Address)) &&
399 return true; 438 (mscene.RegionInfo.InternalEndPoint.Port == ipEndPoint.Port))
439 {
440 scene = mscene;
441 return true;
442 }
400 } 443 }
401 } 444 }
402 445
@@ -465,11 +508,14 @@ namespace OpenSim.Region.Framework.Scenes
465 508
466 public RegionInfo GetRegionInfo(UUID regionID) 509 public RegionInfo GetRegionInfo(UUID regionID)
467 { 510 {
468 foreach (Scene scene in m_localScenes) 511 lock (m_localScenes)
469 { 512 {
470 if (scene.RegionInfo.RegionID == regionID) 513 foreach (Scene scene in m_localScenes)
471 { 514 {
472 return scene.RegionInfo; 515 if (scene.RegionInfo.RegionID == regionID)
516 {
517 return scene.RegionInfo;
518 }
473 } 519 }
474 } 520 }
475 521
@@ -488,11 +534,14 @@ namespace OpenSim.Region.Framework.Scenes
488 534
489 public bool TryGetScenePresence(UUID avatarId, out ScenePresence avatar) 535 public bool TryGetScenePresence(UUID avatarId, out ScenePresence avatar)
490 { 536 {
491 foreach (Scene scene in m_localScenes) 537 lock (m_localScenes)
492 { 538 {
493 if (scene.TryGetScenePresence(avatarId, out avatar)) 539 foreach (Scene scene in m_localScenes)
494 { 540 {
495 return true; 541 if (scene.TryGetScenePresence(avatarId, out avatar))
542 {
543 return true;
544 }
496 } 545 }
497 } 546 }
498 547
@@ -503,12 +552,16 @@ namespace OpenSim.Region.Framework.Scenes
503 public bool TryGetAvatarsScene(UUID avatarId, out Scene scene) 552 public bool TryGetAvatarsScene(UUID avatarId, out Scene scene)
504 { 553 {
505 ScenePresence avatar = null; 554 ScenePresence avatar = null;
506 foreach (Scene mScene in m_localScenes) 555
556 lock (m_localScenes)
507 { 557 {
508 if (mScene.TryGetScenePresence(avatarId, out avatar)) 558 foreach (Scene mScene in m_localScenes)
509 { 559 {
510 scene = mScene; 560 if (mScene.TryGetScenePresence(avatarId, out avatar))
511 return true; 561 {
562 scene = mScene;
563 return true;
564 }
512 } 565 }
513 } 566 }
514 567
@@ -518,17 +571,22 @@ namespace OpenSim.Region.Framework.Scenes
518 571
519 public void CloseScene(Scene scene) 572 public void CloseScene(Scene scene)
520 { 573 {
521 m_localScenes.Remove(scene); 574 lock (m_localScenes)
575 m_localScenes.Remove(scene);
576
522 scene.Close(); 577 scene.Close();
523 } 578 }
524 579
525 public bool TryGetAvatarByName(string avatarName, out ScenePresence avatar) 580 public bool TryGetAvatarByName(string avatarName, out ScenePresence avatar)
526 { 581 {
527 foreach (Scene scene in m_localScenes) 582 lock (m_localScenes)
528 { 583 {
529 if (scene.TryGetAvatarByName(avatarName, out avatar)) 584 foreach (Scene scene in m_localScenes)
530 { 585 {
531 return true; 586 if (scene.TryGetAvatarByName(avatarName, out avatar))
587 {
588 return true;
589 }
532 } 590 }
533 } 591 }
534 592
@@ -538,7 +596,8 @@ namespace OpenSim.Region.Framework.Scenes
538 596
539 public void ForEachScene(Action<Scene> action) 597 public void ForEachScene(Action<Scene> action)
540 { 598 {
541 m_localScenes.ForEach(action); 599 lock (m_localScenes)
600 m_localScenes.ForEach(action);
542 } 601 }
543 } 602 }
544} 603}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 6c47645..b1b76dd 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -209,25 +209,87 @@ namespace OpenSim.Region.Framework.Scenes
209 return true; 209 return true;
210 return false; 210 return false;
211 } 211 }
212 212
213 /// <value> 213 /// <summary>
214 /// Is this scene object acting as an attachment? 214 /// Is this scene object acting as an attachment?
215 /// 215 /// </summary>
216 /// We return false if the group has already been deleted. 216 public bool IsAttachment { get; set; }
217 /// 217
218 /// TODO: At the moment set must be done on the part itself. There may be a case for doing it here since I 218 /// <summary>
219 /// presume either all or no parts in a linkset can be part of an attachment (in which 219 /// The avatar to which this scene object is attached.
220 /// case the value would get proprogated down into all the descendent parts). 220 /// </summary>
221 /// </value> 221 /// <remarks>
222 public bool IsAttachment 222 /// If we're not attached to an avatar then this is UUID.Zero
223 /// </remarks>
224 public UUID AttachedAvatar { get; set; }
225
226 /// <summary>
227 /// Attachment point of this scene object to an avatar.
228 /// </summary>
229 /// <remarks>
230 /// 0 if we're not attached to anything
231 /// </remarks>
232 public uint AttachmentPoint
223 { 233 {
224 get 234 get
225 { 235 {
226 if (!IsDeleted) 236 return m_rootPart.Shape.State;
227 return m_rootPart.IsAttachment;
228
229 return false;
230 } 237 }
238
239 set
240 {
241 IsAttachment = value != 0;
242 m_rootPart.Shape.State = (byte)value;
243 }
244 }
245
246 public void ClearPartAttachmentData()
247 {
248 AttachmentPoint = 0;
249
250 // Even though we don't use child part state parameters for attachments any more, we still need to set
251 // these to zero since having them non-zero in rezzed scene objects will crash some clients. Even if
252 // we store them correctly, scene objects that we receive from elsewhere might not.
253 foreach (SceneObjectPart part in Parts)
254 part.Shape.State = 0;
255 }
256
257 /// <summary>
258 /// Is this scene object phantom?
259 /// </summary>
260 /// <remarks>
261 /// Updating must currently take place through UpdatePrimFlags()
262 /// </remarks>
263 public bool IsPhantom
264 {
265 get { return (RootPart.Flags & PrimFlags.Phantom) != 0; }
266 }
267
268 /// <summary>
269 /// Does this scene object use physics?
270 /// </summary>
271 /// <remarks>
272 /// Updating must currently take place through UpdatePrimFlags()
273 /// </remarks>
274 public bool UsesPhysics
275 {
276 get { return (RootPart.Flags & PrimFlags.TemporaryOnRez) != 0; }
277 }
278
279 /// <summary>
280 /// Is this scene object temporary?
281 /// </summary>
282 /// <remarks>
283 /// Updating must currently take place through UpdatePrimFlags()
284 /// </remarks>
285 public bool IsTemporary
286 {
287 get { return (RootPart.Flags & PrimFlags.TemporaryOnRez) != 0; }
288 }
289
290 public bool IsVolumeDetect
291 {
292 get { return RootPart.VolumeDetectActive; }
231 } 293 }
232 294
233 public float scriptScore; 295 public float scriptScore;
@@ -261,11 +323,7 @@ namespace OpenSim.Region.Framework.Scenes
261 /// </summary> 323 /// </summary>
262 public override string Name 324 public override string Name
263 { 325 {
264 get { 326 get { return RootPart.Name; }
265 if (RootPart == null)
266 return String.Empty;
267 return RootPart.Name;
268 }
269 set { RootPart.Name = value; } 327 set { RootPart.Name = value; }
270 } 328 }
271 329
@@ -305,6 +363,38 @@ namespace OpenSim.Region.Framework.Scenes
305 get { return m_rootPart.RotationOffset; } 363 get { return m_rootPart.RotationOffset; }
306 } 364 }
307 365
366 public Vector3 GroupScale
367 {
368 get
369 {
370 Vector3 minScale = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionSize);
371 Vector3 maxScale = Vector3.Zero;
372 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
373
374 SceneObjectPart[] parts = m_parts.GetArray();
375 for (int i = 0; i < parts.Length; i++)
376 {
377 SceneObjectPart part = parts[i];
378 Vector3 partscale = part.Scale;
379 Vector3 partoffset = part.OffsetPosition;
380
381 minScale.X = (partscale.X + partoffset.X < minScale.X) ? partscale.X + partoffset.X : minScale.X;
382 minScale.Y = (partscale.Y + partoffset.Y < minScale.Y) ? partscale.Y + partoffset.Y : minScale.Y;
383 minScale.Z = (partscale.Z + partoffset.Z < minScale.Z) ? partscale.Z + partoffset.Z : minScale.Z;
384
385 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
386 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
387 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
388 }
389
390 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
391 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
392 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
393
394 return finalScale;
395 }
396 }
397
308 public UUID GroupID 398 public UUID GroupID
309 { 399 {
310 get { return m_rootPart.GroupID; } 400 get { return m_rootPart.GroupID; }
@@ -344,11 +434,13 @@ namespace OpenSim.Region.Framework.Scenes
344 /// <summary> 434 /// <summary>
345 /// Check both the attachment property and the relevant properties of the underlying root part. 435 /// Check both the attachment property and the relevant properties of the underlying root part.
346 /// </summary> 436 /// </summary>
437 /// <remarks>
347 /// This is necessary in some cases, particularly when a scene object has just crossed into a region and doesn't 438 /// This is necessary in some cases, particularly when a scene object has just crossed into a region and doesn't
348 /// have the IsAttachment property yet checked. 439 /// have the IsAttachment property yet checked.
349 /// 440 ///
350 /// FIXME: However, this should be fixed so that this property 441 /// FIXME: However, this should be fixed so that this property
351 /// propertly reflects the underlying status. 442 /// propertly reflects the underlying status.
443 /// </remarks>
352 /// <returns></returns> 444 /// <returns></returns>
353 public bool IsAttachmentCheckFull() 445 public bool IsAttachmentCheckFull()
354 { 446 {
@@ -682,7 +774,7 @@ namespace OpenSim.Region.Framework.Scenes
682 part.ParentID = m_rootPart.LocalId; 774 part.ParentID = m_rootPart.LocalId;
683 //m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID); 775 //m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID);
684 } 776 }
685 777
686 ApplyPhysics(m_scene.m_physicalPrim); 778 ApplyPhysics(m_scene.m_physicalPrim);
687 779
688 if (RootPart.PhysActor != null) 780 if (RootPart.PhysActor != null)
@@ -693,34 +785,6 @@ namespace OpenSim.Region.Framework.Scenes
693 //ScheduleGroupForFullUpdate(); 785 //ScheduleGroupForFullUpdate();
694 } 786 }
695 787
696 public Vector3 GroupScale()
697 {
698 Vector3 minScale = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionSize);
699 Vector3 maxScale = Vector3.Zero;
700 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
701
702 SceneObjectPart[] parts = m_parts.GetArray();
703 for (int i = 0; i < parts.Length; i++)
704 {
705 SceneObjectPart part = parts[i];
706 Vector3 partscale = part.Scale;
707 Vector3 partoffset = part.OffsetPosition;
708
709 minScale.X = (partscale.X + partoffset.X < minScale.X) ? partscale.X + partoffset.X : minScale.X;
710 minScale.Y = (partscale.Y + partoffset.Y < minScale.Y) ? partscale.Y + partoffset.Y : minScale.Y;
711 minScale.Z = (partscale.Z + partoffset.Z < minScale.Z) ? partscale.Z + partoffset.Z : minScale.Z;
712
713 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
714 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
715 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
716 }
717
718 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
719 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
720 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
721 return finalScale;
722
723 }
724 public EntityIntersection TestIntersection(Ray hRay, bool frontFacesOnly, bool faceCenters) 788 public EntityIntersection TestIntersection(Ray hRay, bool frontFacesOnly, bool faceCenters)
725 { 789 {
726 // We got a request from the inner_scene to raytrace along the Ray hRay 790 // We got a request from the inner_scene to raytrace along the Ray hRay
@@ -1082,6 +1146,7 @@ namespace OpenSim.Region.Framework.Scenes
1082 } 1146 }
1083 } 1147 }
1084 1148
1149<<<<<<< HEAD
1085 /// <summary> 1150 /// <summary>
1086 /// Add the avatar to this linkset (avatar is sat). 1151 /// Add the avatar to this linkset (avatar is sat).
1087 /// </summary> 1152 /// </summary>
@@ -1263,6 +1328,8 @@ namespace OpenSim.Region.Framework.Scenes
1263 //m_rootPart.ScheduleFullUpdate(); 1328 //m_rootPart.ScheduleFullUpdate();
1264 } 1329 }
1265 1330
1331=======
1332>>>>>>> 9f75eaf50e42ef6409fc272ba33a817241907ed8
1266 /// <summary> 1333 /// <summary>
1267 /// 1334 ///
1268 /// </summary> 1335 /// </summary>
@@ -1320,11 +1387,16 @@ namespace OpenSim.Region.Framework.Scenes
1320 public void AddPart(SceneObjectPart part) 1387 public void AddPart(SceneObjectPart part)
1321 { 1388 {
1322 part.SetParent(this); 1389 part.SetParent(this);
1390<<<<<<< HEAD
1323 m_parts.Add(part.UUID, part); 1391 m_parts.Add(part.UUID, part);
1324 1392
1325 part.LinkNum = m_parts.Count; 1393 part.LinkNum = m_parts.Count;
1326 1394
1327 if (part.LinkNum == 2 && RootPart != null) 1395 if (part.LinkNum == 2 && RootPart != null)
1396=======
1397 part.LinkNum = m_parts.Add(part.UUID, part);
1398 if (part.LinkNum == 2)
1399>>>>>>> 9f75eaf50e42ef6409fc272ba33a817241907ed8
1328 RootPart.LinkNum = 1; 1400 RootPart.LinkNum = 1;
1329 } 1401 }
1330 1402
@@ -1407,7 +1479,15 @@ namespace OpenSim.Region.Framework.Scenes
1407 1479
1408 public virtual void OnGrabPart(SceneObjectPart part, Vector3 offsetPos, IClientAPI remoteClient) 1480 public virtual void OnGrabPart(SceneObjectPart part, Vector3 offsetPos, IClientAPI remoteClient)
1409 { 1481 {
1482<<<<<<< HEAD
1410 part.StoreUndoState(UndoType.STATE_PRIM_ALL); 1483 part.StoreUndoState(UndoType.STATE_PRIM_ALL);
1484=======
1485// m_log.DebugFormat(
1486// "[SCENE OBJECT GROUP]: Processing OnGrabPart for {0} on {1} {2}, offsetPos {3}",
1487// remoteClient.Name, part.Name, part.LocalId, offsetPos);
1488
1489 part.StoreUndoState();
1490>>>>>>> 9f75eaf50e42ef6409fc272ba33a817241907ed8
1411 part.OnGrab(offsetPos, remoteClient); 1491 part.OnGrab(offsetPos, remoteClient);
1412 } 1492 }
1413 1493
@@ -1711,16 +1791,30 @@ namespace OpenSim.Region.Framework.Scenes
1711 dupe.m_isBackedUp = false; 1791 dupe.m_isBackedUp = false;
1712 dupe.m_parts = new MapAndArray<OpenMetaverse.UUID, SceneObjectPart>(); 1792 dupe.m_parts = new MapAndArray<OpenMetaverse.UUID, SceneObjectPart>();
1713 1793
1794<<<<<<< HEAD
1714 // Warning, The following code related to previousAttachmentStatus is needed so that clones of 1795 // Warning, The following code related to previousAttachmentStatus is needed so that clones of
1715 // attachments do not bordercross while they're being duplicated. This is hacktastic! 1796 // attachments do not bordercross while they're being duplicated. This is hacktastic!
1716 // Normally, setting AbsolutePosition will bordercross a prim if it's outside the region! 1797 // Normally, setting AbsolutePosition will bordercross a prim if it's outside the region!
1717 // unless IsAttachment is true!, so to prevent border crossing, we save it's attachment state 1798 // unless IsAttachment is true!, so to prevent border crossing, we save it's attachment state
1718 // (which should be false anyway) set it as an Attachment and then set it's Absolute Position, 1799 // (which should be false anyway) set it as an Attachment and then set it's Absolute Position,
1719 // then restore it's attachment state 1800 // then restore it's attachment state
1801=======
1802 bool previousAttachmentStatus = dupe.IsAttachment;
1803
1804 if (!userExposed)
1805 dupe.IsAttachment = true;
1806>>>>>>> 9f75eaf50e42ef6409fc272ba33a817241907ed8
1720 1807
1721 // This is only necessary when userExposed is false! 1808 // This is only necessary when userExposed is false!
1722 1809
1810<<<<<<< HEAD
1723 bool previousAttachmentStatus = dupe.RootPart.IsAttachment; 1811 bool previousAttachmentStatus = dupe.RootPart.IsAttachment;
1812=======
1813 if (!userExposed)
1814 {
1815 dupe.IsAttachment = previousAttachmentStatus;
1816 }
1817>>>>>>> 9f75eaf50e42ef6409fc272ba33a817241907ed8
1724 1818
1725 if (!userExposed) 1819 if (!userExposed)
1726 dupe.RootPart.IsAttachment = true; 1820 dupe.RootPart.IsAttachment = true;
@@ -1781,7 +1875,26 @@ namespace OpenSim.Region.Framework.Scenes
1781 dupe.HasGroupChanged = true; 1875 dupe.HasGroupChanged = true;
1782 dupe.AttachToBackup(); 1876 dupe.AttachToBackup();
1783 1877
1878<<<<<<< HEAD
1784 ScheduleGroupForFullUpdate(); 1879 ScheduleGroupForFullUpdate();
1880=======
1881 // Need to duplicate the physics actor as well
1882 if (part.PhysActor != null && userExposed)
1883 {
1884 PrimitiveBaseShape pbs = newPart.Shape;
1885
1886 newPart.PhysActor
1887 = m_scene.PhysicsScene.AddPrimShape(
1888 string.Format("{0}/{1}", newPart.Name, newPart.UUID),
1889 pbs,
1890 newPart.AbsolutePosition,
1891 newPart.Scale,
1892 newPart.RotationOffset,
1893 part.PhysActor.IsPhysical,
1894 newPart.LocalId);
1895
1896 newPart.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true);
1897>>>>>>> 9f75eaf50e42ef6409fc272ba33a817241907ed8
1785 } 1898 }
1786 } 1899 }
1787 finally 1900 finally
@@ -1802,36 +1915,24 @@ namespace OpenSim.Region.Framework.Scenes
1802 SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed)); 1915 SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed));
1803 } 1916 }
1804 1917
1805 public void ScriptSetPhysicsStatus(bool UsePhysics) 1918 public void ScriptSetPhysicsStatus(bool usePhysics)
1806 { 1919 {
1807 bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0); 1920 UpdatePrimFlags(RootPart.LocalId, usePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
1808 bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0);
1809 bool IsVolumeDetect = RootPart.VolumeDetectActive;
1810 UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
1811 } 1921 }
1812 1922
1813 public void ScriptSetTemporaryStatus(bool TemporaryStatus) 1923 public void ScriptSetTemporaryStatus(bool makeTemporary)
1814 { 1924 {
1815 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 1925 UpdatePrimFlags(RootPart.LocalId, UsesPhysics, makeTemporary, IsPhantom, IsVolumeDetect);
1816 bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0);
1817 bool IsVolumeDetect = RootPart.VolumeDetectActive;
1818 UpdatePrimFlags(RootPart.LocalId, UsePhysics, TemporaryStatus, IsPhantom, IsVolumeDetect);
1819 } 1926 }
1820 1927
1821 public void ScriptSetPhantomStatus(bool PhantomStatus) 1928 public void ScriptSetPhantomStatus(bool makePhantom)
1822 { 1929 {
1823 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 1930 UpdatePrimFlags(RootPart.LocalId, UsesPhysics, IsTemporary, makePhantom, IsVolumeDetect);
1824 bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0);
1825 bool IsVolumeDetect = RootPart.VolumeDetectActive;
1826 UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, PhantomStatus, IsVolumeDetect);
1827 } 1931 }
1828 1932
1829 public void ScriptSetVolumeDetect(bool VDStatus) 1933 public void ScriptSetVolumeDetect(bool makeVolumeDetect)
1830 { 1934 {
1831 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 1935 UpdatePrimFlags(RootPart.LocalId, UsesPhysics, IsTemporary, IsPhantom, makeVolumeDetect);
1832 bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0);
1833 bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0);
1834 UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, IsPhantom, VDStatus);
1835 1936
1836 /* 1937 /*
1837 ScriptSetPhantomStatus(false); // What ever it was before, now it's not phantom anymore 1938 ScriptSetPhantomStatus(false); // What ever it was before, now it's not phantom anymore
@@ -1849,126 +1950,87 @@ namespace OpenSim.Region.Framework.Scenes
1849 1950
1850 public void applyImpulse(Vector3 impulse) 1951 public void applyImpulse(Vector3 impulse)
1851 { 1952 {
1852 // We check if rootpart is null here because scripts don't delete if you delete the host. 1953 if (IsAttachment)
1853 // This means that unfortunately, we can pass a null physics actor to Simulate!
1854 // Make sure we don't do that!
1855 SceneObjectPart rootpart = m_rootPart;
1856 if (rootpart != null)
1857 { 1954 {
1858 if (IsAttachment) 1955 ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar);
1956 if (avatar != null)
1859 { 1957 {
1860 ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar); 1958 avatar.PushForce(impulse);
1861 if (avatar != null)
1862 {
1863 avatar.PushForce(impulse);
1864 }
1865 } 1959 }
1866 else 1960 }
1961 else
1962 {
1963 if (RootPart.PhysActor != null)
1867 { 1964 {
1868 if (rootpart.PhysActor != null) 1965 RootPart.PhysActor.AddForce(impulse, true);
1869 { 1966 m_scene.PhysicsScene.AddPhysicsActorTaint(RootPart.PhysActor);
1870 rootpart.PhysActor.AddForce(impulse, true);
1871 m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor);
1872 }
1873 } 1967 }
1874 } 1968 }
1875 } 1969 }
1876 1970
1877 public void applyAngularImpulse(Vector3 impulse) 1971 public void applyAngularImpulse(Vector3 impulse)
1878 { 1972 {
1879 // We check if rootpart is null here because scripts don't delete if you delete the host. 1973 if (RootPart.PhysActor != null)
1880 // This means that unfortunately, we can pass a null physics actor to Simulate!
1881 // Make sure we don't do that!
1882 SceneObjectPart rootpart = m_rootPart;
1883 if (rootpart != null)
1884 { 1974 {
1885 if (rootpart.PhysActor != null) 1975 if (!IsAttachment)
1886 { 1976 {
1887 if (!IsAttachment) 1977 RootPart.PhysActor.AddAngularForce(impulse, true);
1888 { 1978 m_scene.PhysicsScene.AddPhysicsActorTaint(RootPart.PhysActor);
1889 rootpart.PhysActor.AddAngularForce(impulse, true);
1890 m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor);
1891 }
1892 } 1979 }
1893 } 1980 }
1894 } 1981 }
1895 1982
1896 public void setAngularImpulse(Vector3 impulse) 1983 public void setAngularImpulse(Vector3 impulse)
1897 { 1984 {
1898 // We check if rootpart is null here because scripts don't delete if you delete the host. 1985 if (RootPart.PhysActor != null)
1899 // This means that unfortunately, we can pass a null physics actor to Simulate!
1900 // Make sure we don't do that!
1901 SceneObjectPart rootpart = m_rootPart;
1902 if (rootpart != null)
1903 { 1986 {
1904 if (rootpart.PhysActor != null) 1987 if (!IsAttachment)
1905 { 1988 {
1906 if (!IsAttachment) 1989 RootPart.PhysActor.Torque = impulse;
1907 { 1990 m_scene.PhysicsScene.AddPhysicsActorTaint(RootPart.PhysActor);
1908 rootpart.PhysActor.Torque = impulse;
1909 m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor);
1910 }
1911 } 1991 }
1912 } 1992 }
1913 } 1993 }
1914 1994
1915 public Vector3 GetTorque() 1995 public Vector3 GetTorque()
1916 { 1996 {
1917 // We check if rootpart is null here because scripts don't delete if you delete the host. 1997 if (RootPart.PhysActor != null)
1918 // This means that unfortunately, we can pass a null physics actor to Simulate!
1919 // Make sure we don't do that!
1920 SceneObjectPart rootpart = m_rootPart;
1921 if (rootpart != null)
1922 { 1998 {
1923 if (rootpart.PhysActor != null) 1999 if (!IsAttachment)
1924 { 2000 {
1925 if (!IsAttachment) 2001 Vector3 torque = RootPart.PhysActor.Torque;
1926 { 2002 return torque;
1927 Vector3 torque = rootpart.PhysActor.Torque;
1928 return torque;
1929 }
1930 } 2003 }
1931 } 2004 }
2005
1932 return Vector3.Zero; 2006 return Vector3.Zero;
1933 } 2007 }
1934 2008
1935 // This is used by both Double-Click Auto-Pilot and llMoveToTarget() in an attached object 2009 // This is used by both Double-Click Auto-Pilot and llMoveToTarget() in an attached object
1936 public void moveToTarget(Vector3 target, float tau) 2010 public void moveToTarget(Vector3 target, float tau)
1937 { 2011 {
1938 SceneObjectPart rootpart = m_rootPart; 2012 if (IsAttachment)
1939 if (rootpart != null)
1940 { 2013 {
1941 if (IsAttachment) 2014 ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar);
2015 if (avatar != null)
1942 { 2016 {
1943 ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar); 2017 avatar.MoveToTarget(target, false);
1944 if (avatar != null)
1945 {
1946 List<string> coords = new List<string>();
1947 uint regionX = 0;
1948 uint regionY = 0;
1949 Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY);
1950 target.X += regionX;
1951 target.Y += regionY;
1952 coords.Add(target.X.ToString());
1953 coords.Add(target.Y.ToString());
1954 coords.Add(target.Z.ToString());
1955 avatar.DoMoveToPosition(avatar, "", coords);
1956 }
1957 } 2018 }
1958 else 2019 }
2020 else
2021 {
2022 if (RootPart.PhysActor != null)
1959 { 2023 {
1960 if (rootpart.PhysActor != null) 2024 RootPart.PhysActor.PIDTarget = target;
1961 { 2025 RootPart.PhysActor.PIDTau = tau;
1962 rootpart.PhysActor.PIDTarget = target; 2026 RootPart.PhysActor.PIDActive = true;
1963 rootpart.PhysActor.PIDTau = tau;
1964 rootpart.PhysActor.PIDActive = true;
1965 }
1966 } 2027 }
1967 } 2028 }
1968 } 2029 }
1969 2030
1970 public void stopMoveToTarget() 2031 public void stopMoveToTarget()
1971 { 2032 {
2033<<<<<<< HEAD
1972 SceneObjectPart rootpart = m_rootPart; 2034 SceneObjectPart rootpart = m_rootPart;
1973 if (rootpart != null) 2035 if (rootpart != null)
1974 { 2036 {
@@ -1985,6 +2047,10 @@ namespace OpenSim.Region.Framework.Scenes
1985 } 2047 }
1986 } 2048 }
1987 } 2049 }
2050=======
2051 if (RootPart.PhysActor != null)
2052 RootPart.PhysActor.PIDActive = false;
2053>>>>>>> 9f75eaf50e42ef6409fc272ba33a817241907ed8
1988 } 2054 }
1989 2055
1990 public void rotLookAt(Quaternion target, float strength, float damping) 2056 public void rotLookAt(Quaternion target, float strength, float damping)
@@ -2016,6 +2082,7 @@ namespace OpenSim.Region.Framework.Scenes
2016 2082
2017 public void stopLookAt() 2083 public void stopLookAt()
2018 { 2084 {
2085<<<<<<< HEAD
2019 SceneObjectPart rootpart = m_rootPart; 2086 SceneObjectPart rootpart = m_rootPart;
2020 if (rootpart != null) 2087 if (rootpart != null)
2021 { 2088 {
@@ -2025,6 +2092,10 @@ namespace OpenSim.Region.Framework.Scenes
2025 } 2092 }
2026 } 2093 }
2027 2094
2095=======
2096 if (RootPart.PhysActor != null)
2097 RootPart.PhysActor.APIDActive = false;
2098>>>>>>> 9f75eaf50e42ef6409fc272ba33a817241907ed8
2028 } 2099 }
2029 2100
2030 /// <summary> 2101 /// <summary>
@@ -2035,22 +2106,18 @@ namespace OpenSim.Region.Framework.Scenes
2035 /// <param name="tau">Number of seconds over which to reach target</param> 2106 /// <param name="tau">Number of seconds over which to reach target</param>
2036 public void SetHoverHeight(float height, PIDHoverType hoverType, float tau) 2107 public void SetHoverHeight(float height, PIDHoverType hoverType, float tau)
2037 { 2108 {
2038 SceneObjectPart rootpart = m_rootPart; 2109 if (RootPart.PhysActor != null)
2039 if (rootpart != null)
2040 { 2110 {
2041 if (rootpart.PhysActor != null) 2111 if (height != 0f)
2042 { 2112 {
2043 if (height != 0f) 2113 RootPart.PhysActor.PIDHoverHeight = height;
2044 { 2114 RootPart.PhysActor.PIDHoverType = hoverType;
2045 rootpart.PhysActor.PIDHoverHeight = height; 2115 RootPart.PhysActor.PIDTau = tau;
2046 rootpart.PhysActor.PIDHoverType = hoverType; 2116 RootPart.PhysActor.PIDHoverActive = true;
2047 rootpart.PhysActor.PIDTau = tau; 2117 }
2048 rootpart.PhysActor.PIDHoverActive = true; 2118 else
2049 } 2119 {
2050 else 2120 RootPart.PhysActor.PIDHoverActive = false;
2051 {
2052 rootpart.PhysActor.PIDHoverActive = false;
2053 }
2054 } 2121 }
2055 } 2122 }
2056 } 2123 }
@@ -2145,7 +2212,7 @@ namespace OpenSim.Region.Framework.Scenes
2145 // an object has been deleted from a scene before update was processed. 2212 // an object has been deleted from a scene before update was processed.
2146 // A more fundamental overhaul of the update mechanism is required to eliminate all 2213 // A more fundamental overhaul of the update mechanism is required to eliminate all
2147 // the race conditions. 2214 // the race conditions.
2148 if (m_isDeleted) 2215 if (IsDeleted)
2149 return; 2216 return;
2150 2217
2151 // Even temporary objects take part in physics (e.g. temp-on-rez bullets) 2218 // Even temporary objects take part in physics (e.g. temp-on-rez bullets)
@@ -2458,7 +2525,7 @@ namespace OpenSim.Region.Framework.Scenes
2458 } 2525 }
2459 2526
2460 m_scene.UnlinkSceneObject(objectGroup, true); 2527 m_scene.UnlinkSceneObject(objectGroup, true);
2461 objectGroup.m_isDeleted = true; 2528 objectGroup.IsDeleted = true;
2462 2529
2463 objectGroup.m_parts.Clear(); 2530 objectGroup.m_parts.Clear();
2464 2531
@@ -2595,9 +2662,13 @@ namespace OpenSim.Region.Framework.Scenes
2595 /// <param name="objectGroup"></param> 2662 /// <param name="objectGroup"></param>
2596 public virtual void DetachFromBackup() 2663 public virtual void DetachFromBackup()
2597 { 2664 {
2665<<<<<<< HEAD
2598 m_scene.SceneGraph.FireDetachFromBackup(this); 2666 m_scene.SceneGraph.FireDetachFromBackup(this);
2599 2667
2600 if (m_isBackedUp) 2668 if (m_isBackedUp)
2669=======
2670 if (m_isBackedUp && Scene != null)
2671>>>>>>> 9f75eaf50e42ef6409fc272ba33a817241907ed8
2601 m_scene.EventManager.OnBackup -= ProcessBackup; 2672 m_scene.EventManager.OnBackup -= ProcessBackup;
2602 2673
2603 m_isBackedUp = false; 2674 m_isBackedUp = false;
@@ -2857,14 +2928,15 @@ namespace OpenSim.Region.Framework.Scenes
2857 /// Update prim flags for this group. 2928 /// Update prim flags for this group.
2858 /// </summary> 2929 /// </summary>
2859 /// <param name="localID"></param> 2930 /// <param name="localID"></param>
2860 /// <param name="type"></param> 2931 /// <param name="UsePhysics"></param>
2861 /// <param name="inUse"></param> 2932 /// <param name="SetTemporary"></param>
2862 /// <param name="data"></param> 2933 /// <param name="SetPhantom"></param>
2863 public void UpdatePrimFlags(uint localID, bool UsePhysics, bool IsTemporary, bool IsPhantom, bool IsVolumeDetect) 2934 /// <param name="SetVolumeDetect"></param>
2935 public void UpdatePrimFlags(uint localID, bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVolumeDetect)
2864 { 2936 {
2865 SceneObjectPart selectionPart = GetChildPart(localID); 2937 SceneObjectPart selectionPart = GetChildPart(localID);
2866 2938
2867 if (IsTemporary) 2939 if (SetTemporary && Scene != null)
2868 { 2940 {
2869 DetachFromBackup(); 2941 DetachFromBackup();
2870 // Remove from database and parcel prim count 2942 // Remove from database and parcel prim count
@@ -2876,24 +2948,32 @@ namespace OpenSim.Region.Framework.Scenes
2876 if (selectionPart != null) 2948 if (selectionPart != null)
2877 { 2949 {
2878 SceneObjectPart[] parts = m_parts.GetArray(); 2950 SceneObjectPart[] parts = m_parts.GetArray();
2879 for (int i = 0; i < parts.Length; i++) 2951
2952 if (Scene != null)
2880 { 2953 {
2881 SceneObjectPart part = parts[i]; 2954 for (int i = 0; i < parts.Length; i++)
2882 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax ||
2883 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax ||
2884 part.Scale.Z > m_scene.RegionInfo.PhysPrimMax)
2885 { 2955 {
2886 UsePhysics = false; // Reset physics 2956 SceneObjectPart part = parts[i];
2887 break; 2957 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax ||
2958 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax ||
2959 part.Scale.Z > m_scene.RegionInfo.PhysPrimMax)
2960 {
2961 UsePhysics = false; // Reset physics
2962 break;
2963 }
2888 } 2964 }
2889 } 2965 }
2890 2966
2891 RootPart.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); 2967 RootPart.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
2892 for (int i = 0; i < parts.Length; i++) 2968 for (int i = 0; i < parts.Length; i++)
2969<<<<<<< HEAD
2893 { 2970 {
2894 if (parts[i] != RootPart) 2971 if (parts[i] != RootPart)
2895 parts[i].UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); 2972 parts[i].UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
2896 } 2973 }
2974=======
2975 parts[i].UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect);
2976>>>>>>> 9f75eaf50e42ef6409fc272ba33a817241907ed8
2897 } 2977 }
2898 } 2978 }
2899 2979
@@ -2966,12 +3046,12 @@ namespace OpenSim.Region.Framework.Scenes
2966 #region Resize 3046 #region Resize
2967 3047
2968 /// <summary> 3048 /// <summary>
2969 /// Resize the given part 3049 /// Resize the entire group of prims.
2970 /// </summary> 3050 /// </summary>
2971 /// <param name="scale"></param> 3051 /// <param name="scale"></param>
2972 /// <param name="localID"></param> 3052 public void GroupResize(Vector3 scale)
2973 public void Resize(Vector3 scale, uint localID)
2974 { 3053 {
3054<<<<<<< HEAD
2975 if (scale.X > m_scene.m_maxNonphys) 3055 if (scale.X > m_scene.m_maxNonphys)
2976 scale.X = m_scene.m_maxNonphys; 3056 scale.X = m_scene.m_maxNonphys;
2977 if (scale.Y > m_scene.m_maxNonphys) 3057 if (scale.Y > m_scene.m_maxNonphys)
@@ -2996,23 +3076,25 @@ namespace OpenSim.Region.Framework.Scenes
2996 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); 3076 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
2997 } 3077 }
2998 part.Resize(scale); 3078 part.Resize(scale);
3079=======
3080// m_log.DebugFormat(
3081// "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, LocalId, RootPart.Scale, scale);
2999 3082
3000 HasGroupChanged = true; 3083 RootPart.StoreUndoState(true);
3001 part.TriggerScriptChangedEvent(Changed.SCALE); 3084>>>>>>> 9f75eaf50e42ef6409fc272ba33a817241907ed8
3002 ScheduleGroupForFullUpdate();
3003 3085
3004 //if (part.UUID == m_rootPart.UUID) 3086 scale.X = Math.Min(scale.X, Scene.m_maxNonphys);
3005 //{ 3087 scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys);
3006 //if (m_rootPart.PhysActor != null) 3088 scale.Z = Math.Min(scale.Z, Scene.m_maxNonphys);
3007 //{ 3089
3008 //m_rootPart.PhysActor.Size = 3090 if (RootPart.PhysActor != null && RootPart.PhysActor.IsPhysical)
3009 //new PhysicsVector(m_rootPart.Scale.X, m_rootPart.Scale.Y, m_rootPart.Scale.Z); 3091 {
3010 //m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 3092 scale.X = Math.Min(scale.X, Scene.m_maxPhys);
3011 //} 3093 scale.Y = Math.Min(scale.Y, Scene.m_maxPhys);
3012 //} 3094 scale.Z = Math.Min(scale.Z, Scene.m_maxPhys);
3013 } 3095 }
3014 }
3015 3096
3097<<<<<<< HEAD
3016 public void GroupResize(Vector3 scale, uint localID) 3098 public void GroupResize(Vector3 scale, uint localID)
3017 { 3099 {
3018 SceneObjectPart part = GetChildPart(localID); 3100 SceneObjectPart part = GetChildPart(localID);
@@ -3036,24 +3118,50 @@ namespace OpenSim.Region.Framework.Scenes
3036 float x = (scale.X / part.Scale.X); 3118 float x = (scale.X / part.Scale.X);
3037 float y = (scale.Y / part.Scale.Y); 3119 float y = (scale.Y / part.Scale.Y);
3038 float z = (scale.Z / part.Scale.Z); 3120 float z = (scale.Z / part.Scale.Z);
3121=======
3122 float x = (scale.X / RootPart.Scale.X);
3123 float y = (scale.Y / RootPart.Scale.Y);
3124 float z = (scale.Z / RootPart.Scale.Z);
3125>>>>>>> 9f75eaf50e42ef6409fc272ba33a817241907ed8
3039 3126
3040 SceneObjectPart[] parts; 3127 SceneObjectPart[] parts;
3041 if (x > 1.0f || y > 1.0f || z > 1.0f) 3128 if (x > 1.0f || y > 1.0f || z > 1.0f)
3129 {
3130 parts = m_parts.GetArray();
3131 for (int i = 0; i < parts.Length; i++)
3042 { 3132 {
3043 parts = m_parts.GetArray(); 3133 SceneObjectPart obPart = parts[i];
3044 for (int i = 0; i < parts.Length; i++) 3134 if (obPart.UUID != m_rootPart.UUID)
3045 { 3135 {
3046 SceneObjectPart obPart = parts[i]; 3136// obPart.IgnoreUndoUpdate = true;
3047 if (obPart.UUID != m_rootPart.UUID) 3137 Vector3 oldSize = new Vector3(obPart.Scale);
3138
3139 float f = 1.0f;
3140 float a = 1.0f;
3141
3142 if (RootPart.PhysActor != null && RootPart.PhysActor.IsPhysical)
3048 { 3143 {
3049 obPart.IgnoreUndoUpdate = true; 3144 if (oldSize.X * x > m_scene.m_maxPhys)
3050 Vector3 oldSize = new Vector3(obPart.Scale); 3145 {
3146 f = m_scene.m_maxPhys / oldSize.X;
3147 a = f / x;
3148 x *= a;
3149 y *= a;
3150 z *= a;
3151 }
3051 3152
3052 float f = 1.0f; 3153 if (oldSize.Y * y > m_scene.m_maxPhys)
3053 float a = 1.0f; 3154 {
3155 f = m_scene.m_maxPhys / oldSize.Y;
3156 a = f / y;
3157 x *= a;
3158 y *= a;
3159 z *= a;
3160 }
3054 3161
3055 if (part.PhysActor != null && part.PhysActor.IsPhysical) 3162 if (oldSize.Z * z > m_scene.m_maxPhys)
3056 { 3163 {
3164<<<<<<< HEAD
3057 if (oldSize.X*x > m_scene.m_maxPhys) 3165 if (oldSize.X*x > m_scene.m_maxPhys)
3058 { 3166 {
3059 f = m_scene.m_maxPhys / oldSize.X; 3167 f = m_scene.m_maxPhys / oldSize.X;
@@ -3078,9 +3186,20 @@ namespace OpenSim.Region.Framework.Scenes
3078 y *= a; 3186 y *= a;
3079 z *= a; 3187 z *= a;
3080 } 3188 }
3189=======
3190 f = m_scene.m_maxPhys / oldSize.Z;
3191 a = f / z;
3192 x *= a;
3193 y *= a;
3194 z *= a;
3195>>>>>>> 9f75eaf50e42ef6409fc272ba33a817241907ed8
3081 } 3196 }
3082 else 3197 }
3198 else
3199 {
3200 if (oldSize.X * x > m_scene.m_maxNonphys)
3083 { 3201 {
3202<<<<<<< HEAD
3084 if (oldSize.X*x > m_scene.m_maxNonphys) 3203 if (oldSize.X*x > m_scene.m_maxNonphys)
3085 { 3204 {
3086 f = m_scene.m_maxNonphys / oldSize.X; 3205 f = m_scene.m_maxNonphys / oldSize.X;
@@ -3107,10 +3226,40 @@ namespace OpenSim.Region.Framework.Scenes
3107 } 3226 }
3108 } 3227 }
3109 obPart.IgnoreUndoUpdate = false; 3228 obPart.IgnoreUndoUpdate = false;
3229=======
3230 f = m_scene.m_maxNonphys / oldSize.X;
3231 a = f / x;
3232 x *= a;
3233 y *= a;
3234 z *= a;
3235 }
3236
3237 if (oldSize.Y * y > m_scene.m_maxNonphys)
3238 {
3239 f = m_scene.m_maxNonphys / oldSize.Y;
3240 a = f / y;
3241 x *= a;
3242 y *= a;
3243 z *= a;
3244 }
3245
3246 if (oldSize.Z * z > m_scene.m_maxNonphys)
3247 {
3248 f = m_scene.m_maxNonphys / oldSize.Z;
3249 a = f / z;
3250 x *= a;
3251 y *= a;
3252 z *= a;
3253 }
3254>>>>>>> 9f75eaf50e42ef6409fc272ba33a817241907ed8
3110 } 3255 }
3256
3257// obPart.IgnoreUndoUpdate = false;
3111 } 3258 }
3112 } 3259 }
3260 }
3113 3261
3262<<<<<<< HEAD
3114 Vector3 prevScale = part.Scale; 3263 Vector3 prevScale = part.Scale;
3115 prevScale.X *= x; 3264 prevScale.X *= x;
3116 prevScale.Y *= y; 3265 prevScale.Y *= y;
@@ -3121,12 +3270,26 @@ namespace OpenSim.Region.Framework.Scenes
3121 part.IgnoreUndoUpdate = true; 3270 part.IgnoreUndoUpdate = true;
3122 part.Resize(prevScale); 3271 part.Resize(prevScale);
3123 part.IgnoreUndoUpdate = false; 3272 part.IgnoreUndoUpdate = false;
3273=======
3274 Vector3 prevScale = RootPart.Scale;
3275 prevScale.X *= x;
3276 prevScale.Y *= y;
3277 prevScale.Z *= z;
3278>>>>>>> 9f75eaf50e42ef6409fc272ba33a817241907ed8
3124 3279
3125 parts = m_parts.GetArray(); 3280// RootPart.IgnoreUndoUpdate = true;
3126 for (int i = 0; i < parts.Length; i++) 3281 RootPart.Resize(prevScale);
3282// RootPart.IgnoreUndoUpdate = false;
3283
3284 parts = m_parts.GetArray();
3285 for (int i = 0; i < parts.Length; i++)
3286 {
3287 SceneObjectPart obPart = parts[i];
3288
3289 if (obPart.UUID != m_rootPart.UUID)
3127 { 3290 {
3128 SceneObjectPart obPart = parts[i];
3129 obPart.IgnoreUndoUpdate = true; 3291 obPart.IgnoreUndoUpdate = true;
3292<<<<<<< HEAD
3130 if (obPart.UUID != m_rootPart.UUID) 3293 if (obPart.UUID != m_rootPart.UUID)
3131 { 3294 {
3132 if (obPart.UUID != m_rootPart.UUID) 3295 if (obPart.UUID != m_rootPart.UUID)
@@ -3150,18 +3313,38 @@ namespace OpenSim.Region.Framework.Scenes
3150 } 3313 }
3151 obPart.IgnoreUndoUpdate = false; 3314 obPart.IgnoreUndoUpdate = false;
3152 } 3315 }
3316=======
3317>>>>>>> 9f75eaf50e42ef6409fc272ba33a817241907ed8
3153 3318
3154 if (part.PhysActor != null) 3319 Vector3 currentpos = new Vector3(obPart.OffsetPosition);
3155 { 3320 currentpos.X *= x;
3156 part.PhysActor.Size = prevScale; 3321 currentpos.Y *= y;
3157 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); 3322 currentpos.Z *= z;
3323
3324 Vector3 newSize = new Vector3(obPart.Scale);
3325 newSize.X *= x;
3326 newSize.Y *= y;
3327 newSize.Z *= z;
3328
3329 obPart.Resize(newSize);
3330 obPart.UpdateOffSet(currentpos);
3331
3332 obPart.IgnoreUndoUpdate = false;
3158 } 3333 }
3159 3334
3335<<<<<<< HEAD
3160 part.IgnoreUndoUpdate = false; 3336 part.IgnoreUndoUpdate = false;
3161 HasGroupChanged = true; 3337 HasGroupChanged = true;
3162 m_rootPart.TriggerScriptChangedEvent(Changed.SCALE); 3338 m_rootPart.TriggerScriptChangedEvent(Changed.SCALE);
3163 ScheduleGroupForTerseUpdate(); 3339 ScheduleGroupForTerseUpdate();
3340=======
3341// obPart.IgnoreUndoUpdate = false;
3342// obPart.StoreUndoState();
3343>>>>>>> 9f75eaf50e42ef6409fc272ba33a817241907ed8
3164 } 3344 }
3345
3346// m_log.DebugFormat(
3347// "[SCENE OBJECT GROUP]: Finished group resizing {0} {1} to {2}", Name, LocalId, RootPart.Scale);
3165 } 3348 }
3166 3349
3167 #endregion 3350 #endregion
@@ -3174,6 +3357,17 @@ namespace OpenSim.Region.Framework.Scenes
3174 /// <param name="pos"></param> 3357 /// <param name="pos"></param>
3175 public void UpdateGroupPosition(Vector3 pos) 3358 public void UpdateGroupPosition(Vector3 pos)
3176 { 3359 {
3360<<<<<<< HEAD
3361=======
3362// m_log.DebugFormat("[SCENE OBJECT GROUP]: Updating group position on {0} {1} to {2}", Name, LocalId, pos);
3363
3364 RootPart.StoreUndoState(true);
3365
3366// SceneObjectPart[] parts = m_parts.GetArray();
3367// for (int i = 0; i < parts.Length; i++)
3368// parts[i].StoreUndoState();
3369
3370>>>>>>> 9f75eaf50e42ef6409fc272ba33a817241907ed8
3177 if (m_scene.EventManager.TriggerGroupMove(UUID, pos)) 3371 if (m_scene.EventManager.TriggerGroupMove(UUID, pos))
3178 { 3372 {
3179 if (IsAttachment) 3373 if (IsAttachment)
@@ -3210,12 +3404,24 @@ namespace OpenSim.Region.Framework.Scenes
3210 { 3404 {
3211 SceneObjectPart part = GetChildPart(localID); 3405 SceneObjectPart part = GetChildPart(localID);
3212 3406
3407<<<<<<< HEAD
3213 SceneObjectPart[] parts = m_parts.GetArray(); 3408 SceneObjectPart[] parts = m_parts.GetArray();
3214 for (int i = 0; i < parts.Length; i++) 3409 for (int i = 0; i < parts.Length; i++)
3215 parts[i].StoreUndoState(UndoType.STATE_PRIM_POSITION); 3410 parts[i].StoreUndoState(UndoType.STATE_PRIM_POSITION);
3411=======
3412// SceneObjectPart[] parts = m_parts.GetArray();
3413// for (int i = 0; i < parts.Length; i++)
3414// parts[i].StoreUndoState();
3415>>>>>>> 9f75eaf50e42ef6409fc272ba33a817241907ed8
3216 3416
3217 if (part != null) 3417 if (part != null)
3218 { 3418 {
3419// m_log.DebugFormat(
3420// "[SCENE OBJECT GROUP]: Updating single position of {0} {1} to {2}", part.Name, part.LocalId, pos);
3421
3422 part.StoreUndoState(false);
3423 part.IgnoreUndoUpdate = true;
3424
3219 if (part.UUID == m_rootPart.UUID) 3425 if (part.UUID == m_rootPart.UUID)
3220 { 3426 {
3221 UpdateRootPosition(pos); 3427 UpdateRootPosition(pos);
@@ -3226,18 +3432,28 @@ namespace OpenSim.Region.Framework.Scenes
3226 } 3432 }
3227 3433
3228 HasGroupChanged = true; 3434 HasGroupChanged = true;
3435 part.IgnoreUndoUpdate = false;
3229 } 3436 }
3230 } 3437 }
3231 3438
3232 /// <summary> 3439 /// <summary>
3233 /// 3440 /// Update just the root prim position in a linkset
3234 /// </summary> 3441 /// </summary>
3235 /// <param name="pos"></param> 3442 /// <param name="pos"></param>
3236 private void UpdateRootPosition(Vector3 pos) 3443 public void UpdateRootPosition(Vector3 pos)
3237 { 3444 {
3445<<<<<<< HEAD
3238 SceneObjectPart[] parts = m_parts.GetArray(); 3446 SceneObjectPart[] parts = m_parts.GetArray();
3239 for (int i = 0; i < parts.Length; i++) 3447 for (int i = 0; i < parts.Length; i++)
3240 parts[i].StoreUndoState(UndoType.STATE_PRIM_POSITION); 3448 parts[i].StoreUndoState(UndoType.STATE_PRIM_POSITION);
3449=======
3450// m_log.DebugFormat(
3451// "[SCENE OBJECT GROUP]: Updating root position of {0} {1} to {2}", Name, LocalId, pos);
3452
3453// SceneObjectPart[] parts = m_parts.GetArray();
3454// for (int i = 0; i < parts.Length; i++)
3455// parts[i].StoreUndoState();
3456>>>>>>> 9f75eaf50e42ef6409fc272ba33a817241907ed8
3241 3457
3242 Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); 3458 Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z);
3243 Vector3 oldPos = 3459 Vector3 oldPos =
@@ -3250,7 +3466,7 @@ namespace OpenSim.Region.Framework.Scenes
3250 axDiff *= Quaternion.Inverse(partRotation); 3466 axDiff *= Quaternion.Inverse(partRotation);
3251 diff = axDiff; 3467 diff = axDiff;
3252 3468
3253 parts = m_parts.GetArray(); 3469 SceneObjectPart[] parts = m_parts.GetArray();
3254 for (int i = 0; i < parts.Length; i++) 3470 for (int i = 0; i < parts.Length; i++)
3255 { 3471 {
3256 SceneObjectPart obPart = parts[i]; 3472 SceneObjectPart obPart = parts[i];
@@ -3296,9 +3512,20 @@ namespace OpenSim.Region.Framework.Scenes
3296 /// <param name="rot"></param> 3512 /// <param name="rot"></param>
3297 public void UpdateGroupRotationR(Quaternion rot) 3513 public void UpdateGroupRotationR(Quaternion rot)
3298 { 3514 {
3515<<<<<<< HEAD
3299 SceneObjectPart[] parts = m_parts.GetArray(); 3516 SceneObjectPart[] parts = m_parts.GetArray();
3300 for (int i = 0; i < parts.Length; i++) 3517 for (int i = 0; i < parts.Length; i++)
3301 parts[i].StoreUndoState(UndoType.STATE_GROUP_ROTATION); 3518 parts[i].StoreUndoState(UndoType.STATE_GROUP_ROTATION);
3519=======
3520// m_log.DebugFormat(
3521// "[SCENE OBJECT GROUP]: Updating group rotation R of {0} {1} to {2}", Name, LocalId, rot);
3522
3523// SceneObjectPart[] parts = m_parts.GetArray();
3524// for (int i = 0; i < parts.Length; i++)
3525// parts[i].StoreUndoState();
3526
3527 m_rootPart.StoreUndoState(true);
3528>>>>>>> 9f75eaf50e42ef6409fc272ba33a817241907ed8
3302 3529
3303 m_rootPart.UpdateRotation(rot); 3530 m_rootPart.UpdateRotation(rot);
3304 3531
@@ -3320,9 +3547,21 @@ namespace OpenSim.Region.Framework.Scenes
3320 /// <param name="rot"></param> 3547 /// <param name="rot"></param>
3321 public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot) 3548 public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot)
3322 { 3549 {
3550<<<<<<< HEAD
3323 SceneObjectPart[] parts = m_parts.GetArray(); 3551 SceneObjectPart[] parts = m_parts.GetArray();
3324 for (int i = 0; i < parts.Length; i++) 3552 for (int i = 0; i < parts.Length; i++)
3325 parts[i].StoreUndoState(UndoType.STATE_GROUP_ROTATION); 3553 parts[i].StoreUndoState(UndoType.STATE_GROUP_ROTATION);
3554=======
3555// m_log.DebugFormat(
3556// "[SCENE OBJECT GROUP]: Updating group rotation PR of {0} {1} to {2}", Name, LocalId, rot);
3557
3558// SceneObjectPart[] parts = m_parts.GetArray();
3559// for (int i = 0; i < parts.Length; i++)
3560// parts[i].StoreUndoState();
3561
3562 RootPart.StoreUndoState(true);
3563 RootPart.IgnoreUndoUpdate = true;
3564>>>>>>> 9f75eaf50e42ef6409fc272ba33a817241907ed8
3326 3565
3327 m_rootPart.UpdateRotation(rot); 3566 m_rootPart.UpdateRotation(rot);
3328 3567
@@ -3337,6 +3576,8 @@ namespace OpenSim.Region.Framework.Scenes
3337 3576
3338 HasGroupChanged = true; 3577 HasGroupChanged = true;
3339 ScheduleGroupForTerseUpdate(); 3578 ScheduleGroupForTerseUpdate();
3579
3580 RootPart.IgnoreUndoUpdate = false;
3340 } 3581 }
3341 3582
3342 /// <summary> 3583 /// <summary>
@@ -3353,6 +3594,9 @@ namespace OpenSim.Region.Framework.Scenes
3353 3594
3354 if (part != null) 3595 if (part != null)
3355 { 3596 {
3597// m_log.DebugFormat(
3598// "[SCENE OBJECT GROUP]: Updating single rotation of {0} {1} to {2}", part.Name, part.LocalId, rot);
3599
3356 if (part.UUID == m_rootPart.UUID) 3600 if (part.UUID == m_rootPart.UUID)
3357 { 3601 {
3358 UpdateRootRotation(rot); 3602 UpdateRootRotation(rot);
@@ -3374,6 +3618,13 @@ namespace OpenSim.Region.Framework.Scenes
3374 SceneObjectPart part = GetChildPart(localID); 3618 SceneObjectPart part = GetChildPart(localID);
3375 if (part != null) 3619 if (part != null)
3376 { 3620 {
3621// m_log.DebugFormat(
3622// "[SCENE OBJECT GROUP]: Updating single position and rotation of {0} {1} to {2}",
3623// part.Name, part.LocalId, rot);
3624
3625 part.StoreUndoState();
3626 part.IgnoreUndoUpdate = true;
3627
3377 if (part.UUID == m_rootPart.UUID) 3628 if (part.UUID == m_rootPart.UUID)
3378 { 3629 {
3379 UpdateRootRotation(rot); 3630 UpdateRootRotation(rot);
@@ -3390,12 +3641,19 @@ namespace OpenSim.Region.Framework.Scenes
3390 } 3641 }
3391 else 3642 else
3392 { 3643 {
3644<<<<<<< HEAD
3393 part.StoreUndoState(UndoType.STATE_PRIM_ROTATION); 3645 part.StoreUndoState(UndoType.STATE_PRIM_ROTATION);
3394 part.IgnoreUndoUpdate = true; 3646 part.IgnoreUndoUpdate = true;
3395 part.UpdateRotation(rot); 3647 part.UpdateRotation(rot);
3396 part.OffsetPosition = pos; 3648 part.OffsetPosition = pos;
3397 part.IgnoreUndoUpdate = false; 3649 part.IgnoreUndoUpdate = false;
3650=======
3651 part.UpdateRotation(rot);
3652 part.OffsetPosition = pos;
3653>>>>>>> 9f75eaf50e42ef6409fc272ba33a817241907ed8
3398 } 3654 }
3655
3656 part.IgnoreUndoUpdate = false;
3399 } 3657 }
3400 } 3658 }
3401 3659
@@ -3403,8 +3661,12 @@ namespace OpenSim.Region.Framework.Scenes
3403 /// 3661 ///
3404 /// </summary> 3662 /// </summary>
3405 /// <param name="rot"></param> 3663 /// <param name="rot"></param>
3406 private void UpdateRootRotation(Quaternion rot) 3664 public void UpdateRootRotation(Quaternion rot)
3407 { 3665 {
3666// m_log.DebugFormat(
3667// "[SCENE OBJECT GROUP]: Updating root rotation of {0} {1} to {2}",
3668// Name, LocalId, rot);
3669
3408 Quaternion axRot = rot; 3670 Quaternion axRot = rot;
3409 Quaternion oldParentRot = m_rootPart.RotationOffset; 3671 Quaternion oldParentRot = m_rootPart.RotationOffset;
3410 3672
@@ -3436,6 +3698,7 @@ namespace OpenSim.Region.Framework.Scenes
3436 axPos *= oldParentRot; 3698 axPos *= oldParentRot;
3437 axPos *= Quaternion.Inverse(axRot); 3699 axPos *= Quaternion.Inverse(axRot);
3438 prim.OffsetPosition = axPos; 3700 prim.OffsetPosition = axPos;
3701<<<<<<< HEAD
3439 3702
3440 prim.RotationOffset *= Quaternion.Inverse(prim.GetWorldRotation()) * (oldParentRot * prim.RotationOffset); 3703 prim.RotationOffset *= Quaternion.Inverse(prim.GetWorldRotation()) * (oldParentRot * prim.RotationOffset);
3441 3704
@@ -3448,6 +3711,32 @@ namespace OpenSim.Region.Framework.Scenes
3448 } 3711 }
3449 HasGroupChanged = true; 3712 HasGroupChanged = true;
3450 ScheduleGroupForFullUpdate(); 3713 ScheduleGroupForFullUpdate();
3714=======
3715 Quaternion primsRot = prim.RotationOffset;
3716 Quaternion newRot = primsRot * oldParentRot;
3717 newRot *= Quaternion.Inverse(axRot);
3718 prim.RotationOffset = newRot;
3719 prim.ScheduleTerseUpdate();
3720 prim.IgnoreUndoUpdate = false;
3721 }
3722 }
3723
3724// for (int i = 0; i < parts.Length; i++)
3725// {
3726// SceneObjectPart childpart = parts[i];
3727// if (childpart != m_rootPart)
3728// {
3729//// childpart.IgnoreUndoUpdate = false;
3730//// childpart.StoreUndoState();
3731// }
3732// }
3733
3734 m_rootPart.ScheduleTerseUpdate();
3735
3736// m_log.DebugFormat(
3737// "[SCENE OBJECT GROUP]: Updated root rotation of {0} {1} to {2}",
3738// Name, LocalId, rot);
3739>>>>>>> 9f75eaf50e42ef6409fc272ba33a817241907ed8
3451 } 3740 }
3452 3741
3453 #endregion 3742 #endregion
@@ -3462,28 +3751,23 @@ namespace OpenSim.Region.Framework.Scenes
3462 int yaxis = 4; 3751 int yaxis = 4;
3463 int zaxis = 8; 3752 int zaxis = 8;
3464 3753
3465 if (m_rootPart != null) 3754 setX = ((axis & xaxis) != 0) ? true : false;
3466 { 3755 setY = ((axis & yaxis) != 0) ? true : false;
3467 setX = ((axis & xaxis) != 0) ? true : false; 3756 setZ = ((axis & zaxis) != 0) ? true : false;
3468 setY = ((axis & yaxis) != 0) ? true : false;
3469 setZ = ((axis & zaxis) != 0) ? true : false;
3470 3757
3471 float setval = (rotate10 > 0) ? 1f : 0f; 3758 float setval = (rotate10 > 0) ? 1f : 0f;
3472 3759
3473 if (setX) 3760 if (setX)
3474 m_rootPart.RotationAxis.X = setval; 3761 RootPart.RotationAxis.X = setval;
3475 if (setY) 3762 if (setY)
3476 m_rootPart.RotationAxis.Y = setval; 3763 RootPart.RotationAxis.Y = setval;
3477 if (setZ) 3764 if (setZ)
3478 m_rootPart.RotationAxis.Z = setval; 3765 RootPart.RotationAxis.Z = setval;
3479 3766
3480 if (setX || setY || setZ) 3767 if (setX || setY || setZ)
3481 { 3768 RootPart.SetPhysicsAxisRotation();
3482 m_rootPart.SetPhysicsAxisRotation();
3483 }
3484
3485 }
3486 } 3769 }
3770
3487 public int registerRotTargetWaypoint(Quaternion target, float tolerance) 3771 public int registerRotTargetWaypoint(Quaternion target, float tolerance)
3488 { 3772 {
3489 scriptRotTarget waypoint = new scriptRotTarget(); 3773 scriptRotTarget waypoint = new scriptRotTarget();
@@ -3611,7 +3895,13 @@ namespace OpenSim.Region.Framework.Scenes
3611 foreach (uint idx in m_rotTargets.Keys) 3895 foreach (uint idx in m_rotTargets.Keys)
3612 { 3896 {
3613 scriptRotTarget target = m_rotTargets[idx]; 3897 scriptRotTarget target = m_rotTargets[idx];
3614 double angle = Math.Acos(target.targetRot.X * m_rootPart.RotationOffset.X + target.targetRot.Y * m_rootPart.RotationOffset.Y + target.targetRot.Z * m_rootPart.RotationOffset.Z + target.targetRot.W * m_rootPart.RotationOffset.W) * 2; 3898 double angle
3899 = Math.Acos(
3900 target.targetRot.X * m_rootPart.RotationOffset.X
3901 + target.targetRot.Y * m_rootPart.RotationOffset.Y
3902 + target.targetRot.Z * m_rootPart.RotationOffset.Z
3903 + target.targetRot.W * m_rootPart.RotationOffset.W)
3904 * 2;
3615 if (angle < 0) angle = -angle; 3905 if (angle < 0) angle = -angle;
3616 if (angle > Math.PI) angle = (Math.PI * 2 - angle); 3906 if (angle > Math.PI) angle = (Math.PI * 2 - angle);
3617 if (angle <= target.tolerance) 3907 if (angle <= target.tolerance)
@@ -3676,43 +3966,28 @@ namespace OpenSim.Region.Framework.Scenes
3676 3966
3677 return retmass; 3967 return retmass;
3678 } 3968 }
3679 3969
3970 /// <summary>
3971 /// If the object is a sculpt/mesh, retrieve the mesh data for each part and reinsert it into each shape so that
3972 /// the physics engine can use it.
3973 /// </summary>
3974 /// <remarks>
3975 /// When the physics engine has finished with it, the sculpt data is discarded to save memory.
3976 /// </remarks>
3680 public void CheckSculptAndLoad() 3977 public void CheckSculptAndLoad()
3681 { 3978 {
3682 if (IsDeleted) 3979 if (IsDeleted)
3683 return; 3980 return;
3981
3684 if ((RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0) 3982 if ((RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0)
3685 return; 3983 return;
3686 3984
3687 SceneObjectPart[] parts = m_parts.GetArray(); 3985// m_log.Debug("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId);
3688 for (int i = 0; i < parts.Length; i++)
3689 {
3690 SceneObjectPart part = parts[i];
3691 if (part.Shape.SculptEntry && part.Shape.SculptTexture != UUID.Zero)
3692 {
3693 // check if a previously decoded sculpt map has been cached
3694 if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + part.Shape.SculptTexture.ToString())))
3695 {
3696 part.SculptTextureCallback(part.Shape.SculptTexture, null);
3697 }
3698 else
3699 {
3700 m_scene.AssetService.Get(
3701 part.Shape.SculptTexture.ToString(), part, AssetReceived);
3702 }
3703 }
3704 }
3705 }
3706 3986
3707 protected void AssetReceived(string id, Object sender, AssetBase asset) 3987 SceneObjectPart[] parts = m_parts.GetArray();
3708 {
3709 SceneObjectPart sop = (SceneObjectPart)sender;
3710 3988
3711 if (sop != null) 3989 for (int i = 0; i < parts.Length; i++)
3712 { 3990 parts[i].CheckSculptAndLoad();
3713 if (asset != null)
3714 sop.SculptTextureCallback(asset.FullID, asset);
3715 }
3716 } 3991 }
3717 3992
3718 /// <summary> 3993 /// <summary>
@@ -3747,19 +4022,12 @@ namespace OpenSim.Region.Framework.Scenes
3747 return String.Format("{0} {1} ({2})", Name, UUID, AbsolutePosition); 4022 return String.Format("{0} {1} ({2})", Name, UUID, AbsolutePosition);
3748 } 4023 }
3749 4024
3750 public void SetAttachmentPoint(byte point)
3751 {
3752 SceneObjectPart[] parts = m_parts.GetArray();
3753 for (int i = 0; i < parts.Length; i++)
3754 parts[i].SetAttachmentPoint(point);
3755 }
3756
3757 #region ISceneObject 4025 #region ISceneObject
3758 4026
3759 public virtual ISceneObject CloneForNewScene() 4027 public virtual ISceneObject CloneForNewScene()
3760 { 4028 {
3761 SceneObjectGroup sog = Copy(false); 4029 SceneObjectGroup sog = Copy(false);
3762 sog.m_isDeleted = false; 4030 sog.IsDeleted = false;
3763 return sog; 4031 return sog;
3764 } 4032 }
3765 4033
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 037f384..893faf8 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Drawing; 30using System.Drawing;
31using System.IO;
31using System.Reflection; 32using System.Reflection;
32using System.Runtime.Serialization; 33using System.Runtime.Serialization;
33using System.Security.Permissions; 34using System.Security.Permissions;
@@ -216,28 +217,18 @@ namespace OpenSim.Region.Framework.Scenes
216 /// </value> 217 /// </value>
217 private UUID m_fromUserInventoryItemID; 218 private UUID m_fromUserInventoryItemID;
218 219
219
220 public UUID FromUserInventoryItemID 220 public UUID FromUserInventoryItemID
221 { 221 {
222 get { return m_fromUserInventoryItemID; } 222 get { return m_fromUserInventoryItemID; }
223 set { m_fromUserInventoryItemID = value; }
223 } 224 }
224 225
225
226 public bool IsAttachment;
227
228
229 public scriptEvents AggregateScriptEvents; 226 public scriptEvents AggregateScriptEvents;
230 227
231 228
232 public UUID AttachedAvatar;
233
234
235 public Vector3 AttachedPos; 229 public Vector3 AttachedPos;
236 230
237 231
238 public uint AttachmentPoint;
239
240
241 public Vector3 RotationAxis = Vector3.One; 232 public Vector3 RotationAxis = Vector3.One;
242 233
243 234
@@ -269,12 +260,9 @@ namespace OpenSim.Region.Framework.Scenes
269 } 260 }
270 protected SceneObjectPartInventory m_inventory; 261 protected SceneObjectPartInventory m_inventory;
271 262
272
273 public bool Undoing; 263 public bool Undoing;
274
275 264
276 public bool IgnoreUndoUpdate = false; 265 public bool IgnoreUndoUpdate = false;
277
278 266
279 private PrimFlags LocalFlags; 267 private PrimFlags LocalFlags;
280 268
@@ -296,8 +284,8 @@ namespace OpenSim.Region.Framework.Scenes
296 private bool m_occupied; // KF if any av is sitting on this prim 284 private bool m_occupied; // KF if any av is sitting on this prim
297 private string m_text = String.Empty; 285 private string m_text = String.Empty;
298 private string m_touchName = String.Empty; 286 private string m_touchName = String.Empty;
299 private readonly UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5); 287 private readonly Stack<UndoState> m_undo = new Stack<UndoState>(5);
300 private readonly UndoStack<UndoState> m_redo = new UndoStack<UndoState>(5); 288 private readonly Stack<UndoState> m_redo = new Stack<UndoState>(5);
301 private UUID _creatorID; 289 private UUID _creatorID;
302 290
303 private bool m_passTouches; 291 private bool m_passTouches;
@@ -323,7 +311,6 @@ namespace OpenSim.Region.Framework.Scenes
323 protected string m_name; 311 protected string m_name;
324 protected Vector3 m_offsetPosition; 312 protected Vector3 m_offsetPosition;
325 313
326 // FIXME, TODO, ERROR: 'ParentGroup' can't be in here, move it out.
327 protected SceneObjectGroup m_parentGroup; 314 protected SceneObjectGroup m_parentGroup;
328 protected byte[] m_particleSystem = Utils.EmptyBytes; 315 protected byte[] m_particleSystem = Utils.EmptyBytes;
329 protected ulong m_regionHandle; 316 protected ulong m_regionHandle;
@@ -424,7 +411,6 @@ namespace OpenSim.Region.Framework.Scenes
424 CreateSelected = true; 411 CreateSelected = true;
425 412
426 TrimPermissions(); 413 TrimPermissions();
427 //m_undo = new UndoStack<UndoState>(ParentGroup.GetSceneMaxUndo());
428 414
429 m_inventory = new SceneObjectPartInventory(this); 415 m_inventory = new SceneObjectPartInventory(this);
430 } 416 }
@@ -619,6 +605,7 @@ namespace OpenSim.Region.Framework.Scenes
619 set 605 set
620 { 606 {
621 m_passTouches = value; 607 m_passTouches = value;
608
622 if (ParentGroup != null) 609 if (ParentGroup != null)
623 ParentGroup.HasGroupChanged = true; 610 ParentGroup.HasGroupChanged = true;
624 } 611 }
@@ -744,9 +731,9 @@ namespace OpenSim.Region.Framework.Scenes
744 return m_groupPosition; 731 return m_groupPosition;
745 } 732 }
746 733
747 if (IsAttachment) 734 if (m_parentGroup.IsAttachment)
748 { 735 {
749 ScenePresence sp = m_parentGroup.Scene.GetScenePresence(AttachedAvatar); 736 ScenePresence sp = m_parentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar);
750 if (sp != null) 737 if (sp != null)
751 return sp.AbsolutePosition; 738 return sp.AbsolutePosition;
752 } 739 }
@@ -794,7 +781,6 @@ namespace OpenSim.Region.Framework.Scenes
794 set 781 set
795 { 782 {
796 Vector3 oldpos = m_offsetPosition; 783 Vector3 oldpos = m_offsetPosition;
797 StoreUndoState(UndoType.STATE_PRIM_POSITION);
798 m_offsetPosition = value; 784 m_offsetPosition = value;
799 785
800 if (ParentGroup != null && !ParentGroup.IsDeleted) 786 if (ParentGroup != null && !ParentGroup.IsDeleted)
@@ -834,7 +820,7 @@ namespace OpenSim.Region.Framework.Scenes
834 { 820 {
835 if (IsRoot) 821 if (IsRoot)
836 { 822 {
837 if (IsAttachment) 823 if (m_parentGroup.IsAttachment)
838 return AttachedPos; 824 return AttachedPos;
839 else 825 else
840 return AbsolutePosition; 826 return AbsolutePosition;
@@ -887,7 +873,9 @@ namespace OpenSim.Region.Framework.Scenes
887 actor.Orientation = resultingrotation; 873 actor.Orientation = resultingrotation;
888 //m_log.Info("[PART]: RO2:" + actor.Orientation.ToString()); 874 //m_log.Info("[PART]: RO2:" + actor.Orientation.ToString());
889 } 875 }
890 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 876
877 if (m_parentGroup != null)
878 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
891 //} 879 //}
892 } 880 }
893 catch (Exception ex) 881 catch (Exception ex)
@@ -895,7 +883,6 @@ namespace OpenSim.Region.Framework.Scenes
895 m_log.Error("[SCENEOBJECTPART]: ROTATIONOFFSET" + ex.Message); 883 m_log.Error("[SCENEOBJECTPART]: ROTATIONOFFSET" + ex.Message);
896 } 884 }
897 } 885 }
898
899 } 886 }
900 } 887 }
901 888
@@ -1044,30 +1031,39 @@ namespace OpenSim.Region.Framework.Scenes
1044 get { return m_shape; } 1031 get { return m_shape; }
1045 set { m_shape = value; } 1032 set { m_shape = value; }
1046 } 1033 }
1047 1034
1035 /// <summary>
1036 /// Change the scale of this part.
1037 /// </summary>
1048 public Vector3 Scale 1038 public Vector3 Scale
1049 { 1039 {
1050 get { return m_shape.Scale; } 1040 get { return m_shape.Scale; }
1051 set 1041 set
1052 { 1042 {
1053 StoreUndoState(UndoType.STATE_PRIM_SCALE);
1054 if (m_shape != null) 1043 if (m_shape != null)
1055 { 1044 {
1045 StoreUndoState();
1046
1056 m_shape.Scale = value; 1047 m_shape.Scale = value;
1057 1048
1058 PhysicsActor actor = PhysActor; 1049 PhysicsActor actor = PhysActor;
1059 if (actor != null && m_parentGroup != null) 1050 if (actor != null)
1060 { 1051 {
1061 if (m_parentGroup.Scene != null) 1052 if (m_parentGroup.Scene != null)
1062 { 1053 {
1063 if (m_parentGroup.Scene.PhysicsScene != null) 1054 if (m_parentGroup.Scene.PhysicsScene != null)
1064 { 1055 {
1065 actor.Size = m_shape.Scale; 1056 actor.Size = m_shape.Scale;
1066 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 1057
1058 if (Shape.SculptEntry)
1059 CheckSculptAndLoad();
1060 else
1061 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
1067 } 1062 }
1068 } 1063 }
1069 } 1064 }
1070 } 1065 }
1066
1071 TriggerScriptChangedEvent(Changed.SCALE); 1067 TriggerScriptChangedEvent(Changed.SCALE);
1072 } 1068 }
1073 } 1069 }
@@ -1092,13 +1088,12 @@ namespace OpenSim.Region.Framework.Scenes
1092 set 1088 set
1093 { 1089 {
1094 m_mediaUrl = value; 1090 m_mediaUrl = value;
1095 1091
1096 if (ParentGroup != null) 1092 if (ParentGroup != null)
1097 ParentGroup.HasGroupChanged = true; 1093 ParentGroup.HasGroupChanged = true;
1098 } 1094 }
1099 } 1095 }
1100 1096
1101
1102 public bool CreateSelected 1097 public bool CreateSelected
1103 { 1098 {
1104 get { return m_createSelected; } 1099 get { return m_createSelected; }
@@ -1118,7 +1113,10 @@ namespace OpenSim.Region.Framework.Scenes
1118 { 1113 {
1119 get 1114 get
1120 { 1115 {
1121 return GroupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset); 1116 if (m_parentGroup.IsAttachment)
1117 return GroupPosition;
1118
1119 return m_offsetPosition + m_groupPosition;
1122 } 1120 }
1123 } 1121 }
1124 1122
@@ -1138,7 +1136,6 @@ namespace OpenSim.Region.Framework.Scenes
1138 set { m_sitTargetOrientation = value; } 1136 set { m_sitTargetOrientation = value; }
1139 } 1137 }
1140 1138
1141
1142 public Vector3 SitTargetPosition 1139 public Vector3 SitTargetPosition
1143 { 1140 {
1144 get { return m_sitTargetPosition; } 1141 get { return m_sitTargetPosition; }
@@ -1268,7 +1265,9 @@ namespace OpenSim.Region.Framework.Scenes
1268 /// <summary> 1265 /// <summary>
1269 /// Property flags. See OpenMetaverse.PrimFlags 1266 /// Property flags. See OpenMetaverse.PrimFlags
1270 /// </summary> 1267 /// </summary>
1268 /// <remarks>
1271 /// Example properties are PrimFlags.Phantom and PrimFlags.DieAtEdge 1269 /// Example properties are PrimFlags.Phantom and PrimFlags.DieAtEdge
1270 /// </remarks>
1272 public PrimFlags Flags 1271 public PrimFlags Flags
1273 { 1272 {
1274 get { return _flags; } 1273 get { return _flags; }
@@ -1298,7 +1297,7 @@ namespace OpenSim.Region.Framework.Scenes
1298 { 1297 {
1299 get 1298 get
1300 { 1299 {
1301 if (ParentGroup != null && ParentGroup.Scene != null) 1300 if (ParentGroup.Scene != null)
1302 return ParentGroup.Scene.RegionInfo.RegionID; 1301 return ParentGroup.Scene.RegionInfo.RegionID;
1303 else 1302 else
1304 return UUID.Zero; 1303 return UUID.Zero;
@@ -1313,14 +1312,13 @@ namespace OpenSim.Region.Framework.Scenes
1313 get 1312 get
1314 { 1313 {
1315 if (ParentGroup != null) 1314 if (ParentGroup != null)
1316 {
1317 _parentUUID = ParentGroup.UUID; 1315 _parentUUID = ParentGroup.UUID;
1318 } 1316
1319 return _parentUUID; 1317 return _parentUUID;
1320 } 1318 }
1319
1321 set { _parentUUID = value; } 1320 set { _parentUUID = value; }
1322 } 1321 }
1323
1324 1322
1325 public string SitAnimation 1323 public string SitAnimation
1326 { 1324 {
@@ -1555,10 +1553,7 @@ namespace OpenSim.Region.Framework.Scenes
1555 impulse = newimpulse; 1553 impulse = newimpulse;
1556 } 1554 }
1557 1555
1558 if (m_parentGroup != null) 1556 m_parentGroup.applyAngularImpulse(impulse);
1559 {
1560 m_parentGroup.applyAngularImpulse(impulse);
1561 }
1562 } 1557 }
1563 1558
1564 /// <summary> 1559 /// <summary>
@@ -1581,19 +1576,7 @@ namespace OpenSim.Region.Framework.Scenes
1581 impulse = newimpulse; 1576 impulse = newimpulse;
1582 } 1577 }
1583 1578
1584 if (m_parentGroup != null) 1579 m_parentGroup.setAngularImpulse(impulse);
1585 {
1586 m_parentGroup.setAngularImpulse(impulse);
1587 }
1588 }
1589
1590 public Vector3 GetTorque()
1591 {
1592 if (m_parentGroup != null)
1593 {
1594 m_parentGroup.GetTorque();
1595 }
1596 return Vector3.Zero;
1597 } 1580 }
1598 1581
1599 /// <summary> 1582 /// <summary>
@@ -1623,7 +1606,7 @@ namespace OpenSim.Region.Framework.Scenes
1623 1606
1624 // The only time the physics scene shouldn't know about the prim is if it's phantom or an attachment, which is phantom by definition 1607 // The only time the physics scene shouldn't know about the prim is if it's phantom or an attachment, which is phantom by definition
1625 // or flexible 1608 // or flexible
1626 if (!isPhantom && !IsAttachment && !(Shape.PathCurve == (byte) Extrusion.Flexible)) 1609 if (!isPhantom && !m_parentGroup.IsAttachment && !(Shape.PathCurve == (byte) Extrusion.Flexible))
1627 { 1610 {
1628 try 1611 try
1629 { 1612 {
@@ -1635,7 +1618,6 @@ namespace OpenSim.Region.Framework.Scenes
1635 RotationOffset, 1618 RotationOffset,
1636 RigidBody, 1619 RigidBody,
1637 m_localId); 1620 m_localId);
1638 PhysActor.SetMaterial(Material);
1639 } 1621 }
1640 catch 1622 catch
1641 { 1623 {
@@ -1647,6 +1629,7 @@ namespace OpenSim.Region.Framework.Scenes
1647 { 1629 {
1648 PhysActor.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info 1630 PhysActor.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info
1649 PhysActor.SOPDescription = this.Description; 1631 PhysActor.SOPDescription = this.Description;
1632 PhysActor.SetMaterial(Material);
1650 DoPhysicsPropertyUpdate(RigidBody, true); 1633 DoPhysicsPropertyUpdate(RigidBody, true);
1651 PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0); 1634 PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0);
1652 } 1635 }
@@ -1658,19 +1641,6 @@ namespace OpenSim.Region.Framework.Scenes
1658 } 1641 }
1659 } 1642 }
1660 1643
1661 public void ClearUndoState()
1662 {
1663 lock (m_undo)
1664 {
1665 m_undo.Clear();
1666 }
1667 lock (m_redo)
1668 {
1669 m_redo.Clear();
1670 }
1671 StoreUndoState(UndoType.STATE_ALL);
1672 }
1673
1674 public byte ConvertScriptUintToByte(uint indata) 1644 public byte ConvertScriptUintToByte(uint indata)
1675 { 1645 {
1676 byte outdata = (byte)TextureAnimFlags.NONE; 1646 byte outdata = (byte)TextureAnimFlags.NONE;
@@ -1751,7 +1721,8 @@ namespace OpenSim.Region.Framework.Scenes
1751 { 1721 {
1752 if (dupe.m_shape.SculptEntry && dupe.m_shape.SculptTexture != UUID.Zero) 1722 if (dupe.m_shape.SculptEntry && dupe.m_shape.SculptTexture != UUID.Zero)
1753 { 1723 {
1754 m_parentGroup.Scene.AssetService.Get(dupe.m_shape.SculptTexture.ToString(), dupe, AssetReceived); 1724 ParentGroup.Scene.AssetService.Get(
1725 dupe.m_shape.SculptTexture.ToString(), dupe, dupe.AssetReceived);
1755 } 1726 }
1756 1727
1757 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0); 1728 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0);
@@ -1765,14 +1736,20 @@ namespace OpenSim.Region.Framework.Scenes
1765 return dupe; 1736 return dupe;
1766 } 1737 }
1767 1738
1739 /// <summary>
1740 /// Called back by asynchronous asset fetch.
1741 /// </summary>
1742 /// <param name="id">ID of asset received</param>
1743 /// <param name="sender">Register</param>
1744 /// <param name="asset"></param>
1768 protected void AssetReceived(string id, Object sender, AssetBase asset) 1745 protected void AssetReceived(string id, Object sender, AssetBase asset)
1769 { 1746 {
1770 if (asset != null) 1747 if (asset != null)
1771 { 1748 SculptTextureCallback(asset);
1772 SceneObjectPart sop = (SceneObjectPart)sender; 1749 else
1773 if (sop != null) 1750 m_log.WarnFormat(
1774 sop.SculptTextureCallback(asset.FullID, asset); 1751 "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data",
1775 } 1752 Name, LocalId, id);
1776 } 1753 }
1777 1754
1778 public static SceneObjectPart Create() 1755 public static SceneObjectPart Create()
@@ -1789,97 +1766,111 @@ namespace OpenSim.Region.Framework.Scenes
1789 return part; 1766 return part;
1790 } 1767 }
1791 1768
1792 public void DoPhysicsPropertyUpdate(bool UsePhysics, bool isNew) 1769 /// <summary>
1770 /// Do a physics property update for a NINJA joint.
1771 /// </summary>
1772 /// <param name="UsePhysics"></param>
1773 /// <param name="isNew"></param>
1774 protected void DoPhysicsPropertyUpdateForNinjaJoint(bool UsePhysics, bool isNew)
1793 { 1775 {
1794 if (IsJoint()) 1776 if (UsePhysics)
1795 { 1777 {
1796 if (UsePhysics) 1778 // by turning a joint proxy object physical, we cause creation of a joint in the ODE scene.
1797 { 1779 // note that, as a special case, joints have no bodies or geoms in the physics scene, even though they are physical.
1798 // by turning a joint proxy object physical, we cause creation of a joint in the ODE scene.
1799 // note that, as a special case, joints have no bodies or geoms in the physics scene, even though they are physical.
1800 1780
1801 PhysicsJointType jointType; 1781 PhysicsJointType jointType;
1802 if (IsHingeJoint()) 1782 if (IsHingeJoint())
1803 { 1783 {
1804 jointType = PhysicsJointType.Hinge; 1784 jointType = PhysicsJointType.Hinge;
1805 } 1785 }
1806 else if (IsBallJoint()) 1786 else if (IsBallJoint())
1807 { 1787 {
1808 jointType = PhysicsJointType.Ball; 1788 jointType = PhysicsJointType.Ball;
1809 } 1789 }
1810 else 1790 else
1811 { 1791 {
1812 jointType = PhysicsJointType.Ball; 1792 jointType = PhysicsJointType.Ball;
1813 } 1793 }
1814 1794
1815 List<string> bodyNames = new List<string>(); 1795 List<string> bodyNames = new List<string>();
1816 string RawParams = Description; 1796 string RawParams = Description;
1817 string[] jointParams = RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries); 1797 string[] jointParams = RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries);
1818 string trackedBodyName = null; 1798 string trackedBodyName = null;
1819 if (jointParams.Length >= 2) 1799 if (jointParams.Length >= 2)
1800 {
1801 for (int iBodyName = 0; iBodyName < 2; iBodyName++)
1820 { 1802 {
1821 for (int iBodyName = 0; iBodyName < 2; iBodyName++) 1803 string bodyName = jointParams[iBodyName];
1804 bodyNames.Add(bodyName);
1805 if (bodyName != "NULL")
1822 { 1806 {
1823 string bodyName = jointParams[iBodyName]; 1807 if (trackedBodyName == null)
1824 bodyNames.Add(bodyName);
1825 if (bodyName != "NULL")
1826 { 1808 {
1827 if (trackedBodyName == null) 1809 trackedBodyName = bodyName;
1828 {
1829 trackedBodyName = bodyName;
1830 }
1831 } 1810 }
1832 } 1811 }
1833 } 1812 }
1813 }
1834 1814
1835 SceneObjectPart trackedBody = m_parentGroup.Scene.GetSceneObjectPart(trackedBodyName); // FIXME: causes a sequential lookup 1815 SceneObjectPart trackedBody = m_parentGroup.Scene.GetSceneObjectPart(trackedBodyName); // FIXME: causes a sequential lookup
1836 Quaternion localRotation = Quaternion.Identity; 1816 Quaternion localRotation = Quaternion.Identity;
1837 if (trackedBody != null) 1817 if (trackedBody != null)
1838 { 1818 {
1839 localRotation = Quaternion.Inverse(trackedBody.RotationOffset) * this.RotationOffset; 1819 localRotation = Quaternion.Inverse(trackedBody.RotationOffset) * this.RotationOffset;
1840 } 1820 }
1841 else 1821 else
1842 { 1822 {
1843 // error, output it below 1823 // error, output it below
1844 } 1824 }
1845
1846 PhysicsJoint joint;
1847 1825
1848 joint = m_parentGroup.Scene.PhysicsScene.RequestJointCreation(Name, jointType, 1826 PhysicsJoint joint;
1849 AbsolutePosition,
1850 this.RotationOffset,
1851 Description,
1852 bodyNames,
1853 trackedBodyName,
1854 localRotation);
1855 1827
1856 if (trackedBody == null) 1828 joint = m_parentGroup.Scene.PhysicsScene.RequestJointCreation(Name, jointType,
1857 { 1829 AbsolutePosition,
1858 ParentGroup.Scene.jointErrorMessage(joint, "warning: tracked body name not found! joint location will not be updated properly. joint: " + Name); 1830 this.RotationOffset,
1859 } 1831 Description,
1832 bodyNames,
1833 trackedBodyName,
1834 localRotation);
1860 1835
1836 if (trackedBody == null)
1837 {
1838 ParentGroup.Scene.jointErrorMessage(joint, "warning: tracked body name not found! joint location will not be updated properly. joint: " + Name);
1839 }
1840 }
1841 else
1842 {
1843 if (isNew)
1844 {
1845 // if the joint proxy is new, and it is not physical, do nothing. There is no joint in ODE to
1846 // delete, and if we try to delete it, due to asynchronous processing, the deletion request
1847 // will get processed later at an indeterminate time, which could cancel a later-arriving
1848 // joint creation request.
1861 } 1849 }
1862 else 1850 else
1863 { 1851 {
1864 if (isNew) 1852 // here we turn off the joint object, so remove the joint from the physics scene
1865 { 1853 m_parentGroup.Scene.PhysicsScene.RequestJointDeletion(Name); // FIXME: what if the name changed?
1866 // if the joint proxy is new, and it is not physical, do nothing. There is no joint in ODE to
1867 // delete, and if we try to delete it, due to asynchronous processing, the deletion request
1868 // will get processed later at an indeterminate time, which could cancel a later-arriving
1869 // joint creation request.
1870 }
1871 else
1872 {
1873 // here we turn off the joint object, so remove the joint from the physics scene
1874 m_parentGroup.Scene.PhysicsScene.RequestJointDeletion(Name); // FIXME: what if the name changed?
1875 1854
1876 // make sure client isn't interpolating the joint proxy object 1855 // make sure client isn't interpolating the joint proxy object
1877 Velocity = Vector3.Zero; 1856 Velocity = Vector3.Zero;
1878 AngularVelocity = Vector3.Zero; 1857 AngularVelocity = Vector3.Zero;
1879 Acceleration = Vector3.Zero; 1858 Acceleration = Vector3.Zero;
1880 }
1881 } 1859 }
1882 } 1860 }
1861 }
1862
1863 /// <summary>
1864 /// Do a physics propery update for this part.
1865 /// </summary>
1866 /// <param name="UsePhysics"></param>
1867 /// <param name="isNew"></param>
1868 public void DoPhysicsPropertyUpdate(bool UsePhysics, bool isNew)
1869 {
1870 if (IsJoint())
1871 {
1872 DoPhysicsPropertyUpdateForNinjaJoint(UsePhysics, isNew);
1873 }
1883 else 1874 else
1884 { 1875 {
1885 if (PhysActor != null) 1876 if (PhysActor != null)
@@ -1919,7 +1910,6 @@ namespace OpenSim.Region.Framework.Scenes
1919 1910
1920 PhysActor.IsPhysical = UsePhysics; 1911 PhysActor.IsPhysical = UsePhysics;
1921 1912
1922
1923 // If we're not what we're supposed to be in the physics scene, recreate ourselves. 1913 // If we're not what we're supposed to be in the physics scene, recreate ourselves.
1924 //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 1914 //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor);
1925 /// that's not wholesome. Had to make Scene public 1915 /// that's not wholesome. Had to make Scene public
@@ -1943,7 +1933,13 @@ namespace OpenSim.Region.Framework.Scenes
1943 } 1933 }
1944 } 1934 }
1945 } 1935 }
1946 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 1936
1937 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the
1938 // mesh data.
1939 if (Shape.SculptEntry)
1940 CheckSculptAndLoad();
1941 else
1942 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
1947 } 1943 }
1948 } 1944 }
1949 } 1945 }
@@ -1955,22 +1951,11 @@ namespace OpenSim.Region.Framework.Scenes
1955 /// <returns></returns> 1951 /// <returns></returns>
1956 public static SceneObjectPart FromXml(XmlTextReader xmlReader) 1952 public static SceneObjectPart FromXml(XmlTextReader xmlReader)
1957 { 1953 {
1958 return FromXml(UUID.Zero, xmlReader);
1959 }
1960
1961 /// <summary>
1962 /// Restore this part from the serialized xml representation.
1963 /// </summary>
1964 /// <param name="fromUserInventoryItemId">The inventory id from which this part came, if applicable</param>
1965 /// <param name="xmlReader"></param>
1966 /// <returns></returns>
1967 public static SceneObjectPart FromXml(UUID fromUserInventoryItemId, XmlTextReader xmlReader)
1968 {
1969 SceneObjectPart part = SceneObjectSerializer.Xml2ToSOP(xmlReader); 1954 SceneObjectPart part = SceneObjectSerializer.Xml2ToSOP(xmlReader);
1970 part.m_fromUserInventoryItemID = fromUserInventoryItemId;
1971 1955
1972 // for tempOnRez objects, we have to fix the Expire date. 1956 // for tempOnRez objects, we have to fix the Expire date.
1973 if ((part.Flags & PrimFlags.TemporaryOnRez) != 0) part.ResetExpire(); 1957 if ((part.Flags & PrimFlags.TemporaryOnRez) != 0)
1958 part.ResetExpire();
1974 1959
1975 return part; 1960 return part;
1976 } 1961 }
@@ -1982,8 +1967,6 @@ namespace OpenSim.Region.Framework.Scenes
1982 1967
1983 public bool GetDieAtEdge() 1968 public bool GetDieAtEdge()
1984 { 1969 {
1985 if (m_parentGroup == null)
1986 return false;
1987 if (m_parentGroup.IsDeleted) 1970 if (m_parentGroup.IsDeleted)
1988 return false; 1971 return false;
1989 1972
@@ -1992,8 +1975,6 @@ namespace OpenSim.Region.Framework.Scenes
1992 1975
1993 public bool GetReturnAtEdge() 1976 public bool GetReturnAtEdge()
1994 { 1977 {
1995 if (m_parentGroup == null)
1996 return false;
1997 if (m_parentGroup.IsDeleted) 1978 if (m_parentGroup.IsDeleted)
1998 return false; 1979 return false;
1999 1980
@@ -2002,8 +1983,6 @@ namespace OpenSim.Region.Framework.Scenes
2002 1983
2003 public void SetReturnAtEdge(bool p) 1984 public void SetReturnAtEdge(bool p)
2004 { 1985 {
2005 if (m_parentGroup == null)
2006 return;
2007 if (m_parentGroup.IsDeleted) 1986 if (m_parentGroup.IsDeleted)
2008 return; 1987 return;
2009 1988
@@ -2012,8 +1991,6 @@ namespace OpenSim.Region.Framework.Scenes
2012 1991
2013 public bool GetBlockGrab() 1992 public bool GetBlockGrab()
2014 { 1993 {
2015 if (m_parentGroup == null)
2016 return false;
2017 if (m_parentGroup.IsDeleted) 1994 if (m_parentGroup.IsDeleted)
2018 return false; 1995 return false;
2019 1996
@@ -2022,8 +1999,6 @@ namespace OpenSim.Region.Framework.Scenes
2022 1999
2023 public void SetBlockGrab(bool p) 2000 public void SetBlockGrab(bool p)
2024 { 2001 {
2025 if (m_parentGroup == null)
2026 return;
2027 if (m_parentGroup.IsDeleted) 2002 if (m_parentGroup.IsDeleted)
2028 return; 2003 return;
2029 2004
@@ -2032,8 +2007,6 @@ namespace OpenSim.Region.Framework.Scenes
2032 2007
2033 public void SetStatusSandbox(bool p) 2008 public void SetStatusSandbox(bool p)
2034 { 2009 {
2035 if (m_parentGroup == null)
2036 return;
2037 if (m_parentGroup.IsDeleted) 2010 if (m_parentGroup.IsDeleted)
2038 return; 2011 return;
2039 StatusSandboxPos = m_parentGroup.RootPart.AbsolutePosition; 2012 StatusSandboxPos = m_parentGroup.RootPart.AbsolutePosition;
@@ -2042,8 +2015,6 @@ namespace OpenSim.Region.Framework.Scenes
2042 2015
2043 public bool GetStatusSandbox() 2016 public bool GetStatusSandbox()
2044 { 2017 {
2045 if (m_parentGroup == null)
2046 return false;
2047 if (m_parentGroup.IsDeleted) 2018 if (m_parentGroup.IsDeleted)
2048 return false; 2019 return false;
2049 2020
@@ -2085,25 +2056,17 @@ namespace OpenSim.Region.Framework.Scenes
2085 public Vector3 GetGeometricCenter() 2056 public Vector3 GetGeometricCenter()
2086 { 2057 {
2087 if (PhysActor != null) 2058 if (PhysActor != null)
2088 {
2089 return new Vector3(PhysActor.CenterOfMass.X, PhysActor.CenterOfMass.Y, PhysActor.CenterOfMass.Z); 2059 return new Vector3(PhysActor.CenterOfMass.X, PhysActor.CenterOfMass.Y, PhysActor.CenterOfMass.Z);
2090 }
2091 else 2060 else
2092 {
2093 return new Vector3(0, 0, 0); 2061 return new Vector3(0, 0, 0);
2094 }
2095 } 2062 }
2096 2063
2097 public float GetMass() 2064 public float GetMass()
2098 { 2065 {
2099 if (PhysActor != null) 2066 if (PhysActor != null)
2100 {
2101 return PhysActor.Mass; 2067 return PhysActor.Mass;
2102 }
2103 else 2068 else
2104 {
2105 return 0; 2069 return 0;
2106 }
2107 } 2070 }
2108 2071
2109 public Vector3 GetForce() 2072 public Vector3 GetForce()
@@ -2119,19 +2082,12 @@ namespace OpenSim.Region.Framework.Scenes
2119 client.SendObjectPropertiesReply(this); 2082 client.SendObjectPropertiesReply(this);
2120 } 2083 }
2121 2084
2122 public UUID GetRootPartUUID()
2123 {
2124 if (m_parentGroup != null)
2125 {
2126 return m_parentGroup.UUID;
2127 }
2128 return UUID.Zero;
2129 }
2130
2131 /// <summary> 2085 /// <summary>
2132 /// Method for a prim to get it's world position from the group. 2086 /// Method for a prim to get it's world position from the group.
2133 /// Remember, the Group Position simply gives the position of the group itself
2134 /// </summary> 2087 /// </summary>
2088 /// <remarks>
2089 /// Remember, the Group Position simply gives the position of the group itself
2090 /// </remarks>
2135 /// <returns>A Linked Child Prim objects position in world</returns> 2091 /// <returns>A Linked Child Prim objects position in world</returns>
2136 public Vector3 GetWorldPosition() 2092 public Vector3 GetWorldPosition()
2137 { 2093 {
@@ -2249,8 +2205,6 @@ namespace OpenSim.Region.Framework.Scenes
2249 m_lastColliders.Remove(localID); 2205 m_lastColliders.Remove(localID);
2250 } 2206 }
2251 2207
2252 if (m_parentGroup == null)
2253 return;
2254 if (m_parentGroup.IsDeleted) 2208 if (m_parentGroup.IsDeleted)
2255 return; 2209 return;
2256 2210
@@ -2271,9 +2225,6 @@ namespace OpenSim.Region.Framework.Scenes
2271 { 2225 {
2272 if (localId == 0) 2226 if (localId == 0)
2273 continue; 2227 continue;
2274 // always running this check because if the user deletes the object it would return a null reference.
2275 if (m_parentGroup == null)
2276 return;
2277 2228
2278 if (m_parentGroup.Scene == null) 2229 if (m_parentGroup.Scene == null)
2279 return; 2230 return;
@@ -2282,7 +2233,8 @@ namespace OpenSim.Region.Framework.Scenes
2282 string data = ""; 2233 string data = "";
2283 if (obj != null) 2234 if (obj != null)
2284 { 2235 {
2285 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) 2236 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString())
2237 || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
2286 { 2238 {
2287 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data); 2239 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
2288 //If it is 1, it is to accept ONLY collisions from this object 2240 //If it is 1, it is to accept ONLY collisions from this object
@@ -2329,7 +2281,8 @@ namespace OpenSim.Region.Framework.Scenes
2329 { 2281 {
2330 if (av.LocalId == localId) 2282 if (av.LocalId == localId)
2331 { 2283 {
2332 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) 2284 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString())
2285 || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
2333 { 2286 {
2334 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); 2287 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2335 //If it is 1, it is to accept ONLY collisions from this avatar 2288 //If it is 1, it is to accept ONLY collisions from this avatar
@@ -2377,12 +2330,10 @@ namespace OpenSim.Region.Framework.Scenes
2377 if (colliding.Count > 0) 2330 if (colliding.Count > 0)
2378 { 2331 {
2379 StartCollidingMessage.Colliders = colliding; 2332 StartCollidingMessage.Colliders = colliding;
2380 // always running this check because if the user deletes the object it would return a null reference.
2381 if (m_parentGroup == null)
2382 return;
2383 2333
2384 if (m_parentGroup.Scene == null) 2334 if (m_parentGroup.Scene == null)
2385 return; 2335 return;
2336
2386 if (m_parentGroup.PassCollision == true) 2337 if (m_parentGroup.PassCollision == true)
2387 { 2338 {
2388 //TODO: Add pass to root prim! 2339 //TODO: Add pass to root prim!
@@ -2403,9 +2354,6 @@ namespace OpenSim.Region.Framework.Scenes
2403 // always running this check because if the user deletes the object it would return a null reference. 2354 // always running this check because if the user deletes the object it would return a null reference.
2404 if (localId == 0) 2355 if (localId == 0)
2405 continue; 2356 continue;
2406
2407 if (m_parentGroup == null)
2408 return;
2409 2357
2410 if (m_parentGroup.Scene == null) 2358 if (m_parentGroup.Scene == null)
2411 return; 2359 return;
@@ -2414,7 +2362,8 @@ namespace OpenSim.Region.Framework.Scenes
2414 string data = ""; 2362 string data = "";
2415 if (obj != null) 2363 if (obj != null)
2416 { 2364 {
2417 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) 2365 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString())
2366 || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
2418 { 2367 {
2419 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data); 2368 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
2420 //If it is 1, it is to accept ONLY collisions from this object 2369 //If it is 1, it is to accept ONLY collisions from this object
@@ -2461,7 +2410,8 @@ namespace OpenSim.Region.Framework.Scenes
2461 { 2410 {
2462 if (av.LocalId == localId) 2411 if (av.LocalId == localId)
2463 { 2412 {
2464 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) 2413 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString())
2414 || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
2465 { 2415 {
2466 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); 2416 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2467 //If it is 1, it is to accept ONLY collisions from this avatar 2417 //If it is 1, it is to accept ONLY collisions from this avatar
@@ -2509,9 +2459,6 @@ namespace OpenSim.Region.Framework.Scenes
2509 if (colliding.Count > 0) 2459 if (colliding.Count > 0)
2510 { 2460 {
2511 CollidingMessage.Colliders = colliding; 2461 CollidingMessage.Colliders = colliding;
2512 // always running this check because if the user deletes the object it would return a null reference.
2513 if (m_parentGroup == null)
2514 return;
2515 2462
2516 if (m_parentGroup.Scene == null) 2463 if (m_parentGroup.Scene == null)
2517 return; 2464 return;
@@ -2532,11 +2479,9 @@ namespace OpenSim.Region.Framework.Scenes
2532 if (localId == 0) 2479 if (localId == 0)
2533 continue; 2480 continue;
2534 2481
2535 // always running this check because if the user deletes the object it would return a null reference.
2536 if (m_parentGroup == null)
2537 return;
2538 if (m_parentGroup.Scene == null) 2482 if (m_parentGroup.Scene == null)
2539 return; 2483 return;
2484
2540 SceneObjectPart obj = m_parentGroup.Scene.GetSceneObjectPart(localId); 2485 SceneObjectPart obj = m_parentGroup.Scene.GetSceneObjectPart(localId);
2541 string data = ""; 2486 string data = "";
2542 if (obj != null) 2487 if (obj != null)
@@ -2588,7 +2533,8 @@ namespace OpenSim.Region.Framework.Scenes
2588 { 2533 {
2589 if (av.LocalId == localId) 2534 if (av.LocalId == localId)
2590 { 2535 {
2591 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) 2536 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString())
2537 || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
2592 { 2538 {
2593 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); 2539 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2594 //If it is 1, it is to accept ONLY collisions from this avatar 2540 //If it is 1, it is to accept ONLY collisions from this avatar
@@ -2637,9 +2583,6 @@ namespace OpenSim.Region.Framework.Scenes
2637 if (colliding.Count > 0) 2583 if (colliding.Count > 0)
2638 { 2584 {
2639 EndCollidingMessage.Colliders = colliding; 2585 EndCollidingMessage.Colliders = colliding;
2640 // always running this check because if the user deletes the object it would return a null reference.
2641 if (m_parentGroup == null)
2642 return;
2643 2586
2644 if (m_parentGroup.Scene == null) 2587 if (m_parentGroup.Scene == null)
2645 return; 2588 return;
@@ -2648,6 +2591,7 @@ namespace OpenSim.Region.Framework.Scenes
2648 } 2591 }
2649 } 2592 }
2650 } 2593 }
2594
2651 if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_start) != 0) 2595 if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_start) != 0)
2652 { 2596 {
2653 if (startedColliders.Count > 0) 2597 if (startedColliders.Count > 0)
@@ -2675,9 +2619,6 @@ namespace OpenSim.Region.Framework.Scenes
2675 if (colliding.Count > 0) 2619 if (colliding.Count > 0)
2676 { 2620 {
2677 LandStartCollidingMessage.Colliders = colliding; 2621 LandStartCollidingMessage.Colliders = colliding;
2678 // always running this check because if the user deletes the object it would return a null reference.
2679 if (m_parentGroup == null)
2680 return;
2681 2622
2682 if (m_parentGroup.Scene == null) 2623 if (m_parentGroup.Scene == null)
2683 return; 2624 return;
@@ -2686,6 +2627,7 @@ namespace OpenSim.Region.Framework.Scenes
2686 } 2627 }
2687 } 2628 }
2688 } 2629 }
2630
2689 if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.land_collision) != 0) 2631 if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.land_collision) != 0)
2690 { 2632 {
2691 if (m_lastColliders.Count > 0) 2633 if (m_lastColliders.Count > 0)
@@ -2713,9 +2655,6 @@ namespace OpenSim.Region.Framework.Scenes
2713 if (colliding.Count > 0) 2655 if (colliding.Count > 0)
2714 { 2656 {
2715 LandCollidingMessage.Colliders = colliding; 2657 LandCollidingMessage.Colliders = colliding;
2716 // always running this check because if the user deletes the object it would return a null reference.
2717 if (m_parentGroup == null)
2718 return;
2719 2658
2720 if (m_parentGroup.Scene == null) 2659 if (m_parentGroup.Scene == null)
2721 return; 2660 return;
@@ -2724,6 +2663,7 @@ namespace OpenSim.Region.Framework.Scenes
2724 } 2663 }
2725 } 2664 }
2726 } 2665 }
2666
2727 if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_end) != 0) 2667 if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_end) != 0)
2728 { 2668 {
2729 if (endedColliders.Count > 0) 2669 if (endedColliders.Count > 0)
@@ -2751,9 +2691,6 @@ namespace OpenSim.Region.Framework.Scenes
2751 if (colliding.Count > 0) 2691 if (colliding.Count > 0)
2752 { 2692 {
2753 LandEndCollidingMessage.Colliders = colliding; 2693 LandEndCollidingMessage.Colliders = colliding;
2754 // always running this check because if the user deletes the object it would return a null reference.
2755 if (m_parentGroup == null)
2756 return;
2757 2694
2758 if (m_parentGroup.Scene == null) 2695 if (m_parentGroup.Scene == null)
2759 return; 2696 return;
@@ -2777,10 +2714,12 @@ namespace OpenSim.Region.Framework.Scenes
2777 { 2714 {
2778 if (PhysActor != null) 2715 if (PhysActor != null)
2779 { 2716 {
2780
2781 Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0); 2717 Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0);
2782 2718
2783 if (m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.N) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.S) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.E) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) 2719 if (m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.N)
2720 | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
2721 | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
2722 | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
2784 { 2723 {
2785 m_parentGroup.AbsolutePosition = newpos; 2724 m_parentGroup.AbsolutePosition = newpos;
2786 return; 2725 return;
@@ -2869,13 +2808,29 @@ namespace OpenSim.Region.Framework.Scenes
2869 } 2808 }
2870 2809
2871 /// <summary> 2810 /// <summary>
2872 /// Resize this part. 2811 /// Set the scale of this part.
2873 /// </summary> 2812 /// </summary>
2813 /// <remarks>
2814 /// Unlike the scale property, this checks the new size against scene limits and schedules a full property
2815 /// update to viewers.
2816 /// </remarks>
2874 /// <param name="scale"></param> 2817 /// <param name="scale"></param>
2875 public void Resize(Vector3 scale) 2818 public void Resize(Vector3 scale)
2876 { 2819 {
2877 StoreUndoState(UndoType.STATE_PRIM_SCALE); 2820 scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxNonphys);
2878 m_shape.Scale = scale; 2821 scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxNonphys);
2822 scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxNonphys);
2823
2824 if (PhysActor != null && PhysActor.IsPhysical)
2825 {
2826 scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxPhys);
2827 scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxPhys);
2828 scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxPhys);
2829 }
2830
2831// m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale);
2832
2833 Scale = scale;
2879 2834
2880 ParentGroup.HasGroupChanged = true; 2835 ParentGroup.HasGroupChanged = true;
2881 ScheduleFullUpdate(); 2836 ScheduleFullUpdate();
@@ -2886,20 +2841,48 @@ namespace OpenSim.Region.Framework.Scenes
2886 m_parentGroup.rotLookAt(target, strength, damping); // This calls method in SceneObjectGroup. 2841 m_parentGroup.rotLookAt(target, strength, damping); // This calls method in SceneObjectGroup.
2887 } 2842 }
2888 2843
2844 public void rotLookAt(Quaternion target, float strength, float damping)
2845 {
2846 if (m_parentGroup.IsAttachment)
2847 {
2848 /*
2849 ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar);
2850 if (avatar != null)
2851 {
2852 Rotate the Av?
2853 } */
2854 }
2855 else
2856 {
2857 APIDDamp = damping;
2858 APIDStrength = strength;
2859 APIDTarget = target;
2860 }
2861 }
2862
2863 public void startLookAt(Quaternion rot, float damp, float strength)
2864 {
2865 APIDDamp = damp;
2866 APIDStrength = strength;
2867 APIDTarget = rot;
2868 }
2869
2870 public void stopLookAt()
2871 {
2872 APIDTarget = Quaternion.Identity;
2873 }
2874
2889 /// <summary> 2875 /// <summary>
2890 /// Schedules this prim for a full update 2876 /// Schedules this prim for a full update
2891 /// </summary> 2877 /// </summary>
2892 public void ScheduleFullUpdate() 2878 public void ScheduleFullUpdate()
2893 { 2879 {
2894// m_log.DebugFormat("[SCENE OBJECT PART]: Scheduling full update for {0} {1}", Name, LocalId); 2880// m_log.DebugFormat("[SCENE OBJECT PART]: Scheduling full update for {0} {1}", Name, LocalId);
2895 2881
2896 if (m_parentGroup != null) 2882 if (m_parentGroup == null)
2897 { 2883 return;
2898 if (!m_parentGroup.areUpdatesSuspended) 2884
2899 { 2885 m_parentGroup.QueueForUpdateCheck();
2900 m_parentGroup.QueueForUpdateCheck();
2901 }
2902 }
2903 2886
2904 int timeNow = Util.UnixTimeSinceEpoch(); 2887 int timeNow = Util.UnixTimeSinceEpoch();
2905 2888
@@ -2928,13 +2911,14 @@ namespace OpenSim.Region.Framework.Scenes
2928 /// </summary> 2911 /// </summary>
2929 public void ScheduleTerseUpdate() 2912 public void ScheduleTerseUpdate()
2930 { 2913 {
2914 if (m_parentGroup == null)
2915 return;
2916
2931 if (m_updateFlag < 1) 2917 if (m_updateFlag < 1)
2932 { 2918 {
2933 if (m_parentGroup != null) 2919 m_parentGroup.HasGroupChanged = true;
2934 { 2920 m_parentGroup.QueueForUpdateCheck();
2935 m_parentGroup.HasGroupChanged = true; 2921
2936 m_parentGroup.QueueForUpdateCheck();
2937 }
2938 TimeStampTerse = (uint) Util.UnixTimeSinceEpoch(); 2922 TimeStampTerse = (uint) Util.UnixTimeSinceEpoch();
2939 m_updateFlag = 1; 2923 m_updateFlag = 1;
2940 2924
@@ -2944,40 +2928,16 @@ namespace OpenSim.Region.Framework.Scenes
2944 } 2928 }
2945 } 2929 }
2946 2930
2947 public void ScriptSetPhantomStatus(bool Phantom)
2948 {
2949 if (m_parentGroup != null)
2950 {
2951 m_parentGroup.ScriptSetPhantomStatus(Phantom);
2952 }
2953 }
2954
2955 public void ScriptSetTemporaryStatus(bool Temporary)
2956 {
2957 if (m_parentGroup != null)
2958 {
2959 m_parentGroup.ScriptSetTemporaryStatus(Temporary);
2960 }
2961 }
2962
2963 public void ScriptSetPhysicsStatus(bool UsePhysics) 2931 public void ScriptSetPhysicsStatus(bool UsePhysics)
2964 { 2932 {
2965 if (m_parentGroup == null) 2933 m_parentGroup.ScriptSetPhysicsStatus(UsePhysics);
2966 DoPhysicsPropertyUpdate(UsePhysics, false);
2967 else
2968 m_parentGroup.ScriptSetPhysicsStatus(UsePhysics);
2969 } 2934 }
2970 2935
2971 public void ScriptSetVolumeDetect(bool SetVD) 2936 /// <summary>
2972 { 2937 /// Set sculpt and mesh data, and tell the physics engine to process the change.
2973 2938 /// </summary>
2974 if (m_parentGroup != null) 2939 /// <param name="texture">The mesh itself.</param>
2975 { 2940 public void SculptTextureCallback(AssetBase texture)
2976 m_parentGroup.ScriptSetVolumeDetect(SetVD);
2977 }
2978 }
2979
2980 public void SculptTextureCallback(UUID textureID, AssetBase texture)
2981 { 2941 {
2982 if (m_shape.SculptEntry) 2942 if (m_shape.SculptEntry)
2983 { 2943 {
@@ -2985,14 +2945,17 @@ namespace OpenSim.Region.Framework.Scenes
2985 //if (texture != null) 2945 //if (texture != null)
2986 { 2946 {
2987 if (texture != null) 2947 if (texture != null)
2948 {
2949// m_log.DebugFormat(
2950// "[SCENE OBJECT PART]: Setting sculpt data for {0} on SculptTextureCallback()", Name);
2951
2988 m_shape.SculptData = texture.Data; 2952 m_shape.SculptData = texture.Data;
2953 }
2989 2954
2990 if (PhysActor != null) 2955 if (PhysActor != null)
2991 { 2956 {
2992 // Tricks physics engine into thinking we've changed the part shape. 2957 // Update the physics actor with the new loaded sculpt data and set the taint signal.
2993 PrimitiveBaseShape m_newshape = m_shape.Copy(); 2958 PhysActor.Shape = m_shape;
2994 PhysActor.Shape = m_newshape;
2995 m_shape = m_newshape;
2996 2959
2997 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 2960 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
2998 } 2961 }
@@ -3000,16 +2963,6 @@ namespace OpenSim.Region.Framework.Scenes
3000 } 2963 }
3001 } 2964 }
3002 2965
3003// /// <summary>
3004// ///
3005// /// </summary>
3006// /// <param name="remoteClient"></param>
3007// public void SendFullUpdate(IClientAPI remoteClient, uint clientFlags)
3008// {
3009// m_parentGroup.SendPartFullUpdate(remoteClient, this, clientFlags);
3010// }
3011
3012
3013 /// <summary> 2966 /// <summary>
3014 /// Send a full update to the client for the given part 2967 /// Send a full update to the client for the given part
3015 /// </summary> 2968 /// </summary>
@@ -3017,12 +2970,15 @@ namespace OpenSim.Region.Framework.Scenes
3017 /// <param name="clientFlags"></param> 2970 /// <param name="clientFlags"></param>
3018 protected internal void SendFullUpdate(IClientAPI remoteClient, uint clientFlags) 2971 protected internal void SendFullUpdate(IClientAPI remoteClient, uint clientFlags)
3019 { 2972 {
2973 if (m_parentGroup == null)
2974 return;
2975
3020// m_log.DebugFormat( 2976// m_log.DebugFormat(
3021// "[SOG]: Sendinging part full update to {0} for {1} {2}", remoteClient.Name, part.Name, part.LocalId); 2977// "[SOG]: Sendinging part full update to {0} for {1} {2}", remoteClient.Name, part.Name, part.LocalId);
3022 2978
3023 if (IsRoot) 2979 if (IsRoot)
3024 { 2980 {
3025 if (IsAttachment) 2981 if (m_parentGroup.IsAttachment)
3026 { 2982 {
3027 SendFullUpdateToClient(remoteClient, AttachedPos, clientFlags); 2983 SendFullUpdateToClient(remoteClient, AttachedPos, clientFlags);
3028 } 2984 }
@@ -3042,6 +2998,9 @@ namespace OpenSim.Region.Framework.Scenes
3042 /// </summary> 2998 /// </summary>
3043 public void SendFullUpdateToAllClients() 2999 public void SendFullUpdateToAllClients()
3044 { 3000 {
3001 if (m_parentGroup == null)
3002 return;
3003
3045 m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 3004 m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
3046 { 3005 {
3047 SendFullUpdate(avatar.ControllingClient, avatar.GenerateClientFlags(UUID)); 3006 SendFullUpdate(avatar.ControllingClient, avatar.GenerateClientFlags(UUID));
@@ -3054,6 +3013,9 @@ namespace OpenSim.Region.Framework.Scenes
3054 /// <param name="agentID"></param> 3013 /// <param name="agentID"></param>
3055 public void SendFullUpdateToAllClientsExcept(UUID agentID) 3014 public void SendFullUpdateToAllClientsExcept(UUID agentID)
3056 { 3015 {
3016 if (m_parentGroup == null)
3017 return;
3018
3057 m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 3019 m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
3058 { 3020 {
3059 // Ugly reference :( 3021 // Ugly reference :(
@@ -3082,9 +3044,12 @@ namespace OpenSim.Region.Framework.Scenes
3082 /// <param name="clientFlags"></param> 3044 /// <param name="clientFlags"></param>
3083 public void SendFullUpdateToClient(IClientAPI remoteClient, Vector3 lPos, uint clientFlags) 3045 public void SendFullUpdateToClient(IClientAPI remoteClient, Vector3 lPos, uint clientFlags)
3084 { 3046 {
3047 if (ParentGroup == null)
3048 return;
3049
3085 // Suppress full updates during attachment editing 3050 // Suppress full updates during attachment editing
3086 // 3051 //
3087 if (ParentGroup.IsSelected && IsAttachment) 3052 if (ParentGroup.IsSelected && ParentGroup.IsAttachment)
3088 return; 3053 return;
3089 3054
3090 if (ParentGroup.IsDeleted) 3055 if (ParentGroup.IsDeleted)
@@ -3177,7 +3142,7 @@ namespace OpenSim.Region.Framework.Scenes
3177 3142
3178 UUID ownerID = _ownerID; 3143 UUID ownerID = _ownerID;
3179 UUID objectID = ParentGroup.RootPart.UUID; 3144 UUID objectID = ParentGroup.RootPart.UUID;
3180 UUID parentID = GetRootPartUUID(); 3145 UUID parentID = ParentGroup.UUID;
3181 3146
3182 UUID soundID = UUID.Zero; 3147 UUID soundID = UUID.Zero;
3183 Vector3 position = AbsolutePosition; // region local 3148 Vector3 position = AbsolutePosition; // region local
@@ -3215,7 +3180,7 @@ namespace OpenSim.Region.Framework.Scenes
3215 ParentGroup.PlaySoundMasterPrim = this; 3180 ParentGroup.PlaySoundMasterPrim = this;
3216 ownerID = _ownerID; 3181 ownerID = _ownerID;
3217 objectID = ParentGroup.RootPart.UUID; 3182 objectID = ParentGroup.RootPart.UUID;
3218 parentID = GetRootPartUUID(); 3183 parentID = ParentGroup.UUID;
3219 position = AbsolutePosition; // region local 3184 position = AbsolutePosition; // region local
3220 regionHandle = ParentGroup.Scene.RegionInfo.RegionHandle; 3185 regionHandle = ParentGroup.Scene.RegionInfo.RegionHandle;
3221 if (triggered) 3186 if (triggered)
@@ -3226,7 +3191,7 @@ namespace OpenSim.Region.Framework.Scenes
3226 { 3191 {
3227 ownerID = prim._ownerID; 3192 ownerID = prim._ownerID;
3228 objectID = prim.ParentGroup.RootPart.UUID; 3193 objectID = prim.ParentGroup.RootPart.UUID;
3229 parentID = prim.GetRootPartUUID(); 3194 parentID = prim.ParentGroup.UUID;
3230 position = prim.AbsolutePosition; // region local 3195 position = prim.AbsolutePosition; // region local
3231 regionHandle = prim.ParentGroup.Scene.RegionInfo.RegionHandle; 3196 regionHandle = prim.ParentGroup.Scene.RegionInfo.RegionHandle;
3232 if (triggered) 3197 if (triggered)
@@ -3263,45 +3228,23 @@ namespace OpenSim.Region.Framework.Scenes
3263 }); 3228 });
3264 } 3229 }
3265 3230
3266 public void SetAttachmentPoint(uint AttachmentPoint)
3267 {
3268 this.AttachmentPoint = AttachmentPoint;
3269
3270 if (AttachmentPoint != 0)
3271 {
3272 IsAttachment = true;
3273 }
3274 else
3275 {
3276 IsAttachment = false;
3277 }
3278
3279 // save the attachment point.
3280 //if (AttachmentPoint != 0)
3281 //{
3282 m_shape.State = (byte)AttachmentPoint;
3283 //}
3284 }
3285
3286 public void SetAxisRotation(int axis, int rotate) 3231 public void SetAxisRotation(int axis, int rotate)
3287 { 3232 {
3288 if (m_parentGroup != null) 3233 m_parentGroup.SetAxisRotation(axis, rotate);
3289 { 3234
3290 m_parentGroup.SetAxisRotation(axis, rotate);
3291 }
3292 //Cannot use ScriptBaseClass constants as no referance to it currently. 3235 //Cannot use ScriptBaseClass constants as no referance to it currently.
3293 if (axis == 2)//STATUS_ROTATE_X 3236 if (axis == 2)//STATUS_ROTATE_X
3294 STATUS_ROTATE_X = rotate; 3237 STATUS_ROTATE_X = rotate;
3238
3295 if (axis == 4)//STATUS_ROTATE_Y 3239 if (axis == 4)//STATUS_ROTATE_Y
3296 STATUS_ROTATE_Y = rotate; 3240 STATUS_ROTATE_Y = rotate;
3241
3297 if (axis == 8)//STATUS_ROTATE_Z 3242 if (axis == 8)//STATUS_ROTATE_Z
3298 STATUS_ROTATE_Z = rotate; 3243 STATUS_ROTATE_Z = rotate;
3299 } 3244 }
3300 3245
3301 public void SetDieAtEdge(bool p) 3246 public void SetDieAtEdge(bool p)
3302 { 3247 {
3303 if (m_parentGroup == null)
3304 return;
3305 if (m_parentGroup.IsDeleted) 3248 if (m_parentGroup.IsDeleted)
3306 return; 3249 return;
3307 3250
@@ -3554,7 +3497,7 @@ namespace OpenSim.Region.Framework.Scenes
3554 } 3497 }
3555 3498
3556 /// <summary> 3499 /// <summary>
3557 /// 3500 /// Set the parent group of this prim.
3558 /// </summary> 3501 /// </summary>
3559 public void SetParent(SceneObjectGroup parent) 3502 public void SetParent(SceneObjectGroup parent)
3560 { 3503 {
@@ -3611,8 +3554,11 @@ namespace OpenSim.Region.Framework.Scenes
3611 { 3554 {
3612 Text = text; 3555 Text = text;
3613 3556
3614 ParentGroup.HasGroupChanged = true; 3557 if (ParentGroup != null)
3615 ScheduleFullUpdate(); 3558 {
3559 ParentGroup.HasGroupChanged = true;
3560 ScheduleFullUpdate();
3561 }
3616 } 3562 }
3617 3563
3618 public void StopLookAt() 3564 public void StopLookAt()
@@ -3646,24 +3592,44 @@ namespace OpenSim.Region.Framework.Scenes
3646 } 3592 }
3647 public void StoreUndoState(UndoType type) 3593 public void StoreUndoState(UndoType type)
3648 { 3594 {
3649 if (!Undoing && (m_parentGroup == null || m_parentGroup.RootPart == null || !m_parentGroup.RootPart.Undoing)) 3595 StoreUndoState(false);
3596 }
3597
3598 public void StoreUndoState(bool forGroup)
3599 {
3600 if (!Undoing)
3650 { 3601 {
3651 if (!IgnoreUndoUpdate) 3602 if (!IgnoreUndoUpdate)
3652 { 3603 {
3653 if (m_parentGroup != null) 3604 if (ParentGroup != null)
3654 { 3605 {
3655 lock (m_undo) 3606 lock (m_undo)
3656 { 3607 {
3657 if (m_undo.Count > 0) 3608 if (m_undo.Count > 0)
3658 { 3609 {
3659 UndoState last = m_undo.Peek(); 3610 UndoState last = m_undo.Peek();
3660 3611 if (last != null)
3612 {
3613 // TODO: May need to fix for group comparison
3614 if (last.Compare(this))
3615 {
3616 // m_log.DebugFormat(
3617 // "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}",
3618 // Name, LocalId, m_undo.Count);
3619
3620 return;
3621 }
3622 }
3661 } 3623 }
3662 3624
3625 // m_log.DebugFormat(
3626 // "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}",
3627 // Name, LocalId, forGroup, m_undo.Count);
3628
3663 if (m_parentGroup.GetSceneMaxUndo() > 0) 3629 if (m_parentGroup.GetSceneMaxUndo() > 0)
3664 { 3630 {
3665 UndoState lastUndo = m_undo.Peek(); 3631 UndoState nUndo = new UndoState(this, forGroup);
3666 3632
3667 UndoState nUndo = new UndoState(this, type); 3633 UndoState nUndo = new UndoState(this, type);
3668 3634
3669 if (lastUndo != null) 3635 if (lastUndo != null)
@@ -3677,11 +3643,114 @@ namespace OpenSim.Region.Framework.Scenes
3677 } 3643 }
3678 } 3644 }
3679 m_undo.Push(nUndo); 3645 m_undo.Push(nUndo);
3646
3647 if (m_redo.Count > 0)
3648 m_redo.Clear();
3649
3650 // m_log.DebugFormat(
3651 // "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}",
3652 // Name, LocalId, forGroup, m_undo.Count);
3680 } 3653 }
3654 }
3655 }
3656 }
3657// else
3658// {
3659// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId);
3660// }
3661 }
3662// else
3663// {
3664// m_log.DebugFormat(
3665// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
3666// }
3667 }
3668
3669 /// <summary>
3670 /// Return number of undos on the stack. Here temporarily pending a refactor.
3671 /// </summary>
3672 public int UndoCount
3673 {
3674 get
3675 {
3676 lock (m_undo)
3677 return m_undo.Count;
3678 }
3679 }
3680
3681 public void Undo()
3682 {
3683 lock (m_undo)
3684 {
3685// m_log.DebugFormat(
3686// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}",
3687// Name, LocalId, m_undo.Count);
3688
3689 if (m_undo.Count > 0)
3690 {
3691 UndoState goback = m_undo.Pop();
3681 3692
3693 if (goback != null)
3694 {
3695 UndoState nUndo = null;
3696
3697 if (m_parentGroup.GetSceneMaxUndo() > 0)
3698 {
3699 nUndo = new UndoState(this, goback.ForGroup);
3682 } 3700 }
3701
3702 goback.PlaybackState(this);
3703
3704 if (nUndo != null)
3705 m_redo.Push(nUndo);
3683 } 3706 }
3684 } 3707 }
3708
3709// m_log.DebugFormat(
3710// "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}",
3711// Name, LocalId, m_undo.Count);
3712 }
3713 }
3714
3715 public void Redo()
3716 {
3717 lock (m_undo)
3718 {
3719// m_log.DebugFormat(
3720// "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}",
3721// Name, LocalId, m_redo.Count);
3722
3723 if (m_redo.Count > 0)
3724 {
3725 UndoState gofwd = m_redo.Pop();
3726
3727 if (gofwd != null)
3728 {
3729 if (m_parentGroup.GetSceneMaxUndo() > 0)
3730 {
3731 UndoState nUndo = new UndoState(this, gofwd.ForGroup);
3732
3733 m_undo.Push(nUndo);
3734 }
3735
3736 gofwd.PlayfwdState(this);
3737 }
3738
3739// m_log.DebugFormat(
3740// "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}",
3741// Name, LocalId, m_redo.Count);
3742 }
3743 }
3744 }
3745
3746 public void ClearUndoState()
3747 {
3748// m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId);
3749
3750 lock (m_undo)
3751 {
3752 m_undo.Clear();
3753 m_redo.Clear();
3685 } 3754 }
3686 } 3755 }
3687 3756
@@ -4145,46 +4214,6 @@ namespace OpenSim.Region.Framework.Scenes
4145 _nextOwnerMask &= (uint)PermissionMask.All; 4214 _nextOwnerMask &= (uint)PermissionMask.All;
4146 } 4215 }
4147 4216
4148 public void Undo()
4149 {
4150 lock (m_undo)
4151 {
4152 if (m_undo.Count > 0)
4153 {
4154 UndoState nUndo = null;
4155 UndoState goback = m_undo.Pop();
4156 if (m_parentGroup.GetSceneMaxUndo() > 0)
4157 {
4158 nUndo = new UndoState(this, goback.Type);
4159 }
4160
4161
4162 if (goback != null)
4163 {
4164 goback.PlaybackState(this);
4165 if (nUndo != null)
4166 m_redo.Push(nUndo);
4167 }
4168 }
4169 }
4170 }
4171
4172 public void Redo()
4173 {
4174 lock (m_redo)
4175 {
4176 UndoState gofwd = m_redo.Pop();
4177 if (m_parentGroup.GetSceneMaxUndo() > 0)
4178 {
4179 UndoState nUndo = new UndoState(this, gofwd.Type);
4180
4181 m_undo.Push(nUndo);
4182 }
4183 if (gofwd != null)
4184 gofwd.PlayfwdState(this);
4185 }
4186 }
4187
4188 public void UpdateExtraParam(ushort type, bool inUse, byte[] data) 4217 public void UpdateExtraParam(ushort type, bool inUse, byte[] data)
4189 { 4218 {
4190 m_shape.ReadInUpdateExtraParam(type, inUse, data); 4219 m_shape.ReadInUpdateExtraParam(type, inUse, data);
@@ -4197,8 +4226,11 @@ namespace OpenSim.Region.Framework.Scenes
4197 } 4226 }
4198 } 4227 }
4199 4228
4200 ParentGroup.HasGroupChanged = true; 4229 if (ParentGroup != null)
4201 ScheduleFullUpdate(); 4230 {
4231 ParentGroup.HasGroupChanged = true;
4232 ScheduleFullUpdate();
4233 }
4202 } 4234 }
4203 4235
4204 public void UpdateGroupPosition(Vector3 pos) 4236 public void UpdateGroupPosition(Vector3 pos)
@@ -4345,14 +4377,21 @@ namespace OpenSim.Region.Framework.Scenes
4345 } 4377 }
4346 } 4378 }
4347 4379
4348 public void UpdatePrimFlags(bool UsePhysics, bool IsTemporary, bool IsPhantom, bool IsVD) 4380 /// <summary>
4381 /// Update the flags on this prim. This covers properties such as phantom, physics and temporary.
4382 /// </summary>
4383 /// <param name="UsePhysics"></param>
4384 /// <param name="SetTemporary"></param>
4385 /// <param name="SetPhantom"></param>
4386 /// <param name="SetVD"></param>
4387 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD)
4349 { 4388 {
4350 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0); 4389 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
4351 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0); 4390 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
4352 bool wasPhantom = ((Flags & PrimFlags.Phantom) != 0); 4391 bool wasPhantom = ((Flags & PrimFlags.Phantom) != 0);
4353 bool wasVD = VolumeDetectActive; 4392 bool wasVD = VolumeDetectActive;
4354 4393
4355 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == IsTemporary) && (wasPhantom == IsPhantom) && (IsVD==wasVD)) 4394 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD))
4356 { 4395 {
4357 return; 4396 return;
4358 } 4397 }
@@ -4362,32 +4401,31 @@ namespace OpenSim.Region.Framework.Scenes
4362 // that... 4401 // that...
4363 // ... if VD is changed, all others are not. 4402 // ... if VD is changed, all others are not.
4364 // ... if one of the others is changed, VD is not. 4403 // ... if one of the others is changed, VD is not.
4365 if (IsVD) // VD is active, special logic applies 4404 if (SetVD) // VD is active, special logic applies
4366 { 4405 {
4367 // State machine logic for VolumeDetect 4406 // State machine logic for VolumeDetect
4368 // More logic below 4407 // More logic below
4369 bool phanReset = (IsPhantom != wasPhantom) && !IsPhantom; 4408 bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
4370 4409
4371 if (phanReset) // Phantom changes from on to off switch VD off too 4410 if (phanReset) // Phantom changes from on to off switch VD off too
4372 { 4411 {
4373 IsVD = false; // Switch it of for the course of this routine 4412 SetVD = false; // Switch it of for the course of this routine
4374 VolumeDetectActive = false; // and also permanently 4413 VolumeDetectActive = false; // and also permanently
4375 if (PhysActor != null) 4414 if (PhysActor != null)
4376 PhysActor.SetVolumeDetect(0); // Let physics know about it too 4415 PhysActor.SetVolumeDetect(0); // Let physics know about it too
4377 } 4416 }
4378 else 4417 else
4379 { 4418 {
4380 IsPhantom = false;
4381 // If volumedetect is active we don't want phantom to be applied. 4419 // If volumedetect is active we don't want phantom to be applied.
4382 // If this is a new call to VD out of the state "phantom" 4420 // If this is a new call to VD out of the state "phantom"
4383 // this will also cause the prim to be visible to physics 4421 // this will also cause the prim to be visible to physics
4422 SetPhantom = false;
4384 } 4423 }
4385
4386 } 4424 }
4387 4425
4388 if (UsePhysics && IsJoint()) 4426 if (UsePhysics && IsJoint())
4389 { 4427 {
4390 IsPhantom = true; 4428 SetPhantom = true;
4391 } 4429 }
4392 4430
4393 if (UsePhysics) 4431 if (UsePhysics)
@@ -4396,14 +4434,12 @@ namespace OpenSim.Region.Framework.Scenes
4396 if (!wasUsingPhysics) 4434 if (!wasUsingPhysics)
4397 { 4435 {
4398 DoPhysicsPropertyUpdate(UsePhysics, false); 4436 DoPhysicsPropertyUpdate(UsePhysics, false);
4399 if (m_parentGroup != null) 4437
4438 if (!m_parentGroup.IsDeleted)
4400 { 4439 {
4401 if (!m_parentGroup.IsDeleted) 4440 if (LocalId == m_parentGroup.RootPart.LocalId)
4402 { 4441 {
4403 if (LocalId == m_parentGroup.RootPart.LocalId) 4442 m_parentGroup.CheckSculptAndLoad();
4404 {
4405 m_parentGroup.CheckSculptAndLoad();
4406 }
4407 } 4443 }
4408 } 4444 }
4409 } 4445 }
@@ -4417,8 +4453,9 @@ namespace OpenSim.Region.Framework.Scenes
4417 } 4453 }
4418 } 4454 }
4419 4455
4420 4456 if (SetPhantom
4421 if (IsPhantom || IsAttachment || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints 4457 || ParentGroup.IsAttachment
4458 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
4422 { 4459 {
4423 AddFlag(PrimFlags.Phantom); 4460 AddFlag(PrimFlags.Phantom);
4424 if (PhysActor != null) 4461 if (PhysActor != null)
@@ -4432,7 +4469,11 @@ namespace OpenSim.Region.Framework.Scenes
4432 { 4469 {
4433 RemFlag(PrimFlags.Phantom); 4470 RemFlag(PrimFlags.Phantom);
4434 4471
4472 if (ParentGroup.Scene == null)
4473 return;
4474
4435 PhysicsActor pa = PhysActor; 4475 PhysicsActor pa = PhysActor;
4476
4436 if (pa == null) 4477 if (pa == null)
4437 { 4478 {
4438 // It's not phantom anymore. So make sure the physics engine get's knowledge of it 4479 // It's not phantom anymore. So make sure the physics engine get's knowledge of it
@@ -4444,22 +4485,21 @@ namespace OpenSim.Region.Framework.Scenes
4444 RotationOffset, 4485 RotationOffset,
4445 UsePhysics, 4486 UsePhysics,
4446 m_localId); 4487 m_localId);
4447 PhysActor.SetMaterial(Material);
4448 4488
4449 pa = PhysActor; 4489 pa = PhysActor;
4450 if (pa != null) 4490 if (pa != null)
4451 { 4491 {
4492 PhysActor.SetMaterial(Material);
4452 DoPhysicsPropertyUpdate(UsePhysics, true); 4493 DoPhysicsPropertyUpdate(UsePhysics, true);
4453 if (m_parentGroup != null) 4494
4495 if (!m_parentGroup.IsDeleted)
4454 { 4496 {
4455 if (!m_parentGroup.IsDeleted) 4497 if (LocalId == m_parentGroup.RootPart.LocalId)
4456 { 4498 {
4457 if (LocalId == m_parentGroup.RootPart.LocalId) 4499 m_parentGroup.CheckSculptAndLoad();
4458 {
4459 m_parentGroup.CheckSculptAndLoad();
4460 }
4461 } 4500 }
4462 } 4501 }
4502
4463 if ( 4503 if (
4464 ((AggregateScriptEvents & scriptEvents.collision) != 0) || 4504 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4465 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || 4505 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
@@ -4470,8 +4510,8 @@ namespace OpenSim.Region.Framework.Scenes
4470 (CollisionSound != UUID.Zero) 4510 (CollisionSound != UUID.Zero)
4471 ) 4511 )
4472 { 4512 {
4473 PhysActor.OnCollisionUpdate += PhysicsCollision; 4513 PhysActor.OnCollisionUpdate += PhysicsCollision;
4474 PhysActor.SubscribeEvents(1000); 4514 PhysActor.SubscribeEvents(1000);
4475 } 4515 }
4476 } 4516 }
4477 } 4517 }
@@ -4480,20 +4520,18 @@ namespace OpenSim.Region.Framework.Scenes
4480 pa.IsPhysical = UsePhysics; 4520 pa.IsPhysical = UsePhysics;
4481 4521
4482 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim 4522 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim
4483 if (m_parentGroup != null) 4523
4524 if (!m_parentGroup.IsDeleted)
4484 { 4525 {
4485 if (!m_parentGroup.IsDeleted) 4526 if (LocalId == m_parentGroup.RootPart.LocalId)
4486 { 4527 {
4487 if (LocalId == m_parentGroup.RootPart.LocalId) 4528 m_parentGroup.CheckSculptAndLoad();
4488 {
4489 m_parentGroup.CheckSculptAndLoad();
4490 }
4491 } 4529 }
4492 } 4530 }
4493 } 4531 }
4494 } 4532 }
4495 4533
4496 if (IsVD) 4534 if (SetVD)
4497 { 4535 {
4498 // If the above logic worked (this is urgent candidate to unit tests!) 4536 // If the above logic worked (this is urgent candidate to unit tests!)
4499 // we now have a physicsactor. 4537 // we now have a physicsactor.
@@ -4508,18 +4546,19 @@ namespace OpenSim.Region.Framework.Scenes
4508 } 4546 }
4509 } 4547 }
4510 else 4548 else
4511 { // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like 4549 {
4550 // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like
4512 // (mumbles, well, at least if you have infinte CPU powers :-)) 4551 // (mumbles, well, at least if you have infinte CPU powers :-))
4513 PhysicsActor pa = this.PhysActor; 4552 PhysicsActor pa = this.PhysActor;
4514 if (pa != null) 4553 if (pa != null)
4515 { 4554 {
4516 PhysActor.SetVolumeDetect(0); 4555 PhysActor.SetVolumeDetect(0);
4517 } 4556 }
4557
4518 this.VolumeDetectActive = false; 4558 this.VolumeDetectActive = false;
4519 } 4559 }
4520 4560
4521 4561 if (SetTemporary)
4522 if (IsTemporary)
4523 { 4562 {
4524 AddFlag(PrimFlags.TemporaryOnRez); 4563 AddFlag(PrimFlags.TemporaryOnRez);
4525 } 4564 }
@@ -4529,8 +4568,13 @@ namespace OpenSim.Region.Framework.Scenes
4529 } 4568 }
4530 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString()); 4569 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4531 4570
4532 ParentGroup.HasGroupChanged = true; 4571 if (ParentGroup != null)
4533 ScheduleFullUpdate(); 4572 {
4573 ParentGroup.HasGroupChanged = true;
4574 ScheduleFullUpdate();
4575 }
4576
4577// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags);
4534 } 4578 }
4535 4579
4536 public void UpdateRotation(Quaternion rot) 4580 public void UpdateRotation(Quaternion rot)
@@ -4541,8 +4585,12 @@ namespace OpenSim.Region.Framework.Scenes
4541 (rot.W != RotationOffset.W)) 4585 (rot.W != RotationOffset.W))
4542 { 4586 {
4543 RotationOffset = rot; 4587 RotationOffset = rot;
4544 ParentGroup.HasGroupChanged = true; 4588
4545 ScheduleTerseUpdate(); 4589 if (ParentGroup != null)
4590 {
4591 ParentGroup.HasGroupChanged = true;
4592 ScheduleTerseUpdate();
4593 }
4546 } 4594 }
4547 } 4595 }
4548 4596
@@ -4570,6 +4618,7 @@ namespace OpenSim.Region.Framework.Scenes
4570 m_shape.PathTaperY = shapeBlock.PathTaperY; 4618 m_shape.PathTaperY = shapeBlock.PathTaperY;
4571 m_shape.PathTwist = shapeBlock.PathTwist; 4619 m_shape.PathTwist = shapeBlock.PathTwist;
4572 m_shape.PathTwistBegin = shapeBlock.PathTwistBegin; 4620 m_shape.PathTwistBegin = shapeBlock.PathTwistBegin;
4621
4573 if (PhysActor != null) 4622 if (PhysActor != null)
4574 { 4623 {
4575 PhysActor.Shape = m_shape; 4624 PhysActor.Shape = m_shape;
@@ -4591,11 +4640,46 @@ namespace OpenSim.Region.Framework.Scenes
4591 } 4640 }
4592 4641
4593 /// <summary> 4642 /// <summary>
4643 /// If the part is a sculpt/mesh, retrieve the mesh data and reinsert it into the shape so that the physics
4644 /// engine can use it.
4645 /// </summary>
4646 /// <remarks>
4647 /// When the physics engine has finished with it, the sculpt data is discarded to save memory.
4648 /// </remarks>
4649 public void CheckSculptAndLoad()
4650 {
4651// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId);
4652
4653 if (ParentGroup.IsDeleted)
4654 return;
4655
4656 if ((ParentGroup.RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0)
4657 return;
4658
4659 if (Shape.SculptEntry && Shape.SculptTexture != UUID.Zero)
4660 {
4661 // check if a previously decoded sculpt map has been cached
4662 // We don't read the file here - the meshmerizer will do that later.
4663 // TODO: Could we simplify the meshmerizer code by reading and setting the data here?
4664 if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + Shape.SculptTexture.ToString())))
4665 {
4666 SculptTextureCallback(null);
4667 }
4668 else
4669 {
4670 ParentGroup.Scene.AssetService.Get(Shape.SculptTexture.ToString(), this, AssetReceived);
4671 }
4672 }
4673 }
4674
4675 /// <summary>
4594 /// Update the textures on the part. 4676 /// Update the textures on the part.
4595 /// </summary> 4677 /// </summary>
4678 /// <remarks>
4596 /// Added to handle bug in libsecondlife's TextureEntry.ToBytes() 4679 /// Added to handle bug in libsecondlife's TextureEntry.ToBytes()
4597 /// not handling RGBA properly. Cycles through, and "fixes" the color 4680 /// not handling RGBA properly. Cycles through, and "fixes" the color
4598 /// info 4681 /// info
4682 /// </remarks>
4599 /// <param name="tex"></param> 4683 /// <param name="tex"></param>
4600 public void UpdateTexture(Primitive.TextureEntry tex) 4684 public void UpdateTexture(Primitive.TextureEntry tex)
4601 { 4685 {
@@ -4687,7 +4771,6 @@ namespace OpenSim.Region.Framework.Scenes
4687 { 4771 {
4688 PhysActor.OnCollisionUpdate += PhysicsCollision; 4772 PhysActor.OnCollisionUpdate += PhysicsCollision;
4689 PhysActor.SubscribeEvents(1000); 4773 PhysActor.SubscribeEvents(1000);
4690
4691 } 4774 }
4692 } 4775 }
4693 else 4776 else
@@ -4699,14 +4782,6 @@ namespace OpenSim.Region.Framework.Scenes
4699 } 4782 }
4700 } 4783 }
4701 4784
4702 if (m_parentGroup == null)
4703 {
4704// m_log.DebugFormat(
4705// "[SCENE OBJECT PART]: Scheduling part {0} {1} for full update in aggregateScriptEvents() since m_parentGroup == null", Name, LocalId);
4706 ScheduleFullUpdate();
4707 return;
4708 }
4709
4710 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) 4785 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
4711 //{ 4786 //{
4712 // m_parentGroup.Scene.EventManager.OnScriptTimerEvent += handleTimerAccounting; 4787 // m_parentGroup.Scene.EventManager.OnScriptTimerEvent += handleTimerAccounting;
@@ -4716,7 +4791,7 @@ namespace OpenSim.Region.Framework.Scenes
4716 // m_parentGroup.Scene.EventManager.OnScriptTimerEvent -= handleTimerAccounting; 4791 // m_parentGroup.Scene.EventManager.OnScriptTimerEvent -= handleTimerAccounting;
4717 //} 4792 //}
4718 4793
4719 LocalFlags=(PrimFlags)objectflagupdate; 4794 LocalFlags = (PrimFlags)objectflagupdate;
4720 4795
4721 if (m_parentGroup != null && m_parentGroup.RootPart == this) 4796 if (m_parentGroup != null && m_parentGroup.RootPart == this)
4722 { 4797 {
@@ -4730,40 +4805,6 @@ namespace OpenSim.Region.Framework.Scenes
4730 } 4805 }
4731 } 4806 }
4732 4807
4733 public int registerTargetWaypoint(Vector3 target, float tolerance)
4734 {
4735 if (m_parentGroup != null)
4736 {
4737 return m_parentGroup.registerTargetWaypoint(target, tolerance);
4738 }
4739 return 0;
4740 }
4741
4742 public void unregisterTargetWaypoint(int handle)
4743 {
4744 if (m_parentGroup != null)
4745 {
4746 m_parentGroup.unregisterTargetWaypoint(handle);
4747 }
4748 }
4749
4750 public int registerRotTargetWaypoint(Quaternion target, float tolerance)
4751 {
4752 if (m_parentGroup != null)
4753 {
4754 return m_parentGroup.registerRotTargetWaypoint(target, tolerance);
4755 }
4756 return 0;
4757 }
4758
4759 public void unregisterRotTargetWaypoint(int handle)
4760 {
4761 if (m_parentGroup != null)
4762 {
4763 m_parentGroup.unregisterRotTargetWaypoint(handle);
4764 }
4765 }
4766
4767 public void SetCameraAtOffset(Vector3 v) 4808 public void SetCameraAtOffset(Vector3 v)
4768 { 4809 {
4769 m_cameraAtOffset = v; 4810 m_cameraAtOffset = v;
@@ -4803,10 +4844,10 @@ namespace OpenSim.Region.Framework.Scenes
4803 4844
4804 public void SendTerseUpdateToClient(IClientAPI remoteClient) 4845 public void SendTerseUpdateToClient(IClientAPI remoteClient)
4805 { 4846 {
4806 if (ParentGroup == null || ParentGroup.IsDeleted) 4847 if (ParentGroup.IsDeleted)
4807 return; 4848 return;
4808 4849
4809 if (IsAttachment && ParentGroup.RootPart != this) 4850 if (ParentGroup.IsAttachment && ParentGroup.RootPart != this)
4810 return; 4851 return;
4811 4852
4812 // Causes this thread to dig into the Client Thread Data. 4853 // Causes this thread to dig into the Client Thread Data.
@@ -4827,6 +4868,7 @@ namespace OpenSim.Region.Framework.Scenes
4827 4868
4828 Inventory.ApplyNextOwnerPermissions(); 4869 Inventory.ApplyNextOwnerPermissions();
4829 } 4870 }
4871
4830 public void UpdateLookAt() 4872 public void UpdateLookAt()
4831 { 4873 {
4832 try 4874 try
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 56680df..1f0840d 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -118,14 +118,17 @@ namespace OpenSim.Region.Framework.Scenes
118 } 118 }
119 119
120 /// <summary> 120 /// <summary>
121 /// Reset UUIDs for all the items in the prim's inventory. This involves either generating 121 /// Reset UUIDs for all the items in the prim's inventory.
122 /// </summary>
123 /// <remarks>
124 /// This involves either generating
122 /// new ones or setting existing UUIDs to the correct parent UUIDs. 125 /// new ones or setting existing UUIDs to the correct parent UUIDs.
123 /// 126 ///
124 /// If this method is called and there are inventory items, then we regard the inventory as having changed. 127 /// If this method is called and there are inventory items, then we regard the inventory as having changed.
125 /// </summary> 128 /// </remarks>
126 /// <param name="linkNum">Link number for the part</param>
127 public void ResetInventoryIDs() 129 public void ResetInventoryIDs()
128 { 130 {
131 if (null == m_part)
129 m_items.LockItemsForWrite(true); 132 m_items.LockItemsForWrite(true);
130 133
131 if (Items.Count == 0) 134 if (Items.Count == 0)
@@ -212,7 +215,7 @@ namespace OpenSim.Region.Framework.Scenes
212 // Don't let this set the HasGroupChanged flag for attachments 215 // Don't let this set the HasGroupChanged flag for attachments
213 // as this happens during rez and we don't want a new asset 216 // as this happens during rez and we don't want a new asset
214 // for each attachment each time 217 // for each attachment each time
215 if (!m_part.ParentGroup.RootPart.IsAttachment) 218 if (!m_part.ParentGroup.IsAttachment)
216 { 219 {
217 HasInventoryChanged = true; 220 HasInventoryChanged = true;
218 m_part.ParentGroup.HasGroupChanged = true; 221 m_part.ParentGroup.HasGroupChanged = true;
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index d2f84e3..de9b1f3 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -67,7 +67,7 @@ namespace OpenSim.Region.Framework.Scenes
67 67
68 public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence, List<Vector3> coarseLocations, List<UUID> avatarUUIDs); 68 public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence, List<Vector3> coarseLocations, List<UUID> avatarUUIDs);
69 69
70 public class ScenePresence : EntityBase, ISceneEntity 70 public class ScenePresence : EntityBase, IScenePresence
71 { 71 {
72// ~ScenePresence() 72// ~ScenePresence()
73// { 73// {
@@ -76,6 +76,8 @@ namespace OpenSim.Region.Framework.Scenes
76 76
77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
78 78
79 public PresenceType PresenceType { get; private set; }
80
79// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); 81// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes();
80 private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); 82 private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags));
81 private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); 83 private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f);
@@ -92,6 +94,13 @@ namespace OpenSim.Region.Framework.Scenes
92 // Value revised by KF 091121 by comparison with SL. 94 // Value revised by KF 091121 by comparison with SL.
93 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f); 95 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
94 96
97 /// <summary>
98 /// Movement updates for agents in neighboring regions are sent directly to clients.
99 /// This value only affects how often agent positions are sent to neighbor regions
100 /// for things such as distance-based update prioritization
101 /// </summary>
102 public static readonly float SIGNIFICANT_MOVEMENT = 2.0f;
103
95 public UUID currentParcelUUID = UUID.Zero; 104 public UUID currentParcelUUID = UUID.Zero;
96 105
97 private ISceneViewer m_sceneViewer; 106 private ISceneViewer m_sceneViewer;
@@ -105,14 +114,13 @@ namespace OpenSim.Region.Framework.Scenes
105 } 114 }
106 protected ScenePresenceAnimator m_animator; 115 protected ScenePresenceAnimator m_animator;
107 116
108 /// <value> 117 /// <summary>
109 /// The scene objects attached to this avatar. Do not change this list directly - use methods such as 118 /// Attachments recorded on this avatar.
110 /// AddAttachment() and RemoveAttachment(). Lock this list when performing any read operations upon it. 119 /// </summary>
111 /// </value> 120 /// <remarks>
112 public List<SceneObjectGroup> Attachments 121 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is
113 { 122 /// necessary.
114 get { return m_attachments; } 123 /// </remarks>
115 }
116 124
117 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); 125 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
118 126
@@ -120,7 +128,7 @@ namespace OpenSim.Region.Framework.Scenes
120 private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO; 128 private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO;
121 private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO; 129 private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO;
122 private bool MouseDown = false; 130 private bool MouseDown = false;
123 private SceneObjectGroup proxyObjectGroup; 131// private SceneObjectGroup proxyObjectGroup;
124 //private SceneObjectPart proxyObjectPart = null; 132 //private SceneObjectPart proxyObjectPart = null;
125 public Vector3 lastKnownAllowedPosition; 133 public Vector3 lastKnownAllowedPosition;
126 public Vector4 CollisionPlane = Vector4.UnitW; 134 public Vector4 CollisionPlane = Vector4.UnitW;
@@ -178,7 +186,7 @@ namespace OpenSim.Region.Framework.Scenes
178 186
179 private float m_speedModifier = 1.0f; 187 private float m_speedModifier = 1.0f;
180 188
181 private Quaternion m_bodyRot= Quaternion.Identity; 189 private Quaternion m_bodyRot = Quaternion.Identity;
182 190
183 private Quaternion m_bodyRotPrevious = Quaternion.Identity; 191 private Quaternion m_bodyRotPrevious = Quaternion.Identity;
184 192
@@ -224,8 +232,8 @@ namespace OpenSim.Region.Framework.Scenes
224 private string m_nextSitAnimation = String.Empty; 232 private string m_nextSitAnimation = String.Empty;
225 233
226 //PauPaw:Proper PID Controler for autopilot************ 234 //PauPaw:Proper PID Controler for autopilot************
227 private bool m_moveToPositionInProgress; 235 public bool MovingToTarget { get; private set; }
228 private Vector3 m_moveToPositionTarget; 236 public Vector3 MoveToPositionTarget { get; private set; }
229 private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); 237 private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
230 238
231 private bool m_followCamAuto; 239 private bool m_followCamAuto;
@@ -455,9 +463,6 @@ namespace OpenSim.Region.Framework.Scenes
455 463
456 protected PhysicsActor m_physicsActor; 464 protected PhysicsActor m_physicsActor;
457 465
458 /// <value>
459 /// The client controlling this presence
460 /// </value>
461 public IClientAPI ControllingClient 466 public IClientAPI ControllingClient
462 { 467 {
463 get { return m_controllingClient; } 468 get { return m_controllingClient; }
@@ -765,15 +770,13 @@ namespace OpenSim.Region.Framework.Scenes
765 770
766 #region Constructor(s) 771 #region Constructor(s)
767 772
768 public ScenePresence() 773 public ScenePresence(
774 IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance, PresenceType type)
769 { 775 {
770 m_sendCourseLocationsMethod = SendCoarseLocationsDefault; 776 m_sendCourseLocationsMethod = SendCoarseLocationsDefault;
771 CreateSceneViewer(); 777 m_sceneViewer = new SceneViewer(this);
772 m_animator = new ScenePresenceAnimator(this); 778 m_animator = new ScenePresenceAnimator(this);
773 } 779 PresenceType = type;
774
775 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this()
776 {
777 m_DrawDistance = world.DefaultDrawDistance; 780 m_DrawDistance = world.DefaultDrawDistance;
778 m_rootRegionHandle = reginfo.RegionHandle; 781 m_rootRegionHandle = reginfo.RegionHandle;
779 m_controllingClient = client; 782 m_controllingClient = client;
@@ -817,19 +820,10 @@ namespace OpenSim.Region.Framework.Scenes
817 820
818 RegisterToEvents(); 821 RegisterToEvents();
819 SetDirectionVectors(); 822 SetDirectionVectors();
820 }
821 823
822 public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance)
823 : this(client, world, reginfo)
824 {
825 m_appearance = appearance; 824 m_appearance = appearance;
826 } 825 }
827 826
828 private void CreateSceneViewer()
829 {
830 m_sceneViewer = new SceneViewer(this);
831 }
832
833 public void RegisterToEvents() 827 public void RegisterToEvents()
834 { 828 {
835 m_controllingClient.OnCompleteMovementToRegion += CompleteMovement; 829 m_controllingClient.OnCompleteMovementToRegion += CompleteMovement;
@@ -841,8 +835,7 @@ namespace OpenSim.Region.Framework.Scenes
841 m_controllingClient.OnStartAnim += HandleStartAnim; 835 m_controllingClient.OnStartAnim += HandleStartAnim;
842 m_controllingClient.OnStopAnim += HandleStopAnim; 836 m_controllingClient.OnStopAnim += HandleStopAnim;
843 m_controllingClient.OnForceReleaseControls += HandleForceReleaseControls; 837 m_controllingClient.OnForceReleaseControls += HandleForceReleaseControls;
844 m_controllingClient.OnAutoPilotGo += DoAutoPilot; 838 m_controllingClient.OnAutoPilotGo += MoveToTarget;
845 m_controllingClient.AddGenericPacketHandler("autopilot", DoMoveToPosition);
846 839
847 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); 840 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange);
848 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); 841 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement);
@@ -1029,11 +1022,8 @@ namespace OpenSim.Region.Framework.Scenes
1029 } 1022 }
1030 1023
1031 float localAVHeight = 1.56f; 1024 float localAVHeight = 1.56f;
1032 if (m_appearance != null) 1025 if (m_appearance.AvatarHeight > 0)
1033 { 1026 localAVHeight = m_appearance.AvatarHeight;
1034 if (m_appearance.AvatarHeight > 0)
1035 localAVHeight = m_appearance.AvatarHeight;
1036 }
1037 1027
1038 float posZLimit = 0; 1028 float posZLimit = 0;
1039 1029
@@ -1047,26 +1037,8 @@ namespace OpenSim.Region.Framework.Scenes
1047 } 1037 }
1048 AbsolutePosition = pos; 1038 AbsolutePosition = pos;
1049 1039
1050 if (m_appearance != null)
1051 {
1052 if (m_appearance.AvatarHeight > 0)
1053 SetHeight(m_appearance.AvatarHeight);
1054 }
1055 else
1056 {
1057 m_log.ErrorFormat("[SCENE PRESENCE]: null appearance in MakeRoot in {0}", Scene.RegionInfo.RegionName);
1058 // emergency; this really shouldn't happen
1059 m_appearance = new AvatarAppearance(UUID);
1060 }
1061
1062 AddToPhysicalScene(isFlying); 1040 AddToPhysicalScene(isFlying);
1063 1041
1064 if (m_appearance != null)
1065 {
1066 if (m_appearance.AvatarHeight > 0)
1067 SetHeight(m_appearance.AvatarHeight);
1068 }
1069
1070 if (m_forceFly) 1042 if (m_forceFly)
1071 { 1043 {
1072 m_physicsActor.Flying = true; 1044 m_physicsActor.Flying = true;
@@ -1087,15 +1059,18 @@ namespace OpenSim.Region.Framework.Scenes
1087 // and it has already rezzed the attachments and started their scripts. 1059 // and it has already rezzed the attachments and started their scripts.
1088 // We do the following only for non-login agents, because their scripts 1060 // We do the following only for non-login agents, because their scripts
1089 // haven't started yet. 1061 // haven't started yet.
1090 if (wasChild && Attachments != null && Attachments.Count > 0) 1062 lock (m_attachments)
1091 { 1063 {
1092 m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments..."); 1064 if (wasChild && HasAttachments())
1093 // Resume scripts
1094 Attachments.ForEach(delegate(SceneObjectGroup sog)
1095 { 1065 {
1096 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); 1066 m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments...");
1097 sog.ResumeScripts(); 1067 // Resume scripts
1098 }); 1068 foreach (SceneObjectGroup sog in m_attachments)
1069 {
1070 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1071 sog.ResumeScripts();
1072 }
1073 }
1099 } 1074 }
1100 1075
1101 // send the animations of the other presences to me 1076 // send the animations of the other presences to me
@@ -1105,6 +1080,11 @@ namespace OpenSim.Region.Framework.Scenes
1105 presence.Animator.SendAnimPackToClient(ControllingClient); 1080 presence.Animator.SendAnimPackToClient(ControllingClient);
1106 }); 1081 });
1107 1082
1083 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will
1084 // stall on the border crossing since the existing child agent will still have the last movement
1085 // recorded, which stops the input from being processed.
1086 m_movementflag = 0;
1087
1108 m_scene.EventManager.TriggerOnMakeRootAgent(this); 1088 m_scene.EventManager.TriggerOnMakeRootAgent(this);
1109 } 1089 }
1110 1090
@@ -1196,11 +1176,6 @@ namespace OpenSim.Region.Framework.Scenes
1196 CheckLandingPoint(ref pos); 1176 CheckLandingPoint(ref pos);
1197 AbsolutePosition = pos; 1177 AbsolutePosition = pos;
1198 AddToPhysicalScene(isFlying); 1178 AddToPhysicalScene(isFlying);
1199 if (m_appearance != null)
1200 {
1201 if (m_appearance.AvatarHeight > 0)
1202 SetHeight(m_appearance.AvatarHeight);
1203 }
1204 1179
1205 SendTerseUpdateToAllClients(); 1180 SendTerseUpdateToAllClients();
1206 1181
@@ -1216,22 +1191,10 @@ namespace OpenSim.Region.Framework.Scenes
1216 CheckLandingPoint(ref pos); 1191 CheckLandingPoint(ref pos);
1217 AbsolutePosition = pos; 1192 AbsolutePosition = pos;
1218 AddToPhysicalScene(isFlying); 1193 AddToPhysicalScene(isFlying);
1219 if (m_appearance != null)
1220 {
1221 if (m_appearance.AvatarHeight > 0)
1222 SetHeight(m_appearance.AvatarHeight);
1223 }
1224 1194
1225 SendTerseUpdateToAllClients(); 1195 SendTerseUpdateToAllClients();
1226 } 1196 }
1227 1197
1228 /// <summary>
1229 ///
1230 /// </summary>
1231 public void StopMovement()
1232 {
1233 }
1234
1235 public void StopFlying() 1198 public void StopFlying()
1236 { 1199 {
1237 ControllingClient.StopFlying(this); 1200 ControllingClient.StopFlying(this);
@@ -1281,7 +1244,7 @@ namespace OpenSim.Region.Framework.Scenes
1281 #region Event Handlers 1244 #region Event Handlers
1282 1245
1283 /// <summary> 1246 /// <summary>
1284 /// Sets avatar height in the phyiscs plugin 1247 /// Sets avatar height in the physics plugin
1285 /// </summary> 1248 /// </summary>
1286 public void SetHeight(float height) 1249 public void SetHeight(float height)
1287 { 1250 {
@@ -1294,10 +1257,14 @@ namespace OpenSim.Region.Framework.Scenes
1294 1257
1295 /// <summary> 1258 /// <summary>
1296 /// Complete Avatar's movement into the region. 1259 /// Complete Avatar's movement into the region.
1297 /// This is called upon a very important packet sent from the client,
1298 /// so it's client-controlled. Never call this method directly.
1299 /// </summary> 1260 /// </summary>
1300 public void CompleteMovement(IClientAPI client) 1261 /// <param name="client"></param>
1262 /// <param name="openChildAgents">
1263 /// If true, send notification to neighbour regions to expect
1264 /// a child agent from the client. These neighbours can be some distance away, depending right now on the
1265 /// configuration of DefaultDrawDistance in the [Startup] section of config
1266 /// </param>
1267 public void CompleteMovement(IClientAPI client, bool openChildAgents)
1301 { 1268 {
1302// DateTime startTime = DateTime.Now; 1269// DateTime startTime = DateTime.Now;
1303 1270
@@ -1338,15 +1305,11 @@ namespace OpenSim.Region.Framework.Scenes
1338 SendInitialData(); 1305 SendInitialData();
1339 1306
1340 // Create child agents in neighbouring regions 1307 // Create child agents in neighbouring regions
1341 if (!m_isChildAgent) 1308 if (openChildAgents && !m_isChildAgent)
1342 { 1309 {
1343 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 1310 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
1344 if (m_agentTransfer != null) 1311 if (m_agentTransfer != null)
1345 m_agentTransfer.EnableChildAgents(this); 1312 m_agentTransfer.EnableChildAgents(this);
1346 else
1347 m_log.DebugFormat(
1348 "[SCENE PRESENCE]: Unable to create child agents in neighbours, because AgentTransferModule is not active for region {0}",
1349 m_scene.RegionInfo.RegionName);
1350 1313
1351 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); 1314 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
1352 if (friendsModule != null) 1315 if (friendsModule != null)
@@ -1403,6 +1366,8 @@ namespace OpenSim.Region.Framework.Scenes
1403 /// </summary> 1366 /// </summary>
1404 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 1367 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
1405 { 1368 {
1369// m_log.DebugFormat("[SCENE PRESENCE]: Received agent update from {0}", remoteClient.Name);
1370
1406 //if (m_isChildAgent) 1371 //if (m_isChildAgent)
1407 //{ 1372 //{
1408 // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent"); 1373 // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent");
@@ -1445,7 +1410,6 @@ namespace OpenSim.Region.Framework.Scenes
1445 #region Inputs 1410 #region Inputs
1446 1411
1447 AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags; 1412 AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags;
1448 Quaternion bodyRotation = agentData.BodyRotation;
1449 1413
1450 // Camera location in world. We'll need to raytrace 1414 // Camera location in world. We'll need to raytrace
1451 // from this location from time to time. 1415 // from this location from time to time.
@@ -1530,23 +1494,29 @@ namespace OpenSim.Region.Framework.Scenes
1530 { 1494 {
1531 return; 1495 return;
1532 } 1496 }
1533
1534 bool update_movementflag = false;
1535 1497
1536 if (m_allowMovement && !SitGround) 1498 if (m_allowMovement && !SitGround)
1537 { 1499 {
1500 Quaternion bodyRotation = agentData.BodyRotation;
1501 bool update_rotation = false;
1502
1503 if (bodyRotation != m_bodyRot)
1504 {
1505 Rotation = bodyRotation;
1506 update_rotation = true;
1507 }
1508
1509 bool update_movementflag = false;
1510
1538 if (agentData.UseClientAgentPosition) 1511 if (agentData.UseClientAgentPosition)
1539 { 1512 {
1540 m_moveToPositionInProgress = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f; 1513 MovingToTarget = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f;
1541 m_moveToPositionTarget = agentData.ClientAgentPosition; 1514 MoveToPositionTarget = agentData.ClientAgentPosition;
1542 } 1515 }
1543 1516
1544 int i = 0; 1517 int i = 0;
1545
1546 bool update_rotation = false;
1547 bool DCFlagKeyPressed = false; 1518 bool DCFlagKeyPressed = false;
1548 Vector3 agent_control_v3 = Vector3.Zero; 1519 Vector3 agent_control_v3 = Vector3.Zero;
1549 Quaternion q = bodyRotation;
1550 1520
1551 bool oldflying = PhysicsActor.Flying; 1521 bool oldflying = PhysicsActor.Flying;
1552 1522
@@ -1577,7 +1547,6 @@ namespace OpenSim.Region.Framework.Scenes
1577 if (m_parentID == 0) 1547 if (m_parentID == 0)
1578 { 1548 {
1579 bool bAllowUpdateMoveToPosition = false; 1549 bool bAllowUpdateMoveToPosition = false;
1580 bool bResetMoveToPosition = false;
1581 1550
1582 Vector3[] dirVectors; 1551 Vector3[] dirVectors;
1583 1552
@@ -1598,8 +1567,8 @@ namespace OpenSim.Region.Framework.Scenes
1598 { 1567 {
1599 if (((uint)flags & (uint)DCF) != 0) 1568 if (((uint)flags & (uint)DCF) != 0)
1600 { 1569 {
1601 bResetMoveToPosition = true;
1602 DCFlagKeyPressed = true; 1570 DCFlagKeyPressed = true;
1571
1603 try 1572 try
1604 { 1573 {
1605 agent_control_v3 += dirVectors[i]; 1574 agent_control_v3 += dirVectors[i];
@@ -1615,6 +1584,8 @@ namespace OpenSim.Region.Framework.Scenes
1615 1584
1616 if ((m_movementflag & (uint)DCF) == 0) 1585 if ((m_movementflag & (uint)DCF) == 0)
1617 { 1586 {
1587
1588// m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with {1}", Name, DCF);
1618 m_movementflag += (byte)(uint)DCF; 1589 m_movementflag += (byte)(uint)DCF;
1619 update_movementflag = true; 1590 update_movementflag = true;
1620 } 1591 }
@@ -1631,10 +1602,10 @@ namespace OpenSim.Region.Framework.Scenes
1631 bAllowUpdateMoveToPosition = true; 1602 bAllowUpdateMoveToPosition = true;
1632 } 1603 }
1633 } 1604 }
1605
1634 i++; 1606 i++;
1635 } 1607 }
1636 //Paupaw:Do Proper PID for Autopilot here 1608 if (MovingToTarget)
1637 if (bResetMoveToPosition)
1638 { 1609 {
1639 m_moveToPositionTarget = Vector3.Zero; 1610 m_moveToPositionTarget = Vector3.Zero;
1640 m_moveToPositionInProgress = false; 1611 m_moveToPositionInProgress = false;
@@ -1680,12 +1651,10 @@ namespace OpenSim.Region.Framework.Scenes
1680// if (there) 1651// if (there)
1681 if (Util.GetDistanceTo(abspos, tgt) <= 0.5f) 1652 if (Util.GetDistanceTo(abspos, tgt) <= 0.5f)
1682 { 1653 {
1683 // we are close enough to the target 1654 ResetMoveToTarget();
1684 m_moveToPositionTarget = Vector3.Zero;
1685 m_moveToPositionInProgress = false;
1686 update_movementflag = true; 1655 update_movementflag = true;
1687 } 1656 }
1688 else 1657 else if (bAllowUpdateMoveToPosition)
1689 { 1658 {
1690 try 1659 try
1691 { 1660 {
@@ -1790,14 +1759,26 @@ namespace OpenSim.Region.Framework.Scenes
1790 // which occurs later in the main scene loop 1759 // which occurs later in the main scene loop
1791 if (update_movementflag || (update_rotation && DCFlagKeyPressed)) 1760 if (update_movementflag || (update_rotation && DCFlagKeyPressed))
1792 { 1761 {
1793 // m_log.DebugFormat("{0} {1}", update_movementflag, (update_rotation && DCFlagKeyPressed)); 1762// m_log.DebugFormat(
1794 // m_log.DebugFormat( 1763// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}",
1795 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1764// m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation);
1796 1765
1797 AddNewMovement(agent_control_v3, q, Nudging); 1766 AddNewMovement(agent_control_v3, q, Nudging);
1798 1767
1799 1768
1800 } 1769 }
1770// else
1771// {
1772// if (!update_movementflag)
1773// {
1774// m_log.DebugFormat(
1775// "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false",
1776// m_scene.RegionInfo.RegionName, agent_control_v3, Name);
1777// }
1778// }
1779
1780 if (update_movementflag && m_parentID == 0)
1781 Animator.UpdateMovementAnimations();
1801 } 1782 }
1802 1783
1803 if (update_movementflag && !SitGround) 1784 if (update_movementflag && !SitGround)
@@ -1808,30 +1789,18 @@ namespace OpenSim.Region.Framework.Scenes
1808 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 1789 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
1809 } 1790 }
1810 1791
1811 public void DoAutoPilot(uint not_used, Vector3 Pos, IClientAPI remote_client) 1792 /// <summary>
1793 /// Calculate an update to move the presence to the set target.
1794 /// </summary>
1795 /// <remarks>
1796 /// This doesn't actually perform the movement. Instead, it adds its vector to agent_control_v3.
1797 /// </remarks>
1798 /// <param value="agent_control_v3">Cumulative agent movement that this method will update.</param>
1799 /// <returns>True if movement has been updated in some way. False otherwise.</returns>
1800 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3)
1812 { 1801 {
1813 m_autopilotMoving = true; 1802// m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name);
1814 m_autoPilotTarget = Pos; 1803 bool updated = false;
1815 m_sitAtAutoTarget = false;
1816 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1817 //proxy.PCode = (byte)PCode.ParticleSystem;
1818 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1819 proxyObjectGroup.AttachToScene(m_scene);
1820
1821 // Commented out this code since it could never have executed, but might still be informative.
1822// if (proxyObjectGroup != null)
1823// {
1824 proxyObjectGroup.SendGroupFullUpdate();
1825 remote_client.SendSitResponse(proxyObjectGroup.UUID, Vector3.Zero, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false);
1826 m_scene.DeleteSceneObject(proxyObjectGroup, false);
1827// }
1828// else
1829// {
1830// m_autopilotMoving = false;
1831// m_autoPilotTarget = Vector3.Zero;
1832// ControllingClient.SendAlertMessage("Autopilot cancelled");
1833// }
1834 }
1835 1804
1836 public void StopMoveToPosition() 1805 public void StopMoveToPosition()
1837 { 1806 {
@@ -1844,31 +1813,186 @@ namespace OpenSim.Region.Framework.Scenes
1844//Console.WriteLine("SP:DoMoveToPosition"); 1813//Console.WriteLine("SP:DoMoveToPosition");
1845 try 1814 try
1846 { 1815 {
1847 float locx = 0f; 1816 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget);
1848 float locy = 0f; 1817// m_log.DebugFormat(
1849 float locz = 0f; 1818// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}",
1850 uint regionX = 0; 1819// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
1851 uint regionY = 0; 1820
1852 try 1821 // Check the error term of the current position in relation to the target position
1822 if (distanceToTarget <= 1)
1853 { 1823 {
1854 Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY); 1824 // We are close enough to the target
1855 locx = Convert.ToSingle(args[0]) - (float)regionX; 1825 AbsolutePosition = MoveToPositionTarget;
1856 locy = Convert.ToSingle(args[1]) - (float)regionY; 1826 ResetMoveToTarget();
1857 locz = Convert.ToSingle(args[2]); 1827 updated = true;
1858 } 1828 }
1859 catch (InvalidCastException) 1829 else
1860 { 1830 {
1861 m_log.Error("[CLIENT]: Invalid autopilot request"); 1831 try
1862 return; 1832 {
1833 // move avatar in 3D at one meter/second towards target, in avatar coordinate frame.
1834 // This movement vector gets added to the velocity through AddNewMovement().
1835 // Theoretically we might need a more complex PID approach here if other
1836 // unknown forces are acting on the avatar and we need to adaptively respond
1837 // to such forces, but the following simple approach seems to works fine.
1838 Vector3 LocalVectorToTarget3D =
1839 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1840 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords
1841 // Ignore z component of vector
1842// Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1843 LocalVectorToTarget3D.Normalize();
1844
1845 // update avatar movement flags. the avatar coordinate system is as follows:
1846 //
1847 // +X (forward)
1848 //
1849 // ^
1850 // |
1851 // |
1852 // |
1853 // |
1854 // (left) +Y <--------o--------> -Y
1855 // avatar
1856 // |
1857 // |
1858 // |
1859 // |
1860 // v
1861 // -X
1862 //
1863
1864 // based on the above avatar coordinate system, classify the movement into
1865 // one of left/right/back/forward.
1866 if (LocalVectorToTarget3D.X < 0) //MoveBack
1867 {
1868 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
1869 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
1870 updated = true;
1871 }
1872 else if (LocalVectorToTarget3D.X > 0) //Move Forward
1873 {
1874 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
1875 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
1876 updated = true;
1877 }
1878
1879 if (LocalVectorToTarget3D.Y > 0) //MoveLeft
1880 {
1881 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
1882 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
1883 updated = true;
1884 }
1885 else if (LocalVectorToTarget3D.Y < 0) //MoveRight
1886 {
1887 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
1888 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
1889 updated = true;
1890 }
1891
1892 if (LocalVectorToTarget3D.Z > 0) //Up
1893 {
1894 // Don't set these flags for up or down - doing so will make the avatar crouch or
1895 // keep trying to jump even if walking along level ground
1896 //m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP;
1897 //AgentControlFlags
1898 //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP;
1899 updated = true;
1900 }
1901 else if (LocalVectorToTarget3D.Z < 0) //Down
1902 {
1903 //m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN;
1904 //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN;
1905 updated = true;
1906 }
1907
1908// m_log.DebugFormat(
1909// "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}",
1910// LocalVectorToTarget3D, agent_control_v3, Name);
1911
1912 agent_control_v3 += LocalVectorToTarget3D;
1913 }
1914 catch (Exception e)
1915 {
1916 //Avoid system crash, can be slower but...
1917 m_log.DebugFormat("Crash! {0}", e.ToString());
1918 }
1863 } 1919 }
1864 m_moveToPositionInProgress = true;
1865 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1866 } 1920 }
1867 catch (Exception ex) 1921
1868 { 1922 return updated;
1869 //Why did I get this error? 1923 }
1870 m_log.Error("[SCENEPRESENCE]: DoMoveToPosition" + ex); 1924
1871 } 1925 /// <summary>
1926 /// Move to the given target over time.
1927 /// </summary>
1928 /// <param name="pos"></param>
1929 /// <param name="noFly">
1930 /// If true, then don't allow the avatar to fly to the target, even if it's up in the air.
1931 /// This is to allow movement to targets that are known to be on an elevated platform with a continuous path
1932 /// from start to finish.
1933 /// </param>
1934 public void MoveToTarget(Vector3 pos, bool noFly)
1935 {
1936 m_log.DebugFormat(
1937 "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}",
1938 Name, pos, m_scene.RegionInfo.RegionName);
1939
1940 if (pos.X < 0 || pos.X >= Constants.RegionSize
1941 || pos.Y < 0 || pos.Y >= Constants.RegionSize
1942 || pos.Z < 0)
1943 return;
1944
1945// Vector3 heightAdjust = new Vector3(0, 0, Appearance.AvatarHeight / 2);
1946// pos += heightAdjust;
1947//
1948// // Anti duck-walking measure
1949// if (Math.Abs(pos.Z - AbsolutePosition.Z) < 0.2f)
1950// {
1951//// m_log.DebugFormat("[SCENE PRESENCE]: Adjusting MoveToPosition from {0} to {1}", pos, AbsolutePosition);
1952// pos.Z = AbsolutePosition.Z;
1953// }
1954
1955 float terrainHeight = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
1956 pos.Z = Math.Max(terrainHeight, pos.Z);
1957
1958 // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is
1959 // always slightly higher than the actual terrain height.
1960 // FIXME: This constrains NOC movements as well, so should be somewhere else.
1961 if (pos.Z - terrainHeight < 0.2)
1962 pos.Z = terrainHeight;
1963
1964 m_log.DebugFormat(
1965 "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}",
1966 Name, pos, terrainHeight, m_scene.RegionInfo.RegionName);
1967
1968 if (noFly)
1969 PhysicsActor.Flying = false;
1970 else if (pos.Z > terrainHeight)
1971 PhysicsActor.Flying = true;
1972
1973 MovingToTarget = true;
1974 MoveToPositionTarget = pos;
1975
1976 Vector3 agent_control_v3 = new Vector3();
1977 HandleMoveToTargetUpdate(ref agent_control_v3);
1978 AddNewMovement(agent_control_v3);
1979 }
1980
1981 /// <summary>
1982 /// Reset the move to target.
1983 /// </summary>
1984 public void ResetMoveToTarget()
1985 {
1986 m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
1987
1988 MovingToTarget = false;
1989 MoveToPositionTarget = Vector3.Zero;
1990
1991 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct
1992 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag.
1993 // However, the line is here rather than in the NPC module since it also appears necessary to stop a
1994 // viewer that uses "go here" from juddering on all subsequent avatar movements.
1995 AgentControlFlags = (uint)AgentManager.ControlFlags.NONE;
1872 } 1996 }
1873 1997
1874 private void CheckAtSitTarget() 1998 private void CheckAtSitTarget()
@@ -1997,11 +2121,6 @@ namespace OpenSim.Region.Framework.Scenes
1997 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); 2121 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1998 SendAvatarDataToAllAgents(); 2122 SendAvatarDataToAllAgents();
1999 m_requestedSitTargetID = 0; 2123 m_requestedSitTargetID = 0;
2000 if (m_physicsActor != null && m_appearance != null)
2001 {
2002 if (m_appearance.AvatarHeight > 0)
2003 SetHeight(m_appearance.AvatarHeight);
2004 }
2005 } 2124 }
2006 Animator.TrySetMovementAnimation("STAND"); 2125 Animator.TrySetMovementAnimation("STAND");
2007 } 2126 }
@@ -2057,7 +2176,7 @@ namespace OpenSim.Region.Framework.Scenes
2057 bool forceMouselook = false; 2176 bool forceMouselook = false;
2058 2177
2059 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 2178 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
2060 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 2179 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
2061 if (part == null) return; 2180 if (part == null) return;
2062 2181
2063 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 2182 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
@@ -2215,14 +2334,23 @@ namespace OpenSim.Region.Framework.Scenes
2215 HandleAgentSit(remoteClient, UUID); 2334 HandleAgentSit(remoteClient, UUID);
2216 } 2335 }
2217 2336
2337 // public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset, string sitAnimation)
2218 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset) 2338 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset)
2219 { 2339 {
2220 if (m_parentID != 0) 2340 if (m_parentID != 0)
2221 { 2341 {
2222 StandUp(); 2342 StandUp();
2223 } 2343 }
2344
2345// if (!String.IsNullOrEmpty(sitAnimation))
2346// {
2347// m_nextSitAnimation = sitAnimation;
2348// }
2349// else
2350// {
2224 m_nextSitAnimation = "SIT"; 2351 m_nextSitAnimation = "SIT";
2225 2352// }
2353
2226 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 2354 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
2227 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 2355 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
2228 2356
@@ -2247,7 +2375,6 @@ namespace OpenSim.Region.Framework.Scenes
2247 } 2375 }
2248 else 2376 else
2249 { 2377 {
2250
2251 m_log.Warn("Sit requested on unknown object: " + targetID.ToString()); 2378 m_log.Warn("Sit requested on unknown object: " + targetID.ToString());
2252 } 2379 }
2253 2380
@@ -2445,44 +2572,7 @@ namespace OpenSim.Region.Framework.Scenes
2445 SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); 2572 SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity);
2446 } 2573 }
2447 */ 2574 */
2448 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset, string sitAnimation)
2449 {
2450 if (m_parentID != 0)
2451 {
2452 StandUp();
2453 }
2454 if (!String.IsNullOrEmpty(sitAnimation))
2455 {
2456 m_nextSitAnimation = sitAnimation;
2457 }
2458 else
2459 {
2460 m_nextSitAnimation = "SIT";
2461 }
2462
2463 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
2464 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
2465 if (part != null)
2466 {
2467 m_requestedSitTargetID = part.LocalId;
2468 //m_requestedSitOffset = offset;
2469 m_requestedSitTargetUUID = targetID;
2470 2575
2471 m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
2472
2473 if (m_scene.PhysicsScene.SupportsRayCast())
2474 {
2475 //SitRayCastAvatarPosition(part);
2476 //return;
2477 }
2478 }
2479 else
2480 {
2481 m_log.Warn("Sit requested on unknown object: " + targetID);
2482 }
2483
2484 SendSitResponse(remoteClient, targetID, offset, Quaternion.Identity);
2485 }
2486 2576
2487 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) 2577 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
2488 { 2578 {
@@ -2669,8 +2759,7 @@ namespace OpenSim.Region.Framework.Scenes
2669 2759
2670 m_perfMonMS = Util.EnvironmentTickCount(); 2760 m_perfMonMS = Util.EnvironmentTickCount();
2671 2761
2672 Rotation = rotation; 2762 Vector3 direc = vec * Rotation;
2673 Vector3 direc = vec * rotation;
2674 direc.Normalize(); 2763 direc.Normalize();
2675 PhysicsActor actor = m_physicsActor; 2764 PhysicsActor actor = m_physicsActor;
2676 2765
@@ -2901,13 +2990,7 @@ namespace OpenSim.Region.Framework.Scenes
2901 // We have an appearance but we may not have the baked textures. Check the asset cache 2990 // We have an appearance but we may not have the baked textures. Check the asset cache
2902 // to see if all the baked textures are already here. 2991 // to see if all the baked textures are already here.
2903 if (m_scene.AvatarFactory != null) 2992 if (m_scene.AvatarFactory != null)
2904 {
2905 cachedappearance = m_scene.AvatarFactory.ValidateBakedTextureCache(m_controllingClient); 2993 cachedappearance = m_scene.AvatarFactory.ValidateBakedTextureCache(m_controllingClient);
2906 }
2907 else
2908 {
2909 m_log.WarnFormat("[SCENEPRESENCE]: AvatarFactory not set for {0}", Name);
2910 }
2911 2994
2912 // If we aren't using a cached appearance, then clear out the baked textures 2995 // If we aren't using a cached appearance, then clear out the baked textures
2913 if (!cachedappearance) 2996 if (!cachedappearance)
@@ -3064,19 +3147,21 @@ namespace OpenSim.Region.Framework.Scenes
3064 /// <param name="avatar"></param> 3147 /// <param name="avatar"></param>
3065 public void SendAppearanceToAgent(ScenePresence avatar) 3148 public void SendAppearanceToAgent(ScenePresence avatar)
3066 { 3149 {
3067// m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); 3150// m_log.DebugFormat(
3151// "[SCENE PRESENCE] Send appearance from {0} {1} to {2} {3}", Name, m_uuid, avatar.Name, avatar.UUID);
3068 3152
3069 avatar.ControllingClient.SendAppearance( 3153 avatar.ControllingClient.SendAppearance(
3070 m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); 3154 UUID, m_appearance.VisualParams, m_appearance.Texture.GetBytes());
3071 } 3155 }
3072 3156
3073 // Because appearance setting is in a module, we actually need
3074 // to give it access to our appearance directly, otherwise we
3075 // get a synchronization issue.
3076 public AvatarAppearance Appearance 3157 public AvatarAppearance Appearance
3077 { 3158 {
3078 get { return m_appearance; } 3159 get { return m_appearance; }
3079 set { m_appearance = value; } 3160 set
3161 {
3162 m_appearance = value;
3163// m_log.DebugFormat("[SCENE PRESENCE]: Set appearance for {0} to {1}", Name, value);
3164 }
3080 } 3165 }
3081 3166
3082 #endregion 3167 #endregion
@@ -3088,15 +3173,10 @@ namespace OpenSim.Region.Framework.Scenes
3088 /// </summary> 3173 /// </summary>
3089 protected void CheckForSignificantMovement() 3174 protected void CheckForSignificantMovement()
3090 { 3175 {
3091 // Movement updates for agents in neighboring regions are sent directly to clients.
3092 // This value only affects how often agent positions are sent to neighbor regions
3093 // for things such as distance-based update prioritization
3094 const float SIGNIFICANT_MOVEMENT = 2.0f;
3095
3096 if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > SIGNIFICANT_MOVEMENT) 3176 if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > SIGNIFICANT_MOVEMENT)
3097 { 3177 {
3098 posLastSignificantMove = AbsolutePosition; 3178 posLastSignificantMove = AbsolutePosition;
3099 m_scene.EventManager.TriggerSignificantClientMovement(m_controllingClient); 3179 m_scene.EventManager.TriggerSignificantClientMovement(this);
3100 } 3180 }
3101 3181
3102 // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m 3182 // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m
@@ -3579,7 +3659,7 @@ namespace OpenSim.Region.Framework.Scenes
3579 ISceneObject clone = sog.CloneForNewScene(); 3659 ISceneObject clone = sog.CloneForNewScene();
3580 // Attachment module assumes that GroupPosition holds the offsets...! 3660 // Attachment module assumes that GroupPosition holds the offsets...!
3581 ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; 3661 ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos;
3582 ((SceneObjectGroup)clone).RootPart.IsAttachment = false; 3662 ((SceneObjectGroup)clone).IsAttachment = false;
3583 cAgent.AttachmentObjects.Add(clone); 3663 cAgent.AttachmentObjects.Add(clone);
3584 string state = sog.GetStateSnapshot(); 3664 string state = sog.GetStateSnapshot();
3585 cAgent.AttachmentObjectStates.Add(state); 3665 cAgent.AttachmentObjectStates.Add(state);
@@ -3746,6 +3826,8 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
3746 m_physicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong 3826 m_physicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
3747 m_physicsActor.SubscribeEvents(500); 3827 m_physicsActor.SubscribeEvents(500);
3748 m_physicsActor.LocalID = LocalId; 3828 m_physicsActor.LocalID = LocalId;
3829
3830 SetHeight(m_appearance.AvatarHeight);
3749 } 3831 }
3750 3832
3751 private void OutOfBoundsCall(Vector3 pos) 3833 private void OutOfBoundsCall(Vector3 pos)
@@ -4001,19 +4083,7 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4001 4083
4002 public void Close() 4084 public void Close()
4003 { 4085 {
4004 lock (m_attachments) 4086 m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false);
4005 {
4006 // Delete attachments from scene
4007 // Don't try to save, as this thread won't live long
4008 // enough to complete the save. This would cause no copy
4009 // attachments to poof!
4010 //
4011 foreach (SceneObjectGroup grp in m_attachments)
4012 {
4013 m_scene.DeleteSceneObject(grp, false);
4014 }
4015 m_attachments.Clear();
4016 }
4017 4087
4018 lock (m_knownChildRegions) 4088 lock (m_knownChildRegions)
4019 { 4089 {
@@ -4048,9 +4118,19 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4048 m_attachments.Add(gobj); 4118 m_attachments.Add(gobj);
4049 } 4119 }
4050 } 4120 }
4051 4121
4122 /// <summary>
4123 /// Get all the presence's attachments.
4124 /// </summary>
4125 /// <returns>A copy of the list which contains the attachments.</returns>
4126 public List<SceneObjectGroup> GetAttachments()
4127 {
4128 lock (m_attachments)
4129 return new List<SceneObjectGroup>(m_attachments);
4130 }
4131
4052 /// <summary> 4132 /// <summary>
4053 /// Get the scene object attached to the given point. 4133 /// Get the scene objects attached to the given point.
4054 /// </summary> 4134 /// </summary>
4055 /// <param name="attachmentPoint"></param> 4135 /// <param name="attachmentPoint"></param>
4056 /// <returns>Returns an empty list if there were no attachments at the point.</returns> 4136 /// <returns>Returns an empty list if there were no attachments at the point.</returns>
@@ -4062,7 +4142,7 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4062 { 4142 {
4063 foreach (SceneObjectGroup so in m_attachments) 4143 foreach (SceneObjectGroup so in m_attachments)
4064 { 4144 {
4065 if (attachmentPoint == so.RootPart.AttachmentPoint) 4145 if (attachmentPoint == so.AttachmentPoint)
4066 attachments.Add(so); 4146 attachments.Add(so);
4067 } 4147 }
4068 } 4148 }
@@ -4072,7 +4152,8 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4072 4152
4073 public bool HasAttachments() 4153 public bool HasAttachments()
4074 { 4154 {
4075 return m_attachments.Count > 0; 4155 lock (m_attachments)
4156 return m_attachments.Count > 0;
4076 } 4157 }
4077 4158
4078 public bool HasScriptedAttachments() 4159 public bool HasScriptedAttachments()
@@ -4094,12 +4175,16 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4094 public void RemoveAttachment(SceneObjectGroup gobj) 4175 public void RemoveAttachment(SceneObjectGroup gobj)
4095 { 4176 {
4096 lock (m_attachments) 4177 lock (m_attachments)
4097 { 4178 m_attachments.Remove(gobj);
4098 if (m_attachments.Contains(gobj)) 4179 }
4099 { 4180
4100 m_attachments.Remove(gobj); 4181 /// <summary>
4101 } 4182 /// Clear all attachments
4102 } 4183 /// </summary>
4184 public void ClearAttachments()
4185 {
4186 lock (m_attachments)
4187 m_attachments.Clear();
4103 } 4188 }
4104 4189
4105 public bool ValidateAttachments() 4190 public bool ValidateAttachments()
@@ -4110,12 +4195,22 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4110 foreach (SceneObjectGroup gobj in m_attachments) 4195 foreach (SceneObjectGroup gobj in m_attachments)
4111 { 4196 {
4112 if (gobj == null) 4197 if (gobj == null)
4198 {
4199 m_log.WarnFormat(
4200 "[SCENE PRESENCE]: Failed to validate an attachment for {0} since it was null", Name);
4113 return false; 4201 return false;
4202 }
4114 4203
4115 if (gobj.IsDeleted) 4204 if (gobj.IsDeleted)
4205 {
4206 m_log.WarnFormat(
4207 "[SCENE PRESENCE]: Failed to validate attachment {0} {1} for {2} since it had been deleted",
4208 gobj.Name, gobj.UUID, Name);
4116 return false; 4209 return false;
4210 }
4117 } 4211 }
4118 } 4212 }
4213
4119 return true; 4214 return true;
4120 } 4215 }
4121 4216
@@ -4553,4 +4648,4 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4553 } 4648 }
4554 } 4649 }
4555 } 4650 }
4556} 4651} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
index f04ed4d..501487a 100644
--- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
@@ -110,7 +110,7 @@ namespace OpenSim.Region.Framework.Scenes
110 { 110 {
111 SceneObjectPart part = m_partsUpdateQueue.Dequeue(); 111 SceneObjectPart part = m_partsUpdateQueue.Dequeue();
112 112
113 if (part.ParentGroup == null || part.ParentGroup.IsDeleted) 113 if (part.ParentGroup.IsDeleted)
114 continue; 114 continue;
115 115
116 if (m_updateTimes.ContainsKey(part.UUID)) 116 if (m_updateTimes.ContainsKey(part.UUID))
@@ -120,8 +120,7 @@ namespace OpenSim.Region.Framework.Scenes
120 // We deal with the possibility that two updates occur at 120 // We deal with the possibility that two updates occur at
121 // the same unix time at the update point itself. 121 // the same unix time at the update point itself.
122 122
123 if ((update.LastFullUpdateTime < part.TimeStampFull) || 123 if ((update.LastFullUpdateTime < part.TimeStampFull) || part.ParentGroup.IsAttachment)
124 part.IsAttachment)
125 { 124 {
126 // m_log.DebugFormat( 125 // m_log.DebugFormat(
127 // "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}", 126 // "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}",
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index d6e8223..11dad6c 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -53,19 +53,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
53 /// <summary> 53 /// <summary>
54 /// Deserialize a scene object from the original xml format 54 /// Deserialize a scene object from the original xml format
55 /// </summary> 55 /// </summary>
56 /// <param name="serialization"></param> 56 /// <param name="xmlData"></param>
57 /// <returns></returns> 57 /// <returns></returns>
58 public static SceneObjectGroup FromOriginalXmlFormat(string serialization) 58 public static SceneObjectGroup FromOriginalXmlFormat(string xmlData)
59 {
60 return FromOriginalXmlFormat(UUID.Zero, serialization);
61 }
62
63 /// <summary>
64 /// Deserialize a scene object from the original xml format
65 /// </summary>
66 /// <param name="serialization"></param>
67 /// <returns></returns>
68 public static SceneObjectGroup FromOriginalXmlFormat(UUID fromUserInventoryItemID, string xmlData)
69 { 59 {
70 //m_log.DebugFormat("[SOG]: Starting deserialization of SOG"); 60 //m_log.DebugFormat("[SOG]: Starting deserialization of SOG");
71 //int time = System.Environment.TickCount; 61 //int time = System.Environment.TickCount;
@@ -87,7 +77,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
87 77
88 sr = new StringReader(parts[0].InnerXml); 78 sr = new StringReader(parts[0].InnerXml);
89 reader = new XmlTextReader(sr); 79 reader = new XmlTextReader(sr);
90 SceneObjectGroup sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(fromUserInventoryItemID, reader)); 80 SceneObjectGroup sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(reader));
91 reader.Close(); 81 reader.Close();
92 sr.Close(); 82 sr.Close();
93 83
@@ -102,7 +92,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
102 sceneObject.AddPart(part); 92 sceneObject.AddPart(part);
103 part.LinkNum = linkNum; 93 part.LinkNum = linkNum;
104 part.TrimPermissions(); 94 part.TrimPermissions();
105 part.StoreUndoState(UndoType.STATE_ALL);
106 reader.Close(); 95 reader.Close();
107 sr.Close(); 96 sr.Close();
108 } 97 }
@@ -128,26 +117,36 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
128 /// <returns></returns> 117 /// <returns></returns>
129 public static string ToOriginalXmlFormat(SceneObjectGroup sceneObject) 118 public static string ToOriginalXmlFormat(SceneObjectGroup sceneObject)
130 { 119 {
120 return ToOriginalXmlFormat(sceneObject, true);
121 }
122
123 /// <summary>
124 /// Serialize a scene object to the original xml format
125 /// </summary>
126 /// <param name="sceneObject"></param>
127 /// <param name="doScriptStates">Control whether script states are also serialized.</para>
128 /// <returns></returns>
129 public static string ToOriginalXmlFormat(SceneObjectGroup sceneObject, bool doScriptStates)
130 {
131 using (StringWriter sw = new StringWriter()) 131 using (StringWriter sw = new StringWriter())
132 { 132 {
133 using (XmlTextWriter writer = new XmlTextWriter(sw)) 133 using (XmlTextWriter writer = new XmlTextWriter(sw))
134 { 134 {
135 ToOriginalXmlFormat(sceneObject, writer); 135 ToOriginalXmlFormat(sceneObject, writer, doScriptStates);
136 } 136 }
137 137
138 return sw.ToString(); 138 return sw.ToString();
139 } 139 }
140 } 140 }
141
142 141
143 /// <summary> 142 /// <summary>
144 /// Serialize a scene object to the original xml format 143 /// Serialize a scene object to the original xml format
145 /// </summary> 144 /// </summary>
146 /// <param name="sceneObject"></param> 145 /// <param name="sceneObject"></param>
147 /// <returns></returns> 146 /// <returns></returns>
148 public static void ToOriginalXmlFormat(SceneObjectGroup sceneObject, XmlTextWriter writer) 147 public static void ToOriginalXmlFormat(SceneObjectGroup sceneObject, XmlTextWriter writer, bool doScriptStates)
149 { 148 {
150 ToOriginalXmlFormat(sceneObject, writer, false); 149 ToOriginalXmlFormat(sceneObject, writer, doScriptStates, false);
151 } 150 }
152 151
153 /// <summary> 152 /// <summary>
@@ -157,10 +156,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
157 /// <param name="writer"></param> 156 /// <param name="writer"></param>
158 /// <param name="noRootElement">If false, don't write the enclosing SceneObjectGroup element</param> 157 /// <param name="noRootElement">If false, don't write the enclosing SceneObjectGroup element</param>
159 /// <returns></returns> 158 /// <returns></returns>
160 public static void ToOriginalXmlFormat(SceneObjectGroup sceneObject, XmlTextWriter writer, bool noRootElement) 159 public static void ToOriginalXmlFormat(
160 SceneObjectGroup sceneObject, XmlTextWriter writer, bool doScriptStates, bool noRootElement)
161 { 161 {
162 //m_log.DebugFormat("[SERIALIZER]: Starting serialization of {0}", Name); 162// m_log.DebugFormat("[SERIALIZER]: Starting serialization of {0}", sceneObject.Name);
163 //int time = System.Environment.TickCount; 163// int time = System.Environment.TickCount;
164 164
165 if (!noRootElement) 165 if (!noRootElement)
166 writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty); 166 writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty);
@@ -183,12 +183,14 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
183 } 183 }
184 184
185 writer.WriteEndElement(); // OtherParts 185 writer.WriteEndElement(); // OtherParts
186 sceneObject.SaveScriptedState(writer); 186
187 if (doScriptStates)
188 sceneObject.SaveScriptedState(writer);
187 189
188 if (!noRootElement) 190 if (!noRootElement)
189 writer.WriteEndElement(); // SceneObjectGroup 191 writer.WriteEndElement(); // SceneObjectGroup
190 192
191 //m_log.DebugFormat("[SERIALIZER]: Finished serialization of SOG {0}, {1}ms", Name, System.Environment.TickCount - time); 193// m_log.DebugFormat("[SERIALIZER]: Finished serialization of SOG {0}, {1}ms", sceneObject.Name, System.Environment.TickCount - time);
192 } 194 }
193 195
194 protected static void ToXmlFormat(SceneObjectPart part, XmlTextWriter writer) 196 protected static void ToXmlFormat(SceneObjectPart part, XmlTextWriter writer)
@@ -236,15 +238,14 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
236 if (originalLinkNum != 0) 238 if (originalLinkNum != 0)
237 part.LinkNum = originalLinkNum; 239 part.LinkNum = originalLinkNum;
238 240
239 part.StoreUndoState(UndoType.STATE_ALL);
240 reader.Close(); 241 reader.Close();
241 sr.Close(); 242 sr.Close();
242 } 243 }
243 244
244 // Script state may, or may not, exist. Not having any, is NOT 245 // Script state may, or may not, exist. Not having any, is NOT
245 // ever a problem. 246 // ever a problem.
246
247 sceneObject.LoadScriptState(doc); 247 sceneObject.LoadScriptState(doc);
248
248 return sceneObject; 249 return sceneObject;
249 } 250 }
250 catch (Exception e) 251 catch (Exception e)
@@ -1592,4 +1593,4 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1592 1593
1593 #endregion 1594 #endregion
1594 } 1595 }
1595} 1596} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs
deleted file mode 100644
index cff649b..0000000
--- a/OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs
+++ /dev/null
@@ -1,172 +0,0 @@
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 System.Threading;
33using System.Timers;
34using Timer=System.Timers.Timer;
35using Nini.Config;
36using NUnit.Framework;
37using OpenMetaverse;
38using OpenSim.Framework;
39using OpenSim.Framework.Communications;
40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.CoreModules.World.Serialiser;
43using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
44using OpenSim.Tests.Common;
45using OpenSim.Tests.Common.Mock;
46
47namespace OpenSim.Region.Framework.Scenes.Tests
48{
49 /// <summary>
50 /// Attachment tests
51 /// </summary>
52 [TestFixture]
53 public class AttachmentTests
54 {
55 public Scene scene, scene2;
56 public UUID agent1;
57 public static Random random;
58 public ulong region1, region2;
59 public AgentCircuitData acd1;
60 public SceneObjectGroup sog1, sog2, sog3;
61
62 [TestFixtureSetUp]
63 public void Init()
64 {
65 TestHelper.InMethod();
66
67 scene = SceneSetupHelpers.SetupScene("Neighbour x", UUID.Random(), 1000, 1000);
68 scene2 = SceneSetupHelpers.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000);
69
70 ISharedRegionModule interregionComms = new LocalSimulationConnectorModule();
71 interregionComms.Initialise(new IniConfigSource());
72 interregionComms.PostInitialise();
73 SceneSetupHelpers.SetupSceneModules(scene, new IniConfigSource(), interregionComms);
74 SceneSetupHelpers.SetupSceneModules(scene2, new IniConfigSource(), interregionComms);
75
76 agent1 = UUID.Random();
77 random = new Random();
78 sog1 = NewSOG(UUID.Random(), scene, agent1);
79 sog2 = NewSOG(UUID.Random(), scene, agent1);
80 sog3 = NewSOG(UUID.Random(), scene, agent1);
81
82 //ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
83 region1 = scene.RegionInfo.RegionHandle;
84 region2 = scene2.RegionInfo.RegionHandle;
85
86 SceneSetupHelpers.AddRootAgent(scene, agent1);
87 }
88
89 [Test]
90 public void T030_TestAddAttachments()
91 {
92 TestHelper.InMethod();
93
94 ScenePresence presence = scene.GetScenePresence(agent1);
95
96 presence.AddAttachment(sog1);
97 presence.AddAttachment(sog2);
98 presence.AddAttachment(sog3);
99
100 Assert.That(presence.HasAttachments(), Is.True);
101 Assert.That(presence.ValidateAttachments(), Is.True);
102 }
103
104 [Test]
105 public void T031_RemoveAttachments()
106 {
107 TestHelper.InMethod();
108
109 ScenePresence presence = scene.GetScenePresence(agent1);
110 presence.RemoveAttachment(sog1);
111 presence.RemoveAttachment(sog2);
112 presence.RemoveAttachment(sog3);
113 Assert.That(presence.HasAttachments(), Is.False);
114 }
115
116 // I'm commenting this test because scene setup NEEDS InventoryService to
117 // be non-null
118 //[Test]
119 public void T032_CrossAttachments()
120 {
121 TestHelper.InMethod();
122
123 ScenePresence presence = scene.GetScenePresence(agent1);
124 ScenePresence presence2 = scene2.GetScenePresence(agent1);
125 presence2.AddAttachment(sog1);
126 presence2.AddAttachment(sog2);
127
128 ISharedRegionModule serialiser = new SerialiserModule();
129 SceneSetupHelpers.SetupSceneModules(scene, new IniConfigSource(), serialiser);
130 SceneSetupHelpers.SetupSceneModules(scene2, new IniConfigSource(), serialiser);
131
132 Assert.That(presence.HasAttachments(), Is.False, "Presence has attachments before cross");
133
134 //Assert.That(presence2.CrossAttachmentsIntoNewRegion(region1, true), Is.True, "Cross was not successful");
135 Assert.That(presence2.HasAttachments(), Is.False, "Presence2 objects were not deleted");
136 Assert.That(presence.HasAttachments(), Is.True, "Presence has not received new objects");
137 }
138
139 private SceneObjectGroup NewSOG(UUID uuid, Scene scene, UUID agent)
140 {
141 SceneObjectPart sop = new SceneObjectPart();
142 sop.Name = RandomName();
143 sop.Description = RandomName();
144 sop.Text = RandomName();
145 sop.SitName = RandomName();
146 sop.TouchName = RandomName();
147 sop.UUID = uuid;
148 sop.Shape = PrimitiveBaseShape.Default;
149 sop.Shape.State = 1;
150 sop.OwnerID = agent;
151
152 SceneObjectGroup sog = new SceneObjectGroup(sop);
153 sog.SetScene(scene);
154
155 return sog;
156 }
157
158 private static string RandomName()
159 {
160 StringBuilder name = new StringBuilder();
161 int size = random.Next(5,12);
162 char ch;
163 for (int i = 0; i < size; i++)
164 {
165 ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))) ;
166 name.Append(ch);
167 }
168
169 return name.ToString();
170 }
171 }
172} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs b/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs
index 3a0dd00..ab6311b 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs
@@ -41,7 +41,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
41 [Test] 41 [Test]
42 public void TestCross() 42 public void TestCross()
43 { 43 {
44 TestHelper.InMethod(); 44 TestHelpers.InMethod();
45 45
46 List<Border> testborders = new List<Border>(); 46 List<Border> testborders = new List<Border>();
47 47
@@ -99,7 +99,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
99 [Test] 99 [Test]
100 public void TestCrossSquare512() 100 public void TestCrossSquare512()
101 { 101 {
102 TestHelper.InMethod(); 102 TestHelpers.InMethod();
103 103
104 List<Border> testborders = new List<Border>(); 104 List<Border> testborders = new List<Border>();
105 105
@@ -179,7 +179,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
179 [Test] 179 [Test]
180 public void TestCrossRectangle512x256() 180 public void TestCrossRectangle512x256()
181 { 181 {
182 TestHelper.InMethod(); 182 TestHelpers.InMethod();
183 183
184 List<Border> testborders = new List<Border>(); 184 List<Border> testborders = new List<Border>();
185 185
@@ -259,7 +259,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
259 [Test] 259 [Test]
260 public void TestCrossOdd512x512w256hole() 260 public void TestCrossOdd512x512w256hole()
261 { 261 {
262 TestHelper.InMethod(); 262 TestHelpers.InMethod();
263 263
264 List<Border> testborders = new List<Border>(); 264 List<Border> testborders = new List<Border>();
265 // 512____ 265 // 512____
diff --git a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs
index f69a4b4..a5d2b23 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs
@@ -45,12 +45,12 @@ namespace OpenSim.Region.Framework.Scenes.Tests
45 { 45 {
46 static public Random random; 46 static public Random random;
47 SceneObjectGroup found; 47 SceneObjectGroup found;
48 Scene scene = SceneSetupHelpers.SetupScene(); 48 Scene scene = SceneHelpers.SetupScene();
49 49
50 [Test] 50 [Test]
51 public void T010_AddObjects() 51 public void T010_AddObjects()
52 { 52 {
53 TestHelper.InMethod(); 53 TestHelpers.InMethod();
54 54
55 random = new Random(); 55 random = new Random();
56 SceneObjectGroup found; 56 SceneObjectGroup found;
@@ -85,7 +85,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
85 [Test] 85 [Test]
86 public void T011_ThreadAddRemoveTest() 86 public void T011_ThreadAddRemoveTest()
87 { 87 {
88 TestHelper.InMethod(); 88 TestHelpers.InMethod();
89 89
90 // This test adds and removes with mutiple threads, attempting to break the 90 // This test adds and removes with mutiple threads, attempting to break the
91 // uuid and localid dictionary coherence. 91 // uuid and localid dictionary coherence.
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs
index 895f2bb..9a60e50 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs
@@ -43,8 +43,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
43 [Test] 43 [Test]
44 public void TestDuplicateObject() 44 public void TestDuplicateObject()
45 { 45 {
46 TestHelper.InMethod(); 46 TestHelpers.InMethod();
47 Scene scene = SceneSetupHelpers.SetupScene(); 47 Scene scene = SceneHelpers.SetupScene();
48 48
49 UUID ownerId = new UUID("00000000-0000-0000-0000-000000000010"); 49 UUID ownerId = new UUID("00000000-0000-0000-0000-000000000010");
50 string part1Name = "part1"; 50 string part1Name = "part1";
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
index 0a82c4f..1ea2329 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
@@ -49,9 +49,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests
49 [Test] 49 [Test]
50 public void TestAddSceneObject() 50 public void TestAddSceneObject()
51 { 51 {
52 TestHelper.InMethod(); 52 TestHelpers.InMethod();
53 53
54 Scene scene = SceneSetupHelpers.SetupScene(); 54 Scene scene = SceneHelpers.SetupScene();
55 55
56 string objName = "obj1"; 56 string objName = "obj1";
57 UUID objUuid = new UUID("00000000-0000-0000-0000-000000000001"); 57 UUID objUuid = new UUID("00000000-0000-0000-0000-000000000001");
@@ -76,9 +76,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests
76 /// </summary> 76 /// </summary>
77 public void TestAddExistingSceneObjectUuid() 77 public void TestAddExistingSceneObjectUuid()
78 { 78 {
79 TestHelper.InMethod(); 79 TestHelpers.InMethod();
80 80
81 Scene scene = SceneSetupHelpers.SetupScene(); 81 Scene scene = SceneHelpers.SetupScene();
82 82
83 string obj1Name = "Alfred"; 83 string obj1Name = "Alfred";
84 string obj2Name = "Betty"; 84 string obj2Name = "Betty";
@@ -110,10 +110,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests
110 [Test] 110 [Test]
111 public void TestDeleteSceneObject() 111 public void TestDeleteSceneObject()
112 { 112 {
113 TestHelper.InMethod(); 113 TestHelpers.InMethod();
114 114
115 TestScene scene = SceneSetupHelpers.SetupScene(); 115 TestScene scene = SceneHelpers.SetupScene();
116 SceneObjectPart part = SceneSetupHelpers.AddSceneObject(scene); 116 SceneObjectPart part = SceneHelpers.AddSceneObject(scene);
117 scene.DeleteSceneObject(part.ParentGroup, false); 117 scene.DeleteSceneObject(part.ParentGroup, false);
118 118
119 SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); 119 SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId);
@@ -126,20 +126,20 @@ namespace OpenSim.Region.Framework.Scenes.Tests
126 [Test] 126 [Test]
127 public void TestDeleteSceneObjectAsync() 127 public void TestDeleteSceneObjectAsync()
128 { 128 {
129 TestHelper.InMethod(); 129 TestHelpers.InMethod();
130 //log4net.Config.XmlConfigurator.Configure(); 130 //log4net.Config.XmlConfigurator.Configure();
131 131
132 UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000001"); 132 UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000001");
133 133
134 TestScene scene = SceneSetupHelpers.SetupScene(); 134 TestScene scene = SceneHelpers.SetupScene();
135 135
136 // Turn off the timer on the async sog deleter - we'll crank it by hand for this test. 136 // Turn off the timer on the async sog deleter - we'll crank it by hand for this test.
137 AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter; 137 AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter;
138 sogd.Enabled = false; 138 sogd.Enabled = false;
139 139
140 SceneObjectPart part = SceneSetupHelpers.AddSceneObject(scene); 140 SceneObjectPart part = SceneHelpers.AddSceneObject(scene);
141 141
142 IClientAPI client = SceneSetupHelpers.AddRootAgent(scene, agentId); 142 IClientAPI client = SceneHelpers.AddScenePresence(scene, agentId).ControllingClient;
143 scene.DeRezObjects(client, new System.Collections.Generic.List<uint>() { part.LocalId }, UUID.Zero, DeRezAction.Delete, UUID.Zero); 143 scene.DeRezObjects(client, new System.Collections.Generic.List<uint>() { part.LocalId }, UUID.Zero, DeRezAction.Delete, UUID.Zero);
144 144
145 SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); 145 SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId);
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs
index 5357a06..654b1a2 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs
@@ -56,17 +56,17 @@ namespace OpenSim.Region.Framework.Scenes.Tests
56 [Test] 56 [Test]
57 public void TestDeRezSceneObject() 57 public void TestDeRezSceneObject()
58 { 58 {
59 TestHelper.InMethod(); 59 TestHelpers.InMethod();
60// log4net.Config.XmlConfigurator.Configure(); 60// log4net.Config.XmlConfigurator.Configure();
61 61
62 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001"); 62 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001");
63 63
64 TestScene scene = SceneSetupHelpers.SetupScene(); 64 TestScene scene = SceneHelpers.SetupScene();
65 IConfigSource configSource = new IniConfigSource(); 65 IConfigSource configSource = new IniConfigSource();
66 IConfig config = configSource.AddConfig("Startup"); 66 IConfig config = configSource.AddConfig("Startup");
67 config.Set("serverside_object_permissions", true); 67 config.Set("serverside_object_permissions", true);
68 SceneSetupHelpers.SetupSceneModules(scene, configSource, new object[] { new PermissionsModule() }); 68 SceneHelpers.SetupSceneModules(scene, configSource, new object[] { new PermissionsModule() });
69 TestClient client = SceneSetupHelpers.AddRootAgent(scene, userId); 69 IClientAPI client = SceneHelpers.AddScenePresence(scene, userId).ControllingClient;
70 70
71 // Turn off the timer on the async sog deleter - we'll crank it by hand for this test. 71 // Turn off the timer on the async sog deleter - we'll crank it by hand for this test.
72 AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter; 72 AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter;
@@ -94,18 +94,18 @@ namespace OpenSim.Region.Framework.Scenes.Tests
94 [Test] 94 [Test]
95 public void TestDeRezSceneObjectNotOwner() 95 public void TestDeRezSceneObjectNotOwner()
96 { 96 {
97 TestHelper.InMethod(); 97 TestHelpers.InMethod();
98// log4net.Config.XmlConfigurator.Configure(); 98// log4net.Config.XmlConfigurator.Configure();
99 99
100 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001"); 100 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001");
101 UUID objectOwnerId = UUID.Parse("20000000-0000-0000-0000-000000000001"); 101 UUID objectOwnerId = UUID.Parse("20000000-0000-0000-0000-000000000001");
102 102
103 TestScene scene = SceneSetupHelpers.SetupScene(); 103 TestScene scene = SceneHelpers.SetupScene();
104 IConfigSource configSource = new IniConfigSource(); 104 IConfigSource configSource = new IniConfigSource();
105 IConfig config = configSource.AddConfig("Startup"); 105 IConfig config = configSource.AddConfig("Startup");
106 config.Set("serverside_object_permissions", true); 106 config.Set("serverside_object_permissions", true);
107 SceneSetupHelpers.SetupSceneModules(scene, configSource, new object[] { new PermissionsModule() }); 107 SceneHelpers.SetupSceneModules(scene, configSource, new object[] { new PermissionsModule() });
108 TestClient client = SceneSetupHelpers.AddRootAgent(scene, userId); 108 IClientAPI client = SceneHelpers.AddScenePresence(scene, userId).ControllingClient;
109 109
110 // Turn off the timer on the async sog deleter - we'll crank it by hand for this test. 110 // Turn off the timer on the async sog deleter - we'll crank it by hand for this test.
111 AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter; 111 AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter;
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
index cb1d531..2912a46 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
@@ -50,14 +50,14 @@ namespace OpenSim.Region.Framework.Scenes.Tests
50 [Test] 50 [Test]
51 public void TestLinkDelink2SceneObjects() 51 public void TestLinkDelink2SceneObjects()
52 { 52 {
53 TestHelper.InMethod(); 53 TestHelpers.InMethod();
54 54
55 bool debugtest = false; 55 bool debugtest = false;
56 56
57 Scene scene = SceneSetupHelpers.SetupScene(); 57 Scene scene = SceneHelpers.SetupScene();
58 SceneObjectPart part1 = SceneSetupHelpers.AddSceneObject(scene); 58 SceneObjectPart part1 = SceneHelpers.AddSceneObject(scene);
59 SceneObjectGroup grp1 = part1.ParentGroup; 59 SceneObjectGroup grp1 = part1.ParentGroup;
60 SceneObjectPart part2 = SceneSetupHelpers.AddSceneObject(scene); 60 SceneObjectPart part2 = SceneHelpers.AddSceneObject(scene);
61 SceneObjectGroup grp2 = part2.ParentGroup; 61 SceneObjectGroup grp2 = part2.ParentGroup;
62 62
63 grp1.AbsolutePosition = new Vector3(10, 10, 10); 63 grp1.AbsolutePosition = new Vector3(10, 10, 10);
@@ -132,18 +132,18 @@ namespace OpenSim.Region.Framework.Scenes.Tests
132 [Test] 132 [Test]
133 public void TestLinkDelink2groups4SceneObjects() 133 public void TestLinkDelink2groups4SceneObjects()
134 { 134 {
135 TestHelper.InMethod(); 135 TestHelpers.InMethod();
136 136
137 bool debugtest = false; 137 bool debugtest = false;
138 138
139 Scene scene = SceneSetupHelpers.SetupScene(); 139 Scene scene = SceneHelpers.SetupScene();
140 SceneObjectPart part1 = SceneSetupHelpers.AddSceneObject(scene); 140 SceneObjectPart part1 = SceneHelpers.AddSceneObject(scene);
141 SceneObjectGroup grp1 = part1.ParentGroup; 141 SceneObjectGroup grp1 = part1.ParentGroup;
142 SceneObjectPart part2 = SceneSetupHelpers.AddSceneObject(scene); 142 SceneObjectPart part2 = SceneHelpers.AddSceneObject(scene);
143 SceneObjectGroup grp2 = part2.ParentGroup; 143 SceneObjectGroup grp2 = part2.ParentGroup;
144 SceneObjectPart part3 = SceneSetupHelpers.AddSceneObject(scene); 144 SceneObjectPart part3 = SceneHelpers.AddSceneObject(scene);
145 SceneObjectGroup grp3 = part3.ParentGroup; 145 SceneObjectGroup grp3 = part3.ParentGroup;
146 SceneObjectPart part4 = SceneSetupHelpers.AddSceneObject(scene); 146 SceneObjectPart part4 = SceneHelpers.AddSceneObject(scene);
147 SceneObjectGroup grp4 = part4.ParentGroup; 147 SceneObjectGroup grp4 = part4.ParentGroup;
148 148
149 grp1.AbsolutePosition = new Vector3(10, 10, 10); 149 grp1.AbsolutePosition = new Vector3(10, 10, 10);
@@ -266,10 +266,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests
266 [Test] 266 [Test]
267 public void TestNewSceneObjectLinkPersistence() 267 public void TestNewSceneObjectLinkPersistence()
268 { 268 {
269 TestHelper.InMethod(); 269 TestHelpers.InMethod();
270 //log4net.Config.XmlConfigurator.Configure(); 270 //log4net.Config.XmlConfigurator.Configure();
271 271
272 TestScene scene = SceneSetupHelpers.SetupScene(); 272 TestScene scene = SceneHelpers.SetupScene();
273 273
274 string rootPartName = "rootpart"; 274 string rootPartName = "rootpart";
275 UUID rootPartUuid = new UUID("00000000-0000-0000-0000-000000000001"); 275 UUID rootPartUuid = new UUID("00000000-0000-0000-0000-000000000001");
@@ -305,10 +305,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests
305 [Test] 305 [Test]
306 public void TestDelinkPersistence() 306 public void TestDelinkPersistence()
307 { 307 {
308 TestHelper.InMethod(); 308 TestHelpers.InMethod();
309 //log4net.Config.XmlConfigurator.Configure(); 309 //log4net.Config.XmlConfigurator.Configure();
310 310
311 TestScene scene = SceneSetupHelpers.SetupScene(); 311 TestScene scene = SceneHelpers.SetupScene();
312 312
313 string rootPartName = "rootpart"; 313 string rootPartName = "rootpart";
314 UUID rootPartUuid = new UUID("00000000-0000-0000-0000-000000000001"); 314 UUID rootPartUuid = new UUID("00000000-0000-0000-0000-000000000001");
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs
new file mode 100644
index 0000000..b49c6e7
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs
@@ -0,0 +1,104 @@
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.Reflection;
30using NUnit.Framework;
31using OpenMetaverse;
32using OpenSim.Framework;
33using OpenSim.Framework.Communications;
34using OpenSim.Region.Framework.Scenes;
35using OpenSim.Tests.Common;
36using OpenSim.Tests.Common.Mock;
37
38namespace OpenSim.Region.Framework.Scenes.Tests
39{
40 /// <summary>
41 /// Basic scene object resize tests
42 /// </summary>
43 [TestFixture]
44 public class SceneObjectResizeTests
45 {
46 /// <summary>
47 /// Test resizing an object
48 /// </summary>
49 [Test]
50 public void TestResizeSceneObject()
51 {
52 TestHelpers.InMethod();
53// log4net.Config.XmlConfigurator.Configure();
54
55 Scene scene = SceneHelpers.SetupScene();
56 SceneObjectGroup g1 = SceneHelpers.AddSceneObject(scene).ParentGroup;
57
58 g1.GroupResize(new Vector3(2, 3, 4));
59
60 SceneObjectGroup g1Post = scene.GetSceneObjectGroup(g1.UUID);
61
62 Assert.That(g1Post.RootPart.Scale.X, Is.EqualTo(2));
63 Assert.That(g1Post.RootPart.Scale.Y, Is.EqualTo(3));
64 Assert.That(g1Post.RootPart.Scale.Z, Is.EqualTo(4));
65
66 Assert.That(g1Post.RootPart.UndoCount, Is.EqualTo(1));
67 }
68
69 /// <summary>
70 /// Test resizing an individual part in a scene object.
71 /// </summary>
72 [Test]
73 public void TestResizeSceneObjectPart()
74 {
75 TestHelpers.InMethod();
76 //log4net.Config.XmlConfigurator.Configure();
77
78 Scene scene = SceneHelpers.SetupScene();
79
80 SceneObjectGroup g1 = SceneHelpers.CreateSceneObject(2, UUID.Zero);
81 g1.RootPart.Scale = new Vector3(2, 3, 4);
82 g1.Parts[1].Scale = new Vector3(5, 6, 7);
83
84 scene.AddSceneObject(g1);
85
86 SceneObjectGroup g1Post = scene.GetSceneObjectGroup(g1.UUID);
87
88 g1Post.Parts[1].Resize(new Vector3(8, 9, 10));
89
90 SceneObjectGroup g1PostPost = scene.GetSceneObjectGroup(g1.UUID);
91
92 SceneObjectPart g1RootPart = g1PostPost.RootPart;
93 SceneObjectPart g1ChildPart = g1PostPost.Parts[1];
94
95 Assert.That(g1RootPart.Scale.X, Is.EqualTo(2));
96 Assert.That(g1RootPart.Scale.Y, Is.EqualTo(3));
97 Assert.That(g1RootPart.Scale.Z, Is.EqualTo(4));
98
99 Assert.That(g1ChildPart.Scale.X, Is.EqualTo(8));
100 Assert.That(g1ChildPart.Scale.Y, Is.EqualTo(9));
101 Assert.That(g1ChildPart.Scale.Z, Is.EqualTo(10));
102 }
103 }
104} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs
new file mode 100644
index 0000000..2a342d5
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs
@@ -0,0 +1,66 @@
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.Reflection;
30using NUnit.Framework;
31using OpenMetaverse;
32using OpenSim.Framework;
33using OpenSim.Framework.Communications;
34using OpenSim.Region.Framework.Scenes;
35using OpenSim.Tests.Common;
36using OpenSim.Tests.Common.Mock;
37
38namespace OpenSim.Region.Framework.Scenes.Tests
39{
40 /// <summary>
41 /// Basic scene object status tests
42 /// </summary>
43 [TestFixture]
44 public class SceneObjectStatusTests
45 {
46 [Test]
47 public void TestSetPhantom()
48 {
49 TestHelpers.InMethod();
50
51// Scene scene = SceneSetupHelpers.SetupScene();
52 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, UUID.Zero);
53 SceneObjectPart rootPart = so.RootPart;
54 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None));
55
56 so.ScriptSetPhantomStatus(true);
57
58// Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags);
59 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Phantom));
60
61 so.ScriptSetPhantomStatus(false);
62
63 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None));
64 }
65 }
66} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs
index 77bd4c2..c13d82e 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs
@@ -53,12 +53,12 @@ namespace OpenSim.Region.Framework.Scenes.Tests
53 [Test] 53 [Test]
54 public void TestShareWithGroup() 54 public void TestShareWithGroup()
55 { 55 {
56 TestHelper.InMethod(); 56 TestHelpers.InMethod();
57// log4net.Config.XmlConfigurator.Configure(); 57// log4net.Config.XmlConfigurator.Configure();
58 58
59 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001"); 59 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001");
60 60
61 TestScene scene = SceneSetupHelpers.SetupScene(); 61 TestScene scene = SceneHelpers.SetupScene();
62 IConfigSource configSource = new IniConfigSource(); 62 IConfigSource configSource = new IniConfigSource();
63 63
64 IConfig startupConfig = configSource.AddConfig("Startup"); 64 IConfig startupConfig = configSource.AddConfig("Startup");
@@ -69,13 +69,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests
69 groupsConfig.Set("Module", "GroupsModule"); 69 groupsConfig.Set("Module", "GroupsModule");
70 groupsConfig.Set("DebugEnabled", true); 70 groupsConfig.Set("DebugEnabled", true);
71 71
72 SceneSetupHelpers.SetupSceneModules( 72 SceneHelpers.SetupSceneModules(
73 scene, configSource, new object[] 73 scene, configSource, new object[]
74 { new PermissionsModule(), 74 { new PermissionsModule(),
75 new GroupsModule(), 75 new GroupsModule(),
76 new MockGroupsServicesConnector() }); 76 new MockGroupsServicesConnector() });
77 77
78 TestClient client = SceneSetupHelpers.AddRootAgent(scene, userId); 78 IClientAPI client = SceneHelpers.AddScenePresence(scene, userId).ControllingClient;
79 79
80 IGroupsModule groupsModule = scene.RequestModuleInterface<IGroupsModule>(); 80 IGroupsModule groupsModule = scene.RequestModuleInterface<IGroupsModule>();
81 81
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
index 03ac252..ce9d418 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
@@ -51,7 +51,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
51 /// Scene presence tests 51 /// Scene presence tests
52 /// </summary> 52 /// </summary>
53 [TestFixture] 53 [TestFixture]
54 public class ScenePresenceTests 54 public class ScenePresenceAgentTests
55 { 55 {
56 public Scene scene, scene2, scene3; 56 public Scene scene, scene2, scene3;
57 public UUID agent1, agent2, agent3; 57 public UUID agent1, agent2, agent3;
@@ -64,90 +64,140 @@ namespace OpenSim.Region.Framework.Scenes.Tests
64 [TestFixtureSetUp] 64 [TestFixtureSetUp]
65 public void Init() 65 public void Init()
66 { 66 {
67 TestHelper.InMethod(); 67 TestHelpers.InMethod();
68 68
69 scene = SceneSetupHelpers.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); 69 scene = SceneHelpers.SetupScene("Neighbour x", UUID.Random(), 1000, 1000);
70 scene2 = SceneSetupHelpers.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000); 70 scene2 = SceneHelpers.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000);
71 scene3 = SceneSetupHelpers.SetupScene("Neighbour x-1", UUID.Random(), 999, 1000); 71 scene3 = SceneHelpers.SetupScene("Neighbour x-1", UUID.Random(), 999, 1000);
72 72
73 ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); 73 ISharedRegionModule interregionComms = new LocalSimulationConnectorModule();
74 interregionComms.Initialise(new IniConfigSource()); 74 interregionComms.Initialise(new IniConfigSource());
75 interregionComms.PostInitialise(); 75 interregionComms.PostInitialise();
76 SceneSetupHelpers.SetupSceneModules(scene, new IniConfigSource(), interregionComms); 76 SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), interregionComms);
77 SceneSetupHelpers.SetupSceneModules(scene2, new IniConfigSource(), interregionComms); 77 SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), interregionComms);
78 SceneSetupHelpers.SetupSceneModules(scene3, new IniConfigSource(), interregionComms); 78 SceneHelpers.SetupSceneModules(scene3, new IniConfigSource(), interregionComms);
79 79
80 agent1 = UUID.Random(); 80 agent1 = UUID.Random();
81 agent2 = UUID.Random(); 81 agent2 = UUID.Random();
82 agent3 = UUID.Random(); 82 agent3 = UUID.Random();
83 random = new Random(); 83 random = new Random();
84 sog1 = NewSOG(UUID.Random(), scene, agent1); 84 sog1 = SceneHelpers.CreateSceneObject(1, agent1);
85 sog2 = NewSOG(UUID.Random(), scene, agent1); 85 scene.AddSceneObject(sog1);
86 sog3 = NewSOG(UUID.Random(), scene, agent1); 86 sog2 = SceneHelpers.CreateSceneObject(1, agent1);
87 scene.AddSceneObject(sog2);
88 sog3 = SceneHelpers.CreateSceneObject(1, agent1);
89 scene.AddSceneObject(sog3);
87 90
88 //ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
89 region1 = scene.RegionInfo.RegionHandle; 91 region1 = scene.RegionInfo.RegionHandle;
90 region2 = scene2.RegionInfo.RegionHandle; 92 region2 = scene2.RegionInfo.RegionHandle;
91 region3 = scene3.RegionInfo.RegionHandle; 93 region3 = scene3.RegionInfo.RegionHandle;
92 } 94 }
93 95
94 /// <summary>
95 /// Test adding a root agent to a scene. Doesn't yet actually complete crossing the agent into the scene.
96 /// </summary>
97 [Test] 96 [Test]
98 public void T010_TestAddRootAgent() 97 public void TestCloseAgent()
99 { 98 {
100 TestHelper.InMethod(); 99 TestHelpers.InMethod();
101 100// log4net.Config.XmlConfigurator.Configure();
102 string firstName = "testfirstname";
103
104 AgentCircuitData agent = new AgentCircuitData();
105 agent.AgentID = agent1;
106 agent.firstname = firstName;
107 agent.lastname = "testlastname";
108 agent.SessionID = UUID.Random();
109 agent.SecureSessionID = UUID.Random();
110 agent.circuitcode = 123;
111 agent.BaseFolder = UUID.Zero;
112 agent.InventoryFolder = UUID.Zero;
113 agent.startpos = Vector3.Zero;
114 agent.CapsPath = GetRandomCapsObjectPath();
115 agent.ChildrenCapSeeds = new Dictionary<ulong, string>();
116 agent.child = true;
117 101
118 scene.PresenceService.LoginAgent(agent.AgentID.ToString(), agent.SessionID, agent.SecureSessionID); 102 TestScene scene = SceneHelpers.SetupScene();
103 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
119 104
120 string reason; 105 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Not.Null);
121 scene.NewUserConnection(agent, (uint)TeleportFlags.ViaLogin, out reason);
122 testclient = new TestClient(agent, scene);
123 scene.AddNewClient(testclient);
124 106
125 ScenePresence presence = scene.GetScenePresence(agent1); 107 scene.IncomingCloseAgent(sp.UUID);
126 108
127 Assert.That(presence, Is.Not.Null, "presence is null"); 109 Assert.That(scene.GetScenePresence(sp.UUID), Is.Null);
128 Assert.That(presence.Firstname, Is.EqualTo(firstName), "First name not same"); 110 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null);
129 acd1 = agent;
130 } 111 }
131 112
132 /// <summary> 113 /// <summary>
133 /// Test removing an uncrossed root agent from a scene. 114 /// Test that if a root agent logs into a region, a child agent is also established in the neighbouring region
134 /// </summary> 115 /// </summary>
116 /// <remarks>
117 /// Please note that unlike the other tests here, this doesn't rely on structures
118 /// </remarks>
135 [Test] 119 [Test]
136 public void T011_TestRemoveRootAgent() 120 public void TestChildAgentEstablished()
137 { 121 {
138 TestHelper.InMethod(); 122 TestHelpers.InMethod();
139 123// log4net.Config.XmlConfigurator.Configure();
140 scene.RemoveClient(agent1); 124
141 125 UUID agent1Id = UUID.Parse("00000000-0000-0000-0000-000000000001");
142 ScenePresence presence = scene.GetScenePresence(agent1); 126
127 TestScene myScene1 = SceneHelpers.SetupScene("Neighbour y", UUID.Random(), 1000, 1000);
128// TestScene myScene2 = SceneHelpers.SetupScene("Neighbour y + 1", UUID.Random(), 1001, 1000);
129
130 IConfigSource configSource = new IniConfigSource();
131 configSource.AddConfig("Modules").Set("EntityTransferModule", "BasicEntityTransferModule");
132 EntityTransferModule etm = new EntityTransferModule();
133
134 SceneHelpers.SetupSceneModules(myScene1, configSource, etm);
135
136 SceneHelpers.AddScenePresence(myScene1, agent1Id);
137// ScenePresence childPresence = myScene2.GetScenePresence(agent1);
143 138
144 Assert.That(presence, Is.Null, "presence is not null"); 139 // TODO: Need to do a fair amount of work to allow synchronous establishment of child agents
140// Assert.That(childPresence, Is.Not.Null);
141// Assert.That(childPresence.IsChildAgent, Is.True);
145 } 142 }
146 143
144// /// <summary>
145// /// Test adding a root agent to a scene. Doesn't yet actually complete crossing the agent into the scene.
146// /// </summary>
147// [Test]
148// public void T010_TestAddRootAgent()
149// {
150// TestHelpers.InMethod();
151//
152// string firstName = "testfirstname";
153//
154// AgentCircuitData agent = new AgentCircuitData();
155// agent.AgentID = agent1;
156// agent.firstname = firstName;
157// agent.lastname = "testlastname";
158// agent.SessionID = UUID.Random();
159// agent.SecureSessionID = UUID.Random();
160// agent.circuitcode = 123;
161// agent.BaseFolder = UUID.Zero;
162// agent.InventoryFolder = UUID.Zero;
163// agent.startpos = Vector3.Zero;
164// agent.CapsPath = GetRandomCapsObjectPath();
165// agent.ChildrenCapSeeds = new Dictionary<ulong, string>();
166// agent.child = true;
167//
168// scene.PresenceService.LoginAgent(agent.AgentID.ToString(), agent.SessionID, agent.SecureSessionID);
169//
170// string reason;
171// scene.NewUserConnection(agent, (uint)TeleportFlags.ViaLogin, out reason);
172// testclient = new TestClient(agent, scene);
173// scene.AddNewClient(testclient);
174//
175// ScenePresence presence = scene.GetScenePresence(agent1);
176//
177// Assert.That(presence, Is.Not.Null, "presence is null");
178// Assert.That(presence.Firstname, Is.EqualTo(firstName), "First name not same");
179// acd1 = agent;
180// }
181//
182// /// <summary>
183// /// Test removing an uncrossed root agent from a scene.
184// /// </summary>
185// [Test]
186// public void T011_TestRemoveRootAgent()
187// {
188// TestHelpers.InMethod();
189//
190// scene.RemoveClient(agent1);
191//
192// ScenePresence presence = scene.GetScenePresence(agent1);
193//
194// Assert.That(presence, Is.Null, "presence is not null");
195// }
196
147 [Test] 197 [Test]
148 public void T012_TestAddNeighbourRegion() 198 public void T012_TestAddNeighbourRegion()
149 { 199 {
150 TestHelper.InMethod(); 200 TestHelpers.InMethod();
151 201
152 string reason; 202 string reason;
153 203
@@ -157,7 +207,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
157 scene.NewUserConnection(acd1, 0, out reason); 207 scene.NewUserConnection(acd1, 0, out reason);
158 if (testclient == null) 208 if (testclient == null)
159 testclient = new TestClient(acd1, scene); 209 testclient = new TestClient(acd1, scene);
160 scene.AddNewClient(testclient); 210 scene.AddNewClient(testclient, PresenceType.User);
161 211
162 ScenePresence presence = scene.GetScenePresence(agent1); 212 ScenePresence presence = scene.GetScenePresence(agent1);
163 presence.MakeRootAgent(new Vector3(90,90,90),false); 213 presence.MakeRootAgent(new Vector3(90,90,90),false);
@@ -175,7 +225,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
175 [Test] 225 [Test]
176 public void T013_TestRemoveNeighbourRegion() 226 public void T013_TestRemoveNeighbourRegion()
177 { 227 {
178 TestHelper.InMethod(); 228 TestHelpers.InMethod();
179 229
180 ScenePresence presence = scene.GetScenePresence(agent1); 230 ScenePresence presence = scene.GetScenePresence(agent1);
181 presence.RemoveNeighbourRegion(region3); 231 presence.RemoveNeighbourRegion(region3);
@@ -188,37 +238,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests
188 CompleteAvatarMovement 238 CompleteAvatarMovement
189 */ 239 */
190 } 240 }
191
192 /// <summary>
193 /// Test that if a root agent logs into a region, a child agent is also established in the neighbouring region
194 /// </summary>
195 /// <remarks>
196 /// Please note that unlike the other tests here, this doesn't rely on structures
197 /// </remarks>
198 [Test]
199 public void TestChildAgentEstablished()
200 {
201 TestHelper.InMethod();
202// log4net.Config.XmlConfigurator.Configure();
203
204 UUID agent1Id = UUID.Parse("00000000-0000-0000-0000-000000000001");
205
206 TestScene myScene1 = SceneSetupHelpers.SetupScene("Neighbour y", UUID.Random(), 1000, 1000);
207 TestScene myScene2 = SceneSetupHelpers.SetupScene("Neighbour y + 1", UUID.Random(), 1001, 1000);
208
209 IConfigSource configSource = new IniConfigSource();
210 configSource.AddConfig("Modules").Set("EntityTransferModule", "BasicEntityTransferModule");
211 EntityTransferModule etm = new EntityTransferModule();
212
213 SceneSetupHelpers.SetupSceneModules(myScene1, configSource, etm);
214
215 SceneSetupHelpers.AddRootAgent(myScene1, agent1Id);
216 ScenePresence childPresence = myScene2.GetScenePresence(agent1);
217
218 // TODO: Need to do a fair amount of work to allow synchronous establishment of child agents
219// Assert.That(childPresence, Is.Not.Null);
220// Assert.That(childPresence.IsChildAgent, Is.True);
221 }
222 241
223 // I'm commenting this test because it does not represent 242 // I'm commenting this test because it does not represent
224 // crossings. The Thread.Sleep's in here are not meaningful mocks, 243 // crossings. The Thread.Sleep's in here are not meaningful mocks,
@@ -230,7 +249,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
230 //[Test] 249 //[Test]
231 public void T021_TestCrossToNewRegion() 250 public void T021_TestCrossToNewRegion()
232 { 251 {
233 TestHelper.InMethod(); 252 TestHelpers.InMethod();
234 253
235 scene.RegisterRegionWithGrid(); 254 scene.RegisterRegionWithGrid();
236 scene2.RegisterRegionWithGrid(); 255 scene2.RegisterRegionWithGrid();
@@ -238,7 +257,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
238 // Adding child agent to region 1001 257 // Adding child agent to region 1001
239 string reason; 258 string reason;
240 scene2.NewUserConnection(acd1,0, out reason); 259 scene2.NewUserConnection(acd1,0, out reason);
241 scene2.AddNewClient(testclient); 260 scene2.AddNewClient(testclient, PresenceType.User);
242 261
243 ScenePresence presence = scene.GetScenePresence(agent1); 262 ScenePresence presence = scene.GetScenePresence(agent1);
244 presence.MakeRootAgent(new Vector3(0,unchecked(Constants.RegionSize-1),0), true); 263 presence.MakeRootAgent(new Vector3(0,unchecked(Constants.RegionSize-1),0), true);
@@ -338,6 +357,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
338 agent.InventoryFolder = UUID.Zero; 357 agent.InventoryFolder = UUID.Zero;
339 agent.startpos = Vector3.Zero; 358 agent.startpos = Vector3.Zero;
340 agent.CapsPath = GetRandomCapsObjectPath(); 359 agent.CapsPath = GetRandomCapsObjectPath();
360 agent.Appearance = new AvatarAppearance();
341 361
342 acd1 = agent; 362 acd1 = agent;
343 } 363 }
@@ -349,37 +369,5 @@ namespace OpenSim.Region.Framework.Scenes.Tests
349 capsPath = capsPath.Remove(capsPath.Length - 4, 4); 369 capsPath = capsPath.Remove(capsPath.Length - 4, 4);
350 return capsPath; 370 return capsPath;
351 } 371 }
352
353 private SceneObjectGroup NewSOG(UUID uuid, Scene scene, UUID agent)
354 {
355 SceneObjectPart sop = new SceneObjectPart();
356 sop.Name = RandomName();
357 sop.Description = RandomName();
358 sop.Text = RandomName();
359 sop.SitName = RandomName();
360 sop.TouchName = RandomName();
361 sop.UUID = uuid;
362 sop.Shape = PrimitiveBaseShape.Default;
363 sop.Shape.State = 1;
364 sop.OwnerID = agent;
365
366 SceneObjectGroup sog = new SceneObjectGroup(sop);
367 sog.SetScene(scene);
368
369 return sog;
370 }
371
372 private static string RandomName()
373 {
374 StringBuilder name = new StringBuilder();
375 int size = random.Next(5,12);
376 char ch ;
377 for (int i=0; i<size; i++)
378 {
379 ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))) ;
380 name.Append(ch);
381 }
382 return name.ToString();
383 }
384 } 372 }
385} \ No newline at end of file 373} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/StandaloneTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
index 1b5a54e..39bb43a 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/StandaloneTeleportTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
@@ -44,7 +44,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
44 /// Teleport tests in a standalone OpenSim 44 /// Teleport tests in a standalone OpenSim
45 /// </summary> 45 /// </summary>
46 [TestFixture] 46 [TestFixture]
47 public class StandaloneTeleportTests 47 public class ScenePresenceTeleportTests
48 { 48 {
49 /// <summary> 49 /// <summary>
50 /// Test a teleport between two regions that are not neighbours and do not share any neighbours in common. 50 /// Test a teleport between two regions that are not neighbours and do not share any neighbours in common.
@@ -54,7 +54,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
54 //[Test, LongRunning] 54 //[Test, LongRunning]
55 public void TestSimpleNotNeighboursTeleport() 55 public void TestSimpleNotNeighboursTeleport()
56 { 56 {
57 TestHelper.InMethod(); 57 TestHelpers.InMethod();
58 ThreadRunResults results = new ThreadRunResults(); 58 ThreadRunResults results = new ThreadRunResults();
59 results.Result = false; 59 results.Result = false;
60 results.Message = "Test did not run"; 60 results.Message = "Test did not run";
@@ -116,16 +116,16 @@ namespace OpenSim.Region.Framework.Scenes.Tests
116 ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); 116 ISharedRegionModule interregionComms = new LocalSimulationConnectorModule();
117 117
118 118
119 Scene sceneB = SceneSetupHelpers.SetupScene("sceneB", sceneBId, 1010, 1010); 119 Scene sceneB = SceneHelpers.SetupScene("sceneB", sceneBId, 1010, 1010);
120 SceneSetupHelpers.SetupSceneModules(sceneB, new IniConfigSource(), interregionComms); 120 SceneHelpers.SetupSceneModules(sceneB, new IniConfigSource(), interregionComms);
121 sceneB.RegisterRegionWithGrid(); 121 sceneB.RegisterRegionWithGrid();
122 122
123 Scene sceneA = SceneSetupHelpers.SetupScene("sceneA", sceneAId, 1000, 1000); 123 Scene sceneA = SceneHelpers.SetupScene("sceneA", sceneAId, 1000, 1000);
124 SceneSetupHelpers.SetupSceneModules(sceneA, new IniConfigSource(), interregionComms); 124 SceneHelpers.SetupSceneModules(sceneA, new IniConfigSource(), interregionComms);
125 sceneA.RegisterRegionWithGrid(); 125 sceneA.RegisterRegionWithGrid();
126 126
127 UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000041"); 127 UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000041");
128 TestClient client = SceneSetupHelpers.AddRootAgent(sceneA, agentId); 128 TestClient client = (TestClient)SceneHelpers.AddScenePresence(sceneA, agentId).ControllingClient;
129 129
130 ICapabilitiesModule sceneACapsModule = sceneA.RequestModuleInterface<ICapabilitiesModule>(); 130 ICapabilitiesModule sceneACapsModule = sceneA.RequestModuleInterface<ICapabilitiesModule>();
131 131
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
index 13d93f9..8b8aea5 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
@@ -58,9 +58,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests
58 [Test] 58 [Test]
59 public void TestUpdateScene() 59 public void TestUpdateScene()
60 { 60 {
61 TestHelper.InMethod(); 61 TestHelpers.InMethod();
62 62
63 Scene scene = SceneSetupHelpers.SetupScene(); 63 Scene scene = SceneHelpers.SetupScene();
64 scene.Update(); 64 scene.Update();
65 65
66 Assert.That(scene.Frame, Is.EqualTo(1)); 66 Assert.That(scene.Frame, Is.EqualTo(1));
diff --git a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
index f4e14d4..1abef8d 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
@@ -55,12 +55,12 @@ namespace OpenSim.Region.Framework.Tests
55 [Test] 55 [Test]
56 public void TestRezObjectFromInventoryItem() 56 public void TestRezObjectFromInventoryItem()
57 { 57 {
58 TestHelper.InMethod(); 58 TestHelpers.InMethod();
59// log4net.Config.XmlConfigurator.Configure(); 59// log4net.Config.XmlConfigurator.Configure();
60 60
61 Scene scene = SceneSetupHelpers.SetupScene(); 61 Scene scene = SceneHelpers.SetupScene();
62 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); 62 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene);
63 SceneObjectGroup sog1 = SceneSetupHelpers.CreateSceneObject(1, user1.PrincipalID); 63 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID);
64 SceneObjectPart sop1 = sog1.RootPart; 64 SceneObjectPart sop1 = sog1.RootPart;
65 65
66 // Create an object embedded inside the first 66 // Create an object embedded inside the first
@@ -98,12 +98,12 @@ namespace OpenSim.Region.Framework.Tests
98 [Test] 98 [Test]
99 public void TestMoveTaskInventoryItem() 99 public void TestMoveTaskInventoryItem()
100 { 100 {
101 TestHelper.InMethod(); 101 TestHelpers.InMethod();
102// log4net.Config.XmlConfigurator.Configure(); 102// log4net.Config.XmlConfigurator.Configure();
103 103
104 Scene scene = SceneSetupHelpers.SetupScene(); 104 Scene scene = SceneHelpers.SetupScene();
105 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); 105 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene);
106 SceneObjectGroup sog1 = SceneSetupHelpers.CreateSceneObject(1, user1.PrincipalID); 106 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID);
107 SceneObjectPart sop1 = sog1.RootPart; 107 SceneObjectPart sop1 = sog1.RootPart;
108 TaskInventoryItem sopItem1 = TaskInventoryHelpers.AddNotecard(scene, sop1); 108 TaskInventoryItem sopItem1 = TaskInventoryHelpers.AddNotecard(scene, sop1);
109 109
@@ -125,12 +125,12 @@ namespace OpenSim.Region.Framework.Tests
125 [Test] 125 [Test]
126 public void TestMoveTaskInventoryItemNoParent() 126 public void TestMoveTaskInventoryItemNoParent()
127 { 127 {
128 TestHelper.InMethod(); 128 TestHelpers.InMethod();
129// log4net.Config.XmlConfigurator.Configure(); 129// log4net.Config.XmlConfigurator.Configure();
130 130
131 Scene scene = SceneSetupHelpers.SetupScene(); 131 Scene scene = SceneHelpers.SetupScene();
132 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); 132 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene);
133 SceneObjectGroup sog1 = SceneSetupHelpers.CreateSceneObject(1, user1.PrincipalID); 133 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID);
134 SceneObjectPart sop1 = sog1.RootPart; 134 SceneObjectPart sop1 = sog1.RootPart;
135 TaskInventoryItem sopItem1 = TaskInventoryHelpers.AddNotecard(scene, sop1); 135 TaskInventoryItem sopItem1 = TaskInventoryHelpers.AddNotecard(scene, sop1);
136 136
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
index abca792..55fc1e7 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
@@ -55,12 +55,12 @@ namespace OpenSim.Region.Framework.Tests
55 [Test] 55 [Test]
56 public void TestGiveInventoryItem() 56 public void TestGiveInventoryItem()
57 { 57 {
58 TestHelper.InMethod(); 58 TestHelpers.InMethod();
59// log4net.Config.XmlConfigurator.Configure(); 59// log4net.Config.XmlConfigurator.Configure();
60 60
61 Scene scene = SceneSetupHelpers.SetupScene(); 61 Scene scene = SceneHelpers.SetupScene();
62 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, 1001); 62 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001));
63 UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, 1002); 63 UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1002));
64 InventoryItemBase item1 = UserInventoryHelpers.CreateInventoryItem(scene, "item1", user1.PrincipalID); 64 InventoryItemBase item1 = UserInventoryHelpers.CreateInventoryItem(scene, "item1", user1.PrincipalID);
65 65
66 scene.GiveInventoryItem(user2.PrincipalID, user1.PrincipalID, item1.ID); 66 scene.GiveInventoryItem(user2.PrincipalID, user1.PrincipalID, item1.ID);
@@ -82,12 +82,12 @@ namespace OpenSim.Region.Framework.Tests
82 [Test] 82 [Test]
83 public void TestGiveInventoryFolder() 83 public void TestGiveInventoryFolder()
84 { 84 {
85 TestHelper.InMethod(); 85 TestHelpers.InMethod();
86// log4net.Config.XmlConfigurator.Configure(); 86// log4net.Config.XmlConfigurator.Configure();
87 87
88 Scene scene = SceneSetupHelpers.SetupScene(); 88 Scene scene = SceneHelpers.SetupScene();
89 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, 1001); 89 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001));
90 UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, 1002); 90 UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1002));
91 InventoryFolderBase folder1 91 InventoryFolderBase folder1
92 = UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, "folder1"); 92 = UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, "folder1");
93 93
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
index 4da8df1..24de56e 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
@@ -47,7 +47,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
47 public void Init() 47 public void Init()
48 { 48 {
49 // FIXME: We don't need a full scene here - it would be enough to set up the asset service. 49 // FIXME: We don't need a full scene here - it would be enough to set up the asset service.
50 Scene scene = SceneSetupHelpers.SetupScene(); 50 Scene scene = SceneHelpers.SetupScene();
51 m_assetService = scene.AssetService; 51 m_assetService = scene.AssetService;
52 m_uuidGatherer = new UuidGatherer(m_assetService); 52 m_uuidGatherer = new UuidGatherer(m_assetService);
53 } 53 }
@@ -55,7 +55,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
55 [Test] 55 [Test]
56 public void TestCorruptAsset() 56 public void TestCorruptAsset()
57 { 57 {
58 TestHelper.InMethod(); 58 TestHelpers.InMethod();
59 59
60 UUID corruptAssetUuid = UUID.Parse("00000000-0000-0000-0000-000000000666"); 60 UUID corruptAssetUuid = UUID.Parse("00000000-0000-0000-0000-000000000666");
61 AssetBase corruptAsset 61 AssetBase corruptAsset
@@ -75,7 +75,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
75 [Test] 75 [Test]
76 public void TestMissingAsset() 76 public void TestMissingAsset()
77 { 77 {
78 TestHelper.InMethod(); 78 TestHelpers.InMethod();
79 79
80 UUID missingAssetUuid = UUID.Parse("00000000-0000-0000-0000-000000000666"); 80 UUID missingAssetUuid = UUID.Parse("00000000-0000-0000-0000-000000000666");
81 IDictionary<UUID, AssetType> foundAssetUuids = new Dictionary<UUID, AssetType>(); 81 IDictionary<UUID, AssetType> foundAssetUuids = new Dictionary<UUID, AssetType>();
diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs
index f71b507..81f41db 100644
--- a/OpenSim/Region/Framework/Scenes/UndoState.cs
+++ b/OpenSim/Region/Framework/Scenes/UndoState.cs
@@ -25,6 +25,9 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System;
29using System.Reflection;
30using log4net;
28using OpenMetaverse; 31using OpenMetaverse;
29using OpenSim.Region.Framework.Interfaces; 32using OpenSim.Region.Framework.Interfaces;
30using System; 33using System;
@@ -47,6 +50,8 @@ namespace OpenSim.Region.Framework.Scenes
47 50
48 public class UndoState 51 public class UndoState
49 { 52 {
53// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54
50 public Vector3 Position = Vector3.Zero; 55 public Vector3 Position = Vector3.Zero;
51 public Vector3 Scale = Vector3.Zero; 56 public Vector3 Scale = Vector3.Zero;
52 public Quaternion Rotation = Quaternion.Identity; 57 public Quaternion Rotation = Quaternion.Identity;
@@ -56,13 +61,23 @@ namespace OpenSim.Region.Framework.Scenes
56 public DateTime LastUpdated = DateTime.Now; 61 public DateTime LastUpdated = DateTime.Now;
57 public UndoType Type; 62 public UndoType Type;
58 63
59 public UndoState(SceneObjectPart part, UndoType type) 64 /// <summary>
65 /// Is this undo state for an entire group?
66 /// </summary>
67 public bool ForGroup;
68
69 /// <summary>
70 /// Constructor.
71 /// </summary>
72 /// <param name="part"></param>
73 /// <param name="forGroup">True if the undo is for an entire group</param>
74 public UndoState(SceneObjectPart part, bool forGroup)
60 { 75 {
61 Type = type; 76 if (part.ParentID == 0)
62 if (part != null)
63 { 77 {
64 if (part.ParentID == 0) 78 ForGroup = forGroup;
65 { 79
80// if (ForGroup)
66 GroupScale = part.ParentGroup.RootPart.Shape.Scale; 81 GroupScale = part.ParentGroup.RootPart.Shape.Scale;
67 82
68 //FUBAR WARNING: Do NOT get the group's absoluteposition here 83 //FUBAR WARNING: Do NOT get the group's absoluteposition here
@@ -70,23 +85,35 @@ namespace OpenSim.Region.Framework.Scenes
70 GroupPosition = part.ParentGroup.RootPart.AbsolutePosition; 85 GroupPosition = part.ParentGroup.RootPart.AbsolutePosition;
71 GroupRotation = part.ParentGroup.GroupRotation; 86 GroupRotation = part.ParentGroup.GroupRotation;
72 Position = part.ParentGroup.RootPart.AbsolutePosition; 87 Position = part.ParentGroup.RootPart.AbsolutePosition;
73 Rotation = part.RotationOffset; 88// else
74 Scale = part.Shape.Scale; 89// Position = part.OffsetPosition;
75 LastUpdated = DateTime.Now;
76 }
77 else
78 {
79 GroupScale = part.Shape.Scale;
80 90
81 //FUBAR WARNING: Do NOT get the group's absoluteposition here 91// m_log.DebugFormat(
82 //or you'll experience a loop and/or a stack issue 92// "[UNDO STATE]: Storing undo position {0} for root part", Position);
83 GroupPosition = part.ParentGroup.RootPart.AbsolutePosition; 93
84 GroupRotation = part.ParentGroup.Rotation; 94 Rotation = part.RotationOffset;
85 Position = part.OffsetPosition; 95
86 Rotation = part.RotationOffset; 96// m_log.DebugFormat(
87 Scale = part.Shape.Scale; 97// "[UNDO STATE]: Storing undo rotation {0} for root part", Rotation);
88 LastUpdated = DateTime.Now; 98
89 } 99 Scale = part.Shape.Scale;
100
101// m_log.DebugFormat(
102// "[UNDO STATE]: Storing undo scale {0} for root part", Scale);
103 }
104 else
105 {
106 Position = part.OffsetPosition;
107// m_log.DebugFormat(
108// "[UNDO STATE]: Storing undo position {0} for child part", Position);
109
110 Rotation = part.RotationOffset;
111// m_log.DebugFormat(
112// "[UNDO STATE]: Storing undo rotation {0} for child part", Rotation);
113
114 Scale = part.Shape.Scale;
115// m_log.DebugFormat(
116// "[UNDO STATE]: Storing undo scale {0} for child part", Scale);
90 } 117 }
91 } 118 }
92 public void Merge(UndoState last) 119 public void Merge(UndoState last)
@@ -132,95 +159,143 @@ namespace OpenSim.Region.Framework.Scenes
132 return false; 159 return false;
133 } 160 }
134 } 161 }
162 /// <summary>
163 /// Compare the relevant state in the given part to this state.
164 /// </summary>
165 /// <param name="part"></param>
166 /// <returns>true if both the part's position, rotation and scale match those in this undo state. False otherwise.</returns>
135 public bool Compare(SceneObjectPart part) 167 public bool Compare(SceneObjectPart part)
136 { 168 {
137 if (part != null) 169 if (part != null)
138 { 170 {
139 if (part.ParentID == 0) 171 if (part.ParentID == 0)
140 { 172 return
141 if (Position == part.ParentGroup.RootPart.AbsolutePosition && Rotation == part.ParentGroup.Rotation && GroupPosition == part.ParentGroup.RootPart.AbsolutePosition && part.ParentGroup.Rotation == GroupRotation && part.Shape.Scale == GroupScale) 173 Position == part.ParentGroup.AbsolutePosition
142 return true; 174 && Rotation == part.RotationOffset
143 else 175 && Scale == part.Shape.Scale;
144 return false;
145 }
146 else 176 else
147 { 177 return
148 if (Position == part.OffsetPosition && Rotation == part.RotationOffset && Scale == part.Shape.Scale && GroupPosition == part.ParentGroup.RootPart.AbsolutePosition && part.ParentGroup.Rotation == GroupRotation && part.Shape.Scale == GroupScale) 178 Position == part.OffsetPosition
149 return true; 179 && Rotation == part.RotationOffset
150 else 180 && Scale == part.Shape.Scale;
151 return false;
152
153 }
154 } 181 }
182
155 return false; 183 return false;
156 } 184 }
157 185
158 private void RestoreState(SceneObjectPart part) 186 private void RestoreState(SceneObjectPart part)
159 { 187 {
160 bool GroupChange = false; 188 part.Undoing = true;
161 if ((Type & UndoType.STATE_GROUP_POSITION) != 0
162 || (Type & UndoType.STATE_GROUP_ROTATION) != 0
163 || (Type & UndoType.STATE_GROUP_SCALE) != 0)
164 {
165 GroupChange = true;
166 }
167 189
168 if (part != null) 190 if (part.ParentID == 0)
169 { 191 {
170 part.Undoing = true; 192// m_log.DebugFormat(
193// "[UNDO STATE]: Undoing position to {0} for root part {1} {2}",
194// Position, part.Name, part.LocalId);
171 195
172 if (part.ParentID == 0 && GroupChange == false) 196 if (Position != Vector3.Zero)
173 { 197 {
174 if (Position != Vector3.Zero) 198 if (ForGroup)
175 199 part.ParentGroup.AbsolutePosition = Position;
176 part.ParentGroup.UpdateSinglePosition(Position, part.LocalId); 200 else
177 part.ParentGroup.UpdateSingleRotation(Rotation, part.LocalId); 201 part.ParentGroup.UpdateRootPosition(Position);
178 if (Scale != Vector3.Zero)
179 part.Resize(Scale);
180 part.ParentGroup.ScheduleGroupForTerseUpdate();
181 } 202 }
203
204// m_log.DebugFormat(
205// "[UNDO STATE]: Undoing rotation {0} to {1} for root part {2} {3}",
206// part.RotationOffset, Rotation, part.Name, part.LocalId);
207
208 if (ForGroup)
209 part.UpdateRotation(Rotation);
182 else 210 else
211 part.ParentGroup.UpdateRootRotation(Rotation);
212
213 if (Scale != Vector3.Zero)
183 { 214 {
184 if (GroupChange) 215// m_log.DebugFormat(
185 { 216// "[UNDO STATE]: Undoing scale {0} to {1} for root part {2} {3}",
186 part.ParentGroup.RootPart.Undoing = true; 217// part.Shape.Scale, Scale, part.Name, part.LocalId);
187 if (GroupPosition != Vector3.Zero) 218
188 { 219 if (ForGroup)
189 //Calculate the scale... 220 part.ParentGroup.GroupResize(Scale);
190 Vector3 gs = part.Shape.Scale;
191 float scale = GroupScale.Z / gs.Z;
192
193 //Scale first since it can affect our position
194 part.ParentGroup.GroupResize(gs * scale, part.LocalId);
195 part.ParentGroup.AbsolutePosition = GroupPosition;
196 part.ParentGroup.UpdateGroupRotationR(GroupRotation);
197
198 }
199 part.ParentGroup.RootPart.Undoing = false;
200 }
201 else 221 else
202 { 222 part.Resize(Scale);
203 if (Position != Vector3.Zero) //We can use this for all the updates since all are set
204 {
205 part.OffsetPosition = Position;
206 part.UpdateRotation(Rotation);
207 part.Resize(Scale); part.ScheduleTerseUpdate();
208 }
209 }
210 } 223 }
211 part.Undoing = false;
212 224
225 part.ParentGroup.ScheduleGroupForTerseUpdate();
213 } 226 }
227 else
228 {
229 if (Position != Vector3.Zero)
230 {
231// m_log.DebugFormat(
232// "[UNDO STATE]: Undoing position {0} to {1} for child part {2} {3}",
233// part.OffsetPosition, Position, part.Name, part.LocalId);
234
235 part.OffsetPosition = Position;
236 }
237
238// m_log.DebugFormat(
239// "[UNDO STATE]: Undoing rotation {0} to {1} for child part {2} {3}",
240// part.RotationOffset, Rotation, part.Name, part.LocalId);
241
242 part.UpdateRotation(Rotation);
243
244 if (Scale != Vector3.Zero)
245 {
246// m_log.DebugFormat(
247// "[UNDO STATE]: Undoing scale {0} to {1} for child part {2} {3}",
248// part.Shape.Scale, Scale, part.Name, part.LocalId);
249
250 part.Resize(Scale);
251 }
252
253 part.ScheduleTerseUpdate();
254 }
255
256 part.Undoing = false;
214 } 257 }
215 public void PlaybackState(SceneObjectPart part) 258
216 {
217 RestoreState(part);
218 }
219 public void PlayfwdState(SceneObjectPart part) 259 public void PlayfwdState(SceneObjectPart part)
220 { 260 {
221 RestoreState(part); 261 part.Undoing = true;
262
263 if (part.ParentID == 0)
264 {
265 if (Position != Vector3.Zero)
266 part.ParentGroup.AbsolutePosition = Position;
267
268 if (Rotation != Quaternion.Identity)
269 part.UpdateRotation(Rotation);
270
271 if (Scale != Vector3.Zero)
272 {
273 if (ForGroup)
274 part.ParentGroup.GroupResize(Scale);
275 else
276 part.Resize(Scale);
277 }
278
279 part.ParentGroup.ScheduleGroupForTerseUpdate();
280 }
281 else
282 {
283 if (Position != Vector3.Zero)
284 part.OffsetPosition = Position;
285
286 if (Rotation != Quaternion.Identity)
287 part.UpdateRotation(Rotation);
288
289 if (Scale != Vector3.Zero)
290 part.Resize(Scale);
291
292 part.ScheduleTerseUpdate();
293 }
294
295 part.Undoing = false;
222 } 296 }
223 } 297 }
298
224 public class LandUndoState 299 public class LandUndoState
225 { 300 {
226 public ITerrainModule m_terrainModule; 301 public ITerrainModule m_terrainModule;
@@ -234,10 +309,7 @@ namespace OpenSim.Region.Framework.Scenes
234 309
235 public bool Compare(ITerrainChannel terrainChannel) 310 public bool Compare(ITerrainChannel terrainChannel)
236 { 311 {
237 if (m_terrainChannel != terrainChannel) 312 return m_terrainChannel == terrainChannel;
238 return false;
239 else
240 return false;
241 } 313 }
242 314
243 public void PlaybackState() 315 public void PlaybackState()
@@ -246,4 +318,3 @@ namespace OpenSim.Region.Framework.Scenes
246 } 318 }
247 } 319 }
248} 320}
249
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 26934e8..00b1c1e 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -677,7 +677,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
677 public event DeRezObject OnDeRezObject; 677 public event DeRezObject OnDeRezObject;
678 public event Action<IClientAPI> OnRegionHandShakeReply; 678 public event Action<IClientAPI> OnRegionHandShakeReply;
679 public event GenericCall1 OnRequestWearables; 679 public event GenericCall1 OnRequestWearables;
680 public event GenericCall1 OnCompleteMovementToRegion; 680 public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
681 public event UpdateAgent OnPreAgentUpdate; 681 public event UpdateAgent OnPreAgentUpdate;
682 public event UpdateAgent OnAgentUpdate; 682 public event UpdateAgent OnAgentUpdate;
683 public event AgentRequestSit OnAgentRequestSit; 683 public event AgentRequestSit OnAgentRequestSit;
@@ -806,7 +806,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
806 public event ScriptReset OnScriptReset; 806 public event ScriptReset OnScriptReset;
807 public event GetScriptRunning OnGetScriptRunning; 807 public event GetScriptRunning OnGetScriptRunning;
808 public event SetScriptRunning OnSetScriptRunning; 808 public event SetScriptRunning OnSetScriptRunning;
809 public event UpdateVector OnAutoPilotGo; 809 public event Action<Vector3, bool> OnAutoPilotGo;
810 public event TerrainUnacked OnUnackedTerrain; 810 public event TerrainUnacked OnUnackedTerrain;
811 public event ActivateGesture OnActivateGesture; 811 public event ActivateGesture OnActivateGesture;
812 public event DeactivateGesture OnDeactivateGesture; 812 public event DeactivateGesture OnDeactivateGesture;
@@ -899,7 +899,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
899 899
900 public void Start() 900 public void Start()
901 { 901 {
902 Scene.AddNewClient(this); 902 Scene.AddNewClient(this, PresenceType.User);
903 903
904 // Mimicking LLClientView which gets always set appearance from client. 904 // Mimicking LLClientView which gets always set appearance from client.
905 Scene scene = (Scene)Scene; 905 Scene scene = (Scene)Scene;
@@ -919,7 +919,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
919 919
920 if (OnCompleteMovementToRegion != null) 920 if (OnCompleteMovementToRegion != null)
921 { 921 {
922 OnCompleteMovementToRegion(this); 922 OnCompleteMovementToRegion(this, true);
923 } 923 }
924 } 924 }
925 925
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs
index ee52a39..d2f6327 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs
@@ -47,16 +47,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests
47 [Test] 47 [Test]
48 public void TestBasic() 48 public void TestBasic()
49 { 49 {
50 TestHelper.InMethod(); 50 TestHelpers.InMethod();
51// log4net.Config.XmlConfigurator.Configure(); 51// log4net.Config.XmlConfigurator.Configure();
52 52
53 TestScene scene = SceneSetupHelpers.SetupScene(); 53 TestScene scene = SceneHelpers.SetupScene();
54 IConfigSource configSource = new IniConfigSource(); 54 IConfigSource configSource = new IniConfigSource();
55 IConfig config = configSource.AddConfig("Groups"); 55 IConfig config = configSource.AddConfig("Groups");
56 config.Set("Enabled", true); 56 config.Set("Enabled", true);
57 config.Set("Module", "GroupsModule"); 57 config.Set("Module", "GroupsModule");
58 config.Set("DebugEnabled", true); 58 config.Set("DebugEnabled", true);
59 SceneSetupHelpers.SetupSceneModules( 59 SceneHelpers.SetupSceneModules(
60 scene, configSource, new object[] { new MockGroupsServicesConnector() }); 60 scene, configSource, new object[] { new MockGroupsServicesConnector() });
61 } 61 }
62 } 62 }
diff --git a/OpenSim/Region/OptionalModules/Framework/Monitoring/MonitorServicesModule.cs b/OpenSim/Region/OptionalModules/Framework/Monitoring/MonitorServicesModule.cs
new file mode 100644
index 0000000..a25e034
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Framework/Monitoring/MonitorServicesModule.cs
@@ -0,0 +1,119 @@
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.Reflection;
30using System.Text;
31using log4net;
32using Mono.Addins;
33using Nini.Config;
34using OpenMetaverse;
35using OpenSim.Framework;
36using OpenSim.Framework.Console;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39
40namespace OpenSim.Region.OptionalModules.Framework.Monitoring
41{
42 /// <summary>
43 /// An experimental module to return data on services used by the simulator.
44 /// </summary>
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MonitorServicesModule")]
46 public class MonitorServicesModule : ISharedRegionModule
47 {
48 protected Scene m_scene;
49
50// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51
52 public string Name { get { return "Services Health Monitoring Module"; } }
53
54 public Type ReplaceableInterface { get { return null; } }
55
56 public void Initialise(IConfigSource source)
57 {
58 }
59
60 public void PostInitialise()
61 {
62 }
63
64 public void Close()
65 {
66 }
67
68 public void AddRegion(Scene scene)
69 {
70 if (m_scene == null)
71 {
72 m_scene = scene;
73
74// m_scene.AddCommand(this, "monitor services",
75// "monitor services",
76// "Returns the status of services used by the simulator. Experimental.",
77// HandleMonitorServices);
78 }
79 }
80
81 public void RemoveRegion(Scene scene)
82 {
83 }
84
85 public void RegionLoaded(Scene scene)
86 {
87 }
88
89 protected void HandleMonitorServices(string module, string[] args)
90 {
91 MainConsole.Instance.Output(GenerateServicesReport());
92 }
93
94 protected string GenerateServicesReport()
95 {
96 StringBuilder sb = new StringBuilder();
97 sb.Append("This is an experimental module. Please don't rely on these results\n");
98 sb.Append("Asset service: ");
99
100 try
101 {
102 CheckAssetService();
103 sb.Append("OK");
104 }
105 catch (Exception e)
106 {
107 sb.AppendFormat("FAIL ({0})", e.Message);
108 }
109
110 return sb.ToString();
111 }
112
113 protected void CheckAssetService()
114 {
115 // Try to fetch an asset that will not exist (and hence avoid hitting cache)
116 m_scene.AssetService.Get(UUID.Random().ToString());
117 }
118 }
119} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs b/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs
new file mode 100755
index 0000000..2a44360
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs
@@ -0,0 +1,277 @@
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.Reflection;
30using System.Collections.Generic;
31using log4net;
32using Mono.Addins;
33using Nini.Config;
34using OpenSim.Framework;
35using OpenSim.Framework.Console;
36using OpenSim.Region.CoreModules.Framework.InterfaceCommander;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Region.Physics.Manager;
40
41namespace OpenSim.Region.OptionalModules.PhysicsParameters
42{
43 /// <summary>
44 /// </summary>
45 /// <remarks>
46 /// </remarks>
47 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "PhysicsParameters")]
48 public class PhysicsParameters : ISharedRegionModule
49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 private static string LogHeader = "[PHYSICS PARAMETERS]";
52
53 private List<Scene> m_scenes = new List<Scene>();
54 private static bool m_commandsLoaded = false;
55
56 #region ISharedRegionModule
57 public string Name { get { return "Runtime Physics Parameter Module"; } }
58
59 public Type ReplaceableInterface { get { return null; } }
60
61 public void Initialise(IConfigSource source)
62 {
63 // m_log.DebugFormat("{0}: INITIALIZED MODULE", LogHeader);
64 }
65
66 public void PostInitialise()
67 {
68 // m_log.DebugFormat("[{0}: POST INITIALIZED MODULE", LogHeader);
69 InstallInterfaces();
70 }
71
72 public void Close()
73 {
74 // m_log.DebugFormat("{0}: CLOSED MODULE", LogHeader);
75 }
76
77 public void AddRegion(Scene scene)
78 {
79 // m_log.DebugFormat("{0}: REGION {1} ADDED", LogHeader, scene.RegionInfo.RegionName);
80 m_scenes.Add(scene);
81 }
82
83 public void RemoveRegion(Scene scene)
84 {
85 // m_log.DebugFormat("{0}: REGION {1} REMOVED", LogHeader, scene.RegionInfo.RegionName);
86 if (m_scenes.Contains(scene))
87 m_scenes.Remove(scene);
88 }
89
90 public void RegionLoaded(Scene scene)
91 {
92 // m_log.DebugFormat("{0}: REGION {1} LOADED", LogHeader, scene.RegionInfo.RegionName);
93 }
94 #endregion INonSharedRegionModule
95
96 private const string getInvocation = "physics get [<param>|ALL]";
97 private const string setInvocation = "physics set <param> [<value>|TRUE|FALSE] [localID|ALL]";
98 private const string listInvocation = "physics list";
99 private void InstallInterfaces()
100 {
101 if (!m_commandsLoaded)
102 {
103 MainConsole.Instance.Commands.AddCommand("Physics", false, "physics set",
104 "physics set",
105 "Set physics parameter from currently selected region" + Environment.NewLine
106 + "Invocation: " + setInvocation,
107 ProcessPhysicsSet);
108
109 MainConsole.Instance.Commands.AddCommand("Physics", false, "physics get",
110 "physics get",
111 "Get physics parameter from currently selected region" + Environment.NewLine
112 + "Invocation: " + getInvocation,
113 ProcessPhysicsGet);
114
115 MainConsole.Instance.Commands.AddCommand("Physics", false, "physics list",
116 "physics list",
117 "List settable physics parameters" + Environment.NewLine
118 + "Invocation: " + listInvocation,
119 ProcessPhysicsList);
120
121 m_commandsLoaded = true;
122 }
123 }
124
125 // TODO: extend get so you can get a value from an individual localID
126 private void ProcessPhysicsGet(string module, string[] cmdparms)
127 {
128 if (cmdparms.Length != 3)
129 {
130 WriteError("Parameter count error. Invocation: " + getInvocation);
131 return;
132 }
133 string parm = cmdparms[2];
134
135 if (SceneManager.Instance == null || SceneManager.Instance.CurrentScene == null)
136 {
137 WriteError("Error: no region selected. Use 'change region' to select a region.");
138 return;
139 }
140
141 Scene scene = SceneManager.Instance.CurrentScene;
142 IPhysicsParameters physScene = scene.PhysicsScene as IPhysicsParameters;
143 if (physScene != null)
144 {
145 if (parm.ToLower() == "all")
146 {
147 foreach (PhysParameterEntry ppe in physScene.GetParameterList())
148 {
149 float val = 0.0f;
150 if (physScene.GetPhysicsParameter(ppe.name, out val))
151 {
152 WriteOut(" {0}/{1} = {2}", scene.RegionInfo.RegionName, ppe.name, val);
153 }
154 else
155 {
156 WriteOut(" {0}/{1} = {2}", scene.RegionInfo.RegionName, ppe.name, "unknown");
157 }
158 }
159 }
160 else
161 {
162 float val = 0.0f;
163 if (physScene.GetPhysicsParameter(parm, out val))
164 {
165 WriteOut(" {0}/{1} = {2}", scene.RegionInfo.RegionName, parm, val);
166 }
167 else
168 {
169 WriteError("Failed fetch of parameter '{0}' from region '{1}'", parm, scene.RegionInfo.RegionName);
170 }
171 }
172 }
173 else
174 {
175 WriteError("Region '{0}' physics engine has no gettable physics parameters", scene.RegionInfo.RegionName);
176 }
177 return;
178 }
179
180 private void ProcessPhysicsSet(string module, string[] cmdparms)
181 {
182 if (cmdparms.Length < 4 || cmdparms.Length > 5)
183 {
184 WriteError("Parameter count error. Invocation: " + getInvocation);
185 return;
186 }
187 string parm = "xxx";
188 float val = 0f;
189 uint localID = (uint)PhysParameterEntry.APPLY_TO_NONE; // set default value
190 try
191 {
192 parm = cmdparms[2];
193 string valparm = cmdparms[3].ToLower();
194 if (valparm == "true")
195 val = PhysParameterEntry.NUMERIC_TRUE;
196 else
197 {
198 if (valparm == "false")
199 val = PhysParameterEntry.NUMERIC_FALSE;
200 else
201 val = float.Parse(valparm, Culture.NumberFormatInfo);
202 }
203 if (cmdparms.Length > 4)
204 {
205 if (cmdparms[4].ToLower() == "all")
206 localID = (uint)PhysParameterEntry.APPLY_TO_ALL;
207 else
208 localID = uint.Parse(cmdparms[2], Culture.NumberFormatInfo);
209 }
210 }
211 catch
212 {
213 WriteError(" Error parsing parameters. Invocation: " + setInvocation);
214 return;
215 }
216
217 if (SceneManager.Instance == null || SceneManager.Instance.CurrentScene == null)
218 {
219 WriteError("Error: no region selected. Use 'change region' to select a region.");
220 return;
221 }
222
223 Scene scene = SceneManager.Instance.CurrentScene;
224 IPhysicsParameters physScene = scene.PhysicsScene as IPhysicsParameters;
225 if (physScene != null)
226 {
227 if (!physScene.SetPhysicsParameter(parm, val, localID))
228 {
229 WriteError("Failed set of parameter '{0}' for region '{1}'", parm, scene.RegionInfo.RegionName);
230 }
231 }
232 else
233 {
234 WriteOut("Region '{0}'s physics engine has no settable physics parameters", scene.RegionInfo.RegionName);
235 }
236 return;
237 }
238
239 private void ProcessPhysicsList(string module, string[] cmdparms)
240 {
241 if (SceneManager.Instance == null || SceneManager.Instance.CurrentScene == null)
242 {
243 WriteError("Error: no region selected. Use 'change region' to select a region.");
244 return;
245 }
246 Scene scene = SceneManager.Instance.CurrentScene;
247
248 IPhysicsParameters physScene = scene.PhysicsScene as IPhysicsParameters;
249 if (physScene != null)
250 {
251 WriteOut("Available physics parameters:");
252 PhysParameterEntry[] parms = physScene.GetParameterList();
253 foreach (PhysParameterEntry ent in parms)
254 {
255 WriteOut(" {0}: {1}", ent.name, ent.desc);
256 }
257 }
258 else
259 {
260 WriteError("Current regions's physics engine has no settable physics parameters");
261 }
262 return;
263 }
264
265 private void WriteOut(string msg, params object[] args)
266 {
267 m_log.InfoFormat(msg, args);
268 // MainConsole.Instance.OutputFormat(msg, args);
269 }
270
271 private void WriteError(string msg, params object[] args)
272 {
273 m_log.ErrorFormat(msg, args);
274 // MainConsole.Instance.OutputFormat(msg, args);
275 }
276 }
277} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
index 05c729a..963d1e2 100644
--- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
@@ -126,6 +126,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
126 m_scene.EventManager.OnEmptyScriptCompileQueue -= OnEmptyScriptCompileQueue; 126 m_scene.EventManager.OnEmptyScriptCompileQueue -= OnEmptyScriptCompileQueue;
127 m_scene.EventManager.OnOarFileLoaded -= OnOarFileLoaded; 127 m_scene.EventManager.OnOarFileLoaded -= OnOarFileLoaded;
128 128
129 if(m_uri != string.Empty)
130 {
131 RRAlert("shutdown");
132 }
133
129 m_scene = null; 134 m_scene = null;
130 } 135 }
131 136
diff --git a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs
index d18ac0a..2187449 100644
--- a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs
@@ -106,7 +106,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule
106 info.channel = channel; 106 info.channel = channel;
107 info.uri = uri; 107 info.uri = uri;
108 108
109 bool success = SynchronousRestObjectPoster.BeginPostObject<XmlRpcInfo, bool>( 109 bool success = SynchronousRestObjectRequester.MakeRequest<XmlRpcInfo, bool>(
110 "POST", m_ServerURI+"/RegisterChannel/", info); 110 "POST", m_ServerURI+"/RegisterChannel/", info);
111 111
112 if (!success) 112 if (!success)
@@ -125,7 +125,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule
125 125
126 if (m_Channels.ContainsKey(itemID)) 126 if (m_Channels.ContainsKey(itemID))
127 { 127 {
128 bool success = SynchronousRestObjectPoster.BeginPostObject<UUID, bool>( 128 bool success = SynchronousRestObjectRequester.MakeRequest<UUID, bool>(
129 "POST", m_ServerURI+"/RemoveChannel/", m_Channels[itemID]); 129 "POST", m_ServerURI+"/RemoveChannel/", m_Channels[itemID]);
130 130
131 if (!success) 131 if (!success)
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index 69d6261..4f831a4 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -37,6 +37,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC
37{ 37{
38 public class NPCAvatar : IClientAPI 38 public class NPCAvatar : IClientAPI
39 { 39 {
40 /// <summary>
41 /// Signal whether the avatar should land when it reaches a move target
42 /// </summary>
43 public bool LandAtTarget { get; set; }
44
40 private readonly string m_firstname; 45 private readonly string m_firstname;
41 private readonly string m_lastname; 46 private readonly string m_lastname;
42 private readonly Vector3 m_startPos; 47 private readonly Vector3 m_startPos;
@@ -99,6 +104,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
99 { 104 {
100 105
101 } 106 }
107
102 public void SendSitResponse(UUID TargetID, Vector3 OffsetPos, Quaternion SitOrientation, bool autopilot, 108 public void SendSitResponse(UUID TargetID, Vector3 OffsetPos, Quaternion SitOrientation, bool autopilot,
103 Vector3 CameraAtOffset, Vector3 CameraEyeOffset, bool ForceMouseLook) 109 Vector3 CameraAtOffset, Vector3 CameraEyeOffset, bool ForceMouseLook)
104 { 110 {
@@ -189,7 +195,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
189 public event DeRezObject OnDeRezObject; 195 public event DeRezObject OnDeRezObject;
190 public event Action<IClientAPI> OnRegionHandShakeReply; 196 public event Action<IClientAPI> OnRegionHandShakeReply;
191 public event GenericCall1 OnRequestWearables; 197 public event GenericCall1 OnRequestWearables;
192 public event GenericCall1 OnCompleteMovementToRegion; 198 public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
193 public event UpdateAgent OnPreAgentUpdate; 199 public event UpdateAgent OnPreAgentUpdate;
194 public event UpdateAgent OnAgentUpdate; 200 public event UpdateAgent OnAgentUpdate;
195 public event AgentRequestSit OnAgentRequestSit; 201 public event AgentRequestSit OnAgentRequestSit;
@@ -327,7 +333,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
327 public event ScriptReset OnScriptReset; 333 public event ScriptReset OnScriptReset;
328 public event GetScriptRunning OnGetScriptRunning; 334 public event GetScriptRunning OnGetScriptRunning;
329 public event SetScriptRunning OnSetScriptRunning; 335 public event SetScriptRunning OnSetScriptRunning;
330 public event UpdateVector OnAutoPilotGo; 336 public event Action<Vector3, bool> OnAutoPilotGo;
331 337
332 public event TerrainUnacked OnUnackedTerrain; 338 public event TerrainUnacked OnUnackedTerrain;
333 339
@@ -744,12 +750,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC
744 { 750 {
745 OnRegionHandShakeReply(this); 751 OnRegionHandShakeReply(this);
746 } 752 }
747
748 if (OnCompleteMovementToRegion != null)
749 {
750 OnCompleteMovementToRegion(this);
751 }
752 } 753 }
754
753 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) 755 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID)
754 { 756 {
755 } 757 }
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
index 3cdd06d..2fdeeab 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
@@ -44,32 +44,119 @@ namespace OpenSim.Region.OptionalModules.World.NPC
44 { 44 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 46
47 // private const bool m_enabled = false; 47 private Dictionary<UUID, NPCAvatar> m_avatars = new Dictionary<UUID, NPCAvatar>();
48
49 private Dictionary<UUID,NPCAvatar> m_avatars = new Dictionary<UUID, NPCAvatar>();
50 private Dictionary<UUID,AvatarAppearance> m_appearanceCache = new Dictionary<UUID, AvatarAppearance>();
51 48
52 public void Initialise(Scene scene, IConfigSource source) 49 public void Initialise(Scene scene, IConfigSource source)
53 { 50 {
54 scene.RegisterModuleInterface<INPCModule>(this); 51 IConfig config = source.Configs["NPC"];
52
53 if (config != null && config.GetBoolean("Enabled", false))
54 {
55 scene.RegisterModuleInterface<INPCModule>(this);
56 scene.EventManager.OnSignificantClientMovement += HandleOnSignificantClientMovement;
57 }
55 } 58 }
56 59
57 private AvatarAppearance GetAppearance(UUID target, Scene scene) 60 public void HandleOnSignificantClientMovement(ScenePresence presence)
58 { 61 {
59 if (m_appearanceCache.ContainsKey(target)) 62 lock (m_avatars)
60 return m_appearanceCache[target];
61
62 AvatarAppearance appearance = scene.AvatarService.GetAppearance(target);
63 if (appearance != null)
64 { 63 {
65 m_appearanceCache.Add(target, appearance); 64 if (m_avatars.ContainsKey(presence.UUID) && presence.MovingToTarget)
66 return appearance; 65 {
66 double distanceToTarget = Util.GetDistanceTo(presence.AbsolutePosition, presence.MoveToPositionTarget);
67// m_log.DebugFormat(
68// "[NPC MODULE]: Abs pos of {0} is {1}, target {2}, distance {3}",
69// presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget, distanceToTarget);
70
71 // Check the error term of the current position in relation to the target position
72 if (distanceToTarget <= ScenePresence.SIGNIFICANT_MOVEMENT)
73 {
74 // We are close enough to the target
75 m_log.DebugFormat("[NPC MODULE]: Stopping movement of npc {0}", presence.Name);
76
77 presence.Velocity = Vector3.Zero;
78 presence.AbsolutePosition = presence.MoveToPositionTarget;
79 presence.ResetMoveToTarget();
80
81 if (presence.PhysicsActor.Flying)
82 {
83 // A horrible hack to stop the NPC dead in its tracks rather than having them overshoot
84 // the target if flying.
85 // We really need to be more subtle (slow the avatar as it approaches the target) or at
86 // least be able to set collision status once, rather than 5 times to give it enough
87 // weighting so that that PhysicsActor thinks it really is colliding.
88 for (int i = 0; i < 5; i++)
89 presence.PhysicsActor.IsColliding = true;
90
91// Vector3 targetPos = presence.MoveToPositionTarget;
92 if (m_avatars[presence.UUID].LandAtTarget)
93 presence.PhysicsActor.Flying = false;
94
95// float terrainHeight = (float)presence.Scene.Heightmap[(int)targetPos.X, (int)targetPos.Y];
96// if (targetPos.Z - terrainHeight < 0.2)
97// {
98// presence.PhysicsActor.Flying = false;
99// }
100 }
101
102// m_log.DebugFormat(
103// "[NPC MODULE]: AgentControlFlags {0}, MovementFlag {1} for {2}",
104// presence.AgentControlFlags, presence.MovementFlag, presence.Name);
105 }
106 else
107 {
108// m_log.DebugFormat(
109// "[NPC MODULE]: Updating npc {0} at {1} for next movement to {2}",
110// presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget);
111
112 Vector3 agent_control_v3 = new Vector3();
113 presence.HandleMoveToTargetUpdate(ref agent_control_v3);
114 presence.AddNewMovement(agent_control_v3);
115 }
116//
117//// presence.DoMoveToPositionUpdate((0, presence.MoveToPositionTarget, null);
118
119//
120//
121
122 }
67 } 123 }
124 }
125
126 public bool IsNPC(UUID agentId, Scene scene)
127 {
128 ScenePresence sp = scene.GetScenePresence(agentId);
129 if (sp == null || sp.IsChildAgent)
130 return false;
68 131
69 return new AvatarAppearance(); 132 lock (m_avatars)
133 return m_avatars.ContainsKey(agentId);
70 } 134 }
71 135
72 public UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, UUID cloneAppearanceFrom) 136 public bool SetNPCAppearance(UUID agentId, AvatarAppearance appearance, Scene scene)
137 {
138 ScenePresence sp = scene.GetScenePresence(agentId);
139 if (sp == null || sp.IsChildAgent)
140 return false;
141
142 lock (m_avatars)
143 if (!m_avatars.ContainsKey(agentId))
144 return false;
145
146 scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, false);
147
148 AvatarAppearance npcAppearance = new AvatarAppearance(appearance, true);
149 sp.Appearance = npcAppearance;
150 scene.AttachmentsModule.RezAttachments(sp);
151
152 IAvatarFactory module = scene.RequestModuleInterface<IAvatarFactory>();
153 module.SendAppearance(sp.UUID);
154
155 return true;
156 }
157
158 public UUID CreateNPC(
159 string firstname, string lastname, Vector3 position, Scene scene, AvatarAppearance appearance)
73 { 160 {
74 NPCAvatar npcAvatar = new NPCAvatar(firstname, lastname, position, scene); 161 NPCAvatar npcAvatar = new NPCAvatar(firstname, lastname, position, scene);
75 npcAvatar.CircuitCode = (uint)Util.RandomClass.Next(0, int.MaxValue); 162 npcAvatar.CircuitCode = (uint)Util.RandomClass.Next(0, int.MaxValue);
@@ -84,12 +171,18 @@ namespace OpenSim.Region.OptionalModules.World.NPC
84 acd.lastname = lastname; 171 acd.lastname = lastname;
85 acd.ServiceURLs = new Dictionary<string, object>(); 172 acd.ServiceURLs = new Dictionary<string, object>();
86 173
87 AvatarAppearance originalAppearance = GetAppearance(cloneAppearanceFrom, scene); 174 AvatarAppearance npcAppearance = new AvatarAppearance(appearance, true);
88 AvatarAppearance npcAppearance = new AvatarAppearance(originalAppearance, true);
89 acd.Appearance = npcAppearance; 175 acd.Appearance = npcAppearance;
90 176
177// for (int i = 0; i < acd.Appearance.Texture.FaceTextures.Length; i++)
178// {
179// m_log.DebugFormat(
180// "[NPC MODULE]: NPC avatar {0} has texture id {1} : {2}",
181// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]);
182// }
183
91 scene.AuthenticateHandler.AddNewCircuit(npcAvatar.CircuitCode, acd); 184 scene.AuthenticateHandler.AddNewCircuit(npcAvatar.CircuitCode, acd);
92 scene.AddNewClient(npcAvatar); 185 scene.AddNewClient(npcAvatar, PresenceType.Npc);
93 186
94 ScenePresence sp; 187 ScenePresence sp;
95 if (scene.TryGetScenePresence(npcAvatar.AgentId, out sp)) 188 if (scene.TryGetScenePresence(npcAvatar.AgentId, out sp))
@@ -97,13 +190,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
97 m_log.DebugFormat( 190 m_log.DebugFormat(
98 "[NPC MODULE]: Successfully retrieved scene presence for NPC {0} {1}", sp.Name, sp.UUID); 191 "[NPC MODULE]: Successfully retrieved scene presence for NPC {0} {1}", sp.Name, sp.UUID);
99 192
100 // Shouldn't call this - temporary. 193 sp.CompleteMovement(npcAvatar, false);
101 sp.CompleteMovement(npcAvatar);
102
103// sp.SendAppearanceToAllOtherAgents();
104//
105// // Send animations back to the avatar as well
106// sp.Animator.SendAnimPack();
107 } 194 }
108 else 195 else
109 { 196 {
@@ -118,7 +205,30 @@ namespace OpenSim.Region.OptionalModules.World.NPC
118 return npcAvatar.AgentId; 205 return npcAvatar.AgentId;
119 } 206 }
120 207
121 public void Autopilot(UUID agentID, Scene scene, Vector3 pos) 208 public bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos, bool noFly, bool landAtTarget)
209 {
210 lock (m_avatars)
211 {
212 if (m_avatars.ContainsKey(agentID))
213 {
214 ScenePresence sp;
215 scene.TryGetScenePresence(agentID, out sp);
216
217 m_log.DebugFormat(
218 "[NPC MODULE]: Moving {0} to {1} in {2}, noFly {3}, landAtTarget {4}",
219 sp.Name, pos, scene.RegionInfo.RegionName, noFly, landAtTarget);
220
221 m_avatars[agentID].LandAtTarget = landAtTarget;
222 sp.MoveToTarget(pos, noFly);
223
224 return true;
225 }
226 }
227
228 return false;
229 }
230
231 public bool StopMoveToTarget(UUID agentID, Scene scene)
122 { 232 {
123 lock (m_avatars) 233 lock (m_avatars)
124 { 234 {
@@ -126,32 +236,49 @@ namespace OpenSim.Region.OptionalModules.World.NPC
126 { 236 {
127 ScenePresence sp; 237 ScenePresence sp;
128 scene.TryGetScenePresence(agentID, out sp); 238 scene.TryGetScenePresence(agentID, out sp);
129 sp.DoAutoPilot(0, pos, m_avatars[agentID]); 239
240 sp.Velocity = Vector3.Zero;
241 sp.ResetMoveToTarget();
242
243 return true;
130 } 244 }
131 } 245 }
246
247 return false;
132 } 248 }
133 249
134 public void Say(UUID agentID, Scene scene, string text) 250 public bool Say(UUID agentID, Scene scene, string text)
135 { 251 {
136 lock (m_avatars) 252 lock (m_avatars)
137 { 253 {
138 if (m_avatars.ContainsKey(agentID)) 254 if (m_avatars.ContainsKey(agentID))
139 { 255 {
256 ScenePresence sp;
257 scene.TryGetScenePresence(agentID, out sp);
258
140 m_avatars[agentID].Say(text); 259 m_avatars[agentID].Say(text);
260
261 return true;
141 } 262 }
142 } 263 }
264
265 return false;
143 } 266 }
144 267
145 public void DeleteNPC(UUID agentID, Scene scene) 268 public bool DeleteNPC(UUID agentID, Scene scene)
146 { 269 {
147 lock (m_avatars) 270 lock (m_avatars)
148 { 271 {
149 if (m_avatars.ContainsKey(agentID)) 272 if (m_avatars.ContainsKey(agentID))
150 { 273 {
151 scene.RemoveClient(agentID); 274 scene.RemoveClient(agentID, false);
152 m_avatars.Remove(agentID); 275 m_avatars.Remove(agentID);
276
277 return true;
153 } 278 }
154 } 279 }
280
281 return false;
155 } 282 }
156 283
157 public void PostInitialise() 284 public void PostInitialise()
diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
index 899e721..78296a4 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
@@ -27,11 +27,14 @@
27 27
28using System; 28using System;
29using System.Reflection; 29using System.Reflection;
30using log4net;
30using Nini.Config; 31using Nini.Config;
31using NUnit.Framework; 32using NUnit.Framework;
32using OpenMetaverse; 33using OpenMetaverse;
33using OpenSim.Framework; 34using OpenSim.Framework;
34using OpenSim.Framework.Communications; 35using OpenSim.Framework.Communications;
36using OpenSim.Region.CoreModules.Avatar.AvatarFactory;
37using OpenSim.Region.CoreModules.Framework.UserManagement;
35using OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar; 38using OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar;
36using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
@@ -47,25 +50,112 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
47 [Test] 50 [Test]
48 public void TestCreate() 51 public void TestCreate()
49 { 52 {
50 TestHelper.InMethod(); 53 TestHelpers.InMethod();
51// log4net.Config.XmlConfigurator.Configure(); 54// log4net.Config.XmlConfigurator.Configure();
52 55
53 IConfigSource config = new IniConfigSource(); 56 IConfigSource config = new IniConfigSource();
57 config.AddConfig("NPC");
58 config.Configs["NPC"].Set("Enabled", "true");
54 59
55 config.AddConfig("Modules"); 60 AvatarFactoryModule afm = new AvatarFactoryModule();
56 config.Configs["Modules"].Set("AvatarServices", "LocalAvatarServicesConnector"); 61 UserManagementModule umm = new UserManagementModule();
57 config.AddConfig("AvatarService");
58 config.Configs["AvatarService"].Set("LocalServiceModule", "OpenSim.Services.AvatarService.dll:AvatarService");
59 config.Configs["AvatarService"].Set("StorageProvider", "OpenSim.Data.Null.dll");
60 62
61 TestScene scene = SceneSetupHelpers.SetupScene(); 63 TestScene scene = SceneHelpers.SetupScene();
62 SceneSetupHelpers.SetupSceneModules(scene, config, new NPCModule(), new LocalAvatarServicesConnector()); 64 SceneHelpers.SetupSceneModules(scene, config, afm, umm, new NPCModule());
65 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
66// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId);
67
68 // 8 is the index of the first baked texture in AvatarAppearance
69 UUID originalFace8TextureId = TestHelpers.ParseTail(0x10);
70 Primitive.TextureEntry originalTe = new Primitive.TextureEntry(UUID.Zero);
71 Primitive.TextureEntryFace originalTef = originalTe.CreateFace(8);
72 originalTef.TextureID = originalFace8TextureId;
73
74 // We also need to add the texture to the asset service, otherwise the AvatarFactoryModule will tell
75 // ScenePresence.SendInitialData() to reset our entire appearance.
76 scene.AssetService.Store(AssetHelpers.CreateAsset(originalFace8TextureId));
77
78 afm.SetAppearanceFromClient(sp.ControllingClient, originalTe, null);
63 79
64 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 80 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
65 UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, UUID.Zero); 81 UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, sp.Appearance);
66 82
67 ScenePresence npc = scene.GetScenePresence(npcId); 83 ScenePresence npc = scene.GetScenePresence(npcId);
84
68 Assert.That(npc, Is.Not.Null); 85 Assert.That(npc, Is.Not.Null);
86 Assert.That(npc.Appearance.Texture.FaceTextures[8].TextureID, Is.EqualTo(originalFace8TextureId));
87 Assert.That(umm.GetUserName(npc.UUID), Is.EqualTo(string.Format("{0} {1}", npc.Firstname, npc.Lastname)));
88 }
89
90 [Test]
91 public void TestMove()
92 {
93 TestHelpers.InMethod();
94// log4net.Config.XmlConfigurator.Configure();
95
96 IConfigSource config = new IniConfigSource();
97
98 config.AddConfig("NPC");
99 config.Configs["NPC"].Set("Enabled", "true");
100
101 TestScene scene = SceneHelpers.SetupScene();
102 SceneHelpers.SetupSceneModules(scene, config, new NPCModule());
103 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
104// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId);
105
106 Vector3 startPos = new Vector3(128, 128, 30);
107 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
108 UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, scene, sp.Appearance);
109
110 ScenePresence npc = scene.GetScenePresence(npcId);
111 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
112
113 // For now, we'll make the scene presence fly to simplify this test, but this needs to change.
114 npc.PhysicsActor.Flying = true;
115
116 scene.Update();
117 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
118
119 Vector3 targetPos = startPos + new Vector3(0, 0, 10);
120 npcModule.MoveToTarget(npc.UUID, scene, targetPos, false, false);
121
122 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
123
124 scene.Update();
125
126 // We should really check the exact figure.
127 Assert.That(npc.AbsolutePosition.X, Is.EqualTo(startPos.X));
128 Assert.That(npc.AbsolutePosition.Y, Is.EqualTo(startPos.Y));
129 Assert.That(npc.AbsolutePosition.Z, Is.GreaterThan(startPos.Z));
130 Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.Z));
131
132 for (int i = 0; i < 10; i++)
133 scene.Update();
134
135 double distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos);
136 Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on first move");
137 Assert.That(npc.AbsolutePosition, Is.EqualTo(targetPos));
138 Assert.That(npc.AgentControlFlags, Is.EqualTo((uint)AgentManager.ControlFlags.NONE));
139
140 // Try a second movement
141 startPos = npc.AbsolutePosition;
142 targetPos = startPos + new Vector3(10, 0, 0);
143 npcModule.MoveToTarget(npc.UUID, scene, targetPos, false, false);
144
145 scene.Update();
146
147 // We should really check the exact figure.
148 Assert.That(npc.AbsolutePosition.X, Is.GreaterThan(startPos.X));
149 Assert.That(npc.AbsolutePosition.X, Is.LessThan(targetPos.X));
150 Assert.That(npc.AbsolutePosition.Y, Is.EqualTo(startPos.Y));
151 Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
152
153 for (int i = 0; i < 10; i++)
154 scene.Update();
155
156 distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos);
157 Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on second move");
158 Assert.That(npc.AbsolutePosition, Is.EqualTo(targetPos));
69 } 159 }
70 } 160 }
71} \ No newline at end of file 161} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs
index 2563361..38c2f7b 100644
--- a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs
+++ b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs
@@ -381,7 +381,6 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator
381 { 381 {
382 SceneObjectPart selectedTree = ((SceneObjectGroup)m_scene.Entities[tree]).RootPart; 382 SceneObjectPart selectedTree = ((SceneObjectGroup)m_scene.Entities[tree]).RootPart;
383 383
384
385 m_scene.DeleteSceneObject(selectedTree.ParentGroup, false); 384 m_scene.DeleteSceneObject(selectedTree.ParentGroup, false);
386 m_scene.ForEachClient(delegate(IClientAPI controller) 385 m_scene.ForEachClient(delegate(IClientAPI controller)
387 { 386 {
diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs
index 6c9d9ab..1ceed1a 100644
--- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs
+++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs
@@ -123,11 +123,15 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
123 actorPosition.X = ((int)Constants.RegionSize - 0.1f); 123 actorPosition.X = ((int)Constants.RegionSize - 0.1f);
124 } 124 }
125 125
126 float height = _heightMap[(int)actor.Position.Y * Constants.RegionSize + (int)actor.Position.X] + actor.Size.Z; 126 float terrainHeight = 0;
127 if (_heightMap != null)
128 terrainHeight = _heightMap[(int)actor.Position.Y * Constants.RegionSize + (int)actor.Position.X];
129
130 float height = terrainHeight + actor.Size.Z;
131
127 if (actor.Flying) 132 if (actor.Flying)
128 { 133 {
129 if (actor.Position.Z + (actor.Velocity.Z*timeStep) < 134 if (actor.Position.Z + (actor.Velocity.Z * timeStep) < terrainHeight + 2)
130 _heightMap[(int)actor.Position.Y * Constants.RegionSize + (int)actor.Position.X] + 2)
131 { 135 {
132 actorPosition.Z = height; 136 actorPosition.Z = height;
133 actorVelocity.Z = 0; 137 actorVelocity.Z = 0;
@@ -135,7 +139,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
135 } 139 }
136 else 140 else
137 { 141 {
138 actorPosition.Z += actor.Velocity.Z*timeStep; 142 actorPosition.Z += actor.Velocity.Z * timeStep;
139 actor.IsColliding = false; 143 actor.IsColliding = false;
140 } 144 }
141 } 145 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
new file mode 100644
index 0000000..682eb80
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -0,0 +1,451 @@
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.Reflection;
30using log4net;
31using OpenMetaverse;
32using OpenSim.Framework;
33using OpenSim.Region.Physics.Manager;
34
35namespace OpenSim.Region.Physics.BulletSPlugin
36{
37public class BSCharacter : PhysicsActor
38{
39 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
40 private static readonly string LogHeader = "[BULLETS CHAR]";
41
42 private BSScene _scene;
43 private String _avName;
44 private bool _stopped;
45 private Vector3 _size;
46 private Vector3 _scale;
47 private PrimitiveBaseShape _pbs;
48 private uint _localID = 0;
49 private bool _grabbed;
50 private bool _selected;
51 private Vector3 _position;
52 private float _mass;
53 public float _density;
54 public float _avatarVolume;
55 private Vector3 _force;
56 private Vector3 _velocity;
57 private Vector3 _torque;
58 private float _collisionScore;
59 private Vector3 _acceleration;
60 private Quaternion _orientation;
61 private int _physicsActorType;
62 private bool _isPhysical;
63 private bool _flying;
64 private bool _setAlwaysRun;
65 private bool _throttleUpdates;
66 private bool _isColliding;
67 private long _collidingStep;
68 private bool _collidingGround;
69 private long _collidingGroundStep;
70 private bool _collidingObj;
71 private bool _floatOnWater;
72 private Vector3 _rotationalVelocity;
73 private bool _kinematic;
74 private float _buoyancy;
75
76 private int _subscribedEventsMs = 0;
77 private int _lastCollisionTime = 0;
78
79 private Vector3 _PIDTarget;
80 private bool _usePID;
81 private float _PIDTau;
82 private bool _useHoverPID;
83 private float _PIDHoverHeight;
84 private PIDHoverType _PIDHoverType;
85 private float _PIDHoverTao;
86
87 public BSCharacter(uint localID, String avName, BSScene parent_scene, Vector3 pos, Vector3 size, bool isFlying)
88 {
89 _localID = localID;
90 _avName = avName;
91 _scene = parent_scene;
92 _position = pos;
93 _size = size;
94 _flying = isFlying;
95 _orientation = Quaternion.Identity;
96 _velocity = Vector3.Zero;
97 _buoyancy = isFlying ? 1f : 0f;
98 _scale = new Vector3(1f, 1f, 1f);
99 _density = _scene.Params.avatarDensity;
100 ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale
101
102 ShapeData shapeData = new ShapeData();
103 shapeData.ID = _localID;
104 shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR;
105 shapeData.Position = _position;
106 shapeData.Rotation = _orientation;
107 shapeData.Velocity = _velocity;
108 shapeData.Scale = _scale;
109 shapeData.Mass = _mass;
110 shapeData.Buoyancy = _buoyancy;
111 shapeData.Static = ShapeData.numericFalse;
112 shapeData.Friction = _scene.Params.avatarFriction;
113 shapeData.Restitution = _scene.Params.defaultRestitution;
114
115 // do actual create at taint time
116 _scene.TaintedObject(delegate()
117 {
118 BulletSimAPI.CreateObject(parent_scene.WorldID, shapeData);
119 });
120
121 return;
122 }
123
124 // called when this character is being destroyed and the resources should be released
125 public void Destroy()
126 {
127 _scene.TaintedObject(delegate()
128 {
129 BulletSimAPI.DestroyObject(_scene.WorldID, _localID);
130 });
131 }
132
133 public override void RequestPhysicsterseUpdate()
134 {
135 base.RequestPhysicsterseUpdate();
136 }
137
138 public override bool Stopped {
139 get { return _stopped; }
140 }
141 public override Vector3 Size {
142 get { return _size; }
143 set { _size = value;
144 }
145 }
146 public override PrimitiveBaseShape Shape {
147 set { _pbs = value;
148 }
149 }
150 public override uint LocalID {
151 set { _localID = value;
152 }
153 get { return _localID; }
154 }
155 public override bool Grabbed {
156 set { _grabbed = value;
157 }
158 }
159 public override bool Selected {
160 set { _selected = value;
161 }
162 }
163 public override void CrossingFailure() { return; }
164 public override void link(PhysicsActor obj) { return; }
165 public override void delink() { return; }
166 public override void LockAngularMotion(Vector3 axis) { return; }
167
168 public override Vector3 Position {
169 get {
170 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
171 return _position;
172 }
173 set {
174 _position = value;
175 _scene.TaintedObject(delegate()
176 {
177 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
178 });
179 }
180 }
181 public override float Mass {
182 get {
183 return _mass;
184 }
185 }
186 public override Vector3 Force {
187 get { return _force; }
188 set {
189 _force = value;
190 // m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force);
191 _scene.TaintedObject(delegate()
192 {
193 BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
194 });
195 }
196 }
197
198 public override int VehicleType {
199 get { return 0; }
200 set { return; }
201 }
202 public override void VehicleFloatParam(int param, float value) { }
203 public override void VehicleVectorParam(int param, Vector3 value) {}
204 public override void VehicleRotationParam(int param, Quaternion rotation) { }
205 public override void VehicleFlags(int param, bool remove) { }
206
207 // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more
208 public override void SetVolumeDetect(int param) { return; }
209
210 public override Vector3 GeometricCenter { get { return Vector3.Zero; } }
211 public override Vector3 CenterOfMass { get { return Vector3.Zero; } }
212 public override Vector3 Velocity {
213 get { return _velocity; }
214 set {
215 _velocity = value;
216 // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity);
217 _scene.TaintedObject(delegate()
218 {
219 BulletSimAPI.SetObjectVelocity(_scene.WorldID, _localID, _velocity);
220 });
221 }
222 }
223 public override Vector3 Torque {
224 get { return _torque; }
225 set { _torque = value;
226 }
227 }
228 public override float CollisionScore {
229 get { return _collisionScore; }
230 set { _collisionScore = value;
231 }
232 }
233 public override Vector3 Acceleration {
234 get { return _acceleration; }
235 }
236 public override Quaternion Orientation {
237 get { return _orientation; }
238 set {
239 _orientation = value;
240 // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation);
241 _scene.TaintedObject(delegate()
242 {
243 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
244 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
245 });
246 }
247 }
248 public override int PhysicsActorType {
249 get { return _physicsActorType; }
250 set { _physicsActorType = value;
251 }
252 }
253 public override bool IsPhysical {
254 get { return _isPhysical; }
255 set { _isPhysical = value;
256 }
257 }
258 public override bool Flying {
259 get { return _flying; }
260 set {
261 _flying = value;
262 _scene.TaintedObject(delegate()
263 {
264 // simulate flying by changing the effect of gravity
265 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _flying ? 1f : 0f);
266 });
267 }
268 }
269 public override bool
270 SetAlwaysRun {
271 get { return _setAlwaysRun; }
272 set { _setAlwaysRun = value; }
273 }
274 public override bool ThrottleUpdates {
275 get { return _throttleUpdates; }
276 set { _throttleUpdates = value; }
277 }
278 public override bool IsColliding {
279 get { return (_collidingStep == _scene.SimulationStep); }
280 set { _isColliding = value; }
281 }
282 public override bool CollidingGround {
283 get { return (_collidingGroundStep == _scene.SimulationStep); }
284 set { _collidingGround = value; }
285 }
286 public override bool CollidingObj {
287 get { return _collidingObj; }
288 set { _collidingObj = value; }
289 }
290 public override bool FloatOnWater {
291 set { _floatOnWater = value; }
292 }
293 public override Vector3 RotationalVelocity {
294 get { return _rotationalVelocity; }
295 set { _rotationalVelocity = value; }
296 }
297 public override bool Kinematic {
298 get { return _kinematic; }
299 set { _kinematic = value; }
300 }
301 public override float Buoyancy {
302 get { return _buoyancy; }
303 set { _buoyancy = value;
304 _scene.TaintedObject(delegate()
305 {
306 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy);
307 });
308 }
309 }
310
311 // Used for MoveTo
312 public override Vector3 PIDTarget {
313 set { _PIDTarget = value; }
314 }
315 public override bool PIDActive {
316 set { _usePID = value; }
317 }
318 public override float PIDTau {
319 set { _PIDTau = value; }
320 }
321
322 // Used for llSetHoverHeight and maybe vehicle height
323 // Hover Height will override MoveTo target's Z
324 public override bool PIDHoverActive {
325 set { _useHoverPID = value; }
326 }
327 public override float PIDHoverHeight {
328 set { _PIDHoverHeight = value; }
329 }
330 public override PIDHoverType PIDHoverType {
331 set { _PIDHoverType = value; }
332 }
333 public override float PIDHoverTau {
334 set { _PIDHoverTao = value; }
335 }
336
337 // For RotLookAt
338 public override Quaternion APIDTarget { set { return; } }
339 public override bool APIDActive { set { return; } }
340 public override float APIDStrength { set { return; } }
341 public override float APIDDamping { set { return; } }
342
343 public override void AddForce(Vector3 force, bool pushforce) {
344 if (force.IsFinite())
345 {
346 _force.X += force.X;
347 _force.Y += force.Y;
348 _force.Z += force.Z;
349 // m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force);
350 _scene.TaintedObject(delegate()
351 {
352 BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
353 });
354 }
355 else
356 {
357 m_log.WarnFormat("{0}: Got a NaN force applied to a Character", LogHeader);
358 }
359 //m_lastUpdateSent = false;
360 }
361 public override void AddAngularForce(Vector3 force, bool pushforce) {
362 }
363 public override void SetMomentum(Vector3 momentum) {
364 }
365 public override void SubscribeEvents(int ms) {
366 _subscribedEventsMs = ms;
367 _lastCollisionTime = Util.EnvironmentTickCount() - _subscribedEventsMs; // make first collision happen
368 }
369 public override void UnSubscribeEvents() {
370 _subscribedEventsMs = 0;
371 }
372 public override bool SubscribedEvents() {
373 return (_subscribedEventsMs > 0);
374 }
375
376 // set _avatarVolume and _mass based on capsule size, _density and _scale
377 private void ComputeAvatarVolumeAndMass()
378 {
379 _avatarVolume = (float)(
380 Math.PI
381 * _scene.Params.avatarCapsuleRadius * _scale.X
382 * _scene.Params.avatarCapsuleRadius * _scale.Y
383 * _scene.Params.avatarCapsuleHeight * _scale.Z);
384 _mass = _density * _avatarVolume;
385 }
386
387 // The physics engine says that properties have updated. Update same and inform
388 // the world that things have changed.
389 public void UpdateProperties(EntityProperties entprop)
390 {
391 bool changed = false;
392 // we assign to the local variables so the normal set action does not happen
393 if (_position != entprop.Position)
394 {
395 _position = entprop.Position;
396 changed = true;
397 }
398 if (_orientation != entprop.Rotation)
399 {
400 _orientation = entprop.Rotation;
401 changed = true;
402 }
403 if (_velocity != entprop.Velocity)
404 {
405 _velocity = entprop.Velocity;
406 changed = true;
407 }
408 if (_acceleration != entprop.Acceleration)
409 {
410 _acceleration = entprop.Acceleration;
411 changed = true;
412 }
413 if (_rotationalVelocity != entprop.RotationalVelocity)
414 {
415 _rotationalVelocity = entprop.RotationalVelocity;
416 changed = true;
417 }
418 if (changed)
419 {
420 // m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation);
421 // Avatar movement is not done by generating this event. There is a system that
422 // checks for avatar updates each heartbeat loop.
423 // base.RequestPhysicsterseUpdate();
424 }
425 }
426
427 public void Collide(uint collidingWith, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth)
428 {
429 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);
430
431 // The following makes IsColliding() and IsCollidingGround() work
432 _collidingStep = _scene.SimulationStep;
433 if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID)
434 {
435 _collidingGroundStep = _scene.SimulationStep;
436 }
437
438 // throttle collisions to the rate specified in the subscription
439 if (_subscribedEventsMs == 0) return; // don't want collisions
440 int nowTime = _scene.SimulationNowTime;
441 if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return;
442 _lastCollisionTime = nowTime;
443
444 Dictionary<uint, ContactPoint> contactPoints = new Dictionary<uint, ContactPoint>();
445 contactPoints.Add(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
446 CollisionEventUpdate args = new CollisionEventUpdate(LocalID, (int)type, 1, contactPoints);
447 base.SendCollisionUpdate(args);
448 }
449
450}
451}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
new file mode 100644
index 0000000..046726d
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -0,0 +1,951 @@
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
28/* RA: June 14, 2011. Copied from ODEDynamics.cs and converted to
29 * call the BulletSim system.
30 */
31/* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces
32 * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised:
33 * ODEPrim.cs contains methods dealing with Prim editing, Prim
34 * characteristics and Kinetic motion.
35 * ODEDynamics.cs contains methods dealing with Prim Physical motion
36 * (dynamics) and the associated settings. Old Linear and angular
37 * motors for dynamic motion have been replace with MoveLinear()
38 * and MoveAngular(); 'Physical' is used only to switch ODE dynamic
39 * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
40 * switch between 'VEHICLE' parameter use and general dynamics
41 * settings use.
42 */
43
44using System;
45using System.Collections.Generic;
46using System.Reflection;
47using System.Runtime.InteropServices;
48using log4net;
49using OpenMetaverse;
50using OpenSim.Framework;
51using OpenSim.Region.Physics.Manager;
52
53namespace OpenSim.Region.Physics.BulletSPlugin
54{
55 public class BSDynamics
56 {
57 private int frcount = 0; // Used to limit dynamics debug output to
58 // every 100th frame
59
60 // private BSScene m_parentScene = null;
61 private BSPrim m_prim; // the prim this dynamic controller belongs to
62
63 // Vehicle properties
64 private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind
65 public Vehicle Type
66 {
67 get { return m_type; }
68 }
69 // private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier
70 private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings:
71 // HOVER_TERRAIN_ONLY
72 // HOVER_GLOBAL_HEIGHT
73 // NO_DEFLECTION_UP
74 // HOVER_WATER_ONLY
75 // HOVER_UP_ONLY
76 // LIMIT_MOTOR_UP
77 // LIMIT_ROLL_ONLY
78 private VehicleFlag m_Hoverflags = (VehicleFlag)0;
79 private Vector3 m_BlockingEndPoint = Vector3.Zero;
80 private Quaternion m_RollreferenceFrame = Quaternion.Identity;
81 // Linear properties
82 private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time
83 private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL
84 private Vector3 m_dir = Vector3.Zero; // velocity applied to body
85 private Vector3 m_linearFrictionTimescale = Vector3.Zero;
86 private float m_linearMotorDecayTimescale = 0;
87 private float m_linearMotorTimescale = 0;
88 private Vector3 m_lastLinearVelocityVector = Vector3.Zero;
89 private Vector3 m_lastPositionVector = Vector3.Zero;
90 // private bool m_LinearMotorSetLastFrame = false;
91 // private Vector3 m_linearMotorOffset = Vector3.Zero;
92
93 //Angular properties
94 private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor
95 private int m_angularMotorApply = 0; // application frame counter
96 private Vector3 m_angularMotorVelocity = Vector3.Zero; // current angular motor velocity
97 private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate
98 private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate
99 private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate
100 private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body
101 // private Vector3 m_lastVertAttractor = Vector3.Zero; // what VA was last applied to body
102
103 //Deflection properties
104 // private float m_angularDeflectionEfficiency = 0;
105 // private float m_angularDeflectionTimescale = 0;
106 // private float m_linearDeflectionEfficiency = 0;
107 // private float m_linearDeflectionTimescale = 0;
108
109 //Banking properties
110 // private float m_bankingEfficiency = 0;
111 // private float m_bankingMix = 0;
112 // private float m_bankingTimescale = 0;
113
114 //Hover and Buoyancy properties
115 private float m_VhoverHeight = 0f;
116// private float m_VhoverEfficiency = 0f;
117 private float m_VhoverTimescale = 0f;
118 private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height
119 private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle.
120 // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity)
121 // KF: So far I have found no good method to combine a script-requested .Z velocity and gravity.
122 // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity.
123
124 //Attractor properties
125 private float m_verticalAttractionEfficiency = 1.0f; // damped
126 private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor.
127
128 public BSDynamics(BSPrim myPrim)
129 {
130 m_prim = myPrim;
131 m_type = Vehicle.TYPE_NONE;
132 }
133
134 internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
135 {
136 switch (pParam)
137 {
138 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
139 if (pValue < 0.01f) pValue = 0.01f;
140 // m_angularDeflectionEfficiency = pValue;
141 break;
142 case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
143 if (pValue < 0.01f) pValue = 0.01f;
144 // m_angularDeflectionTimescale = pValue;
145 break;
146 case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
147 if (pValue < 0.01f) pValue = 0.01f;
148 m_angularMotorDecayTimescale = pValue;
149 break;
150 case Vehicle.ANGULAR_MOTOR_TIMESCALE:
151 if (pValue < 0.01f) pValue = 0.01f;
152 m_angularMotorTimescale = pValue;
153 break;
154 case Vehicle.BANKING_EFFICIENCY:
155 if (pValue < 0.01f) pValue = 0.01f;
156 // m_bankingEfficiency = pValue;
157 break;
158 case Vehicle.BANKING_MIX:
159 if (pValue < 0.01f) pValue = 0.01f;
160 // m_bankingMix = pValue;
161 break;
162 case Vehicle.BANKING_TIMESCALE:
163 if (pValue < 0.01f) pValue = 0.01f;
164 // m_bankingTimescale = pValue;
165 break;
166 case Vehicle.BUOYANCY:
167 if (pValue < -1f) pValue = -1f;
168 if (pValue > 1f) pValue = 1f;
169 m_VehicleBuoyancy = pValue;
170 break;
171// case Vehicle.HOVER_EFFICIENCY:
172// if (pValue < 0f) pValue = 0f;
173// if (pValue > 1f) pValue = 1f;
174// m_VhoverEfficiency = pValue;
175// break;
176 case Vehicle.HOVER_HEIGHT:
177 m_VhoverHeight = pValue;
178 break;
179 case Vehicle.HOVER_TIMESCALE:
180 if (pValue < 0.01f) pValue = 0.01f;
181 m_VhoverTimescale = pValue;
182 break;
183 case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
184 if (pValue < 0.01f) pValue = 0.01f;
185 // m_linearDeflectionEfficiency = pValue;
186 break;
187 case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
188 if (pValue < 0.01f) pValue = 0.01f;
189 // m_linearDeflectionTimescale = pValue;
190 break;
191 case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
192 if (pValue < 0.01f) pValue = 0.01f;
193 m_linearMotorDecayTimescale = pValue;
194 break;
195 case Vehicle.LINEAR_MOTOR_TIMESCALE:
196 if (pValue < 0.01f) pValue = 0.01f;
197 m_linearMotorTimescale = pValue;
198 break;
199 case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
200 if (pValue < 0.1f) pValue = 0.1f; // Less goes unstable
201 if (pValue > 1.0f) pValue = 1.0f;
202 m_verticalAttractionEfficiency = pValue;
203 break;
204 case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
205 if (pValue < 0.01f) pValue = 0.01f;
206 m_verticalAttractionTimescale = pValue;
207 break;
208
209 // These are vector properties but the engine lets you use a single float value to
210 // set all of the components to the same value
211 case Vehicle.ANGULAR_FRICTION_TIMESCALE:
212 m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
213 break;
214 case Vehicle.ANGULAR_MOTOR_DIRECTION:
215 m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
216 m_angularMotorApply = 10;
217 break;
218 case Vehicle.LINEAR_FRICTION_TIMESCALE:
219 m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
220 break;
221 case Vehicle.LINEAR_MOTOR_DIRECTION:
222 m_linearMotorDirection = new Vector3(pValue, pValue, pValue);
223 m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue);
224 break;
225 case Vehicle.LINEAR_MOTOR_OFFSET:
226 // m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
227 break;
228
229 }
230 }//end ProcessFloatVehicleParam
231
232 internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue)
233 {
234 switch (pParam)
235 {
236 case Vehicle.ANGULAR_FRICTION_TIMESCALE:
237 m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
238 break;
239 case Vehicle.ANGULAR_MOTOR_DIRECTION:
240 m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
241 // Limit requested angular speed to 2 rps= 4 pi rads/sec
242 if (m_angularMotorDirection.X > 12.56f) m_angularMotorDirection.X = 12.56f;
243 if (m_angularMotorDirection.X < - 12.56f) m_angularMotorDirection.X = - 12.56f;
244 if (m_angularMotorDirection.Y > 12.56f) m_angularMotorDirection.Y = 12.56f;
245 if (m_angularMotorDirection.Y < - 12.56f) m_angularMotorDirection.Y = - 12.56f;
246 if (m_angularMotorDirection.Z > 12.56f) m_angularMotorDirection.Z = 12.56f;
247 if (m_angularMotorDirection.Z < - 12.56f) m_angularMotorDirection.Z = - 12.56f;
248 m_angularMotorApply = 10;
249 break;
250 case Vehicle.LINEAR_FRICTION_TIMESCALE:
251 m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
252 break;
253 case Vehicle.LINEAR_MOTOR_DIRECTION:
254 m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
255 m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z);
256 break;
257 case Vehicle.LINEAR_MOTOR_OFFSET:
258 // m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
259 break;
260 case Vehicle.BLOCK_EXIT:
261 m_BlockingEndPoint = new Vector3(pValue.X, pValue.Y, pValue.Z);
262 break;
263 }
264 }//end ProcessVectorVehicleParam
265
266 internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
267 {
268 switch (pParam)
269 {
270 case Vehicle.REFERENCE_FRAME:
271 // m_referenceFrame = pValue;
272 break;
273 case Vehicle.ROLL_FRAME:
274 m_RollreferenceFrame = pValue;
275 break;
276 }
277 }//end ProcessRotationVehicleParam
278
279 internal void ProcessVehicleFlags(int pParam, bool remove)
280 {
281 if (remove)
282 {
283 if (pParam == -1)
284 {
285 m_flags = (VehicleFlag)0;
286 m_Hoverflags = (VehicleFlag)0;
287 return;
288 }
289 if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT)
290 {
291 if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != (VehicleFlag)0)
292 m_Hoverflags &= ~(VehicleFlag.HOVER_GLOBAL_HEIGHT);
293 }
294 if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY)
295 {
296 if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != (VehicleFlag)0)
297 m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY);
298 }
299 if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY)
300 {
301 if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != (VehicleFlag)0)
302 m_Hoverflags &= ~(VehicleFlag.HOVER_UP_ONLY);
303 }
304 if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY)
305 {
306 if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != (VehicleFlag)0)
307 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY);
308 }
309 if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP)
310 {
311 if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != (VehicleFlag)0)
312 m_flags &= ~(VehicleFlag.LIMIT_MOTOR_UP);
313 }
314 if ((pParam & (int)VehicleFlag.LIMIT_ROLL_ONLY) == (int)VehicleFlag.LIMIT_ROLL_ONLY)
315 {
316 if ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) != (VehicleFlag)0)
317 m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY);
318 }
319 if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK)
320 {
321 if ((m_flags & VehicleFlag.MOUSELOOK_BANK) != (VehicleFlag)0)
322 m_flags &= ~(VehicleFlag.MOUSELOOK_BANK);
323 }
324 if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER)
325 {
326 if ((m_flags & VehicleFlag.MOUSELOOK_STEER) != (VehicleFlag)0)
327 m_flags &= ~(VehicleFlag.MOUSELOOK_STEER);
328 }
329 if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP)
330 {
331 if ((m_flags & VehicleFlag.NO_DEFLECTION_UP) != (VehicleFlag)0)
332 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP);
333 }
334 if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED)
335 {
336 if ((m_flags & VehicleFlag.CAMERA_DECOUPLED) != (VehicleFlag)0)
337 m_flags &= ~(VehicleFlag.CAMERA_DECOUPLED);
338 }
339 if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X)
340 {
341 if ((m_flags & VehicleFlag.NO_X) != (VehicleFlag)0)
342 m_flags &= ~(VehicleFlag.NO_X);
343 }
344 if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y)
345 {
346 if ((m_flags & VehicleFlag.NO_Y) != (VehicleFlag)0)
347 m_flags &= ~(VehicleFlag.NO_Y);
348 }
349 if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z)
350 {
351 if ((m_flags & VehicleFlag.NO_Z) != (VehicleFlag)0)
352 m_flags &= ~(VehicleFlag.NO_Z);
353 }
354 if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT)
355 {
356 if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != (VehicleFlag)0)
357 m_Hoverflags &= ~(VehicleFlag.LOCK_HOVER_HEIGHT);
358 }
359 if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION)
360 {
361 if ((m_flags & VehicleFlag.NO_DEFLECTION) != (VehicleFlag)0)
362 m_flags &= ~(VehicleFlag.NO_DEFLECTION);
363 }
364 if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION)
365 {
366 if ((m_flags & VehicleFlag.LOCK_ROTATION) != (VehicleFlag)0)
367 m_flags &= ~(VehicleFlag.LOCK_ROTATION);
368 }
369 }
370 else
371 {
372 if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT)
373 {
374 m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT | m_flags);
375 }
376 if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY)
377 {
378 m_Hoverflags |= (VehicleFlag.HOVER_TERRAIN_ONLY | m_flags);
379 }
380 if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY)
381 {
382 m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY | m_flags);
383 }
384 if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY)
385 {
386 m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY | m_flags);
387 }
388 if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP)
389 {
390 m_flags |= (VehicleFlag.LIMIT_MOTOR_UP | m_flags);
391 }
392 if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK)
393 {
394 m_flags |= (VehicleFlag.MOUSELOOK_BANK | m_flags);
395 }
396 if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER)
397 {
398 m_flags |= (VehicleFlag.MOUSELOOK_STEER | m_flags);
399 }
400 if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP)
401 {
402 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | m_flags);
403 }
404 if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED)
405 {
406 m_flags |= (VehicleFlag.CAMERA_DECOUPLED | m_flags);
407 }
408 if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X)
409 {
410 m_flags |= (VehicleFlag.NO_X);
411 }
412 if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y)
413 {
414 m_flags |= (VehicleFlag.NO_Y);
415 }
416 if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z)
417 {
418 m_flags |= (VehicleFlag.NO_Z);
419 }
420 if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT)
421 {
422 m_Hoverflags |= (VehicleFlag.LOCK_HOVER_HEIGHT);
423 }
424 if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION)
425 {
426 m_flags |= (VehicleFlag.NO_DEFLECTION);
427 }
428 if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION)
429 {
430 m_flags |= (VehicleFlag.LOCK_ROTATION);
431 }
432 }
433 }//end ProcessVehicleFlags
434
435 internal void ProcessTypeChange(Vehicle pType)
436 {
437 // Set Defaults For Type
438 m_type = pType;
439 switch (pType)
440 {
441 case Vehicle.TYPE_NONE:
442 m_linearFrictionTimescale = new Vector3(0, 0, 0);
443 m_angularFrictionTimescale = new Vector3(0, 0, 0);
444 m_linearMotorDirection = Vector3.Zero;
445 m_linearMotorTimescale = 0;
446 m_linearMotorDecayTimescale = 0;
447 m_angularMotorDirection = Vector3.Zero;
448 m_angularMotorTimescale = 0;
449 m_angularMotorDecayTimescale = 0;
450 m_VhoverHeight = 0;
451 m_VhoverTimescale = 0;
452 m_VehicleBuoyancy = 0;
453 m_flags = (VehicleFlag)0;
454 break;
455
456 case Vehicle.TYPE_SLED:
457 m_linearFrictionTimescale = new Vector3(30, 1, 1000);
458 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
459 m_linearMotorDirection = Vector3.Zero;
460 m_linearMotorTimescale = 1000;
461 m_linearMotorDecayTimescale = 120;
462 m_angularMotorDirection = Vector3.Zero;
463 m_angularMotorTimescale = 1000;
464 m_angularMotorDecayTimescale = 120;
465 m_VhoverHeight = 0;
466// m_VhoverEfficiency = 1;
467 m_VhoverTimescale = 10;
468 m_VehicleBuoyancy = 0;
469 // m_linearDeflectionEfficiency = 1;
470 // m_linearDeflectionTimescale = 1;
471 // m_angularDeflectionEfficiency = 1;
472 // m_angularDeflectionTimescale = 1000;
473 // m_bankingEfficiency = 0;
474 // m_bankingMix = 1;
475 // m_bankingTimescale = 10;
476 // m_referenceFrame = Quaternion.Identity;
477 m_Hoverflags &=
478 ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
479 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
480 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
481 break;
482 case Vehicle.TYPE_CAR:
483 m_linearFrictionTimescale = new Vector3(100, 2, 1000);
484 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
485 m_linearMotorDirection = Vector3.Zero;
486 m_linearMotorTimescale = 1;
487 m_linearMotorDecayTimescale = 60;
488 m_angularMotorDirection = Vector3.Zero;
489 m_angularMotorTimescale = 1;
490 m_angularMotorDecayTimescale = 0.8f;
491 m_VhoverHeight = 0;
492// m_VhoverEfficiency = 0;
493 m_VhoverTimescale = 1000;
494 m_VehicleBuoyancy = 0;
495 // // m_linearDeflectionEfficiency = 1;
496 // // m_linearDeflectionTimescale = 2;
497 // // m_angularDeflectionEfficiency = 0;
498 // m_angularDeflectionTimescale = 10;
499 m_verticalAttractionEfficiency = 1f;
500 m_verticalAttractionTimescale = 10f;
501 // m_bankingEfficiency = -0.2f;
502 // m_bankingMix = 1;
503 // m_bankingTimescale = 1;
504 // m_referenceFrame = Quaternion.Identity;
505 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
506 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY |
507 VehicleFlag.LIMIT_MOTOR_UP);
508 m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY);
509 break;
510 case Vehicle.TYPE_BOAT:
511 m_linearFrictionTimescale = new Vector3(10, 3, 2);
512 m_angularFrictionTimescale = new Vector3(10,10,10);
513 m_linearMotorDirection = Vector3.Zero;
514 m_linearMotorTimescale = 5;
515 m_linearMotorDecayTimescale = 60;
516 m_angularMotorDirection = Vector3.Zero;
517 m_angularMotorTimescale = 4;
518 m_angularMotorDecayTimescale = 4;
519 m_VhoverHeight = 0;
520// m_VhoverEfficiency = 0.5f;
521 m_VhoverTimescale = 2;
522 m_VehicleBuoyancy = 1;
523 // m_linearDeflectionEfficiency = 0.5f;
524 // m_linearDeflectionTimescale = 3;
525 // m_angularDeflectionEfficiency = 0.5f;
526 // m_angularDeflectionTimescale = 5;
527 m_verticalAttractionEfficiency = 0.5f;
528 m_verticalAttractionTimescale = 5f;
529 // m_bankingEfficiency = -0.3f;
530 // m_bankingMix = 0.8f;
531 // m_bankingTimescale = 1;
532 // m_referenceFrame = Quaternion.Identity;
533 m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY |
534 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
535 m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY);
536 m_flags |= (VehicleFlag.NO_DEFLECTION_UP |
537 VehicleFlag.LIMIT_MOTOR_UP);
538 m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY);
539 break;
540 case Vehicle.TYPE_AIRPLANE:
541 m_linearFrictionTimescale = new Vector3(200, 10, 5);
542 m_angularFrictionTimescale = new Vector3(20, 20, 20);
543 m_linearMotorDirection = Vector3.Zero;
544 m_linearMotorTimescale = 2;
545 m_linearMotorDecayTimescale = 60;
546 m_angularMotorDirection = Vector3.Zero;
547 m_angularMotorTimescale = 4;
548 m_angularMotorDecayTimescale = 4;
549 m_VhoverHeight = 0;
550// m_VhoverEfficiency = 0.5f;
551 m_VhoverTimescale = 1000;
552 m_VehicleBuoyancy = 0;
553 // m_linearDeflectionEfficiency = 0.5f;
554 // m_linearDeflectionTimescale = 3;
555 // m_angularDeflectionEfficiency = 1;
556 // m_angularDeflectionTimescale = 2;
557 m_verticalAttractionEfficiency = 0.9f;
558 m_verticalAttractionTimescale = 2f;
559 // m_bankingEfficiency = 1;
560 // m_bankingMix = 0.7f;
561 // m_bankingTimescale = 2;
562 // m_referenceFrame = Quaternion.Identity;
563 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
564 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
565 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP);
566 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
567 break;
568 case Vehicle.TYPE_BALLOON:
569 m_linearFrictionTimescale = new Vector3(5, 5, 5);
570 m_angularFrictionTimescale = new Vector3(10, 10, 10);
571 m_linearMotorDirection = Vector3.Zero;
572 m_linearMotorTimescale = 5;
573 m_linearMotorDecayTimescale = 60;
574 m_angularMotorDirection = Vector3.Zero;
575 m_angularMotorTimescale = 6;
576 m_angularMotorDecayTimescale = 10;
577 m_VhoverHeight = 5;
578// m_VhoverEfficiency = 0.8f;
579 m_VhoverTimescale = 10;
580 m_VehicleBuoyancy = 1;
581 // m_linearDeflectionEfficiency = 0;
582 // m_linearDeflectionTimescale = 5;
583 // m_angularDeflectionEfficiency = 0;
584 // m_angularDeflectionTimescale = 5;
585 m_verticalAttractionEfficiency = 1f;
586 m_verticalAttractionTimescale = 100f;
587 // m_bankingEfficiency = 0;
588 // m_bankingMix = 0.7f;
589 // m_bankingTimescale = 5;
590 // m_referenceFrame = Quaternion.Identity;
591 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
592 VehicleFlag.HOVER_UP_ONLY);
593 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP);
594 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
595 m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT);
596 break;
597
598 }
599 }//end SetDefaultsForType
600
601 internal void Step(float pTimestep, BSScene pParentScene)
602 {
603 if (m_type == Vehicle.TYPE_NONE) return;
604
605 frcount++; // used to limit debug comment output
606 if (frcount > 100)
607 frcount = 0;
608
609 MoveLinear(pTimestep, pParentScene);
610 MoveAngular(pTimestep);
611 LimitRotation(pTimestep);
612 }// end Step
613
614 private void MoveLinear(float pTimestep, BSScene _pParentScene)
615 {
616 if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) // requested m_linearMotorDirection is significant
617 {
618 // add drive to body
619 Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep);
620 m_lastLinearVelocityVector += (addAmount*10); // lastLinearVelocityVector is the current body velocity vector?
621
622 // This will work temporarily, but we really need to compare speed on an axis
623 // KF: Limit body velocity to applied velocity?
624 if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X))
625 m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X;
626 if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y))
627 m_lastLinearVelocityVector.Y = m_linearMotorDirectionLASTSET.Y;
628 if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z))
629 m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z;
630
631 // decay applied velocity
632 Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep)));
633 //Console.WriteLine("decay: " + decayfraction);
634 m_linearMotorDirection -= m_linearMotorDirection * decayfraction * 0.5f;
635 //Console.WriteLine("actual: " + m_linearMotorDirection);
636 }
637 else
638 { // requested is not significant
639 // if what remains of applied is small, zero it.
640 if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f))
641 m_lastLinearVelocityVector = Vector3.Zero;
642 }
643
644 // convert requested object velocity to world-referenced vector
645 m_dir = m_lastLinearVelocityVector;
646 Quaternion rot = m_prim.Orientation;
647 Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object
648 m_dir *= rotq; // apply obj rotation to velocity vector
649
650 // add Gravity andBuoyancy
651 // KF: So far I have found no good method to combine a script-requested
652 // .Z velocity and gravity. Therefore only 0g will used script-requested
653 // .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only.
654 Vector3 grav = Vector3.Zero;
655 // There is some gravity, make a gravity force vector
656 // that is applied after object velocity.
657 float objMass = m_prim.Mass;
658 // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
659 grav.Z = _pParentScene.DefaultGravity.Z * objMass * (1f - m_VehicleBuoyancy);
660 // Preserve the current Z velocity
661 Vector3 vel_now = m_prim.Velocity;
662 m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity
663
664 Vector3 pos = m_prim.Position;
665// Vector3 accel = new Vector3(-(m_dir.X - m_lastLinearVelocityVector.X / 0.1f), -(m_dir.Y - m_lastLinearVelocityVector.Y / 0.1f), m_dir.Z - m_lastLinearVelocityVector.Z / 0.1f);
666 Vector3 posChange = new Vector3();
667 posChange.X = pos.X - m_lastPositionVector.X;
668 posChange.Y = pos.Y - m_lastPositionVector.Y;
669 posChange.Z = pos.Z - m_lastPositionVector.Z;
670 double Zchange = Math.Abs(posChange.Z);
671 if (m_BlockingEndPoint != Vector3.Zero)
672 {
673 if (pos.X >= (m_BlockingEndPoint.X - (float)1))
674 {
675 pos.X -= posChange.X + 1;
676 m_prim.Position = pos;
677 }
678 if (pos.Y >= (m_BlockingEndPoint.Y - (float)1))
679 {
680 pos.Y -= posChange.Y + 1;
681 m_prim.Position = pos;
682 }
683 if (pos.Z >= (m_BlockingEndPoint.Z - (float)1))
684 {
685 pos.Z -= posChange.Z + 1;
686 m_prim.Position = pos;
687 }
688 if (pos.X <= 0)
689 {
690 pos.X += posChange.X + 1;
691 m_prim.Position = pos;
692 }
693 if (pos.Y <= 0)
694 {
695 pos.Y += posChange.Y + 1;
696 m_prim.Position = pos;
697 }
698 }
699 if (pos.Z < _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y))
700 {
701 pos.Z = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + 2;
702 m_prim.Position = pos;
703 }
704
705 // Check if hovering
706 if ((m_Hoverflags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
707 {
708 // We should hover, get the target height
709 if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != 0)
710 {
711 m_VhoverTargetHeight = _pParentScene.GetWaterLevel() + m_VhoverHeight;
712 }
713 if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
714 {
715 m_VhoverTargetHeight = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight;
716 }
717 if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0)
718 {
719 m_VhoverTargetHeight = m_VhoverHeight;
720 }
721
722 if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != 0)
723 {
724 // If body is aready heigher, use its height as target height
725 if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z;
726 }
727 if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
728 {
729 if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2)
730 {
731 m_prim.Position = pos;
732 }
733 }
734 else
735 {
736 float herr0 = pos.Z - m_VhoverTargetHeight;
737 // Replace Vertical speed with correction figure if significant
738 if (Math.Abs(herr0) > 0.01f)
739 {
740 m_dir.Z = -((herr0 * pTimestep * 50.0f) / m_VhoverTimescale);
741 //KF: m_VhoverEfficiency is not yet implemented
742 }
743 else
744 {
745 m_dir.Z = 0f;
746 }
747 }
748
749// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped
750// m_VhoverTimescale = 0f; // time to acheive height
751// pTimestep is time since last frame,in secs
752 }
753
754 if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0)
755 {
756 //Start Experimental Values
757 if (Zchange > .3)
758 {
759 grav.Z = (float)(grav.Z * 3);
760 }
761 if (Zchange > .15)
762 {
763 grav.Z = (float)(grav.Z * 2);
764 }
765 if (Zchange > .75)
766 {
767 grav.Z = (float)(grav.Z * 1.5);
768 }
769 if (Zchange > .05)
770 {
771 grav.Z = (float)(grav.Z * 1.25);
772 }
773 if (Zchange > .025)
774 {
775 grav.Z = (float)(grav.Z * 1.125);
776 }
777 float terraintemp = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y);
778 float postemp = (pos.Z - terraintemp);
779 if (postemp > 2.5f)
780 {
781 grav.Z = (float)(grav.Z * 1.037125);
782 }
783 //End Experimental Values
784 }
785 if ((m_flags & (VehicleFlag.NO_X)) != 0)
786 {
787 m_dir.X = 0;
788 }
789 if ((m_flags & (VehicleFlag.NO_Y)) != 0)
790 {
791 m_dir.Y = 0;
792 }
793 if ((m_flags & (VehicleFlag.NO_Z)) != 0)
794 {
795 m_dir.Z = 0;
796 }
797
798 m_lastPositionVector = m_prim.Position;
799
800 // Apply velocity
801 m_prim.Velocity = m_dir;
802 // apply gravity force
803 m_prim.Force = grav;
804
805
806 // apply friction
807 Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep);
808 m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount;
809 } // end MoveLinear()
810
811 private void MoveAngular(float pTimestep)
812 {
813 /*
814 private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor
815 private int m_angularMotorApply = 0; // application frame counter
816 private float m_angularMotorVelocity = 0; // current angular motor velocity (ramps up and down)
817 private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate
818 private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate
819 private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate
820 private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body
821 */
822
823 // Get what the body is doing, this includes 'external' influences
824 Vector3 angularVelocity = m_prim.AngularVelocity;
825 // Vector3 angularVelocity = Vector3.Zero;
826
827 if (m_angularMotorApply > 0)
828 {
829 // ramp up to new value
830 // current velocity += error / (time to get there / step interval)
831 // requested speed - last motor speed
832 m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / pTimestep);
833 m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep);
834 m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep);
835
836 m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected
837 // velocity may still be acheived.
838 }
839 else
840 {
841 // no motor recently applied, keep the body velocity
842 /* m_angularMotorVelocity.X = angularVelocity.X;
843 m_angularMotorVelocity.Y = angularVelocity.Y;
844 m_angularMotorVelocity.Z = angularVelocity.Z; */
845
846 // and decay the velocity
847 m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep);
848 } // end motor section
849
850 // Vertical attractor section
851 Vector3 vertattr = Vector3.Zero;
852
853 if (m_verticalAttractionTimescale < 300)
854 {
855 float VAservo = 0.2f / (m_verticalAttractionTimescale * pTimestep);
856 // get present body rotation
857 Quaternion rotq = m_prim.Orientation;
858 // make a vector pointing up
859 Vector3 verterr = Vector3.Zero;
860 verterr.Z = 1.0f;
861 // rotate it to Body Angle
862 verterr = verterr * rotq;
863 // verterr.X and .Y are the World error ammounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1.
864 // As the body leans to its side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall and .Z will go
865 // negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body.
866 if (verterr.Z < 0.0f)
867 {
868 verterr.X = 2.0f - verterr.X;
869 verterr.Y = 2.0f - verterr.Y;
870 }
871 // Error is 0 (no error) to +/- 2 (max error)
872 // scale it by VAservo
873 verterr = verterr * VAservo;
874//if (frcount == 0) Console.WriteLine("VAerr=" + verterr);
875
876 // As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so
877 // Change Body angular velocity X based on Y, and Y based on X. Z is not changed.
878 vertattr.X = verterr.Y;
879 vertattr.Y = - verterr.X;
880 vertattr.Z = 0f;
881
882 // scaling appears better usingsquare-law
883 float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency);
884 vertattr.X += bounce * angularVelocity.X;
885 vertattr.Y += bounce * angularVelocity.Y;
886
887 } // else vertical attractor is off
888
889 // m_lastVertAttractor = vertattr;
890
891 // Bank section tba
892 // Deflection section tba
893
894 // Sum velocities
895 m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // + bank + deflection
896
897 if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
898 {
899 m_lastAngularVelocity.X = 0;
900 m_lastAngularVelocity.Y = 0;
901 }
902
903 if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
904 {
905 m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero.
906 }
907
908 // apply friction
909 Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / pTimestep);
910 m_lastAngularVelocity -= m_lastAngularVelocity * decayamount;
911
912 // Apply to the body
913 m_prim.AngularVelocity = m_lastAngularVelocity;
914
915 } //end MoveAngular
916 internal void LimitRotation(float timestep)
917 {
918 Quaternion rotq = m_prim.Orientation; // rotq = rotation of object
919 Quaternion m_rot = rotq;
920 bool changed = false;
921 if (m_RollreferenceFrame != Quaternion.Identity)
922 {
923 if (rotq.X >= m_RollreferenceFrame.X)
924 {
925 m_rot.X = rotq.X - (m_RollreferenceFrame.X / 2);
926 }
927 if (rotq.Y >= m_RollreferenceFrame.Y)
928 {
929 m_rot.Y = rotq.Y - (m_RollreferenceFrame.Y / 2);
930 }
931 if (rotq.X <= -m_RollreferenceFrame.X)
932 {
933 m_rot.X = rotq.X + (m_RollreferenceFrame.X / 2);
934 }
935 if (rotq.Y <= -m_RollreferenceFrame.Y)
936 {
937 m_rot.Y = rotq.Y + (m_RollreferenceFrame.Y / 2);
938 }
939 changed = true;
940 }
941 if ((m_flags & VehicleFlag.LOCK_ROTATION) != 0)
942 {
943 m_rot.X = 0;
944 m_rot.Y = 0;
945 changed = true;
946 }
947 if (changed)
948 m_prim.Orientation = m_rot;
949 }
950 }
951}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs
new file mode 100644
index 0000000..61be56d
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs
@@ -0,0 +1,68 @@
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 OpenSim.Framework;
30using OpenSim.Region.Physics.Manager;
31using OpenMetaverse;
32
33namespace OpenSim.Region.Physics.BulletSPlugin
34{
35public class BSPlugin : IPhysicsPlugin
36{
37 //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
38
39 private BSScene _mScene;
40
41 public BSPlugin()
42 {
43 }
44
45 public bool Init()
46 {
47 return true;
48 }
49
50 public PhysicsScene GetScene(String sceneIdentifier)
51 {
52 if (_mScene == null)
53 {
54 _mScene = new BSScene(sceneIdentifier);
55 }
56 return (_mScene);
57 }
58
59 public string GetName()
60 {
61 return ("BulletSim");
62 }
63
64 public void Dispose()
65 {
66 }
67}
68}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
new file mode 100644
index 0000000..bb8d601
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -0,0 +1,1357 @@
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.Reflection;
29using System.Collections.Generic;
30using System.Xml;
31using log4net;
32using OMV = OpenMetaverse;
33using OpenSim.Framework;
34using OpenSim.Region.Physics.Manager;
35using OpenSim.Region.Physics.ConvexDecompositionDotNet;
36
37namespace OpenSim.Region.Physics.BulletSPlugin
38{
39 [Serializable]
40public sealed class BSPrim : PhysicsActor
41{
42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43 private static readonly string LogHeader = "[BULLETS PRIM]";
44
45 private IMesh _mesh;
46 private PrimitiveBaseShape _pbs;
47 private ShapeData.PhysicsShapeType _shapeType;
48 private ulong _meshKey;
49 private ulong _hullKey;
50 private List<ConvexResult> _hulls;
51
52 private BSScene _scene;
53 private String _avName;
54 private uint _localID = 0;
55
56 // _size is what the user passed. _scale is what we pass to the physics engine with the mesh.
57 // Often _scale is unity because the meshmerizer will apply _size when creating the mesh.
58 private OMV.Vector3 _size; // the multiplier for each mesh dimension as passed by the user
59 private OMV.Vector3 _scale; // the multiplier for each mesh dimension for the mesh as created by the meshmerizer
60
61 private bool _stopped;
62 private bool _grabbed;
63 private bool _isSelected;
64 private bool _isVolumeDetect;
65 private OMV.Vector3 _position;
66 private float _mass;
67 private float _density;
68 private OMV.Vector3 _force;
69 private OMV.Vector3 _velocity;
70 private OMV.Vector3 _torque;
71 private float _collisionScore;
72 private OMV.Vector3 _acceleration;
73 private OMV.Quaternion _orientation;
74 private int _physicsActorType;
75 private bool _isPhysical;
76 private bool _flying;
77 private float _friction;
78 private float _restitution;
79 private bool _setAlwaysRun;
80 private bool _throttleUpdates;
81 private bool _isColliding;
82 private bool _collidingGround;
83 private bool _collidingObj;
84 private bool _floatOnWater;
85 private OMV.Vector3 _rotationalVelocity;
86 private bool _kinematic;
87 private float _buoyancy;
88 private OMV.Vector3 _angularVelocity;
89
90 private List<BSPrim> _childrenPrims;
91 private BSPrim _parentPrim;
92
93 private int _subscribedEventsMs = 0;
94 private int _lastCollisionTime = 0;
95 long _collidingStep;
96 long _collidingGroundStep;
97
98 private BSDynamics _vehicle;
99
100 private OMV.Vector3 _PIDTarget;
101 private bool _usePID;
102 private float _PIDTau;
103 private bool _useHoverPID;
104 private float _PIDHoverHeight;
105 private PIDHoverType _PIDHoverType;
106 private float _PIDHoverTao;
107
108 public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
109 OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
110 {
111 // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID);
112 _localID = localID;
113 _avName = primName;
114 _scene = parent_scene;
115 _position = pos;
116 _size = size;
117 _scale = new OMV.Vector3(1f, 1f, 1f); // the scale will be set by CreateGeom depending on object type
118 _orientation = rotation;
119 _buoyancy = 1f;
120 _velocity = OMV.Vector3.Zero;
121 _rotationalVelocity = OMV.Vector3.Zero;
122 _angularVelocity = OMV.Vector3.Zero;
123 _hullKey = 0;
124 _meshKey = 0;
125 _pbs = pbs;
126 _isPhysical = pisPhysical;
127 _isVolumeDetect = false;
128 _subscribedEventsMs = 0;
129 _friction = _scene.Params.defaultFriction; // TODO: compute based on object material
130 _density = _scene.Params.defaultDensity; // TODO: compute based on object material
131 _restitution = _scene.Params.defaultRestitution;
132 _parentPrim = null; // not a child or a parent
133 _vehicle = new BSDynamics(this); // add vehicleness
134 _childrenPrims = new List<BSPrim>();
135 if (_isPhysical)
136 _mass = CalculateMass();
137 else
138 _mass = 0f;
139 // do the actual object creation at taint time
140 _scene.TaintedObject(delegate()
141 {
142 RecreateGeomAndObject();
143 });
144 }
145
146 // called when this prim is being destroyed and we should free all the resources
147 public void Destroy()
148 {
149 // m_log.DebugFormat("{0}: Destroy", LogHeader);
150 // Undo any vehicle properties
151 _vehicle.ProcessTypeChange(Vehicle.TYPE_NONE);
152 _scene.RemoveVehiclePrim(this); // just to make sure
153 _scene.TaintedObject(delegate()
154 {
155 // everything in the C# world will get garbage collected. Tell the C++ world to free stuff.
156 BulletSimAPI.DestroyObject(_scene.WorldID, _localID);
157 });
158 }
159
160 public override bool Stopped {
161 get { return _stopped; }
162 }
163 public override OMV.Vector3 Size {
164 get { return _size; }
165 set {
166 _size = value;
167 _scene.TaintedObject(delegate()
168 {
169 if (_isPhysical) _mass = CalculateMass(); // changing size changes the mass
170 BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, _mass, _isPhysical);
171 RecreateGeomAndObject();
172 });
173 }
174 }
175 public override PrimitiveBaseShape Shape {
176 set {
177 _pbs = value;
178 _scene.TaintedObject(delegate()
179 {
180 if (_isPhysical) _mass = CalculateMass(); // changing the shape changes the mass
181 RecreateGeomAndObject();
182 });
183 }
184 }
185 public override uint LocalID {
186 set { _localID = value; }
187 get { return _localID; }
188 }
189 public override bool Grabbed {
190 set { _grabbed = value;
191 }
192 }
193 public override bool Selected {
194 set {
195 _isSelected = value;
196 _scene.TaintedObject(delegate()
197 {
198 SetObjectDynamic();
199 });
200 }
201 }
202 public override void CrossingFailure() { return; }
203
204 // link me to the specified parent
205 public override void link(PhysicsActor obj) {
206 BSPrim parent = (BSPrim)obj;
207 // m_log.DebugFormat("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID);
208 // TODO: decide if this parent checking needs to happen at taint time
209 if (_parentPrim == null)
210 {
211 if (parent != null)
212 {
213 // I don't have a parent so I am joining a linkset
214 parent.AddChildToLinkset(this);
215 }
216 }
217 else
218 {
219 // I already have a parent, is parenting changing?
220 if (parent != _parentPrim)
221 {
222 if (parent == null)
223 {
224 // we are being removed from a linkset
225 _parentPrim.RemoveChildFromLinkset(this);
226 }
227 else
228 {
229 // asking to reparent a prim should not happen
230 m_log.ErrorFormat("{0}: Reparenting a prim. ", LogHeader);
231 }
232 }
233 }
234 return;
235 }
236
237 // delink me from my linkset
238 public override void delink() {
239 // TODO: decide if this parent checking needs to happen at taint time
240 // Race condition here: if link() and delink() in same simulation tick, the delink will not happen
241 // m_log.DebugFormat("{0}: delink {1}/{2}", LogHeader, _avName, _localID);
242 if (_parentPrim != null)
243 {
244 _parentPrim.RemoveChildFromLinkset(this);
245 }
246 return;
247 }
248
249 // I am the root of a linkset and a new child is being added
250 public void AddChildToLinkset(BSPrim pchild)
251 {
252 BSPrim child = pchild;
253 _scene.TaintedObject(delegate()
254 {
255 if (!_childrenPrims.Contains(child))
256 {
257 _childrenPrims.Add(child);
258 child.ParentPrim = this; // the child has gained a parent
259 RecreateGeomAndObject(); // rebuild my shape with the new child added
260 }
261 });
262 return;
263 }
264
265 // I am the root of a linkset and one of my children is being removed.
266 // Safe to call even if the child is not really in my linkset.
267 public void RemoveChildFromLinkset(BSPrim pchild)
268 {
269 BSPrim child = pchild;
270 _scene.TaintedObject(delegate()
271 {
272 if (_childrenPrims.Contains(child))
273 {
274 BulletSimAPI.RemoveConstraint(_scene.WorldID, child.LocalID, this.LocalID);
275 _childrenPrims.Remove(child);
276 child.ParentPrim = null; // the child has lost its parent
277 RecreateGeomAndObject(); // rebuild my shape with the child removed
278 }
279 else
280 {
281 m_log.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset");
282 }
283 });
284 return;
285 }
286
287 public BSPrim ParentPrim
288 {
289 set { _parentPrim = value; }
290 }
291
292 // return true if we are the root of a linkset (there are children to manage)
293 public bool IsRootOfLinkset
294 {
295 get { return (_parentPrim == null && _childrenPrims.Count != 0); }
296 }
297
298 // Set motion values to zero.
299 // Do it to the properties so the values get set in the physics engine.
300 // Push the setting of the values to the viewer.
301 private void ZeroMotion()
302 {
303 Velocity = OMV.Vector3.Zero;
304 _acceleration = OMV.Vector3.Zero;
305 RotationalVelocity = OMV.Vector3.Zero;
306 base.RequestPhysicsterseUpdate();
307 }
308
309 public override void LockAngularMotion(OMV.Vector3 axis) { return; }
310
311 public override OMV.Vector3 Position {
312 get {
313 // don't do the following GetObjectPosition because this function is called a zillion times
314 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
315 return _position;
316 }
317 set {
318 _position = value;
319 _scene.TaintedObject(delegate()
320 {
321 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
322 // m_log.DebugFormat("{0}: setPosition: id={1}, position={2}", LogHeader, _localID, _position);
323 });
324 }
325 }
326 public override float Mass {
327 get { return _mass; }
328 }
329 public override OMV.Vector3 Force {
330 get { return _force; }
331 set {
332 _force = value;
333 _scene.TaintedObject(delegate()
334 {
335 BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
336 });
337 }
338 }
339
340 public override int VehicleType {
341 get {
342 return (int)_vehicle.Type; // if we are a vehicle, return that type
343 }
344 set {
345 Vehicle type = (Vehicle)value;
346 _vehicle.ProcessTypeChange(type);
347 _scene.TaintedObject(delegate()
348 {
349 if (type == Vehicle.TYPE_NONE)
350 {
351 _scene.RemoveVehiclePrim(this);
352 }
353 else
354 {
355 // make it so the scene will call us each tick to do vehicle things
356 _scene.AddVehiclePrim(this);
357 }
358 return;
359 });
360 }
361 }
362 public override void VehicleFloatParam(int param, float value)
363 {
364 _vehicle.ProcessFloatVehicleParam((Vehicle)param, value);
365 }
366 public override void VehicleVectorParam(int param, OMV.Vector3 value)
367 {
368 _vehicle.ProcessVectorVehicleParam((Vehicle)param, value);
369 }
370 public override void VehicleRotationParam(int param, OMV.Quaternion rotation)
371 {
372 _vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
373 }
374 public override void VehicleFlags(int param, bool remove)
375 {
376 _vehicle.ProcessVehicleFlags(param, remove);
377 }
378 // Called each simulation step to advance vehicle characteristics
379 public void StepVehicle(float timeStep)
380 {
381 _vehicle.Step(timeStep, _scene);
382 }
383
384 // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more
385 public override void SetVolumeDetect(int param) {
386 bool newValue = (param != 0);
387 if (_isVolumeDetect != newValue)
388 {
389 _isVolumeDetect = newValue;
390 _scene.TaintedObject(delegate()
391 {
392 SetObjectDynamic();
393 });
394 }
395 return;
396 }
397
398 public override OMV.Vector3 GeometricCenter { get { return OMV.Vector3.Zero; } }
399 public override OMV.Vector3 CenterOfMass { get { return OMV.Vector3.Zero; } }
400 public override OMV.Vector3 Velocity {
401 get { return _velocity; }
402 set { _velocity = value;
403 _scene.TaintedObject(delegate()
404 {
405 BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity);
406 });
407 }
408 }
409 public override OMV.Vector3 Torque {
410 get { return _torque; }
411 set { _torque = value;
412 }
413 }
414 public override float CollisionScore {
415 get { return _collisionScore; }
416 set { _collisionScore = value;
417 }
418 }
419 public override OMV.Vector3 Acceleration {
420 get { return _acceleration; }
421 }
422 public override OMV.Quaternion Orientation {
423 get { return _orientation; }
424 set {
425 _orientation = value;
426 // m_log.DebugFormat("{0}: set orientation: id={1}, ori={2}", LogHeader, LocalID, _orientation);
427 _scene.TaintedObject(delegate()
428 {
429 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
430 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
431 });
432 }
433 }
434 public override int PhysicsActorType {
435 get { return _physicsActorType; }
436 set { _physicsActorType = value;
437 }
438 }
439 public override bool IsPhysical {
440 get { return _isPhysical; }
441 set {
442 _isPhysical = value;
443 _scene.TaintedObject(delegate()
444 {
445 SetObjectDynamic();
446 });
447 }
448 }
449
450 // An object is static (does not move) if selected or not physical
451 private bool IsStatic
452 {
453 get { return _isSelected || !IsPhysical; }
454 }
455
456 // An object is solid if it's not phantom and if it's not doing VolumeDetect
457 private bool IsSolid
458 {
459 get { return !IsPhantom && !_isVolumeDetect; }
460 }
461
462 // make gravity work if the object is physical and not selected
463 // no locking here because only called when it is safe
464 private void SetObjectDynamic()
465 {
466 // m_log.DebugFormat("{0}: ID={1}, SetObjectDynamic: IsStatic={2}, IsSolid={3}", LogHeader, _localID, IsStatic, IsSolid);
467 // non-physical things work best with a mass of zero
468 if (IsStatic)
469 {
470 _mass = 0f;
471 }
472 else
473 {
474 _mass = CalculateMass();
475 // If it's dynamic, make sure the hull has been created for it
476 // This shouldn't do much work if the object had previously been built
477 RecreateGeomAndObject();
478
479 }
480 BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), _mass);
481 }
482
483 // prims don't fly
484 public override bool Flying {
485 get { return _flying; }
486 set { _flying = value; }
487 }
488 public override bool SetAlwaysRun {
489 get { return _setAlwaysRun; }
490 set { _setAlwaysRun = value; }
491 }
492 public override bool ThrottleUpdates {
493 get { return _throttleUpdates; }
494 set { _throttleUpdates = value; }
495 }
496 public override bool IsColliding {
497 get { return (_collidingStep == _scene.SimulationStep); }
498 set { _isColliding = value; }
499 }
500 public override bool CollidingGround {
501 get { return (_collidingGroundStep == _scene.SimulationStep); }
502 set { _collidingGround = value; }
503 }
504 public override bool CollidingObj {
505 get { return _collidingObj; }
506 set { _collidingObj = value; }
507 }
508 public bool IsPhantom {
509 get {
510 // SceneObjectPart removes phantom objects from the physics scene
511 // so, although we could implement touching and such, we never
512 // are invoked as a phantom object
513 return false;
514 }
515 }
516 public override bool FloatOnWater {
517 set { _floatOnWater = value; }
518 }
519 public override OMV.Vector3 RotationalVelocity {
520 get { return _rotationalVelocity; }
521 set { _rotationalVelocity = value;
522 // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
523 _scene.TaintedObject(delegate()
524 {
525 BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity);
526 });
527 }
528 }
529 public OMV.Vector3 AngularVelocity {
530 get { return _angularVelocity; }
531 set { _angularVelocity = value; }
532 }
533 public override bool Kinematic {
534 get { return _kinematic; }
535 set { _kinematic = value;
536 // m_log.DebugFormat("{0}: Kinematic={1}", LogHeader, _kinematic);
537 }
538 }
539 public override float Buoyancy {
540 get { return _buoyancy; }
541 set { _buoyancy = value;
542 _scene.TaintedObject(delegate()
543 {
544 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy);
545 });
546 }
547 }
548
549 // Used for MoveTo
550 public override OMV.Vector3 PIDTarget {
551 set { _PIDTarget = value; }
552 }
553 public override bool PIDActive {
554 set { _usePID = value; }
555 }
556 public override float PIDTau {
557 set { _PIDTau = value; }
558 }
559
560 // Used for llSetHoverHeight and maybe vehicle height
561 // Hover Height will override MoveTo target's Z
562 public override bool PIDHoverActive {
563 set { _useHoverPID = value; }
564 }
565 public override float PIDHoverHeight {
566 set { _PIDHoverHeight = value; }
567 }
568 public override PIDHoverType PIDHoverType {
569 set { _PIDHoverType = value; }
570 }
571 public override float PIDHoverTau {
572 set { _PIDHoverTao = value; }
573 }
574
575 // For RotLookAt
576 public override OMV.Quaternion APIDTarget { set { return; } }
577 public override bool APIDActive { set { return; } }
578 public override float APIDStrength { set { return; } }
579 public override float APIDDamping { set { return; } }
580
581 public override void AddForce(OMV.Vector3 force, bool pushforce) {
582 if (force.IsFinite())
583 {
584 _force.X += force.X;
585 _force.Y += force.Y;
586 _force.Z += force.Z;
587 }
588 else
589 {
590 m_log.WarnFormat("{0}: Got a NaN force applied to a Character", LogHeader);
591 }
592 _scene.TaintedObject(delegate()
593 {
594 BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
595 });
596 }
597
598 public override void AddAngularForce(OMV.Vector3 force, bool pushforce) {
599 // m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce);
600 }
601 public override void SetMomentum(OMV.Vector3 momentum) {
602 }
603 public override void SubscribeEvents(int ms) {
604 _subscribedEventsMs = ms;
605 _lastCollisionTime = Util.EnvironmentTickCount() - _subscribedEventsMs; // make first collision happen
606 }
607 public override void UnSubscribeEvents() {
608 _subscribedEventsMs = 0;
609 }
610 public override bool SubscribedEvents() {
611 return (_subscribedEventsMs > 0);
612 }
613
614 #region Mass Calculation
615
616 private float CalculateMass()
617 {
618 float volume = _size.X * _size.Y * _size.Z; // default
619 float tmp;
620
621 float returnMass = 0;
622 float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f;
623 float hollowVolume = hollowAmount * hollowAmount;
624
625 switch (_pbs.ProfileShape)
626 {
627 case ProfileShape.Square:
628 // default box
629
630 if (_pbs.PathCurve == (byte)Extrusion.Straight)
631 {
632 if (hollowAmount > 0.0)
633 {
634 switch (_pbs.HollowShape)
635 {
636 case HollowShape.Square:
637 case HollowShape.Same:
638 break;
639
640 case HollowShape.Circle:
641
642 hollowVolume *= 0.78539816339f;
643 break;
644
645 case HollowShape.Triangle:
646
647 hollowVolume *= (0.5f * .5f);
648 break;
649
650 default:
651 hollowVolume = 0;
652 break;
653 }
654 volume *= (1.0f - hollowVolume);
655 }
656 }
657
658 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
659 {
660 //a tube
661
662 volume *= 0.78539816339e-2f * (float)(200 - _pbs.PathScaleX);
663 tmp= 1.0f -2.0e-2f * (float)(200 - _pbs.PathScaleY);
664 volume -= volume*tmp*tmp;
665
666 if (hollowAmount > 0.0)
667 {
668 hollowVolume *= hollowAmount;
669
670 switch (_pbs.HollowShape)
671 {
672 case HollowShape.Square:
673 case HollowShape.Same:
674 break;
675
676 case HollowShape.Circle:
677 hollowVolume *= 0.78539816339f;;
678 break;
679
680 case HollowShape.Triangle:
681 hollowVolume *= 0.5f * 0.5f;
682 break;
683 default:
684 hollowVolume = 0;
685 break;
686 }
687 volume *= (1.0f - hollowVolume);
688 }
689 }
690
691 break;
692
693 case ProfileShape.Circle:
694
695 if (_pbs.PathCurve == (byte)Extrusion.Straight)
696 {
697 volume *= 0.78539816339f; // elipse base
698
699 if (hollowAmount > 0.0)
700 {
701 switch (_pbs.HollowShape)
702 {
703 case HollowShape.Same:
704 case HollowShape.Circle:
705 break;
706
707 case HollowShape.Square:
708 hollowVolume *= 0.5f * 2.5984480504799f;
709 break;
710
711 case HollowShape.Triangle:
712 hollowVolume *= .5f * 1.27323954473516f;
713 break;
714
715 default:
716 hollowVolume = 0;
717 break;
718 }
719 volume *= (1.0f - hollowVolume);
720 }
721 }
722
723 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
724 {
725 volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - _pbs.PathScaleX);
726 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY);
727 volume *= (1.0f - tmp * tmp);
728
729 if (hollowAmount > 0.0)
730 {
731
732 // calculate the hollow volume by it's shape compared to the prim shape
733 hollowVolume *= hollowAmount;
734
735 switch (_pbs.HollowShape)
736 {
737 case HollowShape.Same:
738 case HollowShape.Circle:
739 break;
740
741 case HollowShape.Square:
742 hollowVolume *= 0.5f * 2.5984480504799f;
743 break;
744
745 case HollowShape.Triangle:
746 hollowVolume *= .5f * 1.27323954473516f;
747 break;
748
749 default:
750 hollowVolume = 0;
751 break;
752 }
753 volume *= (1.0f - hollowVolume);
754 }
755 }
756 break;
757
758 case ProfileShape.HalfCircle:
759 if (_pbs.PathCurve == (byte)Extrusion.Curve1)
760 {
761 volume *= 0.52359877559829887307710723054658f;
762 }
763 break;
764
765 case ProfileShape.EquilateralTriangle:
766
767 if (_pbs.PathCurve == (byte)Extrusion.Straight)
768 {
769 volume *= 0.32475953f;
770
771 if (hollowAmount > 0.0)
772 {
773
774 // calculate the hollow volume by it's shape compared to the prim shape
775 switch (_pbs.HollowShape)
776 {
777 case HollowShape.Same:
778 case HollowShape.Triangle:
779 hollowVolume *= .25f;
780 break;
781
782 case HollowShape.Square:
783 hollowVolume *= 0.499849f * 3.07920140172638f;
784 break;
785
786 case HollowShape.Circle:
787 // Hollow shape is a perfect cyllinder in respect to the cube's scale
788 // Cyllinder hollow volume calculation
789
790 hollowVolume *= 0.1963495f * 3.07920140172638f;
791 break;
792
793 default:
794 hollowVolume = 0;
795 break;
796 }
797 volume *= (1.0f - hollowVolume);
798 }
799 }
800 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
801 {
802 volume *= 0.32475953f;
803 volume *= 0.01f * (float)(200 - _pbs.PathScaleX);
804 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY);
805 volume *= (1.0f - tmp * tmp);
806
807 if (hollowAmount > 0.0)
808 {
809
810 hollowVolume *= hollowAmount;
811
812 switch (_pbs.HollowShape)
813 {
814 case HollowShape.Same:
815 case HollowShape.Triangle:
816 hollowVolume *= .25f;
817 break;
818
819 case HollowShape.Square:
820 hollowVolume *= 0.499849f * 3.07920140172638f;
821 break;
822
823 case HollowShape.Circle:
824
825 hollowVolume *= 0.1963495f * 3.07920140172638f;
826 break;
827
828 default:
829 hollowVolume = 0;
830 break;
831 }
832 volume *= (1.0f - hollowVolume);
833 }
834 }
835 break;
836
837 default:
838 break;
839 }
840
841
842
843 float taperX1;
844 float taperY1;
845 float taperX;
846 float taperY;
847 float pathBegin;
848 float pathEnd;
849 float profileBegin;
850 float profileEnd;
851
852 if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)Extrusion.Flexible)
853 {
854 taperX1 = _pbs.PathScaleX * 0.01f;
855 if (taperX1 > 1.0f)
856 taperX1 = 2.0f - taperX1;
857 taperX = 1.0f - taperX1;
858
859 taperY1 = _pbs.PathScaleY * 0.01f;
860 if (taperY1 > 1.0f)
861 taperY1 = 2.0f - taperY1;
862 taperY = 1.0f - taperY1;
863 }
864 else
865 {
866 taperX = _pbs.PathTaperX * 0.01f;
867 if (taperX < 0.0f)
868 taperX = -taperX;
869 taperX1 = 1.0f - taperX;
870
871 taperY = _pbs.PathTaperY * 0.01f;
872 if (taperY < 0.0f)
873 taperY = -taperY;
874 taperY1 = 1.0f - taperY;
875
876 }
877
878
879 volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY);
880
881 pathBegin = (float)_pbs.PathBegin * 2.0e-5f;
882 pathEnd = 1.0f - (float)_pbs.PathEnd * 2.0e-5f;
883 volume *= (pathEnd - pathBegin);
884
885 // this is crude aproximation
886 profileBegin = (float)_pbs.ProfileBegin * 2.0e-5f;
887 profileEnd = 1.0f - (float)_pbs.ProfileEnd * 2.0e-5f;
888 volume *= (profileEnd - profileBegin);
889
890 returnMass = _density * volume;
891
892 if (IsRootOfLinkset)
893 {
894 foreach (BSPrim prim in _childrenPrims)
895 {
896 returnMass += prim.CalculateMass();
897 }
898 }
899
900 if (returnMass <= 0)
901 returnMass = 0.0001f;
902
903 if (returnMass > _scene.MaximumObjectMass)
904 returnMass = _scene.MaximumObjectMass;
905
906 return returnMass;
907 }// end CalculateMass
908 #endregion Mass Calculation
909
910 // Create the geometry information in Bullet for later use
911 // The objects needs a hull if it's physical otherwise a mesh is enough
912 // No locking here because this is done when we know physics is not simulating
913 // if 'forceRebuild' is true, the geometry is rebuilt. Otherwise a previously built version is used
914 private void CreateGeom(bool forceRebuild)
915 {
916 // the mesher thought this was too simple to mesh. Use a native Bullet collision shape.
917 if (!_scene.NeedsMeshing(_pbs))
918 {
919 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
920 {
921 if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
922 {
923 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size);
924 _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE;
925 // Bullet native objects are scaled by the Bullet engine so pass the size in
926 _scale = _size;
927 }
928 }
929 else
930 {
931 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, size={2}", LogHeader, LocalID, _size);
932 _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX;
933 _scale = _size;
934 }
935 }
936 else
937 {
938 if (IsPhysical)
939 {
940 if (forceRebuild || _hullKey == 0)
941 {
942 // physical objects require a hull for interaction.
943 // This will create the mesh if it doesn't already exist
944 CreateGeomHull();
945 }
946 }
947 else
948 {
949 if (forceRebuild || _meshKey == 0)
950 {
951 // Static (non-physical) objects only need a mesh for bumping into
952 CreateGeomMesh();
953 }
954 }
955 }
956 }
957
958 // No locking here because this is done when we know physics is not simulating
959 private void CreateGeomMesh()
960 {
961 float lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD;
962 ulong newMeshKey = (ulong)_pbs.GetMeshKey(_size, lod);
963 // m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey);
964
965 // if this new shape is the same as last time, don't recreate the mesh
966 if (_meshKey == newMeshKey) return;
967
968 // Since we're recreating new, get rid of any previously generated shape
969 if (_meshKey != 0)
970 {
971 // m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey);
972 BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey);
973 _mesh = null;
974 _meshKey = 0;
975 }
976
977 _meshKey = newMeshKey;
978 // always pass false for physicalness as this creates some sort of bounding box which we don't need
979 _mesh = _scene.mesher.CreateMesh(_avName, _pbs, _size, lod, false);
980
981 int[] indices = _mesh.getIndexListAsInt();
982 List<OMV.Vector3> vertices = _mesh.getVertexList();
983
984 float[] verticesAsFloats = new float[vertices.Count * 3];
985 int vi = 0;
986 foreach (OMV.Vector3 vv in vertices)
987 {
988 // m_log.DebugFormat("{0}: {1}: <{2:0.00}, {3:0.00}, {4:0.00}>", LogHeader, vi / 3, vv.X, vv.Y, vv.Z);
989 verticesAsFloats[vi++] = vv.X;
990 verticesAsFloats[vi++] = vv.Y;
991 verticesAsFloats[vi++] = vv.Z;
992 }
993
994 // m_log.DebugFormat("{0}: CreateGeomMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}",
995 // LogHeader, _localID, _meshKey, indices.Length, vertices.Count);
996 BulletSimAPI.CreateMesh(_scene.WorldID, _meshKey, indices.GetLength(0), indices,
997 vertices.Count, verticesAsFloats);
998
999 _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH;
1000 // meshes are already scaled by the meshmerizer
1001 _scale = new OMV.Vector3(1f, 1f, 1f);
1002 return;
1003 }
1004
1005 // No locking here because this is done when we know physics is not simulating
1006 private void CreateGeomHull()
1007 {
1008 float lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD;
1009 ulong newHullKey = (ulong)_pbs.GetMeshKey(_size, lod);
1010 // m_log.DebugFormat("{0}: CreateGeomHull: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _hullKey, newHullKey);
1011
1012 // if the hull hasn't changed, don't rebuild it
1013 if (newHullKey == _hullKey) return;
1014
1015 // Since we're recreating new, get rid of any previously generated shape
1016 if (_hullKey != 0)
1017 {
1018 // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey);
1019 BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey);
1020 _hullKey = 0;
1021 _hulls.Clear();
1022 BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey);
1023 _mesh = null; // the mesh cannot match either
1024 _meshKey = 0;
1025 }
1026
1027 _hullKey = newHullKey;
1028 if (_meshKey != _hullKey)
1029 {
1030 // if the underlying mesh has changed, rebuild it
1031 CreateGeomMesh();
1032 }
1033
1034 int[] indices = _mesh.getIndexListAsInt();
1035 List<OMV.Vector3> vertices = _mesh.getVertexList();
1036
1037 //format conversion from IMesh format to DecompDesc format
1038 List<int> convIndices = new List<int>();
1039 List<float3> convVertices = new List<float3>();
1040 for (int ii = 0; ii < indices.GetLength(0); ii++)
1041 {
1042 convIndices.Add(indices[ii]);
1043 }
1044 foreach (OMV.Vector3 vv in vertices)
1045 {
1046 convVertices.Add(new float3(vv.X, vv.Y, vv.Z));
1047 }
1048
1049 // setup and do convex hull conversion
1050 _hulls = new List<ConvexResult>();
1051 DecompDesc dcomp = new DecompDesc();
1052 dcomp.mIndices = convIndices;
1053 dcomp.mVertices = convVertices;
1054 ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn);
1055 // create the hull into the _hulls variable
1056 convexBuilder.process(dcomp);
1057
1058 // Convert the vertices and indices for passing to unmanaged
1059 // The hull information is passed as a large floating point array.
1060 // The format is:
1061 // convHulls[0] = number of hulls
1062 // convHulls[1] = number of vertices in first hull
1063 // convHulls[2] = hull centroid X coordinate
1064 // convHulls[3] = hull centroid Y coordinate
1065 // convHulls[4] = hull centroid Z coordinate
1066 // convHulls[5] = first hull vertex X
1067 // convHulls[6] = first hull vertex Y
1068 // convHulls[7] = first hull vertex Z
1069 // convHulls[8] = second hull vertex X
1070 // ...
1071 // convHulls[n] = number of vertices in second hull
1072 // convHulls[n+1] = second hull centroid X coordinate
1073 // ...
1074 //
1075 // TODO: is is very inefficient. Someday change the convex hull generator to return
1076 // data structures that do not need to be converted in order to pass to Bullet.
1077 // And maybe put the values directly into pinned memory rather than marshaling.
1078 int hullCount = _hulls.Count;
1079 int totalVertices = 1; // include one for the count of the hulls
1080 foreach (ConvexResult cr in _hulls)
1081 {
1082 totalVertices += 4; // add four for the vertex count and centroid
1083 totalVertices += cr.HullIndices.Count * 3; // we pass just triangles
1084 }
1085 float[] convHulls = new float[totalVertices];
1086
1087 convHulls[0] = (float)hullCount;
1088 int jj = 1;
1089 foreach (ConvexResult cr in _hulls)
1090 {
1091 // copy vertices for index access
1092 float3[] verts = new float3[cr.HullVertices.Count];
1093 int kk = 0;
1094 foreach (float3 ff in cr.HullVertices)
1095 {
1096 verts[kk++] = ff;
1097 }
1098
1099 // add to the array one hull's worth of data
1100 convHulls[jj++] = cr.HullIndices.Count;
1101 convHulls[jj++] = 0f; // centroid x,y,z
1102 convHulls[jj++] = 0f;
1103 convHulls[jj++] = 0f;
1104 foreach (int ind in cr.HullIndices)
1105 {
1106 convHulls[jj++] = verts[ind].x;
1107 convHulls[jj++] = verts[ind].y;
1108 convHulls[jj++] = verts[ind].z;
1109 }
1110 }
1111
1112 // create the hull definition in Bullet
1113 // m_log.DebugFormat("{0}: CreateGeom: calling CreateHull. lid={1}, key={2}, hulls={3}", LogHeader, _localID, _hullKey, hullCount);
1114 BulletSimAPI.CreateHull(_scene.WorldID, _hullKey, hullCount, convHulls);
1115 _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL;
1116 // meshes are already scaled by the meshmerizer
1117 _scale = new OMV.Vector3(1f, 1f, 1f);
1118 return;
1119 }
1120
1121 // Callback from convex hull creater with a newly created hull.
1122 // Just add it to the collection of hulls for this shape.
1123 private void HullReturn(ConvexResult result)
1124 {
1125 _hulls.Add(result);
1126 return;
1127 }
1128
1129 // Create an object in Bullet
1130 // No locking here because this is done when the physics engine is not simulating
1131 private void CreateObject()
1132 {
1133 if (IsRootOfLinkset)
1134 {
1135 // Create a linkset around this object
1136 // CreateLinksetWithCompoundHull();
1137 CreateLinksetWithConstraints();
1138 }
1139 else
1140 {
1141 // simple object
1142 // the mesh or hull must have already been created in Bullet
1143 ShapeData shape;
1144 FillShapeInfo(out shape);
1145 // m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, _localID, shape.Type);
1146 BulletSimAPI.CreateObject(_scene.WorldID, shape);
1147 }
1148 }
1149
1150 // Create a linkset by creating a compound hull at the root prim that consists of all
1151 // the children.
1152 // NOTE: This does not allow proper collisions with the children prims so it is not a workable solution
1153 void CreateLinksetWithCompoundHull()
1154 {
1155 // If I am the root prim of a linkset, replace my physical shape with all the
1156 // pieces of the children.
1157 // All of the children should have called CreateGeom so they have a hull
1158 // in the physics engine already. Here we pull together all of those hulls
1159 // into one shape.
1160 int totalPrimsInLinkset = _childrenPrims.Count + 1;
1161 // m_log.DebugFormat("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, totalPrimsInLinkset);
1162 ShapeData[] shapes = new ShapeData[totalPrimsInLinkset];
1163 FillShapeInfo(out shapes[0]);
1164 int ii = 1;
1165 foreach (BSPrim prim in _childrenPrims)
1166 {
1167 // m_log.DebugFormat("{0}: CreateLinkset: adding prim {1}", LogHeader, prim.LocalID);
1168 prim.FillShapeInfo(out shapes[ii]);
1169 ii++;
1170 }
1171 BulletSimAPI.CreateLinkset(_scene.WorldID, totalPrimsInLinkset, shapes);
1172 }
1173
1174 // Copy prim's info into the BulletSim shape description structure
1175 public void FillShapeInfo(out ShapeData shape)
1176 {
1177 shape.ID = _localID;
1178 shape.Type = _shapeType;
1179 shape.Position = _position;
1180 shape.Rotation = _orientation;
1181 shape.Velocity = _velocity;
1182 shape.Scale = _scale;
1183 shape.Mass = _isPhysical ? _mass : 0f;
1184 shape.Buoyancy = _buoyancy;
1185 shape.HullKey = _hullKey;
1186 shape.MeshKey = _meshKey;
1187 shape.Friction = _friction;
1188 shape.Restitution = _restitution;
1189 shape.Collidable = (!IsPhantom) ? ShapeData.numericTrue : ShapeData.numericFalse;
1190 shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue;
1191 }
1192
1193 // Create the linkset by putting constraints between the objects of the set so they cannot move
1194 // relative to each other.
1195 // TODO: make this more effeicient: a large linkset gets rebuilt over and over and prims are added
1196 void CreateLinksetWithConstraints()
1197 {
1198 // m_log.DebugFormat("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1);
1199
1200 // remove any constraints that might be in place
1201 foreach (BSPrim prim in _childrenPrims)
1202 {
1203 // m_log.DebugFormat("{0}: CreateLinkset: RemoveConstraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID);
1204 BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, prim.LocalID);
1205 }
1206 // create constraints between the root prim and each of the children
1207 foreach (BSPrim prim in _childrenPrims)
1208 {
1209 // m_log.DebugFormat("{0}: CreateLinkset: AddConstraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID);
1210
1211 // Zero motion for children so they don't interpolate
1212 prim.ZeroMotion();
1213
1214 // relative position normalized to the root prim
1215 OMV.Vector3 childRelativePosition = (prim._position - this._position) * OMV.Quaternion.Inverse(this._orientation);
1216
1217 // relative rotation of the child to the parent
1218 OMV.Quaternion relativeRotation = OMV.Quaternion.Inverse(prim._orientation) * this._orientation;
1219
1220 // this is a constraint that allows no freedom of movement between the two objects
1221 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
1222 BulletSimAPI.AddConstraint(_scene.WorldID, LocalID, prim.LocalID,
1223 childRelativePosition,
1224 relativeRotation,
1225 OMV.Vector3.Zero,
1226 OMV.Quaternion.Identity,
1227 OMV.Vector3.Zero, OMV.Vector3.Zero,
1228 OMV.Vector3.Zero, OMV.Vector3.Zero);
1229 }
1230 }
1231
1232 // Rebuild the geometry and object.
1233 // This is called when the shape changes so we need to recreate the mesh/hull.
1234 // No locking here because this is done when the physics engine is not simulating
1235 private void RecreateGeomAndObject()
1236 {
1237 // m_log.DebugFormat("{0}: RecreateGeomAndObject. lID={1}", LogHeader, _localID);
1238 CreateGeom(true);
1239 CreateObject();
1240 return;
1241 }
1242
1243 // The physics engine says that properties have updated. Update same and inform
1244 // the world that things have changed.
1245 // TODO: do we really need to check for changed? Maybe just copy values and call RequestPhysicsterseUpdate()
1246 enum UpdatedProperties {
1247 Position = 1 << 0,
1248 Rotation = 1 << 1,
1249 Velocity = 1 << 2,
1250 Acceleration = 1 << 3,
1251 RotationalVel = 1 << 4
1252 }
1253
1254 const float ROTATION_TOLERANCE = 0.01f;
1255 const float VELOCITY_TOLERANCE = 0.001f;
1256 const float POSITION_TOLERANCE = 0.05f;
1257 const float ACCELERATION_TOLERANCE = 0.01f;
1258 const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f;
1259 const bool SHOULD_DAMP_UPDATES = false;
1260
1261 public void UpdateProperties(EntityProperties entprop)
1262 {
1263 UpdatedProperties changed = 0;
1264 if (SHOULD_DAMP_UPDATES)
1265 {
1266 // assign to the local variables so the normal set action does not happen
1267 // if (_position != entprop.Position)
1268 if (!_position.ApproxEquals(entprop.Position, POSITION_TOLERANCE))
1269 {
1270 _position = entprop.Position;
1271 // m_log.DebugFormat("{0}: UpdateProperties: id={1}, pos = {2}", LogHeader, LocalID, _position);
1272 changed |= UpdatedProperties.Position;
1273 }
1274 // if (_orientation != entprop.Rotation)
1275 if (!_orientation.ApproxEquals(entprop.Rotation, ROTATION_TOLERANCE))
1276 {
1277 _orientation = entprop.Rotation;
1278 // m_log.DebugFormat("{0}: UpdateProperties: id={1}, rot = {2}", LogHeader, LocalID, _orientation);
1279 changed |= UpdatedProperties.Rotation;
1280 }
1281 // if (_velocity != entprop.Velocity)
1282 if (!_velocity.ApproxEquals(entprop.Velocity, VELOCITY_TOLERANCE))
1283 {
1284 _velocity = entprop.Velocity;
1285 // m_log.DebugFormat("{0}: UpdateProperties: velocity = {1}", LogHeader, _velocity);
1286 changed |= UpdatedProperties.Velocity;
1287 }
1288 // if (_acceleration != entprop.Acceleration)
1289 if (!_acceleration.ApproxEquals(entprop.Acceleration, ACCELERATION_TOLERANCE))
1290 {
1291 _acceleration = entprop.Acceleration;
1292 // m_log.DebugFormat("{0}: UpdateProperties: acceleration = {1}", LogHeader, _acceleration);
1293 changed |= UpdatedProperties.Acceleration;
1294 }
1295 // if (_rotationalVelocity != entprop.RotationalVelocity)
1296 if (!_rotationalVelocity.ApproxEquals(entprop.RotationalVelocity, ROTATIONAL_VELOCITY_TOLERANCE))
1297 {
1298 _rotationalVelocity = entprop.RotationalVelocity;
1299 // m_log.DebugFormat("{0}: UpdateProperties: rotationalVelocity = {1}", LogHeader, _rotationalVelocity);
1300 changed |= UpdatedProperties.RotationalVel;
1301 }
1302 if (changed != 0)
1303 {
1304 // m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation);
1305 // Only update the position of single objects and linkset roots
1306 if (this._parentPrim == null)
1307 {
1308 // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation);
1309 base.RequestPhysicsterseUpdate();
1310 }
1311 }
1312 }
1313 else
1314 {
1315 // Don't check for damping here -- it's done in BulletSim and SceneObjectPart.
1316
1317 // Only updates only for individual prims and for the root object of a linkset.
1318 if (this._parentPrim == null)
1319 {
1320 // Assign to the local variables so the normal set action does not happen
1321 _position = entprop.Position;
1322 _orientation = entprop.Rotation;
1323 _velocity = entprop.Velocity;
1324 _acceleration = entprop.Acceleration;
1325 _rotationalVelocity = entprop.RotationalVelocity;
1326 // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation);
1327 base.RequestPhysicsterseUpdate();
1328 }
1329 }
1330 }
1331
1332 // I've collided with something
1333 public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
1334 {
1335 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);
1336
1337 // The following lines make IsColliding() and IsCollidingGround() work
1338 _collidingStep = _scene.SimulationStep;
1339 if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID)
1340 {
1341 _collidingGroundStep = _scene.SimulationStep;
1342 }
1343
1344 if (_subscribedEventsMs == 0) return; // nothing in the object is waiting for collision events
1345 // throttle the collisions to the number of milliseconds specified in the subscription
1346 int nowTime = _scene.SimulationNowTime;
1347 if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return;
1348 _lastCollisionTime = nowTime;
1349
1350 // create the event for the collision
1351 Dictionary<uint, ContactPoint> contactPoints = new Dictionary<uint, ContactPoint>();
1352 contactPoints.Add(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
1353 CollisionEventUpdate args = new CollisionEventUpdate(LocalID, (int)type, 1, contactPoints);
1354 base.SendCollisionUpdate(args);
1355 }
1356}
1357}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
new file mode 100644
index 0000000..7704002
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -0,0 +1,860 @@
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.Runtime.InteropServices;
30using System.Text;
31using System.Threading;
32using Nini.Config;
33using log4net;
34using OpenSim.Framework;
35using OpenSim.Region.Physics.Manager;
36using OpenMetaverse;
37using OpenSim.Region.Framework;
38
39// TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim)
40// Adjust character capsule size when height is adjusted (ScenePresence.SetHeight)
41// Test sculpties
42// Compute physics FPS reasonably
43// Based on material, set density and friction
44// More efficient memory usage in passing hull information from BSPrim to BulletSim
45// Four states of prim: Physical, regular, phantom and selected. Are we modeling these correctly?
46// In SL one can set both physical and phantom (gravity, does not effect others, makes collisions with ground)
47// At the moment, physical and phantom causes object to drop through the terrain
48// Should prim.link() and prim.delink() membership checking happen at taint time?
49// Mesh sharing. Use meshHash to tell if we already have a hull of that shape and only create once
50// Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect
51// Implement the genCollisions feature in BulletSim::SetObjectProperties (don't pass up unneeded collisions)
52// Implement LockAngularMotion
53// Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation)
54// Does NeedsMeshing() really need to exclude all the different shapes?
55//
56namespace OpenSim.Region.Physics.BulletSPlugin
57{
58public class BSScene : PhysicsScene, IPhysicsParameters
59{
60 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
61 private static readonly string LogHeader = "[BULLETS SCENE]";
62
63 public string BulletSimVersion = "?";
64
65 private Dictionary<uint, BSCharacter> m_avatars = new Dictionary<uint, BSCharacter>();
66 private Dictionary<uint, BSPrim> m_prims = new Dictionary<uint, BSPrim>();
67 private List<BSPrim> m_vehicles = new List<BSPrim>();
68 private float[] m_heightMap;
69 private float m_waterLevel;
70 private uint m_worldID;
71 public uint WorldID { get { return m_worldID; } }
72
73 private bool m_initialized = false;
74
75 public IMesher mesher;
76 private float m_meshLOD;
77 public float MeshLOD
78 {
79 get { return m_meshLOD; }
80 }
81 private float m_sculptLOD;
82 public float SculptLOD
83 {
84 get { return m_sculptLOD; }
85 }
86
87 private int m_maxSubSteps;
88 private float m_fixedTimeStep;
89 private long m_simulationStep = 0;
90 public long SimulationStep { get { return m_simulationStep; } }
91
92 // A value of the time now so all the collision and update routines do not have to get their own
93 // Set to 'now' just before all the prims and actors are called for collisions and updates
94 private int m_simulationNowTime;
95 public int SimulationNowTime { get { return m_simulationNowTime; } }
96
97 private int m_maxCollisionsPerFrame;
98 private CollisionDesc[] m_collisionArray;
99 private GCHandle m_collisionArrayPinnedHandle;
100
101 private int m_maxUpdatesPerFrame;
102 private EntityProperties[] m_updateArray;
103 private GCHandle m_updateArrayPinnedHandle;
104
105 private bool _meshSculptedPrim = true; // cause scuplted prims to get meshed
106 private bool _forceSimplePrimMeshing = false; // if a cube or sphere, let Bullet do internal shapes
107
108 public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero
109 public const uint GROUNDPLANE_ID = 1;
110
111 public ConfigurationParameters Params
112 {
113 get { return m_params[0]; }
114 }
115 public Vector3 DefaultGravity
116 {
117 get { return new Vector3(0f, 0f, Params.gravity); }
118 }
119
120 private float m_maximumObjectMass;
121 public float MaximumObjectMass
122 {
123 get { return m_maximumObjectMass; }
124 }
125
126 public delegate void TaintCallback();
127 private List<TaintCallback> _taintedObjects;
128 private Object _taintLock = new Object();
129
130 // A pointer to an instance if this structure is passed to the C++ code
131 ConfigurationParameters[] m_params;
132 GCHandle m_paramsHandle;
133
134 private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle;
135
136 public BSScene(string identifier)
137 {
138 m_initialized = false;
139 }
140
141 public override void Initialise(IMesher meshmerizer, IConfigSource config)
142 {
143 // Allocate pinned memory to pass parameters.
144 m_params = new ConfigurationParameters[1];
145 m_paramsHandle = GCHandle.Alloc(m_params, GCHandleType.Pinned);
146
147 // Set default values for physics parameters plus any overrides from the ini file
148 GetInitialParameterValues(config);
149
150 // allocate more pinned memory close to the above in an attempt to get the memory all together
151 m_collisionArray = new CollisionDesc[m_maxCollisionsPerFrame];
152 m_collisionArrayPinnedHandle = GCHandle.Alloc(m_collisionArray, GCHandleType.Pinned);
153 m_updateArray = new EntityProperties[m_maxUpdatesPerFrame];
154 m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned);
155
156 // Get the version of the DLL
157 // TODO: this doesn't work yet. Something wrong with marshaling the returned string.
158 // BulletSimVersion = BulletSimAPI.GetVersion();
159 // m_log.WarnFormat("{0}: BulletSim.dll version='{1}'", LogHeader, BulletSimVersion);
160
161 // if Debug, enable logging from the unmanaged code
162 if (m_log.IsDebugEnabled)
163 {
164 m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader);
165 m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger);
166 BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle);
167 }
168
169 _taintedObjects = new List<TaintCallback>();
170
171 mesher = meshmerizer;
172 // The bounding box for the simulated world
173 Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 4096f);
174
175 // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader);
176 m_worldID = BulletSimAPI.Initialize(worldExtent, m_paramsHandle.AddrOfPinnedObject(),
177 m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(),
178 m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject());
179
180 m_initialized = true;
181 }
182
183 // All default parameter values are set here. There should be no values set in the
184 // variable definitions.
185 private void GetInitialParameterValues(IConfigSource config)
186 {
187 ConfigurationParameters parms = new ConfigurationParameters();
188
189 _meshSculptedPrim = true; // mesh sculpted prims
190 _forceSimplePrimMeshing = false; // use complex meshing if called for
191
192 m_meshLOD = 8f;
193 m_sculptLOD = 32f;
194
195 m_maxSubSteps = 10;
196 m_fixedTimeStep = 1f / 60f;
197 m_maxCollisionsPerFrame = 2048;
198 m_maxUpdatesPerFrame = 2048;
199 m_maximumObjectMass = 10000.01f;
200
201 parms.defaultFriction = 0.5f;
202 parms.defaultDensity = 10.000006836f; // Aluminum g/cm3
203 parms.defaultRestitution = 0f;
204 parms.collisionMargin = 0.0f;
205 parms.gravity = -9.80665f;
206
207 parms.linearDamping = 0.0f;
208 parms.angularDamping = 0.0f;
209 parms.deactivationTime = 0.2f;
210 parms.linearSleepingThreshold = 0.8f;
211 parms.angularSleepingThreshold = 1.0f;
212 parms.ccdMotionThreshold = 0.5f; // set to zero to disable
213 parms.ccdSweptSphereRadius = 0.2f;
214
215 parms.terrainFriction = 0.5f;
216 parms.terrainHitFraction = 0.8f;
217 parms.terrainRestitution = 0f;
218 parms.avatarFriction = 0.0f;
219 parms.avatarDensity = 60f;
220 parms.avatarCapsuleRadius = 0.37f;
221 parms.avatarCapsuleHeight = 1.5f; // 2.140599f
222
223 if (config != null)
224 {
225 // If there are specifications in the ini file, use those values
226 // WHEN ADDING OR UPDATING THIS SECTION, BE SURE TO UPDATE OpenSimDefaults.ini
227 // ALSO REMEMBER TO UPDATE THE RUNTIME SETTING OF THE PARAMETERS.
228 IConfig pConfig = config.Configs["BulletSim"];
229 if (pConfig != null)
230 {
231 _meshSculptedPrim = pConfig.GetBoolean("MeshSculptedPrim", _meshSculptedPrim);
232 _forceSimplePrimMeshing = pConfig.GetBoolean("ForceSimplePrimMeshing", _forceSimplePrimMeshing);
233
234 m_meshLOD = pConfig.GetFloat("MeshLevelOfDetail", m_meshLOD);
235 m_sculptLOD = pConfig.GetFloat("SculptLevelOfDetail", m_sculptLOD);
236
237 m_maxSubSteps = pConfig.GetInt("MaxSubSteps", m_maxSubSteps);
238 m_fixedTimeStep = pConfig.GetFloat("FixedTimeStep", m_fixedTimeStep);
239 m_maxCollisionsPerFrame = pConfig.GetInt("MaxCollisionsPerFrame", m_maxCollisionsPerFrame);
240 m_maxUpdatesPerFrame = pConfig.GetInt("MaxUpdatesPerFrame", m_maxUpdatesPerFrame);
241 m_maximumObjectMass = pConfig.GetFloat("MaxObjectMass", m_maximumObjectMass);
242
243 parms.defaultFriction = pConfig.GetFloat("DefaultFriction", parms.defaultFriction);
244 parms.defaultDensity = pConfig.GetFloat("DefaultDensity", parms.defaultDensity);
245 parms.defaultRestitution = pConfig.GetFloat("DefaultRestitution", parms.defaultRestitution);
246 parms.collisionMargin = pConfig.GetFloat("CollisionMargin", parms.collisionMargin);
247 parms.gravity = pConfig.GetFloat("Gravity", parms.gravity);
248
249 parms.linearDamping = pConfig.GetFloat("LinearDamping", parms.linearDamping);
250 parms.angularDamping = pConfig.GetFloat("AngularDamping", parms.angularDamping);
251 parms.deactivationTime = pConfig.GetFloat("DeactivationTime", parms.deactivationTime);
252 parms.linearSleepingThreshold = pConfig.GetFloat("LinearSleepingThreshold", parms.linearSleepingThreshold);
253 parms.angularSleepingThreshold = pConfig.GetFloat("AngularSleepingThreshold", parms.angularSleepingThreshold);
254 parms.ccdMotionThreshold = pConfig.GetFloat("CcdMotionThreshold", parms.ccdMotionThreshold);
255 parms.ccdSweptSphereRadius = pConfig.GetFloat("CcdSweptSphereRadius", parms.ccdSweptSphereRadius);
256
257 parms.terrainFriction = pConfig.GetFloat("TerrainFriction", parms.terrainFriction);
258 parms.terrainHitFraction = pConfig.GetFloat("TerrainHitFraction", parms.terrainHitFraction);
259 parms.terrainRestitution = pConfig.GetFloat("TerrainRestitution", parms.terrainRestitution);
260 parms.avatarFriction = pConfig.GetFloat("AvatarFriction", parms.avatarFriction);
261 parms.avatarDensity = pConfig.GetFloat("AvatarDensity", parms.avatarDensity);
262 parms.avatarCapsuleRadius = pConfig.GetFloat("AvatarCapsuleRadius", parms.avatarCapsuleRadius);
263 parms.avatarCapsuleHeight = pConfig.GetFloat("AvatarCapsuleHeight", parms.avatarCapsuleHeight);
264 }
265 }
266 m_params[0] = parms;
267 }
268
269 // Called directly from unmanaged code so don't do much
270 private void BulletLogger(string msg)
271 {
272 m_log.Debug("[BULLETS UNMANAGED]:" + msg);
273 }
274
275 public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying)
276 {
277 m_log.ErrorFormat("{0}: CALL TO AddAvatar in BSScene. NOT IMPLEMENTED", LogHeader);
278 return null;
279 }
280
281 public override PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, bool isFlying)
282 {
283 // m_log.DebugFormat("{0}: AddAvatar: {1}", LogHeader, avName);
284 BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying);
285 lock (m_avatars) m_avatars.Add(localID, actor);
286 return actor;
287 }
288
289 public override void RemoveAvatar(PhysicsActor actor)
290 {
291 // m_log.DebugFormat("{0}: RemoveAvatar", LogHeader);
292 if (actor is BSCharacter)
293 {
294 ((BSCharacter)actor).Destroy();
295 }
296 try
297 {
298 lock (m_avatars) m_avatars.Remove(actor.LocalID);
299 }
300 catch (Exception e)
301 {
302 m_log.WarnFormat("{0}: Attempt to remove avatar that is not in physics scene: {1}", LogHeader, e);
303 }
304 }
305
306 public override void RemovePrim(PhysicsActor prim)
307 {
308 // m_log.DebugFormat("{0}: RemovePrim", LogHeader);
309 if (prim is BSPrim)
310 {
311 ((BSPrim)prim).Destroy();
312 }
313 try
314 {
315 lock (m_prims) m_prims.Remove(prim.LocalID);
316 }
317 catch (Exception e)
318 {
319 m_log.WarnFormat("{0}: Attempt to remove prim that is not in physics scene: {1}", LogHeader, e);
320 }
321 }
322
323 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
324 Vector3 size, Quaternion rotation, bool isPhysical, uint localID)
325 {
326 // m_log.DebugFormat("{0}: AddPrimShape2: {1}", LogHeader, primName);
327 BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical);
328 lock (m_prims) m_prims.Add(localID, prim);
329 return prim;
330 }
331
332 // This is a call from the simulator saying that some physical property has been updated.
333 // The BulletSim driver senses the changing of relevant properties so this taint
334 // information call is not needed.
335 public override void AddPhysicsActorTaint(PhysicsActor prim) { }
336
337 // Simulate one timestep
338 public override float Simulate(float timeStep)
339 {
340 int updatedEntityCount;
341 IntPtr updatedEntitiesPtr;
342 int collidersCount;
343 IntPtr collidersPtr;
344
345 // prevent simulation until we've been initialized
346 if (!m_initialized) return 10.0f;
347
348 // update the prim states while we know the physics engine is not busy
349 ProcessTaints();
350
351 // Some of the prims operate with special vehicle properties
352 ProcessVehicles(timeStep);
353 ProcessTaints(); // the vehicles might have added taints
354
355 // step the physical world one interval
356 m_simulationStep++;
357 int numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep,
358 out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr);
359
360 // Don't have to use the pointers passed back since we know it is the same pinned memory we passed in
361
362 // Get a value for 'now' so all the collision and update routines don't have to get their own
363 m_simulationNowTime = Util.EnvironmentTickCount();
364
365 // If there were collisions, process them by sending the event to the prim.
366 // Collisions must be processed before updates.
367 if (collidersCount > 0)
368 {
369 for (int ii = 0; ii < collidersCount; ii++)
370 {
371 uint cA = m_collisionArray[ii].aID;
372 uint cB = m_collisionArray[ii].bID;
373 Vector3 point = m_collisionArray[ii].point;
374 Vector3 normal = m_collisionArray[ii].normal;
375 SendCollision(cA, cB, point, normal, 0.01f);
376 SendCollision(cB, cA, point, -normal, 0.01f);
377 }
378 }
379
380 // If any of the objects had updated properties, tell the object it has been changed by the physics engine
381 if (updatedEntityCount > 0)
382 {
383 for (int ii = 0; ii < updatedEntityCount; ii++)
384 {
385 EntityProperties entprop = m_updateArray[ii];
386 // m_log.DebugFormat("{0}: entprop[{1}]: id={2}, pos={3}", LogHeader, ii, entprop.ID, entprop.Position);
387 BSCharacter actor;
388 if (m_avatars.TryGetValue(entprop.ID, out actor))
389 {
390 actor.UpdateProperties(entprop);
391 continue;
392 }
393 BSPrim prim;
394 if (m_prims.TryGetValue(entprop.ID, out prim))
395 {
396 prim.UpdateProperties(entprop);
397 }
398 }
399 }
400
401 // TODO: FIX THIS: fps calculation wrong. This calculation always returns about 1 in normal operation.
402 return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f;
403 }
404
405 // Something has collided
406 private void SendCollision(uint localID, uint collidingWith, Vector3 collidePoint, Vector3 collideNormal, float penitration)
407 {
408 if (localID == TERRAIN_ID || localID == GROUNDPLANE_ID)
409 {
410 return; // don't send collisions to the terrain
411 }
412
413 ActorTypes type = ActorTypes.Prim;
414 if (collidingWith == TERRAIN_ID || collidingWith == GROUNDPLANE_ID)
415 type = ActorTypes.Ground;
416 else if (m_avatars.ContainsKey(collidingWith))
417 type = ActorTypes.Agent;
418
419 BSPrim prim;
420 if (m_prims.TryGetValue(localID, out prim)) {
421 prim.Collide(collidingWith, type, collidePoint, collideNormal, penitration);
422 return;
423 }
424 BSCharacter actor;
425 if (m_avatars.TryGetValue(localID, out actor)) {
426 actor.Collide(collidingWith, type, collidePoint, collideNormal, penitration);
427 return;
428 }
429 return;
430 }
431
432 public override void GetResults() { }
433
434 public override void SetTerrain(float[] heightMap) {
435 m_heightMap = heightMap;
436 this.TaintedObject(delegate()
437 {
438 BulletSimAPI.SetHeightmap(m_worldID, m_heightMap);
439 });
440 }
441
442 public float GetTerrainHeightAtXY(float tX, float tY)
443 {
444 return m_heightMap[((int)tX) * Constants.RegionSize + ((int)tY)];
445 }
446
447 public override void SetWaterLevel(float baseheight)
448 {
449 m_waterLevel = baseheight;
450 }
451 public float GetWaterLevel()
452 {
453 return m_waterLevel;
454 }
455
456 public override void DeleteTerrain()
457 {
458 m_log.DebugFormat("{0}: DeleteTerrain()", LogHeader);
459 }
460
461 public override void Dispose()
462 {
463 m_log.DebugFormat("{0}: Dispose()", LogHeader);
464 }
465
466 public override Dictionary<uint, float> GetTopColliders()
467 {
468 return new Dictionary<uint, float>();
469 }
470
471 public override bool IsThreaded { get { return false; } }
472
473 /// <summary>
474 /// Routine to figure out if we need to mesh this prim with our mesher
475 /// </summary>
476 /// <param name="pbs"></param>
477 /// <returns>true if the prim needs meshing</returns>
478 public bool NeedsMeshing(PrimitiveBaseShape pbs)
479 {
480 // most of this is redundant now as the mesher will return null if it cant mesh a prim
481 // but we still need to check for sculptie meshing being enabled so this is the most
482 // convenient place to do it for now...
483
484 // int iPropertiesNotSupportedDefault = 0;
485
486 if (pbs.SculptEntry && !_meshSculptedPrim)
487 {
488 // Render sculpties as boxes
489 return false;
490 }
491
492 // if it's a standard box or sphere with no cuts, hollows, twist or top shear, return false since Bullet
493 // can use an internal representation for the prim
494 if (!_forceSimplePrimMeshing)
495 {
496 if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight)
497 || (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1
498 && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z))
499 {
500
501 if (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0
502 && pbs.ProfileHollow == 0
503 && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0
504 && pbs.PathBegin == 0 && pbs.PathEnd == 0
505 && pbs.PathTaperX == 0 && pbs.PathTaperY == 0
506 && pbs.PathScaleX == 100 && pbs.PathScaleY == 100
507 && pbs.PathShearX == 0 && pbs.PathShearY == 0)
508 {
509 return false;
510 }
511 }
512 }
513
514 /* TODO: verify that the mesher will now do all these shapes
515 if (pbs.ProfileHollow != 0)
516 iPropertiesNotSupportedDefault++;
517
518 if ((pbs.PathBegin != 0) || pbs.PathEnd != 0)
519 iPropertiesNotSupportedDefault++;
520
521 if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0))
522 iPropertiesNotSupportedDefault++;
523
524 if ((pbs.ProfileBegin != 0) || pbs.ProfileEnd != 0)
525 iPropertiesNotSupportedDefault++;
526
527 if ((pbs.PathScaleX != 100) || (pbs.PathScaleY != 100))
528 iPropertiesNotSupportedDefault++;
529
530 if ((pbs.PathShearX != 0) || (pbs.PathShearY != 0))
531 iPropertiesNotSupportedDefault++;
532
533 if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight)
534 iPropertiesNotSupportedDefault++;
535
536 if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 && (pbs.Scale.X != pbs.Scale.Y || pbs.Scale.Y != pbs.Scale.Z || pbs.Scale.Z != pbs.Scale.X))
537 iPropertiesNotSupportedDefault++;
538
539 if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte) Extrusion.Curve1)
540 iPropertiesNotSupportedDefault++;
541
542 // test for torus
543 if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Square)
544 {
545 if (pbs.PathCurve == (byte)Extrusion.Curve1)
546 {
547 iPropertiesNotSupportedDefault++;
548 }
549 }
550 else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
551 {
552 if (pbs.PathCurve == (byte)Extrusion.Straight)
553 {
554 iPropertiesNotSupportedDefault++;
555 }
556 // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
557 else if (pbs.PathCurve == (byte)Extrusion.Curve1)
558 {
559 iPropertiesNotSupportedDefault++;
560 }
561 }
562 else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
563 {
564 if (pbs.PathCurve == (byte)Extrusion.Curve1 || pbs.PathCurve == (byte)Extrusion.Curve2)
565 {
566 iPropertiesNotSupportedDefault++;
567 }
568 }
569 else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
570 {
571 if (pbs.PathCurve == (byte)Extrusion.Straight)
572 {
573 iPropertiesNotSupportedDefault++;
574 }
575 else if (pbs.PathCurve == (byte)Extrusion.Curve1)
576 {
577 iPropertiesNotSupportedDefault++;
578 }
579 }
580 if (iPropertiesNotSupportedDefault == 0)
581 {
582 return false;
583 }
584 */
585 return true;
586 }
587
588 // The calls to the PhysicsActors can't directly call into the physics engine
589 // because it might be busy. We we delay changes to a known time.
590 // We rely on C#'s closure to save and restore the context for the delegate.
591 public void TaintedObject(TaintCallback callback)
592 {
593 lock (_taintLock)
594 _taintedObjects.Add(callback);
595 return;
596 }
597
598 // When someone tries to change a property on a BSPrim or BSCharacter, the object queues
599 // a callback into itself to do the actual property change. That callback is called
600 // here just before the physics engine is called to step the simulation.
601 public void ProcessTaints()
602 {
603 if (_taintedObjects.Count > 0) // save allocating new list if there is nothing to process
604 {
605 // swizzle a new list into the list location so we can process what's there
606 List<TaintCallback> oldList;
607 lock (_taintLock)
608 {
609 oldList = _taintedObjects;
610 _taintedObjects = new List<TaintCallback>();
611 }
612
613 foreach (TaintCallback callback in oldList)
614 {
615 try
616 {
617 callback();
618 }
619 catch (Exception e)
620 {
621 m_log.ErrorFormat("{0}: ProcessTaints: Exception: {1}", LogHeader, e);
622 }
623 }
624 oldList.Clear();
625 }
626 }
627
628 #region Vehicles
629 // Make so the scene will call this prim for vehicle actions each tick.
630 // Safe to call if prim is already in the vehicle list.
631 public void AddVehiclePrim(BSPrim vehicle)
632 {
633 lock (m_vehicles)
634 {
635 if (!m_vehicles.Contains(vehicle))
636 {
637 m_vehicles.Add(vehicle);
638 }
639 }
640 }
641
642 // Remove a prim from our list of vehicles.
643 // Safe to call if the prim is not in the vehicle list.
644 public void RemoveVehiclePrim(BSPrim vehicle)
645 {
646 lock (m_vehicles)
647 {
648 if (m_vehicles.Contains(vehicle))
649 {
650 m_vehicles.Remove(vehicle);
651 }
652 }
653 }
654
655 // Some prims have extra vehicle actions
656 // no locking because only called when physics engine is not busy
657 private void ProcessVehicles(float timeStep)
658 {
659 foreach (BSPrim prim in m_vehicles)
660 {
661 prim.StepVehicle(timeStep);
662 }
663 }
664 #endregion Vehicles
665
666 #region Runtime settable parameters
667 public static PhysParameterEntry[] SettableParameters = new PhysParameterEntry[]
668 {
669 new PhysParameterEntry("MeshLOD", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)"),
670 new PhysParameterEntry("SculptLOD", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)"),
671 new PhysParameterEntry("MaxSubStep", "In simulation step, maximum number of substeps"),
672 new PhysParameterEntry("FixedTimeStep", "In simulation step, seconds of one substep (1/60)"),
673 new PhysParameterEntry("MaxObjectMass", "Maximum object mass (10000.01)"),
674
675 new PhysParameterEntry("DefaultFriction", "Friction factor used on new objects"),
676 new PhysParameterEntry("DefaultDensity", "Density for new objects" ),
677 new PhysParameterEntry("DefaultRestitution", "Bouncyness of an object" ),
678 // new PhysParameterEntry("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!!)" ),
679 new PhysParameterEntry("Gravity", "Vertical force of gravity (negative means down)" ),
680
681 new PhysParameterEntry("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)" ),
682 new PhysParameterEntry("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)" ),
683 new PhysParameterEntry("DeactivationTime", "Seconds before considering an object potentially static" ),
684 new PhysParameterEntry("LinearSleepingThreshold", "Seconds to measure linear movement before considering static" ),
685 new PhysParameterEntry("AngularSleepingThreshold", "Seconds to measure angular movement before considering static" ),
686 // new PhysParameterEntry("CcdMotionThreshold", "" ),
687 // new PhysParameterEntry("CcdSweptSphereRadius", "" ),
688
689 new PhysParameterEntry("TerrainFriction", "Factor to reduce movement against terrain surface" ),
690 new PhysParameterEntry("TerrainHitFraction", "Distance to measure hit collisions" ),
691 new PhysParameterEntry("TerrainRestitution", "Bouncyness" ),
692 new PhysParameterEntry("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation." ),
693 new PhysParameterEntry("AvatarDensity", "Density of an avatar. Changed on avatar recreation." ),
694 new PhysParameterEntry("AvatarRestitution", "Bouncyness. Changed on avatar recreation." ),
695 new PhysParameterEntry("AvatarCapsuleRadius", "Radius of space around an avatar" ),
696 new PhysParameterEntry("AvatarCapsuleHeight", "Default height of space around avatar" )
697 };
698
699 #region IPhysicsParameters
700 // Get the list of parameters this physics engine supports
701 public PhysParameterEntry[] GetParameterList()
702 {
703 return SettableParameters;
704 }
705
706 // Set parameter on a specific or all instances.
707 // Return 'false' if not able to set the parameter.
708 // Setting the value in the m_params block will change the value the physics engine
709 // will use the next time since it's pinned and shared memory.
710 // Some of the values require calling into the physics engine to get the new
711 // value activated ('terrainFriction' for instance).
712 public bool SetPhysicsParameter(string parm, float val, uint localID)
713 {
714 bool ret = true;
715 string lparm = parm.ToLower();
716 switch (lparm)
717 {
718 case "meshlod": m_meshLOD = (int)val; break;
719 case "sculptlod": m_sculptLOD = (int)val; break;
720 case "maxsubstep": m_maxSubSteps = (int)val; break;
721 case "fixedtimestep": m_fixedTimeStep = val; break;
722 case "maxobjectmass": m_maximumObjectMass = val; break;
723
724 case "defaultfriction": m_params[0].defaultFriction = val; break;
725 case "defaultdensity": m_params[0].defaultDensity = val; break;
726 case "defaultrestitution": m_params[0].defaultRestitution = val; break;
727 case "collisionmargin": m_params[0].collisionMargin = val; break;
728 case "gravity": m_params[0].gravity = val; TaintedUpdateParameter(lparm, PhysParameterEntry.APPLY_TO_NONE, val); break;
729
730 case "lineardamping": UpdateParameterPrims(ref m_params[0].linearDamping, lparm, localID, val); break;
731 case "angulardamping": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break;
732 case "deactivationtime": UpdateParameterPrims(ref m_params[0].deactivationTime, lparm, localID, val); break;
733 case "linearsleepingthreshold": UpdateParameterPrims(ref m_params[0].linearSleepingThreshold, lparm, localID, val); break;
734 case "angularsleepingthreshold": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break;
735 case "ccdmotionthreshold": UpdateParameterPrims(ref m_params[0].ccdMotionThreshold, lparm, localID, val); break;
736 case "ccdsweptsphereradius": UpdateParameterPrims(ref m_params[0].ccdSweptSphereRadius, lparm, localID, val); break;
737
738 // set a terrain physical feature and cause terrain to be recalculated
739 case "terrainfriction": m_params[0].terrainFriction = val; TaintedUpdateParameter("terrain", 0, val); break;
740 case "terrainhitfraction": m_params[0].terrainHitFraction = val; TaintedUpdateParameter("terrain", 0, val); break;
741 case "terrainrestitution": m_params[0].terrainRestitution = val; TaintedUpdateParameter("terrain", 0, val); break;
742 // set an avatar physical feature and cause avatar(s) to be recalculated
743 case "avatarfriction": UpdateParameterAvatars(ref m_params[0].avatarFriction, "avatar", localID, val); break;
744 case "avatardensity": UpdateParameterAvatars(ref m_params[0].avatarDensity, "avatar", localID, val); break;
745 case "avatarrestitution": UpdateParameterAvatars(ref m_params[0].avatarRestitution, "avatar", localID, val); break;
746 case "avatarcapsuleradius": UpdateParameterAvatars(ref m_params[0].avatarCapsuleRadius, "avatar", localID, val); break;
747 case "avatarcapsuleheight": UpdateParameterAvatars(ref m_params[0].avatarCapsuleHeight, "avatar", localID, val); break;
748
749 default: ret = false; break;
750 }
751 return ret;
752 }
753
754 // check to see if we are updating a parameter for a particular or all of the prims
755 private void UpdateParameterPrims(ref float loc, string parm, uint localID, float val)
756 {
757 List<uint> operateOn;
758 lock (m_prims) operateOn = new List<uint>(m_prims.Keys);
759 UpdateParameterSet(operateOn, ref loc, parm, localID, val);
760 }
761
762 // check to see if we are updating a parameter for a particular or all of the avatars
763 private void UpdateParameterAvatars(ref float loc, string parm, uint localID, float val)
764 {
765 List<uint> operateOn;
766 lock (m_avatars) operateOn = new List<uint>(m_avatars.Keys);
767 UpdateParameterSet(operateOn, ref loc, parm, localID, val);
768 }
769
770 // update all the localIDs specified
771 // If the local ID is APPLY_TO_NONE, just change the default value
772 // If the localID is APPLY_TO_ALL change the default value and apply the new value to all the lIDs
773 // If the localID is a specific object, apply the parameter change to only that object
774 private void UpdateParameterSet(List<uint> lIDs, ref float defaultLoc, string parm, uint localID, float val)
775 {
776 switch (localID)
777 {
778 case PhysParameterEntry.APPLY_TO_NONE:
779 defaultLoc = val; // setting only the default value
780 break;
781 case PhysParameterEntry.APPLY_TO_ALL:
782 defaultLoc = val; // setting ALL also sets the default value
783 List<uint> objectIDs = lIDs;
784 string xparm = parm.ToLower();
785 float xval = val;
786 TaintedObject(delegate() {
787 foreach (uint lID in objectIDs)
788 {
789 BulletSimAPI.UpdateParameter(m_worldID, lID, xparm, xval);
790 }
791 });
792 break;
793 default:
794 // setting only one localID
795 TaintedUpdateParameter(parm, localID, val);
796 break;
797 }
798 }
799
800 // schedule the actual updating of the paramter to when the phys engine is not busy
801 private void TaintedUpdateParameter(string parm, uint localID, float val)
802 {
803 uint xlocalID = localID;
804 string xparm = parm.ToLower();
805 float xval = val;
806 TaintedObject(delegate() {
807 BulletSimAPI.UpdateParameter(m_worldID, xlocalID, xparm, xval);
808 });
809 }
810
811 // Get parameter.
812 // Return 'false' if not able to get the parameter.
813 public bool GetPhysicsParameter(string parm, out float value)
814 {
815 float val = 0f;
816 bool ret = true;
817 switch (parm.ToLower())
818 {
819 case "meshlod": val = (float)m_meshLOD; break;
820 case "sculptlod": val = (float)m_sculptLOD; break;
821 case "maxsubstep": val = (float)m_maxSubSteps; break;
822 case "fixedtimestep": val = m_fixedTimeStep; break;
823 case "maxobjectmass": val = m_maximumObjectMass; break;
824
825 case "defaultfriction": val = m_params[0].defaultFriction; break;
826 case "defaultdensity": val = m_params[0].defaultDensity; break;
827 case "defaultrestitution": val = m_params[0].defaultRestitution; break;
828 case "collisionmargin": val = m_params[0].collisionMargin; break;
829 case "gravity": val = m_params[0].gravity; break;
830
831 case "lineardamping": val = m_params[0].linearDamping; break;
832 case "angulardamping": val = m_params[0].angularDamping; break;
833 case "deactivationtime": val = m_params[0].deactivationTime; break;
834 case "linearsleepingthreshold": val = m_params[0].linearSleepingThreshold; break;
835 case "angularsleepingthreshold": val = m_params[0].angularDamping; break;
836 case "ccdmotionthreshold": val = m_params[0].ccdMotionThreshold; break;
837 case "ccdsweptsphereradius": val = m_params[0].ccdSweptSphereRadius; break;
838
839 case "terrainfriction": val = m_params[0].terrainFriction; break;
840 case "terrainhitfraction": val = m_params[0].terrainHitFraction; break;
841 case "terrainrestitution": val = m_params[0].terrainRestitution; break;
842
843 case "avatarfriction": val = m_params[0].avatarFriction; break;
844 case "avatardensity": val = m_params[0].avatarDensity; break;
845 case "avatarrestitution": val = m_params[0].avatarRestitution; break;
846 case "avatarcapsuleradius": val = m_params[0].avatarCapsuleRadius; break;
847 case "avatarcapsuleheight": val = m_params[0].avatarCapsuleHeight; break;
848 default: ret = false; break;
849
850 }
851 value = val;
852 return ret;
853 }
854
855 #endregion IPhysicsParameters
856
857 #endregion Runtime settable parameters
858
859}
860}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
new file mode 100644
index 0000000..a610c8d
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
@@ -0,0 +1,257 @@
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.Runtime.InteropServices;
29using System.Security;
30using System.Text;
31using OpenMetaverse;
32
33namespace OpenSim.Region.Physics.BulletSPlugin {
34
35[StructLayout(LayoutKind.Sequential)]
36public struct ConvexHull
37{
38 Vector3 Offset;
39 int VertexCount;
40 Vector3[] Vertices;
41}
42[StructLayout(LayoutKind.Sequential)]
43public struct ShapeData
44{
45 public enum PhysicsShapeType
46 {
47 SHAPE_AVATAR = 0,
48 SHAPE_BOX = 1,
49 SHAPE_CONE = 2,
50 SHAPE_CYLINDER = 3,
51 SHAPE_SPHERE = 4,
52 SHAPE_MESH = 5,
53 SHAPE_HULL = 6
54 };
55 public uint ID;
56 public PhysicsShapeType Type;
57 public Vector3 Position;
58 public Quaternion Rotation;
59 public Vector3 Velocity;
60 public Vector3 Scale;
61 public float Mass;
62 public float Buoyancy;
63 public System.UInt64 HullKey;
64 public System.UInt64 MeshKey;
65 public float Friction;
66 public float Restitution;
67 public int Collidable;
68 public int Static; // true if a static object. Otherwise gravity, etc.
69
70 // note that bools are passed as ints since bool size changes by language and architecture
71 public const int numericTrue = 1;
72 public const int numericFalse = 0;
73}
74[StructLayout(LayoutKind.Sequential)]
75public struct SweepHit
76{
77 public uint ID;
78 public float Fraction;
79 public Vector3 Normal;
80 public Vector3 Point;
81}
82[StructLayout(LayoutKind.Sequential)]
83public struct RaycastHit
84{
85 public uint ID;
86 public float Fraction;
87 public Vector3 Normal;
88}
89[StructLayout(LayoutKind.Sequential)]
90public struct CollisionDesc
91{
92 public uint aID;
93 public uint bID;
94 public Vector3 point;
95 public Vector3 normal;
96}
97[StructLayout(LayoutKind.Sequential)]
98public struct EntityProperties
99{
100 public uint ID;
101 public Vector3 Position;
102 public Quaternion Rotation;
103 public Vector3 Velocity;
104 public Vector3 Acceleration;
105 public Vector3 RotationalVelocity;
106}
107
108// Format of this structure must match the definition in the C++ code
109[StructLayout(LayoutKind.Sequential)]
110public struct ConfigurationParameters
111{
112 public float defaultFriction;
113 public float defaultDensity;
114 public float defaultRestitution;
115 public float collisionMargin;
116 public float gravity;
117
118 public float linearDamping;
119 public float angularDamping;
120 public float deactivationTime;
121 public float linearSleepingThreshold;
122 public float angularSleepingThreshold;
123 public float ccdMotionThreshold;
124 public float ccdSweptSphereRadius;
125
126 public float terrainFriction;
127 public float terrainHitFraction;
128 public float terrainRestitution;
129 public float avatarFriction;
130 public float avatarDensity;
131 public float avatarRestitution;
132 public float avatarCapsuleRadius;
133 public float avatarCapsuleHeight;
134
135 public const float numericTrue = 1f;
136 public const float numericFalse = 0f;
137}
138
139static class BulletSimAPI {
140
141[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
142[return: MarshalAs(UnmanagedType.LPStr)]
143public static extern string GetVersion();
144
145[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
146public static extern uint Initialize(Vector3 maxPosition, IntPtr parms,
147 int maxCollisions, IntPtr collisionArray,
148 int maxUpdates, IntPtr updateArray);
149
150[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
151public static extern bool UpdateParameter(uint worldID, uint localID,
152 [MarshalAs(UnmanagedType.LPStr)]string paramCode, float value);
153
154[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
155public static extern void SetHeightmap(uint worldID, [MarshalAs(UnmanagedType.LPArray)] float[] heightMap);
156
157[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
158public static extern void Shutdown(uint worldID);
159
160
161[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
162public static extern int PhysicsStep(uint worldID, float timeStep, int maxSubSteps, float fixedTimeStep,
163 out int updatedEntityCount,
164 out IntPtr updatedEntitiesPtr,
165 out int collidersCount,
166 out IntPtr collidersPtr);
167
168[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
169public static extern bool CreateHull(uint worldID, System.UInt64 meshKey,
170 int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls
171 );
172
173[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
174public static extern bool CreateMesh(uint worldID, System.UInt64 meshKey,
175 int indexCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices,
176 int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices
177 );
178
179[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
180public static extern bool DestroyHull(uint worldID, System.UInt64 meshKey);
181
182[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
183public static extern bool DestroyMesh(uint worldID, System.UInt64 meshKey);
184
185[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
186public static extern bool CreateObject(uint worldID, ShapeData shapeData);
187
188[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
189public static extern void CreateLinkset(uint worldID, int objectCount, ShapeData[] shapeDatas);
190
191[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
192public static extern void AddConstraint(uint worldID, uint id1, uint id2,
193 Vector3 frame1, Quaternion frame1rot,
194 Vector3 frame2, Quaternion frame2rot,
195 Vector3 lowLinear, Vector3 hiLinear, Vector3 lowAngular, Vector3 hiAngular);
196
197[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
198public static extern bool RemoveConstraintByID(uint worldID, uint id1);
199
200[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
201public static extern bool RemoveConstraint(uint worldID, uint id1, uint id2);
202
203[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
204public static extern Vector3 GetObjectPosition(uint WorldID, uint id);
205
206[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
207public static extern bool SetObjectTranslation(uint worldID, uint id, Vector3 position, Quaternion rotation);
208
209[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
210public static extern bool SetObjectVelocity(uint worldID, uint id, Vector3 velocity);
211
212[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
213public static extern bool SetObjectAngularVelocity(uint worldID, uint id, Vector3 angularVelocity);
214
215[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
216public static extern bool SetObjectForce(uint worldID, uint id, Vector3 force);
217
218[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
219public static extern bool SetObjectScaleMass(uint worldID, uint id, Vector3 scale, float mass, bool isDynamic);
220
221[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
222public static extern bool SetObjectCollidable(uint worldID, uint id, bool phantom);
223
224[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
225public static extern bool SetObjectDynamic(uint worldID, uint id, bool isDynamic, float mass);
226
227[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
228public static extern bool SetObjectGhost(uint worldID, uint id, bool ghostly);
229
230[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
231public static extern bool SetObjectProperties(uint worldID, uint id, bool isStatic, bool isSolid, bool genCollisions, float mass);
232
233[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
234public static extern bool SetObjectBuoyancy(uint worldID, uint id, float buoyancy);
235
236[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
237public static extern bool HasObject(uint worldID, uint id);
238
239[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
240public static extern bool DestroyObject(uint worldID, uint id);
241
242[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
243public static extern SweepHit ConvexSweepTest(uint worldID, uint id, Vector3 to, float extraMargin);
244
245[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
246public static extern RaycastHit RayTest(uint worldID, uint id, Vector3 from, Vector3 to);
247
248[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
249public static extern Vector3 RecoverFromPenetration(uint worldID, uint id);
250
251// Log a debug message
252[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
253public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg);
254[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
255public static extern void SetDebugLogCallback(DebugLogCallback callback);
256}
257}
diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/CTri.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/CTri.cs
new file mode 100644
index 0000000..4d84c44
--- /dev/null
+++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/CTri.cs
@@ -0,0 +1,341 @@
1/* The MIT License
2 *
3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved.
5 *
6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
27
28using System;
29using System.Collections.Generic;
30
31namespace OpenSim.Region.Physics.ConvexDecompositionDotNet
32{
33 public class Wpoint
34 {
35 public float3 mPoint;
36 public float mWeight;
37
38 public Wpoint(float3 p, float w)
39 {
40 mPoint = p;
41 mWeight = w;
42 }
43 }
44
45 public class CTri
46 {
47 private const int WSCALE = 4;
48
49 public float3 mP1;
50 public float3 mP2;
51 public float3 mP3;
52 public float3 mNear1;
53 public float3 mNear2;
54 public float3 mNear3;
55 public float3 mNormal;
56 public float mPlaneD;
57 public float mConcavity;
58 public float mC1;
59 public float mC2;
60 public float mC3;
61 public int mI1;
62 public int mI2;
63 public int mI3;
64 public int mProcessed; // already been added...
65
66 public CTri(float3 p1, float3 p2, float3 p3, int i1, int i2, int i3)
67 {
68 mProcessed = 0;
69 mI1 = i1;
70 mI2 = i2;
71 mI3 = i3;
72
73 mP1 = new float3(p1);
74 mP2 = new float3(p2);
75 mP3 = new float3(p3);
76
77 mNear1 = new float3();
78 mNear2 = new float3();
79 mNear3 = new float3();
80
81 mNormal = new float3();
82 mPlaneD = mNormal.ComputePlane(mP1, mP2, mP3);
83 }
84
85 public float Facing(CTri t)
86 {
87 return float3.dot(mNormal, t.mNormal);
88 }
89
90 public bool clip(float3 start, ref float3 end)
91 {
92 float3 sect = new float3();
93 bool hit = lineIntersectsTriangle(start, end, mP1, mP2, mP3, ref sect);
94
95 if (hit)
96 end = sect;
97 return hit;
98 }
99
100 public bool Concave(float3 p, ref float distance, ref float3 n)
101 {
102 n.NearestPointInTriangle(p, mP1, mP2, mP3);
103 distance = p.Distance(n);
104 return true;
105 }
106
107 public void addTri(int[] indices, int i1, int i2, int i3, ref int tcount)
108 {
109 indices[tcount * 3 + 0] = i1;
110 indices[tcount * 3 + 1] = i2;
111 indices[tcount * 3 + 2] = i3;
112 tcount++;
113 }
114
115 public float getVolume()
116 {
117 int[] indices = new int[8 * 3];
118
119 int tcount = 0;
120
121 addTri(indices, 0, 1, 2, ref tcount);
122 addTri(indices, 3, 4, 5, ref tcount);
123
124 addTri(indices, 0, 3, 4, ref tcount);
125 addTri(indices, 0, 4, 1, ref tcount);
126
127 addTri(indices, 1, 4, 5, ref tcount);
128 addTri(indices, 1, 5, 2, ref tcount);
129
130 addTri(indices, 0, 3, 5, ref tcount);
131 addTri(indices, 0, 5, 2, ref tcount);
132
133 List<float3> vertices = new List<float3> { mP1, mP2, mP3, mNear1, mNear2, mNear3 };
134 List<int> indexList = new List<int>(indices);
135
136 float v = Concavity.computeMeshVolume(vertices, indexList);
137 return v;
138 }
139
140 public float raySect(float3 p, float3 dir, ref float3 sect)
141 {
142 float4 plane = new float4();
143
144 plane.x = mNormal.x;
145 plane.y = mNormal.y;
146 plane.z = mNormal.z;
147 plane.w = mPlaneD;
148
149 float3 dest = p + dir * 100000f;
150
151 intersect(p, dest, ref sect, plane);
152
153 return sect.Distance(p); // return the intersection distance
154 }
155
156 public float planeDistance(float3 p)
157 {
158 float4 plane = new float4();
159
160 plane.x = mNormal.x;
161 plane.y = mNormal.y;
162 plane.z = mNormal.z;
163 plane.w = mPlaneD;
164
165 return DistToPt(p, plane);
166 }
167
168 public bool samePlane(CTri t)
169 {
170 const float THRESH = 0.001f;
171 float dd = Math.Abs(t.mPlaneD - mPlaneD);
172 if (dd > THRESH)
173 return false;
174 dd = Math.Abs(t.mNormal.x - mNormal.x);
175 if (dd > THRESH)
176 return false;
177 dd = Math.Abs(t.mNormal.y - mNormal.y);
178 if (dd > THRESH)
179 return false;
180 dd = Math.Abs(t.mNormal.z - mNormal.z);
181 if (dd > THRESH)
182 return false;
183 return true;
184 }
185
186 public bool hasIndex(int i)
187 {
188 if (i == mI1 || i == mI2 || i == mI3)
189 return true;
190 return false;
191 }
192
193 public bool sharesEdge(CTri t)
194 {
195 bool ret = false;
196 uint count = 0;
197
198 if (t.hasIndex(mI1))
199 count++;
200 if (t.hasIndex(mI2))
201 count++;
202 if (t.hasIndex(mI3))
203 count++;
204
205 if (count >= 2)
206 ret = true;
207
208 return ret;
209 }
210
211 public float area()
212 {
213 float a = mConcavity * mP1.Area(mP2, mP3);
214 return a;
215 }
216
217 public void addWeighted(List<Wpoint> list)
218 {
219 Wpoint p1 = new Wpoint(mP1, mC1);
220 Wpoint p2 = new Wpoint(mP2, mC2);
221 Wpoint p3 = new Wpoint(mP3, mC3);
222
223 float3 d1 = mNear1 - mP1;
224 float3 d2 = mNear2 - mP2;
225 float3 d3 = mNear3 - mP3;
226
227 d1 *= WSCALE;
228 d2 *= WSCALE;
229 d3 *= WSCALE;
230
231 d1 = d1 + mP1;
232 d2 = d2 + mP2;
233 d3 = d3 + mP3;
234
235 Wpoint p4 = new Wpoint(d1, mC1);
236 Wpoint p5 = new Wpoint(d2, mC2);
237 Wpoint p6 = new Wpoint(d3, mC3);
238
239 list.Add(p1);
240 list.Add(p2);
241 list.Add(p3);
242
243 list.Add(p4);
244 list.Add(p5);
245 list.Add(p6);
246 }
247
248 private static float DistToPt(float3 p, float4 plane)
249 {
250 float x = p.x;
251 float y = p.y;
252 float z = p.z;
253 float d = x*plane.x + y*plane.y + z*plane.z + plane.w;
254 return d;
255 }
256
257 private static void intersect(float3 p1, float3 p2, ref float3 split, float4 plane)
258 {
259 float dp1 = DistToPt(p1, plane);
260
261 float3 dir = new float3();
262 dir.x = p2[0] - p1[0];
263 dir.y = p2[1] - p1[1];
264 dir.z = p2[2] - p1[2];
265
266 float dot1 = dir[0] * plane[0] + dir[1] * plane[1] + dir[2] * plane[2];
267 float dot2 = dp1 - plane[3];
268
269 float t = -(plane[3] + dot2) / dot1;
270
271 split.x = (dir[0] * t) + p1[0];
272 split.y = (dir[1] * t) + p1[1];
273 split.z = (dir[2] * t) + p1[2];
274 }
275
276 private static bool rayIntersectsTriangle(float3 p, float3 d, float3 v0, float3 v1, float3 v2, out float t)
277 {
278 t = 0f;
279
280 float3 e1, e2, h, s, q;
281 float a, f, u, v;
282
283 e1 = v1 - v0;
284 e2 = v2 - v0;
285 h = float3.cross(d, e2);
286 a = float3.dot(e1, h);
287
288 if (a > -0.00001f && a < 0.00001f)
289 return false;
290
291 f = 1f / a;
292 s = p - v0;
293 u = f * float3.dot(s, h);
294
295 if (u < 0.0f || u > 1.0f)
296 return false;
297
298 q = float3.cross(s, e1);
299 v = f * float3.dot(d, q);
300 if (v < 0.0f || u + v > 1.0f)
301 return false;
302
303 // at this stage we can compute t to find out where
304 // the intersection point is on the line
305 t = f * float3.dot(e2, q);
306 if (t > 0f) // ray intersection
307 return true;
308 else // this means that there is a line intersection but not a ray intersection
309 return false;
310 }
311
312 private static bool lineIntersectsTriangle(float3 rayStart, float3 rayEnd, float3 p1, float3 p2, float3 p3, ref float3 sect)
313 {
314 float3 dir = rayEnd - rayStart;
315
316 float d = (float)Math.Sqrt(dir[0] * dir[0] + dir[1] * dir[1] + dir[2] * dir[2]);
317 float r = 1.0f / d;
318
319 dir *= r;
320
321 float t;
322 bool ret = rayIntersectsTriangle(rayStart, dir, p1, p2, p3, out t);
323
324 if (ret)
325 {
326 if (t > d)
327 {
328 sect.x = rayStart.x + dir.x * t;
329 sect.y = rayStart.y + dir.y * t;
330 sect.z = rayStart.z + dir.z * t;
331 }
332 else
333 {
334 ret = false;
335 }
336 }
337
338 return ret;
339 }
340 }
341}
diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/Concavity.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Concavity.cs
new file mode 100644
index 0000000..cc6383a
--- /dev/null
+++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Concavity.cs
@@ -0,0 +1,233 @@
1/* The MIT License
2 *
3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved.
5 *
6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Text;
31
32namespace OpenSim.Region.Physics.ConvexDecompositionDotNet
33{
34 public static class Concavity
35 {
36 // compute's how 'concave' this object is and returns the total volume of the
37 // convex hull as well as the volume of the 'concavity' which was found.
38 public static float computeConcavity(List<float3> vertices, List<int> indices, ref float4 plane, ref float volume)
39 {
40 float cret = 0f;
41 volume = 1f;
42
43 HullResult result = new HullResult();
44 HullDesc desc = new HullDesc();
45
46 desc.MaxFaces = 256;
47 desc.MaxVertices = 256;
48 desc.SetHullFlag(HullFlag.QF_TRIANGLES);
49 desc.Vertices = vertices;
50
51 HullError ret = HullUtils.CreateConvexHull(desc, ref result);
52
53 if (ret == HullError.QE_OK)
54 {
55 volume = computeMeshVolume2(result.OutputVertices, result.Indices);
56
57 // ok..now..for each triangle on the original mesh..
58 // we extrude the points to the nearest point on the hull.
59 List<CTri> tris = new List<CTri>();
60
61 for (int i = 0; i < result.Indices.Count / 3; i++)
62 {
63 int i1 = result.Indices[i * 3 + 0];
64 int i2 = result.Indices[i * 3 + 1];
65 int i3 = result.Indices[i * 3 + 2];
66
67 float3 p1 = result.OutputVertices[i1];
68 float3 p2 = result.OutputVertices[i2];
69 float3 p3 = result.OutputVertices[i3];
70
71 CTri t = new CTri(p1, p2, p3, i1, i2, i3);
72 tris.Add(t);
73 }
74
75 // we have not pre-computed the plane equation for each triangle in the convex hull..
76 float totalVolume = 0;
77
78 List<CTri> ftris = new List<CTri>(); // 'feature' triangles.
79 List<CTri> input_mesh = new List<CTri>();
80
81 for (int i = 0; i < indices.Count / 3; i++)
82 {
83 int i1 = indices[i * 3 + 0];
84 int i2 = indices[i * 3 + 1];
85 int i3 = indices[i * 3 + 2];
86
87 float3 p1 = vertices[i1];
88 float3 p2 = vertices[i2];
89 float3 p3 = vertices[i3];
90
91 CTri t = new CTri(p1, p2, p3, i1, i2, i3);
92 input_mesh.Add(t);
93 }
94
95 for (int i = 0; i < indices.Count / 3; i++)
96 {
97 int i1 = indices[i * 3 + 0];
98 int i2 = indices[i * 3 + 1];
99 int i3 = indices[i * 3 + 2];
100
101 float3 p1 = vertices[i1];
102 float3 p2 = vertices[i2];
103 float3 p3 = vertices[i3];
104
105 CTri t = new CTri(p1, p2, p3, i1, i2, i3);
106
107 featureMatch(t, tris, input_mesh);
108
109 if (t.mConcavity > 0.05f)
110 {
111 float v = t.getVolume();
112 totalVolume += v;
113 ftris.Add(t);
114 }
115 }
116
117 SplitPlane.computeSplitPlane(vertices, indices, ref plane);
118 cret = totalVolume;
119 }
120
121 return cret;
122 }
123
124 public static bool featureMatch(CTri m, List<CTri> tris, List<CTri> input_mesh)
125 {
126 bool ret = false;
127 float neardot = 0.707f;
128 m.mConcavity = 0;
129
130 for (int i = 0; i < tris.Count; i++)
131 {
132 CTri t = tris[i];
133
134 if (t.samePlane(m))
135 {
136 ret = false;
137 break;
138 }
139
140 float dot = float3.dot(t.mNormal, m.mNormal);
141
142 if (dot > neardot)
143 {
144 float d1 = t.planeDistance(m.mP1);
145 float d2 = t.planeDistance(m.mP2);
146 float d3 = t.planeDistance(m.mP3);
147
148 if (d1 > 0.001f || d2 > 0.001f || d3 > 0.001f) // can't be near coplaner!
149 {
150 neardot = dot;
151
152 t.raySect(m.mP1, m.mNormal, ref m.mNear1);
153 t.raySect(m.mP2, m.mNormal, ref m.mNear2);
154 t.raySect(m.mP3, m.mNormal, ref m.mNear3);
155
156 ret = true;
157 }
158 }
159 }
160
161 if (ret)
162 {
163 m.mC1 = m.mP1.Distance(m.mNear1);
164 m.mC2 = m.mP2.Distance(m.mNear2);
165 m.mC3 = m.mP3.Distance(m.mNear3);
166
167 m.mConcavity = m.mC1;
168
169 if (m.mC2 > m.mConcavity)
170 m.mConcavity = m.mC2;
171 if (m.mC3 > m.mConcavity)
172 m.mConcavity = m.mC3;
173 }
174
175 return ret;
176 }
177
178 private static float det(float3 p1, float3 p2, float3 p3)
179 {
180 return p1.x * p2.y * p3.z + p2.x * p3.y * p1.z + p3.x * p1.y * p2.z - p1.x * p3.y * p2.z - p2.x * p1.y * p3.z - p3.x * p2.y * p1.z;
181 }
182
183 public static float computeMeshVolume(List<float3> vertices, List<int> indices)
184 {
185 float volume = 0f;
186
187 for (int i = 0; i < indices.Count / 3; i++)
188 {
189 float3 p1 = vertices[indices[i * 3 + 0]];
190 float3 p2 = vertices[indices[i * 3 + 1]];
191 float3 p3 = vertices[indices[i * 3 + 2]];
192
193 volume += det(p1, p2, p3); // compute the volume of the tetrahedran relative to the origin.
194 }
195
196 volume *= (1.0f / 6.0f);
197 if (volume < 0f)
198 return -volume;
199 return volume;
200 }
201
202 public static float computeMeshVolume2(List<float3> vertices, List<int> indices)
203 {
204 float volume = 0f;
205
206 float3 p0 = vertices[0];
207 for (int i = 0; i < indices.Count / 3; i++)
208 {
209 float3 p1 = vertices[indices[i * 3 + 0]];
210 float3 p2 = vertices[indices[i * 3 + 1]];
211 float3 p3 = vertices[indices[i * 3 + 2]];
212
213 volume += tetVolume(p0, p1, p2, p3); // compute the volume of the tetrahedron relative to the root vertice
214 }
215
216 return volume * (1.0f / 6.0f);
217 }
218
219 private static float tetVolume(float3 p0, float3 p1, float3 p2, float3 p3)
220 {
221 float3 a = p1 - p0;
222 float3 b = p2 - p0;
223 float3 c = p3 - p0;
224
225 float3 cross = float3.cross(b, c);
226 float volume = float3.dot(a, cross);
227
228 if (volume < 0f)
229 return -volume;
230 return volume;
231 }
232 }
233}
diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/ConvexBuilder.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/ConvexBuilder.cs
new file mode 100644
index 0000000..dfaede1
--- /dev/null
+++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/ConvexBuilder.cs
@@ -0,0 +1,411 @@
1/* The MIT License
2 *
3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved.
5 *
6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Diagnostics;
31
32namespace OpenSim.Region.Physics.ConvexDecompositionDotNet
33{
34 public class DecompDesc
35 {
36 public List<float3> mVertices;
37 public List<int> mIndices;
38
39 // options
40 public uint mDepth; // depth to split, a maximum of 10, generally not over 7.
41 public float mCpercent; // the concavity threshold percentage. 0=20 is reasonable.
42 public float mPpercent; // the percentage volume conservation threshold to collapse hulls. 0-30 is reasonable.
43
44 // hull output limits.
45 public uint mMaxVertices; // maximum number of vertices in the output hull. Recommended 32 or less.
46 public float mSkinWidth; // a skin width to apply to the output hulls.
47
48 public ConvexDecompositionCallback mCallback; // the interface to receive back the results.
49
50 public DecompDesc()
51 {
52 mDepth = 5;
53 mCpercent = 5;
54 mPpercent = 5;
55 mMaxVertices = 32;
56 }
57 }
58
59 public class CHull
60 {
61 public float[] mMin = new float[3];
62 public float[] mMax = new float[3];
63 public float mVolume;
64 public float mDiagonal;
65 public ConvexResult mResult;
66
67 public CHull(ConvexResult result)
68 {
69 mResult = new ConvexResult(result);
70 mVolume = Concavity.computeMeshVolume(result.HullVertices, result.HullIndices);
71
72 mDiagonal = getBoundingRegion(result.HullVertices, mMin, mMax);
73
74 float dx = mMax[0] - mMin[0];
75 float dy = mMax[1] - mMin[1];
76 float dz = mMax[2] - mMin[2];
77
78 dx *= 0.1f; // inflate 1/10th on each edge
79 dy *= 0.1f; // inflate 1/10th on each edge
80 dz *= 0.1f; // inflate 1/10th on each edge
81
82 mMin[0] -= dx;
83 mMin[1] -= dy;
84 mMin[2] -= dz;
85
86 mMax[0] += dx;
87 mMax[1] += dy;
88 mMax[2] += dz;
89 }
90
91 public void Dispose()
92 {
93 mResult = null;
94 }
95
96 public bool overlap(CHull h)
97 {
98 return overlapAABB(mMin, mMax, h.mMin, h.mMax);
99 }
100
101 // returns the d1Giagonal distance
102 private static float getBoundingRegion(List<float3> points, float[] bmin, float[] bmax)
103 {
104 float3 first = points[0];
105
106 bmin[0] = first.x;
107 bmin[1] = first.y;
108 bmin[2] = first.z;
109
110 bmax[0] = first.x;
111 bmax[1] = first.y;
112 bmax[2] = first.z;
113
114 for (int i = 1; i < points.Count; i++)
115 {
116 float3 p = points[i];
117
118 if (p[0] < bmin[0]) bmin[0] = p[0];
119 if (p[1] < bmin[1]) bmin[1] = p[1];
120 if (p[2] < bmin[2]) bmin[2] = p[2];
121
122 if (p[0] > bmax[0]) bmax[0] = p[0];
123 if (p[1] > bmax[1]) bmax[1] = p[1];
124 if (p[2] > bmax[2]) bmax[2] = p[2];
125 }
126
127 float dx = bmax[0] - bmin[0];
128 float dy = bmax[1] - bmin[1];
129 float dz = bmax[2] - bmin[2];
130
131 return (float)Math.Sqrt(dx * dx + dy * dy + dz * dz);
132 }
133
134 // return true if the two AABB's overlap.
135 private static bool overlapAABB(float[] bmin1, float[] bmax1, float[] bmin2, float[] bmax2)
136 {
137 if (bmax2[0] < bmin1[0]) return false; // if the maximum is less than our minimum on any axis
138 if (bmax2[1] < bmin1[1]) return false;
139 if (bmax2[2] < bmin1[2]) return false;
140
141 if (bmin2[0] > bmax1[0]) return false; // if the minimum is greater than our maximum on any axis
142 if (bmin2[1] > bmax1[1]) return false; // if the minimum is greater than our maximum on any axis
143 if (bmin2[2] > bmax1[2]) return false; // if the minimum is greater than our maximum on any axis
144
145 return true; // the extents overlap
146 }
147 }
148
149 public class ConvexBuilder
150 {
151 public List<CHull> mChulls = new List<CHull>();
152 private ConvexDecompositionCallback mCallback;
153
154 private int MAXDEPTH = 8;
155 private float CONCAVE_PERCENT = 1f;
156 private float MERGE_PERCENT = 2f;
157
158 public ConvexBuilder(ConvexDecompositionCallback callback)
159 {
160 mCallback = callback;
161 }
162
163 public void Dispose()
164 {
165 int i;
166 for (i = 0; i < mChulls.Count; i++)
167 {
168 CHull cr = mChulls[i];
169 cr.Dispose();
170 }
171 }
172
173 public bool isDuplicate(uint i1, uint i2, uint i3, uint ci1, uint ci2, uint ci3)
174 {
175 uint dcount = 0;
176
177 Debug.Assert(i1 != i2 && i1 != i3 && i2 != i3);
178 Debug.Assert(ci1 != ci2 && ci1 != ci3 && ci2 != ci3);
179
180 if (i1 == ci1 || i1 == ci2 || i1 == ci3)
181 dcount++;
182 if (i2 == ci1 || i2 == ci2 || i2 == ci3)
183 dcount++;
184 if (i3 == ci1 || i3 == ci2 || i3 == ci3)
185 dcount++;
186
187 return dcount == 3;
188 }
189
190 public void getMesh(ConvexResult cr, VertexPool vc, List<int> indices)
191 {
192 List<int> src = cr.HullIndices;
193
194 for (int i = 0; i < src.Count / 3; i++)
195 {
196 int i1 = src[i * 3 + 0];
197 int i2 = src[i * 3 + 1];
198 int i3 = src[i * 3 + 2];
199
200 float3 p1 = cr.HullVertices[i1];
201 float3 p2 = cr.HullVertices[i2];
202 float3 p3 = cr.HullVertices[i3];
203
204 i1 = vc.getIndex(p1);
205 i2 = vc.getIndex(p2);
206 i3 = vc.getIndex(p3);
207 }
208 }
209
210 public CHull canMerge(CHull a, CHull b)
211 {
212 if (!a.overlap(b)) // if their AABB's (with a little slop) don't overlap, then return.
213 return null;
214
215 CHull ret = null;
216
217 // ok..we are going to combine both meshes into a single mesh
218 // and then we are going to compute the concavity...
219
220 VertexPool vc = new VertexPool();
221
222 List<int> indices = new List<int>();
223
224 getMesh(a.mResult, vc, indices);
225 getMesh(b.mResult, vc, indices);
226
227 int vcount = vc.GetSize();
228 List<float3> vertices = vc.GetVertices();
229 int tcount = indices.Count / 3;
230
231 //don't do anything if hull is empty
232 if (tcount == 0)
233 {
234 vc.Clear();
235 return null;
236 }
237
238 HullResult hresult = new HullResult();
239 HullDesc desc = new HullDesc();
240
241 desc.SetHullFlag(HullFlag.QF_TRIANGLES);
242 desc.Vertices = vertices;
243
244 HullError hret = HullUtils.CreateConvexHull(desc, ref hresult);
245
246 if (hret == HullError.QE_OK)
247 {
248 float combineVolume = Concavity.computeMeshVolume(hresult.OutputVertices, hresult.Indices);
249 float sumVolume = a.mVolume + b.mVolume;
250
251 float percent = (sumVolume * 100) / combineVolume;
252 if (percent >= (100.0f - MERGE_PERCENT))
253 {
254 ConvexResult cr = new ConvexResult(hresult.OutputVertices, hresult.Indices);
255 ret = new CHull(cr);
256 }
257 }
258
259 vc.Clear();
260 return ret;
261 }
262
263 public bool combineHulls()
264 {
265 bool combine = false;
266
267 sortChulls(mChulls); // sort the convex hulls, largest volume to least...
268
269 List<CHull> output = new List<CHull>(); // the output hulls...
270
271 int i;
272 for (i = 0; i < mChulls.Count && !combine; ++i)
273 {
274 CHull cr = mChulls[i];
275
276 int j;
277 for (j = 0; j < mChulls.Count; j++)
278 {
279 CHull match = mChulls[j];
280
281 if (cr != match) // don't try to merge a hull with itself, that be stoopid
282 {
283
284 CHull merge = canMerge(cr, match); // if we can merge these two....
285
286 if (merge != null)
287 {
288 output.Add(merge);
289
290 ++i;
291 while (i != mChulls.Count)
292 {
293 CHull cr2 = mChulls[i];
294 if (cr2 != match)
295 {
296 output.Add(cr2);
297 }
298 i++;
299 }
300
301 cr.Dispose();
302 match.Dispose();
303 combine = true;
304 break;
305 }
306 }
307 }
308
309 if (combine)
310 {
311 break;
312 }
313 else
314 {
315 output.Add(cr);
316 }
317 }
318
319 if (combine)
320 {
321 mChulls.Clear();
322 mChulls = output;
323 output.Clear();
324 }
325
326 return combine;
327 }
328
329 public int process(DecompDesc desc)
330 {
331 int ret = 0;
332
333 MAXDEPTH = (int)desc.mDepth;
334 CONCAVE_PERCENT = desc.mCpercent;
335 MERGE_PERCENT = desc.mPpercent;
336
337 ConvexDecomposition.calcConvexDecomposition(desc.mVertices, desc.mIndices, ConvexDecompResult, 0f, 0, MAXDEPTH, CONCAVE_PERCENT, MERGE_PERCENT);
338
339 while (combineHulls()) // keep combinging hulls until I can't combine any more...
340 ;
341
342 int i;
343 for (i = 0; i < mChulls.Count; i++)
344 {
345 CHull cr = mChulls[i];
346
347 // before we hand it back to the application, we need to regenerate the hull based on the
348 // limits given by the user.
349
350 ConvexResult c = cr.mResult; // the high resolution hull...
351
352 HullResult result = new HullResult();
353 HullDesc hdesc = new HullDesc();
354
355 hdesc.SetHullFlag(HullFlag.QF_TRIANGLES);
356
357 hdesc.Vertices = c.HullVertices;
358 hdesc.MaxVertices = desc.mMaxVertices; // maximum number of vertices allowed in the output
359
360 if (desc.mSkinWidth != 0f)
361 {
362 hdesc.SkinWidth = desc.mSkinWidth;
363 hdesc.SetHullFlag(HullFlag.QF_SKIN_WIDTH); // do skin width computation.
364 }
365
366 HullError ret2 = HullUtils.CreateConvexHull(hdesc, ref result);
367
368 if (ret2 == HullError.QE_OK)
369 {
370 ConvexResult r = new ConvexResult(result.OutputVertices, result.Indices);
371
372 r.mHullVolume = Concavity.computeMeshVolume(result.OutputVertices, result.Indices); // the volume of the hull.
373
374 // compute the best fit OBB
375 //computeBestFitOBB(result.mNumOutputVertices, result.mOutputVertices, sizeof(float) * 3, r.mOBBSides, r.mOBBTransform);
376
377 //r.mOBBVolume = r.mOBBSides[0] * r.mOBBSides[1] * r.mOBBSides[2]; // compute the OBB volume.
378
379 //fm_getTranslation(r.mOBBTransform, r.mOBBCenter); // get the translation component of the 4x4 matrix.
380
381 //fm_matrixToQuat(r.mOBBTransform, r.mOBBOrientation); // extract the orientation as a quaternion.
382
383 //r.mSphereRadius = computeBoundingSphere(result.mNumOutputVertices, result.mOutputVertices, r.mSphereCenter);
384 //r.mSphereVolume = fm_sphereVolume(r.mSphereRadius);
385
386 mCallback(r);
387 }
388
389 result = null;
390 cr.Dispose();
391 }
392
393 ret = mChulls.Count;
394
395 mChulls.Clear();
396
397 return ret;
398 }
399
400 public void ConvexDecompResult(ConvexResult result)
401 {
402 CHull ch = new CHull(result);
403 mChulls.Add(ch);
404 }
405
406 public void sortChulls(List<CHull> hulls)
407 {
408 hulls.Sort(delegate(CHull a, CHull b) { return a.mVolume.CompareTo(b.mVolume); });
409 }
410 }
411}
diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/ConvexDecomposition.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/ConvexDecomposition.cs
new file mode 100644
index 0000000..2e2bb70
--- /dev/null
+++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/ConvexDecomposition.cs
@@ -0,0 +1,200 @@
1/* The MIT License
2 *
3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved.
5 *
6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Diagnostics;
31
32namespace OpenSim.Region.Physics.ConvexDecompositionDotNet
33{
34 public delegate void ConvexDecompositionCallback(ConvexResult result);
35
36 public class FaceTri
37 {
38 public float3 P1;
39 public float3 P2;
40 public float3 P3;
41
42 public FaceTri() { }
43
44 public FaceTri(List<float3> vertices, int i1, int i2, int i3)
45 {
46 P1 = new float3(vertices[i1]);
47 P2 = new float3(vertices[i2]);
48 P3 = new float3(vertices[i3]);
49 }
50 }
51
52 public static class ConvexDecomposition
53 {
54 private static void addTri(VertexPool vl, List<int> list, float3 p1, float3 p2, float3 p3)
55 {
56 int i1 = vl.getIndex(p1);
57 int i2 = vl.getIndex(p2);
58 int i3 = vl.getIndex(p3);
59
60 // do *not* process degenerate triangles!
61 if ( i1 != i2 && i1 != i3 && i2 != i3 )
62 {
63 list.Add(i1);
64 list.Add(i2);
65 list.Add(i3);
66 }
67 }
68
69 public static void calcConvexDecomposition(List<float3> vertices, List<int> indices, ConvexDecompositionCallback callback, float masterVolume, int depth,
70 int maxDepth, float concavePercent, float mergePercent)
71 {
72 float4 plane = new float4();
73 bool split = false;
74
75 if (depth < maxDepth)
76 {
77 float volume = 0f;
78 float c = Concavity.computeConcavity(vertices, indices, ref plane, ref volume);
79
80 if (depth == 0)
81 {
82 masterVolume = volume;
83 }
84
85 float percent = (c * 100.0f) / masterVolume;
86
87 if (percent > concavePercent) // if great than 5% of the total volume is concave, go ahead and keep splitting.
88 {
89 split = true;
90 }
91 }
92
93 if (depth >= maxDepth || !split)
94 {
95 HullResult result = new HullResult();
96 HullDesc desc = new HullDesc();
97
98 desc.SetHullFlag(HullFlag.QF_TRIANGLES);
99
100 desc.Vertices = vertices;
101
102 HullError ret = HullUtils.CreateConvexHull(desc, ref result);
103
104 if (ret == HullError.QE_OK)
105 {
106 ConvexResult r = new ConvexResult(result.OutputVertices, result.Indices);
107 callback(r);
108 }
109
110 return;
111 }
112
113 List<int> ifront = new List<int>();
114 List<int> iback = new List<int>();
115
116 VertexPool vfront = new VertexPool();
117 VertexPool vback = new VertexPool();
118
119 // ok..now we are going to 'split' all of the input triangles against this plane!
120 for (int i = 0; i < indices.Count / 3; i++)
121 {
122 int i1 = indices[i * 3 + 0];
123 int i2 = indices[i * 3 + 1];
124 int i3 = indices[i * 3 + 2];
125
126 FaceTri t = new FaceTri(vertices, i1, i2, i3);
127
128 float3[] front = new float3[4];
129 float3[] back = new float3[4];
130
131 int fcount = 0;
132 int bcount = 0;
133
134 PlaneTriResult result = PlaneTri.planeTriIntersection(plane, t, 0.00001f, ref front, out fcount, ref back, out bcount);
135
136 if (fcount > 4 || bcount > 4)
137 {
138 result = PlaneTri.planeTriIntersection(plane, t, 0.00001f, ref front, out fcount, ref back, out bcount);
139 }
140
141 switch (result)
142 {
143 case PlaneTriResult.PTR_FRONT:
144 Debug.Assert(fcount == 3);
145 addTri(vfront, ifront, front[0], front[1], front[2]);
146 break;
147 case PlaneTriResult.PTR_BACK:
148 Debug.Assert(bcount == 3);
149 addTri(vback, iback, back[0], back[1], back[2]);
150 break;
151 case PlaneTriResult.PTR_SPLIT:
152 Debug.Assert(fcount >= 3 && fcount <= 4);
153 Debug.Assert(bcount >= 3 && bcount <= 4);
154
155 addTri(vfront, ifront, front[0], front[1], front[2]);
156 addTri(vback, iback, back[0], back[1], back[2]);
157
158 if (fcount == 4)
159 {
160 addTri(vfront, ifront, front[0], front[2], front[3]);
161 }
162
163 if (bcount == 4)
164 {
165 addTri(vback, iback, back[0], back[2], back[3]);
166 }
167
168 break;
169 }
170 }
171
172 // ok... here we recursively call
173 if (ifront.Count > 0)
174 {
175 int vcount = vfront.GetSize();
176 List<float3> vertices2 = vfront.GetVertices();
177 for (int i = 0; i < vertices2.Count; i++)
178 vertices2[i] = new float3(vertices2[i]);
179 int tcount = ifront.Count / 3;
180
181 calcConvexDecomposition(vertices2, ifront, callback, masterVolume, depth + 1, maxDepth, concavePercent, mergePercent);
182 }
183
184 ifront.Clear();
185 vfront.Clear();
186
187 if (iback.Count > 0)
188 {
189 int vcount = vback.GetSize();
190 List<float3> vertices2 = vback.GetVertices();
191 int tcount = iback.Count / 3;
192
193 calcConvexDecomposition(vertices2, iback, callback, masterVolume, depth + 1, maxDepth, concavePercent, mergePercent);
194 }
195
196 iback.Clear();
197 vback.Clear();
198 }
199 }
200}
diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/ConvexResult.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/ConvexResult.cs
new file mode 100644
index 0000000..87758b5
--- /dev/null
+++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/ConvexResult.cs
@@ -0,0 +1,74 @@
1/* The MIT License
2 *
3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved.
5 *
6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
27
28using System;
29using System.Collections.Generic;
30
31namespace OpenSim.Region.Physics.ConvexDecompositionDotNet
32{
33 public class ConvexResult
34 {
35 public List<float3> HullVertices;
36 public List<int> HullIndices;
37
38 public float mHullVolume; // the volume of the convex hull.
39
40 //public float[] OBBSides = new float[3]; // the width, height and breadth of the best fit OBB
41 //public float[] OBBCenter = new float[3]; // the center of the OBB
42 //public float[] OBBOrientation = new float[4]; // the quaternion rotation of the OBB.
43 //public float[] OBBTransform = new float[16]; // the 4x4 transform of the OBB.
44 //public float OBBVolume; // the volume of the OBB
45
46 //public float SphereRadius; // radius and center of best fit sphere
47 //public float[] SphereCenter = new float[3];
48 //public float SphereVolume; // volume of the best fit sphere
49
50 public ConvexResult()
51 {
52 HullVertices = new List<float3>();
53 HullIndices = new List<int>();
54 }
55
56 public ConvexResult(List<float3> hvertices, List<int> hindices)
57 {
58 HullVertices = hvertices;
59 HullIndices = hindices;
60 }
61
62 public ConvexResult(ConvexResult r)
63 {
64 HullVertices = new List<float3>(r.HullVertices);
65 HullIndices = new List<int>(r.HullIndices);
66 }
67
68 public void Dispose()
69 {
70 HullVertices = null;
71 HullIndices = null;
72 }
73 }
74}
diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/HullClasses.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/HullClasses.cs
new file mode 100644
index 0000000..d81df26
--- /dev/null
+++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/HullClasses.cs
@@ -0,0 +1,171 @@
1/* The MIT License
2 *
3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved.
5 *
6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
27
28using System;
29using System.Collections.Generic;
30
31namespace OpenSim.Region.Physics.ConvexDecompositionDotNet
32{
33 public class HullResult
34 {
35 public bool Polygons = true; // true if indices represents polygons, false indices are triangles
36 public List<float3> OutputVertices = new List<float3>();
37 public List<int> Indices;
38
39 // If triangles, then indices are array indexes into the vertex list.
40 // If polygons, indices are in the form (number of points in face) (p1, p2, p3, ..) etc..
41 }
42
43 public class PHullResult
44 {
45 public List<float3> Vertices = new List<float3>();
46 public List<int> Indices = new List<int>();
47 }
48
49 [Flags]
50 public enum HullFlag : int
51 {
52 QF_DEFAULT = 0,
53 QF_TRIANGLES = (1 << 0), // report results as triangles, not polygons.
54 QF_SKIN_WIDTH = (1 << 2) // extrude hull based on this skin width
55 }
56
57 public enum HullError : int
58 {
59 QE_OK, // success!
60 QE_FAIL // failed.
61 }
62
63 public class HullDesc
64 {
65 public HullFlag Flags; // flags to use when generating the convex hull.
66 public List<float3> Vertices;
67 public float NormalEpsilon; // the epsilon for removing duplicates. This is a normalized value, if normalized bit is on.
68 public float SkinWidth;
69 public uint MaxVertices; // maximum number of vertices to be considered for the hull!
70 public uint MaxFaces;
71
72 public HullDesc()
73 {
74 Flags = HullFlag.QF_DEFAULT;
75 Vertices = new List<float3>();
76 NormalEpsilon = 0.001f;
77 MaxVertices = 4096;
78 MaxFaces = 4096;
79 SkinWidth = 0.01f;
80 }
81
82 public HullDesc(HullFlag flags, List<float3> vertices)
83 {
84 Flags = flags;
85 Vertices = new List<float3>(vertices);
86 NormalEpsilon = 0.001f;
87 MaxVertices = 4096;
88 MaxFaces = 4096;
89 SkinWidth = 0.01f;
90 }
91
92 public bool HasHullFlag(HullFlag flag)
93 {
94 return (Flags & flag) != 0;
95 }
96
97 public void SetHullFlag(HullFlag flag)
98 {
99 Flags |= flag;
100 }
101
102 public void ClearHullFlag(HullFlag flag)
103 {
104 Flags &= ~flag;
105 }
106 }
107
108 public class ConvexH
109 {
110 public struct HalfEdge
111 {
112 public short ea; // the other half of the edge (index into edges list)
113 public byte v; // the vertex at the start of this edge (index into vertices list)
114 public byte p; // the facet on which this edge lies (index into facets list)
115
116 public HalfEdge(short _ea, byte _v, byte _p)
117 {
118 ea = _ea;
119 v = _v;
120 p = _p;
121 }
122
123 public HalfEdge(HalfEdge e)
124 {
125 ea = e.ea;
126 v = e.v;
127 p = e.p;
128 }
129 }
130
131 public List<float3> vertices = new List<float3>();
132 public List<HalfEdge> edges = new List<HalfEdge>();
133 public List<Plane> facets = new List<Plane>();
134
135 public ConvexH(int vertices_size, int edges_size, int facets_size)
136 {
137 vertices = new List<float3>(vertices_size);
138 edges = new List<HalfEdge>(edges_size);
139 facets = new List<Plane>(facets_size);
140 }
141 }
142
143 public class VertFlag
144 {
145 public byte planetest;
146 public byte junk;
147 public byte undermap;
148 public byte overmap;
149 }
150
151 public class EdgeFlag
152 {
153 public byte planetest;
154 public byte fixes;
155 public short undermap;
156 public short overmap;
157 }
158
159 public class PlaneFlag
160 {
161 public byte undermap;
162 public byte overmap;
163 }
164
165 public class Coplanar
166 {
167 public ushort ea;
168 public byte v0;
169 public byte v1;
170 }
171}
diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/HullTriangle.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/HullTriangle.cs
new file mode 100644
index 0000000..1119a75
--- /dev/null
+++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/HullTriangle.cs
@@ -0,0 +1,99 @@
1/* The MIT License
2 *
3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved.
5 *
6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Diagnostics;
31
32namespace OpenSim.Region.Physics.ConvexDecompositionDotNet
33{
34 public class HullTriangle : int3
35 {
36 public int3 n = new int3();
37 public int id;
38 public int vmax;
39 public float rise;
40 private List<HullTriangle> tris;
41
42 public HullTriangle(int a, int b, int c, List<HullTriangle> tris)
43 : base(a, b, c)
44 {
45 this.tris = tris;
46
47 n = new int3(-1, -1, -1);
48 id = tris.Count;
49 tris.Add(this);
50 vmax = -1;
51 rise = 0.0f;
52 }
53
54 public void Dispose()
55 {
56 Debug.Assert(tris[id] == this);
57 tris[id] = null;
58 }
59
60 public int neib(int a, int b)
61 {
62 int i;
63
64 for (i = 0; i < 3; i++)
65 {
66 int i1 = (i + 1) % 3;
67 int i2 = (i + 2) % 3;
68 if ((this)[i] == a && (this)[i1] == b)
69 return n[i2];
70 if ((this)[i] == b && (this)[i1] == a)
71 return n[i2];
72 }
73
74 Debug.Assert(false);
75 return -1;
76 }
77
78 public void setneib(int a, int b, int value)
79 {
80 int i;
81
82 for (i = 0; i < 3; i++)
83 {
84 int i1 = (i + 1) % 3;
85 int i2 = (i + 2) % 3;
86 if ((this)[i] == a && (this)[i1] == b)
87 {
88 n[i2] = value;
89 return;
90 }
91 if ((this)[i] == b && (this)[i1] == a)
92 {
93 n[i2] = value;
94 return;
95 }
96 }
97 }
98 }
99}
diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/HullUtils.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/HullUtils.cs
new file mode 100644
index 0000000..c9ccfe2
--- /dev/null
+++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/HullUtils.cs
@@ -0,0 +1,1868 @@
1/* The MIT License
2 *
3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved.
5 *
6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Diagnostics;
31
32namespace OpenSim.Region.Physics.ConvexDecompositionDotNet
33{
34 public static class HullUtils
35 {
36 public static int argmin(float[] a, int n)
37 {
38 int r = 0;
39 for (int i = 1; i < n; i++)
40 {
41 if (a[i] < a[r])
42 {
43 r = i;
44 }
45 }
46 return r;
47 }
48
49 public static float clampf(float a)
50 {
51 return Math.Min(1.0f, Math.Max(0.0f, a));
52 }
53
54 public static float Round(float a, float precision)
55 {
56 return (float)Math.Floor(0.5f + a / precision) * precision;
57 }
58
59 public static float Interpolate(float f0, float f1, float alpha)
60 {
61 return f0 * (1 - alpha) + f1 * alpha;
62 }
63
64 public static void Swap<T>(ref T a, ref T b)
65 {
66 T tmp = a;
67 a = b;
68 b = tmp;
69 }
70
71 public static bool above(List<float3> vertices, int3 t, float3 p, float epsilon)
72 {
73 float3 vtx = vertices[t.x];
74 float3 n = TriNormal(vtx, vertices[t.y], vertices[t.z]);
75 return (float3.dot(n, p - vtx) > epsilon); // EPSILON???
76 }
77
78 public static int hasedge(int3 t, int a, int b)
79 {
80 for (int i = 0; i < 3; i++)
81 {
82 int i1 = (i + 1) % 3;
83 if (t[i] == a && t[i1] == b)
84 return 1;
85 }
86 return 0;
87 }
88
89 public static bool hasvert(int3 t, int v)
90 {
91 return (t[0] == v || t[1] == v || t[2] == v);
92 }
93
94 public static int shareedge(int3 a, int3 b)
95 {
96 int i;
97 for (i = 0; i < 3; i++)
98 {
99 int i1 = (i + 1) % 3;
100 if (hasedge(a, b[i1], b[i]) != 0)
101 return 1;
102 }
103 return 0;
104 }
105
106 public static void b2bfix(HullTriangle s, HullTriangle t, List<HullTriangle> tris)
107 {
108 int i;
109 for (i = 0; i < 3; i++)
110 {
111 int i1 = (i + 1) % 3;
112 int i2 = (i + 2) % 3;
113 int a = (s)[i1];
114 int b = (s)[i2];
115 Debug.Assert(tris[s.neib(a, b)].neib(b, a) == s.id);
116 Debug.Assert(tris[t.neib(a, b)].neib(b, a) == t.id);
117 tris[s.neib(a, b)].setneib(b, a, t.neib(b, a));
118 tris[t.neib(b, a)].setneib(a, b, s.neib(a, b));
119 }
120 }
121
122 public static void removeb2b(HullTriangle s, HullTriangle t, List<HullTriangle> tris)
123 {
124 b2bfix(s, t, tris);
125 s.Dispose();
126 t.Dispose();
127 }
128
129 public static void checkit(HullTriangle t, List<HullTriangle> tris)
130 {
131 int i;
132 Debug.Assert(tris[t.id] == t);
133 for (i = 0; i < 3; i++)
134 {
135 int i1 = (i + 1) % 3;
136 int i2 = (i + 2) % 3;
137 int a = (t)[i1];
138 int b = (t)[i2];
139 Debug.Assert(a != b);
140 Debug.Assert(tris[t.n[i]].neib(b, a) == t.id);
141 }
142 }
143
144 public static void extrude(HullTriangle t0, int v, List<HullTriangle> tris)
145 {
146 int3 t = t0;
147 int n = tris.Count;
148 HullTriangle ta = new HullTriangle(v, t[1], t[2], tris);
149 ta.n = new int3(t0.n[0], n + 1, n + 2);
150 tris[t0.n[0]].setneib(t[1], t[2], n + 0);
151 HullTriangle tb = new HullTriangle(v, t[2], t[0], tris);
152 tb.n = new int3(t0.n[1], n + 2, n + 0);
153 tris[t0.n[1]].setneib(t[2], t[0], n + 1);
154 HullTriangle tc = new HullTriangle(v, t[0], t[1], tris);
155 tc.n = new int3(t0.n[2], n + 0, n + 1);
156 tris[t0.n[2]].setneib(t[0], t[1], n + 2);
157 checkit(ta, tris);
158 checkit(tb, tris);
159 checkit(tc, tris);
160 if (hasvert(tris[ta.n[0]], v))
161 removeb2b(ta, tris[ta.n[0]], tris);
162 if (hasvert(tris[tb.n[0]], v))
163 removeb2b(tb, tris[tb.n[0]], tris);
164 if (hasvert(tris[tc.n[0]], v))
165 removeb2b(tc, tris[tc.n[0]], tris);
166 t0.Dispose();
167 }
168
169 public static HullTriangle extrudable(float epsilon, List<HullTriangle> tris)
170 {
171 int i;
172 HullTriangle t = null;
173 for (i = 0; i < tris.Count; i++)
174 {
175 if (t == null || (tris.Count > i && (object)tris[i] != null && t.rise < tris[i].rise))
176 {
177 t = tris[i];
178 }
179 }
180 return (t.rise > epsilon) ? t : null;
181 }
182
183 public static Quaternion RotationArc(float3 v0, float3 v1)
184 {
185 Quaternion q = new Quaternion();
186 v0 = float3.normalize(v0); // Comment these two lines out if you know its not needed.
187 v1 = float3.normalize(v1); // If vector is already unit length then why do it again?
188 float3 c = float3.cross(v0, v1);
189 float d = float3.dot(v0, v1);
190 if (d <= -1.0f) // 180 about x axis
191 {
192 return new Quaternion(1f, 0f, 0f, 0f);
193 }
194 float s = (float)Math.Sqrt((1 + d) * 2f);
195 q.x = c.x / s;
196 q.y = c.y / s;
197 q.z = c.z / s;
198 q.w = s / 2.0f;
199 return q;
200 }
201
202 public static float3 PlaneLineIntersection(Plane plane, float3 p0, float3 p1)
203 {
204 // returns the point where the line p0-p1 intersects the plane n&d
205 float3 dif = p1 - p0;
206 float dn = float3.dot(plane.normal, dif);
207 float t = -(plane.dist + float3.dot(plane.normal, p0)) / dn;
208 return p0 + (dif * t);
209 }
210
211 public static float3 LineProject(float3 p0, float3 p1, float3 a)
212 {
213 float3 w = new float3();
214 w = p1 - p0;
215 float t = float3.dot(w, (a - p0)) / (w.x * w.x + w.y * w.y + w.z * w.z);
216 return p0 + w * t;
217 }
218
219 public static float3 PlaneProject(Plane plane, float3 point)
220 {
221 return point - plane.normal * (float3.dot(point, plane.normal) + plane.dist);
222 }
223
224 public static float LineProjectTime(float3 p0, float3 p1, float3 a)
225 {
226 float3 w = new float3();
227 w = p1 - p0;
228 float t = float3.dot(w, (a - p0)) / (w.x * w.x + w.y * w.y + w.z * w.z);
229 return t;
230 }
231
232 public static float3 ThreePlaneIntersection(Plane p0, Plane p1, Plane p2)
233 {
234 float3x3 mp = float3x3.Transpose(new float3x3(p0.normal, p1.normal, p2.normal));
235 float3x3 mi = float3x3.Inverse(mp);
236 float3 b = new float3(p0.dist, p1.dist, p2.dist);
237 return -b * mi;
238 }
239
240 public static bool PolyHit(List<float3> vert, float3 v0, float3 v1)
241 {
242 float3 impact = new float3();
243 float3 normal = new float3();
244 return PolyHit(vert, v0, v1, out impact, out normal);
245 }
246
247 public static bool PolyHit(List<float3> vert, float3 v0, float3 v1, out float3 impact)
248 {
249 float3 normal = new float3();
250 return PolyHit(vert, v0, v1, out impact, out normal);
251 }
252
253 public static bool PolyHit(List<float3> vert, float3 v0, float3 v1, out float3 impact, out float3 normal)
254 {
255 float3 the_point = new float3();
256
257 impact = null;
258 normal = null;
259
260 int i;
261 float3 nrml = new float3(0, 0, 0);
262 for (i = 0; i < vert.Count; i++)
263 {
264 int i1 = (i + 1) % vert.Count;
265 int i2 = (i + 2) % vert.Count;
266 nrml = nrml + float3.cross(vert[i1] - vert[i], vert[i2] - vert[i1]);
267 }
268
269 float m = float3.magnitude(nrml);
270 if (m == 0.0)
271 {
272 return false;
273 }
274 nrml = nrml * (1.0f / m);
275 float dist = -float3.dot(nrml, vert[0]);
276 float d0;
277 float d1;
278 if ((d0 = float3.dot(v0, nrml) + dist) < 0 || (d1 = float3.dot(v1, nrml) + dist) > 0)
279 {
280 return false;
281 }
282
283 // By using the cached plane distances d0 and d1
284 // we can optimize the following:
285 // the_point = planelineintersection(nrml,dist,v0,v1);
286 float a = d0 / (d0 - d1);
287 the_point = v0 * (1 - a) + v1 * a;
288
289
290 bool inside = true;
291 for (int j = 0; inside && j < vert.Count; j++)
292 {
293 // let inside = 0 if outside
294 float3 pp1 = new float3();
295 float3 pp2 = new float3();
296 float3 side = new float3();
297 pp1 = vert[j];
298 pp2 = vert[(j + 1) % vert.Count];
299 side = float3.cross((pp2 - pp1), (the_point - pp1));
300 inside = (float3.dot(nrml, side) >= 0.0);
301 }
302 if (inside)
303 {
304 if (normal != null)
305 {
306 normal = nrml;
307 }
308 if (impact != null)
309 {
310 impact = the_point;
311 }
312 }
313 return inside;
314 }
315
316 public static bool BoxInside(float3 p, float3 bmin, float3 bmax)
317 {
318 return (p.x >= bmin.x && p.x <= bmax.x && p.y >= bmin.y && p.y <= bmax.y && p.z >= bmin.z && p.z <= bmax.z);
319 }
320
321 public static bool BoxIntersect(float3 v0, float3 v1, float3 bmin, float3 bmax, float3 impact)
322 {
323 if (BoxInside(v0, bmin, bmax))
324 {
325 impact = v0;
326 return true;
327 }
328 if (v0.x <= bmin.x && v1.x >= bmin.x)
329 {
330 float a = (bmin.x - v0.x) / (v1.x - v0.x);
331 //v.x = bmin.x;
332 float vy = (1 - a) * v0.y + a * v1.y;
333 float vz = (1 - a) * v0.z + a * v1.z;
334 if (vy >= bmin.y && vy <= bmax.y && vz >= bmin.z && vz <= bmax.z)
335 {
336 impact.x = bmin.x;
337 impact.y = vy;
338 impact.z = vz;
339 return true;
340 }
341 }
342 else if (v0.x >= bmax.x && v1.x <= bmax.x)
343 {
344 float a = (bmax.x - v0.x) / (v1.x - v0.x);
345 //v.x = bmax.x;
346 float vy = (1 - a) * v0.y + a * v1.y;
347 float vz = (1 - a) * v0.z + a * v1.z;
348 if (vy >= bmin.y && vy <= bmax.y && vz >= bmin.z && vz <= bmax.z)
349 {
350 impact.x = bmax.x;
351 impact.y = vy;
352 impact.z = vz;
353 return true;
354 }
355 }
356 if (v0.y <= bmin.y && v1.y >= bmin.y)
357 {
358 float a = (bmin.y - v0.y) / (v1.y - v0.y);
359 float vx = (1 - a) * v0.x + a * v1.x;
360 //v.y = bmin.y;
361 float vz = (1 - a) * v0.z + a * v1.z;
362 if (vx >= bmin.x && vx <= bmax.x && vz >= bmin.z && vz <= bmax.z)
363 {
364 impact.x = vx;
365 impact.y = bmin.y;
366 impact.z = vz;
367 return true;
368 }
369 }
370 else if (v0.y >= bmax.y && v1.y <= bmax.y)
371 {
372 float a = (bmax.y - v0.y) / (v1.y - v0.y);
373 float vx = (1 - a) * v0.x + a * v1.x;
374 // vy = bmax.y;
375 float vz = (1 - a) * v0.z + a * v1.z;
376 if (vx >= bmin.x && vx <= bmax.x && vz >= bmin.z && vz <= bmax.z)
377 {
378 impact.x = vx;
379 impact.y = bmax.y;
380 impact.z = vz;
381 return true;
382 }
383 }
384 if (v0.z <= bmin.z && v1.z >= bmin.z)
385 {
386 float a = (bmin.z - v0.z) / (v1.z - v0.z);
387 float vx = (1 - a) * v0.x + a * v1.x;
388 float vy = (1 - a) * v0.y + a * v1.y;
389 // v.z = bmin.z;
390 if (vy >= bmin.y && vy <= bmax.y && vx >= bmin.x && vx <= bmax.x)
391 {
392 impact.x = vx;
393 impact.y = vy;
394 impact.z = bmin.z;
395 return true;
396 }
397 }
398 else if (v0.z >= bmax.z && v1.z <= bmax.z)
399 {
400 float a = (bmax.z - v0.z) / (v1.z - v0.z);
401 float vx = (1 - a) * v0.x + a * v1.x;
402 float vy = (1 - a) * v0.y + a * v1.y;
403 // v.z = bmax.z;
404 if (vy >= bmin.y && vy <= bmax.y && vx >= bmin.x && vx <= bmax.x)
405 {
406 impact.x = vx;
407 impact.y = vy;
408 impact.z = bmax.z;
409 return true;
410 }
411 }
412 return false;
413 }
414
415 public static float DistanceBetweenLines(float3 ustart, float3 udir, float3 vstart, float3 vdir, float3 upoint)
416 {
417 return DistanceBetweenLines(ustart, udir, vstart, vdir, upoint, null);
418 }
419
420 public static float DistanceBetweenLines(float3 ustart, float3 udir, float3 vstart, float3 vdir)
421 {
422 return DistanceBetweenLines(ustart, udir, vstart, vdir, null, null);
423 }
424
425 public static float DistanceBetweenLines(float3 ustart, float3 udir, float3 vstart, float3 vdir, float3 upoint, float3 vpoint)
426 {
427 float3 cp = float3.normalize(float3.cross(udir, vdir));
428
429 float distu = -float3.dot(cp, ustart);
430 float distv = -float3.dot(cp, vstart);
431 float dist = (float)Math.Abs(distu - distv);
432 if (upoint != null)
433 {
434 Plane plane = new Plane();
435 plane.normal = float3.normalize(float3.cross(vdir, cp));
436 plane.dist = -float3.dot(plane.normal, vstart);
437 upoint = PlaneLineIntersection(plane, ustart, ustart + udir);
438 }
439 if (vpoint != null)
440 {
441 Plane plane = new Plane();
442 plane.normal = float3.normalize(float3.cross(udir, cp));
443 plane.dist = -float3.dot(plane.normal, ustart);
444 vpoint = PlaneLineIntersection(plane, vstart, vstart + vdir);
445 }
446 return dist;
447 }
448
449 public static float3 TriNormal(float3 v0, float3 v1, float3 v2)
450 {
451 // return the normal of the triangle
452 // inscribed by v0, v1, and v2
453 float3 cp = float3.cross(v1 - v0, v2 - v1);
454 float m = float3.magnitude(cp);
455 if (m == 0)
456 return new float3(1, 0, 0);
457 return cp * (1.0f / m);
458 }
459
460 public static int PlaneTest(Plane p, float3 v, float planetestepsilon)
461 {
462 float a = float3.dot(v, p.normal) + p.dist;
463 int flag = (a > planetestepsilon) ? (2) : ((a < -planetestepsilon) ? (1) : (0));
464 return flag;
465 }
466
467 public static int SplitTest(ref ConvexH convex, Plane plane, float planetestepsilon)
468 {
469 int flag = 0;
470 for (int i = 0; i < convex.vertices.Count; i++)
471 {
472 flag |= PlaneTest(plane, convex.vertices[i], planetestepsilon);
473 }
474 return flag;
475 }
476
477 public static Quaternion VirtualTrackBall(float3 cop, float3 cor, float3 dir1, float3 dir2)
478 {
479 // routine taken from game programming gems.
480 // Implement track ball functionality to spin stuf on the screen
481 // cop center of projection
482 // cor center of rotation
483 // dir1 old mouse direction
484 // dir2 new mouse direction
485 // pretend there is a sphere around cor. Then find the points
486 // where dir1 and dir2 intersect that sphere. Find the
487 // rotation that takes the first point to the second.
488 float m;
489 // compute plane
490 float3 nrml = cor - cop;
491 float fudgefactor = 1.0f / (float3.magnitude(nrml) * 0.25f); // since trackball proportional to distance from cop
492 nrml = float3.normalize(nrml);
493 float dist = -float3.dot(nrml, cor);
494 float3 u = PlaneLineIntersection(new Plane(nrml, dist), cop, cop + dir1);
495 u = u - cor;
496 u = u * fudgefactor;
497 m = float3.magnitude(u);
498 if (m > 1)
499 {
500 u /= m;
501 }
502 else
503 {
504 u = u - (nrml * (float)Math.Sqrt(1 - m * m));
505 }
506 float3 v = PlaneLineIntersection(new Plane(nrml, dist), cop, cop + dir2);
507 v = v - cor;
508 v = v * fudgefactor;
509 m = float3.magnitude(v);
510 if (m > 1)
511 {
512 v /= m;
513 }
514 else
515 {
516 v = v - (nrml * (float)Math.Sqrt(1 - m * m));
517 }
518 return RotationArc(u, v);
519 }
520
521 public static bool AssertIntact(ConvexH convex, float planetestepsilon)
522 {
523 int i;
524 int estart = 0;
525 for (i = 0; i < convex.edges.Count; i++)
526 {
527 if (convex.edges[estart].p != convex.edges[i].p)
528 {
529 estart = i;
530 }
531 int inext = i + 1;
532 if (inext >= convex.edges.Count || convex.edges[inext].p != convex.edges[i].p)
533 {
534 inext = estart;
535 }
536 Debug.Assert(convex.edges[inext].p == convex.edges[i].p);
537 int nb = convex.edges[i].ea;
538 Debug.Assert(nb != 255);
539 if (nb == 255 || nb == -1)
540 return false;
541 Debug.Assert(nb != -1);
542 Debug.Assert(i == convex.edges[nb].ea);
543 }
544 for (i = 0; i < convex.edges.Count; i++)
545 {
546 Debug.Assert((0) == PlaneTest(convex.facets[convex.edges[i].p], convex.vertices[convex.edges[i].v], planetestepsilon));
547 if ((0) != PlaneTest(convex.facets[convex.edges[i].p], convex.vertices[convex.edges[i].v], planetestepsilon))
548 return false;
549 if (convex.edges[estart].p != convex.edges[i].p)
550 {
551 estart = i;
552 }
553 int i1 = i + 1;
554 if (i1 >= convex.edges.Count || convex.edges[i1].p != convex.edges[i].p)
555 {
556 i1 = estart;
557 }
558 int i2 = i1 + 1;
559 if (i2 >= convex.edges.Count || convex.edges[i2].p != convex.edges[i].p)
560 {
561 i2 = estart;
562 }
563 if (i == i2) // i sliced tangent to an edge and created 2 meaningless edges
564 continue;
565 float3 localnormal = TriNormal(convex.vertices[convex.edges[i].v], convex.vertices[convex.edges[i1].v], convex.vertices[convex.edges[i2].v]);
566 Debug.Assert(float3.dot(localnormal, convex.facets[convex.edges[i].p].normal) > 0);
567 if (float3.dot(localnormal, convex.facets[convex.edges[i].p].normal) <= 0)
568 return false;
569 }
570 return true;
571 }
572
573 public static ConvexH test_btbq(float planetestepsilon)
574 {
575 // back to back quads
576 ConvexH convex = new ConvexH(4, 8, 2);
577 convex.vertices[0] = new float3(0, 0, 0);
578 convex.vertices[1] = new float3(1, 0, 0);
579 convex.vertices[2] = new float3(1, 1, 0);
580 convex.vertices[3] = new float3(0, 1, 0);
581 convex.facets[0] = new Plane(new float3(0, 0, 1), 0);
582 convex.facets[1] = new Plane(new float3(0, 0, -1), 0);
583 convex.edges[0] = new ConvexH.HalfEdge(7, 0, 0);
584 convex.edges[1] = new ConvexH.HalfEdge(6, 1, 0);
585 convex.edges[2] = new ConvexH.HalfEdge(5, 2, 0);
586 convex.edges[3] = new ConvexH.HalfEdge(4, 3, 0);
587
588 convex.edges[4] = new ConvexH.HalfEdge(3, 0, 1);
589 convex.edges[5] = new ConvexH.HalfEdge(2, 3, 1);
590 convex.edges[6] = new ConvexH.HalfEdge(1, 2, 1);
591 convex.edges[7] = new ConvexH.HalfEdge(0, 1, 1);
592 AssertIntact(convex, planetestepsilon);
593 return convex;
594 }
595
596 public static ConvexH test_cube()
597 {
598 ConvexH convex = new ConvexH(8, 24, 6);
599 convex.vertices[0] = new float3(0, 0, 0);
600 convex.vertices[1] = new float3(0, 0, 1);
601 convex.vertices[2] = new float3(0, 1, 0);
602 convex.vertices[3] = new float3(0, 1, 1);
603 convex.vertices[4] = new float3(1, 0, 0);
604 convex.vertices[5] = new float3(1, 0, 1);
605 convex.vertices[6] = new float3(1, 1, 0);
606 convex.vertices[7] = new float3(1, 1, 1);
607
608 convex.facets[0] = new Plane(new float3(-1, 0, 0), 0);
609 convex.facets[1] = new Plane(new float3(1, 0, 0), -1);
610 convex.facets[2] = new Plane(new float3(0, -1, 0), 0);
611 convex.facets[3] = new Plane(new float3(0, 1, 0), -1);
612 convex.facets[4] = new Plane(new float3(0, 0, -1), 0);
613 convex.facets[5] = new Plane(new float3(0, 0, 1), -1);
614
615 convex.edges[0] = new ConvexH.HalfEdge(11, 0, 0);
616 convex.edges[1] = new ConvexH.HalfEdge(23, 1, 0);
617 convex.edges[2] = new ConvexH.HalfEdge(15, 3, 0);
618 convex.edges[3] = new ConvexH.HalfEdge(16, 2, 0);
619
620 convex.edges[4] = new ConvexH.HalfEdge(13, 6, 1);
621 convex.edges[5] = new ConvexH.HalfEdge(21, 7, 1);
622 convex.edges[6] = new ConvexH.HalfEdge(9, 5, 1);
623 convex.edges[7] = new ConvexH.HalfEdge(18, 4, 1);
624
625 convex.edges[8] = new ConvexH.HalfEdge(19, 0, 2);
626 convex.edges[9] = new ConvexH.HalfEdge(6, 4, 2);
627 convex.edges[10] = new ConvexH.HalfEdge(20, 5, 2);
628 convex.edges[11] = new ConvexH.HalfEdge(0, 1, 2);
629
630 convex.edges[12] = new ConvexH.HalfEdge(22, 3, 3);
631 convex.edges[13] = new ConvexH.HalfEdge(4, 7, 3);
632 convex.edges[14] = new ConvexH.HalfEdge(17, 6, 3);
633 convex.edges[15] = new ConvexH.HalfEdge(2, 2, 3);
634
635 convex.edges[16] = new ConvexH.HalfEdge(3, 0, 4);
636 convex.edges[17] = new ConvexH.HalfEdge(14, 2, 4);
637 convex.edges[18] = new ConvexH.HalfEdge(7, 6, 4);
638 convex.edges[19] = new ConvexH.HalfEdge(8, 4, 4);
639
640 convex.edges[20] = new ConvexH.HalfEdge(10, 1, 5);
641 convex.edges[21] = new ConvexH.HalfEdge(5, 5, 5);
642 convex.edges[22] = new ConvexH.HalfEdge(12, 7, 5);
643 convex.edges[23] = new ConvexH.HalfEdge(1, 3, 5);
644
645 return convex;
646 }
647
648 public static ConvexH ConvexHMakeCube(float3 bmin, float3 bmax)
649 {
650 ConvexH convex = test_cube();
651 convex.vertices[0] = new float3(bmin.x, bmin.y, bmin.z);
652 convex.vertices[1] = new float3(bmin.x, bmin.y, bmax.z);
653 convex.vertices[2] = new float3(bmin.x, bmax.y, bmin.z);
654 convex.vertices[3] = new float3(bmin.x, bmax.y, bmax.z);
655 convex.vertices[4] = new float3(bmax.x, bmin.y, bmin.z);
656 convex.vertices[5] = new float3(bmax.x, bmin.y, bmax.z);
657 convex.vertices[6] = new float3(bmax.x, bmax.y, bmin.z);
658 convex.vertices[7] = new float3(bmax.x, bmax.y, bmax.z);
659
660 convex.facets[0] = new Plane(new float3(-1, 0, 0), bmin.x);
661 convex.facets[1] = new Plane(new float3(1, 0, 0), -bmax.x);
662 convex.facets[2] = new Plane(new float3(0, -1, 0), bmin.y);
663 convex.facets[3] = new Plane(new float3(0, 1, 0), -bmax.y);
664 convex.facets[4] = new Plane(new float3(0, 0, -1), bmin.z);
665 convex.facets[5] = new Plane(new float3(0, 0, 1), -bmax.z);
666 return convex;
667 }
668
669 public static ConvexH ConvexHCrop(ref ConvexH convex, Plane slice, float planetestepsilon)
670 {
671 int i;
672 int vertcountunder = 0;
673 int vertcountover = 0;
674 List<int> vertscoplanar = new List<int>(); // existing vertex members of convex that are coplanar
675 List<int> edgesplit = new List<int>(); // existing edges that members of convex that cross the splitplane
676
677 Debug.Assert(convex.edges.Count < 480);
678
679 EdgeFlag[] edgeflag = new EdgeFlag[512];
680 VertFlag[] vertflag = new VertFlag[256];
681 PlaneFlag[] planeflag = new PlaneFlag[128];
682 ConvexH.HalfEdge[] tmpunderedges = new ConvexH.HalfEdge[512];
683 Plane[] tmpunderplanes = new Plane[128];
684 Coplanar[] coplanaredges = new Coplanar[512];
685 int coplanaredges_num = 0;
686
687 List<float3> createdverts = new List<float3>();
688
689 // do the side-of-plane tests
690 for (i = 0; i < convex.vertices.Count; i++)
691 {
692 vertflag[i].planetest = (byte)PlaneTest(slice, convex.vertices[i], planetestepsilon);
693 if (vertflag[i].planetest == (0))
694 {
695 // ? vertscoplanar.Add(i);
696 vertflag[i].undermap = (byte)vertcountunder++;
697 vertflag[i].overmap = (byte)vertcountover++;
698 }
699 else if (vertflag[i].planetest == (1))
700 {
701 vertflag[i].undermap = (byte)vertcountunder++;
702 }
703 else
704 {
705 Debug.Assert(vertflag[i].planetest == (2));
706 vertflag[i].overmap = (byte)vertcountover++;
707 vertflag[i].undermap = 255; // for debugging purposes
708 }
709 }
710 int vertcountunderold = vertcountunder; // for debugging only
711
712 int under_edge_count = 0;
713 int underplanescount = 0;
714 int e0 = 0;
715
716 for (int currentplane = 0; currentplane < convex.facets.Count; currentplane++)
717 {
718 int estart = e0;
719 int enextface = 0;
720 int planeside = 0;
721 int e1 = e0 + 1;
722 int vout = -1;
723 int vin = -1;
724 int coplanaredge = -1;
725 do
726 {
727
728 if (e1 >= convex.edges.Count || convex.edges[e1].p != currentplane)
729 {
730 enextface = e1;
731 e1 = estart;
732 }
733 ConvexH.HalfEdge edge0 = convex.edges[e0];
734 ConvexH.HalfEdge edge1 = convex.edges[e1];
735 ConvexH.HalfEdge edgea = convex.edges[edge0.ea];
736
737 planeside |= vertflag[edge0.v].planetest;
738 //if((vertflag[edge0.v].planetest & vertflag[edge1.v].planetest) == COPLANAR) {
739 // assert(ecop==-1);
740 // ecop=e;
741 //}
742
743 if (vertflag[edge0.v].planetest == (2) && vertflag[edge1.v].planetest == (2))
744 {
745 // both endpoints over plane
746 edgeflag[e0].undermap = -1;
747 }
748 else if ((vertflag[edge0.v].planetest | vertflag[edge1.v].planetest) == (1))
749 {
750 // at least one endpoint under, the other coplanar or under
751
752 edgeflag[e0].undermap = (short)under_edge_count;
753 tmpunderedges[under_edge_count].v = vertflag[edge0.v].undermap;
754 tmpunderedges[under_edge_count].p = (byte)underplanescount;
755 if (edge0.ea < e0)
756 {
757 // connect the neighbors
758 Debug.Assert(edgeflag[edge0.ea].undermap != -1);
759 tmpunderedges[under_edge_count].ea = edgeflag[edge0.ea].undermap;
760 tmpunderedges[edgeflag[edge0.ea].undermap].ea = (short)under_edge_count;
761 }
762 under_edge_count++;
763 }
764 else if ((vertflag[edge0.v].planetest | vertflag[edge1.v].planetest) == (0))
765 {
766 // both endpoints coplanar
767 // must check a 3rd point to see if UNDER
768 int e2 = e1 + 1;
769 if (e2 >= convex.edges.Count || convex.edges[e2].p != currentplane)
770 {
771 e2 = estart;
772 }
773 Debug.Assert(convex.edges[e2].p == currentplane);
774 ConvexH.HalfEdge edge2 = convex.edges[e2];
775 if (vertflag[edge2.v].planetest == (1))
776 {
777
778 edgeflag[e0].undermap = (short)under_edge_count;
779 tmpunderedges[under_edge_count].v = vertflag[edge0.v].undermap;
780 tmpunderedges[under_edge_count].p = (byte)underplanescount;
781 tmpunderedges[under_edge_count].ea = -1;
782 // make sure this edge is added to the "coplanar" list
783 coplanaredge = under_edge_count;
784 vout = vertflag[edge0.v].undermap;
785 vin = vertflag[edge1.v].undermap;
786 under_edge_count++;
787 }
788 else
789 {
790 edgeflag[e0].undermap = -1;
791 }
792 }
793 else if (vertflag[edge0.v].planetest == (1) && vertflag[edge1.v].planetest == (2))
794 {
795 // first is under 2nd is over
796
797 edgeflag[e0].undermap = (short)under_edge_count;
798 tmpunderedges[under_edge_count].v = vertflag[edge0.v].undermap;
799 tmpunderedges[under_edge_count].p = (byte)underplanescount;
800 if (edge0.ea < e0)
801 {
802 Debug.Assert(edgeflag[edge0.ea].undermap != -1);
803 // connect the neighbors
804 tmpunderedges[under_edge_count].ea = edgeflag[edge0.ea].undermap;
805 tmpunderedges[edgeflag[edge0.ea].undermap].ea = (short)under_edge_count;
806 vout = tmpunderedges[edgeflag[edge0.ea].undermap].v;
807 }
808 else
809 {
810 Plane p0 = convex.facets[edge0.p];
811 Plane pa = convex.facets[edgea.p];
812 createdverts.Add(ThreePlaneIntersection(p0, pa, slice));
813 //createdverts.Add(PlaneProject(slice,PlaneLineIntersection(slice,convex.vertices[edge0.v],convex.vertices[edgea.v])));
814 //createdverts.Add(PlaneLineIntersection(slice,convex.vertices[edge0.v],convex.vertices[edgea.v]));
815 vout = vertcountunder++;
816 }
817 under_edge_count++;
818 /// hmmm something to think about: i might be able to output this edge regarless of
819 // wheter or not we know v-in yet. ok i;ll try this now:
820 tmpunderedges[under_edge_count].v = (byte)vout;
821 tmpunderedges[under_edge_count].p = (byte)underplanescount;
822 tmpunderedges[under_edge_count].ea = -1;
823 coplanaredge = under_edge_count;
824 under_edge_count++;
825
826 if (vin != -1)
827 {
828 // we previously processed an edge where we came under
829 // now we know about vout as well
830
831 // ADD THIS EDGE TO THE LIST OF EDGES THAT NEED NEIGHBOR ON PARTITION PLANE!!
832 }
833
834 }
835 else if (vertflag[edge0.v].planetest == (0) && vertflag[edge1.v].planetest == (2))
836 {
837 // first is coplanar 2nd is over
838
839 edgeflag[e0].undermap = -1;
840 vout = vertflag[edge0.v].undermap;
841 // I hate this but i have to make sure part of this face is UNDER before ouputting this vert
842 int k = estart;
843 Debug.Assert(edge0.p == currentplane);
844 while (!((planeside & 1) != 0) && k < convex.edges.Count && convex.edges[k].p == edge0.p)
845 {
846 planeside |= vertflag[convex.edges[k].v].planetest;
847 k++;
848 }
849 if ((planeside & 1) != 0)
850 {
851 tmpunderedges[under_edge_count].v = (byte)vout;
852 tmpunderedges[under_edge_count].p = (byte)underplanescount;
853 tmpunderedges[under_edge_count].ea = -1;
854 coplanaredge = under_edge_count; // hmmm should make a note of the edge # for later on
855 under_edge_count++;
856
857 }
858 }
859 else if (vertflag[edge0.v].planetest == (2) && vertflag[edge1.v].planetest == (1))
860 {
861 // first is over next is under
862 // new vertex!!!
863 Debug.Assert(vin == -1);
864 if (e0 < edge0.ea)
865 {
866 Plane p0 = convex.facets[edge0.p];
867 Plane pa = convex.facets[edgea.p];
868 createdverts.Add(ThreePlaneIntersection(p0, pa, slice));
869 //createdverts.Add(PlaneLineIntersection(slice,convex.vertices[edge0.v],convex.vertices[edgea.v]));
870 //createdverts.Add(PlaneProject(slice,PlaneLineIntersection(slice,convex.vertices[edge0.v],convex.vertices[edgea.v])));
871 vin = vertcountunder++;
872 }
873 else
874 {
875 // find the new vertex that was created by edge[edge0.ea]
876 int nea = edgeflag[edge0.ea].undermap;
877 Debug.Assert(tmpunderedges[nea].p == tmpunderedges[nea + 1].p);
878 vin = tmpunderedges[nea + 1].v;
879 Debug.Assert(vin < vertcountunder);
880 Debug.Assert(vin >= vertcountunderold); // for debugging only
881 }
882 if (vout != -1)
883 {
884 // we previously processed an edge where we went over
885 // now we know vin too
886 // ADD THIS EDGE TO THE LIST OF EDGES THAT NEED NEIGHBOR ON PARTITION PLANE!!
887 }
888 // output edge
889 tmpunderedges[under_edge_count].v = (byte)vin;
890 tmpunderedges[under_edge_count].p = (byte)underplanescount;
891 edgeflag[e0].undermap = (short)under_edge_count;
892 if (e0 > edge0.ea)
893 {
894 Debug.Assert(edgeflag[edge0.ea].undermap != -1);
895 // connect the neighbors
896 tmpunderedges[under_edge_count].ea = edgeflag[edge0.ea].undermap;
897 tmpunderedges[edgeflag[edge0.ea].undermap].ea = (short)under_edge_count;
898 }
899 Debug.Assert(edgeflag[e0].undermap == under_edge_count);
900 under_edge_count++;
901 }
902 else if (vertflag[edge0.v].planetest == (2) && vertflag[edge1.v].planetest == (0))
903 {
904 // first is over next is coplanar
905
906 edgeflag[e0].undermap = -1;
907 vin = vertflag[edge1.v].undermap;
908 Debug.Assert(vin != -1);
909 if (vout != -1)
910 {
911 // we previously processed an edge where we came under
912 // now we know both endpoints
913 // ADD THIS EDGE TO THE LIST OF EDGES THAT NEED NEIGHBOR ON PARTITION PLANE!!
914 }
915
916 }
917 else
918 {
919 Debug.Assert(false);
920 }
921
922
923 e0 = e1;
924 e1++; // do the modulo at the beginning of the loop
925
926 } while (e0 != estart);
927 e0 = enextface;
928 if ((planeside & 1) != 0)
929 {
930 planeflag[currentplane].undermap = (byte)underplanescount;
931 tmpunderplanes[underplanescount] = convex.facets[currentplane];
932 underplanescount++;
933 }
934 else
935 {
936 planeflag[currentplane].undermap = 0;
937 }
938 if (vout >= 0 && (planeside & 1) != 0)
939 {
940 Debug.Assert(vin >= 0);
941 Debug.Assert(coplanaredge >= 0);
942 Debug.Assert(coplanaredge != 511);
943 coplanaredges[coplanaredges_num].ea = (ushort)coplanaredge;
944 coplanaredges[coplanaredges_num].v0 = (byte)vin;
945 coplanaredges[coplanaredges_num].v1 = (byte)vout;
946 coplanaredges_num++;
947 }
948 }
949
950 // add the new plane to the mix:
951 if (coplanaredges_num > 0)
952 {
953 tmpunderplanes[underplanescount++] = slice;
954 }
955 for (i = 0; i < coplanaredges_num - 1; i++)
956 {
957 if (coplanaredges[i].v1 != coplanaredges[i + 1].v0)
958 {
959 int j = 0;
960 for (j = i + 2; j < coplanaredges_num; j++)
961 {
962 if (coplanaredges[i].v1 == coplanaredges[j].v0)
963 {
964 Coplanar tmp = coplanaredges[i + 1];
965 coplanaredges[i + 1] = coplanaredges[j];
966 coplanaredges[j] = tmp;
967 break;
968 }
969 }
970 if (j >= coplanaredges_num)
971 {
972 Debug.Assert(j < coplanaredges_num);
973 return null;
974 }
975 }
976 }
977
978 ConvexH punder = new ConvexH(vertcountunder, under_edge_count + coplanaredges_num, underplanescount);
979 ConvexH under = punder;
980
981 {
982 int k = 0;
983 for (i = 0; i < convex.vertices.Count; i++)
984 {
985 if (vertflag[i].planetest != (2))
986 {
987 under.vertices[k++] = convex.vertices[i];
988 }
989 }
990 i = 0;
991 while (k < vertcountunder)
992 {
993 under.vertices[k++] = createdverts[i++];
994 }
995 Debug.Assert(i == createdverts.Count);
996 }
997
998 for (i = 0; i < coplanaredges_num; i++)
999 {
1000 ConvexH.HalfEdge edge = under.edges[under_edge_count + i];
1001 edge.p = (byte)(underplanescount - 1);
1002 edge.ea = (short)coplanaredges[i].ea;
1003 edge.v = (byte)coplanaredges[i].v0;
1004 under.edges[under_edge_count + i] = edge;
1005
1006 tmpunderedges[coplanaredges[i].ea].ea = (short)(under_edge_count + i);
1007 }
1008
1009 under.edges = new List<ConvexH.HalfEdge>(tmpunderedges);
1010 under.facets = new List<Plane>(tmpunderplanes);
1011 return punder;
1012 }
1013
1014 public static ConvexH ConvexHDup(ConvexH src)
1015 {
1016 ConvexH dst = new ConvexH(src.vertices.Count, src.edges.Count, src.facets.Count);
1017 dst.vertices = new List<float3>(src.vertices.Count);
1018 foreach (float3 f in src.vertices)
1019 dst.vertices.Add(new float3(f));
1020 dst.edges = new List<ConvexH.HalfEdge>(src.edges.Count);
1021 foreach (ConvexH.HalfEdge e in src.edges)
1022 dst.edges.Add(new ConvexH.HalfEdge(e));
1023 dst.facets = new List<Plane>(src.facets.Count);
1024 foreach (Plane p in src.facets)
1025 dst.facets.Add(new Plane(p));
1026 return dst;
1027 }
1028
1029 public static int candidateplane(List<Plane> planes, int planes_count, ConvexH convex, float epsilon)
1030 {
1031 int p = 0;
1032 float md = 0;
1033 int i;
1034 for (i = 0; i < planes_count; i++)
1035 {
1036 float d = 0;
1037 for (int j = 0; j < convex.vertices.Count; j++)
1038 {
1039 d = Math.Max(d, float3.dot(convex.vertices[j], planes[i].normal) + planes[i].dist);
1040 }
1041 if (i == 0 || d > md)
1042 {
1043 p = i;
1044 md = d;
1045 }
1046 }
1047 return (md > epsilon) ? p : -1;
1048 }
1049
1050 public static float3 orth(float3 v)
1051 {
1052 float3 a = float3.cross(v, new float3(0f, 0f, 1f));
1053 float3 b = float3.cross(v, new float3(0f, 1f, 0f));
1054 return float3.normalize((float3.magnitude(a) > float3.magnitude(b)) ? a : b);
1055 }
1056
1057 public static int maxdir(List<float3> p, int count, float3 dir)
1058 {
1059 Debug.Assert(count != 0);
1060 int m = 0;
1061 float currDotm = float3.dot(p[0], dir);
1062 for (int i = 1; i < count; i++)
1063 {
1064 float currDoti = float3.dot(p[i], dir);
1065 if (currDoti > currDotm)
1066 {
1067 currDotm = currDoti;
1068 m = i;
1069 }
1070 }
1071 return m;
1072 }
1073
1074 public static int maxdirfiltered(List<float3> p, int count, float3 dir, byte[] allow)
1075 {
1076 //Debug.Assert(count != 0);
1077 int m = 0;
1078 float currDotm = float3.dot(p[0], dir);
1079 float currDoti;
1080
1081 while (allow[m] == 0)
1082 m++;
1083
1084 for (int i = 1; i < count; i++)
1085 {
1086 if (allow[i] != 0)
1087 {
1088 currDoti = float3.dot(p[i], dir);
1089 if (currDoti > currDotm)
1090 {
1091 currDotm = currDoti;
1092 m = i;
1093 }
1094 }
1095 }
1096 //Debug.Assert(m != -1);
1097 return m;
1098 }
1099
1100 public static int maxdirsterid(List<float3> p, int count, float3 dir, byte[] allow)
1101 {
1102 int m = -1;
1103 while (m == -1)
1104 {
1105 m = maxdirfiltered(p, count, dir, allow);
1106 if (allow[m] == 3)
1107 return m;
1108 float3 u = orth(dir);
1109 float3 v = float3.cross(u, dir);
1110 int ma = -1;
1111 for (float x = 0.0f; x <= 360.0f; x += 45.0f)
1112 {
1113 int mb;
1114 {
1115 float s = (float)Math.Sin((3.14159264f / 180.0f) * (x));
1116 float c = (float)Math.Cos((3.14159264f / 180.0f) * (x));
1117 mb = maxdirfiltered(p, count, dir + (u * s + v * c) * 0.025f, allow);
1118 }
1119 if (ma == m && mb == m)
1120 {
1121 allow[m] = 3;
1122 return m;
1123 }
1124 if (ma != -1 && ma != mb) // Yuck - this is really ugly
1125 {
1126 int mc = ma;
1127 for (float xx = x - 40.0f; xx <= x; xx += 5.0f)
1128 {
1129 float s = (float)Math.Sin((3.14159264f / 180.0f) * (xx));
1130 float c = (float)Math.Cos((3.14159264f / 180.0f) * (xx));
1131 int md = maxdirfiltered(p, count, dir + (u * s + v * c) * 0.025f, allow);
1132 if (mc == m && md == m)
1133 {
1134 allow[m] = 3;
1135 return m;
1136 }
1137 mc = md;
1138 }
1139 }
1140 ma = mb;
1141 }
1142 allow[m] = 0;
1143 m = -1;
1144 }
1145
1146 Debug.Assert(false);
1147 return m;
1148 }
1149
1150 public static int4 FindSimplex(List<float3> verts, byte[] allow)
1151 {
1152 float3[] basis = new float3[3];
1153 basis[0] = new float3(0.01f, 0.02f, 1.0f);
1154 int p0 = maxdirsterid(verts, verts.Count, basis[0], allow);
1155 int p1 = maxdirsterid(verts, verts.Count, -basis[0], allow);
1156 basis[0] = verts[p0] - verts[p1];
1157 if (p0 == p1 || basis[0] == new float3(0, 0, 0))
1158 return new int4(-1, -1, -1, -1);
1159 basis[1] = float3.cross(new float3(1, 0.02f, 0), basis[0]);
1160 basis[2] = float3.cross(new float3(-0.02f, 1, 0), basis[0]);
1161 basis[1] = float3.normalize((float3.magnitude(basis[1]) > float3.magnitude(basis[2])) ? basis[1] : basis[2]);
1162 int p2 = maxdirsterid(verts, verts.Count, basis[1], allow);
1163 if (p2 == p0 || p2 == p1)
1164 {
1165 p2 = maxdirsterid(verts, verts.Count, -basis[1], allow);
1166 }
1167 if (p2 == p0 || p2 == p1)
1168 return new int4(-1, -1, -1, -1);
1169 basis[1] = verts[p2] - verts[p0];
1170 basis[2] = float3.normalize(float3.cross(basis[1], basis[0]));
1171 int p3 = maxdirsterid(verts, verts.Count, basis[2], allow);
1172 if (p3 == p0 || p3 == p1 || p3 == p2)
1173 p3 = maxdirsterid(verts, verts.Count, -basis[2], allow);
1174 if (p3 == p0 || p3 == p1 || p3 == p2)
1175 return new int4(-1, -1, -1, -1);
1176 Debug.Assert(!(p0 == p1 || p0 == p2 || p0 == p3 || p1 == p2 || p1 == p3 || p2 == p3));
1177 if (float3.dot(verts[p3] - verts[p0], float3.cross(verts[p1] - verts[p0], verts[p2] - verts[p0])) < 0)
1178 {
1179 Swap(ref p2, ref p3);
1180 }
1181 return new int4(p0, p1, p2, p3);
1182 }
1183
1184 public static float GetDist(float px, float py, float pz, float3 p2)
1185 {
1186 float dx = px - p2.x;
1187 float dy = py - p2.y;
1188 float dz = pz - p2.z;
1189
1190 return dx * dx + dy * dy + dz * dz;
1191 }
1192
1193 public static void ReleaseHull(PHullResult result)
1194 {
1195 if (result.Indices != null)
1196 result.Indices = null;
1197 if (result.Vertices != null)
1198 result.Vertices = null;
1199 }
1200
1201 public static int calchullgen(List<float3> verts, int vlimit, List<HullTriangle> tris)
1202 {
1203 if (verts.Count < 4)
1204 return 0;
1205 if (vlimit == 0)
1206 vlimit = 1000000000;
1207 int j;
1208 float3 bmin = new float3(verts[0]);
1209 float3 bmax = new float3(verts[0]);
1210 List<int> isextreme = new List<int>(verts.Count);
1211 byte[] allow = new byte[verts.Count];
1212 for (j = 0; j < verts.Count; j++)
1213 {
1214 allow[j] = 1;
1215 isextreme.Add(0);
1216 bmin = float3.VectorMin(bmin, verts[j]);
1217 bmax = float3.VectorMax(bmax, verts[j]);
1218 }
1219 float epsilon = float3.magnitude(bmax - bmin) * 0.001f;
1220
1221 int4 p = FindSimplex(verts, allow);
1222 if (p.x == -1) // simplex failed
1223 return 0;
1224
1225 float3 center = (verts[p[0]] + verts[p[1]] + verts[p[2]] + verts[p[3]]) / 4.0f; // a valid interior point
1226 HullTriangle t0 = new HullTriangle(p[2], p[3], p[1], tris);
1227 t0.n = new int3(2, 3, 1);
1228 HullTriangle t1 = new HullTriangle(p[3], p[2], p[0], tris);
1229 t1.n = new int3(3, 2, 0);
1230 HullTriangle t2 = new HullTriangle(p[0], p[1], p[3], tris);
1231 t2.n = new int3(0, 1, 3);
1232 HullTriangle t3 = new HullTriangle(p[1], p[0], p[2], tris);
1233 t3.n = new int3(1, 0, 2);
1234 isextreme[p[0]] = isextreme[p[1]] = isextreme[p[2]] = isextreme[p[3]] = 1;
1235 checkit(t0, tris);
1236 checkit(t1, tris);
1237 checkit(t2, tris);
1238 checkit(t3, tris);
1239
1240 for (j = 0; j < tris.Count; j++)
1241 {
1242 HullTriangle t = tris[j];
1243 Debug.Assert((object)t != null);
1244 Debug.Assert(t.vmax < 0);
1245 float3 n = TriNormal(verts[(t)[0]], verts[(t)[1]], verts[(t)[2]]);
1246 t.vmax = maxdirsterid(verts, verts.Count, n, allow);
1247 t.rise = float3.dot(n, verts[t.vmax] - verts[(t)[0]]);
1248 }
1249 HullTriangle te;
1250 vlimit -= 4;
1251 while (vlimit > 0 && (te = extrudable(epsilon, tris)) != null)
1252 {
1253 int3 ti = te;
1254 int v = te.vmax;
1255 Debug.Assert(isextreme[v] == 0); // wtf we've already done this vertex
1256 isextreme[v] = 1;
1257 //if(v==p0 || v==p1 || v==p2 || v==p3) continue; // done these already
1258 j = tris.Count;
1259 while (j-- != 0)
1260 {
1261 if (tris.Count <= j || (object)tris[j] == null)
1262 continue;
1263 int3 t = tris[j];
1264 if (above(verts, t, verts[v], 0.01f * epsilon))
1265 {
1266 extrude(tris[j], v, tris);
1267 }
1268 }
1269 // now check for those degenerate cases where we have a flipped triangle or a really skinny triangle
1270 j = tris.Count;
1271 while (j-- != 0)
1272 {
1273 if (tris.Count <= j || (object)tris[j] == null)
1274 continue;
1275 if (!hasvert(tris[j], v))
1276 break;
1277 int3 nt = tris[j];
1278 if (above(verts, nt, center, 0.01f * epsilon) || float3.magnitude(float3.cross(verts[nt[1]] - verts[nt[0]], verts[nt[2]] - verts[nt[1]])) < epsilon * epsilon * 0.1f)
1279 {
1280 HullTriangle nb = tris[tris[j].n[0]];
1281 Debug.Assert(nb != null);
1282 Debug.Assert(!hasvert(nb, v));
1283 Debug.Assert(nb.id < j);
1284 extrude(nb, v, tris);
1285 j = tris.Count;
1286 }
1287 }
1288 j = tris.Count;
1289 while (j-- != 0)
1290 {
1291 HullTriangle t = tris[j];
1292 if (t == null)
1293 continue;
1294 if (t.vmax >= 0)
1295 break;
1296 float3 n = TriNormal(verts[(t)[0]], verts[(t)[1]], verts[(t)[2]]);
1297 t.vmax = maxdirsterid(verts, verts.Count, n, allow);
1298 if (isextreme[t.vmax] != 0)
1299 {
1300 t.vmax = -1; // already done that vertex - algorithm needs to be able to terminate.
1301 }
1302 else
1303 {
1304 t.rise = float3.dot(n, verts[t.vmax] - verts[(t)[0]]);
1305 }
1306 }
1307 vlimit--;
1308 }
1309 return 1;
1310 }
1311
1312 public static bool calchull(List<float3> verts, out List<int> tris_out, int vlimit, List<HullTriangle> tris)
1313 {
1314 tris_out = null;
1315
1316 int rc = calchullgen(verts, vlimit, tris);
1317 if (rc == 0)
1318 return false;
1319 List<int> ts = new List<int>();
1320 for (int i = 0; i < tris.Count; i++)
1321 {
1322 if ((object)tris[i] != null)
1323 {
1324 for (int j = 0; j < 3; j++)
1325 ts.Add((tris[i])[j]);
1326 tris[i] = null;
1327 }
1328 }
1329
1330 tris_out = ts;
1331 tris.Clear();
1332 return true;
1333 }
1334
1335 public static int calchullpbev(List<float3> verts, int vlimit, out List<Plane> planes, float bevangle, List<HullTriangle> tris)
1336 {
1337 int i;
1338 int j;
1339 planes = new List<Plane>();
1340 int rc = calchullgen(verts, vlimit, tris);
1341 if (rc == 0)
1342 return 0;
1343 for (i = 0; i < tris.Count; i++)
1344 {
1345 if (tris[i] != null)
1346 {
1347 Plane p = new Plane();
1348 HullTriangle t = tris[i];
1349 p.normal = TriNormal(verts[(t)[0]], verts[(t)[1]], verts[(t)[2]]);
1350 p.dist = -float3.dot(p.normal, verts[(t)[0]]);
1351 planes.Add(p);
1352 for (j = 0; j < 3; j++)
1353 {
1354 if (t.n[j] < t.id)
1355 continue;
1356 HullTriangle s = tris[t.n[j]];
1357 float3 snormal = TriNormal(verts[(s)[0]], verts[(s)[1]], verts[(s)[2]]);
1358 if (float3.dot(snormal, p.normal) >= Math.Cos(bevangle * (3.14159264f / 180.0f)))
1359 continue;
1360 float3 n = float3.normalize(snormal + p.normal);
1361 planes.Add(new Plane(n, -float3.dot(n, verts[maxdir(verts, verts.Count, n)])));
1362 }
1363 }
1364 }
1365
1366 tris.Clear();
1367 return 1;
1368 }
1369
1370 public static int overhull(List<Plane> planes, List<float3> verts, int maxplanes, out List<float3> verts_out, out List<int> faces_out, float inflate)
1371 {
1372 verts_out = null;
1373 faces_out = null;
1374
1375 int i;
1376 int j;
1377 if (verts.Count < 4)
1378 return 0;
1379 maxplanes = Math.Min(maxplanes, planes.Count);
1380 float3 bmin = new float3(verts[0]);
1381 float3 bmax = new float3(verts[0]);
1382 for (i = 0; i < verts.Count; i++)
1383 {
1384 bmin = float3.VectorMin(bmin, verts[i]);
1385 bmax = float3.VectorMax(bmax, verts[i]);
1386 }
1387 // float diameter = magnitude(bmax-bmin);
1388 // inflate *=diameter; // RELATIVE INFLATION
1389 bmin -= new float3(inflate, inflate, inflate);
1390 bmax += new float3(inflate, inflate, inflate);
1391 for (i = 0; i < planes.Count; i++)
1392 {
1393 planes[i].dist -= inflate;
1394 }
1395 float3 emin = new float3(bmin);
1396 float3 emax = new float3(bmax);
1397 float epsilon = float3.magnitude(emax - emin) * 0.025f;
1398 float planetestepsilon = float3.magnitude(emax - emin) * (0.001f);
1399 // todo: add bounding cube planes to force bevel. or try instead not adding the diameter expansion ??? must think.
1400 // ConvexH *convex = ConvexHMakeCube(bmin - float3(diameter,diameter,diameter),bmax+float3(diameter,diameter,diameter));
1401 ConvexH c = ConvexHMakeCube(new float3(bmin), new float3(bmax));
1402 int k;
1403 while (maxplanes-- != 0 && (k = candidateplane(planes, planes.Count, c, epsilon)) >= 0)
1404 {
1405 ConvexH tmp = c;
1406 c = ConvexHCrop(ref tmp, planes[k], planetestepsilon);
1407 if (c == null) // might want to debug this case better!!!
1408 {
1409 c = tmp;
1410 break;
1411 }
1412 if (AssertIntact(c, planetestepsilon) == false) // might want to debug this case better too!!!
1413 {
1414 c = tmp;
1415 break;
1416 }
1417 tmp.edges = null;
1418 tmp.facets = null;
1419 tmp.vertices = null;
1420 }
1421
1422 Debug.Assert(AssertIntact(c, planetestepsilon));
1423 //return c;
1424 //C++ TO C# CONVERTER TODO TASK: The memory management function 'malloc' has no equivalent in C#:
1425 faces_out = new List<int>(); //(int)malloc(sizeof(int) * (1 + c.facets.Count + c.edges.Count)); // new int[1+c->facets.count+c->edges.count];
1426 int faces_count_out = 0;
1427 i = 0;
1428 faces_out[faces_count_out++] = -1;
1429 k = 0;
1430 while (i < c.edges.Count)
1431 {
1432 j = 1;
1433 while (j + i < c.edges.Count && c.edges[i].p == c.edges[i + j].p)
1434 {
1435 j++;
1436 }
1437 faces_out[faces_count_out++] = j;
1438 while (j-- != 0)
1439 {
1440 faces_out[faces_count_out++] = c.edges[i].v;
1441 i++;
1442 }
1443 k++;
1444 }
1445 faces_out[0] = k; // number of faces.
1446 Debug.Assert(k == c.facets.Count);
1447 Debug.Assert(faces_count_out == 1 + c.facets.Count + c.edges.Count);
1448 verts_out = c.vertices; // new float3[c->vertices.count];
1449 int verts_count_out = c.vertices.Count;
1450 for (i = 0; i < c.vertices.Count; i++)
1451 {
1452 verts_out[i] = new float3(c.vertices[i]);
1453 }
1454
1455 c.edges = null;
1456 c.facets = null;
1457 c.vertices = null;
1458 return 1;
1459 }
1460
1461 public static int overhullv(List<float3> verts, int maxplanes, out List<float3> verts_out, out List<int> faces_out, float inflate, float bevangle, int vlimit, List<HullTriangle> tris)
1462 {
1463 verts_out = null;
1464 faces_out = null;
1465
1466 if (verts.Count == 0)
1467 return 0;
1468 List<Plane> planes = new List<Plane>();
1469 int rc = calchullpbev(verts, vlimit, out planes, bevangle, tris);
1470 if (rc == 0)
1471 return 0;
1472 return overhull(planes, verts, maxplanes, out verts_out, out faces_out, inflate);
1473 }
1474
1475 public static void addPoint(ref uint vcount, List<float3> p, float x, float y, float z)
1476 {
1477 p.Add(new float3(x, y, z));
1478 vcount++;
1479 }
1480
1481 public static bool ComputeHull(List<float3> vertices, ref PHullResult result, int vlimit, float inflate)
1482 {
1483 List<HullTriangle> tris = new List<HullTriangle>();
1484 List<int> faces;
1485 List<float3> verts_out;
1486
1487 if (inflate == 0.0f)
1488 {
1489 List<int> tris_out;
1490 bool ret = calchull(vertices, out tris_out, vlimit, tris);
1491 if (ret == false)
1492 return false;
1493
1494 result.Indices = tris_out;
1495 result.Vertices = vertices;
1496 return true;
1497 }
1498 else
1499 {
1500 int ret = overhullv(vertices, 35, out verts_out, out faces, inflate, 120.0f, vlimit, tris);
1501 if (ret == 0)
1502 return false;
1503
1504 List<int3> tris2 = new List<int3>();
1505 int n = faces[0];
1506 int k = 1;
1507 for (int i = 0; i < n; i++)
1508 {
1509 int pn = faces[k++];
1510 for (int j = 2; j < pn; j++)
1511 tris2.Add(new int3(faces[k], faces[k + j - 1], faces[k + j]));
1512 k += pn;
1513 }
1514 Debug.Assert(tris2.Count == faces.Count - 1 - (n * 3));
1515
1516 result.Indices = new List<int>(tris2.Count * 3);
1517 for (int i = 0; i < tris2.Count; i++)
1518 {
1519 result.Indices.Add(tris2[i].x);
1520 result.Indices.Add(tris2[i].y);
1521 result.Indices.Add(tris2[i].z);
1522 }
1523 result.Vertices = verts_out;
1524
1525 return true;
1526 }
1527 }
1528
1529 private static bool CleanupVertices(List<float3> svertices, out List<float3> vertices, float normalepsilon, out float3 scale)
1530 {
1531 const float EPSILON = 0.000001f;
1532
1533 vertices = new List<float3>();
1534 scale = new float3(1f, 1f, 1f);
1535
1536 if (svertices.Count == 0)
1537 return false;
1538
1539 uint vcount = 0;
1540
1541 float[] recip = new float[3];
1542
1543 float[] bmin = { Single.MaxValue, Single.MaxValue, Single.MaxValue };
1544 float[] bmax = { Single.MinValue, Single.MinValue, Single.MinValue };
1545
1546 for (int i = 0; i < svertices.Count; i++)
1547 {
1548 float3 p = svertices[i];
1549
1550 for (int j = 0; j < 3; j++)
1551 {
1552 if (p[j] < bmin[j])
1553 bmin[j] = p[j];
1554 if (p[j] > bmax[j])
1555 bmax[j] = p[j];
1556 }
1557 }
1558
1559 float dx = bmax[0] - bmin[0];
1560 float dy = bmax[1] - bmin[1];
1561 float dz = bmax[2] - bmin[2];
1562
1563 float3 center = new float3();
1564
1565 center.x = dx * 0.5f + bmin[0];
1566 center.y = dy * 0.5f + bmin[1];
1567 center.z = dz * 0.5f + bmin[2];
1568
1569 if (dx < EPSILON || dy < EPSILON || dz < EPSILON || svertices.Count < 3)
1570 {
1571 float len = Single.MaxValue;
1572
1573 if (dx > EPSILON && dx < len)
1574 len = dx;
1575 if (dy > EPSILON && dy < len)
1576 len = dy;
1577 if (dz > EPSILON && dz < len)
1578 len = dz;
1579
1580 if (len == Single.MaxValue)
1581 {
1582 dx = dy = dz = 0.01f; // one centimeter
1583 }
1584 else
1585 {
1586 if (dx < EPSILON) // 1/5th the shortest non-zero edge.
1587 dx = len * 0.05f;
1588 if (dy < EPSILON)
1589 dy = len * 0.05f;
1590 if (dz < EPSILON)
1591 dz = len * 0.05f;
1592 }
1593
1594 float x1 = center[0] - dx;
1595 float x2 = center[0] + dx;
1596
1597 float y1 = center[1] - dy;
1598 float y2 = center[1] + dy;
1599
1600 float z1 = center[2] - dz;
1601 float z2 = center[2] + dz;
1602
1603 addPoint(ref vcount, vertices, x1, y1, z1);
1604 addPoint(ref vcount, vertices, x2, y1, z1);
1605 addPoint(ref vcount, vertices, x2, y2, z1);
1606 addPoint(ref vcount, vertices, x1, y2, z1);
1607 addPoint(ref vcount, vertices, x1, y1, z2);
1608 addPoint(ref vcount, vertices, x2, y1, z2);
1609 addPoint(ref vcount, vertices, x2, y2, z2);
1610 addPoint(ref vcount, vertices, x1, y2, z2);
1611
1612 return true; // return cube
1613 }
1614 else
1615 {
1616 scale.x = dx;
1617 scale.y = dy;
1618 scale.z = dz;
1619
1620 recip[0] = 1f / dx;
1621 recip[1] = 1f / dy;
1622 recip[2] = 1f / dz;
1623
1624 center.x *= recip[0];
1625 center.y *= recip[1];
1626 center.z *= recip[2];
1627 }
1628
1629 for (int i = 0; i < svertices.Count; i++)
1630 {
1631 float3 p = svertices[i];
1632
1633 float px = p[0];
1634 float py = p[1];
1635 float pz = p[2];
1636
1637 px = px * recip[0]; // normalize
1638 py = py * recip[1]; // normalize
1639 pz = pz * recip[2]; // normalize
1640
1641 if (true)
1642 {
1643 int j;
1644
1645 for (j = 0; j < vcount; j++)
1646 {
1647 float3 v = vertices[j];
1648
1649 float x = v[0];
1650 float y = v[1];
1651 float z = v[2];
1652
1653 float dx1 = Math.Abs(x - px);
1654 float dy1 = Math.Abs(y - py);
1655 float dz1 = Math.Abs(z - pz);
1656
1657 if (dx1 < normalepsilon && dy1 < normalepsilon && dz1 < normalepsilon)
1658 {
1659 // ok, it is close enough to the old one
1660 // now let us see if it is further from the center of the point cloud than the one we already recorded.
1661 // in which case we keep this one instead.
1662 float dist1 = GetDist(px, py, pz, center);
1663 float dist2 = GetDist(v[0], v[1], v[2], center);
1664
1665 if (dist1 > dist2)
1666 {
1667 v.x = px;
1668 v.y = py;
1669 v.z = pz;
1670 }
1671
1672 break;
1673 }
1674 }
1675
1676 if (j == vcount)
1677 {
1678 float3 dest = new float3(px, py, pz);
1679 vertices.Add(dest);
1680 vcount++;
1681 }
1682 }
1683 }
1684
1685 // ok..now make sure we didn't prune so many vertices it is now invalid.
1686 if (true)
1687 {
1688 float[] bmin2 = { Single.MaxValue, Single.MaxValue, Single.MaxValue };
1689 float[] bmax2 = { Single.MinValue, Single.MinValue, Single.MinValue };
1690
1691 for (int i = 0; i < vcount; i++)
1692 {
1693 float3 p = vertices[i];
1694 for (int j = 0; j < 3; j++)
1695 {
1696 if (p[j] < bmin2[j])
1697 bmin2[j] = p[j];
1698 if (p[j] > bmax2[j])
1699 bmax2[j] = p[j];
1700 }
1701 }
1702
1703 float dx2 = bmax2[0] - bmin2[0];
1704 float dy2 = bmax2[1] - bmin2[1];
1705 float dz2 = bmax2[2] - bmin2[2];
1706
1707 if (dx2 < EPSILON || dy2 < EPSILON || dz2 < EPSILON || vcount < 3)
1708 {
1709 float cx = dx2 * 0.5f + bmin2[0];
1710 float cy = dy2 * 0.5f + bmin2[1];
1711 float cz = dz2 * 0.5f + bmin2[2];
1712
1713 float len = Single.MaxValue;
1714
1715 if (dx2 >= EPSILON && dx2 < len)
1716 len = dx2;
1717 if (dy2 >= EPSILON && dy2 < len)
1718 len = dy2;
1719 if (dz2 >= EPSILON && dz2 < len)
1720 len = dz2;
1721
1722 if (len == Single.MaxValue)
1723 {
1724 dx2 = dy2 = dz2 = 0.01f; // one centimeter
1725 }
1726 else
1727 {
1728 if (dx2 < EPSILON) // 1/5th the shortest non-zero edge.
1729 dx2 = len * 0.05f;
1730 if (dy2 < EPSILON)
1731 dy2 = len * 0.05f;
1732 if (dz2 < EPSILON)
1733 dz2 = len * 0.05f;
1734 }
1735
1736 float x1 = cx - dx2;
1737 float x2 = cx + dx2;
1738
1739 float y1 = cy - dy2;
1740 float y2 = cy + dy2;
1741
1742 float z1 = cz - dz2;
1743 float z2 = cz + dz2;
1744
1745 vcount = 0; // add box
1746
1747 addPoint(ref vcount, vertices, x1, y1, z1);
1748 addPoint(ref vcount, vertices, x2, y1, z1);
1749 addPoint(ref vcount, vertices, x2, y2, z1);
1750 addPoint(ref vcount, vertices, x1, y2, z1);
1751 addPoint(ref vcount, vertices, x1, y1, z2);
1752 addPoint(ref vcount, vertices, x2, y1, z2);
1753 addPoint(ref vcount, vertices, x2, y2, z2);
1754 addPoint(ref vcount, vertices, x1, y2, z2);
1755
1756 return true;
1757 }
1758 }
1759
1760 return true;
1761 }
1762
1763 private static void BringOutYourDead(List<float3> verts, out List<float3> overts, List<int> indices)
1764 {
1765 int[] used = new int[verts.Count];
1766 int ocount = 0;
1767
1768 overts = new List<float3>();
1769
1770 for (int i = 0; i < indices.Count; i++)
1771 {
1772 int v = indices[i]; // original array index
1773
1774 Debug.Assert(v >= 0 && v < verts.Count);
1775
1776 if (used[v] != 0) // if already remapped
1777 {
1778 indices[i] = used[v] - 1; // index to new array
1779 }
1780 else
1781 {
1782 indices[i] = ocount; // new index mapping
1783
1784 overts.Add(verts[v]); // copy old vert to new vert array
1785
1786 ocount++; // increment output vert count
1787
1788 Debug.Assert(ocount >= 0 && ocount <= verts.Count);
1789
1790 used[v] = ocount; // assign new index remapping
1791 }
1792 }
1793 }
1794
1795 public static HullError CreateConvexHull(HullDesc desc, ref HullResult result)
1796 {
1797 HullError ret = HullError.QE_FAIL;
1798
1799 PHullResult hr = new PHullResult();
1800
1801 uint vcount = (uint)desc.Vertices.Count;
1802 if (vcount < 8)
1803 vcount = 8;
1804
1805 List<float3> vsource;
1806 float3 scale = new float3();
1807
1808 bool ok = CleanupVertices(desc.Vertices, out vsource, desc.NormalEpsilon, out scale); // normalize point cloud, remove duplicates!
1809
1810 if (ok)
1811 {
1812 if (true) // scale vertices back to their original size.
1813 {
1814 for (int i = 0; i < vsource.Count; i++)
1815 {
1816 float3 v = vsource[i];
1817 v.x *= scale[0];
1818 v.y *= scale[1];
1819 v.z *= scale[2];
1820 }
1821 }
1822
1823 float skinwidth = 0;
1824 if (desc.HasHullFlag(HullFlag.QF_SKIN_WIDTH))
1825 skinwidth = desc.SkinWidth;
1826
1827 ok = ComputeHull(vsource, ref hr, (int)desc.MaxVertices, skinwidth);
1828
1829 if (ok)
1830 {
1831 List<float3> vscratch;
1832 BringOutYourDead(hr.Vertices, out vscratch, hr.Indices);
1833
1834 ret = HullError.QE_OK;
1835
1836 if (desc.HasHullFlag(HullFlag.QF_TRIANGLES)) // if he wants the results as triangle!
1837 {
1838 result.Polygons = false;
1839 result.Indices = hr.Indices;
1840 result.OutputVertices = vscratch;
1841 }
1842 else
1843 {
1844 result.Polygons = true;
1845 result.OutputVertices = vscratch;
1846
1847 if (true)
1848 {
1849 List<int> source = hr.Indices;
1850 List<int> dest = new List<int>();
1851 for (int i = 0; i < hr.Indices.Count / 3; i++)
1852 {
1853 dest.Add(3);
1854 dest.Add(source[i * 3 + 0]);
1855 dest.Add(source[i * 3 + 1]);
1856 dest.Add(source[i * 3 + 2]);
1857 }
1858
1859 result.Indices = dest;
1860 }
1861 }
1862 }
1863 }
1864
1865 return ret;
1866 }
1867 }
1868}
diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/LICENSE.txt b/OpenSim/Region/Physics/ConvexDecompositionDotNet/LICENSE.txt
new file mode 100644
index 0000000..714ae89
--- /dev/null
+++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/LICENSE.txt
@@ -0,0 +1,28 @@
1ConvexDecompositionDotNet
2-------------------------
3
4The MIT License
5
6Copyright (c) 2010 Intel Corporation.
7All rights reserved.
8
9Based on the convexdecomposition library from
10<http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files (the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions:
18
19The above copyright notice and this permission notice shall be included in
20all copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28THE SOFTWARE.
diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/Plane.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Plane.cs
new file mode 100644
index 0000000..d099676
--- /dev/null
+++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Plane.cs
@@ -0,0 +1,99 @@
1/* The MIT License
2 *
3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved.
5 *
6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
27
28using System;
29
30namespace OpenSim.Region.Physics.ConvexDecompositionDotNet
31{
32 public class Plane
33 {
34 public float3 normal = new float3();
35 public float dist; // distance below origin - the D from plane equasion Ax+By+Cz+D=0
36
37 public Plane(float3 n, float d)
38 {
39 normal = new float3(n);
40 dist = d;
41 }
42
43 public Plane(Plane p)
44 {
45 normal = new float3(p.normal);
46 dist = p.dist;
47 }
48
49 public Plane()
50 {
51 dist = 0;
52 }
53
54 public void Transform(float3 position, Quaternion orientation)
55 {
56 // Transforms the plane to the space defined by the
57 // given position/orientation
58 float3 newNormal = Quaternion.Inverse(orientation) * normal;
59 float3 origin = Quaternion.Inverse(orientation) * (-normal * dist - position);
60
61 normal = newNormal;
62 dist = -float3.dot(newNormal, origin);
63 }
64
65 public override int GetHashCode()
66 {
67 return normal.GetHashCode() ^ dist.GetHashCode();
68 }
69
70 public override bool Equals(object obj)
71 {
72 Plane p = obj as Plane;
73 if (p == null)
74 return false;
75
76 return this == p;
77 }
78
79 public static bool operator ==(Plane a, Plane b)
80 {
81 return (a.normal == b.normal && a.dist == b.dist);
82 }
83
84 public static bool operator !=(Plane a, Plane b)
85 {
86 return !(a == b);
87 }
88
89 public static Plane PlaneFlip(Plane plane)
90 {
91 return new Plane(-plane.normal, -plane.dist);
92 }
93
94 public static bool coplanar(Plane a, Plane b)
95 {
96 return (a == b || a == PlaneFlip(b));
97 }
98 }
99}
diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/PlaneTri.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/PlaneTri.cs
new file mode 100644
index 0000000..31f0182
--- /dev/null
+++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/PlaneTri.cs
@@ -0,0 +1,211 @@
1/* The MIT License
2 *
3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved.
5 *
6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Diagnostics;
31
32namespace OpenSim.Region.Physics.ConvexDecompositionDotNet
33{
34 public enum PlaneTriResult : int
35 {
36 PTR_FRONT,
37 PTR_BACK,
38 PTR_SPLIT
39 }
40
41 public static class PlaneTri
42 {
43 private static float DistToPt(float3 p, float4 plane)
44 {
45 return p.x * plane.x + p.y * plane.y + p.z * plane.z + plane.w;
46 }
47
48 private static PlaneTriResult getSidePlane(float3 p, float4 plane, float epsilon)
49 {
50 float d = DistToPt(p, plane);
51
52 if ((d + epsilon) > 0f)
53 return PlaneTriResult.PTR_FRONT; // it is 'in front' within the provided epsilon value.
54
55 return PlaneTriResult.PTR_BACK;
56 }
57
58 private static void add(float3 p, float3[] dest, ref int pcount)
59 {
60 dest[pcount++] = new float3(p);
61 Debug.Assert(pcount <= 4);
62 }
63
64 // assumes that the points are on opposite sides of the plane!
65 private static void intersect(float3 p1, float3 p2, float3 split, float4 plane)
66 {
67 float dp1 = DistToPt(p1, plane);
68 float[] dir = new float[3];
69
70 dir[0] = p2[0] - p1[0];
71 dir[1] = p2[1] - p1[1];
72 dir[2] = p2[2] - p1[2];
73
74 float dot1 = dir[0] * plane[0] + dir[1] * plane[1] + dir[2] * plane[2];
75 float dot2 = dp1 - plane[3];
76
77 float t = -(plane[3] + dot2) / dot1;
78
79 split.x = (dir[0] * t) + p1[0];
80 split.y = (dir[1] * t) + p1[1];
81 split.z = (dir[2] * t) + p1[2];
82 }
83
84 public static PlaneTriResult planeTriIntersection(float4 plane, FaceTri triangle, float epsilon, ref float3[] front, out int fcount, ref float3[] back, out int bcount)
85 {
86 fcount = 0;
87 bcount = 0;
88
89 // get the three vertices of the triangle.
90 float3 p1 = triangle.P1;
91 float3 p2 = triangle.P2;
92 float3 p3 = triangle.P3;
93
94 PlaneTriResult r1 = getSidePlane(p1, plane, epsilon); // compute the side of the plane each vertex is on
95 PlaneTriResult r2 = getSidePlane(p2, plane, epsilon);
96 PlaneTriResult r3 = getSidePlane(p3, plane, epsilon);
97
98 if (r1 == r2 && r1 == r3) // if all three vertices are on the same side of the plane.
99 {
100 if (r1 == PlaneTriResult.PTR_FRONT) // if all three are in front of the plane, then copy to the 'front' output triangle.
101 {
102 add(p1, front, ref fcount);
103 add(p2, front, ref fcount);
104 add(p3, front, ref fcount);
105 }
106 else
107 {
108 add(p1, back, ref bcount); // if all three are in 'back' then copy to the 'back' output triangle.
109 add(p2, back, ref bcount);
110 add(p3, back, ref bcount);
111 }
112 return r1; // if all three points are on the same side of the plane return result
113 }
114
115 // ok.. we need to split the triangle at the plane.
116
117 // First test ray segment P1 to P2
118 if (r1 == r2) // if these are both on the same side...
119 {
120 if (r1 == PlaneTriResult.PTR_FRONT)
121 {
122 add(p1, front, ref fcount);
123 add(p2, front, ref fcount);
124 }
125 else
126 {
127 add(p1, back, ref bcount);
128 add(p2, back, ref bcount);
129 }
130 }
131 else
132 {
133 float3 split = new float3();
134 intersect(p1, p2, split, plane);
135
136 if (r1 == PlaneTriResult.PTR_FRONT)
137 {
138
139 add(p1, front, ref fcount);
140 add(split, front, ref fcount);
141
142 add(split, back, ref bcount);
143 add(p2, back, ref bcount);
144
145 }
146 else
147 {
148 add(p1, back, ref bcount);
149 add(split, back, ref bcount);
150
151 add(split, front, ref fcount);
152 add(p2, front, ref fcount);
153 }
154
155 }
156
157 // Next test ray segment P2 to P3
158 if (r2 == r3) // if these are both on the same side...
159 {
160 if (r3 == PlaneTriResult.PTR_FRONT)
161 {
162 add(p3, front, ref fcount);
163 }
164 else
165 {
166 add(p3, back, ref bcount);
167 }
168 }
169 else
170 {
171 float3 split = new float3(); // split the point
172 intersect(p2, p3, split, plane);
173
174 if (r3 == PlaneTriResult.PTR_FRONT)
175 {
176 add(split, front, ref fcount);
177 add(split, back, ref bcount);
178
179 add(p3, front, ref fcount);
180 }
181 else
182 {
183 add(split, front, ref fcount);
184 add(split, back, ref bcount);
185
186 add(p3, back, ref bcount);
187 }
188 }
189
190 // Next test ray segment P3 to P1
191 if (r3 != r1) // if these are both on the same side...
192 {
193 float3 split = new float3(); // split the point
194 intersect(p3, p1, split, plane);
195
196 if (r1 == PlaneTriResult.PTR_FRONT)
197 {
198 add(split, front, ref fcount);
199 add(split, back, ref bcount);
200 }
201 else
202 {
203 add(split, front, ref fcount);
204 add(split, back, ref bcount);
205 }
206 }
207
208 return PlaneTriResult.PTR_SPLIT;
209 }
210 }
211}
diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..4285e8c
--- /dev/null
+++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
1using System.Reflection;
2using System.Runtime.CompilerServices;
3using System.Runtime.InteropServices;
4
5// General Information about an assembly is controlled through the following
6// set of attributes. Change these attribute values to modify the information
7// associated with an assembly.
8[assembly: AssemblyTitle("ConvexDecompositionDotNet")]
9[assembly: AssemblyDescription("")]
10[assembly: AssemblyConfiguration("")]
11[assembly: AssemblyCompany("Intel Corporation")]
12[assembly: AssemblyProduct("ConvexDecompositionDotNet")]
13[assembly: AssemblyCopyright("Copyright © Intel Corporation 2010")]
14[assembly: AssemblyTrademark("")]
15[assembly: AssemblyCulture("")]
16
17// Setting ComVisible to false makes the types in this assembly not visible
18// to COM components. If you need to access a type in this assembly from
19// COM, set the ComVisible attribute to true on that type.
20[assembly: ComVisible(false)]
21
22// The following GUID is for the ID of the typelib if this project is exposed to COM
23[assembly: Guid("2a1c9467-1a17-4c8d-bf9f-4b4d86dd0cbb")]
24
25// Version information for an assembly consists of the following four values:
26//
27// Major Version
28// Minor Version
29// Build Number
30// Revision
31//
32// You can specify all the values or you can default the Build and Revision Numbers
33// by using the '*' as shown below:
34// [assembly: AssemblyVersion("1.0.*")]
35[assembly: AssemblyVersion("1.0.0.0")]
36[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/Quaternion.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Quaternion.cs
new file mode 100644
index 0000000..0ba8f17
--- /dev/null
+++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Quaternion.cs
@@ -0,0 +1,209 @@
1/* The MIT License
2 *
3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved.
5 *
6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
27
28using System;
29
30namespace OpenSim.Region.Physics.ConvexDecompositionDotNet
31{
32 public class Quaternion : float4
33 {
34 public Quaternion()
35 {
36 x = y = z = 0.0f;
37 w = 1.0f;
38 }
39
40 public Quaternion(float3 v, float t)
41 {
42 v = float3.normalize(v);
43 w = (float)Math.Cos(t / 2.0f);
44 v = v * (float)Math.Sin(t / 2.0f);
45 x = v.x;
46 y = v.y;
47 z = v.z;
48 }
49
50 public Quaternion(float _x, float _y, float _z, float _w)
51 {
52 x = _x;
53 y = _y;
54 z = _z;
55 w = _w;
56 }
57
58 public float angle()
59 {
60 return (float)Math.Acos(w) * 2.0f;
61 }
62
63 public float3 axis()
64 {
65 float3 a = new float3(x, y, z);
66 if (Math.Abs(angle()) < 0.0000001f)
67 return new float3(1f, 0f, 0f);
68 return a * (1 / (float)Math.Sin(angle() / 2.0f));
69 }
70
71 public float3 xdir()
72 {
73 return new float3(1 - 2 * (y * y + z * z), 2 * (x * y + w * z), 2 * (x * z - w * y));
74 }
75
76 public float3 ydir()
77 {
78 return new float3(2 * (x * y - w * z), 1 - 2 * (x * x + z * z), 2 * (y * z + w * x));
79 }
80
81 public float3 zdir()
82 {
83 return new float3(2 * (x * z + w * y), 2 * (y * z - w * x), 1 - 2 * (x * x + y * y));
84 }
85
86 public float3x3 getmatrix()
87 {
88 return new float3x3(xdir(), ydir(), zdir());
89 }
90
91 public static implicit operator float3x3(Quaternion q)
92 {
93 return q.getmatrix();
94 }
95
96 public static Quaternion operator *(Quaternion a, Quaternion b)
97 {
98 Quaternion c = new Quaternion();
99 c.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;
100 c.x = a.w * b.x + a.x * b.w + a.y * b.z - a.z * b.y;
101 c.y = a.w * b.y - a.x * b.z + a.y * b.w + a.z * b.x;
102 c.z = a.w * b.z + a.x * b.y - a.y * b.x + a.z * b.w;
103 return c;
104 }
105
106 public static float3 operator *(Quaternion q, float3 v)
107 {
108 // The following is equivalent to:
109 //return (q.getmatrix() * v);
110 float qx2 = q.x * q.x;
111 float qy2 = q.y * q.y;
112 float qz2 = q.z * q.z;
113
114 float qxqy = q.x * q.y;
115 float qxqz = q.x * q.z;
116 float qxqw = q.x * q.w;
117 float qyqz = q.y * q.z;
118 float qyqw = q.y * q.w;
119 float qzqw = q.z * q.w;
120 return new float3((1 - 2 * (qy2 + qz2)) * v.x + (2 * (qxqy - qzqw)) * v.y + (2 * (qxqz + qyqw)) * v.z, (2 * (qxqy + qzqw)) * v.x + (1 - 2 * (qx2 + qz2)) * v.y + (2 * (qyqz - qxqw)) * v.z, (2 * (qxqz - qyqw)) * v.x + (2 * (qyqz + qxqw)) * v.y + (1 - 2 * (qx2 + qy2)) * v.z);
121 }
122
123 public static Quaternion operator +(Quaternion a, Quaternion b)
124 {
125 return new Quaternion(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
126 }
127
128 public static Quaternion operator *(Quaternion a, float b)
129 {
130 return new Quaternion(a.x *b, a.y *b, a.z *b, a.w *b);
131 }
132
133 public static Quaternion normalize(Quaternion a)
134 {
135 float m = (float)Math.Sqrt(a.w * a.w + a.x * a.x + a.y * a.y + a.z * a.z);
136 if (m < 0.000000001f)
137 {
138 a.w = 1;
139 a.x = a.y = a.z = 0;
140 return a;
141 }
142 return a * (1f / m);
143 }
144
145 public static float dot(Quaternion a, Quaternion b)
146 {
147 return (a.w * b.w + a.x * b.x + a.y * b.y + a.z * b.z);
148 }
149
150 public static Quaternion slerp(Quaternion a, Quaternion b, float interp)
151 {
152 if (dot(a, b) < 0.0)
153 {
154 a.w = -a.w;
155 a.x = -a.x;
156 a.y = -a.y;
157 a.z = -a.z;
158 }
159 float d = dot(a, b);
160 if (d >= 1.0)
161 {
162 return a;
163 }
164 float theta = (float)Math.Acos(d);
165 if (theta == 0.0f)
166 {
167 return (a);
168 }
169 return a * ((float)Math.Sin(theta - interp * theta) / (float)Math.Sin(theta)) + b * ((float)Math.Sin(interp * theta) / (float)Math.Sin(theta));
170 }
171
172 public static Quaternion Interpolate(Quaternion q0, Quaternion q1, float alpha)
173 {
174 return slerp(q0, q1, alpha);
175 }
176
177 public static Quaternion Inverse(Quaternion q)
178 {
179 return new Quaternion(-q.x, -q.y, -q.z, q.w);
180 }
181
182 public static Quaternion YawPitchRoll(float yaw, float pitch, float roll)
183 {
184 roll *= (3.14159264f / 180.0f);
185 yaw *= (3.14159264f / 180.0f);
186 pitch *= (3.14159264f / 180.0f);
187 return new Quaternion(new float3(0.0f, 0.0f, 1.0f), yaw) * new Quaternion(new float3(1.0f, 0.0f, 0.0f), pitch) * new Quaternion(new float3(0.0f, 1.0f, 0.0f), roll);
188 }
189
190 public static float Yaw(Quaternion q)
191 {
192 float3 v = q.ydir();
193 return (v.y == 0.0 && v.x == 0.0) ? 0.0f : (float)Math.Atan2(-v.x, v.y) * (180.0f / 3.14159264f);
194 }
195
196 public static float Pitch(Quaternion q)
197 {
198 float3 v = q.ydir();
199 return (float)Math.Atan2(v.z, Math.Sqrt(v.x * v.x + v.y * v.y)) * (180.0f / 3.14159264f);
200 }
201
202 public static float Roll(Quaternion q)
203 {
204 q = new Quaternion(new float3(0.0f, 0.0f, 1.0f), -Yaw(q) * (3.14159264f / 180.0f)) * q;
205 q = new Quaternion(new float3(1.0f, 0.0f, 0.0f), -Pitch(q) * (3.14159264f / 180.0f)) * q;
206 return (float)Math.Atan2(-q.xdir().z, q.xdir().x) * (180.0f / 3.14159264f);
207 }
208 }
209}
diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/README.txt b/OpenSim/Region/Physics/ConvexDecompositionDotNet/README.txt
new file mode 100644
index 0000000..fc53ae7
--- /dev/null
+++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/README.txt
@@ -0,0 +1,7 @@
1ConvexDecompositionDotNet
2=========================
3
4A C# port of the ConvexDecomposition library by John W. Ratcliff and Stan Melax.
5The original C++ version is available at <http://codesuppository.googlecode.com/>.
6See the blog post at <http://codesuppository.blogspot.com/2006/08/approximate-convexdecomposition.html>
7for a thorough explanation of generating convex hulls from concave meshes.
diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/SplitPlane.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/SplitPlane.cs
new file mode 100644
index 0000000..9f06a9a
--- /dev/null
+++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/SplitPlane.cs
@@ -0,0 +1,265 @@
1/* The MIT License
2 *
3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved.
5 *
6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
27
28using System;
29using System.Collections.Generic;
30
31namespace OpenSim.Region.Physics.ConvexDecompositionDotNet
32{
33 public class Rect3d
34 {
35 public float[] mMin = new float[3];
36 public float[] mMax = new float[3];
37
38 public Rect3d()
39 {
40 }
41
42 public Rect3d(float[] bmin, float[] bmax)
43 {
44 mMin[0] = bmin[0];
45 mMin[1] = bmin[1];
46 mMin[2] = bmin[2];
47
48 mMax[0] = bmax[0];
49 mMax[1] = bmax[1];
50 mMax[2] = bmax[2];
51 }
52
53 public void SetMin(float[] bmin)
54 {
55 mMin[0] = bmin[0];
56 mMin[1] = bmin[1];
57 mMin[2] = bmin[2];
58 }
59
60 public void SetMax(float[] bmax)
61 {
62 mMax[0] = bmax[0];
63 mMax[1] = bmax[1];
64 mMax[2] = bmax[2];
65 }
66
67 public void SetMin(float x, float y, float z)
68 {
69 mMin[0] = x;
70 mMin[1] = y;
71 mMin[2] = z;
72 }
73
74 public void SetMax(float x, float y, float z)
75 {
76 mMax[0] = x;
77 mMax[1] = y;
78 mMax[2] = z;
79 }
80 }
81
82 public static class SplitPlane
83 {
84 public static bool computeSplitPlane(List<float3> vertices, List<int> indices, ref float4 plane)
85 {
86 float[] bmin = { Single.MaxValue, Single.MaxValue, Single.MaxValue };
87 float[] bmax = { Single.MinValue, Single.MinValue, Single.MinValue };
88
89 for (int i = 0; i < vertices.Count; i++)
90 {
91 float3 p = vertices[i];
92
93 if (p[0] < bmin[0])
94 bmin[0] = p[0];
95 if (p[1] < bmin[1])
96 bmin[1] = p[1];
97 if (p[2] < bmin[2])
98 bmin[2] = p[2];
99
100 if (p[0] > bmax[0])
101 bmax[0] = p[0];
102 if (p[1] > bmax[1])
103 bmax[1] = p[1];
104 if (p[2] > bmax[2])
105 bmax[2] = p[2];
106 }
107
108 float dx = bmax[0] - bmin[0];
109 float dy = bmax[1] - bmin[1];
110 float dz = bmax[2] - bmin[2];
111
112 float laxis = dx;
113
114 int axis = 0;
115
116 if (dy > dx)
117 {
118 axis = 1;
119 laxis = dy;
120 }
121
122 if (dz > dx && dz > dy)
123 {
124 axis = 2;
125 laxis = dz;
126 }
127
128 float[] p1 = new float[3];
129 float[] p2 = new float[3];
130 float[] p3 = new float[3];
131
132 p3[0] = p2[0] = p1[0] = bmin[0] + dx * 0.5f;
133 p3[1] = p2[1] = p1[1] = bmin[1] + dy * 0.5f;
134 p3[2] = p2[2] = p1[2] = bmin[2] + dz * 0.5f;
135
136 Rect3d b = new Rect3d(bmin, bmax);
137
138 Rect3d b1 = new Rect3d();
139 Rect3d b2 = new Rect3d();
140
141 splitRect(axis, b, b1, b2, p1);
142
143 switch (axis)
144 {
145 case 0:
146 p2[1] = bmin[1];
147 p2[2] = bmin[2];
148
149 if (dz > dy)
150 {
151 p3[1] = bmax[1];
152 p3[2] = bmin[2];
153 }
154 else
155 {
156 p3[1] = bmin[1];
157 p3[2] = bmax[2];
158 }
159
160 break;
161 case 1:
162 p2[0] = bmin[0];
163 p2[2] = bmin[2];
164
165 if (dx > dz)
166 {
167 p3[0] = bmax[0];
168 p3[2] = bmin[2];
169 }
170 else
171 {
172 p3[0] = bmin[0];
173 p3[2] = bmax[2];
174 }
175
176 break;
177 case 2:
178 p2[0] = bmin[0];
179 p2[1] = bmin[1];
180
181 if (dx > dy)
182 {
183 p3[0] = bmax[0];
184 p3[1] = bmin[1];
185 }
186 else
187 {
188 p3[0] = bmin[0];
189 p3[1] = bmax[1];
190 }
191
192 break;
193 }
194
195 computePlane(p1, p2, p3, plane);
196
197 return true;
198 }
199
200 internal static void computePlane(float[] A, float[] B, float[] C, float4 plane)
201 {
202 float vx = (B[0] - C[0]);
203 float vy = (B[1] - C[1]);
204 float vz = (B[2] - C[2]);
205
206 float wx = (A[0] - B[0]);
207 float wy = (A[1] - B[1]);
208 float wz = (A[2] - B[2]);
209
210 float vw_x = vy * wz - vz * wy;
211 float vw_y = vz * wx - vx * wz;
212 float vw_z = vx * wy - vy * wx;
213
214 float mag = (float)Math.Sqrt((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z));
215
216 if (mag < 0.000001f)
217 {
218 mag = 0;
219 }
220 else
221 {
222 mag = 1.0f / mag;
223 }
224
225 float x = vw_x * mag;
226 float y = vw_y * mag;
227 float z = vw_z * mag;
228
229 float D = 0.0f - ((x * A[0]) + (y * A[1]) + (z * A[2]));
230
231 plane.x = x;
232 plane.y = y;
233 plane.z = z;
234 plane.w = D;
235 }
236
237 public static void splitRect(int axis, Rect3d source, Rect3d b1, Rect3d b2, float[] midpoint)
238 {
239 switch (axis)
240 {
241 case 0:
242 b1.SetMin(source.mMin);
243 b1.SetMax(midpoint[0], source.mMax[1], source.mMax[2]);
244
245 b2.SetMin(midpoint[0], source.mMin[1], source.mMin[2]);
246 b2.SetMax(source.mMax);
247 break;
248 case 1:
249 b1.SetMin(source.mMin);
250 b1.SetMax(source.mMax[0], midpoint[1], source.mMax[2]);
251
252 b2.SetMin(source.mMin[0], midpoint[1], source.mMin[2]);
253 b2.SetMax(source.mMax);
254 break;
255 case 2:
256 b1.SetMin(source.mMin);
257 b1.SetMax(source.mMax[0], source.mMax[1], midpoint[2]);
258
259 b2.SetMin(source.mMin[0], source.mMin[1], midpoint[2]);
260 b2.SetMax(source.mMax);
261 break;
262 }
263 }
264 }
265}
diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/VertexLookup.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/VertexLookup.cs
new file mode 100644
index 0000000..6f17c9f
--- /dev/null
+++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/VertexLookup.cs
@@ -0,0 +1,70 @@
1/* The MIT License
2 *
3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved.
5 *
6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
27
28using System;
29using System.Collections.Generic;
30
31namespace OpenSim.Region.Physics.ConvexDecompositionDotNet
32{
33 public class VertexPool
34 {
35 private List<float3> mVertices = new List<float3>();
36 private Dictionary<float3, int> mIndices = new Dictionary<float3, int>();
37
38 public int getIndex(float3 vtx)
39 {
40 int idx;
41 if (mIndices.TryGetValue(vtx, out idx))
42 return idx;
43
44 idx = mVertices.Count;
45 mVertices.Add(vtx);
46 mIndices.Add(vtx, idx);
47 return idx;
48 }
49
50 public float3 Get(int idx)
51 {
52 return mVertices[idx];
53 }
54
55 public int GetSize()
56 {
57 return mVertices.Count;
58 }
59
60 public List<float3> GetVertices()
61 {
62 return mVertices;
63 }
64
65 public void Clear()
66 {
67 mVertices.Clear();
68 }
69 }
70}
diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/float2.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/float2.cs
new file mode 100644
index 0000000..ce88fc8
--- /dev/null
+++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/float2.cs
@@ -0,0 +1,70 @@
1/* The MIT License
2 *
3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved.
5 *
6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
27
28using System;
29
30namespace OpenSim.Region.Physics.ConvexDecompositionDotNet
31{
32 public class float2
33 {
34 public float x;
35 public float y;
36
37 public float2()
38 {
39 }
40
41 public float2(float _x, float _y)
42 {
43 x = _x;
44 y = _y;
45 }
46
47 public float this[int i]
48 {
49 get
50 {
51 switch (i)
52 {
53 case 0: return x;
54 case 1: return y;
55 }
56 throw new ArgumentOutOfRangeException();
57 }
58 }
59
60 public static float2 operator -(float2 a, float2 b)
61 {
62 return new float2(a.x - b.x, a.y - b.y);
63 }
64
65 public static float2 operator +(float2 a, float2 b)
66 {
67 return new float2(a.x + b.x, a.y + b.y);
68 }
69 }
70}
diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/float3.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/float3.cs
new file mode 100644
index 0000000..4389114
--- /dev/null
+++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/float3.cs
@@ -0,0 +1,444 @@
1/* The MIT License
2 *
3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved.
5 *
6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
27
28using System;
29
30namespace OpenSim.Region.Physics.ConvexDecompositionDotNet
31{
32 public class float3 : IEquatable<float3>
33 {
34 public float x;
35 public float y;
36 public float z;
37
38 public float3()
39 {
40 x = 0;
41 y = 0;
42 z = 0;
43 }
44
45 public float3(float _x, float _y, float _z)
46 {
47 x = _x;
48 y = _y;
49 z = _z;
50 }
51
52 public float3(float3 f)
53 {
54 x = f.x;
55 y = f.y;
56 z = f.z;
57 }
58
59 public float this[int i]
60 {
61 get
62 {
63 switch (i)
64 {
65 case 0: return x;
66 case 1: return y;
67 case 2: return z;
68 }
69 throw new ArgumentOutOfRangeException();
70 }
71 }
72
73 public float Distance(float3 a)
74 {
75 float3 d = new float3(a.x - x, a.y - y, a.z - z);
76 return d.Length();
77 }
78
79 public float Distance2(float3 a)
80 {
81 float dx = a.x - x;
82 float dy = a.y - y;
83 float dz = a.z - z;
84 return dx * dx + dy * dy + dz * dz;
85 }
86
87 public float Length()
88 {
89 return (float)Math.Sqrt(x * x + y * y + z * z);
90 }
91
92 public float Area(float3 p1, float3 p2)
93 {
94 float A = Partial(p1);
95 A += p1.Partial(p2);
96 A += p2.Partial(this);
97 return A * 0.5f;
98 }
99
100 public float Partial(float3 p)
101 {
102 return (x * p.y) - (p.x * y);
103 }
104
105 // Given a point and a line (defined by two points), compute the closest point
106 // in the line. (The line is treated as infinitely long.)
107 public void NearestPointInLine(float3 point, float3 line0, float3 line1)
108 {
109 float3 nearestPoint = new float3();
110 float3 lineDelta = line1 - line0;
111
112 // Handle degenerate lines
113 if (lineDelta == float3.Zero)
114 {
115 nearestPoint = line0;
116 }
117 else
118 {
119 float delta = float3.dot(point - line0, lineDelta) / float3.dot(lineDelta, lineDelta);
120 nearestPoint = line0 + lineDelta * delta;
121 }
122
123 this.x = nearestPoint.x;
124 this.y = nearestPoint.y;
125 this.z = nearestPoint.z;
126 }
127
128 // Given a point and a line segment (defined by two points), compute the closest point
129 // in the line. Cap the point at the endpoints of the line segment.
130 public void NearestPointInLineSegment(float3 point, float3 line0, float3 line1)
131 {
132 float3 nearestPoint = new float3();
133 float3 lineDelta = line1 - line0;
134
135 // Handle degenerate lines
136 if (lineDelta == Zero)
137 {
138 nearestPoint = line0;
139 }
140 else
141 {
142 float delta = float3.dot(point - line0, lineDelta) / float3.dot(lineDelta, lineDelta);
143
144 // Clamp the point to conform to the segment's endpoints
145 if (delta < 0)
146 delta = 0;
147 else if (delta > 1)
148 delta = 1;
149
150 nearestPoint = line0 + lineDelta * delta;
151 }
152
153 this.x = nearestPoint.x;
154 this.y = nearestPoint.y;
155 this.z = nearestPoint.z;
156 }
157
158 // Given a point and a triangle (defined by three points), compute the closest point
159 // in the triangle. Clamp the point so it's confined to the area of the triangle.
160 public void NearestPointInTriangle(float3 point, float3 triangle0, float3 triangle1, float3 triangle2)
161 {
162 float3 nearestPoint = new float3();
163
164 float3 lineDelta0 = triangle1 - triangle0;
165 float3 lineDelta1 = triangle2 - triangle0;
166
167 // Handle degenerate triangles
168 if ((lineDelta0 == Zero) || (lineDelta1 == Zero))
169 {
170 nearestPoint.NearestPointInLineSegment(point, triangle1, triangle2);
171 }
172 else if (lineDelta0 == lineDelta1)
173 {
174 nearestPoint.NearestPointInLineSegment(point, triangle0, triangle1);
175 }
176 else
177 {
178 float3[] axis = new float3[3] { new float3(), new float3(), new float3() };
179 axis[0].NearestPointInLine(triangle0, triangle1, triangle2);
180 axis[1].NearestPointInLine(triangle1, triangle0, triangle2);
181 axis[2].NearestPointInLine(triangle2, triangle0, triangle1);
182
183 float3 axisDot = new float3();
184 axisDot.x = dot(triangle0 - axis[0], point - axis[0]);
185 axisDot.y = dot(triangle1 - axis[1], point - axis[1]);
186 axisDot.z = dot(triangle2 - axis[2], point - axis[2]);
187
188 bool bForce = true;
189 float bestMagnitude2 = 0;
190 float closeMagnitude2;
191 float3 closePoint = new float3();
192
193 if (axisDot.x < 0f)
194 {
195 closePoint.NearestPointInLineSegment(point, triangle1, triangle2);
196 closeMagnitude2 = point.Distance2(closePoint);
197 if (bForce || (bestMagnitude2 > closeMagnitude2))
198 {
199 bForce = false;
200 bestMagnitude2 = closeMagnitude2;
201 nearestPoint = closePoint;
202 }
203 }
204 if (axisDot.y < 0f)
205 {
206 closePoint.NearestPointInLineSegment(point, triangle0, triangle2);
207 closeMagnitude2 = point.Distance2(closePoint);
208 if (bForce || (bestMagnitude2 > closeMagnitude2))
209 {
210 bForce = false;
211 bestMagnitude2 = closeMagnitude2;
212 nearestPoint = closePoint;
213 }
214 }
215 if (axisDot.z < 0f)
216 {
217 closePoint.NearestPointInLineSegment(point, triangle0, triangle1);
218 closeMagnitude2 = point.Distance2(closePoint);
219 if (bForce || (bestMagnitude2 > closeMagnitude2))
220 {
221 bForce = false;
222 bestMagnitude2 = closeMagnitude2;
223 nearestPoint = closePoint;
224 }
225 }
226
227 // If bForce is true at this point, it means the nearest point lies
228 // inside the triangle; use the nearest-point-on-a-plane equation
229 if (bForce)
230 {
231 float3 normal;
232
233 // Get the normal of the polygon (doesn't have to be a unit vector)
234 normal = float3.cross(lineDelta0, lineDelta1);
235
236 float3 pointDelta = point - triangle0;
237 float delta = float3.dot(normal, pointDelta) / float3.dot(normal, normal);
238
239 nearestPoint = point - normal * delta;
240 }
241 }
242
243 this.x = nearestPoint.x;
244 this.y = nearestPoint.y;
245 this.z = nearestPoint.z;
246 }
247
248 public static float3 operator +(float3 a, float3 b)
249 {
250 return new float3(a.x + b.x, a.y + b.y, a.z + b.z);
251 }
252
253 public static float3 operator -(float3 a, float3 b)
254 {
255 return new float3(a.x - b.x, a.y - b.y, a.z - b.z);
256 }
257
258 public static float3 operator -(float3 a, float s)
259 {
260 return new float3(a.x - s, a.y - s, a.z - s);
261 }
262
263 public static float3 operator -(float3 v)
264 {
265 return new float3(-v.x, -v.y, -v.z);
266 }
267
268 public static float3 operator *(float3 v, float s)
269 {
270 return new float3(v.x * s, v.y * s, v.z * s);
271 }
272
273 public static float3 operator *(float s, float3 v)
274 {
275 return new float3(v.x * s, v.y * s, v.z * s);
276 }
277
278 public static float3 operator *(float3 v, float3x3 m)
279 {
280 return new float3((m.x.x * v.x + m.y.x * v.y + m.z.x * v.z), (m.x.y * v.x + m.y.y * v.y + m.z.y * v.z), (m.x.z * v.x + m.y.z * v.y + m.z.z * v.z));
281 }
282
283 public static float3 operator *(float3x3 m, float3 v)
284 {
285 return new float3(dot(m.x, v), dot(m.y, v), dot(m.z, v));
286 }
287
288 public static float3 operator /(float3 v, float s)
289 {
290 float sinv = 1.0f / s;
291 return new float3(v.x * sinv, v.y * sinv, v.z * sinv);
292 }
293
294 public bool Equals(float3 other)
295 {
296 return this == other;
297 }
298
299 public override bool Equals(object obj)
300 {
301 float3 f = obj as float3;
302 if (f == null)
303 return false;
304
305 return this == f;
306 }
307
308 public override int GetHashCode()
309 {
310 return x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode();
311 }
312
313 public static bool operator ==(float3 a, float3 b)
314 {
315 // If both are null, or both are same instance, return true.
316 if (System.Object.ReferenceEquals(a, b))
317 return true;
318 // If one is null, but not both, return false.
319 if (((object)a == null) || ((object)b == null))
320 return false;
321
322 return (a.x == b.x && a.y == b.y && a.z == b.z);
323 }
324
325 public static bool operator !=(float3 a, float3 b)
326 {
327 return (a.x != b.x || a.y != b.y || a.z != b.z);
328 }
329
330 public static float dot(float3 a, float3 b)
331 {
332 return a.x * b.x + a.y * b.y + a.z * b.z;
333 }
334
335 public static float3 cmul(float3 v1, float3 v2)
336 {
337 return new float3(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z);
338 }
339
340 public static float3 cross(float3 a, float3 b)
341 {
342 return new float3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
343 }
344
345 public static float3 Interpolate(float3 v0, float3 v1, float alpha)
346 {
347 return v0 * (1 - alpha) + v1 * alpha;
348 }
349
350 public static float3 Round(float3 a, int digits)
351 {
352 return new float3((float)Math.Round(a.x, digits), (float)Math.Round(a.y, digits), (float)Math.Round(a.z, digits));
353 }
354
355 public static float3 VectorMax(float3 a, float3 b)
356 {
357 return new float3(Math.Max(a.x, b.x), Math.Max(a.y, b.y), Math.Max(a.z, b.z));
358 }
359
360 public static float3 VectorMin(float3 a, float3 b)
361 {
362 return new float3(Math.Min(a.x, b.x), Math.Min(a.y, b.y), Math.Min(a.z, b.z));
363 }
364
365 public static float3 vabs(float3 v)
366 {
367 return new float3(Math.Abs(v.x), Math.Abs(v.y), Math.Abs(v.z));
368 }
369
370 public static float magnitude(float3 v)
371 {
372 return (float)Math.Sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
373 }
374
375 public static float3 normalize(float3 v)
376 {
377 float d = magnitude(v);
378 if (d == 0)
379 d = 0.1f;
380 d = 1 / d;
381 return new float3(v.x * d, v.y * d, v.z * d);
382 }
383
384 public static float3 safenormalize(float3 v)
385 {
386 if (magnitude(v) <= 0.0f)
387 return new float3(1, 0, 0);
388 else
389 return normalize(v);
390 }
391
392 public static float Yaw(float3 v)
393 {
394 return (v.y == 0.0 && v.x == 0.0) ? 0.0f : (float)Math.Atan2(-v.x, v.y) * (180.0f / 3.14159264f);
395 }
396
397 public static float Pitch(float3 v)
398 {
399 return (float)Math.Atan2(v.z, Math.Sqrt(v.x * v.x + v.y * v.y)) * (180.0f / 3.14159264f);
400 }
401
402 public float ComputePlane(float3 A, float3 B, float3 C)
403 {
404 float vx, vy, vz, wx, wy, wz, vw_x, vw_y, vw_z, mag;
405
406 vx = (B.x - C.x);
407 vy = (B.y - C.y);
408 vz = (B.z - C.z);
409
410 wx = (A.x - B.x);
411 wy = (A.y - B.y);
412 wz = (A.z - B.z);
413
414 vw_x = vy * wz - vz * wy;
415 vw_y = vz * wx - vx * wz;
416 vw_z = vx * wy - vy * wx;
417
418 mag = (float)Math.Sqrt((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z));
419
420 if (mag < 0.000001f)
421 {
422 mag = 0;
423 }
424 else
425 {
426 mag = 1.0f / mag;
427 }
428
429 x = vw_x * mag;
430 y = vw_y * mag;
431 z = vw_z * mag;
432
433 float D = 0.0f - ((x * A.x) + (y * A.y) + (z * A.z));
434 return D;
435 }
436
437 public override string ToString()
438 {
439 return String.Format("<{0}, {1}, {2}>", x, y, z);
440 }
441
442 public static readonly float3 Zero = new float3();
443 }
444}
diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/float3x3.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/float3x3.cs
new file mode 100644
index 0000000..76cf063
--- /dev/null
+++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/float3x3.cs
@@ -0,0 +1,195 @@
1/* The MIT License
2 *
3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved.
5 *
6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Diagnostics;
31
32namespace OpenSim.Region.Physics.ConvexDecompositionDotNet
33{
34 public class float3x3
35 {
36 public float3 x = new float3();
37 public float3 y = new float3();
38 public float3 z = new float3();
39
40 public float3x3()
41 {
42 }
43
44 public float3x3(float xx, float xy, float xz, float yx, float yy, float yz, float zx, float zy, float zz)
45 {
46 x = new float3(xx, xy, xz);
47 y = new float3(yx, yy, yz);
48 z = new float3(zx, zy, zz);
49 }
50
51 public float3x3(float3 _x, float3 _y, float3 _z)
52 {
53 x = new float3(_x);
54 y = new float3(_y);
55 z = new float3(_z);
56 }
57
58 public float3 this[int i]
59 {
60 get
61 {
62 switch (i)
63 {
64 case 0: return x;
65 case 1: return y;
66 case 2: return z;
67 }
68 throw new ArgumentOutOfRangeException();
69 }
70 }
71
72 public float this[int i, int j]
73 {
74 get
75 {
76 switch (i)
77 {
78 case 0:
79 switch (j)
80 {
81 case 0: return x.x;
82 case 1: return x.y;
83 case 2: return x.z;
84 }
85 break;
86 case 1:
87 switch (j)
88 {
89 case 0: return y.x;
90 case 1: return y.y;
91 case 2: return y.z;
92 }
93 break;
94 case 2:
95 switch (j)
96 {
97 case 0: return z.x;
98 case 1: return z.y;
99 case 2: return z.z;
100 }
101 break;
102 }
103 throw new ArgumentOutOfRangeException();
104 }
105 set
106 {
107 switch (i)
108 {
109 case 0:
110 switch (j)
111 {
112 case 0: x.x = value; return;
113 case 1: x.y = value; return;
114 case 2: x.z = value; return;
115 }
116 break;
117 case 1:
118 switch (j)
119 {
120 case 0: y.x = value; return;
121 case 1: y.y = value; return;
122 case 2: y.z = value; return;
123 }
124 break;
125 case 2:
126 switch (j)
127 {
128 case 0: z.x = value; return;
129 case 1: z.y = value; return;
130 case 2: z.z = value; return;
131 }
132 break;
133 }
134 throw new ArgumentOutOfRangeException();
135 }
136 }
137
138 public static float3x3 Transpose(float3x3 m)
139 {
140 return new float3x3(new float3(m.x.x, m.y.x, m.z.x), new float3(m.x.y, m.y.y, m.z.y), new float3(m.x.z, m.y.z, m.z.z));
141 }
142
143 public static float3x3 operator *(float3x3 a, float3x3 b)
144 {
145 return new float3x3(a.x * b, a.y * b, a.z * b);
146 }
147
148 public static float3x3 operator *(float3x3 a, float s)
149 {
150 return new float3x3(a.x * s, a.y * s, a.z * s);
151 }
152
153 public static float3x3 operator /(float3x3 a, float s)
154 {
155 float t = 1f / s;
156 return new float3x3(a.x * t, a.y * t, a.z * t);
157 }
158
159 public static float3x3 operator +(float3x3 a, float3x3 b)
160 {
161 return new float3x3(a.x + b.x, a.y + b.y, a.z + b.z);
162 }
163
164 public static float3x3 operator -(float3x3 a, float3x3 b)
165 {
166 return new float3x3(a.x - b.x, a.y - b.y, a.z - b.z);
167 }
168
169 public static float Determinant(float3x3 m)
170 {
171 return m.x.x * m.y.y * m.z.z + m.y.x * m.z.y * m.x.z + m.z.x * m.x.y * m.y.z - m.x.x * m.z.y * m.y.z - m.y.x * m.x.y * m.z.z - m.z.x * m.y.y * m.x.z;
172 }
173
174 public static float3x3 Inverse(float3x3 a)
175 {
176 float3x3 b = new float3x3();
177 float d = Determinant(a);
178 Debug.Assert(d != 0);
179 for (int i = 0; i < 3; i++)
180 {
181 for (int j = 0; j < 3; j++)
182 {
183 int i1 = (i + 1) % 3;
184 int i2 = (i + 2) % 3;
185 int j1 = (j + 1) % 3;
186 int j2 = (j + 2) % 3;
187
188 // reverse indexs i&j to take transpose
189 b[i, j] = (a[i1][j1] * a[i2][j2] - a[i1][j2] * a[i2][j1]) / d;
190 }
191 }
192 return b;
193 }
194 }
195}
diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/float4.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/float4.cs
new file mode 100644
index 0000000..fa60876
--- /dev/null
+++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/float4.cs
@@ -0,0 +1,170 @@
1/* The MIT License
2 *
3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved.
5 *
6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
27
28using System;
29
30namespace OpenSim.Region.Physics.ConvexDecompositionDotNet
31{
32 public class float4
33 {
34 public float x;
35 public float y;
36 public float z;
37 public float w;
38
39 public float4()
40 {
41 x = 0;
42 y = 0;
43 z = 0;
44 w = 0;
45 }
46
47 public float4(float _x, float _y, float _z, float _w)
48 {
49 x = _x;
50 y = _y;
51 z = _z;
52 w = _w;
53 }
54
55 public float4(float3 v, float _w)
56 {
57 x = v.x;
58 y = v.y;
59 z = v.z;
60 w = _w;
61 }
62
63 public float4(float4 f)
64 {
65 x = f.x;
66 y = f.y;
67 z = f.z;
68 w = f.w;
69 }
70
71 public float this[int i]
72 {
73 get
74 {
75 switch (i)
76 {
77 case 0: return x;
78 case 1: return y;
79 case 2: return z;
80 case 3: return w;
81 }
82 throw new ArgumentOutOfRangeException();
83 }
84 }
85
86 public float3 xyz()
87 {
88 return new float3(x, y, z);
89 }
90
91 public void setxyz(float3 xyz)
92 {
93 x = xyz.x;
94 y = xyz.y;
95 z = xyz.z;
96 }
97
98 public override int GetHashCode()
99 {
100 return x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode() ^ w.GetHashCode();
101 }
102
103 public override bool Equals(object obj)
104 {
105 float4 f = obj as float4;
106 if (f == null)
107 return false;
108
109 return this == f;
110 }
111
112 public static float4 Homogenize(float3 v3)
113 {
114 return Homogenize(v3, 1.0f);
115 }
116
117 //C++ TO C# CONVERTER NOTE: C# does not allow default values for parameters. Overloaded methods are inserted above.
118 //ORIGINAL LINE: float4 Homogenize(const float3 &v3, const float &w =1.0f)
119 public static float4 Homogenize(float3 v3, float w)
120 {
121 return new float4(v3.x, v3.y, v3.z, w);
122 }
123
124 public static float4 cmul(float4 a, float4 b)
125 {
126 return new float4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
127 }
128
129 public static float4 operator +(float4 a, float4 b)
130 {
131 return new float4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
132 }
133 public static float4 operator -(float4 a, float4 b)
134 {
135 return new float4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
136 }
137
138 public static float4 operator *(float4 v, float4x4 m)
139 {
140 return v.x * m.x + v.y * m.y + v.z * m.z + v.w * m.w; // yes this actually works
141 }
142
143 public static bool operator ==(float4 a, float4 b)
144 {
145 // If both are null, or both are same instance, return true.
146 if (System.Object.ReferenceEquals(a, b))
147 return true;
148 // If one is null, but not both, return false.
149 if (((object)a == null) || ((object)b == null))
150 return false;
151
152 return (a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w);
153 }
154
155 public static bool operator !=(float4 a, float4 b)
156 {
157 return !(a == b);
158 }
159
160 public static float4 operator *(float4 v, float s)
161 {
162 return new float4(v.x * s, v.y * s, v.z * s, v.w * s);
163 }
164
165 public static float4 operator *(float s, float4 v)
166 {
167 return new float4(v.x * s, v.y * s, v.z * s, v.w * s);
168 }
169 }
170}
diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/float4x4.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/float4x4.cs
new file mode 100644
index 0000000..7d1592f
--- /dev/null
+++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/float4x4.cs
@@ -0,0 +1,284 @@
1/* The MIT License
2 *
3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved.
5 *
6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Text;
32
33namespace OpenSim.Region.Physics.ConvexDecompositionDotNet
34{
35 public class float4x4
36 {
37 public float4 x = new float4();
38 public float4 y = new float4();
39 public float4 z = new float4();
40 public float4 w = new float4();
41
42 public float4x4()
43 {
44 }
45
46 public float4x4(float4 _x, float4 _y, float4 _z, float4 _w)
47 {
48 x = new float4(_x);
49 y = new float4(_y);
50 z = new float4(_z);
51 w = new float4(_w);
52 }
53
54 public float4x4(
55 float m00, float m01, float m02, float m03,
56 float m10, float m11, float m12, float m13,
57 float m20, float m21, float m22, float m23,
58 float m30, float m31, float m32, float m33)
59 {
60 x = new float4(m00, m01, m02, m03);
61 y = new float4(m10, m11, m12, m13);
62 z = new float4(m20, m21, m22, m23);
63 w = new float4(m30, m31, m32, m33);
64 }
65
66 public float4x4(float4x4 m)
67 {
68 x = new float4(m.x);
69 y = new float4(m.y);
70 z = new float4(m.z);
71 w = new float4(m.w);
72 }
73
74 public float4 this[int i]
75 {
76 get
77 {
78 switch (i)
79 {
80 case 0: return x;
81 case 1: return y;
82 case 2: return z;
83 case 3: return w;
84 }
85 throw new ArgumentOutOfRangeException();
86 }
87 set
88 {
89 switch (i)
90 {
91 case 0: x = value; return;
92 case 1: y = value; return;
93 case 2: z = value; return;
94 case 3: w = value; return;
95 }
96 throw new ArgumentOutOfRangeException();
97 }
98 }
99
100 public override int GetHashCode()
101 {
102 return x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode() ^ w.GetHashCode();
103 }
104
105 public override bool Equals(object obj)
106 {
107 float4x4 m = obj as float4x4;
108 if (m == null)
109 return false;
110
111 return this == m;
112 }
113
114 public static float4x4 operator *(float4x4 a, float4x4 b)
115 {
116 return new float4x4(a.x * b, a.y * b, a.z * b, a.w * b);
117 }
118
119 public static bool operator ==(float4x4 a, float4x4 b)
120 {
121 return (a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w);
122 }
123
124 public static bool operator !=(float4x4 a, float4x4 b)
125 {
126 return !(a == b);
127 }
128
129 public static float4x4 Inverse(float4x4 m)
130 {
131 float4x4 d = new float4x4();
132 //float dst = d.x.x;
133 float[] tmp = new float[12]; // temp array for pairs
134 float[] src = new float[16]; // array of transpose source matrix
135 float det; // determinant
136 // transpose matrix
137 for (int i = 0; i < 4; i++)
138 {
139 src[i] = m[i].x;
140 src[i + 4] = m[i].y;
141 src[i + 8] = m[i].z;
142 src[i + 12] = m[i].w;
143 }
144 // calculate pairs for first 8 elements (cofactors)
145 tmp[0] = src[10] * src[15];
146 tmp[1] = src[11] * src[14];
147 tmp[2] = src[9] * src[15];
148 tmp[3] = src[11] * src[13];
149 tmp[4] = src[9] * src[14];
150 tmp[5] = src[10] * src[13];
151 tmp[6] = src[8] * src[15];
152 tmp[7] = src[11] * src[12];
153 tmp[8] = src[8] * src[14];
154 tmp[9] = src[10] * src[12];
155 tmp[10] = src[8] * src[13];
156 tmp[11] = src[9] * src[12];
157 // calculate first 8 elements (cofactors)
158 d.x.x = tmp[0]*src[5] + tmp[3]*src[6] + tmp[4]*src[7];
159 d.x.x -= tmp[1]*src[5] + tmp[2]*src[6] + tmp[5]*src[7];
160 d.x.y = tmp[1]*src[4] + tmp[6]*src[6] + tmp[9]*src[7];
161 d.x.y -= tmp[0]*src[4] + tmp[7]*src[6] + tmp[8]*src[7];
162 d.x.z = tmp[2]*src[4] + tmp[7]*src[5] + tmp[10]*src[7];
163 d.x.z -= tmp[3]*src[4] + tmp[6]*src[5] + tmp[11]*src[7];
164 d.x.w = tmp[5]*src[4] + tmp[8]*src[5] + tmp[11]*src[6];
165 d.x.w -= tmp[4]*src[4] + tmp[9]*src[5] + tmp[10]*src[6];
166 d.y.x = tmp[1]*src[1] + tmp[2]*src[2] + tmp[5]*src[3];
167 d.y.x -= tmp[0]*src[1] + tmp[3]*src[2] + tmp[4]*src[3];
168 d.y.y = tmp[0]*src[0] + tmp[7]*src[2] + tmp[8]*src[3];
169 d.y.y -= tmp[1]*src[0] + tmp[6]*src[2] + tmp[9]*src[3];
170 d.y.z = tmp[3]*src[0] + tmp[6]*src[1] + tmp[11]*src[3];
171 d.y.z -= tmp[2]*src[0] + tmp[7]*src[1] + tmp[10]*src[3];
172 d.y.w = tmp[4]*src[0] + tmp[9]*src[1] + tmp[10]*src[2];
173 d.y.w -= tmp[5]*src[0] + tmp[8]*src[1] + tmp[11]*src[2];
174 // calculate pairs for second 8 elements (cofactors)
175 tmp[0] = src[2]*src[7];
176 tmp[1] = src[3]*src[6];
177 tmp[2] = src[1]*src[7];
178 tmp[3] = src[3]*src[5];
179 tmp[4] = src[1]*src[6];
180 tmp[5] = src[2]*src[5];
181 tmp[6] = src[0]*src[7];
182 tmp[7] = src[3]*src[4];
183 tmp[8] = src[0]*src[6];
184 tmp[9] = src[2]*src[4];
185 tmp[10] = src[0]*src[5];
186 tmp[11] = src[1]*src[4];
187 // calculate second 8 elements (cofactors)
188 d.z.x = tmp[0]*src[13] + tmp[3]*src[14] + tmp[4]*src[15];
189 d.z.x -= tmp[1]*src[13] + tmp[2]*src[14] + tmp[5]*src[15];
190 d.z.y = tmp[1]*src[12] + tmp[6]*src[14] + tmp[9]*src[15];
191 d.z.y -= tmp[0]*src[12] + tmp[7]*src[14] + tmp[8]*src[15];
192 d.z.z = tmp[2]*src[12] + tmp[7]*src[13] + tmp[10]*src[15];
193 d.z.z -= tmp[3]*src[12] + tmp[6]*src[13] + tmp[11]*src[15];
194 d.z.w = tmp[5]*src[12] + tmp[8]*src[13] + tmp[11]*src[14];
195 d.z.w-= tmp[4]*src[12] + tmp[9]*src[13] + tmp[10]*src[14];
196 d.w.x = tmp[2]*src[10] + tmp[5]*src[11] + tmp[1]*src[9];
197 d.w.x-= tmp[4]*src[11] + tmp[0]*src[9] + tmp[3]*src[10];
198 d.w.y = tmp[8]*src[11] + tmp[0]*src[8] + tmp[7]*src[10];
199 d.w.y-= tmp[6]*src[10] + tmp[9]*src[11] + tmp[1]*src[8];
200 d.w.z = tmp[6]*src[9] + tmp[11]*src[11] + tmp[3]*src[8];
201 d.w.z-= tmp[10]*src[11] + tmp[2]*src[8] + tmp[7]*src[9];
202 d.w.w = tmp[10]*src[10] + tmp[4]*src[8] + tmp[9]*src[9];
203 d.w.w-= tmp[8]*src[9] + tmp[11]*src[10] + tmp[5]*src[8];
204 // calculate determinant
205 det = src[0] * d.x.x + src[1] * d.x.y + src[2] * d.x.z + src[3] * d.x.w;
206 // calculate matrix inverse
207 det = 1/det;
208 for (int j = 0; j < 4; j++)
209 d[j] *= det;
210 return d;
211 }
212
213 public static float4x4 MatrixRigidInverse(float4x4 m)
214 {
215 float4x4 trans_inverse = MatrixTranslation(-m.w.xyz());
216 float4x4 rot = new float4x4(m);
217 rot.w = new float4(0f, 0f, 0f, 1f);
218 return trans_inverse * MatrixTranspose(rot);
219 }
220 public static float4x4 MatrixTranspose(float4x4 m)
221 {
222 return new float4x4(m.x.x, m.y.x, m.z.x, m.w.x, m.x.y, m.y.y, m.z.y, m.w.y, m.x.z, m.y.z, m.z.z, m.w.z, m.x.w, m.y.w, m.z.w, m.w.w);
223 }
224 public static float4x4 MatrixPerspectiveFov(float fovy, float aspect, float zn, float zf)
225 {
226 float h = 1.0f / (float)Math.Tan(fovy / 2.0f); // view space height
227 float w = h / aspect; // view space width
228 return new float4x4(w, 0, 0, 0, 0, h, 0, 0, 0, 0, zf / (zn - zf), -1, 0, 0, zn * zf / (zn - zf), 0);
229 }
230 public static float4x4 MatrixTranslation(float3 t)
231 {
232 return new float4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, t.x, t.y, t.z, 1);
233 }
234 public static float4x4 MatrixRotationZ(float angle_radians)
235 {
236 float s = (float)Math.Sin(angle_radians);
237 float c = (float)Math.Cos(angle_radians);
238 return new float4x4(c, s, 0, 0, -s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
239 }
240 public static float4x4 MatrixLookAt(float3 eye, float3 at, float3 up)
241 {
242 float4x4 m = new float4x4();
243 m.w.w = 1.0f;
244 m.w.setxyz(eye);
245 m.z.setxyz(float3.normalize(eye - at));
246 m.x.setxyz(float3.normalize(float3.cross(up, m.z.xyz())));
247 m.y.setxyz(float3.cross(m.z.xyz(), m.x.xyz()));
248 return MatrixRigidInverse(m);
249 }
250
251 public static float4x4 MatrixFromQuatVec(Quaternion q, float3 v)
252 {
253 // builds a 4x4 transformation matrix based on orientation q and translation v
254 float qx2 = q.x * q.x;
255 float qy2 = q.y * q.y;
256 float qz2 = q.z * q.z;
257
258 float qxqy = q.x * q.y;
259 float qxqz = q.x * q.z;
260 float qxqw = q.x * q.w;
261 float qyqz = q.y * q.z;
262 float qyqw = q.y * q.w;
263 float qzqw = q.z * q.w;
264
265 return new float4x4(
266 1 - 2 * (qy2 + qz2),
267 2 * (qxqy + qzqw),
268 2 * (qxqz - qyqw),
269 0,
270 2 * (qxqy - qzqw),
271 1 - 2 * (qx2 + qz2),
272 2 * (qyqz + qxqw),
273 0,
274 2 * (qxqz + qyqw),
275 2 * (qyqz - qxqw),
276 1 - 2 * (qx2 + qy2),
277 0,
278 v.x,
279 v.y,
280 v.z,
281 1.0f);
282 }
283 }
284}
diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/int3.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/int3.cs
new file mode 100644
index 0000000..9c5760d
--- /dev/null
+++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/int3.cs
@@ -0,0 +1,128 @@
1/* The MIT License
2 *
3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved.
5 *
6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
27
28using System;
29
30namespace OpenSim.Region.Physics.ConvexDecompositionDotNet
31{
32 public class int3
33 {
34 public int x;
35 public int y;
36 public int z;
37
38 public int3()
39 {
40 }
41
42 public int3(int _x, int _y, int _z)
43 {
44 x = _x;
45 y = _y;
46 z = _z;
47 }
48
49 public int this[int i]
50 {
51 get
52 {
53 switch (i)
54 {
55 case 0: return x;
56 case 1: return y;
57 case 2: return z;
58 }
59 throw new ArgumentOutOfRangeException();
60 }
61 set
62 {
63 switch (i)
64 {
65 case 0: x = value; return;
66 case 1: y = value; return;
67 case 2: z = value; return;
68 }
69 throw new ArgumentOutOfRangeException();
70 }
71 }
72
73 public override int GetHashCode()
74 {
75 return x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode();
76 }
77
78 public override bool Equals(object obj)
79 {
80 int3 i = obj as int3;
81 if (i == null)
82 return false;
83
84 return this == i;
85 }
86
87 public static bool operator ==(int3 a, int3 b)
88 {
89 // If both are null, or both are same instance, return true.
90 if (System.Object.ReferenceEquals(a, b))
91 return true;
92 // If one is null, but not both, return false.
93 if (((object)a == null) || ((object)b == null))
94 return false;
95
96 for (int i = 0; i < 3; i++)
97 {
98 if (a[i] != b[i])
99 return false;
100 }
101 return true;
102 }
103
104 public static bool operator !=(int3 a, int3 b)
105 {
106 return !(a == b);
107 }
108
109 public static int3 roll3(int3 a)
110 {
111 int tmp = a[0];
112 a[0] = a[1];
113 a[1] = a[2];
114 a[2] = tmp;
115 return a;
116 }
117
118 public static bool isa(int3 a, int3 b)
119 {
120 return (a == b || roll3(a) == b || a == roll3(b));
121 }
122
123 public static bool b2b(int3 a, int3 b)
124 {
125 return isa(a, new int3(b[2], b[1], b[0]));
126 }
127 }
128}
diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/int4.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/int4.cs
new file mode 100644
index 0000000..c2b32e5
--- /dev/null
+++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/int4.cs
@@ -0,0 +1,66 @@
1/* The MIT License
2 *
3 * Copyright (c) 2010 Intel Corporation.
4 * All rights reserved.
5 *
6 * Based on the convexdecomposition library from
7 * <http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
27
28using System;
29
30namespace OpenSim.Region.Physics.ConvexDecompositionDotNet
31{
32 public class int4
33 {
34 public int x;
35 public int y;
36 public int z;
37 public int w;
38
39 public int4()
40 {
41 }
42
43 public int4(int _x, int _y, int _z, int _w)
44 {
45 x = _x;
46 y = _y;
47 z = _z;
48 w = _w;
49 }
50
51 public int this[int i]
52 {
53 get
54 {
55 switch (i)
56 {
57 case 0: return x;
58 case 1: return y;
59 case 2: return z;
60 case 3: return w;
61 }
62 throw new ArgumentOutOfRangeException();
63 }
64 }
65 }
66}
diff --git a/OpenSim/Region/Physics/Manager/IMesher.cs b/OpenSim/Region/Physics/Manager/IMesher.cs
index 1181b8d..3a9ca1b 100644
--- a/OpenSim/Region/Physics/Manager/IMesher.cs
+++ b/OpenSim/Region/Physics/Manager/IMesher.cs
@@ -38,6 +38,17 @@ namespace OpenSim.Region.Physics.Manager
38 IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical); 38 IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical);
39 } 39 }
40 40
41 // Values for level of detail to be passed to the mesher.
42 // Values origionally chosen for the LOD of sculpties (the sqrt(width*heigth) of sculpt texture)
43 // Lower level of detail reduces the number of vertices used to represent the meshed shape.
44 public enum LevelOfDetail
45 {
46 High = 32,
47 Medium = 16,
48 Low = 8,
49 VeryLow = 4
50 }
51
41 public interface IVertex 52 public interface IVertex
42 { 53 {
43 } 54 }
diff --git a/OpenSim/Region/Physics/Manager/IPhysicsParameters.cs b/OpenSim/Region/Physics/Manager/IPhysicsParameters.cs
new file mode 100755
index 0000000..b8676ba
--- /dev/null
+++ b/OpenSim/Region/Physics/Manager/IPhysicsParameters.cs
@@ -0,0 +1,73 @@
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 OpenSim.Framework;
31using OpenMetaverse;
32
33namespace OpenSim.Region.Physics.Manager
34{
35 public struct PhysParameterEntry
36 {
37 // flags to say to apply to all or no instances (I wish one could put consts into interfaces)
38 public const uint APPLY_TO_ALL = 0xfffffff3;
39 public const uint APPLY_TO_NONE = 0xfffffff4;
40
41 // values that denote true and false values
42 public const float NUMERIC_TRUE = 1f;
43 public const float NUMERIC_FALSE = 0f;
44
45 public string name;
46 public string desc;
47
48 public PhysParameterEntry(string n, string d)
49 {
50 name = n;
51 desc = d;
52 }
53 }
54
55 // Interface for a physics scene that implements the runtime setting and getting of physics parameters
56 public interface IPhysicsParameters
57 {
58 // Get the list of parameters this physics engine supports
59 PhysParameterEntry[] GetParameterList();
60
61 // Set parameter on a specific or all instances.
62 // Return 'false' if not able to set the parameter.
63 bool SetPhysicsParameter(string parm, float value, uint localID);
64
65 // Get parameter.
66 // Return 'false' if not able to get the parameter.
67 bool GetPhysicsParameter(string parm, out float value);
68
69 // Get parameter from a particular object
70 // TODO:
71 // bool GetPhysicsParameter(string parm, out float value, uint localID);
72 }
73}
diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
index de22fae..72b01ac 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
@@ -37,6 +37,18 @@ namespace OpenSim.Region.Physics.Manager
37 public delegate void physicsCrash(); 37 public delegate void physicsCrash();
38 38
39 public delegate void RaycastCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal); 39 public delegate void RaycastCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal);
40 public delegate void RayCallback(List<ContactResult> list);
41
42 /// <summary>
43 /// Contact result from a raycast.
44 /// </summary>
45 public struct ContactResult
46 {
47 public Vector3 Pos;
48 public float Depth;
49 public uint ConsumerID;
50 public Vector3 Normal;
51 }
40 52
41 public abstract class PhysicsScene 53 public abstract class PhysicsScene
42 { 54 {
@@ -61,7 +73,6 @@ namespace OpenSim.Region.Physics.Manager
61 } 73 }
62 } 74 }
63 75
64
65 public abstract void Initialise(IMesher meshmerizer, IConfigSource config); 76 public abstract void Initialise(IMesher meshmerizer, IConfigSource config);
66 77
67 public abstract PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying); 78 public abstract PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying);
@@ -75,6 +86,10 @@ namespace OpenSim.Region.Physics.Manager
75 86
76 public abstract void RemoveAvatar(PhysicsActor actor); 87 public abstract void RemoveAvatar(PhysicsActor actor);
77 88
89 /// <summary>
90 /// Remove a prim from the physics scene.
91 /// </summary>
92 /// <param name="prim"></param>
78 public abstract void RemovePrim(PhysicsActor prim); 93 public abstract void RemovePrim(PhysicsActor prim);
79 94
80 //public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, 95 //public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
@@ -83,17 +98,6 @@ namespace OpenSim.Region.Physics.Manager
83 public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, 98 public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
84 Vector3 size, Quaternion rotation, bool isPhysical, uint localid); 99 Vector3 size, Quaternion rotation, bool isPhysical, uint localid);
85 100
86 public virtual PhysicsActor AddPrimShape(uint localID, string primName, PrimitiveBaseShape pbs, Vector3 position,
87 Vector3 size, Quaternion rotation, bool isPhysical, uint localid)
88 {
89 PhysicsActor ret = AddPrimShape(primName, pbs, position, size, rotation, isPhysical, localid);
90
91 if (ret != null)
92 ret.LocalID = localID;
93
94 return ret;
95 }
96
97 public virtual float TimeDilation 101 public virtual float TimeDilation
98 { 102 {
99 get { return 1.0f; } 103 get { return 1.0f; }
@@ -226,6 +230,17 @@ namespace OpenSim.Region.Physics.Manager
226 retMethod(false, Vector3.Zero, 0, 999999999999f, Vector3.Zero); 230 retMethod(false, Vector3.Zero, 0, 999999999999f, Vector3.Zero);
227 } 231 }
228 232
233 public virtual void RaycastWorld(Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod)
234 {
235 if (retMethod != null)
236 retMethod(new List<ContactResult>());
237 }
238
239 public virtual List<ContactResult> RaycastWorld(Vector3 position, Vector3 direction, float length, int Count)
240 {
241 return new List<ContactResult>();
242 }
243
229 private class NullPhysicsScene : PhysicsScene 244 private class NullPhysicsScene : PhysicsScene
230 { 245 {
231 private static int m_workIndicator; 246 private static int m_workIndicator;
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index b79e1a1..53d5e4c 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -193,67 +193,6 @@ namespace OpenSim.Region.Physics.Meshing
193 m_log.Error("****** PrimMesh Parameters ******\n" + primMesh.ParamsToDisplayString()); 193 m_log.Error("****** PrimMesh Parameters ******\n" + primMesh.ParamsToDisplayString());
194 } 194 }
195 195
196 private ulong GetMeshKey(PrimitiveBaseShape pbs, Vector3 size, float lod)
197 {
198 ulong hash = 5381;
199
200 hash = djb2(hash, pbs.PathCurve);
201 hash = djb2(hash, (byte)((byte)pbs.HollowShape | (byte)pbs.ProfileShape));
202 hash = djb2(hash, pbs.PathBegin);
203 hash = djb2(hash, pbs.PathEnd);
204 hash = djb2(hash, pbs.PathScaleX);
205 hash = djb2(hash, pbs.PathScaleY);
206 hash = djb2(hash, pbs.PathShearX);
207 hash = djb2(hash, pbs.PathShearY);
208 hash = djb2(hash, (byte)pbs.PathTwist);
209 hash = djb2(hash, (byte)pbs.PathTwistBegin);
210 hash = djb2(hash, (byte)pbs.PathRadiusOffset);
211 hash = djb2(hash, (byte)pbs.PathTaperX);
212 hash = djb2(hash, (byte)pbs.PathTaperY);
213 hash = djb2(hash, pbs.PathRevolutions);
214 hash = djb2(hash, (byte)pbs.PathSkew);
215 hash = djb2(hash, pbs.ProfileBegin);
216 hash = djb2(hash, pbs.ProfileEnd);
217 hash = djb2(hash, pbs.ProfileHollow);
218
219 // TODO: Separate scale out from the primitive shape data (after
220 // scaling is supported at the physics engine level)
221 byte[] scaleBytes = size.GetBytes();
222 for (int i = 0; i < scaleBytes.Length; i++)
223 hash = djb2(hash, scaleBytes[i]);
224
225 // Include LOD in hash, accounting for endianness
226 byte[] lodBytes = new byte[4];
227 Buffer.BlockCopy(BitConverter.GetBytes(lod), 0, lodBytes, 0, 4);
228 if (!BitConverter.IsLittleEndian)
229 {
230 Array.Reverse(lodBytes, 0, 4);
231 }
232 for (int i = 0; i < lodBytes.Length; i++)
233 hash = djb2(hash, lodBytes[i]);
234
235 // include sculpt UUID
236 if (pbs.SculptEntry)
237 {
238 scaleBytes = pbs.SculptTexture.GetBytes();
239 for (int i = 0; i < scaleBytes.Length; i++)
240 hash = djb2(hash, scaleBytes[i]);
241 }
242
243 return hash;
244 }
245
246 private ulong djb2(ulong hash, byte c)
247 {
248 return ((hash << 5) + hash) + (ulong)c;
249 }
250
251 private ulong djb2(ulong hash, ushort c)
252 {
253 hash = ((hash << 5) + hash) + (ulong)((byte)c);
254 return ((hash << 5) + hash) + (ulong)(c >> 8);
255 }
256
257 /// <summary> 196 /// <summary>
258 /// Add a submesh to an existing list of coords and faces. 197 /// Add a submesh to an existing list of coords and faces.
259 /// </summary> 198 /// </summary>
@@ -301,16 +240,22 @@ namespace OpenSim.Region.Physics.Meshing
301 } 240 }
302 } 241 }
303 242
243 /// <summary>
244 /// Create a physics mesh from data that comes with the prim. The actual data used depends on the prim type.
245 /// </summary>
246 /// <param name="primName"></param>
247 /// <param name="primShape"></param>
248 /// <param name="size"></param>
249 /// <param name="lod"></param>
250 /// <returns></returns>
304 private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod) 251 private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod)
305 { 252 {
306 PrimMesh primMesh; 253// m_log.DebugFormat(
307 PrimMesher.SculptMesh sculptMesh; 254// "[MESH]: Creating physics proxy for {0}, shape {1}",
308 255// primName, (OpenMetaverse.SculptType)primShape.SculptType);
309 List<Coord> coords = new List<Coord>();
310 List<Face> faces = new List<Face>();
311 256
312 Image idata = null; 257 List<Coord> coords;
313 string decodedSculptFileName = ""; 258 List<Face> faces;
314 259
315 if (primShape.SculptEntry) 260 if (primShape.SculptEntry)
316 { 261 {
@@ -319,337 +264,440 @@ namespace OpenSim.Region.Physics.Meshing
319 if (!useMeshiesPhysicsMesh) 264 if (!useMeshiesPhysicsMesh)
320 return null; 265 return null;
321 266
322 m_log.Debug("[MESH]: experimental mesh proxy generation"); 267 if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, size, out coords, out faces))
268 return null;
269 }
270 else
271 {
272 if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, size, lod, out coords, out faces))
273 return null;
274 }
275 }
276 else
277 {
278 if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, lod, out coords, out faces))
279 return null;
280 }
323 281
324 OSD meshOsd = null; 282 // Remove the reference to any JPEG2000 sculpt data so it can be GCed
283 primShape.SculptData = Utils.EmptyBytes;
325 284
326 if (primShape.SculptData.Length <= 0) 285 int numCoords = coords.Count;
327 { 286 int numFaces = faces.Count;
328 m_log.Error("[MESH]: asset data is zero length");
329 return null;
330 }
331 287
332 long start = 0; 288 // Create the list of vertices
333 using (MemoryStream data = new MemoryStream(primShape.SculptData)) 289 List<Vertex> vertices = new List<Vertex>();
334 { 290 for (int i = 0; i < numCoords; i++)
335 try 291 {
336 { 292 Coord c = coords[i];
337 OSD osd = OSDParser.DeserializeLLSDBinary(data); 293 vertices.Add(new Vertex(c.X, c.Y, c.Z));
338 if (osd is OSDMap) 294 }
339 meshOsd = (OSDMap)osd;
340 else
341 {
342 m_log.Warn("[Mesh}: unable to cast mesh asset to OSDMap");
343 return null;
344 }
345 }
346 catch (Exception e)
347 {
348 m_log.Error("[MESH]: Exception deserializing mesh asset header:" + e.ToString());
349 }
350 295
351 start = data.Position; 296 Mesh mesh = new Mesh();
352 } 297 // Add the corresponding triangles to the mesh
298 for (int i = 0; i < numFaces; i++)
299 {
300 Face f = faces[i];
301 mesh.Add(new Triangle(vertices[f.v1], vertices[f.v2], vertices[f.v3]));
302 }
303
304 return mesh;
305 }
306
307 /// <summary>
308 /// Generate the co-ords and faces necessary to construct a mesh from the mesh data the accompanies a prim.
309 /// </summary>
310 /// <param name="primName"></param>
311 /// <param name="primShape"></param>
312 /// <param name="size"></param>
313 /// <param name="coords">Coords are added to this list by the method.</param>
314 /// <param name="faces">Faces are added to this list by the method.</param>
315 /// <returns>true if coords and faces were successfully generated, false if not</returns>
316 private bool GenerateCoordsAndFacesFromPrimMeshData(
317 string primName, PrimitiveBaseShape primShape, Vector3 size, out List<Coord> coords, out List<Face> faces)
318 {
319 m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName);
320
321 coords = new List<Coord>();
322 faces = new List<Face>();
323 OSD meshOsd = null;
324
325 if (primShape.SculptData.Length <= 0)
326 {
327 m_log.Error("[MESH]: asset data is zero length");
328 return false;
329 }
353 330
354 if (meshOsd is OSDMap) 331 long start = 0;
332 using (MemoryStream data = new MemoryStream(primShape.SculptData))
333 {
334 try
335 {
336 OSD osd = OSDParser.DeserializeLLSDBinary(data);
337 if (osd is OSDMap)
338 meshOsd = (OSDMap)osd;
339 else
355 { 340 {
356 OSDMap physicsParms = null; 341 m_log.Warn("[Mesh}: unable to cast mesh asset to OSDMap");
357 OSDMap map = (OSDMap)meshOsd; 342 return false;
358 if (map.ContainsKey("physics_shape")) 343 }
359 physicsParms = (OSDMap)map["physics_shape"]; // old asset format 344 }
360 else if (map.ContainsKey("physics_mesh")) 345 catch (Exception e)
361 physicsParms = (OSDMap)map["physics_mesh"]; // new asset format 346 {
362 347 m_log.Error("[MESH]: Exception deserializing mesh asset header:" + e.ToString());
363 if (physicsParms == null) 348 }
364 { 349
365 m_log.Warn("[MESH]: no recognized physics mesh found in mesh asset"); 350 start = data.Position;
366 return null; 351 }
367 } 352
353 if (meshOsd is OSDMap)
354 {
355 OSDMap physicsParms = null;
356 OSDMap map = (OSDMap)meshOsd;
357 if (map.ContainsKey("physics_shape"))
358 physicsParms = (OSDMap)map["physics_shape"]; // old asset format
359 else if (map.ContainsKey("physics_mesh"))
360 physicsParms = (OSDMap)map["physics_mesh"]; // new asset format
361
362 if (physicsParms == null)
363 {
364 m_log.Warn("[MESH]: no recognized physics mesh found in mesh asset");
365 return false;
366 }
368 367
369 int physOffset = physicsParms["offset"].AsInteger() + (int)start; 368 int physOffset = physicsParms["offset"].AsInteger() + (int)start;
370 int physSize = physicsParms["size"].AsInteger(); 369 int physSize = physicsParms["size"].AsInteger();
371 370
372 if (physOffset < 0 || physSize == 0) 371 if (physOffset < 0 || physSize == 0)
373 return null; // no mesh data in asset 372 return false; // no mesh data in asset
374 373
375 OSD decodedMeshOsd = new OSD(); 374 OSD decodedMeshOsd = new OSD();
376 byte[] meshBytes = new byte[physSize]; 375 byte[] meshBytes = new byte[physSize];
377 System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize); 376 System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize);
378// byte[] decompressed = new byte[physSize * 5]; 377// byte[] decompressed = new byte[physSize * 5];
379 try 378 try
379 {
380 using (MemoryStream inMs = new MemoryStream(meshBytes))
381 {
382 using (MemoryStream outMs = new MemoryStream())
380 { 383 {
381 using (MemoryStream inMs = new MemoryStream(meshBytes)) 384 using (ZOutputStream zOut = new ZOutputStream(outMs))
382 { 385 {
383 using (MemoryStream outMs = new MemoryStream()) 386 byte[] readBuffer = new byte[2048];
387 int readLen = 0;
388 while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
384 { 389 {
385 using (ZOutputStream zOut = new ZOutputStream(outMs)) 390 zOut.Write(readBuffer, 0, readLen);
386 {
387 byte[] readBuffer = new byte[2048];
388 int readLen = 0;
389 while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
390 {
391 zOut.Write(readBuffer, 0, readLen);
392 }
393 zOut.Flush();
394 outMs.Seek(0, SeekOrigin.Begin);
395
396 byte[] decompressedBuf = outMs.GetBuffer();
397
398 decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
399 }
400 } 391 }
392 zOut.Flush();
393 outMs.Seek(0, SeekOrigin.Begin);
394
395 byte[] decompressedBuf = outMs.GetBuffer();
396
397 decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
401 } 398 }
402 } 399 }
403 catch (Exception e) 400 }
404 { 401 }
405 m_log.Error("[MESH]: exception decoding physical mesh: " + e.ToString()); 402 catch (Exception e)
406 return null; 403 {
407 } 404 m_log.Error("[MESH]: exception decoding physical mesh: " + e.ToString());
405 return false;
406 }
408 407
409 OSDArray decodedMeshOsdArray = null; 408 OSDArray decodedMeshOsdArray = null;
410 409
411 // physics_shape is an array of OSDMaps, one for each submesh 410 // physics_shape is an array of OSDMaps, one for each submesh
412 if (decodedMeshOsd is OSDArray) 411 if (decodedMeshOsd is OSDArray)
413 { 412 {
414// Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); 413// Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd));
415 414
416 decodedMeshOsdArray = (OSDArray)decodedMeshOsd; 415 decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
417 foreach (OSD subMeshOsd in decodedMeshOsdArray) 416 foreach (OSD subMeshOsd in decodedMeshOsdArray)
418 { 417 {
419 if (subMeshOsd is OSDMap) 418 if (subMeshOsd is OSDMap)
420 AddSubMesh(subMeshOsd as OSDMap, size, coords, faces); 419 AddSubMesh(subMeshOsd as OSDMap, size, coords, faces);
421 }
422 }
423 } 420 }
424 } 421 }
425 else 422 }
423
424 return true;
425 }
426
427 /// <summary>
428 /// Generate the co-ords and faces necessary to construct a mesh from the sculpt data the accompanies a prim.
429 /// </summary>
430 /// <param name="primName"></param>
431 /// <param name="primShape"></param>
432 /// <param name="size"></param>
433 /// <param name="lod"></param>
434 /// <param name="coords">Coords are added to this list by the method.</param>
435 /// <param name="faces">Faces are added to this list by the method.</param>
436 /// <returns>true if coords and faces were successfully generated, false if not</returns>
437 private bool GenerateCoordsAndFacesFromPrimSculptData(
438 string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, out List<Coord> coords, out List<Face> faces)
439 {
440 coords = new List<Coord>();
441 faces = new List<Face>();
442 PrimMesher.SculptMesh sculptMesh;
443 Image idata = null;
444 string decodedSculptFileName = "";
445
446 if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero)
447 {
448 decodedSculptFileName = System.IO.Path.Combine(decodedSculptMapPath, "smap_" + primShape.SculptTexture.ToString());
449 try
426 { 450 {
427 if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero) 451 if (File.Exists(decodedSculptFileName))
428 { 452 {
429 decodedSculptFileName = System.IO.Path.Combine(decodedSculptMapPath, "smap_" + primShape.SculptTexture.ToString()); 453 idata = Image.FromFile(decodedSculptFileName);
430 try
431 {
432 if (File.Exists(decodedSculptFileName))
433 {
434 idata = Image.FromFile(decodedSculptFileName);
435 }
436 }
437 catch (Exception e)
438 {
439 m_log.Error("[SCULPT]: unable to load cached sculpt map " + decodedSculptFileName + " " + e.Message);
440
441 }
442 //if (idata != null)
443 // m_log.Debug("[SCULPT]: loaded cached map asset for map ID: " + primShape.SculptTexture.ToString());
444 } 454 }
455 }
456 catch (Exception e)
457 {
458 m_log.Error("[SCULPT]: unable to load cached sculpt map " + decodedSculptFileName + " " + e.Message);
459
460 }
461 //if (idata != null)
462 // m_log.Debug("[SCULPT]: loaded cached map asset for map ID: " + primShape.SculptTexture.ToString());
463 }
464
465 if (idata == null)
466 {
467 if (primShape.SculptData == null || primShape.SculptData.Length == 0)
468 return false;
469
470 try
471 {
472 OpenMetaverse.Imaging.ManagedImage unusedData;
473 OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata);
445 474
446 if (idata == null) 475 if (idata == null)
447 { 476 {
448 if (primShape.SculptData == null || primShape.SculptData.Length == 0) 477 // In some cases it seems that the decode can return a null bitmap without throwing
449 return null; 478 // an exception
479 m_log.WarnFormat("[PHYSICS]: OpenJPEG decoded sculpt data for {0} to a null bitmap. Ignoring.", primName);
450 480
451 try 481 return false;
452 { 482 }
453 OpenMetaverse.Imaging.ManagedImage unusedData;
454 OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata);
455 unusedData = null;
456 483
457 //idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData); 484 unusedData = null;
458 485
459 if (cacheSculptMaps && idata != null) 486 //idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData);
460 {
461 try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); }
462 catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); }
463 }
464 }
465 catch (DllNotFoundException)
466 {
467 m_log.Error("[PHYSICS]: OpenJpeg is not installed correctly on this system. Physics Proxy generation failed. Often times this is because of an old version of GLIBC. You must have version 2.4 or above!");
468 return null;
469 }
470 catch (IndexOutOfRangeException)
471 {
472 m_log.Error("[PHYSICS]: OpenJpeg was unable to decode this. Physics Proxy generation failed");
473 return null;
474 }
475 catch (Exception ex)
476 {
477 m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " + ex.Message);
478 return null;
479 }
480 }
481 487
482 PrimMesher.SculptMesh.SculptType sculptType; 488 if (cacheSculptMaps)
483 switch ((OpenMetaverse.SculptType)primShape.SculptType)
484 { 489 {
485 case OpenMetaverse.SculptType.Cylinder: 490 try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); }
486 sculptType = PrimMesher.SculptMesh.SculptType.cylinder; 491 catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); }
487 break;
488 case OpenMetaverse.SculptType.Plane:
489 sculptType = PrimMesher.SculptMesh.SculptType.plane;
490 break;
491 case OpenMetaverse.SculptType.Torus:
492 sculptType = PrimMesher.SculptMesh.SculptType.torus;
493 break;
494 case OpenMetaverse.SculptType.Sphere:
495 sculptType = PrimMesher.SculptMesh.SculptType.sphere;
496 break;
497 default:
498 sculptType = PrimMesher.SculptMesh.SculptType.plane;
499 break;
500 } 492 }
493 }
494 catch (DllNotFoundException)
495 {
496 m_log.Error("[PHYSICS]: OpenJpeg is not installed correctly on this system. Physics Proxy generation failed. Often times this is because of an old version of GLIBC. You must have version 2.4 or above!");
497 return false;
498 }
499 catch (IndexOutOfRangeException)
500 {
501 m_log.Error("[PHYSICS]: OpenJpeg was unable to decode this. Physics Proxy generation failed");
502 return false;
503 }
504 catch (Exception ex)
505 {
506 m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " + ex.Message);
507 return false;
508 }
509 }
510
511 PrimMesher.SculptMesh.SculptType sculptType;
512 switch ((OpenMetaverse.SculptType)primShape.SculptType)
513 {
514 case OpenMetaverse.SculptType.Cylinder:
515 sculptType = PrimMesher.SculptMesh.SculptType.cylinder;
516 break;
517 case OpenMetaverse.SculptType.Plane:
518 sculptType = PrimMesher.SculptMesh.SculptType.plane;
519 break;
520 case OpenMetaverse.SculptType.Torus:
521 sculptType = PrimMesher.SculptMesh.SculptType.torus;
522 break;
523 case OpenMetaverse.SculptType.Sphere:
524 sculptType = PrimMesher.SculptMesh.SculptType.sphere;
525 break;
526 default:
527 sculptType = PrimMesher.SculptMesh.SculptType.plane;
528 break;
529 }
501 530
502 bool mirror = ((primShape.SculptType & 128) != 0); 531 bool mirror = ((primShape.SculptType & 128) != 0);
503 bool invert = ((primShape.SculptType & 64) != 0); 532 bool invert = ((primShape.SculptType & 64) != 0);
504 533
505 sculptMesh = new PrimMesher.SculptMesh((Bitmap)idata, sculptType, (int)lod, false, mirror, invert); 534 sculptMesh = new PrimMesher.SculptMesh((Bitmap)idata, sculptType, (int)lod, false, mirror, invert);
506
507 idata.Dispose();
508 535
509 sculptMesh.DumpRaw(baseDir, primName, "primMesh"); 536 idata.Dispose();
510 537
511 sculptMesh.Scale(size.X, size.Y, size.Z); 538 sculptMesh.DumpRaw(baseDir, primName, "primMesh");
512 539
513 coords = sculptMesh.coords; 540 sculptMesh.Scale(size.X, size.Y, size.Z);
514 faces = sculptMesh.faces; 541
542 coords = sculptMesh.coords;
543 faces = sculptMesh.faces;
544
545 return true;
546 }
547
548 /// <summary>
549 /// Generate the co-ords and faces necessary to construct a mesh from the shape data the accompanies a prim.
550 /// </summary>
551 /// <param name="primName"></param>
552 /// <param name="primShape"></param>
553 /// <param name="size"></param>
554 /// <param name="coords">Coords are added to this list by the method.</param>
555 /// <param name="faces">Faces are added to this list by the method.</param>
556 /// <returns>true if coords and faces were successfully generated, false if not</returns>
557 private bool GenerateCoordsAndFacesFromPrimShapeData(
558 string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, out List<Coord> coords, out List<Face> faces)
559 {
560 PrimMesh primMesh;
561 coords = new List<Coord>();
562 faces = new List<Face>();
563
564 float pathShearX = primShape.PathShearX < 128 ? (float)primShape.PathShearX * 0.01f : (float)(primShape.PathShearX - 256) * 0.01f;
565 float pathShearY = primShape.PathShearY < 128 ? (float)primShape.PathShearY * 0.01f : (float)(primShape.PathShearY - 256) * 0.01f;
566 float pathBegin = (float)primShape.PathBegin * 2.0e-5f;
567 float pathEnd = 1.0f - (float)primShape.PathEnd * 2.0e-5f;
568 float pathScaleX = (float)(primShape.PathScaleX - 100) * 0.01f;
569 float pathScaleY = (float)(primShape.PathScaleY - 100) * 0.01f;
570
571 float profileBegin = (float)primShape.ProfileBegin * 2.0e-5f;
572 float profileEnd = 1.0f - (float)primShape.ProfileEnd * 2.0e-5f;
573 float profileHollow = (float)primShape.ProfileHollow * 2.0e-5f;
574 if (profileHollow > 0.95f)
575 profileHollow = 0.95f;
576
577 int sides = 4;
578 LevelOfDetail iLOD = (LevelOfDetail)lod;
579 if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
580 sides = 3;
581 else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
582 {
583 switch (iLOD)
584 {
585 case LevelOfDetail.High: sides = 24; break;
586 case LevelOfDetail.Medium: sides = 12; break;
587 case LevelOfDetail.Low: sides = 6; break;
588 case LevelOfDetail.VeryLow: sides = 3; break;
589 default: sides = 24; break;
515 } 590 }
516 } 591 }
517 else 592 else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
593 { // half circle, prim is a sphere
594 switch (iLOD)
595 {
596 case LevelOfDetail.High: sides = 24; break;
597 case LevelOfDetail.Medium: sides = 12; break;
598 case LevelOfDetail.Low: sides = 6; break;
599 case LevelOfDetail.VeryLow: sides = 3; break;
600 default: sides = 24; break;
601 }
602
603 profileBegin = 0.5f * profileBegin + 0.5f;
604 profileEnd = 0.5f * profileEnd + 0.5f;
605 }
606
607 int hollowSides = sides;
608 if (primShape.HollowShape == HollowShape.Circle)
518 { 609 {
519 float pathShearX = primShape.PathShearX < 128 ? (float)primShape.PathShearX * 0.01f : (float)(primShape.PathShearX - 256) * 0.01f; 610 switch (iLOD)
520 float pathShearY = primShape.PathShearY < 128 ? (float)primShape.PathShearY * 0.01f : (float)(primShape.PathShearY - 256) * 0.01f; 611 {
521 float pathBegin = (float)primShape.PathBegin * 2.0e-5f; 612 case LevelOfDetail.High: hollowSides = 24; break;
522 float pathEnd = 1.0f - (float)primShape.PathEnd * 2.0e-5f; 613 case LevelOfDetail.Medium: hollowSides = 12; break;
523 float pathScaleX = (float)(primShape.PathScaleX - 100) * 0.01f; 614 case LevelOfDetail.Low: hollowSides = 6; break;
524 float pathScaleY = (float)(primShape.PathScaleY - 100) * 0.01f; 615 case LevelOfDetail.VeryLow: hollowSides = 3; break;
525 616 default: hollowSides = 24; break;
526 float profileBegin = (float)primShape.ProfileBegin * 2.0e-5f;
527 float profileEnd = 1.0f - (float)primShape.ProfileEnd * 2.0e-5f;
528 float profileHollow = (float)primShape.ProfileHollow * 2.0e-5f;
529 if (profileHollow > 0.95f)
530 profileHollow = 0.95f;
531
532 int sides = 4;
533 if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
534 sides = 3;
535 else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
536 sides = 24;
537 else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
538 { // half circle, prim is a sphere
539 sides = 24;
540
541 profileBegin = 0.5f * profileBegin + 0.5f;
542 profileEnd = 0.5f * profileEnd + 0.5f;
543 } 617 }
618 }
619 else if (primShape.HollowShape == HollowShape.Square)
620 hollowSides = 4;
621 else if (primShape.HollowShape == HollowShape.Triangle)
622 hollowSides = 3;
544 623
545 int hollowSides = sides; 624 primMesh = new PrimMesh(sides, profileBegin, profileEnd, profileHollow, hollowSides);
546 if (primShape.HollowShape == HollowShape.Circle)
547 hollowSides = 24;
548 else if (primShape.HollowShape == HollowShape.Square)
549 hollowSides = 4;
550 else if (primShape.HollowShape == HollowShape.Triangle)
551 hollowSides = 3;
552 625
553 primMesh = new PrimMesh(sides, profileBegin, profileEnd, profileHollow, hollowSides); 626 if (primMesh.errorMessage != null)
627 if (primMesh.errorMessage.Length > 0)
628 m_log.Error("[ERROR] " + primMesh.errorMessage);
554 629
555 if (primMesh.errorMessage != null) 630 primMesh.topShearX = pathShearX;
556 if (primMesh.errorMessage.Length > 0) 631 primMesh.topShearY = pathShearY;
557 m_log.Error("[ERROR] " + primMesh.errorMessage); 632 primMesh.pathCutBegin = pathBegin;
633 primMesh.pathCutEnd = pathEnd;
558 634
559 primMesh.topShearX = pathShearX; 635 if (primShape.PathCurve == (byte)Extrusion.Straight || primShape.PathCurve == (byte) Extrusion.Flexible)
560 primMesh.topShearY = pathShearY; 636 {
561 primMesh.pathCutBegin = pathBegin; 637 primMesh.twistBegin = primShape.PathTwistBegin * 18 / 10;
562 primMesh.pathCutEnd = pathEnd; 638 primMesh.twistEnd = primShape.PathTwist * 18 / 10;
639 primMesh.taperX = pathScaleX;
640 primMesh.taperY = pathScaleY;
563 641
564 if (primShape.PathCurve == (byte)Extrusion.Straight || primShape.PathCurve == (byte) Extrusion.Flexible) 642 if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f)
565 { 643 {
566 primMesh.twistBegin = primShape.PathTwistBegin * 18 / 10; 644 ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh);
567 primMesh.twistEnd = primShape.PathTwist * 18 / 10; 645 if (profileBegin < 0.0f) profileBegin = 0.0f;
568 primMesh.taperX = pathScaleX; 646 if (profileEnd > 1.0f) profileEnd = 1.0f;
569 primMesh.taperY = pathScaleY; 647 }
570
571 if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f)
572 {
573 ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh);
574 if (profileBegin < 0.0f) profileBegin = 0.0f;
575 if (profileEnd > 1.0f) profileEnd = 1.0f;
576 }
577#if SPAM 648#if SPAM
578 m_log.Debug("****** PrimMesh Parameters (Linear) ******\n" + primMesh.ParamsToDisplayString()); 649 m_log.Debug("****** PrimMesh Parameters (Linear) ******\n" + primMesh.ParamsToDisplayString());
579#endif 650#endif
580 try 651 try
581 { 652 {
582 primMesh.ExtrudeLinear(); 653 primMesh.ExtrudeLinear();
583 }
584 catch (Exception ex)
585 {
586 ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh);
587 return null;
588 }
589 } 654 }
590 else 655 catch (Exception ex)
591 { 656 {
592 primMesh.holeSizeX = (200 - primShape.PathScaleX) * 0.01f; 657 ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh);
593 primMesh.holeSizeY = (200 - primShape.PathScaleY) * 0.01f; 658 return false;
594 primMesh.radius = 0.01f * primShape.PathRadiusOffset; 659 }
595 primMesh.revolutions = 1.0f + 0.015f * primShape.PathRevolutions; 660 }
596 primMesh.skew = 0.01f * primShape.PathSkew; 661 else
597 primMesh.twistBegin = primShape.PathTwistBegin * 36 / 10; 662 {
598 primMesh.twistEnd = primShape.PathTwist * 36 / 10; 663 primMesh.holeSizeX = (200 - primShape.PathScaleX) * 0.01f;
599 primMesh.taperX = primShape.PathTaperX * 0.01f; 664 primMesh.holeSizeY = (200 - primShape.PathScaleY) * 0.01f;
600 primMesh.taperY = primShape.PathTaperY * 0.01f; 665 primMesh.radius = 0.01f * primShape.PathRadiusOffset;
601 666 primMesh.revolutions = 1.0f + 0.015f * primShape.PathRevolutions;
602 if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f) 667 primMesh.skew = 0.01f * primShape.PathSkew;
603 { 668 primMesh.twistBegin = primShape.PathTwistBegin * 36 / 10;
604 ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh); 669 primMesh.twistEnd = primShape.PathTwist * 36 / 10;
605 if (profileBegin < 0.0f) profileBegin = 0.0f; 670 primMesh.taperX = primShape.PathTaperX * 0.01f;
606 if (profileEnd > 1.0f) profileEnd = 1.0f; 671 primMesh.taperY = primShape.PathTaperY * 0.01f;
607 } 672
673 if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f)
674 {
675 ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh);
676 if (profileBegin < 0.0f) profileBegin = 0.0f;
677 if (profileEnd > 1.0f) profileEnd = 1.0f;
678 }
608#if SPAM 679#if SPAM
609 m_log.Debug("****** PrimMesh Parameters (Circular) ******\n" + primMesh.ParamsToDisplayString()); 680 m_log.Debug("****** PrimMesh Parameters (Circular) ******\n" + primMesh.ParamsToDisplayString());
610#endif 681#endif
611 try 682 try
612 { 683 {
613 primMesh.ExtrudeCircular(); 684 primMesh.ExtrudeCircular();
614 } 685 }
615 catch (Exception ex) 686 catch (Exception ex)
616 { 687 {
617 ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh); 688 ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh);
618 return null; 689 return false;
619 }
620 } 690 }
621
622 primMesh.DumpRaw(baseDir, primName, "primMesh");
623
624 primMesh.Scale(size.X, size.Y, size.Z);
625
626 coords = primMesh.coords;
627 faces = primMesh.faces;
628 } 691 }
629 692
630 // Remove the reference to any JPEG2000 sculpt data so it can be GCed 693 primMesh.DumpRaw(baseDir, primName, "primMesh");
631 primShape.SculptData = Utils.EmptyBytes;
632 694
633 int numCoords = coords.Count; 695 primMesh.Scale(size.X, size.Y, size.Z);
634 int numFaces = faces.Count;
635
636 // Create the list of vertices
637 List<Vertex> vertices = new List<Vertex>();
638 for (int i = 0; i < numCoords; i++)
639 {
640 Coord c = coords[i];
641 vertices.Add(new Vertex(c.X, c.Y, c.Z));
642 }
643 696
644 Mesh mesh = new Mesh(); 697 coords = primMesh.coords;
645 // Add the corresponding triangles to the mesh 698 faces = primMesh.faces;
646 for (int i = 0; i < numFaces; i++)
647 {
648 Face f = faces[i];
649 mesh.Add(new Triangle(vertices[f.v1], vertices[f.v2], vertices[f.v3]));
650 }
651 699
652 return mesh; 700 return true;
653 } 701 }
654 702
655 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) 703 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod)
@@ -668,8 +716,7 @@ namespace OpenSim.Region.Physics.Meshing
668 716
669 // If this mesh has been created already, return it instead of creating another copy 717 // If this mesh has been created already, return it instead of creating another copy
670 // For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory 718 // For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory
671 719 key = primShape.GetMeshKey(size, lod);
672 key = GetMeshKey(primShape, size, lod);
673 if (m_uniqueMeshes.TryGetValue(key, out mesh)) 720 if (m_uniqueMeshes.TryGetValue(key, out mesh))
674 return mesh; 721 return mesh;
675 722
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index 0e7dd81..c165a41 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -258,7 +258,11 @@ namespace OpenSim.Region.Physics.OdePlugin
258 public override bool Flying 258 public override bool Flying
259 { 259 {
260 get { return flying; } 260 get { return flying; }
261 set { flying = value; } 261 set
262 {
263 flying = value;
264// m_log.DebugFormat("[PHYSICS]: Set OdeCharacter Flying to {0}", flying);
265 }
262 } 266 }
263 267
264 /// <summary> 268 /// <summary>
@@ -305,10 +309,12 @@ namespace OpenSim.Region.Physics.OdePlugin
305 { 309 {
306 m_iscolliding = true; 310 m_iscolliding = true;
307 } 311 }
312
308 if (m_wascolliding != m_iscolliding) 313 if (m_wascolliding != m_iscolliding)
309 { 314 {
310 //base.SendCollisionUpdate(new CollisionEventUpdate()); 315 //base.SendCollisionUpdate(new CollisionEventUpdate());
311 } 316 }
317
312 m_wascolliding = m_iscolliding; 318 m_wascolliding = m_iscolliding;
313 } 319 }
314 } 320 }
@@ -1219,18 +1225,23 @@ namespace OpenSim.Region.Physics.OdePlugin
1219 { 1225 {
1220 m_requestedUpdateFrequency = ms; 1226 m_requestedUpdateFrequency = ms;
1221 m_eventsubscription = ms; 1227 m_eventsubscription = ms;
1222 _parent_scene.addCollisionEventReporting(this); 1228 _parent_scene.AddCollisionEventReporting(this);
1223 } 1229 }
1230
1224 public override void UnSubscribeEvents() 1231 public override void UnSubscribeEvents()
1225 { 1232 {
1226 _parent_scene.remCollisionEventReporting(this); 1233 _parent_scene.RemoveCollisionEventReporting(this);
1227 m_requestedUpdateFrequency = 0; 1234 m_requestedUpdateFrequency = 0;
1228 m_eventsubscription = 0; 1235 m_eventsubscription = 0;
1229 } 1236 }
1237
1230 public void AddCollisionEvent(uint CollidedWith, ContactPoint contact) 1238 public void AddCollisionEvent(uint CollidedWith, ContactPoint contact)
1231 { 1239 {
1232 if (m_eventsubscription > 0) 1240 if (m_eventsubscription > 0)
1233 { 1241 {
1242// m_log.DebugFormat(
1243// "[PHYSICS]: Adding collision event for {0}, collidedWith {1}, contact {2}", "", CollidedWith, contact);
1244
1234 CollisionEventsThisFrame.addCollider(CollidedWith, contact); 1245 CollisionEventsThisFrame.addCollider(CollidedWith, contact);
1235 } 1246 }
1236 } 1247 }
@@ -1247,6 +1258,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1247 m_eventsubscription = 0; 1258 m_eventsubscription = 0;
1248 } 1259 }
1249 } 1260 }
1261
1250 public override bool SubscribedEvents() 1262 public override bool SubscribedEvents()
1251 { 1263 {
1252 if (m_eventsubscription > 0) 1264 if (m_eventsubscription > 0)
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 5fe0775..0a4fc51 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -61,6 +61,22 @@ namespace OpenSim.Region.Physics.OdePlugin
61 { 61 {
62 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 62 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
63 63
64 private bool m_isphysical;
65
66 /// <summary>
67 /// Is this prim subject to physics? Even if not, it's still solid for collision purposes.
68 /// </summary>
69 public override bool IsPhysical
70 {
71 get { return m_isphysical; }
72 set
73 {
74 m_isphysical = value;
75 if (!m_isphysical) // Zero the remembered last velocity
76 m_lastVelocity = Vector3.Zero;
77 }
78 }
79
64 private Vector3 _position; 80 private Vector3 _position;
65 private Vector3 _velocity; 81 private Vector3 _velocity;
66 private Vector3 _torque; 82 private Vector3 _torque;
@@ -138,12 +154,15 @@ namespace OpenSim.Region.Physics.OdePlugin
138 private List<Vector3> m_forcelist = new List<Vector3>(); 154 private List<Vector3> m_forcelist = new List<Vector3>();
139 private List<Vector3> m_angularforcelist = new List<Vector3>(); 155 private List<Vector3> m_angularforcelist = new List<Vector3>();
140 156
141 private IMesh _mesh;
142 private PrimitiveBaseShape _pbs; 157 private PrimitiveBaseShape _pbs;
143 private OdeScene _parent_scene; 158 private OdeScene _parent_scene;
159
160 /// <summary>
161 /// The physics space which contains prim geometries
162 /// </summary>
144 public IntPtr m_targetSpace = IntPtr.Zero; 163 public IntPtr m_targetSpace = IntPtr.Zero;
164
145 public IntPtr prim_geom; 165 public IntPtr prim_geom;
146 public IntPtr prev_geom;
147 public IntPtr _triMeshData; 166 public IntPtr _triMeshData;
148 167
149 private IntPtr _linkJointGroup = IntPtr.Zero; 168 private IntPtr _linkJointGroup = IntPtr.Zero;
@@ -153,7 +172,6 @@ namespace OpenSim.Region.Physics.OdePlugin
153 private List<OdePrim> childrenPrim = new List<OdePrim>(); 172 private List<OdePrim> childrenPrim = new List<OdePrim>();
154 173
155 private bool iscolliding; 174 private bool iscolliding;
156 private bool m_isphysical;
157 private bool m_isSelected; 175 private bool m_isSelected;
158 176
159 internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively 177 internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively
@@ -188,7 +206,7 @@ namespace OpenSim.Region.Physics.OdePlugin
188 internal int m_material = (int)Material.Wood; 206 internal int m_material = (int)Material.Wood;
189 207
190 public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size, 208 public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size,
191 Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode) 209 Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode)
192 { 210 {
193 Name = primName; 211 Name = primName;
194 m_vehicle = new ODEDynamics(); 212 m_vehicle = new ODEDynamics();
@@ -208,9 +226,7 @@ namespace OpenSim.Region.Physics.OdePlugin
208 // m_tensor = parent_scene.bodyMotorJointMaxforceTensor; 226 // m_tensor = parent_scene.bodyMotorJointMaxforceTensor;
209 body_autodisable_frames = parent_scene.bodyFramesAutoDisable; 227 body_autodisable_frames = parent_scene.bodyFramesAutoDisable;
210 228
211
212 prim_geom = IntPtr.Zero; 229 prim_geom = IntPtr.Zero;
213 prev_geom = IntPtr.Zero;
214 230
215 if (!pos.IsFinite()) 231 if (!pos.IsFinite())
216 { 232 {
@@ -233,20 +249,21 @@ namespace OpenSim.Region.Physics.OdePlugin
233 249
234 _orientation = rotation; 250 _orientation = rotation;
235 m_taintrot = _orientation; 251 m_taintrot = _orientation;
236 _mesh = mesh;
237 _pbs = pbs; 252 _pbs = pbs;
238 253
239 _parent_scene = parent_scene; 254 _parent_scene = parent_scene;
240 m_targetSpace = (IntPtr)0; 255 m_targetSpace = (IntPtr)0;
241 256
242 if (pos.Z < 0) 257 if (pos.Z < 0)
243 m_isphysical = false; 258 {
259 IsPhysical = false;
260 }
244 else 261 else
245 { 262 {
246 m_isphysical = pisPhysical; 263 IsPhysical = pisPhysical;
247 // If we're physical, we need to be in the master space for now. 264 // If we're physical, we need to be in the master space for now.
248 // linksets *should* be in a space together.. but are not currently 265 // linksets *should* be in a space together.. but are not currently
249 if (m_isphysical) 266 if (IsPhysical)
250 m_targetSpace = _parent_scene.space; 267 m_targetSpace = _parent_scene.space;
251 } 268 }
252 269
@@ -289,7 +306,7 @@ namespace OpenSim.Region.Physics.OdePlugin
289 // through it while it's selected 306 // through it while it's selected
290 m_collisionscore = 0; 307 m_collisionscore = 0;
291 308
292 if ((m_isphysical && !_zeroFlag) || !value) 309 if ((IsPhysical && !_zeroFlag) || !value)
293 { 310 {
294 m_taintselected = value; 311 m_taintselected = value;
295 _parent_scene.AddPhysicsActorTaint(this); 312 _parent_scene.AddPhysicsActorTaint(this);
@@ -305,15 +322,21 @@ namespace OpenSim.Region.Physics.OdePlugin
305 } 322 }
306 } 323 }
307 324
325 /// <summary>
326 /// Set a new geometry for this prim.
327 /// </summary>
328 /// <param name="geom"></param>
308 public void SetGeom(IntPtr geom) 329 public void SetGeom(IntPtr geom)
309 { 330 {
310 prev_geom = prim_geom;
311 prim_geom = geom; 331 prim_geom = geom;
312//Console.WriteLine("SetGeom to " + prim_geom + " for " + Name); 332//Console.WriteLine("SetGeom to " + prim_geom + " for " + Name);
313 if (prim_geom != IntPtr.Zero) 333 if (prim_geom != IntPtr.Zero)
314 { 334 {
315 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 335 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
316 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 336 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
337
338 _parent_scene.geom_name_map[prim_geom] = Name;
339 _parent_scene.actor_name_map[prim_geom] = this;
317 } 340 }
318 341
319 if (childPrim) 342 if (childPrim)
@@ -332,7 +355,7 @@ namespace OpenSim.Region.Physics.OdePlugin
332 { 355 {
333 if (!childPrim) 356 if (!childPrim)
334 { 357 {
335 if (m_isphysical && Body != IntPtr.Zero) 358 if (IsPhysical && Body != IntPtr.Zero)
336 { 359 {
337 d.BodyEnable(Body); 360 d.BodyEnable(Body);
338 if (m_vehicle.Type != Vehicle.TYPE_NONE) 361 if (m_vehicle.Type != Vehicle.TYPE_NONE)
@@ -347,12 +370,15 @@ namespace OpenSim.Region.Physics.OdePlugin
347 { 370 {
348 m_disabled = true; 371 m_disabled = true;
349 372
350 if (m_isphysical && Body != IntPtr.Zero) 373 if (IsPhysical && Body != IntPtr.Zero)
351 { 374 {
352 d.BodyDisable(Body); 375 d.BodyDisable(Body);
353 } 376 }
354 } 377 }
355 378
379 /// <summary>
380 /// Make a prim subject to physics.
381 /// </summary>
356 public void enableBody() 382 public void enableBody()
357 { 383 {
358 // Don't enable this body if we're a child prim 384 // Don't enable this body if we're a child prim
@@ -638,7 +664,7 @@ namespace OpenSim.Region.Physics.OdePlugin
638 float profileEnd; 664 float profileEnd;
639 665
640 if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)Extrusion.Flexible) 666 if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)Extrusion.Flexible)
641 { 667 {
642 taperX1 = _pbs.PathScaleX * 0.01f; 668 taperX1 = _pbs.PathScaleX * 0.01f;
643 if (taperX1 > 1.0f) 669 if (taperX1 > 1.0f)
644 taperX1 = 2.0f - taperX1; 670 taperX1 = 2.0f - taperX1;
@@ -648,9 +674,9 @@ namespace OpenSim.Region.Physics.OdePlugin
648 if (taperY1 > 1.0f) 674 if (taperY1 > 1.0f)
649 taperY1 = 2.0f - taperY1; 675 taperY1 = 2.0f - taperY1;
650 taperY = 1.0f - taperY1; 676 taperY = 1.0f - taperY1;
651 } 677 }
652 else 678 else
653 { 679 {
654 taperX = _pbs.PathTaperX * 0.01f; 680 taperX = _pbs.PathTaperX * 0.01f;
655 if (taperX < 0.0f) 681 if (taperX < 0.0f)
656 taperX = -taperX; 682 taperX = -taperX;
@@ -660,9 +686,7 @@ namespace OpenSim.Region.Physics.OdePlugin
660 if (taperY < 0.0f) 686 if (taperY < 0.0f)
661 taperY = -taperY; 687 taperY = -taperY;
662 taperY1 = 1.0f - taperY; 688 taperY1 = 1.0f - taperY;
663 689 }
664 }
665
666 690
667 volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY); 691 volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY);
668 692
@@ -730,6 +754,9 @@ namespace OpenSim.Region.Physics.OdePlugin
730 } 754 }
731 } 755 }
732 756
757 /// <summary>
758 /// Stop a prim from being subject to physics.
759 /// </summary>
733 public void disableBody() 760 public void disableBody()
734 { 761 {
735 //this kills the body so things like 'mesh' can re-create it. 762 //this kills the body so things like 'mesh' can re-create it.
@@ -780,6 +807,7 @@ namespace OpenSim.Region.Physics.OdePlugin
780 Body = IntPtr.Zero; 807 Body = IntPtr.Zero;
781 } 808 }
782 } 809 }
810
783 m_disabled = true; 811 m_disabled = true;
784 m_collisionscore = 0; 812 m_collisionscore = 0;
785 } 813 }
@@ -846,7 +874,6 @@ namespace OpenSim.Region.Physics.OdePlugin
846 return; 874 return;
847 } 875 }
848 876
849
850 // if (IsPhysical && Body == (IntPtr) 0) 877 // if (IsPhysical && Body == (IntPtr) 0)
851 // { 878 // {
852 // Recreate the body 879 // Recreate the body
@@ -859,7 +886,9 @@ namespace OpenSim.Region.Physics.OdePlugin
859 886
860 public void ProcessTaints(float timestep) 887 public void ProcessTaints(float timestep)
861 { 888 {
862Console.WriteLine("ProcessTaints for " + Name); 889#if SPAM
890Console.WriteLine("ZProcessTaints for " + Name);
891#endif
863 if (m_taintadd) 892 if (m_taintadd)
864 { 893 {
865 changeadd(timestep); 894 changeadd(timestep);
@@ -887,7 +916,7 @@ Console.WriteLine("ProcessTaints for " + Name);
887 } 916 }
888 } 917 }
889 918
890 if (m_taintPhysics != m_isphysical && !(m_taintparent != _parent)) 919 if (m_taintPhysics != IsPhysical && !(m_taintparent != _parent))
891 changePhysicsStatus(timestep); 920 changePhysicsStatus(timestep);
892 921
893 if (!_size.ApproxEquals(m_taintsize, 0f)) 922 if (!_size.ApproxEquals(m_taintsize, 0f))
@@ -969,7 +998,7 @@ Console.WriteLine("ProcessTaints for " + Name);
969 OdePrim obj = (OdePrim)m_taintparent; 998 OdePrim obj = (OdePrim)m_taintparent;
970 //obj.disableBody(); 999 //obj.disableBody();
971//Console.WriteLine("changelink calls ParentPrim"); 1000//Console.WriteLine("changelink calls ParentPrim");
972 obj.ParentPrim(this); 1001 obj.AddChildPrim(this);
973 1002
974 /* 1003 /*
975 if (obj.Body != (IntPtr)0 && Body != (IntPtr)0 && obj.Body != Body) 1004 if (obj.Body != (IntPtr)0 && Body != (IntPtr)0 && obj.Body != Body)
@@ -1006,14 +1035,16 @@ Console.WriteLine("ProcessTaints for " + Name);
1006 } 1035 }
1007 1036
1008 _parent = m_taintparent; 1037 _parent = m_taintparent;
1009 m_taintPhysics = m_isphysical; 1038 m_taintPhysics = IsPhysical;
1010 } 1039 }
1011 1040
1012 // I'm the parent 1041 /// <summary>
1013 // prim is the child 1042 /// Add a child prim to this parent prim.
1014 public void ParentPrim(OdePrim prim) 1043 /// </summary>
1044 /// <param name="prim">Child prim</param>
1045 public void AddChildPrim(OdePrim prim)
1015 { 1046 {
1016//Console.WriteLine("ParentPrim " + Name); 1047//Console.WriteLine("AddChildPrim " + Name);
1017 if (this.m_localID != prim.m_localID) 1048 if (this.m_localID != prim.m_localID)
1018 { 1049 {
1019 if (Body == IntPtr.Zero) 1050 if (Body == IntPtr.Zero)
@@ -1036,7 +1067,6 @@ Console.WriteLine("ProcessTaints for " + Name);
1036 d.MassSetZero(out m2); 1067 d.MassSetZero(out m2);
1037 d.MassSetBoxTotal(out m2, prim.CalculateMass(), prm._size.X, prm._size.Y, prm._size.Z); 1068 d.MassSetBoxTotal(out m2, prim.CalculateMass(), prm._size.X, prm._size.Y, prm._size.Z);
1038 1069
1039
1040 d.Quaternion quat = new d.Quaternion(); 1070 d.Quaternion quat = new d.Quaternion();
1041 quat.W = prm._orientation.W; 1071 quat.W = prm._orientation.W;
1042 quat.X = prm._orientation.X; 1072 quat.X = prm._orientation.X;
@@ -1106,6 +1136,7 @@ Console.WriteLine("ProcessTaints for " + Name);
1106 prm.Body = Body; 1136 prm.Body = Body;
1107 _parent_scene.addActivePrim(prm); 1137 _parent_scene.addActivePrim(prm);
1108 } 1138 }
1139
1109 m_collisionCategories |= CollisionCategories.Body; 1140 m_collisionCategories |= CollisionCategories.Body;
1110 m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); 1141 m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1111 1142
@@ -1114,7 +1145,6 @@ Console.WriteLine("ProcessTaints for " + Name);
1114//Console.WriteLine(" Post GeomSetCategoryBits 2"); 1145//Console.WriteLine(" Post GeomSetCategoryBits 2");
1115 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 1146 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1116 1147
1117
1118 d.Quaternion quat2 = new d.Quaternion(); 1148 d.Quaternion quat2 = new d.Quaternion();
1119 quat2.W = _orientation.W; 1149 quat2.W = _orientation.W;
1120 quat2.X = _orientation.X; 1150 quat2.X = _orientation.X;
@@ -1136,7 +1166,6 @@ Console.WriteLine("ProcessTaints for " + Name);
1136 d.BodySetAutoDisableFlag(Body, true); 1166 d.BodySetAutoDisableFlag(Body, true);
1137 d.BodySetAutoDisableSteps(Body, body_autodisable_frames); 1167 d.BodySetAutoDisableSteps(Body, body_autodisable_frames);
1138 1168
1139
1140 m_interpenetrationcount = 0; 1169 m_interpenetrationcount = 0;
1141 m_collisionscore = 0; 1170 m_collisionscore = 0;
1142 m_disabled = false; 1171 m_disabled = false;
@@ -1147,7 +1176,9 @@ Console.WriteLine("ProcessTaints for " + Name);
1147 createAMotor(m_angularlock); 1176 createAMotor(m_angularlock);
1148 } 1177 }
1149 d.BodySetPosition(Body, Position.X, Position.Y, Position.Z); 1178 d.BodySetPosition(Body, Position.X, Position.Y, Position.Z);
1150 if (m_vehicle.Type != Vehicle.TYPE_NONE) m_vehicle.Enable(Body, _parent_scene); 1179 if (m_vehicle.Type != Vehicle.TYPE_NONE)
1180 m_vehicle.Enable(Body, _parent_scene);
1181
1151 _parent_scene.addActivePrim(this); 1182 _parent_scene.addActivePrim(this);
1152 } 1183 }
1153 } 1184 }
@@ -1157,7 +1188,7 @@ Console.WriteLine("ProcessTaints for " + Name);
1157 1188
1158 private void ChildSetGeom(OdePrim odePrim) 1189 private void ChildSetGeom(OdePrim odePrim)
1159 { 1190 {
1160 //if (m_isphysical && Body != IntPtr.Zero) 1191 //if (IsPhysical && Body != IntPtr.Zero)
1161 lock (childrenPrim) 1192 lock (childrenPrim)
1162 { 1193 {
1163 foreach (OdePrim prm in childrenPrim) 1194 foreach (OdePrim prm in childrenPrim)
@@ -1173,7 +1204,6 @@ Console.WriteLine("ProcessTaints for " + Name);
1173 } 1204 }
1174 disableBody(); 1205 disableBody();
1175 1206
1176
1177 if (Body != IntPtr.Zero) 1207 if (Body != IntPtr.Zero)
1178 { 1208 {
1179 _parent_scene.remActivePrim(this); 1209 _parent_scene.remActivePrim(this);
@@ -1184,10 +1214,9 @@ Console.WriteLine("ProcessTaints for " + Name);
1184 foreach (OdePrim prm in childrenPrim) 1214 foreach (OdePrim prm in childrenPrim)
1185 { 1215 {
1186//Console.WriteLine("ChildSetGeom calls ParentPrim"); 1216//Console.WriteLine("ChildSetGeom calls ParentPrim");
1187 ParentPrim(prm); 1217 AddChildPrim(prm);
1188 } 1218 }
1189 } 1219 }
1190
1191 } 1220 }
1192 1221
1193 private void ChildDelink(OdePrim odePrim) 1222 private void ChildDelink(OdePrim odePrim)
@@ -1224,7 +1253,7 @@ Console.WriteLine("ProcessTaints for " + Name);
1224 foreach (OdePrim prm in childrenPrim) 1253 foreach (OdePrim prm in childrenPrim)
1225 { 1254 {
1226//Console.WriteLine("ChildDelink calls ParentPrim"); 1255//Console.WriteLine("ChildDelink calls ParentPrim");
1227 ParentPrim(prm); 1256 AddChildPrim(prm);
1228 } 1257 }
1229 } 1258 }
1230 } 1259 }
@@ -1258,7 +1287,7 @@ Console.WriteLine("ProcessTaints for " + Name);
1258 // first 50 again. then the last 50 are disabled. then the first 50, which were just woken 1287 // first 50 again. then the last 50 are disabled. then the first 50, which were just woken
1259 // up, start simulating again, which in turn wakes up the last 50. 1288 // up, start simulating again, which in turn wakes up the last 50.
1260 1289
1261 if (m_isphysical) 1290 if (IsPhysical)
1262 { 1291 {
1263 disableBodySoft(); 1292 disableBodySoft();
1264 } 1293 }
@@ -1269,7 +1298,7 @@ Console.WriteLine("ProcessTaints for " + Name);
1269 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 1298 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1270 } 1299 }
1271 1300
1272 if (m_isphysical) 1301 if (IsPhysical)
1273 { 1302 {
1274 disableBodySoft(); 1303 disableBodySoft();
1275 } 1304 }
@@ -1278,7 +1307,7 @@ Console.WriteLine("ProcessTaints for " + Name);
1278 { 1307 {
1279 m_collisionCategories = CollisionCategories.Geom; 1308 m_collisionCategories = CollisionCategories.Geom;
1280 1309
1281 if (m_isphysical) 1310 if (IsPhysical)
1282 m_collisionCategories |= CollisionCategories.Body; 1311 m_collisionCategories |= CollisionCategories.Body;
1283 1312
1284 m_collisionFlags = m_default_collisionFlags; 1313 m_collisionFlags = m_default_collisionFlags;
@@ -1293,7 +1322,8 @@ Console.WriteLine("ProcessTaints for " + Name);
1293 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 1322 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1294 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 1323 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1295 } 1324 }
1296 if (m_isphysical) 1325
1326 if (IsPhysical)
1297 { 1327 {
1298 if (Body != IntPtr.Zero) 1328 if (Body != IntPtr.Zero)
1299 { 1329 {
@@ -1312,7 +1342,7 @@ Console.WriteLine("ProcessTaints for " + Name);
1312 { 1342 {
1313 m_taintposition = _position; 1343 m_taintposition = _position;
1314 m_taintrot = _orientation; 1344 m_taintrot = _orientation;
1315 m_taintPhysics = m_isphysical; 1345 m_taintPhysics = IsPhysical;
1316 m_taintselected = m_isSelected; 1346 m_taintselected = m_isSelected;
1317 m_taintsize = _size; 1347 m_taintsize = _size;
1318 m_taintshape = false; 1348 m_taintshape = false;
@@ -1321,12 +1351,19 @@ Console.WriteLine("ProcessTaints for " + Name);
1321 m_taintVelocity = Vector3.Zero; 1351 m_taintVelocity = Vector3.Zero;
1322 } 1352 }
1323 1353
1324 public void CreateGeom(IntPtr m_targetSpace, IMesh _mesh) 1354 /// <summary>
1355 /// Create a geometry for the given mesh in the given target space.
1356 /// </summary>
1357 /// <param name="m_targetSpace"></param>
1358 /// <param name="mesh">If null, then a mesh is used that is based on the profile shape data.</param>
1359 public void CreateGeom(IntPtr m_targetSpace, IMesh mesh)
1325 { 1360 {
1326//Console.WriteLine("CreateGeom:"); 1361#if SPAM
1327 if (_mesh != null) 1362Console.WriteLine("CreateGeom:");
1363#endif
1364 if (mesh != null)
1328 { 1365 {
1329 setMesh(_parent_scene, _mesh); 1366 setMesh(_parent_scene, mesh);
1330 } 1367 }
1331 else 1368 else
1332 { 1369 {
@@ -1399,6 +1436,39 @@ Console.WriteLine("ProcessTaints for " + Name);
1399 } 1436 }
1400 } 1437 }
1401 1438
1439 /// <summary>
1440 /// Remove the existing geom from this prim.
1441 /// </summary>
1442 /// <param name="m_targetSpace"></param>
1443 /// <param name="mesh">If null, then a mesh is used that is based on the profile shape data.</param>
1444 /// <returns>true if the geom was successfully removed, false if it was already gone or the remove failed.</returns>
1445 public bool RemoveGeom()
1446 {
1447 if (prim_geom != IntPtr.Zero)
1448 {
1449 try
1450 {
1451 _parent_scene.geom_name_map.Remove(prim_geom);
1452 _parent_scene.actor_name_map.Remove(prim_geom);
1453 d.GeomDestroy(prim_geom);
1454 prim_geom = IntPtr.Zero;
1455 }
1456 catch (System.AccessViolationException)
1457 {
1458 prim_geom = IntPtr.Zero;
1459 m_log.ErrorFormat("[PHYSICS]: PrimGeom dead for {0}", Name);
1460
1461 return false;
1462 }
1463
1464 return true;
1465 }
1466 else
1467 {
1468 return false;
1469 }
1470 }
1471
1402 public void changeadd(float timestep) 1472 public void changeadd(float timestep)
1403 { 1473 {
1404 int[] iprimspaceArrItem = _parent_scene.calculateSpaceArrayItemFromPos(_position); 1474 int[] iprimspaceArrItem = _parent_scene.calculateSpaceArrayItemFromPos(_position);
@@ -1409,15 +1479,14 @@ Console.WriteLine("ProcessTaints for " + Name);
1409 1479
1410 m_targetSpace = targetspace; 1480 m_targetSpace = targetspace;
1411 1481
1412 if (_mesh == null) 1482 IMesh mesh = null;
1483
1484 if (_parent_scene.needsMeshing(_pbs))
1413 { 1485 {
1414 if (_parent_scene.needsMeshing(_pbs)) 1486 // Don't need to re-enable body.. it's done in SetMesh
1415 { 1487 mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical);
1416 // Don't need to re-enable body.. it's done in SetMesh 1488 // createmesh returns null when it's a shape that isn't a cube.
1417 _mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical); 1489 // m_log.Debug(m_localID);
1418 // createmesh returns null when it's a shape that isn't a cube.
1419 // m_log.Debug(m_localID);
1420 }
1421 } 1490 }
1422 1491
1423 lock (_parent_scene.OdeLock) 1492 lock (_parent_scene.OdeLock)
@@ -1425,7 +1494,7 @@ Console.WriteLine("ProcessTaints for " + Name);
1425#if SPAM 1494#if SPAM
1426Console.WriteLine("changeadd 1"); 1495Console.WriteLine("changeadd 1");
1427#endif 1496#endif
1428 CreateGeom(m_targetSpace, _mesh); 1497 CreateGeom(m_targetSpace, mesh);
1429 1498
1430 if (prim_geom != IntPtr.Zero) 1499 if (prim_geom != IntPtr.Zero)
1431 { 1500 {
@@ -1438,15 +1507,12 @@ Console.WriteLine("changeadd 1");
1438 d.GeomSetQuaternion(prim_geom, ref myrot); 1507 d.GeomSetQuaternion(prim_geom, ref myrot);
1439 } 1508 }
1440 1509
1441 if (m_isphysical && Body == IntPtr.Zero) 1510 if (IsPhysical && Body == IntPtr.Zero)
1442 { 1511 {
1443 enableBody(); 1512 enableBody();
1444 } 1513 }
1445 } 1514 }
1446 1515
1447 _parent_scene.geom_name_map[prim_geom] = this.Name;
1448 _parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this;
1449
1450 changeSelectedStatus(timestep); 1516 changeSelectedStatus(timestep);
1451 1517
1452 m_taintadd = false; 1518 m_taintadd = false;
@@ -1454,9 +1520,8 @@ Console.WriteLine("changeadd 1");
1454 1520
1455 public void changemove(float timestep) 1521 public void changemove(float timestep)
1456 { 1522 {
1457 if (m_isphysical) 1523 if (IsPhysical)
1458 { 1524 {
1459
1460 if (!m_disabled && !m_taintremove && !childPrim) 1525 if (!m_disabled && !m_taintremove && !childPrim)
1461 { 1526 {
1462 if (Body == IntPtr.Zero) 1527 if (Body == IntPtr.Zero)
@@ -1788,7 +1853,7 @@ Console.WriteLine(" JointCreateFixed");
1788 { 1853 {
1789 // KF: If this is a root prim do BodySet 1854 // KF: If this is a root prim do BodySet
1790 d.BodySetQuaternion(Body, ref myrot); 1855 d.BodySetQuaternion(Body, ref myrot);
1791 if (m_isphysical) 1856 if (IsPhysical)
1792 { 1857 {
1793 if (!m_angularlock.ApproxEquals(Vector3.One, 0f)) 1858 if (!m_angularlock.ApproxEquals(Vector3.One, 0f))
1794 createAMotor(m_angularlock); 1859 createAMotor(m_angularlock);
@@ -1825,7 +1890,7 @@ Console.WriteLine(" JointCreateFixed");
1825 1890
1826 public void changePhysicsStatus(float timestep) 1891 public void changePhysicsStatus(float timestep)
1827 { 1892 {
1828 if (m_isphysical == true) 1893 if (IsPhysical)
1829 { 1894 {
1830 if (Body == IntPtr.Zero) 1895 if (Body == IntPtr.Zero)
1831 { 1896 {
@@ -1845,25 +1910,12 @@ Console.WriteLine(" JointCreateFixed");
1845 { 1910 {
1846 if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim) 1911 if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim)
1847 { 1912 {
1848 1913 RemoveGeom();
1849 1914
1850 if (prim_geom != IntPtr.Zero)
1851 {
1852 try
1853 {
1854 d.GeomDestroy(prim_geom);
1855 prim_geom = IntPtr.Zero;
1856 _mesh = null;
1857 }
1858 catch (System.AccessViolationException)
1859 {
1860 prim_geom = IntPtr.Zero;
1861 m_log.ErrorFormat("[PHYSICS]: PrimGeom dead for {0}", Name);
1862 }
1863 }
1864//Console.WriteLine("changePhysicsStatus for " + Name); 1915//Console.WriteLine("changePhysicsStatus for " + Name);
1865 changeadd(2f); 1916 changeadd(2f);
1866 } 1917 }
1918
1867 if (childPrim) 1919 if (childPrim)
1868 { 1920 {
1869 if (_parent != null) 1921 if (_parent != null)
@@ -1882,7 +1934,7 @@ Console.WriteLine(" JointCreateFixed");
1882 changeSelectedStatus(timestep); 1934 changeSelectedStatus(timestep);
1883 1935
1884 resetCollisionAccounting(); 1936 resetCollisionAccounting();
1885 m_taintPhysics = m_isphysical; 1937 m_taintPhysics = IsPhysical;
1886 } 1938 }
1887 1939
1888 public void changesize(float timestamp) 1940 public void changesize(float timestamp)
@@ -1891,18 +1943,10 @@ Console.WriteLine(" JointCreateFixed");
1891 m_log.DebugFormat("[ODE PRIM]: Called changesize"); 1943 m_log.DebugFormat("[ODE PRIM]: Called changesize");
1892#endif 1944#endif
1893 1945
1894 string oldname = _parent_scene.geom_name_map[prim_geom];
1895
1896 if (_size.X <= 0) _size.X = 0.01f; 1946 if (_size.X <= 0) _size.X = 0.01f;
1897 if (_size.Y <= 0) _size.Y = 0.01f; 1947 if (_size.Y <= 0) _size.Y = 0.01f;
1898 if (_size.Z <= 0) _size.Z = 0.01f; 1948 if (_size.Z <= 0) _size.Z = 0.01f;
1899 1949
1900 // Cleanup of old prim geometry
1901 if (_mesh != null)
1902 {
1903 // TODO: Cleanup meshing here
1904 }
1905
1906 //kill body to rebuild 1950 //kill body to rebuild
1907 if (IsPhysical && Body != IntPtr.Zero) 1951 if (IsPhysical && Body != IntPtr.Zero)
1908 { 1952 {
@@ -1926,10 +1970,12 @@ Console.WriteLine(" JointCreateFixed");
1926 d.SpaceRemove(m_targetSpace, prim_geom); 1970 d.SpaceRemove(m_targetSpace, prim_geom);
1927 } 1971 }
1928 1972
1929 d.GeomDestroy(prim_geom); 1973 RemoveGeom();
1930 prim_geom = IntPtr.Zero; 1974
1931 // we don't need to do space calculation because the client sends a position update also. 1975 // we don't need to do space calculation because the client sends a position update also.
1932 1976
1977 IMesh mesh = null;
1978
1933 // Construction of new prim 1979 // Construction of new prim
1934 if (_parent_scene.needsMeshing(_pbs)) 1980 if (_parent_scene.needsMeshing(_pbs))
1935 { 1981 {
@@ -1939,28 +1985,11 @@ Console.WriteLine(" JointCreateFixed");
1939 meshlod = _parent_scene.MeshSculptphysicalLOD; 1985 meshlod = _parent_scene.MeshSculptphysicalLOD;
1940 // Don't need to re-enable body.. it's done in SetMesh 1986 // Don't need to re-enable body.. it's done in SetMesh
1941 1987
1942 IMesh mesh = null;
1943
1944 if (_parent_scene.needsMeshing(_pbs)) 1988 if (_parent_scene.needsMeshing(_pbs))
1945 mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); 1989 mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, meshlod, IsPhysical);
1946
1947 //IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical);
1948#if SPAM
1949Console.WriteLine("changesize 1");
1950#endif
1951 CreateGeom(m_targetSpace, mesh);
1952 }
1953 else
1954 {
1955 _mesh = null;
1956
1957#if SPAM
1958Console.WriteLine("changesize 2");
1959#endif
1960
1961 CreateGeom(m_targetSpace, _mesh);
1962 } 1990 }
1963 1991
1992 CreateGeom(m_targetSpace, mesh);
1964 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); 1993 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
1965 d.Quaternion myrot = new d.Quaternion(); 1994 d.Quaternion myrot = new d.Quaternion();
1966 myrot.X = _orientation.X; 1995 myrot.X = _orientation.X;
@@ -1978,8 +2007,6 @@ Console.WriteLine("changesize 2");
1978 d.BodyEnable(Body); 2007 d.BodyEnable(Body);
1979 } 2008 }
1980 2009
1981 _parent_scene.geom_name_map[prim_geom] = oldname;
1982
1983 changeSelectedStatus(timestamp); 2010 changeSelectedStatus(timestamp);
1984 if (childPrim) 2011 if (childPrim)
1985 { 2012 {
@@ -2013,8 +2040,6 @@ Console.WriteLine("changesize 2");
2013 2040
2014 public void changeshape(float timestamp) 2041 public void changeshape(float timestamp)
2015 { 2042 {
2016 string oldname = _parent_scene.geom_name_map[prim_geom];
2017
2018 // Cleanup of old prim geometry and Bodies 2043 // Cleanup of old prim geometry and Bodies
2019 if (IsPhysical && Body != IntPtr.Zero) 2044 if (IsPhysical && Body != IntPtr.Zero)
2020 { 2045 {
@@ -2031,23 +2056,17 @@ Console.WriteLine("changesize 2");
2031 disableBody(); 2056 disableBody();
2032 } 2057 }
2033 } 2058 }
2034 try
2035 {
2036 d.GeomDestroy(prim_geom);
2037 }
2038 catch (System.AccessViolationException)
2039 {
2040 prim_geom = IntPtr.Zero;
2041 m_log.ErrorFormat("[PHYSICS]: PrimGeom dead for {0}", Name);
2042 }
2043 2059
2044 prim_geom = IntPtr.Zero; 2060 RemoveGeom();
2061
2045 // we don't need to do space calculation because the client sends a position update also. 2062 // we don't need to do space calculation because the client sends a position update also.
2046 if (_size.X <= 0) _size.X = 0.01f; 2063 if (_size.X <= 0) _size.X = 0.01f;
2047 if (_size.Y <= 0) _size.Y = 0.01f; 2064 if (_size.Y <= 0) _size.Y = 0.01f;
2048 if (_size.Z <= 0) _size.Z = 0.01f; 2065 if (_size.Z <= 0) _size.Z = 0.01f;
2049 // Construction of new prim 2066 // Construction of new prim
2050 2067
2068 IMesh mesh = null;
2069
2051 if (_parent_scene.needsMeshing(_pbs)) 2070 if (_parent_scene.needsMeshing(_pbs))
2052 { 2071 {
2053 // Don't need to re-enable body.. it's done in CreateMesh 2072 // Don't need to re-enable body.. it's done in CreateMesh
@@ -2056,23 +2075,11 @@ Console.WriteLine("changesize 2");
2056 if (IsPhysical) 2075 if (IsPhysical)
2057 meshlod = _parent_scene.MeshSculptphysicalLOD; 2076 meshlod = _parent_scene.MeshSculptphysicalLOD;
2058 2077
2059 IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical);
2060 // createmesh returns null when it doesn't mesh. 2078 // createmesh returns null when it doesn't mesh.
2061#if SPAM 2079 mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, meshlod, IsPhysical);
2062Console.WriteLine("changeshape needed meshing");
2063#endif
2064 CreateGeom(m_targetSpace, mesh);
2065 }
2066 else
2067 {
2068 _mesh = null;
2069
2070#if SPAM
2071Console.WriteLine("changeshape not need meshing");
2072#endif
2073 CreateGeom(m_targetSpace, null);
2074 } 2080 }
2075 2081
2082 CreateGeom(m_targetSpace, mesh);
2076 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); 2083 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
2077 d.Quaternion myrot = new d.Quaternion(); 2084 d.Quaternion myrot = new d.Quaternion();
2078 //myrot.W = _orientation.w; 2085 //myrot.W = _orientation.w;
@@ -2093,7 +2100,6 @@ Console.WriteLine("changeshape not need meshing");
2093 d.BodyEnable(Body); 2100 d.BodyEnable(Body);
2094 } 2101 }
2095 } 2102 }
2096 _parent_scene.geom_name_map[prim_geom] = oldname;
2097 2103
2098 changeSelectedStatus(timestamp); 2104 changeSelectedStatus(timestamp);
2099 if (childPrim) 2105 if (childPrim)
@@ -2104,6 +2110,7 @@ Console.WriteLine("changeshape not need meshing");
2104 parent.ChildSetGeom(this); 2110 parent.ChildSetGeom(this);
2105 } 2111 }
2106 } 2112 }
2113
2107 resetCollisionAccounting(); 2114 resetCollisionAccounting();
2108 m_taintshape = false; 2115 m_taintshape = false;
2109 } 2116 }
@@ -2215,16 +2222,6 @@ Console.WriteLine("changeshape not need meshing");
2215 m_taintVelocity = Vector3.Zero; 2222 m_taintVelocity = Vector3.Zero;
2216 } 2223 }
2217 2224
2218 public override bool IsPhysical
2219 {
2220 get { return m_isphysical; }
2221 set {
2222 m_isphysical = value;
2223 if (!m_isphysical) // Zero the remembered last velocity
2224 m_lastVelocity = Vector3.Zero;
2225 }
2226 }
2227
2228 public void setPrimForRemoval() 2225 public void setPrimForRemoval()
2229 { 2226 {
2230 m_taintremove = true; 2227 m_taintremove = true;
@@ -2283,6 +2280,7 @@ Console.WriteLine("changeshape not need meshing");
2283 if (value.IsFinite()) 2280 if (value.IsFinite())
2284 { 2281 {
2285 _size = value; 2282 _size = value;
2283// m_log.DebugFormat("[PHYSICS]: Set size on {0} to {1}", Name, value);
2286 } 2284 }
2287 else 2285 else
2288 { 2286 {
@@ -2343,7 +2341,7 @@ Console.WriteLine("changeshape not need meshing");
2343 { 2341 {
2344 lock (_parent_scene.OdeLock) 2342 lock (_parent_scene.OdeLock)
2345 { 2343 {
2346 m_isVolumeDetect = (param!=0); 2344 m_isVolumeDetect = (param != 0);
2347 } 2345 }
2348 } 2346 }
2349 2347
@@ -2402,7 +2400,7 @@ Console.WriteLine("changeshape not need meshing");
2402 { 2400 {
2403 get 2401 get
2404 { 2402 {
2405 if (!m_isphysical || Body == IntPtr.Zero) 2403 if (!IsPhysical || Body == IntPtr.Zero)
2406 return Vector3.Zero; 2404 return Vector3.Zero;
2407 2405
2408 return _torque; 2406 return _torque;
@@ -2984,12 +2982,12 @@ Console.WriteLine("changeshape not need meshing");
2984 public override void SubscribeEvents(int ms) 2982 public override void SubscribeEvents(int ms)
2985 { 2983 {
2986 m_eventsubscription = ms; 2984 m_eventsubscription = ms;
2987 _parent_scene.addCollisionEventReporting(this); 2985 _parent_scene.AddCollisionEventReporting(this);
2988 } 2986 }
2989 2987
2990 public override void UnSubscribeEvents() 2988 public override void UnSubscribeEvents()
2991 { 2989 {
2992 _parent_scene.remCollisionEventReporting(this); 2990 _parent_scene.RemoveCollisionEventReporting(this);
2993 m_eventsubscription = 0; 2991 m_eventsubscription = 0;
2994 } 2992 }
2995 2993
@@ -2997,6 +2995,7 @@ Console.WriteLine("changeshape not need meshing");
2997 { 2995 {
2998 if (CollisionEventsThisFrame == null) 2996 if (CollisionEventsThisFrame == null)
2999 CollisionEventsThisFrame = new CollisionEventUpdate(); 2997 CollisionEventsThisFrame = new CollisionEventUpdate();
2998
3000 CollisionEventsThisFrame.addCollider(CollidedWith, contact); 2999 CollisionEventsThisFrame.addCollider(CollidedWith, contact);
3001 } 3000 }
3002 3001
diff --git a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
index 15ccddc..9d7aa94 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
@@ -45,11 +45,16 @@ namespace OpenSim.Region.Physics.OdePlugin
45 public class ODERayCastRequestManager 45 public class ODERayCastRequestManager
46 { 46 {
47 /// <summary> 47 /// <summary>
48 /// Pending Raycast Requests 48 /// Pending raycast requests
49 /// </summary> 49 /// </summary>
50 protected List<ODERayCastRequest> m_PendingRequests = new List<ODERayCastRequest>(); 50 protected List<ODERayCastRequest> m_PendingRequests = new List<ODERayCastRequest>();
51 51
52 /// <summary> 52 /// <summary>
53 /// Pending ray requests
54 /// </summary>
55 protected List<ODERayRequest> m_PendingRayRequests = new List<ODERayRequest>();
56
57 /// <summary>
53 /// Scene that created this object. 58 /// Scene that created this object.
54 /// </summary> 59 /// </summary>
55 private OdeScene m_scene; 60 private OdeScene m_scene;
@@ -96,6 +101,29 @@ namespace OpenSim.Region.Physics.OdePlugin
96 } 101 }
97 102
98 /// <summary> 103 /// <summary>
104 /// Queues a raycast
105 /// </summary>
106 /// <param name="position">Origin of Ray</param>
107 /// <param name="direction">Ray normal</param>
108 /// <param name="length">Ray length</param>
109 /// <param name="count"></param>
110 /// <param name="retMethod">Return method to send the results</param>
111 public void QueueRequest(Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod)
112 {
113 lock (m_PendingRequests)
114 {
115 ODERayRequest req = new ODERayRequest();
116 req.callbackMethod = retMethod;
117 req.length = length;
118 req.Normal = direction;
119 req.Origin = position;
120 req.Count = count;
121
122 m_PendingRayRequests.Add(req);
123 }
124 }
125
126 /// <summary>
99 /// Process all queued raycast requests 127 /// Process all queued raycast requests
100 /// </summary> 128 /// </summary>
101 /// <returns>Time in MS the raycasts took to process.</returns> 129 /// <returns>Time in MS the raycasts took to process.</returns>
@@ -119,15 +147,23 @@ namespace OpenSim.Region.Physics.OdePlugin
119 //Fail silently 147 //Fail silently
120 } 148 }
121 } 149 }
122 /* 150
123 foreach (ODERayCastRequest req in m_PendingRequests) 151 m_PendingRequests.Clear();
152 }
153 }
154
155 lock (m_PendingRayRequests)
156 {
157 if (m_PendingRayRequests.Count > 0)
158 {
159 ODERayRequest[] reqs = m_PendingRayRequests.ToArray();
160 for (int i = 0; i < reqs.Length; i++)
124 { 161 {
125 if (req.callbackMethod != null) // quick optimization here, don't raycast 162 if (reqs[i].callbackMethod != null) // quick optimization here, don't raycast
126 RayCast(req); // if there isn't anyone to send results to 163 RayCast(reqs[i]); // if there isn't anyone to send results
127
128 } 164 }
129 */ 165
130 m_PendingRequests.Clear(); 166 m_PendingRayRequests.Clear();
131 } 167 }
132 } 168 }
133 169
@@ -153,7 +189,6 @@ namespace OpenSim.Region.Physics.OdePlugin
153 // Remove Ray 189 // Remove Ray
154 d.GeomDestroy(ray); 190 d.GeomDestroy(ray);
155 191
156
157 // Define default results 192 // Define default results
158 bool hitYN = false; 193 bool hitYN = false;
159 uint hitConsumerID = 0; 194 uint hitConsumerID = 0;
@@ -184,6 +219,31 @@ namespace OpenSim.Region.Physics.OdePlugin
184 req.callbackMethod(hitYN, closestcontact, hitConsumerID, distance, snormal); 219 req.callbackMethod(hitYN, closestcontact, hitConsumerID, distance, snormal);
185 } 220 }
186 221
222 /// <summary>
223 /// Method that actually initiates the raycast
224 /// </summary>
225 /// <param name="req"></param>
226 private void RayCast(ODERayRequest req)
227 {
228 // Create the ray
229 IntPtr ray = d.CreateRay(m_scene.space, req.length);
230 d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
231
232 // Collide test
233 d.SpaceCollide2(m_scene.space, ray, IntPtr.Zero, nearCallback);
234
235 // Remove Ray
236 d.GeomDestroy(ray);
237
238 // Find closest contact and object.
239 lock (m_contactResults)
240 {
241 // Return results
242 if (req.callbackMethod != null)
243 req.callbackMethod(m_contactResults);
244 }
245 }
246
187 // This is the standard Near. Uses space AABBs to speed up detection. 247 // This is the standard Near. Uses space AABBs to speed up detection.
188 private void near(IntPtr space, IntPtr g1, IntPtr g2) 248 private void near(IntPtr space, IntPtr g1, IntPtr g2)
189 { 249 {
@@ -349,10 +409,7 @@ namespace OpenSim.Region.Physics.OdePlugin
349 m_contactResults.Add(collisionresult); 409 m_contactResults.Add(collisionresult);
350 } 410 }
351 } 411 }
352
353
354 } 412 }
355
356 } 413 }
357 414
358 /// <summary> 415 /// <summary>
@@ -372,11 +429,12 @@ namespace OpenSim.Region.Physics.OdePlugin
372 public RaycastCallback callbackMethod; 429 public RaycastCallback callbackMethod;
373 } 430 }
374 431
375 public struct ContactResult 432 public struct ODERayRequest
376 { 433 {
377 public Vector3 Pos; 434 public Vector3 Origin;
378 public float Depth;
379 public uint ConsumerID;
380 public Vector3 Normal; 435 public Vector3 Normal;
436 public int Count;
437 public float length;
438 public RayCallback callbackMethod;
381 } 439 }
382} 440} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
index 88902b0..6e603e8 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
@@ -26,7 +26,7 @@
26 */ 26 */
27 27
28//#define USE_DRAWSTUFF 28//#define USE_DRAWSTUFF
29#define SPAM 29//#define SPAM
30 30
31using System; 31using System;
32using System.Collections.Generic; 32using System.Collections.Generic;
@@ -100,7 +100,7 @@ namespace OpenSim.Region.Physics.OdePlugin
100 Rubber = 6 100 Rubber = 6
101 } 101 }
102 102
103 public sealed class OdeScene : PhysicsScene 103 public class OdeScene : PhysicsScene
104 { 104 {
105 private readonly ILog m_log; 105 private readonly ILog m_log;
106 // private Dictionary<string, sCollisionData> m_storedCollisions = new Dictionary<string, sCollisionData>(); 106 // private Dictionary<string, sCollisionData> m_storedCollisions = new Dictionary<string, sCollisionData>();
@@ -198,7 +198,12 @@ namespace OpenSim.Region.Physics.OdePlugin
198 private readonly List<OdePrim> _taintedPrimL = new List<OdePrim>(); 198 private readonly List<OdePrim> _taintedPrimL = new List<OdePrim>();
199 private readonly HashSet<OdeCharacter> _taintedActors = new HashSet<OdeCharacter>(); 199 private readonly HashSet<OdeCharacter> _taintedActors = new HashSet<OdeCharacter>();
200 private readonly List<d.ContactGeom> _perloopContact = new List<d.ContactGeom>(); 200 private readonly List<d.ContactGeom> _perloopContact = new List<d.ContactGeom>();
201
202 /// <summary>
203 /// A list of actors that should receive collision events.
204 /// </summary>
201 private readonly List<PhysicsActor> _collisionEventPrim = new List<PhysicsActor>(); 205 private readonly List<PhysicsActor> _collisionEventPrim = new List<PhysicsActor>();
206
202 private readonly HashSet<OdeCharacter> _badCharacter = new HashSet<OdeCharacter>(); 207 private readonly HashSet<OdeCharacter> _badCharacter = new HashSet<OdeCharacter>();
203 public Dictionary<IntPtr, String> geom_name_map = new Dictionary<IntPtr, String>(); 208 public Dictionary<IntPtr, String> geom_name_map = new Dictionary<IntPtr, String>();
204 public Dictionary<IntPtr, PhysicsActor> actor_name_map = new Dictionary<IntPtr, PhysicsActor>(); 209 public Dictionary<IntPtr, PhysicsActor> actor_name_map = new Dictionary<IntPtr, PhysicsActor>();
@@ -299,7 +304,6 @@ namespace OpenSim.Region.Physics.OdePlugin
299 // Create the world and the first space 304 // Create the world and the first space
300 world = d.WorldCreate(); 305 world = d.WorldCreate();
301 space = d.HashSpaceCreate(IntPtr.Zero); 306 space = d.HashSpaceCreate(IntPtr.Zero);
302
303 307
304 contactgroup = d.JointGroupCreate(0); 308 contactgroup = d.JointGroupCreate(0);
305 //contactgroup 309 //contactgroup
@@ -952,7 +956,6 @@ namespace OpenSim.Region.Physics.OdePlugin
952 character.SetPidStatus(true); 956 character.SetPidStatus(true);
953 } 957 }
954 } 958 }
955
956 959
957 if (p1.PhysicsActorType == (int) ActorTypes.Agent) 960 if (p1.PhysicsActorType == (int) ActorTypes.Agent)
958 { 961 {
@@ -1053,9 +1056,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1053 { 1056 {
1054 joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); 1057 joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]);
1055 m_global_contactcount++; 1058 m_global_contactcount++;
1056
1057 } 1059 }
1058
1059 } 1060 }
1060 else 1061 else
1061 { 1062 {
@@ -1078,7 +1079,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1078 { 1079 {
1079 joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); 1080 joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]);
1080 m_global_contactcount++; 1081 m_global_contactcount++;
1081
1082 } 1082 }
1083 } 1083 }
1084 } 1084 }
@@ -1290,6 +1290,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1290 1290
1291 //returncollisions = true; 1291 //returncollisions = true;
1292 break; 1292 break;
1293
1293 case ActorTypes.Prim: 1294 case ActorTypes.Prim:
1294 if (p1 is OdePrim) 1295 if (p1 is OdePrim)
1295 { 1296 {
@@ -1317,6 +1318,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1317 1318
1318 cc2.AddCollisionEvent(obj2LocalID, contact); 1319 cc2.AddCollisionEvent(obj2LocalID, contact);
1319 break; 1320 break;
1321
1320 case ActorTypes.Prim: 1322 case ActorTypes.Prim:
1321 1323
1322 if (p2 is OdePrim) 1324 if (p2 is OdePrim)
@@ -1421,18 +1423,18 @@ namespace OpenSim.Region.Physics.OdePlugin
1421 1423
1422 public int TriCallback(IntPtr trimesh, IntPtr refObject, int triangleIndex) 1424 public int TriCallback(IntPtr trimesh, IntPtr refObject, int triangleIndex)
1423 { 1425 {
1424 String name1 = null; 1426// String name1 = null;
1425 String name2 = null; 1427// String name2 = null;
1426 1428//
1427 if (!geom_name_map.TryGetValue(trimesh, out name1)) 1429// if (!geom_name_map.TryGetValue(trimesh, out name1))
1428 { 1430// {
1429 name1 = "null"; 1431// name1 = "null";
1430 } 1432// }
1431 1433//
1432 if (!geom_name_map.TryGetValue(refObject, out name2)) 1434// if (!geom_name_map.TryGetValue(refObject, out name2))
1433 { 1435// {
1434 name2 = "null"; 1436// name2 = "null";
1435 } 1437// }
1436 1438
1437 // m_log.InfoFormat("TriCallback: A collision was detected between {1} and {2}. Index was {3}", 0, name1, name2, triangleIndex); 1439 // m_log.InfoFormat("TriCallback: A collision was detected between {1} and {2}. Index was {3}", 0, name1, name2, triangleIndex);
1438 1440
@@ -1604,7 +1606,11 @@ namespace OpenSim.Region.Physics.OdePlugin
1604 } 1606 }
1605// End recovered. Kitto Flora 1607// End recovered. Kitto Flora
1606 1608
1607 public void addCollisionEventReporting(PhysicsActor obj) 1609 /// <summary>
1610 /// Add actor to the list that should receive collision events in the simulate loop.
1611 /// </summary>
1612 /// <param name="obj"></param>
1613 public void AddCollisionEventReporting(PhysicsActor obj)
1608 { 1614 {
1609 lock (_collisionEventPrim) 1615 lock (_collisionEventPrim)
1610 { 1616 {
@@ -1613,7 +1619,11 @@ namespace OpenSim.Region.Physics.OdePlugin
1613 } 1619 }
1614 } 1620 }
1615 1621
1616 public void remCollisionEventReporting(PhysicsActor obj) 1622 /// <summary>
1623 /// Remove actor from the list that should receive collision events in the simulate loop.
1624 /// </summary>
1625 /// <param name="obj"></param>
1626 public void RemoveCollisionEventReporting(PhysicsActor obj)
1617 { 1627 {
1618 lock (_collisionEventPrim) 1628 lock (_collisionEventPrim)
1619 { 1629 {
@@ -1677,7 +1687,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1677 } 1687 }
1678 1688
1679 private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation, 1689 private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation,
1680 IMesh mesh, PrimitiveBaseShape pbs, bool isphysical) 1690 PrimitiveBaseShape pbs, bool isphysical, uint localID)
1681 { 1691 {
1682 Vector3 pos = position; 1692 Vector3 pos = position;
1683 Vector3 siz = size; 1693 Vector3 siz = size;
@@ -1686,12 +1696,12 @@ namespace OpenSim.Region.Physics.OdePlugin
1686 OdePrim newPrim; 1696 OdePrim newPrim;
1687 lock (OdeLock) 1697 lock (OdeLock)
1688 { 1698 {
1689 newPrim = new OdePrim(name, this, pos, siz, rot, mesh, pbs, isphysical, ode); 1699 newPrim = new OdePrim(name, this, pos, siz, rot, pbs, isphysical, ode);
1690 1700
1691 lock (_prims) 1701 lock (_prims)
1692 _prims.Add(newPrim); 1702 _prims.Add(newPrim);
1693 } 1703 }
1694 1704 newPrim.LocalID = localID;
1695 return newPrim; 1705 return newPrim;
1696 } 1706 }
1697 1707
@@ -1714,27 +1724,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1714 m_log.DebugFormat("[PHYSICS]: Adding physics actor to {0}", primName); 1724 m_log.DebugFormat("[PHYSICS]: Adding physics actor to {0}", primName);
1715#endif 1725#endif
1716 1726
1717 PhysicsActor result; 1727 return AddPrim(primName, position, size, rotation, pbs, isPhysical, localid);
1718 IMesh mesh = null;
1719
1720 if (needsMeshing(pbs))
1721 {
1722 try
1723 {
1724 mesh = mesher.CreateMesh(primName, pbs, size, 32f, isPhysical);
1725 }
1726 catch(Exception e)
1727 {
1728 m_log.ErrorFormat("[PHYSICS]: Exception while meshing prim {0}.", primName);
1729 m_log.Debug(e.ToString());
1730 mesh = null;
1731 return null;
1732 }
1733 }
1734
1735 result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical);
1736
1737 return result;
1738 } 1728 }
1739 1729
1740 public override float TimeDilation 1730 public override float TimeDilation
@@ -2104,6 +2094,8 @@ namespace OpenSim.Region.Physics.OdePlugin
2104 2094
2105 public override void RemovePrim(PhysicsActor prim) 2095 public override void RemovePrim(PhysicsActor prim)
2106 { 2096 {
2097 // As with all ODE physics operations, we don't remove the prim immediately but signal that it should be
2098 // removed in the next physics simulate pass.
2107 if (prim is OdePrim) 2099 if (prim is OdePrim)
2108 { 2100 {
2109 lock (OdeLock) 2101 lock (OdeLock)
@@ -2120,6 +2112,9 @@ namespace OpenSim.Region.Physics.OdePlugin
2120 /// <summary> 2112 /// <summary>
2121 /// This is called from within simulate but outside the locked portion 2113 /// This is called from within simulate but outside the locked portion
2122 /// We need to do our own locking here 2114 /// We need to do our own locking here
2115 /// (Note: As of 20110801 this no longer appears to be true - this is being called within lock (odeLock) in
2116 /// Simulate() -- justincc).
2117 ///
2123 /// Essentially, we need to remove the prim from our space segment, whatever segment it's in. 2118 /// Essentially, we need to remove the prim from our space segment, whatever segment it's in.
2124 /// 2119 ///
2125 /// If there are no more prim in the segment, we need to empty (spacedestroy)the segment and reclaim memory 2120 /// If there are no more prim in the segment, we need to empty (spacedestroy)the segment and reclaim memory
@@ -2131,7 +2126,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2131//Console.WriteLine("RemovePrimThreadLocked " + prim.m_primName); 2126//Console.WriteLine("RemovePrimThreadLocked " + prim.m_primName);
2132 lock (prim) 2127 lock (prim)
2133 { 2128 {
2134 remCollisionEventReporting(prim); 2129 RemoveCollisionEventReporting(prim);
2135 lock (ode) 2130 lock (ode)
2136 { 2131 {
2137 if (prim.prim_geom != IntPtr.Zero) 2132 if (prim.prim_geom != IntPtr.Zero)
@@ -2176,24 +2171,12 @@ namespace OpenSim.Region.Physics.OdePlugin
2176 //} 2171 //}
2177 //} 2172 //}
2178 //m_log.Warn(prim.prim_geom); 2173 //m_log.Warn(prim.prim_geom);
2179 try 2174
2180 { 2175 if (!prim.RemoveGeom())
2181 if (prim.prim_geom != IntPtr.Zero) 2176 m_log.Warn("[PHYSICS]: Unable to remove prim from physics scene");
2182 { 2177
2183 d.GeomDestroy(prim.prim_geom);
2184 prim.prim_geom = IntPtr.Zero;
2185 }
2186 else
2187 {
2188 m_log.Warn("[PHYSICS]: Unable to remove prim from physics scene");
2189 }
2190 }
2191 catch (AccessViolationException)
2192 {
2193 m_log.Info("[PHYSICS]: Couldn't remove prim from physics scene, it was already be removed.");
2194 }
2195 lock (_prims) 2178 lock (_prims)
2196 _prims.Remove(prim); 2179 _prims.Remove(prim);
2197 2180
2198 //If there are no more geometries in the sub-space, we don't need it in the main space anymore 2181 //If there are no more geometries in the sub-space, we don't need it in the main space anymore
2199 //if (d.SpaceGetNumGeoms(prim.m_targetSpace) == 0) 2182 //if (d.SpaceGetNumGeoms(prim.m_targetSpace) == 0)
@@ -2584,7 +2567,9 @@ namespace OpenSim.Region.Physics.OdePlugin
2584 { 2567 {
2585 if (!(_taintedPrimH.Contains(taintedprim))) 2568 if (!(_taintedPrimH.Contains(taintedprim)))
2586 { 2569 {
2587//Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.m_primName); 2570#if SPAM
2571Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
2572#endif
2588 _taintedPrimH.Add(taintedprim); // HashSet for searching 2573 _taintedPrimH.Add(taintedprim); // HashSet for searching
2589 _taintedPrimL.Add(taintedprim); // List for ordered readout 2574 _taintedPrimL.Add(taintedprim); // List for ordered readout
2590 } 2575 }
@@ -2684,320 +2669,148 @@ namespace OpenSim.Region.Physics.OdePlugin
2684 //if (!ode.lockquery()) 2669 //if (!ode.lockquery())
2685 //{ 2670 //{
2686 // ode.dlock(world); 2671 // ode.dlock(world);
2687 try
2688 {
2689 // Insert, remove Characters
2690 bool processedtaints = false;
2691 2672
2692 lock (_taintedActors) 2673 try
2693 { 2674 {
2694 if (_taintedActors.Count > 0) 2675 // Insert, remove Characters
2695 { 2676 bool processedtaints = false;
2696 foreach (OdeCharacter character in _taintedActors)
2697 {
2698 character.ProcessTaints(timeStep);
2699 2677
2700 processedtaints = true; 2678 lock (_taintedActors)
2701 //character.m_collisionscore = 0; 2679 {
2702 } 2680 if (_taintedActors.Count > 0)
2681 {
2682 foreach (OdeCharacter character in _taintedActors)
2683 {
2684 character.ProcessTaints(timeStep);
2703 2685
2704 if (processedtaints) 2686 processedtaints = true;
2705 _taintedActors.Clear(); 2687 //character.m_collisionscore = 0;
2706 }
2707 } 2688 }
2708 2689
2709 // Modify other objects in the scene. 2690 if (processedtaints)
2710 processedtaints = false; 2691 _taintedActors.Clear();
2692 }
2693 }
2694
2695 // Modify other objects in the scene.
2696 processedtaints = false;
2711 2697
2712 lock (_taintedPrimLock) 2698 lock (_taintedPrimLock)
2699 {
2700 foreach (OdePrim prim in _taintedPrimL)
2701 {
2702 if (prim.m_taintremove)
2713 { 2703 {
2714 foreach (OdePrim prim in _taintedPrimL) 2704// Console.WriteLine("Simulate calls RemovePrimThreadLocked for {0}", prim.Name);
2715 { 2705 RemovePrimThreadLocked(prim);
2716 if (prim.m_taintremove) 2706 }
2717 { 2707 else
2718 //Console.WriteLine("Simulate calls RemovePrimThreadLocked"); 2708 {
2719 RemovePrimThreadLocked(prim); 2709// Console.WriteLine("Simulate calls ProcessTaints for {0}", prim.Name);
2720 } 2710 prim.ProcessTaints(timeStep);
2721 else 2711 }
2722 {
2723 //Console.WriteLine("Simulate calls ProcessTaints");
2724 prim.ProcessTaints(timeStep);
2725 }
2726 processedtaints = true;
2727 prim.m_collisionscore = 0;
2728
2729 // This loop can block up the Heartbeat for a very long time on large regions.
2730 // We need to let the Watchdog know that the Heartbeat is not dead
2731 // NOTE: This is currently commented out, but if things like OAR loading are
2732 // timing the heartbeat out we will need to uncomment it
2733 //Watchdog.UpdateThread();
2734 }
2735 2712
2736 if (SupportsNINJAJoints) 2713 processedtaints = true;
2737 { 2714 prim.m_collisionscore = 0;
2738 // Create pending joints, if possible
2739 2715
2740 // joints can only be processed after ALL bodies are processed (and exist in ODE), since creating 2716 // This loop can block up the Heartbeat for a very long time on large regions.
2741 // a joint requires specifying the body id of both involved bodies 2717 // We need to let the Watchdog know that the Heartbeat is not dead
2742 if (pendingJoints.Count > 0) 2718 // NOTE: This is currently commented out, but if things like OAR loading are
2743 { 2719 // timing the heartbeat out we will need to uncomment it
2744 List<PhysicsJoint> successfullyProcessedPendingJoints = new List<PhysicsJoint>(); 2720 //Watchdog.UpdateThread();
2745 //DoJointErrorMessage(joints_connecting_actor, "taint: " + pendingJoints.Count + " pending joints"); 2721 }
2746 foreach (PhysicsJoint joint in pendingJoints) 2722
2747 { 2723 if (SupportsNINJAJoints)
2748 //DoJointErrorMessage(joint, "taint: time to create joint with parms: " + joint.RawParams); 2724 SimulatePendingNINJAJoints();
2749 string[] jointParams = joint.RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries);
2750 List<IntPtr> jointBodies = new List<IntPtr>();
2751 bool allJointBodiesAreReady = true;
2752 foreach (string jointParam in jointParams)
2753 {
2754 if (jointParam == "NULL")
2755 {
2756 //DoJointErrorMessage(joint, "attaching NULL joint to world");
2757 jointBodies.Add(IntPtr.Zero);
2758 }
2759 else
2760 {
2761 //DoJointErrorMessage(joint, "looking for prim name: " + jointParam);
2762 bool foundPrim = false;
2763 lock (_prims)
2764 {
2765 foreach (OdePrim prim in _prims) // FIXME: inefficient
2766 {
2767 if (prim.SOPName == jointParam)
2768 {
2769 //DoJointErrorMessage(joint, "found for prim name: " + jointParam);
2770 if (prim.IsPhysical && prim.Body != IntPtr.Zero)
2771 {
2772 jointBodies.Add(prim.Body);
2773 foundPrim = true;
2774 break;
2775 }
2776 else
2777 {
2778 DoJointErrorMessage(joint, "prim name " + jointParam +
2779 " exists but is not (yet) physical; deferring joint creation. " +
2780 "IsPhysical property is " + prim.IsPhysical +
2781 " and body is " + prim.Body);
2782 foundPrim = false;
2783 break;
2784 }
2785 }
2786 }
2787 }
2788 if (foundPrim)
2789 {
2790 // all is fine
2791 }
2792 else
2793 {
2794 allJointBodiesAreReady = false;
2795 break;
2796 }
2797 }
2798 }
2799 if (allJointBodiesAreReady)
2800 {
2801 //DoJointErrorMessage(joint, "allJointBodiesAreReady for " + joint.ObjectNameInScene + " with parms " + joint.RawParams);
2802 if (jointBodies[0] == jointBodies[1])
2803 {
2804 DoJointErrorMessage(joint, "ERROR: joint cannot be created; the joint bodies are the same, body1==body2. Raw body is " + jointBodies[0] + ". raw parms: " + joint.RawParams);
2805 }
2806 else
2807 {
2808 switch (joint.Type)
2809 {
2810 case PhysicsJointType.Ball:
2811 {
2812 IntPtr odeJoint;
2813 //DoJointErrorMessage(joint, "ODE creating ball joint ");
2814 odeJoint = d.JointCreateBall(world, IntPtr.Zero);
2815 //DoJointErrorMessage(joint, "ODE attaching ball joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]);
2816 d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]);
2817 //DoJointErrorMessage(joint, "ODE setting ball anchor: " + odeJoint + " to vec:" + joint.Position);
2818 d.JointSetBallAnchor(odeJoint,
2819 joint.Position.X,
2820 joint.Position.Y,
2821 joint.Position.Z);
2822 //DoJointErrorMessage(joint, "ODE joint setting OK");
2823 //DoJointErrorMessage(joint, "The ball joint's bodies are here: b0: ");
2824 //DoJointErrorMessage(joint, "" + (jointBodies[0] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[0]) : "fixed environment"));
2825 //DoJointErrorMessage(joint, "The ball joint's bodies are here: b1: ");
2826 //DoJointErrorMessage(joint, "" + (jointBodies[1] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[1]) : "fixed environment"));
2827
2828 if (joint is OdePhysicsJoint)
2829 {
2830 ((OdePhysicsJoint)joint).jointID = odeJoint;
2831 }
2832 else
2833 {
2834 DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!");
2835 }
2836 }
2837 break;
2838 case PhysicsJointType.Hinge:
2839 {
2840 IntPtr odeJoint;
2841 //DoJointErrorMessage(joint, "ODE creating hinge joint ");
2842 odeJoint = d.JointCreateHinge(world, IntPtr.Zero);
2843 //DoJointErrorMessage(joint, "ODE attaching hinge joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]);
2844 d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]);
2845 //DoJointErrorMessage(joint, "ODE setting hinge anchor: " + odeJoint + " to vec:" + joint.Position);
2846 d.JointSetHingeAnchor(odeJoint,
2847 joint.Position.X,
2848 joint.Position.Y,
2849 joint.Position.Z);
2850 // We use the orientation of the x-axis of the joint's coordinate frame
2851 // as the axis for the hinge.
2852
2853 // Therefore, we must get the joint's coordinate frame based on the
2854 // joint.Rotation field, which originates from the orientation of the
2855 // joint's proxy object in the scene.
2856
2857 // The joint's coordinate frame is defined as the transformation matrix
2858 // that converts a vector from joint-local coordinates into world coordinates.
2859 // World coordinates are defined as the XYZ coordinate system of the sim,
2860 // as shown in the top status-bar of the viewer.
2861
2862 // Once we have the joint's coordinate frame, we extract its X axis (AtAxis)
2863 // and use that as the hinge axis.
2864
2865 //joint.Rotation.Normalize();
2866 Matrix4 proxyFrame = Matrix4.CreateFromQuaternion(joint.Rotation);
2867
2868 // Now extract the X axis of the joint's coordinate frame.
2869
2870 // Do not try to use proxyFrame.AtAxis or you will become mired in the
2871 // tar pit of transposed, inverted, and generally messed-up orientations.
2872 // (In other words, Matrix4.AtAxis() is borked.)
2873 // Vector3 jointAxis = proxyFrame.AtAxis; <--- this path leadeth to madness
2874
2875 // Instead, compute the X axis of the coordinate frame by transforming
2876 // the (1,0,0) vector. At least that works.
2877
2878 //m_log.Debug("PHY: making axis: complete matrix is " + proxyFrame);
2879 Vector3 jointAxis = Vector3.Transform(Vector3.UnitX, proxyFrame);
2880 //m_log.Debug("PHY: making axis: hinge joint axis is " + jointAxis);
2881 //DoJointErrorMessage(joint, "ODE setting hinge axis: " + odeJoint + " to vec:" + jointAxis);
2882 d.JointSetHingeAxis(odeJoint,
2883 jointAxis.X,
2884 jointAxis.Y,
2885 jointAxis.Z);
2886 //d.JointSetHingeParam(odeJoint, (int)dParam.CFM, 0.1f);
2887 if (joint is OdePhysicsJoint)
2888 {
2889 ((OdePhysicsJoint)joint).jointID = odeJoint;
2890 }
2891 else
2892 {
2893 DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!");
2894 }
2895 }
2896 break;
2897 }
2898 successfullyProcessedPendingJoints.Add(joint);
2899 }
2900 }
2901 else
2902 {
2903 DoJointErrorMessage(joint, "joint could not yet be created; still pending");
2904 }
2905 }
2906 foreach (PhysicsJoint successfullyProcessedJoint in successfullyProcessedPendingJoints)
2907 {
2908 //DoJointErrorMessage(successfullyProcessedJoint, "finalizing succesfully procsssed joint " + successfullyProcessedJoint.ObjectNameInScene + " parms " + successfullyProcessedJoint.RawParams);
2909 //DoJointErrorMessage(successfullyProcessedJoint, "removing from pending");
2910 InternalRemovePendingJoint(successfullyProcessedJoint);
2911 //DoJointErrorMessage(successfullyProcessedJoint, "adding to active");
2912 InternalAddActiveJoint(successfullyProcessedJoint);
2913 //DoJointErrorMessage(successfullyProcessedJoint, "done");
2914 }
2915 }
2916 }
2917 2725
2918 if (processedtaints) 2726 if (processedtaints)
2727 {
2919//Console.WriteLine("Simulate calls Clear of _taintedPrim list"); 2728//Console.WriteLine("Simulate calls Clear of _taintedPrim list");
2920 _taintedPrimH.Clear(); 2729 _taintedPrimH.Clear();
2921 _taintedPrimL.Clear(); 2730 _taintedPrimL.Clear();
2922 } 2731 }
2732 }
2923 2733
2924 // Move characters 2734 // Move characters
2925 lock (_characters) 2735 lock (_characters)
2736 {
2737 List<OdeCharacter> defects = new List<OdeCharacter>();
2738 foreach (OdeCharacter actor in _characters)
2739 {
2740 if (actor != null)
2741 actor.Move(timeStep, defects);
2742 }
2743 if (0 != defects.Count)
2744 {
2745 foreach (OdeCharacter defect in defects)
2926 { 2746 {
2927 List<OdeCharacter> defects = new List<OdeCharacter>(); 2747 RemoveCharacter(defect);
2928 foreach (OdeCharacter actor in _characters)
2929 {
2930 if (actor != null)
2931 actor.Move(timeStep, defects);
2932 }
2933 if (0 != defects.Count)
2934 {
2935 foreach (OdeCharacter defect in defects)
2936 {
2937 RemoveCharacter(defect);
2938 }
2939 }
2940 } 2748 }
2749 }
2750 }
2941 2751
2942 // Move other active objects 2752 // Move other active objects
2943 lock (_activeprims) 2753 lock (_activeprims)
2944 { 2754 {
2945 foreach (OdePrim prim in _activeprims) 2755 foreach (OdePrim prim in _activeprims)
2946 { 2756 {
2947 prim.m_collisionscore = 0; 2757 prim.m_collisionscore = 0;
2948 prim.Move(timeStep); 2758 prim.Move(timeStep);
2949 } 2759 }
2950 } 2760 }
2951 2761
2952 //if ((framecount % m_randomizeWater) == 0) 2762 //if ((framecount % m_randomizeWater) == 0)
2953 // randomizeWater(waterlevel); 2763 // randomizeWater(waterlevel);
2954 2764
2955 //int RayCastTimeMS = m_rayCastManager.ProcessQueuedRequests(); 2765 //int RayCastTimeMS = m_rayCastManager.ProcessQueuedRequests();
2956 m_rayCastManager.ProcessQueuedRequests(); 2766 m_rayCastManager.ProcessQueuedRequests();
2767
2768 collision_optimized(timeStep);
2769
2770 lock (_collisionEventPrim)
2771 {
2772 foreach (PhysicsActor obj in _collisionEventPrim)
2773 {
2774 if (obj == null)
2775 continue;
2957 2776
2958 collision_optimized(timeStep); 2777// m_log.DebugFormat("[PHYSICS]: Assessing {0} for collision events", obj.SOPName);
2959 2778
2960 lock (_collisionEventPrim) 2779 switch ((ActorTypes)obj.PhysicsActorType)
2961 { 2780 {
2962 foreach (PhysicsActor obj in _collisionEventPrim) 2781 case ActorTypes.Agent:
2963 { 2782 OdeCharacter cobj = (OdeCharacter)obj;
2964 if (obj == null) 2783 cobj.AddCollisionFrameTime(100);
2965 continue; 2784 cobj.SendCollisions();
2785 break;
2966 2786
2967 switch ((ActorTypes)obj.PhysicsActorType) 2787 case ActorTypes.Prim:
2968 { 2788 OdePrim pobj = (OdePrim)obj;
2969 case ActorTypes.Agent: 2789 pobj.SendCollisions();
2970 OdeCharacter cobj = (OdeCharacter)obj; 2790 break;
2971 cobj.AddCollisionFrameTime(100);
2972 cobj.SendCollisions();
2973 break;
2974 case ActorTypes.Prim:
2975 OdePrim pobj = (OdePrim)obj;
2976 pobj.SendCollisions();
2977 break;
2978 }
2979 }
2980 } 2791 }
2792 }
2793 }
2981 2794
2982 //if (m_global_contactcount > 5) 2795 //if (m_global_contactcount > 5)
2983 //{ 2796 //{
2984 // m_log.DebugFormat("[PHYSICS]: Contacts:{0}", m_global_contactcount); 2797 // m_log.DebugFormat("[PHYSICS]: Contacts:{0}", m_global_contactcount);
2985 //} 2798 //}
2986 2799
2987 m_global_contactcount = 0; 2800 m_global_contactcount = 0;
2988 2801
2989 d.WorldQuickStep(world, ODE_STEPSIZE); 2802 d.WorldQuickStep(world, ODE_STEPSIZE);
2990 d.JointGroupEmpty(contactgroup); 2803 d.JointGroupEmpty(contactgroup);
2991 //ode.dunlock(world); 2804 //ode.dunlock(world);
2992 } 2805 }
2993 catch (Exception e) 2806 catch (Exception e)
2994 { 2807 {
2995 m_log.ErrorFormat("[PHYSICS]: {0}, {1}, {2}", e.Message, e.TargetSite, e); 2808 m_log.ErrorFormat("[PHYSICS]: {0}, {1}, {2}", e.Message, e.TargetSite, e);
2996 ode.dunlock(world); 2809 ode.dunlock(world);
2997 } 2810 }
2998 2811
2999 step_time -= ODE_STEPSIZE; 2812 step_time -= ODE_STEPSIZE;
3000 i++; 2813 i++;
3001 //} 2814 //}
3002 //else 2815 //else
3003 //{ 2816 //{
@@ -3014,6 +2827,7 @@ namespace OpenSim.Region.Physics.OdePlugin
3014 { 2827 {
3015 if (actor.bad) 2828 if (actor.bad)
3016 m_log.WarnFormat("[PHYSICS]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid); 2829 m_log.WarnFormat("[PHYSICS]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid);
2830
3017 actor.UpdatePositionAndVelocity(); 2831 actor.UpdatePositionAndVelocity();
3018 } 2832 }
3019 } 2833 }
@@ -3027,6 +2841,7 @@ namespace OpenSim.Region.Physics.OdePlugin
3027 { 2841 {
3028 RemoveCharacter(chr); 2842 RemoveCharacter(chr);
3029 } 2843 }
2844
3030 _badCharacter.Clear(); 2845 _badCharacter.Clear();
3031 } 2846 }
3032 } 2847 }
@@ -3042,30 +2857,7 @@ namespace OpenSim.Region.Physics.OdePlugin
3042 actor.UpdatePositionAndVelocity(); 2857 actor.UpdatePositionAndVelocity();
3043 2858
3044 if (SupportsNINJAJoints) 2859 if (SupportsNINJAJoints)
3045 { 2860 SimulateActorPendingJoints(actor);
3046 // If an actor moved, move its joint proxy objects as well.
3047 // There seems to be an event PhysicsActor.OnPositionUpdate that could be used
3048 // for this purpose but it is never called! So we just do the joint
3049 // movement code here.
3050
3051 if (actor.SOPName != null &&
3052 joints_connecting_actor.ContainsKey(actor.SOPName) &&
3053 joints_connecting_actor[actor.SOPName] != null &&
3054 joints_connecting_actor[actor.SOPName].Count > 0)
3055 {
3056 foreach (PhysicsJoint affectedJoint in joints_connecting_actor[actor.SOPName])
3057 {
3058 if (affectedJoint.IsInPhysicsEngine)
3059 {
3060 DoJointMoved(affectedJoint);
3061 }
3062 else
3063 {
3064 DoJointErrorMessage(affectedJoint, "a body connected to a joint was moved, but the joint doesn't exist yet! this will lead to joint error. joint was: " + affectedJoint.ObjectNameInScene + " parms:" + affectedJoint.RawParams);
3065 }
3066 }
3067 }
3068 }
3069 } 2861 }
3070 } 2862 }
3071 } 2863 }
@@ -3076,7 +2868,7 @@ namespace OpenSim.Region.Physics.OdePlugin
3076 // Finished with all sim stepping. If requested, dump world state to file for debugging. 2868 // Finished with all sim stepping. If requested, dump world state to file for debugging.
3077 // TODO: This call to the export function is already inside lock (OdeLock) - but is an extra lock needed? 2869 // TODO: This call to the export function is already inside lock (OdeLock) - but is an extra lock needed?
3078 // TODO: This overwrites all dump files in-place. Should this be a growing logfile, or separate snapshots? 2870 // TODO: This overwrites all dump files in-place. Should this be a growing logfile, or separate snapshots?
3079 if (physics_logging && (physics_logging_interval>0) && (framecount % physics_logging_interval == 0)) 2871 if (physics_logging && (physics_logging_interval > 0) && (framecount % physics_logging_interval == 0))
3080 { 2872 {
3081 string fname = "state-" + world.ToString() + ".DIF"; // give each physics world a separate filename 2873 string fname = "state-" + world.ToString() + ".DIF"; // give each physics world a separate filename
3082 string prefix = "world" + world.ToString(); // prefix for variable names in exported .DIF file 2874 string prefix = "world" + world.ToString(); // prefix for variable names in exported .DIF file
@@ -3088,8 +2880,10 @@ namespace OpenSim.Region.Physics.OdePlugin
3088 fwriter.WriteLine(header); 2880 fwriter.WriteLine(header);
3089 fwriter.Close(); 2881 fwriter.Close();
3090 } 2882 }
2883
3091 d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix); 2884 d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix);
3092 } 2885 }
2886
3093 latertickcount = Util.EnvironmentTickCount() - tickCountFrameRun; 2887 latertickcount = Util.EnvironmentTickCount() - tickCountFrameRun;
3094 2888
3095 // OpenSimulator above does 10 fps. 10 fps = means that the main thread loop and physics 2889 // OpenSimulator above does 10 fps. 10 fps = means that the main thread loop and physics
@@ -3098,7 +2892,9 @@ namespace OpenSim.Region.Physics.OdePlugin
3098 // If Physics stalls, it takes longer which makes the tick count ms larger. 2892 // If Physics stalls, it takes longer which makes the tick count ms larger.
3099 2893
3100 if (latertickcount < 100) 2894 if (latertickcount < 100)
2895 {
3101 m_timeDilation = 1.0f; 2896 m_timeDilation = 1.0f;
2897 }
3102 else 2898 else
3103 { 2899 {
3104 m_timeDilation = 100f / latertickcount; 2900 m_timeDilation = 100f / latertickcount;
@@ -3111,6 +2907,229 @@ namespace OpenSim.Region.Physics.OdePlugin
3111 return fps; 2907 return fps;
3112 } 2908 }
3113 2909
2910 /// <summary>
2911 /// Simulate pending NINJA joints.
2912 /// </summary>
2913 /// <remarks>
2914 /// Called by the main Simulate() loop if NINJA joints are active. Should not be called from anywhere else.
2915 /// </remarks>
2916 protected void SimulatePendingNINJAJoints()
2917 {
2918 // Create pending joints, if possible
2919
2920 // joints can only be processed after ALL bodies are processed (and exist in ODE), since creating
2921 // a joint requires specifying the body id of both involved bodies
2922 if (pendingJoints.Count > 0)
2923 {
2924 List<PhysicsJoint> successfullyProcessedPendingJoints = new List<PhysicsJoint>();
2925 //DoJointErrorMessage(joints_connecting_actor, "taint: " + pendingJoints.Count + " pending joints");
2926 foreach (PhysicsJoint joint in pendingJoints)
2927 {
2928 //DoJointErrorMessage(joint, "taint: time to create joint with parms: " + joint.RawParams);
2929 string[] jointParams = joint.RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries);
2930 List<IntPtr> jointBodies = new List<IntPtr>();
2931 bool allJointBodiesAreReady = true;
2932 foreach (string jointParam in jointParams)
2933 {
2934 if (jointParam == "NULL")
2935 {
2936 //DoJointErrorMessage(joint, "attaching NULL joint to world");
2937 jointBodies.Add(IntPtr.Zero);
2938 }
2939 else
2940 {
2941 //DoJointErrorMessage(joint, "looking for prim name: " + jointParam);
2942 bool foundPrim = false;
2943 lock (_prims)
2944 {
2945 foreach (OdePrim prim in _prims) // FIXME: inefficient
2946 {
2947 if (prim.SOPName == jointParam)
2948 {
2949 //DoJointErrorMessage(joint, "found for prim name: " + jointParam);
2950 if (prim.IsPhysical && prim.Body != IntPtr.Zero)
2951 {
2952 jointBodies.Add(prim.Body);
2953 foundPrim = true;
2954 break;
2955 }
2956 else
2957 {
2958 DoJointErrorMessage(joint, "prim name " + jointParam +
2959 " exists but is not (yet) physical; deferring joint creation. " +
2960 "IsPhysical property is " + prim.IsPhysical +
2961 " and body is " + prim.Body);
2962 foundPrim = false;
2963 break;
2964 }
2965 }
2966 }
2967 }
2968 if (foundPrim)
2969 {
2970 // all is fine
2971 }
2972 else
2973 {
2974 allJointBodiesAreReady = false;
2975 break;
2976 }
2977 }
2978 }
2979
2980 if (allJointBodiesAreReady)
2981 {
2982 //DoJointErrorMessage(joint, "allJointBodiesAreReady for " + joint.ObjectNameInScene + " with parms " + joint.RawParams);
2983 if (jointBodies[0] == jointBodies[1])
2984 {
2985 DoJointErrorMessage(joint, "ERROR: joint cannot be created; the joint bodies are the same, body1==body2. Raw body is " + jointBodies[0] + ". raw parms: " + joint.RawParams);
2986 }
2987 else
2988 {
2989 switch (joint.Type)
2990 {
2991 case PhysicsJointType.Ball:
2992 {
2993 IntPtr odeJoint;
2994 //DoJointErrorMessage(joint, "ODE creating ball joint ");
2995 odeJoint = d.JointCreateBall(world, IntPtr.Zero);
2996 //DoJointErrorMessage(joint, "ODE attaching ball joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]);
2997 d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]);
2998 //DoJointErrorMessage(joint, "ODE setting ball anchor: " + odeJoint + " to vec:" + joint.Position);
2999 d.JointSetBallAnchor(odeJoint,
3000 joint.Position.X,
3001 joint.Position.Y,
3002 joint.Position.Z);
3003 //DoJointErrorMessage(joint, "ODE joint setting OK");
3004 //DoJointErrorMessage(joint, "The ball joint's bodies are here: b0: ");
3005 //DoJointErrorMessage(joint, "" + (jointBodies[0] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[0]) : "fixed environment"));
3006 //DoJointErrorMessage(joint, "The ball joint's bodies are here: b1: ");
3007 //DoJointErrorMessage(joint, "" + (jointBodies[1] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[1]) : "fixed environment"));
3008
3009 if (joint is OdePhysicsJoint)
3010 {
3011 ((OdePhysicsJoint)joint).jointID = odeJoint;
3012 }
3013 else
3014 {
3015 DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!");
3016 }
3017 }
3018 break;
3019 case PhysicsJointType.Hinge:
3020 {
3021 IntPtr odeJoint;
3022 //DoJointErrorMessage(joint, "ODE creating hinge joint ");
3023 odeJoint = d.JointCreateHinge(world, IntPtr.Zero);
3024 //DoJointErrorMessage(joint, "ODE attaching hinge joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]);
3025 d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]);
3026 //DoJointErrorMessage(joint, "ODE setting hinge anchor: " + odeJoint + " to vec:" + joint.Position);
3027 d.JointSetHingeAnchor(odeJoint,
3028 joint.Position.X,
3029 joint.Position.Y,
3030 joint.Position.Z);
3031 // We use the orientation of the x-axis of the joint's coordinate frame
3032 // as the axis for the hinge.
3033
3034 // Therefore, we must get the joint's coordinate frame based on the
3035 // joint.Rotation field, which originates from the orientation of the
3036 // joint's proxy object in the scene.
3037
3038 // The joint's coordinate frame is defined as the transformation matrix
3039 // that converts a vector from joint-local coordinates into world coordinates.
3040 // World coordinates are defined as the XYZ coordinate system of the sim,
3041 // as shown in the top status-bar of the viewer.
3042
3043 // Once we have the joint's coordinate frame, we extract its X axis (AtAxis)
3044 // and use that as the hinge axis.
3045
3046 //joint.Rotation.Normalize();
3047 Matrix4 proxyFrame = Matrix4.CreateFromQuaternion(joint.Rotation);
3048
3049 // Now extract the X axis of the joint's coordinate frame.
3050
3051 // Do not try to use proxyFrame.AtAxis or you will become mired in the
3052 // tar pit of transposed, inverted, and generally messed-up orientations.
3053 // (In other words, Matrix4.AtAxis() is borked.)
3054 // Vector3 jointAxis = proxyFrame.AtAxis; <--- this path leadeth to madness
3055
3056 // Instead, compute the X axis of the coordinate frame by transforming
3057 // the (1,0,0) vector. At least that works.
3058
3059 //m_log.Debug("PHY: making axis: complete matrix is " + proxyFrame);
3060 Vector3 jointAxis = Vector3.Transform(Vector3.UnitX, proxyFrame);
3061 //m_log.Debug("PHY: making axis: hinge joint axis is " + jointAxis);
3062 //DoJointErrorMessage(joint, "ODE setting hinge axis: " + odeJoint + " to vec:" + jointAxis);
3063 d.JointSetHingeAxis(odeJoint,
3064 jointAxis.X,
3065 jointAxis.Y,
3066 jointAxis.Z);
3067 //d.JointSetHingeParam(odeJoint, (int)dParam.CFM, 0.1f);
3068 if (joint is OdePhysicsJoint)
3069 {
3070 ((OdePhysicsJoint)joint).jointID = odeJoint;
3071 }
3072 else
3073 {
3074 DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!");
3075 }
3076 }
3077 break;
3078 }
3079 successfullyProcessedPendingJoints.Add(joint);
3080 }
3081 }
3082 else
3083 {
3084 DoJointErrorMessage(joint, "joint could not yet be created; still pending");
3085 }
3086 }
3087
3088 foreach (PhysicsJoint successfullyProcessedJoint in successfullyProcessedPendingJoints)
3089 {
3090 //DoJointErrorMessage(successfullyProcessedJoint, "finalizing succesfully procsssed joint " + successfullyProcessedJoint.ObjectNameInScene + " parms " + successfullyProcessedJoint.RawParams);
3091 //DoJointErrorMessage(successfullyProcessedJoint, "removing from pending");
3092 InternalRemovePendingJoint(successfullyProcessedJoint);
3093 //DoJointErrorMessage(successfullyProcessedJoint, "adding to active");
3094 InternalAddActiveJoint(successfullyProcessedJoint);
3095 //DoJointErrorMessage(successfullyProcessedJoint, "done");
3096 }
3097 }
3098 }
3099
3100 /// <summary>
3101 /// Simulate the joint proxies of a NINJA actor.
3102 /// </summary>
3103 /// <remarks>
3104 /// Called as part of the Simulate() loop if NINJA physics is active. Must only be called from there.
3105 /// </remarks>
3106 /// <param name="actor"></param>
3107 protected void SimulateActorPendingJoints(OdePrim actor)
3108 {
3109 // If an actor moved, move its joint proxy objects as well.
3110 // There seems to be an event PhysicsActor.OnPositionUpdate that could be used
3111 // for this purpose but it is never called! So we just do the joint
3112 // movement code here.
3113
3114 if (actor.SOPName != null &&
3115 joints_connecting_actor.ContainsKey(actor.SOPName) &&
3116 joints_connecting_actor[actor.SOPName] != null &&
3117 joints_connecting_actor[actor.SOPName].Count > 0)
3118 {
3119 foreach (PhysicsJoint affectedJoint in joints_connecting_actor[actor.SOPName])
3120 {
3121 if (affectedJoint.IsInPhysicsEngine)
3122 {
3123 DoJointMoved(affectedJoint);
3124 }
3125 else
3126 {
3127 DoJointErrorMessage(affectedJoint, "a body connected to a joint was moved, but the joint doesn't exist yet! this will lead to joint error. joint was: " + affectedJoint.ObjectNameInScene + " parms:" + affectedJoint.RawParams);
3128 }
3129 }
3130 }
3131 }
3132
3114 public override void GetResults() 3133 public override void GetResults()
3115 { 3134 {
3116 } 3135 }
@@ -3456,24 +3475,21 @@ namespace OpenSim.Region.Physics.OdePlugin
3456 float hfmin = 2000; 3475 float hfmin = 2000;
3457 float hfmax = -2000; 3476 float hfmax = -2000;
3458 3477
3459 for (int x = 0; x < heightmapWidthSamples; x++) 3478 for (int x = 0; x < heightmapWidthSamples; x++)
3479 {
3480 for (int y = 0; y < heightmapHeightSamples; y++)
3460 { 3481 {
3461 for (int y = 0; y < heightmapHeightSamples; y++) 3482 int xx = Util.Clip(x - 1, 0, regionsize - 1);
3462 { 3483 int yy = Util.Clip(y - 1, 0, regionsize - 1);
3463 int xx = Util.Clip(x - 1, 0, regionsize - 1); 3484
3464 int yy = Util.Clip(y - 1, 0, regionsize - 1); 3485
3465 3486 float val= heightMap[yy * (int)Constants.RegionSize + xx];
3466 3487 _heightmap[x * ((int)Constants.RegionSize + 2) + y] = val;
3467 float val= heightMap[yy * (int)Constants.RegionSize + xx]; 3488
3468 _heightmap[x * ((int)Constants.RegionSize + 2) + y] = val; 3489 hfmin = (val < hfmin) ? val : hfmin;
3469 3490 hfmax = (val > hfmax) ? val : hfmax;
3470 hfmin = (val < hfmin) ? val : hfmin;
3471 hfmax = (val > hfmax) ? val : hfmax;
3472 }
3473 } 3491 }
3474 3492 }
3475
3476
3477 3493
3478 lock (OdeLock) 3494 lock (OdeLock)
3479 { 3495 {
@@ -3528,7 +3544,6 @@ namespace OpenSim.Region.Physics.OdePlugin
3528 } 3544 }
3529 RegionTerrain.Add(pOffset, GroundGeom, GroundGeom); 3545 RegionTerrain.Add(pOffset, GroundGeom, GroundGeom);
3530 TerrainHeightFieldHeights.Add(GroundGeom,_heightmap); 3546 TerrainHeightFieldHeights.Add(GroundGeom,_heightmap);
3531
3532 } 3547 }
3533 } 3548 }
3534 3549
@@ -3691,6 +3706,7 @@ namespace OpenSim.Region.Physics.OdePlugin
3691 //d.CloseODE(); 3706 //d.CloseODE();
3692 } 3707 }
3693 } 3708 }
3709
3694 public override Dictionary<uint, float> GetTopColliders() 3710 public override Dictionary<uint, float> GetTopColliders()
3695 { 3711 {
3696 Dictionary<uint, float> returncolliders = new Dictionary<uint, float>(); 3712 Dictionary<uint, float> returncolliders = new Dictionary<uint, float>();
@@ -3727,6 +3743,34 @@ namespace OpenSim.Region.Physics.OdePlugin
3727 } 3743 }
3728 } 3744 }
3729 3745
3746 public override void RaycastWorld(Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod)
3747 {
3748 if (retMethod != null)
3749 {
3750 m_rayCastManager.QueueRequest(position, direction, length, Count, retMethod);
3751 }
3752 }
3753
3754 public override List<ContactResult> RaycastWorld(Vector3 position, Vector3 direction, float length, int Count)
3755 {
3756 ContactResult[] ourResults = null;
3757 RayCallback retMethod = delegate(List<ContactResult> results)
3758 {
3759 ourResults = new ContactResult[results.Count];
3760 results.CopyTo(ourResults, 0);
3761 };
3762 int waitTime = 0;
3763 m_rayCastManager.QueueRequest(position, direction, length, Count, retMethod);
3764 while (ourResults == null && waitTime < 1000)
3765 {
3766 Thread.Sleep(1);
3767 waitTime++;
3768 }
3769 if (ourResults == null)
3770 return new List<ContactResult> ();
3771 return new List<ContactResult>(ourResults);
3772 }
3773
3730#if USE_DRAWSTUFF 3774#if USE_DRAWSTUFF
3731 // Keyboard callback 3775 // Keyboard callback
3732 public void command(int cmd) 3776 public void command(int cmd)
diff --git a/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs b/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs
index 5dcd6f5..2ea810f 100644
--- a/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs
+++ b/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs
@@ -31,17 +31,18 @@ using NUnit.Framework;
31using OpenMetaverse; 31using OpenMetaverse;
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Region.Physics.Manager; 33using OpenSim.Region.Physics.Manager;
34using OpenSim.Region.Physics.OdePlugin;
34using log4net; 35using log4net;
35using System.Reflection; 36using System.Reflection;
36 37
37namespace OpenSim.Region.Physics.OdePlugin 38namespace OpenSim.Region.Physics.OdePlugin.Tests
38{ 39{
39 [TestFixture] 40 [TestFixture]
40 public class ODETestClass 41 public class ODETestClass
41 { 42 {
42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43 44
44 private OdePlugin cbt; 45 private OpenSim.Region.Physics.OdePlugin.OdePlugin cbt;
45 private PhysicsScene ps; 46 private PhysicsScene ps;
46 private IMeshingPlugin imp; 47 private IMeshingPlugin imp;
47 48
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
index 8b7871b..0cc0fe7 100644
--- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
@@ -58,7 +58,11 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
58 /// </summary> 58 /// </summary>
59 public interface IScriptInstance 59 public interface IScriptInstance
60 { 60 {
61 /// <summary>
62 /// Is this script currently running?
63 /// </summary>
61 bool Running { get; set; } 64 bool Running { get; set; }
65
62 bool ShuttingDown { get; set; } 66 bool ShuttingDown { get; set; }
63 string State { get; set; } 67 string State { get; set; }
64 IScriptEngine Engine { get; } 68 IScriptEngine Engine { get; }
@@ -78,7 +82,14 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
78 82
79 void Init(); 83 void Init();
80 void Start(); 84 void Start();
85
86 /// <summary>
87 /// Stop the script.
88 /// </summary>
89 /// <param name="timeout"></param>
90 /// <returns>true if the script was successfully stopped, false otherwise</returns>
81 bool Stop(int timeout); 91 bool Stop(int timeout);
92
82 void SetState(string state); 93 void SetState(string state);
83 94
84 void PostEvent(EventParams data); 95 void PostEvent(EventParams data);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index ecfac6f..bf791a9 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -303,35 +303,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
303 switch (linkType) 303 switch (linkType)
304 { 304 {
305 case ScriptBaseClass.LINK_SET: 305 case ScriptBaseClass.LINK_SET:
306 if (m_host.ParentGroup != null) 306 return new List<SceneObjectPart>(m_host.ParentGroup.Parts);
307 {
308 return new List<SceneObjectPart>(m_host.ParentGroup.Parts);
309 }
310 return ret;
311 307
312 case ScriptBaseClass.LINK_ROOT: 308 case ScriptBaseClass.LINK_ROOT:
313 if (m_host.ParentGroup != null) 309 ret = new List<SceneObjectPart>();
314 { 310 ret.Add(m_host.ParentGroup.RootPart);
315 ret = new List<SceneObjectPart>();
316 ret.Add(m_host.ParentGroup.RootPart);
317 return ret;
318 }
319 return ret; 311 return ret;
320 312
321 case ScriptBaseClass.LINK_ALL_OTHERS: 313 case ScriptBaseClass.LINK_ALL_OTHERS:
322 if (m_host.ParentGroup == null)
323 return new List<SceneObjectPart>();
324
325 ret = new List<SceneObjectPart>(m_host.ParentGroup.Parts); 314 ret = new List<SceneObjectPart>(m_host.ParentGroup.Parts);
326 315
327 if (ret.Contains(m_host)) 316 if (ret.Contains(m_host))
328 ret.Remove(m_host); 317 ret.Remove(m_host);
318
329 return ret; 319 return ret;
330 320
331 case ScriptBaseClass.LINK_ALL_CHILDREN: 321 case ScriptBaseClass.LINK_ALL_CHILDREN:
332 if (m_host.ParentGroup == null)
333 return new List<SceneObjectPart>();
334
335 ret = new List<SceneObjectPart>(m_host.ParentGroup.Parts); 322 ret = new List<SceneObjectPart>(m_host.ParentGroup.Parts);
336 323
337 if (ret.Contains(m_host.ParentGroup.RootPart)) 324 if (ret.Contains(m_host.ParentGroup.RootPart))
@@ -342,15 +329,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
342 return ret; 329 return ret;
343 330
344 default: 331 default:
345 if (linkType < 0 || m_host.ParentGroup == null) 332 if (linkType < 0)
346 return new List<SceneObjectPart>(); 333 return new List<SceneObjectPart>();
334
347 SceneObjectPart target = m_host.ParentGroup.GetLinkNumPart(linkType); 335 SceneObjectPart target = m_host.ParentGroup.GetLinkNumPart(linkType);
348 if (target == null) 336 if (target == null)
349 return new List<SceneObjectPart>(); 337 return new List<SceneObjectPart>();
350 ret = new List<SceneObjectPart>(); 338 ret = new List<SceneObjectPart>();
351 ret.Add(target); 339 ret.Add(target);
352 return ret; 340 return ret;
353
354 } 341 }
355 } 342 }
356 343
@@ -450,7 +437,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
450 } 437 }
451 438
452 // convert a LSL_Rotation to a Quaternion 439 // convert a LSL_Rotation to a Quaternion
453 protected Quaternion Rot2Quaternion(LSL_Rotation r) 440 public static Quaternion Rot2Quaternion(LSL_Rotation r)
454 { 441 {
455 Quaternion q = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s); 442 Quaternion q = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
456 q.Normalize(); 443 q.Normalize();
@@ -957,6 +944,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
957 wComm.DeliverMessage(ChatTypeEnum.Region, channelID, m_host.Name, m_host.UUID, text); 944 wComm.DeliverMessage(ChatTypeEnum.Region, channelID, m_host.Name, m_host.UUID, text);
958 } 945 }
959 946
947 public void llRegionSayTo(string target, int channel, string msg)
948 {
949 string error = String.Empty;
950
951 if (msg.Length > 1023)
952 msg = msg.Substring(0, 1023);
953
954 m_host.AddScriptLPS(1);
955
956 UUID TargetID;
957 UUID.TryParse(target, out TargetID);
958
959 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
960 if (wComm != null)
961 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
962 LSLError(error);
963 }
964
960 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 965 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
961 { 966 {
962 m_host.AddScriptLPS(1); 967 m_host.AddScriptLPS(1);
@@ -1298,8 +1303,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1298 if (value != 0) 1303 if (value != 0)
1299 { 1304 {
1300 SceneObjectGroup group = m_host.ParentGroup; 1305 SceneObjectGroup group = m_host.ParentGroup;
1301 if (group == null)
1302 return;
1303 bool allow = true; 1306 bool allow = true;
1304 1307
1305 foreach (SceneObjectPart part in group.Parts) 1308 foreach (SceneObjectPart part in group.Parts)
@@ -1313,18 +1316,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1313 1316
1314 if (!allow) 1317 if (!allow)
1315 return; 1318 return;
1319
1316 m_host.ScriptSetPhysicsStatus(true); 1320 m_host.ScriptSetPhysicsStatus(true);
1317 } 1321 }
1318 else 1322 else
1323 {
1319 m_host.ScriptSetPhysicsStatus(false); 1324 m_host.ScriptSetPhysicsStatus(false);
1325 }
1320 } 1326 }
1321 1327
1322 if ((status & ScriptBaseClass.STATUS_PHANTOM) == ScriptBaseClass.STATUS_PHANTOM) 1328 if ((status & ScriptBaseClass.STATUS_PHANTOM) == ScriptBaseClass.STATUS_PHANTOM)
1323 { 1329 {
1324 if (value != 0) 1330 m_host.ParentGroup.ScriptSetPhantomStatus(value != 0);
1325 m_host.ScriptSetPhantomStatus(true);
1326 else
1327 m_host.ScriptSetPhantomStatus(false);
1328 } 1331 }
1329 1332
1330 if ((status & ScriptBaseClass.STATUS_CAST_SHADOWS) == ScriptBaseClass.STATUS_CAST_SHADOWS) 1333 if ((status & ScriptBaseClass.STATUS_CAST_SHADOWS) == ScriptBaseClass.STATUS_CAST_SHADOWS)
@@ -1466,8 +1469,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1466 protected void SetScale(SceneObjectPart part, LSL_Vector scale) 1469 protected void SetScale(SceneObjectPart part, LSL_Vector scale)
1467 { 1470 {
1468 // TODO: this needs to trigger a persistance save as well 1471 // TODO: this needs to trigger a persistance save as well
1469 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 1472 if (part == null || part.ParentGroup.IsDeleted)
1470 return; 1473 return;
1474
1471 if (scale.x < 0.01) 1475 if (scale.x < 0.01)
1472 scale.x = 0.01; 1476 scale.x = 0.01;
1473 if (scale.y < 0.01) 1477 if (scale.y < 0.01)
@@ -1510,7 +1514,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1510 { 1514 {
1511 m_host.AddScriptLPS(1); 1515 m_host.AddScriptLPS(1);
1512 m_host.ClickAction = (byte)action; 1516 m_host.ClickAction = (byte)action;
1513 if (m_host.ParentGroup != null) m_host.ParentGroup.HasGroupChanged = true; 1517 m_host.ParentGroup.HasGroupChanged = true;
1514 m_host.ScheduleFullUpdate(); 1518 m_host.ScheduleFullUpdate();
1515 return; 1519 return;
1516 } 1520 }
@@ -1786,9 +1790,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1786 tex.FaceTextures[i].RGBA = texcolor; 1790 tex.FaceTextures[i].RGBA = texcolor;
1787 } 1791 }
1788 } 1792 }
1789 texcolor = tex.DefaultTexture.RGBA; 1793
1790 texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f); 1794 // In some cases, the default texture can be null, eg when every face
1791 tex.DefaultTexture.RGBA = texcolor; 1795 // has a unique texture
1796 if (tex.DefaultTexture != null)
1797 {
1798 texcolor = tex.DefaultTexture.RGBA;
1799 texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f);
1800 tex.DefaultTexture.RGBA = texcolor;
1801 }
1802
1792 part.UpdateTexture(tex); 1803 part.UpdateTexture(tex);
1793 return; 1804 return;
1794 } 1805 }
@@ -2149,7 +2160,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2149 2160
2150 if (part.ParentGroup.RootPart == part) 2161 if (part.ParentGroup.RootPart == part)
2151 { 2162 {
2152 if ((targetPos.z < ground) && disable_underground_movement && m_host.AttachmentPoint == 0) 2163 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2153 targetPos.z = ground; 2164 targetPos.z = ground;
2154 } 2165 }
2155 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos); 2166 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos);
@@ -2236,14 +2247,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2236 else 2247 else
2237 { 2248 {
2238 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 2249 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
2239 SceneObjectGroup group = m_host.ParentGroup; 2250 SceneObjectPart rootPart = m_host.ParentGroup.RootPart;
2240 if (group != null) // a bit paranoid, maybe 2251 if (rootPart != null) // better safe than sorry
2241 { 2252 {
2242 SceneObjectPart rootPart = group.RootPart; 2253 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot));
2243 if (rootPart != null) // again, better safe than sorry
2244 {
2245 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot));
2246 }
2247 } 2254 }
2248 } 2255 }
2249 2256
@@ -2292,6 +2299,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2292 { 2299 {
2293 return llGetRootRotation(); 2300 return llGetRootRotation();
2294 } 2301 }
2302
2295 m_host.AddScriptLPS(1); 2303 m_host.AddScriptLPS(1);
2296 Quaternion q = m_host.GetWorldRotation(); 2304 Quaternion q = m_host.GetWorldRotation();
2297 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2305 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
@@ -2302,9 +2310,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2302 Quaternion q; 2310 Quaternion q;
2303 if (part.LinkNum == 0 || part.LinkNum == 1) // unlinked or root prim 2311 if (part.LinkNum == 0 || part.LinkNum == 1) // unlinked or root prim
2304 { 2312 {
2305 if (part.ParentGroup.RootPart.AttachmentPoint != 0) 2313 if (part.ParentGroup.AttachmentPoint != 0)
2306 { 2314 {
2307 ScenePresence avatar = World.GetScenePresence(part.AttachedAvatar); 2315 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
2308 if (avatar != null) 2316 if (avatar != null)
2309 { 2317 {
2310 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 2318 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
@@ -2333,15 +2341,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2333 { 2341 {
2334 m_host.AddScriptLPS(1); 2342 m_host.AddScriptLPS(1);
2335 2343
2336 if (m_host.ParentGroup != null) 2344 if (!m_host.ParentGroup.IsDeleted)
2337 { 2345 {
2338 if (!m_host.ParentGroup.IsDeleted) 2346 if (local != 0)
2339 { 2347 force *= llGetRot();
2340 if (local != 0)
2341 force *= llGetRot();
2342 2348
2343 m_host.ParentGroup.RootPart.SetForce(new Vector3((float)force.x, (float)force.y, (float)force.z)); 2349 m_host.ParentGroup.RootPart.SetForce(new Vector3((float)force.x, (float)force.y, (float)force.z));
2344 }
2345 } 2350 }
2346 } 2351 }
2347 2352
@@ -2351,15 +2356,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2351 2356
2352 m_host.AddScriptLPS(1); 2357 m_host.AddScriptLPS(1);
2353 2358
2354 if (m_host.ParentGroup != null) 2359 if (!m_host.ParentGroup.IsDeleted)
2355 { 2360 {
2356 if (!m_host.ParentGroup.IsDeleted) 2361 Vector3 tmpForce = m_host.ParentGroup.RootPart.GetForce();
2357 { 2362 force.x = tmpForce.X;
2358 Vector3 tmpForce = m_host.ParentGroup.RootPart.GetForce(); 2363 force.y = tmpForce.Y;
2359 force.x = tmpForce.X; 2364 force.z = tmpForce.Z;
2360 force.y = tmpForce.Y;
2361 force.z = tmpForce.Z;
2362 }
2363 } 2365 }
2364 2366
2365 return force; 2367 return force;
@@ -2368,25 +2370,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2368 public LSL_Integer llTarget(LSL_Vector position, double range) 2370 public LSL_Integer llTarget(LSL_Vector position, double range)
2369 { 2371 {
2370 m_host.AddScriptLPS(1); 2372 m_host.AddScriptLPS(1);
2371 return m_host.registerTargetWaypoint(new Vector3((float)position.x, (float)position.y, (float)position.z), (float)range); 2373 return m_host.ParentGroup.registerTargetWaypoint(
2374 new Vector3((float)position.x, (float)position.y, (float)position.z), (float)range);
2372 } 2375 }
2373 2376
2374 public void llTargetRemove(int number) 2377 public void llTargetRemove(int number)
2375 { 2378 {
2376 m_host.AddScriptLPS(1); 2379 m_host.AddScriptLPS(1);
2377 m_host.unregisterTargetWaypoint(number); 2380 m_host.ParentGroup.unregisterTargetWaypoint(number);
2378 } 2381 }
2379 2382
2380 public LSL_Integer llRotTarget(LSL_Rotation rot, double error) 2383 public LSL_Integer llRotTarget(LSL_Rotation rot, double error)
2381 { 2384 {
2382 m_host.AddScriptLPS(1); 2385 m_host.AddScriptLPS(1);
2383 return m_host.registerRotTargetWaypoint(new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s), (float)error); 2386 return m_host.ParentGroup.registerRotTargetWaypoint(
2387 new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s), (float)error);
2384 } 2388 }
2385 2389
2386 public void llRotTargetRemove(int number) 2390 public void llRotTargetRemove(int number)
2387 { 2391 {
2388 m_host.AddScriptLPS(1); 2392 m_host.AddScriptLPS(1);
2389 m_host.unregisterRotTargetWaypoint(number); 2393 m_host.ParentGroup.unregisterRotTargetWaypoint(number);
2390 } 2394 }
2391 2395
2392 public void llMoveToTarget(LSL_Vector target, double tau) 2396 public void llMoveToTarget(LSL_Vector target, double tau)
@@ -2429,7 +2433,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2429 public LSL_Vector llGetTorque() 2433 public LSL_Vector llGetTorque()
2430 { 2434 {
2431 m_host.AddScriptLPS(1); 2435 m_host.AddScriptLPS(1);
2432 Vector3 torque = m_host.GetTorque(); 2436 Vector3 torque = m_host.ParentGroup.GetTorque();
2433 return new LSL_Vector(torque.X,torque.Y,torque.Z); 2437 return new LSL_Vector(torque.X,torque.Y,torque.Z);
2434 } 2438 }
2435 2439
@@ -2443,7 +2447,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2443 public LSL_Vector llGetVel() 2447 public LSL_Vector llGetVel()
2444 { 2448 {
2445 m_host.AddScriptLPS(1); 2449 m_host.AddScriptLPS(1);
2446 return new LSL_Vector(m_host.Velocity.X, m_host.Velocity.Y, m_host.Velocity.Z); 2450
2451 Vector3 vel;
2452
2453 if (m_host.ParentGroup.IsAttachment)
2454 {
2455 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2456 vel = avatar.Velocity;
2457 }
2458 else
2459 {
2460 vel = m_host.Velocity;
2461 }
2462
2463 return new LSL_Vector(vel.X, vel.Y, vel.Z);
2447 } 2464 }
2448 2465
2449 public LSL_Vector llGetAccel() 2466 public LSL_Vector llGetAccel()
@@ -2739,10 +2756,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2739 /// negative (indicating end-relative) and may be inverted, 2756 /// negative (indicating end-relative) and may be inverted,
2740 /// i.e. end < start. 2757 /// i.e. end < start.
2741 /// </summary> 2758 /// </summary>
2742
2743 public LSL_String llDeleteSubString(string src, int start, int end) 2759 public LSL_String llDeleteSubString(string src, int start, int end)
2744 { 2760 {
2745
2746 m_host.AddScriptLPS(1); 2761 m_host.AddScriptLPS(1);
2747 2762
2748 // Normalize indices (if negative). 2763 // Normalize indices (if negative).
@@ -2822,10 +2837,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2822 /// which case it is end-relative. The index may exceed either 2837 /// which case it is end-relative. The index may exceed either
2823 /// string bound, with the result being a concatenation. 2838 /// string bound, with the result being a concatenation.
2824 /// </summary> 2839 /// </summary>
2825
2826 public LSL_String llInsertString(string dest, int index, string src) 2840 public LSL_String llInsertString(string dest, int index, string src)
2827 { 2841 {
2828
2829 m_host.AddScriptLPS(1); 2842 m_host.AddScriptLPS(1);
2830 2843
2831 // Normalize indices (if negative). 2844 // Normalize indices (if negative).
@@ -2983,8 +2996,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2983 // If either of these are null, then there was an unknown error. 2996 // If either of these are null, then there was an unknown error.
2984 if (new_group == null) 2997 if (new_group == null)
2985 continue; 2998 continue;
2986 if (new_group.RootPart == null)
2987 continue;
2988 2999
2989 // objects rezzed with this method are die_at_edge by default. 3000 // objects rezzed with this method are die_at_edge by default.
2990 new_group.RootPart.SetDieAtEdge(true); 3001 new_group.RootPart.SetDieAtEdge(true);
@@ -3248,7 +3259,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3248 { 3259 {
3249 m_host.AddScriptLPS(1); 3260 m_host.AddScriptLPS(1);
3250 3261
3251 if (m_host.ParentGroup.RootPart.AttachmentPoint == 0) 3262 if (m_host.ParentGroup.AttachmentPoint == 0)
3252 return; 3263 return;
3253 3264
3254 TaskInventoryItem item; 3265 TaskInventoryItem item;
@@ -3288,7 +3299,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3288 3299
3289 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3300 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3290 if (attachmentsModule != null) 3301 if (attachmentsModule != null)
3291 attachmentsModule.ShowDetachInUserInventory(itemID, presence.ControllingClient); 3302 attachmentsModule.DetachSingleAttachmentToInv(itemID, presence.ControllingClient);
3292 } 3303 }
3293 3304
3294 public void llTakeCamera(string avatar) 3305 public void llTakeCamera(string avatar)
@@ -3449,12 +3460,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3449 public void llSetBuoyancy(double buoyancy) 3460 public void llSetBuoyancy(double buoyancy)
3450 { 3461 {
3451 m_host.AddScriptLPS(1); 3462 m_host.AddScriptLPS(1);
3452 if (m_host.ParentGroup != null) 3463
3464 if (!m_host.ParentGroup.IsDeleted)
3453 { 3465 {
3454 if (!m_host.ParentGroup.IsDeleted) 3466 m_host.ParentGroup.RootPart.SetBuoyancy((float)buoyancy);
3455 {
3456 m_host.ParentGroup.RootPart.Buoyancy = (float)buoyancy;
3457 }
3458 } 3467 }
3459 } 3468 }
3460 3469
@@ -3683,7 +3692,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3683 3692
3684 m_host.AddScriptLPS(1); 3693 m_host.AddScriptLPS(1);
3685 3694
3686 if (m_host.ParentGroup.IsAttachment && (UUID)agent == m_host.ParentGroup.RootPart.AttachedAvatar) 3695 if (m_host.ParentGroup.IsAttachment && (UUID)agent == m_host.ParentGroup.AttachedAvatar)
3687 { 3696 {
3688 // When attached, certain permissions are implicit if requested from owner 3697 // When attached, certain permissions are implicit if requested from owner
3689 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3698 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
@@ -3909,7 +3918,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3909 3918
3910 SceneObjectPart targetPart = World.GetSceneObjectPart((UUID)targetID); 3919 SceneObjectPart targetPart = World.GetSceneObjectPart((UUID)targetID);
3911 3920
3912 if (targetPart.ParentGroup.RootPart.AttachmentPoint != 0) 3921 if (targetPart.ParentGroup.AttachmentPoint != 0)
3913 return; // Fail silently if attached 3922 return; // Fail silently if attached
3914 3923
3915 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID) 3924 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
@@ -3967,7 +3976,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3967 3976
3968 SceneObjectGroup parentPrim = m_host.ParentGroup; 3977 SceneObjectGroup parentPrim = m_host.ParentGroup;
3969 3978
3970 if (parentPrim.RootPart.AttachmentPoint != 0) 3979 if (parentPrim.AttachmentPoint != 0)
3971 return; // Fail silently if attached 3980 return; // Fail silently if attached
3972 SceneObjectPart childPrim = null; 3981 SceneObjectPart childPrim = null;
3973 3982
@@ -4075,7 +4084,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4075 } 4084 }
4076 4085
4077 SceneObjectGroup parentPrim = m_host.ParentGroup; 4086 SceneObjectGroup parentPrim = m_host.ParentGroup;
4078 if (parentPrim.RootPart.AttachmentPoint != 0) 4087 if (parentPrim.AttachmentPoint != 0)
4079 return; // Fail silently if attached 4088 return; // Fail silently if attached
4080 4089
4081 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4090 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
@@ -4311,7 +4320,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4311 GridInstantMessage msg = new GridInstantMessage(World, 4320 GridInstantMessage msg = new GridInstantMessage(World,
4312 m_host.UUID, m_host.Name+", an object owned by "+ 4321 m_host.UUID, m_host.Name+", an object owned by "+
4313 resolveName(m_host.OwnerID)+",", destId, 4322 resolveName(m_host.OwnerID)+",", destId,
4314 (byte)InstantMessageDialog.InventoryOffered, 4323 (byte)InstantMessageDialog.TaskInventoryOffered,
4315 false, objName+"\n"+m_host.Name+" is located at "+ 4324 false, objName+"\n"+m_host.Name+" is located at "+
4316 World.RegionInfo.RegionName+" "+ 4325 World.RegionInfo.RegionName+" "+
4317 m_host.AbsolutePosition.ToString(), 4326 m_host.AbsolutePosition.ToString(),
@@ -4749,7 +4758,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4749 return; 4758 return;
4750 4759
4751 // Object not pushable. Not an attachment and has no physics component 4760 // Object not pushable. Not an attachment and has no physics component
4752 if (!pusheeob.IsAttachment && pusheeob.PhysActor == null) 4761 if (!pusheeob.ParentGroup.IsAttachment && pusheeob.PhysActor == null)
4753 return; 4762 return;
4754 4763
4755 PusheePos = pusheeob.AbsolutePosition; 4764 PusheePos = pusheeob.AbsolutePosition;
@@ -6279,7 +6288,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6279 public LSL_Integer llGetAttached() 6288 public LSL_Integer llGetAttached()
6280 { 6289 {
6281 m_host.AddScriptLPS(1); 6290 m_host.AddScriptLPS(1);
6282 return m_host.ParentGroup.RootPart.AttachmentPoint; 6291 return m_host.ParentGroup.AttachmentPoint;
6283 } 6292 }
6284 6293
6285 public virtual LSL_Integer llGetFreeMemory() 6294 public virtual LSL_Integer llGetFreeMemory()
@@ -6663,12 +6672,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6663 public void llSetVehicleType(int type) 6672 public void llSetVehicleType(int type)
6664 { 6673 {
6665 m_host.AddScriptLPS(1); 6674 m_host.AddScriptLPS(1);
6666 if (m_host.ParentGroup != null) 6675
6676 if (!m_host.ParentGroup.IsDeleted)
6667 { 6677 {
6668 if (!m_host.ParentGroup.IsDeleted) 6678 m_host.ParentGroup.RootPart.SetVehicleType(type);
6669 {
6670 m_host.ParentGroup.RootPart.SetVehicleType(type);
6671 }
6672 } 6679 }
6673 } 6680 }
6674 6681
@@ -6678,12 +6685,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6678 { 6685 {
6679 m_host.AddScriptLPS(1); 6686 m_host.AddScriptLPS(1);
6680 6687
6681 if (m_host.ParentGroup != null) 6688 if (!m_host.ParentGroup.IsDeleted)
6682 { 6689 {
6683 if (!m_host.ParentGroup.IsDeleted) 6690 m_host.ParentGroup.RootPart.SetVehicleFloatParam(param, (float)value);
6684 {
6685 m_host.ParentGroup.RootPart.SetVehicleFloatParam(param, (float)value);
6686 }
6687 } 6691 }
6688 } 6692 }
6689 6693
@@ -6692,13 +6696,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6692 public void llSetVehicleVectorParam(int param, LSL_Vector vec) 6696 public void llSetVehicleVectorParam(int param, LSL_Vector vec)
6693 { 6697 {
6694 m_host.AddScriptLPS(1); 6698 m_host.AddScriptLPS(1);
6695 if (m_host.ParentGroup != null) 6699
6700 if (!m_host.ParentGroup.IsDeleted)
6696 { 6701 {
6697 if (!m_host.ParentGroup.IsDeleted) 6702 m_host.ParentGroup.RootPart.SetVehicleVectorParam(param,
6698 { 6703 new Vector3((float)vec.x, (float)vec.y, (float)vec.z));
6699 m_host.ParentGroup.RootPart.SetVehicleVectorParam(param,
6700 new Vector3((float)vec.x, (float)vec.y, (float)vec.z));
6701 }
6702 } 6704 }
6703 } 6705 }
6704 6706
@@ -6707,37 +6709,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6707 public void llSetVehicleRotationParam(int param, LSL_Rotation rot) 6709 public void llSetVehicleRotationParam(int param, LSL_Rotation rot)
6708 { 6710 {
6709 m_host.AddScriptLPS(1); 6711 m_host.AddScriptLPS(1);
6710 if (m_host.ParentGroup != null) 6712
6713 if (!m_host.ParentGroup.IsDeleted)
6711 { 6714 {
6712 if (!m_host.ParentGroup.IsDeleted) 6715 m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, Rot2Quaternion(rot));
6713 {
6714 m_host.ParentGroup.RootPart.SetVehicleRotationParam(param,
6715 Rot2Quaternion(rot));
6716 }
6717 } 6716 }
6718 } 6717 }
6719 6718
6720 public void llSetVehicleFlags(int flags) 6719 public void llSetVehicleFlags(int flags)
6721 { 6720 {
6722 m_host.AddScriptLPS(1); 6721 m_host.AddScriptLPS(1);
6723 if (m_host.ParentGroup != null) 6722
6723 if (!m_host.ParentGroup.IsDeleted)
6724 { 6724 {
6725 if (!m_host.ParentGroup.IsDeleted) 6725 m_host.ParentGroup.RootPart.SetVehicleFlags(flags, false);
6726 {
6727 m_host.ParentGroup.RootPart.SetVehicleFlags(flags, false);
6728 }
6729 } 6726 }
6730 } 6727 }
6731 6728
6732 public void llRemoveVehicleFlags(int flags) 6729 public void llRemoveVehicleFlags(int flags)
6733 { 6730 {
6734 m_host.AddScriptLPS(1); 6731 m_host.AddScriptLPS(1);
6735 if (m_host.ParentGroup != null) 6732
6733 if (!m_host.ParentGroup.IsDeleted)
6736 { 6734 {
6737 if (!m_host.ParentGroup.IsDeleted) 6735 m_host.ParentGroup.RootPart.SetVehicleFlags(flags, true);
6738 {
6739 m_host.ParentGroup.RootPart.SetVehicleFlags(flags, true);
6740 }
6741 } 6736 }
6742 } 6737 }
6743 6738
@@ -6891,20 +6886,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6891 public void llVolumeDetect(int detect) 6886 public void llVolumeDetect(int detect)
6892 { 6887 {
6893 m_host.AddScriptLPS(1); 6888 m_host.AddScriptLPS(1);
6894 if (m_host.ParentGroup != null) 6889
6895 { 6890 if (!m_host.ParentGroup.IsDeleted)
6896 if (!m_host.ParentGroup.IsDeleted) 6891 m_host.ParentGroup.ScriptSetVolumeDetect(detect != 0);
6897 {
6898 m_host.ParentGroup.RootPart.ScriptSetVolumeDetect(detect!=0);
6899 }
6900 }
6901 } 6892 }
6902 6893
6903 /// <summary> 6894 /// <summary>
6904 /// This is a depecated function so this just replicates the result of 6895 /// This is a depecated function so this just replicates the result of
6905 /// invoking it in SL 6896 /// invoking it in SL
6906 /// </summary> 6897 /// </summary>
6907
6908 public void llRemoteLoadScript(string target, string name, int running, int start_param) 6898 public void llRemoteLoadScript(string target, string name, int running, int start_param)
6909 { 6899 {
6910 m_host.AddScriptLPS(1); 6900 m_host.AddScriptLPS(1);
@@ -7046,7 +7036,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7046 return Util.SHA1Hash(src, Encoding.UTF8).ToLower(); 7036 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
7047 } 7037 }
7048 7038
7049 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 7039 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
7050 { 7040 {
7051 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7041 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7052 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 7042 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
@@ -7059,7 +7049,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7059 { 7049 {
7060 holeshape = (int)ScriptBaseClass.PRIM_HOLE_DEFAULT; 7050 holeshape = (int)ScriptBaseClass.PRIM_HOLE_DEFAULT;
7061 } 7051 }
7062 shapeBlock.ProfileCurve = (byte)holeshape; 7052 shapeBlock.PathCurve = pathcurve;
7053 shapeBlock.ProfileCurve = (byte)holeshape; // Set the hole shape.
7054 shapeBlock.ProfileCurve += profileshape; // Add in the profile shape.
7063 if (cut.x < 0f) 7055 if (cut.x < 0f)
7064 { 7056 {
7065 cut.x = 0f; 7057 cut.x = 0f;
@@ -7091,9 +7083,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7091 { 7083 {
7092 hollow = 0f; 7084 hollow = 0f;
7093 } 7085 }
7094 if (hollow > 0.95) 7086 // If the prim is a Cylinder, Prism, Sphere, Torus or Ring (or not a
7087 // Box or Tube) and the hole shape is a square, hollow is limited to
7088 // a max of 70%. The viewer performs its own check on this value but
7089 // we need to do it here also so llGetPrimitiveParams can have access
7090 // to the correct value.
7091 if (profileshape != (byte)ProfileCurve.Square &&
7092 holeshape == (int)ScriptBaseClass.PRIM_HOLE_SQUARE)
7095 { 7093 {
7096 hollow = 0.95f; 7094 if (hollow > 0.70f)
7095 {
7096 hollow = 0.70f;
7097 }
7098 }
7099 // Otherwise, hollow is limited to 95%.
7100 else
7101 {
7102 if (hollow > 0.95f)
7103 {
7104 hollow = 0.95f;
7105 }
7097 } 7106 }
7098 shapeBlock.ProfileHollow = (ushort)(50000 * hollow); 7107 shapeBlock.ProfileHollow = (ushort)(50000 * hollow);
7099 if (twist.x < -1.0f) 7108 if (twist.x < -1.0f)
@@ -7117,23 +7126,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7117 7126
7118 shapeBlock.ObjectLocalID = part.LocalId; 7127 shapeBlock.ObjectLocalID = part.LocalId;
7119 7128
7120 // retain pathcurve
7121 shapeBlock.PathCurve = part.Shape.PathCurve;
7122
7123 part.Shape.SculptEntry = false; 7129 part.Shape.SculptEntry = false;
7124 return shapeBlock; 7130 return shapeBlock;
7125 } 7131 }
7126 7132
7127 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) 7133 // Prim type box, cylinder and prism.
7134 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve)
7128 { 7135 {
7129 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 7136 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7130 return; 7137 return;
7131 7138
7132 ObjectShapePacket.ObjectDataBlock shapeBlock; 7139 ObjectShapePacket.ObjectDataBlock shapeBlock;
7133 7140
7134 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7141 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
7135
7136 shapeBlock.ProfileCurve += fudge;
7137 7142
7138 if (taper_b.x < 0f) 7143 if (taper_b.x < 0f)
7139 { 7144 {
@@ -7176,21 +7181,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7176 part.UpdateShape(shapeBlock); 7181 part.UpdateShape(shapeBlock);
7177 } 7182 }
7178 7183
7179 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 7184 // Prim type sphere.
7185 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7180 { 7186 {
7181 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 7187 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7182 return; 7188 return;
7183 7189
7184 ObjectShapePacket.ObjectDataBlock shapeBlock; 7190 ObjectShapePacket.ObjectDataBlock shapeBlock;
7185 7191
7186 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7192 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
7187 7193
7188 // profile/path swapped for a sphere 7194 // profile/path swapped for a sphere
7189 shapeBlock.PathBegin = shapeBlock.ProfileBegin; 7195 shapeBlock.PathBegin = shapeBlock.ProfileBegin;
7190 shapeBlock.PathEnd = shapeBlock.ProfileEnd; 7196 shapeBlock.PathEnd = shapeBlock.ProfileEnd;
7191 7197
7192 shapeBlock.ProfileCurve += fudge;
7193
7194 shapeBlock.PathScaleX = 100; 7198 shapeBlock.PathScaleX = 100;
7195 shapeBlock.PathScaleY = 100; 7199 shapeBlock.PathScaleY = 100;
7196 7200
@@ -7221,16 +7225,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7221 part.UpdateShape(shapeBlock); 7225 part.UpdateShape(shapeBlock);
7222 } 7226 }
7223 7227
7224 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte fudge) 7228 // Prim type torus, tube and ring.
7229 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte profileshape, byte pathcurve)
7225 { 7230 {
7226 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 7231 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7227 return; 7232 return;
7228 7233
7229 ObjectShapePacket.ObjectDataBlock shapeBlock; 7234 ObjectShapePacket.ObjectDataBlock shapeBlock;
7230 7235
7231 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7236 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
7232
7233 shapeBlock.ProfileCurve += fudge;
7234 7237
7235 // profile/path swapped for a torrus, tube, ring 7238 // profile/path swapped for a torrus, tube, ring
7236 shapeBlock.PathBegin = shapeBlock.ProfileBegin; 7239 shapeBlock.PathBegin = shapeBlock.ProfileBegin;
@@ -7350,7 +7353,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7350 part.UpdateShape(shapeBlock); 7353 part.UpdateShape(shapeBlock);
7351 } 7354 }
7352 7355
7353 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7356 // Prim type sculpt.
7357 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7354 { 7358 {
7355 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 7359 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7356 return; 7360 return;
@@ -7366,6 +7370,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7366 if (sculptId == UUID.Zero) 7370 if (sculptId == UUID.Zero)
7367 return; 7371 return;
7368 7372
7373 shapeBlock.PathCurve = pathcurve;
7369 shapeBlock.ObjectLocalID = part.LocalId; 7374 shapeBlock.ObjectLocalID = part.LocalId;
7370 shapeBlock.PathScaleX = 100; 7375 shapeBlock.PathScaleX = 100;
7371 shapeBlock.PathScaleY = 150; 7376 shapeBlock.PathScaleY = 150;
@@ -7379,9 +7384,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7379 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7384 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7380 } 7385 }
7381 7386
7382 // retain pathcurve
7383 shapeBlock.PathCurve = part.Shape.PathCurve;
7384
7385 part.Shape.SetSculptProperties((byte)type, sculptId); 7387 part.Shape.SetSculptProperties((byte)type, sculptId);
7386 part.Shape.SculptEntry = true; 7388 part.Shape.SculptEntry = true;
7387 part.UpdateShape(shapeBlock); 7389 part.UpdateShape(shapeBlock);
@@ -7518,15 +7520,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7518 else 7520 else
7519 { 7521 {
7520 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 7522 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
7521 SceneObjectGroup group = part.ParentGroup; 7523 SceneObjectPart rootPart = part.ParentGroup.RootPart;
7522 if (group != null) // a bit paranoid, maybe 7524 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q));
7523 {
7524 SceneObjectPart rootPart = group.RootPart;
7525 if (rootPart != null) // again, better safe than sorry
7526 {
7527 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q));
7528 }
7529 }
7530 } 7525 }
7531 7526
7532 break; 7527 break;
@@ -7561,8 +7556,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7561 taper_b = rules.GetVector3Item(idx++); 7556 taper_b = rules.GetVector3Item(idx++);
7562 topshear = rules.GetVector3Item(idx++); 7557 topshear = rules.GetVector3Item(idx++);
7563 7558
7564 part.Shape.PathCurve = (byte)Extrusion.Straight; 7559 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear,
7565 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear, 1); 7560 (byte)ProfileShape.Square, (byte)Extrusion.Straight);
7566 break; 7561 break;
7567 7562
7568 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER: 7563 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
@@ -7575,9 +7570,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7575 twist = rules.GetVector3Item(idx++); 7570 twist = rules.GetVector3Item(idx++);
7576 taper_b = rules.GetVector3Item(idx++); 7571 taper_b = rules.GetVector3Item(idx++);
7577 topshear = rules.GetVector3Item(idx++); 7572 topshear = rules.GetVector3Item(idx++);
7578 part.Shape.ProfileShape = ProfileShape.Circle; 7573 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear,
7579 part.Shape.PathCurve = (byte)Extrusion.Straight; 7574 (byte)ProfileShape.Circle, (byte)Extrusion.Straight);
7580 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear, 0);
7581 break; 7575 break;
7582 7576
7583 case (int)ScriptBaseClass.PRIM_TYPE_PRISM: 7577 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
@@ -7590,8 +7584,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7590 twist = rules.GetVector3Item(idx++); 7584 twist = rules.GetVector3Item(idx++);
7591 taper_b = rules.GetVector3Item(idx++); 7585 taper_b = rules.GetVector3Item(idx++);
7592 topshear = rules.GetVector3Item(idx++); 7586 topshear = rules.GetVector3Item(idx++);
7593 part.Shape.PathCurve = (byte)Extrusion.Straight; 7587 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear,
7594 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear, 3); 7588 (byte)ProfileShape.EquilateralTriangle, (byte)Extrusion.Straight);
7595 break; 7589 break;
7596 7590
7597 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE: 7591 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
@@ -7603,8 +7597,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7603 hollow = (float)rules.GetLSLFloatItem(idx++); 7597 hollow = (float)rules.GetLSLFloatItem(idx++);
7604 twist = rules.GetVector3Item(idx++); 7598 twist = rules.GetVector3Item(idx++);
7605 taper_b = rules.GetVector3Item(idx++); // dimple 7599 taper_b = rules.GetVector3Item(idx++); // dimple
7606 part.Shape.PathCurve = (byte)Extrusion.Curve1; 7600 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b,
7607 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, 5); 7601 (byte)ProfileShape.HalfCircle, (byte)Extrusion.Curve1);
7608 break; 7602 break;
7609 7603
7610 case (int)ScriptBaseClass.PRIM_TYPE_TORUS: 7604 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
@@ -7622,9 +7616,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7622 revolutions = (float)rules.GetLSLFloatItem(idx++); 7616 revolutions = (float)rules.GetLSLFloatItem(idx++);
7623 radiusoffset = (float)rules.GetLSLFloatItem(idx++); 7617 radiusoffset = (float)rules.GetLSLFloatItem(idx++);
7624 skew = (float)rules.GetLSLFloatItem(idx++); 7618 skew = (float)rules.GetLSLFloatItem(idx++);
7625 part.Shape.PathCurve = (byte)Extrusion.Curve1;
7626 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b, 7619 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b,
7627 revolutions, radiusoffset, skew, 0); 7620 revolutions, radiusoffset, skew, (byte)ProfileShape.Circle, (byte)Extrusion.Curve1);
7628 break; 7621 break;
7629 7622
7630 case (int)ScriptBaseClass.PRIM_TYPE_TUBE: 7623 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
@@ -7642,9 +7635,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7642 revolutions = (float)rules.GetLSLFloatItem(idx++); 7635 revolutions = (float)rules.GetLSLFloatItem(idx++);
7643 radiusoffset = (float)rules.GetLSLFloatItem(idx++); 7636 radiusoffset = (float)rules.GetLSLFloatItem(idx++);
7644 skew = (float)rules.GetLSLFloatItem(idx++); 7637 skew = (float)rules.GetLSLFloatItem(idx++);
7645 part.Shape.PathCurve = (byte)Extrusion.Curve1;
7646 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b, 7638 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b,
7647 revolutions, radiusoffset, skew, 1); 7639 revolutions, radiusoffset, skew, (byte)ProfileShape.Square, (byte)Extrusion.Curve1);
7648 break; 7640 break;
7649 7641
7650 case (int)ScriptBaseClass.PRIM_TYPE_RING: 7642 case (int)ScriptBaseClass.PRIM_TYPE_RING:
@@ -7662,9 +7654,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7662 revolutions = (float)rules.GetLSLFloatItem(idx++); 7654 revolutions = (float)rules.GetLSLFloatItem(idx++);
7663 radiusoffset = (float)rules.GetLSLFloatItem(idx++); 7655 radiusoffset = (float)rules.GetLSLFloatItem(idx++);
7664 skew = (float)rules.GetLSLFloatItem(idx++); 7656 skew = (float)rules.GetLSLFloatItem(idx++);
7665 part.Shape.PathCurve = (byte)Extrusion.Curve1;
7666 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b, 7657 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b,
7667 revolutions, radiusoffset, skew, 3); 7658 revolutions, radiusoffset, skew, (byte)ProfileShape.EquilateralTriangle, (byte)Extrusion.Curve1);
7668 break; 7659 break;
7669 7660
7670 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT: 7661 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
@@ -7673,8 +7664,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7673 7664
7674 string map = rules.Data[idx++].ToString(); 7665 string map = rules.Data[idx++].ToString();
7675 face = (int)rules.GetLSLIntegerItem(idx++); // type 7666 face = (int)rules.GetLSLIntegerItem(idx++); // type
7676 part.Shape.PathCurve = (byte)Extrusion.Curve1; 7667 SetPrimitiveShapeParams(part, map, face, (byte)Extrusion.Curve1);
7677 SetPrimitiveShapeParams(part, map, face);
7678 break; 7668 break;
7679 } 7669 }
7680 7670
@@ -7779,18 +7769,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7779 break; 7769 break;
7780 7770
7781 case (int)ScriptBaseClass.PRIM_PHANTOM: 7771 case (int)ScriptBaseClass.PRIM_PHANTOM:
7782 if (remain < 1) 7772 if (remain < 1)
7783 return; 7773 return;
7784 7774
7785 string ph = rules.Data[idx++].ToString(); 7775 string ph = rules.Data[idx++].ToString();
7786 bool phantom; 7776 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1"));
7787 7777
7788 if (ph.Equals("1"))
7789 phantom = true;
7790 else
7791 phantom = false;
7792
7793 part.ScriptSetPhantomStatus(phantom);
7794 break; 7778 break;
7795 7779
7796 case (int)ScriptBaseClass.PRIM_PHYSICS: 7780 case (int)ScriptBaseClass.PRIM_PHYSICS:
@@ -7811,14 +7795,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7811 if (remain < 1) 7795 if (remain < 1)
7812 return; 7796 return;
7813 string temp = rules.Data[idx++].ToString(); 7797 string temp = rules.Data[idx++].ToString();
7814 bool tempOnRez;
7815 7798
7816 if (temp.Equals("1")) 7799 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1"));
7817 tempOnRez = true;
7818 else
7819 tempOnRez = false;
7820 7800
7821 part.ScriptSetTemporaryStatus(tempOnRez);
7822 break; 7801 break;
7823 7802
7824 case (int)ScriptBaseClass.PRIM_TEXGEN: 7803 case (int)ScriptBaseClass.PRIM_TEXGEN:
@@ -7983,9 +7962,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7983 { 7962 {
7984 m_host.AddScriptLPS(1); 7963 m_host.AddScriptLPS(1);
7985 Quaternion q; 7964 Quaternion q;
7986 if (m_host.ParentGroup.RootPart.AttachmentPoint != 0) 7965 if (m_host.ParentGroup.AttachmentPoint != 0)
7987 { 7966 {
7988 ScenePresence avatar = World.GetScenePresence(m_host.AttachedAvatar); 7967 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
7989 if (avatar != null) 7968 if (avatar != null)
7990 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 7969 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
7991 q = avatar.CameraRotation; // Mouselook 7970 q = avatar.CameraRotation; // Mouselook
@@ -8238,7 +8217,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8238 case ScriptBaseClass.PRIM_TYPE_BOX: 8217 case ScriptBaseClass.PRIM_TYPE_BOX:
8239 case ScriptBaseClass.PRIM_TYPE_CYLINDER: 8218 case ScriptBaseClass.PRIM_TYPE_CYLINDER:
8240 case ScriptBaseClass.PRIM_TYPE_PRISM: 8219 case ScriptBaseClass.PRIM_TYPE_PRISM:
8241 res.Add(new LSL_Integer(Shape.ProfileCurve)); 8220 res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble.
8242 res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0)); 8221 res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0));
8243 res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0)); 8222 res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0));
8244 res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0)); 8223 res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0));
@@ -8247,7 +8226,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8247 break; 8226 break;
8248 8227
8249 case ScriptBaseClass.PRIM_TYPE_SPHERE: 8228 case ScriptBaseClass.PRIM_TYPE_SPHERE:
8250 res.Add(new LSL_Integer(Shape.ProfileCurve)); 8229 res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble.
8251 res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0)); 8230 res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0));
8252 res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0)); 8231 res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0));
8253 res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0)); 8232 res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0));
@@ -8263,7 +8242,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8263 case ScriptBaseClass.PRIM_TYPE_TUBE: 8242 case ScriptBaseClass.PRIM_TYPE_TUBE:
8264 case ScriptBaseClass.PRIM_TYPE_TORUS: 8243 case ScriptBaseClass.PRIM_TYPE_TORUS:
8265 // holeshape 8244 // holeshape
8266 res.Add(new LSL_Integer(Shape.ProfileCurve)); 8245 res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble.
8267 8246
8268 // cut 8247 // cut
8269 res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0)); 8248 res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0));
@@ -10666,6 +10645,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10666 public LSL_List llGetObjectDetails(string id, LSL_List args) 10645 public LSL_List llGetObjectDetails(string id, LSL_List args)
10667 { 10646 {
10668 m_host.AddScriptLPS(1); 10647 m_host.AddScriptLPS(1);
10648
10669 LSL_List ret = new LSL_List(); 10649 LSL_List ret = new LSL_List();
10670 UUID key = new UUID(); 10650 UUID key = new UUID();
10671 if (UUID.TryParse(id, out key)) 10651 if (UUID.TryParse(id, out key))
@@ -10676,72 +10656,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10676 { 10656 {
10677 foreach (object o in args.Data) 10657 foreach (object o in args.Data)
10678 { 10658 {
10679 switch (o.ToString()) 10659 switch (int.Parse(o.ToString()))
10680 { 10660 {
10681 case "1": 10661 case ScriptBaseClass.OBJECT_NAME:
10682 ret.Add(new LSL_String(av.Firstname + " " + av.Lastname)); 10662 ret.Add(new LSL_String(av.Firstname + " " + av.Lastname));
10683 break; 10663 break;
10684 case "2": 10664 case ScriptBaseClass.OBJECT_DESC:
10685 ret.Add(new LSL_String("")); 10665 ret.Add(new LSL_String(""));
10686 break; 10666 break;
10687 case "3": 10667 case ScriptBaseClass.OBJECT_POS:
10688 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 10668 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z));
10689 break; 10669 break;
10690 case "4": 10670 case ScriptBaseClass.OBJECT_ROT:
10691 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 10671 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W));
10692 break; 10672 break;
10693 case "5": 10673 case ScriptBaseClass.OBJECT_VELOCITY:
10694 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 10674 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z));
10695 break; 10675 break;
10696 case "6": 10676 case ScriptBaseClass.OBJECT_OWNER:
10697 ret.Add(new LSL_String(id)); 10677 ret.Add(new LSL_String(id));
10698 break; 10678 break;
10699 case "7": 10679 case ScriptBaseClass.OBJECT_GROUP:
10700 ret.Add(new LSL_String(UUID.Zero.ToString())); 10680 ret.Add(new LSL_String(UUID.Zero.ToString()));
10701 break; 10681 break;
10702 case "8": 10682 case ScriptBaseClass.OBJECT_CREATOR:
10703 ret.Add(new LSL_String(UUID.Zero.ToString())); 10683 ret.Add(new LSL_String(UUID.Zero.ToString()));
10704 break; 10684 break;
10705 } 10685 }
10706 } 10686 }
10687
10707 return ret; 10688 return ret;
10708 } 10689 }
10690
10709 SceneObjectPart obj = World.GetSceneObjectPart(key); 10691 SceneObjectPart obj = World.GetSceneObjectPart(key);
10710 if (obj != null) 10692 if (obj != null)
10711 { 10693 {
10712 foreach (object o in args.Data) 10694 foreach (object o in args.Data)
10713 { 10695 {
10714 switch (o.ToString()) 10696 switch (int.Parse(o.ToString()))
10715 { 10697 {
10716 case "1": 10698 case ScriptBaseClass.OBJECT_NAME:
10717 ret.Add(new LSL_String(obj.Name)); 10699 ret.Add(new LSL_String(obj.Name));
10718 break; 10700 break;
10719 case "2": 10701 case ScriptBaseClass.OBJECT_DESC:
10720 ret.Add(new LSL_String(obj.Description)); 10702 ret.Add(new LSL_String(obj.Description));
10721 break; 10703 break;
10722 case "3": 10704 case ScriptBaseClass.OBJECT_POS:
10723 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 10705 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z));
10724 break; 10706 break;
10725 case "4": 10707 case ScriptBaseClass.OBJECT_ROT:
10726 ret.Add(new LSL_Rotation(obj.RotationOffset.X, obj.RotationOffset.Y, obj.RotationOffset.Z, obj.RotationOffset.W)); 10708 ret.Add(new LSL_Rotation(obj.RotationOffset.X, obj.RotationOffset.Y, obj.RotationOffset.Z, obj.RotationOffset.W));
10727 break; 10709 break;
10728 case "5": 10710 case ScriptBaseClass.OBJECT_VELOCITY:
10729 ret.Add(new LSL_Vector(obj.Velocity.X, obj.Velocity.Y, obj.Velocity.Z)); 10711 ret.Add(new LSL_Vector(obj.Velocity.X, obj.Velocity.Y, obj.Velocity.Z));
10730 break; 10712 break;
10731 case "6": 10713 case ScriptBaseClass.OBJECT_OWNER:
10732 ret.Add(new LSL_String(obj.OwnerID.ToString())); 10714 ret.Add(new LSL_String(obj.OwnerID.ToString()));
10733 break; 10715 break;
10734 case "7": 10716 case ScriptBaseClass.OBJECT_GROUP:
10735 ret.Add(new LSL_String(obj.GroupID.ToString())); 10717 ret.Add(new LSL_String(obj.GroupID.ToString()));
10736 break; 10718 break;
10737 case "8": 10719 case ScriptBaseClass.OBJECT_CREATOR:
10738 ret.Add(new LSL_String(obj.CreatorID.ToString())); 10720 ret.Add(new LSL_String(obj.CreatorID.ToString()));
10739 break; 10721 break;
10740 } 10722 }
10741 } 10723 }
10724
10742 return ret; 10725 return ret;
10743 } 10726 }
10744 } 10727 }
10728
10745 return new LSL_List(); 10729 return new LSL_List();
10746 } 10730 }
10747 10731
@@ -11000,31 +10984,173 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11000 { 10984 {
11001 m_SayShoutCount = 0; 10985 m_SayShoutCount = 0;
11002 } 10986 }
10987 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10988 {
10989 m_host.AddScriptLPS(1);
10990
10991 Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z);
10992 Vector3 startvector = new Vector3((float)start.x, (float)start.y, (float)start.z);
10993 Vector3 endvector = new Vector3((float)end.x, (float)end.y, (float)end.z);
10994
10995 int count = 0;
10996// int detectPhantom = 0;
10997 int dataFlags = 0;
10998 int rejectTypes = 0;
10999
11000 for (int i = 0; i < options.Length; i += 2)
11001 {
11002 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
11003 {
11004 count = options.GetLSLIntegerItem(i + 1);
11005 }
11006// else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
11007// {
11008// detectPhantom = options.GetLSLIntegerItem(i + 1);
11009// }
11010 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
11011 {
11012 dataFlags = options.GetLSLIntegerItem(i + 1);
11013 }
11014 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
11015 {
11016 rejectTypes = options.GetLSLIntegerItem(i + 1);
11017 }
11018 }
11019
11020 LSL_List list = new LSL_List();
11021 List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count);
11022
11023 double distance = Util.GetDistanceTo(startvector, endvector);
11024
11025 if (distance == 0)
11026 distance = 0.001;
11027
11028 Vector3 posToCheck = startvector;
11029 ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();
11030
11031 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
11032 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
11033 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
11034 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11035
11036 for (float i = 0; i <= distance; i += 0.1f)
11037 {
11038 posToCheck = startvector + (dir * (i / (float)distance));
11039
11040 if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z)
11041 {
11042 ContactResult result = new ContactResult();
11043 result.ConsumerID = 0;
11044 result.Depth = 0;
11045 result.Normal = Vector3.Zero;
11046 result.Pos = posToCheck;
11047 results.Add(result);
11048 checkTerrain = false;
11049 }
11050
11051 if (checkAgents)
11052 {
11053 World.ForEachScenePresence(delegate(ScenePresence sp)
11054 {
11055 if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X))
11056 {
11057 ContactResult result = new ContactResult ();
11058 result.ConsumerID = sp.LocalId;
11059 result.Depth = 0;
11060 result.Normal = Vector3.Zero;
11061 result.Pos = posToCheck;
11062 results.Add(result);
11063 }
11064 });
11065 }
11066 }
11067
11068 int refcount = 0;
11069 foreach (ContactResult result in results)
11070 {
11071 if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND)
11072 == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0)
11073 continue;
11074
11075 ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID);
11076
11077 if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS)
11078 entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents
11079
11080 if (entity == null)
11081 {
11082 list.Add(UUID.Zero);
11083
11084 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
11085 list.Add(0);
11086
11087 list.Add(result.Pos);
11088
11089 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
11090 list.Add(result.Normal);
11091
11092 continue; //Can't find it, so add UUID.Zero
11093 }
11094
11095 /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity &&
11096 ((ISceneChildEntity)intersection.obj).PhysActor == null)
11097 continue;*/ //Can't do this ATM, physics engine knows only of non phantom objects
11098
11099 if (entity is SceneObjectPart)
11100 {
11101 if (((SceneObjectPart)entity).PhysActor != null && ((SceneObjectPart)entity).PhysActor.IsPhysical)
11102 {
11103 if (!checkPhysical)
11104 continue;
11105 }
11106 else
11107 {
11108 if (!checkNonPhysical)
11109 continue;
11110 }
11111 }
11112
11113 refcount++;
11114 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is SceneObjectPart)
11115 list.Add(((SceneObjectPart)entity).ParentGroup.UUID);
11116 else
11117 list.Add(entity.UUID);
11118
11119 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
11120 {
11121 if (entity is SceneObjectPart)
11122 list.Add(((SceneObjectPart)entity).LinkNum);
11123 else
11124 list.Add(0);
11125 }
11126
11127 list.Add(result.Pos);
11128
11129 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
11130 list.Add(result.Normal);
11131 }
11132
11133 list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED
11134
11135 return list;
11136 }
11003 11137
11004 #region Not Implemented 11138 #region Not Implemented
11005 // 11139 //
11006 // Listing the unimplemented lsl functions here, please move 11140 // Listing the unimplemented lsl functions here, please move
11007 // them from this region as they are completed 11141 // them from this region as they are completed
11008 // 11142 //
11009 public void llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11010 {
11011 m_host.AddScriptLPS(1);
11012 NotImplemented("llCastRay");
11013
11014 }
11015 11143
11016 public void llGetEnv(LSL_String name) 11144 public void llGetEnv(LSL_String name)
11017 { 11145 {
11018 m_host.AddScriptLPS(1); 11146 m_host.AddScriptLPS(1);
11019 NotImplemented("llGetEnv"); 11147 NotImplemented("llGetEnv");
11020
11021 } 11148 }
11022 11149
11023 public void llGetSPMaxMemory() 11150 public void llGetSPMaxMemory()
11024 { 11151 {
11025 m_host.AddScriptLPS(1); 11152 m_host.AddScriptLPS(1);
11026 NotImplemented("llGetSPMaxMemory"); 11153 NotImplemented("llGetSPMaxMemory");
11027
11028 } 11154 }
11029 11155
11030 public virtual LSL_Integer llGetUsedMemory() 11156 public virtual LSL_Integer llGetUsedMemory()
@@ -11034,18 +11160,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11034 return 0; 11160 return 0;
11035 } 11161 }
11036 11162
11037 public void llRegionSayTo( LSL_Key target, LSL_Integer channel, LSL_String msg ) 11163 public void llScriptProfiler(LSL_Integer flags)
11038 {
11039 m_host.AddScriptLPS(1);
11040 NotImplemented("llRegionSayTo");
11041
11042 }
11043
11044 public void llScriptProfiler( LSL_Integer flags )
11045 { 11164 {
11046 m_host.AddScriptLPS(1); 11165 m_host.AddScriptLPS(1);
11047 //NotImplemented("llScriptProfiler"); 11166 //NotImplemented("llScriptProfiler");
11048
11049 } 11167 }
11050 11168
11051 public void llSetSoundQueueing(int queue) 11169 public void llSetSoundQueueing(int queue)
@@ -11164,9 +11282,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11164 } 11282 }
11165 } 11283 }
11166 11284
11167 public static string GetLine(UUID assetID, int line, int maxLength) 11285 /// <summary>
11286 /// Get a notecard line.
11287 /// </summary>
11288 /// <param name="assetID"></param>
11289 /// <param name="line">Lines start at index 0</param>
11290 /// <returns></returns>
11291 public static string GetLine(UUID assetID, int lineNumber)
11168 { 11292 {
11169 if (line < 0) 11293 if (lineNumber < 0)
11170 return ""; 11294 return "";
11171 11295
11172 string data; 11296 string data;
@@ -11178,17 +11302,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11178 { 11302 {
11179 m_Notecards[assetID].lastRef = DateTime.Now; 11303 m_Notecards[assetID].lastRef = DateTime.Now;
11180 11304
11181 if (line >= m_Notecards[assetID].text.Length) 11305 if (lineNumber >= m_Notecards[assetID].text.Length)
11182 return "\n\n\n"; 11306 return "\n\n\n";
11183 11307
11184 data = m_Notecards[assetID].text[line]; 11308 data = m_Notecards[assetID].text[lineNumber];
11185 if (data.Length > maxLength)
11186 data = data.Substring(0, maxLength);
11187 11309
11188 return data; 11310 return data;
11189 } 11311 }
11190 } 11312 }
11191 11313
11314 /// <summary>
11315 /// Get a notecard line.
11316 /// </summary>
11317 /// <param name="assetID"></param>
11318 /// <param name="line">Lines start at index 0</param>
11319 /// <param name="maxLength">Maximum length of the returned line. Longer lines will be truncated</para>
11320 /// <returns></returns>
11321 public static string GetLine(UUID assetID, int lineNumber, int maxLength)
11322 {
11323 string line = GetLine(assetID, lineNumber);
11324
11325 if (line.Length > maxLength)
11326 line = line.Substring(0, maxLength);
11327
11328 return line;
11329 }
11330
11192 public static void CacheCheck() 11331 public static void CacheCheck()
11193 { 11332 {
11194 foreach (UUID key in new List<UUID>(m_Notecards.Keys)) 11333 foreach (UUID key in new List<UUID>(m_Notecards.Keys))
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
index 645566e..80daf5b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
@@ -130,7 +130,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
130 int idx = 0; 130 int idx = 0;
131 while (idx < rules.Length) 131 while (idx < rules.Length)
132 { 132 {
133 uint rule = (uint)rules.GetLSLIntegerItem(idx); 133 LSL_Integer ruleInt = rules.GetLSLIntegerItem(idx);
134 uint rule = (uint)ruleInt;
134 LSL_List toadd = new LSL_List(); 135 LSL_List toadd = new LSL_List();
135 136
136 switch (rule) 137 switch (rule)
@@ -247,7 +248,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
247 248
248 if (toadd.Length > 0) 249 if (toadd.Length > 0)
249 { 250 {
250 values.Add(rule); 251 values.Add(ruleInt);
251 values.Add(toadd.Data[0]); 252 values.Add(toadd.Data[0]);
252 } 253 }
253 idx++; 254 idx++;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 6d2efce..9ec8a42 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -28,11 +28,16 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 33using System.Runtime.Remoting.Lifetime;
32using System.Text; 34using System.Text;
33using System.Net; 35using System.Net;
34using System.Threading; 36using System.Threading;
37using System.Xml;
38using log4net;
35using OpenMetaverse; 39using OpenMetaverse;
40using OpenMetaverse.StructuredData;
36using Nini.Config; 41using Nini.Config;
37using OpenSim; 42using OpenSim;
38using OpenSim.Framework; 43using OpenSim.Framework;
@@ -119,6 +124,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
119 [Serializable] 124 [Serializable]
120 public class OSSL_Api : MarshalByRefObject, IOSSL_Api, IScriptApi 125 public class OSSL_Api : MarshalByRefObject, IOSSL_Api, IScriptApi
121 { 126 {
127// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
128
122 internal IScriptEngine m_ScriptEngine; 129 internal IScriptEngine m_ScriptEngine;
123 internal ILSL_Api m_LSL_Api = null; // get a reference to the LSL API so we can call methods housed there 130 internal ILSL_Api m_LSL_Api = null; // get a reference to the LSL API so we can call methods housed there
124 internal SceneObjectPart m_host; 131 internal SceneObjectPart m_host;
@@ -357,20 +364,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
357 System.Threading.Thread.Sleep(delay); 364 System.Threading.Thread.Sleep(delay);
358 } 365 }
359 366
360 //
361 // OpenSim functions
362 //
363 public LSL_Integer osSetTerrainHeight(int x, int y, double val) 367 public LSL_Integer osSetTerrainHeight(int x, int y, double val)
364 { 368 {
365 CheckThreatLevel(ThreatLevel.High, "osSetTerrainHeight"); 369 CheckThreatLevel(ThreatLevel.High, "osSetTerrainHeight");
366 return SetTerrainHeight(x, y, val); 370 return SetTerrainHeight(x, y, val);
367 } 371 }
372
368 public LSL_Integer osTerrainSetHeight(int x, int y, double val) 373 public LSL_Integer osTerrainSetHeight(int x, int y, double val)
369 { 374 {
370 CheckThreatLevel(ThreatLevel.High, "osTerrainSetHeight"); 375 CheckThreatLevel(ThreatLevel.High, "osTerrainSetHeight");
371 OSSLDeprecated("osTerrainSetHeight", "osSetTerrainHeight"); 376 OSSLDeprecated("osTerrainSetHeight", "osSetTerrainHeight");
372 return SetTerrainHeight(x, y, val); 377 return SetTerrainHeight(x, y, val);
373 } 378 }
379
374 private LSL_Integer SetTerrainHeight(int x, int y, double val) 380 private LSL_Integer SetTerrainHeight(int x, int y, double val)
375 { 381 {
376 m_host.AddScriptLPS(1); 382 m_host.AddScriptLPS(1);
@@ -393,12 +399,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
393 CheckThreatLevel(ThreatLevel.None, "osGetTerrainHeight"); 399 CheckThreatLevel(ThreatLevel.None, "osGetTerrainHeight");
394 return GetTerrainHeight(x, y); 400 return GetTerrainHeight(x, y);
395 } 401 }
402
396 public LSL_Float osTerrainGetHeight(int x, int y) 403 public LSL_Float osTerrainGetHeight(int x, int y)
397 { 404 {
398 CheckThreatLevel(ThreatLevel.None, "osTerrainGetHeight"); 405 CheckThreatLevel(ThreatLevel.None, "osTerrainGetHeight");
399 OSSLDeprecated("osTerrainGetHeight", "osGetTerrainHeight"); 406 OSSLDeprecated("osTerrainGetHeight", "osGetTerrainHeight");
400 return GetTerrainHeight(x, y); 407 return GetTerrainHeight(x, y);
401 } 408 }
409
402 private LSL_Float GetTerrainHeight(int x, int y) 410 private LSL_Float GetTerrainHeight(int x, int y)
403 { 411 {
404 m_host.AddScriptLPS(1); 412 m_host.AddScriptLPS(1);
@@ -673,13 +681,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
673 CheckThreatLevel(ThreatLevel.VeryLow, "osSetPrimFloatOnWater"); 681 CheckThreatLevel(ThreatLevel.VeryLow, "osSetPrimFloatOnWater");
674 682
675 m_host.AddScriptLPS(1); 683 m_host.AddScriptLPS(1);
676 if (m_host.ParentGroup != null) 684
677 { 685 m_host.ParentGroup.RootPart.SetFloatOnWater(floatYN);
678 if (m_host.ParentGroup.RootPart != null)
679 {
680 m_host.ParentGroup.RootPart.SetFloatOnWater(floatYN);
681 }
682 }
683 } 686 }
684 687
685 // Teleport functions 688 // Teleport functions
@@ -870,7 +873,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
870 ScenePresence target = (ScenePresence)World.Entities[avatarID]; 873 ScenePresence target = (ScenePresence)World.Entities[avatarID];
871 if (target != null) 874 if (target != null)
872 { 875 {
873 UUID animID=UUID.Zero; 876 UUID animID = UUID.Zero;
874 m_host.TaskInventory.LockItemsForRead(true); 877 m_host.TaskInventory.LockItemsForRead(true);
875 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 878 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
876 { 879 {
@@ -1028,6 +1031,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1028 drawList += "PenColor " + color + "; "; 1031 drawList += "PenColor " + color + "; ";
1029 return drawList; 1032 return drawList;
1030 } 1033 }
1034
1031 // Deprecated 1035 // Deprecated
1032 public string osSetPenColour(string drawList, string colour) 1036 public string osSetPenColour(string drawList, string colour)
1033 { 1037 {
@@ -1189,11 +1193,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1189 OSSLDeprecated("osSunGetParam", "osGetSunParam"); 1193 OSSLDeprecated("osSunGetParam", "osGetSunParam");
1190 return GetSunParam(param); 1194 return GetSunParam(param);
1191 } 1195 }
1196
1192 public double osGetSunParam(string param) 1197 public double osGetSunParam(string param)
1193 { 1198 {
1194 CheckThreatLevel(ThreatLevel.None, "osGetSunParam"); 1199 CheckThreatLevel(ThreatLevel.None, "osGetSunParam");
1195 return GetSunParam(param); 1200 return GetSunParam(param);
1196 } 1201 }
1202
1197 private double GetSunParam(string param) 1203 private double GetSunParam(string param)
1198 { 1204 {
1199 m_host.AddScriptLPS(1); 1205 m_host.AddScriptLPS(1);
@@ -1215,11 +1221,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1215 OSSLDeprecated("osSunSetParam", "osSetSunParam"); 1221 OSSLDeprecated("osSunSetParam", "osSetSunParam");
1216 SetSunParam(param, value); 1222 SetSunParam(param, value);
1217 } 1223 }
1224
1218 public void osSetSunParam(string param, double value) 1225 public void osSetSunParam(string param, double value)
1219 { 1226 {
1220 CheckThreatLevel(ThreatLevel.None, "osSetSunParam"); 1227 CheckThreatLevel(ThreatLevel.None, "osSetSunParam");
1221 SetSunParam(param, value); 1228 SetSunParam(param, value);
1222 } 1229 }
1230
1223 private void SetSunParam(string param, double value) 1231 private void SetSunParam(string param, double value)
1224 { 1232 {
1225 m_host.AddScriptLPS(1); 1233 m_host.AddScriptLPS(1);
@@ -1229,10 +1237,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1229 { 1237 {
1230 module.SetSunParameter(param, value); 1238 module.SetSunParameter(param, value);
1231 } 1239 }
1232
1233 } 1240 }
1234 1241
1235
1236 public string osWindActiveModelPluginName() 1242 public string osWindActiveModelPluginName()
1237 { 1243 {
1238 CheckThreatLevel(ThreatLevel.None, "osWindActiveModelPluginName"); 1244 CheckThreatLevel(ThreatLevel.None, "osWindActiveModelPluginName");
@@ -1311,12 +1317,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1311 OSSLDeprecated(functionName, "osSetParcelDetails"); 1317 OSSLDeprecated(functionName, "osSetParcelDetails");
1312 SetParcelDetails(pos, rules, functionName); 1318 SetParcelDetails(pos, rules, functionName);
1313 } 1319 }
1320
1314 public void osSetParcelDetails(LSL_Vector pos, LSL_List rules) 1321 public void osSetParcelDetails(LSL_Vector pos, LSL_List rules)
1315 { 1322 {
1316 const string functionName = "osSetParcelDetails"; 1323 const string functionName = "osSetParcelDetails";
1317 CheckThreatLevel(ThreatLevel.High, functionName); 1324 CheckThreatLevel(ThreatLevel.High, functionName);
1318 SetParcelDetails(pos, rules, functionName); 1325 SetParcelDetails(pos, rules, functionName);
1319 } 1326 }
1327
1320 private void SetParcelDetails(LSL_Vector pos, LSL_List rules, string functionName) 1328 private void SetParcelDetails(LSL_Vector pos, LSL_List rules, string functionName)
1321 { 1329 {
1322 m_host.AddScriptLPS(1); 1330 m_host.AddScriptLPS(1);
@@ -1436,8 +1444,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1436 voiceModule.setLandSIPAddress(SIPAddress,land.LandData.GlobalID); 1444 voiceModule.setLandSIPAddress(SIPAddress,land.LandData.GlobalID);
1437 else 1445 else
1438 OSSLError("osSetParcelSIPAddress: No voice module enabled for this land"); 1446 OSSLError("osSetParcelSIPAddress: No voice module enabled for this land");
1439
1440
1441 } 1447 }
1442 1448
1443 public string osGetScriptEngineName() 1449 public string osGetScriptEngineName()
@@ -1690,8 +1696,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1690 return jsondata; 1696 return jsondata;
1691 } 1697 }
1692 1698
1693 // send a message to to object identified by the given UUID, a script in the object must implement the dataserver function 1699 /// <summary>
1694 // the dataserver function is passed the ID of the calling function and a string message 1700 /// Send a message to to object identified by the given UUID
1701 /// </summary>
1702 /// <remarks>
1703 /// A script in the object must implement the dataserver function
1704 /// the dataserver function is passed the ID of the calling function and a string message
1705 /// </remarks>
1706 /// <param name="objectUUID"></param>
1707 /// <param name="message"></param>
1695 public void osMessageObject(LSL_Key objectUUID, string message) 1708 public void osMessageObject(LSL_Key objectUUID, string message)
1696 { 1709 {
1697 CheckThreatLevel(ThreatLevel.Low, "osMessageObject"); 1710 CheckThreatLevel(ThreatLevel.Low, "osMessageObject");
@@ -1706,34 +1719,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1706 "dataserver", resobj, new DetectParams[0])); 1719 "dataserver", resobj, new DetectParams[0]));
1707 } 1720 }
1708 1721
1709 1722 /// <summary>
1710 // This needs ThreatLevel high. It is an excellent griefer tool, 1723 /// Write a notecard directly to the prim's inventory.
1711 // In a loop, it can cause asset bloat and DOS levels of asset 1724 /// </summary>
1712 // writes. 1725 /// <remarks>
1713 // 1726 /// This needs ThreatLevel high. It is an excellent griefer tool,
1727 /// In a loop, it can cause asset bloat and DOS levels of asset
1728 /// writes.
1729 /// </remarks>
1730 /// <param name="notecardName">The name of the notecard to write.</param>
1731 /// <param name="contents">The contents of the notecard.</param>
1714 public void osMakeNotecard(string notecardName, LSL_Types.list contents) 1732 public void osMakeNotecard(string notecardName, LSL_Types.list contents)
1715 { 1733 {
1716 CheckThreatLevel(ThreatLevel.High, "osMakeNotecard"); 1734 CheckThreatLevel(ThreatLevel.High, "osMakeNotecard");
1717 m_host.AddScriptLPS(1); 1735 m_host.AddScriptLPS(1);
1718 1736
1719 // Create new asset 1737 StringBuilder notecardData = new StringBuilder();
1720 AssetBase asset = new AssetBase(UUID.Random(), notecardName, (sbyte)AssetType.Notecard, m_host.OwnerID.ToString());
1721 asset.Description = "Script Generated Notecard";
1722 string notecardData = String.Empty;
1723 1738
1724 for (int i = 0; i < contents.Length; i++) { 1739 for (int i = 0; i < contents.Length; i++)
1725 notecardData += contents.GetLSLStringItem(i) + "\n"; 1740 notecardData.Append((string)(contents.GetLSLStringItem(i) + "\n"));
1726 } 1741
1742 SaveNotecard(notecardName, "Script generated notecard", notecardData.ToString(), false);
1743 }
1727 1744
1728 int textLength = notecardData.Length; 1745 /// <summary>
1729 notecardData = "Linden text version 2\n{\nLLEmbeddedItems version 1\n{\ncount 0\n}\nText length " 1746 /// Save a notecard to prim inventory.
1730 + textLength.ToString() + "\n" + notecardData + "}\n"; 1747 /// </summary>
1748 /// <param name="name"></param>
1749 /// <param name="description">Description of notecard</param>
1750 /// <param name="notecardData"></param>
1751 /// <param name="forceSameName">
1752 /// If true, then if an item exists with the same name, it is replaced.
1753 /// If false, then a new item is created witha slightly different name (e.g. name 1)
1754 /// </param>
1755 /// <returns>Prim inventory item created.</returns>
1756 protected TaskInventoryItem SaveNotecard(string name, string description, string data, bool forceSameName)
1757 {
1758 // Create new asset
1759 AssetBase asset = new AssetBase(UUID.Random(), name, (sbyte)AssetType.Notecard, m_host.OwnerID.ToString());
1760 asset.Description = description;
1761
1762 int textLength = data.Length;
1763 data
1764 = "Linden text version 2\n{\nLLEmbeddedItems version 1\n{\ncount 0\n}\nText length "
1765 + textLength.ToString() + "\n" + data + "}\n";
1731 1766
1732 asset.Data = Util.UTF8.GetBytes(notecardData); 1767 asset.Data = Util.UTF8.GetBytes(data);
1733 World.AssetService.Store(asset); 1768 World.AssetService.Store(asset);
1734 1769
1735 // Create Task Entry 1770 // Create Task Entry
1736 TaskInventoryItem taskItem=new TaskInventoryItem(); 1771 TaskInventoryItem taskItem = new TaskInventoryItem();
1737 1772
1738 taskItem.ResetIDs(m_host.UUID); 1773 taskItem.ResetIDs(m_host.UUID);
1739 taskItem.ParentID = m_host.UUID; 1774 taskItem.ParentID = m_host.UUID;
@@ -1755,29 +1790,54 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1755 taskItem.PermsMask = 0; 1790 taskItem.PermsMask = 0;
1756 taskItem.AssetID = asset.FullID; 1791 taskItem.AssetID = asset.FullID;
1757 1792
1758 m_host.Inventory.AddInventoryItem(taskItem, false); 1793 if (forceSameName)
1794 m_host.Inventory.AddInventoryItemExclusive(taskItem, false);
1795 else
1796 m_host.Inventory.AddInventoryItem(taskItem, false);
1797
1798 return taskItem;
1759 } 1799 }
1760 1800
1801 /// <summary>
1802 /// Load the notecard data found at the given prim inventory item name or asset uuid.
1803 /// </summary>
1804 /// <param name="notecardNameOrUuid"></param>
1805 /// <returns>The text loaded. Null if no notecard was found.</returns>
1806 protected string LoadNotecard(string notecardNameOrUuid)
1807 {
1808 UUID assetID = CacheNotecard(notecardNameOrUuid);
1809 StringBuilder notecardData = new StringBuilder();
1761 1810
1762 /*Instead of using the LSL Dataserver event to pull notecard data, 1811 for (int count = 0; count < NotecardCache.GetLines(assetID); count++)
1763 this will simply read the requested line and return its data as a string. 1812 {
1813 string line = NotecardCache.GetLine(assetID, count) + "\n";
1764 1814
1765 Warning - due to the synchronous method this function uses to fetch assets, its use 1815// m_log.DebugFormat("[OSSL]: From notecard {0} loading line {1}", notecardNameOrUuid, line);
1766 may be dangerous and unreliable while running in grid mode. 1816
1767 */ 1817 notecardData.Append(line);
1768 public string osGetNotecardLine(string name, int line) 1818 }
1769 { 1819
1770 CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNotecardLine"); 1820 return notecardData.ToString();
1771 m_host.AddScriptLPS(1); 1821 }
1772 1822
1823 /// <summary>
1824 /// Cache a notecard's contents.
1825 /// </summary>
1826 /// <param name="notecardNameOrUuid"></param>
1827 /// <returns>
1828 /// The asset id of the notecard, which is used for retrieving the cached data.
1829 /// UUID.Zero if no asset could be found.
1830 /// </returns>
1831 protected UUID CacheNotecard(string notecardNameOrUuid)
1832 {
1773 UUID assetID = UUID.Zero; 1833 UUID assetID = UUID.Zero;
1774 1834
1775 if (!UUID.TryParse(name, out assetID)) 1835 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1776 { 1836 {
1777 m_host.TaskInventory.LockItemsForRead(true); 1837 m_host.TaskInventory.LockItemsForRead(true);
1778 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1838 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1779 { 1839 {
1780 if (item.Type == 7 && item.Name == name) 1840 if (item.Type == 7 && item.Name == notecardNameOrUuid)
1781 { 1841 {
1782 assetID = item.AssetID; 1842 assetID = item.AssetID;
1783 } 1843 }
@@ -1786,118 +1846,100 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1786 } 1846 }
1787 1847
1788 if (assetID == UUID.Zero) 1848 if (assetID == UUID.Zero)
1789 { 1849 return UUID.Zero;
1790 OSSLShoutError("Notecard '" + name + "' could not be found.");
1791 return "ERROR!";
1792 }
1793 1850
1794 if (!NotecardCache.IsCached(assetID)) 1851 if (!NotecardCache.IsCached(assetID))
1795 { 1852 {
1796 AssetBase a = World.AssetService.Get(assetID.ToString()); 1853 AssetBase a = World.AssetService.Get(assetID.ToString());
1797 if (a != null)
1798 {
1799 System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
1800 string data = enc.GetString(a.Data);
1801 NotecardCache.Cache(assetID, data);
1802 }
1803 else
1804 {
1805 OSSLShoutError("Notecard '" + name + "' could not be found.");
1806 return "ERROR!";
1807 }
1808 };
1809 1854
1810 return NotecardCache.GetLine(assetID, line, 255); 1855 if (a == null)
1856 return UUID.Zero;
1811 1857
1858 System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
1859 string data = enc.GetString(a.Data);
1860 NotecardCache.Cache(assetID, data);
1861 };
1812 1862
1863 return assetID;
1813 } 1864 }
1814 1865
1815 /*Instead of using the LSL Dataserver event to pull notecard data line by line, 1866 /// <summary>
1816 this will simply read the entire notecard and return its data as a string. 1867 /// Directly get an entire notecard at once.
1868 /// </summary>
1869 /// <remarks>
1870 /// Instead of using the LSL Dataserver event to pull notecard data
1871 /// this will simply read the entire notecard and return its data as a string.
1872 ///
1873 /// Warning - due to the synchronous method this function uses to fetch assets, its use
1874 /// may be dangerous and unreliable while running in grid mode.
1875 /// </remarks>
1876 /// <param name="name">Name of the notecard or its asset id</param>
1877 /// <param name="line">The line number to read. The first line is line 0</param>
1878 /// <returns>Notecard line</returns>
1879 public string osGetNotecardLine(string name, int line)
1880 {
1881 CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNotecardLine");
1882 m_host.AddScriptLPS(1);
1817 1883
1818 Warning - due to the synchronous method this function uses to fetch assets, its use 1884 UUID assetID = CacheNotecard(name);
1819 may be dangerous and unreliable while running in grid mode.
1820 */
1821 1885
1886 if (assetID == UUID.Zero)
1887 {
1888 OSSLShoutError("Notecard '" + name + "' could not be found.");
1889 return "ERROR!";
1890 }
1891
1892 return NotecardCache.GetLine(assetID, line);
1893 }
1894
1895 /// <summary>
1896 /// Get an entire notecard at once.
1897 /// </summary>
1898 /// <remarks>
1899 /// Instead of using the LSL Dataserver event to pull notecard data line by line,
1900 /// this will simply read the entire notecard and return its data as a string.
1901 ///
1902 /// Warning - due to the synchronous method this function uses to fetch assets, its use
1903 /// may be dangerous and unreliable while running in grid mode.
1904 /// </remarks>
1905 /// <param name="name">Name of the notecard or its asset id</param>
1906 /// <returns>Notecard text</returns>
1822 public string osGetNotecard(string name) 1907 public string osGetNotecard(string name)
1823 { 1908 {
1824 CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNotecard"); 1909 CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNotecard");
1825 m_host.AddScriptLPS(1); 1910 m_host.AddScriptLPS(1);
1826 1911
1827 UUID assetID = UUID.Zero; 1912 string text = LoadNotecard(name);
1828 string NotecardData = "";
1829 1913
1830 if (!UUID.TryParse(name, out assetID)) 1914 if (text == null)
1831 {
1832 m_host.TaskInventory.LockItemsForRead(true);
1833 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1834 {
1835 if (item.Type == 7 && item.Name == name)
1836 {
1837 assetID = item.AssetID;
1838 }
1839 }
1840 m_host.TaskInventory.LockItemsForRead(false);
1841 }
1842
1843 if (assetID == UUID.Zero)
1844 { 1915 {
1845 OSSLShoutError("Notecard '" + name + "' could not be found."); 1916 OSSLShoutError("Notecard '" + name + "' could not be found.");
1846 return "ERROR!"; 1917 return "ERROR!";
1847 } 1918 }
1848 1919 else
1849 if (!NotecardCache.IsCached(assetID))
1850 {
1851 AssetBase a = World.AssetService.Get(assetID.ToString());
1852 if (a != null)
1853 {
1854 System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
1855 string data = enc.GetString(a.Data);
1856 NotecardCache.Cache(assetID, data);
1857 }
1858 else
1859 {
1860 OSSLShoutError("Notecard '" + name + "' could not be found.");
1861 return "ERROR!";
1862 }
1863 };
1864
1865 for (int count = 0; count < NotecardCache.GetLines(assetID); count++)
1866 { 1920 {
1867 NotecardData += NotecardCache.GetLine(assetID, count, 255) + "\n"; 1921 return text;
1868 } 1922 }
1869
1870 return NotecardData;
1871
1872
1873 } 1923 }
1874 1924
1875 /*Instead of using the LSL Dataserver event to pull notecard data, 1925 /// <summary>
1876 this will simply read the number of note card lines and return this data as an integer. 1926 /// Get the number of lines in the given notecard.
1877 1927 /// </summary>
1878 Warning - due to the synchronous method this function uses to fetch assets, its use 1928 /// <remarks>
1879 may be dangerous and unreliable while running in grid mode. 1929 /// Instead of using the LSL Dataserver event to pull notecard data,
1880 */ 1930 /// this will simply read the number of note card lines and return this data as an integer.
1881 1931 ///
1932 /// Warning - due to the synchronous method this function uses to fetch assets, its use
1933 /// may be dangerous and unreliable while running in grid mode.
1934 /// </remarks>
1935 /// <param name="name">Name of the notecard or its asset id</param>
1936 /// <returns></returns>
1882 public int osGetNumberOfNotecardLines(string name) 1937 public int osGetNumberOfNotecardLines(string name)
1883 { 1938 {
1884 CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNumberOfNotecardLines"); 1939 CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNumberOfNotecardLines");
1885 m_host.AddScriptLPS(1); 1940 m_host.AddScriptLPS(1);
1886 1941
1887 UUID assetID = UUID.Zero; 1942 UUID assetID = CacheNotecard(name);
1888
1889 if (!UUID.TryParse(name, out assetID))
1890 {
1891 m_host.TaskInventory.LockItemsForRead(true);
1892 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1893 {
1894 if (item.Type == 7 && item.Name == name)
1895 {
1896 assetID = item.AssetID;
1897 }
1898 }
1899 m_host.TaskInventory.LockItemsForRead(false);
1900 }
1901 1943
1902 if (assetID == UUID.Zero) 1944 if (assetID == UUID.Zero)
1903 { 1945 {
@@ -1905,25 +1947,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1905 return -1; 1947 return -1;
1906 } 1948 }
1907 1949
1908 if (!NotecardCache.IsCached(assetID))
1909 {
1910 AssetBase a = World.AssetService.Get(assetID.ToString());
1911 if (a != null)
1912 {
1913 System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
1914 string data = enc.GetString(a.Data);
1915 NotecardCache.Cache(assetID, data);
1916 }
1917 else
1918 {
1919 OSSLShoutError("Notecard '" + name + "' could not be found.");
1920 return -1;
1921 }
1922 };
1923
1924 return NotecardCache.GetLines(assetID); 1950 return NotecardCache.GetLines(assetID);
1925
1926
1927 } 1951 }
1928 1952
1929 public string osAvatarName2Key(string firstname, string lastname) 1953 public string osAvatarName2Key(string firstname, string lastname)
@@ -1962,15 +1986,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1962 { 1986 {
1963 return ""; 1987 return "";
1964 } 1988 }
1965
1966 } 1989 }
1967 1990
1991 /// <summary>
1992 /// Get the nickname of this grid, as set in the [GridInfo] config section.
1993 /// </summary>
1994 /// <remarks>
1968 /// Threat level is Moderate because intentional abuse, for instance 1995 /// Threat level is Moderate because intentional abuse, for instance
1969 /// scripts that are written to be malicious only on one grid, 1996 /// scripts that are written to be malicious only on one grid,
1970 /// for instance in a HG scenario, are a distinct possibility. 1997 /// for instance in a HG scenario, are a distinct possibility.
1971 /// 1998 /// </remarks>
1972 /// Use value from the config file and return it. 1999 /// <returns></returns>
1973 ///
1974 public string osGetGridNick() 2000 public string osGetGridNick()
1975 { 2001 {
1976 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridNick"); 2002 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridNick");
@@ -2037,7 +2063,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2037 // Find matches beginning at start position 2063 // Find matches beginning at start position
2038 Regex matcher = new Regex(pattern); 2064 Regex matcher = new Regex(pattern);
2039 Match match = matcher.Match(src, start); 2065 Match match = matcher.Match(src, start);
2040 if (match.Success) 2066 while (match.Success)
2041 { 2067 {
2042 foreach (System.Text.RegularExpressions.Group g in match.Groups) 2068 foreach (System.Text.RegularExpressions.Group g in match.Groups)
2043 { 2069 {
@@ -2047,6 +2073,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2047 result.Add(new LSL_Integer(g.Index)); 2073 result.Add(new LSL_Integer(g.Index));
2048 } 2074 }
2049 } 2075 }
2076
2077 match = match.NextMatch();
2050 } 2078 }
2051 2079
2052 return result; 2080 return result;
@@ -2076,12 +2104,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2076 return World.RegionInfo.RegionSettings.LoadedCreationID; 2104 return World.RegionInfo.RegionSettings.LoadedCreationID;
2077 } 2105 }
2078 2106
2079 // Threat level is 'Low' because certain users could possibly be tricked into 2107 /// <summary>
2080 // dropping an unverified script into one of their own objects, which could 2108 /// Get the primitive parameters of a linked prim.
2081 // then gather the physical construction details of the object and transmit it 2109 /// </summary>
2082 // to an unscrupulous third party, thus permitting unauthorized duplication of 2110 /// <remarks>
2083 // the object's form. 2111 /// Threat level is 'Low' because certain users could possibly be tricked into
2084 // 2112 /// dropping an unverified script into one of their own objects, which could
2113 /// then gather the physical construction details of the object and transmit it
2114 /// to an unscrupulous third party, thus permitting unauthorized duplication of
2115 /// the object's form.
2116 /// </remarks>
2117 /// <param name="linknumber"></param>
2118 /// <param name="rules"></param>
2119 /// <returns></returns>
2085 public LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules) 2120 public LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules)
2086 { 2121 {
2087 CheckThreatLevel(ThreatLevel.High, "osGetLinkPrimitiveParams"); 2122 CheckThreatLevel(ThreatLevel.High, "osGetLinkPrimitiveParams");
@@ -2096,25 +2131,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2096 return retVal; 2131 return retVal;
2097 } 2132 }
2098 2133
2099 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, LSL_Key cloneFrom) 2134 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard)
2100 { 2135 {
2101 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2136 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2102 //QueueUserWorkItem
2103 2137
2104 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2138 INPCModule module = World.RequestModuleInterface<INPCModule>();
2105 if (module != null) 2139 if (module != null)
2106 { 2140 {
2141 AvatarAppearance appearance = null;
2142
2143 UUID id;
2144 if (UUID.TryParse(notecard, out id))
2145 {
2146 ScenePresence clonePresence = World.GetScenePresence(id);
2147 if (clonePresence != null)
2148 appearance = clonePresence.Appearance;
2149 }
2150
2151 if (appearance == null)
2152 {
2153 string appearanceSerialized = LoadNotecard(notecard);
2154
2155 if (appearanceSerialized != null)
2156 {
2157 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2158 appearance = new AvatarAppearance();
2159 appearance.Unpack(appearanceOsd);
2160 }
2161 }
2162
2163 if (appearance == null)
2164 return new LSL_Key(UUID.Zero.ToString());
2165
2107 UUID x = module.CreateNPC(firstname, 2166 UUID x = module.CreateNPC(firstname,
2108 lastname, 2167 lastname,
2109 new Vector3((float) position.x, (float) position.y, (float) position.z), 2168 new Vector3((float) position.x, (float) position.y, (float) position.z),
2110 World, 2169 World,
2111 new UUID(cloneFrom)); 2170 appearance);
2112 2171
2113 return new LSL_Key(x.ToString()); 2172 return new LSL_Key(x.ToString());
2114 } 2173 }
2174
2175 return new LSL_Key(UUID.Zero.ToString());
2176 }
2177
2178 /// <summary>
2179 /// Save the current appearance of the NPC permanently to the named notecard.
2180 /// </summary>
2181 /// <param name="avatar"></param>
2182 /// <param name="notecard">The name of the notecard to which to save the appearance.</param>
2183 /// <returns>The asset ID of the notecard saved.</returns>
2184 public LSL_Key osNpcSaveAppearance(LSL_Key npc, string notecard)
2185 {
2186 CheckThreatLevel(ThreatLevel.High, "osNpcSaveAppearance");
2187
2188 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2189
2190 if (npcModule != null)
2191 {
2192 UUID npcId;
2193 if (!UUID.TryParse(npc.m_string, out npcId))
2194 return new LSL_Key(UUID.Zero.ToString());
2195
2196 if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene))
2197 return new LSL_Key(UUID.Zero.ToString());
2198
2199 return SaveAppearanceToNotecard(npcId, notecard);
2200 }
2201
2115 return new LSL_Key(UUID.Zero.ToString()); 2202 return new LSL_Key(UUID.Zero.ToString());
2116 } 2203 }
2117 2204
2205 public void osNpcLoadAppearance(LSL_Key npc, string notecard)
2206 {
2207 CheckThreatLevel(ThreatLevel.High, "osNpcLoadAppearance");
2208
2209 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2210
2211 if (npcModule != null)
2212 {
2213 UUID npcId;
2214 if (!UUID.TryParse(npc.m_string, out npcId))
2215 return;
2216
2217 string appearanceSerialized = LoadNotecard(notecard);
2218 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2219// OSD a = OSDParser.DeserializeLLSDXml(appearanceSerialized);
2220// Console.WriteLine("appearanceSerialized {0}", appearanceSerialized);
2221// Console.WriteLine("a.Type {0}, a.ToString() {1}", a.Type, a);
2222 AvatarAppearance appearance = new AvatarAppearance();
2223 appearance.Unpack(appearanceOsd);
2224
2225 npcModule.SetNPCAppearance(npcId, appearance, m_host.ParentGroup.Scene);
2226 }
2227 }
2228
2229 public LSL_Vector osNpcGetPos(LSL_Key npc)
2230 {
2231 CheckThreatLevel(ThreatLevel.High, "osNpcGetPos");
2232
2233 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2234 if (npcModule != null)
2235 {
2236 UUID npcId;
2237 if (!UUID.TryParse(npc.m_string, out npcId))
2238 return new LSL_Vector(0, 0, 0);
2239
2240 if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene))
2241 return new LSL_Vector(0, 0, 0);
2242
2243 Vector3 pos = World.GetScenePresence(npcId).AbsolutePosition;
2244 return new LSL_Vector(pos.X, pos.Y, pos.Z);
2245 }
2246
2247 return new LSL_Vector(0, 0, 0);
2248 }
2249
2118 public void osNpcMoveTo(LSL_Key npc, LSL_Vector position) 2250 public void osNpcMoveTo(LSL_Key npc, LSL_Vector position)
2119 { 2251 {
2120 CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo"); 2252 CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo");
@@ -2122,11 +2254,87 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2122 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2254 INPCModule module = World.RequestModuleInterface<INPCModule>();
2123 if (module != null) 2255 if (module != null)
2124 { 2256 {
2257 UUID npcId;
2258 if (!UUID.TryParse(npc.m_string, out npcId))
2259 return;
2260
2125 Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z); 2261 Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z);
2126 module.Autopilot(new UUID(npc.m_string), World, pos); 2262 module.MoveToTarget(npcId, World, pos, false, true);
2127 } 2263 }
2128 } 2264 }
2129 2265
2266 public void osNpcMoveToTarget(LSL_Key npc, LSL_Vector target, int options)
2267 {
2268 CheckThreatLevel(ThreatLevel.High, "osNpcMoveToTarget");
2269
2270 INPCModule module = World.RequestModuleInterface<INPCModule>();
2271 if (module != null)
2272 {
2273 UUID npcId;
2274 if (!UUID.TryParse(npc.m_string, out npcId))
2275 return;
2276
2277 Vector3 pos = new Vector3((float)target.x, (float)target.y, (float)target.z);
2278 module.MoveToTarget(
2279 new UUID(npc.m_string),
2280 World,
2281 pos,
2282 (options & ScriptBaseClass.OS_NPC_NO_FLY) != 0,
2283 (options & ScriptBaseClass.OS_NPC_LAND_AT_TARGET) != 0);
2284 }
2285 }
2286
2287 public LSL_Rotation osNpcGetRot(LSL_Key npc)
2288 {
2289 CheckThreatLevel(ThreatLevel.High, "osNpcGetRot");
2290
2291 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2292 if (npcModule != null)
2293 {
2294 UUID npcId;
2295 if (!UUID.TryParse(npc.m_string, out npcId))
2296 return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W);
2297
2298 if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene))
2299 return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W);
2300
2301 ScenePresence sp = World.GetScenePresence(npcId);
2302 Quaternion rot = sp.Rotation;
2303
2304 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2305 }
2306
2307 return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W);
2308 }
2309
2310 public void osNpcSetRot(LSL_Key npc, LSL_Rotation rotation)
2311 {
2312 CheckThreatLevel(ThreatLevel.High, "osNpcSetRot");
2313
2314 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2315 if (npcModule != null)
2316 {
2317 UUID npcId;
2318 if (!UUID.TryParse(npc.m_string, out npcId))
2319 return;
2320
2321 if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene))
2322 return;
2323
2324 ScenePresence sp = World.GetScenePresence(npcId);
2325 sp.Rotation = LSL_Api.Rot2Quaternion(rotation);
2326 }
2327 }
2328
2329 public void osNpcStopMoveToTarget(LSL_Key npc)
2330 {
2331 CheckThreatLevel(ThreatLevel.VeryLow, "osNpcStopMoveTo");
2332
2333 INPCModule module = World.RequestModuleInterface<INPCModule>();
2334 if (module != null)
2335 module.StopMoveToTarget(new UUID(npc.m_string), World);
2336 }
2337
2130 public void osNpcSay(LSL_Key npc, string message) 2338 public void osNpcSay(LSL_Key npc, string message)
2131 { 2339 {
2132 CheckThreatLevel(ThreatLevel.High, "osNpcSay"); 2340 CheckThreatLevel(ThreatLevel.High, "osNpcSay");
@@ -2148,6 +2356,64 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2148 module.DeleteNPC(new UUID(npc.m_string), World); 2356 module.DeleteNPC(new UUID(npc.m_string), World);
2149 } 2357 }
2150 } 2358 }
2359
2360 /// <summary>
2361 /// Save the current appearance of the script owner permanently to the named notecard.
2362 /// </summary>
2363 /// <param name="notecard">The name of the notecard to which to save the appearance.</param>
2364 /// <returns>The asset ID of the notecard saved.</returns>
2365 public LSL_Key osOwnerSaveAppearance(string notecard)
2366 {
2367 CheckThreatLevel(ThreatLevel.High, "osOwnerSaveAppearance");
2368
2369 return SaveAppearanceToNotecard(m_host.OwnerID, notecard);
2370 }
2371
2372 public LSL_Key osAgentSaveAppearance(LSL_Key avatarId, string notecard)
2373 {
2374 CheckThreatLevel(ThreatLevel.VeryHigh, "osAgentSaveAppearance");
2375
2376 return SaveAppearanceToNotecard(avatarId, notecard);
2377 }
2378
2379 protected LSL_Key SaveAppearanceToNotecard(ScenePresence sp, string notecard)
2380 {
2381 IAvatarFactory appearanceModule = World.RequestModuleInterface<IAvatarFactory>();
2382
2383 if (appearanceModule != null)
2384 {
2385 appearanceModule.SaveBakedTextures(sp.UUID);
2386 OSDMap appearancePacked = sp.Appearance.Pack();
2387
2388 TaskInventoryItem item
2389 = SaveNotecard(notecard, "Avatar Appearance", Util.GetFormattedXml(appearancePacked as OSD), true);
2390
2391 return new LSL_Key(item.AssetID.ToString());
2392 }
2393 else
2394 {
2395 return new LSL_Key(UUID.Zero.ToString());
2396 }
2397 }
2398
2399 protected LSL_Key SaveAppearanceToNotecard(UUID avatarId, string notecard)
2400 {
2401 ScenePresence sp = World.GetScenePresence(avatarId);
2402
2403 if (sp == null || sp.IsChildAgent)
2404 return new LSL_Key(UUID.Zero.ToString());
2405
2406 return SaveAppearanceToNotecard(sp, notecard);
2407 }
2408
2409 protected LSL_Key SaveAppearanceToNotecard(LSL_Key rawAvatarId, string notecard)
2410 {
2411 UUID avatarId;
2412 if (!UUID.TryParse(rawAvatarId, out avatarId))
2413 return new LSL_Key(UUID.Zero.ToString());
2414
2415 return SaveAppearanceToNotecard(avatarId, notecard);
2416 }
2151 2417
2152 /// <summary> 2418 /// <summary>
2153 /// Get current region's map texture UUID 2419 /// Get current region's map texture UUID
@@ -2357,10 +2623,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2357 obj.Shape.ProjectionFocus = (float)focus; 2623 obj.Shape.ProjectionFocus = (float)focus;
2358 obj.Shape.ProjectionAmbiance = (float)amb; 2624 obj.Shape.ProjectionAmbiance = (float)amb;
2359 2625
2360
2361 obj.ParentGroup.HasGroupChanged = true; 2626 obj.ParentGroup.HasGroupChanged = true;
2362 obj.ScheduleFullUpdate(); 2627 obj.ScheduleFullUpdate();
2363
2364 } 2628 }
2365 2629
2366 /// <summary> 2630 /// <summary>
@@ -2385,6 +2649,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2385 } 2649 }
2386 } 2650 }
2387 }); 2651 });
2652
2388 return result; 2653 return result;
2389 } 2654 }
2390 2655
@@ -2404,4 +2669,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2404 return date.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ"); 2669 return date.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ");
2405 } 2670 }
2406 } 2671 }
2407} 2672} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index d695a0c..6de0773 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -304,12 +304,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
304 304
305// Quaternion q = SensePoint.RotationOffset; 305// Quaternion q = SensePoint.RotationOffset;
306 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation! 306 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
307 if (SensePoint.ParentGroup.RootPart.IsAttachment) 307 if (SensePoint.ParentGroup.IsAttachment)
308 { 308 {
309 // In attachments, the sensor cone always orients with the 309 // In attachments, the sensor cone always orients with the
310 // avatar rotation. This may include a nonzero elevation if 310 // avatar rotation. This may include a nonzero elevation if
311 // in mouselook. 311 // in mouselook.
312 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar); 312 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
313 fromRegionPos = avatar.AbsolutePosition; 313 fromRegionPos = avatar.AbsolutePosition;
314 q = avatar.Rotation; 314 q = avatar.Rotation;
315 } 315 }
@@ -354,7 +354,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
354 objtype = 0; 354 objtype = 0;
355 355
356 part = ((SceneObjectGroup)ent).RootPart; 356 part = ((SceneObjectGroup)ent).RootPart;
357 if (part.AttachmentPoint != 0) // Attached so ignore 357 if (part.ParentGroup.AttachmentPoint != 0) // Attached so ignore
358 continue; 358 continue;
359 359
360 if (part.Inventory.ContainsScripts()) 360 if (part.Inventory.ContainsScripts())
@@ -425,13 +425,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
425 Vector3 fromRegionPos = SensePoint.AbsolutePosition; 425 Vector3 fromRegionPos = SensePoint.AbsolutePosition;
426 426
427 Quaternion q = SensePoint.RotationOffset; 427 Quaternion q = SensePoint.RotationOffset;
428 if (SensePoint.ParentGroup.RootPart.IsAttachment) 428 if (SensePoint.ParentGroup.IsAttachment)
429 { 429 {
430 // In attachments, the sensor cone always orients with the 430 // In attachments, the sensor cone always orients with the
431 // avatar rotation. This may include a nonzero elevation if 431 // avatar rotation. This may include a nonzero elevation if
432 // in mouselook. 432 // in mouselook.
433 433 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
434 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
435 fromRegionPos = avatar.AbsolutePosition; 434 fromRegionPos = avatar.AbsolutePosition;
436 q = avatar.Rotation; 435 q = avatar.Rotation;
437 } 436 }
@@ -439,7 +438,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
439 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 438 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
440 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); 439 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
441 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); 440 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
442 bool attached = (SensePoint.AttachmentPoint != 0); 441 bool attached = (SensePoint.ParentGroup.AttachmentPoint != 0);
443 Vector3 toRegionPos; 442 Vector3 toRegionPos;
444 double dis; 443 double dis;
445 444
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index ce13d6b..7c388fe 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -60,6 +60,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
60 LSL_String llBase64ToString(string str); 60 LSL_String llBase64ToString(string str);
61 void llBreakAllLinks(); 61 void llBreakAllLinks();
62 void llBreakLink(int linknum); 62 void llBreakLink(int linknum);
63 LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options);
63 LSL_Integer llCeil(double f); 64 LSL_Integer llCeil(double f);
64 void llClearCameraParams(); 65 void llClearCameraParams();
65 LSL_Integer llClearPrimMedia(LSL_Integer face); 66 LSL_Integer llClearPrimMedia(LSL_Integer face);
@@ -271,6 +272,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
271 void llPushObject(string target, LSL_Vector impulse, LSL_Vector ang_impulse, int local); 272 void llPushObject(string target, LSL_Vector impulse, LSL_Vector ang_impulse, int local);
272 void llRefreshPrimURL(); 273 void llRefreshPrimURL();
273 void llRegionSay(int channelID, string text); 274 void llRegionSay(int channelID, string text);
275 void llRegionSayTo(string target, int channelID, string text);
274 void llReleaseCamera(string avatar); 276 void llReleaseCamera(string avatar);
275 void llReleaseControls(); 277 void llReleaseControls();
276 void llReleaseURL(string url); 278 void llReleaseURL(string url);
@@ -405,7 +407,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
405 LSL_String llXorBase64StringsCorrect(string str1, string str2); 407 LSL_String llXorBase64StringsCorrect(string str1, string str2);
406 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link); 408 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
407 409
408 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 410 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
409 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 411 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
410 } 412 }
411} 413}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 5a809e6..5ddba60 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -168,12 +168,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
168 168
169 LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules); 169 LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules);
170 170
171 171 key osNpcCreate(string user, string name, vector position, string notecard);
172 key osNpcCreate(string user, string name, vector position, key cloneFrom); 172 LSL_Key osNpcSaveAppearance(key npc, string notecard);
173 void osNpcLoadAppearance(key npc, string notecard);
174 vector osNpcGetPos(key npc);
173 void osNpcMoveTo(key npc, vector position); 175 void osNpcMoveTo(key npc, vector position);
176 void osNpcMoveToTarget(key npc, vector target, int options);
177 rotation osNpcGetRot(key npc);
178 void osNpcSetRot(LSL_Key npc, rotation rot);
179 void osNpcStopMoveToTarget(LSL_Key npc);
174 void osNpcSay(key npc, string message); 180 void osNpcSay(key npc, string message);
175 void osNpcRemove(key npc); 181 void osNpcRemove(key npc);
176 182
183 LSL_Key osOwnerSaveAppearance(string notecard);
184 LSL_Key osAgentSaveAppearance(key agentId, string notecard);
185
177 key osGetMapTexture(); 186 key osGetMapTexture();
178 key osGetRegionMapTexture(string regionName); 187 key osGetRegionMapTexture(string regionName);
179 LSL_List osGetRegionStats(); 188 LSL_List osGetRegionStats();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index 5f94ff5..59eaccb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -594,7 +594,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
594 public const int STATS_ACTIVE_SCRIPTS = 19; 594 public const int STATS_ACTIVE_SCRIPTS = 19;
595 public const int STATS_SCRIPT_LPS = 20; 595 public const int STATS_SCRIPT_LPS = 20;
596 596
597 // Constants for osNpc* functions
598 public const int OS_NPC_FLY = 0;
599 public const int OS_NPC_NO_FLY = 1;
600 public const int OS_NPC_LAND_AT_TARGET = 2;
601
597 public const string URL_REQUEST_GRANTED = "URL_REQUEST_GRANTED"; 602 public const string URL_REQUEST_GRANTED = "URL_REQUEST_GRANTED";
598 public const string URL_REQUEST_DENIED = "URL_REQUEST_DENIED"; 603 public const string URL_REQUEST_DENIED = "URL_REQUEST_DENIED";
604
605 public static readonly LSLInteger RC_REJECT_TYPES = 2;
606 public static readonly LSLInteger RC_DATA_FLAGS = 4;
607 public static readonly LSLInteger RC_MAX_HITS = 8;
608 public static readonly LSLInteger RC_DETECT_PHANTOM = 16;
609
610 public static readonly LSLInteger RC_REJECT_AGENTS = 2;
611 public static readonly LSLInteger RC_REJECT_PHYSICAL = 4;
612 public static readonly LSLInteger RC_REJECT_NONPHYSICAL = 8;
613 public static readonly LSLInteger RC_REJECT_LAND = 16;
614
615 public static readonly LSLInteger RC_GET_NORMAL = 2;
616 public static readonly LSLInteger RC_GET_ROOT_KEY = 4;
617 public static readonly LSLInteger RC_GET_LINK_NUM = 8;
618
619 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 1;
599 } 620 }
600} 621}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 7d7e54e..ca54862 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -1206,6 +1206,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1206 m_LSL_Functions.llRegionSay(channelID, text); 1206 m_LSL_Functions.llRegionSay(channelID, text);
1207 } 1207 }
1208 1208
1209 public void llRegionSayTo(string key, int channelID, string text)
1210 {
1211 m_LSL_Functions.llRegionSayTo(key, channelID, text);
1212 }
1213
1209 public void llReleaseCamera(string avatar) 1214 public void llReleaseCamera(string avatar)
1210 { 1215 {
1211 m_LSL_Functions.llReleaseCamera(avatar); 1216 m_LSL_Functions.llReleaseCamera(avatar);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index 7c59098..bbc8cc6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -483,11 +483,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
483 return m_OSSL_Functions.osNpcCreate(user, name, position, cloneFrom); 483 return m_OSSL_Functions.osNpcCreate(user, name, position, cloneFrom);
484 } 484 }
485 485
486 public key osNpcSaveAppearance(key npc, string notecard)
487 {
488 return m_OSSL_Functions.osNpcSaveAppearance(npc, notecard);
489 }
490
491 public void osNpcLoadAppearance(key npc, string notecard)
492 {
493 m_OSSL_Functions.osNpcLoadAppearance(npc, notecard);
494 }
495
496 public vector osNpcGetPos(LSL_Key npc)
497 {
498 return m_OSSL_Functions.osNpcGetPos(npc);
499 }
500
486 public void osNpcMoveTo(key npc, vector position) 501 public void osNpcMoveTo(key npc, vector position)
487 { 502 {
488 m_OSSL_Functions.osNpcMoveTo(npc, position); 503 m_OSSL_Functions.osNpcMoveTo(npc, position);
489 } 504 }
490 505
506 public void osNpcMoveToTarget(key npc, vector target, int options)
507 {
508 m_OSSL_Functions.osNpcMoveToTarget(npc, target, options);
509 }
510
511 public rotation osNpcGetRot(key npc)
512 {
513 return m_OSSL_Functions.osNpcGetRot(npc);
514 }
515
516 public void osNpcSetRot(key npc, rotation rot)
517 {
518 m_OSSL_Functions.osNpcSetRot(npc, rot);
519 }
520
521 public void osNpcStopMoveToTarget(LSL_Key npc)
522 {
523 m_OSSL_Functions.osNpcStopMoveToTarget(npc);
524 }
525
491 public void osNpcSay(key npc, string message) 526 public void osNpcSay(key npc, string message)
492 { 527 {
493 m_OSSL_Functions.osNpcSay(npc, message); 528 m_OSSL_Functions.osNpcSay(npc, message);
@@ -498,6 +533,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
498 m_OSSL_Functions.osNpcRemove(npc); 533 m_OSSL_Functions.osNpcRemove(npc);
499 } 534 }
500 535
536 public LSL_Key osOwnerSaveAppearance(string notecard)
537 {
538 return m_OSSL_Functions.osOwnerSaveAppearance(notecard);
539 }
540
541 public LSL_Key osAgentSaveAppearance(LSL_Key agentId, string notecard)
542 {
543 return m_OSSL_Functions.osAgentSaveAppearance(agentId, notecard);
544 }
545
501 public OSSLPrim Prim; 546 public OSSLPrim Prim;
502 547
503 [Serializable] 548 [Serializable]
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index e9edf6c..7e7e278 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -205,7 +205,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
205 return; 205 return;
206 } 206 }
207 207
208 part=part.ParentGroup.RootPart; // We detect objects only 208 part = part.ParentGroup.RootPart; // We detect objects only
209 209
210 LinkNum = 0; // Not relevant 210 LinkNum = 0; // Not relevant
211 211
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 9548253..cf25189 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -234,7 +234,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
234 m_MaxScriptQueue = maxScriptQueue; 234 m_MaxScriptQueue = maxScriptQueue;
235 m_stateSource = stateSource; 235 m_stateSource = stateSource;
236 m_postOnRez = postOnRez; 236 m_postOnRez = postOnRez;
237 m_AttachedAvatar = part.AttachedAvatar; 237 m_AttachedAvatar = part.ParentGroup.AttachedAvatar;
238 m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID; 238 m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID;
239 239
240 if (part != null) 240 if (part != null)
@@ -772,13 +772,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
772 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) 772 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException))
773 { 773 {
774 m_InSelfDelete = true; 774 m_InSelfDelete = true;
775 if (part != null && part.ParentGroup != null) 775 if (part != null)
776 m_Engine.World.DeleteSceneObject(part.ParentGroup, false); 776 m_Engine.World.DeleteSceneObject(part.ParentGroup, false);
777 } 777 }
778 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException)) 778 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException))
779 { 779 {
780 m_InSelfDelete = true; 780 m_InSelfDelete = true;
781 if (part != null && part.ParentGroup != null) 781 if (part != null)
782 part.Inventory.RemoveInventoryItem(m_ItemID); 782 part.Inventory.RemoveInventoryItem(m_ItemID);
783 } 783 }
784 } 784 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index 6bfee91..9e6752c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -1373,7 +1373,9 @@ namespace OpenSim.Region.ScriptEngine.Shared
1373 public struct LSLString 1373 public struct LSLString
1374 { 1374 {
1375 public string m_string; 1375 public string m_string;
1376
1376 #region Constructors 1377 #region Constructors
1378
1377 public LSLString(string s) 1379 public LSLString(string s)
1378 { 1380 {
1379 m_string = s; 1381 m_string = s;
@@ -1381,22 +1383,24 @@ namespace OpenSim.Region.ScriptEngine.Shared
1381 1383
1382 public LSLString(double d) 1384 public LSLString(double d)
1383 { 1385 {
1384 string s=String.Format(Culture.FormatProvider, "{0:0.000000}", d); 1386 string s = String.Format(Culture.FormatProvider, "{0:0.000000}", d);
1385 m_string=s; 1387 m_string = s;
1386 } 1388 }
1387 1389
1388 public LSLString(LSLFloat f) 1390 public LSLString(LSLFloat f)
1389 { 1391 {
1390 string s = String.Format(Culture.FormatProvider, "{0:0.000000}", f.value); 1392 string s = String.Format(Culture.FormatProvider, "{0:0.000000}", f.value);
1391 m_string=s; 1393 m_string = s;
1392 } 1394 }
1393 1395
1394 public LSLString(LSLInteger i) 1396 public LSLString(int i)
1395 { 1397 {
1396 string s = String.Format("{0}", i); 1398 string s = String.Format("{0}", i);
1397 m_string = s; 1399 m_string = s;
1398 } 1400 }
1399 1401
1402 public LSLString(LSLInteger i) : this(i.value) {}
1403
1400 #endregion 1404 #endregion
1401 1405
1402 #region Operators 1406 #region Operators
@@ -1463,6 +1467,11 @@ namespace OpenSim.Region.ScriptEngine.Shared
1463 { 1467 {
1464 return new LSLString(d); 1468 return new LSLString(d);
1465 } 1469 }
1470
1471 static public explicit operator LSLString(int i)
1472 {
1473 return new LSLString(i);
1474 }
1466 1475
1467 public static explicit operator LSLString(LSLFloat f) 1476 public static explicit operator LSLString(LSLFloat f)
1468 { 1477 {
@@ -1736,7 +1745,17 @@ namespace OpenSim.Region.ScriptEngine.Shared
1736 public override bool Equals(Object o) 1745 public override bool Equals(Object o)
1737 { 1746 {
1738 if (!(o is LSLInteger)) 1747 if (!(o is LSLInteger))
1739 return false; 1748 {
1749 if (o is int)
1750 {
1751 return value == (int)o;
1752 }
1753 else
1754 {
1755 return false;
1756 }
1757 }
1758
1740 return value == ((LSLInteger)o).value; 1759 return value == ((LSLInteger)o).value;
1741 } 1760 }
1742 1761
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
index 80b60a4..8cd1e84 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
@@ -27,11 +27,13 @@
27 27
28using System.Collections.Generic; 28using System.Collections.Generic;
29using NUnit.Framework; 29using NUnit.Framework;
30using OpenSim.Framework;
30using OpenSim.Tests.Common; 31using OpenSim.Tests.Common;
31using OpenSim.Region.ScriptEngine.Shared; 32using OpenSim.Region.ScriptEngine.Shared;
32using OpenSim.Region.Framework.Scenes; 33using OpenSim.Region.Framework.Scenes;
33using Nini.Config; 34using Nini.Config;
34using OpenSim.Region.ScriptEngine.Shared.Api; 35using OpenSim.Region.ScriptEngine.Shared.Api;
36using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
35using OpenMetaverse; 37using OpenMetaverse;
36using System; 38using System;
37using OpenSim.Tests.Common.Mock; 39using OpenSim.Tests.Common.Mock;
@@ -47,6 +49,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
47 49
48 private const double ANGLE_ACCURACY_IN_RADIANS = 1E-6; 50 private const double ANGLE_ACCURACY_IN_RADIANS = 1E-6;
49 private const double VECTOR_COMPONENT_ACCURACY = 0.0000005d; 51 private const double VECTOR_COMPONENT_ACCURACY = 0.0000005d;
52 private const double FLOAT_ACCURACY = 0.00005d;
50 private LSL_Api m_lslApi; 53 private LSL_Api m_lslApi;
51 54
52 [SetUp] 55 [SetUp]
@@ -57,8 +60,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
57 IConfig config = initConfigSource.AddConfig("XEngine"); 60 IConfig config = initConfigSource.AddConfig("XEngine");
58 config.Set("Enabled", "true"); 61 config.Set("Enabled", "true");
59 62
60 Scene scene = SceneSetupHelpers.SetupScene(); 63 Scene scene = SceneHelpers.SetupScene();
61 SceneObjectPart part = SceneSetupHelpers.AddSceneObject(scene); 64 SceneObjectPart part = SceneHelpers.AddSceneObject(scene);
62 65
63 XEngine.XEngine engine = new XEngine.XEngine(); 66 XEngine.XEngine engine = new XEngine.XEngine();
64 engine.Initialise(initConfigSource); 67 engine.Initialise(initConfigSource);
@@ -166,6 +169,231 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
166 } 169 }
167 170
168 [Test] 171 [Test]
172 // llSetPrimitiveParams and llGetPrimitiveParams test.
173 public void TestllSetPrimitiveParams()
174 {
175 // Create Prim1.
176 Scene scene = SceneHelpers.SetupScene();
177 string obj1Name = "Prim1";
178 UUID objUuid = new UUID("00000000-0000-0000-0000-000000000001");
179 SceneObjectPart part1 =
180 new SceneObjectPart(UUID.Zero, PrimitiveBaseShape.Default,
181 Vector3.Zero, Quaternion.Identity,
182 Vector3.Zero) { Name = obj1Name, UUID = objUuid };
183 Assert.That(scene.AddNewSceneObject(new SceneObjectGroup(part1), false), Is.True);
184
185 // Note that prim hollow check is passed with the other prim params in order to allow the
186 // specification of a different check value from the prim param. A cylinder, prism, sphere,
187 // torus or ring, with a hole shape of square, is limited to a hollow of 70%. Test 5 below
188 // specifies a value of 95% and checks to see if 70% was properly returned.
189
190 // Test a sphere.
191 CheckllSetPrimitiveParams(
192 "test 1", // Prim test identification string
193 new LSL_Types.Vector3(6.0d, 9.9d, 9.9d), // Prim size
194 ScriptBaseClass.PRIM_TYPE_SPHERE, // Prim type
195 ScriptBaseClass.PRIM_HOLE_DEFAULT, // Prim hole type
196 new LSL_Types.Vector3(0.0d, 0.075d, 0.0d), // Prim cut
197 0.80d, // Prim hollow
198 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist
199 new LSL_Types.Vector3(0.32d, 0.76d, 0.0d), // Prim dimple
200 0.80d); // Prim hollow check
201
202 // Test a prism.
203 CheckllSetPrimitiveParams(
204 "test 2", // Prim test identification string
205 new LSL_Types.Vector3(3.5d, 3.5d, 3.5d), // Prim size
206 ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type
207 ScriptBaseClass.PRIM_HOLE_CIRCLE, // Prim hole type
208 new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
209 0.90d, // Prim hollow
210 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist
211 new LSL_Types.Vector3(2.0d, 1.0d, 0.0d), // Prim taper
212 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
213 0.90d); // Prim hollow check
214
215 // Test a box.
216 CheckllSetPrimitiveParams(
217 "test 3", // Prim test identification string
218 new LSL_Types.Vector3(3.5d, 3.5d, 3.5d), // Prim size
219 ScriptBaseClass.PRIM_TYPE_BOX, // Prim type
220 ScriptBaseClass.PRIM_HOLE_TRIANGLE, // Prim hole type
221 new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
222 0.95d, // Prim hollow
223 new LSL_Types.Vector3(1.0d, 0.0d, 0.0d), // Prim twist
224 new LSL_Types.Vector3(1.0d, 1.0d, 0.0d), // Prim taper
225 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
226 0.95d); // Prim hollow check
227
228 // Test a tube.
229 CheckllSetPrimitiveParams(
230 "test 4", // Prim test identification string
231 new LSL_Types.Vector3(4.2d, 4.2d, 4.2d), // Prim size
232 ScriptBaseClass.PRIM_TYPE_TUBE, // Prim type
233 ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type
234 new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
235 0.00d, // Prim hollow
236 new LSL_Types.Vector3(1.0d, -1.0d, 0.0d), // Prim twist
237 new LSL_Types.Vector3(1.0d, 0.5d, 0.0d), // Prim hole size
238 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
239 new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim profile cut
240 new LSL_Types.Vector3(-1.0d, 1.0d, 0.0d), // Prim taper
241 1.0d, // Prim revolutions
242 1.0d, // Prim radius
243 0.0d, // Prim skew
244 0.00d); // Prim hollow check
245
246 // Test a prism.
247 CheckllSetPrimitiveParams(
248 "test 5", // Prim test identification string
249 new LSL_Types.Vector3(3.5d, 3.5d, 3.5d), // Prim size
250 ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type
251 ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type
252 new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
253 0.95d, // Prim hollow
254 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist
255 new LSL_Types.Vector3(2.0d, 1.0d, 0.0d), // Prim taper
256 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
257 0.70d); // Prim hollow check
258
259 // Test a sculpted prim.
260 CheckllSetPrimitiveParams(
261 "test 6", // Prim test identification string
262 new LSL_Types.Vector3(2.0d, 2.0d, 2.0d), // Prim size
263 ScriptBaseClass.PRIM_TYPE_SCULPT, // Prim type
264 "be293869-d0d9-0a69-5989-ad27f1946fd4", // Prim map
265 ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE); // Prim sculpt type
266 }
267
268 // Set prim params for a box, cylinder or prism and check results.
269 public void CheckllSetPrimitiveParams(string primTest,
270 LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut,
271 double primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primTaper, LSL_Types.Vector3 primShear,
272 double primHollowCheck)
273 {
274 // Set the prim params.
275 m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
276 ScriptBaseClass.PRIM_TYPE, primType, primHoleType,
277 primCut, primHollow, primTwist, primTaper, primShear));
278
279 // Get params for prim to validate settings.
280 LSL_Types.list primParams =
281 m_lslApi.llGetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, ScriptBaseClass.PRIM_TYPE));
282
283 // Validate settings.
284 CheckllSetPrimitiveParamsVector(primSize, m_lslApi.llList2Vector(primParams, 0), primTest + " prim size");
285 Assert.AreEqual(primType, m_lslApi.llList2Integer(primParams, 1),
286 "TestllSetPrimitiveParams " + primTest + " prim type check fail");
287 Assert.AreEqual(primHoleType, m_lslApi.llList2Integer(primParams, 2),
288 "TestllSetPrimitiveParams " + primTest + " prim hole default check fail");
289 CheckllSetPrimitiveParamsVector(primCut, m_lslApi.llList2Vector(primParams, 3), primTest + " prim cut");
290 Assert.AreEqual(primHollowCheck, m_lslApi.llList2Float(primParams, 4), FLOAT_ACCURACY,
291 "TestllSetPrimitiveParams " + primTest + " prim hollow check fail");
292 CheckllSetPrimitiveParamsVector(primTwist, m_lslApi.llList2Vector(primParams, 5), primTest + " prim twist");
293 CheckllSetPrimitiveParamsVector(primTaper, m_lslApi.llList2Vector(primParams, 6), primTest + " prim taper");
294 CheckllSetPrimitiveParamsVector(primShear, m_lslApi.llList2Vector(primParams, 7), primTest + " prim shear");
295 }
296
297 // Set prim params for a sphere and check results.
298 public void CheckllSetPrimitiveParams(string primTest,
299 LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut,
300 double primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primDimple, double primHollowCheck)
301 {
302 // Set the prim params.
303 m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
304 ScriptBaseClass.PRIM_TYPE, primType, primHoleType,
305 primCut, primHollow, primTwist, primDimple));
306
307 // Get params for prim to validate settings.
308 LSL_Types.list primParams =
309 m_lslApi.llGetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, ScriptBaseClass.PRIM_TYPE));
310
311 // Validate settings.
312 CheckllSetPrimitiveParamsVector(primSize, m_lslApi.llList2Vector(primParams, 0), primTest + " prim size");
313 Assert.AreEqual(primType, m_lslApi.llList2Integer(primParams, 1),
314 "TestllSetPrimitiveParams " + primTest + " prim type check fail");
315 Assert.AreEqual(primHoleType, m_lslApi.llList2Integer(primParams, 2),
316 "TestllSetPrimitiveParams " + primTest + " prim hole default check fail");
317 CheckllSetPrimitiveParamsVector(primCut, m_lslApi.llList2Vector(primParams, 3), primTest + " prim cut");
318 Assert.AreEqual(primHollowCheck, m_lslApi.llList2Float(primParams, 4), FLOAT_ACCURACY,
319 "TestllSetPrimitiveParams " + primTest + " prim hollow check fail");
320 CheckllSetPrimitiveParamsVector(primTwist, m_lslApi.llList2Vector(primParams, 5), primTest + " prim twist");
321 CheckllSetPrimitiveParamsVector(primDimple, m_lslApi.llList2Vector(primParams, 6), primTest + " prim dimple");
322 }
323
324 // Set prim params for a torus, tube or ring and check results.
325 public void CheckllSetPrimitiveParams(string primTest,
326 LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut,
327 double primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primHoleSize,
328 LSL_Types.Vector3 primShear, LSL_Types.Vector3 primProfCut, LSL_Types.Vector3 primTaper,
329 double primRev, double primRadius, double primSkew, double primHollowCheck)
330 {
331 // Set the prim params.
332 m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
333 ScriptBaseClass.PRIM_TYPE, primType, primHoleType,
334 primCut, primHollow, primTwist, primHoleSize, primShear, primProfCut,
335 primTaper, primRev, primRadius, primSkew));
336
337 // Get params for prim to validate settings.
338 LSL_Types.list primParams =
339 m_lslApi.llGetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, ScriptBaseClass.PRIM_TYPE));
340
341 // Valdate settings.
342 CheckllSetPrimitiveParamsVector(primSize, m_lslApi.llList2Vector(primParams, 0), primTest + " prim size");
343 Assert.AreEqual(primType, m_lslApi.llList2Integer(primParams, 1),
344 "TestllSetPrimitiveParams " + primTest + " prim type check fail");
345 Assert.AreEqual(primHoleType, m_lslApi.llList2Integer(primParams, 2),
346 "TestllSetPrimitiveParams " + primTest + " prim hole default check fail");
347 CheckllSetPrimitiveParamsVector(primCut, m_lslApi.llList2Vector(primParams, 3), primTest + " prim cut");
348 Assert.AreEqual(primHollowCheck, m_lslApi.llList2Float(primParams, 4), FLOAT_ACCURACY,
349 "TestllSetPrimitiveParams " + primTest + " prim hollow check fail");
350 CheckllSetPrimitiveParamsVector(primTwist, m_lslApi.llList2Vector(primParams, 5), primTest + " prim twist");
351 CheckllSetPrimitiveParamsVector(primHoleSize, m_lslApi.llList2Vector(primParams, 6), primTest + " prim hole size");
352 CheckllSetPrimitiveParamsVector(primShear, m_lslApi.llList2Vector(primParams, 7), primTest + " prim shear");
353 CheckllSetPrimitiveParamsVector(primProfCut, m_lslApi.llList2Vector(primParams, 8), primTest + " prim profile cut");
354 CheckllSetPrimitiveParamsVector(primTaper, m_lslApi.llList2Vector(primParams, 9), primTest + " prim taper");
355 Assert.AreEqual(primRev, m_lslApi.llList2Float(primParams, 10), FLOAT_ACCURACY,
356 "TestllSetPrimitiveParams " + primTest + " prim revolution fail");
357 Assert.AreEqual(primRadius, m_lslApi.llList2Float(primParams, 11), FLOAT_ACCURACY,
358 "TestllSetPrimitiveParams " + primTest + " prim radius fail");
359 Assert.AreEqual(primSkew, m_lslApi.llList2Float(primParams, 12), FLOAT_ACCURACY,
360 "TestllSetPrimitiveParams " + primTest + " prim skew fail");
361 }
362
363 // Set prim params for a sculpted prim and check results.
364 public void CheckllSetPrimitiveParams(string primTest,
365 LSL_Types.Vector3 primSize, int primType, string primMap, int primSculptType)
366 {
367 // Set the prim params.
368 m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
369 ScriptBaseClass.PRIM_TYPE, primType, primMap, primSculptType));
370
371 // Get params for prim to validate settings.
372 LSL_Types.list primParams =
373 m_lslApi.llGetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, ScriptBaseClass.PRIM_TYPE));
374
375 // Validate settings.
376 CheckllSetPrimitiveParamsVector(primSize, m_lslApi.llList2Vector(primParams, 0), primTest + " prim size");
377 Assert.AreEqual(primType, m_lslApi.llList2Integer(primParams, 1),
378 "TestllSetPrimitiveParams " + primTest + " prim type check fail");
379 Assert.AreEqual(primMap, (string)m_lslApi.llList2String(primParams, 2),
380 "TestllSetPrimitiveParams " + primTest + " prim map check fail");
381 Assert.AreEqual(primSculptType, m_lslApi.llList2Integer(primParams, 3),
382 "TestllSetPrimitiveParams " + primTest + " prim type scuplt check fail");
383 }
384
385 public void CheckllSetPrimitiveParamsVector(LSL_Types.Vector3 vecCheck, LSL_Types.Vector3 vecReturned, string msg)
386 {
387 // Check each vector component against expected result.
388 Assert.AreEqual(vecCheck.x, vecReturned.x, VECTOR_COMPONENT_ACCURACY,
389 "TestllSetPrimitiveParams " + msg + " vector check fail on x component");
390 Assert.AreEqual(vecCheck.y, vecReturned.y, VECTOR_COMPONENT_ACCURACY,
391 "TestllSetPrimitiveParams " + msg + " vector check fail on y component");
392 Assert.AreEqual(vecCheck.z, vecReturned.z, VECTOR_COMPONENT_ACCURACY,
393 "TestllSetPrimitiveParams " + msg + " vector check fail on z component");
394 }
395
396 [Test]
169 // llVecNorm test. 397 // llVecNorm test.
170 public void TestllVecNorm() 398 public void TestllVecNorm()
171 { 399 {
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
new file mode 100644
index 0000000..7573dff
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
@@ -0,0 +1,229 @@
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.Services.Interfaces;
45using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock;
47
48namespace OpenSim.Region.ScriptEngine.Shared.Tests
49{
50 /// <summary>
51 /// Tests for OSSL_Api
52 /// </summary>
53 [TestFixture]
54 public class OSSL_ApiAppearanceTest
55 {
56 protected Scene m_scene;
57 protected XEngine.XEngine m_engine;
58
59 [SetUp]
60 public void SetUp()
61 {
62 IConfigSource initConfigSource = new IniConfigSource();
63 IConfig config = initConfigSource.AddConfig("XEngine");
64 config.Set("Enabled", "true");
65 config.Set("AllowOSFunctions", "true");
66 config.Set("OSFunctionThreatLevel", "Severe");
67 config = initConfigSource.AddConfig("NPC");
68 config.Set("Enabled", "true");
69
70 m_scene = SceneHelpers.SetupScene();
71 SceneHelpers.SetupSceneModules(m_scene, initConfigSource, new AvatarFactoryModule(), new NPCModule());
72
73 m_engine = new XEngine.XEngine();
74 m_engine.Initialise(initConfigSource);
75 m_engine.AddRegion(m_scene);
76 }
77
78 /// <summary>
79 /// Test creation of an NPC where the appearance data comes from a notecard
80 /// </summary>
81 [Test]
82 public void TestOsNpcCreateFromNotecard()
83 {
84 TestHelpers.InMethod();
85// log4net.Config.XmlConfigurator.Configure();
86
87 // Store an avatar with a different height from default in a notecard.
88 UUID userId = TestHelpers.ParseTail(0x1);
89 float newHeight = 1.9f;
90
91 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
92 sp.Appearance.AvatarHeight = newHeight;
93 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId);
94 SceneObjectPart part = so.RootPart;
95 m_scene.AddSceneObject(so);
96
97 OSSL_Api osslApi = new OSSL_Api();
98 osslApi.Initialize(m_engine, part, part.LocalId, part.UUID);
99
100 string notecardName = "appearanceNc";
101 osslApi.osOwnerSaveAppearance(notecardName);
102
103 // Try creating a bot using the appearance in the notecard.
104 string npcRaw = osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), notecardName);
105 Assert.That(npcRaw, Is.Not.Null);
106
107 UUID npcId = new UUID(npcRaw);
108 ScenePresence npc = m_scene.GetScenePresence(npcId);
109 Assert.That(npc, Is.Not.Null);
110 Assert.That(npc.Appearance.AvatarHeight, Is.EqualTo(newHeight));
111 }
112
113 /// <summary>
114 /// Test creation of an NPC where the appearance data comes from an avatar already in the region.
115 /// </summary>
116 [Test]
117 public void TestOsNpcCreateFromAvatar()
118 {
119 TestHelpers.InMethod();
120// log4net.Config.XmlConfigurator.Configure();
121
122 // Store an avatar with a different height from default in a notecard.
123 UUID userId = TestHelpers.ParseTail(0x1);
124 float newHeight = 1.9f;
125
126 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
127 sp.Appearance.AvatarHeight = newHeight;
128 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId);
129 SceneObjectPart part = so.RootPart;
130 m_scene.AddSceneObject(so);
131
132 OSSL_Api osslApi = new OSSL_Api();
133 osslApi.Initialize(m_engine, part, part.LocalId, part.UUID);
134
135 string notecardName = "appearanceNc";
136 osslApi.osOwnerSaveAppearance(notecardName);
137
138 // Try creating a bot using the existing avatar's appearance
139 string npcRaw = osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), sp.UUID.ToString());
140 Assert.That(npcRaw, Is.Not.Null);
141
142 UUID npcId = new UUID(npcRaw);
143 ScenePresence npc = m_scene.GetScenePresence(npcId);
144 Assert.That(npc, Is.Not.Null);
145 Assert.That(npc.Appearance.AvatarHeight, Is.EqualTo(newHeight));
146 }
147
148 [Test]
149 public void TestOsOwnerSaveAppearance()
150 {
151 TestHelpers.InMethod();
152// log4net.Config.XmlConfigurator.Configure();
153
154 UUID userId = TestHelpers.ParseTail(0x1);
155 float newHeight = 1.9f;
156
157 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
158 sp.Appearance.AvatarHeight = newHeight;
159 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId);
160 SceneObjectPart part = so.RootPart;
161 m_scene.AddSceneObject(so);
162
163 OSSL_Api osslApi = new OSSL_Api();
164 osslApi.Initialize(m_engine, part, part.LocalId, part.UUID);
165
166 string notecardName = "appearanceNc";
167
168 osslApi.osOwnerSaveAppearance(notecardName);
169
170 IList<TaskInventoryItem> items = part.Inventory.GetInventoryItems(notecardName);
171 Assert.That(items.Count, Is.EqualTo(1));
172
173 TaskInventoryItem ncItem = items[0];
174 Assert.That(ncItem.Name, Is.EqualTo(notecardName));
175
176 AssetBase ncAsset = m_scene.AssetService.Get(ncItem.AssetID.ToString());
177 Assert.That(ncAsset, Is.Not.Null);
178
179 AssetNotecard anc = new AssetNotecard(UUID.Zero, ncAsset.Data);
180 anc.Decode();
181 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(anc.BodyText);
182 AvatarAppearance savedAppearance = new AvatarAppearance();
183 savedAppearance.Unpack(appearanceOsd);
184
185 Assert.That(savedAppearance.AvatarHeight, Is.EqualTo(sp.Appearance.AvatarHeight));
186 }
187
188 [Test]
189 public void TestOsAgentSaveAppearance()
190 {
191 TestHelpers.InMethod();
192// log4net.Config.XmlConfigurator.Configure();
193
194 UUID ownerId = TestHelpers.ParseTail(0x1);
195 UUID nonOwnerId = TestHelpers.ParseTail(0x2);
196 float newHeight = 1.9f;
197
198 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, nonOwnerId);
199 sp.Appearance.AvatarHeight = newHeight;
200 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, ownerId);
201 SceneObjectPart part = so.RootPart;
202 m_scene.AddSceneObject(so);
203
204 OSSL_Api osslApi = new OSSL_Api();
205 osslApi.Initialize(m_engine, part, part.LocalId, part.UUID);
206
207 string notecardName = "appearanceNc";
208
209 osslApi.osAgentSaveAppearance(new LSL_Types.LSLString(nonOwnerId.ToString()), notecardName);
210
211 IList<TaskInventoryItem> items = part.Inventory.GetInventoryItems(notecardName);
212 Assert.That(items.Count, Is.EqualTo(1));
213
214 TaskInventoryItem ncItem = items[0];
215 Assert.That(ncItem.Name, Is.EqualTo(notecardName));
216
217 AssetBase ncAsset = m_scene.AssetService.Get(ncItem.AssetID.ToString());
218 Assert.That(ncAsset, Is.Not.Null);
219
220 AssetNotecard anc = new AssetNotecard(UUID.Zero, ncAsset.Data);
221 anc.Decode();
222 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(anc.BodyText);
223 AvatarAppearance savedAppearance = new AvatarAppearance();
224 savedAppearance.Unpack(appearanceOsd);
225
226 Assert.That(savedAppearance.AvatarHeight, Is.EqualTo(sp.Appearance.AvatarHeight));
227 }
228 }
229} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
index 0ac8b5c..5c4174e 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
@@ -97,13 +97,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
97 return; 97 return;
98 98
99 m_log.Debug("Paid: " + objectID + " from " + agentID + ", amount " + amount); 99 m_log.Debug("Paid: " + objectID + " from " + agentID + ", amount " + amount);
100 if (part.ParentGroup != null)
101 part = part.ParentGroup.RootPart;
102 100
103 if (part != null) 101 part = part.ParentGroup.RootPart;
104 { 102 money(part.LocalId, agentID, amount);
105 money(part.LocalId, agentID, amount);
106 }
107 } 103 }
108 104
109 /// <summary> 105 /// <summary>
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 4f3432d..9cb074a 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -1373,9 +1373,15 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1373 1373
1374 public string GetXMLState(UUID itemID) 1374 public string GetXMLState(UUID itemID)
1375 { 1375 {
1376// m_log.DebugFormat("[XEngine]: Getting XML state for {0}", itemID);
1377
1376 IScriptInstance instance = GetInstance(itemID); 1378 IScriptInstance instance = GetInstance(itemID);
1377 if (instance == null) 1379 if (instance == null)
1380 {
1381// m_log.DebugFormat("[XEngine]: Found no script for {0}, returning empty string", itemID);
1378 return ""; 1382 return "";
1383 }
1384
1379 string xml = instance.GetXMLState(); 1385 string xml = instance.GetXMLState();
1380 1386
1381 XmlDocument sdoc = new XmlDocument(); 1387 XmlDocument sdoc = new XmlDocument();
@@ -1516,6 +1522,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1516 mapData.InnerText = map; 1522 mapData.InnerText = map;
1517 1523
1518 stateData.AppendChild(mapData); 1524 stateData.AppendChild(mapData);
1525
1526// m_log.DebugFormat("[XEngine]: Got XML state for {0}", itemID);
1527
1519 return doc.InnerXml; 1528 return doc.InnerXml;
1520 } 1529 }
1521 1530
diff --git a/OpenSim/Server/Handlers/Authorization/AuthorizationServerPostHandler.cs b/OpenSim/Server/Handlers/Authorization/AuthorizationServerPostHandler.cs
index f987de4..d656238 100644
--- a/OpenSim/Server/Handlers/Authorization/AuthorizationServerPostHandler.cs
+++ b/OpenSim/Server/Handlers/Authorization/AuthorizationServerPostHandler.cs
@@ -61,7 +61,7 @@ namespace OpenSim.Server.Handlers.Authorization
61 AuthorizationRequest Authorization = (AuthorizationRequest) xs.Deserialize(request); 61 AuthorizationRequest Authorization = (AuthorizationRequest) xs.Deserialize(request);
62 62
63 string message = String.Empty; 63 string message = String.Empty;
64 bool authorized = m_AuthorizationService.IsAuthorizedForRegion(Authorization.ID, Authorization.RegionID,out message); 64 bool authorized = m_AuthorizationService.IsAuthorizedForRegion(Authorization.ID, Authorization.FirstName, Authorization.SurName, Authorization.RegionID, out message);
65 65
66 AuthorizationResponse result = new AuthorizationResponse(authorized, Authorization.ID + " has been authorized"); 66 AuthorizationResponse result = new AuthorizationResponse(authorized, Authorization.ID + " has been authorized");
67 67
diff --git a/OpenSim/Services/AssetService/AssetService.cs b/OpenSim/Services/AssetService/AssetService.cs
index ffdaa60..0feb59d 100644
--- a/OpenSim/Services/AssetService/AssetService.cs
+++ b/OpenSim/Services/AssetService/AssetService.cs
@@ -83,7 +83,7 @@ namespace OpenSim.Services.AssetService
83 83
84 if (assetLoaderEnabled) 84 if (assetLoaderEnabled)
85 { 85 {
86 m_log.InfoFormat("[ASSET]: Loading default asset set from {0}", loaderArgs); 86 m_log.DebugFormat("[ASSET]: Loading default asset set from {0}", loaderArgs);
87 87
88 m_AssetLoader.ForEachDefaultXmlAsset( 88 m_AssetLoader.ForEachDefaultXmlAsset(
89 loaderArgs, 89 loaderArgs,
@@ -100,7 +100,7 @@ namespace OpenSim.Services.AssetService
100 }); 100 });
101 } 101 }
102 102
103 m_log.Info("[ASSET SERVICE]: Local asset service enabled"); 103 m_log.Debug("[ASSET SERVICE]: Local asset service enabled");
104 } 104 }
105 } 105 }
106 } 106 }
@@ -174,11 +174,20 @@ namespace OpenSim.Services.AssetService
174 174
175 public virtual string Store(AssetBase asset) 175 public virtual string Store(AssetBase asset)
176 { 176 {
177 //m_log.DebugFormat("[ASSET SERVICE]: Store asset {0} {1}", asset.Name, asset.ID); 177 if (!m_Database.ExistsAsset(asset.FullID))
178 if (!m_Database.StoreAsset(asset))
179 { 178 {
179// m_log.DebugFormat(
180// "[ASSET SERVICE]: Storing asset {0} {1}, bytes {2}", asset.Name, asset.FullID, asset.Data.Length);
181 if (!m_Database.StoreAsset(asset))
182 {
180 return UUID.Zero.ToString(); 183 return UUID.Zero.ToString();
184 }
181 } 185 }
186// else
187// {
188// m_log.DebugFormat(
189// "[ASSET SERVICE]: Not storing asset {0} {1}, bytes {2} as it already exists", asset.Name, asset.FullID, asset.Data.Length);
190// }
182 191
183 return asset.ID; 192 return asset.ID;
184 } 193 }
diff --git a/OpenSim/Services/AuthenticationService/WebkeyOrPasswordAuthenticationService.cs b/OpenSim/Services/AuthenticationService/WebkeyOrPasswordAuthenticationService.cs
index 3590e12..2c6cebd 100644
--- a/OpenSim/Services/AuthenticationService/WebkeyOrPasswordAuthenticationService.cs
+++ b/OpenSim/Services/AuthenticationService/WebkeyOrPasswordAuthenticationService.cs
@@ -42,15 +42,13 @@ namespace OpenSim.Services.AuthenticationService
42 public class WebkeyOrPasswordAuthenticationService : AuthenticationServiceBase, IAuthenticationService 42 public class WebkeyOrPasswordAuthenticationService : AuthenticationServiceBase, IAuthenticationService
43 { 43 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 45
46 private IConfigSource m_config;
47 private Dictionary<string, IAuthenticationService> m_svcChecks 46 private Dictionary<string, IAuthenticationService> m_svcChecks
48 = new Dictionary<string, IAuthenticationService>(); 47 = new Dictionary<string, IAuthenticationService>();
49 48
50 public WebkeyOrPasswordAuthenticationService(IConfigSource config) 49 public WebkeyOrPasswordAuthenticationService(IConfigSource config)
51 : base(config) 50 : base(config)
52 { 51 {
53 this.m_config = config;
54 m_svcChecks["web_login_key"] = new WebkeyAuthenticationService(config); 52 m_svcChecks["web_login_key"] = new WebkeyAuthenticationService(config);
55 m_svcChecks["password"] = new PasswordAuthenticationService(config); 53 m_svcChecks["password"] = new PasswordAuthenticationService(config);
56 } 54 }
diff --git a/OpenSim/Services/AuthorizationService/AuthorizationService.cs b/OpenSim/Services/AuthorizationService/AuthorizationService.cs
index d658368..03da6e1 100644
--- a/OpenSim/Services/AuthorizationService/AuthorizationService.cs
+++ b/OpenSim/Services/AuthorizationService/AuthorizationService.cs
@@ -48,10 +48,11 @@ namespace OpenSim.Services.AuthorizationService
48 m_log.Info("[AUTHORIZATION CONNECTOR]: Local Authorization service enabled"); 48 m_log.Info("[AUTHORIZATION CONNECTOR]: Local Authorization service enabled");
49 } 49 }
50 50
51 public bool IsAuthorizedForRegion(string userID, string regionID, out string message) 51 public bool IsAuthorizedForRegion(
52 string userID, string firstName, string lastName, string regionID, out string message)
52 { 53 {
53 message = "Authorized"; 54 message = "Authorized";
54 return true; 55 return true;
55 } 56 }
56 } 57 }
57} 58} \ No newline at end of file
diff --git a/OpenSim/Services/AvatarService/AvatarService.cs b/OpenSim/Services/AvatarService/AvatarService.cs
index 53ca7c8..c59a9e0 100644
--- a/OpenSim/Services/AvatarService/AvatarService.cs
+++ b/OpenSim/Services/AvatarService/AvatarService.cs
@@ -54,7 +54,7 @@ namespace OpenSim.Services.AvatarService
54 public AvatarAppearance GetAppearance(UUID principalID) 54 public AvatarAppearance GetAppearance(UUID principalID)
55 { 55 {
56 AvatarData avatar = GetAvatar(principalID); 56 AvatarData avatar = GetAvatar(principalID);
57 return avatar.ToAvatarAppearance(principalID); 57 return avatar.ToAvatarAppearance();
58 } 58 }
59 59
60 public bool SetAppearance(UUID principalID, AvatarAppearance appearance) 60 public bool SetAppearance(UUID principalID, AvatarAppearance appearance)
@@ -109,7 +109,33 @@ namespace OpenSim.Services.AvatarService
109 foreach (KeyValuePair<string,string> kvp in avatar.Data) 109 foreach (KeyValuePair<string,string> kvp in avatar.Data)
110 { 110 {
111 av.Data["Name"] = kvp.Key; 111 av.Data["Name"] = kvp.Key;
112 av.Data["Value"] = kvp.Value; 112
113 // justincc 20110730. Yes, this is a hack to get around the fact that a bug in OpenSim is causing
114 // various simulators on osgrid to inject bad values. Since these simulators might be around for a
115 // long time, we are going to manually police the value.
116 //
117 // It should be possible to remove this in half a year if we don't want to police values server side.
118 if (kvp.Key == "AvatarHeight")
119 {
120 float height;
121 if (!float.TryParse(kvp.Value, out height) || height < 0 || height > 10)
122 {
123 string rawHeight = kvp.Value.Replace(",", ".");
124
125 if (!float.TryParse(rawHeight, out height) || height < 0 || height > 10)
126 height = 1.771488f;
127
128 m_log.DebugFormat(
129 "[AVATAR SERVICE]: Rectifying height of avatar {0} from {1} to {2}",
130 principalID, kvp.Value, height);
131 }
132
133 av.Data["Value"] = height.ToString();
134 }
135 else
136 {
137 av.Data["Value"] = kvp.Value;
138 }
113 139
114 if (!m_Database.Store(av)) 140 if (!m_Database.Store(av))
115 { 141 {
diff --git a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs
index 565e4f2..2bfa597 100644
--- a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs
@@ -51,6 +51,13 @@ namespace OpenSim.Services.Connectors
51 private int m_retryCounter; 51 private int m_retryCounter;
52 private Dictionary<int, List<AssetBase>> m_retryQueue = new Dictionary<int, List<AssetBase>>(); 52 private Dictionary<int, List<AssetBase>> m_retryQueue = new Dictionary<int, List<AssetBase>>();
53 private Timer m_retryTimer; 53 private Timer m_retryTimer;
54 private delegate void AssetRetrievedEx(AssetBase asset);
55
56 // Keeps track of concurrent requests for the same asset, so that it's only loaded once.
57 // Maps: Asset ID -> Handlers which will be called when the asset has been loaded
58 private Dictionary<string, AssetRetrievedEx> m_AssetHandlers = new Dictionary<string, AssetRetrievedEx>();
59
60
54 public AssetServicesConnector() 61 public AssetServicesConnector()
55 { 62 {
56 } 63 }
@@ -230,23 +237,56 @@ namespace OpenSim.Services.Connectors
230 237
231 if (asset == null || asset.Data == null || asset.Data.Length == 0) 238 if (asset == null || asset.Data == null || asset.Data.Length == 0)
232 { 239 {
233 bool result = false; 240 lock (m_AssetHandlers)
241 {
242 AssetRetrievedEx handlerEx = new AssetRetrievedEx(delegate(AssetBase _asset) { handler(id, sender, _asset); });
243
244 AssetRetrievedEx handlers;
245 if (m_AssetHandlers.TryGetValue(id, out handlers))
246 {
247 // Someone else is already loading this asset. It will notify our handler when done.
248 handlers += handlerEx;
249 return true;
250 }
251
252 // Load the asset ourselves
253 handlers += handlerEx;
254 m_AssetHandlers.Add(id, handlers);
255 }
234 256
235 AsynchronousRestObjectRequester. 257 bool success = false;
236 MakeRequest<int, AssetBase>("GET", uri, 0, 258 try
259 {
260 AsynchronousRestObjectRequester.MakeRequest<int, AssetBase>("GET", uri, 0,
237 delegate(AssetBase a) 261 delegate(AssetBase a)
238 { 262 {
239 if (m_Cache != null) 263 if (m_Cache != null)
240 m_Cache.Cache(a); 264 m_Cache.Cache(a);
241 handler(id, sender, a);
242 result = true;
243 });
244 265
245 return result; 266 AssetRetrievedEx handlers;
267 lock (m_AssetHandlers)
268 {
269 handlers = m_AssetHandlers[id];
270 m_AssetHandlers.Remove(id);
271 }
272 handlers.Invoke(a);
273 });
274
275 success = true;
276 }
277 finally
278 {
279 if (!success)
280 {
281 lock (m_AssetHandlers)
282 {
283 m_AssetHandlers.Remove(id);
284 }
285 }
286 }
246 } 287 }
247 else 288 else
248 { 289 {
249 //Util.FireAndForget(delegate { handler(id, sender, asset); });
250 handler(id, sender, asset); 290 handler(id, sender, asset);
251 } 291 }
252 292
diff --git a/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs b/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs
index 1a93ae7..8fdb4d0 100644
--- a/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs
@@ -89,7 +89,7 @@ namespace OpenSim.Services.Connectors
89 public AvatarAppearance GetAppearance(UUID userID) 89 public AvatarAppearance GetAppearance(UUID userID)
90 { 90 {
91 AvatarData avatar = GetAvatar(userID); 91 AvatarData avatar = GetAvatar(userID);
92 return avatar.ToAvatarAppearance(userID); 92 return avatar.ToAvatarAppearance();
93 } 93 }
94 94
95 public bool SetAppearance(UUID userID, AvatarAppearance appearance) 95 public bool SetAppearance(UUID userID, AvatarAppearance appearance)
diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
index 4ce406c..9c1f158 100644
--- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
@@ -242,6 +242,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
242 { 242 {
243 m_log.Debug("[USER AGENT CONNECTOR]: PackAgentCircuitData failed with exception: " + e.Message); 243 m_log.Debug("[USER AGENT CONNECTOR]: PackAgentCircuitData failed with exception: " + e.Message);
244 } 244 }
245
245 // Add the input arguments 246 // Add the input arguments
246 args["gatekeeper_serveruri"] = OSD.FromString(gatekeeper.ServerURI); 247 args["gatekeeper_serveruri"] = OSD.FromString(gatekeeper.ServerURI);
247 args["gatekeeper_host"] = OSD.FromString(gatekeeper.ExternalHostName); 248 args["gatekeeper_host"] = OSD.FromString(gatekeeper.ExternalHostName);
@@ -427,7 +428,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
427 paramList.Add(hash); 428 paramList.Add(hash);
428 429
429 XmlRpcRequest request = new XmlRpcRequest("status_notification", paramList); 430 XmlRpcRequest request = new XmlRpcRequest("status_notification", paramList);
430 string reason = string.Empty; 431// string reason = string.Empty;
431 432
432 // Send and get reply 433 // Send and get reply
433 List<UUID> friendsOnline = new List<UUID>(); 434 List<UUID> friendsOnline = new List<UUID>();
@@ -436,17 +437,17 @@ namespace OpenSim.Services.Connectors.Hypergrid
436 { 437 {
437 response = request.Send(m_ServerURL, 6000); 438 response = request.Send(m_ServerURL, 6000);
438 } 439 }
439 catch (Exception e) 440 catch
440 { 441 {
441 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL); 442 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
442 reason = "Exception: " + e.Message; 443// reason = "Exception: " + e.Message;
443 return friendsOnline; 444 return friendsOnline;
444 } 445 }
445 446
446 if (response.IsFault) 447 if (response.IsFault)
447 { 448 {
448 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString); 449 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
449 reason = "XMLRPC Fault"; 450// reason = "XMLRPC Fault";
450 return friendsOnline; 451 return friendsOnline;
451 } 452 }
452 453
@@ -458,7 +459,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
458 if (hash == null) 459 if (hash == null)
459 { 460 {
460 m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetOnlineFriends Got null response from {0}! THIS IS BAAAAD", m_ServerURL); 461 m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetOnlineFriends Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
461 reason = "Internal error 1"; 462// reason = "Internal error 1";
462 return friendsOnline; 463 return friendsOnline;
463 } 464 }
464 465
@@ -474,10 +475,10 @@ namespace OpenSim.Services.Connectors.Hypergrid
474 } 475 }
475 476
476 } 477 }
477 catch (Exception e) 478 catch
478 { 479 {
479 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetOnlineFriends response."); 480 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetOnlineFriends response.");
480 reason = "Exception: " + e.Message; 481// reason = "Exception: " + e.Message;
481 } 482 }
482 483
483 return friendsOnline; 484 return friendsOnline;
@@ -498,7 +499,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
498 paramList.Add(hash); 499 paramList.Add(hash);
499 500
500 XmlRpcRequest request = new XmlRpcRequest("get_online_friends", paramList); 501 XmlRpcRequest request = new XmlRpcRequest("get_online_friends", paramList);
501 string reason = string.Empty; 502// string reason = string.Empty;
502 503
503 // Send and get reply 504 // Send and get reply
504 List<UUID> online = new List<UUID>(); 505 List<UUID> online = new List<UUID>();
@@ -507,17 +508,17 @@ namespace OpenSim.Services.Connectors.Hypergrid
507 { 508 {
508 response = request.Send(m_ServerURL, 10000); 509 response = request.Send(m_ServerURL, 10000);
509 } 510 }
510 catch (Exception e) 511 catch
511 { 512 {
512 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL); 513 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
513 reason = "Exception: " + e.Message; 514// reason = "Exception: " + e.Message;
514 return online; 515 return online;
515 } 516 }
516 517
517 if (response.IsFault) 518 if (response.IsFault)
518 { 519 {
519 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString); 520 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
520 reason = "XMLRPC Fault"; 521// reason = "XMLRPC Fault";
521 return online; 522 return online;
522 } 523 }
523 524
@@ -529,7 +530,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
529 if (hash == null) 530 if (hash == null)
530 { 531 {
531 m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetOnlineFriends Got null response from {0}! THIS IS BAAAAD", m_ServerURL); 532 m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetOnlineFriends Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
532 reason = "Internal error 1"; 533// reason = "Internal error 1";
533 return online; 534 return online;
534 } 535 }
535 536
@@ -545,10 +546,10 @@ namespace OpenSim.Services.Connectors.Hypergrid
545 } 546 }
546 547
547 } 548 }
548 catch (Exception e) 549 catch
549 { 550 {
550 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetOnlineFriends response."); 551 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetOnlineFriends response.");
551 reason = "Exception: " + e.Message; 552// reason = "Exception: " + e.Message;
552 } 553 }
553 554
554 return online; 555 return online;
@@ -563,7 +564,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
563 paramList.Add(hash); 564 paramList.Add(hash);
564 565
565 XmlRpcRequest request = new XmlRpcRequest("get_server_urls", paramList); 566 XmlRpcRequest request = new XmlRpcRequest("get_server_urls", paramList);
566 string reason = string.Empty; 567// string reason = string.Empty;
567 568
568 // Send and get reply 569 // Send and get reply
569 Dictionary<string, object> serverURLs = new Dictionary<string,object>(); 570 Dictionary<string, object> serverURLs = new Dictionary<string,object>();
@@ -572,17 +573,17 @@ namespace OpenSim.Services.Connectors.Hypergrid
572 { 573 {
573 response = request.Send(m_ServerURL, 10000); 574 response = request.Send(m_ServerURL, 10000);
574 } 575 }
575 catch (Exception e) 576 catch
576 { 577 {
577 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL); 578 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
578 reason = "Exception: " + e.Message; 579// reason = "Exception: " + e.Message;
579 return serverURLs; 580 return serverURLs;
580 } 581 }
581 582
582 if (response.IsFault) 583 if (response.IsFault)
583 { 584 {
584 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString); 585 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
585 reason = "XMLRPC Fault"; 586// reason = "XMLRPC Fault";
586 return serverURLs; 587 return serverURLs;
587 } 588 }
588 589
@@ -594,7 +595,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
594 if (hash == null) 595 if (hash == null)
595 { 596 {
596 m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetServerURLs Got null response from {0}! THIS IS BAAAAD", m_ServerURL); 597 m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetServerURLs Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
597 reason = "Internal error 1"; 598// reason = "Internal error 1";
598 return serverURLs; 599 return serverURLs;
599 } 600 }
600 601
@@ -609,10 +610,10 @@ namespace OpenSim.Services.Connectors.Hypergrid
609 } 610 }
610 611
611 } 612 }
612 catch (Exception e) 613 catch
613 { 614 {
614 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetOnlineFriends response."); 615 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetOnlineFriends response.");
615 reason = "Exception: " + e.Message; 616// reason = "Exception: " + e.Message;
616 } 617 }
617 618
618 return serverURLs; 619 return serverURLs;
@@ -627,7 +628,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
627 paramList.Add(hash); 628 paramList.Add(hash);
628 629
629 XmlRpcRequest request = new XmlRpcRequest("locate_user", paramList); 630 XmlRpcRequest request = new XmlRpcRequest("locate_user", paramList);
630 string reason = string.Empty; 631// string reason = string.Empty;
631 632
632 // Send and get reply 633 // Send and get reply
633 string url = string.Empty; 634 string url = string.Empty;
@@ -636,17 +637,17 @@ namespace OpenSim.Services.Connectors.Hypergrid
636 { 637 {
637 response = request.Send(m_ServerURL, 10000); 638 response = request.Send(m_ServerURL, 10000);
638 } 639 }
639 catch (Exception e) 640 catch
640 { 641 {
641 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL); 642 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
642 reason = "Exception: " + e.Message; 643// reason = "Exception: " + e.Message;
643 return url; 644 return url;
644 } 645 }
645 646
646 if (response.IsFault) 647 if (response.IsFault)
647 { 648 {
648 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString); 649 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
649 reason = "XMLRPC Fault"; 650// reason = "XMLRPC Fault";
650 return url; 651 return url;
651 } 652 }
652 653
@@ -658,7 +659,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
658 if (hash == null) 659 if (hash == null)
659 { 660 {
660 m_log.ErrorFormat("[USER AGENT CONNECTOR]: LocateUser Got null response from {0}! THIS IS BAAAAD", m_ServerURL); 661 m_log.ErrorFormat("[USER AGENT CONNECTOR]: LocateUser Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
661 reason = "Internal error 1"; 662// reason = "Internal error 1";
662 return url; 663 return url;
663 } 664 }
664 665
@@ -667,10 +668,10 @@ namespace OpenSim.Services.Connectors.Hypergrid
667 url = hash["URL"].ToString(); 668 url = hash["URL"].ToString();
668 669
669 } 670 }
670 catch (Exception e) 671 catch
671 { 672 {
672 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on LocateUser response."); 673 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on LocateUser response.");
673 reason = "Exception: " + e.Message; 674// reason = "Exception: " + e.Message;
674 } 675 }
675 676
676 return url; 677 return url;
@@ -686,7 +687,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
686 paramList.Add(hash); 687 paramList.Add(hash);
687 688
688 XmlRpcRequest request = new XmlRpcRequest("get_uui", paramList); 689 XmlRpcRequest request = new XmlRpcRequest("get_uui", paramList);
689 string reason = string.Empty; 690// string reason = string.Empty;
690 691
691 // Send and get reply 692 // Send and get reply
692 string uui = string.Empty; 693 string uui = string.Empty;
@@ -695,17 +696,17 @@ namespace OpenSim.Services.Connectors.Hypergrid
695 { 696 {
696 response = request.Send(m_ServerURL, 10000); 697 response = request.Send(m_ServerURL, 10000);
697 } 698 }
698 catch (Exception e) 699 catch
699 { 700 {
700 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL); 701 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
701 reason = "Exception: " + e.Message; 702// reason = "Exception: " + e.Message;
702 return uui; 703 return uui;
703 } 704 }
704 705
705 if (response.IsFault) 706 if (response.IsFault)
706 { 707 {
707 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString); 708 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
708 reason = "XMLRPC Fault"; 709// reason = "XMLRPC Fault";
709 return uui; 710 return uui;
710 } 711 }
711 712
@@ -717,7 +718,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
717 if (hash == null) 718 if (hash == null)
718 { 719 {
719 m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetUUI Got null response from {0}! THIS IS BAAAAD", m_ServerURL); 720 m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetUUI Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
720 reason = "Internal error 1"; 721// reason = "Internal error 1";
721 return uui; 722 return uui;
722 } 723 }
723 724
@@ -726,10 +727,10 @@ namespace OpenSim.Services.Connectors.Hypergrid
726 uui = hash["UUI"].ToString(); 727 uui = hash["UUI"].ToString();
727 728
728 } 729 }
729 catch (Exception e) 730 catch
730 { 731 {
731 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on LocateUser response."); 732 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on LocateUser response.");
732 reason = "Exception: " + e.Message; 733// reason = "Exception: " + e.Message;
733 } 734 }
734 735
735 return uui; 736 return uui;
diff --git a/OpenSim/Services/Connectors/MapImage/MapImageServiceConnector.cs b/OpenSim/Services/Connectors/MapImage/MapImageServiceConnector.cs
index 520d639..69e2d17 100644
--- a/OpenSim/Services/Connectors/MapImage/MapImageServiceConnector.cs
+++ b/OpenSim/Services/Connectors/MapImage/MapImageServiceConnector.cs
@@ -50,7 +50,6 @@ namespace OpenSim.Services.Connectors
50 MethodBase.GetCurrentMethod().DeclaringType); 50 MethodBase.GetCurrentMethod().DeclaringType);
51 51
52 private string m_ServerURI = String.Empty; 52 private string m_ServerURI = String.Empty;
53 private IImprovedAssetCache m_Cache = null;
54 53
55 public MapImageServicesConnector() 54 public MapImageServicesConnector()
56 { 55 {
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs
index b8703c6..2267325 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs
@@ -97,7 +97,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
97 } 97 }
98 } 98 }
99 99
100 m_log.DebugFormat("[SIMIAN ACTIVITY DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); 100// m_log.DebugFormat("[SIMIAN ACTIVITY DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName);
101 m_GridUserService.LoggedOut(client.AgentId.ToString(), client.SessionId, client.Scene.RegionInfo.RegionID, position, lookat); 101 m_GridUserService.LoggedOut(client.AgentId.ToString(), client.SessionId, client.Scene.RegionInfo.RegionID, position, lookat);
102 } 102 }
103 } 103 }
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs
index 810399c..360f0dd 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs
@@ -213,7 +213,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
213 wearables[11] = new AvatarWearable(map["UnderpantsItem"].AsUUID(), map["UnderpantsAsset"].AsUUID()); 213 wearables[11] = new AvatarWearable(map["UnderpantsItem"].AsUUID(), map["UnderpantsAsset"].AsUUID());
214 wearables[12] = new AvatarWearable(map["SkirtItem"].AsUUID(), map["SkirtAsset"].AsUUID()); 214 wearables[12] = new AvatarWearable(map["SkirtItem"].AsUUID(), map["SkirtAsset"].AsUUID());
215 215
216 AvatarAppearance appearance = new AvatarAppearance(userID); 216 AvatarAppearance appearance = new AvatarAppearance();
217 appearance.Wearables = wearables; 217 appearance.Wearables = wearables;
218 appearance.AvatarHeight = (float)map["Height"].AsReal(); 218 appearance.AvatarHeight = (float)map["Height"].AsReal();
219 219
@@ -257,7 +257,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
257 257
258 if (avatar.AvatarType == 1) // LLAvatar 258 if (avatar.AvatarType == 1) // LLAvatar
259 { 259 {
260 AvatarAppearance appearance = avatar.ToAvatarAppearance(userID); 260 AvatarAppearance appearance = avatar.ToAvatarAppearance();
261 261
262 OSDMap map = new OSDMap(); 262 OSDMap map = new OSDMap();
263 263
diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs
index 985d77b..0a4372a 100644
--- a/OpenSim/Services/GridService/GridService.cs
+++ b/OpenSim/Services/GridService/GridService.cs
@@ -320,18 +320,25 @@ namespace OpenSim.Services.GridService
320 return null; 320 return null;
321 } 321 }
322 322
323 public GridRegion GetRegionByName(UUID scopeID, string regionName) 323 public GridRegion GetRegionByName(UUID scopeID, string name)
324 { 324 {
325 List<RegionData> rdatas = m_Database.Get(regionName + "%", scopeID); 325 List<RegionData> rdatas = m_Database.Get(name, scopeID);
326 if ((rdatas != null) && (rdatas.Count > 0)) 326 if ((rdatas != null) && (rdatas.Count > 0))
327 return RegionData2RegionInfo(rdatas[0]); // get the first 327 return RegionData2RegionInfo(rdatas[0]); // get the first
328 328
329 if (m_AllowHypergridMapSearch)
330 {
331 GridRegion r = GetHypergridRegionByName(scopeID, name);
332 if (r != null)
333 return r;
334 }
335
329 return null; 336 return null;
330 } 337 }
331 338
332 public List<GridRegion> GetRegionsByName(UUID scopeID, string name, int maxNumber) 339 public List<GridRegion> GetRegionsByName(UUID scopeID, string name, int maxNumber)
333 { 340 {
334 m_log.DebugFormat("[GRID SERVICE]: GetRegionsByName {0}", name); 341// m_log.DebugFormat("[GRID SERVICE]: GetRegionsByName {0}", name);
335 342
336 List<RegionData> rdatas = m_Database.Get(name + "%", scopeID); 343 List<RegionData> rdatas = m_Database.Get(name + "%", scopeID);
337 344
@@ -340,7 +347,7 @@ namespace OpenSim.Services.GridService
340 347
341 if (rdatas != null) 348 if (rdatas != null)
342 { 349 {
343 m_log.DebugFormat("[GRID SERVICE]: Found {0} regions", rdatas.Count); 350// m_log.DebugFormat("[GRID SERVICE]: Found {0} regions", rdatas.Count);
344 foreach (RegionData rdata in rdatas) 351 foreach (RegionData rdata in rdatas)
345 { 352 {
346 if (count++ < maxNumber) 353 if (count++ < maxNumber)
@@ -348,9 +355,9 @@ namespace OpenSim.Services.GridService
348 } 355 }
349 } 356 }
350 357
351 if (m_AllowHypergridMapSearch && (rdatas == null || (rdatas != null && rdatas.Count == 0)) && name.Contains(".")) 358 if (m_AllowHypergridMapSearch && (rdatas == null || (rdatas != null && rdatas.Count == 0)))
352 { 359 {
353 GridRegion r = m_HypergridLinker.LinkRegion(scopeID, name); 360 GridRegion r = GetHypergridRegionByName(scopeID, name);
354 if (r != null) 361 if (r != null)
355 rinfos.Add(r); 362 rinfos.Add(r);
356 } 363 }
@@ -358,6 +365,20 @@ namespace OpenSim.Services.GridService
358 return rinfos; 365 return rinfos;
359 } 366 }
360 367
368 /// <summary>
369 /// Get a hypergrid region.
370 /// </summary>
371 /// <param name="scopeID"></param>
372 /// <param name="name"></param>
373 /// <returns>null if no hypergrid region could be found.</returns>
374 protected GridRegion GetHypergridRegionByName(UUID scopeID, string name)
375 {
376 if (name.Contains("."))
377 return m_HypergridLinker.LinkRegion(scopeID, name);
378 else
379 return null;
380 }
381
361 public List<GridRegion> GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax) 382 public List<GridRegion> GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax)
362 { 383 {
363 int xminSnap = (int)(xmin / Constants.RegionSize) * (int)Constants.RegionSize; 384 int xminSnap = (int)(xmin / Constants.RegionSize) * (int)Constants.RegionSize;
@@ -489,8 +510,9 @@ namespace OpenSim.Services.GridService
489 OpenSim.Data.RegionFlags flags = (OpenSim.Data.RegionFlags)Convert.ToInt32(r.Data["flags"]); 510 OpenSim.Data.RegionFlags flags = (OpenSim.Data.RegionFlags)Convert.ToInt32(r.Data["flags"]);
490 MainConsole.Instance.Output(String.Format("{0,-20} {1}\n{2,-20} {3}\n{4,-39} {5}\n\n", 511 MainConsole.Instance.Output(String.Format("{0,-20} {1}\n{2,-20} {3}\n{4,-39} {5}\n\n",
491 r.RegionName, r.RegionID, 512 r.RegionName, r.RegionID,
492 String.Format("{0},{1}", r.posX, r.posY), r.Data["serverURI"], 513 String.Format("{0},{1}", r.posX / Constants.RegionSize, r.posY / Constants.RegionSize),
493 r.Data["owner_uuid"].ToString(), flags.ToString())); 514 r.Data["serverURI"],
515 r.Data["owner_uuid"], flags));
494 } 516 }
495 return; 517 return;
496 } 518 }
diff --git a/OpenSim/Services/HypergridService/HGInstantMessageService.cs b/OpenSim/Services/HypergridService/HGInstantMessageService.cs
index ded589d..0c9cfd3 100644
--- a/OpenSim/Services/HypergridService/HGInstantMessageService.cs
+++ b/OpenSim/Services/HypergridService/HGInstantMessageService.cs
@@ -95,7 +95,6 @@ namespace OpenSim.Services.HypergridService
95 m_InGatekeeper = serverConfig.GetBoolean("InGatekeeper", false); 95 m_InGatekeeper = serverConfig.GetBoolean("InGatekeeper", false);
96 m_log.DebugFormat("[HG IM SERVICE]: Starting... InRobust? {0}", m_InGatekeeper); 96 m_log.DebugFormat("[HG IM SERVICE]: Starting... InRobust? {0}", m_InGatekeeper);
97 97
98
99 if (gridService == string.Empty || presenceService == string.Empty) 98 if (gridService == string.Empty || presenceService == string.Empty)
100 throw new Exception(String.Format("Incomplete specifications, InstantMessage Service cannot function.")); 99 throw new Exception(String.Format("Incomplete specifications, InstantMessage Service cannot function."));
101 100
@@ -120,8 +119,8 @@ namespace OpenSim.Services.HypergridService
120 119
121 public bool IncomingInstantMessage(GridInstantMessage im) 120 public bool IncomingInstantMessage(GridInstantMessage im)
122 { 121 {
123 m_log.DebugFormat("[HG IM SERVICE]: Received message from {0} to {1}", im.fromAgentID, im.toAgentID); 122// m_log.DebugFormat("[HG IM SERVICE]: Received message from {0} to {1}", im.fromAgentID, im.toAgentID);
124 UUID toAgentID = new UUID(im.toAgentID); 123// UUID toAgentID = new UUID(im.toAgentID);
125 124
126 bool success = false; 125 bool success = false;
127 if (m_IMSimConnector != null) 126 if (m_IMSimConnector != null)
@@ -142,7 +141,7 @@ namespace OpenSim.Services.HypergridService
142 141
143 public bool OutgoingInstantMessage(GridInstantMessage im, string url, bool foreigner) 142 public bool OutgoingInstantMessage(GridInstantMessage im, string url, bool foreigner)
144 { 143 {
145 m_log.DebugFormat("[HG IM SERVICE]: Sending message from {0} to {1}@{2}", im.fromAgentID, im.toAgentID, url); 144// m_log.DebugFormat("[HG IM SERVICE]: Sending message from {0} to {1}@{2}", im.fromAgentID, im.toAgentID, url);
146 if (url != string.Empty) 145 if (url != string.Empty)
147 return TrySendInstantMessage(im, url, true, foreigner); 146 return TrySendInstantMessage(im, url, true, foreigner);
148 else 147 else
@@ -326,7 +325,6 @@ namespace OpenSim.Services.HypergridService
326 // This is recursive!!!!! 325 // This is recursive!!!!!
327 return TrySendInstantMessage(im, url, false, foreigner); 326 return TrySendInstantMessage(im, url, false, foreigner);
328 } 327 }
329
330 } 328 }
331 329
332 private bool UndeliveredMessage(GridInstantMessage im) 330 private bool UndeliveredMessage(GridInstantMessage im)
@@ -334,16 +332,15 @@ namespace OpenSim.Services.HypergridService
334 if (m_RestURL != string.Empty && (im.offline != 0) 332 if (m_RestURL != string.Empty && (im.offline != 0)
335 && (!im.fromGroup || (im.fromGroup && m_ForwardOfflineGroupMessages))) 333 && (!im.fromGroup || (im.fromGroup && m_ForwardOfflineGroupMessages)))
336 { 334 {
337 m_log.DebugFormat("[HG IM SERVICE]: Message saved"); 335// m_log.DebugFormat("[HG IM SERVICE]: Message saved");
338 return SynchronousRestObjectPoster.BeginPostObject<GridInstantMessage, bool>(
339 "POST", m_RestURL + "/SaveMessage/", im);
340 336
337 return SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>(
338 "POST", m_RestURL + "/SaveMessage/", im);
341 } 339 }
342
343 else 340 else
344 { 341 {
345 return false; 342 return false;
346 } 343 }
347 } 344 }
348 } 345 }
349} 346} \ No newline at end of file
diff --git a/OpenSim/Services/Interfaces/IAssetService.cs b/OpenSim/Services/Interfaces/IAssetService.cs
index 1ac1cec..80494f1 100644
--- a/OpenSim/Services/Interfaces/IAssetService.cs
+++ b/OpenSim/Services/Interfaces/IAssetService.cs
@@ -56,7 +56,7 @@ namespace OpenSim.Services.Interfaces
56 byte[] GetData(string id); 56 byte[] GetData(string id);
57 57
58 /// <summary> 58 /// <summary>
59 /// Synchronously fetches an asset from the local cache only 59 /// Synchronously fetches an asset from the local cache only.
60 /// </summary> 60 /// </summary>
61 /// <param name="id">Asset ID</param> 61 /// <param name="id">Asset ID</param>
62 /// <returns>The fetched asset, or null if it did not exist in the local cache</returns> 62 /// <returns>The fetched asset, or null if it did not exist in the local cache</returns>
@@ -75,7 +75,9 @@ namespace OpenSim.Services.Interfaces
75 /// <summary> 75 /// <summary>
76 /// Creates a new asset 76 /// Creates a new asset
77 /// </summary> 77 /// </summary>
78 /// Returns a random ID if none is passed into it 78 /// <remarks>
79 /// Returns a random ID if none is passed via the asset argument.
80 /// </remarks>
79 /// <param name="asset"></param> 81 /// <param name="asset"></param>
80 /// <returns></returns> 82 /// <returns></returns>
81 string Store(AssetBase asset); 83 string Store(AssetBase asset);
@@ -83,7 +85,9 @@ namespace OpenSim.Services.Interfaces
83 /// <summary> 85 /// <summary>
84 /// Update an asset's content 86 /// Update an asset's content
85 /// </summary> 87 /// </summary>
88 /// <remarks>
86 /// Attachments and bare scripts need this!! 89 /// Attachments and bare scripts need this!!
90 /// </remarks>
87 /// <param name="id"> </param> 91 /// <param name="id"> </param>
88 /// <param name="data"></param> 92 /// <param name="data"></param>
89 /// <returns></returns> 93 /// <returns></returns>
diff --git a/OpenSim/Services/Interfaces/IAuthorizationService.cs b/OpenSim/Services/Interfaces/IAuthorizationService.cs
index c5d577a..e5c68f6 100644
--- a/OpenSim/Services/Interfaces/IAuthorizationService.cs
+++ b/OpenSim/Services/Interfaces/IAuthorizationService.cs
@@ -34,14 +34,21 @@ namespace OpenSim.Services.Interfaces
34 34
35 public interface IAuthorizationService 35 public interface IAuthorizationService
36 { 36 {
37 ////////////////////////////////////////////////////// 37 /// <summary>
38 // Authorized 38 /// Check whether the user should be given access to the region.
39 // 39 /// </summary>
40 // This method returns a simple true false indicating 40 /// <remarks>
41 // whether or not a user has access to the region 41 /// We also supply user first name and last name for situations where the user does not have an account
42 // 42 /// on the region (e.g. they're a visitor via Hypergrid).
43 bool IsAuthorizedForRegion(string userID, string regionID, out string message); 43 /// </remarks>
44 44 /// <param name="userID"></param>
45 /// <param name="firstName">/param>
46 /// <param name="lastName"></param>
47 /// <param name="regionID"></param>
48 /// <param name="message"></param>
49 /// <returns></returns>
50 bool IsAuthorizedForRegion(
51 string userID, string firstName, string lastName, string regionID, out string message);
45 } 52 }
46 53
47 public class AuthorizationRequest 54 public class AuthorizationRequest
@@ -63,7 +70,8 @@ namespace OpenSim.Services.Interfaces
63 m_regionID = RegionID; 70 m_regionID = RegionID;
64 } 71 }
65 72
66 public AuthorizationRequest(string ID,string FirstName, string SurName, string Email, string RegionName, string RegionID) 73 public AuthorizationRequest(
74 string ID, string FirstName, string SurName, string Email, string RegionName, string RegionID)
67 { 75 {
68 m_userID = ID; 76 m_userID = ID;
69 m_firstname = FirstName; 77 m_firstname = FirstName;
@@ -108,9 +116,6 @@ namespace OpenSim.Services.Interfaces
108 get { return m_regionID; } 116 get { return m_regionID; }
109 set { m_regionID = value; } 117 set { m_regionID = value; }
110 } 118 }
111
112
113
114 } 119 }
115 120
116 public class AuthorizationResponse 121 public class AuthorizationResponse
@@ -126,7 +131,6 @@ namespace OpenSim.Services.Interfaces
126 { 131 {
127 m_isAuthorized = isAuthorized; 132 m_isAuthorized = isAuthorized;
128 m_message = message; 133 m_message = message;
129
130 } 134 }
131 135
132 public bool IsAuthorized 136 public bool IsAuthorized
@@ -141,4 +145,4 @@ namespace OpenSim.Services.Interfaces
141 set { m_message = value; } 145 set { m_message = value; }
142 } 146 }
143 } 147 }
144} 148} \ No newline at end of file
diff --git a/OpenSim/Services/Interfaces/IAvatarService.cs b/OpenSim/Services/Interfaces/IAvatarService.cs
index d7af562..0d5ab7d 100644
--- a/OpenSim/Services/Interfaces/IAvatarService.cs
+++ b/OpenSim/Services/Interfaces/IAvatarService.cs
@@ -180,9 +180,9 @@ namespace OpenSim.Services.Interfaces
180 } 180 }
181 } 181 }
182 182
183 public AvatarAppearance ToAvatarAppearance(UUID owner) 183 public AvatarAppearance ToAvatarAppearance()
184 { 184 {
185 AvatarAppearance appearance = new AvatarAppearance(owner); 185 AvatarAppearance appearance = new AvatarAppearance();
186 186
187 if (Data.Count == 0) 187 if (Data.Count == 0)
188 return appearance; 188 return appearance;
diff --git a/OpenSim/Services/Interfaces/IGridService.cs b/OpenSim/Services/Interfaces/IGridService.cs
index f569fc8..a084309 100644
--- a/OpenSim/Services/Interfaces/IGridService.cs
+++ b/OpenSim/Services/Interfaces/IGridService.cs
@@ -71,6 +71,12 @@ namespace OpenSim.Services.Interfaces
71 /// <returns></returns> 71 /// <returns></returns>
72 GridRegion GetRegionByPosition(UUID scopeID, int x, int y); 72 GridRegion GetRegionByPosition(UUID scopeID, int x, int y);
73 73
74 /// <summary>
75 /// Get information about a region which exactly matches the name given.
76 /// </summary>
77 /// <param name="scopeID"></param>
78 /// <param name="regionName"></param>
79 /// <returns>Returns the region information if the name matched. Null otherwise.</returns>
74 GridRegion GetRegionByName(UUID scopeID, string regionName); 80 GridRegion GetRegionByName(UUID scopeID, string regionName);
75 81
76 /// <summary> 82 /// <summary>
diff --git a/OpenSim/Services/InventoryService/LibraryService.cs b/OpenSim/Services/InventoryService/LibraryService.cs
index 383f311..f90895b 100644
--- a/OpenSim/Services/InventoryService/LibraryService.cs
+++ b/OpenSim/Services/InventoryService/LibraryService.cs
@@ -193,10 +193,11 @@ namespace OpenSim.Services.InventoryService
193 item.Description = config.GetString("description", item.Name); 193 item.Description = config.GetString("description", item.Name);
194 item.InvType = config.GetInt("inventoryType", 0); 194 item.InvType = config.GetInt("inventoryType", 0);
195 item.AssetType = config.GetInt("assetType", item.InvType); 195 item.AssetType = config.GetInt("assetType", item.InvType);
196 item.CurrentPermissions = (uint)config.GetLong("currentPermissions", 0x7FFFFFFF); 196 item.CurrentPermissions = (uint)config.GetLong("currentPermissions", (uint)PermissionMask.All);
197 item.NextPermissions = (uint)config.GetLong("nextPermissions", 0x7FFFFFFF); 197 item.NextPermissions = (uint)config.GetLong("nextPermissions", (uint)PermissionMask.All);
198 item.EveryOnePermissions = (uint)config.GetLong("everyonePermissions", 0x7FFFFFFF); 198 item.EveryOnePermissions
199 item.BasePermissions = (uint)config.GetLong("basePermissions", 0x7FFFFFFF); 199 = (uint)config.GetLong("everyonePermissions", (uint)PermissionMask.All - (uint)PermissionMask.Modify);
200 item.BasePermissions = (uint)config.GetLong("basePermissions", (uint)PermissionMask.All);
200 item.Flags = (uint)config.GetInt("flags", 0); 201 item.Flags = (uint)config.GetInt("flags", 0);
201 202
202 if (libraryFolders.ContainsKey(item.Folder)) 203 if (libraryFolders.ContainsKey(item.Folder))
diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
index 82acfbc..de05f28 100644
--- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs
+++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
@@ -188,6 +188,8 @@ namespace OpenSim.Services.LLLoginService
188 188
189 private BuddyList m_buddyList = null; 189 private BuddyList m_buddyList = null;
190 190
191 private string currency;
192
191 static LLLoginResponse() 193 static LLLoginResponse()
192 { 194 {
193 // This is being set, but it's not used 195 // This is being set, but it's not used
@@ -223,7 +225,7 @@ namespace OpenSim.Services.LLLoginService
223 public LLLoginResponse(UserAccount account, AgentCircuitData aCircuit, GridUserInfo pinfo, 225 public LLLoginResponse(UserAccount account, AgentCircuitData aCircuit, GridUserInfo pinfo,
224 GridRegion destination, List<InventoryFolderBase> invSkel, FriendInfo[] friendsList, ILibraryService libService, 226 GridRegion destination, List<InventoryFolderBase> invSkel, FriendInfo[] friendsList, ILibraryService libService,
225 string where, string startlocation, Vector3 position, Vector3 lookAt, List<InventoryItemBase> gestures, string message, 227 string where, string startlocation, Vector3 position, Vector3 lookAt, List<InventoryItemBase> gestures, string message,
226 GridRegion home, IPEndPoint clientIP, string mapTileURL, string searchURL) 228 GridRegion home, IPEndPoint clientIP, string mapTileURL, string searchURL, string currency)
227 : this() 229 : this()
228 { 230 {
229 FillOutInventoryData(invSkel, libService); 231 FillOutInventoryData(invSkel, libService);
@@ -241,6 +243,7 @@ namespace OpenSim.Services.LLLoginService
241 StartLocation = where; 243 StartLocation = where;
242 MapTileURL = mapTileURL; 244 MapTileURL = mapTileURL;
243 SearchURL = searchURL; 245 SearchURL = searchURL;
246 Currency = currency;
244 247
245 FillOutHomeData(pinfo, home); 248 FillOutHomeData(pinfo, home);
246 LookAt = String.Format("[r{0},r{1},r{2}]", lookAt.X, lookAt.Y, lookAt.Z); 249 LookAt = String.Format("[r{0},r{1},r{2}]", lookAt.X, lookAt.Y, lookAt.Z);
@@ -388,6 +391,8 @@ namespace OpenSim.Services.LLLoginService
388 initialOutfit.Add(InitialOutfitHash); 391 initialOutfit.Add(InitialOutfitHash);
389 mapTileURL = String.Empty; 392 mapTileURL = String.Empty;
390 searchURL = String.Empty; 393 searchURL = String.Empty;
394
395 currency = String.Empty;
391 } 396 }
392 397
393 398
@@ -462,6 +467,12 @@ namespace OpenSim.Services.LLLoginService
462 responseData["buddy-list"] = m_buddyList.ToArray(); 467 responseData["buddy-list"] = m_buddyList.ToArray();
463 } 468 }
464 469
470 if (currency != String.Empty)
471 {
472 // responseData["real_currency"] = currency;
473 responseData["currency"] = currency;
474 }
475
465 responseData["login"] = "true"; 476 responseData["login"] = "true";
466 477
467 return responseData; 478 return responseData;
@@ -946,6 +957,12 @@ namespace OpenSim.Services.LLLoginService
946 set { m_buddyList = value; } 957 set { m_buddyList = value; }
947 } 958 }
948 959
960 public string Currency
961 {
962 get { return currency; }
963 set { currency = value; }
964 }
965
949 #endregion 966 #endregion
950 967
951 public class UserInfo 968 public class UserInfo
diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs
index e7dd15e..d8a2054 100644
--- a/OpenSim/Services/LLLoginService/LLLoginService.cs
+++ b/OpenSim/Services/LLLoginService/LLLoginService.cs
@@ -75,6 +75,7 @@ namespace OpenSim.Services.LLLoginService
75 protected bool m_AllowRemoteSetLoginLevel; 75 protected bool m_AllowRemoteSetLoginLevel;
76 protected string m_MapTileURL; 76 protected string m_MapTileURL;
77 protected string m_SearchURL; 77 protected string m_SearchURL;
78 protected string m_Currency;
78 79
79 protected string m_AllowedClients; 80 protected string m_AllowedClients;
80 protected string m_DeniedClients; 81 protected string m_DeniedClients;
@@ -108,6 +109,7 @@ namespace OpenSim.Services.LLLoginService
108 m_GatekeeperURL = m_LoginServerConfig.GetString("GatekeeperURI", string.Empty); 109 m_GatekeeperURL = m_LoginServerConfig.GetString("GatekeeperURI", string.Empty);
109 m_MapTileURL = m_LoginServerConfig.GetString("MapTileURL", string.Empty); 110 m_MapTileURL = m_LoginServerConfig.GetString("MapTileURL", string.Empty);
110 m_SearchURL = m_LoginServerConfig.GetString("SearchURL", string.Empty); 111 m_SearchURL = m_LoginServerConfig.GetString("SearchURL", string.Empty);
112 m_Currency = m_LoginServerConfig.GetString("Currency", string.Empty);
111 113
112 m_AllowedClients = m_LoginServerConfig.GetString("AllowedClients", string.Empty); 114 m_AllowedClients = m_LoginServerConfig.GetString("AllowedClients", string.Empty);
113 m_DeniedClients = m_LoginServerConfig.GetString("DeniedClients", string.Empty); 115 m_DeniedClients = m_LoginServerConfig.GetString("DeniedClients", string.Empty);
@@ -408,14 +410,14 @@ namespace OpenSim.Services.LLLoginService
408 if (m_FriendsService != null) 410 if (m_FriendsService != null)
409 { 411 {
410 friendsList = m_FriendsService.GetFriends(account.PrincipalID); 412 friendsList = m_FriendsService.GetFriends(account.PrincipalID);
411 m_log.DebugFormat("[LLOGIN SERVICE]: Retrieved {0} friends", friendsList.Length); 413// m_log.DebugFormat("[LLOGIN SERVICE]: Retrieved {0} friends", friendsList.Length);
412 } 414 }
413 415
414 // 416 //
415 // Finally, fill out the response and return it 417 // Finally, fill out the response and return it
416 // 418 //
417 LLLoginResponse response = new LLLoginResponse(account, aCircuit, guinfo, destination, inventorySkel, friendsList, m_LibraryService, 419 LLLoginResponse response = new LLLoginResponse(account, aCircuit, guinfo, destination, inventorySkel, friendsList, m_LibraryService,
418 where, startLocation, position, lookAt, gestures, m_WelcomeMessage, home, clientIP, m_MapTileURL, m_SearchURL); 420 where, startLocation, position, lookAt, gestures, m_WelcomeMessage, home, clientIP, m_MapTileURL, m_SearchURL, m_Currency);
419 421
420 m_log.DebugFormat("[LLOGIN SERVICE]: All clear. Sending login response to client."); 422 m_log.DebugFormat("[LLOGIN SERVICE]: All clear. Sending login response to client.");
421 return response; 423 return response;
@@ -792,7 +794,7 @@ namespace OpenSim.Services.LLLoginService
792 if (avatar != null) 794 if (avatar != null)
793 aCircuit.Appearance = new AvatarAppearance(avatar); 795 aCircuit.Appearance = new AvatarAppearance(avatar);
794 else 796 else
795 aCircuit.Appearance = new AvatarAppearance(account.PrincipalID); 797 aCircuit.Appearance = new AvatarAppearance();
796 798
797 //aCircuit.BaseFolder = irrelevant 799 //aCircuit.BaseFolder = irrelevant
798 aCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); 800 aCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
diff --git a/OpenSim/Tests/Common/Helpers/AssetHelpers.cs b/OpenSim/Tests/Common/Helpers/AssetHelpers.cs
index 9b68331..99eb124 100644
--- a/OpenSim/Tests/Common/Helpers/AssetHelpers.cs
+++ b/OpenSim/Tests/Common/Helpers/AssetHelpers.cs
@@ -42,7 +42,7 @@ namespace OpenSim.Tests.Common
42 /// <returns></returns> 42 /// <returns></returns>
43 public static AssetBase CreateAsset() 43 public static AssetBase CreateAsset()
44 { 44 {
45 return CreateAsset(UUID.Random(), AssetType.Notecard, "hello", UUID.Random()); 45 return CreateAsset(UUID.Random());
46 } 46 }
47 47
48 /// <summary> 48 /// <summary>
@@ -50,9 +50,9 @@ namespace OpenSim.Tests.Common
50 /// </summary> 50 /// </summary>
51 /// <param name="creatorId">/param> 51 /// <param name="creatorId">/param>
52 /// <returns></returns> 52 /// <returns></returns>
53 public static AssetBase CreateAsset(UUID creatorId) 53 public static AssetBase CreateAsset(UUID id)
54 { 54 {
55 return CreateAsset(UUID.Random(), AssetType.Notecard, "hello", creatorId); 55 return CreateAsset(id, AssetType.Notecard, "hello", UUID.Random());
56 } 56 }
57 57
58 /// <summary> 58 /// <summary>
diff --git a/OpenSim/Tests/Common/Helpers/SceneSetupHelpers.cs b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs
index bef0481..ea433a6 100644
--- a/OpenSim/Tests/Common/Helpers/SceneSetupHelpers.cs
+++ b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs
@@ -40,6 +40,7 @@ using OpenSim.Region.Framework;
40using OpenSim.Region.Framework.Interfaces; 40using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes; 41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Region.CoreModules.Avatar.Gods; 42using OpenSim.Region.CoreModules.Avatar.Gods;
43using OpenSim.Region.CoreModules.Asset;
43using OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset; 44using OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset;
44using OpenSim.Region.CoreModules.ServiceConnectorsOut.Authentication; 45using OpenSim.Region.CoreModules.ServiceConnectorsOut.Authentication;
45using OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory; 46using OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory;
@@ -54,8 +55,13 @@ namespace OpenSim.Tests.Common
54 /// <summary> 55 /// <summary>
55 /// Helpers for setting up scenes. 56 /// Helpers for setting up scenes.
56 /// </summary> 57 /// </summary>
57 public class SceneSetupHelpers 58 public class SceneHelpers
58 { 59 {
60 public static TestScene SetupScene()
61 {
62 return SetupScene(null);
63 }
64
59 /// <summary> 65 /// <summary>
60 /// Set up a test scene 66 /// Set up a test scene
61 /// </summary> 67 /// </summary>
@@ -63,9 +69,14 @@ namespace OpenSim.Tests.Common
63 /// Automatically starts service threads, as would the normal runtime. 69 /// Automatically starts service threads, as would the normal runtime.
64 /// </remarks> 70 /// </remarks>
65 /// <returns></returns> 71 /// <returns></returns>
66 public static TestScene SetupScene() 72 public static TestScene SetupScene(CoreAssetCache cache)
73 {
74 return SetupScene("Unit test region", UUID.Random(), 1000, 1000, cache);
75 }
76
77 public static TestScene SetupScene(string name, UUID id, uint x, uint y)
67 { 78 {
68 return SetupScene("Unit test region", UUID.Random(), 1000, 1000); 79 return SetupScene(name, id, x, y, null);
69 } 80 }
70 81
71 /// <summary> 82 /// <summary>
@@ -78,7 +89,7 @@ namespace OpenSim.Tests.Common
78 /// <param name="y">Y co-ordinate of the region</param> 89 /// <param name="y">Y co-ordinate of the region</param>
79 /// <param name="cm">This should be the same if simulating two scenes within a standalone</param> 90 /// <param name="cm">This should be the same if simulating two scenes within a standalone</param>
80 /// <returns></returns> 91 /// <returns></returns>
81 public static TestScene SetupScene(string name, UUID id, uint x, uint y) 92 public static TestScene SetupScene(string name, UUID id, uint x, uint y, CoreAssetCache cache)
82 { 93 {
83 Console.WriteLine("Setting up test scene {0}", name); 94 Console.WriteLine("Setting up test scene {0}", name);
84 95
@@ -103,7 +114,7 @@ namespace OpenSim.Tests.Common
103 godsModule.Initialise(testScene, new IniConfigSource()); 114 godsModule.Initialise(testScene, new IniConfigSource());
104 testScene.AddModule(godsModule.Name, godsModule); 115 testScene.AddModule(godsModule.Name, godsModule);
105 116
106 LocalAssetServicesConnector assetService = StartAssetService(testScene); 117 LocalAssetServicesConnector assetService = StartAssetService(testScene, cache);
107 StartAuthenticationService(testScene); 118 StartAuthenticationService(testScene);
108 LocalInventoryServicesConnector inventoryService = StartInventoryService(testScene); 119 LocalInventoryServicesConnector inventoryService = StartInventoryService(testScene);
109 StartGridService(testScene); 120 StartGridService(testScene);
@@ -132,7 +143,7 @@ namespace OpenSim.Tests.Common
132 return testScene; 143 return testScene;
133 } 144 }
134 145
135 private static LocalAssetServicesConnector StartAssetService(Scene testScene) 146 private static LocalAssetServicesConnector StartAssetService(Scene testScene, CoreAssetCache cache)
136 { 147 {
137 LocalAssetServicesConnector assetService = new LocalAssetServicesConnector(); 148 LocalAssetServicesConnector assetService = new LocalAssetServicesConnector();
138 IConfigSource config = new IniConfigSource(); 149 IConfigSource config = new IniConfigSource();
@@ -145,6 +156,20 @@ namespace OpenSim.Tests.Common
145 156
146 assetService.Initialise(config); 157 assetService.Initialise(config);
147 assetService.AddRegion(testScene); 158 assetService.AddRegion(testScene);
159
160 if (cache != null)
161 {
162 IConfigSource cacheConfig = new IniConfigSource();
163 cacheConfig.AddConfig("Modules");
164 cacheConfig.Configs["Modules"].Set("AssetCaching", "CoreAssetCache");
165 cacheConfig.AddConfig("AssetCache");
166
167 cache.Initialise(cacheConfig);
168 cache.AddRegion(testScene);
169 cache.RegionLoaded(testScene);
170 testScene.AddRegionModule(cache.Name, cache);
171 }
172
148 assetService.RegionLoaded(testScene); 173 assetService.RegionLoaded(testScene);
149 testScene.AddRegionModule(assetService.Name, assetService); 174 testScene.AddRegionModule(assetService.Name, assetService);
150 175
@@ -331,6 +356,8 @@ namespace OpenSim.Tests.Common
331 agentData.InventoryFolder = UUID.Zero; 356 agentData.InventoryFolder = UUID.Zero;
332 agentData.startpos = Vector3.Zero; 357 agentData.startpos = Vector3.Zero;
333 agentData.CapsPath = "http://wibble.com"; 358 agentData.CapsPath = "http://wibble.com";
359 agentData.ServiceURLs = new Dictionary<string, object>();
360 agentData.Appearance = new AvatarAppearance();
334 361
335 return agentData; 362 return agentData;
336 } 363 }
@@ -341,9 +368,9 @@ namespace OpenSim.Tests.Common
341 /// <param name="scene"></param> 368 /// <param name="scene"></param>
342 /// <param name="agentId"></param> 369 /// <param name="agentId"></param>
343 /// <returns></returns> 370 /// <returns></returns>
344 public static TestClient AddRootAgent(Scene scene, UUID agentId) 371 public static ScenePresence AddScenePresence(Scene scene, UUID agentId)
345 { 372 {
346 return AddRootAgent(scene, GenerateAgentData(agentId)); 373 return AddScenePresence(scene, GenerateAgentData(agentId));
347 } 374 }
348 375
349 /// <summary> 376 /// <summary>
@@ -364,7 +391,7 @@ namespace OpenSim.Tests.Common
364 /// <param name="scene"></param> 391 /// <param name="scene"></param>
365 /// <param name="agentData"></param> 392 /// <param name="agentData"></param>
366 /// <returns></returns> 393 /// <returns></returns>
367 public static TestClient AddRootAgent(Scene scene, AgentCircuitData agentData) 394 public static ScenePresence AddScenePresence(Scene scene, AgentCircuitData agentData)
368 { 395 {
369 string reason; 396 string reason;
370 397
@@ -379,14 +406,14 @@ namespace OpenSim.Tests.Common
379 406
380 // Stage 2: add the new client as a child agent to the scene 407 // Stage 2: add the new client as a child agent to the scene
381 TestClient client = new TestClient(agentData, scene); 408 TestClient client = new TestClient(agentData, scene);
382 scene.AddNewClient(client); 409 scene.AddNewClient(client, PresenceType.User);
383 410
384 // Stage 3: Complete the entrance into the region. This converts the child agent into a root agent. 411 // Stage 3: Complete the entrance into the region. This converts the child agent into a root agent.
385 ScenePresence scp = scene.GetScenePresence(agentData.AgentID); 412 ScenePresence scp = scene.GetScenePresence(agentData.AgentID);
386 scp.CompleteMovement(client); 413 scp.CompleteMovement(client, true);
387 //scp.MakeRootAgent(new Vector3(90, 90, 90), true); 414 //scp.MakeRootAgent(new Vector3(90, 90, 90), true);
388 415
389 return client; 416 return scp;
390 } 417 }
391 418
392 /// <summary> 419 /// <summary>
diff --git a/OpenSim/Tests/Common/Helpers/TaskInventoryHelpers.cs b/OpenSim/Tests/Common/Helpers/TaskInventoryHelpers.cs
index 5215c34..a8f0d59 100644
--- a/OpenSim/Tests/Common/Helpers/TaskInventoryHelpers.cs
+++ b/OpenSim/Tests/Common/Helpers/TaskInventoryHelpers.cs
@@ -74,7 +74,7 @@ namespace OpenSim.Tests.Common
74 /// <param name="id"></param> 74 /// <param name="id"></param>
75 public static TaskInventoryItem AddSceneObject(Scene scene, SceneObjectPart sop, string itemName, UUID id) 75 public static TaskInventoryItem AddSceneObject(Scene scene, SceneObjectPart sop, string itemName, UUID id)
76 { 76 {
77 SceneObjectGroup taskSceneObject = SceneSetupHelpers.CreateSceneObject(1, UUID.Zero); 77 SceneObjectGroup taskSceneObject = SceneHelpers.CreateSceneObject(1, UUID.Zero);
78 AssetBase taskSceneObjectAsset = AssetHelpers.CreateAsset(0x10, taskSceneObject); 78 AssetBase taskSceneObjectAsset = AssetHelpers.CreateAsset(0x10, taskSceneObject);
79 scene.AssetService.Store(taskSceneObjectAsset); 79 scene.AssetService.Store(taskSceneObjectAsset);
80 TaskInventoryItem taskSceneObjectItem 80 TaskInventoryItem taskSceneObjectItem
diff --git a/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs b/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs
index d924ecd..b73df2c 100644
--- a/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs
+++ b/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs
@@ -118,13 +118,12 @@ namespace OpenSim.Tests.Common
118 118
119 public static UserAccount CreateUserWithInventory(Scene scene) 119 public static UserAccount CreateUserWithInventory(Scene scene)
120 { 120 {
121 return CreateUserWithInventory(scene, 99); 121 return CreateUserWithInventory(scene, TestHelpers.ParseTail(99));
122 } 122 }
123 123
124 public static UserAccount CreateUserWithInventory(Scene scene, int uuidTail) 124 public static UserAccount CreateUserWithInventory(Scene scene, UUID userId)
125 { 125 {
126 return CreateUserWithInventory( 126 return CreateUserWithInventory(scene, "Bill", "Bailey", userId, "troll");
127 scene, "Bill", "Bailey", new UUID(string.Format("00000000-0000-0000-0000-{0:X12}", uuidTail)), "troll");
128 } 127 }
129 128
130 public static UserAccount CreateUserWithInventory( 129 public static UserAccount CreateUserWithInventory(
@@ -139,7 +138,6 @@ namespace OpenSim.Tests.Common
139 { 138 {
140 // FIXME: This should really be set up by UserAccount itself 139 // FIXME: This should really be set up by UserAccount itself
141 ua.ServiceURLs = new Dictionary<string, object>(); 140 ua.ServiceURLs = new Dictionary<string, object>();
142
143 scene.UserAccountService.StoreUserAccount(ua); 141 scene.UserAccountService.StoreUserAccount(ua);
144 scene.InventoryService.CreateUserInventory(ua.PrincipalID); 142 scene.InventoryService.CreateUserInventory(ua.PrincipalID);
145 scene.AuthenticationService.SetPassword(ua.PrincipalID, pw); 143 scene.AuthenticationService.SetPassword(ua.PrincipalID, pw);
diff --git a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs
index 1703597..4e60ca9 100644
--- a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs
+++ b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs
@@ -52,7 +52,22 @@ namespace OpenSim.Tests.Common
52 /// <returns></returns> 52 /// <returns></returns>
53 public static InventoryItemBase CreateInventoryItem(Scene scene, string itemName, UUID userId) 53 public static InventoryItemBase CreateInventoryItem(Scene scene, string itemName, UUID userId)
54 { 54 {
55 return CreateInventoryItem(scene, itemName, UUID.Random(), userId); 55 return CreateInventoryItem(scene, itemName, UUID.Random(), UUID.Random(), userId, InventoryType.Notecard);
56 }
57
58 /// <summary>
59 /// Creates an item of the given type with an accompanying asset.
60 /// </summary>
61 /// <param name="scene"></param>
62 /// <param name="itemName"></param>
63 /// <param name="itemId"></param>
64 /// <param name="userId"></param>
65 /// <param name="type">Type of item to create</param>
66 /// <returns></returns>
67 public static InventoryItemBase CreateInventoryItem(
68 Scene scene, string itemName, UUID userId, InventoryType type)
69 {
70 return CreateInventoryItem(scene, itemName, UUID.Random(), UUID.Random(), userId, type);
56 } 71 }
57 72
58 /// <summary> 73 /// <summary>
@@ -61,18 +76,32 @@ namespace OpenSim.Tests.Common
61 /// <param name="scene"></param> 76 /// <param name="scene"></param>
62 /// <param name="itemName"></param> 77 /// <param name="itemName"></param>
63 /// <param name="itemId"></param> 78 /// <param name="itemId"></param>
79 /// <param name="assetId"></param>
64 /// <param name="userId"></param> 80 /// <param name="userId"></param>
81 /// <param name="type">Type of item to create</param>
65 /// <returns></returns> 82 /// <returns></returns>
66 public static InventoryItemBase CreateInventoryItem(Scene scene, string itemName, UUID itemId, UUID userId) 83 public static InventoryItemBase CreateInventoryItem(
84 Scene scene, string itemName, UUID itemId, UUID assetId, UUID userId, InventoryType type)
67 { 85 {
68 AssetBase asset = AssetHelpers.CreateAsset(scene, userId); 86 AssetBase asset = null;
87
88 if (type == InventoryType.Notecard)
89 asset = AssetHelpers.CreateAsset(scene, userId);
90 else if (type == InventoryType.Object)
91 asset
92 = AssetHelpers.CreateAsset(assetId, SceneHelpers.CreateSceneObject(1, userId));
93 else
94 throw new Exception(string.Format("Inventory type {0} not supported", type));
95
96 scene.AssetService.Store(asset);
97
69 InventoryItemBase item = new InventoryItemBase(); 98 InventoryItemBase item = new InventoryItemBase();
70 item.Name = itemName; 99 item.Name = itemName;
71 item.AssetID = asset.FullID; 100 item.AssetID = asset.FullID;
72 item.ID = itemId; 101 item.ID = itemId;
73 item.Owner = userId; 102 item.Owner = userId;
74 item.AssetType = asset.Type; 103 item.AssetType = asset.Type;
75 item.InvType = (int)InventoryType.Notecard; 104 item.InvType = (int)type;
76 105
77 InventoryFolderBase folder = scene.InventoryService.GetFolderForType(userId, AssetType.Notecard); 106 InventoryFolderBase folder = scene.InventoryService.GetFolderForType(userId, AssetType.Notecard);
78 107
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs
index 0f89f84..014f7f6 100644
--- a/OpenSim/Tests/Common/Mock/TestClient.cs
+++ b/OpenSim/Tests/Common/Mock/TestClient.cs
@@ -95,7 +95,7 @@ namespace OpenSim.Tests.Common.Mock
95 public event DeRezObject OnDeRezObject; 95 public event DeRezObject OnDeRezObject;
96 public event Action<IClientAPI> OnRegionHandShakeReply; 96 public event Action<IClientAPI> OnRegionHandShakeReply;
97 public event GenericCall1 OnRequestWearables; 97 public event GenericCall1 OnRequestWearables;
98 public event GenericCall1 OnCompleteMovementToRegion; 98 public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
99 public event UpdateAgent OnPreAgentUpdate; 99 public event UpdateAgent OnPreAgentUpdate;
100 public event UpdateAgent OnAgentUpdate; 100 public event UpdateAgent OnAgentUpdate;
101 public event AgentRequestSit OnAgentRequestSit; 101 public event AgentRequestSit OnAgentRequestSit;
@@ -234,7 +234,7 @@ namespace OpenSim.Tests.Common.Mock
234 public event ScriptReset OnScriptReset; 234 public event ScriptReset OnScriptReset;
235 public event GetScriptRunning OnGetScriptRunning; 235 public event GetScriptRunning OnGetScriptRunning;
236 public event SetScriptRunning OnSetScriptRunning; 236 public event SetScriptRunning OnSetScriptRunning;
237 public event UpdateVector OnAutoPilotGo; 237 public event Action<Vector3, bool> OnAutoPilotGo;
238 238
239 public event TerrainUnacked OnUnackedTerrain; 239 public event TerrainUnacked OnUnackedTerrain;
240 240
@@ -455,7 +455,7 @@ namespace OpenSim.Tests.Common.Mock
455 455
456 public void CompleteMovement() 456 public void CompleteMovement()
457 { 457 {
458 OnCompleteMovementToRegion(this); 458 OnCompleteMovementToRegion(this, true);
459 } 459 }
460 460
461 public virtual void ActivateGesture(UUID assetId, UUID gestureId) 461 public virtual void ActivateGesture(UUID assetId, UUID gestureId)
@@ -579,7 +579,7 @@ namespace OpenSim.Tests.Common.Mock
579 579
580 // Stage 2: add the new client as a child agent to the scene 580 // Stage 2: add the new client as a child agent to the scene
581 TeleportSceneClient = new TestClient(newAgent, TeleportTargetScene); 581 TeleportSceneClient = new TestClient(newAgent, TeleportTargetScene);
582 TeleportTargetScene.AddNewClient(TeleportSceneClient); 582 TeleportTargetScene.AddNewClient(TeleportSceneClient, PresenceType.User);
583 } 583 }
584 584
585 public virtual void SendRegionTeleport(ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint, 585 public virtual void SendRegionTeleport(ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint,
@@ -759,9 +759,10 @@ namespace OpenSim.Tests.Common.Mock
759 759
760 if (OnCompleteMovementToRegion != null) 760 if (OnCompleteMovementToRegion != null)
761 { 761 {
762 OnCompleteMovementToRegion(this); 762 OnCompleteMovementToRegion(this, true);
763 } 763 }
764 } 764 }
765
765 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) 766 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID)
766 { 767 {
767 } 768 }
@@ -890,7 +891,7 @@ namespace OpenSim.Tests.Common.Mock
890 } 891 }
891 public void Close(bool sendStop) 892 public void Close(bool sendStop)
892 { 893 {
893 m_scene.RemoveClient(AgentId); 894 m_scene.RemoveClient(AgentId, true);
894 } 895 }
895 896
896 public void Start() 897 public void Start()
diff --git a/OpenSim/Tests/Common/TestHelper.cs b/OpenSim/Tests/Common/TestHelpers.cs
index 86bd107..ced06de 100644
--- a/OpenSim/Tests/Common/TestHelper.cs
+++ b/OpenSim/Tests/Common/TestHelpers.cs
@@ -32,7 +32,7 @@ using OpenMetaverse;
32 32
33namespace OpenSim.Tests.Common 33namespace OpenSim.Tests.Common
34{ 34{
35 public class TestHelper 35 public class TestHelpers
36 { 36 {
37 public static bool AssertThisDelegateCausesArgumentException(TestDelegate d) 37 public static bool AssertThisDelegateCausesArgumentException(TestDelegate d)
38 { 38 {
diff --git a/Prebuild/src/Core/Targets/.NAntTarget.cs.swp b/Prebuild/src/Core/Targets/.NAntTarget.cs.swp
deleted file mode 100644
index afec61c..0000000
--- a/Prebuild/src/Core/Targets/.NAntTarget.cs.swp
+++ /dev/null
Binary files differ
diff --git a/Prebuild/src/Core/Targets/NAntTarget.cs b/Prebuild/src/Core/Targets/NAntTarget.cs
index d4a33f8..1966f66 100644
--- a/Prebuild/src/Core/Targets/NAntTarget.cs
+++ b/Prebuild/src/Core/Targets/NAntTarget.cs
@@ -644,9 +644,12 @@ namespace Prebuild.Core.Targets
644 ss.WriteLine(" <delete failonerror=\"false\">"); 644 ss.WriteLine(" <delete failonerror=\"false\">");
645 ss.WriteLine(" <fileset basedir=\"${bin.dir}\">"); 645 ss.WriteLine(" <fileset basedir=\"${bin.dir}\">");
646 ss.WriteLine(" <include name=\"OpenSim*.dll\"/>"); 646 ss.WriteLine(" <include name=\"OpenSim*.dll\"/>");
647 ss.WriteLine(" <include name=\"OpenSim*.dll.mdb\"/>");
647 ss.WriteLine(" <include name=\"OpenSim*.exe\"/>"); 648 ss.WriteLine(" <include name=\"OpenSim*.exe\"/>");
649 ss.WriteLine(" <include name=\"OpenSim*.exe.mdb\"/>");
648 ss.WriteLine(" <include name=\"ScriptEngines/*\"/>"); 650 ss.WriteLine(" <include name=\"ScriptEngines/*\"/>");
649 ss.WriteLine(" <include name=\"Physics/*\"/>"); 651 ss.WriteLine(" <include name=\"Physics/*.dll\"/>");
652 ss.WriteLine(" <include name=\"Physics/*.dll.mdb\"/>");
650 ss.WriteLine(" <exclude name=\"OpenSim.32BitLaunch.exe\"/>"); 653 ss.WriteLine(" <exclude name=\"OpenSim.32BitLaunch.exe\"/>");
651 ss.WriteLine(" <exclude name=\"ScriptEngines/Default.lsl\"/>"); 654 ss.WriteLine(" <exclude name=\"ScriptEngines/Default.lsl\"/>");
652 ss.WriteLine(" </fileset>"); 655 ss.WriteLine(" </fileset>");
diff --git a/ThirdPartyLicenses/ConvexDecompositionDotNet.txt b/ThirdPartyLicenses/ConvexDecompositionDotNet.txt
new file mode 100644
index 0000000..714ae89
--- /dev/null
+++ b/ThirdPartyLicenses/ConvexDecompositionDotNet.txt
@@ -0,0 +1,28 @@
1ConvexDecompositionDotNet
2-------------------------
3
4The MIT License
5
6Copyright (c) 2010 Intel Corporation.
7All rights reserved.
8
9Based on the convexdecomposition library from
10<http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files (the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions:
18
19The above copyright notice and this permission notice shall be included in
20all copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28THE SOFTWARE.
diff --git a/bin/BulletSim-x86_64.dll b/bin/BulletSim-x86_64.dll
new file mode 100755
index 0000000..6620759
--- /dev/null
+++ b/bin/BulletSim-x86_64.dll
Binary files differ
diff --git a/bin/BulletSim.dll b/bin/BulletSim.dll
new file mode 100755
index 0000000..ffb5380
--- /dev/null
+++ b/bin/BulletSim.dll
Binary files differ
diff --git a/bin/HttpServer.dll b/bin/HttpServer.dll
deleted file mode 100755
index 717ceed..0000000
--- a/bin/HttpServer.dll
+++ /dev/null
Binary files differ
diff --git a/bin/MXP.pdb b/bin/MXP.pdb
deleted file mode 100644
index deadeef..0000000
--- a/bin/MXP.pdb
+++ /dev/null
Binary files differ
diff --git a/bin/OpenSim.Region.OptionalModules.Tests.dll.config b/bin/OpenSim.Region.OptionalModules.Tests.dll.config
new file mode 100644
index 0000000..a3f681d
--- /dev/null
+++ b/bin/OpenSim.Region.OptionalModules.Tests.dll.config
@@ -0,0 +1,33 @@
1<?xml version="1.0" encoding="utf-8" ?>
2<configuration>
3 <configSections>
4 <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
5 </configSections>
6 <runtime>
7 <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
8 <dependentAssembly>
9 <assemblyIdentity name="nunit.framework" publicKeyToken="96d09a1eb7f44a77" culture="Neutral" />
10 <bindingRedirect oldVersion="2.0.6.0" newVersion="2.4.6.0" />
11 <bindingRedirect oldVersion="2.1.4.0" newVersion="2.4.6.0" />
12 <bindingRedirect oldVersion="2.2.8.0" newVersion="2.4.6.0" />
13 </dependentAssembly>
14 </assemblyBinding>
15 </runtime>
16 <log4net>
17 <!-- A1 is set to be a ConsoleAppender -->
18 <appender name="A1" type="log4net.Appender.ConsoleAppender">
19
20 <!-- A1 uses PatternLayout -->
21 <layout type="log4net.Layout.PatternLayout">
22 <!-- Print the date in ISO 8601 format -->
23 <conversionPattern value="%date [%thread] %-5level %logger %ndc - %message%newline" />
24 </layout>
25 </appender>
26
27 <!-- Set root logger level to DEBUG and its only appender to A1 -->
28 <root>
29 <level value="DEBUG" />
30 <appender-ref ref="A1" />
31 </root>
32 </log4net>
33</configuration>
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example
index 60d37fb..c36d2a4 100644
--- a/bin/OpenSim.ini.example
+++ b/bin/OpenSim.ini.example
@@ -39,6 +39,9 @@
39 ;# {save_crashes} {} {Save crashes to disk?} {true false} false 39 ;# {save_crashes} {} {Save crashes to disk?} {true false} false
40 ;; Set this to true if you want to log crashes to disk 40 ;; Set this to true if you want to log crashes to disk
41 ;; this can be useful when submitting bug reports. 41 ;; this can be useful when submitting bug reports.
42 ;; However, this will only log crashes within OpenSimulator that cause the entire program to exit
43 ;; It will not log crashes caused by virtual machine failures, which includes mono and ODE failures.
44 ;; You will need to capture these native stack traces by recording the session log itself.
42 ; save_crashes = false 45 ; save_crashes = false
43 46
44 ;# {crash_dir} {save_crashes:true} {Directory to save crashes to?} {} crashes 47 ;# {crash_dir} {save_crashes:true} {Directory to save crashes to?} {} crashes
@@ -68,15 +71,6 @@
68 ;; in a <Regions> tag. 71 ;; in a <Regions> tag.
69 ; regionload_webserver_url = "http://example.com/regions.xml"; 72 ; regionload_webserver_url = "http://example.com/regions.xml";
70 73
71 ;# {TextureOnMapTile} {} {Use terrain textures for map tiles?} {true false} false
72 ;; Use terrain texture for maptiles if true, use shaded green if false
73 ; TextureOnMapTile = false
74
75 ;# {DrawPrimOnMapTile} {} {Draw prim shapes on map tiles?} {true false} false
76 ;; Draw objects on maptile. This step might take a long time if you've
77 ;; got a large number of objects, so you can turn it off here if you'd like.
78 ; DrawPrimOnMapTile = true
79
80 ;# {NonPhysicalPrimMax} {} {Maximum size of nonphysical prims?} {} 256 74 ;# {NonPhysicalPrimMax} {} {Maximum size of nonphysical prims?} {} 256
81 ;; Maximum size for non-physical prims. Affects resizing of existing prims. This can be overriden in the region config file (as NonphysicalPrimMax!). 75 ;; Maximum size for non-physical prims. Affects resizing of existing prims. This can be overriden in the region config file (as NonphysicalPrimMax!).
82 ; NonPhysicalPrimMax = 256 76 ; NonPhysicalPrimMax = 256
@@ -89,9 +83,11 @@
89 ;; This can be overriden in the region config file. 83 ;; This can be overriden in the region config file.
90 ; ClampPrimSize = false 84 ; ClampPrimSize = false
91 85
92 ;# {AllowScriptCrossing} {} {Allow scripts to cross into this region} {true false} false 86 ;# {AllowScriptCrossing} {} {Allow scripts to cross into this region} {true false} true
93 ;; Allow scripts to keep running when they cross region boundaries, rather than being restarted. Script code is recompiled on the destination region and the state reloaded. 87 ;; Allow scripts to keep running when they cross region boundaries, rather than being restarted. State is reloaded on the destination region.
94 ; AllowScriptCrossing = false 88 ;; This only applies when crossing to a region running in a different simulator.
89 ;; For crossings where the regions are on the same simulator the script is always kept running.
90 ; AllowScriptCrossing = true
95 91
96 ;# {TrustBinaries} {AllowScriptCrossing:true} {Accept compiled binary script code? (DANGEROUS!)} {true false} false 92 ;# {TrustBinaries} {AllowScriptCrossing:true} {Accept compiled binary script code? (DANGEROUS!)} {true false} false
97 ;; Allow compiled script binary code to cross region boundaries. 93 ;; Allow compiled script binary code to cross region boundaries.
@@ -155,6 +151,7 @@
155 ;; OpenDynamicsEngine is by some distance the most developed physics engine 151 ;; OpenDynamicsEngine is by some distance the most developed physics engine
156 ;; basicphysics effectively does not model physics at all, making all 152 ;; basicphysics effectively does not model physics at all, making all
157 ;; objects phantom 153 ;; objects phantom
154 ;; The Bullet plugins do not work properly right now. A better Bullet plugin is on the way.
158 ;; Default is OpenDynamicsEngine 155 ;; Default is OpenDynamicsEngine
159 ; physics = OpenDynamicsEngine 156 ; physics = OpenDynamicsEngine
160 ; physics = basicphysics 157 ; physics = basicphysics
@@ -190,7 +187,7 @@
190 ;; Map tile options. You can choose to generate no map tiles at all, 187 ;; Map tile options. You can choose to generate no map tiles at all,
191 ;; generate normal maptiles, or nominate an uploaded texture to 188 ;; generate normal maptiles, or nominate an uploaded texture to
192 ;; be the map tile 189 ;; be the map tile
193 ; GenerateMaptiles = "true" 190 ; GenerateMaptiles = true
194 191
195 ;; If desired, a running region can update the map tiles periodically 192 ;; If desired, a running region can update the map tiles periodically
196 ;; to reflect building activity. This names no sense of you don't have 193 ;; to reflect building activity. This names no sense of you don't have
@@ -200,6 +197,15 @@
200 ;; If not generating maptiles, use this static texture asset ID 197 ;; If not generating maptiles, use this static texture asset ID
201 ; MaptileStaticUUID = "00000000-0000-0000-0000-000000000000" 198 ; MaptileStaticUUID = "00000000-0000-0000-0000-000000000000"
202 199
200 ;# {TextureOnMapTile} {} {Use terrain textures for map tiles?} {true false} true
201 ;; Use terrain texture for maptiles if true, use shaded green if false
202 ; TextureOnMapTile = true
203
204 ;# {DrawPrimOnMapTile} {} {Draw prim shapes on map tiles?} {true false} false
205 ;; Draw objects on maptile. This step might take a long time if you've
206 ;; got a large number of objects, so you can turn it off here if you'd like.
207 ; DrawPrimOnMapTile = true
208
203 ;; Http proxy setting for llHTTPRequest and dynamic texture loading, if required 209 ;; Http proxy setting for llHTTPRequest and dynamic texture loading, if required
204 ; HttpProxy = "http://proxy.com:8080" 210 ; HttpProxy = "http://proxy.com:8080"
205 211
@@ -218,7 +224,7 @@
218 ;; The SMTP server enabled the email module to send email to external 224 ;; The SMTP server enabled the email module to send email to external
219 ;; destinations. 225 ;; destinations.
220 226
221 ;# {enabled} {[Startup]emailmodule:DefaultEmailModule} {Enable SMTP service?} {true false} true 227 ;# {enabled} {[Startup]emailmodule:DefaultEmailModule} {Enable SMTP service?} {true false} false
222 ;; Enable sending email via SMTP 228 ;; Enable sending email via SMTP
223 ; enabled = false 229 ; enabled = false
224 230
@@ -313,8 +319,8 @@
313 ; meant to override the MapImage and search server url given at login, and varying 319 ; meant to override the MapImage and search server url given at login, and varying
314 ; on a sim-basis. 320 ; on a sim-basis.
315 ; Viewers that don't understand it, will ignore it 321 ; Viewers that don't understand it, will ignore it
316 ;MapImageServerURI = "http://127.0.0.1:9000/ 322 ;MapImageServerURI = "http://127.0.0.1:9000/"
317 ;SearchServerURI = "http://127.0.0.1:9000/ 323 ;SearchServerURI = "http://127.0.0.1:9000/"
318 324
319 325
320[Chat] 326[Chat]
@@ -711,6 +717,11 @@
711 ; Enabled = true; 717 ; Enabled = true;
712 718
713 719
720[NPC]
721 ;# {Enabled} {} {Enable Non Player Character (NPC) facilities} {true false} false
722 ; Enabled = false
723
724
714[PrimLimitsModule] 725[PrimLimitsModule]
715 ;# {EnforcePrimLimits} {} {Enforce parcel prim limits} {true false} false 726 ;# {EnforcePrimLimits} {} {Enforce parcel prim limits} {true false} false
716 ;; Enable parcel prim limits. Off by default to emulate pre-existing behavior. 727 ;; Enable parcel prim limits. Off by default to emulate pre-existing behavior.
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini
index 5aeadce..ca4fbfb 100644
--- a/bin/OpenSimDefaults.ini
+++ b/bin/OpenSimDefaults.ini
@@ -5,6 +5,9 @@
5[Startup] 5[Startup]
6 ; Set this to true if you want to log crashes to disk 6 ; Set this to true if you want to log crashes to disk
7 ; this can be useful when submitting bug reports. 7 ; this can be useful when submitting bug reports.
8 ; However, this will only log crashes within OpenSimulator that cause the entire program to exit
9 ; It will not log crashes caused by virtual machine failures, which includes mono and ODE failures.
10 ; You will need to capture these native stack traces by recording the session log itself.
8 save_crashes = false 11 save_crashes = false
9 12
10 ; Directory to save crashes to if above is enabled 13 ; Directory to save crashes to if above is enabled
@@ -67,12 +70,6 @@
67 ; except that everything is also enclosed in a <Regions> tag. 70 ; except that everything is also enclosed in a <Regions> tag.
68 ; regionload_webserver_url = "http://example.com/regions.xml"; 71 ; regionload_webserver_url = "http://example.com/regions.xml";
69 72
70 ; Draw objects on maptile. This step might take a long time if you've got a large number of
71 ; objects, so you can turn it off here if you'd like.
72 DrawPrimOnMapTile = true
73 ; Use terrain texture for maptiles if true, use shaded green if false
74 TextureOnMapTile = false
75
76 ; Maximum size of non physical prims. Affects resizing of existing prims. This can be overriden in the region config file (as NonphysicalPrimMax!). 73 ; Maximum size of non physical prims. Affects resizing of existing prims. This can be overriden in the region config file (as NonphysicalPrimMax!).
77 NonPhysicalPrimMax = 256 74 NonPhysicalPrimMax = 256
78 75
@@ -83,8 +80,10 @@
83 ; This can be overriden in the region config file. 80 ; This can be overriden in the region config file.
84 ClampPrimSize = false 81 ClampPrimSize = false
85 82
86 ; Allow scripts to keep running when they cross region boundaries, rather than being restarted. Script code is recompiled on the destination region and the state reloaded. 83 ; Allow scripts to keep running when they cross region boundaries, rather than being restarted. State is reloaded on the destination region.
87 AllowScriptCrossing = false 84 ; This only applies when crossing to a region running in a different simulator.
85 ; For crossings where the regions are on the same simulator the script is always kept running.
86 AllowScriptCrossing = true
88 87
89 ; Allow compiled script binary code to cross region boundaries. 88 ; Allow compiled script binary code to cross region boundaries.
90 ; If you set this to "true", any region that can teleport to you can 89 ; If you set this to "true", any region that can teleport to you can
@@ -165,6 +164,7 @@
165 ;physics = basicphysics 164 ;physics = basicphysics
166 ;physics = POS 165 ;physics = POS
167 ;physics = modified_BulletX 166 ;physics = modified_BulletX
167 ;physics = BulletSim
168 168
169 ; ## 169 ; ##
170 ; ## PERMISSIONS 170 ; ## PERMISSIONS
@@ -175,8 +175,8 @@
175 ; If set to false, then, in theory, the server never carries out permission checks (allowing anybody to copy 175 ; If set to false, then, in theory, the server never carries out permission checks (allowing anybody to copy
176 ; any item, etc. This may not yet be implemented uniformally. 176 ; any item, etc. This may not yet be implemented uniformally.
177 ; If set to true, then all permissions checks are carried out 177 ; If set to true, then all permissions checks are carried out
178 ; Default is false 178 ; Default is true
179 serverside_object_permissions = false 179 serverside_object_permissions = true
180 180
181 allow_grid_gods = false 181 allow_grid_gods = false
182 182
@@ -216,13 +216,26 @@
216 216
217 ;WorldMapModule = "WorldMap" 217 ;WorldMapModule = "WorldMap"
218 ;MapImageModule = "MapImageModule" 218 ;MapImageModule = "MapImageModule"
219
220 ; World map blacklist timeout in seconds
221 ;BlacklistTimeout = 600
222
219 ; Set to false to not generate any maptiles 223 ; Set to false to not generate any maptiles
220 ;GenerateMaptiles = "true" 224 ;GenerateMaptiles = true
225
221 ; Refresh (in seconds) the map tile periodically 226 ; Refresh (in seconds) the map tile periodically
222 ;MaptileRefresh = 0 227 ;MaptileRefresh = 0
228
223 ; If not generating maptiles, use this static texture asset ID 229 ; If not generating maptiles, use this static texture asset ID
224 ;MaptileStaticUUID = "00000000-0000-0000-0000-000000000000" 230 ;MaptileStaticUUID = "00000000-0000-0000-0000-000000000000"
225 231
232 ; Draw objects on maptile. This step might take a long time if you've got a large number of
233 ; objects, so you can turn it off here if you'd like.
234 DrawPrimOnMapTile = true
235
236 ; Use terrain texture for maptiles if true, use shaded green if false
237 TextureOnMapTile = true
238
226 ; ## 239 ; ##
227 ; ## EMAIL MODULE 240 ; ## EMAIL MODULE
228 ; ## 241 ; ##
@@ -273,15 +286,15 @@
273 286
274 287
275[SMTP] 288[SMTP]
276 enabled=false 289 enabled = false
277 290
278 ;enabled=true 291 ;enabled = true
279 ;internal_object_host=lsl.opensim.local 292 ;internal_object_host = lsl.opensim.local
280 ;host_domain_header_from=127.0.0.1 293 ;host_domain_header_from = 127.0.0.1
281 ;SMTP_SERVER_HOSTNAME=127.0.0.1 294 ;SMTP_SERVER_HOSTNAME = 127.0.0.1
282 ;SMTP_SERVER_PORT=25 295 ;SMTP_SERVER_PORT = 25
283 ;SMTP_SERVER_LOGIN=foo 296 ;SMTP_SERVER_LOGIN = foo
284 ;SMTP_SERVER_PASSWORD=bar 297 ;SMTP_SERVER_PASSWORD = bar
285 298
286 299
287[Network] 300[Network]
@@ -721,6 +734,49 @@
721 ; true. Note that this will increase memory usage and region startup time. Default is false. 734 ; true. Note that this will increase memory usage and region startup time. Default is false.
722 ;force_simple_prim_meshing = true 735 ;force_simple_prim_meshing = true
723 736
737[BulletSim]
738 ; World parameters
739 DefaultFriction = 0.50
740 DefaultDensity = 10.000006836
741 DefaultRestitution = 0.0
742 Gravity = -9.80665
743
744 TerrainFriction = 0.50
745 TerrainHitFriction = 0.8
746 TerrainRestitution = 0
747 AvatarFriction = 0
748 AvatarDensity = 60.0
749 AvatarCapsuleRadius = 0.37
750 AvatarCapsuleHeight = 1.5
751
752 MaxObjectMass = 10000.01
753
754 ; Dynamic parameters
755 LinearDamping = 0.0
756 AngularDamping = 0.0
757 DeactivationTime = 0.2
758 LinearSleepingThreshold = 0.8
759 AngularSleepingThreshold = 1.0
760 CcdMotionThreshold = 0.5
761 CcdSweptSphereRadius = 0.2
762
763 ; Whether to mesh sculpties
764 MeshSculptedPrim = true
765
766 ; If 'true', force simple prims (box and sphere) to be meshed
767 ForceSimplePrimMeshing = false
768
769 ; level of detail for physical meshes. 32,16,8 or 4 with 32 being full detail
770 MeshLevelOfDetail = 8
771 ; number^2 non-physical level of detail of the sculpt texture. 32x32 - 1024 verticies
772 SculptLevelOfDetail = 32
773
774 ; Bullet step parameters
775 MaxSubSteps = 10;
776 FixedTimeStep = .01667
777
778 MaxCollisionsPerFrame = 2048
779 MaxUpdatesPerFrame = 2048
724 780
725[RemoteAdmin] 781[RemoteAdmin]
726 enabled = false 782 enabled = false
@@ -1357,6 +1413,18 @@
1357 ; Enable media on a prim facilities 1413 ; Enable media on a prim facilities
1358 Enabled = true; 1414 Enabled = true;
1359 1415
1416[NPC]
1417 ;; Enable Non Player Character (NPC) facilities
1418 Enabled = false
1419
1420;;
1421;; If you are using a simian grid frontend you can enable
1422;; this module to upload tile images for the mapping fn
1423;;
1424[SimianGridMaptiles]
1425 Enabled = False
1426 MaptileURL = "http://www.mygrid.com/Grid/"
1427 RefreshTime = 3600
1360 1428
1361;; 1429;;
1362;; These are defaults that are overwritten below in [Architecture]. 1430;; These are defaults that are overwritten below in [Architecture].
diff --git a/bin/Physics/OpenSim.Region.Physics.BulletSPlugin.dll.config b/bin/Physics/OpenSim.Region.Physics.BulletSPlugin.dll.config
new file mode 100755
index 0000000..026417a
--- /dev/null
+++ b/bin/Physics/OpenSim.Region.Physics.BulletSPlugin.dll.config
@@ -0,0 +1,6 @@
1<configuration>
2 <dllmap os="windows" cpu="x86" dll="BulletSim" target="BulletSim" />
3 <dllmap os="windows" cpu="x86-64,ia64" dll="BulletSim" target="BulletSim-x86_64" />
4 <dllmap os="!windows,osx" cpu="x86" dll="BulletSim" target="./libBulletSim.so" />
5 <dllmap os="!windows,osx" cpu="x86-64,ia64" dll="BulletSim" target="./libBulletSim-x86_64.so" />
6</configuration>
diff --git a/bin/Prebuild.exe b/bin/Prebuild.exe
index d79227c..ead3c6b 100755
--- a/bin/Prebuild.exe
+++ b/bin/Prebuild.exe
Binary files differ
diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example
index ea271b8..910ba02 100644
--- a/bin/Robust.HG.ini.example
+++ b/bin/Robust.HG.ini.example
@@ -203,6 +203,9 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
203 UserAgentService = "OpenSim.Services.HypergridService.dll:UserAgentService" 203 UserAgentService = "OpenSim.Services.HypergridService.dll:UserAgentService"
204 FriendsService = "OpenSim.Services.FriendsService.dll:FriendsService" 204 FriendsService = "OpenSim.Services.FriendsService.dll:FriendsService"
205 205
206 ;; Ask co-operative viewers to use a different currency name
207 ;Currency = ""
208
206 WelcomeMessage = "Welcome, Avatar!" 209 WelcomeMessage = "Welcome, Avatar!"
207 AllowRemoteSetLoginLevel = "false" 210 AllowRemoteSetLoginLevel = "false"
208 211
diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example
index 14f79aa..f7781ab 100644
--- a/bin/Robust.ini.example
+++ b/bin/Robust.ini.example
@@ -188,6 +188,9 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
188 LibraryService = "OpenSim.Services.InventoryService.dll:LibraryService" 188 LibraryService = "OpenSim.Services.InventoryService.dll:LibraryService"
189 FriendsService = "OpenSim.Services.FriendsService.dll:FriendsService" 189 FriendsService = "OpenSim.Services.FriendsService.dll:FriendsService"
190 190
191 ;; Ask co-operative viewers to use a different currency name
192 ;Currency = ""
193
191 WelcomeMessage = "Welcome, Avatar!" 194 WelcomeMessage = "Welcome, Avatar!"
192 AllowRemoteSetLoginLevel = "false" 195 AllowRemoteSetLoginLevel = "false"
193 196
diff --git a/bin/config-include/GridCommon.ini.example b/bin/config-include/GridCommon.ini.example
index 4eb6fcf..c5598c0 100644
--- a/bin/config-include/GridCommon.ini.example
+++ b/bin/config-include/GridCommon.ini.example
@@ -28,19 +28,19 @@
28 AssetLoaderArgs = "assets/AssetSets.xml" 28 AssetLoaderArgs = "assets/AssetSets.xml"
29 29
30 ; 30 ;
31 ; change this to your grid-wide asset server 31 ; Change this to your grid-wide asset server. Do not add a slash to the end of any of these addresses.
32 ; 32 ;
33 AssetServerURI = "http://myassetserver.com:8003" 33 AssetServerURI = "http://myassetserver.com:8003"
34 34
35[InventoryService] 35[InventoryService]
36 ; 36 ;
37 ; change this to your grid-wide inventory server 37 ; Change this to your grid-wide inventory server
38 ; 38 ;
39 InventoryServerURI = "http://myinventoryserver.com:8003" 39 InventoryServerURI = "http://myinventoryserver.com:8003"
40 40
41[GridService] 41[GridService]
42 ; 42 ;
43 ; change this to your grid-wide grid server 43 ; Change this to your grid-wide grid server
44 ; 44 ;
45 GridServerURI = "http://mygridserver.com:8003" 45 GridServerURI = "http://mygridserver.com:8003"
46 ;AllowHypergridMapSearch = true 46 ;AllowHypergridMapSearch = true
@@ -49,51 +49,51 @@
49 ; MapTileDirectory = "./maptiles" 49 ; MapTileDirectory = "./maptiles"
50 50
51 ; === HG ONLY === 51 ; === HG ONLY ===
52 ;; change this to the address of your Gatekeeper service 52 ;; Change this to the address of your Gatekeeper service
53 ;; (usually bundled with the rest of the services in one 53 ;; (usually bundled with the rest of the services in one
54 ;; Robust server in port 8002, but not always) 54 ;; Robust server in port 8002, but not always)
55 Gatekeeper="http://mygridserver.com:8002" 55 Gatekeeper="http://mygridserver.com:8002"
56 56
57[Messaging] 57[Messaging]
58 ; === HG ONLY === 58 ; === HG ONLY ===
59 ;; change this to the address of your Gatekeeper service 59 ;; Change this to the address of your Gatekeeper service
60 ;; (usually bundled with the rest of the services in one 60 ;; (usually bundled with the rest of the services in one
61 ;; Robust server in port 8002, but not always) 61 ;; Robust server in port 8002, but not always)
62 Gatekeeper = "http://mygridserver.com:8002" 62 Gatekeeper = "http://mygridserver.com:8002"
63 63
64[AvatarService] 64[AvatarService]
65 ; 65 ;
66 ; change this to your grid-wide grid server 66 ; Change this to your grid-wide grid server
67 ; 67 ;
68 AvatarServerURI = "http://mygridserver.com:8003" 68 AvatarServerURI = "http://mygridserver.com:8003"
69 69
70[PresenceService] 70[PresenceService]
71 ; 71 ;
72 ; change this to your grid-wide presence server 72 ; Change this to your grid-wide presence server
73 ; 73 ;
74 PresenceServerURI = "http://mygridserver.com:8003" 74 PresenceServerURI = "http://mygridserver.com:8003"
75 75
76[UserAccountService] 76[UserAccountService]
77 ; 77 ;
78 ; change this to your grid-wide user accounts server 78 ; Change this to your grid-wide user accounts server
79 ; 79 ;
80 UserAccountServerURI = "http://mygridserver.com:8003" 80 UserAccountServerURI = "http://mygridserver.com:8003"
81 81
82[GridUserService] 82[GridUserService]
83 ; 83 ;
84 ; change this to your grid-wide user accounts server 84 ; Change this to your grid-wide user accounts server
85 ; 85 ;
86 GridUserServerURI = "http://mygridserver.com:8003" 86 GridUserServerURI = "http://mygridserver.com:8003"
87 87
88[AuthenticationService] 88[AuthenticationService]
89 ; 89 ;
90 ; change this to your grid-wide authentication server 90 ; Change this to your grid-wide authentication server
91 ; 91 ;
92 AuthenticationServerURI = "http://mygridserver.com:8003" 92 AuthenticationServerURI = "http://mygridserver.com:8003"
93 93
94[FriendsService] 94[FriendsService]
95 ; 95 ;
96 ; change this to your grid-wide friends server 96 ; Change this to your grid-wide friends server
97 ; 97 ;
98 FriendsServerURI = "http://mygridserver.com:8003" 98 FriendsServerURI = "http://mygridserver.com:8003"
99 99
@@ -104,10 +104,10 @@
104 ; accessible from other grids 104 ; accessible from other grids
105 ; 105 ;
106 ProfileServerURI = "http://mygridserver.com:8002/user" 106 ProfileServerURI = "http://mygridserver.com:8002/user"
107 Gatekeeper = "http://mygridserver.com:8002" 107 Gatekeeper = "http://mygridserver.com:8002"
108 ;; If you want to protect your assets from being copied by foreign visitors 108 ;; If you want to protect your assets from being copied by foreign visitors
109 ;; uncomment the next line. You may want to do this on sims that have licensed content. 109 ;; uncomment the next line. You may want to do this on sims that have licensed content.
110 ; OutboundPermission = False 110 ; OutboundPermission = False
111 111
112[UserAgentService] 112[UserAgentService]
113 ; 113 ;
@@ -122,6 +122,7 @@
122[Modules] 122[Modules]
123 ;; Choose 0 or 1 cache modules, and the corresponding config file, if it exists. 123 ;; Choose 0 or 1 cache modules, and the corresponding config file, if it exists.
124 ;; Copy the config .example file into your own .ini file and change configs there 124 ;; Copy the config .example file into your own .ini file and change configs there
125 ;; We recommend the use of the FlotsamAssetCache since this is most actively maintained.
125 126
126 AssetCaching = "FlotsamAssetCache" 127 AssetCaching = "FlotsamAssetCache"
127 Include-FlotsamCache = "config-include/FlotsamCache.ini" 128 Include-FlotsamCache = "config-include/FlotsamCache.ini"
diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example
index ee0523f..c057887 100644
--- a/bin/config-include/StandaloneCommon.ini.example
+++ b/bin/config-include/StandaloneCommon.ini.example
@@ -45,14 +45,15 @@
45[Modules] 45[Modules]
46 ;; Choose 0 or 1 cache modules, and the corresponding config file, if it exists. 46 ;; Choose 0 or 1 cache modules, and the corresponding config file, if it exists.
47 ;; Copy the config .example file into your own .ini file and change configs there 47 ;; Copy the config .example file into your own .ini file and change configs there
48 ;; We recommend the use of the FlotsamAssetCache since this is most actively maintained.
48 49
49 ;AssetCaching = "GlynnTuckerAssetCache" 50 AssetCaching = "FlotsamAssetCache"
51 Include-FlotsamCache = "config-include/FlotsamCache.ini"
50 52
51 ;AssetCaching = "FlotsamAssetCache" 53 ;AssetCaching = "GlynnTuckerAssetCache"
52 ;Include-FlotsamCache = "config-include/FlotsamCache.ini"
53 54
54 AssetCaching = "CenomeMemoryAssetCache" 55 ; AssetCaching = "CenomeMemoryAssetCache"
55 Include-CenomeCache = "config-include/CenomeCache.ini" 56 ; Include-CenomeCache = "config-include/CenomeCache.ini"
56 57
57 ;; Authorization is not on by default, as it depends on external php 58 ;; Authorization is not on by default, as it depends on external php
58 ;AuthorizationServices = "LocalAuthorizationServicesConnector" 59 ;AuthorizationServices = "LocalAuthorizationServicesConnector"
@@ -96,23 +97,26 @@
96 SRV_FriendsServerURI = "http://127.0.0.1:9000" 97 SRV_FriendsServerURI = "http://127.0.0.1:9000"
97 SRV_IMServerURI = "http://127.0.0.1:9000" 98 SRV_IMServerURI = "http://127.0.0.1:9000"
98 99
99 ;; For Viewer 2 100 ;; For Viewer 2
100 MapTileURL = "http://127.0.0.1:9000/" 101 MapTileURL = "http://127.0.0.1:9000/"
101 102
102 ;; Regular expressions for controlling which client versions are accepted/denied. 103 ;; Ask co-operative viewers to use a different currency name
103 ;; An empty string means nothing is checked. 104 ;Currency = ""
104 ;; 105
105 ;; Example 1: allow only these 3 types of clients (any version of them) 106 ;; Regular expressions for controlling which client versions are accepted/denied.
106 ;; AllowedClients = "Imprudence|Hippo|Second Life" 107 ;; An empty string means nothing is checked.
107 ;; 108 ;;
108 ;; Example 2: allow all clients except these 109 ;; Example 1: allow only these 3 types of clients (any version of them)
109 ;; DeniedClients = "Twisted|Crawler|Cryolife|FuckLife|StreetLife|GreenLife|AntiLife|KORE-Phaze|Synlyfe|Purple Second Life|SecondLi |Emerald" 110 ;; AllowedClients = "Imprudence|Hippo|Second Life"
110 ;; 111 ;;
111 ;; Note that these are regular expressions, so every character counts. 112 ;; Example 2: allow all clients except these
112 ;; Also note that this is very weak security and should not be trusted as a reliable means 113 ;; DeniedClients = "Twisted|Crawler|Cryolife|FuckLife|StreetLife|GreenLife|AntiLife|KORE-Phaze|Synlyfe|Purple Second Life|SecondLi |Emerald"
113 ;; for keeping bad clients out; modified clients can fake their identifiers. 114 ;;
114 ;; 115 ;; Note that these are regular expressions, so every character counts.
115 ;; 116 ;; Also note that this is very weak security and should not be trusted as a reliable means
117 ;; for keeping bad clients out; modified clients can fake their identifiers.
118 ;;
119 ;;
116 ;AllowedClients = "" 120 ;AllowedClients = ""
117 ;DeniedClients = "" 121 ;DeniedClients = ""
118 122
diff --git a/bin/inventory/AnimationsLibrary/AnimationsLibraryItems.xml b/bin/inventory/AnimationsLibrary/AnimationsLibraryItems.xml
index 2a6ceb4..9cfadf0 100644
--- a/bin/inventory/AnimationsLibrary/AnimationsLibraryItems.xml
+++ b/bin/inventory/AnimationsLibrary/AnimationsLibraryItems.xml
@@ -108,8 +108,6 @@
108 <Key Name="inventoryType" Value="19" /> 108 <Key Name="inventoryType" Value="19" />
109 </Section> 109 </Section>
110 110
111
112
113<!-- 111<!--
114 <Section Name="Example Library Item"> 112 <Section Name="Example Library Item">
115 <Key Name="inventoryID" Value="30000000-0000-2222-4444-000000000001" /> 113 <Key Name="inventoryID" Value="30000000-0000-2222-4444-000000000001" />
@@ -119,10 +117,6 @@
119 <Key Name="name" Value="Example Library Item" /> 117 <Key Name="name" Value="Example Library Item" />
120 <Key Name="assetType" Value="7" /> 118 <Key Name="assetType" Value="7" />
121 <Key Name="inventoryType" Value="7" /> 119 <Key Name="inventoryType" Value="7" />
122 <Key Name="currentPermissions" Value="2147483647" />
123 <Key Name="nextPermissions" Value="2147483647" />
124 <Key Name="everyonePermissions" Value="2147483647" />
125 <Key Name="basePermissions" Value="2147483647" />
126 </Section> 120 </Section>
127--> 121-->
128 122
diff --git a/bin/inventory/BodyPartsLibrary/BodyPartsLibraryItems.xml b/bin/inventory/BodyPartsLibrary/BodyPartsLibraryItems.xml
index aa8d9d9..d9adf1c 100644
--- a/bin/inventory/BodyPartsLibrary/BodyPartsLibraryItems.xml
+++ b/bin/inventory/BodyPartsLibrary/BodyPartsLibraryItems.xml
@@ -9,10 +9,6 @@
9 <Key Name="name" Value="Example Library Item" /> 9 <Key Name="name" Value="Example Library Item" />
10 <Key Name="assetType" Value="7" /> 10 <Key Name="assetType" Value="7" />
11 <Key Name="inventoryType" Value="7" /> 11 <Key Name="inventoryType" Value="7" />
12 <Key Name="currentPermissions" Value="2147483647" />
13 <Key Name="nextPermissions" Value="2147483647" />
14 <Key Name="everyonePermissions" Value="2147483647" />
15 <Key Name="basePermissions" Value="2147483647" />
16 </Section> 12 </Section>
17--> 13-->
18<!-- 14<!--
@@ -24,10 +20,6 @@
24 <Key Name="name" Value="Hair" /> 20 <Key Name="name" Value="Hair" />
25 <Key Name="assetType" Value="13" /> 21 <Key Name="assetType" Value="13" />
26 <Key Name="inventoryType" Value="18" /> 22 <Key Name="inventoryType" Value="18" />
27 <Key Name="currentPermissions" Value="2147483647" />
28 <Key Name="nextPermissions" Value="2147483647" />
29 <Key Name="everyonePermissions" Value="2147483647" />
30 <Key Name="basePermissions" Value="2147483647" />
31 </Section> 23 </Section>
32 24
33 <Section Name="Skin"> 25 <Section Name="Skin">
@@ -38,10 +30,6 @@
38 <Key Name="name" Value="Skin" /> 30 <Key Name="name" Value="Skin" />
39 <Key Name="assetType" Value="13" /> 31 <Key Name="assetType" Value="13" />
40 <Key Name="inventoryType" Value="18" /> 32 <Key Name="inventoryType" Value="18" />
41 <Key Name="currentPermissions" Value="2147483647" />
42 <Key Name="nextPermissions" Value="2147483647" />
43 <Key Name="everyonePermissions" Value="2147483647" />
44 <Key Name="basePermissions" Value="2147483647" />
45 </Section> 33 </Section>
46--> 34-->
47<!-- 35<!--
@@ -53,10 +41,6 @@
53 <Key Name="name" Value="Jim Skin" /> 41 <Key Name="name" Value="Jim Skin" />
54 <Key Name="assetType" Value="13" /> 42 <Key Name="assetType" Value="13" />
55 <Key Name="inventoryType" Value="13" /> 43 <Key Name="inventoryType" Value="13" />
56 <Key Name="currentPermissions" Value="2147483647" />
57 <Key Name="nextPermissions" Value="2147483647" />
58 <Key Name="everyonePermissions" Value="2147483647" />
59 <Key Name="basePermissions" Value="2147483647" />
60 </Section> 44 </Section>
61 45
62 <Section Name="Little Goblin Skin"> 46 <Section Name="Little Goblin Skin">
@@ -67,10 +51,6 @@
67 <Key Name="name" Value="Little Goblin Skin" /> 51 <Key Name="name" Value="Little Goblin Skin" />
68 <Key Name="assetType" Value="13" /> 52 <Key Name="assetType" Value="13" />
69 <Key Name="inventoryType" Value="13" /> 53 <Key Name="inventoryType" Value="13" />
70 <Key Name="currentPermissions" Value="2147483647" />
71 <Key Name="nextPermissions" Value="2147483647" />
72 <Key Name="everyonePermissions" Value="2147483647" />
73 <Key Name="basePermissions" Value="2147483647" />
74 </Section> 54 </Section>
75--> 55-->
76<!-- 56<!--
@@ -82,10 +62,6 @@
82 <Key Name="name" Value="Shape" /> 62 <Key Name="name" Value="Shape" />
83 <Key Name="assetType" Value="13" /> 63 <Key Name="assetType" Value="13" />
84 <Key Name="inventoryType" Value="18" /> 64 <Key Name="inventoryType" Value="18" />
85 <Key Name="currentPermissions" Value="2147483647" />
86 <Key Name="nextPermissions" Value="2147483647" />
87 <Key Name="everyonePermissions" Value="2147483647" />
88 <Key Name="basePermissions" Value="2147483647" />
89 </Section> 65 </Section>
90--> 66-->
91<!-- 67<!--
@@ -97,10 +73,6 @@
97 <Key Name="name" Value="Jim Shape" /> 73 <Key Name="name" Value="Jim Shape" />
98 <Key Name="assetType" Value="13" /> 74 <Key Name="assetType" Value="13" />
99 <Key Name="inventoryType" Value="13" /> 75 <Key Name="inventoryType" Value="13" />
100 <Key Name="currentPermissions" Value="2147483647" />
101 <Key Name="nextPermissions" Value="2147483647" />
102 <Key Name="everyonePermissions" Value="2147483647" />
103 <Key Name="basePermissions" Value="2147483647" />
104 </Section> 76 </Section>
105 77
106 <Section Name="Little Goblin Shape"> 78 <Section Name="Little Goblin Shape">
@@ -111,10 +83,7 @@
111 <Key Name="name" Value="Little Goblin Shape" /> 83 <Key Name="name" Value="Little Goblin Shape" />
112 <Key Name="assetType" Value="13" /> 84 <Key Name="assetType" Value="13" />
113 <Key Name="inventoryType" Value="13" /> 85 <Key Name="inventoryType" Value="13" />
114 <Key Name="currentPermissions" Value="2147483647" />
115 <Key Name="nextPermissions" Value="2147483647" />
116 <Key Name="everyonePermissions" Value="2147483647" />
117 <Key Name="basePermissions" Value="2147483647" />
118 </Section> 86 </Section>
119 --> 87 -->
88
120</Nini> 89</Nini>
diff --git a/bin/inventory/ClothingLibrary/ClothingLibraryItems.xml b/bin/inventory/ClothingLibrary/ClothingLibraryItems.xml
index 9e297f0..a12bb8a 100644
--- a/bin/inventory/ClothingLibrary/ClothingLibraryItems.xml
+++ b/bin/inventory/ClothingLibrary/ClothingLibraryItems.xml
@@ -9,10 +9,6 @@
9 <Key Name="name" Value="Example Library Item" /> 9 <Key Name="name" Value="Example Library Item" />
10 <Key Name="assetType" Value="7" /> 10 <Key Name="assetType" Value="7" />
11 <Key Name="inventoryType" Value="7" /> 11 <Key Name="inventoryType" Value="7" />
12 <Key Name="currentPermissions" Value="2147483647" />
13 <Key Name="nextPermissions" Value="2147483647" />
14 <Key Name="everyonePermissions" Value="2147483647" />
15 <Key Name="basePermissions" Value="2147483647" />
16 </Section> 12 </Section>
17--> 13-->
18<!-- 14<!--
@@ -24,11 +20,8 @@
24 <Key Name="name" Value="Shirt" /> 20 <Key Name="name" Value="Shirt" />
25 <Key Name="assetType" Value="5" /> 21 <Key Name="assetType" Value="5" />
26 <Key Name="inventoryType" Value="18" /> 22 <Key Name="inventoryType" Value="18" />
27 <Key Name="currentPermissions" Value="2147483647" />
28 <Key Name="nextPermissions" Value="2147483647" />
29 <Key Name="everyonePermissions" Value="2147483647" />
30 <Key Name="basePermissions" Value="2147483647" />
31 </Section> 23 </Section>
24
32 <Section Name="Pants"> 25 <Section Name="Pants">
33 <Key Name="inventoryID" Value="d5e46211-b9d1-11dc-95ff-0800200c9a66" /> 26 <Key Name="inventoryID" Value="d5e46211-b9d1-11dc-95ff-0800200c9a66" />
34 <Key Name="assetID" Value="00000000-38f9-1111-024e-222222111120" /> 27 <Key Name="assetID" Value="00000000-38f9-1111-024e-222222111120" />
@@ -37,10 +30,7 @@
37 <Key Name="name" Value="Pants" /> 30 <Key Name="name" Value="Pants" />
38 <Key Name="assetType" Value="5" /> 31 <Key Name="assetType" Value="5" />
39 <Key Name="inventoryType" Value="18" /> 32 <Key Name="inventoryType" Value="18" />
40 <Key Name="currentPermissions" Value="2147483647" />
41 <Key Name="nextPermissions" Value="2147483647" />
42 <Key Name="everyonePermissions" Value="2147483647" />
43 <Key Name="basePermissions" Value="2147483647" />
44 </Section> 33 </Section>
45--> 34-->
35
46</Nini> 36</Nini>
diff --git a/bin/inventory/GesturesLibrary/GesturesLibraryItems.xml b/bin/inventory/GesturesLibrary/GesturesLibraryItems.xml
index 1312129..ca3ce2d 100644
--- a/bin/inventory/GesturesLibrary/GesturesLibraryItems.xml
+++ b/bin/inventory/GesturesLibrary/GesturesLibraryItems.xml
@@ -7,11 +7,8 @@
7 <Key Name="name" Value="can we move along?" /> 7 <Key Name="name" Value="can we move along?" />
8 <Key Name="assetType" Value="21"/> 8 <Key Name="assetType" Value="21"/>
9 <Key Name="inventoryType" Value="20"/> 9 <Key Name="inventoryType" Value="20"/>
10 <Key Name="currentPermissions" Value="2147483647"/>
11 <Key Name="nextPermissions" Value="2147483647"/>
12 <Key Name="everyonePermissions" Value="2147483647" />
13 <Key Name="basePermissions" Value="2147483647"/>
14 </Section> 10 </Section>
11
15 <Section Name="me!"> 12 <Section Name="me!">
16 <Key Name="inventoryID" Value="4c141851-1bef-4c00-9058-8c4d97ab48fe"/> 13 <Key Name="inventoryID" Value="4c141851-1bef-4c00-9058-8c4d97ab48fe"/>
17 <Key Name="assetID" Value="652475bc-ffb7-4a18-b6bb-7731ddeb6a51"/> 14 <Key Name="assetID" Value="652475bc-ffb7-4a18-b6bb-7731ddeb6a51"/>
@@ -20,11 +17,8 @@
20 <Key Name="name" Value="me!" /> 17 <Key Name="name" Value="me!" />
21 <Key Name="assetType" Value="21"/> 18 <Key Name="assetType" Value="21"/>
22 <Key Name="inventoryType" Value="20"/> 19 <Key Name="inventoryType" Value="20"/>
23 <Key Name="currentPermissions" Value="2147483647"/>
24 <Key Name="nextPermissions" Value="2147483647"/>
25 <Key Name="everyonePermissions" Value="2147483647" />
26 <Key Name="basePermissions" Value="2147483647"/>
27 </Section> 20 </Section>
21
28 <Section Name="clap"> 22 <Section Name="clap">
29 <Key Name="inventoryID" Value="a5a30fdb-613f-44fa-8bc2-7806e4da67f6"/> 23 <Key Name="inventoryID" Value="a5a30fdb-613f-44fa-8bc2-7806e4da67f6"/>
30 <Key Name="assetID" Value="712e81fd-a215-498c-ab1a-caf1f5bf950d"/> 24 <Key Name="assetID" Value="712e81fd-a215-498c-ab1a-caf1f5bf950d"/>
@@ -33,11 +27,8 @@
33 <Key Name="name" Value="clap" /> 27 <Key Name="name" Value="clap" />
34 <Key Name="assetType" Value="21"/> 28 <Key Name="assetType" Value="21"/>
35 <Key Name="inventoryType" Value="20"/> 29 <Key Name="inventoryType" Value="20"/>
36 <Key Name="currentPermissions" Value="2147483647"/>
37 <Key Name="nextPermissions" Value="2147483647"/>
38 <Key Name="everyonePermissions" Value="2147483647" />
39 <Key Name="basePermissions" Value="2147483647"/>
40 </Section> 30 </Section>
31
41 <Section Name="no"> 32 <Section Name="no">
42 <Key Name="inventoryID" Value="514b3ca6-1571-4f58-a24e-f58eb5cb8460"/> 33 <Key Name="inventoryID" Value="514b3ca6-1571-4f58-a24e-f58eb5cb8460"/>
43 <Key Name="assetID" Value="6c123970-0f5a-448e-920a-07bae9aadf4c"/> 34 <Key Name="assetID" Value="6c123970-0f5a-448e-920a-07bae9aadf4c"/>
@@ -46,11 +37,8 @@
46 <Key Name="name" Value="no" /> 37 <Key Name="name" Value="no" />
47 <Key Name="assetType" Value="21"/> 38 <Key Name="assetType" Value="21"/>
48 <Key Name="inventoryType" Value="20"/> 39 <Key Name="inventoryType" Value="20"/>
49 <Key Name="currentPermissions" Value="2147483647"/>
50 <Key Name="nextPermissions" Value="2147483647"/>
51 <Key Name="everyonePermissions" Value="2147483647" />
52 <Key Name="basePermissions" Value="2147483647"/>
53 </Section> 40 </Section>
41
54 <Section Name="suprised"> 42 <Section Name="suprised">
55 <Key Name="inventoryID" Value="120fb1f3-112b-4bc4-a7d3-a784ecc360af"/> 43 <Key Name="inventoryID" Value="120fb1f3-112b-4bc4-a7d3-a784ecc360af"/>
56 <Key Name="assetID" Value="dbaf104b-cba8-4df7-b5d3-0cb57d0d63b2"/> 44 <Key Name="assetID" Value="dbaf104b-cba8-4df7-b5d3-0cb57d0d63b2"/>
@@ -59,11 +47,8 @@
59 <Key Name="name" Value="suprised" /> 47 <Key Name="name" Value="suprised" />
60 <Key Name="assetType" Value="21"/> 48 <Key Name="assetType" Value="21"/>
61 <Key Name="inventoryType" Value="20"/> 49 <Key Name="inventoryType" Value="20"/>
62 <Key Name="currentPermissions" Value="2147483647"/>
63 <Key Name="nextPermissions" Value="2147483647"/>
64 <Key Name="everyonePermissions" Value="2147483647" />
65 <Key Name="basePermissions" Value="2147483647"/>
66 </Section> 50 </Section>
51
67 <Section Name="dance2"> 52 <Section Name="dance2">
68 <Key Name="inventoryID" Value="1ca0e368-5a11-4da1-8503-925a55e7c45f"/> 53 <Key Name="inventoryID" Value="1ca0e368-5a11-4da1-8503-925a55e7c45f"/>
69 <Key Name="assetID" Value="3bd1792a-6756-4ee0-a54e-3ae6493c2036"/> 54 <Key Name="assetID" Value="3bd1792a-6756-4ee0-a54e-3ae6493c2036"/>
@@ -72,11 +57,8 @@
72 <Key Name="name" Value="dance2" /> 57 <Key Name="name" Value="dance2" />
73 <Key Name="assetType" Value="21"/> 58 <Key Name="assetType" Value="21"/>
74 <Key Name="inventoryType" Value="20"/> 59 <Key Name="inventoryType" Value="20"/>
75 <Key Name="currentPermissions" Value="2147483647"/>
76 <Key Name="nextPermissions" Value="2147483647"/>
77 <Key Name="everyonePermissions" Value="2147483647" />
78 <Key Name="basePermissions" Value="2147483647"/>
79 </Section> 60 </Section>
61
80 <Section Name="definitely YES"> 62 <Section Name="definitely YES">
81 <Key Name="inventoryID" Value="022fa770-abb1-4266-963a-4ece4747b748"/> 63 <Key Name="inventoryID" Value="022fa770-abb1-4266-963a-4ece4747b748"/>
82 <Key Name="assetID" Value="392c292f-3d27-45ff-9437-c79c06699237"/> 64 <Key Name="assetID" Value="392c292f-3d27-45ff-9437-c79c06699237"/>
@@ -85,11 +67,8 @@
85 <Key Name="name" Value="definitely YES" /> 67 <Key Name="name" Value="definitely YES" />
86 <Key Name="assetType" Value="21"/> 68 <Key Name="assetType" Value="21"/>
87 <Key Name="inventoryType" Value="20"/> 69 <Key Name="inventoryType" Value="20"/>
88 <Key Name="currentPermissions" Value="2147483647"/>
89 <Key Name="nextPermissions" Value="2147483647"/>
90 <Key Name="everyonePermissions" Value="2147483647" />
91 <Key Name="basePermissions" Value="2147483647"/>
92 </Section> 70 </Section>
71
93 <Section Name="Wave"> 72 <Section Name="Wave">
94 <Key Name="inventoryID" Value="6406a7c6-a690-44be-a444-ba723e50c17d"/> 73 <Key Name="inventoryID" Value="6406a7c6-a690-44be-a444-ba723e50c17d"/>
95 <Key Name="assetID" Value="cce0e317-2c49-411e-8716-f9ce3007c715"/> 74 <Key Name="assetID" Value="cce0e317-2c49-411e-8716-f9ce3007c715"/>
@@ -98,11 +77,8 @@
98 <Key Name="name" Value="Wave" /> 77 <Key Name="name" Value="Wave" />
99 <Key Name="assetType" Value="21"/> 78 <Key Name="assetType" Value="21"/>
100 <Key Name="inventoryType" Value="20"/> 79 <Key Name="inventoryType" Value="20"/>
101 <Key Name="currentPermissions" Value="2147483647"/>
102 <Key Name="nextPermissions" Value="2147483647"/>
103 <Key Name="everyonePermissions" Value="2147483647" />
104 <Key Name="basePermissions" Value="2147483647"/>
105 </Section> 80 </Section>
81
106 <Section Name="take it outside"> 82 <Section Name="take it outside">
107 <Key Name="inventoryID" Value="1488b988-c300-4c2e-b48a-3b8eacb93659"/> 83 <Key Name="inventoryID" Value="1488b988-c300-4c2e-b48a-3b8eacb93659"/>
108 <Key Name="assetID" Value="d082bd28-f655-43b7-a0eb-cb80db03753e"/> 84 <Key Name="assetID" Value="d082bd28-f655-43b7-a0eb-cb80db03753e"/>
@@ -111,11 +87,8 @@
111 <Key Name="name" Value="take it outside" /> 87 <Key Name="name" Value="take it outside" />
112 <Key Name="assetType" Value="21"/> 88 <Key Name="assetType" Value="21"/>
113 <Key Name="inventoryType" Value="20"/> 89 <Key Name="inventoryType" Value="20"/>
114 <Key Name="currentPermissions" Value="2147483647"/>
115 <Key Name="nextPermissions" Value="2147483647"/>
116 <Key Name="everyonePermissions" Value="2147483647" />
117 <Key Name="basePermissions" Value="2147483647"/>
118 </Section> 90 </Section>
91
119 <Section Name="whoohoo!"> 92 <Section Name="whoohoo!">
120 <Key Name="inventoryID" Value="18c1a2fc-17f6-4af4-a519-827b272feaac"/> 93 <Key Name="inventoryID" Value="18c1a2fc-17f6-4af4-a519-827b272feaac"/>
121 <Key Name="assetID" Value="7f7384c0-848c-4bf0-8e83-50879981e1a4"/> 94 <Key Name="assetID" Value="7f7384c0-848c-4bf0-8e83-50879981e1a4"/>
@@ -124,11 +97,8 @@
124 <Key Name="name" Value="whoohoo!" /> 97 <Key Name="name" Value="whoohoo!" />
125 <Key Name="assetType" Value="21"/> 98 <Key Name="assetType" Value="21"/>
126 <Key Name="inventoryType" Value="20"/> 99 <Key Name="inventoryType" Value="20"/>
127 <Key Name="currentPermissions" Value="2147483647"/>
128 <Key Name="nextPermissions" Value="2147483647"/>
129 <Key Name="everyonePermissions" Value="2147483647" />
130 <Key Name="basePermissions" Value="2147483647"/>
131 </Section> 100 </Section>
101
132 <Section Name="raise hand"> 102 <Section Name="raise hand">
133 <Key Name="inventoryID" Value="5c0afacd-bbd0-4f66-a516-4ac4e380853c"/> 103 <Key Name="inventoryID" Value="5c0afacd-bbd0-4f66-a516-4ac4e380853c"/>
134 <Key Name="assetID" Value="2d0819cf-452b-4db8-b7ac-cda443bc89e7"/> 104 <Key Name="assetID" Value="2d0819cf-452b-4db8-b7ac-cda443bc89e7"/>
@@ -137,11 +107,8 @@
137 <Key Name="name" Value="raise hand" /> 107 <Key Name="name" Value="raise hand" />
138 <Key Name="assetType" Value="21"/> 108 <Key Name="assetType" Value="21"/>
139 <Key Name="inventoryType" Value="20"/> 109 <Key Name="inventoryType" Value="20"/>
140 <Key Name="currentPermissions" Value="2147483647"/>
141 <Key Name="nextPermissions" Value="2147483647"/>
142 <Key Name="everyonePermissions" Value="2147483647" />
143 <Key Name="basePermissions" Value="2147483647"/>
144 </Section> 110 </Section>
111
145 <Section Name="LOL"> 112 <Section Name="LOL">
146 <Key Name="inventoryID" Value="407f6a99-1a12-43c6-bec1-8fad974c8f42"/> 113 <Key Name="inventoryID" Value="407f6a99-1a12-43c6-bec1-8fad974c8f42"/>
147 <Key Name="assetID" Value="d545ac78-09cc-4811-8700-8df1a37d7f56"/> 114 <Key Name="assetID" Value="d545ac78-09cc-4811-8700-8df1a37d7f56"/>
@@ -150,11 +117,8 @@
150 <Key Name="name" Value="LOL" /> 117 <Key Name="name" Value="LOL" />
151 <Key Name="assetType" Value="21"/> 118 <Key Name="assetType" Value="21"/>
152 <Key Name="inventoryType" Value="20"/> 119 <Key Name="inventoryType" Value="20"/>
153 <Key Name="currentPermissions" Value="2147483647"/>
154 <Key Name="nextPermissions" Value="2147483647"/>
155 <Key Name="everyonePermissions" Value="2147483647" />
156 <Key Name="basePermissions" Value="2147483647"/>
157 </Section> 120 </Section>
121
158 <Section Name="dance1"> 122 <Section Name="dance1">
159 <Key Name="inventoryID" Value="59cce8ab-5c0c-49be-aa3b-036f05fbd7f4"/> 123 <Key Name="inventoryID" Value="59cce8ab-5c0c-49be-aa3b-036f05fbd7f4"/>
160 <Key Name="assetID" Value="9cc5bb24-bacf-44f9-a1d0-d409e6ccfa6c"/> 124 <Key Name="assetID" Value="9cc5bb24-bacf-44f9-a1d0-d409e6ccfa6c"/>
@@ -163,11 +127,8 @@
163 <Key Name="name" Value="dance1" /> 127 <Key Name="name" Value="dance1" />
164 <Key Name="assetType" Value="21"/> 128 <Key Name="assetType" Value="21"/>
165 <Key Name="inventoryType" Value="20"/> 129 <Key Name="inventoryType" Value="20"/>
166 <Key Name="currentPermissions" Value="2147483647"/>
167 <Key Name="nextPermissions" Value="2147483647"/>
168 <Key Name="everyonePermissions" Value="2147483647" />
169 <Key Name="basePermissions" Value="2147483647"/>
170 </Section> 130 </Section>
131
171 <Section Name="wink!"> 132 <Section Name="wink!">
172 <Key Name="inventoryID" Value="ba33e8ab-b816-4ead-9302-c8475deb1845"/> 133 <Key Name="inventoryID" Value="ba33e8ab-b816-4ead-9302-c8475deb1845"/>
173 <Key Name="assetID" Value="67d47cd0-9634-4c99-97db-ddce9bda467c"/> 134 <Key Name="assetID" Value="67d47cd0-9634-4c99-97db-ddce9bda467c"/>
@@ -176,11 +137,8 @@
176 <Key Name="name" Value="wink!" /> 137 <Key Name="name" Value="wink!" />
177 <Key Name="assetType" Value="21"/> 138 <Key Name="assetType" Value="21"/>
178 <Key Name="inventoryType" Value="20"/> 139 <Key Name="inventoryType" Value="20"/>
179 <Key Name="currentPermissions" Value="2147483647"/>
180 <Key Name="nextPermissions" Value="2147483647"/>
181 <Key Name="everyonePermissions" Value="2147483647" />
182 <Key Name="basePermissions" Value="2147483647"/>
183 </Section> 140 </Section>
141
184 <Section Name="not sure"> 142 <Section Name="not sure">
185 <Key Name="inventoryID" Value="02da80eb-cad0-4cd1-9ff7-d3d3dd150fbc"/> 143 <Key Name="inventoryID" Value="02da80eb-cad0-4cd1-9ff7-d3d3dd150fbc"/>
186 <Key Name="assetID" Value="9bc46cd2-95cb-456d-9070-a4439e42af9e"/> 144 <Key Name="assetID" Value="9bc46cd2-95cb-456d-9070-a4439e42af9e"/>
@@ -189,11 +147,8 @@
189 <Key Name="name" Value="not sure" /> 147 <Key Name="name" Value="not sure" />
190 <Key Name="assetType" Value="21"/> 148 <Key Name="assetType" Value="21"/>
191 <Key Name="inventoryType" Value="20"/> 149 <Key Name="inventoryType" Value="20"/>
192 <Key Name="currentPermissions" Value="2147483647"/>
193 <Key Name="nextPermissions" Value="2147483647"/>
194 <Key Name="everyonePermissions" Value="2147483647" />
195 <Key Name="basePermissions" Value="2147483647"/>
196 </Section> 150 </Section>
151
197 <Section Name="dance3"> 152 <Section Name="dance3">
198 <Key Name="inventoryID" Value="05e53736-dacb-4935-a1e9-d9897b35b962"/> 153 <Key Name="inventoryID" Value="05e53736-dacb-4935-a1e9-d9897b35b962"/>
199 <Key Name="assetID" Value="fd9ad83a-4921-4b6e-8b8e-558556d9f503"/> 154 <Key Name="assetID" Value="fd9ad83a-4921-4b6e-8b8e-558556d9f503"/>
@@ -202,9 +157,6 @@
202 <Key Name="name" Value="dance3" /> 157 <Key Name="name" Value="dance3" />
203 <Key Name="assetType" Value="21"/> 158 <Key Name="assetType" Value="21"/>
204 <Key Name="inventoryType" Value="20"/> 159 <Key Name="inventoryType" Value="20"/>
205 <Key Name="currentPermissions" Value="2147483647"/>
206 <Key Name="nextPermissions" Value="2147483647"/>
207 <Key Name="everyonePermissions" Value="2147483647" />
208 <Key Name="basePermissions" Value="2147483647"/>
209 </Section> 160 </Section>
161
210</Nini> 162</Nini>
diff --git a/bin/inventory/LandmarksLibrary/LandmarksLibraryItems.xml b/bin/inventory/LandmarksLibrary/LandmarksLibraryItems.xml
index 4047a58..44194cd 100644
--- a/bin/inventory/LandmarksLibrary/LandmarksLibraryItems.xml
+++ b/bin/inventory/LandmarksLibrary/LandmarksLibraryItems.xml
@@ -9,10 +9,6 @@
9 <Key Name="name" Value="Example Library Item" /> 9 <Key Name="name" Value="Example Library Item" />
10 <Key Name="assetType" Value="7" /> 10 <Key Name="assetType" Value="7" />
11 <Key Name="inventoryType" Value="7" /> 11 <Key Name="inventoryType" Value="7" />
12 <Key Name="currentPermissions" Value="2147483647" />
13 <Key Name="nextPermissions" Value="2147483647" />
14 <Key Name="everyonePermissions" Value="2147483647" />
15 <Key Name="basePermissions" Value="2147483647" />
16 </Section> 12 </Section>
17--> 13-->
18 14
diff --git a/bin/inventory/NotecardsLibrary/NotecardsLibraryItems.xml b/bin/inventory/NotecardsLibrary/NotecardsLibraryItems.xml
index 713c365..e232bcc 100644
--- a/bin/inventory/NotecardsLibrary/NotecardsLibraryItems.xml
+++ b/bin/inventory/NotecardsLibrary/NotecardsLibraryItems.xml
@@ -9,10 +9,6 @@
9 <Key Name="name" Value="Example Library Item" /> 9 <Key Name="name" Value="Example Library Item" />
10 <Key Name="assetType" Value="7" /> 10 <Key Name="assetType" Value="7" />
11 <Key Name="inventoryType" Value="7" /> 11 <Key Name="inventoryType" Value="7" />
12 <Key Name="currentPermissions" Value="2147483647" />
13 <Key Name="nextPermissions" Value="2147483647" />
14 <Key Name="everyonePermissions" Value="2147483647" />
15 <Key Name="basePermissions" Value="2147483647" />
16 </Section> 12 </Section>
17--> 13-->
18 14
@@ -24,11 +20,8 @@
24 <Key Name="name" Value="Welcome" /> 20 <Key Name="name" Value="Welcome" />
25 <Key Name="assetType" Value="7" /> 21 <Key Name="assetType" Value="7" />
26 <Key Name="inventoryType" Value="7" /> 22 <Key Name="inventoryType" Value="7" />
27 <Key Name="currentPermissions" Value="2147483647" />
28 <Key Name="nextPermissions" Value="2147483647" />
29 <Key Name="everyonePermissions" Value="2147483647" />
30 <Key Name="basePermissions" Value="2147483647" />
31 </Section> 23 </Section>
24
32 <Section Name="Example notecard"> 25 <Section Name="Example notecard">
33 <Key Name="inventoryID" Value="a170ffc0-b9c7-11dc-95ff-0800200c9a66" /> 26 <Key Name="inventoryID" Value="a170ffc0-b9c7-11dc-95ff-0800200c9a66" />
34 <Key Name="assetID" Value="8d1ada50-b9c7-11dc-95ff-0800200c9a66" /> 27 <Key Name="assetID" Value="8d1ada50-b9c7-11dc-95ff-0800200c9a66" />
@@ -37,9 +30,6 @@
37 <Key Name="name" Value="Example notecard" /> 30 <Key Name="name" Value="Example notecard" />
38 <Key Name="assetType" Value="7" /> 31 <Key Name="assetType" Value="7" />
39 <Key Name="inventoryType" Value="7" /> 32 <Key Name="inventoryType" Value="7" />
40 <Key Name="currentPermissions" Value="2147483647" />
41 <Key Name="nextPermissions" Value="2147483647" />
42 <Key Name="everyonePermissions" Value="2147483647" />
43 <Key Name="basePermissions" Value="2147483647" />
44 </Section> 33 </Section>
34
45</Nini> 35</Nini>
diff --git a/bin/inventory/ObjectsLibrary/ObjectsLibraryItems.xml b/bin/inventory/ObjectsLibrary/ObjectsLibraryItems.xml
index 4047a58..44194cd 100644
--- a/bin/inventory/ObjectsLibrary/ObjectsLibraryItems.xml
+++ b/bin/inventory/ObjectsLibrary/ObjectsLibraryItems.xml
@@ -9,10 +9,6 @@
9 <Key Name="name" Value="Example Library Item" /> 9 <Key Name="name" Value="Example Library Item" />
10 <Key Name="assetType" Value="7" /> 10 <Key Name="assetType" Value="7" />
11 <Key Name="inventoryType" Value="7" /> 11 <Key Name="inventoryType" Value="7" />
12 <Key Name="currentPermissions" Value="2147483647" />
13 <Key Name="nextPermissions" Value="2147483647" />
14 <Key Name="everyonePermissions" Value="2147483647" />
15 <Key Name="basePermissions" Value="2147483647" />
16 </Section> 12 </Section>
17--> 13-->
18 14
diff --git a/bin/inventory/OpenSimLibrary/OpenSimLibrary.xml b/bin/inventory/OpenSimLibrary/OpenSimLibrary.xml
index 7eb8de3..bef59d8 100644
--- a/bin/inventory/OpenSimLibrary/OpenSimLibrary.xml
+++ b/bin/inventory/OpenSimLibrary/OpenSimLibrary.xml
@@ -10,10 +10,6 @@
10 <Key Name="name" Value="Example Library Item" /> 10 <Key Name="name" Value="Example Library Item" />
11 <Key Name="assetType" Value="7" /> 11 <Key Name="assetType" Value="7" />
12 <Key Name="inventoryType" Value="7" /> 12 <Key Name="inventoryType" Value="7" />
13 <Key Name="currentPermissions" Value="2147483647" />
14 <Key Name="nextPermissions" Value="2147483647" />
15 <Key Name="everyonePermissions" Value="2147483647" />
16 <Key Name="basePermissions" Value="2147483647" />
17 </Section> 13 </Section>
18--> 14-->
19 15
diff --git a/bin/inventory/PhotosLibrary/PhotosLibraryItems.xml b/bin/inventory/PhotosLibrary/PhotosLibraryItems.xml
index 4047a58..44194cd 100644
--- a/bin/inventory/PhotosLibrary/PhotosLibraryItems.xml
+++ b/bin/inventory/PhotosLibrary/PhotosLibraryItems.xml
@@ -9,10 +9,6 @@
9 <Key Name="name" Value="Example Library Item" /> 9 <Key Name="name" Value="Example Library Item" />
10 <Key Name="assetType" Value="7" /> 10 <Key Name="assetType" Value="7" />
11 <Key Name="inventoryType" Value="7" /> 11 <Key Name="inventoryType" Value="7" />
12 <Key Name="currentPermissions" Value="2147483647" />
13 <Key Name="nextPermissions" Value="2147483647" />
14 <Key Name="everyonePermissions" Value="2147483647" />
15 <Key Name="basePermissions" Value="2147483647" />
16 </Section> 12 </Section>
17--> 13-->
18 14
diff --git a/bin/inventory/ScriptsLibrary/ScriptsLibraryItems.xml b/bin/inventory/ScriptsLibrary/ScriptsLibraryItems.xml
index 9641f7d..df9d867 100644
--- a/bin/inventory/ScriptsLibrary/ScriptsLibraryItems.xml
+++ b/bin/inventory/ScriptsLibrary/ScriptsLibraryItems.xml
@@ -25,11 +25,8 @@
25 <Key Name="name" Value="llAbs" /> 25 <Key Name="name" Value="llAbs" />
26 <Key Name="assetType" Value="10" /> 26 <Key Name="assetType" Value="10" />
27 <Key Name="inventoryType" Value="10" /> 27 <Key Name="inventoryType" Value="10" />
28 <Key Name="currentPermissions" Value="257487132" />
29 <Key Name="nextPermissions" Value="257487132" />
30 <Key Name="everyonePermissions" Value="257487132" />
31 <Key Name="basePermissions" Value="257487132" />
32 </Section> 28 </Section>
29
33 <Section Name="llAcos"> 30 <Section Name="llAcos">
34 <Key Name="inventoryID" Value="6519bf38-b19f-11dc-8314-0800200c9a66" /> 31 <Key Name="inventoryID" Value="6519bf38-b19f-11dc-8314-0800200c9a66" />
35 <Key Name="assetID" Value="6519bf39-b19f-11dc-8314-0800200c9a66" /> 32 <Key Name="assetID" Value="6519bf39-b19f-11dc-8314-0800200c9a66" />
@@ -38,11 +35,8 @@
38 <Key Name="name" Value="llAcos" /> 35 <Key Name="name" Value="llAcos" />
39 <Key Name="assetType" Value="10" /> 36 <Key Name="assetType" Value="10" />
40 <Key Name="inventoryType" Value="10" /> 37 <Key Name="inventoryType" Value="10" />
41 <Key Name="currentPermissions" Value="257487132" />
42 <Key Name="nextPermissions" Value="257487132" />
43 <Key Name="everyonePermissions" Value="257487132" />
44 <Key Name="basePermissions" Value="257487132" />
45 </Section> 38 </Section>
39
46 <Section Name="llAddToLandBanList"> 40 <Section Name="llAddToLandBanList">
47 <Key Name="inventoryID" Value="7ceba3f0-b1a0-11dc-8314-0800200c9a66" /> 41 <Key Name="inventoryID" Value="7ceba3f0-b1a0-11dc-8314-0800200c9a66" />
48 <Key Name="assetID" Value="7ceba3f1-b1a0-11dc-8314-0800200c9a66" /> 42 <Key Name="assetID" Value="7ceba3f1-b1a0-11dc-8314-0800200c9a66" />
@@ -51,11 +45,8 @@
51 <Key Name="name" Value="llAddToLandBanList" /> 45 <Key Name="name" Value="llAddToLandBanList" />
52 <Key Name="assetType" Value="10" /> 46 <Key Name="assetType" Value="10" />
53 <Key Name="inventoryType" Value="10" /> 47 <Key Name="inventoryType" Value="10" />
54 <Key Name="currentPermissions" Value="257487132" />
55 <Key Name="nextPermissions" Value="257487132" />
56 <Key Name="everyonePermissions" Value="257487132" />
57 <Key Name="basePermissions" Value="257487132" />
58 </Section> 48 </Section>
49
59 <Section Name="llAddToLandPassList"> 50 <Section Name="llAddToLandPassList">
60 <Key Name="inventoryID" Value="609047e6-b390-11dc-8314-0800200c9a66" /> 51 <Key Name="inventoryID" Value="609047e6-b390-11dc-8314-0800200c9a66" />
61 <Key Name="assetID" Value="609047e7-b390-11dc-8314-0800200c9a66" /> 52 <Key Name="assetID" Value="609047e7-b390-11dc-8314-0800200c9a66" />
@@ -64,11 +55,8 @@
64 <Key Name="name" Value="llAddToLandPassList" /> 55 <Key Name="name" Value="llAddToLandPassList" />
65 <Key Name="assetType" Value="10" /> 56 <Key Name="assetType" Value="10" />
66 <Key Name="inventoryType" Value="10" /> 57 <Key Name="inventoryType" Value="10" />
67 <Key Name="currentPermissions" Value="257487132" />
68 <Key Name="nextPermissions" Value="257487132" />
69 <Key Name="everyonePermissions" Value="257487132" />
70 <Key Name="basePermissions" Value="257487132" />
71 </Section> 58 </Section>
59
72 <Section Name="llAdjustSoundVolume"> 60 <Section Name="llAdjustSoundVolume">
73 <Key Name="inventoryID" Value="56df4bcc-b393-11dc-8314-0800200c9a66" /> 61 <Key Name="inventoryID" Value="56df4bcc-b393-11dc-8314-0800200c9a66" />
74 <Key Name="assetID" Value="56df4bcd-b393-11dc-8314-0800200c9a66" /> 62 <Key Name="assetID" Value="56df4bcd-b393-11dc-8314-0800200c9a66" />
@@ -77,11 +65,8 @@
77 <Key Name="name" Value="llAdjustSoundVolume" /> 65 <Key Name="name" Value="llAdjustSoundVolume" />
78 <Key Name="assetType" Value="10" /> 66 <Key Name="assetType" Value="10" />
79 <Key Name="inventoryType" Value="10" /> 67 <Key Name="inventoryType" Value="10" />
80 <Key Name="currentPermissions" Value="257487132" />
81 <Key Name="nextPermissions" Value="257487132" />
82 <Key Name="everyonePermissions" Value="257487132" />
83 <Key Name="basePermissions" Value="257487132" />
84 </Section> 68 </Section>
69
85 <Section Name="llAllowInventoryDrop"> 70 <Section Name="llAllowInventoryDrop">
86 <Key Name="inventoryID" Value="54d6962c-b394-11dc-8314-0800200c9a66" /> 71 <Key Name="inventoryID" Value="54d6962c-b394-11dc-8314-0800200c9a66" />
87 <Key Name="assetID" Value="54d6962d-b394-11dc-8314-0800200c9a66" /> 72 <Key Name="assetID" Value="54d6962d-b394-11dc-8314-0800200c9a66" />
@@ -90,11 +75,8 @@
90 <Key Name="name" Value="llAllowInventoryDrop" /> 75 <Key Name="name" Value="llAllowInventoryDrop" />
91 <Key Name="assetType" Value="10" /> 76 <Key Name="assetType" Value="10" />
92 <Key Name="inventoryType" Value="10" /> 77 <Key Name="inventoryType" Value="10" />
93 <Key Name="currentPermissions" Value="257487132" />
94 <Key Name="nextPermissions" Value="257487132" />
95 <Key Name="everyonePermissions" Value="257487132" />
96 <Key Name="basePermissions" Value="257487132" />
97 </Section> 78 </Section>
79
98 <Section Name="llAngleBetween"> 80 <Section Name="llAngleBetween">
99 <Key Name="inventoryID" Value="6b341608-b34e-11dc-8314-0800200c9a66" /> 81 <Key Name="inventoryID" Value="6b341608-b34e-11dc-8314-0800200c9a66" />
100 <Key Name="assetID" Value="6b341609-b34e-11dc-8314-0800200c9a66" /> 82 <Key Name="assetID" Value="6b341609-b34e-11dc-8314-0800200c9a66" />
@@ -103,11 +85,8 @@
103 <Key Name="name" Value="llAngleBetween" /> 85 <Key Name="name" Value="llAngleBetween" />
104 <Key Name="assetType" Value="10" /> 86 <Key Name="assetType" Value="10" />
105 <Key Name="inventoryType" Value="10" /> 87 <Key Name="inventoryType" Value="10" />
106 <Key Name="currentPermissions" Value="257487132" />
107 <Key Name="nextPermissions" Value="257487132" />
108 <Key Name="everyonePermissions" Value="257487132" />
109 <Key Name="basePermissions" Value="257487132" />
110 </Section> 88 </Section>
89
111 <Section Name="llAsin"> 90 <Section Name="llAsin">
112 <Key Name="inventoryID" Value="7e7422ec-b425-11dc-8314-0800200c9a66" /> 91 <Key Name="inventoryID" Value="7e7422ec-b425-11dc-8314-0800200c9a66" />
113 <Key Name="assetID" Value="7e7422ed-b425-11dc-8314-0800200c9a66" /> 92 <Key Name="assetID" Value="7e7422ed-b425-11dc-8314-0800200c9a66" />
@@ -116,11 +95,8 @@
116 <Key Name="name" Value="llAsin" /> 95 <Key Name="name" Value="llAsin" />
117 <Key Name="assetType" Value="10" /> 96 <Key Name="assetType" Value="10" />
118 <Key Name="inventoryType" Value="10" /> 97 <Key Name="inventoryType" Value="10" />
119 <Key Name="currentPermissions" Value="257487132" />
120 <Key Name="nextPermissions" Value="257487132" />
121 <Key Name="everyonePermissions" Value="257487132" />
122 <Key Name="basePermissions" Value="257487132" />
123 </Section> 98 </Section>
99
124 <Section Name="llAtan2"> 100 <Section Name="llAtan2">
125 <Key Name="inventoryID" Value="7e7422ee-b425-11dc-8314-0800200c9a66" /> 101 <Key Name="inventoryID" Value="7e7422ee-b425-11dc-8314-0800200c9a66" />
126 <Key Name="assetID" Value="7e7422ef-b425-11dc-8314-0800200c9a66" /> 102 <Key Name="assetID" Value="7e7422ef-b425-11dc-8314-0800200c9a66" />
@@ -129,11 +105,8 @@
129 <Key Name="name" Value="llAtan2" /> 105 <Key Name="name" Value="llAtan2" />
130 <Key Name="assetType" Value="10" /> 106 <Key Name="assetType" Value="10" />
131 <Key Name="inventoryType" Value="10" /> 107 <Key Name="inventoryType" Value="10" />
132 <Key Name="currentPermissions" Value="257487132" />
133 <Key Name="nextPermissions" Value="257487132" />
134 <Key Name="everyonePermissions" Value="257487132" />
135 <Key Name="basePermissions" Value="257487132" />
136 </Section> 108 </Section>
109
137 <Section Name="llApplyImpulse"> 110 <Section Name="llApplyImpulse">
138 <Key Name="inventoryID" Value="714ec678-b419-11dc-8314-0800200c9a66" /> 111 <Key Name="inventoryID" Value="714ec678-b419-11dc-8314-0800200c9a66" />
139 <Key Name="assetID" Value="714ec679-b419-11dc-8314-0800200c9a66" /> 112 <Key Name="assetID" Value="714ec679-b419-11dc-8314-0800200c9a66" />
@@ -142,11 +115,8 @@
142 <Key Name="name" Value="llApplyImpulse" /> 115 <Key Name="name" Value="llApplyImpulse" />
143 <Key Name="assetType" Value="10" /> 116 <Key Name="assetType" Value="10" />
144 <Key Name="inventoryType" Value="10" /> 117 <Key Name="inventoryType" Value="10" />
145 <Key Name="currentPermissions" Value="257487132" />
146 <Key Name="nextPermissions" Value="257487132" />
147 <Key Name="everyonePermissions" Value="257487132" />
148 <Key Name="basePermissions" Value="257487132" />
149 </Section> 118 </Section>
119
150 <Section Name="llAvatarOnSitTarget"> 120 <Section Name="llAvatarOnSitTarget">
151 <Key Name="inventoryID" Value="579fc820-b426-11dc-8314-0800200c9a66" /> 121 <Key Name="inventoryID" Value="579fc820-b426-11dc-8314-0800200c9a66" />
152 <Key Name="assetID" Value="579fc821-b426-11dc-8314-0800200c9a66" /> 122 <Key Name="assetID" Value="579fc821-b426-11dc-8314-0800200c9a66" />
@@ -155,11 +125,8 @@
155 <Key Name="name" Value="llAvatarOnSitTarget" /> 125 <Key Name="name" Value="llAvatarOnSitTarget" />
156 <Key Name="assetType" Value="10" /> 126 <Key Name="assetType" Value="10" />
157 <Key Name="inventoryType" Value="10" /> 127 <Key Name="inventoryType" Value="10" />
158 <Key Name="currentPermissions" Value="257487132" />
159 <Key Name="nextPermissions" Value="257487132" />
160 <Key Name="everyonePermissions" Value="257487132" />
161 <Key Name="basePermissions" Value="257487132" />
162 </Section> 128 </Section>
129
163<!-- B == <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba004"/> --> 130<!-- B == <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba004"/> -->
164 <Section Name="llBase64ToString"> 131 <Section Name="llBase64ToString">
165 <Key Name="inventoryID" Value="1d4c71d8-b428-11dc-8314-0800200c9a66" /> 132 <Key Name="inventoryID" Value="1d4c71d8-b428-11dc-8314-0800200c9a66" />
@@ -169,11 +136,8 @@
169 <Key Name="name" Value="llBase64ToString" /> 136 <Key Name="name" Value="llBase64ToString" />
170 <Key Name="assetType" Value="10" /> 137 <Key Name="assetType" Value="10" />
171 <Key Name="inventoryType" Value="10" /> 138 <Key Name="inventoryType" Value="10" />
172 <Key Name="currentPermissions" Value="257487132" />
173 <Key Name="nextPermissions" Value="257487132" />
174 <Key Name="everyonePermissions" Value="257487132" />
175 <Key Name="basePermissions" Value="257487132" />
176 </Section> 139 </Section>
140
177<!-- C == <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba005"/> --> 141<!-- C == <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba005"/> -->
178<!-- D == <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba006"/> --> 142<!-- D == <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba006"/> -->
179<!-- E == <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba007"/> --> 143<!-- E == <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba007"/> -->
@@ -187,6 +151,7 @@
187<!-- O == <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba015"/> --> 151<!-- O == <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba015"/> -->
188<!-- P == <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba016"/> --> 152<!-- P == <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba016"/> -->
189<!-- R == <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba017"/> --> 153<!-- R == <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba017"/> -->
154
190 <Section Name="llRemoveFromLandBanList"> 155 <Section Name="llRemoveFromLandBanList">
191 <Key Name="inventoryID" Value="299b2100-b392-11dc-8314-0800200c9a66" /> 156 <Key Name="inventoryID" Value="299b2100-b392-11dc-8314-0800200c9a66" />
192 <Key Name="assetID" Value="299b2101-b392-11dc-8314-0800200c9a66" /> 157 <Key Name="assetID" Value="299b2101-b392-11dc-8314-0800200c9a66" />
@@ -195,11 +160,8 @@
195 <Key Name="name" Value="llRemoveFromLandBanList" /> 160 <Key Name="name" Value="llRemoveFromLandBanList" />
196 <Key Name="assetType" Value="10" /> 161 <Key Name="assetType" Value="10" />
197 <Key Name="inventoryType" Value="10" /> 162 <Key Name="inventoryType" Value="10" />
198 <Key Name="currentPermissions" Value="257487132" />
199 <Key Name="nextPermissions" Value="257487132" />
200 <Key Name="everyonePermissions" Value="257487132" />
201 <Key Name="basePermissions" Value="257487132" />
202 </Section> 163 </Section>
164
203 <Section Name="llRemoveFromLandPassList"> 165 <Section Name="llRemoveFromLandPassList">
204 <Key Name="inventoryID" Value="299b2102-b392-11dc-8314-0800200c9a66" /> 166 <Key Name="inventoryID" Value="299b2102-b392-11dc-8314-0800200c9a66" />
205 <Key Name="assetID" Value="299b2103-b392-11dc-8314-0800200c9a66" /> 167 <Key Name="assetID" Value="299b2103-b392-11dc-8314-0800200c9a66" />
@@ -208,11 +170,8 @@
208 <Key Name="name" Value="llRemoveFromLandPassList" /> 170 <Key Name="name" Value="llRemoveFromLandPassList" />
209 <Key Name="assetType" Value="10" /> 171 <Key Name="assetType" Value="10" />
210 <Key Name="inventoryType" Value="10" /> 172 <Key Name="inventoryType" Value="10" />
211 <Key Name="currentPermissions" Value="257487132" />
212 <Key Name="nextPermissions" Value="257487132" />
213 <Key Name="everyonePermissions" Value="257487132" />
214 <Key Name="basePermissions" Value="257487132" />
215 </Section> 173 </Section>
174
216 <Section Name="llResetLandBanList"> 175 <Section Name="llResetLandBanList">
217 <Key Name="inventoryID" Value="366ac8e6-b391-11dc-8314-0800200c9a66" /> 176 <Key Name="inventoryID" Value="366ac8e6-b391-11dc-8314-0800200c9a66" />
218 <Key Name="assetID" Value="366ac8e7-b391-11dc-8314-0800200c9a66" /> 177 <Key Name="assetID" Value="366ac8e7-b391-11dc-8314-0800200c9a66" />
@@ -221,11 +180,8 @@
221 <Key Name="name" Value="llResetLandBanList" /> 180 <Key Name="name" Value="llResetLandBanList" />
222 <Key Name="assetType" Value="10" /> 181 <Key Name="assetType" Value="10" />
223 <Key Name="inventoryType" Value="10" /> 182 <Key Name="inventoryType" Value="10" />
224 <Key Name="currentPermissions" Value="257487132" />
225 <Key Name="nextPermissions" Value="257487132" />
226 <Key Name="everyonePermissions" Value="257487132" />
227 <Key Name="basePermissions" Value="257487132" />
228 </Section> 183 </Section>
184
229 <Section Name="llResetLandPassList"> 185 <Section Name="llResetLandPassList">
230 <Key Name="inventoryID" Value="366ac8e8-b391-11dc-8314-0800200c9a66" /> 186 <Key Name="inventoryID" Value="366ac8e8-b391-11dc-8314-0800200c9a66" />
231 <Key Name="assetID" Value="366ac8e9-b391-11dc-8314-0800200c9a66" /> 187 <Key Name="assetID" Value="366ac8e9-b391-11dc-8314-0800200c9a66" />
@@ -234,11 +190,8 @@
234 <Key Name="name" Value="llResetLandPassList" /> 190 <Key Name="name" Value="llResetLandPassList" />
235 <Key Name="assetType" Value="10" /> 191 <Key Name="assetType" Value="10" />
236 <Key Name="inventoryType" Value="10" /> 192 <Key Name="inventoryType" Value="10" />
237 <Key Name="currentPermissions" Value="257487132" />
238 <Key Name="nextPermissions" Value="257487132" />
239 <Key Name="everyonePermissions" Value="257487132" />
240 <Key Name="basePermissions" Value="257487132" />
241 </Section> 193 </Section>
194
242<!-- S == <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba018"/> --> 195<!-- S == <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba018"/> -->
243 <Section Name="llSay"> 196 <Section Name="llSay">
244 <Key Name="inventoryID" Value="3af51d20-b38f-11dc-8314-0800200c9a66" /> 197 <Key Name="inventoryID" Value="3af51d20-b38f-11dc-8314-0800200c9a66" />
@@ -248,11 +201,8 @@
248 <Key Name="name" Value="llSay" /> 201 <Key Name="name" Value="llSay" />
249 <Key Name="assetType" Value="10" /> 202 <Key Name="assetType" Value="10" />
250 <Key Name="inventoryType" Value="10" /> 203 <Key Name="inventoryType" Value="10" />
251 <Key Name="currentPermissions" Value="257487132" />
252 <Key Name="nextPermissions" Value="257487132" />
253 <Key Name="everyonePermissions" Value="257487132" />
254 <Key Name="basePermissions" Value="257487132" />
255 </Section> 204 </Section>
205
256 <Section Name="llSetParcelMusicURL"> 206 <Section Name="llSetParcelMusicURL">
257 <Key Name="inventoryID" Value="3603a4f9-b360-11dc-8314-0800200c9a66" /> 207 <Key Name="inventoryID" Value="3603a4f9-b360-11dc-8314-0800200c9a66" />
258 <Key Name="assetID" Value="3603a4f8-b360-11dc-8314-0800200c9a66" /> 208 <Key Name="assetID" Value="3603a4f8-b360-11dc-8314-0800200c9a66" />
@@ -261,11 +211,8 @@
261 <Key Name="name" Value="llSetParcelMusicURL" /> 211 <Key Name="name" Value="llSetParcelMusicURL" />
262 <Key Name="assetType" Value="10" /> 212 <Key Name="assetType" Value="10" />
263 <Key Name="inventoryType" Value="10" /> 213 <Key Name="inventoryType" Value="10" />
264 <Key Name="currentPermissions" Value="257487132" />
265 <Key Name="nextPermissions" Value="257487132" />
266 <Key Name="everyonePermissions" Value="257487132" />
267 <Key Name="basePermissions" Value="257487132" />
268 </Section> 214 </Section>
215
269 <Section Name="llSetRot"> 216 <Section Name="llSetRot">
270 <Key Name="inventoryID" Value="220baef8-b376-11dc-8314-0800200c9a66" /> 217 <Key Name="inventoryID" Value="220baef8-b376-11dc-8314-0800200c9a66" />
271 <Key Name="assetID" Value="220baef9-b376-11dc-8314-0800200c9a66" /> 218 <Key Name="assetID" Value="220baef9-b376-11dc-8314-0800200c9a66" />
@@ -274,11 +221,8 @@
274 <Key Name="name" Value="llSetRot" /> 221 <Key Name="name" Value="llSetRot" />
275 <Key Name="assetType" Value="10" /> 222 <Key Name="assetType" Value="10" />
276 <Key Name="inventoryType" Value="10" /> 223 <Key Name="inventoryType" Value="10" />
277 <Key Name="currentPermissions" Value="257487132" />
278 <Key Name="nextPermissions" Value="257487132" />
279 <Key Name="everyonePermissions" Value="257487132" />
280 <Key Name="basePermissions" Value="257487132" />
281 </Section> 224 </Section>
225
282<!-- T == <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba019"/> --> 226<!-- T == <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba019"/> -->
283<!-- U == <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba020"/> --> 227<!-- U == <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba020"/> -->
284<!-- V == <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba021"/> --> 228<!-- V == <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba021"/> -->
@@ -288,213 +232,166 @@
288 <Section Name="Kan-Ed Test1"> 232 <Section Name="Kan-Ed Test1">
289 <Key Name="inventoryID" Value="42b6ac70-d21f-11dd-ad8b-0800200c9a66" /> 233 <Key Name="inventoryID" Value="42b6ac70-d21f-11dd-ad8b-0800200c9a66" />
290 <Key Name="assetID" Value="42b6ac70-d21f-11dd-ad8b-0800200c9a66" /> 234 <Key Name="assetID" Value="42b6ac70-d21f-11dd-ad8b-0800200c9a66" />
291 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/> 235 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/>
292 <Key Name="description" Value="Kan-Ed Test1" /> 236 <Key Name="description" Value="Kan-Ed Test1" />
293 <Key Name="name" Value="Kan-Ed Test1" /> 237 <Key Name="name" Value="Kan-Ed Test1" />
294 <Key Name="assetType" Value="10" /> 238 <Key Name="assetType" Value="10" />
295 <Key Name="inventoryType" Value="10" /> 239 <Key Name="inventoryType" Value="10" />
296 <Key Name="currentPermissions" Value="257487132" />
297 <Key Name="nextPermissions" Value="257487132" />
298 <Key Name="everyonePermissions" Value="257487132" />
299 <Key Name="basePermissions" Value="257487132" />
300 </Section> 240 </Section>
241
301 <Section Name="Kan-Ed Test2"> 242 <Section Name="Kan-Ed Test2">
302 <Key Name="inventoryID" Value="42b6ac71-d21f-11dd-ad8b-0800200c9a66" /> 243 <Key Name="inventoryID" Value="42b6ac71-d21f-11dd-ad8b-0800200c9a66" />
303 <Key Name="assetID" Value="42b6ac71-d21f-11dd-ad8b-0800200c9a66" /> 244 <Key Name="assetID" Value="42b6ac71-d21f-11dd-ad8b-0800200c9a66" />
304 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/> 245 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/>
305 <Key Name="description" Value="Kan-Ed Test2" /> 246 <Key Name="description" Value="Kan-Ed Test2" />
306 <Key Name="name" Value="Kan-Ed Test2" /> 247 <Key Name="name" Value="Kan-Ed Test2" />
307 <Key Name="assetType" Value="10" /> 248 <Key Name="assetType" Value="10" />
308 <Key Name="inventoryType" Value="10" /> 249 <Key Name="inventoryType" Value="10" />
309 <Key Name="currentPermissions" Value="257487132" />
310 <Key Name="nextPermissions" Value="257487132" />
311 <Key Name="everyonePermissions" Value="257487132" />
312 <Key Name="basePermissions" Value="257487132" />
313 </Section> 250 </Section>
251
314 <Section Name="Kan-Ed Test3"> 252 <Section Name="Kan-Ed Test3">
315 <Key Name="inventoryID" Value="42b6ac72-d21f-11dd-ad8b-0800200c9a66" /> 253 <Key Name="inventoryID" Value="42b6ac72-d21f-11dd-ad8b-0800200c9a66" />
316 <Key Name="assetID" Value="42b6ac72-d21f-11dd-ad8b-0800200c9a66" /> 254 <Key Name="assetID" Value="42b6ac72-d21f-11dd-ad8b-0800200c9a66" />
317 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/> 255 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/>
318 <Key Name="description" Value="Kan-Ed Test3" /> 256 <Key Name="description" Value="Kan-Ed Test3" />
319 <Key Name="name" Value="Kan-Ed Test3" /> 257 <Key Name="name" Value="Kan-Ed Test3" />
320 <Key Name="assetType" Value="10" /> 258 <Key Name="assetType" Value="10" />
321 <Key Name="inventoryType" Value="10" /> 259 <Key Name="inventoryType" Value="10" />
322 <Key Name="currentPermissions" Value="257487132" />
323 <Key Name="nextPermissions" Value="257487132" />
324 <Key Name="everyonePermissions" Value="257487132" />
325 <Key Name="basePermissions" Value="257487132" />
326 </Section> 260 </Section>
261
327 <Section Name="Kan-Ed Test4"> 262 <Section Name="Kan-Ed Test4">
328 <Key Name="inventoryID" Value="42b6ac73-d21f-11dd-ad8b-0800200c9a66" /> 263 <Key Name="inventoryID" Value="42b6ac73-d21f-11dd-ad8b-0800200c9a66" />
329 <Key Name="assetID" Value="42b6ac73-d21f-11dd-ad8b-0800200c9a66" /> 264 <Key Name="assetID" Value="42b6ac73-d21f-11dd-ad8b-0800200c9a66" />
330 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/> 265 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/>
331 <Key Name="description" Value="Kan-Ed Test4" /> 266 <Key Name="description" Value="Kan-Ed Test4" />
332 <Key Name="name" Value="Kan-Ed Test4" /> 267 <Key Name="name" Value="Kan-Ed Test4" />
333 <Key Name="assetType" Value="10" /> 268 <Key Name="assetType" Value="10" />
334 <Key Name="inventoryType" Value="10" /> 269 <Key Name="inventoryType" Value="10" />
335 <Key Name="currentPermissions" Value="257487132" />
336 <Key Name="nextPermissions" Value="257487132" />
337 <Key Name="everyonePermissions" Value="257487132" />
338 <Key Name="basePermissions" Value="257487132" />
339 </Section> 270 </Section>
271
340 <Section Name="Kan-Ed Test5"> 272 <Section Name="Kan-Ed Test5">
341 <Key Name="inventoryID" Value="42b6ac74-d21f-11dd-ad8b-0800200c9a66" /> 273 <Key Name="inventoryID" Value="42b6ac74-d21f-11dd-ad8b-0800200c9a66" />
342 <Key Name="assetID" Value="42b6ac74-d21f-11dd-ad8b-0800200c9a66" /> 274 <Key Name="assetID" Value="42b6ac74-d21f-11dd-ad8b-0800200c9a66" />
343 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/> 275 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/>
344 <Key Name="description" Value="Kan-Ed Test5" /> 276 <Key Name="description" Value="Kan-Ed Test5" />
345 <Key Name="name" Value="Kan-Ed Test5" /> 277 <Key Name="name" Value="Kan-Ed Test5" />
346 <Key Name="assetType" Value="10" /> 278 <Key Name="assetType" Value="10" />
347 <Key Name="inventoryType" Value="10" /> 279 <Key Name="inventoryType" Value="10" />
348 <Key Name="currentPermissions" Value="257487132" />
349 <Key Name="nextPermissions" Value="257487132" />
350 <Key Name="everyonePermissions" Value="257487132" />
351 <Key Name="basePermissions" Value="257487132" />
352 </Section> 280 </Section>
281
353 <Section Name="Kan-Ed Test6"> 282 <Section Name="Kan-Ed Test6">
354 <Key Name="inventoryID" Value="42b6ac75-d21f-11dd-ad8b-0800200c9a66" /> 283 <Key Name="inventoryID" Value="42b6ac75-d21f-11dd-ad8b-0800200c9a66" />
355 <Key Name="assetID" Value="42b6ac75-d21f-11dd-ad8b-0800200c9a66" /> 284 <Key Name="assetID" Value="42b6ac75-d21f-11dd-ad8b-0800200c9a66" />
356 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/> 285 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/>
357 <Key Name="description" Value="Kan-Ed Test6" /> 286 <Key Name="description" Value="Kan-Ed Test6" />
358 <Key Name="name" Value="Kan-Ed Test6" /> 287 <Key Name="name" Value="Kan-Ed Test6" />
359 <Key Name="assetType" Value="10" /> 288 <Key Name="assetType" Value="10" />
360 <Key Name="inventoryType" Value="10" /> 289 <Key Name="inventoryType" Value="10" />
361 <Key Name="currentPermissions" Value="257487132" />
362 <Key Name="nextPermissions" Value="257487132" />
363 <Key Name="everyonePermissions" Value="257487132" />
364 <Key Name="basePermissions" Value="257487132" />
365 </Section> 290 </Section>
291
366 <Section Name="Kan-Ed Test7"> 292 <Section Name="Kan-Ed Test7">
367 <Key Name="inventoryID" Value="42b6ac76-d21f-11dd-ad8b-0800200c9a66" /> 293 <Key Name="inventoryID" Value="42b6ac76-d21f-11dd-ad8b-0800200c9a66" />
368 <Key Name="assetID" Value="42b6ac76-d21f-11dd-ad8b-0800200c9a66" /> 294 <Key Name="assetID" Value="42b6ac76-d21f-11dd-ad8b-0800200c9a66" />
369 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/> 295 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/>
370 <Key Name="description" Value="Kan-Ed Test7" /> 296 <Key Name="description" Value="Kan-Ed Test7" />
371 <Key Name="name" Value="Kan-Ed Test7" /> 297 <Key Name="name" Value="Kan-Ed Test7" />
372 <Key Name="assetType" Value="10" /> 298 <Key Name="assetType" Value="10" />
373 <Key Name="inventoryType" Value="10" /> 299 <Key Name="inventoryType" Value="10" />
374 <Key Name="currentPermissions" Value="257487132" />
375 <Key Name="nextPermissions" Value="257487132" />
376 <Key Name="everyonePermissions" Value="257487132" />
377 <Key Name="basePermissions" Value="257487132" />
378 </Section> 300 </Section>
301
379 <Section Name="Kan-Ed Test8"> 302 <Section Name="Kan-Ed Test8">
380 <Key Name="inventoryID" Value="42b6ac77-d21f-11dd-ad8b-0800200c9a66" /> 303 <Key Name="inventoryID" Value="42b6ac77-d21f-11dd-ad8b-0800200c9a66" />
381 <Key Name="assetID" Value="42b6ac77-d21f-11dd-ad8b-0800200c9a66" /> 304 <Key Name="assetID" Value="42b6ac77-d21f-11dd-ad8b-0800200c9a66" />
382 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/> 305 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/>
383 <Key Name="description" Value="Kan-Ed Test8" /> 306 <Key Name="description" Value="Kan-Ed Test8" />
384 <Key Name="name" Value="Kan-Ed Test8" /> 307 <Key Name="name" Value="Kan-Ed Test8" />
385 <Key Name="assetType" Value="10" /> 308 <Key Name="assetType" Value="10" />
386 <Key Name="inventoryType" Value="10" /> 309 <Key Name="inventoryType" Value="10" />
387 <Key Name="currentPermissions" Value="257487132" />
388 <Key Name="nextPermissions" Value="257487132" />
389 <Key Name="everyonePermissions" Value="257487132" />
390 <Key Name="basePermissions" Value="257487132" />
391 </Section> 310 </Section>
311
392 <Section Name="Kan-Ed Test9"> 312 <Section Name="Kan-Ed Test9">
393 <Key Name="inventoryID" Value="42b6ac78-d21f-11dd-ad8b-0800200c9a66" /> 313 <Key Name="inventoryID" Value="42b6ac78-d21f-11dd-ad8b-0800200c9a66" />
394 <Key Name="assetID" Value="42b6ac78-d21f-11dd-ad8b-0800200c9a66" /> 314 <Key Name="assetID" Value="42b6ac78-d21f-11dd-ad8b-0800200c9a66" />
395 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/> 315 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/>
396 <Key Name="description" Value="Kan-Ed Test9" /> 316 <Key Name="description" Value="Kan-Ed Test9" />
397 <Key Name="name" Value="Kan-Ed Test9" /> 317 <Key Name="name" Value="Kan-Ed Test9" />
398 <Key Name="assetType" Value="10" /> 318 <Key Name="assetType" Value="10" />
399 <Key Name="inventoryType" Value="10" /> 319 <Key Name="inventoryType" Value="10" />
400 <Key Name="currentPermissions" Value="257487132" />
401 <Key Name="nextPermissions" Value="257487132" />
402 <Key Name="everyonePermissions" Value="257487132" />
403 <Key Name="basePermissions" Value="257487132" />
404 </Section> 320 </Section>
321
405 <Section Name="Kan-Ed Test10"> 322 <Section Name="Kan-Ed Test10">
406 <Key Name="inventoryID" Value="42b6ac79-d21f-11dd-ad8b-0800200c9a66" /> 323 <Key Name="inventoryID" Value="42b6ac79-d21f-11dd-ad8b-0800200c9a66" />
407 <Key Name="assetID" Value="42b6ac79-d21f-11dd-ad8b-0800200c9a66" /> 324 <Key Name="assetID" Value="42b6ac79-d21f-11dd-ad8b-0800200c9a66" />
408 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/> 325 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/>
409 <Key Name="description" Value="Kan-Ed Test10" /> 326 <Key Name="description" Value="Kan-Ed Test10" />
410 <Key Name="name" Value="Kan-Ed Test10" /> 327 <Key Name="name" Value="Kan-Ed Test10" />
411 <Key Name="assetType" Value="10" /> 328 <Key Name="assetType" Value="10" />
412 <Key Name="inventoryType" Value="10" /> 329 <Key Name="inventoryType" Value="10" />
413 <Key Name="currentPermissions" Value="257487132" />
414 <Key Name="nextPermissions" Value="257487132" />
415 <Key Name="everyonePermissions" Value="257487132" />
416 <Key Name="basePermissions" Value="257487132" />
417 </Section> 330 </Section>
331
418 <Section Name="Kan-Ed Test11"> 332 <Section Name="Kan-Ed Test11">
419 <Key Name="inventoryID" Value="42b6ac7a-d21f-11dd-ad8b-0800200c9a66" /> 333 <Key Name="inventoryID" Value="42b6ac7a-d21f-11dd-ad8b-0800200c9a66" />
420 <Key Name="assetID" Value="42b6ac7a-d21f-11dd-ad8b-0800200c9a66" /> 334 <Key Name="assetID" Value="42b6ac7a-d21f-11dd-ad8b-0800200c9a66" />
421 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/> 335 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/>
422 <Key Name="description" Value="Kan-Ed Test11" /> 336 <Key Name="description" Value="Kan-Ed Test11" />
423 <Key Name="name" Value="Kan-Ed Test11" /> 337 <Key Name="name" Value="Kan-Ed Test11" />
424 <Key Name="assetType" Value="10" /> 338 <Key Name="assetType" Value="10" />
425 <Key Name="inventoryType" Value="10" /> 339 <Key Name="inventoryType" Value="10" />
426 <Key Name="currentPermissions" Value="257487132" />
427 <Key Name="nextPermissions" Value="257487132" />
428 <Key Name="everyonePermissions" Value="257487132" />
429 <Key Name="basePermissions" Value="257487132" />
430 </Section> 340 </Section>
341
431 <Section Name="Kan-Ed Test12"> 342 <Section Name="Kan-Ed Test12">
432 <Key Name="inventoryID" Value="42b6ac7b-d21f-11dd-ad8b-0800200c9a66" /> 343 <Key Name="inventoryID" Value="42b6ac7b-d21f-11dd-ad8b-0800200c9a66" />
433 <Key Name="assetID" Value="42b6ac7b-d21f-11dd-ad8b-0800200c9a66" /> 344 <Key Name="assetID" Value="42b6ac7b-d21f-11dd-ad8b-0800200c9a66" />
434 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/> 345 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/>
435 <Key Name="description" Value="Kan-Ed Test12" /> 346 <Key Name="description" Value="Kan-Ed Test12" />
436 <Key Name="name" Value="Kan-Ed Test12" /> 347 <Key Name="name" Value="Kan-Ed Test12" />
437 <Key Name="assetType" Value="10" /> 348 <Key Name="assetType" Value="10" />
438 <Key Name="inventoryType" Value="10" /> 349 <Key Name="inventoryType" Value="10" />
439 <Key Name="currentPermissions" Value="257487132" />
440 <Key Name="nextPermissions" Value="257487132" />
441 <Key Name="everyonePermissions" Value="257487132" />
442 <Key Name="basePermissions" Value="257487132" />
443 </Section> 350 </Section>
351
444 <Section Name="Kan-Ed Test13"> 352 <Section Name="Kan-Ed Test13">
445 <Key Name="inventoryID" Value="42b6ac7c-d21f-11dd-ad8b-0800200c9a66" /> 353 <Key Name="inventoryID" Value="42b6ac7c-d21f-11dd-ad8b-0800200c9a66" />
446 <Key Name="assetID" Value="42b6ac7c-d21f-11dd-ad8b-0800200c9a66" /> 354 <Key Name="assetID" Value="42b6ac7c-d21f-11dd-ad8b-0800200c9a66" />
447 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/> 355 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/>
448 <Key Name="description" Value="Kan-Ed Test13" /> 356 <Key Name="description" Value="Kan-Ed Test13" />
449 <Key Name="name" Value="Kan-Ed Test13" /> 357 <Key Name="name" Value="Kan-Ed Test13" />
450 <Key Name="assetType" Value="10" /> 358 <Key Name="assetType" Value="10" />
451 <Key Name="inventoryType" Value="10" /> 359 <Key Name="inventoryType" Value="10" />
452 <Key Name="currentPermissions" Value="257487132" />
453 <Key Name="nextPermissions" Value="257487132" />
454 <Key Name="everyonePermissions" Value="257487132" />
455 <Key Name="basePermissions" Value="257487132" />
456 </Section> 360 </Section>
361
457 <Section Name="Kan-Ed Test14"> 362 <Section Name="Kan-Ed Test14">
458 <Key Name="inventoryID" Value="42b6ac7d-d21f-11dd-ad8b-0800200c9a66" /> 363 <Key Name="inventoryID" Value="42b6ac7d-d21f-11dd-ad8b-0800200c9a66" />
459 <Key Name="assetID" Value="42b6ac7d-d21f-11dd-ad8b-0800200c9a66" /> 364 <Key Name="assetID" Value="42b6ac7d-d21f-11dd-ad8b-0800200c9a66" />
460 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/> 365 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/>
461 <Key Name="description" Value="Kan-Ed Test14" /> 366 <Key Name="description" Value="Kan-Ed Test14" />
462 <Key Name="name" Value="Kan-Ed Test14" /> 367 <Key Name="name" Value="Kan-Ed Test14" />
463 <Key Name="assetType" Value="10" /> 368 <Key Name="assetType" Value="10" />
464 <Key Name="inventoryType" Value="10" /> 369 <Key Name="inventoryType" Value="10" />
465 <Key Name="currentPermissions" Value="257487132" />
466 <Key Name="nextPermissions" Value="257487132" />
467 <Key Name="everyonePermissions" Value="257487132" />
468 <Key Name="basePermissions" Value="257487132" />
469 </Section> 370 </Section>
371
470 <Section Name="Kan-Ed Test15"> 372 <Section Name="Kan-Ed Test15">
471 <Key Name="inventoryID" Value="42b6ac7e-d21f-11dd-ad8b-0800200c9a66" /> 373 <Key Name="inventoryID" Value="42b6ac7e-d21f-11dd-ad8b-0800200c9a66" />
472 <Key Name="assetID" Value="42b6ac7e-d21f-11dd-ad8b-0800200c9a66" /> 374 <Key Name="assetID" Value="42b6ac7e-d21f-11dd-ad8b-0800200c9a66" />
473 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/> 375 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/>
474 <Key Name="description" Value="Kan-Ed Test15" /> 376 <Key Name="description" Value="Kan-Ed Test15" />
475 <Key Name="name" Value="Kan-Ed Test15" /> 377 <Key Name="name" Value="Kan-Ed Test15" />
476 <Key Name="assetType" Value="10" /> 378 <Key Name="assetType" Value="10" />
477 <Key Name="inventoryType" Value="10" /> 379 <Key Name="inventoryType" Value="10" />
478 <Key Name="currentPermissions" Value="257487132" />
479 <Key Name="nextPermissions" Value="257487132" />
480 <Key Name="everyonePermissions" Value="257487132" />
481 <Key Name="basePermissions" Value="257487132" />
482 </Section> 380 </Section>
381
483 <Section Name="Kan-Ed Test16"> 382 <Section Name="Kan-Ed Test16">
484 <Key Name="inventoryID" Value="42b6ac7f-d21f-11dd-ad8b-0800200c9a66" /> 383 <Key Name="inventoryID" Value="42b6ac7f-d21f-11dd-ad8b-0800200c9a66" />
485 <Key Name="assetID" Value="42b6ac7f-d21f-11dd-ad8b-0800200c9a66" /> 384 <Key Name="assetID" Value="42b6ac7f-d21f-11dd-ad8b-0800200c9a66" />
486 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/> 385 <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba024"/>
487 <Key Name="description" Value="Kan-Ed Test16" /> 386 <Key Name="description" Value="Kan-Ed Test16" />
488 <Key Name="name" Value="Kan-Ed Test16" /> 387 <Key Name="name" Value="Kan-Ed Test16" />
489 <Key Name="assetType" Value="10" /> 388 <Key Name="assetType" Value="10" />
490 <Key Name="inventoryType" Value="10" /> 389 <Key Name="inventoryType" Value="10" />
491 <Key Name="currentPermissions" Value="257487132" />
492 <Key Name="nextPermissions" Value="257487132" />
493 <Key Name="everyonePermissions" Value="257487132" />
494 <Key Name="basePermissions" Value="257487132" />
495 </Section> 390 </Section>
391
496<!-- .Other testing scripts == <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba025"/> --> 392<!-- .Other testing scripts == <Key Name="folderID" Value="30000112-000f-0000-0000-000100bba025"/> -->
497<!-- OpenSim Specific Scripts == <Key Name="folderID" Value="284858c8-9391-6bf1-ddf5-b936f73de853"/> --> 393<!-- OpenSim Specific Scripts == <Key Name="folderID" Value="284858c8-9391-6bf1-ddf5-b936f73de853"/> -->
394
498 <Section Name="osTextBoard"> 395 <Section Name="osTextBoard">
499 <Key Name="inventoryID" Value="2ddcb059-20c5-d169-4c42-673f16d3284b" /> 396 <Key Name="inventoryID" Value="2ddcb059-20c5-d169-4c42-673f16d3284b" />
500 <Key Name="assetID" Value="2ddcb059-20c5-d169-4c42-673f16d3284b" /> 397 <Key Name="assetID" Value="2ddcb059-20c5-d169-4c42-673f16d3284b" />
@@ -503,11 +400,8 @@
503 <Key Name="name" Value="osTextBoard" /> 400 <Key Name="name" Value="osTextBoard" />
504 <Key Name="assetType" Value="10" /> 401 <Key Name="assetType" Value="10" />
505 <Key Name="inventoryType" Value="10" /> 402 <Key Name="inventoryType" Value="10" />
506 <Key Name="currentPermissions" Value="257487132" />
507 <Key Name="nextPermissions" Value="257487132" />
508 <Key Name="everyonePermissions" Value="257487132" />
509 <Key Name="basePermissions" Value="257487132" />
510 </Section> 403 </Section>
404
511 <Section Name="osWeatherMap"> 405 <Section Name="osWeatherMap">
512 <Key Name="inventoryID" Value="d63ad3ec-b687-6c38-410d-31ba3e50ce4d" /> 406 <Key Name="inventoryID" Value="d63ad3ec-b687-6c38-410d-31ba3e50ce4d" />
513 <Key Name="assetID" Value="d63ad3ec-b687-6c38-410d-31ba3e50ce4d" /> 407 <Key Name="assetID" Value="d63ad3ec-b687-6c38-410d-31ba3e50ce4d" />
@@ -516,11 +410,8 @@
516 <Key Name="name" Value="osWeatherMap" /> 410 <Key Name="name" Value="osWeatherMap" />
517 <Key Name="assetType" Value="10" /> 411 <Key Name="assetType" Value="10" />
518 <Key Name="inventoryType" Value="10" /> 412 <Key Name="inventoryType" Value="10" />
519 <Key Name="currentPermissions" Value="257487132" />
520 <Key Name="nextPermissions" Value="257487132" />
521 <Key Name="everyonePermissions" Value="257487132" />
522 <Key Name="basePermissions" Value="257487132" />
523 </Section> 413 </Section>
414
524 <Section Name="GrafittiBoard"> 415 <Section Name="GrafittiBoard">
525 <Key Name="inventoryID" Value="81305ee4-8caa-9e0a-69a4-76ed57df0c8f" /> 416 <Key Name="inventoryID" Value="81305ee4-8caa-9e0a-69a4-76ed57df0c8f" />
526 <Key Name="assetID" Value="81305ee4-8caa-9e0a-69a4-76ed57df0c8f" /> 417 <Key Name="assetID" Value="81305ee4-8caa-9e0a-69a4-76ed57df0c8f" />
@@ -529,9 +420,5 @@
529 <Key Name="name" Value="GrafittiBoard" /> 420 <Key Name="name" Value="GrafittiBoard" />
530 <Key Name="assetType" Value="10" /> 421 <Key Name="assetType" Value="10" />
531 <Key Name="inventoryType" Value="10" /> 422 <Key Name="inventoryType" Value="10" />
532 <Key Name="currentPermissions" Value="257487132" />
533 <Key Name="nextPermissions" Value="257487132" />
534 <Key Name="everyonePermissions" Value="257487132" />
535 <Key Name="basePermissions" Value="257487132" />
536 </Section> 423 </Section>
537</Nini> 424</Nini>
diff --git a/bin/inventory/SoundsLibrary/SoundsLibraryItems.xml b/bin/inventory/SoundsLibrary/SoundsLibraryItems.xml
index 4047a58..44194cd 100644
--- a/bin/inventory/SoundsLibrary/SoundsLibraryItems.xml
+++ b/bin/inventory/SoundsLibrary/SoundsLibraryItems.xml
@@ -9,10 +9,6 @@
9 <Key Name="name" Value="Example Library Item" /> 9 <Key Name="name" Value="Example Library Item" />
10 <Key Name="assetType" Value="7" /> 10 <Key Name="assetType" Value="7" />
11 <Key Name="inventoryType" Value="7" /> 11 <Key Name="inventoryType" Value="7" />
12 <Key Name="currentPermissions" Value="2147483647" />
13 <Key Name="nextPermissions" Value="2147483647" />
14 <Key Name="everyonePermissions" Value="2147483647" />
15 <Key Name="basePermissions" Value="2147483647" />
16 </Section> 12 </Section>
17--> 13-->
18 14
diff --git a/bin/inventory/TexturesLibrary/TexturesLibraryItems.xml b/bin/inventory/TexturesLibrary/TexturesLibraryItems.xml
index adba99a..a018a0d 100644
--- a/bin/inventory/TexturesLibrary/TexturesLibraryItems.xml
+++ b/bin/inventory/TexturesLibrary/TexturesLibraryItems.xml
@@ -9,10 +9,6 @@
9 <Key Name="name" Value="Example Library Item" /> 9 <Key Name="name" Value="Example Library Item" />
10 <Key Name="assetType" Value="7" /> 10 <Key Name="assetType" Value="7" />
11 <Key Name="inventoryType" Value="7" /> 11 <Key Name="inventoryType" Value="7" />
12 <Key Name="currentPermissions" Value="2147483647" />
13 <Key Name="nextPermissions" Value="2147483647" />
14 <Key Name="everyonePermissions" Value="2147483647" />
15 <Key Name="basePermissions" Value="2147483647" />
16 </Section> 12 </Section>
17--> 13-->
18 14
@@ -24,11 +20,8 @@
24 <Key Name="name" Value="4-tile2" /> 20 <Key Name="name" Value="4-tile2" />
25 <Key Name="assetType" Value="0" /> 21 <Key Name="assetType" Value="0" />
26 <Key Name="inventoryType" Value="0" /> 22 <Key Name="inventoryType" Value="0" />
27 <Key Name="currentPermissions" Value="2147483647" />
28 <Key Name="nextPermissions" Value="2147483647" />
29 <Key Name="everyonePermissions" Value="2147483647" />
30 <Key Name="basePermissions" Value="2147483647" />
31 </Section> 23 </Section>
24
32 <Section Name="4-tile3 Texture"> 25 <Section Name="4-tile3 Texture">
33 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001001" /> 26 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001001" />
34 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001001" /> 27 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001001" />
@@ -37,11 +30,8 @@
37 <Key Name="name" Value="4-tile3" /> 30 <Key Name="name" Value="4-tile3" />
38 <Key Name="assetType" Value="0" /> 31 <Key Name="assetType" Value="0" />
39 <Key Name="inventoryType" Value="0" /> 32 <Key Name="inventoryType" Value="0" />
40 <Key Name="currentPermissions" Value="2147483647" />
41 <Key Name="nextPermissions" Value="2147483647" />
42 <Key Name="everyonePermissions" Value="2147483647" />
43 <Key Name="basePermissions" Value="2147483647" />
44 </Section> 33 </Section>
34
45 <Section Name="brick1_256 Texture"> 35 <Section Name="brick1_256 Texture">
46 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001002" /> 36 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001002" />
47 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001002" /> 37 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001002" />
@@ -50,11 +40,8 @@
50 <Key Name="name" Value="brick1_256" /> 40 <Key Name="name" Value="brick1_256" />
51 <Key Name="assetType" Value="0" /> 41 <Key Name="assetType" Value="0" />
52 <Key Name="inventoryType" Value="0" /> 42 <Key Name="inventoryType" Value="0" />
53 <Key Name="currentPermissions" Value="2147483647" />
54 <Key Name="nextPermissions" Value="2147483647" />
55 <Key Name="everyonePermissions" Value="2147483647" />
56 <Key Name="basePermissions" Value="2147483647" />
57 </Section> 43 </Section>
44
58 <Section Name="brick2_256 Texture"> 45 <Section Name="brick2_256 Texture">
59 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001003" /> 46 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001003" />
60 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001003" /> 47 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001003" />
@@ -63,11 +50,8 @@
63 <Key Name="name" Value="brick2_256" /> 50 <Key Name="name" Value="brick2_256" />
64 <Key Name="assetType" Value="0" /> 51 <Key Name="assetType" Value="0" />
65 <Key Name="inventoryType" Value="0" /> 52 <Key Name="inventoryType" Value="0" />
66 <Key Name="currentPermissions" Value="2147483647" />
67 <Key Name="nextPermissions" Value="2147483647" />
68 <Key Name="everyonePermissions" Value="2147483647" />
69 <Key Name="basePermissions" Value="2147483647" />
70 </Section> 53 </Section>
54
71 <Section Name="brick_mono Texture"> 55 <Section Name="brick_mono Texture">
72 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001004" /> 56 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001004" />
73 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001004" /> 57 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001004" />
@@ -76,11 +60,8 @@
76 <Key Name="name" Value="brick_mono" /> 60 <Key Name="name" Value="brick_mono" />
77 <Key Name="assetType" Value="0" /> 61 <Key Name="assetType" Value="0" />
78 <Key Name="inventoryType" Value="0" /> 62 <Key Name="inventoryType" Value="0" />
79 <Key Name="currentPermissions" Value="2147483647" />
80 <Key Name="nextPermissions" Value="2147483647" />
81 <Key Name="everyonePermissions" Value="2147483647" />
82 <Key Name="basePermissions" Value="2147483647" />
83 </Section> 63 </Section>
64
84 <Section Name="cedar Texture"> 65 <Section Name="cedar Texture">
85 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001005" /> 66 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001005" />
86 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001005" /> 67 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001005" />
@@ -89,11 +70,8 @@
89 <Key Name="name" Value="cedar" /> 70 <Key Name="name" Value="cedar" />
90 <Key Name="assetType" Value="0" /> 71 <Key Name="assetType" Value="0" />
91 <Key Name="inventoryType" Value="0" /> 72 <Key Name="inventoryType" Value="0" />
92 <Key Name="currentPermissions" Value="2147483647" />
93 <Key Name="nextPermissions" Value="2147483647" />
94 <Key Name="everyonePermissions" Value="2147483647" />
95 <Key Name="basePermissions" Value="2147483647" />
96 </Section> 73 </Section>
74
97 <Section Name="cement_block Texture"> 75 <Section Name="cement_block Texture">
98 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001006" /> 76 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001006" />
99 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001006" /> 77 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001006" />
@@ -102,11 +80,8 @@
102 <Key Name="name" Value="cement_block" /> 80 <Key Name="name" Value="cement_block" />
103 <Key Name="assetType" Value="0" /> 81 <Key Name="assetType" Value="0" />
104 <Key Name="inventoryType" Value="0" /> 82 <Key Name="inventoryType" Value="0" />
105 <Key Name="currentPermissions" Value="2147483647" />
106 <Key Name="nextPermissions" Value="2147483647" />
107 <Key Name="everyonePermissions" Value="2147483647" />
108 <Key Name="basePermissions" Value="2147483647" />
109 </Section> 83 </Section>
84
110 <Section Name="clear Texture"> 85 <Section Name="clear Texture">
111 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001007" /> 86 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001007" />
112 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001007" /> 87 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001007" />
@@ -115,11 +90,8 @@
115 <Key Name="name" Value="clear" /> 90 <Key Name="name" Value="clear" />
116 <Key Name="assetType" Value="0" /> 91 <Key Name="assetType" Value="0" />
117 <Key Name="inventoryType" Value="0" /> 92 <Key Name="inventoryType" Value="0" />
118 <Key Name="currentPermissions" Value="2147483647" />
119 <Key Name="nextPermissions" Value="2147483647" />
120 <Key Name="everyonePermissions" Value="2147483647" />
121 <Key Name="basePermissions" Value="2147483647" />
122 </Section> 93 </Section>
94
123 <Section Name="cobbles Texture"> 95 <Section Name="cobbles Texture">
124 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001008" /> 96 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001008" />
125 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001008" /> 97 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001008" />
@@ -128,11 +100,8 @@
128 <Key Name="name" Value="cobbles" /> 100 <Key Name="name" Value="cobbles" />
129 <Key Name="assetType" Value="0" /> 101 <Key Name="assetType" Value="0" />
130 <Key Name="inventoryType" Value="0" /> 102 <Key Name="inventoryType" Value="0" />
131 <Key Name="currentPermissions" Value="2147483647" />
132 <Key Name="nextPermissions" Value="2147483647" />
133 <Key Name="everyonePermissions" Value="2147483647" />
134 <Key Name="basePermissions" Value="2147483647" />
135 </Section> 103 </Section>
104
136 <Section Name="creambrick Texture"> 105 <Section Name="creambrick Texture">
137 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001009" /> 106 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001009" />
138 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001009" /> 107 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001009" />
@@ -141,11 +110,8 @@
141 <Key Name="name" Value="creambrick" /> 110 <Key Name="name" Value="creambrick" />
142 <Key Name="assetType" Value="0" /> 111 <Key Name="assetType" Value="0" />
143 <Key Name="inventoryType" Value="0" /> 112 <Key Name="inventoryType" Value="0" />
144 <Key Name="currentPermissions" Value="2147483647" />
145 <Key Name="nextPermissions" Value="2147483647" />
146 <Key Name="everyonePermissions" Value="2147483647" />
147 <Key Name="basePermissions" Value="2147483647" />
148 </Section> 113 </Section>
114
149 <Section Name="fgrass Texture"> 115 <Section Name="fgrass Texture">
150 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001010" /> 116 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001010" />
151 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001010" /> 117 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001010" />
@@ -154,11 +120,8 @@
154 <Key Name="name" Value="fgrass" /> 120 <Key Name="name" Value="fgrass" />
155 <Key Name="assetType" Value="0" /> 121 <Key Name="assetType" Value="0" />
156 <Key Name="inventoryType" Value="0" /> 122 <Key Name="inventoryType" Value="0" />
157 <Key Name="currentPermissions" Value="2147483647" />
158 <Key Name="nextPermissions" Value="2147483647" />
159 <Key Name="everyonePermissions" Value="2147483647" />
160 <Key Name="basePermissions" Value="2147483647" />
161 </Section> 123 </Section>
124
162 <Section Name="glasstile2 Texture"> 125 <Section Name="glasstile2 Texture">
163 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001011" /> 126 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001011" />
164 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001011" /> 127 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001011" />
@@ -167,11 +130,8 @@
167 <Key Name="name" Value="glasstile2" /> 130 <Key Name="name" Value="glasstile2" />
168 <Key Name="assetType" Value="0" /> 131 <Key Name="assetType" Value="0" />
169 <Key Name="inventoryType" Value="0" /> 132 <Key Name="inventoryType" Value="0" />
170 <Key Name="currentPermissions" Value="2147483647" />
171 <Key Name="nextPermissions" Value="2147483647" />
172 <Key Name="everyonePermissions" Value="2147483647" />
173 <Key Name="basePermissions" Value="2147483647" />
174 </Section> 133 </Section>
134
175 <Section Name="graniteblock Texture"> 135 <Section Name="graniteblock Texture">
176 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001012" /> 136 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001012" />
177 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001012" /> 137 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001012" />
@@ -180,11 +140,8 @@
180 <Key Name="name" Value="graniteblock" /> 140 <Key Name="name" Value="graniteblock" />
181 <Key Name="assetType" Value="0" /> 141 <Key Name="assetType" Value="0" />
182 <Key Name="inventoryType" Value="0" /> 142 <Key Name="inventoryType" Value="0" />
183 <Key Name="currentPermissions" Value="2147483647" />
184 <Key Name="nextPermissions" Value="2147483647" />
185 <Key Name="everyonePermissions" Value="2147483647" />
186 <Key Name="basePermissions" Value="2147483647" />
187 </Section> 143 </Section>
144
188 <Section Name="grass Texture"> 145 <Section Name="grass Texture">
189 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001013" /> 146 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001013" />
190 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001013" /> 147 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001013" />
@@ -193,11 +150,8 @@
193 <Key Name="name" Value="grass" /> 150 <Key Name="name" Value="grass" />
194 <Key Name="assetType" Value="0" /> 151 <Key Name="assetType" Value="0" />
195 <Key Name="inventoryType" Value="0" /> 152 <Key Name="inventoryType" Value="0" />
196 <Key Name="currentPermissions" Value="2147483647" />
197 <Key Name="nextPermissions" Value="2147483647" />
198 <Key Name="everyonePermissions" Value="2147483647" />
199 <Key Name="basePermissions" Value="2147483647" />
200 </Section> 153 </Section>
154
201 <Section Name="gravel Texture"> 155 <Section Name="gravel Texture">
202 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001014" /> 156 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001014" />
203 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001014" /> 157 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001014" />
@@ -206,11 +160,8 @@
206 <Key Name="name" Value="gravel" /> 160 <Key Name="name" Value="gravel" />
207 <Key Name="assetType" Value="0" /> 161 <Key Name="assetType" Value="0" />
208 <Key Name="inventoryType" Value="0" /> 162 <Key Name="inventoryType" Value="0" />
209 <Key Name="currentPermissions" Value="2147483647" />
210 <Key Name="nextPermissions" Value="2147483647" />
211 <Key Name="everyonePermissions" Value="2147483647" />
212 <Key Name="basePermissions" Value="2147483647" />
213 </Section> 163 </Section>
164
214 <Section Name="greybrick Texture"> 165 <Section Name="greybrick Texture">
215 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001015" /> 166 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001015" />
216 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001015" /> 167 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001015" />
@@ -219,11 +170,8 @@
219 <Key Name="name" Value="greybrick" /> 170 <Key Name="name" Value="greybrick" />
220 <Key Name="assetType" Value="0" /> 171 <Key Name="assetType" Value="0" />
221 <Key Name="inventoryType" Value="0" /> 172 <Key Name="inventoryType" Value="0" />
222 <Key Name="currentPermissions" Value="2147483647" />
223 <Key Name="nextPermissions" Value="2147483647" />
224 <Key Name="everyonePermissions" Value="2147483647" />
225 <Key Name="basePermissions" Value="2147483647" />
226 </Section> 173 </Section>
174
227 <Section Name="ivy Texture"> 175 <Section Name="ivy Texture">
228 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001016" /> 176 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001016" />
229 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001016" /> 177 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001016" />
@@ -232,11 +180,8 @@
232 <Key Name="name" Value="ivy" /> 180 <Key Name="name" Value="ivy" />
233 <Key Name="assetType" Value="0" /> 181 <Key Name="assetType" Value="0" />
234 <Key Name="inventoryType" Value="0" /> 182 <Key Name="inventoryType" Value="0" />
235 <Key Name="currentPermissions" Value="2147483647" />
236 <Key Name="nextPermissions" Value="2147483647" />
237 <Key Name="everyonePermissions" Value="2147483647" />
238 <Key Name="basePermissions" Value="2147483647" />
239 </Section> 183 </Section>
184
240 <Section Name="mahogany Texture"> 185 <Section Name="mahogany Texture">
241 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001017" /> 186 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001017" />
242 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001017" /> 187 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001017" />
@@ -245,11 +190,8 @@
245 <Key Name="name" Value="mahogany" /> 190 <Key Name="name" Value="mahogany" />
246 <Key Name="assetType" Value="0" /> 191 <Key Name="assetType" Value="0" />
247 <Key Name="inventoryType" Value="0" /> 192 <Key Name="inventoryType" Value="0" />
248 <Key Name="currentPermissions" Value="2147483647" />
249 <Key Name="nextPermissions" Value="2147483647" />
250 <Key Name="everyonePermissions" Value="2147483647" />
251 <Key Name="basePermissions" Value="2147483647" />
252 </Section> 193 </Section>
194
253 <Section Name="maple Texture"> 195 <Section Name="maple Texture">
254 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001018" /> 196 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001018" />
255 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001018" /> 197 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001018" />
@@ -258,11 +200,8 @@
258 <Key Name="name" Value="maple" /> 200 <Key Name="name" Value="maple" />
259 <Key Name="assetType" Value="0" /> 201 <Key Name="assetType" Value="0" />
260 <Key Name="inventoryType" Value="0" /> 202 <Key Name="inventoryType" Value="0" />
261 <Key Name="currentPermissions" Value="2147483647" />
262 <Key Name="nextPermissions" Value="2147483647" />
263 <Key Name="everyonePermissions" Value="2147483647" />
264 <Key Name="basePermissions" Value="2147483647" />
265 </Section> 203 </Section>
204
266 <Section Name="mosaic02 Texture"> 205 <Section Name="mosaic02 Texture">
267 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001019" /> 206 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001019" />
268 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001019" /> 207 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001019" />
@@ -271,11 +210,8 @@
271 <Key Name="name" Value="mosaic02" /> 210 <Key Name="name" Value="mosaic02" />
272 <Key Name="assetType" Value="0" /> 211 <Key Name="assetType" Value="0" />
273 <Key Name="inventoryType" Value="0" /> 212 <Key Name="inventoryType" Value="0" />
274 <Key Name="currentPermissions" Value="2147483647" />
275 <Key Name="nextPermissions" Value="2147483647" />
276 <Key Name="everyonePermissions" Value="2147483647" />
277 <Key Name="basePermissions" Value="2147483647" />
278 </Section> 213 </Section>
214
279 <Section Name="palm1 Texture"> 215 <Section Name="palm1 Texture">
280 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001020" /> 216 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001020" />
281 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001020" /> 217 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001020" />
@@ -284,11 +220,8 @@
284 <Key Name="name" Value="palm1" /> 220 <Key Name="name" Value="palm1" />
285 <Key Name="assetType" Value="0" /> 221 <Key Name="assetType" Value="0" />
286 <Key Name="inventoryType" Value="0" /> 222 <Key Name="inventoryType" Value="0" />
287 <Key Name="currentPermissions" Value="2147483647" />
288 <Key Name="nextPermissions" Value="2147483647" />
289 <Key Name="everyonePermissions" Value="2147483647" />
290 <Key Name="basePermissions" Value="2147483647" />
291 </Section> 223 </Section>
224
292 <Section Name="papaya Texture"> 225 <Section Name="papaya Texture">
293 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001021" /> 226 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001021" />
294 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001021" /> 227 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001021" />
@@ -297,11 +230,8 @@
297 <Key Name="name" Value="papaya" /> 230 <Key Name="name" Value="papaya" />
298 <Key Name="assetType" Value="0" /> 231 <Key Name="assetType" Value="0" />
299 <Key Name="inventoryType" Value="0" /> 232 <Key Name="inventoryType" Value="0" />
300 <Key Name="currentPermissions" Value="2147483647" />
301 <Key Name="nextPermissions" Value="2147483647" />
302 <Key Name="everyonePermissions" Value="2147483647" />
303 <Key Name="basePermissions" Value="2147483647" />
304 </Section> 233 </Section>
234
305 <Section Name="papaya_bark Texture"> 235 <Section Name="papaya_bark Texture">
306 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001022" /> 236 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001022" />
307 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001022" /> 237 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001022" />
@@ -310,11 +240,8 @@
310 <Key Name="name" Value="papaya_bark" /> 240 <Key Name="name" Value="papaya_bark" />
311 <Key Name="assetType" Value="0" /> 241 <Key Name="assetType" Value="0" />
312 <Key Name="inventoryType" Value="0" /> 242 <Key Name="inventoryType" Value="0" />
313 <Key Name="currentPermissions" Value="2147483647" />
314 <Key Name="nextPermissions" Value="2147483647" />
315 <Key Name="everyonePermissions" Value="2147483647" />
316 <Key Name="basePermissions" Value="2147483647" />
317 </Section> 243 </Section>
244
318 <Section Name="pastelbrick Texture"> 245 <Section Name="pastelbrick Texture">
319 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001023" /> 246 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001023" />
320 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001023" /> 247 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001023" />
@@ -323,11 +250,8 @@
323 <Key Name="name" Value="pastelbrick" /> 250 <Key Name="name" Value="pastelbrick" />
324 <Key Name="assetType" Value="0" /> 251 <Key Name="assetType" Value="0" />
325 <Key Name="inventoryType" Value="0" /> 252 <Key Name="inventoryType" Value="0" />
326 <Key Name="currentPermissions" Value="2147483647" />
327 <Key Name="nextPermissions" Value="2147483647" />
328 <Key Name="everyonePermissions" Value="2147483647" />
329 <Key Name="basePermissions" Value="2147483647" />
330 </Section> 253 </Section>
254
331 <Section Name="pine1_10m Texture"> 255 <Section Name="pine1_10m Texture">
332 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001024" /> 256 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001024" />
333 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001024" /> 257 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001024" />
@@ -336,11 +260,8 @@
336 <Key Name="name" Value="pine1_10m" /> 260 <Key Name="name" Value="pine1_10m" />
337 <Key Name="assetType" Value="0" /> 261 <Key Name="assetType" Value="0" />
338 <Key Name="inventoryType" Value="0" /> 262 <Key Name="inventoryType" Value="0" />
339 <Key Name="currentPermissions" Value="2147483647" />
340 <Key Name="nextPermissions" Value="2147483647" />
341 <Key Name="everyonePermissions" Value="2147483647" />
342 <Key Name="basePermissions" Value="2147483647" />
343 </Section> 263 </Section>
264
344 <Section Name="poplar Texture"> 265 <Section Name="poplar Texture">
345 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001025" /> 266 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001025" />
346 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001025" /> 267 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001025" />
@@ -349,11 +270,8 @@
349 <Key Name="name" Value="poplar" /> 270 <Key Name="name" Value="poplar" />
350 <Key Name="assetType" Value="0" /> 271 <Key Name="assetType" Value="0" />
351 <Key Name="inventoryType" Value="0" /> 272 <Key Name="inventoryType" Value="0" />
352 <Key Name="currentPermissions" Value="2147483647" />
353 <Key Name="nextPermissions" Value="2147483647" />
354 <Key Name="everyonePermissions" Value="2147483647" />
355 <Key Name="basePermissions" Value="2147483647" />
356 </Section> 273 </Section>
274
357 <Section Name="redtri_tile Texture"> 275 <Section Name="redtri_tile Texture">
358 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001026" /> 276 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001026" />
359 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001026" /> 277 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001026" />
@@ -362,11 +280,8 @@
362 <Key Name="name" Value="redtri_tile" /> 280 <Key Name="name" Value="redtri_tile" />
363 <Key Name="assetType" Value="0" /> 281 <Key Name="assetType" Value="0" />
364 <Key Name="inventoryType" Value="0" /> 282 <Key Name="inventoryType" Value="0" />
365 <Key Name="currentPermissions" Value="2147483647" />
366 <Key Name="nextPermissions" Value="2147483647" />
367 <Key Name="everyonePermissions" Value="2147483647" />
368 <Key Name="basePermissions" Value="2147483647" />
369 </Section> 283 </Section>
284
370 <Section Name="rockbuilding Texture"> 285 <Section Name="rockbuilding Texture">
371 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001027" /> 286 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001027" />
372 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001027" /> 287 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001027" />
@@ -375,11 +290,8 @@
375 <Key Name="name" Value="rockbuilding" /> 290 <Key Name="name" Value="rockbuilding" />
376 <Key Name="assetType" Value="0" /> 291 <Key Name="assetType" Value="0" />
377 <Key Name="inventoryType" Value="0" /> 292 <Key Name="inventoryType" Value="0" />
378 <Key Name="currentPermissions" Value="2147483647" />
379 <Key Name="nextPermissions" Value="2147483647" />
380 <Key Name="everyonePermissions" Value="2147483647" />
381 <Key Name="basePermissions" Value="2147483647" />
382 </Section> 293 </Section>
294
383 <Section Name="rockwallbig Texture"> 295 <Section Name="rockwallbig Texture">
384 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001028" /> 296 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001028" />
385 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001028" /> 297 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001028" />
@@ -388,11 +300,8 @@
388 <Key Name="name" Value="rockwallbig" /> 300 <Key Name="name" Value="rockwallbig" />
389 <Key Name="assetType" Value="0" /> 301 <Key Name="assetType" Value="0" />
390 <Key Name="inventoryType" Value="0" /> 302 <Key Name="inventoryType" Value="0" />
391 <Key Name="currentPermissions" Value="2147483647" />
392 <Key Name="nextPermissions" Value="2147483647" />
393 <Key Name="everyonePermissions" Value="2147483647" />
394 <Key Name="basePermissions" Value="2147483647" />
395 </Section> 303 </Section>
304
396 <Section Name="roof01 Texture"> 305 <Section Name="roof01 Texture">
397 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001029" /> 306 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001029" />
398 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001029" /> 307 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001029" />
@@ -401,11 +310,8 @@
401 <Key Name="name" Value="roof01" /> 310 <Key Name="name" Value="roof01" />
402 <Key Name="assetType" Value="0" /> 311 <Key Name="assetType" Value="0" />
403 <Key Name="inventoryType" Value="0" /> 312 <Key Name="inventoryType" Value="0" />
404 <Key Name="currentPermissions" Value="2147483647" />
405 <Key Name="nextPermissions" Value="2147483647" />
406 <Key Name="everyonePermissions" Value="2147483647" />
407 <Key Name="basePermissions" Value="2147483647" />
408 </Section> 313 </Section>
314
409 <Section Name="rooftiles1 Texture"> 315 <Section Name="rooftiles1 Texture">
410 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001030" /> 316 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001030" />
411 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001030" /> 317 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001030" />
@@ -414,11 +320,8 @@
414 <Key Name="name" Value="rooftiles1" /> 320 <Key Name="name" Value="rooftiles1" />
415 <Key Name="assetType" Value="0" /> 321 <Key Name="assetType" Value="0" />
416 <Key Name="inventoryType" Value="0" /> 322 <Key Name="inventoryType" Value="0" />
417 <Key Name="currentPermissions" Value="2147483647" />
418 <Key Name="nextPermissions" Value="2147483647" />
419 <Key Name="everyonePermissions" Value="2147483647" />
420 <Key Name="basePermissions" Value="2147483647" />
421 </Section> 323 </Section>
324
422 <Section Name="rooftiles2_peach Texture"> 325 <Section Name="rooftiles2_peach Texture">
423 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001031" /> 326 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001031" />
424 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001031" /> 327 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001031" />
@@ -427,11 +330,8 @@
427 <Key Name="name" Value="rooftiles2_peach" /> 330 <Key Name="name" Value="rooftiles2_peach" />
428 <Key Name="assetType" Value="0" /> 331 <Key Name="assetType" Value="0" />
429 <Key Name="inventoryType" Value="0" /> 332 <Key Name="inventoryType" Value="0" />
430 <Key Name="currentPermissions" Value="2147483647" />
431 <Key Name="nextPermissions" Value="2147483647" />
432 <Key Name="everyonePermissions" Value="2147483647" />
433 <Key Name="basePermissions" Value="2147483647" />
434 </Section> 333 </Section>
334
435 <Section Name="rooftiles2_roy Texture"> 335 <Section Name="rooftiles2_roy Texture">
436 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001032" /> 336 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001032" />
437 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001032" /> 337 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001032" />
@@ -440,11 +340,8 @@
440 <Key Name="name" Value="rooftiles2_roy" /> 340 <Key Name="name" Value="rooftiles2_roy" />
441 <Key Name="assetType" Value="0" /> 341 <Key Name="assetType" Value="0" />
442 <Key Name="inventoryType" Value="0" /> 342 <Key Name="inventoryType" Value="0" />
443 <Key Name="currentPermissions" Value="2147483647" />
444 <Key Name="nextPermissions" Value="2147483647" />
445 <Key Name="everyonePermissions" Value="2147483647" />
446 <Key Name="basePermissions" Value="2147483647" />
447 </Section> 343 </Section>
344
448 <Section Name="saguaro_8m Texture"> 345 <Section Name="saguaro_8m Texture">
449 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001033" /> 346 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001033" />
450 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001033" /> 347 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001033" />
@@ -453,11 +350,8 @@
453 <Key Name="name" Value="saguaro_8m" /> 350 <Key Name="name" Value="saguaro_8m" />
454 <Key Name="assetType" Value="0" /> 351 <Key Name="assetType" Value="0" />
455 <Key Name="inventoryType" Value="0" /> 352 <Key Name="inventoryType" Value="0" />
456 <Key Name="currentPermissions" Value="2147483647" />
457 <Key Name="nextPermissions" Value="2147483647" />
458 <Key Name="everyonePermissions" Value="2147483647" />
459 <Key Name="basePermissions" Value="2147483647" />
460 </Section> 353 </Section>
354
461 <Section Name="seawater Texture"> 355 <Section Name="seawater Texture">
462 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001034" /> 356 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001034" />
463 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001034" /> 357 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001034" />
@@ -466,11 +360,8 @@
466 <Key Name="name" Value="seawater" /> 360 <Key Name="name" Value="seawater" />
467 <Key Name="assetType" Value="0" /> 361 <Key Name="assetType" Value="0" />
468 <Key Name="inventoryType" Value="0" /> 362 <Key Name="inventoryType" Value="0" />
469 <Key Name="currentPermissions" Value="2147483647" />
470 <Key Name="nextPermissions" Value="2147483647" />
471 <Key Name="everyonePermissions" Value="2147483647" />
472 <Key Name="basePermissions" Value="2147483647" />
473 </Section> 363 </Section>
364
474 <Section Name="snow1 Texture"> 365 <Section Name="snow1 Texture">
475 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001035" /> 366 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001035" />
476 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001035" /> 367 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001035" />
@@ -479,11 +370,8 @@
479 <Key Name="name" Value="snow1" /> 370 <Key Name="name" Value="snow1" />
480 <Key Name="assetType" Value="0" /> 371 <Key Name="assetType" Value="0" />
481 <Key Name="inventoryType" Value="0" /> 372 <Key Name="inventoryType" Value="0" />
482 <Key Name="currentPermissions" Value="2147483647" />
483 <Key Name="nextPermissions" Value="2147483647" />
484 <Key Name="everyonePermissions" Value="2147483647" />
485 <Key Name="basePermissions" Value="2147483647" />
486 </Section> 373 </Section>
374
487 <Section Name="steel Texture"> 375 <Section Name="steel Texture">
488 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001036" /> 376 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001036" />
489 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001036" /> 377 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001036" />
@@ -492,11 +380,8 @@
492 <Key Name="name" Value="steel" /> 380 <Key Name="name" Value="steel" />
493 <Key Name="assetType" Value="0" /> 381 <Key Name="assetType" Value="0" />
494 <Key Name="inventoryType" Value="0" /> 382 <Key Name="inventoryType" Value="0" />
495 <Key Name="currentPermissions" Value="2147483647" />
496 <Key Name="nextPermissions" Value="2147483647" />
497 <Key Name="everyonePermissions" Value="2147483647" />
498 <Key Name="basePermissions" Value="2147483647" />
499 </Section> 383 </Section>
384
500 <Section Name="stone1wall Texture"> 385 <Section Name="stone1wall Texture">
501 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001037" /> 386 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001037" />
502 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001037" /> 387 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001037" />
@@ -505,11 +390,8 @@
505 <Key Name="name" Value="stone1wall" /> 390 <Key Name="name" Value="stone1wall" />
506 <Key Name="assetType" Value="0" /> 391 <Key Name="assetType" Value="0" />
507 <Key Name="inventoryType" Value="0" /> 392 <Key Name="inventoryType" Value="0" />
508 <Key Name="currentPermissions" Value="2147483647" />
509 <Key Name="nextPermissions" Value="2147483647" />
510 <Key Name="everyonePermissions" Value="2147483647" />
511 <Key Name="basePermissions" Value="2147483647" />
512 </Section> 393 </Section>
394
513 <Section Name="stonetile Texture"> 395 <Section Name="stonetile Texture">
514 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001038" /> 396 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001038" />
515 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001038" /> 397 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001038" />
@@ -518,11 +400,8 @@
518 <Key Name="name" Value="stonetile" /> 400 <Key Name="name" Value="stonetile" />
519 <Key Name="assetType" Value="0" /> 401 <Key Name="assetType" Value="0" />
520 <Key Name="inventoryType" Value="0" /> 402 <Key Name="inventoryType" Value="0" />
521 <Key Name="currentPermissions" Value="2147483647" />
522 <Key Name="nextPermissions" Value="2147483647" />
523 <Key Name="everyonePermissions" Value="2147483647" />
524 <Key Name="basePermissions" Value="2147483647" />
525 </Section> 403 </Section>
404
526 <Section Name="street2 Texture"> 405 <Section Name="street2 Texture">
527 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001039" /> 406 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001039" />
528 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001039" /> 407 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001039" />
@@ -531,11 +410,8 @@
531 <Key Name="name" Value="street2" /> 410 <Key Name="name" Value="street2" />
532 <Key Name="assetType" Value="0" /> 411 <Key Name="assetType" Value="0" />
533 <Key Name="inventoryType" Value="0" /> 412 <Key Name="inventoryType" Value="0" />
534 <Key Name="currentPermissions" Value="2147483647" />
535 <Key Name="nextPermissions" Value="2147483647" />
536 <Key Name="everyonePermissions" Value="2147483647" />
537 <Key Name="basePermissions" Value="2147483647" />
538 </Section> 413 </Section>
414
539 <Section Name="thatch Texture"> 415 <Section Name="thatch Texture">
540 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001040" /> 416 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001040" />
541 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001040" /> 417 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001040" />
@@ -544,11 +420,8 @@
544 <Key Name="name" Value="thatch" /> 420 <Key Name="name" Value="thatch" />
545 <Key Name="assetType" Value="0" /> 421 <Key Name="assetType" Value="0" />
546 <Key Name="inventoryType" Value="0" /> 422 <Key Name="inventoryType" Value="0" />
547 <Key Name="currentPermissions" Value="2147483647" />
548 <Key Name="nextPermissions" Value="2147483647" />
549 <Key Name="everyonePermissions" Value="2147483647" />
550 <Key Name="basePermissions" Value="2147483647" />
551 </Section> 423 </Section>
424
552 <Section Name="water1 Texture"> 425 <Section Name="water1 Texture">
553 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001041" /> 426 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001041" />
554 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001041" /> 427 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001041" />
@@ -557,11 +430,8 @@
557 <Key Name="name" Value="water1" /> 430 <Key Name="name" Value="water1" />
558 <Key Name="assetType" Value="0" /> 431 <Key Name="assetType" Value="0" />
559 <Key Name="inventoryType" Value="0" /> 432 <Key Name="inventoryType" Value="0" />
560 <Key Name="currentPermissions" Value="2147483647" />
561 <Key Name="nextPermissions" Value="2147483647" />
562 <Key Name="everyonePermissions" Value="2147483647" />
563 <Key Name="basePermissions" Value="2147483647" />
564 </Section> 433 </Section>
434
565 <Section Name="water3 Texture"> 435 <Section Name="water3 Texture">
566 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001042" /> 436 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001042" />
567 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001042" /> 437 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001042" />
@@ -570,11 +440,8 @@
570 <Key Name="name" Value="water3" /> 440 <Key Name="name" Value="water3" />
571 <Key Name="assetType" Value="0" /> 441 <Key Name="assetType" Value="0" />
572 <Key Name="inventoryType" Value="0" /> 442 <Key Name="inventoryType" Value="0" />
573 <Key Name="currentPermissions" Value="2147483647" />
574 <Key Name="nextPermissions" Value="2147483647" />
575 <Key Name="everyonePermissions" Value="2147483647" />
576 <Key Name="basePermissions" Value="2147483647" />
577 </Section> 443 </Section>
444
578 <Section Name="wood1 Texture"> 445 <Section Name="wood1 Texture">
579 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001043" /> 446 <Key Name="inventoryID" Value="00000000-0000-2222-4444-100000001043" />
580 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001043" /> 447 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001043" />
@@ -583,11 +450,8 @@
583 <Key Name="name" Value="wood1" /> 450 <Key Name="name" Value="wood1" />
584 <Key Name="assetType" Value="0" /> 451 <Key Name="assetType" Value="0" />
585 <Key Name="inventoryType" Value="0" /> 452 <Key Name="inventoryType" Value="0" />
586 <Key Name="currentPermissions" Value="2147483647" />
587 <Key Name="nextPermissions" Value="2147483647" />
588 <Key Name="everyonePermissions" Value="2147483647" />
589 <Key Name="basePermissions" Value="2147483647" />
590 </Section> 453 </Section>
454
591 <Section Name="bricks Texture"> 455 <Section Name="bricks Texture">
592 <Key Name="inventoryID" Value="00000000-0000-2222-9999-000000000001"/> 456 <Key Name="inventoryID" Value="00000000-0000-2222-9999-000000000001"/>
593 <Key Name="assetID" Value="00000000-0000-1111-9999-000000000001"/> 457 <Key Name="assetID" Value="00000000-0000-1111-9999-000000000001"/>
@@ -596,11 +460,8 @@
596 <Key Name="name" Value="bricks" /> 460 <Key Name="name" Value="bricks" />
597 <Key Name="assetType" Value="0" /> 461 <Key Name="assetType" Value="0" />
598 <Key Name="inventoryType" Value="0" /> 462 <Key Name="inventoryType" Value="0" />
599 <Key Name="currentPermissions" Value="2147483647" />
600 <Key Name="nextPermissions" Value="2147483647" />
601 <Key Name="everyonePermissions" Value="2147483647" />
602 <Key Name="basePermissions" Value="2147483647" />
603 </Section> 463 </Section>
464
604 <Section Name="granite Texture"> 465 <Section Name="granite Texture">
605 <Key Name="inventoryID" Value="00000000-0000-2222-9999-000000000004"/> 466 <Key Name="inventoryID" Value="00000000-0000-2222-9999-000000000004"/>
606 <Key Name="assetID" Value="00000000-0000-1111-9999-000000000004"/> 467 <Key Name="assetID" Value="00000000-0000-1111-9999-000000000004"/>
@@ -609,11 +470,8 @@
609 <Key Name="name" Value="granite" /> 470 <Key Name="name" Value="granite" />
610 <Key Name="assetType" Value="0" /> 471 <Key Name="assetType" Value="0" />
611 <Key Name="inventoryType" Value="0" /> 472 <Key Name="inventoryType" Value="0" />
612 <Key Name="currentPermissions" Value="2147483647" />
613 <Key Name="nextPermissions" Value="2147483647" />
614 <Key Name="everyonePermissions" Value="2147483647" />
615 <Key Name="basePermissions" Value="2147483647" />
616 </Section> 473 </Section>
474
617 <Section Name="hardwood Texture"> 475 <Section Name="hardwood Texture">
618 <Key Name="inventoryID" Value="00000000-0000-2222-9999-000000000005"/> 476 <Key Name="inventoryID" Value="00000000-0000-2222-9999-000000000005"/>
619 <Key Name="assetID" Value="00000000-0000-1111-9999-000000000005"/> 477 <Key Name="assetID" Value="00000000-0000-1111-9999-000000000005"/>
@@ -622,11 +480,8 @@
622 <Key Name="name" Value="hardwood" /> 480 <Key Name="name" Value="hardwood" />
623 <Key Name="assetType" Value="0" /> 481 <Key Name="assetType" Value="0" />
624 <Key Name="inventoryType" Value="0" /> 482 <Key Name="inventoryType" Value="0" />
625 <Key Name="currentPermissions" Value="2147483647" />
626 <Key Name="nextPermissions" Value="2147483647" />
627 <Key Name="everyonePermissions" Value="2147483647" />
628 <Key Name="basePermissions" Value="2147483647" />
629 </Section> 483 </Section>
484
630 <Section Name="rocks Texture"> 485 <Section Name="rocks Texture">
631 <Key Name="inventoryID" Value="00000000-0000-2222-9999-000000000003"/> 486 <Key Name="inventoryID" Value="00000000-0000-2222-9999-000000000003"/>
632 <Key Name="assetID" Value="00000000-0000-1111-9999-000000000003"/> 487 <Key Name="assetID" Value="00000000-0000-1111-9999-000000000003"/>
@@ -635,10 +490,6 @@
635 <Key Name="name" Value="rocks" /> 490 <Key Name="name" Value="rocks" />
636 <Key Name="assetType" Value="0" /> 491 <Key Name="assetType" Value="0" />
637 <Key Name="inventoryType" Value="0" /> 492 <Key Name="inventoryType" Value="0" />
638 <Key Name="currentPermissions" Value="2147483647" />
639 <Key Name="nextPermissions" Value="2147483647" />
640 <Key Name="everyonePermissions" Value="2147483647" />
641 <Key Name="basePermissions" Value="2147483647" />
642 </Section> 493 </Section>
643 494
644 <Section Name="Terrain Dirt"> 495 <Section Name="Terrain Dirt">
@@ -649,11 +500,8 @@
649 <Key Name="name" Value="Terrain Dirt" /> 500 <Key Name="name" Value="Terrain Dirt" />
650 <Key Name="assetType" Value="0" /> 501 <Key Name="assetType" Value="0" />
651 <Key Name="inventoryType" Value="0" /> 502 <Key Name="inventoryType" Value="0" />
652 <Key Name="currentPermissions" Value="2147483647" />
653 <Key Name="nextPermissions" Value="2147483647" />
654 <Key Name="everyonePermissions" Value="2147483647" />
655 <Key Name="basePermissions" Value="2147483647" />
656 </Section> 503 </Section>
504
657 <Section Name="Terrain Grass"> 505 <Section Name="Terrain Grass">
658 <Key Name="inventoryID" Value="00000000-0000-2222-9999-000000000007"/> 506 <Key Name="inventoryID" Value="00000000-0000-2222-9999-000000000007"/>
659 <Key Name="assetID" Value="abb783e6-3e93-26c0-248a-247666855da3"/> 507 <Key Name="assetID" Value="abb783e6-3e93-26c0-248a-247666855da3"/>
@@ -662,11 +510,8 @@
662 <Key Name="name" Value="Terrain Grass" /> 510 <Key Name="name" Value="Terrain Grass" />
663 <Key Name="assetType" Value="0" /> 511 <Key Name="assetType" Value="0" />
664 <Key Name="inventoryType" Value="0" /> 512 <Key Name="inventoryType" Value="0" />
665 <Key Name="currentPermissions" Value="2147483647" />
666 <Key Name="nextPermissions" Value="2147483647" />
667 <Key Name="everyonePermissions" Value="2147483647" />
668 <Key Name="basePermissions" Value="2147483647" />
669 </Section> 513 </Section>
514
670 <Section Name="Terrain Mountain"> 515 <Section Name="Terrain Mountain">
671 <Key Name="inventoryID" Value="00000000-0000-2222-9999-000000000008"/> 516 <Key Name="inventoryID" Value="00000000-0000-2222-9999-000000000008"/>
672 <Key Name="assetID" Value="179cdabd-398a-9b6b-1391-4dc333ba321f"/> 517 <Key Name="assetID" Value="179cdabd-398a-9b6b-1391-4dc333ba321f"/>
@@ -675,11 +520,8 @@
675 <Key Name="name" Value="Terrain Mountain" /> 520 <Key Name="name" Value="Terrain Mountain" />
676 <Key Name="assetType" Value="0" /> 521 <Key Name="assetType" Value="0" />
677 <Key Name="inventoryType" Value="0" /> 522 <Key Name="inventoryType" Value="0" />
678 <Key Name="currentPermissions" Value="2147483647" />
679 <Key Name="nextPermissions" Value="2147483647" />
680 <Key Name="everyonePermissions" Value="2147483647" />
681 <Key Name="basePermissions" Value="2147483647" />
682 </Section> 523 </Section>
524
683 <Section Name="Terrain Rock"> 525 <Section Name="Terrain Rock">
684 <Key Name="inventoryID" Value="00000000-0000-2222-9999-000000000009"/> 526 <Key Name="inventoryID" Value="00000000-0000-2222-9999-000000000009"/>
685 <Key Name="assetID" Value="beb169c7-11ea-fff2-efe5-0f24dc881df2"/> 527 <Key Name="assetID" Value="beb169c7-11ea-fff2-efe5-0f24dc881df2"/>
@@ -688,10 +530,6 @@
688 <Key Name="name" Value="Terrain Rock" /> 530 <Key Name="name" Value="Terrain Rock" />
689 <Key Name="assetType" Value="0" /> 531 <Key Name="assetType" Value="0" />
690 <Key Name="inventoryType" Value="0" /> 532 <Key Name="inventoryType" Value="0" />
691 <Key Name="currentPermissions" Value="2147483647" />
692 <Key Name="nextPermissions" Value="2147483647" />
693 <Key Name="everyonePermissions" Value="2147483647" />
694 <Key Name="basePermissions" Value="2147483647" />
695 </Section> 533 </Section>
696 534
697 <Section Name="Blank Texture"> 535 <Section Name="Blank Texture">
@@ -702,10 +540,6 @@
702 <Key Name="name" Value="Blank Texture" /> 540 <Key Name="name" Value="Blank Texture" />
703 <Key Name="assetType" Value="0" /> 541 <Key Name="assetType" Value="0" />
704 <Key Name="inventoryType" Value="0" /> 542 <Key Name="inventoryType" Value="0" />
705 <Key Name="currentPermissions" Value="2147483647" />
706 <Key Name="nextPermissions" Value="2147483647" />
707 <Key Name="everyonePermissions" Value="2147483647" />
708 <Key Name="basePermissions" Value="2147483647" />
709 </Section> 543 </Section>
710 544
711 <Section Name="Default Media Texture"> 545 <Section Name="Default Media Texture">
@@ -716,10 +550,6 @@
716 <Key Name="name" Value="Default Media Texture" /> 550 <Key Name="name" Value="Default Media Texture" />
717 <Key Name="assetType" Value="0" /> 551 <Key Name="assetType" Value="0" />
718 <Key Name="inventoryType" Value="0" /> 552 <Key Name="inventoryType" Value="0" />
719 <Key Name="currentPermissions" Value="2147483647" />
720 <Key Name="nextPermissions" Value="2147483647" />
721 <Key Name="everyonePermissions" Value="2147483647" />
722 <Key Name="basePermissions" Value="2147483647" />
723 </Section> 553 </Section>
724 554
725 <Section Name="Default Transparent Texture"> 555 <Section Name="Default Transparent Texture">
@@ -730,9 +560,5 @@
730 <Key Name="name" Value="Default Transparent Texture" /> 560 <Key Name="name" Value="Default Transparent Texture" />
731 <Key Name="assetType" Value="0" /> 561 <Key Name="assetType" Value="0" />
732 <Key Name="inventoryType" Value="0" /> 562 <Key Name="inventoryType" Value="0" />
733 <Key Name="currentPermissions" Value="2147483647" />
734 <Key Name="nextPermissions" Value="2147483647" />
735 <Key Name="everyonePermissions" Value="2147483647" />
736 <Key Name="basePermissions" Value="2147483647" />
737 </Section> 563 </Section>
738</Nini> 564</Nini>
diff --git a/bin/libBulletSim-x86_64.so b/bin/libBulletSim-x86_64.so
new file mode 100755
index 0000000..cd2db40
--- /dev/null
+++ b/bin/libBulletSim-x86_64.so
Binary files differ
diff --git a/bin/libBulletSim.so b/bin/libBulletSim.so
new file mode 100755
index 0000000..44afb5e
--- /dev/null
+++ b/bin/libBulletSim.so
Binary files differ
diff --git a/bin/protobuf-net.pdb b/bin/protobuf-net.pdb
deleted file mode 100644
index 9c85bdc..0000000
--- a/bin/protobuf-net.pdb
+++ /dev/null
Binary files differ
diff --git a/prebuild.xml b/prebuild.xml
index 6362848..0dd599d 100644
--- a/prebuild.xml
+++ b/prebuild.xml
@@ -631,6 +631,64 @@
631 </Files> 631 </Files>
632 </Project> 632 </Project>
633 633
634 <Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.ConvexDecompositionDotNet" path="OpenSim/Region/Physics/ConvexDecompositionDotNet" type="Library">
635 <Configuration name="Debug">
636 <Options>
637 <OutputPath>../../../../bin/</OutputPath>
638 </Options>
639 </Configuration>
640 <Configuration name="Release">
641 <Options>
642 <OutputPath>../../../../bin/</OutputPath>
643 </Options>
644 </Configuration>
645
646 <ReferencePath>../../../../bin/</ReferencePath>
647 <Reference name="System"/>
648 <Reference name="System.Core"/>
649 <Reference name="System.Data"/>
650 <Reference name="System.Xml"/>
651
652 <Files>
653 <Match pattern="*.cs" recurse="true">
654 <Exclude name="Tests" pattern="Tests"/>
655 </Match>
656 </Files>
657 </Project>
658
659 <Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.BulletSPlugin" path="OpenSim/Region/Physics/BulletSPlugin" type="Library">
660 <Configuration name="Debug">
661 <Options>
662 <OutputPath>../../../../bin/Physics/</OutputPath>
663 </Options>
664 </Configuration>
665 <Configuration name="Release">
666 <Options>
667 <OutputPath>../../../../bin/Physics/</OutputPath>
668 </Options>
669 </Configuration>
670
671 <ReferencePath>../../../../bin/</ReferencePath>
672 <Reference name="System"/>
673 <Reference name="System.Core"/>
674 <Reference name="System.Xml"/>
675 <Reference name="OpenMetaverseTypes" path="../../../../bin/"/>
676 <Reference name="Nini.dll" path="../../../../bin/"/>
677 <Reference name="OpenSim.Framework"/>
678 <Reference name="OpenSim.Region.Framework"/>
679 <Reference name="OpenSim.Region.CoreModules"/>
680 <Reference name="OpenSim.Framework.Console"/>
681 <Reference name="OpenSim.Region.Physics.Manager"/>
682 <Reference name="OpenSim.Region.Physics.ConvexDecompositionDotNet"/>
683 <Reference name="log4net.dll" path="../../../../bin/"/>
684
685 <Files>
686 <Match pattern="*.cs" recurse="true">
687 <Exclude name="Tests" pattern="Tests"/>
688 </Match>
689 </Files>
690 </Project>
691
634 <Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.Meshing" path="OpenSim/Region/Physics/Meshing" type="Library"> 692 <Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.Meshing" path="OpenSim/Region/Physics/Meshing" type="Library">
635 <Configuration name="Debug"> 693 <Configuration name="Debug">
636 <Options> 694 <Options>
@@ -1711,6 +1769,7 @@
1711 1769
1712 <ReferencePath>../../../bin/</ReferencePath> 1770 <ReferencePath>../../../bin/</ReferencePath>
1713 <Reference name="System"/> 1771 <Reference name="System"/>
1772 <Reference name="System.Core"/>
1714 <Reference name="System.Xml"/> 1773 <Reference name="System.Xml"/>
1715 <Reference name="System.Drawing"/> 1774 <Reference name="System.Drawing"/>
1716 <Reference name="System.Web"/> 1775 <Reference name="System.Web"/>
@@ -2094,6 +2153,7 @@
2094 <Reference name="OpenMetaverseTypes" path="../../../../bin/"/> 2153 <Reference name="OpenMetaverseTypes" path="../../../../bin/"/>
2095 <Reference name="OpenMetaverse" path="../../../../bin/"/> 2154 <Reference name="OpenMetaverse" path="../../../../bin/"/>
2096 <Reference name="System"/> 2155 <Reference name="System"/>
2156 <Reference name="System.Core"/>
2097 <Reference name="OpenSim.Framework"/> 2157 <Reference name="OpenSim.Framework"/>
2098 <Reference name="OpenSim.Region.Framework"/> 2158 <Reference name="OpenSim.Region.Framework"/>
2099 <Reference name="Nini" path="../../../../bin/"/> 2159 <Reference name="Nini" path="../../../../bin/"/>
@@ -2340,6 +2400,7 @@
2340 <Reference name="System.Xml"/> 2400 <Reference name="System.Xml"/>
2341 <Reference name="OpenMetaverseTypes" path="../../../../../../bin/"/> 2401 <Reference name="OpenMetaverseTypes" path="../../../../../../bin/"/>
2342 <Reference name="OpenMetaverse" path="../../../../../../bin/"/> 2402 <Reference name="OpenMetaverse" path="../../../../../../bin/"/>
2403 <Reference name="OpenMetaverse.StructuredData" path="../../../../../../bin/"/>
2343 <Reference name="OpenSim"/> 2404 <Reference name="OpenSim"/>
2344 <Reference name="OpenSim.Framework"/> 2405 <Reference name="OpenSim.Framework"/>
2345 <Reference name="OpenSim.Framework.Communications"/> 2406 <Reference name="OpenSim.Framework.Communications"/>
@@ -2748,6 +2809,7 @@
2748 2809
2749 <ReferencePath>../../../bin/</ReferencePath> 2810 <ReferencePath>../../../bin/</ReferencePath>
2750 <Reference name="System"/> 2811 <Reference name="System"/>
2812 <Reference name="System.Core"/>
2751 <Reference name="System.Drawing"/> 2813 <Reference name="System.Drawing"/>
2752 <Reference name="System.Xml"/> 2814 <Reference name="System.Xml"/>
2753 <Reference name="System.Data"/> 2815 <Reference name="System.Data"/>
@@ -2986,6 +3048,8 @@
2986 <!-- SADLY the way this works means you need to keep adding these paths --> 3048 <!-- SADLY the way this works means you need to keep adding these paths -->
2987 <Match path="Agent/TextureSender/Tests" pattern="*.cs" recurse="true"/> 3049 <Match path="Agent/TextureSender/Tests" pattern="*.cs" recurse="true"/>
2988 <Match path="Asset/Tests" pattern="*.cs" recurse="true"/> 3050 <Match path="Asset/Tests" pattern="*.cs" recurse="true"/>
3051 <Match path="Avatar/Attachments/Tests" pattern="*.cs" recurse="true"/>
3052 <Match path="Avatar/AvatarFactory/Tests" pattern="*.cs" recurse="true"/>
2989 <Match path="Avatar/Inventory/Archiver/Tests" pattern="*.cs" recurse="true"/> 3053 <Match path="Avatar/Inventory/Archiver/Tests" pattern="*.cs" recurse="true"/>
2990 <Match path="Framework/InventoryAccess/Tests" pattern="*.cs" recurse="true"/> 3054 <Match path="Framework/InventoryAccess/Tests" pattern="*.cs" recurse="true"/>
2991 <Match path="World/Archiver/Tests" pattern="*.cs" recurse="true"/> 3055 <Match path="World/Archiver/Tests" pattern="*.cs" recurse="true"/>
@@ -3165,15 +3229,23 @@
3165 3229
3166 <ReferencePath>../../../bin/</ReferencePath> 3230 <ReferencePath>../../../bin/</ReferencePath>
3167 <Reference name="System"/> 3231 <Reference name="System"/>
3232 <Reference name="System.Xml"/>
3168 <Reference name="OpenSim.Framework"/> 3233 <Reference name="OpenSim.Framework"/>
3169 <Reference name="OpenSim.Framework.Communications"/> 3234 <Reference name="OpenSim.Framework.Communications"/>
3235 <Reference name="OpenSim.Region.CoreModules"/>
3170 <Reference name="OpenSim.Region.Framework"/> 3236 <Reference name="OpenSim.Region.Framework"/>
3237 <Reference name="OpenSim.Region.OptionalModules"/>
3171 <Reference name="OpenSim.Region.ScriptEngine.Shared"/> 3238 <Reference name="OpenSim.Region.ScriptEngine.Shared"/>
3172 <Reference name="OpenSim.Region.ScriptEngine.Shared.Api"/> 3239 <Reference name="OpenSim.Region.ScriptEngine.Shared.Api"/>
3240 <Reference name="OpenSim.Region.ScriptEngine.Shared.Api.Runtime"/>
3173 <Reference name="OpenSim.Region.ScriptEngine.XEngine"/> 3241 <Reference name="OpenSim.Region.ScriptEngine.XEngine"/>
3242 <Reference name="OpenSim.Services.Interfaces"/>
3174 <Reference name="OpenSim.Tests.Common"/> 3243 <Reference name="OpenSim.Tests.Common"/>
3244 <Reference name="log4net" path="../../../bin/"/>
3175 <Reference name="nunit.framework" path="../../../bin/"/> 3245 <Reference name="nunit.framework" path="../../../bin/"/>
3176 <Reference name="Nini" path="../../../bin/"/> 3246 <Reference name="Nini" path="../../../bin/"/>
3247 <Reference name="OpenMetaverse" path="../../../bin/"/>
3248 <Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/>
3177 <Reference name="OpenMetaverseTypes" path="../../../bin/"/> 3249 <Reference name="OpenMetaverseTypes" path="../../../bin/"/>
3178 <Reference name="OpenSim.Region.ScriptEngine.Shared.CodeTools"/> 3250 <Reference name="OpenSim.Region.ScriptEngine.Shared.CodeTools"/>
3179 <Reference name="OpenSim.Region.ScriptEngine.Shared"/> 3251 <Reference name="OpenSim.Region.ScriptEngine.Shared"/>
@@ -3197,29 +3269,30 @@
3197 TODO: this is kind of lame, we basically build a duplicate 3269 TODO: this is kind of lame, we basically build a duplicate
3198 assembly but with tests added in, just because we can't resolve cross-bin-dir-refs. 3270 assembly but with tests added in, just because we can't resolve cross-bin-dir-refs.
3199 --> 3271 -->
3200 <Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.OdePlugin.Tests" path="OpenSim/Region/Physics/OdePlugin" type="Library"> 3272 <Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.OdePlugin.Tests" path="OpenSim/Region/Physics/OdePlugin/Tests" type="Library">
3201 <Configuration name="Debug"> 3273 <Configuration name="Debug">
3202 <Options> 3274 <Options>
3203 <OutputPath>../../../../bin/</OutputPath> 3275 <OutputPath>../../../../../bin/</OutputPath>
3204 </Options> 3276 </Options>
3205 </Configuration> 3277 </Configuration>
3206 <Configuration name="Release"> 3278 <Configuration name="Release">
3207 <Options> 3279 <Options>
3208 <OutputPath>../../../../bin/</OutputPath> 3280 <OutputPath>../../../../../bin/</OutputPath>
3209 </Options> 3281 </Options>
3210 </Configuration> 3282 </Configuration>
3211 3283
3212 <ReferencePath>../../../../bin/</ReferencePath> 3284 <ReferencePath>../../../../../bin/</ReferencePath>
3213 <Reference name="System"/> 3285 <Reference name="System"/>
3214 <Reference name="System.Core"/> 3286 <Reference name="System.Core"/>
3215 <Reference name="OpenMetaverseTypes" path="../../../../bin/"/> 3287 <Reference name="OpenMetaverseTypes" path="../../../../../bin/"/>
3216 <Reference name="Nini" path="../../../../bin/"/> 3288 <Reference name="Nini" path="../../../../../bin/"/>
3217 <Reference name="OpenSim.Framework"/> 3289 <Reference name="OpenSim.Framework"/>
3218 <Reference name="OpenSim.Framework.Console"/> 3290 <Reference name="OpenSim.Framework.Console"/>
3219 <Reference name="OpenSim.Region.Physics.Manager"/> 3291 <Reference name="OpenSim.Region.Physics.Manager"/>
3220 <Reference name="Ode.NET" path="../../../../bin/"/> 3292 <Reference name="OpenSim.Region.Physics.OdePlugin" path="../../../../../bin/Physics/"/>
3221 <Reference name="nunit.framework" path="../../../../bin/"/> 3293 <Reference name="Ode.NET" path="../../../../../bin/"/>
3222 <Reference name="log4net" path="../../../../bin/"/> 3294 <Reference name="nunit.framework" path="../../../../../bin/"/>
3295 <Reference name="log4net" path="../../../../../bin/"/>
3223 3296
3224 <Files> 3297 <Files>
3225 <Match pattern="*.cs" recurse="true"/> 3298 <Match pattern="*.cs" recurse="true"/>