aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorMelanie2011-10-12 00:10:15 +0200
committerMelanie2011-10-12 00:10:15 +0200
commit1c2b5d99c9601a3d301f4bc0f53389cca831ee04 (patch)
tree97fa9c758f429d5dee64234e442f2c83cd1b9994 /OpenSim
parentMerge branch 'careminster-presence-refactor' into bigmerge (diff)
parentMerge commit '92c88121c72386f85472c6cf4891eca8b62b9867' into bigmerge (diff)
downloadopensim-SC_OLD-1c2b5d99c9601a3d301f4bc0f53389cca831ee04.zip
opensim-SC_OLD-1c2b5d99c9601a3d301f4bc0f53389cca831ee04.tar.gz
opensim-SC_OLD-1c2b5d99c9601a3d301f4bc0f53389cca831ee04.tar.bz2
opensim-SC_OLD-1c2b5d99c9601a3d301f4bc0f53389cca831ee04.tar.xz
Merge branch 'bigmerge' of ssh://3dhosting.de/var/git/careminster into bigmerge
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs30
-rw-r--r--OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs26
-rw-r--r--OpenSim/ApplicationPlugins/Rest/Inventory/tests/Remote.cs2
-rw-r--r--OpenSim/Data/MSSQL/MSSQLEstateData.cs117
-rw-r--r--OpenSim/Data/MSSQL/MSSQLUserAccountData.cs18
-rw-r--r--OpenSim/Data/MSSQL/Resources/FriendsStore.migrations28
-rw-r--r--OpenSim/Data/MSSQL/Resources/InventoryStore.migrations32
-rw-r--r--OpenSim/Data/MSSQL/Resources/OpenSim.Data.MSSQL.addin.xml23
-rw-r--r--OpenSim/Data/MySQL/MySQLEstateData.cs123
-rw-r--r--OpenSim/Data/MySQL/Resources/OpenSim.Data.MySQL.addin.xml23
-rwxr-xr-xOpenSim/Data/Null/NullEstateData.cs5
-rw-r--r--OpenSim/Data/Null/NullSimulationData.cs6
-rw-r--r--OpenSim/Data/SQLite/Resources/OpenSim.Data.SQLite.addin.xml20
-rw-r--r--OpenSim/Data/SQLite/SQLiteEstateData.cs126
-rw-r--r--OpenSim/Framework/AssetBase.cs1
-rw-r--r--OpenSim/Framework/AvatarAppearance.cs2
-rw-r--r--OpenSim/Framework/Console/LocalConsole.cs180
-rw-r--r--OpenSim/Framework/IClientAPI.cs5
-rw-r--r--OpenSim/Framework/IScene.cs3
-rw-r--r--OpenSim/Framework/RegionLoader/Filesystem/RegionLoaderFileSystem.cs4
-rw-r--r--OpenSim/Framework/RegionLoader/Web/RegionLoaderWebServer.cs93
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs2
-rw-r--r--OpenSim/Region/Application/OpenSim.cs9
-rw-r--r--OpenSim/Region/Application/OpenSimBase.cs67
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs31
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs17
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs22
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs184
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs25
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs127
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs876
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs12
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs38
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs11
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs16
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs1
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs9
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs12
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs15
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs15
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs26
-rw-r--r--OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs4
-rw-r--r--OpenSim/Region/Examples/SimpleModule/ComplexObject.cs131
-rw-r--r--OpenSim/Region/Examples/SimpleModule/CpuCounterObject.cs68
-rw-r--r--OpenSim/Region/Examples/SimpleModule/FileSystemObject.cs51
-rw-r--r--OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs1172
-rw-r--r--OpenSim/Region/Examples/SimpleModule/Properties/AssemblyInfo.cs62
-rw-r--r--OpenSim/Region/Examples/SimpleModule/README.txt9
-rw-r--r--OpenSim/Region/Examples/SimpleModule/RegionModule.cs147
-rw-r--r--OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs72
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEstateDataService.cs10
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEstateDataStore.cs8
-rw-r--r--OpenSim/Region/Framework/Interfaces/IRegionModule.cs9
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs16
-rw-r--r--OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs5
-rw-r--r--OpenSim/Region/Framework/Scenes/EntityBase.cs16
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs25
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs235
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs37
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs67
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs17
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs94
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs135
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs2
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs7
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs72
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs22
-rw-r--r--OpenSim/Region/Physics/BulletDotNETPlugin/AssemblyInfo.cs58
-rw-r--r--OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs1190
-rw-r--r--OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPlugin.cs65
-rw-r--r--OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPluginStructs.cs60
-rw-r--r--OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs2767
-rw-r--r--OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs776
-rw-r--r--OpenSim/Region/Physics/BulletXPlugin/AssemblyInfo.cs58
-rw-r--r--OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs1855
-rw-r--r--OpenSim/Region/Physics/BulletXPlugin/TriangleIndexVertexArray.cs197
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODECharacter.cs19
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs90
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs5
-rw-r--r--OpenSim/Services/Connectors/Simulation/EstateDataService.cs7
-rw-r--r--OpenSim/Services/InventoryService/XInventoryService.cs14
-rw-r--r--OpenSim/Services/UserAccountService/UserAccountService.cs159
-rw-r--r--OpenSim/Tests/Common/Mock/TestClient.cs2
-rw-r--r--OpenSim/Tests/Common/QuaternionToleranceConstraint.cs82
-rw-r--r--OpenSim/Tools/Configger/ConfigurationLoader.cs1
88 files changed, 2211 insertions, 10078 deletions
diff --git a/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs b/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs
index e26c1d2..6e28eba 100644
--- a/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs
+++ b/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs
@@ -186,35 +186,5 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
186 186
187 return true; 187 return true;
188 } 188 }
189
190 public void LoadRegionFromConfig(OpenSimBase openSim, ulong regionhandle)
191 {
192 m_log.Info("[LOADREGIONS]: Load Regions addin being initialised");
193
194 IRegionLoader regionLoader;
195 if (openSim.ConfigSource.Source.Configs["Startup"].GetString("region_info_source", "filesystem") == "filesystem")
196 {
197 m_log.Info("[LOADREGIONS]: Loading Region Info from filesystem");
198 regionLoader = new RegionLoaderFileSystem();
199 }
200 else
201 {
202 m_log.Info("[LOADREGIONS]: Loading Region Info from web");
203 regionLoader = new RegionLoaderWebServer();
204 }
205
206 regionLoader.SetIniConfigSource(openSim.ConfigSource.Source);
207 RegionInfo[] regionsToLoad = regionLoader.LoadRegions();
208 for (int i = 0; i < regionsToLoad.Length; i++)
209 {
210 if (regionhandle == regionsToLoad[i].RegionHandle)
211 {
212 IScene scene;
213 m_log.Debug("[LOADREGIONS]: Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " +
214 Thread.CurrentThread.ManagedThreadId.ToString() + ")");
215 openSim.CreateRegion(regionsToLoad[i], true, out scene);
216 }
217 }
218 }
219 } 189 }
220} 190}
diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
index 86c0ac8..535712e 100644
--- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
+++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
@@ -844,21 +844,30 @@ namespace OpenSim.ApplicationPlugins.RemoteController
844 } 844 }
845 845
846 // Create a new estate with the name provided 846 // Create a new estate with the name provided
847 region.EstateSettings = m_application.EstateDataService.LoadEstateSettings(region.RegionID, true); 847 region.EstateSettings = m_application.EstateDataService.CreateNewEstate();
848 848
849 region.EstateSettings.EstateName = (string) requestData["estate_name"]; 849 region.EstateSettings.EstateName = (string) requestData["estate_name"];
850 region.EstateSettings.EstateOwner = userID; 850 region.EstateSettings.EstateOwner = userID;
851 // Persistence does not seem to effect the need to save a new estate 851 // Persistence does not seem to effect the need to save a new estate
852 region.EstateSettings.Save(); 852 region.EstateSettings.Save();
853
854 if (!m_application.EstateDataService.LinkRegion(region.RegionID, (int) region.EstateSettings.EstateID))
855 throw new Exception("Failed to join estate.");
853 } 856 }
854 else 857 else
855 { 858 {
856 int estateID = estateIDs[0]; 859 int estateID = estateIDs[0];
857 860
858 region.EstateSettings = m_application.EstateDataService.LoadEstateSettings(estateID); 861 region.EstateSettings = m_application.EstateDataService.LoadEstateSettings(region.RegionID, false);
859 862
860 if (!m_application.EstateDataService.LinkRegion(region.RegionID, estateID)) 863 if (region.EstateSettings.EstateID != estateID)
861 throw new Exception("Failed to join estate."); 864 {
865 // The region is already part of an estate, but not the one we want.
866 region.EstateSettings = m_application.EstateDataService.LoadEstateSettings(estateID);
867
868 if (!m_application.EstateDataService.LinkRegion(region.RegionID, estateID))
869 throw new Exception("Failed to join estate.");
870 }
862 } 871 }
863 872
864 // Create the region and perform any initial initialization 873 // Create the region and perform any initial initialization
@@ -2434,10 +2443,12 @@ namespace OpenSim.ApplicationPlugins.RemoteController
2434 /// <description>UUID of the region</description></item> 2443 /// <description>UUID of the region</description></item>
2435 /// <item><term>region_name</term> 2444 /// <item><term>region_name</term>
2436 /// <description>region name</description></item> 2445 /// <description>region name</description></item>
2437 /// <item><term>profile</term> 2446 /// <item><term>profile</term>
2438 /// <description>profile url</description></item> 2447 /// <description>profile url</description></item>
2439 /// <item><term>noassets</term> 2448 /// <item><term>noassets</term>
2440 /// <description>true if no assets should be saved</description></item> 2449 /// <description>true if no assets should be saved</description></item>
2450 /// <item><term>perm</term>
2451 /// <description>C and/or T</description></item>
2441 /// </list> 2452 /// </list>
2442 /// 2453 ///
2443 /// <code>region_uuid</code> takes precedence over 2454 /// <code>region_uuid</code> takes precedence over
@@ -2512,6 +2523,11 @@ namespace OpenSim.ApplicationPlugins.RemoteController
2512 options["noassets"] = (string)requestData["noassets"] ; 2523 options["noassets"] = (string)requestData["noassets"] ;
2513 } 2524 }
2514 2525
2526 if (requestData.Contains("perm"))
2527 {
2528 options["checkPermissions"] = (string)requestData["perm"];
2529 }
2530
2515 IRegionArchiverModule archiver = scene.RequestModuleInterface<IRegionArchiverModule>(); 2531 IRegionArchiverModule archiver = scene.RequestModuleInterface<IRegionArchiverModule>();
2516 2532
2517 if (archiver != null) 2533 if (archiver != null)
diff --git a/OpenSim/ApplicationPlugins/Rest/Inventory/tests/Remote.cs b/OpenSim/ApplicationPlugins/Rest/Inventory/tests/Remote.cs
index 1023108..b53806c 100644
--- a/OpenSim/ApplicationPlugins/Rest/Inventory/tests/Remote.cs
+++ b/OpenSim/ApplicationPlugins/Rest/Inventory/tests/Remote.cs
@@ -169,7 +169,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests
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.MoveToTarget(vector, false); 172 presence.MoveToTarget(vector, false, false);
173 } 173 }
174 catch (Exception e) 174 catch (Exception e)
175 { 175 {
diff --git a/OpenSim/Data/MSSQL/MSSQLEstateData.cs b/OpenSim/Data/MSSQL/MSSQLEstateData.cs
index 9c54e77..1faa249 100644
--- a/OpenSim/Data/MSSQL/MSSQLEstateData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLEstateData.cs
@@ -148,56 +148,29 @@ namespace OpenSim.Data.MSSQL
148 } 148 }
149 } 149 }
150 150
151
152 if (insertEstate && create) 151 if (insertEstate && create)
153 { 152 {
154 List<string> names = new List<string>(FieldList); 153 DoCreate(es);
155 154 LinkRegion(regionID, (int)es.EstateID);
156 names.Remove("EstateID"); 155 }
157
158 sql = string.Format("insert into estate_settings ({0}) values ( @{1})", String.Join(",", names.ToArray()), String.Join(", @", names.ToArray()));
159
160 //_Log.Debug("[DB ESTATE]: SQL: " + sql);
161 using (SqlConnection conn = new SqlConnection(m_connectionString))
162 using (SqlCommand insertCommand = new SqlCommand(sql, conn))
163 {
164 insertCommand.CommandText = sql + " SET @ID = SCOPE_IDENTITY()";
165 156
166 foreach (string name in names) 157 LoadBanList(es);
167 {
168 insertCommand.Parameters.Add(_Database.CreateParameter("@" + name, _FieldMap[name].GetValue(es)));
169 }
170 SqlParameter idParameter = new SqlParameter("@ID", SqlDbType.Int);
171 idParameter.Direction = ParameterDirection.Output;
172 insertCommand.Parameters.Add(idParameter);
173 conn.Open();
174 insertCommand.ExecuteNonQuery();
175 158
176 es.EstateID = Convert.ToUInt32(idParameter.Value); 159 es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
177 } 160 es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
161 es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
178 162
179 sql = "INSERT INTO [estate_map] ([RegionID] ,[EstateID]) VALUES (@RegionID, @EstateID)"; 163 //Set event
180 using (SqlConnection conn = new SqlConnection(m_connectionString)) 164 es.OnSave += StoreEstateSettings;
181 using (SqlCommand cmd = new SqlCommand(sql, conn)) 165 return es;
182 { 166 }
183 167
184 cmd.Parameters.Add(_Database.CreateParameter("@RegionID", regionID)); 168 public EstateSettings CreateNewEstate()
185 cmd.Parameters.Add(_Database.CreateParameter("@EstateID", es.EstateID)); 169 {
186 // This will throw on dupe key 170 EstateSettings es = new EstateSettings();
187 try 171 es.OnSave += StoreEstateSettings;
188 {
189 conn.Open();
190 cmd.ExecuteNonQuery();
191 }
192 catch (Exception e)
193 {
194 m_log.DebugFormat("[ESTATE DB]: Error inserting regionID and EstateID in estate_map: {0}", e);
195 }
196 }
197 172
198 //TODO check if this is needed?? 173 DoCreate(es);
199 es.Save();
200 }
201 174
202 LoadBanList(es); 175 LoadBanList(es);
203 176
@@ -205,11 +178,40 @@ namespace OpenSim.Data.MSSQL
205 es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users"); 178 es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
206 es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups"); 179 es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
207 180
208 //Set event
209 es.OnSave += StoreEstateSettings;
210 return es; 181 return es;
211 } 182 }
212 183
184 private void DoCreate(EstateSettings es)
185 {
186 List<string> names = new List<string>(FieldList);
187
188 names.Remove("EstateID");
189
190 string sql = string.Format("insert into estate_settings ({0}) values ( @{1})", String.Join(",", names.ToArray()), String.Join(", @", names.ToArray()));
191
192 //_Log.Debug("[DB ESTATE]: SQL: " + sql);
193 using (SqlConnection conn = new SqlConnection(m_connectionString))
194 using (SqlCommand insertCommand = new SqlCommand(sql, conn))
195 {
196 insertCommand.CommandText = sql + " SET @ID = SCOPE_IDENTITY()";
197
198 foreach (string name in names)
199 {
200 insertCommand.Parameters.Add(_Database.CreateParameter("@" + name, _FieldMap[name].GetValue(es)));
201 }
202 SqlParameter idParameter = new SqlParameter("@ID", SqlDbType.Int);
203 idParameter.Direction = ParameterDirection.Output;
204 insertCommand.Parameters.Add(idParameter);
205 conn.Open();
206 insertCommand.ExecuteNonQuery();
207
208 es.EstateID = Convert.ToUInt32(idParameter.Value);
209 }
210
211 //TODO check if this is needed??
212 es.Save();
213 }
214
213 /// <summary> 215 /// <summary>
214 /// Stores the estate settings. 216 /// Stores the estate settings.
215 /// </summary> 217 /// </summary>
@@ -498,24 +500,43 @@ namespace OpenSim.Data.MSSQL
498 500
499 public bool LinkRegion(UUID regionID, int estateID) 501 public bool LinkRegion(UUID regionID, int estateID)
500 { 502 {
501 string sql = "insert into estate_map values (@RegionID, @EstateID)"; 503 string deleteSQL = "delete from estate_map where RegionID = @RegionID";
504 string insertSQL = "insert into estate_map values (@RegionID, @EstateID)";
502 using (SqlConnection conn = new SqlConnection(m_connectionString)) 505 using (SqlConnection conn = new SqlConnection(m_connectionString))
503 { 506 {
504 conn.Open(); 507 conn.Open();
508 SqlTransaction transaction = conn.BeginTransaction();
509
505 try 510 try
506 { 511 {
507 using (SqlCommand cmd = new SqlCommand(sql, conn)) 512 using (SqlCommand cmd = new SqlCommand(deleteSQL, conn))
508 { 513 {
509 cmd.Parameters.AddWithValue("@RegionID", regionID); 514 cmd.Transaction = transaction;
515 cmd.Parameters.AddWithValue("@RegionID", regionID.Guid);
516
517 cmd.ExecuteNonQuery();
518 }
519
520 using (SqlCommand cmd = new SqlCommand(insertSQL, conn))
521 {
522 cmd.Transaction = transaction;
523 cmd.Parameters.AddWithValue("@RegionID", regionID.Guid);
510 cmd.Parameters.AddWithValue("@EstateID", estateID); 524 cmd.Parameters.AddWithValue("@EstateID", estateID);
511 525
512 int ret = cmd.ExecuteNonQuery(); 526 int ret = cmd.ExecuteNonQuery();
527
528 if (ret != 0)
529 transaction.Commit();
530 else
531 transaction.Rollback();
532
513 return (ret != 0); 533 return (ret != 0);
514 } 534 }
515 } 535 }
516 catch (Exception ex) 536 catch (Exception ex)
517 { 537 {
518 m_log.Error("[REGION DB]: LinkRegion failed: " + ex.Message); 538 m_log.Error("[REGION DB]: LinkRegion failed: " + ex.Message);
539 transaction.Rollback();
519 } 540 }
520 } 541 }
521 return false; 542 return false;
diff --git a/OpenSim/Data/MSSQL/MSSQLUserAccountData.cs b/OpenSim/Data/MSSQL/MSSQLUserAccountData.cs
index f24b441..dd0689c 100644
--- a/OpenSim/Data/MSSQL/MSSQLUserAccountData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLUserAccountData.cs
@@ -218,23 +218,27 @@ namespace OpenSim.Data.MSSQL
218 if (words.Length > 2) 218 if (words.Length > 2)
219 return new UserAccountData[0]; 219 return new UserAccountData[0];
220 220
221 string sql = "";
222
221 using (SqlConnection conn = new SqlConnection(m_ConnectionString)) 223 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
222 using (SqlCommand cmd = new SqlCommand()) 224 using (SqlCommand cmd = new SqlCommand())
223 { 225 {
224 if (words.Length == 1) 226 if (words.Length == 1)
225 { 227 {
226 cmd.CommandText = String.Format("select * from {0} where ([ScopeID]=@ScopeID or [ScopeID]='00000000-0000-0000-0000-000000000000') and ([FirstName] like @search or [LastName] like @search)", m_Realm); 228 sql = String.Format("select * from {0} where ([ScopeID]=@ScopeID or [ScopeID]='00000000-0000-0000-0000-000000000000') and ([FirstName] like @search or [LastName] like @search)", m_Realm);
227 cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID)); 229 cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID));
228 cmd.Parameters.Add(m_database.CreateParameter("@search", "%" + words[0] + "%")); 230 cmd.Parameters.Add(m_database.CreateParameter("@search", "%" + words[0] + "%"));
229 } 231 }
230 else 232 else
231 { 233 {
232 cmd.CommandText = String.Format("select * from {0} where ([ScopeID]=@ScopeID or [ScopeID]='00000000-0000-0000-0000-000000000000') and ([FirstName] like @searchFirst or [LastName] like @searchLast)", m_Realm); 234 sql = String.Format("select * from {0} where ([ScopeID]=@ScopeID or [ScopeID]='00000000-0000-0000-0000-000000000000') and ([FirstName] like @searchFirst or [LastName] like @searchLast)", m_Realm);
233 cmd.Parameters.Add(m_database.CreateParameter("@searchFirst", "%" + words[0] + "%")); 235 cmd.Parameters.Add(m_database.CreateParameter("@searchFirst", "%" + words[0] + "%"));
234 cmd.Parameters.Add(m_database.CreateParameter("@searchLast", "%" + words[1] + "%")); 236 cmd.Parameters.Add(m_database.CreateParameter("@searchLast", "%" + words[1] + "%"));
235 cmd.Parameters.Add(m_database.CreateParameter("@ScopeID", scopeID.ToString())); 237 cmd.Parameters.Add(m_database.CreateParameter("@ScopeID", scopeID.ToString()));
236 } 238 }
237 239 cmd.Connection = conn;
240 cmd.CommandText = sql;
241 conn.Open();
238 return DoQuery(cmd); 242 return DoQuery(cmd);
239 } 243 }
240 } 244 }
diff --git a/OpenSim/Data/MSSQL/Resources/FriendsStore.migrations b/OpenSim/Data/MSSQL/Resources/FriendsStore.migrations
index 4d8ab0f..cc94c4e 100644
--- a/OpenSim/Data/MSSQL/Resources/FriendsStore.migrations
+++ b/OpenSim/Data/MSSQL/Resources/FriendsStore.migrations
@@ -19,4 +19,32 @@ IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[userf
19INSERT INTO Friends (PrincipalID, Friend, Flags, Offered) 19INSERT INTO Friends (PrincipalID, Friend, Flags, Offered)
20SELECT [ownerID], [friendID], [friendPerms], 0 FROM userfriends; 20SELECT [ownerID], [friendID], [friendPerms], 0 FROM userfriends;
21 21
22COMMIT
23
24:VERSION 3
25
26BEGIN TRANSACTION
27
28CREATE TABLE [Tmp_Friends]
29 ([PrincipalID] varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
30[Friend] varchar(255) NOT NULL,
31[Flags] char(16) NOT NULL DEFAULT '0',
32[Offered] varchar(32) NOT NULL DEFAULT 0)
33ON [PRIMARY]
34
35
36IF EXISTS(SELECT * FROM dbo.Friends)
37 EXEC('INSERT INTO dbo.Tmp_Friends (PrincipalID, Friend, Flags, Offered)
38 SELECT CONVERT(varchar(255),PrincipalID), Friend, Flags, Offered FROM dbo.Friends WITH (HOLDLOCK TABLOCKX)')
39
40DROP TABLE dbo.Friends
41
42EXECUTE sp_rename N'dbo.Tmp_Friends', N'Friends', 'OBJECT'
43
44ALTER TABLE dbo.Friends ADD
45 PRIMARY KEY CLUSTERED
46(
47 [PrincipalID] ASC, [Friend] ASC
48)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
49
22COMMIT \ No newline at end of file 50COMMIT \ No newline at end of file
diff --git a/OpenSim/Data/MSSQL/Resources/InventoryStore.migrations b/OpenSim/Data/MSSQL/Resources/InventoryStore.migrations
index 4a3cb27..4e43653 100644
--- a/OpenSim/Data/MSSQL/Resources/InventoryStore.migrations
+++ b/OpenSim/Data/MSSQL/Resources/InventoryStore.migrations
@@ -244,4 +244,36 @@ ALTER TABLE inventoryitems
244ADD CONSTRAINT DF_inventoryitems_creatorID 244ADD CONSTRAINT DF_inventoryitems_creatorID
245DEFAULT '00000000-0000-0000-0000-000000000000' FOR creatorID 245DEFAULT '00000000-0000-0000-0000-000000000000' FOR creatorID
246 246
247:GO
248
249:VERSION 9
250
251BEGIN TRANSACTION
252
253# CreatorID goes up to VARCHAR(255)
254
255exec sp_rename 'inventoryitems.CreatorID', 'cr_old', 'COLUMN'
256
257:GO
258
259alter table inventoryitems
260 add creatorID varchar(255) NULL
261
262:GO
263
264update inventoryitems set creatorID = cr_old
265
266alter table inventoryitems
267drop CONSTRAINT DF_inventoryitems_creatorID
268:GO
269
270alter table inventoryitems
271 drop column cr_old
272 :GO
273COMMIT
274
275ALTER TABLE inventoryitems
276ADD CONSTRAINT DF_inventoryitems_creatorID
277DEFAULT '00000000-0000-0000-0000-000000000000' FOR creatorID
278
247:GO \ No newline at end of file 279:GO \ No newline at end of file
diff --git a/OpenSim/Data/MSSQL/Resources/OpenSim.Data.MSSQL.addin.xml b/OpenSim/Data/MSSQL/Resources/OpenSim.Data.MSSQL.addin.xml
deleted file mode 100644
index 15fd29e..0000000
--- a/OpenSim/Data/MSSQL/Resources/OpenSim.Data.MSSQL.addin.xml
+++ /dev/null
@@ -1,23 +0,0 @@
1<Addin id="OpenSim.Data.MSSQL" version="0.1">
2 <Runtime>
3 <Import assembly="OpenSim.Data.MSSQL.dll"/>
4 </Runtime>
5 <Dependencies>
6 <Addin id="OpenSim.Data" version="0.5" />
7 </Dependencies>
8 <Extension path = "/OpenSim/GridData">
9 <Plugin id="MSSQLGridData" provider="OpenSim.Data.MSSQL.dll" type="OpenSim.Data.MSSQL.MSSQLGridData" />
10 </Extension>
11 <Extension path = "/OpenSim/LogData">
12 <Plugin id="MSSQLLogData" provider="OpenSim.Data.MSSQL.dll" type="OpenSim.Data.MSSQL.MSSQLLogData" />
13 </Extension>
14 <Extension path = "/OpenSim/AssetData">
15 <Plugin id="MSSQLAssetData" provider="OpenSim.Data.MSSQL.dll" type="OpenSim.Data.MSSQL.MSSQLAssetData" />
16 </Extension>
17 <Extension path = "/OpenSim/InventoryData">
18 <Plugin id="MSSQLInventoryData" provider="OpenSim.Data.MSSQL.dll" type="OpenSim.Data.MSSQL.MSSQLInventoryData" />
19 </Extension>
20 <Extension path = "/OpenSim/UserData">
21 <Plugin id="MSSQLUserData" provider="OpenSim.Data.MSSQL.dll" type="OpenSim.Data.MSSQL.MSSQLUserData" />
22 </Extension>
23</Addin>
diff --git a/OpenSim/Data/MySQL/MySQLEstateData.cs b/OpenSim/Data/MySQL/MySQLEstateData.cs
index 9dcf5e2..3d647ca 100644
--- a/OpenSim/Data/MySQL/MySQLEstateData.cs
+++ b/OpenSim/Data/MySQL/MySQLEstateData.cs
@@ -149,6 +149,22 @@ namespace OpenSim.Data.MySQL
149 } 149 }
150 } 150 }
151 151
152 public EstateSettings CreateNewEstate()
153 {
154 EstateSettings es = new EstateSettings();
155 es.OnSave += StoreEstateSettings;
156
157 DoCreate(es);
158
159 LoadBanList(es);
160
161 es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
162 es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
163 es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
164
165 return es;
166 }
167
152 private EstateSettings DoLoad(MySqlCommand cmd, UUID regionID, bool create) 168 private EstateSettings DoLoad(MySqlCommand cmd, UUID regionID, bool create)
153 { 169 {
154 EstateSettings es = new EstateSettings(); 170 EstateSettings es = new EstateSettings();
@@ -188,63 +204,65 @@ namespace OpenSim.Data.MySQL
188 204
189 if (!found && create) 205 if (!found && create)
190 { 206 {
191 // Migration case 207 DoCreate(es);
192 List<string> names = new List<string>(FieldList); 208 LinkRegion(regionID, (int)es.EstateID);
209 }
210 }
193 211
194 names.Remove("EstateID"); 212 LoadBanList(es);
195 213
196 string sql = "insert into estate_settings (" + String.Join(",", names.ToArray()) + ") values ( ?" + String.Join(", ?", names.ToArray()) + ")"; 214 es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
215 es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
216 es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
217 return es;
218 }
197 219
198 using (MySqlCommand cmd2 = dbcon.CreateCommand()) 220 private void DoCreate(EstateSettings es)
199 { 221 {
200 cmd2.CommandText = sql; 222 // Migration case
201 cmd2.Parameters.Clear(); 223 List<string> names = new List<string>(FieldList);
202 224
203 foreach (string name in FieldList) 225 names.Remove("EstateID");
204 {
205 if (m_FieldMap[name].GetValue(es) is bool)
206 {
207 if ((bool)m_FieldMap[name].GetValue(es))
208 cmd2.Parameters.AddWithValue("?" + name, "1");
209 else
210 cmd2.Parameters.AddWithValue("?" + name, "0");
211 }
212 else
213 {
214 cmd2.Parameters.AddWithValue("?" + name, m_FieldMap[name].GetValue(es).ToString());
215 }
216 }
217 226
218 cmd2.ExecuteNonQuery(); 227 string sql = "insert into estate_settings (" + String.Join(",", names.ToArray()) + ") values ( ?" + String.Join(", ?", names.ToArray()) + ")";
219 228
220 cmd2.CommandText = "select LAST_INSERT_ID() as id"; 229 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
221 cmd2.Parameters.Clear(); 230 {
231 dbcon.Open();
232 using (MySqlCommand cmd2 = dbcon.CreateCommand())
233 {
234 cmd2.CommandText = sql;
235 cmd2.Parameters.Clear();
222 236
223 using (IDataReader r = cmd2.ExecuteReader()) 237 foreach (string name in FieldList)
238 {
239 if (m_FieldMap[name].GetValue(es) is bool)
240 {
241 if ((bool)m_FieldMap[name].GetValue(es))
242 cmd2.Parameters.AddWithValue("?" + name, "1");
243 else
244 cmd2.Parameters.AddWithValue("?" + name, "0");
245 }
246 else
224 { 247 {
225 r.Read(); 248 cmd2.Parameters.AddWithValue("?" + name, m_FieldMap[name].GetValue(es).ToString());
226 es.EstateID = Convert.ToUInt32(r["id"]);
227 } 249 }
250 }
228 251
229 cmd2.CommandText = "insert into estate_map values (?RegionID, ?EstateID)"; 252 cmd2.ExecuteNonQuery();
230 cmd2.Parameters.AddWithValue("?RegionID", regionID.ToString());
231 cmd2.Parameters.AddWithValue("?EstateID", es.EstateID.ToString());
232 253
233 // This will throw on dupe key 254 cmd2.CommandText = "select LAST_INSERT_ID() as id";
234 try { cmd2.ExecuteNonQuery(); } 255 cmd2.Parameters.Clear();
235 catch (Exception) { }
236 256
237 es.Save(); 257 using (IDataReader r = cmd2.ExecuteReader())
258 {
259 r.Read();
260 es.EstateID = Convert.ToUInt32(r["id"]);
238 } 261 }
262
263 es.Save();
239 } 264 }
240 } 265 }
241
242 LoadBanList(es);
243
244 es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
245 es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
246 es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
247 return es;
248 } 266 }
249 267
250 public void StoreEstateSettings(EstateSettings es) 268 public void StoreEstateSettings(EstateSettings es)
@@ -477,7 +495,6 @@ namespace OpenSim.Data.MySQL
477 } 495 }
478 } 496 }
479 497
480
481 dbcon.Close(); 498 dbcon.Close();
482 } 499 }
483 500
@@ -507,7 +524,6 @@ namespace OpenSim.Data.MySQL
507 } 524 }
508 } 525 }
509 526
510
511 dbcon.Close(); 527 dbcon.Close();
512 } 528 }
513 529
@@ -519,16 +535,34 @@ namespace OpenSim.Data.MySQL
519 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) 535 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
520 { 536 {
521 dbcon.Open(); 537 dbcon.Open();
538 MySqlTransaction transaction = dbcon.BeginTransaction();
522 539
523 try 540 try
524 { 541 {
542 // Delete any existing association of this region with an estate.
543 using (MySqlCommand cmd = dbcon.CreateCommand())
544 {
545 cmd.Transaction = transaction;
546 cmd.CommandText = "delete from estate_map where RegionID = ?RegionID";
547 cmd.Parameters.AddWithValue("?RegionID", regionID);
548
549 cmd.ExecuteNonQuery();
550 }
551
525 using (MySqlCommand cmd = dbcon.CreateCommand()) 552 using (MySqlCommand cmd = dbcon.CreateCommand())
526 { 553 {
554 cmd.Transaction = transaction;
527 cmd.CommandText = "insert into estate_map values (?RegionID, ?EstateID)"; 555 cmd.CommandText = "insert into estate_map values (?RegionID, ?EstateID)";
528 cmd.Parameters.AddWithValue("?RegionID", regionID); 556 cmd.Parameters.AddWithValue("?RegionID", regionID);
529 cmd.Parameters.AddWithValue("?EstateID", estateID); 557 cmd.Parameters.AddWithValue("?EstateID", estateID);
530 558
531 int ret = cmd.ExecuteNonQuery(); 559 int ret = cmd.ExecuteNonQuery();
560
561 if (ret != 0)
562 transaction.Commit();
563 else
564 transaction.Rollback();
565
532 dbcon.Close(); 566 dbcon.Close();
533 567
534 return (ret != 0); 568 return (ret != 0);
@@ -537,6 +571,7 @@ namespace OpenSim.Data.MySQL
537 catch (MySqlException ex) 571 catch (MySqlException ex)
538 { 572 {
539 m_log.Error("[REGION DB]: LinkRegion failed: " + ex.Message); 573 m_log.Error("[REGION DB]: LinkRegion failed: " + ex.Message);
574 transaction.Rollback();
540 } 575 }
541 576
542 dbcon.Close(); 577 dbcon.Close();
diff --git a/OpenSim/Data/MySQL/Resources/OpenSim.Data.MySQL.addin.xml b/OpenSim/Data/MySQL/Resources/OpenSim.Data.MySQL.addin.xml
deleted file mode 100644
index 9e99547..0000000
--- a/OpenSim/Data/MySQL/Resources/OpenSim.Data.MySQL.addin.xml
+++ /dev/null
@@ -1,23 +0,0 @@
1<Addin id="OpenSim.Data.MySQL" version="0.1">
2 <Runtime>
3 <Import assembly="OpenSim.Data.MySQL.dll"/>
4 </Runtime>
5 <Dependencies>
6 <Addin id="OpenSim.Data" version="0.5" />
7 </Dependencies>
8 <Extension path = "/OpenSim/GridData">
9 <Plugin id="MySQLGridData" provider="OpenSim.Data.MySQL.dll" type="OpenSim.Data.MySQL.MySQLGridData" />
10 </Extension>
11 <Extension path = "/OpenSim/LogData">
12 <Plugin id="MySQLLogData" provider="OpenSim.Data.MySQL.dll" type="OpenSim.Data.MySQL.MySQLLogData" />
13 </Extension>
14 <Extension path = "/OpenSim/AssetData">
15 <Plugin id="MySQLAssetData" provider="OpenSim.Data.MySQL.dll" type="OpenSim.Data.MySQL.MySQLAssetData" />
16 </Extension>
17 <Extension path = "/OpenSim/InventoryData">
18 <Plugin id="MySQLInventoryData" provider="OpenSim.Data.MySQL.dll" type="OpenSim.Data.MySQL.MySQLInventoryData" />
19 </Extension>
20 <Extension path = "/OpenSim/UserData">
21 <Plugin id="MySQLUserData" provider="OpenSim.Data.MySQL.dll" type="OpenSim.Data.MySQL.MySQLUserData" />
22 </Extension>
23</Addin>
diff --git a/OpenSim/Data/Null/NullEstateData.cs b/OpenSim/Data/Null/NullEstateData.cs
index 8db8064..d64136d 100755
--- a/OpenSim/Data/Null/NullEstateData.cs
+++ b/OpenSim/Data/Null/NullEstateData.cs
@@ -84,6 +84,11 @@ namespace OpenSim.Data.Null
84 { 84 {
85 return new EstateSettings(); 85 return new EstateSettings();
86 } 86 }
87
88 public EstateSettings CreateNewEstate()
89 {
90 return new EstateSettings();
91 }
87 92
88 public List<EstateSettings> LoadEstateSettingsAll() 93 public List<EstateSettings> LoadEstateSettingsAll()
89 { 94 {
diff --git a/OpenSim/Data/Null/NullSimulationData.cs b/OpenSim/Data/Null/NullSimulationData.cs
index c33a6f2..b788976 100644
--- a/OpenSim/Data/Null/NullSimulationData.cs
+++ b/OpenSim/Data/Null/NullSimulationData.cs
@@ -77,8 +77,10 @@ namespace OpenSim.Data.Null
77 } 77 }
78 78
79 public RegionSettings LoadRegionSettings(UUID regionUUID) 79 public RegionSettings LoadRegionSettings(UUID regionUUID)
80 { 80 {
81 return null; 81 RegionSettings rs = new RegionSettings();
82 rs.RegionUUID = regionUUID;
83 return rs;
82 } 84 }
83 85
84 public void StoreObject(SceneObjectGroup obj, UUID regionUUID) 86 public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
diff --git a/OpenSim/Data/SQLite/Resources/OpenSim.Data.SQLite.addin.xml b/OpenSim/Data/SQLite/Resources/OpenSim.Data.SQLite.addin.xml
deleted file mode 100644
index e6764fa..0000000
--- a/OpenSim/Data/SQLite/Resources/OpenSim.Data.SQLite.addin.xml
+++ /dev/null
@@ -1,20 +0,0 @@
1<Addin id="OpenSim.Data.SQLite" version="0.1">
2 <Runtime>
3 <Import assembly="OpenSim.Data.SQLite.dll"/>
4 </Runtime>
5 <Dependencies>
6 <Addin id="OpenSim.Data" version="0.5" />
7 </Dependencies>
8 <Extension path = "/OpenSim/GridData">
9 <Plugin id="SQLiteGridData" provider="OpenSim.Data.SQLite.dll" type="OpenSim.Data.SQLite.SQLiteGridData" />
10 </Extension>
11 <Extension path = "/OpenSim/AssetData">
12 <Plugin id="SQLiteAssetData" provider="OpenSim.Data.SQLite.dll" type="OpenSim.Data.SQLite.SQLiteAssetData" />
13 </Extension>
14 <Extension path = "/OpenSim/InventoryData">
15 <Plugin id="SQLiteInventoryData" provider="OpenSim.Data.SQLite.dll" type="OpenSim.Data.SQLite.SQLiteInventoryStore" />
16 </Extension>
17 <Extension path = "/OpenSim/UserData">
18 <Plugin id="SQLiteUserData" provider="OpenSim.Data.SQLite.dll" type="OpenSim.Data.SQLite.SQLiteUserData" />
19 </Extension>
20</Addin>
diff --git a/OpenSim/Data/SQLite/SQLiteEstateData.cs b/OpenSim/Data/SQLite/SQLiteEstateData.cs
index 65719a6..8db9262 100644
--- a/OpenSim/Data/SQLite/SQLiteEstateData.cs
+++ b/OpenSim/Data/SQLite/SQLiteEstateData.cs
@@ -151,67 +151,77 @@ namespace OpenSim.Data.SQLite
151 } 151 }
152 else if (create) 152 else if (create)
153 { 153 {
154 r.Close(); 154 DoCreate(es);
155 LinkRegion(regionID, (int)es.EstateID);
156 }
155 157
156 List<string> names = new List<string>(FieldList); 158 LoadBanList(es);
157 159
158 names.Remove("EstateID"); 160 es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
161 es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
162 es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
163 return es;
164 }
159 165
160 string sql = "insert into estate_settings ("+String.Join(",", names.ToArray())+") values ( :"+String.Join(", :", names.ToArray())+")"; 166 public EstateSettings CreateNewEstate()
167 {
168 EstateSettings es = new EstateSettings();
169 es.OnSave += StoreEstateSettings;
161 170
162 cmd.CommandText = sql; 171 DoCreate(es);
163 cmd.Parameters.Clear();
164 172
165 foreach (string name in FieldList) 173 LoadBanList(es);
166 {
167 if (m_FieldMap[name].GetValue(es) is bool)
168 {
169 if ((bool)m_FieldMap[name].GetValue(es))
170 cmd.Parameters.AddWithValue(":"+name, "1");
171 else
172 cmd.Parameters.AddWithValue(":"+name, "0");
173 }
174 else
175 {
176 cmd.Parameters.AddWithValue(":"+name, m_FieldMap[name].GetValue(es).ToString());
177 }
178 }
179 174
180 cmd.ExecuteNonQuery(); 175 es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
176 es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
177 es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
181 178
182 cmd.CommandText = "select LAST_INSERT_ROWID() as id"; 179 return es;
183 cmd.Parameters.Clear(); 180 }
184 181
185 r = cmd.ExecuteReader(); 182 private void DoCreate(EstateSettings es)
183 {
184 List<string> names = new List<string>(FieldList);
186 185
187 r.Read(); 186 SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
187 IDataReader r = null;
188 188
189 es.EstateID = Convert.ToUInt32(r["id"]); 189 names.Remove("EstateID");
190 190
191 r.Close(); 191 string sql = "insert into estate_settings ("+String.Join(",", names.ToArray())+") values ( :"+String.Join(", :", names.ToArray())+")";
192 192
193 cmd.CommandText = "insert into estate_map values (:RegionID, :EstateID)"; 193 cmd.CommandText = sql;
194 cmd.Parameters.AddWithValue(":RegionID", regionID.ToString()); 194 cmd.Parameters.Clear();
195 cmd.Parameters.AddWithValue(":EstateID", es.EstateID.ToString());
196 195
197 // This will throw on dupe key 196 foreach (string name in FieldList)
198 try 197 {
198 if (m_FieldMap[name].GetValue(es) is bool)
199 { 199 {
200 cmd.ExecuteNonQuery(); 200 if ((bool)m_FieldMap[name].GetValue(es))
201 cmd.Parameters.AddWithValue(":"+name, "1");
202 else
203 cmd.Parameters.AddWithValue(":"+name, "0");
201 } 204 }
202 catch (Exception) 205 else
203 { 206 {
207 cmd.Parameters.AddWithValue(":"+name, m_FieldMap[name].GetValue(es).ToString());
204 } 208 }
205
206 es.Save();
207 } 209 }
208 210
209 LoadBanList(es); 211 cmd.ExecuteNonQuery();
210 212
211 es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers"); 213 cmd.CommandText = "select LAST_INSERT_ROWID() as id";
212 es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users"); 214 cmd.Parameters.Clear();
213 es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups"); 215
214 return es; 216 r = cmd.ExecuteReader();
217
218 r.Read();
219
220 es.EstateID = Convert.ToUInt32(r["id"]);
221
222 r.Close();
223
224 es.Save();
215 } 225 }
216 226
217 public void StoreEstateSettings(EstateSettings es) 227 public void StoreEstateSettings(EstateSettings es)
@@ -440,16 +450,36 @@ namespace OpenSim.Data.SQLite
440 450
441 public bool LinkRegion(UUID regionID, int estateID) 451 public bool LinkRegion(UUID regionID, int estateID)
442 { 452 {
443 SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); 453 SqliteTransaction transaction = m_connection.BeginTransaction();
444 454
445 cmd.CommandText = "insert into estate_map values (:RegionID, :EstateID)"; 455 // Delete any existing estate mapping for this region.
446 cmd.Parameters.AddWithValue(":RegionID", regionID.ToString()); 456 using(SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
447 cmd.Parameters.AddWithValue(":EstateID", estateID.ToString()); 457 {
458 cmd.CommandText = "delete from estate_map where RegionID = :RegionID";
459 cmd.Transaction = transaction;
460 cmd.Parameters.AddWithValue(":RegionID", regionID.ToString());
448 461
449 if (cmd.ExecuteNonQuery() == 0) 462 cmd.ExecuteNonQuery();
450 return false; 463 }
451 464
452 return true; 465 using(SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
466 {
467 cmd.CommandText = "insert into estate_map values (:RegionID, :EstateID)";
468 cmd.Transaction = transaction;
469 cmd.Parameters.AddWithValue(":RegionID", regionID.ToString());
470 cmd.Parameters.AddWithValue(":EstateID", estateID.ToString());
471
472 if (cmd.ExecuteNonQuery() == 0)
473 {
474 transaction.Rollback();
475 return false;
476 }
477 else
478 {
479 transaction.Commit();
480 return true;
481 }
482 }
453 } 483 }
454 484
455 public List<UUID> GetRegions(int estateID) 485 public List<UUID> GetRegions(int estateID)
diff --git a/OpenSim/Framework/AssetBase.cs b/OpenSim/Framework/AssetBase.cs
index 06e040f..ff240be 100644
--- a/OpenSim/Framework/AssetBase.cs
+++ b/OpenSim/Framework/AssetBase.cs
@@ -169,6 +169,7 @@ namespace OpenSim.Framework
169 get { return m_metadata.FullID; } 169 get { return m_metadata.FullID; }
170 set { m_metadata.FullID = value; } 170 set { m_metadata.FullID = value; }
171 } 171 }
172
172 /// <summary> 173 /// <summary>
173 /// Asset MetaData ID (transferring from UUID to string ID) 174 /// Asset MetaData ID (transferring from UUID to string ID)
174 /// </summary> 175 /// </summary>
diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs
index 21e2233..f147e14 100644
--- a/OpenSim/Framework/AvatarAppearance.cs
+++ b/OpenSim/Framework/AvatarAppearance.cs
@@ -225,6 +225,8 @@ namespace OpenSim.Framework
225 /// </summary> 225 /// </summary>
226 public virtual void ResetAppearance() 226 public virtual void ResetAppearance()
227 { 227 {
228// m_log.WarnFormat("[AVATAR APPEARANCE]: Reset appearance");
229
228 m_serial = 0; 230 m_serial = 0;
229 231
230 SetDefaultTexture(); 232 SetDefaultTexture();
diff --git a/OpenSim/Framework/Console/LocalConsole.cs b/OpenSim/Framework/Console/LocalConsole.cs
index eda41b8..7c8626d 100644
--- a/OpenSim/Framework/Console/LocalConsole.cs
+++ b/OpenSim/Framework/Console/LocalConsole.cs
@@ -46,12 +46,11 @@ namespace OpenSim.Framework.Console
46 // private readonly object m_syncRoot = new object(); 46 // private readonly object m_syncRoot = new object();
47 private const string LOGLEVEL_NONE = "(none)"; 47 private const string LOGLEVEL_NONE = "(none)";
48 48
49 private int y = -1; 49 private int m_cursorYPosition = -1;
50 private int cp = 0; 50 private int m_cursorXPosition = 0;
51 private int h = 1; 51 private StringBuilder m_commandLine = new StringBuilder();
52 private StringBuilder cmdline = new StringBuilder(); 52 private bool m_echo = true;
53 private bool echo = true; 53 private List<string> m_history = new List<string>();
54 private List<string> history = new List<string>();
55 54
56 private static readonly ConsoleColor[] Colors = { 55 private static readonly ConsoleColor[] Colors = {
57 // the dark colors don't seem to be visible on some black background terminals like putty :( 56 // the dark colors don't seem to be visible on some black background terminals like putty :(
@@ -81,10 +80,10 @@ namespace OpenSim.Framework.Console
81 80
82 private void AddToHistory(string text) 81 private void AddToHistory(string text)
83 { 82 {
84 while (history.Count >= 100) 83 while (m_history.Count >= 100)
85 history.RemoveAt(0); 84 m_history.RemoveAt(0);
86 85
87 history.Add(text); 86 m_history.Add(text);
88 } 87 }
89 88
90 /// <summary> 89 /// <summary>
@@ -111,11 +110,11 @@ namespace OpenSim.Framework.Console
111 } 110 }
112 else 111 else
113 { 112 {
114 int bw = System.Console.BufferWidth; 113 int bufferWidth = System.Console.BufferWidth;
115 114
116 // On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657) 115 // On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657)
117 if (bw > 0 && left >= bw) 116 if (bufferWidth > 0 && left >= bufferWidth)
118 System.Console.CursorLeft = bw - 1; 117 System.Console.CursorLeft = bufferWidth - 1;
119 } 118 }
120 119
121 if (top < 0) 120 if (top < 0)
@@ -124,11 +123,11 @@ namespace OpenSim.Framework.Console
124 } 123 }
125 else 124 else
126 { 125 {
127 int bh = System.Console.BufferHeight; 126 int bufferHeight = System.Console.BufferHeight;
128 127
129 // On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657) 128 // On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657)
130 if (bh > 0 && top >= bh) 129 if (bufferHeight > 0 && top >= bufferHeight)
131 top = bh - 1; 130 top = bufferHeight - 1;
132 } 131 }
133 132
134 System.Console.CursorTop = top; 133 System.Console.CursorTop = top;
@@ -160,10 +159,10 @@ namespace OpenSim.Framework.Console
160 } 159 }
161 else 160 else
162 { 161 {
163 int bh = System.Console.BufferHeight; 162 int bufferHeight = System.Console.BufferHeight;
164 // On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657) 163 // On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657)
165 if (bh > 0 && top >= bh) 164 if (bufferHeight > 0 && top >= bufferHeight)
166 System.Console.CursorTop = bh - 1; 165 System.Console.CursorTop = bufferHeight - 1;
167 } 166 }
168 167
169 if (left < 0) 168 if (left < 0)
@@ -172,11 +171,11 @@ namespace OpenSim.Framework.Console
172 } 171 }
173 else 172 else
174 { 173 {
175 int bw = System.Console.BufferWidth; 174 int bufferWidth = System.Console.BufferWidth;
176 175
177 // On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657) 176 // On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657)
178 if (bw > 0 && left >= bw) 177 if (bufferWidth > 0 && left >= bufferWidth)
179 left = bw - 1; 178 left = bufferWidth - 1;
180 } 179 }
181 180
182 System.Console.CursorLeft = left; 181 System.Console.CursorLeft = left;
@@ -186,31 +185,30 @@ namespace OpenSim.Framework.Console
186 185
187 private void Show() 186 private void Show()
188 { 187 {
189 lock (cmdline) 188 lock (m_commandLine)
190 { 189 {
191 if (y == -1 || System.Console.BufferWidth == 0) 190 if (m_cursorYPosition == -1 || System.Console.BufferWidth == 0)
192 return; 191 return;
193 192
194 int xc = prompt.Length + cp; 193 int xc = prompt.Length + m_cursorXPosition;
195 int new_x = xc % System.Console.BufferWidth; 194 int new_x = xc % System.Console.BufferWidth;
196 int new_y = y + xc / System.Console.BufferWidth; 195 int new_y = m_cursorYPosition + xc / System.Console.BufferWidth;
197 int end_y = y + (cmdline.Length + prompt.Length) / System.Console.BufferWidth; 196 int end_y = m_cursorYPosition + (m_commandLine.Length + prompt.Length) / System.Console.BufferWidth;
198 if (end_y / System.Console.BufferWidth >= h) 197
199 h++;
200 if (end_y >= System.Console.BufferHeight) // wrap 198 if (end_y >= System.Console.BufferHeight) // wrap
201 { 199 {
202 y--; 200 m_cursorYPosition--;
203 new_y--; 201 new_y--;
204 SetCursorLeft(0); 202 SetCursorLeft(0);
205 SetCursorTop(System.Console.BufferHeight - 1); 203 SetCursorTop(System.Console.BufferHeight - 1);
206 System.Console.WriteLine(" "); 204 System.Console.WriteLine(" ");
207 } 205 }
208 206
209 y = SetCursorTop(y); 207 m_cursorYPosition = SetCursorTop(m_cursorYPosition);
210 SetCursorLeft(0); 208 SetCursorLeft(0);
211 209
212 if (echo) 210 if (m_echo)
213 System.Console.Write("{0}{1}", prompt, cmdline); 211 System.Console.Write("{0}{1}", prompt, m_commandLine);
214 else 212 else
215 System.Console.Write("{0}", prompt); 213 System.Console.Write("{0}", prompt);
216 214
@@ -221,20 +219,20 @@ namespace OpenSim.Framework.Console
221 219
222 public override void LockOutput() 220 public override void LockOutput()
223 { 221 {
224 Monitor.Enter(cmdline); 222 Monitor.Enter(m_commandLine);
225 try 223 try
226 { 224 {
227 if (y != -1) 225 if (m_cursorYPosition != -1)
228 { 226 {
229 y = SetCursorTop(y); 227 m_cursorYPosition = SetCursorTop(m_cursorYPosition);
230 System.Console.CursorLeft = 0; 228 System.Console.CursorLeft = 0;
231 229
232 int count = cmdline.Length + prompt.Length; 230 int count = m_commandLine.Length + prompt.Length;
233 231
234 while (count-- > 0) 232 while (count-- > 0)
235 System.Console.Write(" "); 233 System.Console.Write(" ");
236 234
237 y = SetCursorTop(y); 235 m_cursorYPosition = SetCursorTop(m_cursorYPosition);
238 SetCursorLeft(0); 236 SetCursorLeft(0);
239 } 237 }
240 } 238 }
@@ -245,12 +243,12 @@ namespace OpenSim.Framework.Console
245 243
246 public override void UnlockOutput() 244 public override void UnlockOutput()
247 { 245 {
248 if (y != -1) 246 if (m_cursorYPosition != -1)
249 { 247 {
250 y = System.Console.CursorTop; 248 m_cursorYPosition = System.Console.CursorTop;
251 Show(); 249 Show();
252 } 250 }
253 Monitor.Exit(cmdline); 251 Monitor.Exit(m_commandLine);
254 } 252 }
255 253
256 private void WriteColorText(ConsoleColor color, string sender) 254 private void WriteColorText(ConsoleColor color, string sender)
@@ -317,29 +315,29 @@ namespace OpenSim.Framework.Console
317 315
318 public override void Output(string text, string level) 316 public override void Output(string text, string level)
319 { 317 {
320 lock (cmdline) 318 lock (m_commandLine)
321 { 319 {
322 if (y == -1) 320 if (m_cursorYPosition == -1)
323 { 321 {
324 WriteLocalText(text, level); 322 WriteLocalText(text, level);
325 323
326 return; 324 return;
327 } 325 }
328 326
329 y = SetCursorTop(y); 327 m_cursorYPosition = SetCursorTop(m_cursorYPosition);
330 SetCursorLeft(0); 328 SetCursorLeft(0);
331 329
332 int count = cmdline.Length + prompt.Length; 330 int count = m_commandLine.Length + prompt.Length;
333 331
334 while (count-- > 0) 332 while (count-- > 0)
335 System.Console.Write(" "); 333 System.Console.Write(" ");
336 334
337 y = SetCursorTop(y); 335 m_cursorYPosition = SetCursorTop(m_cursorYPosition);
338 SetCursorLeft(0); 336 SetCursorLeft(0);
339 337
340 WriteLocalText(text, level); 338 WriteLocalText(text, level);
341 339
342 y = System.Console.CursorTop; 340 m_cursorYPosition = System.Console.CursorTop;
343 341
344 Show(); 342 Show();
345 } 343 }
@@ -347,9 +345,9 @@ namespace OpenSim.Framework.Console
347 345
348 private bool ContextHelp() 346 private bool ContextHelp()
349 { 347 {
350 string[] words = Parser.Parse(cmdline.ToString()); 348 string[] words = Parser.Parse(m_commandLine.ToString());
351 349
352 bool trailingSpace = cmdline.ToString().EndsWith(" "); 350 bool trailingSpace = m_commandLine.ToString().EndsWith(" ");
353 351
354 // Allow ? through while typing a URI 352 // Allow ? through while typing a URI
355 // 353 //
@@ -368,19 +366,18 @@ namespace OpenSim.Framework.Console
368 366
369 public override string ReadLine(string p, bool isCommand, bool e) 367 public override string ReadLine(string p, bool isCommand, bool e)
370 { 368 {
371 h = 1; 369 m_cursorXPosition = 0;
372 cp = 0;
373 prompt = p; 370 prompt = p;
374 echo = e; 371 m_echo = e;
375 int historyLine = history.Count; 372 int historyLine = m_history.Count;
376 373
377 SetCursorLeft(0); // Needed for mono 374 SetCursorLeft(0); // Needed for mono
378 System.Console.Write(" "); // Needed for mono 375 System.Console.Write(" "); // Needed for mono
379 376
380 lock (cmdline) 377 lock (m_commandLine)
381 { 378 {
382 y = System.Console.CursorTop; 379 m_cursorYPosition = System.Console.CursorTop;
383 cmdline.Remove(0, cmdline.Length); 380 m_commandLine.Remove(0, m_commandLine.Length);
384 } 381 }
385 382
386 while (true) 383 while (true)
@@ -388,92 +385,95 @@ namespace OpenSim.Framework.Console
388 Show(); 385 Show();
389 386
390 ConsoleKeyInfo key = System.Console.ReadKey(true); 387 ConsoleKeyInfo key = System.Console.ReadKey(true);
391 char c = key.KeyChar; 388 char enteredChar = key.KeyChar;
392 389
393 if (!Char.IsControl(c)) 390 if (!Char.IsControl(enteredChar))
394 { 391 {
395 if (cp >= 318) 392 if (m_cursorXPosition >= 318)
396 continue; 393 continue;
397 394
398 if (c == '?' && isCommand) 395 if (enteredChar == '?' && isCommand)
399 { 396 {
400 if (ContextHelp()) 397 if (ContextHelp())
401 continue; 398 continue;
402 } 399 }
403 400
404 cmdline.Insert(cp, c); 401 m_commandLine.Insert(m_cursorXPosition, enteredChar);
405 cp++; 402 m_cursorXPosition++;
406 } 403 }
407 else 404 else
408 { 405 {
409 switch (key.Key) 406 switch (key.Key)
410 { 407 {
411 case ConsoleKey.Backspace: 408 case ConsoleKey.Backspace:
412 if (cp == 0) 409 if (m_cursorXPosition == 0)
413 break; 410 break;
414 cmdline.Remove(cp-1, 1); 411 m_commandLine.Remove(m_cursorXPosition-1, 1);
415 cp--; 412 m_cursorXPosition--;
416 413
417 SetCursorLeft(0); 414 SetCursorLeft(0);
418 y = SetCursorTop(y); 415 m_cursorYPosition = SetCursorTop(m_cursorYPosition);
419 416
420 System.Console.Write("{0}{1} ", prompt, cmdline); 417 if (m_echo)
418 System.Console.Write("{0}{1} ", prompt, m_commandLine);
419 else
420 System.Console.Write("{0}", prompt);
421 421
422 break; 422 break;
423 case ConsoleKey.End: 423 case ConsoleKey.End:
424 cp = cmdline.Length; 424 m_cursorXPosition = m_commandLine.Length;
425 break; 425 break;
426 case ConsoleKey.Home: 426 case ConsoleKey.Home:
427 cp = 0; 427 m_cursorXPosition = 0;
428 break; 428 break;
429 case ConsoleKey.UpArrow: 429 case ConsoleKey.UpArrow:
430 if (historyLine < 1) 430 if (historyLine < 1)
431 break; 431 break;
432 historyLine--; 432 historyLine--;
433 LockOutput(); 433 LockOutput();
434 cmdline.Remove(0, cmdline.Length); 434 m_commandLine.Remove(0, m_commandLine.Length);
435 cmdline.Append(history[historyLine]); 435 m_commandLine.Append(m_history[historyLine]);
436 cp = cmdline.Length; 436 m_cursorXPosition = m_commandLine.Length;
437 UnlockOutput(); 437 UnlockOutput();
438 break; 438 break;
439 case ConsoleKey.DownArrow: 439 case ConsoleKey.DownArrow:
440 if (historyLine >= history.Count) 440 if (historyLine >= m_history.Count)
441 break; 441 break;
442 historyLine++; 442 historyLine++;
443 LockOutput(); 443 LockOutput();
444 if (historyLine == history.Count) 444 if (historyLine == m_history.Count)
445 { 445 {
446 cmdline.Remove(0, cmdline.Length); 446 m_commandLine.Remove(0, m_commandLine.Length);
447 } 447 }
448 else 448 else
449 { 449 {
450 cmdline.Remove(0, cmdline.Length); 450 m_commandLine.Remove(0, m_commandLine.Length);
451 cmdline.Append(history[historyLine]); 451 m_commandLine.Append(m_history[historyLine]);
452 } 452 }
453 cp = cmdline.Length; 453 m_cursorXPosition = m_commandLine.Length;
454 UnlockOutput(); 454 UnlockOutput();
455 break; 455 break;
456 case ConsoleKey.LeftArrow: 456 case ConsoleKey.LeftArrow:
457 if (cp > 0) 457 if (m_cursorXPosition > 0)
458 cp--; 458 m_cursorXPosition--;
459 break; 459 break;
460 case ConsoleKey.RightArrow: 460 case ConsoleKey.RightArrow:
461 if (cp < cmdline.Length) 461 if (m_cursorXPosition < m_commandLine.Length)
462 cp++; 462 m_cursorXPosition++;
463 break; 463 break;
464 case ConsoleKey.Enter: 464 case ConsoleKey.Enter:
465 SetCursorLeft(0); 465 SetCursorLeft(0);
466 y = SetCursorTop(y); 466 m_cursorYPosition = SetCursorTop(m_cursorYPosition);
467 467
468 System.Console.WriteLine(); 468 System.Console.WriteLine();
469 //Show(); 469 //Show();
470 470
471 lock (cmdline) 471 lock (m_commandLine)
472 { 472 {
473 y = -1; 473 m_cursorYPosition = -1;
474 } 474 }
475 475
476 string commandLine = cmdline.ToString(); 476 string commandLine = m_commandLine.ToString();
477 477
478 if (isCommand) 478 if (isCommand)
479 { 479 {
@@ -481,12 +481,12 @@ namespace OpenSim.Framework.Console
481 481
482 if (cmd.Length != 0) 482 if (cmd.Length != 0)
483 { 483 {
484 int i; 484 int index;
485 485
486 for (i=0 ; i < cmd.Length ; i++) 486 for (index=0 ; index < cmd.Length ; index++)
487 { 487 {
488 if (cmd[i].Contains(" ")) 488 if (cmd[index].Contains(" "))
489 cmd[i] = "\"" + cmd[i] + "\""; 489 cmd[index] = "\"" + cmd[index] + "\"";
490 } 490 }
491 AddToHistory(String.Join(" ", cmd)); 491 AddToHistory(String.Join(" ", cmd));
492 return String.Empty; 492 return String.Empty;
@@ -494,7 +494,7 @@ namespace OpenSim.Framework.Console
494 } 494 }
495 495
496 // If we're not echoing to screen (e.g. a password) then we probably don't want it in history 496 // If we're not echoing to screen (e.g. a password) then we probably don't want it in history
497 if (echo && commandLine != "") 497 if (m_echo && commandLine != "")
498 AddToHistory(commandLine); 498 AddToHistory(commandLine);
499 499
500 return commandLine; 500 return commandLine;
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index ee3d6b6..f02543d 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -53,8 +53,7 @@ namespace OpenSim.Framework
53 53
54 public delegate ISceneEntity 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, List<KeyValuePair<UUID, uint>> rezlist );
57 RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects);
58 57
59 public delegate void ObjectAttach( 58 public delegate void ObjectAttach(
60 IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent); 59 IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent);
@@ -940,7 +939,7 @@ namespace OpenSim.Framework
940 event ScriptReset OnScriptReset; 939 event ScriptReset OnScriptReset;
941 event GetScriptRunning OnGetScriptRunning; 940 event GetScriptRunning OnGetScriptRunning;
942 event SetScriptRunning OnSetScriptRunning; 941 event SetScriptRunning OnSetScriptRunning;
943 event Action<Vector3, bool> OnAutoPilotGo; 942 event Action<Vector3, bool, bool> OnAutoPilotGo;
944 943
945 event TerrainUnacked OnUnackedTerrain; 944 event TerrainUnacked OnUnackedTerrain;
946 event ActivateGesture OnActivateGesture; 945 event ActivateGesture OnActivateGesture;
diff --git a/OpenSim/Framework/IScene.cs b/OpenSim/Framework/IScene.cs
index 8f7a2e5..e0cb897 100644
--- a/OpenSim/Framework/IScene.cs
+++ b/OpenSim/Framework/IScene.cs
@@ -33,15 +33,12 @@ namespace OpenSim.Framework
33{ 33{
34 public delegate void restart(RegionInfo thisRegion); 34 public delegate void restart(RegionInfo thisRegion);
35 35
36 //public delegate void regionup (RegionInfo thisRegion);
37
38 public enum RegionStatus : int 36 public enum RegionStatus : int
39 { 37 {
40 Down = 0, 38 Down = 0,
41 Up = 1, 39 Up = 1,
42 Crashed = 2, 40 Crashed = 2,
43 Starting = 3, 41 Starting = 3,
44 SlaveScene = 4
45 }; 42 };
46 43
47 /// <value> 44 /// <value>
diff --git a/OpenSim/Framework/RegionLoader/Filesystem/RegionLoaderFileSystem.cs b/OpenSim/Framework/RegionLoader/Filesystem/RegionLoaderFileSystem.cs
index 0aae4ff..8332c14 100644
--- a/OpenSim/Framework/RegionLoader/Filesystem/RegionLoaderFileSystem.cs
+++ b/OpenSim/Framework/RegionLoader/Filesystem/RegionLoaderFileSystem.cs
@@ -48,11 +48,13 @@ namespace OpenSim.Framework.RegionLoader.Filesystem
48 public RegionInfo[] LoadRegions() 48 public RegionInfo[] LoadRegions()
49 { 49 {
50 string regionConfigPath = Path.Combine(Util.configDir(), "Regions"); 50 string regionConfigPath = Path.Combine(Util.configDir(), "Regions");
51 bool allowRegionless = false;
51 52
52 try 53 try
53 { 54 {
54 IConfig startupConfig = (IConfig)m_configSource.Configs["Startup"]; 55 IConfig startupConfig = (IConfig)m_configSource.Configs["Startup"];
55 regionConfigPath = startupConfig.GetString("regionload_regionsdir", regionConfigPath).Trim(); 56 regionConfigPath = startupConfig.GetString("regionload_regionsdir", regionConfigPath).Trim();
57 allowRegionless = startupConfig.GetBoolean("allow_regionless", false);
56 } 58 }
57 catch (Exception) 59 catch (Exception)
58 { 60 {
@@ -68,7 +70,7 @@ namespace OpenSim.Framework.RegionLoader.Filesystem
68 string[] iniFiles = Directory.GetFiles(regionConfigPath, "*.ini"); 70 string[] iniFiles = Directory.GetFiles(regionConfigPath, "*.ini");
69 71
70 // Create an empty Regions.ini if there are no existing config files. 72 // Create an empty Regions.ini if there are no existing config files.
71 if (configFiles.Length == 0 && iniFiles.Length == 0) 73 if (!allowRegionless && configFiles.Length == 0 && iniFiles.Length == 0)
72 { 74 {
73 new RegionInfo("DEFAULT REGION CONFIG", Path.Combine(regionConfigPath, "Regions.ini"), false, m_configSource); 75 new RegionInfo("DEFAULT REGION CONFIG", Path.Combine(regionConfigPath, "Regions.ini"), false, m_configSource);
74 iniFiles = Directory.GetFiles(regionConfigPath, "*.ini"); 76 iniFiles = Directory.GetFiles(regionConfigPath, "*.ini");
diff --git a/OpenSim/Framework/RegionLoader/Web/RegionLoaderWebServer.cs b/OpenSim/Framework/RegionLoader/Web/RegionLoaderWebServer.cs
index f0ffc2c..c7caf6f 100644
--- a/OpenSim/Framework/RegionLoader/Web/RegionLoaderWebServer.cs
+++ b/OpenSim/Framework/RegionLoader/Web/RegionLoaderWebServer.cs
@@ -60,6 +60,8 @@ namespace OpenSim.Framework.RegionLoader.Web
60 { 60 {
61 IConfig startupConfig = (IConfig) m_configSource.Configs["Startup"]; 61 IConfig startupConfig = (IConfig) m_configSource.Configs["Startup"];
62 string url = startupConfig.GetString("regionload_webserver_url", String.Empty).Trim(); 62 string url = startupConfig.GetString("regionload_webserver_url", String.Empty).Trim();
63 bool allowRegionless = startupConfig.GetBoolean("allow_regionless", false);
64
63 if (url == String.Empty) 65 if (url == String.Empty)
64 { 66 {
65 m_log.Error("[WEBLOADER]: Unable to load webserver URL - URL was empty."); 67 m_log.Error("[WEBLOADER]: Unable to load webserver URL - URL was empty.");
@@ -67,39 +69,60 @@ namespace OpenSim.Framework.RegionLoader.Web
67 } 69 }
68 else 70 else
69 { 71 {
70 while (tries > 0) 72 while(tries > 0)
71 { 73 {
72 HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create(url); 74 RegionInfo[] regionInfos = new RegionInfo[] {};
73 webRequest.Timeout = 30000; //30 Second Timeout 75 int regionCount = 0;
74 m_log.Debug("[WEBLOADER]: Sending Download Request..."); 76 HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create(url);
75 HttpWebResponse webResponse = (HttpWebResponse) webRequest.GetResponse(); 77 webRequest.Timeout = 30000; //30 Second Timeout
76 m_log.Debug("[WEBLOADER]: Downloading Region Information From Remote Server..."); 78 m_log.DebugFormat("[WEBLOADER]: Sending download request to {0}", url);
77 StreamReader reader = new StreamReader(webResponse.GetResponseStream());
78 string xmlSource = String.Empty;
79 string tempStr = reader.ReadLine();
80 while (tempStr != null)
81 {
82 xmlSource = xmlSource + tempStr;
83 tempStr = reader.ReadLine();
84 }
85 m_log.Debug("[WEBLOADER]: Done downloading region information from server. Total Bytes: " +
86 xmlSource.Length);
87 XmlDocument xmlDoc = new XmlDocument();
88 xmlDoc.LoadXml(xmlSource);
89 if (xmlDoc.FirstChild.Name == "Regions")
90 {
91 RegionInfo[] regionInfos = new RegionInfo[xmlDoc.FirstChild.ChildNodes.Count];
92 int i;
93 for (i = 0; i < xmlDoc.FirstChild.ChildNodes.Count; i++)
94 {
95 m_log.Debug(xmlDoc.FirstChild.ChildNodes[i].OuterXml);
96 regionInfos[i] =
97 new RegionInfo("REGION CONFIG #" + (i + 1), xmlDoc.FirstChild.ChildNodes[i],false,m_configSource);
98 }
99 79
100 if (i > 0) 80 try
101 return regionInfos; 81 {
102 } 82 HttpWebResponse webResponse = (HttpWebResponse) webRequest.GetResponse();
83 m_log.Debug("[WEBLOADER]: Downloading region information...");
84 StreamReader reader = new StreamReader(webResponse.GetResponseStream());
85 string xmlSource = String.Empty;
86 string tempStr = reader.ReadLine();
87 while (tempStr != null)
88 {
89 xmlSource = xmlSource + tempStr;
90 tempStr = reader.ReadLine();
91 }
92 m_log.Debug("[WEBLOADER]: Done downloading region information from server. Total Bytes: " +
93 xmlSource.Length);
94 XmlDocument xmlDoc = new XmlDocument();
95 xmlDoc.LoadXml(xmlSource);
96 if (xmlDoc.FirstChild.Name == "Regions")
97 {
98 regionCount = xmlDoc.FirstChild.ChildNodes.Count;
99
100 if (regionCount > 0)
101 {
102 regionInfos = new RegionInfo[regionCount];
103 int i;
104 for (i = 0; i < xmlDoc.FirstChild.ChildNodes.Count; i++)
105 {
106 m_log.Debug(xmlDoc.FirstChild.ChildNodes[i].OuterXml);
107 regionInfos[i] =
108 new RegionInfo("REGION CONFIG #" + (i + 1), xmlDoc.FirstChild.ChildNodes[i],false,m_configSource);
109 }
110 }
111 }
112 }
113 catch (WebException ex)
114 {
115 if (((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.NotFound)
116 {
117 if (!allowRegionless)
118 throw ex;
119 }
120 else
121 throw ex;
122 }
123
124 if (regionCount > 0 | allowRegionless)
125 return regionInfos;
103 126
104 m_log.Debug("[WEBLOADER]: Request yielded no regions."); 127 m_log.Debug("[WEBLOADER]: Request yielded no regions.");
105 tries--; 128 tries--;
@@ -108,8 +131,10 @@ namespace OpenSim.Framework.RegionLoader.Web
108 m_log.Debug("[WEBLOADER]: Retrying"); 131 m_log.Debug("[WEBLOADER]: Retrying");
109 System.Threading.Thread.Sleep(wait); 132 System.Threading.Thread.Sleep(wait);
110 } 133 }
111 } 134 }
112 return null; 135
136 m_log.Error("[WEBLOADER]: No region configs were available.");
137 return null;
113 } 138 }
114 } 139 }
115 } 140 }
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index c0d65ac..a6bdc2d 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -442,7 +442,7 @@ namespace OpenSim.Framework.Servers.HttpServer
442 string path = request.RawUrl; 442 string path = request.RawUrl;
443 string handlerKey = GetHandlerKey(request.HttpMethod, path); 443 string handlerKey = GetHandlerKey(request.HttpMethod, path);
444 444
445 //m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path); 445// m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path);
446 446
447 if (TryGetStreamHandler(handlerKey, out requestHandler)) 447 if (TryGetStreamHandler(handlerKey, out requestHandler))
448 { 448 {
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index 92ccb06..9d3a1cd 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -210,10 +210,6 @@ namespace OpenSim
210 /// </summary> 210 /// </summary>
211 private void RegisterConsoleCommands() 211 private void RegisterConsoleCommands()
212 { 212 {
213 m_console.Commands.AddCommand("region", false, "clear assets",
214 "clear assets",
215 "Clear the asset cache", HandleClearAssets);
216
217 m_console.Commands.AddCommand("region", false, "force update", 213 m_console.Commands.AddCommand("region", false, "force update",
218 "force update", 214 "force update",
219 "Force the update of all objects on clients", 215 "Force the update of all objects on clients",
@@ -509,11 +505,6 @@ namespace OpenSim
509 } 505 }
510 } 506 }
511 507
512 private void HandleClearAssets(string module, string[] args)
513 {
514 MainConsole.Instance.Output("Not implemented.");
515 }
516
517 /// <summary> 508 /// <summary>
518 /// Force resending of all updates to all clients in active region(s) 509 /// Force resending of all updates to all clients in active region(s)
519 /// </summary> 510 /// </summary>
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs
index dd0ea67..77f38ed 100644
--- a/OpenSim/Region/Application/OpenSimBase.cs
+++ b/OpenSim/Region/Application/OpenSimBase.cs
@@ -41,11 +41,15 @@ using OpenSim.Framework.Servers;
41using OpenSim.Framework.Servers.HttpServer; 41using OpenSim.Framework.Servers.HttpServer;
42using OpenSim.Framework.Statistics; 42using OpenSim.Framework.Statistics;
43using OpenSim.Region.ClientStack; 43using OpenSim.Region.ClientStack;
44using OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts;
44using OpenSim.Region.Framework; 45using OpenSim.Region.Framework;
45using OpenSim.Region.Framework.Interfaces; 46using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 47using OpenSim.Region.Framework.Scenes;
47using OpenSim.Region.Physics.Manager; 48using OpenSim.Region.Physics.Manager;
48using OpenSim.Server.Base; 49using OpenSim.Server.Base;
50using OpenSim.Services.Base;
51using OpenSim.Services.Interfaces;
52using OpenSim.Services.UserAccountService;
49 53
50namespace OpenSim 54namespace OpenSim
51{ 55{
@@ -411,6 +415,9 @@ namespace OpenSim
411 scene.SnmpService.BootInfo("Loading prins", scene); 415 scene.SnmpService.BootInfo("Loading prins", scene);
412 } 416 }
413 417
418 while (regionInfo.EstateSettings.EstateOwner == UUID.Zero && MainConsole.Instance != null)
419 SetUpEstateOwner(scene);
420
414 // Prims have to be loaded after module configuration since some modules may be invoked during the load 421 // Prims have to be loaded after module configuration since some modules may be invoked during the load
415 scene.LoadPrimsFromStorage(regionInfo.originRegionID); 422 scene.LoadPrimsFromStorage(regionInfo.originRegionID);
416 423
@@ -494,6 +501,64 @@ namespace OpenSim
494 return clientServer; 501 return clientServer;
495 } 502 }
496 503
504 /// <summary>
505 /// Try to set up the estate owner for the given scene.
506 /// </summary>
507 /// <remarks>
508 /// The involves asking the user for information about the user on the console. If the user does not already
509 /// exist then it is created.
510 /// </remarks>
511 /// <param name="scene"></param>
512 private void SetUpEstateOwner(Scene scene)
513 {
514 RegionInfo regionInfo = scene.RegionInfo;
515
516 MainConsole.Instance.OutputFormat("Estate {0} has no owner set.", regionInfo.EstateSettings.EstateName);
517 List<char> excluded = new List<char>(new char[1]{' '});
518 string first = MainConsole.Instance.CmdPrompt("Estate owner first name", "Test", excluded);
519 string last = MainConsole.Instance.CmdPrompt("Estate owner last name", "User", excluded);
520
521 UserAccount account = scene.UserAccountService.GetUserAccount(regionInfo.ScopeID, first, last);
522
523 if (account == null)
524 {
525
526 // XXX: The LocalUserAccountServicesConnector is currently registering its inner service rather than
527 // itself!
528// if (scene.UserAccountService is LocalUserAccountServicesConnector)
529// {
530// IUserAccountService innerUas
531// = ((LocalUserAccountServicesConnector)scene.UserAccountService).UserAccountService;
532//
533// m_log.DebugFormat("B {0}", innerUas.GetType());
534//
535// if (innerUas is UserAccountService)
536// {
537
538 if (scene.UserAccountService is UserAccountService)
539 {
540 string password = MainConsole.Instance.PasswdPrompt("Password");
541 string email = MainConsole.Instance.CmdPrompt("Email", "");
542
543 account
544 = ((UserAccountService)scene.UserAccountService).CreateUser(
545 regionInfo.ScopeID, first, last, password, email);
546 }
547// }
548 }
549
550 if (account == null)
551 {
552 m_log.ErrorFormat(
553 "[OPENSIM]: Unable to store account. If this simulator is connected to a grid, you must create the estate owner account first.");
554 }
555 else
556 {
557 regionInfo.EstateSettings.EstateOwner = account.PrincipalID;
558 regionInfo.EstateSettings.Save();
559 }
560 }
561
497 private void ShutdownRegion(Scene scene) 562 private void ShutdownRegion(Scene scene)
498 { 563 {
499 m_log.DebugFormat("[SHUTDOWN]: Shutting down region {0}", scene.RegionInfo.RegionName); 564 m_log.DebugFormat("[SHUTDOWN]: Shutting down region {0}", scene.RegionInfo.RegionName);
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
index 139d8b8..8d0c7a1 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
@@ -179,9 +179,10 @@ namespace OpenSim.Region.ClientStack.Linden
179 { 179 {
180 Queue<OSD> queue = GetQueue(avatarID); 180 Queue<OSD> queue = GetQueue(avatarID);
181 if (queue != null) 181 if (queue != null)
182 queue.Enqueue(ev); 182 lock (queue)
183 queue.Enqueue(ev);
183 } 184 }
184 catch(NullReferenceException e) 185 catch (NullReferenceException e)
185 { 186 {
186 m_log.Error("[EVENTQUEUE] Caught exception: " + e); 187 m_log.Error("[EVENTQUEUE] Caught exception: " + e);
187 return false; 188 return false;
@@ -338,12 +339,8 @@ namespace OpenSim.Region.ClientStack.Linden
338 Queue<OSD> queue = GetQueue(agentID); 339 Queue<OSD> queue = GetQueue(agentID);
339 if (queue != null) 340 if (queue != null)
340 lock (queue) 341 lock (queue)
341 { 342 return queue.Count > 0;
342 if (queue.Count > 0) 343
343 return true;
344 else
345 return false;
346 }
347 return false; 344 return false;
348 } 345 }
349 346
@@ -358,8 +355,6 @@ namespace OpenSim.Region.ClientStack.Linden
358 element = queue.Dequeue(); // 15s timeout 355 element = queue.Dequeue(); // 15s timeout
359 } 356 }
360 357
361
362
363 int thisID = 0; 358 int thisID = 0;
364 lock (m_ids) 359 lock (m_ids)
365 thisID = m_ids[pAgentId]; 360 thisID = m_ids[pAgentId];
@@ -431,7 +426,10 @@ namespace OpenSim.Region.ClientStack.Linden
431// } 426// }
432 427
433 Queue<OSD> queue = TryGetQueue(agentID); 428 Queue<OSD> queue = TryGetQueue(agentID);
434 OSD element = queue.Dequeue(); // 15s timeout 429 OSD element;
430
431 lock (queue)
432 element = queue.Dequeue(); // 15s timeout
435 433
436 Hashtable responsedata = new Hashtable(); 434 Hashtable responsedata = new Hashtable();
437 435
@@ -470,10 +468,14 @@ namespace OpenSim.Region.ClientStack.Linden
470 else 468 else
471 { 469 {
472 array.Add(element); 470 array.Add(element);
473 while (queue.Count > 0) 471
472 lock (queue)
474 { 473 {
475 array.Add(queue.Dequeue()); 474 while (queue.Count > 0)
476 thisID++; 475 {
476 array.Add(queue.Dequeue());
477 thisID++;
478 }
477 } 479 }
478 } 480 }
479 481
@@ -520,6 +522,7 @@ namespace OpenSim.Region.ClientStack.Linden
520 AvatarID = m_QueueUUIDAvatarMapping[capUUID]; 522 AvatarID = m_QueueUUIDAvatarMapping[capUUID];
521 } 523 }
522 } 524 }
525
523 if (AvatarID != UUID.Zero) 526 if (AvatarID != UUID.Zero)
524 { 527 {
525 return ProcessQueue(request, AvatarID, m_scene.CapsModule.GetCapsForUser(AvatarID)); 528 return ProcessQueue(request, AvatarID, m_scene.CapsModule.GetCapsForUser(AvatarID));
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index db81fea..575e5a2 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -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 Action<Vector3, bool> OnAutoPilotGo; 235 public event Action<Vector3, bool, 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;
@@ -4173,8 +4173,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4173 while (updatesThisCall < m_maxUpdates) 4173 while (updatesThisCall < m_maxUpdates)
4174 { 4174 {
4175 lock (m_entityProps.SyncRoot) 4175 lock (m_entityProps.SyncRoot)
4176 if (!m_entityProps.TryDequeue(out iupdate, out timeinqueue)) 4176 if (!m_entityProps.TryDequeue(out iupdate, out timeinqueue))
4177 break; 4177 break;
4178 4178
4179 ObjectPropertyUpdate update = (ObjectPropertyUpdate)iupdate; 4179 ObjectPropertyUpdate update = (ObjectPropertyUpdate)iupdate;
4180 if (update.SendFamilyProps) 4180 if (update.SendFamilyProps)
@@ -6145,9 +6145,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6145 RezMultipleAttachmentsFromInv handlerRezMultipleAttachments = OnRezMultipleAttachmentsFromInv; 6145 RezMultipleAttachmentsFromInv handlerRezMultipleAttachments = OnRezMultipleAttachmentsFromInv;
6146 if (handlerRezMultipleAttachments != null) 6146 if (handlerRezMultipleAttachments != null)
6147 { 6147 {
6148 RezMultipleAttachmentsFromInvPacket rez = (RezMultipleAttachmentsFromInvPacket)Pack; 6148 List<KeyValuePair<UUID, uint>> rezlist = new List<KeyValuePair<UUID, uint>>();
6149 handlerRezMultipleAttachments(this, rez.HeaderData, 6149 foreach (RezMultipleAttachmentsFromInvPacket.ObjectDataBlock obj in ((RezMultipleAttachmentsFromInvPacket)Pack).ObjectData)
6150 rez.ObjectData); 6150 rezlist.Add(new KeyValuePair<UUID, uint>(obj.ItemID, obj.AttachmentPt));
6151 handlerRezMultipleAttachments(this, rezlist);
6151 } 6152 }
6152 6153
6153 return true; 6154 return true;
@@ -11756,9 +11757,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11756 locy = Convert.ToSingle(args[1]) - (float)regionY; 11757 locy = Convert.ToSingle(args[1]) - (float)regionY;
11757 locz = Convert.ToSingle(args[2]); 11758 locz = Convert.ToSingle(args[2]);
11758 11759
11759 Action<Vector3, bool> handlerAutoPilotGo = OnAutoPilotGo; 11760 Action<Vector3, bool, bool> handlerAutoPilotGo = OnAutoPilotGo;
11760 if (handlerAutoPilotGo != null) 11761 if (handlerAutoPilotGo != null)
11761 handlerAutoPilotGo(new Vector3(locx, locy, locz), false); 11762 handlerAutoPilotGo(new Vector3(locx, locy, locz), false, false);
11762 } 11763 }
11763 11764
11764 /// <summary> 11765 /// <summary>
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index fead4d9..d5b061b 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -929,25 +929,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
929 UUID sessionID = useCircuitCode.CircuitCode.SessionID; 929 UUID sessionID = useCircuitCode.CircuitCode.SessionID;
930 uint circuitCode = useCircuitCode.CircuitCode.Code; 930 uint circuitCode = useCircuitCode.CircuitCode.Code;
931 931
932 if (m_scene.RegionStatus != RegionStatus.SlaveScene) 932 AuthenticateResponse sessionInfo;
933 if (IsClientAuthorized(useCircuitCode, out sessionInfo))
933 { 934 {
934 AuthenticateResponse sessionInfo; 935 AddClient(circuitCode, agentID, sessionID, remoteEndPoint, sessionInfo);
935 if (IsClientAuthorized(useCircuitCode, out sessionInfo))
936 {
937 AddClient(circuitCode, agentID, sessionID, remoteEndPoint, sessionInfo);
938 }
939 else
940 {
941 // Don't create circuits for unauthorized clients
942 m_log.WarnFormat(
943 "[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
944 useCircuitCode.CircuitCode.ID, useCircuitCode.CircuitCode.Code, remoteEndPoint);
945 }
946 } 936 }
947 else 937 else
948 { 938 {
949 // Slave regions don't accept new clients 939 // Don't create circuits for unauthorized clients
950 m_log.Debug("[LLUDPSERVER]: Slave region " + m_scene.RegionInfo.RegionName + " ignoring UseCircuitCode packet"); 940 m_log.WarnFormat(
941 "[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
942 useCircuitCode.CircuitCode.ID, useCircuitCode.CircuitCode.Code, remoteEndPoint);
951 } 943 }
952 } 944 }
953 945
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
index ff4ec4c..eed7cd5 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
@@ -41,14 +41,13 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
41 /// </summary> 41 /// </summary>
42 public class AgentAssetTransactions 42 public class AgentAssetTransactions
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 // Fields 46 // Fields
47 private bool m_dumpAssetsToFile; 47 private bool m_dumpAssetsToFile;
48 private Scene m_Scene; 48 private Scene m_Scene;
49 public UUID UserID; 49 private UUID UserID;
50 public Dictionary<UUID, AssetXferUploader> XferUploaders = 50 private Dictionary<UUID, AssetXferUploader> XferUploaders = new Dictionary<UUID, AssetXferUploader>();
51 new Dictionary<UUID, AssetXferUploader>();
52 51
53 // Methods 52 // Methods
54 public AgentAssetTransactions(UUID agentID, Scene scene, 53 public AgentAssetTransactions(UUID agentID, Scene scene,
@@ -59,36 +58,94 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
59 m_dumpAssetsToFile = dumpAssetsToFile; 58 m_dumpAssetsToFile = dumpAssetsToFile;
60 } 59 }
61 60
62 public AssetXferUploader RequestXferUploader(UUID transactionID) 61 /// <summary>
62 /// Return a xfer uploader if one does not already exist.
63 /// </summary>
64 /// <param name="transactionID"></param>
65 /// <param name="assetID">
66 /// We must transfer the new asset ID into the uploader on creation, otherwise
67 /// we can see race conditions with other threads which can retrieve an item before it is updated with the new
68 /// asset id.
69 /// </param>
70 /// <returns>
71 /// The xfer uploader requested. Null if one is already in existence.
72 /// FIXME: This is a bizarre thing to do, and is probably meant to signal an error condition if multiple
73 /// transfers are made. Needs to be corrected.
74 /// </returns>
75 public AssetXferUploader RequestXferUploader(UUID transactionID, UUID assetID)
63 { 76 {
64 if (!XferUploaders.ContainsKey(transactionID)) 77 lock (XferUploaders)
65 { 78 {
66 AssetXferUploader uploader = new AssetXferUploader(m_Scene, 79 if (!XferUploaders.ContainsKey(transactionID))
67 m_dumpAssetsToFile);
68
69 lock (XferUploaders)
70 { 80 {
81 AssetXferUploader uploader = new AssetXferUploader(this, m_Scene, assetID, m_dumpAssetsToFile);
82
83// m_log.DebugFormat(
84// "[AGENT ASSETS TRANSACTIONS]: Adding asset xfer uploader {0} since it didn't previously exist", transactionID);
85
71 XferUploaders.Add(transactionID, uploader); 86 XferUploaders.Add(transactionID, uploader);
72 }
73 87
74 return uploader; 88 return uploader;
89 }
75 } 90 }
91
92 m_log.WarnFormat("[AGENT ASSETS TRANSACTIONS]: Ignoring request for asset xfer uploader {0} since it already exists", transactionID);
93
76 return null; 94 return null;
77 } 95 }
78 96
79 public void HandleXfer(ulong xferID, uint packetID, byte[] data) 97 public void HandleXfer(ulong xferID, uint packetID, byte[] data)
80 { 98 {
99 AssetXferUploader foundUploader = null;
100
81 lock (XferUploaders) 101 lock (XferUploaders)
82 { 102 {
83 foreach (AssetXferUploader uploader in XferUploaders.Values) 103 foreach (AssetXferUploader uploader in XferUploaders.Values)
84 { 104 {
105// m_log.DebugFormat(
106// "[AGENT ASSETS TRANSACTIONS]: In HandleXfer, inspect xfer upload with xfer id {0}",
107// uploader.XferID);
108
85 if (uploader.XferID == xferID) 109 if (uploader.XferID == xferID)
86 { 110 {
87 uploader.HandleXferPacket(xferID, packetID, data); 111 foundUploader = uploader;
88 break; 112 break;
89 } 113 }
90 } 114 }
91 } 115 }
116
117 if (foundUploader != null)
118 {
119// m_log.DebugFormat(
120// "[AGENT ASSETS TRANSACTIONS]: Found xfer uploader for xfer id {0}, packet id {1}, data length {2}",
121// xferID, packetID, data.Length);
122
123 foundUploader.HandleXferPacket(xferID, packetID, data);
124 }
125 else
126 {
127 m_log.ErrorFormat(
128 "[AGENT ASSET TRANSACTIONS]: Could not find uploader for xfer id {0}, packet id {1}, data length {2}",
129 xferID, packetID, data.Length);
130 }
131 }
132
133 public bool RemoveXferUploader(UUID transactionID)
134 {
135 lock (XferUploaders)
136 {
137 bool removed = XferUploaders.Remove(transactionID);
138
139 if (!removed)
140 m_log.WarnFormat(
141 "[AGENT ASSET TRANSACTIONS]: Received request to remove xfer uploader with transaction ID {0} but none found",
142 transactionID);
143// else
144// m_log.DebugFormat(
145// "[AGENT ASSET TRANSACTIONS]: Removed xfer uploader with transaction ID {0}", transactionID);
146
147 return removed;
148 }
92 } 149 }
93 150
94 public void RequestCreateInventoryItem(IClientAPI remoteClient, 151 public void RequestCreateInventoryItem(IClientAPI remoteClient,
@@ -96,16 +153,24 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
96 string description, string name, sbyte invType, 153 string description, string name, sbyte invType,
97 sbyte type, byte wearableType, uint nextOwnerMask) 154 sbyte type, byte wearableType, uint nextOwnerMask)
98 { 155 {
99 if (XferUploaders.ContainsKey(transactionID)) 156 AssetXferUploader uploader = null;
157
158 lock (XferUploaders)
100 { 159 {
101 XferUploaders[transactionID].RequestCreateInventoryItem( 160 if (XferUploaders.ContainsKey(transactionID))
102 remoteClient, transactionID, folderID, 161 uploader = XferUploaders[transactionID];
103 callbackID, description, name, invType, type,
104 wearableType, nextOwnerMask);
105 } 162 }
106 }
107
108 163
164 if (uploader != null)
165 uploader.RequestCreateInventoryItem(
166 remoteClient, transactionID, folderID,
167 callbackID, description, name, invType, type,
168 wearableType, nextOwnerMask);
169 else
170 m_log.ErrorFormat(
171 "[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to create inventory item {1} from {2}",
172 transactionID, name, remoteClient.Name);
173 }
109 174
110 /// <summary> 175 /// <summary>
111 /// Get an uploaded asset. If the data is successfully retrieved, 176 /// Get an uploaded asset. If the data is successfully retrieved,
@@ -113,19 +178,18 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
113 /// </summary> 178 /// </summary>
114 /// <param name="transactionID"></param> 179 /// <param name="transactionID"></param>
115 /// <returns>The asset if the upload has completed, null if it has not.</returns> 180 /// <returns>The asset if the upload has completed, null if it has not.</returns>
116 public AssetBase GetTransactionAsset(UUID transactionID) 181 private AssetBase GetTransactionAsset(UUID transactionID)
117 { 182 {
118 if (XferUploaders.ContainsKey(transactionID)) 183 lock (XferUploaders)
119 { 184 {
120 AssetXferUploader uploader = XferUploaders[transactionID]; 185 if (XferUploaders.ContainsKey(transactionID))
121 AssetBase asset = uploader.GetAssetData();
122
123 lock (XferUploaders)
124 { 186 {
125 XferUploaders.Remove(transactionID); 187 AssetXferUploader uploader = XferUploaders[transactionID];
126 } 188 AssetBase asset = uploader.GetAssetData();
189 RemoveXferUploader(transactionID);
127 190
128 return asset; 191 return asset;
192 }
129 } 193 }
130 194
131 return null; 195 return null;
@@ -135,7 +199,15 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
135 SceneObjectPart part, UUID transactionID, 199 SceneObjectPart part, UUID transactionID,
136 TaskInventoryItem item) 200 TaskInventoryItem item)
137 { 201 {
138 if (XferUploaders.ContainsKey(transactionID)) 202 AssetXferUploader uploader = null;
203
204 lock (XferUploaders)
205 {
206 if (XferUploaders.ContainsKey(transactionID))
207 uploader = XferUploaders[transactionID];
208 }
209
210 if (uploader != null)
139 { 211 {
140 AssetBase asset = GetTransactionAsset(transactionID); 212 AssetBase asset = GetTransactionAsset(transactionID);
141 213
@@ -161,44 +233,34 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
161 m_Scene.AssetService.Store(asset); 233 m_Scene.AssetService.Store(asset);
162 } 234 }
163 } 235 }
236 else
237 {
238 m_log.ErrorFormat(
239 "[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to update task inventory item {1} in {2}",
240 transactionID, item.Name, part.Name);
241 }
164 } 242 }
165 243
166 public void RequestUpdateInventoryItem(IClientAPI remoteClient, 244 public void RequestUpdateInventoryItem(IClientAPI remoteClient,
167 UUID transactionID, InventoryItemBase item) 245 UUID transactionID, InventoryItemBase item)
168 { 246 {
169 if (XferUploaders.ContainsKey(transactionID)) 247 AssetXferUploader uploader = null;
170 {
171// m_log.DebugFormat("[XFER]: Asked to update item {0} ({1})",
172// item.Name, item.ID);
173
174 // Here we need to get the old asset to extract the
175 // texture UUIDs if it's a wearable.
176 if (item.AssetType == (int)AssetType.Bodypart ||
177 item.AssetType == (int)AssetType.Clothing)
178 {
179 AssetBase oldAsset = m_Scene.AssetService.Get(item.AssetID.ToString());
180 if (oldAsset != null)
181 XferUploaders[transactionID].SetOldData(oldAsset.Data);
182 }
183
184 AssetBase asset = GetTransactionAsset(transactionID);
185 248
186 if (asset != null) 249 lock (XferUploaders)
187 { 250 {
188 asset.FullID = UUID.Random(); 251 if (XferUploaders.ContainsKey(transactionID))
189 asset.Name = item.Name; 252 uploader = XferUploaders[transactionID];
190 asset.Description = item.Description; 253 }
191 asset.Type = (sbyte)item.AssetType;
192 item.AssetID = asset.FullID;
193
194 m_Scene.AssetService.Store(asset);
195
196 IInventoryService invService = m_Scene.InventoryService;
197 invService.UpdateItem(item);
198 254
199// m_log.DebugFormat("[XFER]: Updated item {0} ({1}) with asset {2}", 255 if (uploader != null)
200// item.Name, item.ID, asset.FullID); 256 {
201 } 257 uploader.RequestUpdateInventoryItem(remoteClient, transactionID, item);
258 }
259 else
260 {
261 m_log.ErrorFormat(
262 "[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to update inventory item {1} for {2}",
263 transactionID, item.Name, remoteClient.Name);
202 } 264 }
203 } 265 }
204 } 266 }
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
index 82558de..a28d5d7 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
@@ -172,11 +172,12 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
172 /// <summary> 172 /// <summary>
173 /// Update an inventory item with data that has been received through a 173 /// Update an inventory item with data that has been received through a
174 /// transaction. 174 /// transaction.
175 /// 175 /// </summary>
176 /// <remarks>
176 /// This is called when clothing or body parts are updated (for 177 /// This is called when clothing or body parts are updated (for
177 /// instance, with new textures or colours). It may also be called in 178 /// instance, with new textures or colours). It may also be called in
178 /// other situations. 179 /// other situations.
179 /// </summary> 180 /// </remarks>
180 /// <param name="remoteClient"></param> 181 /// <param name="remoteClient"></param>
181 /// <param name="transactionID"></param> 182 /// <param name="transactionID"></param>
182 /// <param name="item"></param> 183 /// <param name="item"></param>
@@ -184,14 +185,12 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
184 UUID transactionID, InventoryItemBase item) 185 UUID transactionID, InventoryItemBase item)
185 { 186 {
186// m_log.DebugFormat( 187// m_log.DebugFormat(
187// "[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}", 188// "[ASSET TRANSACTION MODULE]: Called HandleItemUpdateFromTransaction with item {0}",
188// item.Name); 189// item.Name);
189 190
190 AgentAssetTransactions transactions = 191 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
191 GetUserTransactions(remoteClient.AgentId);
192 192
193 transactions.RequestUpdateInventoryItem(remoteClient, 193 transactions.RequestUpdateInventoryItem(remoteClient, transactionID, item);
194 transactionID, item);
195 } 194 }
196 195
197 /// <summary> 196 /// <summary>
@@ -255,11 +254,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
255 } 254 }
256 } 255 }
257 256
258 AgentAssetTransactions transactions = 257 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
259 GetUserTransactions(remoteClient.AgentId); 258 AssetXferUploader uploader = transactions.RequestXferUploader(transaction, assetID);
260
261 AssetXferUploader uploader =
262 transactions.RequestXferUploader(transaction);
263 259
264 if (uploader != null) 260 if (uploader != null)
265 { 261 {
@@ -279,9 +275,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
279 public void HandleXfer(IClientAPI remoteClient, ulong xferID, 275 public void HandleXfer(IClientAPI remoteClient, ulong xferID,
280 uint packetID, byte[] data) 276 uint packetID, byte[] data)
281 { 277 {
282 //m_log.Debug("xferID: " + xferID + " packetID: " + packetID + " data!"); 278// m_log.Debug("xferID: " + xferID + " packetID: " + packetID + " data length " + data.Length);
283 AgentAssetTransactions transactions = 279 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
284 GetUserTransactions(remoteClient.AgentId);
285 280
286 transactions.HandleXfer(xferID, packetID, data); 281 transactions.HandleXfer(xferID, packetID, data);
287 } 282 }
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
index a5dcdcc..4cedfe6 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
@@ -48,11 +48,21 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
48 }; 48 };
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 50
51 /// <summary>
52 /// Reference to the object that holds this uploader. Used to remove ourselves from it's list if we
53 /// are performing a delayed update.
54 /// </summary>
55 AgentAssetTransactions m_transactions;
56
51 private AssetBase m_asset; 57 private AssetBase m_asset;
52 private UUID InventFolder = UUID.Zero; 58 private UUID InventFolder = UUID.Zero;
53 private sbyte invType = 0; 59 private sbyte invType = 0;
60
54 private bool m_createItem = false; 61 private bool m_createItem = false;
55 private uint m_createItemCallback = 0; 62 private uint m_createItemCallback = 0;
63 private bool m_updateItem = false;
64 private InventoryItemBase m_updateItemData;
65
56 private string m_description = String.Empty; 66 private string m_description = String.Empty;
57 private bool m_dumpAssetToFile; 67 private bool m_dumpAssetToFile;
58 private bool m_finished = false; 68 private bool m_finished = false;
@@ -67,9 +77,11 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
67 public ulong XferID; 77 public ulong XferID;
68 private Scene m_Scene; 78 private Scene m_Scene;
69 79
70 public AssetXferUploader(Scene scene, bool dumpAssetToFile) 80 public AssetXferUploader(AgentAssetTransactions transactions, Scene scene, UUID assetID, bool dumpAssetToFile)
71 { 81 {
82 m_transactions = transactions;
72 m_Scene = scene; 83 m_Scene = scene;
84 m_asset = new AssetBase() { FullID = assetID };
73 m_dumpAssetToFile = dumpAssetToFile; 85 m_dumpAssetToFile = dumpAssetToFile;
74 } 86 }
75 87
@@ -82,6 +94,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
82 /// <returns>True if the transfer is complete, false otherwise or if the xferID was not valid</returns> 94 /// <returns>True if the transfer is complete, false otherwise or if the xferID was not valid</returns>
83 public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data) 95 public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data)
84 { 96 {
97// m_log.DebugFormat(
98// "[ASSET XFER UPLOADER]: Received packet {0} for xfer {1} (data length {2})",
99// packetID, xferID, data.Length);
100
85 if (XferID == xferID) 101 if (XferID == xferID)
86 { 102 {
87 if (m_asset.Data.Length > 1) 103 if (m_asset.Data.Length > 1)
@@ -116,16 +132,20 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
116 /// <param name="xferID"></param> 132 /// <param name="xferID"></param>
117 /// <param name="packetID"></param> 133 /// <param name="packetID"></param>
118 /// <param name="data"></param> 134 /// <param name="data"></param>
119 /// <returns>True if the transfer is complete, false otherwise</returns> 135 public void Initialise(IClientAPI remoteClient, UUID assetID,
120 public bool Initialise(IClientAPI remoteClient, UUID assetID,
121 UUID transaction, sbyte type, byte[] data, bool storeLocal, 136 UUID transaction, sbyte type, byte[] data, bool storeLocal,
122 bool tempFile) 137 bool tempFile)
123 { 138 {
139// m_log.DebugFormat(
140// "[ASSET XFER UPLOADER]: Initialised xfer from {0}, asset {1}, transaction {2}, type {3}, storeLocal {4}, tempFile {5}, already received data length {6}",
141// remoteClient.Name, assetID, transaction, type, storeLocal, tempFile, data.Length);
142
124 ourClient = remoteClient; 143 ourClient = remoteClient;
125 m_asset = new AssetBase(assetID, "blank", type, 144 m_asset.Name = "blank";
126 remoteClient.AgentId.ToString());
127 m_asset.Data = data;
128 m_asset.Description = "empty"; 145 m_asset.Description = "empty";
146 m_asset.Type = type;
147 m_asset.CreatorID = remoteClient.AgentId.ToString();
148 m_asset.Data = data;
129 m_asset.Local = storeLocal; 149 m_asset.Local = storeLocal;
130 m_asset.Temporary = tempFile; 150 m_asset.Temporary = tempFile;
131 151
@@ -135,21 +155,22 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
135 if (m_asset.Data.Length > 2) 155 if (m_asset.Data.Length > 2)
136 { 156 {
137 SendCompleteMessage(); 157 SendCompleteMessage();
138 return true;
139 } 158 }
140 else 159 else
141 { 160 {
142 RequestStartXfer(); 161 RequestStartXfer();
143 } 162 }
144
145 return false;
146 } 163 }
147 164
148 protected void RequestStartXfer() 165 protected void RequestStartXfer()
149 { 166 {
150 XferID = Util.GetNextXferID(); 167 XferID = Util.GetNextXferID();
151 ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, 168
152 0, new byte[0]); 169// m_log.DebugFormat(
170// "[ASSET XFER UPLOADER]: Requesting Xfer of asset {0}, type {1}, transfer id {2} from {3}",
171// m_asset.FullID, m_asset.Type, XferID, ourClient.Name);
172
173 ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, 0, new byte[0]);
153 } 174 }
154 175
155 protected void SendCompleteMessage() 176 protected void SendCompleteMessage()
@@ -157,18 +178,32 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
157 ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, 178 ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true,
158 m_asset.FullID); 179 m_asset.FullID);
159 180
160 m_finished = true; 181 // We must lock in order to avoid a race with a separate thread dealing with an inventory item or create
161 if (m_createItem) 182 // message from other client UDP.
183 lock (this)
162 { 184 {
163 DoCreateItem(m_createItemCallback); 185 m_finished = true;
164 } 186 if (m_createItem)
165 else if (m_storeLocal) 187 {
166 { 188 DoCreateItem(m_createItemCallback);
167 m_Scene.AssetService.Store(m_asset); 189 }
190 else if (m_updateItem)
191 {
192 StoreAssetForItemUpdate(m_updateItemData);
193
194 // Remove ourselves from the list of transactions if completion was delayed until the transaction
195 // was complete.
196 // TODO: Should probably do the same for create item.
197 m_transactions.RemoveXferUploader(TransactionID);
198 }
199 else if (m_storeLocal)
200 {
201 m_Scene.AssetService.Store(m_asset);
202 }
168 } 203 }
169 204
170 m_log.DebugFormat( 205 m_log.DebugFormat(
171 "[ASSET TRANSACTIONS]: Uploaded asset {0} for transaction {1}", 206 "[ASSET XFER UPLOADER]: Uploaded asset {0} for transaction {1}",
172 m_asset.FullID, TransactionID); 207 m_asset.FullID, TransactionID);
173 208
174 if (m_dumpAssetToFile) 209 if (m_dumpAssetToFile)
@@ -214,18 +249,66 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
214 m_asset.Description = description; 249 m_asset.Description = description;
215 m_asset.Type = type; 250 m_asset.Type = type;
216 251
252 // We must lock to avoid a race with a separate thread uploading the asset.
253 lock (this)
254 {
255 if (m_finished)
256 {
257 DoCreateItem(callbackID);
258 }
259 else
260 {
261 m_createItem = true; //set flag so the inventory item is created when upload is complete
262 m_createItemCallback = callbackID;
263 }
264 }
265 }
266 }
267
268 public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID, InventoryItemBase item)
269 {
270 // We must lock to avoid a race with a separate thread uploading the asset.
271 lock (this)
272 {
273 m_asset.Name = item.Name;
274 m_asset.Description = item.Description;
275 m_asset.Type = (sbyte)item.AssetType;
276
277 // We must always store the item at this point even if the asset hasn't finished uploading, in order
278 // to avoid a race condition when the appearance module retrieves the item to set the asset id in
279 // the AvatarAppearance structure.
280 item.AssetID = m_asset.FullID;
281 m_Scene.InventoryService.UpdateItem(item);
282
217 if (m_finished) 283 if (m_finished)
218 { 284 {
219 DoCreateItem(callbackID); 285 StoreAssetForItemUpdate(item);
220 } 286 }
221 else 287 else
222 { 288 {
223 m_createItem = true; //set flag so the inventory item is created when upload is complete 289// m_log.DebugFormat(
224 m_createItemCallback = callbackID; 290// "[ASSET XFER UPLOADER]: Holding update inventory item request {0} for {1} pending completion of asset xfer for transaction {2}",
291// item.Name, remoteClient.Name, transactionID);
292
293 m_updateItem = true;
294 m_updateItemData = item;
225 } 295 }
226 } 296 }
227 } 297 }
228 298
299 /// <summary>
300 /// Store the asset for the given item.
301 /// </summary>
302 /// <param name="item"></param>
303 private void StoreAssetForItemUpdate(InventoryItemBase item)
304 {
305// m_log.DebugFormat(
306// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}",
307// m_asset.FullID, item.Name, ourClient.Name);
308
309 m_Scene.AssetService.Store(m_asset);
310 }
311
229 private void DoCreateItem(uint callbackID) 312 private void DoCreateItem(uint callbackID)
230 { 313 {
231 ValidateAssets(); 314 ValidateAssets();
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index a130ed2..09781c7 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -45,29 +45,47 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AttachmentsModule")] 45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AttachmentsModule")]
46 public class AttachmentsModule : IAttachmentsModule, INonSharedRegionModule 46 public class AttachmentsModule : IAttachmentsModule, INonSharedRegionModule
47 { 47 {
48 #region INonSharedRegionModule
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49 50
50 private Scene m_scene; 51 private Scene m_scene;
51 private IDialogModule m_dialogModule; 52 private IDialogModule m_dialogModule;
53
54 /// <summary>
55 /// Are attachments enabled?
56 /// </summary>
57 public bool Enabled { get; private set; }
52 58
53 public string Name { get { return "Attachments Module"; } } 59 public string Name { get { return "Attachments Module"; } }
54 public Type ReplaceableInterface { get { return null; } } 60 public Type ReplaceableInterface { get { return null; } }
55 61
56 public void Initialise(IConfigSource source) {} 62 public void Initialise(IConfigSource source)
63 {
64 IConfig config = source.Configs["Attachments"];
65 if (config != null)
66 Enabled = config.GetBoolean("Enabled", true);
67 else
68 Enabled = true;
69 }
57 70
58 public void AddRegion(Scene scene) 71 public void AddRegion(Scene scene)
59 { 72 {
60 m_scene = scene; 73 m_scene = scene;
61 m_dialogModule = m_scene.RequestModuleInterface<IDialogModule>(); 74 m_dialogModule = m_scene.RequestModuleInterface<IDialogModule>();
62 m_scene.RegisterModuleInterface<IAttachmentsModule>(this); 75 m_scene.RegisterModuleInterface<IAttachmentsModule>(this);
63 m_scene.EventManager.OnNewClient += SubscribeToClientEvents; 76
77 if (Enabled)
78 m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
79
64 // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI 80 // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI
65 } 81 }
66 82
67 public void RemoveRegion(Scene scene) 83 public void RemoveRegion(Scene scene)
68 { 84 {
69 m_scene.UnregisterModuleInterface<IAttachmentsModule>(this); 85 m_scene.UnregisterModuleInterface<IAttachmentsModule>(this);
70 m_scene.EventManager.OnNewClient -= SubscribeToClientEvents; 86
87 if (Enabled)
88 m_scene.EventManager.OnNewClient -= SubscribeToClientEvents;
71 } 89 }
72 90
73 public void RegionLoaded(Scene scene) {} 91 public void RegionLoaded(Scene scene) {}
@@ -76,26 +94,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
76 { 94 {
77 RemoveRegion(m_scene); 95 RemoveRegion(m_scene);
78 } 96 }
79 97
80 public void SubscribeToClientEvents(IClientAPI client) 98 #endregion
81 { 99
82 client.OnRezSingleAttachmentFromInv += RezSingleAttachmentFromInventory; 100 #region IAttachmentsModule
83 client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachmentsFromInventory;
84 client.OnObjectAttach += AttachObject;
85 client.OnObjectDetach += DetachObject;
86 client.OnDetachAttachmentIntoInv += DetachSingleAttachmentToInv;
87 client.OnObjectDrop += DetachSingleAttachmentToGround;
88 }
89
90 public void UnsubscribeFromClientEvents(IClientAPI client)
91 {
92 client.OnRezSingleAttachmentFromInv -= RezSingleAttachmentFromInventory;
93 client.OnRezMultipleAttachmentsFromInv -= RezMultipleAttachmentsFromInventory;
94 client.OnObjectAttach -= AttachObject;
95 client.OnObjectDetach -= DetachObject;
96 client.OnDetachAttachmentIntoInv -= DetachSingleAttachmentToInv;
97 client.OnObjectDrop -= DetachSingleAttachmentToGround;
98 }
99 101
100 /// <summary> 102 /// <summary>
101 /// RezAttachments. This should only be called upon login on the first region. 103 /// RezAttachments. This should only be called upon login on the first region.
@@ -103,6 +105,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
103 /// </summary> 105 /// </summary>
104 public void RezAttachments(IScenePresence sp) 106 public void RezAttachments(IScenePresence sp)
105 { 107 {
108 if (!Enabled)
109 return;
110
106 if (null == sp.Appearance) 111 if (null == sp.Appearance)
107 { 112 {
108 m_log.WarnFormat("[ATTACHMENTS MODULE]: Appearance has not been initialized for agent {0}", sp.UUID); 113 m_log.WarnFormat("[ATTACHMENTS MODULE]: Appearance has not been initialized for agent {0}", sp.UUID);
@@ -133,7 +138,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
133 if (sp.PresenceType == PresenceType.Npc) 138 if (sp.PresenceType == PresenceType.Npc)
134 RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null); 139 RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null);
135 else 140 else
136 RezSingleAttachmentFromInventory(sp.ControllingClient, attach.ItemID, p); 141 RezSingleAttachmentFromInventory(sp, attach.ItemID, p);
137 } 142 }
138 catch (Exception e) 143 catch (Exception e)
139 { 144 {
@@ -146,13 +151,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
146 { 151 {
147// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); 152// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name);
148 153
154 if (!Enabled)
155 return;
156
149 foreach (SceneObjectGroup grp in sp.GetAttachments()) 157 foreach (SceneObjectGroup grp in sp.GetAttachments())
150 { 158 {
151// if (grp.HasGroupChanged) // Resizer scripts? 159// if (grp.HasGroupChanged) // Resizer scripts?
152// { 160// {
153 grp.IsAttachment = false; 161 grp.IsAttachment = false;
154 grp.AbsolutePosition = grp.RootPart.AttachedPos; 162 grp.AbsolutePosition = grp.RootPart.AttachedPos;
155 UpdateKnownItem(sp.ControllingClient, grp); 163 UpdateKnownItem(sp, grp);
156 grp.IsAttachment = true; 164 grp.IsAttachment = true;
157// } 165// }
158 } 166 }
@@ -164,6 +172,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
164// "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}", 172// "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}",
165// m_scene.RegionInfo.RegionName, sp.Name, silent); 173// m_scene.RegionInfo.RegionName, sp.Name, silent);
166 174
175 if (!Enabled)
176 return;
177
167 foreach (SceneObjectGroup sop in sp.GetAttachments()) 178 foreach (SceneObjectGroup sop in sp.GetAttachments())
168 { 179 {
169 sop.Scene.DeleteSceneObject(sop, silent); 180 sop.Scene.DeleteSceneObject(sop, silent);
@@ -172,87 +183,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
172 sp.ClearAttachments(); 183 sp.ClearAttachments();
173 } 184 }
174 185
175 /// <summary> 186 public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent)
176 /// Called by client
177 /// </summary>
178 /// <param name="remoteClient"></param>
179 /// <param name="objectLocalID"></param>
180 /// <param name="AttachmentPt"></param>
181 /// <param name="silent"></param>
182 public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent)
183 {
184// m_log.DebugFormat(
185// "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})",
186// objectLocalID, remoteClient.Name, AttachmentPt, silent);
187
188 try
189 {
190 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
191
192 if (sp == null)
193 {
194 m_log.ErrorFormat(
195 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId);
196 return;
197 }
198
199 // If we can't take it, we can't attach it!
200 SceneObjectPart part = m_scene.GetSceneObjectPart(objectLocalID);
201 if (part == null)
202 return;
203
204 if (!m_scene.Permissions.CanTakeObject(part.UUID, remoteClient.AgentId))
205 {
206 remoteClient.SendAgentAlertMessage(
207 "You don't have sufficient permissions to attach this object", false);
208
209 return;
210 }
211
212 if (part.OwnerID != remoteClient.AgentId) // Not ours
213 {
214 remoteClient.SendAgentAlertMessage(
215 "You don't have sufficient permissions to attach this object", false);
216 return;
217 }
218
219 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
220 // be removed when that functionality is implemented in opensim
221 AttachmentPt &= 0x7f;
222
223 // Calls attach with a Zero position
224 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false))
225 {
226 m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
227
228 // Save avatar attachment information
229 m_log.Debug(
230 "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
231 + ", AttachmentPoint: " + AttachmentPt);
232
233 }
234 }
235 catch (Exception e)
236 {
237 m_log.ErrorFormat("[ATTACHMENTS MODULE]: exception upon Attach Object {0}{1}", e.Message, e.StackTrace);
238 }
239 }
240
241 public bool AttachObject(IClientAPI remoteClient, SceneObjectGroup group, uint AttachmentPt, bool silent)
242 {
243 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
244
245 if (sp == null)
246 {
247 m_log.ErrorFormat(
248 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId);
249 return false;
250 }
251
252 return AttachObject(sp, group, AttachmentPt, silent);
253 }
254
255 private bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent)
256 { 187 {
257 lock (sp.AttachmentsSyncLock) 188 lock (sp.AttachmentsSyncLock)
258 { 189 {
@@ -313,7 +244,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
313 UUID oldAttachmentItemID = attachments[0].GetFromItemID(); 244 UUID oldAttachmentItemID = attachments[0].GetFromItemID();
314 245
315 if (oldAttachmentItemID != UUID.Zero) 246 if (oldAttachmentItemID != UUID.Zero)
316 DetachSingleAttachmentToInv(oldAttachmentItemID, sp); 247 DetachSingleAttachmentToInvInternal(sp, oldAttachmentItemID);
317 else 248 else
318 m_log.WarnFormat( 249 m_log.WarnFormat(
319 "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!", 250 "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!",
@@ -323,7 +254,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
323 // Add the new attachment to inventory if we don't already have it. 254 // Add the new attachment to inventory if we don't already have it.
324 UUID newAttachmentItemID = group.GetFromItemID(); 255 UUID newAttachmentItemID = group.GetFromItemID();
325 if (newAttachmentItemID == UUID.Zero) 256 if (newAttachmentItemID == UUID.Zero)
326 newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp.ControllingClient, group).ID; 257 newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
327 258
328 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group); 259 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group);
329 } 260 }
@@ -334,55 +265,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
334 return true; 265 return true;
335 } 266 }
336 267
337 public void RezMultipleAttachmentsFromInventory( 268 public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt)
338 IClientAPI remoteClient, 269 {
339 RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header, 270 return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt, true, null);
340 RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects) 271 }
341 {
342 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
343
344 if (sp == null)
345 {
346 m_log.ErrorFormat(
347 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezMultipleAttachmentsFromInventory()",
348 remoteClient.Name, remoteClient.AgentId);
349 return;
350 }
351
352 lock (sp.AttachmentsSyncLock)
353 {
354// m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name);
355
356 foreach (RezMultipleAttachmentsFromInvPacket.ObjectDataBlock obj in objects)
357 {
358 RezSingleAttachmentFromInventory(sp, obj.ItemID, obj.AttachmentPt);
359 }
360 }
361 }
362
363 public ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
364 {
365 return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true, null);
366 }
367 272
368 public ISceneEntity RezSingleAttachmentFromInventory( 273 public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt, bool updateInventoryStatus, XmlDocument doc)
369 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus, XmlDocument doc)
370 { 274 {
371 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); 275 if (!Enabled)
372
373 if (sp == null)
374 {
375 m_log.ErrorFormat(
376 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezSingleAttachmentFromInventory()",
377 remoteClient.Name, remoteClient.AgentId);
378 return null; 276 return null;
379 }
380
381 return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt);
382 }
383 277
384 public ISceneEntity RezSingleAttachmentFromInventory(ScenePresence sp, UUID itemID, uint AttachmentPt)
385 {
386// m_log.DebugFormat( 278// m_log.DebugFormat(
387// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}", 279// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}",
388// (AttachmentPoint)AttachmentPt, itemID, sp.Name); 280// (AttachmentPoint)AttachmentPt, itemID, sp.Name);
@@ -417,188 +309,44 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
417 return null; 309 return null;
418 } 310 }
419 311
420 SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, null); 312 SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, doc);
421 313
422 if (att == null) 314 if (att == null)
423 DetachSingleAttachmentToInv(itemID, sp.ControllingClient); 315 DetachSingleAttachmentToInv(sp, itemID);
424 316
425 return att; 317 return att;
426 } 318 }
427 319
428 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 320 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist)
429 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc)
430 {
431 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
432 if (invAccess != null)
433 {
434 lock (sp.AttachmentsSyncLock)
435 {
436 SceneObjectGroup objatt;
437
438 if (itemID != UUID.Zero)
439 objatt = invAccess.RezObject(sp.ControllingClient,
440 itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
441 false, false, sp.UUID, true);
442 else
443 objatt = invAccess.RezObject(sp.ControllingClient,
444 null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
445 false, false, sp.UUID, true);
446
447 // m_log.DebugFormat(
448 // "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
449 // objatt.Name, remoteClient.Name, AttachmentPt);
450
451 if (objatt != null)
452 {
453 // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
454 objatt.HasGroupChanged = false;
455 bool tainted = false;
456 if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
457 tainted = true;
458
459 // This will throw if the attachment fails
460 try
461 {
462 AttachObject(sp, objatt, attachmentPt, false);
463 }
464 catch (Exception e)
465 {
466 m_log.ErrorFormat(
467 "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
468 objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
469
470 // Make sure the object doesn't stick around and bail
471 sp.RemoveAttachment(objatt);
472 m_scene.DeleteSceneObject(objatt, false);
473 return null;
474 }
475
476 if (tainted)
477 objatt.HasGroupChanged = true;
478
479 // Fire after attach, so we don't get messy perms dialogs
480 // 4 == AttachedRez
481 objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
482 objatt.ResumeScripts();
483
484 // Do this last so that event listeners have access to all the effects of the attachment
485 m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID);
486
487 return objatt;
488 }
489 else
490 {
491 m_log.WarnFormat(
492 "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
493 itemID, sp.Name, attachmentPt);
494 }
495
496 if (doc != null)
497 {
498 objatt.LoadScriptState(doc);
499 objatt.ResetOwnerChangeFlag();
500 }
501
502 // Fire after attach, so we don't get messy perms dialogs
503 // 4 == AttachedRez
504 objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
505 objatt.ResumeScripts();
506
507 // Do this last so that event listeners have access to all the effects of the attachment
508 m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID);
509 }
510 }
511
512 return null;
513 }
514
515 /// <summary>
516 /// Update the user inventory to reflect an attachment
517 /// </summary>
518 /// <param name="sp"></param>
519 /// <param name="AttachmentPt"></param>
520 /// <param name="itemID"></param>
521 /// <param name="att"></param>
522 private void ShowAttachInUserInventory(
523 IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att)
524 { 321 {
525// m_log.DebugFormat( 322 if (!Enabled)
526// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
527// att.Name, sp.Name, AttachmentPt, itemID);
528
529 if (UUID.Zero == itemID)
530 {
531 m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment. Error inventory item ID.");
532 return;
533 }
534
535 if (0 == AttachmentPt)
536 {
537 m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment. Error attachment point.");
538 return;
539 }
540
541 if (null == att.RootPart)
542 {
543 m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment for a prim without the rootpart!");
544 return; 323 return;
545 }
546 InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID);
547
548
549
550
551
552
553 item = m_scene.InventoryService.GetItem(item);
554 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID);
555 if (changed && m_scene.AvatarFactory != null)
556 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
557 }
558 324
559 public void DetachObject(uint objectLocalID, IClientAPI remoteClient) 325 // m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name);
560 { 326 lock (sp.AttachmentsSyncLock)
561// m_log.DebugFormat(
562// "[ATTACHMENTS MODULE]: DetachObject() for object {0} on {1}", objectLocalID, remoteClient.Name);
563
564 SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID);
565 if (group != null)
566 {
567 DetachSingleAttachmentToInv(group.GetFromItemID(), remoteClient);
568 }
569 }
570
571 public void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient)
572 {
573 ScenePresence presence;
574 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
575 { 327 {
576 lock (presence.AttachmentsSyncLock) 328 foreach (KeyValuePair<UUID, uint> rez in rezlist)
577 { 329 {
578 // Save avatar attachment information 330 RezSingleAttachmentFromInventory(sp, rez.Key, rez.Value);
579 m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID);
580
581 bool changed = presence.Appearance.DetachAttachment(itemID);
582 if (changed && m_scene.AvatarFactory != null)
583 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
584
585 DetachSingleAttachmentToInv(itemID, presence);
586 } 331 }
587 } 332 }
588 } 333 }
589 334
590 public void DetachSingleAttachmentToGround(uint soLocalId, IClientAPI remoteClient) 335 public void DetachSingleAttachmentToGround(IScenePresence sp, uint soLocalId)
591 { 336 {
337 if (!Enabled)
338 return;
339
592// m_log.DebugFormat( 340// m_log.DebugFormat(
593// "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}", 341// "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}",
594// remoteClient.Name, soLocalId); 342// sp.UUID, soLocalId);
595 343
596 SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId); 344 SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId);
597 345
598 if (so == null) 346 if (so == null)
599 return; 347 return;
600 348
601 if (so.AttachedAvatar != remoteClient.AgentId) 349 if (so.AttachedAvatar != sp.UUID)
602 return; 350 return;
603 351
604 UUID inventoryID = so.GetFromItemID(); 352 UUID inventoryID = so.GetFromItemID();
@@ -607,103 +355,62 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
607// "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}", 355// "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}",
608// so.Name, so.LocalId, inventoryID); 356// so.Name, so.LocalId, inventoryID);
609 357
610 ScenePresence presence; 358 lock (sp.AttachmentsSyncLock)
611 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
612 { 359 {
613 lock (presence.AttachmentsSyncLock) 360 if (!m_scene.Permissions.CanRezObject(
614 { 361 so.PrimCount, sp.UUID, sp.AbsolutePosition))
615 if (!m_scene.Permissions.CanRezObject( 362 return;
616 so.PrimCount, remoteClient.AgentId, presence.AbsolutePosition))
617 return;
618
619 bool changed = presence.Appearance.DetachAttachment(inventoryID);
620 if (changed && m_scene.AvatarFactory != null)
621 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
622
623 presence.RemoveAttachment(so);
624 DetachSceneObjectToGround(so, presence);
625
626 List<UUID> uuids = new List<UUID>();
627 uuids.Add(inventoryID);
628 m_scene.InventoryService.DeleteItems(remoteClient.AgentId, uuids);
629 remoteClient.SendRemoveInventoryItem(inventoryID);
630 }
631 363
632 m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); 364 bool changed = sp.Appearance.DetachAttachment(inventoryID);
365 if (changed && m_scene.AvatarFactory != null)
366 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
367
368 sp.RemoveAttachment(so);
369
370 SceneObjectPart rootPart = so.RootPart;
371 rootPart.FromItemID = UUID.Zero;
372 so.AbsolutePosition = sp.AbsolutePosition;
373 so.AttachedAvatar = UUID.Zero;
374 rootPart.SetParentLocalId(0);
375 so.ClearPartAttachmentData();
376 rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive, m_scene.m_physicalPrim);
377 so.HasGroupChanged = true;
378 rootPart.Rezzed = DateTime.Now;
379 rootPart.RemFlag(PrimFlags.TemporaryOnRez);
380 so.AttachToBackup();
381 m_scene.EventManager.TriggerParcelPrimCountTainted();
382 rootPart.ScheduleFullUpdate();
383 rootPart.ClearUndoState();
384
385 List<UUID> uuids = new List<UUID>();
386 uuids.Add(inventoryID);
387 m_scene.InventoryService.DeleteItems(sp.UUID, uuids);
388 sp.ControllingClient.SendRemoveInventoryItem(inventoryID);
633 } 389 }
634 }
635 390
636 /// <summary> 391 m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero);
637 /// Detach the given scene object to the ground.
638 /// </summary>
639 /// <remarks>
640 /// The caller has to take care of all the other work in updating avatar appearance, inventory, etc.
641 /// </remarks>
642 /// <param name="so">The scene object to detach.</param>
643 /// <param name="sp">The scene presence from which the scene object is being detached.</param>
644 private void DetachSceneObjectToGround(SceneObjectGroup so, ScenePresence sp)
645 {
646 SceneObjectPart rootPart = so.RootPart;
647
648 rootPart.FromItemID = UUID.Zero;
649 so.AbsolutePosition = sp.AbsolutePosition;
650 so.AttachedAvatar = UUID.Zero;
651 rootPart.SetParentLocalId(0);
652 so.ClearPartAttachmentData();
653 rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive, m_scene.m_physicalPrim);
654 so.HasGroupChanged = true;
655 rootPart.Rezzed = DateTime.Now;
656 rootPart.RemFlag(PrimFlags.TemporaryOnRez);
657 so.AttachToBackup();
658 m_scene.EventManager.TriggerParcelPrimCountTainted();
659 rootPart.ScheduleFullUpdate();
660 rootPart.ClearUndoState();
661 } 392 }
662
663 // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards.
664 // To LocalId or UUID, *THAT* is the question. How now Brown UUID??
665 private void DetachSingleAttachmentToInv(UUID itemID, IScenePresence sp)
666 {
667// m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name);
668
669 if (itemID == UUID.Zero) // If this happened, someone made a mistake....
670 return;
671
672 // We can NOT use the dictionries here, as we are looking
673 // for an entity by the fromAssetID, which is NOT the prim UUID
674 EntityBase[] detachEntities = m_scene.GetEntities();
675 SceneObjectGroup group;
676 393
394 public void DetachSingleAttachmentToInv(IScenePresence sp, UUID itemID)
395 {
677 lock (sp.AttachmentsSyncLock) 396 lock (sp.AttachmentsSyncLock)
678 { 397 {
679 foreach (EntityBase entity in detachEntities) 398 // Save avatar attachment information
680 { 399 m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID);
681 if (entity is SceneObjectGroup)
682 {
683 group = (SceneObjectGroup)entity; if (group.GetFromItemID() == itemID) { m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero);
684 // CM / XMREngine!!!! Needed to conclude attach event
685 //SceneObjectSerializer.ToOriginalXmlFormat(group);
686 group.DetachToInventoryPrep();
687 m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString());
688 400
689 // Prepare sog for storage 401 bool changed = sp.Appearance.DetachAttachment(itemID);
690 group.AttachedAvatar = UUID.Zero; 402 if (changed && m_scene.AvatarFactory != null)
691 group.RootPart.SetParentLocalId(0); 403 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
692 group.IsAttachment = false;
693 group.AbsolutePosition = group.RootPart.AttachedPos;
694
695 UpdateKnownItem(sp.ControllingClient, group);
696 m_scene.DeleteSceneObject(group, false);
697 404
698 return; 405 DetachSingleAttachmentToInvInternal(sp, itemID);
699 }
700 }
701 }
702 } 406 }
703 } 407 }
704 408
705 public void UpdateAttachmentPosition(SceneObjectGroup sog, Vector3 pos) 409 public void UpdateAttachmentPosition(SceneObjectGroup sog, Vector3 pos)
706 { 410 {
411 if (!Enabled)
412 return;
413
707 // First we save the 414 // First we save the
708 // attachment point information, then we update the relative 415 // attachment point information, then we update the relative
709 // positioning. Then we have to mark the object as NOT an 416 // positioning. Then we have to mark the object as NOT an
@@ -717,7 +424,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
717 sog.AttachmentPoint = attachmentPoint; 424 sog.AttachmentPoint = attachmentPoint;
718 sog.HasGroupChanged = true; 425 sog.HasGroupChanged = true;
719 } 426 }
720 427
428 #endregion
429
430 #region AttachmentModule private methods
431
432 // This is public but is not part of the IAttachmentsModule interface.
433 // RegionCombiner module needs to poke at it to deliver client events.
434 // This breaks the encapsulation of the module and should get fixed somehow.
435 public void SubscribeToClientEvents(IClientAPI client)
436 {
437 client.OnRezSingleAttachmentFromInv += Client_OnRezSingleAttachmentFromInv;
438 client.OnRezMultipleAttachmentsFromInv += Client_OnRezMultipleAttachmentsFromInv;
439 client.OnObjectAttach += Client_OnObjectAttach;
440 client.OnObjectDetach += Client_OnObjectDetach;
441 client.OnDetachAttachmentIntoInv += Client_OnDetachAttachmentIntoInv;
442 client.OnObjectDrop += Client_OnObjectDrop;
443 }
444
445 // This is public but is not part of the IAttachmentsModule interface.
446 // RegionCombiner module needs to poke at it to deliver client events.
447 // This breaks the encapsulation of the module and should get fixed somehow.
448 public void UnsubscribeFromClientEvents(IClientAPI client)
449 {
450 client.OnRezSingleAttachmentFromInv -= Client_OnRezSingleAttachmentFromInv;
451 client.OnRezMultipleAttachmentsFromInv -= Client_OnRezMultipleAttachmentsFromInv;
452 client.OnObjectAttach -= Client_OnObjectAttach;
453 client.OnObjectDetach -= Client_OnObjectDetach;
454 client.OnDetachAttachmentIntoInv -= Client_OnDetachAttachmentIntoInv;
455 client.OnObjectDrop -= Client_OnObjectDrop;
456 }
457
721 /// <summary> 458 /// <summary>
722 /// Update the attachment asset for the new sog details if they have changed. 459 /// Update the attachment asset for the new sog details if they have changed.
723 /// </summary> 460 /// </summary>
@@ -725,9 +462,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
725 /// This is essential for preserving attachment attributes such as permission. Unlike normal scene objects, 462 /// This is essential for preserving attachment attributes such as permission. Unlike normal scene objects,
726 /// these details are not stored on the region. 463 /// these details are not stored on the region.
727 /// </remarks> 464 /// </remarks>
728 /// <param name="remoteClient"></param> 465 /// <param name="sp"></param>
729 /// <param name="grp"></param> 466 /// <param name="grp"></param>
730 private void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp) 467 private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp)
731 { 468 {
732 if (grp.HasGroupChanged || grp.ContainsScripts()) 469 if (grp.HasGroupChanged || grp.ContainsScripts())
733 { 470 {
@@ -737,7 +474,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
737 474
738 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); 475 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp);
739 476
740 InventoryItemBase item = new InventoryItemBase(grp.GetFromItemID(), remoteClient.AgentId); 477 InventoryItemBase item = new InventoryItemBase(grp.GetFromItemID(), sp.UUID);
741 item = m_scene.InventoryService.GetItem(item); 478 item = m_scene.InventoryService.GetItem(item);
742 479
743 if (item != null) 480 if (item != null)
@@ -747,7 +484,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
747 grp.GetPartDescription(grp.LocalId), 484 grp.GetPartDescription(grp.LocalId),
748 (sbyte)AssetType.Object, 485 (sbyte)AssetType.Object,
749 Utils.StringToBytes(sceneObjectXml), 486 Utils.StringToBytes(sceneObjectXml),
750 remoteClient.AgentId); 487 sp.UUID);
751 m_scene.AssetService.Store(asset); 488 m_scene.AssetService.Store(asset);
752 489
753 item.AssetID = asset.FullID; 490 item.AssetID = asset.FullID;
@@ -759,8 +496,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
759 m_scene.InventoryService.UpdateItem(item); 496 m_scene.InventoryService.UpdateItem(item);
760 497
761 // this gets called when the agent logs off! 498 // this gets called when the agent logs off!
762 if (remoteClient != null) 499 if (sp.ControllingClient != null)
763 remoteClient.SendInventoryItemCreateUpdate(item, 0); 500 sp.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
764 } 501 }
765 } 502 }
766 else 503 else
@@ -769,8 +506,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
769 "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}", 506 "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}",
770 grp.UUID, grp.AttachmentPoint); 507 grp.UUID, grp.AttachmentPoint);
771 } 508 }
772 } 509 }
773 510
774 /// <summary> 511 /// <summary>
775 /// Attach this scene object to the given avatar. 512 /// Attach this scene object to the given avatar.
776 /// </summary> 513 /// </summary>
@@ -784,19 +521,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
784 /// <param name="attachOffset"></param> 521 /// <param name="attachOffset"></param>
785 /// <param name="silent"></param> 522 /// <param name="silent"></param>
786 private void AttachToAgent( 523 private void AttachToAgent(
787 IScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) 524 IScenePresence sp, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent)
788 { 525 {
789// m_log.DebugFormat( 526 // m_log.DebugFormat(
790// "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", 527 // "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}",
791// so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); 528 // so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos);
792 529
793 so.DetachFromBackup(); 530 so.DetachFromBackup();
794 531
795 // Remove from database and parcel prim count 532 // Remove from database and parcel prim count
796 m_scene.DeleteFromStorage(so.UUID); 533 m_scene.DeleteFromStorage(so.UUID);
797 m_scene.EventManager.TriggerParcelPrimCountTainted(); 534 m_scene.EventManager.TriggerParcelPrimCountTainted();
798 535
799 so.AttachedAvatar = avatar.UUID; 536 so.AttachedAvatar = sp.UUID;
800 537
801 if (so.RootPart.PhysActor != null) 538 if (so.RootPart.PhysActor != null)
802 { 539 {
@@ -807,17 +544,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
807 so.AbsolutePosition = attachOffset; 544 so.AbsolutePosition = attachOffset;
808 so.RootPart.AttachedPos = attachOffset; 545 so.RootPart.AttachedPos = attachOffset;
809 so.IsAttachment = true; 546 so.IsAttachment = true;
810 so.RootPart.SetParentLocalId(avatar.LocalId); 547 so.RootPart.SetParentLocalId(sp.LocalId);
811 so.AttachmentPoint = attachmentpoint; 548 so.AttachmentPoint = attachmentpoint;
812 549
813 avatar.AddAttachment(so); 550 sp.AddAttachment(so);
814 551
815 if (!silent) 552 if (!silent)
816 { 553 {
817 so.IsSelected = false; // fudge.... 554 so.IsSelected = false; // fudge....
818 so.ScheduleGroupForFullUpdate(); 555 so.ScheduleGroupForFullUpdate();
819 } 556 }
820 557
821 // In case it is later dropped again, don't let 558 // In case it is later dropped again, don't let
822 // it get cleaned up 559 // it get cleaned up
823 so.RootPart.RemFlag(PrimFlags.TemporaryOnRez); 560 so.RootPart.RemFlag(PrimFlags.TemporaryOnRez);
@@ -829,19 +566,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
829 /// <param name="remoteClient"></param> 566 /// <param name="remoteClient"></param>
830 /// <param name="grp"></param> 567 /// <param name="grp"></param>
831 /// <returns>The user inventory item created that holds the attachment.</returns> 568 /// <returns>The user inventory item created that holds the attachment.</returns>
832 private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IClientAPI remoteClient, SceneObjectGroup grp) 569 private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IScenePresence sp, SceneObjectGroup grp)
833 { 570 {
834// m_log.DebugFormat( 571 // m_log.DebugFormat(
835// "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}", 572 // "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}",
836// grp.Name, grp.LocalId, remoteClient.Name); 573 // grp.Name, grp.LocalId, remoteClient.Name);
837 uint regionSize = Constants.RegionSize; //Avoid VS error "The operation overflows at compile time in checked mode" 574
838 Vector3 inventoryStoredPosition = new Vector3 575 Vector3 inventoryStoredPosition = new Vector3
839 (((grp.AbsolutePosition.X > (int)Constants.RegionSize) 576 (((grp.AbsolutePosition.X > (int)Constants.RegionSize)
840 ? regionSize - 6 577 ? (float)Constants.RegionSize - 6
841 : grp.AbsolutePosition.X) 578 : grp.AbsolutePosition.X)
842 , 579 ,
843 (grp.AbsolutePosition.Y > (int)Constants.RegionSize) 580 (grp.AbsolutePosition.Y > (int)Constants.RegionSize)
844 ? regionSize - 6 581 ? (float)Constants.RegionSize - 6
845 : grp.AbsolutePosition.Y, 582 : grp.AbsolutePosition.Y,
846 grp.AbsolutePosition.Z); 583 grp.AbsolutePosition.Z);
847 584
@@ -862,14 +599,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
862 grp.GetPartDescription(grp.LocalId), 599 grp.GetPartDescription(grp.LocalId),
863 (sbyte)AssetType.Object, 600 (sbyte)AssetType.Object,
864 Utils.StringToBytes(sceneObjectXml), 601 Utils.StringToBytes(sceneObjectXml),
865 remoteClient.AgentId); 602 sp.UUID);
866 603
867 m_scene.AssetService.Store(asset); 604 m_scene.AssetService.Store(asset);
868 605
869 InventoryItemBase item = new InventoryItemBase(); 606 InventoryItemBase item = new InventoryItemBase();
870 item.CreatorId = grp.RootPart.CreatorID.ToString(); 607 item.CreatorId = grp.RootPart.CreatorID.ToString();
871 item.CreatorData = grp.RootPart.CreatorData; 608 item.CreatorData = grp.RootPart.CreatorData;
872 item.Owner = remoteClient.AgentId; 609 item.Owner = sp.UUID;
873 item.ID = UUID.Random(); 610 item.ID = UUID.Random();
874 item.AssetID = asset.FullID; 611 item.AssetID = asset.FullID;
875 item.Description = asset.Description; 612 item.Description = asset.Description;
@@ -877,13 +614,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
877 item.AssetType = asset.Type; 614 item.AssetType = asset.Type;
878 item.InvType = (int)InventoryType.Object; 615 item.InvType = (int)InventoryType.Object;
879 616
880 InventoryFolderBase folder = m_scene.InventoryService.GetFolderForType(remoteClient.AgentId, AssetType.Object); 617 InventoryFolderBase folder = m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object);
881 if (folder != null) 618 if (folder != null)
882 item.Folder = folder.ID; 619 item.Folder = folder.ID;
883 else // oopsies 620 else // oopsies
884 item.Folder = UUID.Zero; 621 item.Folder = UUID.Zero;
885 622
886 if ((remoteClient.AgentId != grp.RootPart.OwnerID) && m_scene.Permissions.PropagatePermissions()) 623 if ((sp.UUID != grp.RootPart.OwnerID) && m_scene.Permissions.PropagatePermissions())
887 { 624 {
888 item.BasePermissions = grp.RootPart.NextOwnerMask; 625 item.BasePermissions = grp.RootPart.NextOwnerMask;
889 item.CurrentPermissions = grp.RootPart.NextOwnerMask; 626 item.CurrentPermissions = grp.RootPart.NextOwnerMask;
@@ -906,15 +643,304 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
906 643
907 if (m_scene.AddInventoryItem(item)) 644 if (m_scene.AddInventoryItem(item))
908 { 645 {
909 remoteClient.SendInventoryItemCreateUpdate(item, 0); 646 sp.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
910 } 647 }
911 else 648 else
912 { 649 {
913 if (m_dialogModule != null) 650 if (m_dialogModule != null)
914 m_dialogModule.SendAlertToUser(remoteClient, "Operation failed"); 651 m_dialogModule.SendAlertToUser(sp.ControllingClient, "Operation failed");
915 } 652 }
916 653
917 return item; 654 return item;
918 } 655 }
656
657 // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards.
658 // To LocalId or UUID, *THAT* is the question. How now Brown UUID??
659 private void DetachSingleAttachmentToInvInternal(IScenePresence sp, UUID itemID)
660 {
661 // m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name);
662
663 if (itemID == UUID.Zero) // If this happened, someone made a mistake....
664 return;
665
666 // We can NOT use the dictionries here, as we are looking
667 // for an entity by the fromAssetID, which is NOT the prim UUID
668 EntityBase[] detachEntities = m_scene.GetEntities();
669 SceneObjectGroup group;
670
671 lock (sp.AttachmentsSyncLock)
672 {
673 foreach (EntityBase entity in detachEntities)
674 {
675 if (entity is SceneObjectGroup)
676 {
677 group = (SceneObjectGroup)entity;
678 if (group.GetFromItemID() == itemID)
679 {
680 m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero);
681 sp.RemoveAttachment(group);
682
683 // Prepare sog for storage
684 group.AttachedAvatar = UUID.Zero;
685 group.RootPart.SetParentLocalId(0);
686 group.IsAttachment = false;
687 group.AbsolutePosition = group.RootPart.AttachedPos;
688
689 UpdateKnownItem(sp, group);
690 m_scene.DeleteSceneObject(group, false);
691
692 return;
693 }
694 }
695 }
696 }
697 }
698
699 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
700 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc)
701 {
702 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
703 if (invAccess != null)
704 {
705 lock (sp.AttachmentsSyncLock)
706 {
707 SceneObjectGroup objatt;
708
709 if (itemID != UUID.Zero)
710 objatt = invAccess.RezObject(sp.ControllingClient,
711 itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
712 false, false, sp.UUID, true);
713 else
714 objatt = invAccess.RezObject(sp.ControllingClient,
715 null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
716 false, false, sp.UUID, true);
717
718 // m_log.DebugFormat(
719 // "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
720 // objatt.Name, remoteClient.Name, AttachmentPt);
721
722 if (objatt != null)
723 {
724 // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
725 objatt.HasGroupChanged = false;
726 bool tainted = false;
727 if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
728 tainted = true;
729
730 // This will throw if the attachment fails
731 try
732 {
733 AttachObject(sp, objatt, attachmentPt, false);
734 }
735 catch (Exception e)
736 {
737 m_log.ErrorFormat(
738 "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
739 objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
740
741 // Make sure the object doesn't stick around and bail
742 sp.RemoveAttachment(objatt);
743 m_scene.DeleteSceneObject(objatt, false);
744 return null;
745 }
746
747 if (tainted)
748 objatt.HasGroupChanged = true;
749
750 // Fire after attach, so we don't get messy perms dialogs
751 // 4 == AttachedRez
752 objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
753 objatt.ResumeScripts();
754
755 // Do this last so that event listeners have access to all the effects of the attachment
756 m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID);
757
758 return objatt;
759 }
760 else
761 {
762 m_log.WarnFormat(
763 "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
764 itemID, sp.Name, attachmentPt);
765 }
766
767 if (doc != null)
768 {
769 objatt.LoadScriptState(doc);
770 objatt.ResetOwnerChangeFlag();
771 }
772
773 // Fire after attach, so we don't get messy perms dialogs
774 // 4 == AttachedRez
775 objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
776 objatt.ResumeScripts();
777
778 // Do this last so that event listeners have access to all the effects of the attachment
779 m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID);
780 }
781 }
782
783 return null;
784 }
785
786 /// <summary>
787 /// Update the user inventory to reflect an attachment
788 /// </summary>
789 /// <param name="sp"></param>
790 /// <param name="AttachmentPt"></param>
791 /// <param name="itemID"></param>
792 /// <param name="att"></param>
793 private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att)
794 {
795 // m_log.DebugFormat(
796 // "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
797 // att.Name, sp.Name, AttachmentPt, itemID);
798
799 if (UUID.Zero == itemID)
800 {
801 m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment. Error inventory item ID.");
802 return;
803 }
804
805 if (0 == AttachmentPt)
806 {
807 m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment. Error attachment point.");
808 return;
809 }
810
811 InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID);
812 item = m_scene.InventoryService.GetItem(item);
813 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID);
814 if (changed && m_scene.AvatarFactory != null)
815 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
816 }
817
818 #endregion
819
820 #region Client Event Handlers
821
822 private ISceneEntity Client_OnRezSingleAttachmentFromInv(IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
823 {
824 if (!Enabled)
825 return null;
826
827 // m_log.DebugFormat(
828 // "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}",
829 // (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name);
830
831 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
832
833 if (sp == null)
834 {
835 m_log.ErrorFormat(
836 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezSingleAttachmentFromInventory()",
837 remoteClient.Name, remoteClient.AgentId);
838 return null;
839 }
840
841 return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt);
842 }
843
844 private void Client_OnRezMultipleAttachmentsFromInv(IClientAPI remoteClient, List<KeyValuePair<UUID, uint>> rezlist)
845 {
846 if (!Enabled)
847 return;
848
849 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
850 if (sp != null)
851 RezMultipleAttachmentsFromInventory(sp, rezlist);
852 else
853 m_log.ErrorFormat(
854 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezMultipleAttachmentsFromInventory()",
855 remoteClient.Name, remoteClient.AgentId);
856 }
857
858 private void Client_OnObjectAttach(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent)
859 {
860 // m_log.DebugFormat(
861 // "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})",
862 // objectLocalID, remoteClient.Name, AttachmentPt, silent);
863
864 if (!Enabled)
865 return;
866
867 try
868 {
869 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
870
871 if (sp == null)
872 {
873 m_log.ErrorFormat(
874 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId);
875 return;
876 }
877
878 // If we can't take it, we can't attach it!
879 SceneObjectPart part = m_scene.GetSceneObjectPart(objectLocalID);
880 if (part == null)
881 return;
882
883 if (!m_scene.Permissions.CanTakeObject(part.UUID, remoteClient.AgentId))
884 {
885 remoteClient.SendAgentAlertMessage(
886 "You don't have sufficient permissions to attach this object", false);
887
888 return;
889 }
890
891 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
892 // be removed when that functionality is implemented in opensim
893 AttachmentPt &= 0x7f;
894
895 // Calls attach with a Zero position
896 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false))
897 {
898 m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
899
900 // Save avatar attachment information
901 m_log.Debug(
902 "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
903 + ", AttachmentPoint: " + AttachmentPt);
904
905 }
906 }
907 catch (Exception e)
908 {
909 m_log.ErrorFormat("[ATTACHMENTS MODULE]: exception upon Attach Object {0}{1}", e.Message, e.StackTrace);
910 }
911 }
912
913 private void Client_OnObjectDetach(uint objectLocalID, IClientAPI remoteClient)
914 {
915 if (!Enabled)
916 return;
917
918 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
919 SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID);
920 if (sp != null && group != null)
921 DetachSingleAttachmentToInv(sp, group.GetFromItemID());
922 }
923
924 private void Client_OnDetachAttachmentIntoInv(UUID itemID, IClientAPI remoteClient)
925 {
926 if (!Enabled)
927 return;
928
929 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
930 if (sp != null)
931 DetachSingleAttachmentToInv(sp, itemID);
932 }
933
934 private void Client_OnObjectDrop(uint soLocalId, IClientAPI remoteClient)
935 {
936 if (!Enabled)
937 return;
938
939 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
940 if (sp != null)
941 DetachSingleAttachmentToGround(sp, soLocalId);
942 }
943
944 #endregion
919 } 945 }
920} \ No newline at end of file 946}
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index ff3358f..86cfb32 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -106,7 +106,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
106 106
107 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName).ParentGroup; 107 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName).ParentGroup;
108 108
109 m_attMod.AttachObject(m_presence.ControllingClient, so, (uint)AttachmentPoint.Chest, false); 109 m_attMod.AttachObject(m_presence, so, (uint)AttachmentPoint.Chest, false);
110 110
111 // Check status on scene presence 111 // Check status on scene presence
112 Assert.That(m_presence.HasAttachments(), Is.True); 112 Assert.That(m_presence.HasAttachments(), Is.True);
@@ -140,7 +140,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
140 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); 140 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
141 141
142 m_attMod.RezSingleAttachmentFromInventory( 142 m_attMod.RezSingleAttachmentFromInventory(
143 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); 143 m_presence, attItemId, (uint)AttachmentPoint.Chest);
144 144
145 // Check scene presence status 145 // Check scene presence status
146 Assert.That(m_presence.HasAttachments(), Is.True); 146 Assert.That(m_presence.HasAttachments(), Is.True);
@@ -174,8 +174,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
174 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); 174 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
175 175
176 ISceneEntity so = m_attMod.RezSingleAttachmentFromInventory( 176 ISceneEntity so = m_attMod.RezSingleAttachmentFromInventory(
177 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); 177 m_presence, attItemId, (uint)AttachmentPoint.Chest);
178 m_attMod.DetachSingleAttachmentToGround(so.LocalId, m_presence.ControllingClient); 178 m_attMod.DetachSingleAttachmentToGround(m_presence, so.LocalId);
179 179
180 // Check scene presence status 180 // Check scene presence status
181 Assert.That(m_presence.HasAttachments(), Is.False); 181 Assert.That(m_presence.HasAttachments(), Is.False);
@@ -208,8 +208,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
208 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); 208 scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
209 209
210 m_attMod.RezSingleAttachmentFromInventory( 210 m_attMod.RezSingleAttachmentFromInventory(
211 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); 211 m_presence, attItemId, (uint)AttachmentPoint.Chest);
212 m_attMod.DetachSingleAttachmentToInv(attItemId, m_presence.ControllingClient); 212 m_attMod.DetachSingleAttachmentToInv(m_presence, attItemId);
213 213
214 // Check status on scene presence 214 // Check status on scene presence
215 Assert.That(m_presence.HasAttachments(), Is.False); 215 Assert.That(m_presence.HasAttachments(), Is.False);
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index b6a1564..d4e1736 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -64,15 +64,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
64 scene.RegisterModuleInterface<IAvatarFactory>(this); 64 scene.RegisterModuleInterface<IAvatarFactory>(this);
65 scene.EventManager.OnNewClient += NewClient; 65 scene.EventManager.OnNewClient += NewClient;
66 66
67 if (config != null) 67 IConfig sconfig = config.Configs["Startup"];
68 if (sconfig != null)
68 { 69 {
69 IConfig sconfig = config.Configs["Startup"]; 70 m_savetime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime)));
70 if (sconfig != null) 71 m_sendtime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime)));
71 { 72 // m_log.InfoFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime);
72 m_savetime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime)));
73 m_sendtime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime)));
74 // m_log.InfoFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime);
75 }
76 } 73 }
77 74
78 if (m_scene == null) 75 if (m_scene == null)
@@ -211,8 +208,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
211 // Process the visual params, this may change height as well 208 // Process the visual params, this may change height as well
212 if (visualParams != null) 209 if (visualParams != null)
213 { 210 {
211// string[] visualParamsStrings = new string[visualParams.Length];
212// for (int i = 0; i < visualParams.Length; i++)
213// visualParamsStrings[i] = visualParams[i].ToString();
214// m_log.DebugFormat(
215// "[AVFACTORY]: Setting visual params for {0} to {1}",
216// client.Name, string.Join(", ", visualParamsStrings));
217
218 float oldHeight = sp.Appearance.AvatarHeight;
214 changed = sp.Appearance.SetVisualParams(visualParams); 219 changed = sp.Appearance.SetVisualParams(visualParams);
215 if (sp.Appearance.AvatarHeight > 0) 220
221 if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0)
216 sp.SetHeight(sp.Appearance.AvatarHeight); 222 sp.SetHeight(sp.Appearance.AvatarHeight);
217 } 223 }
218 224
@@ -416,6 +422,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
416 422
417 // m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid); 423 // m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid);
418 424
425 // This could take awhile since it needs to pull inventory
426 // We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape
427 // assets and item asset id changes to complete.
428 // I don't think we need to worry about doing this within m_setAppearanceLock since the queueing avoids
429 // multiple save requests.
430 SetAppearanceAssets(sp.UUID, sp.Appearance);
431
419 m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); 432 m_scene.AvatarService.SetAppearance(agentid, sp.Appearance);
420 } 433 }
421 434
@@ -467,7 +480,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
467 return; 480 return;
468 } 481 }
469 482
470 // m_log.WarnFormat("[AVFACTORY]: Received request for wearables of {0}", client.AgentId); 483// m_log.DebugFormat("[AVFACTORY]: Received request for wearables of {0}", client.Name);
471 484
472 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); 485 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++);
473 } 486 }
@@ -502,9 +515,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
502 515
503 avatAppearance.GetAssetsFrom(sp.Appearance); 516 avatAppearance.GetAssetsFrom(sp.Appearance);
504 517
505 // This could take awhile since it needs to pull inventory
506 SetAppearanceAssets(sp.UUID, ref avatAppearance);
507
508 lock (m_setAppearanceLock) 518 lock (m_setAppearanceLock)
509 { 519 {
510 // Update only those fields that we have changed. This is important because the viewer 520 // Update only those fields that we have changed. This is important because the viewer
@@ -538,7 +548,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
538 return true; 548 return true;
539 } 549 }
540 550
541 private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) 551 private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance)
542 { 552 {
543 IInventoryService invService = m_scene.InventoryService; 553 IInventoryService invService = m_scene.InventoryService;
544 554
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs
index 7753c25..d294692 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs
@@ -24,6 +24,7 @@
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
27using System; 28using System;
28using System.Collections; 29using System.Collections;
29using System.Collections.Generic; 30using System.Collections.Generic;
@@ -145,14 +146,14 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
145 scene.Entities[toAgentID] is ScenePresence) 146 scene.Entities[toAgentID] is ScenePresence)
146 { 147 {
147// m_log.DebugFormat( 148// m_log.DebugFormat(
148// "[INSTANT MESSAGE]: Looking for root agent {0} in {1}", 149// "[HG INSTANT MESSAGE]: Looking for root agent {0} in {1}",
149// toAgentID.ToString(), scene.RegionInfo.RegionName); 150// toAgentID.ToString(), scene.RegionInfo.RegionName);
150 151
151 ScenePresence user = (ScenePresence) scene.Entities[toAgentID]; 152 ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
152 if (!user.IsChildAgent) 153 if (!user.IsChildAgent)
153 { 154 {
154 // Local message 155 // Local message
155// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID); 156// m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
156 user.ControllingClient.SendInstantMessage(im); 157 user.ControllingClient.SendInstantMessage(im);
157 158
158 // Message sent 159 // Message sent
@@ -166,7 +167,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
166 foreach (Scene scene in m_Scenes) 167 foreach (Scene scene in m_Scenes)
167 { 168 {
168// m_log.DebugFormat( 169// m_log.DebugFormat(
169// "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName); 170// "[HG INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);
170 171
171 if (scene.Entities.ContainsKey(toAgentID) && 172 if (scene.Entities.ContainsKey(toAgentID) &&
172 scene.Entities[toAgentID] is ScenePresence) 173 scene.Entities[toAgentID] is ScenePresence)
@@ -174,7 +175,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
174 // Local message 175 // Local message
175 ScenePresence user = (ScenePresence) scene.Entities[toAgentID]; 176 ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
176 177
177// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID); 178// m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID);
178 user.ControllingClient.SendInstantMessage(im); 179 user.ControllingClient.SendInstantMessage(im);
179 180
180 // Message sent 181 // Message sent
@@ -183,7 +184,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
183 } 184 }
184 } 185 }
185 186
186// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID); 187// m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
187 // Is the user a local user? 188 // Is the user a local user?
188 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, toAgentID); 189 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, toAgentID);
189 string url = string.Empty; 190 string url = string.Empty;
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
index d687e6a..bc5c1ff 100644
--- a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
@@ -154,14 +154,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
154 if (im.dialog == (byte)InstantMessageDialog.RequestTeleport) 154 if (im.dialog == (byte)InstantMessageDialog.RequestTeleport)
155 { 155 {
156 UUID sessionID = new UUID(im.imSessionID); 156 UUID sessionID = new UUID(im.imSessionID);
157 m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", im.imSessionID, im.RegionID, im.message); 157
158 m_PendingLures.Add(sessionID, im, 7200); // 2 hours 158 if (!m_PendingLures.Contains(sessionID))
159 {
160 m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", im.imSessionID, im.RegionID, im.message);
161 m_PendingLures.Add(sessionID, im, 7200); // 2 hours
162 }
159 163
160 // Forward. We do this, because the IM module explicitly rejects 164 // Forward. We do this, because the IM module explicitly rejects
161 // IMs of this type 165 // IMs of this type
162 if (m_TransferModule != null) 166 if (m_TransferModule != null)
163 m_TransferModule.SendInstantMessage(im, delegate(bool success) { }); 167 m_TransferModule.SendInstantMessage(im, delegate(bool success) { });
164
165 } 168 }
166 } 169 }
167 170
@@ -177,12 +180,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
177 180
178 m_log.DebugFormat("[HG LURE MODULE]: TP invite with message {0}", message); 181 m_log.DebugFormat("[HG LURE MODULE]: TP invite with message {0}", message);
179 182
183 UUID sessionID = UUID.Random();
184
180 GridInstantMessage m = new GridInstantMessage(scene, client.AgentId, 185 GridInstantMessage m = new GridInstantMessage(scene, client.AgentId,
181 client.FirstName+" "+client.LastName, targetid, 186 client.FirstName+" "+client.LastName, targetid,
182 (byte)InstantMessageDialog.RequestTeleport, false, 187 (byte)InstantMessageDialog.RequestTeleport, false,
183 message, UUID.Random(), false, presence.AbsolutePosition, 188 message, sessionID, false, presence.AbsolutePosition,
184 new Byte[0]); 189 new Byte[0]);
185 m.RegionID = client.Scene.RegionInfo.RegionID.Guid; 190 m.RegionID = client.Scene.RegionInfo.RegionID.Guid;
191
192 m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", m.imSessionID, m.RegionID, m.message);
193 m_PendingLures.Add(sessionID, m, 7200); // 2 hours
186 194
187 if (m_TransferModule != null) 195 if (m_TransferModule != null)
188 { 196 {
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index f05b090..dd6bdf7 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -150,7 +150,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
150 { 150 {
151 if (!m_Enabled) 151 if (!m_Enabled)
152 return; 152 return;
153
154 } 153 }
155 154
156 #endregion 155 #endregion
diff --git a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
index ed3e516..6f83948 100644
--- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
@@ -112,10 +112,13 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
112 112
113 public void PostInitialise() 113 public void PostInitialise()
114 { 114 {
115 m_textureManager = m_scene.RequestModuleInterface<IDynamicTextureManager>(); 115 if (m_scene != null)
116 if (m_textureManager != null)
117 { 116 {
118 m_textureManager.RegisterRender(GetContentType(), this); 117 m_textureManager = m_scene.RequestModuleInterface<IDynamicTextureManager>();
118 if (m_textureManager != null)
119 {
120 m_textureManager.RegisterRender(GetContentType(), this);
121 }
119 } 122 }
120 } 123 }
121 124
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs
index 003324f..86c0099 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs
@@ -141,11 +141,21 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
141 141
142 if (scene != null) 142 if (scene != null)
143 { 143 {
144 string mail = String.Empty;
145
144 UserAccount account = scene.UserAccountService.GetUserAccount(UUID.Zero, new UUID(userID)); 146 UserAccount account = scene.UserAccountService.GetUserAccount(UUID.Zero, new UUID(userID));
145 147
148 //if account not found, we assume its a foreign visitor from HG, else use account data...
149 if (account != null)
150 {
151 mail = account.Email;
152 firstName = account.FirstName;
153 lastName = account.LastName;
154 }
155
146 isAuthorized 156 isAuthorized
147 = IsAuthorizedForRegion( 157 = IsAuthorizedForRegion(
148 userID, firstName, lastName, account.Email, scene.RegionInfo.RegionName, regionID, out message); 158 userID, firstName, lastName, mail, scene.RegionInfo.RegionName, regionID, out message);
149 } 159 }
150 else 160 else
151 { 161 {
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
index 1c83f8e..097ff1a 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
@@ -185,15 +185,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
185 public InventoryCollection GetFolderContent(UUID userID, UUID folderID) 185 public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
186 { 186 {
187 InventoryCollection invCol = m_InventoryService.GetFolderContent(userID, folderID); 187 InventoryCollection invCol = m_InventoryService.GetFolderContent(userID, folderID);
188 Util.FireAndForget(delegate 188
189 if (UserManager != null)
189 { 190 {
190 if (UserManager != null) 191 // Protect ourselves against the caller subsequently modifying the items list
192 List<InventoryItemBase> items = new List<InventoryItemBase>(invCol.Items);
193
194 Util.FireAndForget(delegate
191 { 195 {
192 // Protect ourselves against the caller subsequently modifying the items list 196 foreach (InventoryItemBase item in items)
193 foreach (InventoryItemBase item in new List<InventoryItemBase>(invCol.Items))
194 UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); 197 UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
195 } 198 });
196 }); 199 }
197 200
198 return invCol; 201 return invCol;
199 } 202 }
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
index c9c716c..73ab4e3 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
@@ -193,15 +193,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
193 public InventoryCollection GetFolderContent(UUID userID, UUID folderID) 193 public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
194 { 194 {
195 InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID, folderID); 195 InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID, folderID);
196 Util.FireAndForget(delegate 196
197 if (UserManager != null)
197 { 198 {
198 if (UserManager != null) 199 // Protect ourselves against the caller subsequently modifying the items list
200 List<InventoryItemBase> items = new List<InventoryItemBase>(invCol.Items);
201
202 Util.FireAndForget(delegate
199 { 203 {
200 // Protect ourselves against the caller subsequently modifying the items list 204 foreach (InventoryItemBase item in items)
201 foreach (InventoryItemBase item in new List<InventoryItemBase>(invCol.Items))
202 UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); 205 UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
203 } 206 });
204 }); 207 }
205 208
206 return invCol; 209 return invCol;
207 } 210 }
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs
index 535a637..1ffd480 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs
@@ -45,7 +45,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
45 LogManager.GetLogger( 45 LogManager.GetLogger(
46 MethodBase.GetCurrentMethod().DeclaringType); 46 MethodBase.GetCurrentMethod().DeclaringType);
47 47
48 private IUserAccountService m_UserService; 48 /// <summary>
49 /// This is not on the IUserAccountService. It's only being used so that standalone scenes can punch through
50 /// to a local UserAccountService when setting up an estate manager.
51 /// </summary>
52 public IUserAccountService UserAccountService { get; private set; }
53
49 private UserAccountCache m_Cache; 54 private UserAccountCache m_Cache;
50 55
51 private bool m_Enabled = false; 56 private bool m_Enabled = false;
@@ -86,9 +91,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
86 } 91 }
87 92
88 Object[] args = new Object[] { source }; 93 Object[] args = new Object[] { source };
89 m_UserService = ServerUtils.LoadPlugin<IUserAccountService>(serviceDll, args); 94 UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(serviceDll, args);
90 95
91 if (m_UserService == null) 96 if (UserAccountService == null)
92 { 97 {
93 m_log.ErrorFormat( 98 m_log.ErrorFormat(
94 "[LOCAL USER ACCOUNT SERVICE CONNECTOR]: Cannot load user account service specified as {0}", serviceDll); 99 "[LOCAL USER ACCOUNT SERVICE CONNECTOR]: Cannot load user account service specified as {0}", serviceDll);
@@ -119,7 +124,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
119 if (!m_Enabled) 124 if (!m_Enabled)
120 return; 125 return;
121 126
122 scene.RegisterModuleInterface<IUserAccountService>(m_UserService); 127 // FIXME: Why do we bother setting this module and caching up if we just end up registering the inner
128 // user account service?!
129 scene.RegisterModuleInterface<IUserAccountService>(UserAccountService);
123 scene.RegisterModuleInterface<IUserAccountCacheModule>(m_Cache); 130 scene.RegisterModuleInterface<IUserAccountCacheModule>(m_Cache);
124 } 131 }
125 132
@@ -148,7 +155,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
148 if (inCache) 155 if (inCache)
149 return account; 156 return account;
150 157
151 account = m_UserService.GetUserAccount(scopeID, userID); 158 account = UserAccountService.GetUserAccount(scopeID, userID);
152 m_Cache.Cache(userID, account); 159 m_Cache.Cache(userID, account);
153 160
154 return account; 161 return account;
@@ -161,7 +168,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
161 if (inCache) 168 if (inCache)
162 return account; 169 return account;
163 170
164 account = m_UserService.GetUserAccount(scopeID, firstName, lastName); 171 account = UserAccountService.GetUserAccount(scopeID, firstName, lastName);
165 if (account != null) 172 if (account != null)
166 m_Cache.Cache(account.PrincipalID, account); 173 m_Cache.Cache(account.PrincipalID, account);
167 174
@@ -170,7 +177,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
170 177
171 public UserAccount GetUserAccount(UUID scopeID, string Email) 178 public UserAccount GetUserAccount(UUID scopeID, string Email)
172 { 179 {
173 return m_UserService.GetUserAccount(scopeID, Email); 180 return UserAccountService.GetUserAccount(scopeID, Email);
174 } 181 }
175 182
176 public List<UserAccount> GetUserAccountsWhere(UUID scopeID, string query) 183 public List<UserAccount> GetUserAccountsWhere(UUID scopeID, string query)
@@ -180,17 +187,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
180 187
181 public List<UserAccount> GetUserAccounts(UUID scopeID, string query) 188 public List<UserAccount> GetUserAccounts(UUID scopeID, string query)
182 { 189 {
183 return m_UserService.GetUserAccounts(scopeID, query); 190 return UserAccountService.GetUserAccounts(scopeID, query);
184 } 191 }
185 192
186 // Update all updatable fields 193 // Update all updatable fields
187 // 194 //
188 public bool StoreUserAccount(UserAccount data) 195 public bool StoreUserAccount(UserAccount data)
189 { 196 {
190 return m_UserService.StoreUserAccount(data); 197 return UserAccountService.StoreUserAccount(data);
191 } 198 }
192 199
193 #endregion 200 #endregion
194
195 } 201 }
196} 202}
diff --git a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
index 49e3236..eb4731c 100644
--- a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
+++ b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
@@ -101,7 +101,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell
101 101
102 part.ParentGroup.HasGroupChanged = true; 102 part.ParentGroup.HasGroupChanged = true;
103 103
104 part.GetProperties(client); 104 part.SendPropertiesToClient(client);
105 } 105 }
106 106
107 public bool BuyObject(IClientAPI remoteClient, UUID categoryID, uint localID, byte saleType, int salePrice) 107 public bool BuyObject(IClientAPI remoteClient, UUID categoryID, uint localID, byte saleType, int salePrice)
@@ -142,7 +142,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell
142 part.SalePrice = 10; 142 part.SalePrice = 10;
143 143
144 group.HasGroupChanged = true; 144 group.HasGroupChanged = true;
145 part.GetProperties(remoteClient); 145 part.SendPropertiesToClient(remoteClient);
146 part.TriggerScriptChangedEvent(Changed.OWNER); 146 part.TriggerScriptChangedEvent(Changed.OWNER);
147 group.ResumeScripts(); 147 group.ResumeScripts();
148 part.ScheduleFullUpdate(); 148 part.ScheduleFullUpdate();
diff --git a/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs b/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs
deleted file mode 100644
index 7a0ce51..0000000
--- a/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs
+++ /dev/null
@@ -1,131 +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.Collections.Generic;
29using OpenMetaverse;
30using OpenSim.Framework;
31using OpenSim.Region.Framework.Scenes;
32
33namespace OpenSim.Region.Examples.SimpleModule
34{
35 public class ComplexObject : SceneObjectGroup
36 {
37 private readonly Quaternion m_rotationDirection;
38
39 protected override bool InSceneBackup
40 {
41 get
42 {
43 return false;
44 }
45 }
46
47 private class RotatingWheel : SceneObjectPart
48 {
49 private readonly Quaternion m_rotationDirection;
50
51 public RotatingWheel()
52 {
53 }
54
55 public RotatingWheel(
56 UUID ownerID, Vector3 groupPosition, Vector3 offsetPosition, Quaternion rotationDirection)
57 : base(ownerID, PrimitiveBaseShape.Default, groupPosition, Quaternion.Identity, offsetPosition)
58 {
59 m_rotationDirection = rotationDirection;
60
61 Flags |= PrimFlags.Touch;
62 }
63
64 public override void UpdateMovement()
65 {
66 UpdateRotation(RotationOffset * m_rotationDirection);
67 }
68 }
69
70 public override void UpdateMovement()
71 {
72 UpdateGroupRotationR(GroupRotation * m_rotationDirection);
73
74 base.UpdateMovement();
75 }
76
77 public ComplexObject()
78 {
79 }
80
81 public ComplexObject(Scene scene, ulong regionHandle, UUID ownerID, uint localID, Vector3 pos)
82 : base(ownerID, pos, PrimitiveBaseShape.Default)
83 {
84 m_rotationDirection = new Quaternion(0.05f, 0.1f, 0.15f);
85
86 AddPart(
87 new RotatingWheel(ownerID, pos, new Vector3(0, 0, 0.75f),
88 new Quaternion(0.05f, 0, 0)));
89 AddPart(
90 new RotatingWheel(ownerID, pos, new Vector3(0, 0, -0.75f),
91 new Quaternion(-0.05f, 0, 0)));
92
93 AddPart(
94 new RotatingWheel(ownerID, pos, new Vector3(0, 0.75f, 0),
95 new Quaternion(0.5f, 0, 0.05f)));
96 AddPart(
97 new RotatingWheel(ownerID, pos, new Vector3(0, -0.75f, 0),
98 new Quaternion(-0.5f, 0, -0.05f)));
99
100 AddPart(
101 new RotatingWheel(ownerID, pos, new Vector3(0.75f, 0, 0),
102 new Quaternion(0, 0.5f, 0.05f)));
103 AddPart(
104 new RotatingWheel(ownerID, pos, new Vector3(-0.75f, 0, 0),
105 new Quaternion(0, -0.5f, -0.05f)));
106
107 RootPart.Flags |= PrimFlags.Touch;
108 }
109
110 public override void OnGrabPart(SceneObjectPart part, Vector3 offsetPos, IClientAPI remoteClient)
111 {
112 m_parts.Remove(part.UUID);
113
114 remoteClient.SendKillObject(m_regionHandle, new List<uint>() { part.LocalId} );
115 remoteClient.AddMoney(1);
116 remoteClient.SendChatMessage("Poof!", 1, AbsolutePosition, "Party Party", UUID.Zero, (byte)ChatSourceType.Object, (byte)ChatAudibleLevel.Fully);
117 }
118
119 public override void OnGrabGroup(Vector3 offsetPos, IClientAPI remoteClient)
120 {
121 if (m_parts.Count == 1)
122 {
123 m_parts.Remove(m_rootPart.UUID);
124 m_scene.DeleteSceneObject(this, false);
125 remoteClient.SendKillObject(m_regionHandle, new List<uint>() { m_rootPart.LocalId });
126 remoteClient.AddMoney(50);
127 remoteClient.SendChatMessage("KABLAM!!!", 1, AbsolutePosition, "Groupie Groupie", UUID.Zero, (byte)ChatSourceType.Object, (byte)ChatAudibleLevel.Fully);
128 }
129 }
130 }
131}
diff --git a/OpenSim/Region/Examples/SimpleModule/CpuCounterObject.cs b/OpenSim/Region/Examples/SimpleModule/CpuCounterObject.cs
deleted file mode 100644
index 8669139..0000000
--- a/OpenSim/Region/Examples/SimpleModule/CpuCounterObject.cs
+++ /dev/null
@@ -1,68 +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.Diagnostics;
30using OpenMetaverse;
31using OpenSim.Framework;
32using OpenSim.Region.Framework.Scenes;
33
34namespace OpenSim.Region.Examples.SimpleModule
35{
36 public class CpuCounterObject : SceneObjectGroup
37 {
38 protected override bool InSceneBackup
39 {
40 get
41 {
42 return false;
43 }
44 }
45
46 private PerformanceCounter m_counter;
47
48 public CpuCounterObject(UUID ownerID, Vector3 pos)
49 : base(ownerID, pos, PrimitiveBaseShape.Default)
50 {
51 String objectName = "Processor";
52 String counterName = "% Processor Time";
53 String instanceName = "_Total";
54
55 m_counter = new PerformanceCounter(objectName, counterName, instanceName);
56 }
57
58 public override void UpdateMovement()
59 {
60 float cpu = m_counter.NextValue()/40f;
61 Vector3 size = new Vector3(cpu, cpu, cpu);
62
63 RootPart.Resize(size);
64
65 base.UpdateMovement();
66 }
67 }
68}
diff --git a/OpenSim/Region/Examples/SimpleModule/FileSystemObject.cs b/OpenSim/Region/Examples/SimpleModule/FileSystemObject.cs
deleted file mode 100644
index f0f684c..0000000
--- a/OpenSim/Region/Examples/SimpleModule/FileSystemObject.cs
+++ /dev/null
@@ -1,51 +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.IO;
29using OpenMetaverse;
30using OpenSim.Framework;
31using OpenSim.Region.Framework.Scenes;
32
33namespace OpenSim.Region.Examples.SimpleModule
34{
35 public class FileSystemObject : SceneObjectGroup
36 {
37 public FileSystemObject(FileInfo fileInfo, Vector3 pos)
38 : base(UUID.Zero, pos, PrimitiveBaseShape.Default)
39 {
40 Text = fileInfo.Name;
41 }
42
43 protected override bool InSceneBackup
44 {
45 get
46 {
47 return false;
48 }
49 }
50 }
51}
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
deleted file mode 100644
index 3b740e2..0000000
--- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
+++ /dev/null
@@ -1,1172 +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.Net;
31using OpenMetaverse;
32using OpenMetaverse.Packets;
33using OpenSim.Framework;
34using OpenSim.Region.Framework.Scenes;
35
36namespace OpenSim.Region.Examples.SimpleModule
37{
38 public class MyNpcCharacter : IClientAPI
39 {
40 private uint movementFlag = 0;
41 private short flyState = 0;
42 private Quaternion bodyDirection = Quaternion.Identity;
43 private short count = 0;
44 private short frame = 0;
45 private Scene m_scene;
46
47// disable warning: public events, part of the public API
48#pragma warning disable 67
49
50 public event Action<IClientAPI> OnLogout;
51 public event ObjectPermissions OnObjectPermissions;
52
53 public event MoneyTransferRequest OnMoneyTransferRequest;
54 public event ParcelBuy OnParcelBuy;
55 public event Action<IClientAPI> OnConnectionClosed;
56
57 public event ImprovedInstantMessage OnInstantMessage;
58 public event ChatMessage OnChatFromClient;
59 public event TextureRequest OnRequestTexture;
60 public event RezObject OnRezObject;
61 public event ModifyTerrain OnModifyTerrain;
62 public event BakeTerrain OnBakeTerrain;
63 public event SetAppearance OnSetAppearance;
64 public event AvatarNowWearing OnAvatarNowWearing;
65 public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
66 public event RezMultipleAttachmentsFromInv OnRezMultipleAttachmentsFromInv;
67 public event UUIDNameRequest OnDetachAttachmentIntoInv;
68 public event ObjectAttach OnObjectAttach;
69 public event ObjectDeselect OnObjectDetach;
70 public event ObjectDrop OnObjectDrop;
71 public event StartAnim OnStartAnim;
72 public event StopAnim OnStopAnim;
73 public event LinkObjects OnLinkObjects;
74 public event DelinkObjects OnDelinkObjects;
75 public event RequestMapBlocks OnRequestMapBlocks;
76 public event RequestMapName OnMapNameRequest;
77 public event TeleportLocationRequest OnTeleportLocationRequest;
78 public event TeleportLandmarkRequest OnTeleportLandmarkRequest;
79 public event DisconnectUser OnDisconnectUser;
80 public event RequestAvatarProperties OnRequestAvatarProperties;
81 public event SetAlwaysRun OnSetAlwaysRun;
82 public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
83 public event DeRezObject OnDeRezObject;
84 public event Action<IClientAPI> OnRegionHandShakeReply;
85 public event GenericCall1 OnRequestWearables;
86 public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
87 public event UpdateAgent OnPreAgentUpdate;
88 public event UpdateAgent OnAgentUpdate;
89 public event AgentRequestSit OnAgentRequestSit;
90 public event AgentSit OnAgentSit;
91 public event AvatarPickerRequest OnAvatarPickerRequest;
92 public event Action<IClientAPI> OnRequestAvatarsData;
93 public event AddNewPrim OnAddPrim;
94 public event RequestGodlikePowers OnRequestGodlikePowers;
95 public event GodKickUser OnGodKickUser;
96 public event ObjectDuplicate OnObjectDuplicate;
97 public event GrabObject OnGrabObject;
98 public event DeGrabObject OnDeGrabObject;
99 public event MoveObject OnGrabUpdate;
100 public event SpinStart OnSpinStart;
101 public event SpinObject OnSpinUpdate;
102 public event SpinStop OnSpinStop;
103 public event ViewerEffectEventHandler OnViewerEffect;
104
105 public event FetchInventory OnAgentDataUpdateRequest;
106 public event TeleportLocationRequest OnSetStartLocationRequest;
107
108 public event UpdateShape OnUpdatePrimShape;
109 public event ObjectExtraParams OnUpdateExtraParams;
110 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
111 public event ObjectRequest OnObjectRequest;
112 public event ObjectSelect OnObjectSelect;
113 public event GenericCall7 OnObjectDescription;
114 public event GenericCall7 OnObjectName;
115 public event GenericCall7 OnObjectClickAction;
116 public event GenericCall7 OnObjectMaterial;
117 public event UpdatePrimFlags OnUpdatePrimFlags;
118 public event UpdatePrimTexture OnUpdatePrimTexture;
119 public event UpdateVector OnUpdatePrimGroupPosition;
120 public event UpdateVector OnUpdatePrimSinglePosition;
121 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
122 public event UpdatePrimSingleRotationPosition OnUpdatePrimSingleRotationPosition;
123 public event UpdatePrimSingleRotation OnUpdatePrimSingleRotation;
124 public event UpdatePrimGroupRotation OnUpdatePrimGroupMouseRotation;
125 public event UpdateVector OnUpdatePrimScale;
126 public event UpdateVector OnUpdatePrimGroupScale;
127 public event StatusChange OnChildAgentStatus;
128 public event GenericCall2 OnStopMovement;
129 public event Action<UUID> OnRemoveAvatar;
130
131 public event CreateNewInventoryItem OnCreateNewInventoryItem;
132 public event LinkInventoryItem OnLinkInventoryItem;
133 public event CreateInventoryFolder OnCreateNewInventoryFolder;
134 public event UpdateInventoryFolder OnUpdateInventoryFolder;
135 public event MoveInventoryFolder OnMoveInventoryFolder;
136 public event RemoveInventoryFolder OnRemoveInventoryFolder;
137 public event RemoveInventoryItem OnRemoveInventoryItem;
138 public event FetchInventoryDescendents OnFetchInventoryDescendents;
139 public event PurgeInventoryDescendents OnPurgeInventoryDescendents;
140 public event FetchInventory OnFetchInventory;
141 public event RequestTaskInventory OnRequestTaskInventory;
142 public event UpdateInventoryItem OnUpdateInventoryItem;
143 public event CopyInventoryItem OnCopyInventoryItem;
144 public event MoveInventoryItem OnMoveInventoryItem;
145 public event UDPAssetUploadRequest OnAssetUploadRequest;
146 public event RequestTerrain OnRequestTerrain;
147 public event RequestTerrain OnUploadTerrain;
148 public event XferReceive OnXferReceive;
149 public event RequestXfer OnRequestXfer;
150 public event ConfirmXfer OnConfirmXfer;
151 public event AbortXfer OnAbortXfer;
152 public event RezScript OnRezScript;
153 public event UpdateTaskInventory OnUpdateTaskInventory;
154 public event MoveTaskInventory OnMoveTaskItem;
155 public event RemoveTaskInventory OnRemoveTaskItem;
156 public event RequestAsset OnRequestAsset;
157 public event GenericMessage OnGenericMessage;
158 public event UUIDNameRequest OnNameFromUUIDRequest;
159 public event UUIDNameRequest OnUUIDGroupNameRequest;
160
161 public event ParcelPropertiesRequest OnParcelPropertiesRequest;
162 public event ParcelDivideRequest OnParcelDivideRequest;
163 public event ParcelJoinRequest OnParcelJoinRequest;
164 public event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest;
165 public event ParcelAbandonRequest OnParcelAbandonRequest;
166 public event ParcelGodForceOwner OnParcelGodForceOwner;
167 public event ParcelReclaim OnParcelReclaim;
168 public event ParcelReturnObjectsRequest OnParcelReturnObjectsRequest;
169 public event ParcelAccessListRequest OnParcelAccessListRequest;
170 public event ParcelAccessListUpdateRequest OnParcelAccessListUpdateRequest;
171 public event ParcelSelectObjects OnParcelSelectObjects;
172 public event ParcelObjectOwnerRequest OnParcelObjectOwnerRequest;
173 public event ParcelDeedToGroup OnParcelDeedToGroup;
174 public event ObjectDeselect OnObjectDeselect;
175 public event RegionInfoRequest OnRegionInfoRequest;
176 public event EstateCovenantRequest OnEstateCovenantRequest;
177 public event EstateChangeInfo OnEstateChangeInfo;
178
179 public event ObjectDuplicateOnRay OnObjectDuplicateOnRay;
180
181 public event FriendActionDelegate OnApproveFriendRequest;
182 public event FriendActionDelegate OnDenyFriendRequest;
183 public event FriendshipTermination OnTerminateFriendship;
184 public event GrantUserFriendRights OnGrantUserRights;
185
186 public event EconomyDataRequest OnEconomyDataRequest;
187 public event MoneyBalanceRequest OnMoneyBalanceRequest;
188 public event UpdateAvatarProperties OnUpdateAvatarProperties;
189
190 public event ObjectIncludeInSearch OnObjectIncludeInSearch;
191 public event UUIDNameRequest OnTeleportHomeRequest;
192
193 public event ScriptAnswer OnScriptAnswer;
194 public event RequestPayPrice OnRequestPayPrice;
195 public event ObjectSaleInfo OnObjectSaleInfo;
196 public event ObjectBuy OnObjectBuy;
197 public event BuyObjectInventory OnBuyObjectInventory;
198 public event AgentSit OnUndo;
199 public event AgentSit OnRedo;
200 public event LandUndo OnLandUndo;
201
202 public event ForceReleaseControls OnForceReleaseControls;
203
204 public event GodLandStatRequest OnLandStatRequest;
205 public event RequestObjectPropertiesFamily OnObjectGroupRequest;
206
207 public event DetailedEstateDataRequest OnDetailedEstateDataRequest;
208 public event SetEstateFlagsRequest OnSetEstateFlagsRequest;
209 public event SetEstateTerrainBaseTexture OnSetEstateTerrainBaseTexture;
210 public event SetEstateTerrainDetailTexture OnSetEstateTerrainDetailTexture;
211 public event SetEstateTerrainTextureHeights OnSetEstateTerrainTextureHeights;
212 public event CommitEstateTerrainTextureRequest OnCommitEstateTerrainTextureRequest;
213 public event SetRegionTerrainSettings OnSetRegionTerrainSettings;
214 public event EstateRestartSimRequest OnEstateRestartSimRequest;
215 public event EstateChangeCovenantRequest OnEstateChangeCovenantRequest;
216 public event UpdateEstateAccessDeltaRequest OnUpdateEstateAccessDeltaRequest;
217 public event SimulatorBlueBoxMessageRequest OnSimulatorBlueBoxMessageRequest;
218 public event EstateBlueBoxMessageRequest OnEstateBlueBoxMessageRequest;
219 public event EstateDebugRegionRequest OnEstateDebugRegionRequest;
220 public event EstateTeleportOneUserHomeRequest OnEstateTeleportOneUserHomeRequest;
221 public event EstateTeleportAllUsersHomeRequest OnEstateTeleportAllUsersHomeRequest;
222 public event ScriptReset OnScriptReset;
223 public event GetScriptRunning OnGetScriptRunning;
224 public event SetScriptRunning OnSetScriptRunning;
225 public event Action<Vector3, bool> OnAutoPilotGo;
226
227 public event TerrainUnacked OnUnackedTerrain;
228
229 public event RegionHandleRequest OnRegionHandleRequest;
230 public event ParcelInfoRequest OnParcelInfoRequest;
231
232 public event ActivateGesture OnActivateGesture;
233 public event DeactivateGesture OnDeactivateGesture;
234 public event ObjectOwner OnObjectOwner;
235
236 public event DirPlacesQuery OnDirPlacesQuery;
237 public event DirFindQuery OnDirFindQuery;
238 public event DirLandQuery OnDirLandQuery;
239 public event DirPopularQuery OnDirPopularQuery;
240 public event DirClassifiedQuery OnDirClassifiedQuery;
241 public event EventInfoRequest OnEventInfoRequest;
242 public event ParcelSetOtherCleanTime OnParcelSetOtherCleanTime;
243
244 public event MapItemRequest OnMapItemRequest;
245
246 public event OfferCallingCard OnOfferCallingCard;
247 public event AcceptCallingCard OnAcceptCallingCard;
248 public event DeclineCallingCard OnDeclineCallingCard;
249 public event SoundTrigger OnSoundTrigger;
250
251 public event StartLure OnStartLure;
252 public event TeleportLureRequest OnTeleportLureRequest;
253 public event NetworkStats OnNetworkStatsUpdate;
254
255 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
256 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
257 public event ClassifiedDelete OnClassifiedDelete;
258 public event ClassifiedGodDelete OnClassifiedGodDelete;
259
260 public event EventNotificationAddRequest OnEventNotificationAddRequest;
261 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
262 public event EventGodDelete OnEventGodDelete;
263
264 public event ParcelDwellRequest OnParcelDwellRequest;
265 public event UserInfoRequest OnUserInfoRequest;
266 public event UpdateUserInfo OnUpdateUserInfo;
267
268 public event RetrieveInstantMessages OnRetrieveInstantMessages;
269
270 public event PickDelete OnPickDelete;
271 public event PickGodDelete OnPickGodDelete;
272 public event PickInfoUpdate OnPickInfoUpdate;
273 public event AvatarNotesUpdate OnAvatarNotesUpdate;
274
275 public event MuteListRequest OnMuteListRequest;
276
277 public event AvatarInterestUpdate OnAvatarInterestUpdate;
278
279 public event PlacesQuery OnPlacesQuery;
280
281 public event FindAgentUpdate OnFindAgent;
282 public event TrackAgentUpdate OnTrackAgent;
283 public event NewUserReport OnUserReport;
284 public event SaveStateHandler OnSaveState;
285 public event GroupAccountSummaryRequest OnGroupAccountSummaryRequest;
286 public event GroupAccountDetailsRequest OnGroupAccountDetailsRequest;
287 public event GroupAccountTransactionsRequest OnGroupAccountTransactionsRequest;
288 public event FreezeUserUpdate OnParcelFreezeUser;
289 public event EjectUserUpdate OnParcelEjectUser;
290 public event ParcelBuyPass OnParcelBuyPass;
291 public event ParcelGodMark OnParcelGodMark;
292 public event GroupActiveProposalsRequest OnGroupActiveProposalsRequest;
293 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
294 public event SimWideDeletesDelegate OnSimWideDeletes;
295 public event SendPostcard OnSendPostcard;
296 public event MuteListEntryUpdate OnUpdateMuteListEntry;
297 public event MuteListEntryRemove OnRemoveMuteListEntry;
298 public event GodlikeMessage onGodlikeMessage;
299 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate;
300
301#pragma warning restore 67
302
303 private UUID myID = UUID.Random();
304
305 public MyNpcCharacter(Scene scene)
306 {
307
308 // startPos = new Vector3(128, (float)(Util.RandomClass.NextDouble()*100), 2);
309 m_scene = scene;
310 m_scene.EventManager.OnFrame += Update;
311 }
312
313 private Vector3 startPos = new Vector3(128, 128, 30);
314
315 public virtual Vector3 StartPos
316 {
317 get { return startPos; }
318 set { }
319 }
320
321 public virtual UUID AgentId
322 {
323 get { return myID; }
324 }
325
326 public UUID SessionId
327 {
328 get { return UUID.Zero; }
329 }
330
331 public UUID SecureSessionId
332 {
333 get { return UUID.Zero; }
334 }
335
336 public virtual string FirstName
337 {
338 get { return "Only"; }
339 }
340
341 private string lastName = "Today" + Util.RandomClass.Next(1, 1000);
342
343 public virtual string LastName
344 {
345 get { return lastName; }
346 }
347
348 public virtual String Name
349 {
350 get { return FirstName + LastName; }
351 }
352
353 public bool IsActive
354 {
355 get { return true; }
356 set { }
357 }
358 public bool IsLoggingOut
359 {
360 get { return false; }
361 set { }
362 }
363 public UUID ActiveGroupId
364 {
365 get { return UUID.Zero; }
366 }
367
368 public string ActiveGroupName
369 {
370 get { return String.Empty; }
371 }
372
373 public ulong ActiveGroupPowers
374 {
375 get { return 0; }
376 }
377
378 public bool IsGroupMember(UUID groupID)
379 {
380 return false;
381 }
382
383 public ulong GetGroupPowers(UUID groupID)
384 {
385 return 0;
386 }
387
388 public virtual int NextAnimationSequenceNumber
389 {
390 get { return 1; }
391 }
392
393 public IScene Scene
394 {
395 get { return m_scene; }
396 }
397
398 public bool SendLogoutPacketWhenClosing
399 {
400 set { }
401 }
402
403 public virtual void ActivateGesture(UUID assetId, UUID gestureId)
404 {
405 }
406
407 public virtual void SendWearables(AvatarWearable[] wearables, int serial)
408 {
409 }
410
411 public virtual void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
412 {
413 }
414
415 public virtual void Kick(string message)
416 {
417 }
418
419 public virtual void SendStartPingCheck(byte seq)
420 {
421 }
422
423 public virtual void SendAvatarPickerReply(AvatarPickerReplyAgentDataArgs AgentData, List<AvatarPickerReplyDataArgs> Data)
424 {
425 }
426
427 public virtual void SendAgentDataUpdate(UUID agentid, UUID activegroupid, string firstname, string lastname, ulong grouppowers, string groupname, string grouptitle)
428 {
429
430 }
431
432 public virtual void SendKillObject(ulong regionHandle, List<uint> localID)
433 {
434 }
435
436 public virtual void SetChildAgentThrottle(byte[] throttle)
437 {
438 }
439 public byte[] GetThrottlesPacked(float multiplier)
440 {
441 return new byte[0];
442 }
443
444
445 public virtual void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs)
446 {
447 }
448
449 public virtual void SendChatMessage(string message, byte type, Vector3 fromPos, string fromName,
450 UUID fromAgentID, byte source, byte audible)
451 {
452 }
453
454 public virtual void SendChatMessage(byte[] message, byte type, Vector3 fromPos, string fromName,
455 UUID fromAgentID, byte source, byte audible)
456 {
457 }
458
459 public void SendInstantMessage(GridInstantMessage im)
460 {
461
462 }
463
464 public void SendGenericMessage(string method, List<string> message)
465 {
466 }
467
468 public void SendGenericMessage(string method, List<byte[]> message)
469 {
470
471 }
472
473 public virtual void SendLayerData(float[] map)
474 {
475 }
476
477 public virtual void SendLayerData(int px, int py, float[] map)
478 {
479 }
480 public virtual void SendLayerData(int px, int py, float[] map, bool track)
481 {
482 }
483
484 public virtual void SendWindData(Vector2[] windSpeeds) { }
485
486 public virtual void SendCloudData(float[] cloudCover) { }
487
488 public virtual void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look)
489 {
490 }
491
492 public virtual void InformClientOfNeighbour(ulong neighbourHandle, IPEndPoint neighbourExternalEndPoint)
493 {
494 }
495
496 public virtual AgentCircuitData RequestClientInfo()
497 {
498 return new AgentCircuitData();
499 }
500
501 public virtual void CrossRegion(ulong newRegionHandle, Vector3 pos, Vector3 lookAt,
502 IPEndPoint newRegionExternalEndPoint, string capsURL)
503 {
504 }
505
506 public virtual void SendMapBlock(List<MapBlockData> mapBlocks, uint flag)
507 {
508 }
509
510 public virtual void SendLocalTeleport(Vector3 position, Vector3 lookAt, uint flags)
511 {
512 }
513
514 public virtual void SendRegionTeleport(ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint,
515 uint locationID, uint flags, string capsURL)
516 {
517 }
518
519 public virtual void SendTeleportFailed(string reason)
520 {
521 }
522
523 public virtual void SendTeleportStart(uint flags)
524 {
525 }
526
527 public virtual void SendTeleportProgress(uint flags, string message)
528 {
529 }
530
531 public virtual void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance)
532 {
533 }
534
535 public virtual void SendPayPrice(UUID objectID, int[] payPrice)
536 {
537 }
538
539 public virtual void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
540 {
541 }
542
543 public virtual void SendDialog(string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels)
544 {
545 }
546
547 public void SendAvatarDataImmediate(ISceneEntity avatar)
548 {
549 }
550
551 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
552 {
553 }
554
555 public void ReprioritizeUpdates()
556 {
557 }
558
559 public void FlushPrimUpdates()
560 {
561 }
562
563 public virtual void SendInventoryFolderDetails(UUID ownerID, UUID folderID,
564 List<InventoryItemBase> items,
565 List<InventoryFolderBase> folders,
566 int version,
567 bool fetchFolders,
568 bool fetchItems)
569 {
570 }
571
572 public virtual void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item)
573 {
574 }
575
576 public virtual void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackID)
577 {
578 }
579
580 public virtual void SendRemoveInventoryItem(UUID itemID)
581 {
582 }
583
584 public virtual void SendBulkUpdateInventory(InventoryNodeBase node)
585 {
586 }
587
588 public UUID GetDefaultAnimation(string name)
589 {
590 return UUID.Zero;
591 }
592
593 public void SendTakeControls(int controls, bool passToAgent, bool TakeControls)
594 {
595 }
596
597 public virtual void SendTaskInventory(UUID taskID, short serial, byte[] fileName)
598 {
599 }
600
601 public virtual void SendXferPacket(ulong xferID, uint packet, byte[] data)
602 {
603 }
604
605 public virtual void SendAbortXferPacket(ulong xferID)
606 {
607
608 }
609
610
611 public virtual void SendEconomyData(float EnergyEfficiency, int ObjectCapacity, int ObjectCount, int PriceEnergyUnit,
612 int PriceGroupCreate, int PriceObjectClaim, float PriceObjectRent, float PriceObjectScaleFactor,
613 int PriceParcelClaim, float PriceParcelClaimFactor, int PriceParcelRent, int PricePublicObjectDecay,
614 int PricePublicObjectDelete, int PriceRentLight, int PriceUpload, int TeleportMinPrice, float TeleportPriceExponent)
615 {
616
617 }
618 public virtual void SendNameReply(UUID profileId, string firstname, string lastname)
619 {
620 }
621
622 public virtual void SendPreLoadSound(UUID objectID, UUID ownerID, UUID soundID)
623 {
624 }
625
626 public virtual void SendPlayAttachedSound(UUID soundID, UUID objectID, UUID ownerID, float gain,
627 byte flags)
628 {
629 }
630
631 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
632 {
633 }
634
635 public void SendAttachedSoundGainChange(UUID objectID, float gain)
636 {
637
638 }
639
640 public void SendAlertMessage(string message)
641 {
642 }
643
644 public void SendAgentAlertMessage(string message, bool modal)
645 {
646 }
647
648 public void SendSystemAlertMessage(string message)
649 {
650 }
651
652 public void SendLoadURL(string objectname, UUID objectID, UUID ownerID, bool groupOwned, string message,
653 string url)
654 {
655 }
656
657 public virtual void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args)
658 {
659 if (OnRegionHandShakeReply != null)
660 {
661 OnRegionHandShakeReply(this);
662 }
663
664 if (OnCompleteMovementToRegion != null)
665 {
666 OnCompleteMovementToRegion(this, true);
667 }
668 }
669 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID)
670 {
671 }
672
673 public void SendConfirmXfer(ulong xferID, uint PacketID)
674 {
675 }
676
677 public void SendXferRequest(ulong XferID, short AssetType, UUID vFileID, byte FilePath, byte[] FileName)
678 {
679 }
680
681 public void SendInitiateDownload(string simFileName, string clientFileName)
682 {
683 }
684
685 public void SendImageFirstPart(ushort numParts, UUID ImageUUID, uint ImageSize, byte[] ImageData, byte imageCodec)
686 {
687 }
688
689 public void SendImageNextPart(ushort partNumber, UUID imageUuid, byte[] imageData)
690 {
691 }
692
693 public void SendImageNotFound(UUID imageid)
694 {
695 }
696
697 public void SendShutdownConnectionNotice()
698 {
699 }
700
701 public void SendSimStats(SimStats stats)
702 {
703 }
704
705 public void SendObjectPropertiesFamilyData(ISceneEntity Entity, uint RequestFlags)
706 {
707
708 }
709
710 public void SendObjectPropertiesReply(ISceneEntity entity)
711 {
712 }
713
714 public void SendAgentOffline(UUID[] agentIDs)
715 {
716
717 }
718
719 public void SendAgentOnline(UUID[] agentIDs)
720 {
721
722 }
723
724 public void SendSitResponse(UUID TargetID, Vector3 OffsetPos, Quaternion SitOrientation, bool autopilot,
725 Vector3 CameraAtOffset, Vector3 CameraEyeOffset, bool ForceMouseLook)
726 {
727 }
728
729 public void SendAdminResponse(UUID Token, uint AdminLevel)
730 {
731
732 }
733
734 public void SendGroupMembership(GroupMembershipData[] GroupMembership)
735 {
736
737 }
738
739 private void Update()
740 {
741 frame++;
742 if (frame > 20)
743 {
744 frame = 0;
745 if (OnAgentUpdate != null)
746 {
747 AgentUpdateArgs pack = new AgentUpdateArgs();
748 pack.ControlFlags = movementFlag;
749 pack.BodyRotation = bodyDirection;
750
751 OnAgentUpdate(this, pack);
752 }
753 if (flyState == 0)
754 {
755 movementFlag = (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY |
756 (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG;
757 flyState = 1;
758 }
759 else if (flyState == 1)
760 {
761 movementFlag = (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY |
762 (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS;
763 flyState = 2;
764 }
765 else
766 {
767 movementFlag = (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
768 flyState = 0;
769 }
770
771 if (count >= 10)
772 {
773 if (OnChatFromClient != null)
774 {
775 OSChatMessage args = new OSChatMessage();
776 args.Message = "Hey You! Get out of my Home. This is my Region";
777 args.Channel = 0;
778 args.From = FirstName + " " + LastName;
779 args.Scene = m_scene;
780 args.Position = new Vector3(128, 128, 26);
781 args.Sender = this;
782 args.Type = ChatTypeEnum.Shout;
783
784 OnChatFromClient(this, args);
785 }
786 count = -1;
787 }
788
789 count++;
790 }
791 }
792
793 public bool AddMoney(int debit)
794 {
795 return false;
796 }
797
798 public void SendSunPos(Vector3 sunPos, Vector3 sunVel, ulong time, uint dlen, uint ylen, float phase)
799 {
800 }
801
802 public void SendViewerEffect(ViewerEffectPacket.EffectBlock[] effectBlocks)
803 {
804 }
805
806 public void SendViewerTime(int phase)
807 {
808 }
809
810 public void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, Byte[] charterMember,
811 string flAbout, uint flags, UUID flImageID, UUID imageID, string profileURL,
812 UUID partnerID)
813 {
814 }
815
816 public void SetDebugPacketLevel(int newDebug)
817 {
818 }
819
820 public void InPacket(object NewPack)
821 {
822 }
823
824 public void ProcessInPacket(Packet NewPack)
825 {
826 }
827
828 public void Close()
829 {
830 Close(true);
831 }
832
833 public void Close(bool sendStop)
834 {
835 }
836
837 public void Start()
838 {
839 }
840
841 public void Stop()
842 {
843 }
844
845 private uint m_circuitCode;
846
847 public uint CircuitCode
848 {
849 get { return m_circuitCode; }
850 set { m_circuitCode = value; }
851 }
852
853 public IPEndPoint RemoteEndPoint
854 {
855 get { return new IPEndPoint(IPAddress.Loopback, (ushort)m_circuitCode); }
856 }
857
858 public void SendBlueBoxMessage(UUID FromAvatarID, String FromAvatarName, String Message)
859 {
860
861 }
862 public void SendLogoutPacket()
863 {
864 }
865
866 public void Terminate()
867 {
868 }
869
870 public EndPoint GetClientEP()
871 {
872 return null;
873 }
874
875 public ClientInfo GetClientInfo()
876 {
877 return null;
878 }
879
880 public void SetClientInfo(ClientInfo info)
881 {
882 }
883
884 public void SendScriptQuestion(UUID objectID, string taskName, string ownerName, UUID itemID, int question)
885 {
886 }
887 public void SendHealth(float health)
888 {
889 }
890
891 public void SendEstateList(UUID invoice, int code, UUID[] Data, uint estateID)
892 {
893 }
894
895 public void SendBannedUserList(UUID invoice, EstateBan[] banlist, uint estateID)
896 {
897 }
898
899 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
900 {
901 }
902
903 public void SendEstateCovenantInformation(UUID covenant)
904 {
905 }
906
907 public void SendDetailedEstateData(UUID invoice, string estateName, uint estateID, uint parentEstate, uint estateFlags, uint sunPosition, UUID covenant, string abuseEmail, UUID estateOwner)
908 {
909 }
910
911 public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, ILandObject lo, float simObjectBonusFactor, int parcelObjectCapacity, int simObjectCapacity, uint regionFlags)
912 {
913 }
914
915 public void SendLandAccessListData(List<UUID> avatars, uint accessFlag, int localLandID)
916 {
917 }
918
919 public void SendForceClientSelectObjects(List<uint> objectIDs)
920 {
921 }
922
923 public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount)
924 {
925 }
926
927 public void SendCameraConstraint(Vector4 ConstraintPlane)
928 {
929
930 }
931
932 public void SendLandParcelOverlay(byte[] data, int sequence_id)
933 {
934 }
935
936 public void SendParcelMediaCommand(uint flags, ParcelMediaCommandEnum command, float time)
937 {
938 }
939
940 public void SendParcelMediaUpdate(string mediaUrl, UUID mediaTextureID, byte autoScale, string mediaType,
941 string mediaDesc, int mediaWidth, int mediaHeight, byte mediaLoop)
942 {
943 }
944
945 public void SendGroupNameReply(UUID groupLLUID, string GroupName)
946 {
947 }
948
949 public void SendLandStatReply(uint reportType, uint requestFlags, uint resultCount, LandStatReportItem[] lsrpia)
950 {
951 }
952
953 public void SendScriptRunningReply(UUID objectID, UUID itemID, bool running)
954 {
955 }
956
957 public void SendAsset(AssetRequestToClient req)
958 {
959 }
960
961 public void SendTexture(AssetBase TextureAsset)
962 {
963
964 }
965
966 public void SendSetFollowCamProperties (UUID objectID, SortedDictionary<int, float> parameters)
967 {
968 }
969
970 public void SendClearFollowCamProperties (UUID objectID)
971 {
972 }
973
974 public void SendRegionHandle (UUID regoinID, ulong handle)
975 {
976 }
977
978 public void SendParcelInfo (RegionInfo info, LandData land, UUID parcelID, uint x, uint y)
979 {
980 }
981
982 public void SetClientOption(string option, string value)
983 {
984 }
985
986 public string GetClientOption(string option)
987 {
988 return string.Empty;
989 }
990
991 public void SendScriptTeleportRequest(string objName, string simName, Vector3 pos, Vector3 lookAt)
992 {
993 }
994
995 public void SendDirPlacesReply(UUID queryID, DirPlacesReplyData[] data)
996 {
997 }
998
999 public void SendDirPeopleReply(UUID queryID, DirPeopleReplyData[] data)
1000 {
1001 }
1002
1003 public void SendDirEventsReply(UUID queryID, DirEventsReplyData[] data)
1004 {
1005 }
1006
1007 public void SendDirGroupsReply(UUID queryID, DirGroupsReplyData[] data)
1008 {
1009 }
1010
1011 public void SendDirClassifiedReply(UUID queryID, DirClassifiedReplyData[] data)
1012 {
1013 }
1014
1015 public void SendDirLandReply(UUID queryID, DirLandReplyData[] data)
1016 {
1017 }
1018
1019 public void SendDirPopularReply(UUID queryID, DirPopularReplyData[] data)
1020 {
1021 }
1022
1023 public void SendMapItemReply(mapItemReply[] replies, uint mapitemtype, uint flags)
1024 {
1025 }
1026
1027 public void KillEndDone()
1028 {
1029 }
1030
1031 public void SendEventInfoReply (EventData info)
1032 {
1033 }
1034
1035 public void SendOfferCallingCard (UUID destID, UUID transactionID)
1036 {
1037 }
1038
1039 public void SendAcceptCallingCard (UUID transactionID)
1040 {
1041 }
1042
1043 public void SendDeclineCallingCard (UUID transactionID)
1044 {
1045 }
1046
1047 public void SendAvatarGroupsReply(UUID avatarID, GroupMembershipData[] data)
1048 {
1049 }
1050
1051 public void SendJoinGroupReply(UUID groupID, bool success)
1052 {
1053 }
1054
1055 public void SendEjectGroupMemberReply(UUID agentID, UUID groupID, bool succss)
1056 {
1057 }
1058
1059 public void SendLeaveGroupReply(UUID groupID, bool success)
1060 {
1061 }
1062
1063 public void SendTerminateFriend(UUID exFriendID)
1064 {
1065 }
1066
1067 #region IClientAPI Members
1068
1069
1070 public bool AddGenericPacketHandler(string MethodName, GenericMessage handler)
1071 {
1072 return true;
1073 }
1074
1075 public void SendAvatarClassifiedReply(UUID targetID, UUID[] classifiedID, string[] name)
1076 {
1077 }
1078
1079 public void SendClassifiedInfoReply(UUID classifiedID, UUID creatorID, uint creationDate, uint expirationDate, uint category, string name, string description, UUID parcelID, uint parentEstate, UUID snapshotID, string simName, Vector3 globalPos, string parcelName, byte classifiedFlags, int price)
1080 {
1081 }
1082
1083 public void SendAgentDropGroup(UUID groupID)
1084 {
1085 }
1086
1087 public void SendAvatarNotesReply(UUID targetID, string text)
1088 {
1089 }
1090
1091 public void SendAvatarPicksReply(UUID targetID, Dictionary<UUID, string> picks)
1092 {
1093 }
1094
1095 public void SendAvatarClassifiedReply(UUID targetID, Dictionary<UUID, string> classifieds)
1096 {
1097 }
1098
1099 public void SendParcelDwellReply(int localID, UUID parcelID, float dwell)
1100 {
1101 }
1102
1103 public void SendUserInfoReply(bool imViaEmail, bool visible, string email)
1104 {
1105 }
1106
1107 public void SendCreateGroupReply(UUID groupID, bool success, string message)
1108 {
1109 }
1110
1111 public void RefreshGroupMembership()
1112 {
1113 }
1114
1115 public void SendUseCachedMuteList()
1116 {
1117 }
1118
1119 public void SendMuteListUpdate(string filename)
1120 {
1121 }
1122
1123 public void SendPickInfoReply(UUID pickID,UUID creatorID, bool topPick, UUID parcelID, string name, string desc, UUID snapshotID, string user, string originalName, string simName, Vector3 posGlobal, int sortOrder, bool enabled)
1124 {
1125 }
1126 #endregion
1127
1128 public void SendRebakeAvatarTextures(UUID textureID)
1129 {
1130 }
1131
1132 public void SendAvatarInterestsReply(UUID avatarID, uint wantMask, string wantText, uint skillsMask, string skillsText, string languages)
1133 {
1134 }
1135
1136 public void SendGroupAccountingDetails(IClientAPI sender,UUID groupID, UUID transactionID, UUID sessionID, int amt)
1137 {
1138 }
1139
1140 public void SendGroupAccountingSummary(IClientAPI sender,UUID groupID, uint moneyAmt, int totalTier, int usedTier)
1141 {
1142 }
1143
1144 public void SendGroupTransactionsSummaryDetails(IClientAPI sender,UUID groupID, UUID transactionID, UUID sessionID,int amt)
1145 {
1146 }
1147
1148 public void SendGroupVoteHistory(UUID groupID, UUID transactionID, GroupVoteHistory[] Votes)
1149 {
1150 }
1151
1152 public void SendGroupActiveProposals(UUID groupID, UUID transactionID, GroupActiveProposals[] Proposals)
1153 {
1154 }
1155
1156 public void SendChangeUserRights(UUID agentID, UUID friendID, int rights)
1157 {
1158 }
1159
1160 public void SendTextBoxRequest(string message, int chatChannel, string objectname, UUID ownerID, string ownerFirstName, string ownerLastName, UUID objectId)
1161 {
1162 }
1163
1164 public void StopFlying(ISceneEntity presence)
1165 {
1166 }
1167
1168 public void SendPlacesReply(UUID queryID, UUID transactionID, PlacesReplyData[] data)
1169 {
1170 }
1171 }
1172}
diff --git a/OpenSim/Region/Examples/SimpleModule/Properties/AssemblyInfo.cs b/OpenSim/Region/Examples/SimpleModule/Properties/AssemblyInfo.cs
deleted file mode 100644
index 5e09adb..0000000
--- a/OpenSim/Region/Examples/SimpleModule/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,62 +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.Reflection;
29using System.Runtime.InteropServices;
30
31// General information about an assembly is controlled through the following
32// set of attributes. Change these attribute values to modify the information
33// associated with an assembly.
34[assembly: AssemblyTitle("OpenSim.Region.Examples.SimpleModule")]
35[assembly: AssemblyDescription("")]
36[assembly: AssemblyConfiguration("")]
37[assembly: AssemblyCompany("http://opensimulator.org")]
38[assembly: AssemblyProduct("OpenSim.Region.Examples.SimpleModule")]
39[assembly: AssemblyCopyright("Copyright (c) 2008")]
40[assembly: AssemblyTrademark("")]
41[assembly: AssemblyCulture("")]
42
43// Setting ComVisible to false makes the types in this assembly not visible
44// to COM components. If you need to access a type in this assembly from
45// COM, set the ComVisible attribute to true on that type.
46[assembly: ComVisible(false)]
47
48// The following GUID is for the ID of the typelib if this project is exposed to COM
49[assembly: Guid("f0caca77-7818-4a43-9200-0a8548009a05")]
50
51// Version information for an assembly consists of the following four values:
52//
53// Major Version
54// Minor Version
55// Build Number
56// Revision
57//
58// You can specify all the values or you can default the Build and Revision Numbers
59// by using the '*' as shown below:
60// [assembly: AssemblyVersion("0.6.5.*")]
61[assembly: AssemblyVersion("0.6.5.*")]
62[assembly: AssemblyFileVersion("0.6.5.0")]
diff --git a/OpenSim/Region/Examples/SimpleModule/README.txt b/OpenSim/Region/Examples/SimpleModule/README.txt
deleted file mode 100644
index 025e33d..0000000
--- a/OpenSim/Region/Examples/SimpleModule/README.txt
+++ /dev/null
@@ -1,9 +0,0 @@
1!!!IMPORTANT NOTE!!!
2
3This code snippet provided as an example of coding functional content with region modules.
4
5As of 13/3 2008 this module actually renders all regions within the instance unusable if enabled by dragging the dll from ./bin to global /bin.
6
7So, use at own peril and in dedicated instance.
8
9Peace.
diff --git a/OpenSim/Region/Examples/SimpleModule/RegionModule.cs b/OpenSim/Region/Examples/SimpleModule/RegionModule.cs
deleted file mode 100644
index 3b8ce37..0000000
--- a/OpenSim/Region/Examples/SimpleModule/RegionModule.cs
+++ /dev/null
@@ -1,147 +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.Collections.Generic;
29using Nini.Config;
30using OpenMetaverse;
31using OpenSim.Framework;
32using OpenSim.Region.Framework.Interfaces;
33using OpenSim.Region.Framework.Scenes;
34
35namespace OpenSim.Region.Examples.SimpleModule
36{
37 /// <summary>
38 /// Example region module.
39 /// </summary>
40 /// <remarks>
41 /// This is an old and unmaintained region module which uses the old style module interface. It is not loaded into
42 /// OpenSim by default. If you want to try enabling it, look in the bin folder of this project.
43 /// Please see the README.txt in this project on the filesystem for some more information.
44 /// Nonetheless, it may contain some useful example code so has been left here for now.
45 ///
46 /// You can see bare bones examples of the more modern region module system in OpenSim/Region/OptionalModules/Example
47 /// </remarks>
48 public class RegionModule : IRegionModule
49 {
50 #region IRegionModule Members
51
52 private Scene m_scene;
53
54 public void Initialise(Scene scene, IConfigSource source)
55 {
56 m_scene = scene;
57 }
58
59 public void PostInitialise()
60 {
61 // RegionInfo regionInfo = m_scene.RegionInfo;
62
63 // Vector3 pos = new Vector3(110, 129, 27);
64
65 //AddCpuCounter(regionInfo, pos);
66 // AddComplexObjects(regionInfo, pos);
67 AddAvatars();
68 // AddFileSystemObjects();
69 }
70
71 // private void AddFileSystemObjects()
72 // {
73 // DirectoryInfo dirInfo = new DirectoryInfo(".");
74
75 // float x = 0;
76 // float z = 0;
77
78 // foreach (FileInfo fileInfo in dirInfo.GetFiles())
79 // {
80 // Vector3 filePos = new Vector3(100 + x, 129, 27 + z);
81 // x = x + 2;
82 // if (x > 50)
83 // {
84 // x = 0;
85 // z = z + 2;
86 // }
87
88 // FileSystemObject fileObject = new FileSystemObject(m_scene, fileInfo, filePos);
89 // m_scene.AddNewSceneObject(fileObject, true);
90 // }
91 // }
92
93 private void AddAvatars()
94 {
95 for (int i = 0; i < 1; i++)
96 {
97 MyNpcCharacter m_character = new MyNpcCharacter(m_scene);
98 m_scene.AddNewClient(m_character, PresenceType.Npc);
99 m_scene.AgentCrossing(m_character.AgentId, Vector3.Zero, false);
100 }
101
102 m_scene.ForEachScenePresence(delegate(ScenePresence sp)
103 {
104 if (!sp.IsChildAgent)
105 sp.AbsolutePosition =
106 new Vector3((float)Util.RandomClass.Next(100, 200), (float)Util.RandomClass.Next(30, 200), 2);
107 });
108 }
109
110 // private void AddComplexObjects(RegionInfo regionInfo, Vector3 pos)
111 // {
112 // int objs = 3;
113
114 // for (int i = 0; i < (objs*objs*objs); i++)
115 // {
116 // Vector3 posOffset = new Vector3((i % objs) * 4, ((i % (objs*objs)) / (objs)) * 4, (i / (objs*objs)) * 4);
117 // ComplexObject complexObject =
118 // new ComplexObject(m_scene, regionInfo.RegionHandle, UUID.Zero, pos + posOffset);
119 // m_scene.AddNewSceneObject(complexObject, true);
120 // }
121 // }
122
123 // private void AddCpuCounter(RegionInfo regionInfo, Vector3 pos)
124 // {
125 // SceneObjectGroup sceneObject =
126 // new CpuCounterObject(m_scene, regionInfo.RegionHandle, UUID.Zero, pos + new Vector3(1f, 1f, 1f));
127 // m_scene.AddNewSceneObject(sceneObject, true);
128 // }
129
130 public void Close()
131 {
132 m_scene = null;
133 }
134
135 public string Name
136 {
137 get { return GetType().AssemblyQualifiedName; }
138 }
139
140 public bool IsSharedModule
141 {
142 get { return false; }
143 }
144
145 #endregion
146 }
147}
diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
index d1b7dc1..a7770ad 100644
--- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
@@ -27,8 +27,8 @@
27 27
28using System; 28using System;
29using System.Xml; 29using System.Xml;
30using System.Collections.Generic;
30using OpenMetaverse; 31using OpenMetaverse;
31using OpenMetaverse.Packets;
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Region.Framework.Scenes; 33using OpenSim.Region.Framework.Scenes;
34 34
@@ -40,6 +40,7 @@ namespace OpenSim.Region.Framework.Interfaces
40 /// RezAttachments. This should only be called upon login on the first region. 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. 41 /// Attachment rezzings on crossings and TPs are done in a different way.
42 /// </summary> 42 /// </summary>
43 /// <param name="sp"></param>
43 void RezAttachments(IScenePresence sp); 44 void RezAttachments(IScenePresence sp);
44 45
45 /// <summary> 46 /// <summary>
@@ -50,43 +51,21 @@ namespace OpenSim.Region.Framework.Interfaces
50 51
51 /// <summary> 52 /// <summary>
52 /// Delete all the presence's attachments from the scene 53 /// 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). 54 /// 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>
61 /// Attach an object to an avatar from the world.
62 /// </summary> 55 /// </summary>
63 /// <param name="controllingClient"></param> 56 /// <param name="sp"></param>
64 /// <param name="localID"></param>
65 /// <param name="attachPoint"></param>
66 /// <param name="rot"></param>
67 /// <param name="silent"></param> 57 /// <param name="silent"></param>
68 void AttachObject( 58 void DeleteAttachmentsFromScene(IScenePresence sp, bool silent);
69 IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent);
70 59
71 /// <summary> 60 /// <summary>
72 /// Attach an object to an avatar 61 /// Attach an object to an avatar
73 /// </summary> 62 /// </summary>
74 /// <param name="remoteClient"></param> 63 /// <param name="sp"></param>
75 /// <param name="grp"></param> 64 /// <param name="grp"></param>
76 /// <param name="AttachmentPt"></param> 65 /// <param name="AttachmentPt"></param>
77 /// <param name="silent"></param> 66 /// <param name="silent"></param>
78 /// <returns>true if the object was successfully attached, false otherwise</returns> 67 /// <returns>true if the object was successfully attached, false otherwise</returns>
79 bool AttachObject( 68 bool AttachObject(IScenePresence sp, SceneObjectGroup grp, uint AttachmentPt, bool silent);
80 IClientAPI remoteClient, SceneObjectGroup grp, uint AttachmentPt, bool silent);
81
82 /// <summary>
83 /// Rez an attachment from user inventory and change inventory status to match.
84 /// </summary>
85 /// <param name="remoteClient"></param>
86 /// <param name="itemID"></param>
87 /// <param name="AttachmentPt"></param>
88 /// <returns>The scene object that was attached. Null if the scene object could not be found</returns>
89 ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt);
90 69
91 /// <summary> 70 /// <summary>
92 /// Rez an attachment from user inventory and change inventory status to match. 71 /// Rez an attachment from user inventory and change inventory status to match.
@@ -95,51 +74,32 @@ namespace OpenSim.Region.Framework.Interfaces
95 /// <param name="itemID"></param> 74 /// <param name="itemID"></param>
96 /// <param name="AttachmentPt"></param> 75 /// <param name="AttachmentPt"></param>
97 /// <returns>The scene object that was attached. Null if the scene object could not be found</returns> 76 /// <returns>The scene object that was attached. Null if the scene object could not be found</returns>
98 ISceneEntity RezSingleAttachmentFromInventory(ScenePresence sp, UUID itemID, uint AttachmentPt); 77 ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt);
99 78
100 // Same as above, but also load script states from a separate doc 79 // Same as above, but also load script states from a separate doc
101 ISceneEntity RezSingleAttachmentFromInventory( 80 ISceneEntity RezSingleAttachmentFromInventory(
102 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus, XmlDocument doc); 81 IScenePresence presence, UUID itemID, uint AttachmentPt, bool updateInventoryStatus, XmlDocument doc);
103 82
104 /// <summary> 83 /// <summary>
105 /// Rez multiple attachments from a user's inventory 84 /// Rez multiple attachments from a user's inventory
106 /// </summary> 85 /// </summary>
107 /// <param name="remoteClient"></param> 86 /// <param name="sp"></param>
108 /// <param name="header"></param> 87 /// <param name="rezlist"></param>
109 /// <param name="objects"></param> 88 void RezMultipleAttachmentsFromInventory(IScenePresence sp,List<KeyValuePair<UUID, uint>> rezlist);
110 void RezMultipleAttachmentsFromInventory(
111 IClientAPI remoteClient,
112 RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header,
113 RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects);
114
115 /// <summary>
116 /// Detach an object from the avatar.
117 /// </summary>
118 /// <remarks>
119 /// This method is called in response to a client's detach request, so we only update the information in
120 /// inventory
121 /// </remarks>
122 /// <param name="objectLocalID"></param>
123 /// <param name="remoteClient"></param>
124 void DetachObject(uint objectLocalID, IClientAPI remoteClient);
125 89
126 /// <summary> 90 /// <summary>
127 /// Detach the given item to the ground. 91 /// Detach the given item to the ground.
128 /// </summary> 92 /// </summary>
93 /// <param name="sp"></param>
129 /// <param name="objectLocalID"></param> 94 /// <param name="objectLocalID"></param>
130 /// <param name="remoteClient"></param> 95 void DetachSingleAttachmentToGround(IScenePresence sp, uint objectLocalID);
131 void DetachSingleAttachmentToGround(uint objectLocalID, IClientAPI remoteClient);
132 96
133 /// <summary> 97 /// <summary>
134 /// Detach the given item so that it remains in the user's inventory. 98 /// Detach the given item so that it remains in the user's inventory.
135 /// </summary> 99 /// </summary>
136 /// <param name="itemID"> 100 /// <param name="sp">/param>
137 /// A <see cref="UUID"/> 101 /// <param name="itemID"></param>
138 /// </param> 102 void DetachSingleAttachmentToInv(IScenePresence sp, UUID itemID);
139 /// <param name="remoteClient">
140 /// A <see cref="IClientAPI"/>
141 /// </param>
142 void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient);
143 103
144 /// Update the position of an attachment. 104 /// Update the position of an attachment.
145 /// </summary> 105 /// </summary>
diff --git a/OpenSim/Region/Framework/Interfaces/IEstateDataService.cs b/OpenSim/Region/Framework/Interfaces/IEstateDataService.cs
index 7066cf2..35cc220 100644
--- a/OpenSim/Region/Framework/Interfaces/IEstateDataService.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEstateDataService.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -48,6 +48,14 @@ namespace OpenSim.Region.Framework.Interfaces
48 /// <param name="estateID"></param> 48 /// <param name="estateID"></param>
49 /// <returns></returns> 49 /// <returns></returns>
50 EstateSettings LoadEstateSettings(int estateID); 50 EstateSettings LoadEstateSettings(int estateID);
51
52 /// <summary>
53 /// Create a new estate.
54 /// </summary>
55 /// <returns>
56 /// A <see cref="EstateSettings"/>
57 /// </returns>
58 EstateSettings CreateNewEstate();
51 59
52 /// <summary> 60 /// <summary>
53 /// Load/Get all estate settings. 61 /// Load/Get all estate settings.
diff --git a/OpenSim/Region/Framework/Interfaces/IEstateDataStore.cs b/OpenSim/Region/Framework/Interfaces/IEstateDataStore.cs
index d790a30..8febb13 100644
--- a/OpenSim/Region/Framework/Interfaces/IEstateDataStore.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEstateDataStore.cs
@@ -55,6 +55,14 @@ namespace OpenSim.Region.Framework.Interfaces
55 EstateSettings LoadEstateSettings(int estateID); 55 EstateSettings LoadEstateSettings(int estateID);
56 56
57 /// <summary> 57 /// <summary>
58 /// Create a new estate.
59 /// </summary>
60 /// <returns>
61 /// A <see cref="EstateSettings"/>
62 /// </returns>
63 EstateSettings CreateNewEstate();
64
65 /// <summary>
58 /// Load/Get all estate settings. 66 /// Load/Get all estate settings.
59 /// </summary> 67 /// </summary>
60 /// <returns>An empty list if no estates were found.</returns> 68 /// <returns>An empty list if no estates were found.</returns>
diff --git a/OpenSim/Region/Framework/Interfaces/IRegionModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionModule.cs
index e25a6e8..2bb0c75 100644
--- a/OpenSim/Region/Framework/Interfaces/IRegionModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IRegionModule.cs
@@ -35,7 +35,16 @@ namespace OpenSim.Region.Framework.Interfaces
35 /// </summary> 35 /// </summary>
36 public interface IRegionModule 36 public interface IRegionModule
37 { 37 {
38 /// <summary>
39 /// Initialize the module.
40 /// </summary>
41 /// <remarks>
42 /// For a shared module this can be called multiple times - once per scene.
43 /// </remarks>
44 /// <param name="scene"></param>
45 /// <param name="source">Configuration information. For a shared module this will be identical on every scene call</param>
38 void Initialise(Scene scene, IConfigSource source); 46 void Initialise(Scene scene, IConfigSource source);
47
39 void PostInitialise(); 48 void PostInitialise();
40 void Close(); 49 void Close();
41 string Name { get; } 50 string Name { get; }
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index 4925175..904a657 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -181,8 +181,8 @@ TrySetMovementAnimation("STAND");
181 bool heldBack = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG); 181 bool heldBack = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG);
182 bool heldLeft = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS); 182 bool heldLeft = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS);
183 bool heldRight = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG); 183 bool heldRight = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG);
184 //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT; 184 bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
185 //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT; 185 bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
186 bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS; 186 bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS;
187 bool heldDown = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG; 187 bool heldDown = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG;
188 //bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY; 188 //bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY;
@@ -404,7 +404,17 @@ TrySetMovementAnimation("STAND");
404 else if (m_scenePresence.SetAlwaysRun) 404 else if (m_scenePresence.SetAlwaysRun)
405 return "RUN"; 405 return "RUN";
406 else 406 else
407 return "WALK"; 407 {
408 // Not walking
409 if (move.Z < 0)
410 return "CROUCH";
411 else if (heldTurnLeft)
412 return "TURNLEFT";
413 else if (heldTurnRight)
414 return "TURNRIGHT";
415 else
416 return "WALK";
417 }
408 } 418 }
409// rm for jumping else 419// rm for jumping else
410 else if (!m_jumping) // add for jumping 420 else if (!m_jumping) // add for jumping
diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
index 088839d..12688bd 100644
--- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
+++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
@@ -119,6 +119,11 @@ namespace OpenSim.Region.Framework.Scenes
119 private void InventoryRunDeleteTimer(object sender, ElapsedEventArgs e) 119 private void InventoryRunDeleteTimer(object sender, ElapsedEventArgs e)
120 { 120 {
121 m_log.Debug("[ASYNC DELETER]: Starting send to inventory loop"); 121 m_log.Debug("[ASYNC DELETER]: Starting send to inventory loop");
122
123 // We must set appearance parameters in the en_US culture in order to avoid issues where values are saved
124 // in a culture where decimal points are commas and then reloaded in a culture which just treats them as
125 // number seperators.
126 Culture.SetCurrentCulture();
122 127
123 while (InventoryDeQueueAndDelete()) 128 while (InventoryDeQueueAndDelete())
124 { 129 {
diff --git a/OpenSim/Region/Framework/Scenes/EntityBase.cs b/OpenSim/Region/Framework/Scenes/EntityBase.cs
index 213431a..680a4a3 100644
--- a/OpenSim/Region/Framework/Scenes/EntityBase.cs
+++ b/OpenSim/Region/Framework/Scenes/EntityBase.cs
@@ -26,8 +26,10 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Reflection;
29using System.Runtime.Serialization; 30using System.Runtime.Serialization;
30using System.Security.Permissions; 31using System.Security.Permissions;
32using log4net;
31using OpenSim.Framework; 33using OpenSim.Framework;
32using OpenMetaverse; 34using OpenMetaverse;
33 35
@@ -35,6 +37,8 @@ namespace OpenSim.Region.Framework.Scenes
35{ 37{
36 public abstract class EntityBase : ISceneEntity 38 public abstract class EntityBase : ISceneEntity
37 { 39 {
40 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41
38 /// <summary> 42 /// <summary>
39 /// The scene to which this entity belongs 43 /// The scene to which this entity belongs
40 /// </summary> 44 /// </summary>
@@ -71,12 +75,15 @@ namespace OpenSim.Region.Framework.Scenes
71 protected Vector3 m_pos; 75 protected Vector3 m_pos;
72 76
73 /// <summary> 77 /// <summary>
74 /// 78 /// Absolute position of this entity in a scene.
75 /// </summary> 79 /// </summary>
76 public virtual Vector3 AbsolutePosition 80 public virtual Vector3 AbsolutePosition
77 { 81 {
78 get { return m_pos; } 82 get { return m_pos; }
79 set { m_pos = value; } 83 set
84 {
85 m_pos = value;
86 }
80 } 87 }
81 88
82 protected Vector3 m_velocity; 89 protected Vector3 m_velocity;
@@ -108,11 +115,6 @@ namespace OpenSim.Region.Framework.Scenes
108 } 115 }
109 116
110 /// <summary> 117 /// <summary>
111 ///
112 /// </summary>
113 public abstract void UpdateMovement();
114
115 /// <summary>
116 /// Performs any updates that need to be done at each frame, as opposed to immediately. 118 /// Performs any updates that need to be done at each frame, as opposed to immediately.
117 /// These included scheduled updates and updates that occur due to physics processing. 119 /// These included scheduled updates and updates that occur due to physics processing.
118 /// </summary> 120 /// </summary>
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index c2ec5d0..53f0f2e 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -261,7 +261,7 @@ namespace OpenSim.Region.Framework.Scenes
261 item.AssetID = asset.FullID; 261 item.AssetID = asset.FullID;
262 group.UpdateInventoryItem(item); 262 group.UpdateInventoryItem(item);
263 263
264 part.GetProperties(remoteClient); 264 part.SendPropertiesToClient(remoteClient);
265 265
266 // Trigger rerunning of script (use TriggerRezScript event, see RezScript) 266 // Trigger rerunning of script (use TriggerRezScript event, see RezScript)
267 ArrayList errors = new ArrayList(); 267 ArrayList errors = new ArrayList();
@@ -316,6 +316,10 @@ namespace OpenSim.Region.Framework.Scenes
316 public void UpdateInventoryItemAsset(IClientAPI remoteClient, UUID transactionID, 316 public void UpdateInventoryItemAsset(IClientAPI remoteClient, UUID transactionID,
317 UUID itemID, InventoryItemBase itemUpd) 317 UUID itemID, InventoryItemBase itemUpd)
318 { 318 {
319// m_log.DebugFormat(
320// "[USER INVENTORY]: Updating asset for item {0} {1}, transaction ID {2} for {3}",
321// itemID, itemUpd.Name, transactionID, remoteClient.Name);
322
319 // This one will let people set next perms on items in agent 323 // This one will let people set next perms on items in agent
320 // inventory. Rut-Roh. Whatever. Make this secure. Yeah. 324 // inventory. Rut-Roh. Whatever. Make this secure. Yeah.
321 // 325 //
@@ -368,8 +372,7 @@ namespace OpenSim.Region.Framework.Scenes
368 IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>(); 372 IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
369 if (agentTransactions != null) 373 if (agentTransactions != null)
370 { 374 {
371 agentTransactions.HandleItemUpdateFromTransaction( 375 agentTransactions.HandleItemUpdateFromTransaction(remoteClient, transactionID, item);
372 remoteClient, transactionID, item);
373 } 376 }
374 } 377 }
375 } 378 }
@@ -1005,7 +1008,7 @@ namespace OpenSim.Region.Framework.Scenes
1005 } 1008 }
1006 1009
1007 group.RemoveInventoryItem(localID, itemID); 1010 group.RemoveInventoryItem(localID, itemID);
1008 part.GetProperties(remoteClient); 1011 part.SendPropertiesToClient(remoteClient);
1009 } 1012 }
1010 } 1013 }
1011 1014
@@ -1283,7 +1286,7 @@ namespace OpenSim.Region.Framework.Scenes
1283 1286
1284 if (TryGetScenePresence(srcTaskItem.OwnerID, out avatar)) 1287 if (TryGetScenePresence(srcTaskItem.OwnerID, out avatar))
1285 { 1288 {
1286 destPart.GetProperties(avatar.ControllingClient); 1289 destPart.SendPropertiesToClient(avatar.ControllingClient);
1287 } 1290 }
1288 } 1291 }
1289 1292
@@ -1446,7 +1449,7 @@ namespace OpenSim.Region.Framework.Scenes
1446 m_log.InfoFormat( 1449 m_log.InfoFormat(
1447 "[PRIM INVENTORY]: Update with item {0} requested of prim {1} for {2}", 1450 "[PRIM INVENTORY]: Update with item {0} requested of prim {1} for {2}",
1448 item.Name, primLocalID, remoteClient.Name); 1451 item.Name, primLocalID, remoteClient.Name);
1449 part.GetProperties(remoteClient); 1452 part.SendPropertiesToClient(remoteClient);
1450 if (!Permissions.BypassPermissions()) 1453 if (!Permissions.BypassPermissions())
1451 { 1454 {
1452 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) 1455 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
@@ -1534,7 +1537,7 @@ namespace OpenSim.Region.Framework.Scenes
1534 1537
1535 if (part.Inventory.UpdateInventoryItem(itemInfo)) 1538 if (part.Inventory.UpdateInventoryItem(itemInfo))
1536 { 1539 {
1537 part.GetProperties(remoteClient); 1540 part.SendPropertiesToClient(remoteClient);
1538 } 1541 }
1539 } 1542 }
1540 } 1543 }
@@ -1586,7 +1589,7 @@ namespace OpenSim.Region.Framework.Scenes
1586 // m_log.InfoFormat("[PRIMINVENTORY]: " + 1589 // m_log.InfoFormat("[PRIMINVENTORY]: " +
1587 // "Rezzed script {0} into prim local ID {1} for user {2}", 1590 // "Rezzed script {0} into prim local ID {1} for user {2}",
1588 // item.inventoryName, localID, remoteClient.Name); 1591 // item.inventoryName, localID, remoteClient.Name);
1589 part.GetProperties(remoteClient); 1592 part.SendPropertiesToClient(remoteClient);
1590 part.ParentGroup.ResumeScripts(); 1593 part.ParentGroup.ResumeScripts();
1591 } 1594 }
1592 else 1595 else
@@ -1644,7 +1647,7 @@ namespace OpenSim.Region.Framework.Scenes
1644 taskItem.AssetID = asset.FullID; 1647 taskItem.AssetID = asset.FullID;
1645 1648
1646 part.Inventory.AddInventoryItem(taskItem, false); 1649 part.Inventory.AddInventoryItem(taskItem, false);
1647 part.GetProperties(remoteClient); 1650 part.SendPropertiesToClient(remoteClient);
1648 1651
1649 part.Inventory.CreateScriptInstance(taskItem, 0, false, DefaultScriptEngine, 0); 1652 part.Inventory.CreateScriptInstance(taskItem, 0, false, DefaultScriptEngine, 0);
1650 part.ParentGroup.ResumeScripts(); 1653 part.ParentGroup.ResumeScripts();
@@ -1758,7 +1761,7 @@ namespace OpenSim.Region.Framework.Scenes
1758 1761
1759 if (TryGetScenePresence(srcTaskItem.OwnerID, out avatar)) 1762 if (TryGetScenePresence(srcTaskItem.OwnerID, out avatar))
1760 { 1763 {
1761 destPart.GetProperties(avatar.ControllingClient); 1764 destPart.SendPropertiesToClient(avatar.ControllingClient);
1762 } 1765 }
1763 } 1766 }
1764 1767
@@ -2217,7 +2220,7 @@ namespace OpenSim.Region.Framework.Scenes
2217 SceneObjectPart part = GetSceneObjectPart(localID); 2220 SceneObjectPart part = GetSceneObjectPart(localID);
2218 if (part == null) 2221 if (part == null)
2219 continue; 2222 continue;
2220 part.GetProperties(remoteClient); 2223 part.SendPropertiesToClient(remoteClient);
2221 } 2224 }
2222 } 2225 }
2223 2226
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
index 9da57a8..575079f 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -144,7 +144,7 @@ namespace OpenSim.Region.Framework.Scenes
144 { 144 {
145 if (((SceneObjectGroup) ent).LocalId == primLocalID) 145 if (((SceneObjectGroup) ent).LocalId == primLocalID)
146 { 146 {
147 ((SceneObjectGroup) ent).GetProperties(remoteClient); 147 ((SceneObjectGroup) ent).SendPropertiesToClient(remoteClient);
148 ((SceneObjectGroup) ent).IsSelected = true; 148 ((SceneObjectGroup) ent).IsSelected = true;
149 // A prim is only tainted if it's allowed to be edited by the person clicking it. 149 // A prim is only tainted if it's allowed to be edited by the person clicking it.
150 if (Permissions.CanEditObject(((SceneObjectGroup)ent).UUID, remoteClient.AgentId) 150 if (Permissions.CanEditObject(((SceneObjectGroup)ent).UUID, remoteClient.AgentId)
@@ -167,7 +167,7 @@ namespace OpenSim.Region.Framework.Scenes
167 { 167 {
168 if (part.LocalId == primLocalID) 168 if (part.LocalId == primLocalID)
169 { 169 {
170 part.GetProperties(remoteClient); 170 part.SendPropertiesToClient(remoteClient);
171 foundPrim = true; 171 foundPrim = true;
172 break; 172 break;
173 } 173 }
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index c5bb2b2..b288c8a 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -896,6 +896,8 @@ namespace OpenSim.Region.Framework.Scenes
896 896
897 if (dm != null) 897 if (dm != null)
898 m_eventManager.OnPermissionError += dm.SendAlertToUser; 898 m_eventManager.OnPermissionError += dm.SendAlertToUser;
899
900 m_eventManager.OnSignificantClientMovement += HandleOnSignificantClientMovement;
899 } 901 }
900 902
901 public override string GetSimulatorVersion() 903 public override string GetSimulatorVersion()
@@ -1198,87 +1200,6 @@ namespace OpenSim.Region.Framework.Scenes
1198 m_dialogModule = RequestModuleInterface<IDialogModule>(); 1200 m_dialogModule = RequestModuleInterface<IDialogModule>();
1199 m_capsModule = RequestModuleInterface<ICapabilitiesModule>(); 1201 m_capsModule = RequestModuleInterface<ICapabilitiesModule>();
1200 m_teleportModule = RequestModuleInterface<IEntityTransferModule>(); 1202 m_teleportModule = RequestModuleInterface<IEntityTransferModule>();
1201
1202 // Shoving this in here for now, because we have the needed
1203 // interfaces at this point
1204 //
1205 // TODO: Find a better place for this
1206 //
1207 while (m_regInfo.EstateSettings.EstateOwner == UUID.Zero && MainConsole.Instance != null)
1208 {
1209 MainConsole.Instance.OutputFormat("Estate {0} has no owner set.", m_regInfo.EstateSettings.EstateName);
1210 List<char> excluded = new List<char>(new char[1]{' '});
1211 string first = MainConsole.Instance.CmdPrompt("Estate owner first name", "Test", excluded);
1212 string last = MainConsole.Instance.CmdPrompt("Estate owner last name", "User", excluded);
1213
1214 UserAccount account = UserAccountService.GetUserAccount(m_regInfo.ScopeID, first, last);
1215
1216 if (account == null)
1217 {
1218 // Create a new account
1219 account = new UserAccount(m_regInfo.ScopeID, first, last, String.Empty);
1220 if (account.ServiceURLs == null || (account.ServiceURLs != null && account.ServiceURLs.Count == 0))
1221 {
1222 account.ServiceURLs = new Dictionary<string, object>();
1223 account.ServiceURLs["HomeURI"] = string.Empty;
1224 account.ServiceURLs["GatekeeperURI"] = string.Empty;
1225 account.ServiceURLs["InventoryServerURI"] = string.Empty;
1226 account.ServiceURLs["AssetServerURI"] = string.Empty;
1227 }
1228
1229 if (UserAccountService.StoreUserAccount(account))
1230 {
1231 string password = MainConsole.Instance.PasswdPrompt("Password");
1232 string email = MainConsole.Instance.CmdPrompt("Email", "");
1233
1234 account.Email = email;
1235 UserAccountService.StoreUserAccount(account);
1236
1237 bool success = false;
1238 success = AuthenticationService.SetPassword(account.PrincipalID, password);
1239 if (!success)
1240 m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to set password for account {0} {1}.",
1241 first, last);
1242
1243 GridRegion home = null;
1244 if (GridService != null)
1245 {
1246 List<GridRegion> defaultRegions = GridService.GetDefaultRegions(UUID.Zero);
1247 if (defaultRegions != null && defaultRegions.Count >= 1)
1248 home = defaultRegions[0];
1249
1250 if (GridUserService != null && home != null)
1251 GridUserService.SetHome(account.PrincipalID.ToString(), home.RegionID, new Vector3(128, 128, 0), new Vector3(0, 1, 0));
1252 else
1253 m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to set home for account {0} {1}.",
1254 first, last);
1255
1256 }
1257 else
1258 m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to retrieve home region for account {0} {1}.",
1259 first, last);
1260
1261 if (InventoryService != null)
1262 success = InventoryService.CreateUserInventory(account.PrincipalID);
1263 if (!success)
1264 m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to create inventory for account {0} {1}.",
1265 first, last);
1266
1267
1268 m_log.InfoFormat("[USER ACCOUNT SERVICE]: Account {0} {1} created successfully", first, last);
1269
1270 m_regInfo.EstateSettings.EstateOwner = account.PrincipalID;
1271 m_regInfo.EstateSettings.Save();
1272 }
1273 else
1274 m_log.ErrorFormat("[SCENE]: Unable to store account. If this simulator is connected to a grid, you must create the estate owner account first.");
1275 }
1276 else
1277 {
1278 m_regInfo.EstateSettings.EstateOwner = account.PrincipalID;
1279 m_regInfo.EstateSettings.Save();
1280 }
1281 }
1282 } 1203 }
1283 1204
1284 #endregion 1205 #endregion
@@ -1382,28 +1303,12 @@ namespace OpenSim.Region.Framework.Scenes
1382 tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS); 1303 tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS);
1383 } 1304 }
1384 1305
1385 if (RegionStatus != RegionStatus.SlaveScene) 1306 if (Frame % m_update_events == 0)
1386 { 1307 {
1387 if (Frame % m_update_events == 0) 1308 int evMS = Util.EnvironmentTickCount();
1388 { 1309 UpdateEvents();
1389 int evMS = Util.EnvironmentTickCount(); 1310 eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
1390 UpdateEvents(); 1311 }
1391 eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
1392 }
1393
1394 if (Frame % m_update_backup == 0)
1395 {
1396 int backMS = Util.EnvironmentTickCount();
1397 UpdateStorageBackup();
1398 backupMS = Util.EnvironmentTickCountSubtract(backMS);
1399 }
1400
1401 if (Frame % m_update_terrain == 0)
1402 {
1403 int terMS = Util.EnvironmentTickCount();
1404 UpdateTerrain();
1405 terrainMS = Util.EnvironmentTickCountSubtract(terMS);
1406 }
1407 1312
1408 // if (Frame % m_update_land == 0) 1313 // if (Frame % m_update_land == 0)
1409 // { 1314 // {
@@ -1412,26 +1317,46 @@ namespace OpenSim.Region.Framework.Scenes
1412 // landMS = Util.EnvironmentTickCountSubtract(ldMS); 1317 // landMS = Util.EnvironmentTickCountSubtract(ldMS);
1413 // } 1318 // }
1414 1319
1415 frameMS = Util.EnvironmentTickCountSubtract(tmpFrameMS); 1320 if (Frame % m_update_backup == 0)
1416 otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS; 1321 {
1417 lastCompletedFrame = Util.EnvironmentTickCount(); 1322 int backMS = Util.EnvironmentTickCount();
1418 1323 UpdateStorageBackup();
1419 // if (Frame%m_update_avatars == 0) 1324 backupMS = Util.EnvironmentTickCountSubtract(backMS);
1420 // UpdateInWorldTime(); 1325 }
1421 StatsReporter.AddPhysicsFPS(physicsFPS); 1326
1422 StatsReporter.AddTimeDilation(TimeDilation); 1327 if (Frame % m_update_terrain == 0)
1423 StatsReporter.AddFPS(1); 1328 {
1424 StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount()); 1329 int terMS = Util.EnvironmentTickCount();
1425 StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount()); 1330 UpdateTerrain();
1426 StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount()); 1331 terrainMS = Util.EnvironmentTickCountSubtract(terMS);
1427 StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
1428 StatsReporter.addFrameMS(frameMS);
1429 StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
1430 StatsReporter.addOtherMS(otherMS);
1431 StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
1432 StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
1433 } 1332 }
1434 1333
1334 //if (Frame % m_update_land == 0)
1335 //{
1336 // int ldMS = Util.EnvironmentTickCount();
1337 // UpdateLand();
1338 // landMS = Util.EnvironmentTickCountSubtract(ldMS);
1339 //}
1340
1341 frameMS = Util.EnvironmentTickCountSubtract(tmpFrameMS);
1342 otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
1343 lastCompletedFrame = Util.EnvironmentTickCount();
1344
1345 // if (Frame%m_update_avatars == 0)
1346 // UpdateInWorldTime();
1347 StatsReporter.AddPhysicsFPS(physicsFPS);
1348 StatsReporter.AddTimeDilation(TimeDilation);
1349 StatsReporter.AddFPS(1);
1350 StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
1351 StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
1352 StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
1353 StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
1354 StatsReporter.addFrameMS(frameMS);
1355 StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
1356 StatsReporter.addOtherMS(otherMS);
1357 StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
1358 StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
1359
1435 if (LoginsDisabled && Frame == 20) 1360 if (LoginsDisabled && Frame == 20)
1436 { 1361 {
1437 // In 99.9% of cases it is a bad idea to manually force garbage collection. However, 1362 // In 99.9% of cases it is a bad idea to manually force garbage collection. However,
@@ -2603,9 +2528,7 @@ namespace OpenSim.Region.Framework.Scenes
2603 RootPrim.RemFlag(PrimFlags.TemporaryOnRez); 2528 RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
2604 2529
2605 if (AttachmentsModule != null) 2530 if (AttachmentsModule != null)
2606 AttachmentsModule.AttachObject(sp.ControllingClient, grp, 0, false); 2531 AttachmentsModule.AttachObject(sp, grp, 0, false);
2607
2608 m_log.DebugFormat("[SCENE]: Attachment {0} arrived and scene presence was found, attaching", sceneObject.UUID);
2609 } 2532 }
2610 else 2533 else
2611 { 2534 {
@@ -5477,7 +5400,7 @@ namespace OpenSim.Region.Framework.Scenes
5477 return true; 5400 return true;
5478 } 5401 }
5479 5402
5480 public void StartTimerWatchdog() 5403 public void StartTimerWatchdog()
5481 { 5404 {
5482 m_timerWatchdog.Interval = 1000; 5405 m_timerWatchdog.Interval = 1000;
5483 m_timerWatchdog.Elapsed += TimerWatchdog; 5406 m_timerWatchdog.Elapsed += TimerWatchdog;
@@ -5488,6 +5411,70 @@ namespace OpenSim.Region.Framework.Scenes
5488 public void TimerWatchdog(object sender, ElapsedEventArgs e) 5411 public void TimerWatchdog(object sender, ElapsedEventArgs e)
5489 { 5412 {
5490 CheckHeartbeat(); 5413 CheckHeartbeat();
5414 }
5415
5416 /// This method deals with movement when an avatar is automatically moving (but this is distinct from the
5417 /// autopilot that moves an avatar to a sit target!.
5418 /// </summary>
5419 /// <remarks>
5420 /// This is not intended as a permament location for this method.
5421 /// </remarks>
5422 /// <param name="presence"></param>
5423 private void HandleOnSignificantClientMovement(ScenePresence presence)
5424 {
5425 if (presence.MovingToTarget)
5426 {
5427 double distanceToTarget = Util.GetDistanceTo(presence.AbsolutePosition, presence.MoveToPositionTarget);
5428// m_log.DebugFormat(
5429// "[SCENE]: Abs pos of {0} is {1}, target {2}, distance {3}",
5430// presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget, distanceToTarget);
5431
5432 // Check the error term of the current position in relation to the target position
5433 if (distanceToTarget <= ScenePresence.SIGNIFICANT_MOVEMENT)
5434 {
5435 // We are close enough to the target
5436// m_log.DebugFormat("[SCENEE]: Stopping autopilot of {0}", presence.Name);
5437
5438 presence.Velocity = Vector3.Zero;
5439 presence.AbsolutePosition = presence.MoveToPositionTarget;
5440 presence.ResetMoveToTarget();
5441
5442 if (presence.PhysicsActor.Flying)
5443 {
5444 // A horrible hack to stop the avatar dead in its tracks rather than having them overshoot
5445 // the target if flying.
5446 // We really need to be more subtle (slow the avatar as it approaches the target) or at
5447 // least be able to set collision status once, rather than 5 times to give it enough
5448 // weighting so that that PhysicsActor thinks it really is colliding.
5449 for (int i = 0; i < 5; i++)
5450 presence.PhysicsActor.IsColliding = true;
5451
5452 if (presence.LandAtTarget)
5453 presence.PhysicsActor.Flying = false;
5454
5455// Vector3 targetPos = presence.MoveToPositionTarget;
5456// float terrainHeight = (float)presence.Scene.Heightmap[(int)targetPos.X, (int)targetPos.Y];
5457// if (targetPos.Z - terrainHeight < 0.2)
5458// {
5459// presence.PhysicsActor.Flying = false;
5460// }
5461 }
5462
5463// m_log.DebugFormat(
5464// "[SCENE]: AgentControlFlags {0}, MovementFlag {1} for {2}",
5465// presence.AgentControlFlags, presence.MovementFlag, presence.Name);
5466 }
5467 else
5468 {
5469// m_log.DebugFormat(
5470// "[SCENE]: Updating npc {0} at {1} for next movement to {2}",
5471// presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget);
5472
5473 Vector3 agent_control_v3 = new Vector3();
5474 presence.HandleMoveToTargetUpdate(ref agent_control_v3);
5475 presence.AddNewMovement(agent_control_v3);
5476 }
5477 }
5491 } 5478 }
5492 } 5479 }
5493} 5480}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 3e1439d..7493368 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -1312,13 +1312,6 @@ namespace OpenSim.Region.Framework.Scenes
1312 part.ClearUndoState(); 1312 part.ClearUndoState();
1313 } 1313 }
1314 1314
1315 public override void UpdateMovement()
1316 {
1317 SceneObjectPart[] parts = m_parts.GetArray();
1318 for (int i = 0; i < parts.Length; i++)
1319 parts[i].UpdateMovement();
1320 }
1321
1322 public ushort GetTimeDilation() 1315 public ushort GetTimeDilation()
1323 { 1316 {
1324 return Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); 1317 return Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f);
@@ -1486,7 +1479,15 @@ namespace OpenSim.Region.Framework.Scenes
1486 avatar.StandUp(); 1479 avatar.StandUp();
1487 1480
1488 if (!silent) 1481 if (!silent)
1482 {
1489 part.UpdateFlag = 0; 1483 part.UpdateFlag = 0;
1484 if (part == m_rootPart)
1485 {
1486 if (!IsAttachment || (AttachedAvatar == avatar.ControllingClient.AgentId) ||
1487 (AttachmentPoint < 31) || (AttachmentPoint > 38))
1488 avatar.ControllingClient.SendKillObject(m_regionHandle, new List<uint>() {part.LocalId});
1489 }
1490 }
1490 }); 1491 });
1491 } 1492 }
1492 1493
@@ -1939,7 +1940,7 @@ namespace OpenSim.Region.Framework.Scenes
1939 ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar); 1940 ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar);
1940 if (avatar != null) 1941 if (avatar != null)
1941 { 1942 {
1942 avatar.MoveToTarget(target, false); 1943 avatar.MoveToTarget(target, false, false);
1943 } 1944 }
1944 } 1945 }
1945 else 1946 else
@@ -2104,8 +2105,6 @@ namespace OpenSim.Region.Framework.Scenes
2104 2105
2105 #endregion 2106 #endregion
2106 2107
2107 #region Scheduling
2108
2109 public override void Update() 2108 public override void Update()
2110 { 2109 {
2111 // Check that the group was not deleted before the scheduled update 2110 // Check that the group was not deleted before the scheduled update
@@ -2256,7 +2255,14 @@ namespace OpenSim.Region.Framework.Scenes
2256 parts[i].SendTerseUpdateToAllClients(); 2255 parts[i].SendTerseUpdateToAllClients();
2257 } 2256 }
2258 2257
2259 #endregion 2258 /// <summary>
2259 /// Send metadata about the root prim (name, description, sale price, etc.) to a client.
2260 /// </summary>
2261 /// <param name="client"></param>
2262 public void SendPropertiesToClient(IClientAPI client)
2263 {
2264 m_rootPart.SendPropertiesToClient(client);
2265 }
2260 2266
2261 #region SceneGroupPart Methods 2267 #region SceneGroupPart Methods
2262 2268
@@ -2752,15 +2758,6 @@ namespace OpenSim.Region.Framework.Scenes
2752 } 2758 }
2753 2759
2754 /// <summary> 2760 /// <summary>
2755 /// Return metadata about a prim (name, description, sale price, etc.)
2756 /// </summary>
2757 /// <param name="client"></param>
2758 public void GetProperties(IClientAPI client)
2759 {
2760 m_rootPart.GetProperties(client);
2761 }
2762
2763 /// <summary>
2764 /// Set the name of a prim 2761 /// Set the name of a prim
2765 /// </summary> 2762 /// </summary>
2766 /// <param name="name"></param> 2763 /// <param name="name"></param>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 0c3b404..1a96f1b 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -804,7 +804,7 @@ namespace OpenSim.Region.Framework.Scenes
804 if (av.LinkedPrim == m_uuid) 804 if (av.LinkedPrim == m_uuid)
805 { 805 {
806 Vector3 offset = (m_offsetPosition - oldpos); 806 Vector3 offset = (m_offsetPosition - oldpos);
807 av.OffsetPosition += offset; 807 av.AbsolutePosition += offset;
808 av.SendAvatarDataToAllAgents(); 808 av.SendAvatarDataToAllAgents();
809 } 809 }
810 } 810 }
@@ -1357,8 +1357,6 @@ namespace OpenSim.Region.Framework.Scenes
1357 1357
1358 #endregion Public Properties with only Get 1358 #endregion Public Properties with only Get
1359 1359
1360 #region Private Methods
1361
1362 private uint ApplyMask(uint val, bool set, uint mask) 1360 private uint ApplyMask(uint val, bool set, uint mask)
1363 { 1361 {
1364 if (set) 1362 if (set)
@@ -1371,14 +1369,35 @@ namespace OpenSim.Region.Framework.Scenes
1371 } 1369 }
1372 } 1370 }
1373 1371
1374 private void SendObjectPropertiesToClient(UUID AgentID) 1372 /// <summary>
1373 /// Clear all pending updates of parts to clients
1374 /// </summary>
1375 private void ClearUpdateSchedule()
1376 {
1377 m_updateFlag = 0;
1378 }
1379
1380 /// <summary>
1381 /// Send this part's properties (name, description, inventory serial, base mask, etc.) to a client
1382 /// </summary>
1383 /// <param name="client"></param>
1384 public void SendPropertiesToClient(IClientAPI client)
1385 {
1386 client.SendObjectPropertiesReply(this);
1387 }
1388
1389 /// <summary>
1390 /// For the scene object group to which this part belongs, send that scene object's root part properties to a client.
1391 /// </summary>
1392 /// <param name="AgentID"></param>
1393 private void SendRootPartPropertiesToClient(UUID AgentID)
1375 { 1394 {
1376 m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 1395 m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
1377 { 1396 {
1378 // Ugly reference :( 1397 // Ugly reference :(
1379 if (avatar.UUID == AgentID) 1398 if (avatar.UUID == AgentID)
1380 { 1399 {
1381 m_parentGroup.GetProperties(avatar.ControllingClient); 1400 m_parentGroup.SendPropertiesToClient(avatar.ControllingClient);
1382 } 1401 }
1383 }); 1402 });
1384 } 1403 }
@@ -1407,8 +1426,6 @@ namespace OpenSim.Region.Framework.Scenes
1407 // } 1426 // }
1408 // } 1427 // }
1409 1428
1410 #endregion Private Methods
1411
1412 #region Public Methods 1429 #region Public Methods
1413 1430
1414 public void ResetExpire() 1431 public void ResetExpire()
@@ -1752,20 +1769,6 @@ namespace OpenSim.Region.Framework.Scenes
1752 Name, LocalId, id); 1769 Name, LocalId, id);
1753 } 1770 }
1754 1771
1755 public static SceneObjectPart Create()
1756 {
1757 SceneObjectPart part = new SceneObjectPart();
1758 part.UUID = UUID.Random();
1759
1760 PrimitiveBaseShape shape = PrimitiveBaseShape.Create();
1761 part.Shape = shape;
1762
1763 part.Name = "Object";
1764 part._ownerID = UUID.Random();
1765
1766 return part;
1767 }
1768
1769 /// <summary> 1772 /// <summary>
1770 /// Do a physics property update for a NINJA joint. 1773 /// Do a physics property update for a NINJA joint.
1771 /// </summary> 1774 /// </summary>
@@ -2077,11 +2080,6 @@ namespace OpenSim.Region.Framework.Scenes
2077 return Vector3.Zero; 2080 return Vector3.Zero;
2078 } 2081 }
2079 2082
2080 public void GetProperties(IClientAPI client)
2081 {
2082 client.SendObjectPropertiesReply(this);
2083 }
2084
2085 /// <summary> 2083 /// <summary>
2086 /// Method for a prim to get it's world position from the group. 2084 /// Method for a prim to get it's world position from the group.
2087 /// </summary> 2085 /// </summary>
@@ -3055,6 +3053,10 @@ namespace OpenSim.Region.Framework.Scenes
3055 if (ParentGroup.IsDeleted) 3053 if (ParentGroup.IsDeleted)
3056 return; 3054 return;
3057 3055
3056 if (ParentGroup.IsAttachment && (ParentGroup.AttachedAvatar != remoteClient.AgentId) &&
3057 (ParentGroup.AttachmentPoint >= 31) && (ParentGroup.AttachmentPoint <= 38))
3058 return;
3059
3058 clientFlags &= ~(uint) PrimFlags.CreateSelected; 3060 clientFlags &= ~(uint) PrimFlags.CreateSelected;
3059 3061
3060 if (remoteClient.AgentId == _ownerID) 3062 if (remoteClient.AgentId == _ownerID)
@@ -3500,7 +3502,7 @@ namespace OpenSim.Region.Framework.Scenes
3500 { 3502 {
3501 _groupID = groupID; 3503 _groupID = groupID;
3502 if (client != null) 3504 if (client != null)
3503 GetProperties(client); 3505 SendPropertiesToClient(client);
3504 m_updateFlag = 2; 3506 m_updateFlag = 2;
3505 } 3507 }
3506 3508
@@ -4242,10 +4244,6 @@ namespace OpenSim.Region.Framework.Scenes
4242 } 4244 }
4243 } 4245 }
4244 4246
4245 public virtual void UpdateMovement()
4246 {
4247 }
4248
4249 /// <summary> 4247 /// <summary>
4250 /// 4248 ///
4251 /// </summary> 4249 /// </summary>
@@ -4320,10 +4318,10 @@ namespace OpenSim.Region.Framework.Scenes
4320 4318
4321 break; 4319 break;
4322 } 4320 }
4323 SendFullUpdateToAllClients();
4324 4321
4325 SendObjectPropertiesToClient(AgentID); 4322 SendFullUpdateToAllClients();
4326 4323
4324 SendRootPartPropertiesToClient(AgentID);
4327 } 4325 }
4328 } 4326 }
4329 4327
@@ -4844,7 +4842,8 @@ namespace OpenSim.Region.Framework.Scenes
4844 if (ParentGroup.IsDeleted) 4842 if (ParentGroup.IsDeleted)
4845 return; 4843 return;
4846 4844
4847 if (ParentGroup.IsAttachment && ParentGroup.RootPart != this) 4845 if (ParentGroup.IsAttachment && ((ParentGroup.RootPart != this) ||
4846 ((ParentGroup.AttachedAvatar != remoteClient.AgentId) && (ParentGroup.AttachmentPoint >= 31) && (ParentGroup.AttachmentPoint <= 38))))
4848 return; 4847 return;
4849 4848
4850 // Causes this thread to dig into the Client Thread Data. 4849 // Causes this thread to dig into the Client Thread Data.
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index f6b690c..4edc220 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -988,11 +988,16 @@ namespace OpenSim.Region.Framework.Scenes
988 988
989 private bool CreateInventoryFileName() 989 private bool CreateInventoryFileName()
990 { 990 {
991// m_log.DebugFormat(
992// "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}",
993// m_part.Name, m_part.UUID, m_part.LocalId, m_inventorySerial);
994
991 if (m_inventoryFileName == String.Empty || 995 if (m_inventoryFileName == String.Empty ||
992 m_inventoryFileNameSerial < m_inventorySerial) 996 m_inventoryFileNameSerial < m_inventorySerial)
993 { 997 {
994 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; 998 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp";
995 m_inventoryFileNameSerial = m_inventorySerial; 999 m_inventoryFileNameSerial = m_inventorySerial;
1000
996 return true; 1001 return true;
997 } 1002 }
998 1003
@@ -1025,6 +1030,12 @@ namespace OpenSim.Region.Framework.Scenes
1025 return; 1030 return;
1026 } 1031 }
1027 1032
1033 if (m_items.Count == 0) // No inventory
1034 {
1035 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
1036 return;
1037 }
1038
1028 if (!changed) 1039 if (!changed)
1029 { 1040 {
1030 if (m_inventoryFileData.Length > 2) 1041 if (m_inventoryFileData.Length > 2)
@@ -1096,10 +1107,12 @@ namespace OpenSim.Region.Framework.Scenes
1096 if (m_inventoryFileData.Length > 2) 1107 if (m_inventoryFileData.Length > 2)
1097 { 1108 {
1098 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); 1109 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData);
1110 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
1111 Util.StringToBytes256(m_inventoryFileName));
1112 return;
1099 } 1113 }
1100 1114
1101 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, 1115 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
1102 Util.StringToBytes256(m_inventoryFileName));
1103 } 1116 }
1104 1117
1105 /// <summary> 1118 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index fa6945c..dee9bc3 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -71,7 +71,7 @@ namespace OpenSim.Region.Framework.Scenes
71 { 71 {
72// ~ScenePresence() 72// ~ScenePresence()
73// { 73// {
74// m_log.Debug("[ScenePresence] Destructor called"); 74// m_log.Debug("[SCENE PRESENCE] Destructor called");
75// } 75// }
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);
@@ -191,8 +191,6 @@ namespace OpenSim.Region.Framework.Scenes
191 191
192 private Quaternion m_bodyRot = Quaternion.Identity; 192 private Quaternion m_bodyRot = Quaternion.Identity;
193 193
194 private Quaternion m_bodyRotPrevious = Quaternion.Identity;
195
196 private const int LAND_VELOCITYMAG_MAX = 12; 194 private const int LAND_VELOCITYMAG_MAX = 12;
197 195
198 public bool IsRestrictedToRegion; 196 public bool IsRestrictedToRegion;
@@ -238,6 +236,11 @@ namespace OpenSim.Region.Framework.Scenes
238 public Vector3 MoveToPositionTarget { get; private set; } 236 public Vector3 MoveToPositionTarget { get; private set; }
239 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);
240 238
239 /// <summary>
240 /// Controls whether an avatar automatically moving to a target will land when it gets there (if flying).
241 /// </summary>
242 public bool LandAtTarget { get; private set; }
243
241 private bool m_followCamAuto; 244 private bool m_followCamAuto;
242 245
243 private int m_movementUpdateCount; 246 private int m_movementUpdateCount;
@@ -492,7 +495,13 @@ namespace OpenSim.Region.Framework.Scenes
492 PhysicsActor actor = m_physicsActor; 495 PhysicsActor actor = m_physicsActor;
493// if (actor != null) 496// if (actor != null)
494 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting! 497 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting!
498 {
495 m_pos = actor.Position; 499 m_pos = actor.Position;
500
501// m_log.DebugFormat(
502// "[SCENE PRESENCE]: Set position {0} for {1} in {2} via getting AbsolutePosition!",
503// m_pos, Name, Scene.RegionInfo.RegionName);
504 }
496 else 505 else
497 { 506 {
498 // Obtain the correct position of a seated avatar. 507 // Obtain the correct position of a seated avatar.
@@ -536,20 +545,28 @@ namespace OpenSim.Region.Framework.Scenes
536 } 545 }
537 catch (Exception e) 546 catch (Exception e)
538 { 547 {
539 m_log.Error("[SCENEPRESENCE]: ABSOLUTE POSITION " + e.Message); 548 m_log.Error("[SCENE PRESENCE]: ABSOLUTE POSITION " + e.Message);
540 } 549 }
541 } 550 }
542 551
543 if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting! 552// Changed this to update unconditionally to make npose work
553// if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
544 m_pos = value; 554 m_pos = value;
545 m_parentPosition = Vector3.Zero; 555 m_parentPosition = Vector3.Zero;
556
557// m_log.DebugFormat(
558// "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}",
559// Scene.RegionInfo.RegionName, Name, m_pos);
546 } 560 }
547 } 561 }
548 562
563 /// <summary>
564 /// If sitting, returns the offset position from the prim the avatar is sitting on.
565 /// Otherwise, returns absolute position in the scene.
566 /// </summary>
549 public Vector3 OffsetPosition 567 public Vector3 OffsetPosition
550 { 568 {
551 get { return m_pos; } 569 get { return m_pos; }
552 set { m_pos = value; }
553 } 570 }
554 571
555 /// <summary> 572 /// <summary>
@@ -561,8 +578,14 @@ namespace OpenSim.Region.Framework.Scenes
561 { 578 {
562 PhysicsActor actor = m_physicsActor; 579 PhysicsActor actor = m_physicsActor;
563 if (actor != null) 580 if (actor != null)
581 {
564 m_velocity = actor.Velocity; 582 m_velocity = actor.Velocity;
565 583
584// m_log.DebugFormat(
585// "[SCENE PRESENCE]: Set velocity {0} for {1} in {2} via getting Velocity!",
586// m_velocity, Name, Scene.RegionInfo.RegionName);
587 }
588
566 return m_velocity; 589 return m_velocity;
567 } 590 }
568 set 591 set
@@ -577,11 +600,15 @@ namespace OpenSim.Region.Framework.Scenes
577 } 600 }
578 catch (Exception e) 601 catch (Exception e)
579 { 602 {
580 m_log.Error("[SCENEPRESENCE]: VELOCITY " + e.Message); 603 m_log.Error("[SCENE PRESENCE]: VELOCITY " + e.Message);
581 } 604 }
582 } 605 }
583 606
584 m_velocity = value; 607 m_velocity = value;
608
609// m_log.DebugFormat(
610// "[SCENE PRESENCE]: In {0} set velocity of {1} to {2}",
611// Scene.RegionInfo.RegionName, Name, m_velocity);
585 } 612 }
586 } 613 }
587 614
@@ -620,12 +647,6 @@ namespace OpenSim.Region.Framework.Scenes
620 } 647 }
621 } 648 }
622 649
623 public Quaternion PreviousRotation
624 {
625 get { return m_bodyRotPrevious; }
626 set { m_bodyRotPrevious = value; }
627 }
628
629 /// <summary> 650 /// <summary>
630 /// If this is true, agent doesn't have a representation in this scene. 651 /// If this is true, agent doesn't have a representation in this scene.
631 /// this is an agent 'looking into' this scene from a nearby scene(region) 652 /// this is an agent 'looking into' this scene from a nearby scene(region)
@@ -1126,7 +1147,7 @@ namespace OpenSim.Region.Framework.Scenes
1126 Animator.ResetAnimations(); 1147 Animator.ResetAnimations();
1127 1148
1128// m_log.DebugFormat( 1149// m_log.DebugFormat(
1129// "[SCENEPRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", 1150// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}",
1130// Name, UUID, m_scene.RegionInfo.RegionName); 1151// Name, UUID, m_scene.RegionInfo.RegionName);
1131 1152
1132 // Don't zero out the velocity since this can cause problems when an avatar is making a region crossing, 1153 // Don't zero out the velocity since this can cause problems when an avatar is making a region crossing,
@@ -1302,7 +1323,7 @@ namespace OpenSim.Region.Framework.Scenes
1302 m_callbackURI = null; 1323 m_callbackURI = null;
1303 } 1324 }
1304 1325
1305 //m_log.DebugFormat("Completed movement"); 1326 //m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
1306 1327
1307 m_controllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); 1328 m_controllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
1308 SendInitialData(); 1329 SendInitialData();
@@ -1813,7 +1834,10 @@ namespace OpenSim.Region.Framework.Scenes
1813 /// This is to allow movement to targets that are known to be on an elevated platform with a continuous path 1834 /// This is to allow movement to targets that are known to be on an elevated platform with a continuous path
1814 /// from start to finish. 1835 /// from start to finish.
1815 /// </param> 1836 /// </param>
1816 public void MoveToTarget(Vector3 pos, bool noFly) 1837 /// <param name="landAtTarget">
1838 /// If true and the avatar starts flying during the move then land at the target.
1839 /// </param>
1840 public void MoveToTarget(Vector3 pos, bool noFly, bool landAtTarget)
1817 { 1841 {
1818 m_log.DebugFormat( 1842 m_log.DebugFormat(
1819 "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}", 1843 "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}",
@@ -1839,7 +1863,7 @@ namespace OpenSim.Region.Framework.Scenes
1839 1863
1840 // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is 1864 // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is
1841 // always slightly higher than the actual terrain height. 1865 // always slightly higher than the actual terrain height.
1842 // FIXME: This constrains NOC movements as well, so should be somewhere else. 1866 // FIXME: This constrains NPC movements as well, so should be somewhere else.
1843 if (pos.Z - terrainHeight < 0.2) 1867 if (pos.Z - terrainHeight < 0.2)
1844 pos.Z = terrainHeight; 1868 pos.Z = terrainHeight;
1845 1869
@@ -1852,9 +1876,25 @@ namespace OpenSim.Region.Framework.Scenes
1852 else if (pos.Z > terrainHeight) 1876 else if (pos.Z > terrainHeight)
1853 PhysicsActor.Flying = true; 1877 PhysicsActor.Flying = true;
1854 1878
1879 LandAtTarget = landAtTarget;
1855 MovingToTarget = true; 1880 MovingToTarget = true;
1856 MoveToPositionTarget = pos; 1881 MoveToPositionTarget = pos;
1857 1882
1883 // Rotate presence around the z-axis to point in same direction as movement.
1884 // Ignore z component of vector
1885 Vector3 localVectorToTarget3D = pos - AbsolutePosition;
1886 Vector3 localVectorToTarget2D = new Vector3((float)(localVectorToTarget3D.X), (float)(localVectorToTarget3D.Y), 0f);
1887
1888// m_log.DebugFormat("[SCENE PRESENCE]: Local vector to target is {0}", localVectorToTarget2D);
1889
1890 // Calculate the yaw.
1891 Vector3 angle = new Vector3(0, 0, (float)(Math.Atan2(localVectorToTarget2D.Y, localVectorToTarget2D.X)));
1892
1893// m_log.DebugFormat("[SCENE PRESENCE]: Angle is {0}", angle);
1894
1895 Rotation = Quaternion.CreateFromEulers(angle);
1896// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, Rotation);
1897
1858 Vector3 agent_control_v3 = new Vector3(); 1898 Vector3 agent_control_v3 = new Vector3();
1859 HandleMoveToTargetUpdate(ref agent_control_v3); 1899 HandleMoveToTargetUpdate(ref agent_control_v3);
1860 AddNewMovement(agent_control_v3); 1900 AddNewMovement(agent_control_v3);
@@ -2744,7 +2784,7 @@ namespace OpenSim.Region.Framework.Scenes
2744 Vector3 pos = m_pos; 2784 Vector3 pos = m_pos;
2745 pos.Z += m_appearance.HipOffset; 2785 pos.Z += m_appearance.HipOffset;
2746 2786
2747 //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); 2787 //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity);
2748 2788
2749 remoteClient.SendPrimUpdate( 2789 remoteClient.SendPrimUpdate(
2750 this, 2790 this,
@@ -2831,6 +2871,7 @@ namespace OpenSim.Region.Framework.Scenes
2831 /// </summary> 2871 /// </summary>
2832 private void SendInitialData() 2872 private void SendInitialData()
2833 { 2873 {
2874 //m_log.DebugFormat("[SCENE PRESENCE] SendInitialData: {0} ({1})", Name, UUID);
2834 // Moved this into CompleteMovement to ensure that m_appearance is initialized before 2875 // Moved this into CompleteMovement to ensure that m_appearance is initialized before
2835 // the inventory arrives 2876 // the inventory arrives
2836 // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); 2877 // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance);
@@ -2875,10 +2916,11 @@ namespace OpenSim.Region.Framework.Scenes
2875 /// </summary> 2916 /// </summary>
2876 public void SendAvatarDataToAllAgents() 2917 public void SendAvatarDataToAllAgents()
2877 { 2918 {
2919 //m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAllAgents: {0} ({1})", Name, UUID);
2878 // only send update from root agents to other clients; children are only "listening posts" 2920 // only send update from root agents to other clients; children are only "listening posts"
2879 if (IsChildAgent) 2921 if (IsChildAgent)
2880 { 2922 {
2881 m_log.Warn("[SCENEPRESENCE] attempt to send avatar data from a child agent"); 2923 m_log.Warn("[SCENE PRESENCE] attempt to send avatar data from a child agent");
2882 return; 2924 return;
2883 } 2925 }
2884 2926
@@ -2928,7 +2970,7 @@ namespace OpenSim.Region.Framework.Scenes
2928 /// <param name="avatar"></param> 2970 /// <param name="avatar"></param>
2929 public void SendAvatarDataToAgent(ScenePresence avatar) 2971 public void SendAvatarDataToAgent(ScenePresence avatar)
2930 { 2972 {
2931// m_log.WarnFormat("[SP] Send avatar data from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); 2973 //m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAgent from {0} ({1}) to {2} ({3})", Name, UUID, avatar.Name, avatar.UUID);
2932 2974
2933 avatar.ControllingClient.SendAvatarDataImmediate(this); 2975 avatar.ControllingClient.SendAvatarDataImmediate(this);
2934 if (Animator != null) 2976 if (Animator != null)
@@ -2941,10 +2983,11 @@ namespace OpenSim.Region.Framework.Scenes
2941 /// </summary> 2983 /// </summary>
2942 public void SendAppearanceToAllOtherAgents() 2984 public void SendAppearanceToAllOtherAgents()
2943 { 2985 {
2986 m_log.DebugFormat("[SCENE PRESENCE] SendAppearanceToAllOtherAgents: {0} ({1})", Name, UUID);
2944 // only send update from root agents to other clients; children are only "listening posts" 2987 // only send update from root agents to other clients; children are only "listening posts"
2945 if (IsChildAgent) 2988 if (IsChildAgent)
2946 { 2989 {
2947 m_log.Warn("[SCENEPRESENCE] attempt to send avatar data from a child agent"); 2990 m_log.Warn("[SCENE PRESENCE] attempt to send avatar data from a child agent");
2948 return; 2991 return;
2949 } 2992 }
2950 2993
@@ -2970,6 +3013,7 @@ namespace OpenSim.Region.Framework.Scenes
2970 /// </summary> 3013 /// </summary>
2971 public void SendOtherAgentsAppearanceToMe() 3014 public void SendOtherAgentsAppearanceToMe()
2972 { 3015 {
3016 //m_log.DebugFormat("[SCENE PRESENCE] SendOtherAgentsAppearanceToMe: {0} ({1})", Name, UUID);
2973 m_perfMonMS = Util.EnvironmentTickCount(); 3017 m_perfMonMS = Util.EnvironmentTickCount();
2974 3018
2975 int count = 0; 3019 int count = 0;
@@ -3618,7 +3662,7 @@ namespace OpenSim.Region.Framework.Scenes
3618 /// <summary> 3662 /// <summary>
3619 /// Handles part of the PID controller function for moving an avatar. 3663 /// Handles part of the PID controller function for moving an avatar.
3620 /// </summary> 3664 /// </summary>
3621 public override void UpdateMovement() 3665 public void UpdateMovement()
3622 { 3666 {
3623 if (m_forceToApply.HasValue) 3667 if (m_forceToApply.HasValue)
3624 { 3668 {
@@ -3637,6 +3681,10 @@ namespace OpenSim.Region.Framework.Scenes
3637 /// </summary> 3681 /// </summary>
3638 public void AddToPhysicalScene(bool isFlying) 3682 public void AddToPhysicalScene(bool isFlying)
3639 { 3683 {
3684// m_log.DebugFormat(
3685// "[SCENE PRESENCE]: Adding physics actor for {0}, ifFlying = {1} in {2}",
3686// Name, isFlying, Scene.RegionInfo.RegionName);
3687
3640 if (m_appearance.AvatarHeight == 0) 3688 if (m_appearance.AvatarHeight == 0)
3641 m_appearance.SetHeight(); 3689 m_appearance.SetHeight();
3642 3690
@@ -4340,4 +4388,4 @@ namespace OpenSim.Region.Framework.Scenes
4340 } 4388 }
4341 } 4389 }
4342 } 4390 }
4343} \ No newline at end of file 4391}
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs
new file mode 100644
index 0000000..64c36ff
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs
@@ -0,0 +1,135 @@
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 log4net;
32using Nini.Config;
33using NUnit.Framework;
34using OpenMetaverse;
35using OpenSim.Framework;
36using OpenSim.Framework.Communications;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Tests.Common;
40using OpenSim.Tests.Common.Mock;
41
42namespace OpenSim.Region.Framework.Scenes.Tests
43{
44 [TestFixture]
45 public class ScenePresenceAutopilotTests
46 {
47 private TestScene m_scene;
48
49 [TestFixtureSetUp]
50 public void FixtureInit()
51 {
52 // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
53 Util.FireAndForgetMethod = FireAndForgetMethod.None;
54 }
55
56 [TestFixtureTearDown]
57 public void TearDown()
58 {
59 // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
60 // threads. Possibly, later tests should be rewritten not to worry about such things.
61 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
62 }
63
64 [SetUp]
65 public void Init()
66 {
67 m_scene = SceneHelpers.SetupScene();
68 }
69
70 [Test]
71 public void TestMove()
72 {
73 TestHelpers.InMethod();
74// log4net.Config.XmlConfigurator.Configure();
75
76 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
77
78 Vector3 startPos = sp.AbsolutePosition;
79// Vector3 startPos = new Vector3(128, 128, 30);
80
81 // For now, we'll make the scene presence fly to simplify this test, but this needs to change.
82 sp.PhysicsActor.Flying = true;
83
84 m_scene.Update();
85 Assert.That(sp.AbsolutePosition, Is.EqualTo(startPos));
86
87 Vector3 targetPos = startPos + new Vector3(0, 10, 0);
88 sp.MoveToTarget(targetPos, false, false);
89
90 Assert.That(sp.AbsolutePosition, Is.EqualTo(startPos));
91 Assert.That(
92 sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001));
93
94 m_scene.Update();
95
96 // We should really check the exact figure.
97 Assert.That(sp.AbsolutePosition.X, Is.EqualTo(startPos.X));
98 Assert.That(sp.AbsolutePosition.Y, Is.GreaterThan(startPos.Y));
99 Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
100 Assert.That(sp.AbsolutePosition.Z, Is.LessThan(targetPos.X));
101
102 for (int i = 0; i < 10; i++)
103 m_scene.Update();
104
105 double distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos);
106 Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on first move");
107 Assert.That(sp.AbsolutePosition, Is.EqualTo(targetPos));
108 Assert.That(sp.AgentControlFlags, Is.EqualTo((uint)AgentManager.ControlFlags.NONE));
109
110 // Try a second movement
111 startPos = sp.AbsolutePosition;
112 targetPos = startPos + new Vector3(10, 0, 0);
113 sp.MoveToTarget(targetPos, false, false);
114
115 Assert.That(sp.AbsolutePosition, Is.EqualTo(startPos));
116 Assert.That(
117 sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001));
118
119 m_scene.Update();
120
121 // We should really check the exact figure.
122 Assert.That(sp.AbsolutePosition.X, Is.GreaterThan(startPos.X));
123 Assert.That(sp.AbsolutePosition.X, Is.LessThan(targetPos.X));
124 Assert.That(sp.AbsolutePosition.Y, Is.EqualTo(startPos.Y));
125 Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
126
127 for (int i = 0; i < 10; i++)
128 m_scene.Update();
129
130 distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos);
131 Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on second move");
132 Assert.That(sp.AbsolutePosition, Is.EqualTo(targetPos));
133 }
134 }
135} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 00b1c1e..c92f121 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -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 Action<Vector3, bool> OnAutoPilotGo; 809 public event Action<Vector3, bool, 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;
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index 4f831a4..253fdee 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -37,11 +37,6 @@ 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
45 private readonly string m_firstname; 40 private readonly string m_firstname;
46 private readonly string m_lastname; 41 private readonly string m_lastname;
47 private readonly Vector3 m_startPos; 42 private readonly Vector3 m_startPos;
@@ -333,7 +328,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
333 public event ScriptReset OnScriptReset; 328 public event ScriptReset OnScriptReset;
334 public event GetScriptRunning OnGetScriptRunning; 329 public event GetScriptRunning OnGetScriptRunning;
335 public event SetScriptRunning OnSetScriptRunning; 330 public event SetScriptRunning OnSetScriptRunning;
336 public event Action<Vector3, bool> OnAutoPilotGo; 331 public event Action<Vector3, bool, bool> OnAutoPilotGo;
337 332
338 public event TerrainUnacked OnUnackedTerrain; 333 public event TerrainUnacked OnUnackedTerrain;
339 334
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
index 2fdeeab..bcd9e94 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
@@ -53,78 +53,13 @@ namespace OpenSim.Region.OptionalModules.World.NPC
53 if (config != null && config.GetBoolean("Enabled", false)) 53 if (config != null && config.GetBoolean("Enabled", false))
54 { 54 {
55 scene.RegisterModuleInterface<INPCModule>(this); 55 scene.RegisterModuleInterface<INPCModule>(this);
56 scene.EventManager.OnSignificantClientMovement += HandleOnSignificantClientMovement;
57 }
58 }
59
60 public void HandleOnSignificantClientMovement(ScenePresence presence)
61 {
62 lock (m_avatars)
63 {
64 if (m_avatars.ContainsKey(presence.UUID) && presence.MovingToTarget)
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 }
123 } 56 }
124 } 57 }
125 58
126 public bool IsNPC(UUID agentId, Scene scene) 59 public bool IsNPC(UUID agentId, Scene scene)
127 { 60 {
61 // FIXME: This implementation could not just use the ScenePresence.PresenceType (and callers could inspect
62 // that directly).
128 ScenePresence sp = scene.GetScenePresence(agentId); 63 ScenePresence sp = scene.GetScenePresence(agentId);
129 if (sp == null || sp.IsChildAgent) 64 if (sp == null || sp.IsChildAgent)
130 return false; 65 return false;
@@ -218,8 +153,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
218 "[NPC MODULE]: Moving {0} to {1} in {2}, noFly {3}, landAtTarget {4}", 153 "[NPC MODULE]: Moving {0} to {1} in {2}, noFly {3}, landAtTarget {4}",
219 sp.Name, pos, scene.RegionInfo.RegionName, noFly, landAtTarget); 154 sp.Name, pos, scene.RegionInfo.RegionName, noFly, landAtTarget);
220 155
221 m_avatars[agentID].LandAtTarget = landAtTarget; 156 sp.MoveToTarget(pos, noFly, landAtTarget);
222 sp.MoveToTarget(pos, noFly);
223 157
224 return true; 158 return true;
225 } 159 }
diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
index 246bc34..49c06bc 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
@@ -132,11 +132,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
132 UUID attAssetId = TestHelpers.ParseTail(0x3); 132 UUID attAssetId = TestHelpers.ParseTail(0x3);
133 string attName = "att"; 133 string attName = "att";
134 134
135 UserInventoryHelpers.CreateInventoryItem( 135 UserInventoryHelpers.CreateInventoryItem(scene, attName, attItemId, attAssetId, sp.UUID, InventoryType.Object);
136 scene, attName, attItemId, attAssetId, sp.UUID, InventoryType.Object);
137 136
138 am.RezSingleAttachmentFromInventory( 137 am.RezSingleAttachmentFromInventory(sp, attItemId, (uint)AttachmentPoint.Chest);
139 sp.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
140 138
141 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 139 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
142 UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, sp.Appearance); 140 UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, sp.Appearance);
@@ -182,18 +180,21 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
182 scene.Update(); 180 scene.Update();
183 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); 181 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
184 182
185 Vector3 targetPos = startPos + new Vector3(0, 0, 10); 183 Vector3 targetPos = startPos + new Vector3(0, 10, 0);
186 npcModule.MoveToTarget(npc.UUID, scene, targetPos, false, false); 184 npcModule.MoveToTarget(npc.UUID, scene, targetPos, false, false);
187 185
188 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); 186 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
187 //Assert.That(npc.Rotation, Is.EqualTo(new Quaternion(0, 0, 0.7071068f, 0.7071068f)));
188 Assert.That(
189 npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001));
189 190
190 scene.Update(); 191 scene.Update();
191 192
192 // We should really check the exact figure. 193 // We should really check the exact figure.
193 Assert.That(npc.AbsolutePosition.X, Is.EqualTo(startPos.X)); 194 Assert.That(npc.AbsolutePosition.X, Is.EqualTo(startPos.X));
194 Assert.That(npc.AbsolutePosition.Y, Is.EqualTo(startPos.Y)); 195 Assert.That(npc.AbsolutePosition.Y, Is.GreaterThan(startPos.Y));
195 Assert.That(npc.AbsolutePosition.Z, Is.GreaterThan(startPos.Z)); 196 Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
196 Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.Z)); 197 Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.X));
197 198
198 for (int i = 0; i < 10; i++) 199 for (int i = 0; i < 10; i++)
199 scene.Update(); 200 scene.Update();
@@ -208,6 +209,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
208 targetPos = startPos + new Vector3(10, 0, 0); 209 targetPos = startPos + new Vector3(10, 0, 0);
209 npcModule.MoveToTarget(npc.UUID, scene, targetPos, false, false); 210 npcModule.MoveToTarget(npc.UUID, scene, targetPos, false, false);
210 211
212 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
213// Assert.That(npc.Rotation, Is.EqualTo(new Quaternion(0, 0, 0, 1)));
214 Assert.That(
215 npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001));
216
211 scene.Update(); 217 scene.Update();
212 218
213 // We should really check the exact figure. 219 // We should really check the exact figure.
diff --git a/OpenSim/Region/Physics/BulletDotNETPlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/BulletDotNETPlugin/AssemblyInfo.cs
deleted file mode 100644
index 2830325..0000000
--- a/OpenSim/Region/Physics/BulletDotNETPlugin/AssemblyInfo.cs
+++ /dev/null
@@ -1,58 +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.Reflection;
29using System.Runtime.InteropServices;
30
31// Information about this assembly is defined by the following
32// attributes.
33//
34// change them to the information which is associated with the assembly
35// you compile.
36
37[assembly : AssemblyTitle("BulletDotNETPlugin")]
38[assembly : AssemblyDescription("")]
39[assembly : AssemblyConfiguration("")]
40[assembly : AssemblyCompany("http://opensimulator.org")]
41[assembly : AssemblyProduct("OdePlugin")]
42[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")]
43[assembly : AssemblyTrademark("")]
44[assembly : AssemblyCulture("")]
45
46// This sets the default COM visibility of types in the assembly to invisible.
47// If you need to expose a type to COM, use [ComVisible(true)] on that type.
48
49[assembly : ComVisible(false)]
50
51// The assembly version has following format :
52//
53// Major.Minor.Build.Revision
54//
55// You can specify all values by your own or you can build default build and revision
56// numbers with the '*' character (the default):
57
58[assembly : AssemblyVersion("0.6.3.*")]
diff --git a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs
deleted file mode 100644
index f13c323..0000000
--- a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs
+++ /dev/null
@@ -1,1190 +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.Reflection;
30using BulletDotNET;
31using OpenMetaverse;
32using OpenSim.Framework;
33using OpenSim.Region.Physics.Manager;
34using log4net;
35
36namespace OpenSim.Region.Physics.BulletDotNETPlugin
37{
38 public class BulletDotNETCharacter : PhysicsActor
39 {
40 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41
42 public btRigidBody Body;
43 public btCollisionShape Shell;
44 public btVector3 tempVector1;
45 public btVector3 tempVector2;
46 public btVector3 tempVector3;
47 public btVector3 tempVector4;
48
49 public btVector3 tempVector5RayCast;
50 public btVector3 tempVector6RayCast;
51 public btVector3 tempVector7RayCast;
52
53 public btQuaternion tempQuat1;
54 public btTransform tempTrans1;
55
56 public ClosestNotMeRayResultCallback ClosestCastResult;
57 private btTransform m_bodyTransform;
58 private btVector3 m_bodyPosition;
59 private btVector3 m_CapsuleOrientationAxis;
60 private btQuaternion m_bodyOrientation;
61 private btDefaultMotionState m_bodyMotionState;
62 private btGeneric6DofConstraint m_aMotor;
63 // private Vector3 m_movementComparision;
64 private Vector3 m_position;
65 private Vector3 m_zeroPosition;
66 private bool m_zeroFlag = false;
67 private bool m_lastUpdateSent = false;
68 private Vector3 m_velocity;
69 private Vector3 m_target_velocity;
70 private Vector3 m_acceleration;
71 private Vector3 m_rotationalVelocity;
72 private bool m_pidControllerActive = true;
73 public float PID_D = 80.0f;
74 public float PID_P = 90.0f;
75 public float CAPSULE_RADIUS = 0.37f;
76 public float CAPSULE_LENGTH = 2.140599f;
77 public float heightFudgeFactor = 0.52f;
78 public float walkDivisor = 1.3f;
79 public float runDivisor = 0.8f;
80 private float m_mass = 80f;
81 public float m_density = 60f;
82 private bool m_flying = false;
83 private bool m_iscolliding = false;
84 private bool m_iscollidingGround = false;
85 private bool m_wascolliding = false;
86 private bool m_wascollidingGround = false;
87 private bool m_iscollidingObj = false;
88 private bool m_alwaysRun = false;
89 private bool m_hackSentFall = false;
90 private bool m_hackSentFly = false;
91 public uint m_localID = 0;
92 public bool m_returnCollisions = false;
93 // taints and their non-tainted counterparts
94 public bool m_isPhysical = false; // the current physical status
95 public bool m_tainted_isPhysical = false; // set when the physical status is tainted (false=not existing in physics engine, true=existing)
96 private float m_tainted_CAPSULE_LENGTH; // set when the capsule length changes.
97 private bool m_taintRemove = false;
98 // private bool m_taintedPosition = false;
99 // private Vector3 m_taintedPosition_value;
100 private Vector3 m_taintedForce;
101
102 private float m_buoyancy = 0f;
103
104 // private CollisionLocker ode;
105
106 // private string m_name = String.Empty;
107
108 private bool[] m_colliderarr = new bool[11];
109 private bool[] m_colliderGroundarr = new bool[11];
110
111 private BulletDotNETScene m_parent_scene;
112
113 public int m_eventsubscription = 0;
114 private CollisionEventUpdate CollisionEventsThisFrame = null;
115 private int m_requestedUpdateFrequency = 0;
116
117 public BulletDotNETCharacter(string avName, BulletDotNETScene parent_scene, Vector3 pos, Vector3 size, float pid_d, float pid_p, float capsule_radius, float tensor, float density, float height_fudge_factor, float walk_divisor, float rundivisor)
118 {
119 m_position = pos;
120 m_zeroPosition = pos;
121 m_parent_scene = parent_scene;
122 PID_D = pid_d;
123 PID_P = pid_p;
124 CAPSULE_RADIUS = capsule_radius;
125 m_density = density;
126 heightFudgeFactor = height_fudge_factor;
127 walkDivisor = walk_divisor;
128 runDivisor = rundivisor;
129
130 for (int i = 0; i < 11; i++)
131 {
132 m_colliderarr[i] = false;
133 }
134 for (int i = 0; i < 11; i++)
135 {
136 m_colliderGroundarr[i] = false;
137 }
138 CAPSULE_LENGTH = (size.Z * 1.15f) - CAPSULE_RADIUS * 2.0f;
139 m_tainted_CAPSULE_LENGTH = CAPSULE_LENGTH;
140 m_isPhysical = false; // current status: no ODE information exists
141 m_tainted_isPhysical = true; // new tainted status: need to create ODE information
142
143 m_parent_scene.AddPhysicsActorTaint(this);
144
145 // m_name = avName;
146 tempVector1 = new btVector3(0, 0, 0);
147 tempVector2 = new btVector3(0, 0, 0);
148 tempVector3 = new btVector3(0, 0, 0);
149 tempVector4 = new btVector3(0, 0, 0);
150
151 tempVector5RayCast = new btVector3(0, 0, 0);
152 tempVector6RayCast = new btVector3(0, 0, 0);
153 tempVector7RayCast = new btVector3(0, 0, 0);
154
155 tempQuat1 = new btQuaternion(0, 0, 0, 1);
156 tempTrans1 = new btTransform(tempQuat1, tempVector1);
157 // m_movementComparision = new PhysicsVector(0, 0, 0);
158 m_CapsuleOrientationAxis = new btVector3(1, 0, 1);
159 }
160
161 /// <summary>
162 /// This creates the Avatar's physical Surrogate at the position supplied
163 /// </summary>
164 /// <param name="npositionX"></param>
165 /// <param name="npositionY"></param>
166 /// <param name="npositionZ"></param>
167
168 // WARNING: This MUST NOT be called outside of ProcessTaints, else we can have unsynchronized access
169 // to ODE internals. ProcessTaints is called from within thread-locked Simulate(), so it is the only
170 // place that is safe to call this routine AvatarGeomAndBodyCreation.
171 private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ)
172 {
173
174 if (CAPSULE_LENGTH <= 0)
175 {
176 m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!");
177 CAPSULE_LENGTH = 0.01f;
178
179 }
180
181 if (CAPSULE_RADIUS <= 0)
182 {
183 m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!");
184 CAPSULE_RADIUS = 0.01f;
185
186 }
187
188 Shell = new btCapsuleShape(CAPSULE_RADIUS, CAPSULE_LENGTH);
189
190 if (m_bodyPosition == null)
191 m_bodyPosition = new btVector3(npositionX, npositionY, npositionZ);
192
193 m_bodyPosition.setValue(npositionX, npositionY, npositionZ);
194
195 if (m_bodyOrientation == null)
196 m_bodyOrientation = new btQuaternion(m_CapsuleOrientationAxis, (Utils.DEG_TO_RAD * 90));
197
198 if (m_bodyTransform == null)
199 m_bodyTransform = new btTransform(m_bodyOrientation, m_bodyPosition);
200 else
201 {
202 m_bodyTransform.Dispose();
203 m_bodyTransform = new btTransform(m_bodyOrientation, m_bodyPosition);
204 }
205
206 if (m_bodyMotionState == null)
207 m_bodyMotionState = new btDefaultMotionState(m_bodyTransform);
208 else
209 m_bodyMotionState.setWorldTransform(m_bodyTransform);
210
211 m_mass = Mass;
212
213 Body = new btRigidBody(m_mass, m_bodyMotionState, Shell);
214 // this is used for self identification. User localID instead of body handle
215 Body.setUserPointer(new IntPtr((int)m_localID));
216
217 if (ClosestCastResult != null)
218 ClosestCastResult.Dispose();
219 ClosestCastResult = new ClosestNotMeRayResultCallback(Body);
220
221 m_parent_scene.AddRigidBody(Body);
222 Body.setActivationState(4);
223 if (m_aMotor != null)
224 {
225 if (m_aMotor.Handle != IntPtr.Zero)
226 {
227 m_parent_scene.getBulletWorld().removeConstraint(m_aMotor);
228 m_aMotor.Dispose();
229 }
230 m_aMotor = null;
231 }
232
233 m_aMotor = new btGeneric6DofConstraint(Body, m_parent_scene.TerrainBody,
234 m_parent_scene.TransZero,
235 m_parent_scene.TransZero, false);
236 m_aMotor.setAngularLowerLimit(m_parent_scene.VectorZero);
237 m_aMotor.setAngularUpperLimit(m_parent_scene.VectorZero);
238
239
240 }
241 public void Remove()
242 {
243 m_taintRemove = true;
244 }
245 public override bool Stopped
246 {
247 get { return m_zeroFlag; }
248 }
249
250 public override Vector3 Size
251 {
252 get { return new Vector3(CAPSULE_RADIUS * 2, CAPSULE_RADIUS * 2, CAPSULE_LENGTH); }
253 set
254 {
255 m_pidControllerActive = true;
256
257 Vector3 SetSize = value;
258 m_tainted_CAPSULE_LENGTH = (SetSize.Z * 1.15f) - CAPSULE_RADIUS * 2.0f;
259 //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString());
260
261 Velocity = Vector3.Zero;
262
263 m_parent_scene.AddPhysicsActorTaint(this);
264 }
265 }
266
267 /// <summary>
268 /// turn the PID controller on or off.
269 /// The PID Controller will turn on all by itself in many situations
270 /// </summary>
271 /// <param name="status"></param>
272 public void SetPidStatus(bool status)
273 {
274 m_pidControllerActive = status;
275 }
276
277 public override PrimitiveBaseShape Shape
278 {
279 set { return; }
280 }
281
282 public override uint LocalID
283 {
284 set { m_localID = value; }
285 }
286
287 public override bool Grabbed
288 {
289 set { return; }
290 }
291
292 public override bool Selected
293 {
294 set { return; }
295 }
296
297
298 public override void CrossingFailure()
299 {
300
301 }
302
303 public override void link(PhysicsActor obj)
304 {
305
306 }
307
308 public override void delink()
309 {
310
311 }
312
313 public override void LockAngularMotion(Vector3 axis)
314 {
315
316 }
317
318 public override Vector3 Position
319 {
320 get { return m_position; }
321 set
322 {
323 // m_taintedPosition_value = value;
324 m_position = value;
325 // m_taintedPosition = true;
326 }
327 }
328
329 public override float Mass
330 {
331 get
332 {
333 float AVvolume = (float)(Math.PI * Math.Pow(CAPSULE_RADIUS, 2) * CAPSULE_LENGTH);
334 return m_density * AVvolume;
335 }
336 }
337
338 public override Vector3 Force
339 {
340 get { return m_target_velocity; }
341 set { return; }
342 }
343
344 public override int VehicleType
345 {
346 get { return 0; }
347 set { return; }
348 }
349
350 public override void VehicleFloatParam(int param, float value)
351 {
352
353 }
354
355 public override void VehicleVectorParam(int param, Vector3 value)
356 {
357
358 }
359
360 public override void VehicleRotationParam(int param, Quaternion rotation)
361 {
362
363 }
364
365 public override void VehicleFlags(int param, bool remove)
366 {
367
368 }
369
370 public override void SetVolumeDetect(int param)
371 {
372
373 }
374
375 public override Vector3 GeometricCenter
376 {
377 get { return Vector3.Zero; }
378 }
379
380 public override Vector3 CenterOfMass
381 {
382 get { return Vector3.Zero; }
383 }
384
385 public override Vector3 Velocity
386 {
387 get
388 {
389 if (m_zeroFlag)
390 return Vector3.Zero;
391 m_lastUpdateSent = false;
392 return m_velocity;
393 }
394 set
395 {
396 m_pidControllerActive = true;
397 m_target_velocity = value;
398 }
399 }
400
401 public override Vector3 Torque
402 {
403 get { return Vector3.Zero; }
404 set { return; }
405 }
406
407 public override float CollisionScore
408 {
409 get { return 0f; }
410 set { }
411 }
412
413 public override Vector3 Acceleration
414 {
415 get { return m_acceleration; }
416 }
417
418 public override Quaternion Orientation
419 {
420 get { return Quaternion.Identity; }
421 set
422 {
423
424 }
425 }
426
427 public override int PhysicsActorType
428 {
429 get { return (int)ActorTypes.Agent; }
430 set { return; }
431 }
432
433 public override bool IsPhysical
434 {
435 get { return false; }
436 set { return; }
437 }
438
439 public override bool Flying
440 {
441 get { return m_flying; }
442 set { m_flying = value; }
443 }
444
445 public override bool SetAlwaysRun
446 {
447 get { return m_alwaysRun; }
448 set { m_alwaysRun = value; }
449 }
450
451
452 public override bool ThrottleUpdates
453 {
454 get { return false; }
455 set { return; }
456 }
457
458 /// <summary>
459 /// Returns if the avatar is colliding in general.
460 /// This includes the ground and objects and avatar.
461 /// </summary>
462 public override bool IsColliding
463 {
464 get { return m_iscolliding; }
465 set
466 {
467 int i;
468 int truecount = 0;
469 int falsecount = 0;
470
471 if (m_colliderarr.Length >= 10)
472 {
473 for (i = 0; i < 10; i++)
474 {
475 m_colliderarr[i] = m_colliderarr[i + 1];
476 }
477 }
478 m_colliderarr[10] = value;
479
480 for (i = 0; i < 11; i++)
481 {
482 if (m_colliderarr[i])
483 {
484 truecount++;
485 }
486 else
487 {
488 falsecount++;
489 }
490 }
491
492 // Equal truecounts and false counts means we're colliding with something.
493 m_log.DebugFormat("[PHYSICS]: TrueCount:{0}, FalseCount:{1}",truecount,falsecount);
494 if (falsecount > 1.2 * truecount)
495 {
496 m_iscolliding = false;
497 }
498 else
499 {
500 m_iscolliding = true;
501 }
502 if (m_wascolliding != m_iscolliding)
503 {
504 //base.SendCollisionUpdate(new CollisionEventUpdate());
505 }
506 m_wascolliding = m_iscolliding;
507 }
508 }
509
510 /// <summary>
511 /// Returns if an avatar is colliding with the ground
512 /// </summary>
513 public override bool CollidingGround
514 {
515 get { return m_iscollidingGround; }
516 set
517 {
518 // Collisions against the ground are not really reliable
519 // So, to get a consistant value we have to average the current result over time
520 // Currently we use 1 second = 10 calls to this.
521 int i;
522 int truecount = 0;
523 int falsecount = 0;
524
525 if (m_colliderGroundarr.Length >= 10)
526 {
527 for (i = 0; i < 10; i++)
528 {
529 m_colliderGroundarr[i] = m_colliderGroundarr[i + 1];
530 }
531 }
532 m_colliderGroundarr[10] = value;
533
534 for (i = 0; i < 11; i++)
535 {
536 if (m_colliderGroundarr[i])
537 {
538 truecount++;
539 }
540 else
541 {
542 falsecount++;
543 }
544 }
545
546 // Equal truecounts and false counts means we're colliding with something.
547
548 if (falsecount > 1.2 * truecount)
549 {
550 m_iscollidingGround = false;
551 }
552 else
553 {
554 m_iscollidingGround = true;
555 }
556 if (m_wascollidingGround != m_iscollidingGround)
557 {
558 //base.SendCollisionUpdate(new CollisionEventUpdate());
559 }
560 m_wascollidingGround = m_iscollidingGround;
561 }
562 }
563
564 /// <summary>
565 /// Returns if the avatar is colliding with an object
566 /// </summary>
567 public override bool CollidingObj
568 {
569 get { return m_iscollidingObj; }
570 set
571 {
572 m_iscollidingObj = value;
573 if (value)
574 m_pidControllerActive = false;
575 else
576 m_pidControllerActive = true;
577 }
578 }
579
580
581 public override bool FloatOnWater
582 {
583 set { return; }
584 }
585
586 public override Vector3 RotationalVelocity
587 {
588 get { return m_rotationalVelocity; }
589 set { m_rotationalVelocity = value; }
590 }
591
592 public override bool Kinematic
593 {
594 get { return false; }
595 set { }
596 }
597
598 public override float Buoyancy
599 {
600 get { return m_buoyancy; }
601 set { m_buoyancy = value; }
602 }
603
604 public override Vector3 PIDTarget { set { return; } }
605 public override bool PIDActive { set { return; } }
606 public override float PIDTau { set { return; } }
607
608 public override bool PIDHoverActive
609 {
610 set { return; }
611 }
612
613 public override float PIDHoverHeight
614 {
615 set { return; }
616 }
617
618 public override PIDHoverType PIDHoverType
619 {
620 set { return; }
621 }
622
623 public override float PIDHoverTau
624 {
625 set { return; }
626 }
627
628 public override Quaternion APIDTarget
629 {
630 set { return; }
631 }
632
633 public override bool APIDActive
634 {
635 set { return; }
636 }
637
638 public override float APIDStrength
639 {
640 set { return; }
641 }
642
643 public override float APIDDamping
644 {
645 set { return; }
646 }
647
648 /// <summary>
649 /// Adds the force supplied to the Target Velocity
650 /// The PID controller takes this target velocity and tries to make it a reality
651 /// </summary>
652 /// <param name="force"></param>
653 /// <param name="pushforce">Is this a push by a script?</param>
654 public override void AddForce(Vector3 force, bool pushforce)
655 {
656 if (pushforce)
657 {
658 m_pidControllerActive = false;
659 force *= 100f;
660 doForce(force, false);
661 //System.Console.WriteLine("Push!");
662 //_target_velocity.X += force.X;
663 // _target_velocity.Y += force.Y;
664 //_target_velocity.Z += force.Z;
665 }
666 else
667 {
668 m_pidControllerActive = true;
669 m_target_velocity.X += force.X;
670 m_target_velocity.Y += force.Y;
671 m_target_velocity.Z += force.Z;
672 }
673 //m_lastUpdateSent = false;
674 }
675
676 public void doForce(Vector3 force, bool now)
677 {
678
679 tempVector3.setValue(force.X, force.Y, force.Z);
680 if (now)
681 {
682 Body.applyCentralForce(tempVector3);
683 }
684 else
685 {
686 m_taintedForce += force;
687 m_parent_scene.AddPhysicsActorTaint(this);
688 }
689 }
690
691 public void doImpulse(Vector3 force, bool now)
692 {
693
694 tempVector3.setValue(force.X, force.Y, force.Z);
695 if (now)
696 {
697 Body.applyCentralImpulse(tempVector3);
698 }
699 else
700 {
701 m_taintedForce += force;
702 m_parent_scene.AddPhysicsActorTaint(this);
703 }
704 }
705
706 public override void AddAngularForce(Vector3 force, bool pushforce)
707 {
708
709 }
710
711 public override void SetMomentum(Vector3 momentum)
712 {
713
714 }
715
716 public override void SubscribeEvents(int ms)
717 {
718 m_eventsubscription = ms;
719 m_requestedUpdateFrequency = ms;
720 m_parent_scene.addCollisionEventReporting(this);
721 }
722
723 public override void UnSubscribeEvents()
724 {
725 m_parent_scene.remCollisionEventReporting(this);
726 m_eventsubscription = 0;
727 m_requestedUpdateFrequency = 0;
728 }
729
730 public override bool SubscribedEvents()
731 {
732 if (m_eventsubscription > 0)
733 return true;
734 return false;
735 }
736
737 public void AddCollision(uint collideWith, ContactPoint contact)
738 {
739 if (CollisionEventsThisFrame == null)
740 {
741 CollisionEventsThisFrame = new CollisionEventUpdate();
742 }
743 CollisionEventsThisFrame.addCollider(collideWith, contact);
744 }
745
746 public void SendCollisions()
747 {
748 if (m_eventsubscription >= m_requestedUpdateFrequency)
749 {
750 if (CollisionEventsThisFrame != null)
751 {
752 base.SendCollisionUpdate(CollisionEventsThisFrame);
753 }
754 CollisionEventsThisFrame = new CollisionEventUpdate();
755 m_eventsubscription = 0;
756 }
757 return;
758 }
759
760 internal void Dispose()
761 {
762 if (Body.isInWorld())
763 m_parent_scene.removeFromWorld(Body);
764
765 if (m_aMotor.Handle != IntPtr.Zero)
766 m_parent_scene.getBulletWorld().removeConstraint(m_aMotor);
767
768 m_aMotor.Dispose(); m_aMotor = null;
769 ClosestCastResult.Dispose(); ClosestCastResult = null;
770 Body.Dispose(); Body = null;
771 Shell.Dispose(); Shell = null;
772 tempQuat1.Dispose();
773 tempTrans1.Dispose();
774 tempVector1.Dispose();
775 tempVector2.Dispose();
776 tempVector3.Dispose();
777 tempVector4.Dispose();
778 tempVector5RayCast.Dispose();
779 tempVector6RayCast.Dispose();
780
781 }
782
783 public void ProcessTaints(float timestep)
784 {
785
786 if (m_tainted_isPhysical != m_isPhysical)
787 {
788 if (m_tainted_isPhysical)
789 {
790 // Create avatar capsule and related ODE data
791 if (!(Shell == null && Body == null))
792 {
793 m_log.Warn("[PHYSICS]: re-creating the following avatar ODE data, even though it already exists - "
794 + (Shell != null ? "Shell " : "")
795 + (Body != null ? "Body " : ""));
796 }
797 AvatarGeomAndBodyCreation(m_position.X, m_position.Y, m_position.Z);
798
799
800 }
801 else
802 {
803 // destroy avatar capsule and related ODE data
804
805 Dispose();
806 tempVector1 = new btVector3(0, 0, 0);
807 tempVector2 = new btVector3(0, 0, 0);
808 tempVector3 = new btVector3(0, 0, 0);
809 tempVector4 = new btVector3(0, 0, 0);
810
811 tempVector5RayCast = new btVector3(0, 0, 0);
812 tempVector6RayCast = new btVector3(0, 0, 0);
813 tempVector7RayCast = new btVector3(0, 0, 0);
814
815 tempQuat1 = new btQuaternion(0, 0, 0, 1);
816 tempTrans1 = new btTransform(tempQuat1, tempVector1);
817 // m_movementComparision = new PhysicsVector(0, 0, 0);
818 m_CapsuleOrientationAxis = new btVector3(1, 0, 1);
819 }
820
821 m_isPhysical = m_tainted_isPhysical;
822 }
823
824 if (m_tainted_CAPSULE_LENGTH != CAPSULE_LENGTH)
825 {
826 if (Body != null)
827 {
828
829 m_pidControllerActive = true;
830 // no lock needed on _parent_scene.OdeLock because we are called from within the thread lock in OdePlugin's simulate()
831 //d.JointDestroy(Amotor);
832 float prevCapsule = CAPSULE_LENGTH;
833 CAPSULE_LENGTH = m_tainted_CAPSULE_LENGTH;
834 //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString());
835 Dispose();
836
837 tempVector1 = new btVector3(0, 0, 0);
838 tempVector2 = new btVector3(0, 0, 0);
839 tempVector3 = new btVector3(0, 0, 0);
840 tempVector4 = new btVector3(0, 0, 0);
841
842 tempVector5RayCast = new btVector3(0, 0, 0);
843 tempVector6RayCast = new btVector3(0, 0, 0);
844 tempVector7RayCast = new btVector3(0, 0, 0);
845
846 tempQuat1 = new btQuaternion(0, 0, 0, 1);
847 tempTrans1 = new btTransform(tempQuat1, tempVector1);
848 // m_movementComparision = new PhysicsVector(0, 0, 0);
849 m_CapsuleOrientationAxis = new btVector3(1, 0, 1);
850
851 AvatarGeomAndBodyCreation(m_position.X, m_position.Y,
852 m_position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2));
853 Velocity = Vector3.Zero;
854
855 }
856 else
857 {
858 m_log.Warn("[PHYSICS]: trying to change capsule size, but the following ODE data is missing - "
859 + (Shell == null ? "Shell " : "")
860 + (Body == null ? "Body " : ""));
861 }
862 }
863 if (m_taintRemove)
864 {
865 Dispose();
866 }
867 }
868
869 /// <summary>
870 /// Called from Simulate
871 /// This is the avatar's movement control + PID Controller
872 /// </summary>
873 /// <param name="timeStep"></param>
874 public void Move(float timeStep)
875 {
876 // no lock; for now it's only called from within Simulate()
877
878 // If the PID Controller isn't active then we set our force
879 // calculating base velocity to the current position
880 if (Body == null)
881 return;
882 tempTrans1.Dispose();
883 tempTrans1 = Body.getInterpolationWorldTransform();
884 tempVector1.Dispose();
885 tempVector1 = tempTrans1.getOrigin();
886 tempVector2.Dispose();
887 tempVector2 = Body.getInterpolationLinearVelocity();
888
889 if (m_pidControllerActive == false)
890 {
891 m_zeroPosition.X = tempVector1.getX();
892 m_zeroPosition.Y = tempVector1.getY();
893 m_zeroPosition.Z = tempVector1.getZ();
894 }
895 //PidStatus = true;
896
897 Vector3 vec = Vector3.Zero;
898
899 Vector3 vel = new Vector3(tempVector2.getX(), tempVector2.getY(), tempVector2.getZ());
900
901 float movementdivisor = 1f;
902
903 if (!m_alwaysRun)
904 {
905 movementdivisor = walkDivisor;
906 }
907 else
908 {
909 movementdivisor = runDivisor;
910 }
911
912 // if velocity is zero, use position control; otherwise, velocity control
913 if (m_target_velocity.X == 0.0f && m_target_velocity.Y == 0.0f && m_target_velocity.Z == 0.0f && m_iscolliding)
914 {
915 // keep track of where we stopped. No more slippin' & slidin'
916 if (!m_zeroFlag)
917 {
918 m_zeroFlag = true;
919 m_zeroPosition.X = tempVector1.getX();
920 m_zeroPosition.Y = tempVector1.getY();
921 m_zeroPosition.Z = tempVector1.getZ();
922 }
923 if (m_pidControllerActive)
924 {
925 // We only want to deactivate the PID Controller if we think we want to have our surrogate
926 // react to the physics scene by moving it's position.
927 // Avatar to Avatar collisions
928 // Prim to avatar collisions
929
930 Vector3 pos = new Vector3(tempVector1.getX(), tempVector1.getY(), tempVector1.getZ());
931 vec.X = (m_target_velocity.X - vel.X) * (PID_D) + (m_zeroPosition.X - pos.X) * (PID_P * 2);
932 vec.Y = (m_target_velocity.Y - vel.Y) * (PID_D) + (m_zeroPosition.Y - pos.Y) * (PID_P * 2);
933 if (m_flying)
934 {
935 vec.Z = (m_target_velocity.Z - vel.Z) * (PID_D) + (m_zeroPosition.Z - pos.Z) * PID_P;
936 }
937 }
938 //PidStatus = true;
939 }
940 else
941 {
942 m_pidControllerActive = true;
943 m_zeroFlag = false;
944 if (m_iscolliding && !m_flying)
945 {
946 // We're standing on something
947 vec.X = ((m_target_velocity.X / movementdivisor) - vel.X) * (PID_D);
948 vec.Y = ((m_target_velocity.Y / movementdivisor) - vel.Y) * (PID_D);
949 }
950 else if (m_iscolliding && m_flying)
951 {
952 // We're flying and colliding with something
953 vec.X = ((m_target_velocity.X / movementdivisor) - vel.X) * (PID_D / 16);
954 vec.Y = ((m_target_velocity.Y / movementdivisor) - vel.Y) * (PID_D / 16);
955 }
956 else if (!m_iscolliding && m_flying)
957 {
958 // we're in mid air suspended
959 vec.X = ((m_target_velocity.X / movementdivisor) - vel.X) * (PID_D / 6);
960 vec.Y = ((m_target_velocity.Y / movementdivisor) - vel.Y) * (PID_D / 6);
961
962 // We don't want linear velocity to cause our avatar to bounce, so we check target Z and actual velocity X, Y
963 // rebound preventing
964 if (m_target_velocity.Z < 0.025f && m_velocity.X < 0.25f && m_velocity.Y < 0.25f)
965 m_zeroFlag = true;
966 }
967
968 if (m_iscolliding && !m_flying && m_target_velocity.Z > 0.0f)
969 {
970 // We're colliding with something and we're not flying but we're moving
971 // This means we're walking or running.
972 Vector3 pos = new Vector3(tempVector1.getX(), tempVector1.getY(), tempVector1.getZ());
973 vec.Z = (m_target_velocity.Z - vel.Z) * PID_D + (m_zeroPosition.Z - pos.Z) * PID_P;
974 if (m_target_velocity.X > 0)
975 {
976 vec.X = ((m_target_velocity.X - vel.X) / 1.2f) * PID_D;
977 }
978 if (m_target_velocity.Y > 0)
979 {
980 vec.Y = ((m_target_velocity.Y - vel.Y) / 1.2f) * PID_D;
981 }
982 }
983 else if (!m_iscolliding && !m_flying)
984 {
985 // we're not colliding and we're not flying so that means we're falling!
986 // m_iscolliding includes collisions with the ground.
987
988 // d.Vector3 pos = d.BodyGetPosition(Body);
989 if (m_target_velocity.X > 0)
990 {
991 vec.X = ((m_target_velocity.X - vel.X) / 1.2f) * PID_D;
992 }
993 if (m_target_velocity.Y > 0)
994 {
995 vec.Y = ((m_target_velocity.Y - vel.Y) / 1.2f) * PID_D;
996 }
997 }
998
999
1000 if (m_flying)
1001 {
1002 vec.Z = (m_target_velocity.Z - vel.Z) * (PID_D);
1003 }
1004 }
1005 if (m_flying)
1006 {
1007 // Slight PID correction
1008 vec.Z += (((-1 * m_parent_scene.gravityz) * m_mass) * 0.06f);
1009
1010
1011 //auto fly height. Kitto Flora
1012 //d.Vector3 pos = d.BodyGetPosition(Body);
1013 float target_altitude = m_parent_scene.GetTerrainHeightAtXY(m_position.X, m_position.Y) + 5.0f;
1014
1015 if (m_position.Z < target_altitude)
1016 {
1017 vec.Z += (target_altitude - m_position.Z) * PID_P * 5.0f;
1018 }
1019
1020 }
1021 if (Body != null && (((m_target_velocity.X > 0.2f || m_target_velocity.X < -0.2f) || (m_target_velocity.Y > 0.2f || m_target_velocity.Y < -0.2f))))
1022 {
1023 Body.setFriction(0.001f);
1024 //m_log.DebugFormat("[PHYSICS]: Avatar force applied: {0}, Target:{1}", vec.ToString(), m_target_velocity.ToString());
1025 }
1026
1027 if (Body != null)
1028 {
1029 int activationstate = Body.getActivationState();
1030 if (activationstate == 0)
1031 {
1032 Body.forceActivationState(1);
1033 }
1034
1035
1036 }
1037 doImpulse(vec, true);
1038 }
1039
1040 /// <summary>
1041 /// Updates the reported position and velocity. This essentially sends the data up to ScenePresence.
1042 /// </summary>
1043 public void UpdatePositionAndVelocity()
1044 {
1045 if (Body == null)
1046 return;
1047 //int val = Environment.TickCount;
1048 CheckIfStandingOnObject();
1049 //m_log.DebugFormat("time:{0}", Environment.TickCount - val);
1050
1051 //IsColliding = Body.checkCollideWith(m_parent_scene.TerrainBody);
1052
1053 tempTrans1.Dispose();
1054 tempTrans1 = Body.getInterpolationWorldTransform();
1055 tempVector1.Dispose();
1056 tempVector1 = tempTrans1.getOrigin();
1057 tempVector2.Dispose();
1058 tempVector2 = Body.getInterpolationLinearVelocity();
1059
1060 // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit!
1061 Vector3 vec = new Vector3(tempVector1.getX(), tempVector1.getY(), tempVector1.getZ());
1062
1063 // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!)
1064 if (vec.X < -10.0f) vec.X = 0.0f;
1065 if (vec.Y < -10.0f) vec.Y = 0.0f;
1066 if (vec.X > (int)Constants.RegionSize + 10.2f) vec.X = (int)Constants.RegionSize + 10.2f;
1067 if (vec.Y > (int)Constants.RegionSize + 10.2f) vec.Y = (int)Constants.RegionSize + 10.2f;
1068
1069 m_position.X = vec.X;
1070 m_position.Y = vec.Y;
1071 m_position.Z = vec.Z;
1072
1073 // Did we move last? = zeroflag
1074 // This helps keep us from sliding all over
1075
1076 if (m_zeroFlag)
1077 {
1078 m_velocity.X = 0.0f;
1079 m_velocity.Y = 0.0f;
1080 m_velocity.Z = 0.0f;
1081
1082 // Did we send out the 'stopped' message?
1083 if (!m_lastUpdateSent)
1084 {
1085 m_lastUpdateSent = true;
1086 //base.RequestPhysicsterseUpdate();
1087
1088 }
1089 }
1090 else
1091 {
1092 m_lastUpdateSent = false;
1093 vec = new Vector3(tempVector2.getX(), tempVector2.getY(), tempVector2.getZ());
1094 m_velocity.X = (vec.X);
1095 m_velocity.Y = (vec.Y);
1096
1097 m_velocity.Z = (vec.Z);
1098 //m_log.Debug(m_target_velocity);
1099 if (m_velocity.Z < -6 && !m_hackSentFall)
1100 {
1101 m_hackSentFall = true;
1102 m_pidControllerActive = false;
1103 }
1104 else if (m_flying && !m_hackSentFly)
1105 {
1106 //m_hackSentFly = true;
1107 //base.SendCollisionUpdate(new CollisionEventUpdate());
1108 }
1109 else
1110 {
1111 m_hackSentFly = false;
1112 m_hackSentFall = false;
1113 }
1114 }
1115 if (Body != null)
1116 {
1117 if (Body.getFriction() < 0.9f)
1118 Body.setFriction(0.9f);
1119 }
1120 //if (Body != null)
1121 // Body.clearForces();
1122 }
1123
1124 public void CheckIfStandingOnObject()
1125 {
1126
1127 float capsuleHalfHeight = ((CAPSULE_LENGTH + 2*CAPSULE_RADIUS)*0.5f);
1128
1129 tempVector5RayCast.setValue(m_position.X, m_position.Y, m_position.Z);
1130 tempVector6RayCast.setValue(m_position.X, m_position.Y, m_position.Z - 1 * capsuleHalfHeight * 1.1f);
1131
1132
1133 ClosestCastResult.Dispose();
1134 ClosestCastResult = new ClosestNotMeRayResultCallback(Body);
1135
1136 try
1137 {
1138 m_parent_scene.getBulletWorld().rayTest(tempVector5RayCast, tempVector6RayCast, ClosestCastResult);
1139 }
1140 catch (AccessViolationException)
1141 {
1142 m_log.Debug("BAD!");
1143 }
1144 if (ClosestCastResult.hasHit())
1145 {
1146
1147 if (tempVector7RayCast != null)
1148 tempVector7RayCast.Dispose();
1149
1150 //tempVector7RayCast = ClosestCastResult.getHitPointWorld();
1151
1152 /*if (tempVector7RayCast == null) // null == no result also
1153 {
1154 CollidingObj = false;
1155 IsColliding = false;
1156 CollidingGround = false;
1157
1158 return;
1159 }
1160 float zVal = tempVector7RayCast.getZ();
1161 if (zVal != 0)
1162 m_log.Debug("[PHYSICS]: HAAAA");
1163 if (zVal < m_position.Z && zVal > ((CAPSULE_LENGTH + 2 * CAPSULE_RADIUS) *0.5f))
1164 {
1165 CollidingObj = true;
1166 IsColliding = true;
1167 }
1168 else
1169 {
1170 CollidingObj = false;
1171 IsColliding = false;
1172 CollidingGround = false;
1173 }*/
1174
1175 //height+2*radius = capsule full length
1176 //CollidingObj = true;
1177 //IsColliding = true;
1178 m_iscolliding = true;
1179 }
1180 else
1181 {
1182 //CollidingObj = false;
1183 //IsColliding = false;
1184 //CollidingGround = false;
1185 m_iscolliding = false;
1186 }
1187 }
1188 }
1189
1190}
diff --git a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPlugin.cs b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPlugin.cs
deleted file mode 100644
index cf75c48..0000000
--- a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPlugin.cs
+++ /dev/null
@@ -1,65 +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 OpenSim.Region.Physics.Manager;
29
30namespace OpenSim.Region.Physics.BulletDotNETPlugin
31{
32 public class BulletDotNetPlugin : IPhysicsPlugin
33 {
34 private BulletDotNETScene m_scene;
35 private const string m_pluginName = "BulletDotNETPlugin";
36
37 #region IPhysicsPlugin Members
38
39 public bool Init()
40 {
41 return true;
42 }
43
44 public PhysicsScene GetScene(string sceneIdentifier)
45 {
46 if (m_scene == null)
47 {
48 m_scene = new BulletDotNETScene(sceneIdentifier);
49 }
50 return m_scene;
51 }
52
53 public string GetName()
54 {
55 return m_pluginName;
56 }
57
58 public void Dispose()
59 {
60
61 }
62
63 #endregion
64 }
65} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPluginStructs.cs b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPluginStructs.cs
deleted file mode 100644
index 578c22a..0000000
--- a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPluginStructs.cs
+++ /dev/null
@@ -1,60 +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;
29
30public enum StatusIndicators : int
31{
32 Generic = 0,
33 Start = 1,
34 End = 2
35}
36
37public struct sCollisionData
38{
39 public uint ColliderLocalId;
40 public uint CollidedWithLocalId;
41 public int NumberOfCollisions;
42 public int CollisionType;
43 public int StatusIndicator;
44 public int lastframe;
45}
46
47[Flags]
48public enum CollisionCategories : int
49{
50 Disabled = 0,
51 Geom = 0x00000001,
52 Body = 0x00000002,
53 Space = 0x00000004,
54 Character = 0x00000008,
55 Land = 0x00000010,
56 Water = 0x00000020,
57 Wind = 0x00000040,
58 Sensor = 0x00000080,
59 Selected = 0x00000100
60} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs
deleted file mode 100644
index dc3229a..0000000
--- a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs
+++ /dev/null
@@ -1,2767 +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.Runtime.InteropServices;
32using System.Threading;
33using log4net;
34using OpenMetaverse;
35using BulletDotNET;
36using OpenSim.Framework;
37using OpenSim.Region.Physics.Manager;
38
39
40namespace OpenSim.Region.Physics.BulletDotNETPlugin
41{
42 public class BulletDotNETPrim : PhysicsActor
43 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45
46 private Vector3 _position;
47 private Vector3 m_zeroPosition;
48 private Vector3 _velocity;
49 private Vector3 _torque;
50 private Vector3 m_lastVelocity;
51 private Vector3 m_lastposition;
52 private Quaternion m_lastorientation = Quaternion.Identity;
53 private Vector3 m_rotationalVelocity;
54 private Vector3 _size;
55 private Vector3 _acceleration;
56 // private d.Vector3 _zeroPosition = new d.Vector3(0.0f, 0.0f, 0.0f);
57 private Quaternion _orientation;
58 private Vector3 m_taintposition;
59 private Vector3 m_taintsize;
60 private Vector3 m_taintVelocity;
61 private Vector3 m_taintTorque;
62 private Quaternion m_taintrot;
63 private Vector3 m_angularlock = Vector3.One;
64 private Vector3 m_taintAngularLock = Vector3.One;
65 // private btGeneric6DofConstraint Amotor;
66
67 private Vector3 m_PIDTarget;
68 private float m_PIDTau;
69 private float m_PIDHoverHeight;
70 private float m_PIDHoverTau;
71 private bool m_useHoverPID;
72 private PIDHoverType m_PIDHoverType = PIDHoverType.Ground;
73 private float m_targetHoverHeight;
74 private float m_groundHeight;
75 private float m_waterHeight;
76 private float PID_D = 35f;
77 private float PID_G = 25f;
78 // private float m_tensor = 5f;
79 // private int body_autodisable_frames = 20;
80 private IMesh primMesh;
81
82 private bool m_usePID;
83
84 private const CollisionCategories m_default_collisionFlags = (CollisionCategories.Geom
85 | CollisionCategories.Space
86 | CollisionCategories.Body
87 | CollisionCategories.Character
88 );
89
90 private bool m_taintshape;
91 private bool m_taintPhysics;
92 // private bool m_collidesLand = true;
93 private bool m_collidesWater;
94 public bool m_returnCollisions;
95
96 // Default we're a Geometry
97 // private CollisionCategories m_collisionCategories = (CollisionCategories.Geom);
98
99 // Default, Collide with Other Geometries, spaces and Bodies
100 // private CollisionCategories m_collisionFlags = m_default_collisionFlags;
101
102 public bool m_taintremove;
103 public bool m_taintdisable;
104 public bool m_disabled;
105 public bool m_taintadd;
106 public bool m_taintselected;
107 public bool m_taintCollidesWater;
108
109 public uint m_localID;
110
111 //public GCHandle gc;
112 // private CollisionLocker ode;
113
114 private bool m_taintforce;
115 private bool m_taintaddangularforce;
116 private Vector3 m_force;
117 private List<Vector3> m_forcelist = new List<Vector3>();
118 private List<Vector3> m_angularforcelist = new List<Vector3>();
119
120 private IMesh _mesh;
121 private PrimitiveBaseShape _pbs;
122 private BulletDotNETScene _parent_scene;
123 public btCollisionShape prim_geom;
124 public IntPtr _triMeshData;
125
126 private PhysicsActor _parent;
127 private PhysicsActor m_taintparent;
128
129 private List<BulletDotNETPrim> childrenPrim = new List<BulletDotNETPrim>();
130
131 private bool iscolliding;
132 private bool m_isphysical;
133 private bool m_isSelected;
134
135 internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively
136
137 private bool m_throttleUpdates;
138 // private int throttleCounter;
139 public int m_interpenetrationcount;
140 public float m_collisionscore;
141 public int m_roundsUnderMotionThreshold;
142 private int m_crossingfailures;
143
144 public float m_buoyancy;
145
146 public bool outofBounds;
147 private float m_density = 10.000006836f; // Aluminum g/cm3;
148
149 public bool _zeroFlag;
150 private bool m_lastUpdateSent;
151
152
153 private String m_primName;
154 private Vector3 _target_velocity;
155
156 public int m_eventsubscription;
157 private int m_requestedUpdateFrequency = 0;
158 private CollisionEventUpdate CollisionEventsThisFrame = null;
159
160 public volatile bool childPrim;
161
162 private btVector3 tempPosition1;
163 private btVector3 tempPosition2;
164 private btVector3 tempPosition3;
165 private btVector3 tempSize1;
166 private btVector3 tempSize2;
167 private btVector3 tempLinearVelocity1;
168 private btVector3 tempLinearVelocity2;
169 private btVector3 tempAngularVelocity1;
170 private btVector3 tempAngularVelocity2;
171 private btVector3 tempInertia1;
172 private btVector3 tempInertia2;
173 private btVector3 tempAddForce;
174 private btQuaternion tempOrientation1;
175 private btQuaternion tempOrientation2;
176 private btMotionState tempMotionState1;
177 private btMotionState tempMotionState2;
178 private btMotionState tempMotionState3;
179 private btTransform tempTransform1;
180 private btTransform tempTransform2;
181 private btTransform tempTransform3;
182 private btTransform tempTransform4;
183 private btTriangleIndexVertexArray btshapeArray;
184 private btVector3 AxisLockAngleHigh;
185 private btVector3 AxisLockLinearLow;
186 private btVector3 AxisLockLinearHigh;
187 private bool forceenable = false;
188
189 private btGeneric6DofConstraint m_aMotor;
190
191 public btRigidBody Body;
192
193 public BulletDotNETPrim(String primName, BulletDotNETScene parent_scene, Vector3 pos, Vector3 size,
194 Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical)
195 {
196 tempPosition1 = new btVector3(0, 0, 0);
197 tempPosition2 = new btVector3(0, 0, 0);
198 tempPosition3 = new btVector3(0, 0, 0);
199 tempSize1 = new btVector3(0, 0, 0);
200 tempSize2 = new btVector3(0, 0, 0);
201 tempLinearVelocity1 = new btVector3(0, 0, 0);
202 tempLinearVelocity2 = new btVector3(0, 0, 0);
203 tempAngularVelocity1 = new btVector3(0, 0, 0);
204 tempAngularVelocity2 = new btVector3(0, 0, 0);
205 tempInertia1 = new btVector3(0, 0, 0);
206 tempInertia2 = new btVector3(0, 0, 0);
207 tempOrientation1 = new btQuaternion(0, 0, 0, 1);
208 tempOrientation2 = new btQuaternion(0, 0, 0, 1);
209 _parent_scene = parent_scene;
210 tempTransform1 = new btTransform(_parent_scene.QuatIdentity, _parent_scene.VectorZero);
211 tempTransform2 = new btTransform(_parent_scene.QuatIdentity, _parent_scene.VectorZero); ;
212 tempTransform3 = new btTransform(_parent_scene.QuatIdentity, _parent_scene.VectorZero); ;
213 tempTransform4 = new btTransform(_parent_scene.QuatIdentity, _parent_scene.VectorZero); ;
214
215 tempMotionState1 = new btDefaultMotionState(_parent_scene.TransZero);
216 tempMotionState2 = new btDefaultMotionState(_parent_scene.TransZero);
217 tempMotionState3 = new btDefaultMotionState(_parent_scene.TransZero);
218
219
220 AxisLockLinearLow = new btVector3(-1 * (int)Constants.RegionSize, -1 * (int)Constants.RegionSize, -1 * (int)Constants.RegionSize);
221 int regionsize = (int)Constants.RegionSize;
222
223 if (regionsize == 256)
224 regionsize = 512;
225
226 AxisLockLinearHigh = new btVector3((int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionSize);
227
228 _target_velocity = Vector3.Zero;
229 _velocity = Vector3.Zero;
230 _position = pos;
231 m_taintposition = pos;
232 PID_D = parent_scene.bodyPIDD;
233 PID_G = parent_scene.bodyPIDG;
234 m_density = parent_scene.geomDefaultDensity;
235 // m_tensor = parent_scene.bodyMotorJointMaxforceTensor;
236 // body_autodisable_frames = parent_scene.bodyFramesAutoDisable;
237
238 prim_geom = null;
239 Body = null;
240
241 if (size.X <= 0) size.X = 0.01f;
242 if (size.Y <= 0) size.Y = 0.01f;
243 if (size.Z <= 0) size.Z = 0.01f;
244
245 _size = size;
246 m_taintsize = _size;
247 _acceleration = Vector3.Zero;
248 m_rotationalVelocity = Vector3.Zero;
249 _orientation = rotation;
250 m_taintrot = _orientation;
251 _mesh = mesh;
252 _pbs = pbs;
253
254 _parent_scene = parent_scene;
255
256 if (pos.Z < 0)
257 m_isphysical = false;
258 else
259 {
260 m_isphysical = pisPhysical;
261 // If we're physical, we need to be in the master space for now.
262 // linksets *should* be in a space together.. but are not currently
263 }
264 m_primName = primName;
265 m_taintadd = true;
266 _parent_scene.AddPhysicsActorTaint(this);
267
268 }
269
270 #region PhysicsActor overrides
271
272 public override bool Stopped
273 {
274 get { return _zeroFlag; }
275 }
276
277 public override Vector3 Size
278 {
279 get { return _size; }
280 set { _size = value; }
281 }
282
283 public override PrimitiveBaseShape Shape
284 {
285 set
286 {
287 _pbs = value;
288 m_taintshape = true;
289 }
290 }
291
292 public override uint LocalID
293 {
294 set
295 {
296 //m_log.Info("[PHYSICS]: Setting TrackerID: " + value);
297 m_localID = value;
298 }
299 }
300
301 public override bool Grabbed
302 {
303 set { return; }
304 }
305
306 public override bool Selected
307 {
308 set
309 {
310 // This only makes the object not collidable if the object
311 // is physical or the object is modified somehow *IN THE FUTURE*
312 // without this, if an avatar selects prim, they can walk right
313 // through it while it's selected
314 m_collisionscore = 0;
315 if ((m_isphysical && !_zeroFlag) || !value)
316 {
317 m_taintselected = value;
318 _parent_scene.AddPhysicsActorTaint(this);
319 }
320 else
321 {
322 m_taintselected = value;
323 m_isSelected = value;
324 }
325 }
326 }
327
328 public override void CrossingFailure()
329 {
330 m_crossingfailures++;
331 if (m_crossingfailures > _parent_scene.geomCrossingFailuresBeforeOutofbounds)
332 {
333 base.RaiseOutOfBounds(_position);
334 return;
335 }
336 else if (m_crossingfailures == _parent_scene.geomCrossingFailuresBeforeOutofbounds)
337 {
338 m_log.Warn("[PHYSICS]: Too many crossing failures for: " + m_primName);
339 }
340 }
341 public override void link(PhysicsActor obj)
342 {
343 m_taintparent = obj;
344 }
345
346 public override void delink()
347 {
348 m_taintparent = null;
349 }
350
351 public override void LockAngularMotion(Vector3 axis)
352 {
353 m_log.DebugFormat("[axislock]: <{0},{1},{2}>", axis.X, axis.Y, axis.Z);
354 m_taintAngularLock = axis;
355 }
356
357 public override Vector3 Position
358 {
359 get { return _position; }
360
361 set
362 {
363 _position = value;
364 //m_log.Info("[PHYSICS]: " + _position.ToString());
365 }
366 }
367
368 public override float Mass
369 {
370 get { return CalculateMass(); }
371 }
372
373 public override Vector3 Force
374 {
375 //get { return Vector3.Zero; }
376 get { return m_force; }
377 set { m_force = value; }
378 }
379
380 public override int VehicleType
381 {
382 get { return 0; }
383 set { return; }
384 }
385
386 public override void VehicleFloatParam(int param, float value)
387 {
388 //TODO:
389 }
390
391 public override void VehicleVectorParam(int param, Vector3 value)
392 {
393 //TODO:
394 }
395
396 public override void VehicleRotationParam(int param, Quaternion rotation)
397 {
398 //TODO:
399 }
400
401 public override void VehicleFlags(int param, bool remove)
402 {
403
404 }
405
406 public override void SetVolumeDetect(int param)
407 {
408 //TODO: GhostObject
409 m_isVolumeDetect = (param != 0);
410
411 }
412
413 public override Vector3 GeometricCenter
414 {
415 get { return Vector3.Zero; }
416 }
417
418 public override Vector3 CenterOfMass
419 {
420 get { return Vector3.Zero; }
421 }
422
423 public override Vector3 Velocity
424 {
425 get
426 {
427 // Averate previous velocity with the new one so
428 // client object interpolation works a 'little' better
429 Vector3 returnVelocity;
430 returnVelocity.X = (m_lastVelocity.X + _velocity.X) / 2;
431 returnVelocity.Y = (m_lastVelocity.Y + _velocity.Y) / 2;
432 returnVelocity.Z = (m_lastVelocity.Z + _velocity.Z) / 2;
433 return returnVelocity;
434 }
435 set
436 {
437 _velocity = value;
438
439 m_taintVelocity = value;
440 _parent_scene.AddPhysicsActorTaint(this);
441 }
442 }
443
444 public override Vector3 Torque
445 {
446 get
447 {
448 if (!m_isphysical || Body.Handle == IntPtr.Zero)
449 return Vector3.Zero;
450
451 return _torque;
452 }
453
454 set
455 {
456 m_taintTorque = value;
457 _parent_scene.AddPhysicsActorTaint(this);
458 }
459 }
460
461 public override float CollisionScore
462 {
463 get { return m_collisionscore; }
464 set { m_collisionscore = value; }
465 }
466
467 public override Vector3 Acceleration
468 {
469 get { return _acceleration; }
470 }
471
472 public override Quaternion Orientation
473 {
474 get { return _orientation; }
475 set { _orientation = value; }
476 }
477
478 public override int PhysicsActorType
479 {
480 get { return (int)ActorTypes.Prim; }
481 set { return; }
482 }
483
484 public override bool IsPhysical
485 {
486 get { return m_isphysical; }
487 set { m_isphysical = value; }
488 }
489
490 public override bool Flying
491 {
492 // no flying prims for you
493 get { return false; }
494 set { }
495 }
496
497 public override bool SetAlwaysRun
498 {
499 get { return false; }
500 set { return; }
501 }
502
503 public override bool ThrottleUpdates
504 {
505 get { return m_throttleUpdates; }
506 set { m_throttleUpdates = value; }
507 }
508
509 public override bool IsColliding
510 {
511 get { return iscolliding; }
512 set { iscolliding = value; }
513 }
514
515 public override bool CollidingGround
516 {
517 get { return false; }
518 set { return; }
519 }
520
521 public override bool CollidingObj
522 {
523 get { return false; }
524 set { return; }
525 }
526
527 public override bool FloatOnWater
528 {
529 set
530 {
531 m_taintCollidesWater = value;
532 _parent_scene.AddPhysicsActorTaint(this);
533 }
534 }
535
536 public override Vector3 RotationalVelocity
537 {
538 get
539 {
540 Vector3 pv = Vector3.Zero;
541 if (_zeroFlag)
542 return pv;
543 m_lastUpdateSent = false;
544
545 if (m_rotationalVelocity.ApproxEquals(pv, 0.2f))
546 return pv;
547
548 return m_rotationalVelocity;
549 }
550 set { m_rotationalVelocity = value; }
551 }
552
553 public override bool Kinematic
554 {
555 get { return false; }
556 set { }
557 }
558
559 public override float Buoyancy
560 {
561 get { return m_buoyancy; }
562 set { m_buoyancy = value; }
563 }
564
565 public override Vector3 PIDTarget { set { m_PIDTarget = value; ; } }
566 public override bool PIDActive { set { m_usePID = value; } }
567 public override float PIDTau { set { m_PIDTau = value; } }
568
569 public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } }
570 public override bool PIDHoverActive { set { m_useHoverPID = value; } }
571 public override PIDHoverType PIDHoverType { set { m_PIDHoverType = value; } }
572 public override float PIDHoverTau { set { m_PIDHoverTau = value; } }
573
574 public override Quaternion APIDTarget { set { return; } }
575 public override bool APIDActive { set { return; } }
576 public override float APIDStrength { set { return; } }
577 public override float APIDDamping { set { return; } }
578
579 public override void AddForce(Vector3 force, bool pushforce)
580 {
581 m_forcelist.Add(force);
582 m_taintforce = true;
583 //m_log.Info("[PHYSICS]: Added Force:" + force.ToString() + " to prim at " + Position.ToString());
584 }
585
586 public override void AddAngularForce(Vector3 force, bool pushforce)
587 {
588 m_angularforcelist.Add(force);
589 m_taintaddangularforce = true;
590 }
591
592 public override void SetMomentum(Vector3 momentum)
593 {
594 }
595
596 public override void SubscribeEvents(int ms)
597 {
598 m_eventsubscription = ms;
599 m_requestedUpdateFrequency = ms;
600 _parent_scene.addCollisionEventReporting(this);
601 }
602
603 public override void UnSubscribeEvents()
604 {
605 _parent_scene.remCollisionEventReporting(this);
606 m_eventsubscription = 0;
607 m_requestedUpdateFrequency = 0;
608 }
609
610 public override bool SubscribedEvents()
611 {
612 return (m_eventsubscription > 0);
613 }
614
615 #endregion
616
617 public void AddCollision(uint collideWith, ContactPoint contact)
618 {
619 if (CollisionEventsThisFrame == null)
620 {
621 CollisionEventsThisFrame = new CollisionEventUpdate();
622 }
623 CollisionEventsThisFrame.addCollider(collideWith, contact);
624 }
625
626 public void SendCollisions()
627 {
628 if (m_eventsubscription >= m_requestedUpdateFrequency)
629 {
630 if (CollisionEventsThisFrame != null)
631 {
632 base.SendCollisionUpdate(CollisionEventsThisFrame);
633 }
634 CollisionEventsThisFrame = null;
635 // m_eventsubscription = 0;
636 }
637 return;
638 }
639
640 internal void Dispose()
641 {
642 //TODO:
643 DisableAxisMotor();
644 DisposeOfBody();
645 SetCollisionShape(null);
646
647 if (tempMotionState3 != null && tempMotionState3.Handle != IntPtr.Zero)
648 {
649 tempMotionState3.Dispose();
650 tempMotionState3 = null;
651 }
652
653 if (tempMotionState2 != null && tempMotionState2.Handle != IntPtr.Zero)
654 {
655 tempMotionState2.Dispose();
656 tempMotionState2 = null;
657 }
658
659 if (tempMotionState1 != null && tempMotionState1.Handle != IntPtr.Zero)
660 {
661 tempMotionState1.Dispose();
662 tempMotionState1 = null;
663 }
664
665 if (tempTransform4 != null && tempTransform4.Handle != IntPtr.Zero)
666 {
667 tempTransform4.Dispose();
668 tempTransform4 = null;
669 }
670
671 if (tempTransform3 != null && tempTransform3.Handle != IntPtr.Zero)
672 {
673 tempTransform3.Dispose();
674 tempTransform3 = null;
675 }
676
677 if (tempTransform2 != null && tempTransform2.Handle != IntPtr.Zero)
678 {
679 tempTransform2.Dispose();
680 tempTransform2 = null;
681 }
682
683 if (tempTransform1 != null && tempTransform1.Handle != IntPtr.Zero)
684 {
685 tempTransform1.Dispose();
686 tempTransform1 = null;
687 }
688
689 if (tempOrientation2 != null && tempOrientation2.Handle != IntPtr.Zero)
690 {
691 tempOrientation2.Dispose();
692 tempOrientation2 = null;
693 }
694
695 if (tempOrientation1 != null && tempOrientation1.Handle != IntPtr.Zero)
696 {
697 tempOrientation1.Dispose();
698 tempOrientation1 = null;
699 }
700
701 if (tempInertia1 != null && tempInertia1.Handle != IntPtr.Zero)
702 {
703 tempInertia1.Dispose();
704 tempInertia1 = null;
705 }
706
707 if (tempInertia2 != null && tempInertia2.Handle != IntPtr.Zero)
708 {
709 tempInertia2.Dispose();
710 tempInertia1 = null;
711 }
712
713
714 if (tempAngularVelocity2 != null && tempAngularVelocity2.Handle != IntPtr.Zero)
715 {
716 tempAngularVelocity2.Dispose();
717 tempAngularVelocity2 = null;
718 }
719
720 if (tempAngularVelocity1 != null && tempAngularVelocity1.Handle != IntPtr.Zero)
721 {
722 tempAngularVelocity1.Dispose();
723 tempAngularVelocity1 = null;
724 }
725
726 if (tempLinearVelocity2 != null && tempLinearVelocity2.Handle != IntPtr.Zero)
727 {
728 tempLinearVelocity2.Dispose();
729 tempLinearVelocity2 = null;
730 }
731
732 if (tempLinearVelocity1 != null && tempLinearVelocity1.Handle != IntPtr.Zero)
733 {
734 tempLinearVelocity1.Dispose();
735 tempLinearVelocity1 = null;
736 }
737
738 if (tempSize2 != null && tempSize2.Handle != IntPtr.Zero)
739 {
740 tempSize2.Dispose();
741 tempSize2 = null;
742 }
743
744 if (tempSize1 != null && tempSize1.Handle != IntPtr.Zero)
745 {
746 tempSize1.Dispose();
747 tempSize1 = null;
748 }
749
750 if (tempPosition3 != null && tempPosition3.Handle != IntPtr.Zero)
751 {
752 tempPosition3.Dispose();
753 tempPosition3 = null;
754 }
755
756 if (tempPosition2 != null && tempPosition2.Handle != IntPtr.Zero)
757 {
758 tempPosition2.Dispose();
759 tempPosition2 = null;
760 }
761
762 if (tempPosition1 != null && tempPosition1.Handle != IntPtr.Zero)
763 {
764 tempPosition1.Dispose();
765 tempPosition1 = null;
766 }
767 if (AxisLockLinearLow != null && AxisLockLinearLow.Handle != IntPtr.Zero)
768 {
769 AxisLockLinearLow.Dispose();
770 AxisLockLinearLow = null;
771 }
772 if (AxisLockLinearHigh != null && AxisLockLinearHigh.Handle != IntPtr.Zero)
773 {
774 AxisLockLinearHigh.Dispose();
775 AxisLockLinearHigh = null;
776 }
777
778 }
779
780
781
782 public void ProcessTaints(float timestep)
783 {
784 if (m_taintadd)
785 {
786 // m_log.Debug("[PHYSICS]: TaintAdd");
787 changeadd(timestep);
788 }
789
790 if (prim_geom == null)
791 {
792 CreateGeom(IntPtr.Zero, primMesh);
793
794 if (IsPhysical)
795 SetBody(Mass);
796 else
797 SetBody(0);
798 // m_log.Debug("[PHYSICS]: GEOM_DOESNT_EXSIT");
799 }
800
801 if (prim_geom.Handle == IntPtr.Zero)
802 {
803 CreateGeom(IntPtr.Zero, primMesh);
804
805 if (IsPhysical)
806 SetBody(Mass);
807 else
808 SetBody(0);
809 // m_log.Debug("[PHYSICS]: GEOM_DOESNT_EXSIT");
810
811 }
812
813 if (!_position.ApproxEquals(m_taintposition, 0f))
814 {
815 // m_log.Debug("[PHYSICS]: TaintMove");
816 changemove(timestep);
817 }
818 if (m_taintrot != _orientation)
819 {
820 // m_log.Debug("[PHYSICS]: TaintRotate");
821 rotate(timestep);
822 } //
823
824 if (m_taintPhysics != m_isphysical && !(m_taintparent != _parent))
825 {
826 // m_log.Debug("[PHYSICS]: TaintPhysics");
827 changePhysicsStatus(timestep);
828 }
829 //
830
831 if (!_size.ApproxEquals(m_taintsize, 0f))
832 {
833 // m_log.Debug("[PHYSICS]: TaintSize");
834 changesize(timestep);
835 }
836
837 //
838
839 if (m_taintshape)
840 {
841 // m_log.Debug("[PHYSICS]: TaintShape");
842 changeshape(timestep);
843 } //
844
845 if (m_taintforce)
846 {
847 // m_log.Debug("[PHYSICS]: TaintForce");
848 changeAddForce(timestep);
849 }
850 if (m_taintaddangularforce)
851 {
852 // m_log.Debug("[PHYSICS]: TaintAngularForce");
853 changeAddAngularForce(timestep);
854 }
855 if (!m_taintTorque.ApproxEquals(Vector3.Zero, 0.001f))
856 {
857 // m_log.Debug("[PHYSICS]: TaintTorque");
858 changeSetTorque(timestep);
859 }
860 if (m_taintdisable)
861 {
862 // m_log.Debug("[PHYSICS]: TaintDisable");
863 changedisable(timestep);
864 }
865 if (m_taintselected != m_isSelected)
866 {
867 // m_log.Debug("[PHYSICS]: TaintSelected");
868 changeSelectedStatus(timestep);
869 }
870 if (!m_taintVelocity.ApproxEquals(Vector3.Zero, 0.001f))
871 {
872 // m_log.Debug("[PHYSICS]: TaintVelocity");
873 changevelocity(timestep);
874 }
875 if (m_taintparent != _parent)
876 {
877 // m_log.Debug("[PHYSICS]: TaintLink");
878 changelink(timestep);
879 }
880 if (m_taintCollidesWater != m_collidesWater)
881 {
882 changefloatonwater(timestep);
883 }
884 if (!m_angularlock.ApproxEquals(m_taintAngularLock, 0))
885 {
886 // m_log.Debug("[PHYSICS]: TaintAngularLock");
887 changeAngularLock(timestep);
888 }
889 if (m_taintremove)
890 {
891 DisposeOfBody();
892 Dispose();
893 }
894
895 }
896
897 #region Physics Scene Change Action routines
898
899 private void changeadd(float timestep)
900 {
901 //SetCollisionShape(null);
902 // Construction of new prim
903 if (Body != null)
904 {
905 if (Body.Handle != IntPtr.Zero)
906 {
907 DisableAxisMotor();
908 _parent_scene.removeFromWorld(this, Body);
909 //Body.Dispose();
910 }
911 //Body = null;
912 // TODO: dispose parts that make up body
913 }
914 if (_parent_scene.needsMeshing(_pbs))
915 {
916 // Don't need to re-enable body.. it's done in SetMesh
917 float meshlod = _parent_scene.meshSculptLOD;
918
919 if (IsPhysical)
920 meshlod = _parent_scene.MeshSculptphysicalLOD;
921
922 IMesh mesh = _parent_scene.mesher.CreateMesh(SOPName, _pbs, _size, meshlod, IsPhysical);
923 // createmesh returns null when it doesn't mesh.
924 CreateGeom(IntPtr.Zero, mesh);
925 }
926 else
927 {
928 _mesh = null;
929 CreateGeom(IntPtr.Zero, null);
930 }
931
932 if (IsPhysical)
933 SetBody(Mass);
934 else
935 SetBody(0);
936 //changeSelectedStatus(timestep);
937 m_taintadd = false;
938
939 }
940
941 private void changemove(float timestep)
942 {
943
944 // m_log.Debug("[PHYSICS]: _________ChangeMove");
945 if (!m_isphysical)
946 {
947 tempTransform2 = Body.getWorldTransform();
948 btQuaternion quat = tempTransform2.getRotation();
949 tempPosition2.setValue(_position.X, _position.Y, _position.Z);
950 tempTransform2.Dispose();
951 tempTransform2 = new btTransform(quat, tempPosition2);
952 Body.setWorldTransform(tempTransform2);
953
954 changeSelectedStatus(timestep);
955
956 resetCollisionAccounting();
957 }
958 else
959 {
960 if (Body != null)
961 {
962 if (Body.Handle != IntPtr.Zero)
963 {
964 DisableAxisMotor();
965 _parent_scene.removeFromWorld(this, Body);
966 //Body.Dispose();
967 }
968 //Body = null;
969 // TODO: dispose parts that make up body
970 }
971 /*
972 if (_parent_scene.needsMeshing(_pbs))
973 {
974 // Don't need to re-enable body.. it's done in SetMesh
975 float meshlod = _parent_scene.meshSculptLOD;
976
977 if (IsPhysical)
978 meshlod = _parent_scene.MeshSculptphysicalLOD;
979
980 IMesh mesh = _parent_scene.mesher.CreateMesh(SOPName, _pbs, _size, meshlod, IsPhysical);
981 // createmesh returns null when it doesn't mesh.
982 CreateGeom(IntPtr.Zero, mesh);
983 }
984 else
985 {
986 _mesh = null;
987 CreateGeom(IntPtr.Zero, null);
988 }
989 SetCollisionShape(prim_geom);
990 */
991 if (m_isphysical)
992 SetBody(Mass);
993 else
994 SetBody(0);
995 changeSelectedStatus(timestep);
996
997 resetCollisionAccounting();
998 }
999 m_taintposition = _position;
1000 }
1001
1002 private void rotate(float timestep)
1003 {
1004 // m_log.Debug("[PHYSICS]: _________ChangeRotate");
1005 tempTransform2 = Body.getWorldTransform();
1006 tempOrientation2 = new btQuaternion(_orientation.X, _orientation.Y, _orientation.Z, _orientation.W);
1007 tempTransform2.setRotation(tempOrientation2);
1008 Body.setWorldTransform(tempTransform2);
1009
1010 resetCollisionAccounting();
1011 m_taintrot = _orientation;
1012 }
1013
1014 private void changePhysicsStatus(float timestep)
1015 {
1016 if (Body != null)
1017 {
1018 if (Body.Handle != IntPtr.Zero)
1019 {
1020 DisableAxisMotor();
1021 _parent_scene.removeFromWorld(this, Body);
1022 //Body.Dispose();
1023 }
1024 //Body = null;
1025 // TODO: dispose parts that make up body
1026 }
1027 // m_log.Debug("[PHYSICS]: _________ChangePhysics");
1028
1029 ProcessGeomCreation();
1030
1031 if (m_isphysical)
1032 SetBody(Mass);
1033 else
1034 SetBody(0);
1035 changeSelectedStatus(timestep);
1036
1037 resetCollisionAccounting();
1038 m_taintPhysics = m_isphysical;
1039 }
1040
1041
1042
1043 internal void ProcessGeomCreation()
1044 {
1045 if (_parent_scene.needsMeshing(_pbs))
1046 {
1047 ProcessGeomCreationAsTriMesh(Vector3.Zero, Quaternion.Identity);
1048 // createmesh returns null when it doesn't mesh.
1049 CreateGeom(IntPtr.Zero, _mesh);
1050 }
1051 else
1052 {
1053 _mesh = null;
1054 CreateGeom(IntPtr.Zero, null);
1055 }
1056 SetCollisionShape(prim_geom);
1057 }
1058
1059 internal bool NeedsMeshing()
1060 {
1061 return _parent_scene.needsMeshing(_pbs);
1062 }
1063
1064 internal void ProcessGeomCreationAsTriMesh(Vector3 positionOffset, Quaternion orientation)
1065 {
1066 // Don't need to re-enable body.. it's done in SetMesh
1067 float meshlod = _parent_scene.meshSculptLOD;
1068
1069 if (IsPhysical)
1070 meshlod = _parent_scene.MeshSculptphysicalLOD;
1071
1072 IMesh mesh = _parent_scene.mesher.CreateMesh(SOPName, _pbs, _size, meshlod, IsPhysical);
1073 if (!positionOffset.ApproxEquals(Vector3.Zero, 0.001f) || orientation != Quaternion.Identity)
1074 {
1075
1076 float[] xyz = new float[3];
1077 xyz[0] = positionOffset.X;
1078 xyz[1] = positionOffset.Y;
1079 xyz[2] = positionOffset.Z;
1080
1081 Matrix4 m4 = Matrix4.CreateFromQuaternion(orientation);
1082
1083 float[,] matrix = new float[3, 3];
1084
1085 matrix[0, 0] = m4.M11;
1086 matrix[0, 1] = m4.M12;
1087 matrix[0, 2] = m4.M13;
1088 matrix[1, 0] = m4.M21;
1089 matrix[1, 1] = m4.M22;
1090 matrix[1, 2] = m4.M23;
1091 matrix[2, 0] = m4.M31;
1092 matrix[2, 1] = m4.M32;
1093 matrix[2, 2] = m4.M33;
1094
1095
1096 mesh.TransformLinear(matrix, xyz);
1097
1098
1099
1100 }
1101
1102 _mesh = mesh;
1103 }
1104
1105 private void changesize(float timestep)
1106 {
1107 if (Body != null)
1108 {
1109 if (Body.Handle != IntPtr.Zero)
1110 {
1111 DisableAxisMotor();
1112 _parent_scene.removeFromWorld(this, Body);
1113 //Body.Dispose();
1114 }
1115 //Body = null;
1116 // TODO: dispose parts that make up body
1117 }
1118
1119 // m_log.Debug("[PHYSICS]: _________ChangeSize");
1120 SetCollisionShape(null);
1121 // Construction of new prim
1122 ProcessGeomCreation();
1123
1124 if (IsPhysical)
1125 SetBody(Mass);
1126 else
1127 SetBody(0);
1128
1129 m_taintsize = _size;
1130
1131 }
1132
1133 private void changeshape(float timestep)
1134 {
1135 if (Body != null)
1136 {
1137 if (Body.Handle != IntPtr.Zero)
1138 {
1139 DisableAxisMotor();
1140 _parent_scene.removeFromWorld(this, Body);
1141 //Body.Dispose();
1142 }
1143 //Body = null;
1144 // TODO: dispose parts that make up body
1145 }
1146 // Cleanup of old prim geometry and Bodies
1147 if (IsPhysical && Body != null && Body.Handle != IntPtr.Zero)
1148 {
1149 if (childPrim)
1150 {
1151 if (_parent != null)
1152 {
1153 BulletDotNETPrim parent = (BulletDotNETPrim)_parent;
1154 parent.ChildDelink(this);
1155 }
1156 }
1157 else
1158 {
1159 //disableBody();
1160 }
1161 }
1162 try
1163 {
1164 //SetCollisionShape(null);
1165 }
1166 catch (System.AccessViolationException)
1167 {
1168 //prim_geom = IntPtr.Zero;
1169 m_log.Error("[PHYSICS]: PrimGeom dead");
1170 }
1171
1172 // we don't need to do space calculation because the client sends a position update also.
1173 if (_size.X <= 0) _size.X = 0.01f;
1174 if (_size.Y <= 0) _size.Y = 0.01f;
1175 if (_size.Z <= 0) _size.Z = 0.01f;
1176 // Construction of new prim
1177
1178 ProcessGeomCreation();
1179
1180 tempPosition1.setValue(_position.X, _position.Y, _position.Z);
1181 if (tempOrientation1.Handle != IntPtr.Zero)
1182 tempOrientation1.Dispose();
1183 tempOrientation1 = new btQuaternion(_orientation.X, Orientation.Y, _orientation.Z, _orientation.W);
1184 if (tempTransform1 != null && tempTransform1.Handle != IntPtr.Zero)
1185 tempTransform1.Dispose();
1186 tempTransform1 = new btTransform(tempOrientation1, tempPosition1);
1187
1188
1189
1190
1191 //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
1192 if (IsPhysical)
1193 {
1194 SetBody(Mass);
1195 // Re creates body on size.
1196 // EnableBody also does setMass()
1197
1198 }
1199 else
1200 {
1201 SetBody(0);
1202 }
1203
1204 changeSelectedStatus(timestep);
1205 if (childPrim)
1206 {
1207 if (_parent is BulletDotNETPrim)
1208 {
1209 BulletDotNETPrim parent = (BulletDotNETPrim)_parent;
1210 parent.ChildSetGeom(this);
1211 }
1212 }
1213 resetCollisionAccounting();
1214
1215 m_taintshape = false;
1216 }
1217
1218 private void resetCollisionAccounting()
1219 {
1220 m_collisionscore = 0;
1221 }
1222
1223 private void ChildSetGeom(BulletDotNETPrim bulletDotNETPrim)
1224 {
1225 // TODO: throw new NotImplementedException();
1226 }
1227
1228 private void changeAddForce(float timestep)
1229 {
1230 if (!m_isSelected)
1231 {
1232 lock (m_forcelist)
1233 {
1234 //m_log.Info("[PHYSICS]: dequeing forcelist");
1235 if (IsPhysical)
1236 {
1237 Vector3 iforce = Vector3.Zero;
1238 for (int i = 0; i < m_forcelist.Count; i++)
1239 {
1240 iforce = iforce + m_forcelist[i];
1241 }
1242
1243 if (Body != null && Body.Handle != IntPtr.Zero)
1244 {
1245 if (tempAddForce != null && tempAddForce.Handle != IntPtr.Zero)
1246 tempAddForce.Dispose();
1247 enableBodySoft();
1248 tempAddForce = new btVector3(iforce.X, iforce.Y, iforce.Z);
1249 Body.applyCentralImpulse(tempAddForce);
1250 }
1251 }
1252 m_forcelist.Clear();
1253 }
1254
1255 m_collisionscore = 0;
1256 m_interpenetrationcount = 0;
1257 }
1258
1259 m_taintforce = false;
1260
1261 }
1262
1263 private void changeAddAngularForce(float timestep)
1264 {
1265 if (!m_isSelected)
1266 {
1267 lock (m_angularforcelist)
1268 {
1269 //m_log.Info("[PHYSICS]: dequeing forcelist");
1270 if (IsPhysical)
1271 {
1272 Vector3 iforce = Vector3.Zero;
1273 for (int i = 0; i < m_angularforcelist.Count; i++)
1274 {
1275 iforce = iforce + m_angularforcelist[i];
1276 }
1277
1278 if (Body != null && Body.Handle != IntPtr.Zero)
1279 {
1280 if (tempAddForce != null && tempAddForce.Handle != IntPtr.Zero)
1281 tempAddForce.Dispose();
1282 enableBodySoft();
1283 tempAddForce = new btVector3(iforce.X, iforce.Y, iforce.Z);
1284 Body.applyTorqueImpulse(tempAddForce);
1285 }
1286
1287 }
1288 m_angularforcelist.Clear();
1289 }
1290
1291 m_collisionscore = 0;
1292 m_interpenetrationcount = 0;
1293 }
1294
1295 m_taintaddangularforce = false;
1296 }
1297
1298 private void changeSetTorque(float timestep)
1299 {
1300 if (!m_isSelected)
1301 {
1302 if (IsPhysical)
1303 {
1304 if (Body != null && Body.Handle != IntPtr.Zero)
1305 {
1306 tempAngularVelocity2.setValue(m_taintTorque.X, m_taintTorque.Y, m_taintTorque.Z);
1307 Body.applyTorque(tempAngularVelocity2);
1308 }
1309 }
1310 }
1311 m_taintTorque = Vector3.Zero;
1312 }
1313
1314 private void changedisable(float timestep)
1315 {
1316 // TODO: throw new NotImplementedException();
1317 }
1318
1319 private void changeSelectedStatus(float timestep)
1320 {
1321 // TODO: throw new NotImplementedException();
1322 if (m_taintselected)
1323 {
1324 // Body.setCollisionFlags((int)ContactFlags.CF_NO_CONTACT_RESPONSE);
1325 disableBodySoft();
1326
1327 }
1328 else
1329 {
1330 // Body.setCollisionFlags(0 | (int)ContactFlags.CF_CUSTOM_MATERIAL_CALLBACK);
1331 enableBodySoft();
1332 }
1333 m_isSelected = m_taintselected;
1334
1335 }
1336
1337 private void changevelocity(float timestep)
1338 {
1339 if (!m_isSelected)
1340 {
1341 if (IsPhysical)
1342 {
1343 if (Body != null && Body.Handle != IntPtr.Zero)
1344 {
1345 tempLinearVelocity2.setValue(m_taintVelocity.X, m_taintVelocity.Y, m_taintVelocity.Z);
1346 Body.setLinearVelocity(tempLinearVelocity2);
1347 }
1348 }
1349
1350 //resetCollisionAccounting();
1351 }
1352 m_taintVelocity = Vector3.Zero;
1353 }
1354
1355 private void changelink(float timestep)
1356 {
1357 if (IsPhysical)
1358 {
1359 // Construction of new prim
1360 if (Body != null)
1361 {
1362 if (Body.Handle != IntPtr.Zero)
1363 {
1364 DisableAxisMotor();
1365 _parent_scene.removeFromWorld(this, Body);
1366 //Body.Dispose();
1367 }
1368 //Body = null;
1369 // TODO: dispose parts that make up body
1370 }
1371
1372 if (_parent == null && m_taintparent != null)
1373 {
1374
1375 if (m_taintparent is BulletDotNETPrim)
1376 {
1377 BulletDotNETPrim obj = (BulletDotNETPrim)m_taintparent;
1378 obj.ParentPrim(this);
1379 childPrim = true;
1380
1381 }
1382 }
1383 else if (_parent != null && m_taintparent == null)
1384 {
1385 if (_parent is BulletDotNETPrim)
1386 {
1387 BulletDotNETPrim obj = (BulletDotNETPrim)_parent;
1388 obj.ChildDelink(obj);
1389
1390 childPrim = false;
1391 }
1392 }
1393
1394 if (m_taintparent != null)
1395 {
1396 Vector3 taintparentPosition = m_taintparent.Position;
1397 taintparentPosition.Z = m_taintparent.Position.Z + 0.02f;
1398 m_taintparent.Position = taintparentPosition;
1399 _parent_scene.AddPhysicsActorTaint(m_taintparent);
1400 }
1401 }
1402 _parent = m_taintparent;
1403
1404 m_taintPhysics = m_isphysical;
1405
1406 }
1407
1408 private void changefloatonwater(float timestep)
1409 {
1410 // TODO: throw new NotImplementedException();
1411 }
1412
1413 private void changeAngularLock(float timestep)
1414 {
1415 if (IsPhysical && Body != null && Body.Handle != IntPtr.Zero)
1416 {
1417 if (_parent == null)
1418 {
1419 if (!m_taintAngularLock.ApproxEquals(Vector3.One, 0f))
1420 {
1421 //d.BodySetFiniteRotationMode(Body, 0);
1422 //d.BodySetFiniteRotationAxis(Body,m_taintAngularLock.X,m_taintAngularLock.Y,m_taintAngularLock.Z);
1423 EnableAxisMotor(m_taintAngularLock);
1424 }
1425 else
1426 {
1427 DisableAxisMotor();
1428 }
1429 }
1430
1431 }
1432 m_angularlock = m_taintAngularLock;
1433
1434 }
1435 #endregion
1436
1437
1438
1439
1440 internal void Move(float timestep)
1441 {
1442 //TODO:
1443 float fx = 0;
1444 float fy = 0;
1445 float fz = 0;
1446
1447 if (IsPhysical && Body != null && Body.Handle != IntPtr.Zero && !m_isSelected)
1448 {
1449 float m_mass = CalculateMass();
1450
1451 fz = 0f;
1452 //m_log.Info(m_collisionFlags.ToString());
1453
1454 if (m_buoyancy != 0)
1455 {
1456 if (m_buoyancy > 0)
1457 {
1458 fz = (((-1 * _parent_scene.gravityz) * m_buoyancy) * m_mass) * 0.035f;
1459
1460 //d.Vector3 l_velocity = d.BodyGetLinearVel(Body);
1461 //m_log.Info("Using Buoyancy: " + buoyancy + " G: " + (_parent_scene.gravityz * m_buoyancy) + "mass:" + m_mass + " Pos: " + Position.ToString());
1462 }
1463 else
1464 {
1465 fz = (-1 * (((-1 * _parent_scene.gravityz) * (-1 * m_buoyancy)) * m_mass) * 0.035f);
1466 }
1467 }
1468
1469 if (m_usePID)
1470 {
1471 PID_D = 61f;
1472 PID_G = 65f;
1473 //if (!d.BodyIsEnabled(Body))
1474 //d.BodySetForce(Body, 0f, 0f, 0f);
1475 // If we're using the PID controller, then we have no gravity
1476 fz = ((-1 * _parent_scene.gravityz) * m_mass) * 1.025f;
1477
1478 // no lock; for now it's only called from within Simulate()
1479
1480 // If the PID Controller isn't active then we set our force
1481 // calculating base velocity to the current position
1482
1483 if ((m_PIDTau < 1) && (m_PIDTau != 0))
1484 {
1485 //PID_G = PID_G / m_PIDTau;
1486 m_PIDTau = 1;
1487 }
1488
1489 if ((PID_G - m_PIDTau) <= 0)
1490 {
1491 PID_G = m_PIDTau + 1;
1492 }
1493
1494 // TODO: NEED btVector3 for Linear Velocity
1495 // NEED btVector3 for Position
1496
1497 Vector3 pos = _position; //TODO: Insert values gotten from bullet
1498 Vector3 vel = _velocity;
1499
1500 _target_velocity =
1501 new Vector3(
1502 (m_PIDTarget.X - pos.X) * ((PID_G - m_PIDTau) * timestep),
1503 (m_PIDTarget.Y - pos.Y) * ((PID_G - m_PIDTau) * timestep),
1504 (m_PIDTarget.Z - pos.Z) * ((PID_G - m_PIDTau) * timestep)
1505 );
1506
1507 if (_target_velocity.ApproxEquals(Vector3.Zero, 0.1f))
1508 {
1509
1510 /* TODO: Do Bullet equiv
1511 *
1512 d.BodySetPosition(Body, m_PIDTarget.X, m_PIDTarget.Y, m_PIDTarget.Z);
1513 d.BodySetLinearVel(Body, 0, 0, 0);
1514 d.BodyAddForce(Body, 0, 0, fz);
1515 return;
1516 */
1517 }
1518 else
1519 {
1520 _zeroFlag = false;
1521
1522 fx = ((_target_velocity.X) - vel.X) * (PID_D);
1523 fy = ((_target_velocity.Y) - vel.Y) * (PID_D);
1524 fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass);
1525
1526 }
1527
1528 }
1529
1530 if (m_useHoverPID && !m_usePID)
1531 {
1532 // If we're using the PID controller, then we have no gravity
1533 fz = (-1 * _parent_scene.gravityz) * m_mass;
1534
1535 // no lock; for now it's only called from within Simulate()
1536
1537 // If the PID Controller isn't active then we set our force
1538 // calculating base velocity to the current position
1539
1540 if ((m_PIDTau < 1))
1541 {
1542 PID_G = PID_G / m_PIDTau;
1543 }
1544
1545 if ((PID_G - m_PIDTau) <= 0)
1546 {
1547 PID_G = m_PIDTau + 1;
1548 }
1549 Vector3 pos = Vector3.Zero; //TODO: Insert values gotten from bullet
1550 Vector3 vel = Vector3.Zero;
1551
1552 // determine what our target height really is based on HoverType
1553 switch (m_PIDHoverType)
1554 {
1555 case PIDHoverType.Absolute:
1556 m_targetHoverHeight = m_PIDHoverHeight;
1557 break;
1558 case PIDHoverType.Ground:
1559 m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y);
1560 m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight;
1561 break;
1562 case PIDHoverType.GroundAndWater:
1563 m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y);
1564 m_waterHeight = _parent_scene.GetWaterLevel();
1565 if (m_groundHeight > m_waterHeight)
1566 {
1567 m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight;
1568 }
1569 else
1570 {
1571 m_targetHoverHeight = m_waterHeight + m_PIDHoverHeight;
1572 }
1573 break;
1574 case PIDHoverType.Water:
1575 m_waterHeight = _parent_scene.GetWaterLevel();
1576 m_targetHoverHeight = m_waterHeight + m_PIDHoverHeight;
1577 break;
1578 }
1579
1580
1581 _target_velocity =
1582 new Vector3(0.0f, 0.0f,
1583 (m_targetHoverHeight - pos.Z) * ((PID_G - m_PIDHoverTau) * timestep)
1584 );
1585
1586 // if velocity is zero, use position control; otherwise, velocity control
1587
1588 if (_target_velocity.ApproxEquals(Vector3.Zero, 0.1f))
1589 {
1590
1591 /* TODO: Do Bullet Equiv
1592 d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight);
1593 d.BodySetLinearVel(Body, vel.X, vel.Y, 0);
1594 d.BodyAddForce(Body, 0, 0, fz);
1595 */
1596 if (Body != null && Body.Handle != IntPtr.Zero)
1597 {
1598 Body.setLinearVelocity(_parent_scene.VectorZero);
1599 Body.clearForces();
1600 }
1601 return;
1602 }
1603 else
1604 {
1605 _zeroFlag = false;
1606
1607 // We're flying and colliding with something
1608 fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass);
1609 }
1610 }
1611
1612 fx *= m_mass;
1613 fy *= m_mass;
1614 //fz *= m_mass;
1615
1616 fx += m_force.X;
1617 fy += m_force.Y;
1618 fz += m_force.Z;
1619
1620 //m_log.Info("[OBJPID]: X:" + fx.ToString() + " Y:" + fy.ToString() + " Z:" + fz.ToString());
1621 if (fx != 0 || fy != 0 || fz != 0)
1622 {
1623 /*
1624 * TODO: Do Bullet Equiv
1625 if (!d.BodyIsEnabled(Body))
1626 {
1627 d.BodySetLinearVel(Body, 0f, 0f, 0f);
1628 d.BodySetForce(Body, 0, 0, 0);
1629 enableBodySoft();
1630 }
1631 */
1632 if (!Body.isActive())
1633 {
1634 Body.clearForces();
1635 enableBodySoft();
1636 }
1637 // 35x10 = 350n times the mass per second applied maximum.
1638
1639 float nmax = 35f * m_mass;
1640 float nmin = -35f * m_mass;
1641
1642
1643 if (fx > nmax)
1644 fx = nmax;
1645 if (fx < nmin)
1646 fx = nmin;
1647 if (fy > nmax)
1648 fy = nmax;
1649 if (fy < nmin)
1650 fy = nmin;
1651
1652 // TODO: Do Bullet Equiv
1653 // d.BodyAddForce(Body, fx, fy, fz);
1654 if (Body != null && Body.Handle != IntPtr.Zero)
1655 {
1656 Body.activate(true);
1657 if (tempAddForce != null && tempAddForce.Handle != IntPtr.Zero)
1658 tempAddForce.Dispose();
1659
1660 tempAddForce = new btVector3(fx * 0.01f, fy * 0.01f, fz * 0.01f);
1661 Body.applyCentralImpulse(tempAddForce);
1662 }
1663 }
1664 else
1665 {
1666 // if no forces on the prim, make sure everything is zero
1667 Body.clearForces();
1668 enableBodySoft();
1669 }
1670 }
1671 else
1672 {
1673 if (m_zeroPosition == null)
1674 m_zeroPosition = Vector3.Zero;
1675 m_zeroPosition = _position;
1676 return;
1677 }
1678 }
1679
1680
1681
1682
1683 #region Mass Calculation
1684
1685 private float CalculateMass()
1686 {
1687 float volume = 0;
1688
1689 // No material is passed to the physics engines yet.. soo..
1690 // we're using the m_density constant in the class definition
1691
1692 float returnMass = 0;
1693
1694 switch (_pbs.ProfileShape)
1695 {
1696 case ProfileShape.Square:
1697 // Profile Volume
1698
1699 volume = _size.X * _size.Y * _size.Z;
1700
1701 // If the user has 'hollowed out'
1702 // ProfileHollow is one of those 0 to 50000 values :P
1703 // we like percentages better.. so turning into a percentage
1704
1705 if (((float)_pbs.ProfileHollow / 50000f) > 0.0)
1706 {
1707 float hollowAmount = (float)_pbs.ProfileHollow / 50000f;
1708
1709 // calculate the hollow volume by it's shape compared to the prim shape
1710 float hollowVolume = 0;
1711 switch (_pbs.HollowShape)
1712 {
1713 case HollowShape.Square:
1714 case HollowShape.Same:
1715 // Cube Hollow volume calculation
1716 float hollowsizex = _size.X * hollowAmount;
1717 float hollowsizey = _size.Y * hollowAmount;
1718 float hollowsizez = _size.Z * hollowAmount;
1719 hollowVolume = hollowsizex * hollowsizey * hollowsizez;
1720 break;
1721
1722 case HollowShape.Circle:
1723 // Hollow shape is a perfect cyllinder in respect to the cube's scale
1724 // Cyllinder hollow volume calculation
1725 float hRadius = _size.X / 2;
1726 float hLength = _size.Z;
1727
1728 // pi * r2 * h
1729 hollowVolume = ((float)(Math.PI * Math.Pow(hRadius, 2) * hLength) * hollowAmount);
1730 break;
1731
1732 case HollowShape.Triangle:
1733 // Equilateral Triangular Prism volume hollow calculation
1734 // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y
1735
1736 float aLength = _size.Y;
1737 // 1/2 abh
1738 hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount);
1739 break;
1740
1741 default:
1742 hollowVolume = 0;
1743 break;
1744 }
1745 volume = volume - hollowVolume;
1746 }
1747
1748 break;
1749 case ProfileShape.Circle:
1750 if (_pbs.PathCurve == (byte)Extrusion.Straight)
1751 {
1752 // Cylinder
1753 float volume1 = (float)(Math.PI * Math.Pow(_size.X / 2, 2) * _size.Z);
1754 float volume2 = (float)(Math.PI * Math.Pow(_size.Y / 2, 2) * _size.Z);
1755
1756 // Approximating the cylinder's irregularity.
1757 if (volume1 > volume2)
1758 {
1759 volume = (float)volume1 - (volume1 - volume2);
1760 }
1761 else if (volume2 > volume1)
1762 {
1763 volume = (float)volume2 - (volume2 - volume1);
1764 }
1765 else
1766 {
1767 // Regular cylinder
1768 volume = volume1;
1769 }
1770 }
1771 else
1772 {
1773 // We don't know what the shape is yet, so use default
1774 volume = _size.X * _size.Y * _size.Z;
1775 }
1776 // If the user has 'hollowed out'
1777 // ProfileHollow is one of those 0 to 50000 values :P
1778 // we like percentages better.. so turning into a percentage
1779
1780 if (((float)_pbs.ProfileHollow / 50000f) > 0.0)
1781 {
1782 float hollowAmount = (float)_pbs.ProfileHollow / 50000f;
1783
1784 // calculate the hollow volume by it's shape compared to the prim shape
1785 float hollowVolume = 0;
1786 switch (_pbs.HollowShape)
1787 {
1788 case HollowShape.Same:
1789 case HollowShape.Circle:
1790 // Hollow shape is a perfect cyllinder in respect to the cube's scale
1791 // Cyllinder hollow volume calculation
1792 float hRadius = _size.X / 2;
1793 float hLength = _size.Z;
1794
1795 // pi * r2 * h
1796 hollowVolume = ((float)(Math.PI * Math.Pow(hRadius, 2) * hLength) * hollowAmount);
1797 break;
1798
1799 case HollowShape.Square:
1800 // Cube Hollow volume calculation
1801 float hollowsizex = _size.X * hollowAmount;
1802 float hollowsizey = _size.Y * hollowAmount;
1803 float hollowsizez = _size.Z * hollowAmount;
1804 hollowVolume = hollowsizex * hollowsizey * hollowsizez;
1805 break;
1806
1807 case HollowShape.Triangle:
1808 // Equilateral Triangular Prism volume hollow calculation
1809 // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y
1810
1811 float aLength = _size.Y;
1812 // 1/2 abh
1813 hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount);
1814 break;
1815
1816 default:
1817 hollowVolume = 0;
1818 break;
1819 }
1820 volume = volume - hollowVolume;
1821 }
1822 break;
1823
1824 case ProfileShape.HalfCircle:
1825 if (_pbs.PathCurve == (byte)Extrusion.Curve1)
1826 {
1827 if (_size.X == _size.Y && _size.Z == _size.X)
1828 {
1829 // regular sphere
1830 // v = 4/3 * pi * r^3
1831 float sradius3 = (float)Math.Pow((_size.X / 2), 3);
1832 volume = (float)((4 / 3f) * Math.PI * sradius3);
1833 }
1834 else
1835 {
1836 // we treat this as a box currently
1837 volume = _size.X * _size.Y * _size.Z;
1838 }
1839 }
1840 else
1841 {
1842 // We don't know what the shape is yet, so use default
1843 volume = _size.X * _size.Y * _size.Z;
1844 }
1845 break;
1846
1847 case ProfileShape.EquilateralTriangle:
1848 /*
1849 v = (abs((xB*yA-xA*yB)+(xC*yB-xB*yC)+(xA*yC-xC*yA))/2) * h
1850
1851 // seed mesh
1852 Vertex MM = new Vertex(-0.25f, -0.45f, 0.0f);
1853 Vertex PM = new Vertex(+0.5f, 0f, 0.0f);
1854 Vertex PP = new Vertex(-0.25f, +0.45f, 0.0f);
1855 */
1856 float xA = -0.25f * _size.X;
1857 float yA = -0.45f * _size.Y;
1858
1859 float xB = 0.5f * _size.X;
1860 float yB = 0;
1861
1862 float xC = -0.25f * _size.X;
1863 float yC = 0.45f * _size.Y;
1864
1865 volume = (float)((Math.Abs((xB * yA - xA * yB) + (xC * yB - xB * yC) + (xA * yC - xC * yA)) / 2) * _size.Z);
1866
1867 // If the user has 'hollowed out'
1868 // ProfileHollow is one of those 0 to 50000 values :P
1869 // we like percentages better.. so turning into a percentage
1870 float fhollowFactor = ((float)_pbs.ProfileHollow / 1.9f);
1871 if (((float)fhollowFactor / 50000f) > 0.0)
1872 {
1873 float hollowAmount = (float)fhollowFactor / 50000f;
1874
1875 // calculate the hollow volume by it's shape compared to the prim shape
1876 float hollowVolume = 0;
1877 switch (_pbs.HollowShape)
1878 {
1879 case HollowShape.Same:
1880 case HollowShape.Triangle:
1881 // Equilateral Triangular Prism volume hollow calculation
1882 // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y
1883
1884 float aLength = _size.Y;
1885 // 1/2 abh
1886 hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount);
1887 break;
1888
1889 case HollowShape.Square:
1890 // Cube Hollow volume calculation
1891 float hollowsizex = _size.X * hollowAmount;
1892 float hollowsizey = _size.Y * hollowAmount;
1893 float hollowsizez = _size.Z * hollowAmount;
1894 hollowVolume = hollowsizex * hollowsizey * hollowsizez;
1895 break;
1896
1897 case HollowShape.Circle:
1898 // Hollow shape is a perfect cyllinder in respect to the cube's scale
1899 // Cyllinder hollow volume calculation
1900 float hRadius = _size.X / 2;
1901 float hLength = _size.Z;
1902
1903 // pi * r2 * h
1904 hollowVolume = ((float)((Math.PI * Math.Pow(hRadius, 2) * hLength) / 2) * hollowAmount);
1905 break;
1906
1907 default:
1908 hollowVolume = 0;
1909 break;
1910 }
1911 volume = volume - hollowVolume;
1912 }
1913 break;
1914
1915 default:
1916 // we don't have all of the volume formulas yet so
1917 // use the common volume formula for all
1918 volume = _size.X * _size.Y * _size.Z;
1919 break;
1920 }
1921
1922 // Calculate Path cut effect on volume
1923 // Not exact, in the triangle hollow example
1924 // They should never be zero or less then zero..
1925 // we'll ignore it if it's less then zero
1926
1927 // ProfileEnd and ProfileBegin are values
1928 // from 0 to 50000
1929
1930 // Turning them back into percentages so that I can cut that percentage off the volume
1931
1932 float PathCutEndAmount = _pbs.ProfileEnd;
1933 float PathCutStartAmount = _pbs.ProfileBegin;
1934 if (((PathCutStartAmount + PathCutEndAmount) / 50000f) > 0.0f)
1935 {
1936 float pathCutAmount = ((PathCutStartAmount + PathCutEndAmount) / 50000f);
1937
1938 // Check the return amount for sanity
1939 if (pathCutAmount >= 0.99f)
1940 pathCutAmount = 0.99f;
1941
1942 volume = volume - (volume * pathCutAmount);
1943 }
1944 UInt16 taperX = _pbs.PathScaleX;
1945 UInt16 taperY = _pbs.PathScaleY;
1946 float taperFactorX = 0;
1947 float taperFactorY = 0;
1948
1949 // Mass = density * volume
1950 if (taperX != 100)
1951 {
1952 if (taperX > 100)
1953 {
1954 taperFactorX = 1.0f - ((float)taperX / 200);
1955 //m_log.Warn("taperTopFactorX: " + extr.taperTopFactorX.ToString());
1956 }
1957 else
1958 {
1959 taperFactorX = 1.0f - ((100 - (float)taperX) / 100);
1960 //m_log.Warn("taperBotFactorX: " + extr.taperBotFactorX.ToString());
1961 }
1962 volume = (float)volume * ((taperFactorX / 3f) + 0.001f);
1963 }
1964
1965 if (taperY != 100)
1966 {
1967 if (taperY > 100)
1968 {
1969 taperFactorY = 1.0f - ((float)taperY / 200);
1970 //m_log.Warn("taperTopFactorY: " + extr.taperTopFactorY.ToString());
1971 }
1972 else
1973 {
1974 taperFactorY = 1.0f - ((100 - (float)taperY) / 100);
1975 //m_log.Warn("taperBotFactorY: " + extr.taperBotFactorY.ToString());
1976 }
1977 volume = (float)volume * ((taperFactorY / 3f) + 0.001f);
1978 }
1979 returnMass = m_density * volume;
1980 if (returnMass <= 0) returnMass = 0.0001f;//ckrinke: Mass must be greater then zero.
1981
1982
1983
1984 // Recursively calculate mass
1985 bool HasChildPrim = false;
1986 lock (childrenPrim)
1987 {
1988 if (childrenPrim.Count > 0)
1989 {
1990 HasChildPrim = true;
1991 }
1992
1993 }
1994 if (HasChildPrim)
1995 {
1996 BulletDotNETPrim[] childPrimArr = new BulletDotNETPrim[0];
1997
1998 lock (childrenPrim)
1999 childPrimArr = childrenPrim.ToArray();
2000
2001 for (int i = 0; i < childPrimArr.Length; i++)
2002 {
2003 if (childPrimArr[i] != null && !childPrimArr[i].m_taintremove)
2004 returnMass += childPrimArr[i].CalculateMass();
2005 // failsafe, this shouldn't happen but with OpenSim, you never know :)
2006 if (i > 256)
2007 break;
2008 }
2009 }
2010
2011
2012
2013
2014
2015 return returnMass;
2016 }
2017
2018 #endregion
2019
2020
2021 public void CreateGeom(IntPtr m_targetSpace, IMesh p_mesh)
2022 {
2023 // m_log.Debug("[PHYSICS]: _________CreateGeom");
2024 if (p_mesh != null)
2025 {
2026 //_mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical);
2027 _mesh = p_mesh;
2028 setMesh(_parent_scene, _mesh);
2029
2030 }
2031 else
2032 {
2033 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
2034 {
2035 if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
2036 {
2037 if (((_size.X / 2f) > 0f))
2038 {
2039 //SetGeom to a Regular Sphere
2040 if (tempSize1 == null)
2041 tempSize1 = new btVector3(0, 0, 0);
2042 tempSize1.setValue(_size.X * 0.5f, _size.Y * 0.5f, _size.Z * 0.5f);
2043 SetCollisionShape(new btSphereShape(_size.X * 0.5f));
2044 }
2045 else
2046 {
2047 // uses halfextents
2048 if (tempSize1 == null)
2049 tempSize1 = new btVector3(0, 0, 0);
2050 tempSize1.setValue(_size.X * 0.5f, _size.Y * 0.5f, _size.Z * 0.5f);
2051 SetCollisionShape(new btBoxShape(tempSize1));
2052 }
2053 }
2054 else
2055 {
2056 // uses halfextents
2057 if (tempSize1 == null)
2058 tempSize1 = new btVector3(0, 0, 0);
2059 tempSize1.setValue(_size.X * 0.5f, _size.Y * 0.5f, _size.Z * 0.5f);
2060 SetCollisionShape(new btBoxShape(tempSize1));
2061 }
2062
2063 }
2064 else
2065 {
2066 if (tempSize1 == null)
2067 tempSize1 = new btVector3(0, 0, 0);
2068 // uses halfextents
2069 tempSize1.setValue(_size.X * 0.5f, _size.Y * 0.5f, _size.Z * 0.5f);
2070 SetCollisionShape(new btBoxShape(tempSize1));
2071 }
2072 }
2073 }
2074
2075 private void setMesh(BulletDotNETScene _parent_scene, IMesh mesh)
2076 {
2077 // TODO: Set Collision Body Mesh
2078 // This sleeper is there to moderate how long it takes between
2079 // setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object
2080 // m_log.Debug("_________SetMesh");
2081 Thread.Sleep(10);
2082
2083 //Kill Body so that mesh can re-make the geom
2084 if (IsPhysical && Body != null && Body.Handle != IntPtr.Zero)
2085 {
2086 if (childPrim)
2087 {
2088 if (_parent != null)
2089 {
2090 BulletDotNETPrim parent = (BulletDotNETPrim)_parent;
2091 parent.ChildDelink(this);
2092 }
2093 }
2094 else
2095 {
2096 //disableBody();
2097 }
2098 }
2099
2100 //IMesh oldMesh = primMesh;
2101
2102 //primMesh = mesh;
2103
2104 //float[] vertexList = primMesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory
2105 //int[] indexList = primMesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage
2106 ////Array.Reverse(indexList);
2107 //primMesh.releaseSourceMeshData(); // free up the original mesh data to save memory
2108
2109 IMesh oldMesh = primMesh;
2110
2111 primMesh = mesh;
2112
2113 float[] vertexList = mesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory
2114 int[] indexList = mesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage
2115 //Array.Reverse(indexList);
2116 mesh.releaseSourceMeshData(); // free up the original mesh data to save memory
2117
2118
2119 int VertexCount = vertexList.GetLength(0) / 3;
2120 int IndexCount = indexList.GetLength(0);
2121
2122 if (btshapeArray != null && btshapeArray.Handle != IntPtr.Zero)
2123 btshapeArray.Dispose();
2124 //Array.Reverse(indexList);
2125 btshapeArray = new btTriangleIndexVertexArray(IndexCount / 3, indexList, (3 * sizeof(int)),
2126 VertexCount, vertexList, 3 * sizeof(float));
2127 SetCollisionShape(new btGImpactMeshShape(btshapeArray));
2128 //((btGImpactMeshShape) prim_geom).updateBound();
2129 ((btGImpactMeshShape)prim_geom).setLocalScaling(new btVector3(1, 1, 1));
2130 ((btGImpactMeshShape)prim_geom).updateBound();
2131 _parent_scene.SetUsingGImpact();
2132 //if (oldMesh != null)
2133 //{
2134 // oldMesh.releasePinned();
2135 // oldMesh = null;
2136 //}
2137
2138 }
2139
2140 private void SetCollisionShape(btCollisionShape shape)
2141 {
2142 /*
2143 if (shape == null)
2144 m_log.Debug("[PHYSICS]:SetShape!Null");
2145 else
2146 m_log.Debug("[PHYSICS]:SetShape!");
2147
2148 if (Body != null)
2149 {
2150 DisposeOfBody();
2151 }
2152
2153 if (prim_geom != null)
2154 {
2155 prim_geom.Dispose();
2156 prim_geom = null;
2157 }
2158 */
2159 prim_geom = shape;
2160
2161 //Body.set
2162 }
2163
2164 public void SetBody(float mass)
2165 {
2166
2167 if (!IsPhysical || childrenPrim.Count == 0)
2168 {
2169 if (tempMotionState1 != null && tempMotionState1.Handle != IntPtr.Zero)
2170 tempMotionState1.Dispose();
2171 if (tempTransform2 != null && tempTransform2.Handle != IntPtr.Zero)
2172 tempTransform2.Dispose();
2173 if (tempOrientation2 != null && tempOrientation2.Handle != IntPtr.Zero)
2174 tempOrientation2.Dispose();
2175
2176 if (tempPosition2 != null && tempPosition2.Handle != IntPtr.Zero)
2177 tempPosition2.Dispose();
2178
2179 tempOrientation2 = new btQuaternion(_orientation.X, _orientation.Y, _orientation.Z, _orientation.W);
2180 tempPosition2 = new btVector3(_position.X, _position.Y, _position.Z);
2181 tempTransform2 = new btTransform(tempOrientation2, tempPosition2);
2182 tempMotionState1 = new btDefaultMotionState(tempTransform2, _parent_scene.TransZero);
2183 if (tempInertia1 != null && tempInertia1.Handle != IntPtr.Zero)
2184 tempInertia1.Dispose();
2185 tempInertia1 = new btVector3(0, 0, 0);
2186
2187
2188 prim_geom.calculateLocalInertia(mass, tempInertia1);
2189
2190 if (mass != 0)
2191 _parent_scene.addActivePrim(this);
2192 else
2193 _parent_scene.remActivePrim(this);
2194
2195 // Body = new btRigidBody(mass, tempMotionState1, prim_geom);
2196 //else
2197 // Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1);
2198 if (Body == null)
2199 {
2200 Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1);
2201 // add localID so we can later map bullet object back to OpenSim object
2202 Body.setUserPointer(new IntPtr((int)m_localID));
2203 }
2204
2205
2206 if (prim_geom is btGImpactMeshShape)
2207 {
2208 ((btGImpactMeshShape)prim_geom).setLocalScaling(new btVector3(1, 1, 1));
2209 ((btGImpactMeshShape)prim_geom).updateBound();
2210 }
2211 //Body.setCollisionFlags(Body.getCollisionFlags() | (int)ContactFlags.CF_CUSTOM_MATERIAL_CALLBACK);
2212 //Body.setUserPointer((IntPtr) (int)m_localID);
2213 _parent_scene.AddPrimToScene(this);
2214 }
2215 else
2216 {
2217 // bool hasTrimesh = false;
2218 lock (childrenPrim)
2219 {
2220 foreach (BulletDotNETPrim chld in childrenPrim)
2221 {
2222 if (chld == null)
2223 continue;
2224
2225 // if (chld.NeedsMeshing())
2226 // hasTrimesh = true;
2227 }
2228 }
2229
2230 //if (hasTrimesh)
2231 //{
2232 ProcessGeomCreationAsTriMesh(Vector3.Zero, Quaternion.Identity);
2233 // createmesh returns null when it doesn't mesh.
2234
2235 /*
2236 if (_mesh is Mesh)
2237 {
2238 }
2239 else
2240 {
2241 m_log.Warn("[PHYSICS]: Can't link a OpenSim.Region.Physics.Meshing.Mesh object");
2242 return;
2243 }
2244 */
2245
2246
2247
2248 foreach (BulletDotNETPrim chld in childrenPrim)
2249 {
2250 if (chld == null)
2251 continue;
2252 Vector3 offset = chld.Position - Position;
2253 Vector3 pos = new Vector3(offset.X, offset.Y, offset.Z);
2254 pos *= Quaternion.Inverse(Orientation);
2255 //pos *= Orientation;
2256 offset = pos;
2257 chld.ProcessGeomCreationAsTriMesh(offset, chld.Orientation);
2258
2259 _mesh.Append(chld._mesh);
2260
2261
2262 }
2263 setMesh(_parent_scene, _mesh);
2264
2265 //}
2266
2267 if (tempMotionState1 != null && tempMotionState1.Handle != IntPtr.Zero)
2268 tempMotionState1.Dispose();
2269 if (tempTransform2 != null && tempTransform2.Handle != IntPtr.Zero)
2270 tempTransform2.Dispose();
2271 if (tempOrientation2 != null && tempOrientation2.Handle != IntPtr.Zero)
2272 tempOrientation2.Dispose();
2273
2274 if (tempPosition2 != null && tempPosition2.Handle != IntPtr.Zero)
2275 tempPosition2.Dispose();
2276
2277 tempOrientation2 = new btQuaternion(_orientation.X, _orientation.Y, _orientation.Z, _orientation.W);
2278 tempPosition2 = new btVector3(_position.X, _position.Y, _position.Z);
2279 tempTransform2 = new btTransform(tempOrientation2, tempPosition2);
2280 tempMotionState1 = new btDefaultMotionState(tempTransform2, _parent_scene.TransZero);
2281 if (tempInertia1 != null && tempInertia1.Handle != IntPtr.Zero)
2282 tempInertia1.Dispose();
2283 tempInertia1 = new btVector3(0, 0, 0);
2284
2285
2286 prim_geom.calculateLocalInertia(mass, tempInertia1);
2287
2288 if (mass != 0)
2289 _parent_scene.addActivePrim(this);
2290 else
2291 _parent_scene.remActivePrim(this);
2292
2293 // Body = new btRigidBody(mass, tempMotionState1, prim_geom);
2294 //else
2295 // Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1);
2296 if (Body == null)
2297 {
2298 Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1);
2299 // each body has the localID stored into it so we can identify collision objects
2300 Body.setUserPointer(new IntPtr((int)m_localID));
2301 }
2302
2303 if (prim_geom is btGImpactMeshShape)
2304 {
2305 ((btGImpactMeshShape)prim_geom).setLocalScaling(new btVector3(1, 1, 1));
2306 ((btGImpactMeshShape)prim_geom).updateBound();
2307 }
2308 _parent_scene.AddPrimToScene(this);
2309
2310 }
2311
2312 if (IsPhysical)
2313 changeAngularLock(0);
2314 }
2315
2316 private void DisposeOfBody()
2317 {
2318 if (Body != null)
2319 {
2320 if (Body.Handle != IntPtr.Zero)
2321 {
2322 DisableAxisMotor();
2323 _parent_scene.removeFromWorld(this, Body);
2324 Body.Dispose();
2325 }
2326 Body = null;
2327 // TODO: dispose parts that make up body
2328 }
2329 }
2330
2331 private void ChildDelink(BulletDotNETPrim pPrim)
2332 {
2333 // Okay, we have a delinked child.. need to rebuild the body.
2334 lock (childrenPrim)
2335 {
2336 foreach (BulletDotNETPrim prm in childrenPrim)
2337 {
2338 prm.childPrim = true;
2339 prm.disableBody();
2340
2341 }
2342 }
2343 disableBody();
2344
2345 lock (childrenPrim)
2346 {
2347 childrenPrim.Remove(pPrim);
2348 }
2349
2350
2351
2352
2353 if (Body != null && Body.Handle != IntPtr.Zero)
2354 {
2355 _parent_scene.remActivePrim(this);
2356 }
2357
2358
2359
2360 lock (childrenPrim)
2361 {
2362 foreach (BulletDotNETPrim prm in childrenPrim)
2363 {
2364 ParentPrim(prm);
2365 }
2366 }
2367
2368 }
2369
2370 internal void ParentPrim(BulletDotNETPrim prm)
2371 {
2372 if (prm == null)
2373 return;
2374
2375
2376
2377 lock (childrenPrim)
2378 {
2379 if (!childrenPrim.Contains(prm))
2380 {
2381 childrenPrim.Add(prm);
2382 }
2383 }
2384
2385
2386 }
2387
2388 public void disableBody()
2389 {
2390 //this kills the body so things like 'mesh' can re-create it.
2391 /*
2392 lock (this)
2393 {
2394 if (!childPrim)
2395 {
2396 if (Body != null && Body.Handle != IntPtr.Zero)
2397 {
2398 _parent_scene.remActivePrim(this);
2399
2400 m_collisionCategories &= ~CollisionCategories.Body;
2401 m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land);
2402
2403 if (prim_geom != null && prim_geom.Handle != IntPtr.Zero)
2404 {
2405 // TODO: Set Category bits and Flags
2406 }
2407
2408 // TODO: destroy body
2409 DisposeOfBody();
2410
2411 lock (childrenPrim)
2412 {
2413 if (childrenPrim.Count > 0)
2414 {
2415 foreach (BulletDotNETPrim prm in childrenPrim)
2416 {
2417 _parent_scene.remActivePrim(prm);
2418 prm.DisposeOfBody();
2419 prm.SetCollisionShape(null);
2420 }
2421 }
2422
2423 }
2424
2425 DisposeOfBody();
2426 }
2427 }
2428 else
2429 {
2430 _parent_scene.remActivePrim(this);
2431 m_collisionCategories &= ~CollisionCategories.Body;
2432 m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land);
2433
2434 if (prim_geom != null && prim_geom.Handle != IntPtr.Zero)
2435 {
2436 // TODO: Set Category bits and Flags
2437 }
2438
2439 DisposeOfBody();
2440 }
2441
2442 }
2443 */
2444 DisableAxisMotor();
2445 m_disabled = true;
2446 m_collisionscore = 0;
2447 }
2448
2449 public void disableBodySoft()
2450 {
2451 m_disabled = true;
2452
2453 if (m_isphysical && Body.Handle != IntPtr.Zero)
2454 {
2455 Body.clearForces();
2456 Body.forceActivationState(0);
2457
2458 }
2459
2460 }
2461
2462 public void enableBodySoft()
2463 {
2464 if (!childPrim)
2465 {
2466 if (m_isphysical && Body.Handle != IntPtr.Zero)
2467 {
2468 Body.clearForces();
2469 Body.forceActivationState(4);
2470 forceenable = true;
2471
2472 }
2473 m_disabled = false;
2474 }
2475 }
2476
2477 public void enableBody()
2478 {
2479 if (!childPrim)
2480 {
2481 //SetCollisionShape(prim_geom);
2482 if (IsPhysical)
2483 SetBody(Mass);
2484 else
2485 SetBody(0);
2486
2487 // TODO: Set Collision Category Bits and Flags
2488 // TODO: Set Auto Disable data
2489
2490 m_interpenetrationcount = 0;
2491 m_collisionscore = 0;
2492 m_disabled = false;
2493 // The body doesn't already have a finite rotation mode set here
2494 if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null)
2495 {
2496 // TODO: Create Angular Motor on Axis Lock!
2497 }
2498 _parent_scene.addActivePrim(this);
2499 }
2500 }
2501
2502 public void UpdatePositionAndVelocity()
2503 {
2504 if (!m_isSelected)
2505 {
2506 if (_parent == null)
2507 {
2508 Vector3 pv = Vector3.Zero;
2509 bool lastZeroFlag = _zeroFlag;
2510 if (tempPosition3 != null && tempPosition3.Handle != IntPtr.Zero)
2511 tempPosition3.Dispose();
2512 if (tempTransform3 != null && tempTransform3.Handle != IntPtr.Zero)
2513 tempTransform3.Dispose();
2514
2515 if (tempOrientation2 != null && tempOrientation2.Handle != IntPtr.Zero)
2516 tempOrientation2.Dispose();
2517
2518 if (tempAngularVelocity1 != null && tempAngularVelocity1.Handle != IntPtr.Zero)
2519 tempAngularVelocity1.Dispose();
2520
2521 if (tempLinearVelocity1 != null && tempLinearVelocity1.Handle != IntPtr.Zero)
2522 tempLinearVelocity1.Dispose();
2523
2524
2525
2526 tempTransform3 = Body.getInterpolationWorldTransform();
2527 tempPosition3 = tempTransform3.getOrigin(); // vec
2528 tempOrientation2 = tempTransform3.getRotation(); // ori
2529 tempAngularVelocity1 = Body.getInterpolationAngularVelocity(); //rotvel
2530 tempLinearVelocity1 = Body.getInterpolationLinearVelocity(); // vel
2531
2532 _torque = new Vector3(tempAngularVelocity1.getX(), tempAngularVelocity1.getX(),
2533 tempAngularVelocity1.getZ());
2534 Vector3 l_position = Vector3.Zero;
2535 Quaternion l_orientation = Quaternion.Identity;
2536 m_lastposition = _position;
2537 m_lastorientation = _orientation;
2538
2539 l_position.X = tempPosition3.getX();
2540 l_position.Y = tempPosition3.getY();
2541 l_position.Z = tempPosition3.getZ();
2542 l_orientation.X = tempOrientation2.getX();
2543 l_orientation.Y = tempOrientation2.getY();
2544 l_orientation.Z = tempOrientation2.getZ();
2545 l_orientation.W = tempOrientation2.getW();
2546
2547 if (l_position.X > ((int)Constants.RegionSize - 0.05f) || l_position.X < 0f || l_position.Y > ((int)Constants.RegionSize - 0.05f) || l_position.Y < 0f)
2548 {
2549 //base.RaiseOutOfBounds(l_position);
2550
2551 if (m_crossingfailures < _parent_scene.geomCrossingFailuresBeforeOutofbounds)
2552 {
2553 _position = l_position;
2554 //_parent_scene.remActivePrim(this);
2555 if (_parent == null)
2556 base.RequestPhysicsterseUpdate();
2557 return;
2558 }
2559 else
2560 {
2561 if (_parent == null)
2562 base.RaiseOutOfBounds(l_position);
2563 return;
2564 }
2565 }
2566
2567 if (l_position.Z < -200000f)
2568 {
2569 // This is so prim that get lost underground don't fall forever and suck up
2570 //
2571 // Sim resources and memory.
2572 // Disables the prim's movement physics....
2573 // It's a hack and will generate a console message if it fails.
2574
2575 //IsPhysical = false;
2576 //if (_parent == null)
2577 //base.RaiseOutOfBounds(_position);
2578
2579 _acceleration.X = 0;
2580 _acceleration.Y = 0;
2581 _acceleration.Z = 0;
2582
2583 _velocity.X = 0;
2584 _velocity.Y = 0;
2585 _velocity.Z = 0;
2586 m_rotationalVelocity.X = 0;
2587 m_rotationalVelocity.Y = 0;
2588 m_rotationalVelocity.Z = 0;
2589
2590 if (_parent == null)
2591 base.RequestPhysicsterseUpdate();
2592
2593 m_throttleUpdates = false;
2594 // throttleCounter = 0;
2595 _zeroFlag = true;
2596 //outofBounds = true;
2597 }
2598
2599 if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02)
2600 && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02)
2601 && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02)
2602 && (1.0 - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)) < 0.01))
2603 {
2604 _zeroFlag = true;
2605 m_throttleUpdates = false;
2606 }
2607 else
2608 {
2609 //m_log.Debug(Math.Abs(m_lastposition.X - l_position.X).ToString());
2610 _zeroFlag = false;
2611 }
2612
2613 if (_zeroFlag)
2614 {
2615 _velocity.X = 0.0f;
2616 _velocity.Y = 0.0f;
2617 _velocity.Z = 0.0f;
2618
2619 _acceleration.X = 0;
2620 _acceleration.Y = 0;
2621 _acceleration.Z = 0;
2622
2623 //_orientation.w = 0f;
2624 //_orientation.X = 0f;
2625 //_orientation.Y = 0f;
2626 //_orientation.Z = 0f;
2627 m_rotationalVelocity.X = 0;
2628 m_rotationalVelocity.Y = 0;
2629 m_rotationalVelocity.Z = 0;
2630 if (!m_lastUpdateSent)
2631 {
2632 m_throttleUpdates = false;
2633 // throttleCounter = 0;
2634 m_rotationalVelocity = pv;
2635
2636 if (_parent == null)
2637 base.RequestPhysicsterseUpdate();
2638
2639 m_lastUpdateSent = true;
2640 }
2641 }
2642 else
2643 {
2644 if (lastZeroFlag != _zeroFlag)
2645 {
2646 if (_parent == null)
2647 base.RequestPhysicsterseUpdate();
2648 }
2649
2650 m_lastVelocity = _velocity;
2651
2652 _position = l_position;
2653
2654 _velocity.X = tempLinearVelocity1.getX();
2655 _velocity.Y = tempLinearVelocity1.getY();
2656 _velocity.Z = tempLinearVelocity1.getZ();
2657
2658 _acceleration = ((_velocity - m_lastVelocity) / 0.1f);
2659 _acceleration = new Vector3(_velocity.X - m_lastVelocity.X / 0.1f,
2660 _velocity.Y - m_lastVelocity.Y / 0.1f,
2661 _velocity.Z - m_lastVelocity.Z / 0.1f);
2662 //m_log.Info("[PHYSICS]: V1: " + _velocity + " V2: " + m_lastVelocity + " Acceleration: " + _acceleration.ToString());
2663
2664 if (_velocity.ApproxEquals(pv, 0.5f))
2665 {
2666 m_rotationalVelocity = pv;
2667 }
2668 else
2669 {
2670 m_rotationalVelocity = new Vector3(tempAngularVelocity1.getX(), tempAngularVelocity1.getY(), tempAngularVelocity1.getZ());
2671 }
2672
2673 //m_log.Debug("ODE: " + m_rotationalVelocity.ToString());
2674
2675 _orientation.X = l_orientation.X;
2676 _orientation.Y = l_orientation.Y;
2677 _orientation.Z = l_orientation.Z;
2678 _orientation.W = l_orientation.W;
2679 m_lastUpdateSent = false;
2680
2681 //if (!m_throttleUpdates || throttleCounter > _parent_scene.geomUpdatesPerThrottledUpdate)
2682 //{
2683 if (_parent == null)
2684 base.RequestPhysicsterseUpdate();
2685 // }
2686 // else
2687 // {
2688 // throttleCounter++;
2689 //}
2690
2691 }
2692 m_lastposition = l_position;
2693 if (forceenable)
2694 {
2695 Body.forceActivationState(1);
2696 forceenable = false;
2697 }
2698 }
2699 else
2700 {
2701 // Not a body.. so Make sure the client isn't interpolating
2702 _velocity.X = 0;
2703 _velocity.Y = 0;
2704 _velocity.Z = 0;
2705
2706 _acceleration.X = 0;
2707 _acceleration.Y = 0;
2708 _acceleration.Z = 0;
2709
2710 m_rotationalVelocity.X = 0;
2711 m_rotationalVelocity.Y = 0;
2712 m_rotationalVelocity.Z = 0;
2713 _zeroFlag = true;
2714 }
2715 }
2716 }
2717
2718
2719 internal void setPrimForRemoval()
2720 {
2721 m_taintremove = true;
2722 }
2723
2724 internal void EnableAxisMotor(Vector3 axislock)
2725 {
2726 if (m_aMotor != null)
2727 DisableAxisMotor();
2728
2729 if (Body == null)
2730 return;
2731
2732 if (Body.Handle == IntPtr.Zero)
2733 return;
2734
2735 if (AxisLockAngleHigh != null && AxisLockAngleHigh.Handle != IntPtr.Zero)
2736 AxisLockAngleHigh.Dispose();
2737
2738
2739
2740 m_aMotor = new btGeneric6DofConstraint(Body, _parent_scene.TerrainBody, _parent_scene.TransZero,
2741 _parent_scene.TransZero, false);
2742
2743 float endNoLock = (360 * Utils.DEG_TO_RAD);
2744 AxisLockAngleHigh = new btVector3((axislock.X == 0) ? 0 : endNoLock, (axislock.Y == 0) ? 0 : endNoLock, (axislock.Z == 0) ? 0 : endNoLock);
2745
2746 m_aMotor.setAngularLowerLimit(_parent_scene.VectorZero);
2747 m_aMotor.setAngularUpperLimit(AxisLockAngleHigh);
2748 m_aMotor.setLinearLowerLimit(AxisLockLinearLow);
2749 m_aMotor.setLinearUpperLimit(AxisLockLinearHigh);
2750 _parent_scene.getBulletWorld().addConstraint((btTypedConstraint)m_aMotor);
2751 //m_aMotor.
2752
2753
2754 }
2755 internal void DisableAxisMotor()
2756 {
2757 if (m_aMotor != null && m_aMotor.Handle != IntPtr.Zero)
2758 {
2759 _parent_scene.getBulletWorld().removeConstraint(m_aMotor);
2760 m_aMotor.Dispose();
2761 m_aMotor = null;
2762 }
2763 }
2764
2765 }
2766}
2767
diff --git a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs
deleted file mode 100644
index 0d1bd82..0000000
--- a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs
+++ /dev/null
@@ -1,776 +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.IO;
32using System.Diagnostics;
33using System.Threading;
34using log4net;
35using Nini.Config;
36using OpenSim.Framework;
37using OpenSim.Region.Physics.Manager;
38using OpenMetaverse;
39using BulletDotNET;
40
41namespace OpenSim.Region.Physics.BulletDotNETPlugin
42{
43 public class BulletDotNETScene : PhysicsScene
44 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46
47 // private string m_sceneIdentifier = string.Empty;
48
49 private List<BulletDotNETCharacter> m_characters = new List<BulletDotNETCharacter>();
50 private Dictionary<uint, BulletDotNETCharacter> m_charactersLocalID = new Dictionary<uint, BulletDotNETCharacter>();
51 private List<BulletDotNETPrim> m_prims = new List<BulletDotNETPrim>();
52 private Dictionary<uint, BulletDotNETPrim> m_primsLocalID = new Dictionary<uint, BulletDotNETPrim>();
53 private List<BulletDotNETPrim> m_activePrims = new List<BulletDotNETPrim>();
54 private List<PhysicsActor> m_taintedActors = new List<PhysicsActor>();
55 private btDiscreteDynamicsWorld m_world;
56 private btAxisSweep3 m_broadphase;
57 private btCollisionConfiguration m_collisionConfiguration;
58 private btConstraintSolver m_solver;
59 private btCollisionDispatcher m_dispatcher;
60 private btHeightfieldTerrainShape m_terrainShape;
61 public btRigidBody TerrainBody;
62 private btVector3 m_terrainPosition;
63 private btVector3 m_gravity;
64 public btMotionState m_terrainMotionState;
65 public btTransform m_terrainTransform;
66 public btVector3 VectorZero;
67 public btQuaternion QuatIdentity;
68 public btTransform TransZero;
69
70 public float geomDefaultDensity = 10.000006836f;
71
72 private float avPIDD = 65f;
73 private float avPIDP = 21f;
74 private float avCapRadius = 0.37f;
75 private float avStandupTensor = 2000000f;
76 private float avDensity = 80f;
77 private float avHeightFudgeFactor = 0.52f;
78 private float avMovementDivisorWalk = 1.8f;
79 private float avMovementDivisorRun = 0.8f;
80
81 // private float minimumGroundFlightOffset = 3f;
82
83 public bool meshSculptedPrim = true;
84
85 public float meshSculptLOD = 32;
86 public float MeshSculptphysicalLOD = 16;
87
88 public float bodyPIDD = 35f;
89 public float bodyPIDG = 25;
90 internal int geomCrossingFailuresBeforeOutofbounds = 4;
91
92 public float bodyMotorJointMaxforceTensor = 2;
93
94 public int bodyFramesAutoDisable = 20;
95
96 public float WorldTimeStep = 10f/60f;
97 public const float WorldTimeComp = 1/60f;
98 public float gravityz = -9.8f;
99
100 private float[] _origheightmap; // Used for Fly height. Kitto Flora
101 private bool usingGImpactAlgorithm = false;
102
103 // private IConfigSource m_config;
104 private readonly btVector3 worldAabbMin = new btVector3(-10f, -10f, 0);
105 private readonly btVector3 worldAabbMax = new btVector3((int)Constants.RegionSize + 10f, (int)Constants.RegionSize + 10f, 9000);
106
107 public IMesher mesher;
108 private ContactAddedCallbackHandler m_CollisionInterface;
109
110 public BulletDotNETScene(string sceneIdentifier)
111 {
112 // m_sceneIdentifier = sceneIdentifier;
113 VectorZero = new btVector3(0, 0, 0);
114 QuatIdentity = new btQuaternion(0, 0, 0, 1);
115 TransZero = new btTransform(QuatIdentity, VectorZero);
116 m_gravity = new btVector3(0, 0, gravityz);
117 _origheightmap = new float[(int)Constants.RegionSize * (int)Constants.RegionSize];
118
119 }
120
121 public override void Initialise(IMesher meshmerizer, IConfigSource config)
122 {
123 mesher = meshmerizer;
124 // m_config = config;
125 /*
126 if (Environment.OSVersion.Platform == PlatformID.Unix)
127 {
128 m_log.Fatal("[BulletDotNET]: This configuration is not supported on *nix currently");
129 Thread.Sleep(5000);
130 Environment.Exit(0);
131 }
132 */
133 m_broadphase = new btAxisSweep3(worldAabbMin, worldAabbMax, 16000);
134 m_collisionConfiguration = new btDefaultCollisionConfiguration();
135 m_solver = new btSequentialImpulseConstraintSolver();
136 m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
137 m_world = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration);
138 m_world.setGravity(m_gravity);
139 EnableCollisionInterface();
140
141
142 }
143
144 public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying)
145 {
146 BulletDotNETCharacter chr = new BulletDotNETCharacter(avName, this, position, size, avPIDD, avPIDP,
147 avCapRadius, avStandupTensor, avDensity,
148 avHeightFudgeFactor, avMovementDivisorWalk,
149 avMovementDivisorRun);
150 try
151 {
152 m_characters.Add(chr);
153 m_charactersLocalID.Add(chr.m_localID, chr);
154 }
155 catch
156 {
157 // noop if it's already there
158 m_log.Debug("[PHYSICS] BulletDotNet: adding duplicate avatar localID");
159 }
160 AddPhysicsActorTaint(chr);
161 return chr;
162 }
163
164 public override void RemoveAvatar(PhysicsActor actor)
165 {
166 BulletDotNETCharacter chr = (BulletDotNETCharacter) actor;
167
168 m_charactersLocalID.Remove(chr.m_localID);
169 m_characters.Remove(chr);
170 m_world.removeRigidBody(chr.Body);
171 m_world.removeCollisionObject(chr.Body);
172
173 chr.Remove();
174 AddPhysicsActorTaint(chr);
175 //chr = null;
176 }
177
178 public override void RemovePrim(PhysicsActor prim)
179 {
180 if (prim is BulletDotNETPrim)
181 {
182
183 BulletDotNETPrim p = (BulletDotNETPrim)prim;
184
185 p.setPrimForRemoval();
186 AddPhysicsActorTaint(prim);
187 //RemovePrimThreadLocked(p);
188
189 }
190 }
191
192 private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation,
193 IMesh mesh, PrimitiveBaseShape pbs, bool isphysical)
194 {
195 Vector3 pos = position;
196 //pos.X = position.X;
197 //pos.Y = position.Y;
198 //pos.Z = position.Z;
199 Vector3 siz = Vector3.Zero;
200 siz.X = size.X;
201 siz.Y = size.Y;
202 siz.Z = size.Z;
203 Quaternion rot = rotation;
204
205 BulletDotNETPrim newPrim;
206
207 newPrim = new BulletDotNETPrim(name, this, pos, siz, rot, mesh, pbs, isphysical);
208
209 //lock (m_prims)
210 // m_prims.Add(newPrim);
211
212
213 return newPrim;
214 }
215
216 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, Vector3 size, Quaternion rotation, bool isPhysical, uint localid)
217 {
218 PhysicsActor result;
219 IMesh mesh = null;
220
221 //switch (pbs.ProfileShape)
222 //{
223 // case ProfileShape.Square:
224 // //support simple box & hollow box now; later, more shapes
225 // if (needsMeshing(pbs))
226 // {
227 // mesh = mesher.CreateMesh(primName, pbs, size, 32f, isPhysical);
228 // }
229
230 // break;
231 //}
232
233 if (needsMeshing(pbs))
234 mesh = mesher.CreateMesh(primName, pbs, size, 32f, isPhysical);
235
236 result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical);
237
238 return result;
239 }
240
241 public override void AddPhysicsActorTaint(PhysicsActor prim)
242 {
243 lock (m_taintedActors)
244 {
245 if (!m_taintedActors.Contains(prim))
246 {
247 m_taintedActors.Add(prim);
248 }
249 }
250 }
251 internal void SetUsingGImpact()
252 {
253 if (!usingGImpactAlgorithm)
254 btGImpactCollisionAlgorithm.registerAlgorithm(m_dispatcher);
255 usingGImpactAlgorithm = true;
256 }
257
258 public override float Simulate(float timeStep)
259 {
260
261 lock (m_taintedActors)
262 {
263 foreach (PhysicsActor act in m_taintedActors)
264 {
265 if (act is BulletDotNETCharacter)
266 ((BulletDotNETCharacter) act).ProcessTaints(timeStep);
267 if (act is BulletDotNETPrim)
268 ((BulletDotNETPrim)act).ProcessTaints(timeStep);
269 }
270 m_taintedActors.Clear();
271 }
272
273 lock (m_characters)
274 {
275 foreach (BulletDotNETCharacter chr in m_characters)
276 {
277 chr.Move(timeStep);
278 }
279 }
280
281 lock (m_prims)
282 {
283 foreach (BulletDotNETPrim prim in m_prims)
284 {
285 if (prim != null)
286 prim.Move(timeStep);
287 }
288 }
289 float steps = m_world.stepSimulation(timeStep, 10, WorldTimeComp);
290
291 foreach (BulletDotNETCharacter chr in m_characters)
292 {
293 chr.UpdatePositionAndVelocity();
294 }
295
296 foreach (BulletDotNETPrim prm in m_activePrims)
297 {
298 /*
299 if (prm != null)
300 if (prm.Body != null)
301 */
302 prm.UpdatePositionAndVelocity();
303 }
304 if (m_CollisionInterface != null)
305 {
306 List<BulletDotNETPrim> primsWithCollisions = new List<BulletDotNETPrim>();
307 List<BulletDotNETCharacter> charactersWithCollisions = new List<BulletDotNETCharacter>();
308
309 // get the collisions that happened this tick
310 List<BulletDotNET.ContactAddedCallbackHandler.ContactInfo> collisions = m_CollisionInterface.GetContactList();
311 // passed back the localID of the prim so we can associate the prim
312 foreach (BulletDotNET.ContactAddedCallbackHandler.ContactInfo ci in collisions)
313 {
314 // ContactPoint = { contactPoint, contactNormal, penetrationDepth }
315 ContactPoint contact = new ContactPoint(new Vector3(ci.pX, ci.pY, ci.pZ),
316 new Vector3(ci.nX, ci.nY, ci.nZ), ci.depth);
317
318 ProcessContact(ci.contact, ci.contactWith, contact, ref primsWithCollisions, ref charactersWithCollisions);
319 ProcessContact(ci.contactWith, ci.contact, contact, ref primsWithCollisions, ref charactersWithCollisions);
320
321 }
322 m_CollisionInterface.Clear();
323 // for those prims and characters that had collisions cause collision events
324 foreach (BulletDotNETPrim bdnp in primsWithCollisions)
325 {
326 bdnp.SendCollisions();
327 }
328 foreach (BulletDotNETCharacter bdnc in charactersWithCollisions)
329 {
330 bdnc.SendCollisions();
331 }
332 }
333 return steps;
334 }
335
336 private void ProcessContact(uint cont, uint contWith, ContactPoint contact,
337 ref List<BulletDotNETPrim> primsWithCollisions,
338 ref List<BulletDotNETCharacter> charactersWithCollisions)
339 {
340 BulletDotNETPrim bdnp;
341 // collisions with a normal prim?
342 if (m_primsLocalID.TryGetValue(cont, out bdnp))
343 {
344 // Added collision event to the prim. This creates a pile of events
345 // that will be sent to any subscribed listeners.
346 bdnp.AddCollision(contWith, contact);
347 if (!primsWithCollisions.Contains(bdnp))
348 {
349 primsWithCollisions.Add(bdnp);
350 }
351 }
352 else
353 {
354 BulletDotNETCharacter bdnc;
355 // if not a prim, maybe it's one of the characters
356 if (m_charactersLocalID.TryGetValue(cont, out bdnc))
357 {
358 bdnc.AddCollision(contWith, contact);
359 if (!charactersWithCollisions.Contains(bdnc))
360 {
361 charactersWithCollisions.Add(bdnc);
362 }
363 }
364 }
365 }
366
367 public override void GetResults()
368 {
369
370 }
371
372 public override void SetTerrain(float[] heightMap)
373 {
374 if (m_terrainShape != null)
375 DeleteTerrain();
376
377 float hfmax = -9000;
378 float hfmin = 90000;
379
380 for (int i = 0; i <heightMap.Length;i++)
381 {
382 if (Single.IsNaN(heightMap[i]) || Single.IsInfinity(heightMap[i]))
383 {
384 heightMap[i] = 0f;
385 }
386
387 hfmin = (heightMap[i] < hfmin) ? heightMap[i] : hfmin;
388 hfmax = (heightMap[i] > hfmax) ? heightMap[i] : hfmax;
389 }
390 // store this for later reference.
391 // Note, we're storing it after we check it for anomolies above
392 _origheightmap = heightMap;
393
394 hfmin = 0;
395 hfmax = 256;
396
397 m_terrainShape = new btHeightfieldTerrainShape((int)Constants.RegionSize, (int)Constants.RegionSize, heightMap,
398 1.0f, hfmin, hfmax, (int)btHeightfieldTerrainShape.UPAxis.Z,
399 (int)btHeightfieldTerrainShape.PHY_ScalarType.PHY_FLOAT, false);
400 float AabbCenterX = Constants.RegionSize/2f;
401 float AabbCenterY = Constants.RegionSize/2f;
402
403 float AabbCenterZ = 0;
404 float temphfmin, temphfmax;
405
406 temphfmin = hfmin;
407 temphfmax = hfmax;
408
409 if (temphfmin < 0)
410 {
411 temphfmax = 0 - temphfmin;
412 temphfmin = 0 - temphfmin;
413 }
414 else if (temphfmin > 0)
415 {
416 temphfmax = temphfmax + (0 - temphfmin);
417 //temphfmin = temphfmin + (0 - temphfmin);
418 }
419 AabbCenterZ = temphfmax/2f;
420
421 if (m_terrainPosition == null)
422 {
423 m_terrainPosition = new btVector3(AabbCenterX, AabbCenterY, AabbCenterZ);
424 }
425 else
426 {
427 try
428 {
429 m_terrainPosition.setValue(AabbCenterX, AabbCenterY, AabbCenterZ);
430 }
431 catch (ObjectDisposedException)
432 {
433 m_terrainPosition = new btVector3(AabbCenterX, AabbCenterY, AabbCenterZ);
434 }
435 }
436 if (m_terrainMotionState != null)
437 {
438 m_terrainMotionState.Dispose();
439 m_terrainMotionState = null;
440 }
441 m_terrainTransform = new btTransform(QuatIdentity, m_terrainPosition);
442 m_terrainMotionState = new btDefaultMotionState(m_terrainTransform);
443 TerrainBody = new btRigidBody(0, m_terrainMotionState, m_terrainShape);
444 TerrainBody.setUserPointer((IntPtr)0);
445 m_world.addRigidBody(TerrainBody);
446
447
448 }
449
450 public override void SetWaterLevel(float baseheight)
451 {
452
453 }
454
455 public override void DeleteTerrain()
456 {
457 if (TerrainBody != null)
458 {
459 m_world.removeRigidBody(TerrainBody);
460 }
461
462 if (m_terrainShape != null)
463 {
464 m_terrainShape.Dispose();
465 m_terrainShape = null;
466 }
467
468 if (m_terrainMotionState != null)
469 {
470 m_terrainMotionState.Dispose();
471 m_terrainMotionState = null;
472 }
473
474 if (m_terrainTransform != null)
475 {
476 m_terrainTransform.Dispose();
477 m_terrainTransform = null;
478 }
479
480 if (m_terrainPosition != null)
481 {
482 m_terrainPosition.Dispose();
483 m_terrainPosition = null;
484 }
485 }
486
487 public override void Dispose()
488 {
489 disposeAllBodies();
490 m_world.Dispose();
491 m_broadphase.Dispose();
492 ((btDefaultCollisionConfiguration) m_collisionConfiguration).Dispose();
493 ((btSequentialImpulseConstraintSolver) m_solver).Dispose();
494 worldAabbMax.Dispose();
495 worldAabbMin.Dispose();
496 VectorZero.Dispose();
497 QuatIdentity.Dispose();
498 m_gravity.Dispose();
499 VectorZero = null;
500 QuatIdentity = null;
501 }
502
503 public override Dictionary<uint, float> GetTopColliders()
504 {
505 return new Dictionary<uint, float>();
506 }
507
508 public btDiscreteDynamicsWorld getBulletWorld()
509 {
510 return m_world;
511 }
512
513 private void disposeAllBodies()
514 {
515 lock (m_prims)
516 {
517 m_primsLocalID.Clear();
518 foreach (BulletDotNETPrim prim in m_prims)
519 {
520 if (prim.Body != null)
521 m_world.removeRigidBody(prim.Body);
522
523 prim.Dispose();
524 }
525 m_prims.Clear();
526
527 foreach (BulletDotNETCharacter chr in m_characters)
528 {
529 if (chr.Body != null)
530 m_world.removeRigidBody(chr.Body);
531 chr.Dispose();
532 }
533 m_characters.Clear();
534 }
535 }
536
537 public override bool IsThreaded
538 {
539 get { return false; }
540 }
541
542 internal void addCollisionEventReporting(PhysicsActor bulletDotNETCharacter)
543 {
544 //TODO: FIXME:
545 }
546
547 internal void remCollisionEventReporting(PhysicsActor bulletDotNETCharacter)
548 {
549 //TODO: FIXME:
550 }
551
552 internal void AddRigidBody(btRigidBody Body)
553 {
554 m_world.addRigidBody(Body);
555 }
556 [Obsolete("bad!")]
557 internal void removeFromWorld(btRigidBody body)
558 {
559
560 m_world.removeRigidBody(body);
561 }
562
563 internal void removeFromWorld(BulletDotNETPrim prm ,btRigidBody body)
564 {
565 lock (m_prims)
566 {
567 if (m_prims.Contains(prm))
568 {
569 m_world.removeRigidBody(body);
570 }
571 remActivePrim(prm);
572 m_primsLocalID.Remove(prm.m_localID);
573 m_prims.Remove(prm);
574 }
575
576 }
577
578 internal float GetWaterLevel()
579 {
580 throw new NotImplementedException();
581 }
582
583 // Recovered for use by fly height. Kitto Flora
584 public float GetTerrainHeightAtXY(float x, float y)
585 {
586 // Teravus: Kitto, this code causes recurring errors that stall physics permenantly unless
587 // the values are checked, so checking below.
588 // Is there any reason that we don't do this in ScenePresence?
589 // The only physics engine that benefits from it in the physics plugin is this one
590
591 if (x > (int)Constants.RegionSize || y > (int)Constants.RegionSize ||
592 x < 0.001f || y < 0.001f)
593 return 0;
594
595 return _origheightmap[(int)y * Constants.RegionSize + (int)x];
596 }
597 // End recovered. Kitto Flora
598
599 /// <summary>
600 /// Routine to figure out if we need to mesh this prim with our mesher
601 /// </summary>
602 /// <param name="pbs"></param>
603 /// <returns></returns>
604 public bool needsMeshing(PrimitiveBaseShape pbs)
605 {
606 // most of this is redundant now as the mesher will return null if it cant mesh a prim
607 // but we still need to check for sculptie meshing being enabled so this is the most
608 // convenient place to do it for now...
609
610 // //if (pbs.PathCurve == (byte)Primitive.PathCurve.Circle && pbs.ProfileCurve == (byte)Primitive.ProfileCurve.Circle && pbs.PathScaleY <= 0.75f)
611 // //m_log.Debug("needsMeshing: " + " pathCurve: " + pbs.PathCurve.ToString() + " profileCurve: " + pbs.ProfileCurve.ToString() + " pathScaleY: " + Primitive.UnpackPathScale(pbs.PathScaleY).ToString());
612 int iPropertiesNotSupportedDefault = 0;
613
614 if (pbs.SculptEntry && !meshSculptedPrim)
615 {
616#if SPAM
617 m_log.Warn("NonMesh");
618#endif
619 return false;
620 }
621
622 // if it's a standard box or sphere with no cuts, hollows, twist or top shear, return false since ODE can use an internal representation for the prim
623 if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight)
624 || (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1
625 && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z))
626 {
627
628 if (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0
629 && pbs.ProfileHollow == 0
630 && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0
631 && pbs.PathBegin == 0 && pbs.PathEnd == 0
632 && pbs.PathTaperX == 0 && pbs.PathTaperY == 0
633 && pbs.PathScaleX == 100 && pbs.PathScaleY == 100
634 && pbs.PathShearX == 0 && pbs.PathShearY == 0)
635 {
636#if SPAM
637 m_log.Warn("NonMesh");
638#endif
639 return false;
640 }
641 }
642
643 if (pbs.ProfileHollow != 0)
644 iPropertiesNotSupportedDefault++;
645
646 if ((pbs.PathBegin != 0) || pbs.PathEnd != 0)
647 iPropertiesNotSupportedDefault++;
648
649 if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0))
650 iPropertiesNotSupportedDefault++;
651
652 if ((pbs.ProfileBegin != 0) || pbs.ProfileEnd != 0)
653 iPropertiesNotSupportedDefault++;
654
655 if ((pbs.PathScaleX != 100) || (pbs.PathScaleY != 100))
656 iPropertiesNotSupportedDefault++;
657
658 if ((pbs.PathShearX != 0) || (pbs.PathShearY != 0))
659 iPropertiesNotSupportedDefault++;
660
661 if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight)
662 iPropertiesNotSupportedDefault++;
663
664 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))
665 iPropertiesNotSupportedDefault++;
666
667 if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1)
668 iPropertiesNotSupportedDefault++;
669
670 // test for torus
671 if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Square)
672 {
673 if (pbs.PathCurve == (byte)Extrusion.Curve1)
674 {
675 iPropertiesNotSupportedDefault++;
676 }
677 }
678 else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
679 {
680 if (pbs.PathCurve == (byte)Extrusion.Straight)
681 {
682 iPropertiesNotSupportedDefault++;
683 }
684
685 // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
686 else if (pbs.PathCurve == (byte)Extrusion.Curve1)
687 {
688 iPropertiesNotSupportedDefault++;
689 }
690 }
691 else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
692 {
693 if (pbs.PathCurve == (byte)Extrusion.Curve1 || pbs.PathCurve == (byte)Extrusion.Curve2)
694 {
695 iPropertiesNotSupportedDefault++;
696 }
697 }
698 else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
699 {
700 if (pbs.PathCurve == (byte)Extrusion.Straight)
701 {
702 iPropertiesNotSupportedDefault++;
703 }
704 else if (pbs.PathCurve == (byte)Extrusion.Curve1)
705 {
706 iPropertiesNotSupportedDefault++;
707 }
708 }
709
710
711 if (iPropertiesNotSupportedDefault == 0)
712 {
713#if SPAM
714 m_log.Warn("NonMesh");
715#endif
716 return false;
717 }
718#if SPAM
719 m_log.Debug("Mesh");
720#endif
721 return true;
722 }
723
724 internal void addActivePrim(BulletDotNETPrim pPrim)
725 {
726 lock (m_activePrims)
727 {
728 if (!m_activePrims.Contains(pPrim))
729 {
730 m_activePrims.Add(pPrim);
731 }
732 }
733 }
734
735 public void remActivePrim(BulletDotNETPrim pDeactivatePrim)
736 {
737 lock (m_activePrims)
738 {
739 m_activePrims.Remove(pDeactivatePrim);
740 }
741 }
742
743 internal void AddPrimToScene(BulletDotNETPrim pPrim)
744 {
745 lock (m_prims)
746 {
747 if (!m_prims.Contains(pPrim))
748 {
749 try
750 {
751 m_prims.Add(pPrim);
752 m_primsLocalID.Add(pPrim.m_localID, pPrim);
753 }
754 catch
755 {
756 // noop if it's already there
757 m_log.Debug("[PHYSICS] BulletDotNet: adding duplicate prim localID");
758 }
759 m_world.addRigidBody(pPrim.Body);
760 // m_log.Debug("[PHYSICS] added prim to scene");
761 }
762 }
763 }
764 internal void EnableCollisionInterface()
765 {
766 if (m_CollisionInterface == null)
767 {
768 m_CollisionInterface = new ContactAddedCallbackHandler(m_world);
769 // m_world.SetCollisionAddedCallback(m_CollisionInterface);
770 }
771 }
772
773
774
775 }
776}
diff --git a/OpenSim/Region/Physics/BulletXPlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/BulletXPlugin/AssemblyInfo.cs
deleted file mode 100644
index 6383f26..0000000
--- a/OpenSim/Region/Physics/BulletXPlugin/AssemblyInfo.cs
+++ /dev/null
@@ -1,58 +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.Reflection;
29using System.Runtime.InteropServices;
30
31// Information about this assembly is defined by the following
32// attributes.
33//
34// change them to the information which is associated with the assembly
35// you compile.
36
37[assembly : AssemblyTitle("BulletXPlugin")]
38[assembly : AssemblyDescription("")]
39[assembly : AssemblyConfiguration("")]
40[assembly : AssemblyCompany("http://opensimulator.org")]
41[assembly : AssemblyProduct("BulletXPlugin")]
42[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")]
43[assembly : AssemblyTrademark("")]
44[assembly : AssemblyCulture("")]
45
46// This sets the default COM visibility of types in the assembly to invisible.
47// If you need to expose a type to COM, use [ComVisible(true)] on that type.
48
49[assembly : ComVisible(false)]
50
51// The assembly version has following format :
52//
53// Major.Minor.Build.Revision
54//
55// You can specify all values by your own or you can build default build and revision
56// numbers with the '*' character (the default):
57
58[assembly : AssemblyVersion("0.6.5.*")]
diff --git a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
deleted file mode 100644
index 8e9edac..0000000
--- a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
+++ /dev/null
@@ -1,1855 +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
28#region References
29
30using System;
31using System.Collections.Generic;
32using OpenMetaverse;
33using MonoXnaCompactMaths;
34using OpenSim.Framework;
35using OpenSim.Region.Physics.Manager;
36using XnaDevRu.BulletX;
37using XnaDevRu.BulletX.Dynamics;
38using Nini.Config;
39using Vector3 = MonoXnaCompactMaths.Vector3;
40using Quaternion = MonoXnaCompactMaths.Quaternion;
41
42#endregion
43
44namespace OpenSim.Region.Physics.BulletXPlugin
45{
46 /// <summary>
47 /// BulletXConversions are called now BulletXMaths
48 /// This Class converts objects and types for BulletX and give some operations
49 /// </summary>
50 public class BulletXMaths
51 {
52 //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
53
54 //Vector3
55 public static Vector3 PhysicsVectorToXnaVector3(OpenMetaverse.Vector3 physicsVector)
56 {
57 return new Vector3(physicsVector.X, physicsVector.Y, physicsVector.Z);
58 }
59
60 public static OpenMetaverse.Vector3 XnaVector3ToPhysicsVector(Vector3 xnaVector3)
61 {
62 return new OpenMetaverse.Vector3(xnaVector3.X, xnaVector3.Y, xnaVector3.Z);
63 }
64
65 //Quaternion
66 public static Quaternion QuaternionToXnaQuaternion(OpenMetaverse.Quaternion quaternion)
67 {
68 return new Quaternion(quaternion.X, quaternion.Y, quaternion.Z, quaternion.W);
69 }
70
71 public static OpenMetaverse.Quaternion XnaQuaternionToQuaternion(Quaternion xnaQuaternion)
72 {
73 return new OpenMetaverse.Quaternion(xnaQuaternion.W, xnaQuaternion.X, xnaQuaternion.Y, xnaQuaternion.Z);
74 }
75
76 //Next methods are extracted from XnaDevRu.BulletX(See 3rd party license):
77 //- SetRotation (class MatrixOperations)
78 //- GetRotation (class MatrixOperations)
79 //- GetElement (class MathHelper)
80 //- SetElement (class MathHelper)
81 internal static void SetRotation(ref Matrix m, Quaternion q)
82 {
83 float d = q.LengthSquared();
84 float s = 2f/d;
85 float xs = q.X*s, ys = q.Y*s, zs = q.Z*s;
86 float wx = q.W*xs, wy = q.W*ys, wz = q.W*zs;
87 float xx = q.X*xs, xy = q.X*ys, xz = q.X*zs;
88 float yy = q.Y*ys, yz = q.Y*zs, zz = q.Z*zs;
89 m = new Matrix(1 - (yy + zz), xy - wz, xz + wy, 0,
90 xy + wz, 1 - (xx + zz), yz - wx, 0,
91 xz - wy, yz + wx, 1 - (xx + yy), 0,
92 m.M41, m.M42, m.M43, 1);
93 }
94
95 internal static Quaternion GetRotation(Matrix m)
96 {
97 Quaternion q;
98
99 float trace = m.M11 + m.M22 + m.M33;
100
101 if (trace > 0)
102 {
103 float s = (float) Math.Sqrt(trace + 1);
104 q.W = s*0.5f;
105 s = 0.5f/s;
106
107 q.X = (m.M32 - m.M23)*s;
108 q.Y = (m.M13 - m.M31)*s;
109 q.Z = (m.M21 - m.M12)*s;
110 }
111 else
112 {
113 q.X = q.Y = q.Z = q.W = 0f;
114
115 int i = m.M11 < m.M22
116 ?
117 (m.M22 < m.M33 ? 2 : 1)
118 :
119 (m.M11 < m.M33 ? 2 : 0);
120 int j = (i + 1)%3;
121 int k = (i + 2)%3;
122
123 float s = (float) Math.Sqrt(GetElement(m, i, i) - GetElement(m, j, j) - GetElement(m, k, k) + 1);
124 SetElement(ref q, i, s*0.5f);
125 s = 0.5f/s;
126
127 q.W = (GetElement(m, k, j) - GetElement(m, j, k))*s;
128 SetElement(ref q, j, (GetElement(m, j, i) + GetElement(m, i, j))*s);
129 SetElement(ref q, k, (GetElement(m, k, i) + GetElement(m, i, k))*s);
130 }
131
132 return q;
133 }
134
135 internal static float SetElement(ref Quaternion q, int index, float value)
136 {
137 switch (index)
138 {
139 case 0:
140 q.X = value;
141 break;
142 case 1:
143 q.Y = value;
144 break;
145 case 2:
146 q.Z = value;
147 break;
148 case 3:
149 q.W = value;
150 break;
151 }
152
153 return 0;
154 }
155
156 internal static float GetElement(Matrix mat, int row, int col)
157 {
158 switch (row)
159 {
160 case 0:
161 switch (col)
162 {
163 case 0:
164 return mat.M11;
165 case 1:
166 return mat.M12;
167 case 2:
168 return mat.M13;
169 }
170 break;
171 case 1:
172 switch (col)
173 {
174 case 0:
175 return mat.M21;
176 case 1:
177 return mat.M22;
178 case 2:
179 return mat.M23;
180 }
181 break;
182 case 2:
183 switch (col)
184 {
185 case 0:
186 return mat.M31;
187 case 1:
188 return mat.M32;
189 case 2:
190 return mat.M33;
191 }
192 break;
193 }
194
195 return 0;
196 }
197 }
198
199 /// <summary>
200 /// PhysicsPlugin Class for BulletX
201 /// </summary>
202 public class BulletXPlugin : IPhysicsPlugin
203 {
204 private BulletXScene _mScene;
205
206 public BulletXPlugin()
207 {
208 }
209
210 public bool Init()
211 {
212 return true;
213 }
214
215 public PhysicsScene GetScene(string sceneIdentifier)
216 {
217 if (_mScene == null)
218 {
219 _mScene = new BulletXScene(sceneIdentifier);
220 }
221 return (_mScene);
222 }
223
224 public string GetName()
225 {
226 return ("modified_BulletX"); //Changed!! "BulletXEngine" To "modified_BulletX"
227 }
228
229 public void Dispose()
230 {
231 }
232 }
233
234
235 // Class to detect and debug collisions
236 // Mainly used for debugging purposes
237 internal class CollisionDispatcherLocal : CollisionDispatcher
238 {
239 private BulletXScene relatedScene;
240
241 public CollisionDispatcherLocal(BulletXScene s)
242 : base()
243 {
244 relatedScene = s;
245 }
246
247 public override bool NeedsCollision(CollisionObject bodyA, CollisionObject bodyB)
248 {
249 RigidBody rb;
250 BulletXCharacter bxcA = null;
251 BulletXPrim bxpA = null;
252 Type t = bodyA.GetType();
253 if (t == typeof (RigidBody))
254 {
255 rb = (RigidBody) bodyA;
256 relatedScene._characters.TryGetValue(rb, out bxcA);
257 relatedScene._prims.TryGetValue(rb, out bxpA);
258 }
259// String nameA;
260// if (bxcA != null)
261// nameA = bxcA._name;
262// else if (bxpA != null)
263// nameA = bxpA._name;
264// else
265// nameA = "null";
266
267
268
269 BulletXCharacter bxcB = null;
270 BulletXPrim bxpB = null;
271 t = bodyB.GetType();
272 if (t == typeof (RigidBody))
273 {
274 rb = (RigidBody) bodyB;
275 relatedScene._characters.TryGetValue(rb, out bxcB);
276 relatedScene._prims.TryGetValue(rb, out bxpB);
277 }
278
279// String nameB;
280// if (bxcB != null)
281// nameB = bxcB._name;
282// else if (bxpB != null)
283// nameB = bxpB._name;
284// else
285 // nameB = "null";
286 bool needsCollision;// = base.NeedsCollision(bodyA, bodyB);
287 int c1 = 3;
288 int c2 = 3;
289
290 ////////////////////////////////////////////////////////
291 //BulletX Mesh Collisions
292 //added by Jed zhu
293 //data: May 07,2005
294 ////////////////////////////////////////////////////////
295 #region BulletXMeshCollisions Fields
296
297
298 if (bxcA != null && bxpB != null)
299 c1 = Collision(bxcA, bxpB);
300 if (bxpA != null && bxcB != null)
301 c2 = Collision(bxcB, bxpA);
302 if (c1 < 2)
303 needsCollision = (c1 > 0) ? true : false;
304 else if (c2 < 2)
305 needsCollision = (c2 > 0) ? true : false;
306 else
307 needsCollision = base.NeedsCollision(bodyA, bodyB);
308
309
310 #endregion
311
312
313 //m_log.DebugFormat("[BulletX]: A collision was detected between {0} and {1} --> {2}", nameA, nameB,
314 //needsCollision);
315
316
317 return needsCollision;
318 }
319 //added by jed zhu
320 //calculas the collision between the Prim and Actor
321 //
322 private int Collision(BulletXCharacter actorA, BulletXPrim primB)
323 {
324 int[] indexBase;
325 Vector3[] vertexBase;
326 Vector3 vNormal;
327 // Vector3 vP1;
328 // Vector3 vP2;
329 // Vector3 vP3;
330 IMesh mesh = primB.GetMesh();
331
332 float fdistance;
333 if (primB == null)
334 return 3;
335 if (mesh == null)
336 return 2;
337 if (actorA == null)
338 return 3;
339
340 int iVertexCount = mesh.getVertexList().Count;
341 int iIndexCount = mesh.getIndexListAsInt().Length;
342 if (iVertexCount == 0)
343 return 3;
344 if (iIndexCount == 0)
345 return 3;
346 lock (BulletXScene.BulletXLock)
347 {
348 indexBase = mesh.getIndexListAsInt();
349 vertexBase = new Vector3[iVertexCount];
350
351 for (int i = 0; i < iVertexCount; i++)
352 {
353 OpenMetaverse.Vector3 v = mesh.getVertexList()[i];
354 if (v != null) // Note, null has special meaning. See meshing code for details
355 vertexBase[i] = BulletXMaths.PhysicsVectorToXnaVector3(v);
356 else
357 vertexBase[i] = Vector3.Zero;
358 }
359
360 for (int ix = 0; ix < iIndexCount; ix += 3)
361 {
362 int ia = indexBase[ix + 0];
363 int ib = indexBase[ix + 1];
364 int ic = indexBase[ix + 2];
365 //
366 Vector3 v1 = vertexBase[ib] - vertexBase[ia];
367 Vector3 v2 = vertexBase[ic] - vertexBase[ia];
368
369 Vector3.Cross(ref v1, ref v2, out vNormal);
370 Vector3.Normalize(ref vNormal, out vNormal);
371
372 fdistance = Vector3.Dot(vNormal, vertexBase[ia]) + 0.50f;
373 if (preCheckCollision(actorA, vNormal, fdistance) == 1)
374 {
375 if (CheckCollision(actorA, ia, ib, ic, vNormal, vertexBase) == 1)
376 {
377 //PhysicsVector v = actorA.Position;
378 //Vector3 v3 = BulletXMaths.PhysicsVectorToXnaVector3(v);
379 //Vector3 vp = vNormal * (fdistance - Vector3.Dot(vNormal, v3) + 0.2f);
380 //actorA.Position += BulletXMaths.XnaVector3ToPhysicsVector(vp);
381 return 1;
382 }
383 }
384 }
385 }
386
387
388 return 0;
389 }
390 //added by jed zhu
391 //return value 1: need second check
392 //return value 0: no need check
393
394 private int preCheckCollision(BulletXActor actA, Vector3 vNormal, float fDist)
395 {
396 float fstartSide;
397 OpenMetaverse.Vector3 v = actA.Position;
398 Vector3 v3 = BulletXMaths.PhysicsVectorToXnaVector3(v);
399
400 fstartSide = Vector3.Dot(vNormal, v3) - fDist;
401 if (fstartSide > 0) return 0;
402 else return 1;
403 }
404 //added by jed zhu
405 private int CheckCollision(BulletXActor actA, int ia, int ib, int ic, Vector3 vNormal, Vector3[] vertBase)
406 {
407 Vector3 perPlaneNormal;
408 float fPerPlaneDist;
409 OpenMetaverse.Vector3 v = actA.Position;
410 Vector3 v3 = BulletXMaths.PhysicsVectorToXnaVector3(v);
411 //check AB
412 Vector3 v1;
413 v1 = vertBase[ib] - vertBase[ia];
414 Vector3.Cross(ref vNormal, ref v1, out perPlaneNormal);
415 Vector3.Normalize(ref perPlaneNormal, out perPlaneNormal);
416
417 if (Vector3.Dot((vertBase[ic] - vertBase[ia]), perPlaneNormal) < 0)
418 perPlaneNormal = -perPlaneNormal;
419 fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ia]) - 0.50f;
420
421
422
423 if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) < 0)
424 return 0;
425 fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ic]) + 0.50f;
426 if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) > 0)
427 return 0;
428
429 //check BC
430
431 v1 = vertBase[ic] - vertBase[ib];
432 Vector3.Cross(ref vNormal, ref v1, out perPlaneNormal);
433 Vector3.Normalize(ref perPlaneNormal, out perPlaneNormal);
434
435 if (Vector3.Dot((vertBase[ia] - vertBase[ib]), perPlaneNormal) < 0)
436 perPlaneNormal = -perPlaneNormal;
437 fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ib]) - 0.50f;
438
439
440 if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) < 0)
441 return 0;
442 fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ia]) + 0.50f;
443 if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) > 0)
444 return 0;
445 //check CA
446 v1 = vertBase[ia] - vertBase[ic];
447 Vector3.Cross(ref vNormal, ref v1, out perPlaneNormal);
448 Vector3.Normalize(ref perPlaneNormal, out perPlaneNormal);
449
450 if (Vector3.Dot((vertBase[ib] - vertBase[ic]), perPlaneNormal) < 0)
451 perPlaneNormal = -perPlaneNormal;
452 fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ic]) - 0.50f;
453
454
455 if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) < 0)
456 return 0;
457 fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ib]) + 0.50f;
458 if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) > 0)
459 return 0;
460
461 return 1;
462
463 }
464 }
465
466 /// <summary>
467 /// PhysicsScene Class for BulletX
468 /// </summary>
469 public class BulletXScene : PhysicsScene
470 {
471 #region BulletXScene Fields
472
473 public DiscreteDynamicsWorld ddWorld;
474 private CollisionDispatcher cDispatcher;
475 private OverlappingPairCache opCache;
476 private SequentialImpulseConstraintSolver sicSolver;
477 public static Object BulletXLock = new Object();
478
479 private const int minXY = 0;
480 private const int minZ = 0;
481 private const int maxXY = (int)Constants.RegionSize;
482 private const int maxZ = 4096;
483 private const int maxHandles = 32766; //Why? I don't know
484 private const float gravity = 9.8f;
485 private const float heightLevel0 = 77.0f;
486 private const float heightLevel1 = 200.0f;
487 private const float lowGravityFactor = 0.2f;
488 //OpenSim calls Simulate 10 times per seconds. So FPS = "Simulate Calls" * simulationSubSteps = 100 FPS
489 private const int simulationSubSteps = 10;
490 //private float[] _heightmap;
491 private BulletXPlanet _simFlatPlanet;
492 internal Dictionary<RigidBody, BulletXCharacter> _characters = new Dictionary<RigidBody, BulletXCharacter>();
493 internal Dictionary<RigidBody, BulletXPrim> _prims = new Dictionary<RigidBody, BulletXPrim>();
494
495 public IMesher mesher;
496 // private IConfigSource m_config;
497
498 // protected internal String identifier;
499
500 public BulletXScene(String sceneIdentifier)
501 {
502 //identifier = sceneIdentifier;
503 cDispatcher = new CollisionDispatcherLocal(this);
504 Vector3 worldMinDim = new Vector3((float)minXY, (float)minXY, (float)minZ);
505 Vector3 worldMaxDim = new Vector3((float)maxXY, (float)maxXY, (float)maxZ);
506 opCache = new AxisSweep3(worldMinDim, worldMaxDim, maxHandles);
507 sicSolver = new SequentialImpulseConstraintSolver();
508
509 lock (BulletXLock)
510 {
511 ddWorld = new DiscreteDynamicsWorld(cDispatcher, opCache, sicSolver);
512 ddWorld.Gravity = new Vector3(0, 0, -gravity);
513 }
514 //this._heightmap = new float[65536];
515 }
516
517 public static float Gravity
518 {
519 get { return gravity; }
520 }
521
522 public static float HeightLevel0
523 {
524 get { return heightLevel0; }
525 }
526
527 public static float HeightLevel1
528 {
529 get { return heightLevel1; }
530 }
531
532 public static float LowGravityFactor
533 {
534 get { return lowGravityFactor; }
535 }
536
537 public static int MaxXY
538 {
539 get { return maxXY; }
540 }
541
542 public static int MaxZ
543 {
544 get { return maxZ; }
545 }
546
547 private List<RigidBody> _forgottenRigidBodies = new List<RigidBody>();
548 internal string is_ex_message = "Can't remove rigidBody!: ";
549
550 #endregion
551
552 public BulletXScene()
553 {
554 cDispatcher = new CollisionDispatcherLocal(this);
555 Vector3 worldMinDim = new Vector3((float) minXY, (float) minXY, (float) minZ);
556 Vector3 worldMaxDim = new Vector3((float) maxXY, (float) maxXY, (float) maxZ);
557 opCache = new AxisSweep3(worldMinDim, worldMaxDim, maxHandles);
558 sicSolver = new SequentialImpulseConstraintSolver();
559
560 lock (BulletXLock)
561 {
562 ddWorld = new DiscreteDynamicsWorld(cDispatcher, opCache, sicSolver);
563 ddWorld.Gravity = new Vector3(0, 0, -gravity);
564 }
565 //this._heightmap = new float[65536];
566 }
567
568 public override void Initialise(IMesher meshmerizer, IConfigSource config)
569 {
570 mesher = meshmerizer;
571 // m_config = config;
572 }
573
574 public override void Dispose()
575 {
576
577 }
578
579 public override Dictionary<uint, float> GetTopColliders()
580 {
581 Dictionary<uint, float> returncolliders = new Dictionary<uint, float>();
582 return returncolliders;
583 }
584
585 public override void SetWaterLevel(float baseheight)
586 {
587
588 }
589
590 public override PhysicsActor AddAvatar(string avName, OpenMetaverse.Vector3 position, OpenMetaverse.Vector3 size, bool isFlying)
591 {
592 OpenMetaverse.Vector3 pos = OpenMetaverse.Vector3.Zero;
593 pos.X = position.X;
594 pos.Y = position.Y;
595 pos.Z = position.Z + 20;
596 BulletXCharacter newAv = null;
597 lock (BulletXLock)
598 {
599 newAv = new BulletXCharacter(avName, this, pos);
600 _characters.Add(newAv.RigidBody, newAv);
601 }
602 newAv.Flying = isFlying;
603 return newAv;
604 }
605
606 public override void RemoveAvatar(PhysicsActor actor)
607 {
608 if (actor is BulletXCharacter)
609 {
610 lock (BulletXLock)
611 {
612 try
613 {
614 ddWorld.RemoveRigidBody(((BulletXCharacter) actor).RigidBody);
615 }
616 catch (Exception ex)
617 {
618 BulletXMessage(is_ex_message + ex.Message, true);
619 ((BulletXCharacter) actor).RigidBody.ActivationState = ActivationState.DisableSimulation;
620 AddForgottenRigidBody(((BulletXCharacter) actor).RigidBody);
621 }
622 _characters.Remove(((BulletXCharacter) actor).RigidBody);
623 }
624 GC.Collect();
625 }
626 }
627
628 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, OpenMetaverse.Vector3 position,
629 OpenMetaverse.Vector3 size, OpenMetaverse.Quaternion rotation, bool isPhysical, uint localid)
630 {
631 PhysicsActor result;
632
633 switch (pbs.ProfileShape)
634 {
635 case ProfileShape.Square:
636 /// support simple box & hollow box now; later, more shapes
637 if (pbs.ProfileHollow == 0)
638 {
639 result = AddPrim(primName, position, size, rotation, null, null, isPhysical);
640 }
641 else
642 {
643 IMesh mesh = mesher.CreateMesh(primName, pbs, size, 32f, isPhysical);
644 result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical);
645 }
646 break;
647
648 default:
649 result = AddPrim(primName, position, size, rotation, null, null, isPhysical);
650 break;
651 }
652
653 return result;
654 }
655
656 public PhysicsActor AddPrim(String name, OpenMetaverse.Vector3 position, OpenMetaverse.Vector3 size, OpenMetaverse.Quaternion rotation,
657 IMesh mesh, PrimitiveBaseShape pbs, bool isPhysical)
658 {
659 BulletXPrim newPrim = null;
660 lock (BulletXLock)
661 {
662 newPrim = new BulletXPrim(name, this, position, size, rotation, mesh, pbs, isPhysical);
663 _prims.Add(newPrim.RigidBody, newPrim);
664 }
665 return newPrim;
666 }
667
668 public override void RemovePrim(PhysicsActor prim)
669 {
670 if (prim is BulletXPrim)
671 {
672 lock (BulletXLock)
673 {
674 try
675 {
676 ddWorld.RemoveRigidBody(((BulletXPrim) prim).RigidBody);
677 }
678 catch (Exception ex)
679 {
680 BulletXMessage(is_ex_message + ex.Message, true);
681 ((BulletXPrim) prim).RigidBody.ActivationState = ActivationState.DisableSimulation;
682 AddForgottenRigidBody(((BulletXPrim) prim).RigidBody);
683 }
684 _prims.Remove(((BulletXPrim) prim).RigidBody);
685 }
686 GC.Collect();
687 }
688 }
689
690 public override void AddPhysicsActorTaint(PhysicsActor prim)
691 {
692 }
693
694 public override float Simulate(float timeStep)
695 {
696 float fps = 0;
697 lock (BulletXLock)
698 {
699 //Try to remove garbage
700 RemoveForgottenRigidBodies();
701 //End of remove
702 MoveAPrimitives(timeStep);
703
704
705 fps = (timeStep*simulationSubSteps);
706
707 ddWorld.StepSimulation(timeStep, simulationSubSteps, timeStep);
708 //Extra Heightmap Validation: BulletX's HeightFieldTerrain somestimes doesn't work so fine.
709 ValidateHeightForAll();
710 //End heightmap validation.
711 UpdateKineticsForAll();
712 }
713 return fps;
714 }
715
716 private void MoveAPrimitives(float timeStep)
717 {
718 foreach (BulletXCharacter actor in _characters.Values)
719 {
720 actor.Move(timeStep);
721 }
722 }
723
724 private void ValidateHeightForAll()
725 {
726 float _height;
727 foreach (BulletXCharacter actor in _characters.Values)
728 {
729 //_height = HeightValue(actor.RigidBodyPosition);
730 _height = _simFlatPlanet.HeightValue(actor.RigidBodyPosition);
731 actor.ValidateHeight(_height);
732 //if (_simFlatPlanet.heightIsNotValid(actor.RigidBodyPosition, out _height)) actor.ValidateHeight(_height);
733 }
734 foreach (BulletXPrim prim in _prims.Values)
735 {
736 //_height = HeightValue(prim.RigidBodyPosition);
737 _height = _simFlatPlanet.HeightValue(prim.RigidBodyPosition);
738 prim.ValidateHeight(_height);
739 //if (_simFlatPlanet.heightIsNotValid(prim.RigidBodyPosition, out _height)) prim.ValidateHeight(_height);
740 }
741 //foreach (BulletXCharacter actor in _characters)
742 //{
743 // actor.ValidateHeight(0);
744 //}
745 //foreach (BulletXPrim prim in _prims)
746 //{
747 // prim.ValidateHeight(0);
748 //}
749 }
750
751 private void UpdateKineticsForAll()
752 {
753 //UpdatePosition > UpdateKinetics.
754 //Not only position will be updated, also velocity cause acceleration.
755 foreach (BulletXCharacter actor in _characters.Values)
756 {
757 actor.UpdateKinetics();
758 }
759 foreach (BulletXPrim prim in _prims.Values)
760 {
761 prim.UpdateKinetics();
762 }
763 //if (this._simFlatPlanet!=null) this._simFlatPlanet.Restore();
764 }
765
766 public override void GetResults()
767 {
768 }
769
770 public override bool IsThreaded
771 {
772 get
773 {
774 return (false); // for now we won't be multithreaded
775 }
776 }
777
778 public override void SetTerrain(float[] heightMap)
779 {
780 ////As the same as ODE, heightmap (x,y) must be swapped for BulletX
781 //for (int i = 0; i < 65536; i++)
782 //{
783 // // this._heightmap[i] = (double)heightMap[i];
784 // // dbm (danx0r) -- heightmap x,y must be swapped for Ode (should fix ODE, but for now...)
785 // int x = i & 0xff;
786 // int y = i >> 8;
787 // this._heightmap[i] = heightMap[x * 256 + y];
788 //}
789
790 //float[] swappedHeightMap = new float[65536];
791 ////As the same as ODE, heightmap (x,y) must be swapped for BulletX
792 //for (int i = 0; i < 65536; i++)
793 //{
794 // // this._heightmap[i] = (double)heightMap[i];
795 // // dbm (danx0r) -- heightmap x,y must be swapped for Ode (should fix ODE, but for now...)
796 // int x = i & 0xff;
797 // int y = i >> 8;
798 // swappedHeightMap[i] = heightMap[x * 256 + y];
799 //}
800 DeleteTerrain();
801 //There is a BulletXLock inside the constructor of BulletXPlanet
802 //this._simFlatPlanet = new BulletXPlanet(this, swappedHeightMap);
803 _simFlatPlanet = new BulletXPlanet(this, heightMap);
804 //this._heightmap = heightMap;
805 }
806
807 public override void DeleteTerrain()
808 {
809 if (_simFlatPlanet != null)
810 {
811 lock (BulletXLock)
812 {
813 try
814 {
815 ddWorld.RemoveRigidBody(_simFlatPlanet.RigidBody);
816 }
817 catch (Exception ex)
818 {
819 BulletXMessage(is_ex_message + ex.Message, true);
820 _simFlatPlanet.RigidBody.ActivationState = ActivationState.DisableSimulation;
821 AddForgottenRigidBody(_simFlatPlanet.RigidBody);
822 }
823 }
824 _simFlatPlanet = null;
825 GC.Collect();
826 BulletXMessage("Terrain erased!", false);
827 }
828
829
830
831 //this._heightmap = null;
832 }
833
834
835
836 internal void AddForgottenRigidBody(RigidBody forgottenRigidBody)
837 {
838 _forgottenRigidBodies.Add(forgottenRigidBody);
839 }
840
841 private void RemoveForgottenRigidBodies()
842 {
843 RigidBody forgottenRigidBody;
844 int nRigidBodies = _forgottenRigidBodies.Count;
845 for (int i = nRigidBodies - 1; i >= 0; i--)
846 {
847 forgottenRigidBody = _forgottenRigidBodies[i];
848 try
849 {
850 ddWorld.RemoveRigidBody(forgottenRigidBody);
851 _forgottenRigidBodies.Remove(forgottenRigidBody);
852 BulletXMessage("Forgotten Rigid Body Removed", false);
853 }
854 catch (Exception ex)
855 {
856 BulletXMessage("Can't remove forgottenRigidBody!: " + ex.Message, false);
857 }
858 }
859 GC.Collect();
860 }
861
862 internal static void BulletXMessage(string message, bool isWarning)
863 {
864 PhysicsPluginManager.PhysicsPluginMessage("[Modified BulletX]:\t" + message, isWarning);
865 }
866
867 //temp
868 //private float HeightValue(MonoXnaCompactMaths.Vector3 position)
869 //{
870 // int li_x, li_y;
871 // float height;
872 // li_x = (int)Math.Round(position.X); if (li_x < 0) li_x = 0;
873 // li_y = (int)Math.Round(position.Y); if (li_y < 0) li_y = 0;
874
875 // height = this._heightmap[li_y * 256 + li_x];
876 // if (height < 0) height = 0;
877 // else if (height > maxZ) height = maxZ;
878
879 // return height;
880 //}
881 }
882
883 /// <summary>
884 /// Generic Physics Actor for BulletX inherit from PhysicActor
885 /// </summary>
886 public class BulletXActor : PhysicsActor
887 {
888 protected bool flying = false;
889 protected bool _physical = false;
890 protected OpenMetaverse.Vector3 _position;
891 protected OpenMetaverse.Vector3 _velocity;
892 protected OpenMetaverse.Vector3 _size;
893 protected OpenMetaverse.Vector3 _acceleration;
894 protected OpenMetaverse.Quaternion _orientation;
895 protected OpenMetaverse.Vector3 m_rotationalVelocity;
896 protected RigidBody rigidBody;
897 protected int m_PhysicsActorType;
898 private Boolean iscolliding = false;
899 internal string _name;
900
901 public BulletXActor(String name)
902 {
903 _name = name;
904 }
905
906 public override bool Stopped
907 {
908 get { return false; }
909 }
910
911 public override OpenMetaverse.Vector3 Position
912 {
913 get { return _position; }
914 set
915 {
916 lock (BulletXScene.BulletXLock)
917 {
918 _position = value;
919 Translate();
920 }
921 }
922 }
923
924 public override OpenMetaverse.Vector3 RotationalVelocity
925 {
926 get { return m_rotationalVelocity; }
927 set { m_rotationalVelocity = value; }
928 }
929
930 public override OpenMetaverse.Vector3 Velocity
931 {
932 get { return _velocity; }
933 set
934 {
935 lock (BulletXScene.BulletXLock)
936 {
937 //Static objects don' have linear velocity
938 if (_physical)
939 {
940 _velocity = value;
941 Speed();
942 }
943 else
944 {
945 _velocity = OpenMetaverse.Vector3.Zero;
946 }
947 }
948 }
949 }
950 public override float CollisionScore
951 {
952 get { return 0f; }
953 set { }
954 }
955 public override OpenMetaverse.Vector3 Size
956 {
957 get { return _size; }
958 set
959 {
960 lock (BulletXScene.BulletXLock)
961 {
962 _size = value;
963 }
964 }
965 }
966
967 public override OpenMetaverse.Vector3 Force
968 {
969 get { return OpenMetaverse.Vector3.Zero; }
970 set { return; }
971 }
972
973 public override int VehicleType
974 {
975 get { return 0; }
976 set { return; }
977 }
978
979 public override void VehicleFloatParam(int param, float value)
980 {
981
982 }
983
984 public override void VehicleVectorParam(int param, OpenMetaverse.Vector3 value)
985 {
986
987 }
988
989 public override void VehicleRotationParam(int param, OpenMetaverse.Quaternion rotation)
990 {
991
992 }
993
994 public override void VehicleFlags(int param, bool remove)
995 {
996
997 }
998
999 public override void SetVolumeDetect(int param)
1000 {
1001
1002 }
1003
1004 public override OpenMetaverse.Vector3 CenterOfMass
1005 {
1006 get { return OpenMetaverse.Vector3.Zero; }
1007 }
1008
1009 public override OpenMetaverse.Vector3 GeometricCenter
1010 {
1011 get { return OpenMetaverse.Vector3.Zero; }
1012 }
1013
1014 public override PrimitiveBaseShape Shape
1015 {
1016 set { return; }
1017 }
1018
1019 public override bool SetAlwaysRun
1020 {
1021 get { return false; }
1022 set { return; }
1023 }
1024
1025 public override OpenMetaverse.Vector3 Acceleration
1026 {
1027 get { return _acceleration; }
1028 }
1029
1030 public override OpenMetaverse.Quaternion Orientation
1031 {
1032 get { return _orientation; }
1033 set
1034 {
1035 lock (BulletXScene.BulletXLock)
1036 {
1037 _orientation = value;
1038 ReOrient();
1039 }
1040 }
1041 }
1042 public override void link(PhysicsActor obj)
1043 {
1044
1045 }
1046
1047 public override void delink()
1048 {
1049
1050 }
1051
1052 public override void LockAngularMotion(OpenMetaverse.Vector3 axis)
1053 {
1054
1055 }
1056
1057 public override float Mass
1058 {
1059 get { return ActorMass; }
1060 }
1061
1062 public virtual float ActorMass
1063 {
1064 get { return 0; }
1065 }
1066
1067 public override int PhysicsActorType
1068 {
1069 get { return (int) m_PhysicsActorType; }
1070 set { m_PhysicsActorType = value; }
1071 }
1072
1073 public RigidBody RigidBody
1074 {
1075 get { return rigidBody; }
1076 }
1077
1078 public Vector3 RigidBodyPosition
1079 {
1080 get { return rigidBody.CenterOfMassPosition; }
1081 }
1082
1083 public override bool IsPhysical
1084 {
1085 get { return _physical; }
1086 set { _physical = value; }
1087 }
1088
1089 public override bool Flying
1090 {
1091 get { return flying; }
1092 set { flying = value; }
1093 }
1094
1095 public override bool ThrottleUpdates
1096 {
1097 get { return false; }
1098 set { return; }
1099 }
1100
1101 public override bool IsColliding
1102 {
1103 get { return iscolliding; }
1104 set { iscolliding = value; }
1105 }
1106
1107 public override bool CollidingGround
1108 {
1109 get { return false; }
1110 set { return; }
1111 }
1112
1113 public override bool CollidingObj
1114 {
1115 get { return false; }
1116 set { return; }
1117 }
1118
1119 public override uint LocalID
1120 {
1121 set { return; }
1122 }
1123
1124 public override bool Grabbed
1125 {
1126 set { return; }
1127 }
1128
1129 public override bool Selected
1130 {
1131 set { return; }
1132 }
1133
1134 public override float Buoyancy
1135 {
1136 get { return 0f; }
1137 set { return; }
1138 }
1139
1140 public override bool FloatOnWater
1141 {
1142 set { return; }
1143 }
1144
1145 public virtual void SetAcceleration(OpenMetaverse.Vector3 accel)
1146 {
1147 lock (BulletXScene.BulletXLock)
1148 {
1149 _acceleration = accel;
1150 }
1151 }
1152
1153 public override bool Kinematic
1154 {
1155 get { return false; }
1156 set { }
1157 }
1158
1159 public override void AddForce(OpenMetaverse.Vector3 force, bool pushforce)
1160 {
1161 }
1162 public override OpenMetaverse.Vector3 Torque
1163 {
1164 get { return OpenMetaverse.Vector3.Zero; }
1165 set { return; }
1166 }
1167 public override void AddAngularForce(OpenMetaverse.Vector3 force, bool pushforce)
1168 {
1169 }
1170
1171 public override void SetMomentum(OpenMetaverse.Vector3 momentum)
1172 {
1173 }
1174
1175 internal virtual void ValidateHeight(float heighmapPositionValue)
1176 {
1177 }
1178
1179 internal virtual void UpdateKinetics()
1180 {
1181 }
1182
1183 #region Methods for updating values of RigidBody
1184
1185 protected internal void Translate()
1186 {
1187 Translate(_position);
1188 }
1189
1190 protected internal void Translate(OpenMetaverse.Vector3 _newPos)
1191 {
1192 Vector3 _translation;
1193 _translation = BulletXMaths.PhysicsVectorToXnaVector3(_newPos) - rigidBody.CenterOfMassPosition;
1194 rigidBody.Translate(_translation);
1195 }
1196
1197 protected internal void Speed()
1198 {
1199 Speed(_velocity);
1200 }
1201
1202 protected internal void Speed(OpenMetaverse.Vector3 _newSpeed)
1203 {
1204 Vector3 _speed;
1205 _speed = BulletXMaths.PhysicsVectorToXnaVector3(_newSpeed);
1206 rigidBody.LinearVelocity = _speed;
1207 }
1208
1209 protected internal void ReOrient()
1210 {
1211 ReOrient(_orientation);
1212 }
1213
1214 protected internal void ReOrient(OpenMetaverse.Quaternion _newOrient)
1215 {
1216 Quaternion _newOrientation;
1217 _newOrientation = BulletXMaths.QuaternionToXnaQuaternion(_newOrient);
1218 Matrix _comTransform = rigidBody.CenterOfMassTransform;
1219 BulletXMaths.SetRotation(ref _comTransform, _newOrientation);
1220 rigidBody.CenterOfMassTransform = _comTransform;
1221 }
1222
1223 protected internal void ReSize()
1224 {
1225 ReSize(_size);
1226 }
1227
1228 protected internal virtual void ReSize(OpenMetaverse.Vector3 _newSize)
1229 {
1230 }
1231
1232 public virtual void ScheduleTerseUpdate()
1233 {
1234 base.RequestPhysicsterseUpdate();
1235 }
1236
1237 #endregion
1238
1239 public override void CrossingFailure()
1240 {
1241
1242 }
1243 public override OpenMetaverse.Vector3 PIDTarget { set { return; } }
1244 public override bool PIDActive { set { return; } }
1245 public override float PIDTau { set { return; } }
1246
1247 public override float PIDHoverHeight { set { return; } }
1248 public override bool PIDHoverActive { set { return; } }
1249 public override PIDHoverType PIDHoverType { set { return; } }
1250 public override float PIDHoverTau { set { return; } }
1251
1252 public override OpenMetaverse.Quaternion APIDTarget
1253 {
1254 set { return; }
1255 }
1256
1257 public override bool APIDActive
1258 {
1259 set { return; }
1260 }
1261
1262 public override float APIDStrength
1263 {
1264 set { return; }
1265 }
1266
1267 public override float APIDDamping
1268 {
1269 set { return; }
1270 }
1271
1272
1273 public override void SubscribeEvents(int ms)
1274 {
1275
1276 }
1277 public override void UnSubscribeEvents()
1278 {
1279
1280 }
1281 public override bool SubscribedEvents()
1282 {
1283 return false;
1284 }
1285 }
1286
1287 /// <summary>
1288 /// PhysicsActor Character Class for BulletX
1289 /// </summary>
1290 public class BulletXCharacter : BulletXActor
1291 {
1292 public BulletXCharacter(BulletXScene parent_scene, OpenMetaverse.Vector3 pos)
1293 : this(String.Empty, parent_scene, pos)
1294 {
1295 }
1296
1297 public BulletXCharacter(String avName, BulletXScene parent_scene, OpenMetaverse.Vector3 pos)
1298 : this(avName, parent_scene, pos, OpenMetaverse.Vector3.Zero, OpenMetaverse.Vector3.Zero, OpenMetaverse.Vector3.Zero,
1299 OpenMetaverse.Quaternion.Identity)
1300 {
1301 }
1302
1303 public BulletXCharacter(String avName, BulletXScene parent_scene, OpenMetaverse.Vector3 pos, OpenMetaverse.Vector3 velocity,
1304 OpenMetaverse.Vector3 size, OpenMetaverse.Vector3 acceleration, OpenMetaverse.Quaternion orientation)
1305 : base(avName)
1306 {
1307 //This fields will be removed. They're temporal
1308 float _sizeX = 0.5f;
1309 float _sizeY = 0.5f;
1310 float _sizeZ = 1.6f;
1311 //.
1312 _position = pos;
1313 _velocity = velocity;
1314 _size = size;
1315 //---
1316 _size.X = _sizeX;
1317 _size.Y = _sizeY;
1318 _size.Z = _sizeZ;
1319 //.
1320 _acceleration = acceleration;
1321 _orientation = orientation;
1322 _physical = true;
1323
1324 float _mass = 50.0f; //This depends of avatar's dimensions
1325 //For RigidBody Constructor. The next values might change
1326 float _linearDamping = 0.0f;
1327 float _angularDamping = 0.0f;
1328 float _friction = 0.5f;
1329 float _restitution = 0.0f;
1330 Matrix _startTransform = Matrix.Identity;
1331 Matrix _centerOfMassOffset = Matrix.Identity;
1332 lock (BulletXScene.BulletXLock)
1333 {
1334 _startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(pos);
1335 //CollisionShape _collisionShape = new BoxShape(new MonoXnaCompactMaths.Vector3(1.0f, 1.0f, 1.60f));
1336 //For now, like ODE, collisionShape = sphere of radious = 1.0
1337 CollisionShape _collisionShape = new SphereShape(1.0f);
1338 DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset);
1339 Vector3 _localInertia = new Vector3();
1340 _collisionShape.CalculateLocalInertia(_mass, out _localInertia); //Always when mass > 0
1341 rigidBody =
1342 new RigidBody(_mass, _motionState, _collisionShape, _localInertia, _linearDamping, _angularDamping,
1343 _friction, _restitution);
1344 //rigidBody.ActivationState = ActivationState.DisableDeactivation;
1345 //It's seems that there are a bug with rigidBody constructor and its CenterOfMassPosition
1346 Vector3 _vDebugTranslation;
1347 _vDebugTranslation = _startTransform.Translation - rigidBody.CenterOfMassPosition;
1348 rigidBody.Translate(_vDebugTranslation);
1349 parent_scene.ddWorld.AddRigidBody(rigidBody);
1350 }
1351 }
1352
1353 public override int PhysicsActorType
1354 {
1355 get { return (int) ActorTypes.Agent; }
1356 set { return; }
1357 }
1358
1359 public override OpenMetaverse.Vector3 Position
1360 {
1361 get { return base.Position; }
1362 set { base.Position = value; }
1363 }
1364
1365 public override OpenMetaverse.Vector3 Velocity
1366 {
1367 get { return base.Velocity; }
1368 set { base.Velocity = value; }
1369 }
1370
1371 public override OpenMetaverse.Vector3 Size
1372 {
1373 get { return base.Size; }
1374 set { base.Size = value; }
1375 }
1376
1377 public override OpenMetaverse.Vector3 Acceleration
1378 {
1379 get { return base.Acceleration; }
1380 }
1381
1382 public override OpenMetaverse.Quaternion Orientation
1383 {
1384 get { return base.Orientation; }
1385 set { base.Orientation = value; }
1386 }
1387
1388 public override bool Flying
1389 {
1390 get { return base.Flying; }
1391 set { base.Flying = value; }
1392 }
1393
1394 public override bool IsColliding
1395 {
1396 get { return base.IsColliding; }
1397 set { base.IsColliding = value; }
1398 }
1399
1400 public override bool Kinematic
1401 {
1402 get { return base.Kinematic; }
1403 set { base.Kinematic = value; }
1404 }
1405
1406 public override void SetAcceleration(OpenMetaverse.Vector3 accel)
1407 {
1408 base.SetAcceleration(accel);
1409 }
1410
1411 public override void AddForce(OpenMetaverse.Vector3 force, bool pushforce)
1412 {
1413 base.AddForce(force, pushforce);
1414 }
1415
1416 public override void SetMomentum(OpenMetaverse.Vector3 momentum)
1417 {
1418 base.SetMomentum(momentum);
1419 }
1420
1421 internal void Move(float timeStep)
1422 {
1423 Vector3 vec = new Vector3();
1424 //At this point it's supossed that:
1425 //_velocity == rigidBody.LinearVelocity
1426 vec.X = _velocity.X;
1427 vec.Y = _velocity.Y;
1428 vec.Z = _velocity.Z;
1429 if ((vec.X != 0.0f) || (vec.Y != 0.0f) || (vec.Z != 0.0f)) rigidBody.Activate();
1430 if (flying)
1431 {
1432 //Antigravity with movement
1433 if (_position.Z <= BulletXScene.HeightLevel0)
1434 {
1435 vec.Z += BulletXScene.Gravity*timeStep;
1436 }
1437 //Lowgravity with movement
1438 else if ((_position.Z > BulletXScene.HeightLevel0)
1439 && (_position.Z <= BulletXScene.HeightLevel1))
1440 {
1441 vec.Z += BulletXScene.Gravity*timeStep*(1.0f - BulletXScene.LowGravityFactor);
1442 }
1443 //Lowgravity with...
1444 else if (_position.Z > BulletXScene.HeightLevel1)
1445 {
1446 if (vec.Z > 0) //no movement
1447 vec.Z = BulletXScene.Gravity*timeStep*(1.0f - BulletXScene.LowGravityFactor);
1448 else
1449 vec.Z += BulletXScene.Gravity*timeStep*(1.0f - BulletXScene.LowGravityFactor);
1450 }
1451 }
1452 rigidBody.LinearVelocity = vec;
1453 }
1454
1455 //This validation is very basic
1456 internal override void ValidateHeight(float heighmapPositionValue)
1457 {
1458 if (rigidBody.CenterOfMassPosition.Z < heighmapPositionValue + _size.Z/2.0f)
1459 {
1460 Matrix m = rigidBody.WorldTransform;
1461 Vector3 v3 = m.Translation;
1462 v3.Z = heighmapPositionValue + _size.Z/2.0f;
1463 m.Translation = v3;
1464 rigidBody.WorldTransform = m;
1465 //When an Avie touch the ground it's vertical velocity it's reduced to ZERO
1466 Speed(new OpenMetaverse.Vector3(rigidBody.LinearVelocity.X, rigidBody.LinearVelocity.Y, 0.0f));
1467 }
1468 }
1469
1470 internal override void UpdateKinetics()
1471 {
1472 _position = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.CenterOfMassPosition);
1473 _velocity = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.LinearVelocity);
1474 //Orientation it seems that it will be the default.
1475 ReOrient();
1476 }
1477 }
1478
1479 /// <summary>
1480 /// PhysicsActor Prim Class for BulletX
1481 /// </summary>
1482 public class BulletXPrim : BulletXActor
1483 {
1484 //Density it will depends of material.
1485 //For now all prims have the same density, all prims are made of water. Be water my friend! :D
1486 private const float _density = 1000.0f;
1487 private BulletXScene _parent_scene;
1488 private OpenMetaverse.Vector3 m_prev_position;
1489 private bool m_lastUpdateSent = false;
1490 //added by jed zhu
1491 private IMesh _mesh;
1492 public IMesh GetMesh() { return _mesh; }
1493
1494
1495
1496 public BulletXPrim(String primName, BulletXScene parent_scene, OpenMetaverse.Vector3 pos, OpenMetaverse.Vector3 size,
1497 OpenMetaverse.Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool isPhysical)
1498 : this(
1499 primName, parent_scene, pos, OpenMetaverse.Vector3.Zero, size, OpenMetaverse.Vector3.Zero, rotation, mesh, pbs,
1500 isPhysical)
1501 {
1502 }
1503
1504 public BulletXPrim(String primName, BulletXScene parent_scene, OpenMetaverse.Vector3 pos, OpenMetaverse.Vector3 velocity,
1505 OpenMetaverse.Vector3 size,
1506 OpenMetaverse.Vector3 acceleration, OpenMetaverse.Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs,
1507 bool isPhysical)
1508 : base(primName)
1509 {
1510 if ((size.X == 0) || (size.Y == 0) || (size.Z == 0))
1511 throw new Exception("Size 0");
1512 if (OpenMetaverse.Quaternion.Normalize(rotation).Length() == 0f)
1513 rotation = OpenMetaverse.Quaternion.Identity;
1514
1515 _position = pos;
1516 _physical = isPhysical;
1517 _velocity = _physical ? velocity : OpenMetaverse.Vector3.Zero;
1518 _size = size;
1519 _acceleration = acceleration;
1520 _orientation = rotation;
1521
1522 _parent_scene = parent_scene;
1523
1524 CreateRigidBody(parent_scene, mesh, pos, size);
1525 }
1526
1527 public override int PhysicsActorType
1528 {
1529 get { return (int) ActorTypes.Prim; }
1530 set { return; }
1531 }
1532
1533 public override OpenMetaverse.Vector3 Position
1534 {
1535 get { return base.Position; }
1536 set { base.Position = value; }
1537 }
1538
1539 public override OpenMetaverse.Vector3 Velocity
1540 {
1541 get { return base.Velocity; }
1542 set { base.Velocity = value; }
1543 }
1544
1545 public override OpenMetaverse.Vector3 Size
1546 {
1547 get { return _size; }
1548 set
1549 {
1550 lock (BulletXScene.BulletXLock)
1551 {
1552 _size = value;
1553 ReSize();
1554 }
1555 }
1556 }
1557
1558 public override OpenMetaverse.Vector3 Acceleration
1559 {
1560 get { return base.Acceleration; }
1561 }
1562
1563 public override OpenMetaverse.Quaternion Orientation
1564 {
1565 get { return base.Orientation; }
1566 set { base.Orientation = value; }
1567 }
1568
1569 public override float ActorMass
1570 {
1571 get
1572 {
1573 //For now all prims are boxes
1574 return (_physical ? 1 : 0)*_density*_size.X*_size.Y*_size.Z;
1575 }
1576 }
1577
1578 public override bool IsPhysical
1579 {
1580 get { return base.IsPhysical; }
1581 set
1582 {
1583 base.IsPhysical = value;
1584 if (value)
1585 {
1586 //---
1587 PhysicsPluginManager.PhysicsPluginMessage("Physical - Recreate", true);
1588 //---
1589 ReCreateRigidBody(_size);
1590 }
1591 else
1592 {
1593 //---
1594 PhysicsPluginManager.PhysicsPluginMessage("Physical - SetMassProps", true);
1595 //---
1596 rigidBody.SetMassProps(Mass, new Vector3());
1597 }
1598 }
1599 }
1600
1601 public override bool Flying
1602 {
1603 get { return base.Flying; }
1604 set { base.Flying = value; }
1605 }
1606
1607 public override bool IsColliding
1608 {
1609 get { return base.IsColliding; }
1610 set { base.IsColliding = value; }
1611 }
1612
1613 public override bool Kinematic
1614 {
1615 get { return base.Kinematic; }
1616 set { base.Kinematic = value; }
1617 }
1618
1619 public override void SetAcceleration(OpenMetaverse.Vector3 accel)
1620 {
1621 lock (BulletXScene.BulletXLock)
1622 {
1623 _acceleration = accel;
1624 }
1625 }
1626
1627 public override void AddForce(OpenMetaverse.Vector3 force, bool pushforce)
1628 {
1629 base.AddForce(force,pushforce);
1630 }
1631
1632 public override void SetMomentum(OpenMetaverse.Vector3 momentum)
1633 {
1634 base.SetMomentum(momentum);
1635 }
1636
1637 internal override void ValidateHeight(float heighmapPositionValue)
1638 {
1639 if (rigidBody.CenterOfMassPosition.Z < heighmapPositionValue + _size.Z/2.0f)
1640 {
1641 Matrix m = rigidBody.WorldTransform;
1642 Vector3 v3 = m.Translation;
1643 v3.Z = heighmapPositionValue + _size.Z/2.0f;
1644 m.Translation = v3;
1645 rigidBody.WorldTransform = m;
1646 //When a Prim touch the ground it's vertical velocity it's reduced to ZERO
1647 //Static objects don't have linear velocity
1648 if (_physical)
1649 Speed(new OpenMetaverse.Vector3(rigidBody.LinearVelocity.X, rigidBody.LinearVelocity.Y, 0.0f));
1650 }
1651 }
1652
1653 internal override void UpdateKinetics()
1654 {
1655 if (_physical) //Updates properties. Prim updates its properties physically
1656 {
1657 _position = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.CenterOfMassPosition);
1658
1659 _velocity = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.LinearVelocity);
1660 _orientation = BulletXMaths.XnaQuaternionToQuaternion(rigidBody.Orientation);
1661
1662 if ((Math.Abs(m_prev_position.X - _position.X) < 0.03)
1663 && (Math.Abs(m_prev_position.Y - _position.Y) < 0.03)
1664 && (Math.Abs(m_prev_position.Z - _position.Z) < 0.03))
1665 {
1666 if (!m_lastUpdateSent)
1667 {
1668 _velocity = OpenMetaverse.Vector3.Zero;
1669 base.ScheduleTerseUpdate();
1670 m_lastUpdateSent = true;
1671 }
1672 }
1673 else
1674 {
1675 m_lastUpdateSent = false;
1676 base.ScheduleTerseUpdate();
1677 }
1678 m_prev_position = _position;
1679 }
1680 else //Doesn't updates properties. That's a cancel
1681 {
1682 Translate();
1683 //Speed(); //<- Static objects don't have linear velocity
1684 ReOrient();
1685 }
1686 }
1687
1688 #region Methods for updating values of RigidBody
1689
1690 protected internal void CreateRigidBody(BulletXScene parent_scene, IMesh mesh, OpenMetaverse.Vector3 pos,
1691 OpenMetaverse.Vector3 size)
1692 {
1693 //For RigidBody Constructor. The next values might change
1694 float _linearDamping = 0.0f;
1695 float _angularDamping = 0.0f;
1696 float _friction = 1.0f;
1697 float _restitution = 0.0f;
1698 Matrix _startTransform = Matrix.Identity;
1699 Matrix _centerOfMassOffset = Matrix.Identity;
1700 //added by jed zhu
1701 _mesh = mesh;
1702
1703 lock (BulletXScene.BulletXLock)
1704 {
1705 _startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(pos);
1706 //For now all prims are boxes
1707 CollisionShape _collisionShape;
1708 if (mesh == null)
1709 {
1710 _collisionShape = new BoxShape(BulletXMaths.PhysicsVectorToXnaVector3(size)/2.0f);
1711 }
1712 else
1713 {
1714 int iVertexCount = mesh.getVertexList().Count;
1715 int[] indices = mesh.getIndexListAsInt();
1716 Vector3[] v3Vertices = new Vector3[iVertexCount];
1717 for (int i = 0; i < iVertexCount; i++)
1718 {
1719 OpenMetaverse.Vector3 v = mesh.getVertexList()[i];
1720 if (v != null) // Note, null has special meaning. See meshing code for details
1721 v3Vertices[i] = BulletXMaths.PhysicsVectorToXnaVector3(v);
1722 else
1723 v3Vertices[i] = Vector3.Zero;
1724 }
1725 TriangleIndexVertexArray triMesh = new TriangleIndexVertexArray(indices, v3Vertices);
1726
1727 _collisionShape = new TriangleMeshShape(triMesh);
1728 }
1729 DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset);
1730 Vector3 _localInertia = new Vector3();
1731 if (_physical) _collisionShape.CalculateLocalInertia(Mass, out _localInertia); //Always when mass > 0
1732 rigidBody =
1733 new RigidBody(Mass, _motionState, _collisionShape, _localInertia, _linearDamping, _angularDamping,
1734 _friction, _restitution);
1735 //rigidBody.ActivationState = ActivationState.DisableDeactivation;
1736 //It's seems that there are a bug with rigidBody constructor and its CenterOfMassPosition
1737 Vector3 _vDebugTranslation;
1738 _vDebugTranslation = _startTransform.Translation - rigidBody.CenterOfMassPosition;
1739 rigidBody.Translate(_vDebugTranslation);
1740 //---
1741 parent_scene.ddWorld.AddRigidBody(rigidBody);
1742 }
1743 }
1744
1745 protected internal void ReCreateRigidBody(OpenMetaverse.Vector3 size)
1746 {
1747 //There is a bug when trying to remove a rigidBody that is colliding with something..
1748 try
1749 {
1750 _parent_scene.ddWorld.RemoveRigidBody(rigidBody);
1751 }
1752 catch (Exception ex)
1753 {
1754 BulletXScene.BulletXMessage(_parent_scene.is_ex_message + ex.Message, true);
1755 rigidBody.ActivationState = ActivationState.DisableSimulation;
1756 _parent_scene.AddForgottenRigidBody(rigidBody);
1757 }
1758 CreateRigidBody(_parent_scene, null, _position, size);
1759 // Note, null for the meshing definitely is wrong. It's here for the moment to apease the compiler
1760 if (_physical) Speed(); //Static objects don't have linear velocity
1761 ReOrient();
1762 GC.Collect();
1763 }
1764
1765 protected internal override void ReSize(OpenMetaverse.Vector3 _newSize)
1766 {
1767 //I wonder to know how to resize with a simple instruction in BulletX. It seems that for now there isn't
1768 //so i have to do it manually. That's recreating rigidbody
1769 ReCreateRigidBody(_newSize);
1770 }
1771
1772 #endregion
1773 }
1774
1775 /// <summary>
1776 /// This Class manage a HeighField as a RigidBody. This is for to be added in the BulletXScene
1777 /// </summary>
1778 internal class BulletXPlanet
1779 {
1780 private OpenMetaverse.Vector3 _staticPosition;
1781// private Vector3 _staticVelocity;
1782// private OpenMetaverse.Quaternion _staticOrientation;
1783 private float _mass;
1784 // private BulletXScene _parentscene;
1785 internal float[] _heightField;
1786 private RigidBody _flatPlanet;
1787
1788 internal RigidBody RigidBody
1789 {
1790 get { return _flatPlanet; }
1791 }
1792
1793 internal BulletXPlanet(BulletXScene parent_scene, float[] heightField)
1794 {
1795 _staticPosition = new OpenMetaverse.Vector3(BulletXScene.MaxXY / 2, BulletXScene.MaxXY / 2, 0);
1796// _staticVelocity = new PhysicsVector();
1797// _staticOrientation = OpenMetaverse.Quaternion.Identity;
1798 _mass = 0; //No active
1799 // _parentscene = parent_scene;
1800 _heightField = heightField;
1801
1802 float _linearDamping = 0.0f;
1803 float _angularDamping = 0.0f;
1804 float _friction = 0.5f;
1805 float _restitution = 0.0f;
1806 Matrix _startTransform = Matrix.Identity;
1807 Matrix _centerOfMassOffset = Matrix.Identity;
1808
1809 lock (BulletXScene.BulletXLock)
1810 {
1811 try
1812 {
1813 _startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(_staticPosition);
1814 CollisionShape _collisionShape =
1815 new HeightfieldTerrainShape(BulletXScene.MaxXY, BulletXScene.MaxXY, _heightField,
1816 (float) BulletXScene.MaxZ, 2, true, false);
1817 DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset);
1818 Vector3 _localInertia = new Vector3();
1819 //_collisionShape.CalculateLocalInertia(_mass, out _localInertia); //Always when mass > 0
1820 _flatPlanet =
1821 new RigidBody(_mass, _motionState, _collisionShape, _localInertia, _linearDamping,
1822 _angularDamping, _friction, _restitution);
1823 //It's seems that there are a bug with rigidBody constructor and its CenterOfMassPosition
1824 Vector3 _vDebugTranslation;
1825 _vDebugTranslation = _startTransform.Translation - _flatPlanet.CenterOfMassPosition;
1826 _flatPlanet.Translate(_vDebugTranslation);
1827 parent_scene.ddWorld.AddRigidBody(_flatPlanet);
1828 }
1829 catch (Exception ex)
1830 {
1831 BulletXScene.BulletXMessage(ex.Message, true);
1832 }
1833 }
1834 BulletXScene.BulletXMessage("BulletXPlanet created.", false);
1835 }
1836
1837 internal float HeightValue(Vector3 position)
1838 {
1839 int li_x, li_y;
1840 float height;
1841 li_x = (int) Math.Round(position.X);
1842 if (li_x < 0) li_x = 0;
1843 if (li_x >= BulletXScene.MaxXY) li_x = BulletXScene.MaxXY - 1;
1844 li_y = (int) Math.Round(position.Y);
1845 if (li_y < 0) li_y = 0;
1846 if (li_y >= BulletXScene.MaxXY) li_y = BulletXScene.MaxXY - 1;
1847
1848 height = ((HeightfieldTerrainShape) _flatPlanet.CollisionShape).getHeightFieldValue(li_x, li_y);
1849 if (height < 0) height = 0;
1850 else if (height > BulletXScene.MaxZ) height = BulletXScene.MaxZ;
1851
1852 return height;
1853 }
1854 }
1855}
diff --git a/OpenSim/Region/Physics/BulletXPlugin/TriangleIndexVertexArray.cs b/OpenSim/Region/Physics/BulletXPlugin/TriangleIndexVertexArray.cs
deleted file mode 100644
index 637cf6e..0000000
--- a/OpenSim/Region/Physics/BulletXPlugin/TriangleIndexVertexArray.cs
+++ /dev/null
@@ -1,197 +0,0 @@
1/*
2 Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
3 Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22/*
23 This file contains a class TriangleIndexVertexArray. I tried using the class with the same name
24 from the BulletX implementation and found it unusable for the purpose of using triangle meshes
25 within BulletX as the implementation was painfully incomplete.
26 The attempt to derive from the original class failed as viable members were hidden.
27 Fiddling around with BulletX itself was not my intention.
28 So I copied the class to the BulletX-plugin and modified it.
29 If you want to fiddle around with it it's up to you to move all this to BulletX.
30 If someone someday implements the missing functionality in BulletX, feel free to remove this class.
31 It's just an ugly hack.
32*/
33
34using System;
35using System.Collections.Generic;
36using MonoXnaCompactMaths;
37using XnaDevRu.BulletX;
38
39namespace OpenSim.Region.Physics.BulletXPlugin
40{
41 /// <summary>
42 /// IndexedMesh indexes into existing vertex and index arrays, in a similar way OpenGL glDrawElements
43 /// instead of the number of indices, we pass the number of triangles
44 /// </summary>
45 public struct IndexedMesh
46 {
47 private int _numTriangles;
48 private int[] _triangleIndexBase;
49 private int _triangleIndexStride;
50 private int _numVertices;
51 private Vector3[] _vertexBase;
52 private int _vertexStride;
53
54 public IndexedMesh(int numTriangleIndices, int[] triangleIndexBase, int triangleIndexStride, int numVertices,
55 Vector3[] vertexBase, int vertexStride)
56 {
57 _numTriangles = numTriangleIndices;
58 _triangleIndexBase = triangleIndexBase;
59 _triangleIndexStride = triangleIndexStride;
60 _vertexBase = vertexBase;
61 _numVertices = numVertices;
62 _vertexStride = vertexStride;
63 }
64
65 public IndexedMesh(int[] triangleIndexBase, Vector3[] vertexBase)
66 {
67 _numTriangles = triangleIndexBase.Length;
68 _triangleIndexBase = triangleIndexBase;
69 _triangleIndexStride = 32;
70 _vertexBase = vertexBase;
71 _numVertices = vertexBase.Length;
72 _vertexStride = 24;
73 }
74
75 public int TriangleCount
76 {
77 get { return _numTriangles; }
78 set { _numTriangles = value; }
79 }
80
81 public int[] TriangleIndexBase
82 {
83 get { return _triangleIndexBase; }
84 set { _triangleIndexBase = value; }
85 }
86
87 public int TriangleIndexStride
88 {
89 get { return _triangleIndexStride; }
90 set { _triangleIndexStride = value; }
91 }
92
93 public int VertexCount
94 {
95 get { return _numVertices; }
96 set { _numVertices = value; }
97 }
98
99 public Vector3[] VertexBase
100 {
101 get { return _vertexBase; }
102 set { _vertexBase = value; }
103 }
104
105 public int VertexStride
106 {
107 get { return _vertexStride; }
108 set { _vertexStride = value; }
109 }
110 }
111
112 /// <summary>
113 /// TriangleIndexVertexArray allows to use multiple meshes, by indexing into existing triangle/index arrays.
114 /// Additional meshes can be added using addIndexedMesh
115 /// </summary>
116 public class TriangleIndexVertexArray : StridingMeshInterface
117 {
118 private List<IndexedMesh> _indexedMeshes = new List<IndexedMesh>();
119
120 public TriangleIndexVertexArray()
121 {
122 }
123
124 public TriangleIndexVertexArray(int numTriangleIndices, int[] triangleIndexBase, int triangleIndexStride,
125 int numVertices, Vector3[] vertexBase, int vertexStride)
126 {
127 IndexedMesh mesh = new IndexedMesh();
128 mesh.TriangleCount = numTriangleIndices;
129 mesh.TriangleIndexBase = triangleIndexBase;
130 mesh.TriangleIndexStride = triangleIndexStride;
131 mesh.VertexBase = vertexBase;
132 mesh.VertexCount = numVertices;
133 mesh.VertexStride = vertexStride;
134
135 AddIndexedMesh(mesh);
136 }
137
138 public TriangleIndexVertexArray(int[] triangleIndexBase, Vector3[] vertexBase)
139 : this(triangleIndexBase.Length, triangleIndexBase, 32, vertexBase.Length, vertexBase, 24)
140 {
141 }
142
143 public void AddIndexedMesh(IndexedMesh indexedMesh)
144 {
145 _indexedMeshes.Add(indexedMesh);
146 }
147
148 public override void GetLockedVertexIndexBase(out List<Vector3> verts, out List<int> indicies, out int numfaces,
149 int subpart)
150 {
151 throw new Exception("The method or operation is not implemented.");
152 }
153
154 public override void GetLockedReadOnlyVertexIndexBase(out List<Vector3> verts, out List<int> indicies,
155 out int numfaces, int subpart)
156 {
157 IndexedMesh m = _indexedMeshes[0];
158 Vector3[] vertexBase = m.VertexBase;
159 verts = new List<Vector3>();
160 foreach (Vector3 v in vertexBase)
161 {
162 verts.Add(v);
163 }
164 int[] indexBase = m.TriangleIndexBase;
165 indicies = new List<int>();
166 foreach (int i in indexBase)
167 {
168 indicies.Add(i);
169 }
170 numfaces = vertexBase.GetLength(0);
171 }
172
173 public override void UnLockVertexBase(int subpart)
174 {
175 throw new Exception("The method or operation is not implemented.");
176 }
177
178 public override void UnLockReadOnlyVertexBase(int subpart)
179 {
180 }
181
182 public override int SubPartsCount()
183 {
184 return _indexedMeshes.Count;
185 }
186
187 public override void PreallocateVertices(int numverts)
188 {
189 throw new Exception("The method or operation is not implemented.");
190 }
191
192 public override void PreallocateIndices(int numindices)
193 {
194 throw new Exception("The method or operation is not implemented.");
195 }
196 }
197}
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index c165a41..c26595c 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -464,10 +464,12 @@ namespace OpenSim.Region.Physics.OdePlugin
464 m_pidControllerActive = true; 464 m_pidControllerActive = true;
465 465
466 Vector3 SetSize = value; 466 Vector3 SetSize = value;
467 m_tainted_CAPSULE_LENGTH = (SetSize.Z*1.15f) - CAPSULE_RADIUS*2.0f; 467 m_tainted_CAPSULE_LENGTH = (SetSize.Z * 1.15f) - CAPSULE_RADIUS * 2.0f;
468 //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); 468// m_log.Info("[SIZE]: " + CAPSULE_LENGTH);
469 469
470 Velocity = Vector3.Zero; 470 // If we reset velocity here, then an avatar stalls when it crosses a border for the first time
471 // (as the height of the new root agent is set).
472// Velocity = Vector3.Zero;
471 473
472 _parent_scene.AddPhysicsActorTaint(this); 474 _parent_scene.AddPhysicsActorTaint(this);
473 } 475 }
@@ -785,6 +787,8 @@ namespace OpenSim.Region.Physics.OdePlugin
785 { 787 {
786 m_log.Warn("[PHYSICS]: Got a NaN velocity from Scene in a Character"); 788 m_log.Warn("[PHYSICS]: Got a NaN velocity from Scene in a Character");
787 } 789 }
790
791// m_log.DebugFormat("[PHYSICS]: Set target velocity of {0}", _target_velocity);
788 } 792 }
789 } 793 }
790 794
@@ -1324,7 +1328,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1324 { 1328 {
1325 if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero) 1329 if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero)
1326 { 1330 {
1327 1331// m_log.DebugFormat("[PHYSICS]: Changing capsule size");
1332
1328 m_pidControllerActive = true; 1333 m_pidControllerActive = true;
1329 // no lock needed on _parent_scene.OdeLock because we are called from within the thread lock in OdePlugin's simulate() 1334 // no lock needed on _parent_scene.OdeLock because we are called from within the thread lock in OdePlugin's simulate()
1330 d.JointDestroy(Amotor); 1335 d.JointDestroy(Amotor);
@@ -1335,7 +1340,10 @@ namespace OpenSim.Region.Physics.OdePlugin
1335 d.GeomDestroy(Shell); 1340 d.GeomDestroy(Shell);
1336 AvatarGeomAndBodyCreation(_position.X, _position.Y, 1341 AvatarGeomAndBodyCreation(_position.X, _position.Y,
1337 _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2), m_tensor); 1342 _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2), m_tensor);
1338 Velocity = Vector3.Zero; 1343
1344 // As with Size, we reset velocity. However, this isn't strictly necessary since it doesn't
1345 // appear to stall initial region crossings when done here. Being done for consistency.
1346// Velocity = Vector3.Zero;
1339 1347
1340 _parent_scene.geom_name_map[Shell] = m_name; 1348 _parent_scene.geom_name_map[Shell] = m_name;
1341 _parent_scene.actor_name_map[Shell] = (PhysicsActor)this; 1349 _parent_scene.actor_name_map[Shell] = (PhysicsActor)this;
@@ -1360,7 +1368,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1360 _position.Z = m_taintPosition.Z; 1368 _position.Z = m_taintPosition.Z;
1361 } 1369 }
1362 } 1370 }
1363
1364 } 1371 }
1365 1372
1366 internal void AddCollisionFrameTime(int p) 1373 internal void AddCollisionFrameTime(int p)
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 0a4fc51..8ad0b7f 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -1526,6 +1526,7 @@ Console.WriteLine("changeadd 1");
1526 { 1526 {
1527 if (Body == IntPtr.Zero) 1527 if (Body == IntPtr.Zero)
1528 enableBody(); 1528 enableBody();
1529
1529 //Prim auto disable after 20 frames, 1530 //Prim auto disable after 20 frames,
1530 //if you move it, re-enable the prim manually. 1531 //if you move it, re-enable the prim manually.
1531 if (_parent != null) 1532 if (_parent != null)
@@ -1536,6 +1537,7 @@ Console.WriteLine("changeadd 1");
1536 m_linkJoint = IntPtr.Zero; 1537 m_linkJoint = IntPtr.Zero;
1537 } 1538 }
1538 } 1539 }
1540
1539 if (Body != IntPtr.Zero) 1541 if (Body != IntPtr.Zero)
1540 { 1542 {
1541 d.BodySetPosition(Body, _position.X, _position.Y, _position.Z); 1543 d.BodySetPosition(Body, _position.X, _position.Y, _position.Z);
@@ -1599,7 +1601,6 @@ Console.WriteLine(" JointCreateFixed");
1599 float fy = 0; 1601 float fy = 0;
1600 float fz = 0; 1602 float fz = 0;
1601 1603
1602
1603 if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims. 1604 if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims.
1604 { 1605 {
1605 if (m_vehicle.Type != Vehicle.TYPE_NONE) 1606 if (m_vehicle.Type != Vehicle.TYPE_NONE)
@@ -1818,7 +1819,6 @@ Console.WriteLine(" JointCreateFixed");
1818 // 35x10 = 350n times the mass per second applied maximum. 1819 // 35x10 = 350n times the mass per second applied maximum.
1819 float nmax = 35f * m_mass; 1820 float nmax = 35f * m_mass;
1820 float nmin = -35f * m_mass; 1821 float nmin = -35f * m_mass;
1821
1822 1822
1823 if (fx > nmax) 1823 if (fx > nmax)
1824 fx = nmax; 1824 fx = nmax;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 18c0dd2..03c1e12 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -2116,15 +2116,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2116 { 2116 {
2117 face = 0; 2117 face = 0;
2118 } 2118 }
2119
2119 if (face >= 0 && face < GetNumberOfSides(part)) 2120 if (face >= 0 && face < GetNumberOfSides(part))
2120 { 2121 {
2121 Primitive.TextureEntryFace texface; 2122 Primitive.TextureEntryFace texface;
2122 texface = tex.GetFace((uint)face); 2123 texface = tex.GetFace((uint)face);
2123 return texface.TextureID.ToString(); 2124 string texture = texface.TextureID.ToString();
2125
2126 lock (part.TaskInventory)
2127 {
2128 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in part.TaskInventory)
2129 {
2130 if (inv.Value.AssetID == texface.TextureID)
2131 {
2132 texture = inv.Value.Name.ToString();
2133 break;
2134 }
2135 }
2136 }
2137
2138 return texture;
2124 } 2139 }
2125 else 2140 else
2126 { 2141 {
2127 return String.Empty; 2142 return UUID.Zero.ToString();
2128 } 2143 }
2129 } 2144 }
2130 2145
@@ -3250,10 +3265,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3250 SceneObjectGroup grp = m_host.ParentGroup; 3265 SceneObjectGroup grp = m_host.ParentGroup;
3251 3266
3252 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3267 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
3253 if (presence.Scene.AttachmentsModule != null) 3268
3254 { 3269 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3255 presence.Scene.AttachmentsModule.AttachObject(presence.ControllingClient, grp, (uint)attachment, false); 3270 if (attachmentsModule != null)
3256 } 3271 attachmentsModule.AttachObject(presence, grp, (uint)attachment, false);
3257 } 3272 }
3258 } 3273 }
3259 3274
@@ -3301,7 +3316,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3301 3316
3302 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3317 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3303 if (attachmentsModule != null) 3318 if (attachmentsModule != null)
3304 attachmentsModule.DetachSingleAttachmentToInv(itemID, presence.ControllingClient); 3319 attachmentsModule.DetachSingleAttachmentToInv(presence, itemID);
3305 } 3320 }
3306 3321
3307 public void llTakeCamera(string avatar) 3322 public void llTakeCamera(string avatar)
@@ -3953,7 +3968,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3953 parentPrim.ScheduleGroupForFullUpdate(); 3968 parentPrim.ScheduleGroupForFullUpdate();
3954 3969
3955 if (client != null) 3970 if (client != null)
3956 parentPrim.GetProperties(client); 3971 parentPrim.SendPropertiesToClient(client);
3957 3972
3958 ScriptSleep(1000); 3973 ScriptSleep(1000);
3959 } 3974 }
@@ -4104,6 +4119,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4104 public LSL_String llGetLinkKey(int linknum) 4119 public LSL_String llGetLinkKey(int linknum)
4105 { 4120 {
4106 m_host.AddScriptLPS(1); 4121 m_host.AddScriptLPS(1);
4122 List<UUID> keytable = new List<UUID>();
4123 // parse for sitting avatare-uuids
4124 World.ForEachScenePresence(delegate(ScenePresence presence)
4125 {
4126 if (!presence.IsChildAgent && presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
4127 keytable.Add(presence.UUID);
4128 });
4129
4130 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
4131 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
4132 {
4133 return keytable[totalprims - linknum].ToString();
4134 }
4135
4136 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
4137 {
4138 return m_host.UUID.ToString();
4139 }
4140
4107 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4141 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
4108 if (part != null) 4142 if (part != null)
4109 { 4143 {
@@ -4160,6 +4194,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4160 public LSL_String llGetLinkName(int linknum) 4194 public LSL_String llGetLinkName(int linknum)
4161 { 4195 {
4162 m_host.AddScriptLPS(1); 4196 m_host.AddScriptLPS(1);
4197 // parse for sitting avatare-names
4198 List<String> nametable = new List<String>();
4199 World.ForEachScenePresence(delegate(ScenePresence presence)
4200 {
4201 if (!presence.IsChildAgent && presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
4202 nametable.Add(presence.ControllingClient.Name);
4203 });
4204
4205 int totalprims = m_host.ParentGroup.PrimCount + nametable.Count;
4206 if (totalprims > m_host.ParentGroup.PrimCount)
4207 {
4208 // sitting Avatar-Name with negativ linknum / SinglePrim
4209 if (linknum < 0 && m_host.ParentGroup.PrimCount == 1 && nametable.Count == 1)
4210 return nametable[0];
4211 // Prim-Name / SinglePrim Sitting Avatar
4212 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && nametable.Count == 1)
4213 return m_host.Name;
4214 // LinkNumber > of Real PrimSet = AvatarName
4215 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
4216 return nametable[totalprims - linknum];
4217 }
4163 4218
4164 // simplest case, this prims link number 4219 // simplest case, this prims link number
4165 if (m_host.LinkNum == linknum) 4220 if (m_host.LinkNum == linknum)
@@ -4173,6 +4228,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4173 else 4228 else
4174 return UUID.Zero.ToString(); 4229 return UUID.Zero.ToString();
4175 } 4230 }
4231
4176 // Link set 4232 // Link set
4177 SceneObjectPart part = null; 4233 SceneObjectPart part = null;
4178 if (m_host.LinkNum == 1) // this is the Root prim 4234 if (m_host.LinkNum == 1) // this is the Root prim
@@ -4619,8 +4675,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4619 4675
4620 public void llCollisionSound(string impact_sound, double impact_volume) 4676 public void llCollisionSound(string impact_sound, double impact_volume)
4621 { 4677 {
4622
4623 m_host.AddScriptLPS(1); 4678 m_host.AddScriptLPS(1);
4679
4624 // TODO: Parameter check logic required. 4680 // TODO: Parameter check logic required.
4625 UUID soundId = UUID.Zero; 4681 UUID soundId = UUID.Zero;
4626 if (!UUID.TryParse(impact_sound, out soundId)) 4682 if (!UUID.TryParse(impact_sound, out soundId))
@@ -6756,6 +6812,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6756 return m_host.GetAvatarOnSitTarget().ToString(); 6812 return m_host.GetAvatarOnSitTarget().ToString();
6757 } 6813 }
6758 6814
6815 // http://wiki.secondlife.com/wiki/LlAvatarOnLinkSitTarget
6816 public LSL_String llAvatarOnLinkSitTarget(int linknum)
6817 {
6818 m_host.AddScriptLPS(1);
6819 if(linknum == ScriptBaseClass.LINK_SET ||
6820 linknum == ScriptBaseClass.LINK_ALL_CHILDREN ||
6821 linknum == ScriptBaseClass.LINK_ALL_OTHERS) return UUID.Zero.ToString();
6822
6823 List<SceneObjectPart> parts = GetLinkParts(linknum);
6824 if (parts.Count == 0) return UUID.Zero.ToString();
6825 return parts[0].SitTargetAvatar.ToString();
6826 }
6827
6828
6759 public void llAddToLandPassList(string avatar, double hours) 6829 public void llAddToLandPassList(string avatar, double hours)
6760 { 6830 {
6761 m_host.AddScriptLPS(1); 6831 m_host.AddScriptLPS(1);
@@ -7481,7 +7551,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7481 return; 7551 return;
7482 LSL_Vector v; 7552 LSL_Vector v;
7483 v = rules.GetVector3Item(idx++); 7553 v = rules.GetVector3Item(idx++);
7484 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z); 7554 av.AbsolutePosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7485 av.SendAvatarDataToAllAgents(); 7555 av.SendAvatarDataToAllAgents();
7486 7556
7487 break; 7557 break;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index 7c388fe..4ad4123 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -54,6 +54,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
54 LSL_Float llAtan2(double x, double y); 54 LSL_Float llAtan2(double x, double y);
55 void llAttachToAvatar(int attachment); 55 void llAttachToAvatar(int attachment);
56 LSL_Key llAvatarOnSitTarget(); 56 LSL_Key llAvatarOnSitTarget();
57 LSL_Key llAvatarOnLinkSitTarget(int linknum);
57 LSL_Rotation llAxes2Rot(LSL_Vector fwd, LSL_Vector left, LSL_Vector up); 58 LSL_Rotation llAxes2Rot(LSL_Vector fwd, LSL_Vector left, LSL_Vector up);
58 LSL_Rotation llAxisAngle2Rot(LSL_Vector axis, double angle); 59 LSL_Rotation llAxisAngle2Rot(LSL_Vector axis, double angle);
59 LSL_Integer llBase64ToInteger(string str); 60 LSL_Integer llBase64ToInteger(string str);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index ca54862..a88a1f4 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -130,6 +130,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
130 return m_LSL_Functions.llAvatarOnSitTarget(); 130 return m_LSL_Functions.llAvatarOnSitTarget();
131 } 131 }
132 132
133 public LSL_Key llAvatarOnLinkSitTarget(int linknum)
134 {
135 return m_LSL_Functions.llAvatarOnLinkSitTarget(linknum);
136 }
137
133 public LSL_Rotation llAxes2Rot(LSL_Vector fwd, LSL_Vector left, LSL_Vector up) 138 public LSL_Rotation llAxes2Rot(LSL_Vector fwd, LSL_Vector left, LSL_Vector up)
134 { 139 {
135 return m_LSL_Functions.llAxes2Rot(fwd, left, up); 140 return m_LSL_Functions.llAxes2Rot(fwd, left, up);
diff --git a/OpenSim/Services/Connectors/Simulation/EstateDataService.cs b/OpenSim/Services/Connectors/Simulation/EstateDataService.cs
index 7184ba1..cdcdecf 100644
--- a/OpenSim/Services/Connectors/Simulation/EstateDataService.cs
+++ b/OpenSim/Services/Connectors/Simulation/EstateDataService.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -90,6 +90,11 @@ namespace OpenSim.Services.Connectors
90 { 90 {
91 return m_database.LoadEstateSettings(estateID); 91 return m_database.LoadEstateSettings(estateID);
92 } 92 }
93
94 public EstateSettings CreateNewEstate()
95 {
96 return m_database.CreateNewEstate();
97 }
93 98
94 public List<EstateSettings> LoadEstateSettingsAll() 99 public List<EstateSettings> LoadEstateSettingsAll()
95 { 100 {
diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs
index eeab67a..1648b51 100644
--- a/OpenSim/Services/InventoryService/XInventoryService.cs
+++ b/OpenSim/Services/InventoryService/XInventoryService.cs
@@ -40,9 +40,9 @@ namespace OpenSim.Services.InventoryService
40{ 40{
41 public class XInventoryService : ServiceBase, IInventoryService 41 public class XInventoryService : ServiceBase, IInventoryService
42 { 42 {
43 //private static readonly ILog m_log = 43// private static readonly ILog m_log =
44 // LogManager.GetLogger( 44// LogManager.GetLogger(
45 // MethodBase.GetCurrentMethod().DeclaringType); 45// MethodBase.GetCurrentMethod().DeclaringType);
46 46
47 protected IXInventoryData m_Database; 47 protected IXInventoryData m_Database;
48 protected bool m_AllowDelete = true; 48 protected bool m_AllowDelete = true;
@@ -385,18 +385,22 @@ namespace OpenSim.Services.InventoryService
385 385
386 public virtual bool AddItem(InventoryItemBase item) 386 public virtual bool AddItem(InventoryItemBase item)
387 { 387 {
388 //m_log.DebugFormat( 388// m_log.DebugFormat(
389 // "[XINVENTORY SERVICE]: Adding item {0} to folder {1} for {2}", item.ID, item.Folder, item.Owner); 389// "[XINVENTORY SERVICE]: Adding item {0} to folder {1} for {2}", item.ID, item.Folder, item.Owner);
390 390
391 return m_Database.StoreItem(ConvertFromOpenSim(item)); 391 return m_Database.StoreItem(ConvertFromOpenSim(item));
392 } 392 }
393 393
394 public virtual bool UpdateItem(InventoryItemBase item) 394 public virtual bool UpdateItem(InventoryItemBase item)
395 { 395 {
396// throw new Exception("urrgh");
396 if (!m_AllowDelete) 397 if (!m_AllowDelete)
397 if (item.AssetType == (sbyte)AssetType.Link || item.AssetType == (sbyte)AssetType.LinkFolder) 398 if (item.AssetType == (sbyte)AssetType.Link || item.AssetType == (sbyte)AssetType.LinkFolder)
398 return false; 399 return false;
399 400
401// m_log.InfoFormat(
402// "[XINVENTORY SERVICE]: Updating item {0} {1} in folder {2}", item.Name, item.ID, item.Folder);
403
400 return m_Database.StoreItem(ConvertFromOpenSim(item)); 404 return m_Database.StoreItem(ConvertFromOpenSim(item));
401 } 405 }
402 406
diff --git a/OpenSim/Services/UserAccountService/UserAccountService.cs b/OpenSim/Services/UserAccountService/UserAccountService.cs
index 7a46165..4c6122d 100644
--- a/OpenSim/Services/UserAccountService/UserAccountService.cs
+++ b/OpenSim/Services/UserAccountService/UserAccountService.cs
@@ -28,15 +28,15 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using log4net;
31using Nini.Config; 32using Nini.Config;
33using OpenMetaverse;
32using OpenSim.Data; 34using OpenSim.Data;
35using OpenSim.Framework;
33using OpenSim.Services.Interfaces; 36using OpenSim.Services.Interfaces;
34using OpenSim.Framework.Console; 37using OpenSim.Framework.Console;
35using GridRegion = OpenSim.Services.Interfaces.GridRegion; 38using GridRegion = OpenSim.Services.Interfaces.GridRegion;
36 39
37using OpenMetaverse;
38using log4net;
39
40namespace OpenSim.Services.UserAccountService 40namespace OpenSim.Services.UserAccountService
41{ 41{
42 public class UserAccountService : UserAccountServiceBase, IUserAccountService 42 public class UserAccountService : UserAccountServiceBase, IUserAccountService
@@ -44,10 +44,16 @@ namespace OpenSim.Services.UserAccountService
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 UserAccountService m_RootInstance; 45 private static UserAccountService m_RootInstance;
46 46
47 /// <summary>
48 /// Should we create default entries (minimum body parts/clothing, avatar wearable entries) for a new avatar?
49 /// </summary>
50 private bool m_CreateDefaultAvatarEntries;
51
47 protected IGridService m_GridService; 52 protected IGridService m_GridService;
48 protected IAuthenticationService m_AuthenticationService; 53 protected IAuthenticationService m_AuthenticationService;
49 protected IGridUserService m_GridUserService; 54 protected IGridUserService m_GridUserService;
50 protected IInventoryService m_InventoryService; 55 protected IInventoryService m_InventoryService;
56 protected IAvatarService m_AvatarService;
51 57
52 public UserAccountService(IConfigSource config) 58 public UserAccountService(IConfigSource config)
53 : base(config) 59 : base(config)
@@ -77,6 +83,12 @@ namespace OpenSim.Services.UserAccountService
77 if (invServiceDll != string.Empty) 83 if (invServiceDll != string.Empty)
78 m_InventoryService = LoadPlugin<IInventoryService>(invServiceDll, new Object[] { config }); 84 m_InventoryService = LoadPlugin<IInventoryService>(invServiceDll, new Object[] { config });
79 85
86 string avatarServiceDll = userConfig.GetString("AvatarService", string.Empty);
87 if (avatarServiceDll != string.Empty)
88 m_AvatarService = LoadPlugin<IAvatarService>(avatarServiceDll, new Object[] { config });
89
90 m_CreateDefaultAvatarEntries = userConfig.GetBoolean("CreateDefaultAvatarEntries", false);
91
80 if (MainConsole.Instance != null) 92 if (MainConsole.Instance != null)
81 { 93 {
82 MainConsole.Instance.Commands.AddCommand("UserService", false, 94 MainConsole.Instance.Commands.AddCommand("UserService", false,
@@ -102,9 +114,7 @@ namespace OpenSim.Services.UserAccountService
102 "show account <first> <last>", 114 "show account <first> <last>",
103 "Show account details for the given user", HandleShowAccount); 115 "Show account details for the given user", HandleShowAccount);
104 } 116 }
105
106 } 117 }
107
108 } 118 }
109 119
110 #region IUserAccountService 120 #region IUserAccountService
@@ -349,7 +359,7 @@ namespace OpenSim.Services.UserAccountService
349 email = MainConsole.Instance.CmdPrompt("Email", ""); 359 email = MainConsole.Instance.CmdPrompt("Email", "");
350 else email = cmdparams[5]; 360 else email = cmdparams[5];
351 361
352 CreateUser(firstName, lastName, password, email); 362 CreateUser(UUID.Zero, firstName, lastName, password, email);
353 } 363 }
354 364
355 protected void HandleShowAccount(string module, string[] cmdparams) 365 protected void HandleShowAccount(string module, string[] cmdparams)
@@ -461,11 +471,12 @@ namespace OpenSim.Services.UserAccountService
461 /// <summary> 471 /// <summary>
462 /// Create a user 472 /// Create a user
463 /// </summary> 473 /// </summary>
474 /// <param name="scopeID">Allows hosting of multiple grids in a single database. Normally left as UUID.Zero</param>
464 /// <param name="firstName"></param> 475 /// <param name="firstName"></param>
465 /// <param name="lastName"></param> 476 /// <param name="lastName"></param>
466 /// <param name="password"></param> 477 /// <param name="password"></param>
467 /// <param name="email"></param> 478 /// <param name="email"></param>
468 private void CreateUser(string firstName, string lastName, string password, string email) 479 public UserAccount CreateUser(UUID scopeID, string firstName, string lastName, string password, string email)
469 { 480 {
470 UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName); 481 UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName);
471 if (null == account) 482 if (null == account)
@@ -512,12 +523,20 @@ namespace OpenSim.Services.UserAccountService
512 { 523 {
513 success = m_InventoryService.CreateUserInventory(account.PrincipalID); 524 success = m_InventoryService.CreateUserInventory(account.PrincipalID);
514 if (!success) 525 if (!success)
526 {
515 m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to create inventory for account {0} {1}.", 527 m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to create inventory for account {0} {1}.",
516 firstName, lastName); 528 firstName, lastName);
529 }
530 else if (m_CreateDefaultAvatarEntries)
531 {
532 CreateDefaultAppearanceEntries(account.PrincipalID);
533 }
517 } 534 }
518 535
519 m_log.InfoFormat("[USER ACCOUNT SERVICE]: Account {0} {1} created successfully", firstName, lastName); 536 m_log.InfoFormat("[USER ACCOUNT SERVICE]: Account {0} {1} created successfully", firstName, lastName);
520 } else { 537 }
538 else
539 {
521 m_log.ErrorFormat("[USER ACCOUNT SERVICE]: Account creation failed for account {0} {1}", firstName, lastName); 540 m_log.ErrorFormat("[USER ACCOUNT SERVICE]: Account creation failed for account {0} {1}", firstName, lastName);
522 } 541 }
523 } 542 }
@@ -525,6 +544,128 @@ namespace OpenSim.Services.UserAccountService
525 { 544 {
526 m_log.ErrorFormat("[USER ACCOUNT SERVICE]: A user with the name {0} {1} already exists!", firstName, lastName); 545 m_log.ErrorFormat("[USER ACCOUNT SERVICE]: A user with the name {0} {1} already exists!", firstName, lastName);
527 } 546 }
547
548 return account;
549 }
550
551 private void CreateDefaultAppearanceEntries(UUID principalID)
552 {
553 m_log.DebugFormat("[USER ACCOUNT SERVICE]: Creating default appearance items for {0}", principalID);
554
555 InventoryFolderBase bodyPartsFolder = m_InventoryService.GetFolderForType(principalID, AssetType.Bodypart);
556
557 InventoryItemBase eyes = new InventoryItemBase(UUID.Random(), principalID);
558 eyes.AssetID = new UUID("4bb6fa4d-1cd2-498a-a84c-95c1a0e745a7");
559 eyes.Name = "Default Eyes";
560 eyes.CreatorId = principalID.ToString();
561 eyes.AssetType = (int)AssetType.Bodypart;
562 eyes.InvType = (int)InventoryType.Wearable;
563 eyes.Folder = bodyPartsFolder.ID;
564 eyes.BasePermissions = (uint)PermissionMask.All;
565 eyes.CurrentPermissions = (uint)PermissionMask.All;
566 eyes.EveryOnePermissions = (uint)PermissionMask.All;
567 eyes.GroupPermissions = (uint)PermissionMask.All;
568 eyes.NextPermissions = (uint)PermissionMask.All;
569 eyes.Flags = (uint)WearableType.Eyes;
570 m_InventoryService.AddItem(eyes);
571
572 InventoryItemBase shape = new InventoryItemBase(UUID.Random(), principalID);
573 shape.AssetID = AvatarWearable.DEFAULT_BODY_ASSET;
574 shape.Name = "Default Shape";
575 shape.CreatorId = principalID.ToString();
576 shape.AssetType = (int)AssetType.Bodypart;
577 shape.InvType = (int)InventoryType.Wearable;
578 shape.Folder = bodyPartsFolder.ID;
579 shape.BasePermissions = (uint)PermissionMask.All;
580 shape.CurrentPermissions = (uint)PermissionMask.All;
581 shape.EveryOnePermissions = (uint)PermissionMask.All;
582 shape.GroupPermissions = (uint)PermissionMask.All;
583 shape.NextPermissions = (uint)PermissionMask.All;
584 shape.Flags = (uint)WearableType.Shape;
585 m_InventoryService.AddItem(shape);
586
587 InventoryItemBase skin = new InventoryItemBase(UUID.Random(), principalID);
588 skin.AssetID = AvatarWearable.DEFAULT_SKIN_ASSET;
589 skin.Name = "Default Skin";
590 skin.CreatorId = principalID.ToString();
591 skin.AssetType = (int)AssetType.Bodypart;
592 skin.InvType = (int)InventoryType.Wearable;
593 skin.Folder = bodyPartsFolder.ID;
594 skin.BasePermissions = (uint)PermissionMask.All;
595 skin.CurrentPermissions = (uint)PermissionMask.All;
596 skin.EveryOnePermissions = (uint)PermissionMask.All;
597 skin.GroupPermissions = (uint)PermissionMask.All;
598 skin.NextPermissions = (uint)PermissionMask.All;
599 skin.Flags = (uint)WearableType.Skin;
600 m_InventoryService.AddItem(skin);
601
602 InventoryItemBase hair = new InventoryItemBase(UUID.Random(), principalID);
603 hair.AssetID = AvatarWearable.DEFAULT_HAIR_ASSET;
604 hair.Name = "Default Hair";
605 hair.CreatorId = principalID.ToString();
606 hair.AssetType = (int)AssetType.Bodypart;
607 hair.InvType = (int)InventoryType.Wearable;
608 hair.Folder = bodyPartsFolder.ID;
609 hair.BasePermissions = (uint)PermissionMask.All;
610 hair.CurrentPermissions = (uint)PermissionMask.All;
611 hair.EveryOnePermissions = (uint)PermissionMask.All;
612 hair.GroupPermissions = (uint)PermissionMask.All;
613 hair.NextPermissions = (uint)PermissionMask.All;
614 hair.Flags = (uint)WearableType.Hair;
615 m_InventoryService.AddItem(hair);
616
617 InventoryFolderBase clothingFolder = m_InventoryService.GetFolderForType(principalID, AssetType.Clothing);
618
619 InventoryItemBase shirt = new InventoryItemBase(UUID.Random(), principalID);
620 shirt.AssetID = AvatarWearable.DEFAULT_SHIRT_ASSET;
621 shirt.Name = "Default Shirt";
622 shirt.CreatorId = principalID.ToString();
623 shirt.AssetType = (int)AssetType.Clothing;
624 shirt.InvType = (int)InventoryType.Wearable;
625 shirt.Folder = clothingFolder.ID;
626 shirt.BasePermissions = (uint)PermissionMask.All;
627 shirt.CurrentPermissions = (uint)PermissionMask.All;
628 shirt.EveryOnePermissions = (uint)PermissionMask.All;
629 shirt.GroupPermissions = (uint)PermissionMask.All;
630 shirt.NextPermissions = (uint)PermissionMask.All;
631 shirt.Flags = (uint)WearableType.Shirt;
632 m_InventoryService.AddItem(shirt);
633
634 InventoryItemBase pants = new InventoryItemBase(UUID.Random(), principalID);
635 pants.AssetID = AvatarWearable.DEFAULT_PANTS_ASSET;
636 pants.Name = "Default Pants";
637 pants.CreatorId = principalID.ToString();
638 pants.AssetType = (int)AssetType.Clothing;
639 pants.InvType = (int)InventoryType.Wearable;
640 pants.Folder = clothingFolder.ID;
641 pants.BasePermissions = (uint)PermissionMask.All;
642 pants.CurrentPermissions = (uint)PermissionMask.All;
643 pants.EveryOnePermissions = (uint)PermissionMask.All;
644 pants.GroupPermissions = (uint)PermissionMask.All;
645 pants.NextPermissions = (uint)PermissionMask.All;
646 pants.Flags = (uint)WearableType.Pants;
647 m_InventoryService.AddItem(pants);
648
649 if (m_AvatarService != null)
650 {
651 m_log.DebugFormat("[USER ACCOUNT SERVICE]: Creating default avatar entries for {0}", principalID);
652
653 AvatarWearable[] wearables = new AvatarWearable[6];
654 wearables[AvatarWearable.EYES] = new AvatarWearable(eyes.ID, eyes.AssetID);
655 wearables[AvatarWearable.BODY] = new AvatarWearable(shape.ID, shape.AssetID);
656 wearables[AvatarWearable.SKIN] = new AvatarWearable(skin.ID, skin.AssetID);
657 wearables[AvatarWearable.HAIR] = new AvatarWearable(hair.ID, hair.AssetID);
658 wearables[AvatarWearable.SHIRT] = new AvatarWearable(shirt.ID, shirt.AssetID);
659 wearables[AvatarWearable.PANTS] = new AvatarWearable(pants.ID, pants.AssetID);
660
661 AvatarAppearance ap = new AvatarAppearance();
662 for (int i = 0; i < 6; i++)
663 {
664 ap.SetWearable(i, wearables[i]);
665 }
666
667 m_AvatarService.SetAppearance(principalID, ap);
668 }
528 } 669 }
529 } 670 }
530} 671} \ No newline at end of file
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs
index 014f7f6..b4f521f 100644
--- a/OpenSim/Tests/Common/Mock/TestClient.cs
+++ b/OpenSim/Tests/Common/Mock/TestClient.cs
@@ -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 Action<Vector3, bool> OnAutoPilotGo; 237 public event Action<Vector3, bool, bool> OnAutoPilotGo;
238 238
239 public event TerrainUnacked OnUnackedTerrain; 239 public event TerrainUnacked OnUnackedTerrain;
240 240
diff --git a/OpenSim/Tests/Common/QuaternionToleranceConstraint.cs b/OpenSim/Tests/Common/QuaternionToleranceConstraint.cs
new file mode 100644
index 0000000..b38c382
--- /dev/null
+++ b/OpenSim/Tests/Common/QuaternionToleranceConstraint.cs
@@ -0,0 +1,82 @@
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;
30using NUnit.Framework;
31using NUnit.Framework.Constraints;
32
33namespace OpenSim.Tests.Common
34{
35 public class QuaternionToleranceConstraint : ANumericalToleranceConstraint
36 {
37 private Quaternion _baseValue;
38 private Quaternion _valueToBeTested;
39
40 public QuaternionToleranceConstraint(Quaternion baseValue, double tolerance) : base(tolerance)
41 {
42 _baseValue = baseValue;
43 }
44
45 /// <summary>
46 /// Test whether the constraint is satisfied by a given value
47 /// </summary>
48 /// <param name="valueToBeTested">The value to be tested</param>
49 /// <returns>
50 /// True for success, false for failure
51 /// </returns>
52 public override bool Matches(object valueToBeTested)
53 {
54 if (valueToBeTested == null)
55 {
56 throw new ArgumentException("Constraint cannot be used upon null values.");
57 }
58 if (valueToBeTested.GetType() != typeof (Quaternion))
59 {
60 throw new ArgumentException("Constraint cannot be used upon non quaternion values.");
61 }
62
63 _valueToBeTested = (Quaternion)valueToBeTested;
64
65 return (IsWithinDoubleConstraint(_valueToBeTested.X, _baseValue.X) &&
66 IsWithinDoubleConstraint(_valueToBeTested.Y, _baseValue.Y) &&
67 IsWithinDoubleConstraint(_valueToBeTested.Z, _baseValue.Z) &&
68 IsWithinDoubleConstraint(_valueToBeTested.W, _baseValue.W));
69 }
70
71 public override void WriteDescriptionTo(MessageWriter writer)
72 {
73 writer.WriteExpectedValue(
74 string.Format("A value {0} within tolerance of plus or minus {1}", _baseValue, _tolerance));
75 }
76
77 public override void WriteActualValueTo(MessageWriter writer)
78 {
79 writer.WriteActualValue(_valueToBeTested);
80 }
81 }
82} \ No newline at end of file
diff --git a/OpenSim/Tools/Configger/ConfigurationLoader.cs b/OpenSim/Tools/Configger/ConfigurationLoader.cs
index 3914652..28bcc99 100644
--- a/OpenSim/Tools/Configger/ConfigurationLoader.cs
+++ b/OpenSim/Tools/Configger/ConfigurationLoader.cs
@@ -233,6 +233,7 @@ namespace OpenSim.Tools.Configger
233 config = defaultConfig.AddConfig("Startup"); 233 config = defaultConfig.AddConfig("Startup");
234 234
235 config.Set("region_info_source", "filesystem"); 235 config.Set("region_info_source", "filesystem");
236 config.Set("allow_regionless", false);
236 237
237 config.Set("gridmode", false); 238 config.Set("gridmode", false);
238 config.Set("physics", "OpenDynamicsEngine"); 239 config.Set("physics", "OpenDynamicsEngine");