diff options
97 files changed, 2667 insertions, 8312 deletions
diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 2fe8b46..239b884 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt | |||
@@ -117,6 +117,7 @@ what it is today. | |||
117 | * nornalbion | 117 | * nornalbion |
118 | * Omar Vera Ustariz (IBM) | 118 | * Omar Vera Ustariz (IBM) |
119 | * openlifegrid.com | 119 | * openlifegrid.com |
120 | * Oren Hurvitz (Kitely) | ||
120 | * otakup0pe | 121 | * otakup0pe |
121 | * ralphos | 122 | * ralphos |
122 | * RemedyTomm | 123 | * RemedyTomm |
diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 93a6915..e20b487 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs | |||
@@ -709,6 +709,14 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
709 | // ok, client wants us to use an explicit UUID | 709 | // ok, client wants us to use an explicit UUID |
710 | // regardless of what the avatar name provided | 710 | // regardless of what the avatar name provided |
711 | userID = new UUID((string) requestData["estate_owner_uuid"]); | 711 | userID = new UUID((string) requestData["estate_owner_uuid"]); |
712 | |||
713 | // Check that the specified user exists | ||
714 | Scene currentOrFirst = m_application.SceneManager.CurrentOrFirstScene; | ||
715 | IUserAccountService accountService = currentOrFirst.UserAccountService; | ||
716 | UserAccount user = accountService.GetUserAccount(currentOrFirst.RegionInfo.ScopeID, userID); | ||
717 | |||
718 | if (user == null) | ||
719 | throw new Exception("Specified user was not found."); | ||
712 | } | 720 | } |
713 | else if (requestData.ContainsKey("estate_owner_first") & requestData.ContainsKey("estate_owner_last")) | 721 | else if (requestData.ContainsKey("estate_owner_first") & requestData.ContainsKey("estate_owner_last")) |
714 | { | 722 | { |
@@ -720,6 +728,11 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
720 | IUserAccountService accountService = currentOrFirst.UserAccountService; | 728 | IUserAccountService accountService = currentOrFirst.UserAccountService; |
721 | UserAccount user = accountService.GetUserAccount(currentOrFirst.RegionInfo.ScopeID, | 729 | UserAccount user = accountService.GetUserAccount(currentOrFirst.RegionInfo.ScopeID, |
722 | ownerFirst, ownerLast); | 730 | ownerFirst, ownerLast); |
731 | |||
732 | // Check that the specified user exists | ||
733 | if (user == null) | ||
734 | throw new Exception("Specified user was not found."); | ||
735 | |||
723 | userID = user.PrincipalID; | 736 | userID = user.PrincipalID; |
724 | } | 737 | } |
725 | else | 738 | else |
@@ -728,21 +741,30 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
728 | } | 741 | } |
729 | 742 | ||
730 | // Create a new estate with the name provided | 743 | // Create a new estate with the name provided |
731 | region.EstateSettings = m_application.EstateDataService.LoadEstateSettings(region.RegionID, true); | 744 | region.EstateSettings = m_application.EstateDataService.CreateNewEstate(); |
732 | 745 | ||
733 | region.EstateSettings.EstateName = (string) requestData["estate_name"]; | 746 | region.EstateSettings.EstateName = (string) requestData["estate_name"]; |
734 | region.EstateSettings.EstateOwner = userID; | 747 | region.EstateSettings.EstateOwner = userID; |
735 | // Persistence does not seem to effect the need to save a new estate | 748 | // Persistence does not seem to effect the need to save a new estate |
736 | region.EstateSettings.Save(); | 749 | region.EstateSettings.Save(); |
750 | |||
751 | if (!m_application.EstateDataService.LinkRegion(region.RegionID, (int) region.EstateSettings.EstateID)) | ||
752 | throw new Exception("Failed to join estate."); | ||
737 | } | 753 | } |
738 | else | 754 | else |
739 | { | 755 | { |
740 | int estateID = estateIDs[0]; | 756 | int estateID = estateIDs[0]; |
741 | 757 | ||
742 | region.EstateSettings = m_application.EstateDataService.LoadEstateSettings(estateID); | 758 | region.EstateSettings = m_application.EstateDataService.LoadEstateSettings(region.RegionID, false); |
743 | 759 | ||
744 | if (!m_application.EstateDataService.LinkRegion(region.RegionID, estateID)) | 760 | if (region.EstateSettings.EstateID != estateID) |
745 | throw new Exception("Failed to join estate."); | 761 | { |
762 | // The region is already part of an estate, but not the one we want. | ||
763 | region.EstateSettings = m_application.EstateDataService.LoadEstateSettings(estateID); | ||
764 | |||
765 | if (!m_application.EstateDataService.LinkRegion(region.RegionID, estateID)) | ||
766 | throw new Exception("Failed to join estate."); | ||
767 | } | ||
746 | } | 768 | } |
747 | 769 | ||
748 | // Create the region and perform any initial initialization | 770 | // Create the region and perform any initial initialization |
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 e7c8dc5..7feec91 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 | |||
19 | INSERT INTO Friends (PrincipalID, Friend, Flags, Offered) | 19 | INSERT INTO Friends (PrincipalID, Friend, Flags, Offered) |
20 | SELECT [ownerID], [friendID], [friendPerms], 0 FROM userfriends; | 20 | SELECT [ownerID], [friendID], [friendPerms], 0 FROM userfriends; |
21 | 21 | ||
22 | COMMIT | ||
23 | |||
24 | :VERSION 3 | ||
25 | |||
26 | BEGIN TRANSACTION | ||
27 | |||
28 | CREATE 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) | ||
33 | ON [PRIMARY] | ||
34 | |||
35 | |||
36 | IF 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 | |||
40 | DROP TABLE dbo.Friends | ||
41 | |||
42 | EXECUTE sp_rename N'dbo.Tmp_Friends', N'Friends', 'OBJECT' | ||
43 | |||
44 | ALTER 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 | |||
22 | COMMIT \ No newline at end of file | 50 | COMMIT \ 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 | |||
244 | ADD CONSTRAINT DF_inventoryitems_creatorID | 244 | ADD CONSTRAINT DF_inventoryitems_creatorID |
245 | DEFAULT '00000000-0000-0000-0000-000000000000' FOR creatorID | 245 | DEFAULT '00000000-0000-0000-0000-000000000000' FOR creatorID |
246 | 246 | ||
247 | :GO | ||
248 | |||
249 | :VERSION 9 | ||
250 | |||
251 | BEGIN TRANSACTION | ||
252 | |||
253 | # CreatorID goes up to VARCHAR(255) | ||
254 | |||
255 | exec sp_rename 'inventoryitems.CreatorID', 'cr_old', 'COLUMN' | ||
256 | |||
257 | :GO | ||
258 | |||
259 | alter table inventoryitems | ||
260 | add creatorID varchar(255) NULL | ||
261 | |||
262 | :GO | ||
263 | |||
264 | update inventoryitems set creatorID = cr_old | ||
265 | |||
266 | alter table inventoryitems | ||
267 | drop CONSTRAINT DF_inventoryitems_creatorID | ||
268 | :GO | ||
269 | |||
270 | alter table inventoryitems | ||
271 | drop column cr_old | ||
272 | :GO | ||
273 | COMMIT | ||
274 | |||
275 | ALTER TABLE inventoryitems | ||
276 | ADD CONSTRAINT DF_inventoryitems_creatorID | ||
277 | DEFAULT '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 e8c85c9..d2c6c57 100644 --- a/OpenSim/Framework/AssetBase.cs +++ b/OpenSim/Framework/AssetBase.cs | |||
@@ -167,6 +167,7 @@ namespace OpenSim.Framework | |||
167 | get { return m_metadata.FullID; } | 167 | get { return m_metadata.FullID; } |
168 | set { m_metadata.FullID = value; } | 168 | set { m_metadata.FullID = value; } |
169 | } | 169 | } |
170 | |||
170 | /// <summary> | 171 | /// <summary> |
171 | /// Asset MetaData ID (transferring from UUID to string ID) | 172 | /// Asset MetaData ID (transferring from UUID to string ID) |
172 | /// </summary> | 173 | /// </summary> |
diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs index cce44b0..72b580b 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(); |
@@ -391,10 +393,14 @@ namespace OpenSim.Framework | |||
391 | public List<AvatarAttachment> GetAttachments() | 393 | public List<AvatarAttachment> GetAttachments() |
392 | { | 394 | { |
393 | List<AvatarAttachment> alist = new List<AvatarAttachment>(); | 395 | List<AvatarAttachment> alist = new List<AvatarAttachment>(); |
394 | foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments) | 396 | |
397 | lock (m_attachments) | ||
395 | { | 398 | { |
396 | foreach (AvatarAttachment attach in kvp.Value) | 399 | foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments) |
397 | alist.Add(new AvatarAttachment(attach)); | 400 | { |
401 | foreach (AvatarAttachment attach in kvp.Value) | ||
402 | alist.Add(new AvatarAttachment(attach)); | ||
403 | } | ||
398 | } | 404 | } |
399 | 405 | ||
400 | return alist; | 406 | return alist; |
@@ -406,10 +412,13 @@ namespace OpenSim.Framework | |||
406 | // "[AVATAR APPEARNCE]: Appending itemID={0}, assetID={1} at {2}", | 412 | // "[AVATAR APPEARNCE]: Appending itemID={0}, assetID={1} at {2}", |
407 | // attach.ItemID, attach.AssetID, attach.AttachPoint); | 413 | // attach.ItemID, attach.AssetID, attach.AttachPoint); |
408 | 414 | ||
409 | if (!m_attachments.ContainsKey(attach.AttachPoint)) | 415 | lock (m_attachments) |
410 | m_attachments[attach.AttachPoint] = new List<AvatarAttachment>(); | 416 | { |
411 | 417 | if (!m_attachments.ContainsKey(attach.AttachPoint)) | |
412 | m_attachments[attach.AttachPoint].Add(attach); | 418 | m_attachments[attach.AttachPoint] = new List<AvatarAttachment>(); |
419 | |||
420 | m_attachments[attach.AttachPoint].Add(attach); | ||
421 | } | ||
413 | } | 422 | } |
414 | 423 | ||
415 | internal void ReplaceAttachment(AvatarAttachment attach) | 424 | internal void ReplaceAttachment(AvatarAttachment attach) |
@@ -418,8 +427,11 @@ namespace OpenSim.Framework | |||
418 | // "[AVATAR APPEARANCE]: Replacing itemID={0}, assetID={1} at {2}", | 427 | // "[AVATAR APPEARANCE]: Replacing itemID={0}, assetID={1} at {2}", |
419 | // attach.ItemID, attach.AssetID, attach.AttachPoint); | 428 | // attach.ItemID, attach.AssetID, attach.AttachPoint); |
420 | 429 | ||
421 | m_attachments[attach.AttachPoint] = new List<AvatarAttachment>(); | 430 | lock (m_attachments) |
422 | m_attachments[attach.AttachPoint].Add(attach); | 431 | { |
432 | m_attachments[attach.AttachPoint] = new List<AvatarAttachment>(); | ||
433 | m_attachments[attach.AttachPoint].Add(attach); | ||
434 | } | ||
423 | } | 435 | } |
424 | 436 | ||
425 | /// <summary> | 437 | /// <summary> |
@@ -448,10 +460,13 @@ namespace OpenSim.Framework | |||
448 | 460 | ||
449 | if (item == UUID.Zero) | 461 | if (item == UUID.Zero) |
450 | { | 462 | { |
451 | if (m_attachments.ContainsKey(attachpoint)) | 463 | lock (m_attachments) |
452 | { | 464 | { |
453 | m_attachments.Remove(attachpoint); | 465 | if (m_attachments.ContainsKey(attachpoint)) |
454 | return true; | 466 | { |
467 | m_attachments.Remove(attachpoint); | ||
468 | return true; | ||
469 | } | ||
455 | } | 470 | } |
456 | 471 | ||
457 | return false; | 472 | return false; |
@@ -494,11 +509,14 @@ namespace OpenSim.Framework | |||
494 | /// <returns>Returns null if this item is not attached.</returns> | 509 | /// <returns>Returns null if this item is not attached.</returns> |
495 | public AvatarAttachment GetAttachmentForItem(UUID itemID) | 510 | public AvatarAttachment GetAttachmentForItem(UUID itemID) |
496 | { | 511 | { |
497 | foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments) | 512 | lock (m_attachments) |
498 | { | 513 | { |
499 | int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; }); | 514 | foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments) |
500 | if (index >= 0) | 515 | { |
501 | return kvp.Value[index]; | 516 | int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; }); |
517 | if (index >= 0) | ||
518 | return kvp.Value[index]; | ||
519 | } | ||
502 | } | 520 | } |
503 | 521 | ||
504 | return null; | 522 | return null; |
@@ -506,11 +524,14 @@ namespace OpenSim.Framework | |||
506 | 524 | ||
507 | public int GetAttachpoint(UUID itemID) | 525 | public int GetAttachpoint(UUID itemID) |
508 | { | 526 | { |
509 | foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments) | 527 | lock (m_attachments) |
510 | { | 528 | { |
511 | int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; }); | 529 | foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments) |
512 | if (index >= 0) | 530 | { |
513 | return kvp.Key; | 531 | int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; }); |
532 | if (index >= 0) | ||
533 | return kvp.Key; | ||
534 | } | ||
514 | } | 535 | } |
515 | 536 | ||
516 | return 0; | 537 | return 0; |
@@ -518,27 +539,32 @@ namespace OpenSim.Framework | |||
518 | 539 | ||
519 | public bool DetachAttachment(UUID itemID) | 540 | public bool DetachAttachment(UUID itemID) |
520 | { | 541 | { |
521 | foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments) | 542 | lock (m_attachments) |
522 | { | 543 | { |
523 | int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; }); | 544 | foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments) |
524 | if (index >= 0) | ||
525 | { | 545 | { |
526 | // Remove it from the list of attachments at that attach point | 546 | int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; }); |
527 | m_attachments[kvp.Key].RemoveAt(index); | 547 | if (index >= 0) |
528 | 548 | { | |
529 | // And remove the list if there are no more attachments here | 549 | // Remove it from the list of attachments at that attach point |
530 | if (m_attachments[kvp.Key].Count == 0) | 550 | m_attachments[kvp.Key].RemoveAt(index); |
531 | m_attachments.Remove(kvp.Key); | 551 | |
532 | 552 | // And remove the list if there are no more attachments here | |
533 | return true; | 553 | if (m_attachments[kvp.Key].Count == 0) |
554 | m_attachments.Remove(kvp.Key); | ||
555 | |||
556 | return true; | ||
557 | } | ||
534 | } | 558 | } |
535 | } | 559 | } |
560 | |||
536 | return false; | 561 | return false; |
537 | } | 562 | } |
538 | 563 | ||
539 | public void ClearAttachments() | 564 | public void ClearAttachments() |
540 | { | 565 | { |
541 | m_attachments.Clear(); | 566 | lock (m_attachments) |
567 | m_attachments.Clear(); | ||
542 | } | 568 | } |
543 | 569 | ||
544 | #region Packing Functions | 570 | #region Packing Functions |
@@ -576,7 +602,8 @@ namespace OpenSim.Framework | |||
576 | data["visualparams"] = visualparams; | 602 | data["visualparams"] = visualparams; |
577 | 603 | ||
578 | // Attachments | 604 | // Attachments |
579 | OSDArray attachs = new OSDArray(m_attachments.Count); | 605 | List<AvatarAttachment> attachments = GetAttachments(); |
606 | OSDArray attachs = new OSDArray(attachments.Count); | ||
580 | foreach (AvatarAttachment attach in GetAttachments()) | 607 | foreach (AvatarAttachment attach in GetAttachments()) |
581 | attachs.Add(attach.Pack()); | 608 | attachs.Add(attach.Pack()); |
582 | data["attachments"] = attachs; | 609 | data["attachments"] = attachs; |
diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index 53ec166..5a4811e 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs | |||
@@ -441,7 +441,6 @@ namespace OpenSim.Framework | |||
441 | args["controllers"] = controls; | 441 | args["controllers"] = controls; |
442 | } | 442 | } |
443 | 443 | ||
444 | |||
445 | if ((CallbackURI != null) && (!CallbackURI.Equals(""))) | 444 | if ((CallbackURI != null) && (!CallbackURI.Equals(""))) |
446 | args["callback_uri"] = OSD.FromString(CallbackURI); | 445 | args["callback_uri"] = OSD.FromString(CallbackURI); |
447 | 446 | ||
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 150ff1b..47e79d1 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs | |||
@@ -935,7 +935,7 @@ namespace OpenSim.Framework | |||
935 | event ScriptReset OnScriptReset; | 935 | event ScriptReset OnScriptReset; |
936 | event GetScriptRunning OnGetScriptRunning; | 936 | event GetScriptRunning OnGetScriptRunning; |
937 | event SetScriptRunning OnSetScriptRunning; | 937 | event SetScriptRunning OnSetScriptRunning; |
938 | event Action<Vector3, bool> OnAutoPilotGo; | 938 | event Action<Vector3, bool, bool> OnAutoPilotGo; |
939 | 939 | ||
940 | event TerrainUnacked OnUnackedTerrain; | 940 | event TerrainUnacked OnUnackedTerrain; |
941 | event ActivateGesture OnActivateGesture; | 941 | event ActivateGesture OnActivateGesture; |
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 745da17..c4fc643 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs | |||
@@ -1372,11 +1372,30 @@ namespace OpenSim.Framework | |||
1372 | return (ipaddr1 != null) ? "http://" + ipaddr1.ToString() + ":" + port1 : uri; | 1372 | return (ipaddr1 != null) ? "http://" + ipaddr1.ToString() + ":" + port1 : uri; |
1373 | } | 1373 | } |
1374 | 1374 | ||
1375 | /// <summary> | ||
1376 | /// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to 256 bytes if necessary. | ||
1377 | /// </summary> | ||
1378 | /// <param name="str"> | ||
1379 | /// If null or empty, then an bytes[0] is returned. | ||
1380 | /// Using "\0" will return a conversion of the null character to a byte. This is not the same as bytes[0] | ||
1381 | /// </param> | ||
1382 | /// <param name="args"> | ||
1383 | /// Arguments to substitute into the string via the {} mechanism. | ||
1384 | /// </param> | ||
1385 | /// <returns></returns> | ||
1375 | public static byte[] StringToBytes256(string str, params object[] args) | 1386 | public static byte[] StringToBytes256(string str, params object[] args) |
1376 | { | 1387 | { |
1377 | return StringToBytes256(string.Format(str, args)); | 1388 | return StringToBytes256(string.Format(str, args)); |
1378 | } | 1389 | } |
1379 | 1390 | ||
1391 | /// <summary> | ||
1392 | /// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to 256 bytes if necessary. | ||
1393 | /// </summary> | ||
1394 | /// <param name="str"> | ||
1395 | /// If null or empty, then an bytes[0] is returned. | ||
1396 | /// Using "\0" will return a conversion of the null character to a byte. This is not the same as bytes[0] | ||
1397 | /// </param> | ||
1398 | /// <returns></returns> | ||
1380 | public static byte[] StringToBytes256(string str) | 1399 | public static byte[] StringToBytes256(string str) |
1381 | { | 1400 | { |
1382 | if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; } | 1401 | if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; } |
@@ -1395,11 +1414,30 @@ namespace OpenSim.Framework | |||
1395 | return data; | 1414 | return data; |
1396 | } | 1415 | } |
1397 | 1416 | ||
1417 | /// <summary> | ||
1418 | /// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to 1024 bytes if necessary. | ||
1419 | /// </summary> | ||
1420 | /// <param name="str"> | ||
1421 | /// If null or empty, then an bytes[0] is returned. | ||
1422 | /// Using "\0" will return a conversion of the null character to a byte. This is not the same as bytes[0] | ||
1423 | /// </param> | ||
1424 | /// <param name="args"> | ||
1425 | /// Arguments to substitute into the string via the {} mechanism. | ||
1426 | /// </param> | ||
1427 | /// <returns></returns> | ||
1398 | public static byte[] StringToBytes1024(string str, params object[] args) | 1428 | public static byte[] StringToBytes1024(string str, params object[] args) |
1399 | { | 1429 | { |
1400 | return StringToBytes1024(string.Format(str, args)); | 1430 | return StringToBytes1024(string.Format(str, args)); |
1401 | } | 1431 | } |
1402 | 1432 | ||
1433 | /// <summary> | ||
1434 | /// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to 1024 bytes if necessary. | ||
1435 | /// </summary> | ||
1436 | /// <param name="str"> | ||
1437 | /// If null or empty, then an bytes[0] is returned. | ||
1438 | /// Using "\0" will return a conversion of the null character to a byte. This is not the same as bytes[0] | ||
1439 | /// </param> | ||
1440 | /// <returns></returns> | ||
1403 | public static byte[] StringToBytes1024(string str) | 1441 | public static byte[] StringToBytes1024(string str) |
1404 | { | 1442 | { |
1405 | if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; } | 1443 | if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; } |
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index fe1525b..e5b9dcb 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs | |||
@@ -269,13 +269,15 @@ namespace OpenSim | |||
269 | 269 | ||
270 | m_console.Commands.AddCommand("region", false, "save oar", | 270 | m_console.Commands.AddCommand("region", false, "save oar", |
271 | //"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]", | 271 | //"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]", |
272 | "save oar [-p|--profile=<url>] [--noassets] [<OAR path>]", | 272 | "save oar [-p|--profile=<url>] [--noassets] [--perm=<permissions>] [<OAR path>]", |
273 | "Save a region's data to an OAR archive.", | 273 | "Save a region's data to an OAR archive.", |
274 | // "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine | 274 | // "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine |
275 | "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine | 275 | "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine |
276 | + " The OAR path must be a filesystem path." | 276 | + "--noassets stops assets being saved to the OAR." + Environment.NewLine |
277 | + " If this is not given then the oar is saved to region.oar in the current directory." + Environment.NewLine | 277 | + "--perm stops objects with insufficient permissions from being saved to the OAR." + Environment.NewLine |
278 | + "--noassets stops assets being saved to the OAR.", | 278 | + " <permissions> can contain one or more of these characters: \"C\" = Copy, \"T\" = Transfer" + Environment.NewLine |
279 | + "The OAR path must be a filesystem path." | ||
280 | + " If this is not given then the oar is saved to region.oar in the current directory.", | ||
279 | SaveOar); | 281 | SaveOar); |
280 | 282 | ||
281 | m_console.Commands.AddCommand("region", false, "edit scale", | 283 | m_console.Commands.AddCommand("region", false, "edit scale", |
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index 00b080c..866ba9a 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs | |||
@@ -41,11 +41,15 @@ using OpenSim.Framework.Servers; | |||
41 | using OpenSim.Framework.Servers.HttpServer; | 41 | using OpenSim.Framework.Servers.HttpServer; |
42 | using OpenSim.Framework.Statistics; | 42 | using OpenSim.Framework.Statistics; |
43 | using OpenSim.Region.ClientStack; | 43 | using OpenSim.Region.ClientStack; |
44 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts; | ||
44 | using OpenSim.Region.Framework; | 45 | using OpenSim.Region.Framework; |
45 | using OpenSim.Region.Framework.Interfaces; | 46 | using OpenSim.Region.Framework.Interfaces; |
46 | using OpenSim.Region.Framework.Scenes; | 47 | using OpenSim.Region.Framework.Scenes; |
47 | using OpenSim.Region.Physics.Manager; | 48 | using OpenSim.Region.Physics.Manager; |
48 | using OpenSim.Server.Base; | 49 | using OpenSim.Server.Base; |
50 | using OpenSim.Services.Base; | ||
51 | using OpenSim.Services.Interfaces; | ||
52 | using OpenSim.Services.UserAccountService; | ||
49 | 53 | ||
50 | namespace OpenSim | 54 | namespace OpenSim |
51 | { | 55 | { |
@@ -362,6 +366,9 @@ namespace OpenSim | |||
362 | 366 | ||
363 | scene.SetModuleInterfaces(); | 367 | scene.SetModuleInterfaces(); |
364 | 368 | ||
369 | while (regionInfo.EstateSettings.EstateOwner == UUID.Zero && MainConsole.Instance != null) | ||
370 | SetUpEstateOwner(scene); | ||
371 | |||
365 | // Prims have to be loaded after module configuration since some modules may be invoked during the load | 372 | // Prims have to be loaded after module configuration since some modules may be invoked during the load |
366 | scene.LoadPrimsFromStorage(regionInfo.originRegionID); | 373 | scene.LoadPrimsFromStorage(regionInfo.originRegionID); |
367 | 374 | ||
@@ -411,9 +418,69 @@ namespace OpenSim | |||
411 | 418 | ||
412 | scene.StartTimer(); | 419 | scene.StartTimer(); |
413 | 420 | ||
421 | scene.StartScripts(); | ||
422 | |||
414 | return clientServer; | 423 | return clientServer; |
415 | } | 424 | } |
416 | 425 | ||
426 | /// <summary> | ||
427 | /// Try to set up the estate owner for the given scene. | ||
428 | /// </summary> | ||
429 | /// <remarks> | ||
430 | /// The involves asking the user for information about the user on the console. If the user does not already | ||
431 | /// exist then it is created. | ||
432 | /// </remarks> | ||
433 | /// <param name="scene"></param> | ||
434 | private void SetUpEstateOwner(Scene scene) | ||
435 | { | ||
436 | RegionInfo regionInfo = scene.RegionInfo; | ||
437 | |||
438 | MainConsole.Instance.OutputFormat("Estate {0} has no owner set.", regionInfo.EstateSettings.EstateName); | ||
439 | List<char> excluded = new List<char>(new char[1]{' '}); | ||
440 | string first = MainConsole.Instance.CmdPrompt("Estate owner first name", "Test", excluded); | ||
441 | string last = MainConsole.Instance.CmdPrompt("Estate owner last name", "User", excluded); | ||
442 | |||
443 | UserAccount account = scene.UserAccountService.GetUserAccount(regionInfo.ScopeID, first, last); | ||
444 | |||
445 | if (account == null) | ||
446 | { | ||
447 | |||
448 | // XXX: The LocalUserAccountServicesConnector is currently registering its inner service rather than | ||
449 | // itself! | ||
450 | // if (scene.UserAccountService is LocalUserAccountServicesConnector) | ||
451 | // { | ||
452 | // IUserAccountService innerUas | ||
453 | // = ((LocalUserAccountServicesConnector)scene.UserAccountService).UserAccountService; | ||
454 | // | ||
455 | // m_log.DebugFormat("B {0}", innerUas.GetType()); | ||
456 | // | ||
457 | // if (innerUas is UserAccountService) | ||
458 | // { | ||
459 | |||
460 | if (scene.UserAccountService is UserAccountService) | ||
461 | { | ||
462 | string password = MainConsole.Instance.PasswdPrompt("Password"); | ||
463 | string email = MainConsole.Instance.CmdPrompt("Email", ""); | ||
464 | |||
465 | account | ||
466 | = ((UserAccountService)scene.UserAccountService).CreateUser( | ||
467 | regionInfo.ScopeID, first, last, password, email); | ||
468 | } | ||
469 | // } | ||
470 | } | ||
471 | |||
472 | if (account == null) | ||
473 | { | ||
474 | m_log.ErrorFormat( | ||
475 | "[OPENSIM]: Unable to store account. If this simulator is connected to a grid, you must create the estate owner account first."); | ||
476 | } | ||
477 | else | ||
478 | { | ||
479 | regionInfo.EstateSettings.EstateOwner = account.PrincipalID; | ||
480 | regionInfo.EstateSettings.Save(); | ||
481 | } | ||
482 | } | ||
483 | |||
417 | private void ShutdownRegion(Scene scene) | 484 | private void ShutdownRegion(Scene scene) |
418 | { | 485 | { |
419 | m_log.DebugFormat("[SHUTDOWN]: Shutting down region {0}", scene.RegionInfo.RegionName); | 486 | m_log.DebugFormat("[SHUTDOWN]: Shutting down region {0}", scene.RegionInfo.RegionName); |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index e9ee7be..ce2ff86 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -231,7 +231,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
231 | public event ScriptReset OnScriptReset; | 231 | public event ScriptReset OnScriptReset; |
232 | public event GetScriptRunning OnGetScriptRunning; | 232 | public event GetScriptRunning OnGetScriptRunning; |
233 | public event SetScriptRunning OnSetScriptRunning; | 233 | public event SetScriptRunning OnSetScriptRunning; |
234 | public event Action<Vector3, bool> OnAutoPilotGo; | 234 | public event Action<Vector3, bool, bool> OnAutoPilotGo; |
235 | public event TerrainUnacked OnUnackedTerrain; | 235 | public event TerrainUnacked OnUnackedTerrain; |
236 | public event ActivateGesture OnActivateGesture; | 236 | public event ActivateGesture OnActivateGesture; |
237 | public event DeactivateGesture OnDeactivateGesture; | 237 | public event DeactivateGesture OnDeactivateGesture; |
@@ -4119,8 +4119,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4119 | while (updatesThisCall < m_maxUpdates) | 4119 | while (updatesThisCall < m_maxUpdates) |
4120 | { | 4120 | { |
4121 | lock (m_entityProps.SyncRoot) | 4121 | lock (m_entityProps.SyncRoot) |
4122 | if (!m_entityProps.TryDequeue(out iupdate, out timeinqueue)) | 4122 | if (!m_entityProps.TryDequeue(out iupdate, out timeinqueue)) |
4123 | break; | 4123 | break; |
4124 | 4124 | ||
4125 | ObjectPropertyUpdate update = (ObjectPropertyUpdate)iupdate; | 4125 | ObjectPropertyUpdate update = (ObjectPropertyUpdate)iupdate; |
4126 | if (update.SendFamilyProps) | 4126 | if (update.SendFamilyProps) |
@@ -11640,9 +11640,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
11640 | locy = Convert.ToSingle(args[1]) - (float)regionY; | 11640 | locy = Convert.ToSingle(args[1]) - (float)regionY; |
11641 | locz = Convert.ToSingle(args[2]); | 11641 | locz = Convert.ToSingle(args[2]); |
11642 | 11642 | ||
11643 | Action<Vector3, bool> handlerAutoPilotGo = OnAutoPilotGo; | 11643 | Action<Vector3, bool, bool> handlerAutoPilotGo = OnAutoPilotGo; |
11644 | if (handlerAutoPilotGo != null) | 11644 | if (handlerAutoPilotGo != null) |
11645 | handlerAutoPilotGo(new Vector3(locx, locy, locz), false); | 11645 | handlerAutoPilotGo(new Vector3(locx, locy, locz), false, false); |
11646 | } | 11646 | } |
11647 | 11647 | ||
11648 | /// <summary> | 11648 | /// <summary> |
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs index 9d8082b..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,28 +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 | AssetBase asset = GetTransactionAsset(transactionID); | ||
172 | 248 | ||
173 | if (asset != null) | 249 | lock (XferUploaders) |
174 | { | 250 | { |
175 | asset.FullID = UUID.Random(); | 251 | if (XferUploaders.ContainsKey(transactionID)) |
176 | asset.Name = item.Name; | 252 | uploader = XferUploaders[transactionID]; |
177 | asset.Description = item.Description; | 253 | } |
178 | asset.Type = (sbyte)item.AssetType; | ||
179 | item.AssetID = asset.FullID; | ||
180 | |||
181 | m_Scene.AssetService.Store(asset); | ||
182 | 254 | ||
183 | IInventoryService invService = m_Scene.InventoryService; | 255 | if (uploader != null) |
184 | invService.UpdateItem(item); | 256 | { |
185 | } | 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); | ||
186 | } | 264 | } |
187 | } | 265 | } |
188 | } | 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 a7929ba..ec4dfd0 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs | |||
@@ -40,11 +40,21 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
40 | { | 40 | { |
41 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 41 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
42 | 42 | ||
43 | /// <summary> | ||
44 | /// Reference to the object that holds this uploader. Used to remove ourselves from it's list if we | ||
45 | /// are performing a delayed update. | ||
46 | /// </summary> | ||
47 | AgentAssetTransactions m_transactions; | ||
48 | |||
43 | private AssetBase m_asset; | 49 | private AssetBase m_asset; |
44 | private UUID InventFolder = UUID.Zero; | 50 | private UUID InventFolder = UUID.Zero; |
45 | private sbyte invType = 0; | 51 | private sbyte invType = 0; |
52 | |||
46 | private bool m_createItem = false; | 53 | private bool m_createItem = false; |
47 | private uint m_createItemCallback = 0; | 54 | private uint m_createItemCallback = 0; |
55 | private bool m_updateItem = false; | ||
56 | private InventoryItemBase m_updateItemData; | ||
57 | |||
48 | private string m_description = String.Empty; | 58 | private string m_description = String.Empty; |
49 | private bool m_dumpAssetToFile; | 59 | private bool m_dumpAssetToFile; |
50 | private bool m_finished = false; | 60 | private bool m_finished = false; |
@@ -58,9 +68,11 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
58 | public ulong XferID; | 68 | public ulong XferID; |
59 | private Scene m_Scene; | 69 | private Scene m_Scene; |
60 | 70 | ||
61 | public AssetXferUploader(Scene scene, bool dumpAssetToFile) | 71 | public AssetXferUploader(AgentAssetTransactions transactions, Scene scene, UUID assetID, bool dumpAssetToFile) |
62 | { | 72 | { |
73 | m_transactions = transactions; | ||
63 | m_Scene = scene; | 74 | m_Scene = scene; |
75 | m_asset = new AssetBase() { FullID = assetID }; | ||
64 | m_dumpAssetToFile = dumpAssetToFile; | 76 | m_dumpAssetToFile = dumpAssetToFile; |
65 | } | 77 | } |
66 | 78 | ||
@@ -73,6 +85,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
73 | /// <returns>True if the transfer is complete, false otherwise or if the xferID was not valid</returns> | 85 | /// <returns>True if the transfer is complete, false otherwise or if the xferID was not valid</returns> |
74 | public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data) | 86 | public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data) |
75 | { | 87 | { |
88 | // m_log.DebugFormat( | ||
89 | // "[ASSET XFER UPLOADER]: Received packet {0} for xfer {1} (data length {2})", | ||
90 | // packetID, xferID, data.Length); | ||
91 | |||
76 | if (XferID == xferID) | 92 | if (XferID == xferID) |
77 | { | 93 | { |
78 | if (m_asset.Data.Length > 1) | 94 | if (m_asset.Data.Length > 1) |
@@ -107,16 +123,20 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
107 | /// <param name="xferID"></param> | 123 | /// <param name="xferID"></param> |
108 | /// <param name="packetID"></param> | 124 | /// <param name="packetID"></param> |
109 | /// <param name="data"></param> | 125 | /// <param name="data"></param> |
110 | /// <returns>True if the transfer is complete, false otherwise</returns> | 126 | public void Initialise(IClientAPI remoteClient, UUID assetID, |
111 | public bool Initialise(IClientAPI remoteClient, UUID assetID, | ||
112 | UUID transaction, sbyte type, byte[] data, bool storeLocal, | 127 | UUID transaction, sbyte type, byte[] data, bool storeLocal, |
113 | bool tempFile) | 128 | bool tempFile) |
114 | { | 129 | { |
130 | // m_log.DebugFormat( | ||
131 | // "[ASSET XFER UPLOADER]: Initialised xfer from {0}, asset {1}, transaction {2}, type {3}, storeLocal {4}, tempFile {5}, already received data length {6}", | ||
132 | // remoteClient.Name, assetID, transaction, type, storeLocal, tempFile, data.Length); | ||
133 | |||
115 | ourClient = remoteClient; | 134 | ourClient = remoteClient; |
116 | m_asset = new AssetBase(assetID, "blank", type, | 135 | m_asset.Name = "blank"; |
117 | remoteClient.AgentId.ToString()); | ||
118 | m_asset.Data = data; | ||
119 | m_asset.Description = "empty"; | 136 | m_asset.Description = "empty"; |
137 | m_asset.Type = type; | ||
138 | m_asset.CreatorID = remoteClient.AgentId.ToString(); | ||
139 | m_asset.Data = data; | ||
120 | m_asset.Local = storeLocal; | 140 | m_asset.Local = storeLocal; |
121 | m_asset.Temporary = tempFile; | 141 | m_asset.Temporary = tempFile; |
122 | 142 | ||
@@ -126,21 +146,22 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
126 | if (m_asset.Data.Length > 2) | 146 | if (m_asset.Data.Length > 2) |
127 | { | 147 | { |
128 | SendCompleteMessage(); | 148 | SendCompleteMessage(); |
129 | return true; | ||
130 | } | 149 | } |
131 | else | 150 | else |
132 | { | 151 | { |
133 | RequestStartXfer(); | 152 | RequestStartXfer(); |
134 | } | 153 | } |
135 | |||
136 | return false; | ||
137 | } | 154 | } |
138 | 155 | ||
139 | protected void RequestStartXfer() | 156 | protected void RequestStartXfer() |
140 | { | 157 | { |
141 | XferID = Util.GetNextXferID(); | 158 | XferID = Util.GetNextXferID(); |
142 | ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, | 159 | |
143 | 0, new byte[0]); | 160 | // m_log.DebugFormat( |
161 | // "[ASSET XFER UPLOADER]: Requesting Xfer of asset {0}, type {1}, transfer id {2} from {3}", | ||
162 | // m_asset.FullID, m_asset.Type, XferID, ourClient.Name); | ||
163 | |||
164 | ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, 0, new byte[0]); | ||
144 | } | 165 | } |
145 | 166 | ||
146 | protected void SendCompleteMessage() | 167 | protected void SendCompleteMessage() |
@@ -148,18 +169,32 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
148 | ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, | 169 | ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, |
149 | m_asset.FullID); | 170 | m_asset.FullID); |
150 | 171 | ||
151 | m_finished = true; | 172 | // We must lock in order to avoid a race with a separate thread dealing with an inventory item or create |
152 | if (m_createItem) | 173 | // message from other client UDP. |
153 | { | 174 | lock (this) |
154 | DoCreateItem(m_createItemCallback); | ||
155 | } | ||
156 | else if (m_storeLocal) | ||
157 | { | 175 | { |
158 | m_Scene.AssetService.Store(m_asset); | 176 | m_finished = true; |
177 | if (m_createItem) | ||
178 | { | ||
179 | DoCreateItem(m_createItemCallback); | ||
180 | } | ||
181 | else if (m_updateItem) | ||
182 | { | ||
183 | StoreAssetForItemUpdate(m_updateItemData); | ||
184 | |||
185 | // Remove ourselves from the list of transactions if completion was delayed until the transaction | ||
186 | // was complete. | ||
187 | // TODO: Should probably do the same for create item. | ||
188 | m_transactions.RemoveXferUploader(TransactionID); | ||
189 | } | ||
190 | else if (m_storeLocal) | ||
191 | { | ||
192 | m_Scene.AssetService.Store(m_asset); | ||
193 | } | ||
159 | } | 194 | } |
160 | 195 | ||
161 | m_log.DebugFormat( | 196 | m_log.DebugFormat( |
162 | "[ASSET TRANSACTIONS]: Uploaded asset {0} for transaction {1}", | 197 | "[ASSET XFER UPLOADER]: Uploaded asset {0} for transaction {1}", |
163 | m_asset.FullID, TransactionID); | 198 | m_asset.FullID, TransactionID); |
164 | 199 | ||
165 | if (m_dumpAssetToFile) | 200 | if (m_dumpAssetToFile) |
@@ -205,18 +240,66 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
205 | m_asset.Description = description; | 240 | m_asset.Description = description; |
206 | m_asset.Type = type; | 241 | m_asset.Type = type; |
207 | 242 | ||
243 | // We must lock to avoid a race with a separate thread uploading the asset. | ||
244 | lock (this) | ||
245 | { | ||
246 | if (m_finished) | ||
247 | { | ||
248 | DoCreateItem(callbackID); | ||
249 | } | ||
250 | else | ||
251 | { | ||
252 | m_createItem = true; //set flag so the inventory item is created when upload is complete | ||
253 | m_createItemCallback = callbackID; | ||
254 | } | ||
255 | } | ||
256 | } | ||
257 | } | ||
258 | |||
259 | public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID, InventoryItemBase item) | ||
260 | { | ||
261 | // We must lock to avoid a race with a separate thread uploading the asset. | ||
262 | lock (this) | ||
263 | { | ||
264 | m_asset.Name = item.Name; | ||
265 | m_asset.Description = item.Description; | ||
266 | m_asset.Type = (sbyte)item.AssetType; | ||
267 | |||
268 | // We must always store the item at this point even if the asset hasn't finished uploading, in order | ||
269 | // to avoid a race condition when the appearance module retrieves the item to set the asset id in | ||
270 | // the AvatarAppearance structure. | ||
271 | item.AssetID = m_asset.FullID; | ||
272 | m_Scene.InventoryService.UpdateItem(item); | ||
273 | |||
208 | if (m_finished) | 274 | if (m_finished) |
209 | { | 275 | { |
210 | DoCreateItem(callbackID); | 276 | StoreAssetForItemUpdate(item); |
211 | } | 277 | } |
212 | else | 278 | else |
213 | { | 279 | { |
214 | m_createItem = true; //set flag so the inventory item is created when upload is complete | 280 | // m_log.DebugFormat( |
215 | m_createItemCallback = callbackID; | 281 | // "[ASSET XFER UPLOADER]: Holding update inventory item request {0} for {1} pending completion of asset xfer for transaction {2}", |
282 | // item.Name, remoteClient.Name, transactionID); | ||
283 | |||
284 | m_updateItem = true; | ||
285 | m_updateItemData = item; | ||
216 | } | 286 | } |
217 | } | 287 | } |
218 | } | 288 | } |
219 | 289 | ||
290 | /// <summary> | ||
291 | /// Store the asset for the given item. | ||
292 | /// </summary> | ||
293 | /// <param name="item"></param> | ||
294 | private void StoreAssetForItemUpdate(InventoryItemBase item) | ||
295 | { | ||
296 | // m_log.DebugFormat( | ||
297 | // "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}", | ||
298 | // m_asset.FullID, item.Name, ourClient.Name); | ||
299 | |||
300 | m_Scene.AssetService.Store(m_asset); | ||
301 | } | ||
302 | |||
220 | private void DoCreateItem(uint callbackID) | 303 | private void DoCreateItem(uint callbackID) |
221 | { | 304 | { |
222 | m_Scene.AssetService.Store(m_asset); | 305 | m_Scene.AssetService.Store(m_asset); |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 996e2ab..b965d75 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -143,20 +143,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
143 | 143 | ||
144 | public void SaveChangedAttachments(IScenePresence sp) | 144 | public void SaveChangedAttachments(IScenePresence sp) |
145 | { | 145 | { |
146 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); | ||
147 | |||
146 | foreach (SceneObjectGroup grp in sp.GetAttachments()) | 148 | foreach (SceneObjectGroup grp in sp.GetAttachments()) |
147 | { | 149 | { |
148 | if (grp.HasGroupChanged) // Resizer scripts? | 150 | // if (grp.HasGroupChanged) // Resizer scripts? |
149 | { | 151 | // { |
150 | grp.IsAttachment = false; | 152 | grp.IsAttachment = false; |
151 | grp.AbsolutePosition = grp.RootPart.AttachedPos; | 153 | grp.AbsolutePosition = grp.RootPart.AttachedPos; |
152 | UpdateKnownItem(sp.ControllingClient, grp, grp.GetFromItemID(), grp.OwnerID); | 154 | UpdateKnownItem(sp.ControllingClient, grp); |
153 | grp.IsAttachment = true; | 155 | grp.IsAttachment = true; |
154 | } | 156 | // } |
155 | } | 157 | } |
156 | } | 158 | } |
157 | 159 | ||
158 | public void DeleteAttachmentsFromScene(IScenePresence sp, bool silent) | 160 | public void DeleteAttachmentsFromScene(IScenePresence sp, bool silent) |
159 | { | 161 | { |
162 | // m_log.DebugFormat( | ||
163 | // "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}", | ||
164 | // m_scene.RegionInfo.RegionName, sp.Name, silent); | ||
165 | |||
160 | foreach (SceneObjectGroup sop in sp.GetAttachments()) | 166 | foreach (SceneObjectGroup sop in sp.GetAttachments()) |
161 | { | 167 | { |
162 | sop.Scene.DeleteSceneObject(sop, silent); | 168 | sop.Scene.DeleteSceneObject(sop, silent); |
@@ -212,7 +218,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
212 | m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); | 218 | m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); |
213 | 219 | ||
214 | // Save avatar attachment information | 220 | // Save avatar attachment information |
215 | m_log.Info( | 221 | m_log.Debug( |
216 | "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId | 222 | "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId |
217 | + ", AttachmentPoint: " + AttachmentPt); | 223 | + ", AttachmentPoint: " + AttachmentPt); |
218 | 224 | ||
@@ -240,80 +246,83 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
240 | 246 | ||
241 | private bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent) | 247 | private bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent) |
242 | { | 248 | { |
243 | // m_log.DebugFormat( | 249 | lock (sp.AttachmentsSyncLock) |
244 | // "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", | ||
245 | // group.Name, group.LocalId, sp.Name, attachmentPt, silent); | ||
246 | |||
247 | if (sp.GetAttachments(attachmentPt).Contains(group)) | ||
248 | { | ||
249 | // m_log.WarnFormat( | ||
250 | // "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", | ||
251 | // group.Name, group.LocalId, sp.Name, AttachmentPt); | ||
252 | |||
253 | return false; | ||
254 | } | ||
255 | |||
256 | Vector3 attachPos = group.AbsolutePosition; | ||
257 | |||
258 | // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should | ||
259 | // be removed when that functionality is implemented in opensim | ||
260 | attachmentPt &= 0x7f; | ||
261 | |||
262 | // If the attachment point isn't the same as the one previously used | ||
263 | // set it's offset position = 0 so that it appears on the attachment point | ||
264 | // and not in a weird location somewhere unknown. | ||
265 | if (attachmentPt != 0 && attachmentPt != group.AttachmentPoint) | ||
266 | { | ||
267 | attachPos = Vector3.Zero; | ||
268 | } | ||
269 | |||
270 | // AttachmentPt 0 means the client chose to 'wear' the attachment. | ||
271 | if (attachmentPt == 0) | ||
272 | { | ||
273 | // Check object for stored attachment point | ||
274 | attachmentPt = group.AttachmentPoint; | ||
275 | } | ||
276 | |||
277 | // if we still didn't find a suitable attachment point....... | ||
278 | if (attachmentPt == 0) | ||
279 | { | ||
280 | // Stick it on left hand with Zero Offset from the attachment point. | ||
281 | attachmentPt = (uint)AttachmentPoint.LeftHand; | ||
282 | attachPos = Vector3.Zero; | ||
283 | } | ||
284 | |||
285 | group.AttachmentPoint = attachmentPt; | ||
286 | group.AbsolutePosition = attachPos; | ||
287 | |||
288 | // We also don't want to do any of the inventory operations for an NPC. | ||
289 | if (sp.PresenceType != PresenceType.Npc) | ||
290 | { | 250 | { |
291 | // Remove any previous attachments | 251 | // m_log.DebugFormat( |
292 | List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); | 252 | // "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", |
293 | 253 | // group.Name, group.LocalId, sp.Name, attachmentPt, silent); | |
294 | // At the moment we can only deal with a single attachment | 254 | |
295 | if (attachments.Count != 0) | 255 | if (sp.GetAttachments(attachmentPt).Contains(group)) |
296 | { | 256 | { |
297 | UUID oldAttachmentItemID = attachments[0].GetFromItemID(); | 257 | // m_log.WarnFormat( |
258 | // "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", | ||
259 | // group.Name, group.LocalId, sp.Name, AttachmentPt); | ||
298 | 260 | ||
299 | if (oldAttachmentItemID != UUID.Zero) | 261 | return false; |
300 | DetachSingleAttachmentToInv(oldAttachmentItemID, sp); | ||
301 | else | ||
302 | m_log.WarnFormat( | ||
303 | "[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!", | ||
304 | attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name); | ||
305 | } | 262 | } |
306 | |||
307 | // Add the new attachment to inventory if we don't already have it. | ||
308 | UUID newAttachmentItemID = group.GetFromItemID(); | ||
309 | if (newAttachmentItemID == UUID.Zero) | ||
310 | newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp.ControllingClient, group).ID; | ||
311 | 263 | ||
312 | ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group); | 264 | Vector3 attachPos = group.AbsolutePosition; |
265 | |||
266 | // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should | ||
267 | // be removed when that functionality is implemented in opensim | ||
268 | attachmentPt &= 0x7f; | ||
269 | |||
270 | // If the attachment point isn't the same as the one previously used | ||
271 | // set it's offset position = 0 so that it appears on the attachment point | ||
272 | // and not in a weird location somewhere unknown. | ||
273 | if (attachmentPt != 0 && attachmentPt != group.AttachmentPoint) | ||
274 | { | ||
275 | attachPos = Vector3.Zero; | ||
276 | } | ||
277 | |||
278 | // AttachmentPt 0 means the client chose to 'wear' the attachment. | ||
279 | if (attachmentPt == 0) | ||
280 | { | ||
281 | // Check object for stored attachment point | ||
282 | attachmentPt = group.AttachmentPoint; | ||
283 | } | ||
284 | |||
285 | // if we still didn't find a suitable attachment point....... | ||
286 | if (attachmentPt == 0) | ||
287 | { | ||
288 | // Stick it on left hand with Zero Offset from the attachment point. | ||
289 | attachmentPt = (uint)AttachmentPoint.LeftHand; | ||
290 | attachPos = Vector3.Zero; | ||
291 | } | ||
292 | |||
293 | group.AttachmentPoint = attachmentPt; | ||
294 | group.AbsolutePosition = attachPos; | ||
295 | |||
296 | // We also don't want to do any of the inventory operations for an NPC. | ||
297 | if (sp.PresenceType != PresenceType.Npc) | ||
298 | { | ||
299 | // Remove any previous attachments | ||
300 | List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); | ||
301 | |||
302 | // At the moment we can only deal with a single attachment | ||
303 | if (attachments.Count != 0) | ||
304 | { | ||
305 | UUID oldAttachmentItemID = attachments[0].GetFromItemID(); | ||
306 | |||
307 | if (oldAttachmentItemID != UUID.Zero) | ||
308 | DetachSingleAttachmentToInv(oldAttachmentItemID, sp); | ||
309 | else | ||
310 | m_log.WarnFormat( | ||
311 | "[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!", | ||
312 | attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name); | ||
313 | } | ||
314 | |||
315 | // Add the new attachment to inventory if we don't already have it. | ||
316 | UUID newAttachmentItemID = group.GetFromItemID(); | ||
317 | if (newAttachmentItemID == UUID.Zero) | ||
318 | newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp.ControllingClient, group).ID; | ||
319 | |||
320 | ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group); | ||
321 | } | ||
322 | |||
323 | AttachToAgent(sp, group, attachmentPt, attachPos, silent); | ||
313 | } | 324 | } |
314 | 325 | ||
315 | AttachToAgent(sp, group, attachmentPt, attachPos, silent); | ||
316 | |||
317 | return true; | 326 | return true; |
318 | } | 327 | } |
319 | 328 | ||
@@ -322,17 +331,31 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
322 | RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header, | 331 | RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header, |
323 | RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects) | 332 | RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects) |
324 | { | 333 | { |
325 | foreach (RezMultipleAttachmentsFromInvPacket.ObjectDataBlock obj in objects) | 334 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); |
335 | |||
336 | if (sp == null) | ||
326 | { | 337 | { |
327 | RezSingleAttachmentFromInventory(remoteClient, obj.ItemID, obj.AttachmentPt); | 338 | m_log.ErrorFormat( |
339 | "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezMultipleAttachmentsFromInventory()", | ||
340 | remoteClient.Name, remoteClient.AgentId); | ||
341 | return; | ||
342 | } | ||
343 | |||
344 | lock (sp.AttachmentsSyncLock) | ||
345 | { | ||
346 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name); | ||
347 | |||
348 | foreach (RezMultipleAttachmentsFromInvPacket.ObjectDataBlock obj in objects) | ||
349 | { | ||
350 | RezSingleAttachmentFromInventory(sp, obj.ItemID, obj.AttachmentPt); | ||
351 | } | ||
328 | } | 352 | } |
329 | } | 353 | } |
330 | 354 | ||
331 | public ISceneEntity RezSingleAttachmentFromInventory( | 355 | public ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) |
332 | IClientAPI remoteClient, UUID itemID, uint AttachmentPt) | ||
333 | { | 356 | { |
334 | // m_log.DebugFormat( | 357 | // m_log.DebugFormat( |
335 | // "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}", | 358 | // "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}", |
336 | // (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name); | 359 | // (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name); |
337 | 360 | ||
338 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); | 361 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); |
@@ -344,11 +367,46 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
344 | remoteClient.Name, remoteClient.AgentId); | 367 | remoteClient.Name, remoteClient.AgentId); |
345 | return null; | 368 | return null; |
346 | } | 369 | } |
347 | 370 | ||
371 | return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt); | ||
372 | } | ||
373 | |||
374 | public ISceneEntity RezSingleAttachmentFromInventory(ScenePresence sp, UUID itemID, uint AttachmentPt) | ||
375 | { | ||
376 | // m_log.DebugFormat( | ||
377 | // "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}", | ||
378 | // (AttachmentPoint)AttachmentPt, itemID, sp.Name); | ||
379 | |||
348 | // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should | 380 | // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should |
349 | // be removed when that functionality is implemented in opensim | 381 | // be removed when that functionality is implemented in opensim |
350 | AttachmentPt &= 0x7f; | 382 | AttachmentPt &= 0x7f; |
351 | 383 | ||
384 | // Viewer 2/3 sometimes asks to re-wear items that are already worn (and show up in it's inventory as such). | ||
385 | // This often happens during login - not sure the exact reason. | ||
386 | // For now, we will ignore the request. Unfortunately, this means that we need to dig through all the | ||
387 | // ScenePresence attachments. We can't use the data in AvatarAppearance because that's present at login | ||
388 | // before anything has actually been attached. | ||
389 | bool alreadyOn = false; | ||
390 | List<SceneObjectGroup> existingAttachments = sp.GetAttachments(); | ||
391 | foreach (SceneObjectGroup so in existingAttachments) | ||
392 | { | ||
393 | if (so.GetFromItemID() == itemID) | ||
394 | { | ||
395 | alreadyOn = true; | ||
396 | break; | ||
397 | } | ||
398 | } | ||
399 | |||
400 | // if (sp.Appearance.GetAttachmentForItem(itemID) != null) | ||
401 | if (alreadyOn) | ||
402 | { | ||
403 | // m_log.WarnFormat( | ||
404 | // "[ATTACHMENTS MODULE]: Ignoring request by {0} to wear item {1} at {2} since it is already worn", | ||
405 | // sp.Name, itemID, AttachmentPt); | ||
406 | |||
407 | return null; | ||
408 | } | ||
409 | |||
352 | SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt); | 410 | SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt); |
353 | 411 | ||
354 | if (att == null) | 412 | if (att == null) |
@@ -363,65 +421,68 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
363 | IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>(); | 421 | IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>(); |
364 | if (invAccess != null) | 422 | if (invAccess != null) |
365 | { | 423 | { |
366 | SceneObjectGroup objatt; | 424 | lock (sp.AttachmentsSyncLock) |
367 | |||
368 | if (itemID != UUID.Zero) | ||
369 | objatt = invAccess.RezObject(sp.ControllingClient, | ||
370 | itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, | ||
371 | false, false, sp.UUID, true); | ||
372 | else | ||
373 | objatt = invAccess.RezObject(sp.ControllingClient, | ||
374 | null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, | ||
375 | false, false, sp.UUID, true); | ||
376 | |||
377 | // m_log.DebugFormat( | ||
378 | // "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}", | ||
379 | // objatt.Name, remoteClient.Name, AttachmentPt); | ||
380 | |||
381 | if (objatt != null) | ||
382 | { | 425 | { |
383 | // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. | 426 | SceneObjectGroup objatt; |
384 | objatt.HasGroupChanged = false; | 427 | |
385 | bool tainted = false; | 428 | if (itemID != UUID.Zero) |
386 | if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) | 429 | objatt = invAccess.RezObject(sp.ControllingClient, |
387 | tainted = true; | 430 | itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, |
388 | 431 | false, false, sp.UUID, true); | |
389 | // This will throw if the attachment fails | 432 | else |
390 | try | 433 | objatt = invAccess.RezObject(sp.ControllingClient, |
434 | null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, | ||
435 | false, false, sp.UUID, true); | ||
436 | |||
437 | // m_log.DebugFormat( | ||
438 | // "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}", | ||
439 | // objatt.Name, remoteClient.Name, AttachmentPt); | ||
440 | |||
441 | if (objatt != null) | ||
391 | { | 442 | { |
392 | AttachObject(sp, objatt, attachmentPt, false); | 443 | // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. |
444 | objatt.HasGroupChanged = false; | ||
445 | bool tainted = false; | ||
446 | if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) | ||
447 | tainted = true; | ||
448 | |||
449 | // This will throw if the attachment fails | ||
450 | try | ||
451 | { | ||
452 | AttachObject(sp, objatt, attachmentPt, false); | ||
453 | } | ||
454 | catch (Exception e) | ||
455 | { | ||
456 | m_log.ErrorFormat( | ||
457 | "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}", | ||
458 | objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); | ||
459 | |||
460 | // Make sure the object doesn't stick around and bail | ||
461 | sp.RemoveAttachment(objatt); | ||
462 | m_scene.DeleteSceneObject(objatt, false); | ||
463 | return null; | ||
464 | } | ||
465 | |||
466 | if (tainted) | ||
467 | objatt.HasGroupChanged = true; | ||
468 | |||
469 | // Fire after attach, so we don't get messy perms dialogs | ||
470 | // 4 == AttachedRez | ||
471 | objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); | ||
472 | objatt.ResumeScripts(); | ||
473 | |||
474 | // Do this last so that event listeners have access to all the effects of the attachment | ||
475 | m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID); | ||
476 | |||
477 | return objatt; | ||
393 | } | 478 | } |
394 | catch (Exception e) | 479 | else |
395 | { | 480 | { |
396 | m_log.ErrorFormat( | 481 | m_log.WarnFormat( |
397 | "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}", | 482 | "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", |
398 | objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); | 483 | itemID, sp.Name, attachmentPt); |
399 | |||
400 | // Make sure the object doesn't stick around and bail | ||
401 | sp.RemoveAttachment(objatt); | ||
402 | m_scene.DeleteSceneObject(objatt, false); | ||
403 | return null; | ||
404 | } | 484 | } |
405 | |||
406 | if (tainted) | ||
407 | objatt.HasGroupChanged = true; | ||
408 | |||
409 | // Fire after attach, so we don't get messy perms dialogs | ||
410 | // 4 == AttachedRez | ||
411 | objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); | ||
412 | objatt.ResumeScripts(); | ||
413 | |||
414 | // Do this last so that event listeners have access to all the effects of the attachment | ||
415 | m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID); | ||
416 | } | ||
417 | else | ||
418 | { | ||
419 | m_log.WarnFormat( | ||
420 | "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", | ||
421 | itemID, sp.Name, attachmentPt); | ||
422 | } | 485 | } |
423 | |||
424 | return objatt; | ||
425 | } | 486 | } |
426 | 487 | ||
427 | return null; | 488 | return null; |
@@ -438,8 +499,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
438 | IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att) | 499 | IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att) |
439 | { | 500 | { |
440 | // m_log.DebugFormat( | 501 | // m_log.DebugFormat( |
441 | // "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", | 502 | // "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", |
442 | // att.Name, remoteClient.Name, AttachmentPt, itemID); | 503 | // att.Name, sp.Name, AttachmentPt, itemID); |
443 | 504 | ||
444 | if (UUID.Zero == itemID) | 505 | if (UUID.Zero == itemID) |
445 | { | 506 | { |
@@ -462,6 +523,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
462 | 523 | ||
463 | public void DetachObject(uint objectLocalID, IClientAPI remoteClient) | 524 | public void DetachObject(uint objectLocalID, IClientAPI remoteClient) |
464 | { | 525 | { |
526 | // m_log.DebugFormat( | ||
527 | // "[ATTACHMENTS MODULE]: DetachObject() for object {0} on {1}", objectLocalID, remoteClient.Name); | ||
528 | |||
465 | SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); | 529 | SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); |
466 | if (group != null) | 530 | if (group != null) |
467 | { | 531 | { |
@@ -474,14 +538,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
474 | ScenePresence presence; | 538 | ScenePresence presence; |
475 | if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) | 539 | if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) |
476 | { | 540 | { |
477 | // Save avatar attachment information | 541 | lock (presence.AttachmentsSyncLock) |
478 | m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID); | 542 | { |
479 | 543 | // Save avatar attachment information | |
480 | bool changed = presence.Appearance.DetachAttachment(itemID); | 544 | m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID); |
481 | if (changed && m_scene.AvatarFactory != null) | ||
482 | m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); | ||
483 | 545 | ||
484 | DetachSingleAttachmentToInv(itemID, presence); | 546 | bool changed = presence.Appearance.DetachAttachment(itemID); |
547 | if (changed && m_scene.AvatarFactory != null) | ||
548 | m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); | ||
549 | |||
550 | DetachSingleAttachmentToInv(itemID, presence); | ||
551 | } | ||
485 | } | 552 | } |
486 | } | 553 | } |
487 | 554 | ||
@@ -489,7 +556,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
489 | { | 556 | { |
490 | // m_log.DebugFormat( | 557 | // m_log.DebugFormat( |
491 | // "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}", | 558 | // "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}", |
492 | // remoteClient.Name, sceneObjectID); | 559 | // remoteClient.Name, soLocalId); |
493 | 560 | ||
494 | SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId); | 561 | SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId); |
495 | 562 | ||
@@ -508,24 +575,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
508 | ScenePresence presence; | 575 | ScenePresence presence; |
509 | if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) | 576 | if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) |
510 | { | 577 | { |
511 | if (!m_scene.Permissions.CanRezObject( | 578 | lock (presence.AttachmentsSyncLock) |
512 | so.PrimCount, remoteClient.AgentId, presence.AbsolutePosition)) | 579 | { |
513 | return; | 580 | if (!m_scene.Permissions.CanRezObject( |
581 | so.PrimCount, remoteClient.AgentId, presence.AbsolutePosition)) | ||
582 | return; | ||
514 | 583 | ||
515 | bool changed = presence.Appearance.DetachAttachment(inventoryID); | 584 | bool changed = presence.Appearance.DetachAttachment(inventoryID); |
516 | if (changed && m_scene.AvatarFactory != null) | 585 | if (changed && m_scene.AvatarFactory != null) |
517 | m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); | 586 | m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); |
518 | 587 | ||
519 | presence.RemoveAttachment(so); | 588 | presence.RemoveAttachment(so); |
520 | DetachSceneObjectToGround(so, presence); | 589 | DetachSceneObjectToGround(so, presence); |
521 | 590 | ||
522 | List<UUID> uuids = new List<UUID>(); | 591 | List<UUID> uuids = new List<UUID>(); |
523 | uuids.Add(inventoryID); | 592 | uuids.Add(inventoryID); |
524 | m_scene.InventoryService.DeleteItems(remoteClient.AgentId, uuids); | 593 | m_scene.InventoryService.DeleteItems(remoteClient.AgentId, uuids); |
525 | remoteClient.SendRemoveInventoryItem(inventoryID); | 594 | remoteClient.SendRemoveInventoryItem(inventoryID); |
526 | } | 595 | } |
527 | 596 | ||
528 | m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); | 597 | m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); |
598 | } | ||
529 | } | 599 | } |
530 | 600 | ||
531 | /// <summary> | 601 | /// <summary> |
@@ -559,6 +629,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
559 | // To LocalId or UUID, *THAT* is the question. How now Brown UUID?? | 629 | // To LocalId or UUID, *THAT* is the question. How now Brown UUID?? |
560 | private void DetachSingleAttachmentToInv(UUID itemID, IScenePresence sp) | 630 | private void DetachSingleAttachmentToInv(UUID itemID, IScenePresence sp) |
561 | { | 631 | { |
632 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name); | ||
633 | |||
562 | if (itemID == UUID.Zero) // If this happened, someone made a mistake.... | 634 | if (itemID == UUID.Zero) // If this happened, someone made a mistake.... |
563 | return; | 635 | return; |
564 | 636 | ||
@@ -567,37 +639,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
567 | EntityBase[] detachEntities = m_scene.GetEntities(); | 639 | EntityBase[] detachEntities = m_scene.GetEntities(); |
568 | SceneObjectGroup group; | 640 | SceneObjectGroup group; |
569 | 641 | ||
570 | foreach (EntityBase entity in detachEntities) | 642 | lock (sp.AttachmentsSyncLock) |
571 | { | 643 | { |
572 | if (entity is SceneObjectGroup) | 644 | foreach (EntityBase entity in detachEntities) |
573 | { | 645 | { |
574 | group = (SceneObjectGroup)entity; | 646 | if (entity is SceneObjectGroup) |
575 | if (group.GetFromItemID() == itemID) | ||
576 | { | 647 | { |
577 | m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); | 648 | group = (SceneObjectGroup)entity; |
578 | sp.RemoveAttachment(group); | 649 | if (group.GetFromItemID() == itemID) |
579 | 650 | { | |
580 | // Prepare sog for storage | 651 | m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); |
581 | group.AttachedAvatar = UUID.Zero; | 652 | sp.RemoveAttachment(group); |
582 | 653 | ||
583 | group.ForEachPart( | 654 | // Prepare sog for storage |
584 | delegate(SceneObjectPart part) | 655 | group.AttachedAvatar = UUID.Zero; |
585 | { | 656 | group.RootPart.SetParentLocalId(0); |
586 | // If there are any scripts, | 657 | group.IsAttachment = false; |
587 | // then always trigger a new object and state persistence in UpdateKnownItem() | 658 | group.AbsolutePosition = group.RootPart.AttachedPos; |
588 | if (part.Inventory.ContainsScripts()) | 659 | |
589 | group.HasGroupChanged = true; | 660 | UpdateKnownItem(sp.ControllingClient, group); |
590 | } | 661 | m_scene.DeleteSceneObject(group, false); |
591 | ); | 662 | |
592 | 663 | return; | |
593 | group.RootPart.SetParentLocalId(0); | 664 | } |
594 | group.IsAttachment = false; | ||
595 | group.AbsolutePosition = group.RootPart.AttachedPos; | ||
596 | |||
597 | UpdateKnownItem(sp.ControllingClient, group, group.GetFromItemID(), group.OwnerID); | ||
598 | m_scene.DeleteSceneObject(group, false); | ||
599 | |||
600 | return; | ||
601 | } | 665 | } |
602 | } | 666 | } |
603 | } | 667 | } |
@@ -628,28 +692,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
628 | /// </remarks> | 692 | /// </remarks> |
629 | /// <param name="remoteClient"></param> | 693 | /// <param name="remoteClient"></param> |
630 | /// <param name="grp"></param> | 694 | /// <param name="grp"></param> |
631 | /// <param name="itemID"></param> | 695 | private void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp) |
632 | /// <param name="agentID"></param> | ||
633 | public void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID) | ||
634 | { | 696 | { |
635 | if (grp != null) | 697 | if (grp.HasGroupChanged || grp.ContainsScripts()) |
636 | { | 698 | { |
637 | if (!grp.HasGroupChanged) | ||
638 | { | ||
639 | m_log.DebugFormat( | ||
640 | "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}", | ||
641 | grp.UUID, grp.AttachmentPoint); | ||
642 | |||
643 | return; | ||
644 | } | ||
645 | |||
646 | m_log.DebugFormat( | 699 | m_log.DebugFormat( |
647 | "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", | 700 | "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", |
648 | grp.UUID, grp.AttachmentPoint); | 701 | grp.UUID, grp.AttachmentPoint); |
649 | 702 | ||
650 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); | 703 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); |
651 | 704 | ||
652 | InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); | 705 | InventoryItemBase item = new InventoryItemBase(grp.GetFromItemID(), remoteClient.AgentId); |
653 | item = m_scene.InventoryService.GetItem(item); | 706 | item = m_scene.InventoryService.GetItem(item); |
654 | 707 | ||
655 | if (item != null) | 708 | if (item != null) |
@@ -675,6 +728,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
675 | remoteClient.SendInventoryItemCreateUpdate(item, 0); | 728 | remoteClient.SendInventoryItemCreateUpdate(item, 0); |
676 | } | 729 | } |
677 | } | 730 | } |
731 | else | ||
732 | { | ||
733 | m_log.DebugFormat( | ||
734 | "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}", | ||
735 | grp.UUID, grp.AttachmentPoint); | ||
736 | } | ||
678 | } | 737 | } |
679 | 738 | ||
680 | /// <summary> | 739 | /// <summary> |
@@ -692,7 +751,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
692 | private void AttachToAgent( | 751 | private void AttachToAgent( |
693 | IScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) | 752 | IScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) |
694 | { | 753 | { |
695 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", | 754 | // m_log.DebugFormat( |
755 | // "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", | ||
696 | // so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); | 756 | // so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); |
697 | 757 | ||
698 | so.DetachFromBackup(); | 758 | so.DetachFromBackup(); |
@@ -745,7 +805,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
745 | /// <returns>The user inventory item created that holds the attachment.</returns> | 805 | /// <returns>The user inventory item created that holds the attachment.</returns> |
746 | private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IClientAPI remoteClient, SceneObjectGroup grp) | 806 | private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IClientAPI remoteClient, SceneObjectGroup grp) |
747 | { | 807 | { |
748 | // m_log.DebugFormat("[SCENE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2} {3} {4}", grp.Name, grp.LocalId, remoteClient.Name, remoteClient.AgentId, AgentId); | 808 | // m_log.DebugFormat( |
809 | // "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}", | ||
810 | // grp.Name, grp.LocalId, remoteClient.Name); | ||
749 | 811 | ||
750 | Vector3 inventoryStoredPosition = new Vector3 | 812 | Vector3 inventoryStoredPosition = new Vector3 |
751 | (((grp.AbsolutePosition.X > (int)Constants.RegionSize) | 813 | (((grp.AbsolutePosition.X > (int)Constants.RegionSize) |
@@ -829,4 +891,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
829 | return item; | 891 | return item; |
830 | } | 892 | } |
831 | } | 893 | } |
832 | } | 894 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 35183b3..ff3358f 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | |||
@@ -220,6 +220,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
220 | Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo(0)); | 220 | Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo(0)); |
221 | } | 221 | } |
222 | 222 | ||
223 | /// <summary> | ||
224 | /// Test that attachments don't hang about in the scene when the agent is closed | ||
225 | /// </summary> | ||
226 | [Test] | ||
227 | public void TestRemoveAttachmentsOnAvatarExit() | ||
228 | { | ||
229 | TestHelpers.InMethod(); | ||
230 | // log4net.Config.XmlConfigurator.Configure(); | ||
231 | |||
232 | UUID userId = TestHelpers.ParseTail(0x1); | ||
233 | UUID attItemId = TestHelpers.ParseTail(0x2); | ||
234 | UUID attAssetId = TestHelpers.ParseTail(0x3); | ||
235 | string attName = "att"; | ||
236 | |||
237 | UserAccountHelpers.CreateUserWithInventory(scene, userId); | ||
238 | InventoryItemBase attItem | ||
239 | = UserInventoryHelpers.CreateInventoryItem( | ||
240 | scene, attName, attItemId, attAssetId, userId, InventoryType.Object); | ||
241 | |||
242 | AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); | ||
243 | acd.Appearance = new AvatarAppearance(); | ||
244 | acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); | ||
245 | ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd); | ||
246 | |||
247 | SceneObjectGroup rezzedAtt = presence.GetAttachments()[0]; | ||
248 | |||
249 | scene.IncomingCloseAgent(presence.UUID); | ||
250 | |||
251 | // Check that we can't retrieve this attachment from the scene. | ||
252 | Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null); | ||
253 | } | ||
254 | |||
223 | [Test] | 255 | [Test] |
224 | public void TestRezAttachmentsOnAvatarEntrance() | 256 | public void TestRezAttachmentsOnAvatarEntrance() |
225 | { | 257 | { |
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index b6a1564..0cadd83 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | |||
@@ -211,8 +211,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
211 | // Process the visual params, this may change height as well | 211 | // Process the visual params, this may change height as well |
212 | if (visualParams != null) | 212 | if (visualParams != null) |
213 | { | 213 | { |
214 | // string[] visualParamsStrings = new string[visualParams.Length]; | ||
215 | // for (int i = 0; i < visualParams.Length; i++) | ||
216 | // visualParamsStrings[i] = visualParams[i].ToString(); | ||
217 | // m_log.DebugFormat( | ||
218 | // "[AVFACTORY]: Setting visual params for {0} to {1}", | ||
219 | // client.Name, string.Join(", ", visualParamsStrings)); | ||
220 | |||
221 | float oldHeight = sp.Appearance.AvatarHeight; | ||
214 | changed = sp.Appearance.SetVisualParams(visualParams); | 222 | changed = sp.Appearance.SetVisualParams(visualParams); |
215 | if (sp.Appearance.AvatarHeight > 0) | 223 | |
224 | if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0) | ||
216 | sp.SetHeight(sp.Appearance.AvatarHeight); | 225 | sp.SetHeight(sp.Appearance.AvatarHeight); |
217 | } | 226 | } |
218 | 227 | ||
@@ -416,6 +425,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
416 | 425 | ||
417 | // m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid); | 426 | // m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid); |
418 | 427 | ||
428 | // This could take awhile since it needs to pull inventory | ||
429 | // 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 | ||
430 | // assets and item asset id changes to complete. | ||
431 | // I don't think we need to worry about doing this within m_setAppearanceLock since the queueing avoids | ||
432 | // multiple save requests. | ||
433 | SetAppearanceAssets(sp.UUID, sp.Appearance); | ||
434 | |||
419 | m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); | 435 | m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); |
420 | } | 436 | } |
421 | 437 | ||
@@ -467,7 +483,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
467 | return; | 483 | return; |
468 | } | 484 | } |
469 | 485 | ||
470 | // m_log.WarnFormat("[AVFACTORY]: Received request for wearables of {0}", client.AgentId); | 486 | // m_log.DebugFormat("[AVFACTORY]: Received request for wearables of {0}", client.Name); |
471 | 487 | ||
472 | client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); | 488 | client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); |
473 | } | 489 | } |
@@ -502,9 +518,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
502 | 518 | ||
503 | avatAppearance.GetAssetsFrom(sp.Appearance); | 519 | avatAppearance.GetAssetsFrom(sp.Appearance); |
504 | 520 | ||
505 | // This could take awhile since it needs to pull inventory | ||
506 | SetAppearanceAssets(sp.UUID, ref avatAppearance); | ||
507 | |||
508 | lock (m_setAppearanceLock) | 521 | lock (m_setAppearanceLock) |
509 | { | 522 | { |
510 | // Update only those fields that we have changed. This is important because the viewer | 523 | // Update only those fields that we have changed. This is important because the viewer |
@@ -538,7 +551,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
538 | return true; | 551 | return true; |
539 | } | 552 | } |
540 | 553 | ||
541 | private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) | 554 | private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance) |
542 | { | 555 | { |
543 | IInventoryService invService = m_scene.InventoryService; | 556 | IInventoryService invService = m_scene.InventoryService; |
544 | 557 | ||
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 | |||
27 | using System; | 28 | using System; |
28 | using System.Collections; | 29 | using System.Collections; |
29 | using System.Collections.Generic; | 30 | using 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/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index ac13d5e..8924c0a 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -59,7 +59,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
59 | get { return m_MaxTransferDistance; } | 59 | get { return m_MaxTransferDistance; } |
60 | set { m_MaxTransferDistance = value; } | 60 | set { m_MaxTransferDistance = value; } |
61 | } | 61 | } |
62 | |||
63 | 62 | ||
64 | protected bool m_Enabled = false; | 63 | protected bool m_Enabled = false; |
65 | protected Scene m_aScene; | 64 | protected Scene m_aScene; |
@@ -68,7 +67,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
68 | private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions = | 67 | private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions = |
69 | new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>(); | 68 | new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>(); |
70 | 69 | ||
71 | |||
72 | #region ISharedRegionModule | 70 | #region ISharedRegionModule |
73 | 71 | ||
74 | public Type ReplaceableInterface | 72 | public Type ReplaceableInterface |
@@ -329,6 +327,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
329 | if (sp.ParentID != (uint)0) | 327 | if (sp.ParentID != (uint)0) |
330 | sp.StandUp(); | 328 | sp.StandUp(); |
331 | 329 | ||
330 | if (!sp.ValidateAttachments()) | ||
331 | m_log.DebugFormat( | ||
332 | "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", | ||
333 | sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName); | ||
334 | |||
332 | // if (!sp.ValidateAttachments()) | 335 | // if (!sp.ValidateAttachments()) |
333 | // { | 336 | // { |
334 | // sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state"); | 337 | // sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state"); |
@@ -939,7 +942,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
939 | /// This Closes child agents on neighbouring regions | 942 | /// This Closes child agents on neighbouring regions |
940 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. | 943 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. |
941 | /// </summary> | 944 | /// </summary> |
942 | protected ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version) | 945 | protected ScenePresence CrossAgentToNewRegionAsync( |
946 | ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, | ||
947 | bool isFlying, string version) | ||
943 | { | 948 | { |
944 | ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); | 949 | ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); |
945 | 950 | ||
@@ -949,7 +954,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
949 | 954 | ||
950 | if (neighbourRegion != null) | 955 | if (neighbourRegion != null) |
951 | { | 956 | { |
952 | agent.ValidateAttachments(); | 957 | if (!agent.ValidateAttachments()) |
958 | m_log.DebugFormat( | ||
959 | "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.", | ||
960 | agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName); | ||
953 | 961 | ||
954 | pos = pos + (agent.Velocity); | 962 | pos = pos + (agent.Velocity); |
955 | 963 | ||
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index f7003db..bef0d69 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs | |||
@@ -363,9 +363,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
363 | lock (m_UserCache) | 363 | lock (m_UserCache) |
364 | m_UserCache[user.Id] = user; | 364 | m_UserCache[user.Id] = user; |
365 | 365 | ||
366 | m_log.DebugFormat( | 366 | // m_log.DebugFormat( |
367 | "[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", | 367 | // "[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", |
368 | user.Id, user.FirstName, user.LastName, user.HomeURL); | 368 | // user.Id, user.FirstName, user.LastName, user.HomeURL); |
369 | } | 369 | } |
370 | 370 | ||
371 | //public void AddUser(UUID uuid, string userData) | 371 | //public void AddUser(UUID uuid, string userData) |
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 30ebb21..0a0ce3c 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 | } | 130 | } |
124 | 131 | ||
125 | public void RemoveRegion(Scene scene) | 132 | public void RemoveRegion(Scene scene) |
@@ -147,7 +154,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts | |||
147 | if (inCache) | 154 | if (inCache) |
148 | return account; | 155 | return account; |
149 | 156 | ||
150 | account = m_UserService.GetUserAccount(scopeID, userID); | 157 | account = UserAccountService.GetUserAccount(scopeID, userID); |
151 | m_Cache.Cache(userID, account); | 158 | m_Cache.Cache(userID, account); |
152 | 159 | ||
153 | return account; | 160 | return account; |
@@ -160,7 +167,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts | |||
160 | if (inCache) | 167 | if (inCache) |
161 | return account; | 168 | return account; |
162 | 169 | ||
163 | account = m_UserService.GetUserAccount(scopeID, firstName, lastName); | 170 | account = UserAccountService.GetUserAccount(scopeID, firstName, lastName); |
164 | if (account != null) | 171 | if (account != null) |
165 | m_Cache.Cache(account.PrincipalID, account); | 172 | m_Cache.Cache(account.PrincipalID, account); |
166 | 173 | ||
@@ -169,22 +176,21 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts | |||
169 | 176 | ||
170 | public UserAccount GetUserAccount(UUID scopeID, string Email) | 177 | public UserAccount GetUserAccount(UUID scopeID, string Email) |
171 | { | 178 | { |
172 | return m_UserService.GetUserAccount(scopeID, Email); | 179 | return UserAccountService.GetUserAccount(scopeID, Email); |
173 | } | 180 | } |
174 | 181 | ||
175 | public List<UserAccount> GetUserAccounts(UUID scopeID, string query) | 182 | public List<UserAccount> GetUserAccounts(UUID scopeID, string query) |
176 | { | 183 | { |
177 | return m_UserService.GetUserAccounts(scopeID, query); | 184 | return UserAccountService.GetUserAccounts(scopeID, query); |
178 | } | 185 | } |
179 | 186 | ||
180 | // Update all updatable fields | 187 | // Update all updatable fields |
181 | // | 188 | // |
182 | public bool StoreUserAccount(UserAccount data) | 189 | public bool StoreUserAccount(UserAccount data) |
183 | { | 190 | { |
184 | return m_UserService.StoreUserAccount(data); | 191 | return UserAccountService.StoreUserAccount(data); |
185 | } | 192 | } |
186 | 193 | ||
187 | #endregion | 194 | #endregion |
188 | |||
189 | } | 195 | } |
190 | } | 196 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index 48130e7..587d260 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs | |||
@@ -284,8 +284,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
284 | part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | 284 | part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; |
285 | 285 | ||
286 | // And zap any troublesome sit target information | 286 | // And zap any troublesome sit target information |
287 | part.SitTargetOrientation = new Quaternion(0, 0, 0, 1); | 287 | // part.SitTargetOrientation = new Quaternion(0, 0, 0, 1); |
288 | part.SitTargetPosition = new Vector3(0, 0, 0); | 288 | // part.SitTargetPosition = new Vector3(0, 0, 0); |
289 | 289 | ||
290 | // Fix ownership/creator of inventory items | 290 | // Fix ownership/creator of inventory items |
291 | // Not doing so results in inventory items | 291 | // Not doing so results in inventory items |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index 10a83ee..b895afe 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs | |||
@@ -127,6 +127,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
127 | 127 | ||
128 | EntityBase[] entities = m_scene.GetEntities(); | 128 | EntityBase[] entities = m_scene.GetEntities(); |
129 | List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); | 129 | List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); |
130 | |||
131 | string checkPermissions = null; | ||
132 | int numObjectsSkippedPermissions = 0; | ||
133 | Object temp; | ||
134 | if (options.TryGetValue("checkPermissions", out temp)) | ||
135 | checkPermissions = (string)temp; | ||
130 | 136 | ||
131 | // Filter entities so that we only have scene objects. | 137 | // Filter entities so that we only have scene objects. |
132 | // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods | 138 | // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods |
@@ -136,9 +142,19 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
136 | if (entity is SceneObjectGroup) | 142 | if (entity is SceneObjectGroup) |
137 | { | 143 | { |
138 | SceneObjectGroup sceneObject = (SceneObjectGroup)entity; | 144 | SceneObjectGroup sceneObject = (SceneObjectGroup)entity; |
139 | 145 | ||
140 | if (!sceneObject.IsDeleted && !sceneObject.IsAttachment) | 146 | if (!sceneObject.IsDeleted && !sceneObject.IsAttachment) |
141 | sceneObjects.Add((SceneObjectGroup)entity); | 147 | { |
148 | if (!CanUserArchiveObject(m_scene.RegionInfo.EstateSettings.EstateOwner, sceneObject, checkPermissions)) | ||
149 | { | ||
150 | // The user isn't allowed to copy/transfer this object, so it will not be included in the OAR. | ||
151 | ++numObjectsSkippedPermissions; | ||
152 | } | ||
153 | else | ||
154 | { | ||
155 | sceneObjects.Add(sceneObject); | ||
156 | } | ||
157 | } | ||
142 | } | 158 | } |
143 | } | 159 | } |
144 | 160 | ||
@@ -159,7 +175,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
159 | { | 175 | { |
160 | m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified"); | 176 | m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified"); |
161 | } | 177 | } |
162 | 178 | ||
179 | if (numObjectsSkippedPermissions > 0) | ||
180 | { | ||
181 | m_log.DebugFormat( | ||
182 | "[ARCHIVER]: {0} scene objects skipped due to lack of permissions", | ||
183 | numObjectsSkippedPermissions); | ||
184 | } | ||
185 | |||
163 | // Make sure that we also request terrain texture assets | 186 | // Make sure that we also request terrain texture assets |
164 | RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings; | 187 | RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings; |
165 | 188 | ||
@@ -211,6 +234,83 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
211 | } | 234 | } |
212 | 235 | ||
213 | /// <summary> | 236 | /// <summary> |
237 | /// Checks whether the user has permission to export an object group to an OAR. | ||
238 | /// </summary> | ||
239 | /// <param name="user">The user</param> | ||
240 | /// <param name="objGroup">The object group</param> | ||
241 | /// <param name="checkPermissions">Which permissions to check: "C" = Copy, "T" = Transfer</param> | ||
242 | /// <returns>Whether the user is allowed to export the object to an OAR</returns> | ||
243 | private bool CanUserArchiveObject(UUID user, SceneObjectGroup objGroup, string checkPermissions) | ||
244 | { | ||
245 | if (checkPermissions == null) | ||
246 | return true; | ||
247 | |||
248 | IPermissionsModule module = m_scene.RequestModuleInterface<IPermissionsModule>(); | ||
249 | if (module == null) | ||
250 | return true; // this shouldn't happen | ||
251 | |||
252 | // Check whether the user is permitted to export all of the parts in the SOG. If any | ||
253 | // part can't be exported then the entire SOG can't be exported. | ||
254 | |||
255 | bool permitted = true; | ||
256 | //int primNumber = 1; | ||
257 | |||
258 | foreach (SceneObjectPart obj in objGroup.Parts) | ||
259 | { | ||
260 | uint perm; | ||
261 | PermissionClass permissionClass = module.GetPermissionClass(user, obj); | ||
262 | switch (permissionClass) | ||
263 | { | ||
264 | case PermissionClass.Owner: | ||
265 | perm = obj.BaseMask; | ||
266 | break; | ||
267 | case PermissionClass.Group: | ||
268 | perm = obj.GroupMask | obj.EveryoneMask; | ||
269 | break; | ||
270 | case PermissionClass.Everyone: | ||
271 | default: | ||
272 | perm = obj.EveryoneMask; | ||
273 | break; | ||
274 | } | ||
275 | |||
276 | bool canCopy = (perm & (uint)PermissionMask.Copy) != 0; | ||
277 | bool canTransfer = (perm & (uint)PermissionMask.Transfer) != 0; | ||
278 | |||
279 | // Special case: if Everyone can copy the object then this implies it can also be | ||
280 | // Transferred. | ||
281 | // However, if the user is the Owner then we don't check EveryoneMask, because it seems that the mask | ||
282 | // always (incorrectly) includes the Copy bit set in this case. But that's a mistake: the viewer | ||
283 | // does NOT show that the object has Everyone-Copy permissions, and doesn't allow it to be copied. | ||
284 | if (permissionClass != PermissionClass.Owner) | ||
285 | { | ||
286 | canTransfer |= (obj.EveryoneMask & (uint)PermissionMask.Copy) != 0; | ||
287 | } | ||
288 | |||
289 | |||
290 | bool partPermitted = true; | ||
291 | if (checkPermissions.Contains("C") && !canCopy) | ||
292 | partPermitted = false; | ||
293 | if (checkPermissions.Contains("T") && !canTransfer) | ||
294 | partPermitted = false; | ||
295 | |||
296 | //string name = (objGroup.PrimCount == 1) ? objGroup.Name : string.Format("{0} ({1}/{2})", obj.Name, primNumber, objGroup.PrimCount); | ||
297 | //m_log.DebugFormat("[ARCHIVER]: Object permissions: {0}: Base={1:X4}, Owner={2:X4}, Everyone={3:X4}, permissionClass={4}, checkPermissions={5}, canCopy={6}, canTransfer={7}, permitted={8}", | ||
298 | // name, obj.BaseMask, obj.OwnerMask, obj.EveryoneMask, | ||
299 | // permissionClass, checkPermissions, canCopy, canTransfer, permitted); | ||
300 | |||
301 | if (!partPermitted) | ||
302 | { | ||
303 | permitted = false; | ||
304 | break; | ||
305 | } | ||
306 | |||
307 | //++primNumber; | ||
308 | } | ||
309 | |||
310 | return permitted; | ||
311 | } | ||
312 | |||
313 | /// <summary> | ||
214 | /// Create the control file for the most up to date archive | 314 | /// Create the control file for the most up to date archive |
215 | /// </summary> | 315 | /// </summary> |
216 | /// <returns></returns> | 316 | /// <returns></returns> |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs index 08eb80c..f44a3ba 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs | |||
@@ -128,6 +128,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
128 | // ops.Add("v|version=", delegate(string v) { options["version"] = v; }); | 128 | // ops.Add("v|version=", delegate(string v) { options["version"] = v; }); |
129 | ops.Add("p|profile=", delegate(string v) { options["profile"] = v; }); | 129 | ops.Add("p|profile=", delegate(string v) { options["profile"] = v; }); |
130 | ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; }); | 130 | ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; }); |
131 | ops.Add("perm=", delegate(string v) { options["checkPermissions"] = v; }); | ||
131 | 132 | ||
132 | List<string> mainParams = ops.Parse(cmdparams); | 133 | List<string> mainParams = ops.Parse(cmdparams); |
133 | 134 | ||
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs index b185d9b..e798e5e 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs | |||
@@ -318,6 +318,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
318 | new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>())); | 318 | new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>())); |
319 | 319 | ||
320 | SceneObjectPart part1 = CreateSceneObjectPart1(); | 320 | SceneObjectPart part1 = CreateSceneObjectPart1(); |
321 | |||
322 | part1.SitTargetOrientation = new Quaternion(0.2f, 0.3f, 0.4f, 0.5f); | ||
323 | part1.SitTargetPosition = new Vector3(1, 2, 3); | ||
324 | |||
321 | SceneObjectGroup object1 = new SceneObjectGroup(part1); | 325 | SceneObjectGroup object1 = new SceneObjectGroup(part1); |
322 | 326 | ||
323 | // Let's put some inventory items into our object | 327 | // Let's put some inventory items into our object |
@@ -390,6 +394,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
390 | object1PartLoaded.RotationOffset, Is.EqualTo(part1.RotationOffset), "object1 rotation offset not equal"); | 394 | object1PartLoaded.RotationOffset, Is.EqualTo(part1.RotationOffset), "object1 rotation offset not equal"); |
391 | Assert.That( | 395 | Assert.That( |
392 | object1PartLoaded.OffsetPosition, Is.EqualTo(part1.OffsetPosition), "object1 offset position not equal"); | 396 | object1PartLoaded.OffsetPosition, Is.EqualTo(part1.OffsetPosition), "object1 offset position not equal"); |
397 | Assert.That(object1PartLoaded.SitTargetOrientation, Is.EqualTo(part1.SitTargetOrientation)); | ||
398 | Assert.That(object1PartLoaded.SitTargetPosition, Is.EqualTo(part1.SitTargetPosition)); | ||
393 | 399 | ||
394 | TaskInventoryItem loadedSoundItem = object1PartLoaded.Inventory.GetInventoryItems(soundItemName)[0]; | 400 | TaskInventoryItem loadedSoundItem = object1PartLoaded.Inventory.GetInventoryItems(soundItemName)[0]; |
395 | Assert.That(loadedSoundItem, Is.Not.Null, "loaded sound item was null"); | 401 | Assert.That(loadedSoundItem, Is.Not.Null, "loaded sound item was null"); |
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 94c1417..c199a77 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs | |||
@@ -968,10 +968,10 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
968 | args.terrainDetail2 = Scene.RegionInfo.RegionSettings.TerrainTexture3; | 968 | args.terrainDetail2 = Scene.RegionInfo.RegionSettings.TerrainTexture3; |
969 | args.terrainDetail3 = Scene.RegionInfo.RegionSettings.TerrainTexture4; | 969 | args.terrainDetail3 = Scene.RegionInfo.RegionSettings.TerrainTexture4; |
970 | 970 | ||
971 | m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 1 {0} for region {1}", args.terrainDetail0, Scene.RegionInfo.RegionName); | 971 | // m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 1 {0} for region {1}", args.terrainDetail0, Scene.RegionInfo.RegionName); |
972 | m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 2 {0} for region {1}", args.terrainDetail1, Scene.RegionInfo.RegionName); | 972 | // m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 2 {0} for region {1}", args.terrainDetail1, Scene.RegionInfo.RegionName); |
973 | m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 3 {0} for region {1}", args.terrainDetail2, Scene.RegionInfo.RegionName); | 973 | // m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 3 {0} for region {1}", args.terrainDetail2, Scene.RegionInfo.RegionName); |
974 | m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 4 {0} for region {1}", args.terrainDetail3, Scene.RegionInfo.RegionName); | 974 | // m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 4 {0} for region {1}", args.terrainDetail3, Scene.RegionInfo.RegionName); |
975 | 975 | ||
976 | remoteClient.SendRegionHandshake(Scene.RegionInfo,args); | 976 | remoteClient.SendRegionHandshake(Scene.RegionInfo,args); |
977 | } | 977 | } |
diff --git a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs index 8b78701..1e4f0a4 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/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index b9bd9a4..3b661ed 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs | |||
@@ -39,7 +39,7 @@ using OpenSim.Services.Interfaces; | |||
39 | 39 | ||
40 | namespace OpenSim.Region.CoreModules.World.Permissions | 40 | namespace OpenSim.Region.CoreModules.World.Permissions |
41 | { | 41 | { |
42 | public class PermissionsModule : IRegionModule | 42 | public class PermissionsModule : IRegionModule, IPermissionsModule |
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 | ||
@@ -150,6 +150,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions | |||
150 | else | 150 | else |
151 | m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks"); | 151 | m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks"); |
152 | 152 | ||
153 | scene.RegisterModuleInterface<IPermissionsModule>(this); | ||
154 | |||
153 | //Register functions with Scene External Checks! | 155 | //Register functions with Scene External Checks! |
154 | m_scene.Permissions.OnBypassPermissions += BypassPermissions; | 156 | m_scene.Permissions.OnBypassPermissions += BypassPermissions; |
155 | m_scene.Permissions.OnSetBypassPermissions += SetBypassPermissions; | 157 | m_scene.Permissions.OnSetBypassPermissions += SetBypassPermissions; |
@@ -574,46 +576,18 @@ namespace OpenSim.Region.CoreModules.World.Permissions | |||
574 | if (objectOwner != UUID.Zero) | 576 | if (objectOwner != UUID.Zero) |
575 | objectEveryoneMask |= (uint)PrimFlags.ObjectAnyOwner; | 577 | objectEveryoneMask |= (uint)PrimFlags.ObjectAnyOwner; |
576 | 578 | ||
577 | if (m_bypassPermissions) | 579 | PermissionClass permissionClass = GetPermissionClass(user, task); |
578 | return objectOwnerMask; | ||
579 | |||
580 | // Object owners should be able to edit their own content | ||
581 | if (user == objectOwner) | ||
582 | return objectOwnerMask; | ||
583 | |||
584 | if (IsFriendWithPerms(user, objectOwner)) | ||
585 | { | ||
586 | return objectOwnerMask; | ||
587 | } | ||
588 | // Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set | ||
589 | if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner)) | ||
590 | { | ||
591 | return objectOwnerMask; | ||
592 | } | ||
593 | |||
594 | // Admin should be able to edit anything in the sim (including admin objects) | ||
595 | if (IsAdministrator(user)) | ||
596 | { | ||
597 | return objectOwnerMask; | ||
598 | } | ||
599 | 580 | ||
600 | // Users should be able to edit what is over their land. | 581 | switch (permissionClass) |
601 | Vector3 taskPos = task.AbsolutePosition; | ||
602 | ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y); | ||
603 | if (parcel != null && parcel.LandData.OwnerID == user && m_ParcelOwnerIsGod) | ||
604 | { | 582 | { |
605 | // Admin objects should not be editable by the above | 583 | case PermissionClass.Owner: |
606 | if (!IsAdministrator(objectOwner)) | ||
607 | { | ||
608 | return objectOwnerMask; | 584 | return objectOwnerMask; |
609 | } | 585 | case PermissionClass.Group: |
586 | return objectGroupMask | objectEveryoneMask; | ||
587 | case PermissionClass.Everyone: | ||
588 | default: | ||
589 | return objectEveryoneMask; | ||
610 | } | 590 | } |
611 | |||
612 | // Group permissions | ||
613 | if ((task.GroupID != UUID.Zero) && IsGroupMember(task.GroupID, user, 0)) | ||
614 | return objectGroupMask | objectEveryoneMask; | ||
615 | |||
616 | return objectEveryoneMask; | ||
617 | } | 591 | } |
618 | 592 | ||
619 | private uint ApplyObjectModifyMasks(uint setPermissionMask, uint objectFlagsMask) | 593 | private uint ApplyObjectModifyMasks(uint setPermissionMask, uint objectFlagsMask) |
@@ -644,6 +618,47 @@ namespace OpenSim.Region.CoreModules.World.Permissions | |||
644 | return objectFlagsMask; | 618 | return objectFlagsMask; |
645 | } | 619 | } |
646 | 620 | ||
621 | public PermissionClass GetPermissionClass(UUID user, SceneObjectPart obj) | ||
622 | { | ||
623 | if (obj == null) | ||
624 | return PermissionClass.Everyone; | ||
625 | |||
626 | if (m_bypassPermissions) | ||
627 | return PermissionClass.Owner; | ||
628 | |||
629 | // Object owners should be able to edit their own content | ||
630 | UUID objectOwner = obj.OwnerID; | ||
631 | if (user == objectOwner) | ||
632 | return PermissionClass.Owner; | ||
633 | |||
634 | if (IsFriendWithPerms(user, objectOwner)) | ||
635 | return PermissionClass.Owner; | ||
636 | |||
637 | // Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set | ||
638 | if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner)) | ||
639 | return PermissionClass.Owner; | ||
640 | |||
641 | // Admin should be able to edit anything in the sim (including admin objects) | ||
642 | if (IsAdministrator(user)) | ||
643 | return PermissionClass.Owner; | ||
644 | |||
645 | // Users should be able to edit what is over their land. | ||
646 | Vector3 taskPos = obj.AbsolutePosition; | ||
647 | ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y); | ||
648 | if (parcel != null && parcel.LandData.OwnerID == user && m_ParcelOwnerIsGod) | ||
649 | { | ||
650 | // Admin objects should not be editable by the above | ||
651 | if (!IsAdministrator(objectOwner)) | ||
652 | return PermissionClass.Owner; | ||
653 | } | ||
654 | |||
655 | // Group permissions | ||
656 | if ((obj.GroupID != UUID.Zero) && IsGroupMember(obj.GroupID, user, 0)) | ||
657 | return PermissionClass.Group; | ||
658 | |||
659 | return PermissionClass.Everyone; | ||
660 | } | ||
661 | |||
647 | /// <summary> | 662 | /// <summary> |
648 | /// General permissions checks for any operation involving an object. These supplement more specific checks | 663 | /// General permissions checks for any operation involving an object. These supplement more specific checks |
649 | /// implemented by callers. | 664 | /// implemented by callers. |
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index c87790f..b0266c5 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs | |||
@@ -222,7 +222,7 @@ namespace OpenSim.Region.Examples.SimpleModule | |||
222 | public event ScriptReset OnScriptReset; | 222 | public event ScriptReset OnScriptReset; |
223 | public event GetScriptRunning OnGetScriptRunning; | 223 | public event GetScriptRunning OnGetScriptRunning; |
224 | public event SetScriptRunning OnSetScriptRunning; | 224 | public event SetScriptRunning OnSetScriptRunning; |
225 | public event Action<Vector3, bool> OnAutoPilotGo; | 225 | public event Action<Vector3, bool, bool> OnAutoPilotGo; |
226 | 226 | ||
227 | public event TerrainUnacked OnUnackedTerrain; | 227 | public event TerrainUnacked OnUnackedTerrain; |
228 | 228 | ||
diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index 73d15a5..5ffbec8 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs | |||
@@ -88,6 +88,15 @@ namespace OpenSim.Region.Framework.Interfaces | |||
88 | ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt); | 88 | ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt); |
89 | 89 | ||
90 | /// <summary> | 90 | /// <summary> |
91 | /// Rez an attachment from user inventory and change inventory status to match. | ||
92 | /// </summary> | ||
93 | /// <param name="sp"></param> | ||
94 | /// <param name="itemID"></param> | ||
95 | /// <param name="AttachmentPt"></param> | ||
96 | /// <returns>The scene object that was attached. Null if the scene object could not be found</returns> | ||
97 | ISceneEntity RezSingleAttachmentFromInventory(ScenePresence sp, UUID itemID, uint AttachmentPt); | ||
98 | |||
99 | /// <summary> | ||
91 | /// Rez multiple attachments from a user's inventory | 100 | /// Rez multiple attachments from a user's inventory |
92 | /// </summary> | 101 | /// </summary> |
93 | /// <param name="remoteClient"></param> | 102 | /// <param name="remoteClient"></param> |
@@ -129,14 +138,5 @@ namespace OpenSim.Region.Framework.Interfaces | |||
129 | /// <param name="sog"></param> | 138 | /// <param name="sog"></param> |
130 | /// <param name="pos"></param> | 139 | /// <param name="pos"></param> |
131 | void UpdateAttachmentPosition(SceneObjectGroup sog, Vector3 pos); | 140 | void UpdateAttachmentPosition(SceneObjectGroup sog, Vector3 pos); |
132 | |||
133 | /// <summary> | ||
134 | /// Update the user inventory with a changed attachment | ||
135 | /// </summary> | ||
136 | /// <param name="remoteClient"></param> | ||
137 | /// <param name="grp"></param> | ||
138 | /// <param name="itemID"></param> | ||
139 | /// <param name="agentID"></param> | ||
140 | void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID); | ||
141 | } | 141 | } |
142 | } | 142 | } |
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/Physics/BulletDotNETPlugin/BulletDotNETPluginStructs.cs b/OpenSim/Region/Framework/Interfaces/IPermissionsModule.cs index 578c22a..1ed978b 100644 --- a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPluginStructs.cs +++ b/OpenSim/Region/Framework/Interfaces/IPermissionsModule.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 | * |
@@ -25,36 +25,30 @@ | |||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using OpenMetaverse; |
29 | using OpenSim.Region.Framework.Scenes; | ||
29 | 30 | ||
30 | public enum StatusIndicators : int | 31 | namespace OpenSim.Region.Framework.Interfaces |
31 | { | 32 | { |
32 | Generic = 0, | 33 | /// <value> |
33 | Start = 1, | 34 | /// Which set of permissions a user has. |
34 | End = 2 | 35 | /// </value> |
35 | } | 36 | public enum PermissionClass |
37 | { | ||
38 | Owner, | ||
39 | Group, | ||
40 | Everyone | ||
41 | }; | ||
36 | 42 | ||
37 | public struct sCollisionData | 43 | public interface IPermissionsModule |
38 | { | 44 | { |
39 | public uint ColliderLocalId; | 45 | |
40 | public uint CollidedWithLocalId; | 46 | /// <summary> |
41 | public int NumberOfCollisions; | 47 | /// Returns the type of permissions that the user has over an object. |
42 | public int CollisionType; | 48 | /// </summary> |
43 | public int StatusIndicator; | 49 | /// <param name="user">The user</param> |
44 | public int lastframe; | 50 | /// <param name="obj">The object</param> |
51 | /// <returns>The type of permissions the user has over the object</returns> | ||
52 | PermissionClass GetPermissionClass(UUID user, SceneObjectPart obj); | ||
53 | } | ||
45 | } | 54 | } |
46 | |||
47 | [Flags] | ||
48 | public 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/Framework/Interfaces/IScenePresence.cs b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs index 8913133..ff39283 100644 --- a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs +++ b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs | |||
@@ -61,6 +61,14 @@ namespace OpenSim.Region.Framework.Interfaces | |||
61 | AvatarAppearance Appearance { get; set; } | 61 | AvatarAppearance Appearance { get; set; } |
62 | 62 | ||
63 | /// <summary> | 63 | /// <summary> |
64 | /// The AttachmentsModule synchronizes on this to avoid race conditions between commands to add and remove attachments. | ||
65 | /// </summary> | ||
66 | /// <remarks> | ||
67 | /// All add and remove attachment operations must synchronize on this for the lifetime of their operations. | ||
68 | /// </remarks> | ||
69 | Object AttachmentsSyncLock { get; } | ||
70 | |||
71 | /// <summary> | ||
64 | /// The scene objects attached to this avatar. | 72 | /// The scene objects attached to this avatar. |
65 | /// </summary> | 73 | /// </summary> |
66 | /// <returns> | 74 | /// <returns> |
diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs index d9752e6..b27b7da 100644 --- a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs | |||
@@ -52,5 +52,10 @@ namespace OpenSim.Region.Framework.Interfaces | |||
52 | ArrayList GetScriptErrors(UUID itemID); | 52 | ArrayList GetScriptErrors(UUID itemID); |
53 | 53 | ||
54 | void SaveAllState(); | 54 | void SaveAllState(); |
55 | |||
56 | /// <summary> | ||
57 | /// Starts the processing threads. | ||
58 | /// </summary> | ||
59 | void StartProcessing(); | ||
55 | } | 60 | } |
56 | } | 61 | } |
diff --git a/OpenSim/Region/Framework/Scenes/EntityBase.cs b/OpenSim/Region/Framework/Scenes/EntityBase.cs index 213431a..320b904 100644 --- a/OpenSim/Region/Framework/Scenes/EntityBase.cs +++ b/OpenSim/Region/Framework/Scenes/EntityBase.cs | |||
@@ -26,8 +26,10 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Reflection; | ||
29 | using System.Runtime.Serialization; | 30 | using System.Runtime.Serialization; |
30 | using System.Security.Permissions; | 31 | using System.Security.Permissions; |
32 | using log4net; | ||
31 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
32 | using OpenMetaverse; | 34 | using 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; |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 4700c3b..663aa22 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | |||
@@ -57,11 +57,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
57 | protected AsyncInventorySender m_asyncInventorySender; | 57 | protected AsyncInventorySender m_asyncInventorySender; |
58 | 58 | ||
59 | /// <summary> | 59 | /// <summary> |
60 | /// Start all the scripts in the scene which should be started. | 60 | /// Creates all the scripts in the scene which should be started. |
61 | /// </summary> | 61 | /// </summary> |
62 | public void CreateScriptInstances() | 62 | public void CreateScriptInstances() |
63 | { | 63 | { |
64 | m_log.Info("[PRIM INVENTORY]: Starting scripts in scene"); | 64 | m_log.Info("[PRIM INVENTORY]: Creating scripts in scene"); |
65 | 65 | ||
66 | EntityBase[] entities = Entities.GetEntities(); | 66 | EntityBase[] entities = Entities.GetEntities(); |
67 | foreach (EntityBase group in entities) | 67 | foreach (EntityBase group in entities) |
@@ -74,6 +74,26 @@ namespace OpenSim.Region.Framework.Scenes | |||
74 | } | 74 | } |
75 | } | 75 | } |
76 | 76 | ||
77 | /// <summary> | ||
78 | /// Lets the script engines start processing scripts. | ||
79 | /// </summary> | ||
80 | public void StartScripts() | ||
81 | { | ||
82 | m_log.Info("[PRIM INVENTORY]: Starting scripts in scene"); | ||
83 | |||
84 | IScriptModule[] engines = RequestModuleInterfaces<IScriptModule>(); | ||
85 | if (engines != null) | ||
86 | { | ||
87 | foreach (IScriptModule engine in engines) | ||
88 | { | ||
89 | if (engine != null) | ||
90 | { | ||
91 | engine.StartProcessing(); | ||
92 | } | ||
93 | } | ||
94 | } | ||
95 | } | ||
96 | |||
77 | public void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item) | 97 | public void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item) |
78 | { | 98 | { |
79 | IMoneyModule money = RequestModuleInterface<IMoneyModule>(); | 99 | IMoneyModule money = RequestModuleInterface<IMoneyModule>(); |
@@ -254,7 +274,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
254 | if (group.UpdateInventoryItem(item)) | 274 | if (group.UpdateInventoryItem(item)) |
255 | remoteClient.SendAgentAlertMessage("Script saved", false); | 275 | remoteClient.SendAgentAlertMessage("Script saved", false); |
256 | 276 | ||
257 | part.GetProperties(remoteClient); | 277 | part.SendPropertiesToClient(remoteClient); |
258 | 278 | ||
259 | // Trigger rerunning of script (use TriggerRezScript event, see RezScript) | 279 | // Trigger rerunning of script (use TriggerRezScript event, see RezScript) |
260 | ArrayList errors = new ArrayList(); | 280 | ArrayList errors = new ArrayList(); |
@@ -314,6 +334,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
314 | public void UpdateInventoryItemAsset(IClientAPI remoteClient, UUID transactionID, | 334 | public void UpdateInventoryItemAsset(IClientAPI remoteClient, UUID transactionID, |
315 | UUID itemID, InventoryItemBase itemUpd) | 335 | UUID itemID, InventoryItemBase itemUpd) |
316 | { | 336 | { |
337 | // m_log.DebugFormat( | ||
338 | // "[USER INVENTORY]: Updating asset for item {0} {1}, transaction ID {2} for {3}", | ||
339 | // itemID, itemUpd.Name, transactionID, remoteClient.Name); | ||
340 | |||
317 | // This one will let people set next perms on items in agent | 341 | // This one will let people set next perms on items in agent |
318 | // inventory. Rut-Roh. Whatever. Make this secure. Yeah. | 342 | // inventory. Rut-Roh. Whatever. Make this secure. Yeah. |
319 | // | 343 | // |
@@ -365,8 +389,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
365 | IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>(); | 389 | IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>(); |
366 | if (agentTransactions != null) | 390 | if (agentTransactions != null) |
367 | { | 391 | { |
368 | agentTransactions.HandleItemUpdateFromTransaction( | 392 | agentTransactions.HandleItemUpdateFromTransaction(remoteClient, transactionID, item); |
369 | remoteClient, transactionID, item); | ||
370 | } | 393 | } |
371 | } | 394 | } |
372 | } | 395 | } |
@@ -979,7 +1002,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
979 | } | 1002 | } |
980 | 1003 | ||
981 | group.RemoveInventoryItem(localID, itemID); | 1004 | group.RemoveInventoryItem(localID, itemID); |
982 | part.GetProperties(remoteClient); | 1005 | part.SendPropertiesToClient(remoteClient); |
983 | } | 1006 | } |
984 | 1007 | ||
985 | private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId) | 1008 | private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId) |
@@ -1252,7 +1275,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1252 | 1275 | ||
1253 | if (TryGetScenePresence(srcTaskItem.OwnerID, out avatar)) | 1276 | if (TryGetScenePresence(srcTaskItem.OwnerID, out avatar)) |
1254 | { | 1277 | { |
1255 | destPart.GetProperties(avatar.ControllingClient); | 1278 | destPart.SendPropertiesToClient(avatar.ControllingClient); |
1256 | } | 1279 | } |
1257 | } | 1280 | } |
1258 | 1281 | ||
@@ -1407,7 +1430,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1407 | m_log.InfoFormat( | 1430 | m_log.InfoFormat( |
1408 | "[PRIM INVENTORY]: Update with item {0} requested of prim {1} for {2}", | 1431 | "[PRIM INVENTORY]: Update with item {0} requested of prim {1} for {2}", |
1409 | item.Name, primLocalID, remoteClient.Name); | 1432 | item.Name, primLocalID, remoteClient.Name); |
1410 | part.GetProperties(remoteClient); | 1433 | part.SendPropertiesToClient(remoteClient); |
1411 | if (!Permissions.BypassPermissions()) | 1434 | if (!Permissions.BypassPermissions()) |
1412 | { | 1435 | { |
1413 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | 1436 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) |
@@ -1502,7 +1525,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1502 | 1525 | ||
1503 | if (part.Inventory.UpdateInventoryItem(itemInfo)) | 1526 | if (part.Inventory.UpdateInventoryItem(itemInfo)) |
1504 | { | 1527 | { |
1505 | part.GetProperties(remoteClient); | 1528 | part.SendPropertiesToClient(remoteClient); |
1506 | } | 1529 | } |
1507 | } | 1530 | } |
1508 | } | 1531 | } |
@@ -1554,7 +1577,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1554 | // m_log.InfoFormat("[PRIMINVENTORY]: " + | 1577 | // m_log.InfoFormat("[PRIMINVENTORY]: " + |
1555 | // "Rezzed script {0} into prim local ID {1} for user {2}", | 1578 | // "Rezzed script {0} into prim local ID {1} for user {2}", |
1556 | // item.inventoryName, localID, remoteClient.Name); | 1579 | // item.inventoryName, localID, remoteClient.Name); |
1557 | part.GetProperties(remoteClient); | 1580 | part.SendPropertiesToClient(remoteClient); |
1558 | part.ParentGroup.ResumeScripts(); | 1581 | part.ParentGroup.ResumeScripts(); |
1559 | } | 1582 | } |
1560 | else | 1583 | else |
@@ -1612,7 +1635,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1612 | taskItem.AssetID = asset.FullID; | 1635 | taskItem.AssetID = asset.FullID; |
1613 | 1636 | ||
1614 | part.Inventory.AddInventoryItem(taskItem, false); | 1637 | part.Inventory.AddInventoryItem(taskItem, false); |
1615 | part.GetProperties(remoteClient); | 1638 | part.SendPropertiesToClient(remoteClient); |
1616 | 1639 | ||
1617 | part.Inventory.CreateScriptInstance(taskItem, 0, false, DefaultScriptEngine, 0); | 1640 | part.Inventory.CreateScriptInstance(taskItem, 0, false, DefaultScriptEngine, 0); |
1618 | part.ParentGroup.ResumeScripts(); | 1641 | part.ParentGroup.ResumeScripts(); |
@@ -1726,7 +1749,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1726 | 1749 | ||
1727 | if (TryGetScenePresence(srcTaskItem.OwnerID, out avatar)) | 1750 | if (TryGetScenePresence(srcTaskItem.OwnerID, out avatar)) |
1728 | { | 1751 | { |
1729 | destPart.GetProperties(avatar.ControllingClient); | 1752 | destPart.SendPropertiesToClient(avatar.ControllingClient); |
1730 | } | 1753 | } |
1731 | } | 1754 | } |
1732 | 1755 | ||
@@ -2064,7 +2087,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2064 | SceneObjectPart part = GetSceneObjectPart(localID); | 2087 | SceneObjectPart part = GetSceneObjectPart(localID); |
2065 | if (part == null) | 2088 | if (part == null) |
2066 | continue; | 2089 | continue; |
2067 | part.GetProperties(remoteClient); | 2090 | part.SendPropertiesToClient(remoteClient); |
2068 | } | 2091 | } |
2069 | } | 2092 | } |
2070 | 2093 | ||
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index 29d01d6..270e582 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 f86b3b6..eadec09 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -656,7 +656,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
656 | EventManager.OnLandObjectRemoved += | 656 | EventManager.OnLandObjectRemoved += |
657 | new EventManager.LandObjectRemoved(simDataService.RemoveLandObject); | 657 | new EventManager.LandObjectRemoved(simDataService.RemoveLandObject); |
658 | 658 | ||
659 | m_sceneGraph = new SceneGraph(this, m_regInfo); | 659 | m_sceneGraph = new SceneGraph(this); |
660 | 660 | ||
661 | // If the scene graph has an Unrecoverable error, restart this sim. | 661 | // If the scene graph has an Unrecoverable error, restart this sim. |
662 | // Currently the only thing that causes it to happen is two kinds of specific | 662 | // Currently the only thing that causes it to happen is two kinds of specific |
@@ -870,6 +870,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
870 | 870 | ||
871 | if (dm != null) | 871 | if (dm != null) |
872 | m_eventManager.OnPermissionError += dm.SendAlertToUser; | 872 | m_eventManager.OnPermissionError += dm.SendAlertToUser; |
873 | |||
874 | m_eventManager.OnSignificantClientMovement += HandleOnSignificantClientMovement; | ||
873 | } | 875 | } |
874 | 876 | ||
875 | public override string GetSimulatorVersion() | 877 | public override string GetSimulatorVersion() |
@@ -1170,87 +1172,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1170 | m_dialogModule = RequestModuleInterface<IDialogModule>(); | 1172 | m_dialogModule = RequestModuleInterface<IDialogModule>(); |
1171 | m_capsModule = RequestModuleInterface<ICapabilitiesModule>(); | 1173 | m_capsModule = RequestModuleInterface<ICapabilitiesModule>(); |
1172 | m_teleportModule = RequestModuleInterface<IEntityTransferModule>(); | 1174 | m_teleportModule = RequestModuleInterface<IEntityTransferModule>(); |
1173 | |||
1174 | // Shoving this in here for now, because we have the needed | ||
1175 | // interfaces at this point | ||
1176 | // | ||
1177 | // TODO: Find a better place for this | ||
1178 | // | ||
1179 | while (m_regInfo.EstateSettings.EstateOwner == UUID.Zero && MainConsole.Instance != null) | ||
1180 | { | ||
1181 | MainConsole.Instance.OutputFormat("Estate {0} has no owner set.", m_regInfo.EstateSettings.EstateName); | ||
1182 | List<char> excluded = new List<char>(new char[1]{' '}); | ||
1183 | string first = MainConsole.Instance.CmdPrompt("Estate owner first name", "Test", excluded); | ||
1184 | string last = MainConsole.Instance.CmdPrompt("Estate owner last name", "User", excluded); | ||
1185 | |||
1186 | UserAccount account = UserAccountService.GetUserAccount(m_regInfo.ScopeID, first, last); | ||
1187 | |||
1188 | if (account == null) | ||
1189 | { | ||
1190 | // Create a new account | ||
1191 | account = new UserAccount(m_regInfo.ScopeID, first, last, String.Empty); | ||
1192 | if (account.ServiceURLs == null || (account.ServiceURLs != null && account.ServiceURLs.Count == 0)) | ||
1193 | { | ||
1194 | account.ServiceURLs = new Dictionary<string, object>(); | ||
1195 | account.ServiceURLs["HomeURI"] = string.Empty; | ||
1196 | account.ServiceURLs["GatekeeperURI"] = string.Empty; | ||
1197 | account.ServiceURLs["InventoryServerURI"] = string.Empty; | ||
1198 | account.ServiceURLs["AssetServerURI"] = string.Empty; | ||
1199 | } | ||
1200 | |||
1201 | if (UserAccountService.StoreUserAccount(account)) | ||
1202 | { | ||
1203 | string password = MainConsole.Instance.PasswdPrompt("Password"); | ||
1204 | string email = MainConsole.Instance.CmdPrompt("Email", ""); | ||
1205 | |||
1206 | account.Email = email; | ||
1207 | UserAccountService.StoreUserAccount(account); | ||
1208 | |||
1209 | bool success = false; | ||
1210 | success = AuthenticationService.SetPassword(account.PrincipalID, password); | ||
1211 | if (!success) | ||
1212 | m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to set password for account {0} {1}.", | ||
1213 | first, last); | ||
1214 | |||
1215 | GridRegion home = null; | ||
1216 | if (GridService != null) | ||
1217 | { | ||
1218 | List<GridRegion> defaultRegions = GridService.GetDefaultRegions(UUID.Zero); | ||
1219 | if (defaultRegions != null && defaultRegions.Count >= 1) | ||
1220 | home = defaultRegions[0]; | ||
1221 | |||
1222 | if (GridUserService != null && home != null) | ||
1223 | GridUserService.SetHome(account.PrincipalID.ToString(), home.RegionID, new Vector3(128, 128, 0), new Vector3(0, 1, 0)); | ||
1224 | else | ||
1225 | m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to set home for account {0} {1}.", | ||
1226 | first, last); | ||
1227 | |||
1228 | } | ||
1229 | else | ||
1230 | m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to retrieve home region for account {0} {1}.", | ||
1231 | first, last); | ||
1232 | |||
1233 | if (InventoryService != null) | ||
1234 | success = InventoryService.CreateUserInventory(account.PrincipalID); | ||
1235 | if (!success) | ||
1236 | m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to create inventory for account {0} {1}.", | ||
1237 | first, last); | ||
1238 | |||
1239 | |||
1240 | m_log.InfoFormat("[USER ACCOUNT SERVICE]: Account {0} {1} created successfully", first, last); | ||
1241 | |||
1242 | m_regInfo.EstateSettings.EstateOwner = account.PrincipalID; | ||
1243 | m_regInfo.EstateSettings.Save(); | ||
1244 | } | ||
1245 | else | ||
1246 | m_log.ErrorFormat("[SCENE]: Unable to store account. If this simulator is connected to a grid, you must create the estate owner account first."); | ||
1247 | } | ||
1248 | else | ||
1249 | { | ||
1250 | m_regInfo.EstateSettings.EstateOwner = account.PrincipalID; | ||
1251 | m_regInfo.EstateSettings.Save(); | ||
1252 | } | ||
1253 | } | ||
1254 | } | 1175 | } |
1255 | 1176 | ||
1256 | #endregion | 1177 | #endregion |
@@ -1579,7 +1500,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1579 | msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID; | 1500 | msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID; |
1580 | msg.Position = Vector3.Zero; | 1501 | msg.Position = Vector3.Zero; |
1581 | msg.RegionID = RegionInfo.RegionID.Guid; | 1502 | msg.RegionID = RegionInfo.RegionID.Guid; |
1582 | msg.binaryBucket = new byte[0]; | 1503 | |
1504 | // We must fill in a null-terminated 'empty' string here since bytes[0] will crash viewer 3. | ||
1505 | msg.binaryBucket = Util.StringToBytes256("\0"); | ||
1583 | if (ret.Value.count > 1) | 1506 | if (ret.Value.count > 1) |
1584 | msg.message = string.Format("Your {0} objects were returned from {1} in region {2} due to {3}", ret.Value.count, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason); | 1507 | msg.message = string.Format("Your {0} objects were returned from {1} in region {2} due to {3}", ret.Value.count, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason); |
1585 | else | 1508 | else |
@@ -2459,14 +2382,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
2459 | /// <returns>False</returns> | 2382 | /// <returns>False</returns> |
2460 | public virtual bool IncomingCreateObject(UUID userID, UUID itemID) | 2383 | public virtual bool IncomingCreateObject(UUID userID, UUID itemID) |
2461 | { | 2384 | { |
2462 | //m_log.DebugFormat(" >>> IncomingCreateObject(userID, itemID) <<< {0} {1}", userID, itemID); | 2385 | m_log.DebugFormat(" >>> IncomingCreateObject(userID, itemID) <<< {0} {1}", userID, itemID); |
2463 | 2386 | ||
2464 | ScenePresence sp = GetScenePresence(userID); | 2387 | // Commented out since this is as yet unused and is arguably not the appropriate place to do this, as |
2465 | if (sp != null && AttachmentsModule != null) | 2388 | // attachments are being rezzed elsewhere in AddNewClient() |
2466 | { | 2389 | // ScenePresence sp = GetScenePresence(userID); |
2467 | uint attPt = (uint)sp.Appearance.GetAttachpoint(itemID); | 2390 | // if (sp != null && AttachmentsModule != null) |
2468 | AttachmentsModule.RezSingleAttachmentFromInventory(sp.ControllingClient, itemID, attPt); | 2391 | // { |
2469 | } | 2392 | // uint attPt = (uint)sp.Appearance.GetAttachpoint(itemID); |
2393 | // AttachmentsModule.RezSingleAttachmentFromInventory(sp.ControllingClient, itemID, attPt); | ||
2394 | // } | ||
2470 | 2395 | ||
2471 | return false; | 2396 | return false; |
2472 | } | 2397 | } |
@@ -5215,5 +5140,70 @@ namespace OpenSim.Region.Framework.Scenes | |||
5215 | reason = String.Empty; | 5140 | reason = String.Empty; |
5216 | return true; | 5141 | return true; |
5217 | } | 5142 | } |
5143 | |||
5144 | /// <summary> | ||
5145 | /// This method deals with movement when an avatar is automatically moving (but this is distinct from the | ||
5146 | /// autopilot that moves an avatar to a sit target!. | ||
5147 | /// </summary> | ||
5148 | /// <remarks> | ||
5149 | /// This is not intended as a permament location for this method. | ||
5150 | /// </remarks> | ||
5151 | /// <param name="presence"></param> | ||
5152 | private void HandleOnSignificantClientMovement(ScenePresence presence) | ||
5153 | { | ||
5154 | if (presence.MovingToTarget) | ||
5155 | { | ||
5156 | double distanceToTarget = Util.GetDistanceTo(presence.AbsolutePosition, presence.MoveToPositionTarget); | ||
5157 | // m_log.DebugFormat( | ||
5158 | // "[SCENE]: Abs pos of {0} is {1}, target {2}, distance {3}", | ||
5159 | // presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget, distanceToTarget); | ||
5160 | |||
5161 | // Check the error term of the current position in relation to the target position | ||
5162 | if (distanceToTarget <= ScenePresence.SIGNIFICANT_MOVEMENT) | ||
5163 | { | ||
5164 | // We are close enough to the target | ||
5165 | // m_log.DebugFormat("[SCENEE]: Stopping autopilot of {0}", presence.Name); | ||
5166 | |||
5167 | presence.Velocity = Vector3.Zero; | ||
5168 | presence.AbsolutePosition = presence.MoveToPositionTarget; | ||
5169 | presence.ResetMoveToTarget(); | ||
5170 | |||
5171 | if (presence.PhysicsActor.Flying) | ||
5172 | { | ||
5173 | // A horrible hack to stop the avatar dead in its tracks rather than having them overshoot | ||
5174 | // the target if flying. | ||
5175 | // We really need to be more subtle (slow the avatar as it approaches the target) or at | ||
5176 | // least be able to set collision status once, rather than 5 times to give it enough | ||
5177 | // weighting so that that PhysicsActor thinks it really is colliding. | ||
5178 | for (int i = 0; i < 5; i++) | ||
5179 | presence.PhysicsActor.IsColliding = true; | ||
5180 | |||
5181 | if (presence.LandAtTarget) | ||
5182 | presence.PhysicsActor.Flying = false; | ||
5183 | |||
5184 | // Vector3 targetPos = presence.MoveToPositionTarget; | ||
5185 | // float terrainHeight = (float)presence.Scene.Heightmap[(int)targetPos.X, (int)targetPos.Y]; | ||
5186 | // if (targetPos.Z - terrainHeight < 0.2) | ||
5187 | // { | ||
5188 | // presence.PhysicsActor.Flying = false; | ||
5189 | // } | ||
5190 | } | ||
5191 | |||
5192 | // m_log.DebugFormat( | ||
5193 | // "[SCENE]: AgentControlFlags {0}, MovementFlag {1} for {2}", | ||
5194 | // presence.AgentControlFlags, presence.MovementFlag, presence.Name); | ||
5195 | } | ||
5196 | else | ||
5197 | { | ||
5198 | // m_log.DebugFormat( | ||
5199 | // "[SCENE]: Updating npc {0} at {1} for next movement to {2}", | ||
5200 | // presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget); | ||
5201 | |||
5202 | Vector3 agent_control_v3 = new Vector3(); | ||
5203 | presence.HandleMoveToTargetUpdate(ref agent_control_v3); | ||
5204 | presence.AddNewMovement(agent_control_v3); | ||
5205 | } | ||
5206 | } | ||
5207 | } | ||
5218 | } | 5208 | } |
5219 | } | 5209 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 6f963ac..36c5c52 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -74,7 +74,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
74 | 74 | ||
75 | protected internal EntityManager Entities = new EntityManager(); | 75 | protected internal EntityManager Entities = new EntityManager(); |
76 | 76 | ||
77 | protected RegionInfo m_regInfo; | ||
78 | protected Scene m_parentScene; | 77 | protected Scene m_parentScene; |
79 | protected Dictionary<UUID, SceneObjectGroup> m_updateList = new Dictionary<UUID, SceneObjectGroup>(); | 78 | protected Dictionary<UUID, SceneObjectGroup> m_updateList = new Dictionary<UUID, SceneObjectGroup>(); |
80 | protected int m_numRootAgents = 0; | 79 | protected int m_numRootAgents = 0; |
@@ -108,10 +107,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
108 | 107 | ||
109 | #endregion | 108 | #endregion |
110 | 109 | ||
111 | protected internal SceneGraph(Scene parent, RegionInfo regInfo) | 110 | protected internal SceneGraph(Scene parent) |
112 | { | 111 | { |
113 | m_parentScene = parent; | 112 | m_parentScene = parent; |
114 | m_regInfo = regInfo; | ||
115 | } | 113 | } |
116 | 114 | ||
117 | public PhysicsScene PhysicsScene | 115 | public PhysicsScene PhysicsScene |
@@ -122,7 +120,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
122 | // If we're not doing the initial set | 120 | // If we're not doing the initial set |
123 | // Then we've got to remove the previous | 121 | // Then we've got to remove the previous |
124 | // event handler | 122 | // event handler |
125 | |||
126 | if (_PhyScene != null) | 123 | if (_PhyScene != null) |
127 | _PhyScene.OnPhysicsCrash -= physicsBasedCrash; | 124 | _PhyScene.OnPhysicsCrash -= physicsBasedCrash; |
128 | 125 | ||
@@ -372,12 +369,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
372 | // "[SCENEGRAPH]: Adding scene object {0} {1}, with {2} parts on {3}", | 369 | // "[SCENEGRAPH]: Adding scene object {0} {1}, with {2} parts on {3}", |
373 | // sceneObject.Name, sceneObject.UUID, sceneObject.Parts.Length, m_parentScene.RegionInfo.RegionName); | 370 | // sceneObject.Name, sceneObject.UUID, sceneObject.Parts.Length, m_parentScene.RegionInfo.RegionName); |
374 | 371 | ||
375 | SceneObjectPart[] children = sceneObject.Parts; | 372 | SceneObjectPart[] parts = sceneObject.Parts; |
376 | 373 | ||
377 | // Clamp child prim sizes and add child prims to the m_numPrim count | 374 | // Clamp child prim sizes and add child prims to the m_numPrim count |
378 | if (m_parentScene.m_clampPrimSize) | 375 | if (m_parentScene.m_clampPrimSize) |
379 | { | 376 | { |
380 | foreach (SceneObjectPart part in children) | 377 | foreach (SceneObjectPart part in parts) |
381 | { | 378 | { |
382 | Vector3 scale = part.Shape.Scale; | 379 | Vector3 scale = part.Shape.Scale; |
383 | 380 | ||
@@ -391,7 +388,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
391 | part.Shape.Scale = scale; | 388 | part.Shape.Scale = scale; |
392 | } | 389 | } |
393 | } | 390 | } |
394 | m_numPrim += children.Length; | 391 | m_numPrim += parts.Length; |
395 | 392 | ||
396 | sceneObject.AttachToScene(m_parentScene); | 393 | sceneObject.AttachToScene(m_parentScene); |
397 | 394 | ||
@@ -411,15 +408,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
411 | 408 | ||
412 | lock (SceneObjectGroupsByFullPartID) | 409 | lock (SceneObjectGroupsByFullPartID) |
413 | { | 410 | { |
414 | SceneObjectGroupsByFullPartID[sceneObject.UUID] = sceneObject; | 411 | foreach (SceneObjectPart part in parts) |
415 | foreach (SceneObjectPart part in children) | ||
416 | SceneObjectGroupsByFullPartID[part.UUID] = sceneObject; | 412 | SceneObjectGroupsByFullPartID[part.UUID] = sceneObject; |
417 | } | 413 | } |
418 | 414 | ||
419 | lock (SceneObjectGroupsByLocalPartID) | 415 | lock (SceneObjectGroupsByLocalPartID) |
420 | { | 416 | { |
421 | SceneObjectGroupsByLocalPartID[sceneObject.LocalId] = sceneObject; | 417 | // m_log.DebugFormat( |
422 | foreach (SceneObjectPart part in children) | 418 | // "[SCENE GRAPH]: Adding scene object {0} {1} {2} to SceneObjectGroupsByLocalPartID in {3}", |
419 | // sceneObject.Name, sceneObject.UUID, sceneObject.LocalId, m_parentScene.RegionInfo.RegionName); | ||
420 | |||
421 | foreach (SceneObjectPart part in parts) | ||
423 | SceneObjectGroupsByLocalPartID[part.LocalId] = sceneObject; | 422 | SceneObjectGroupsByLocalPartID[part.LocalId] = sceneObject; |
424 | } | 423 | } |
425 | 424 | ||
@@ -432,6 +431,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
432 | /// <returns>true if the object was deleted, false if there was no object to delete</returns> | 431 | /// <returns>true if the object was deleted, false if there was no object to delete</returns> |
433 | public bool DeleteSceneObject(UUID uuid, bool resultOfObjectLinked) | 432 | public bool DeleteSceneObject(UUID uuid, bool resultOfObjectLinked) |
434 | { | 433 | { |
434 | // m_log.DebugFormat( | ||
435 | // "[SCENE GRAPH]: Deleting scene object with uuid {0}, resultOfObjectLinked = {1}", | ||
436 | // uuid, resultOfObjectLinked); | ||
437 | |||
435 | EntityBase entity; | 438 | EntityBase entity; |
436 | if (!Entities.TryGetValue(uuid, out entity) || (!(entity is SceneObjectGroup))) | 439 | if (!Entities.TryGetValue(uuid, out entity) || (!(entity is SceneObjectGroup))) |
437 | return false; | 440 | return false; |
@@ -460,7 +463,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
460 | SceneObjectPart[] parts = grp.Parts; | 463 | SceneObjectPart[] parts = grp.Parts; |
461 | for (int i = 0; i < parts.Length; i++) | 464 | for (int i = 0; i < parts.Length; i++) |
462 | SceneObjectGroupsByFullPartID.Remove(parts[i].UUID); | 465 | SceneObjectGroupsByFullPartID.Remove(parts[i].UUID); |
463 | SceneObjectGroupsByFullPartID.Remove(grp.RootPart.UUID); | ||
464 | } | 466 | } |
465 | 467 | ||
466 | lock (SceneObjectGroupsByLocalPartID) | 468 | lock (SceneObjectGroupsByLocalPartID) |
@@ -468,7 +470,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
468 | SceneObjectPart[] parts = grp.Parts; | 470 | SceneObjectPart[] parts = grp.Parts; |
469 | for (int i = 0; i < parts.Length; i++) | 471 | for (int i = 0; i < parts.Length; i++) |
470 | SceneObjectGroupsByLocalPartID.Remove(parts[i].LocalId); | 472 | SceneObjectGroupsByLocalPartID.Remove(parts[i].LocalId); |
471 | SceneObjectGroupsByLocalPartID.Remove(grp.RootPart.LocalId); | ||
472 | } | 473 | } |
473 | 474 | ||
474 | return Entities.Remove(uuid); | 475 | return Entities.Remove(uuid); |
@@ -589,7 +590,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
589 | ScenePresence newAvatar = null; | 590 | ScenePresence newAvatar = null; |
590 | 591 | ||
591 | // ScenePresence always defaults to child agent | 592 | // ScenePresence always defaults to child agent |
592 | newAvatar = new ScenePresence(client, m_parentScene, m_regInfo, appearance, type); | 593 | newAvatar = new ScenePresence(client, m_parentScene, appearance, type); |
593 | 594 | ||
594 | AddScenePresence(newAvatar); | 595 | AddScenePresence(newAvatar); |
595 | 596 | ||
@@ -651,7 +652,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
651 | if (!Entities.Remove(agentID)) | 652 | if (!Entities.Remove(agentID)) |
652 | { | 653 | { |
653 | m_log.WarnFormat( | 654 | m_log.WarnFormat( |
654 | "[SCENEGRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene Entities list", | 655 | "[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene Entities list", |
655 | agentID); | 656 | agentID); |
656 | } | 657 | } |
657 | 658 | ||
@@ -674,7 +675,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
674 | } | 675 | } |
675 | else | 676 | else |
676 | { | 677 | { |
677 | m_log.WarnFormat("[SCENEGRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); | 678 | m_log.WarnFormat("[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); |
678 | } | 679 | } |
679 | } | 680 | } |
680 | } | 681 | } |
@@ -881,7 +882,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
881 | if (Entities.TryGetValue(localID, out entity)) | 882 | if (Entities.TryGetValue(localID, out entity)) |
882 | return entity as SceneObjectGroup; | 883 | return entity as SceneObjectGroup; |
883 | 884 | ||
884 | //m_log.DebugFormat("Entered GetGroupByPrim with localID {0}", localID); | 885 | // m_log.DebugFormat("[SCENE GRAPH]: Entered GetGroupByPrim with localID {0}", localID); |
886 | |||
885 | SceneObjectGroup sog; | 887 | SceneObjectGroup sog; |
886 | lock (SceneObjectGroupsByLocalPartID) | 888 | lock (SceneObjectGroupsByLocalPartID) |
887 | SceneObjectGroupsByLocalPartID.TryGetValue(localID, out sog); | 889 | SceneObjectGroupsByLocalPartID.TryGetValue(localID, out sog); |
@@ -889,8 +891,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
889 | if (sog != null) | 891 | if (sog != null) |
890 | { | 892 | { |
891 | if (sog.HasChildPrim(localID)) | 893 | if (sog.HasChildPrim(localID)) |
894 | { | ||
895 | // m_log.DebugFormat( | ||
896 | // "[SCENE GRAPH]: Found scene object {0} {1} {2} containing part with local id {3} in {4}. Returning.", | ||
897 | // sog.Name, sog.UUID, sog.LocalId, localID, m_parentScene.RegionInfo.RegionName); | ||
898 | |||
892 | return sog; | 899 | return sog; |
893 | SceneObjectGroupsByLocalPartID.Remove(localID); | 900 | } |
901 | else | ||
902 | { | ||
903 | lock (SceneObjectGroupsByLocalPartID) | ||
904 | { | ||
905 | m_log.WarnFormat( | ||
906 | "[SCENE GRAPH]: Found scene object {0} {1} {2} via SceneObjectGroupsByLocalPartID index but it doesn't contain part with local id {3}. Removing from entry from index in {4}.", | ||
907 | sog.Name, sog.UUID, sog.LocalId, localID, m_parentScene.RegionInfo.RegionName); | ||
908 | |||
909 | SceneObjectGroupsByLocalPartID.Remove(localID); | ||
910 | } | ||
911 | } | ||
894 | } | 912 | } |
895 | 913 | ||
896 | EntityBase[] entityList = GetEntities(); | 914 | EntityBase[] entityList = GetEntities(); |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index 4bca3d0..905ecc9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs | |||
@@ -389,5 +389,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
389 | for (int i = 0; i < parts.Length; i++) | 389 | for (int i = 0; i < parts.Length; i++) |
390 | parts[i].Inventory.ResumeScripts(); | 390 | parts[i].Inventory.ResumeScripts(); |
391 | } | 391 | } |
392 | |||
393 | /// <summary> | ||
394 | /// Returns true if any part in the scene object contains scripts, false otherwise. | ||
395 | /// </summary> | ||
396 | /// <returns></returns> | ||
397 | public bool ContainsScripts() | ||
398 | { | ||
399 | foreach (SceneObjectPart part in Parts) | ||
400 | if (part.Inventory.ContainsScripts()) | ||
401 | return true; | ||
402 | |||
403 | return false; | ||
404 | } | ||
392 | } | 405 | } |
393 | } | 406 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 2819545..980b01f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -1599,7 +1599,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1599 | ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar); | 1599 | ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar); |
1600 | if (avatar != null) | 1600 | if (avatar != null) |
1601 | { | 1601 | { |
1602 | avatar.MoveToTarget(target, false); | 1602 | avatar.MoveToTarget(target, false, false); |
1603 | } | 1603 | } |
1604 | } | 1604 | } |
1605 | else | 1605 | else |
@@ -1728,8 +1728,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1728 | 1728 | ||
1729 | #endregion | 1729 | #endregion |
1730 | 1730 | ||
1731 | #region Scheduling | ||
1732 | |||
1733 | public override void Update() | 1731 | public override void Update() |
1734 | { | 1732 | { |
1735 | // Check that the group was not deleted before the scheduled update | 1733 | // Check that the group was not deleted before the scheduled update |
@@ -1880,7 +1878,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1880 | parts[i].SendTerseUpdateToAllClients(); | 1878 | parts[i].SendTerseUpdateToAllClients(); |
1881 | } | 1879 | } |
1882 | 1880 | ||
1883 | #endregion | 1881 | /// <summary> |
1882 | /// Send metadata about the root prim (name, description, sale price, etc.) to a client. | ||
1883 | /// </summary> | ||
1884 | /// <param name="client"></param> | ||
1885 | public void SendPropertiesToClient(IClientAPI client) | ||
1886 | { | ||
1887 | m_rootPart.SendPropertiesToClient(client); | ||
1888 | } | ||
1884 | 1889 | ||
1885 | #region SceneGroupPart Methods | 1890 | #region SceneGroupPart Methods |
1886 | 1891 | ||
@@ -2370,15 +2375,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2370 | } | 2375 | } |
2371 | 2376 | ||
2372 | /// <summary> | 2377 | /// <summary> |
2373 | /// Return metadata about a prim (name, description, sale price, etc.) | ||
2374 | /// </summary> | ||
2375 | /// <param name="client"></param> | ||
2376 | public void GetProperties(IClientAPI client) | ||
2377 | { | ||
2378 | m_rootPart.GetProperties(client); | ||
2379 | } | ||
2380 | |||
2381 | /// <summary> | ||
2382 | /// Set the name of a prim | 2378 | /// Set the name of a prim |
2383 | /// </summary> | 2379 | /// </summary> |
2384 | /// <param name="name"></param> | 2380 | /// <param name="name"></param> |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 04fef83..632ac8f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -1305,8 +1305,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1305 | 1305 | ||
1306 | #endregion Public Properties with only Get | 1306 | #endregion Public Properties with only Get |
1307 | 1307 | ||
1308 | #region Private Methods | ||
1309 | |||
1310 | private uint ApplyMask(uint val, bool set, uint mask) | 1308 | private uint ApplyMask(uint val, bool set, uint mask) |
1311 | { | 1309 | { |
1312 | if (set) | 1310 | if (set) |
@@ -1327,14 +1325,27 @@ namespace OpenSim.Region.Framework.Scenes | |||
1327 | m_updateFlag = 0; | 1325 | m_updateFlag = 0; |
1328 | } | 1326 | } |
1329 | 1327 | ||
1330 | private void SendObjectPropertiesToClient(UUID AgentID) | 1328 | /// <summary> |
1329 | /// Send this part's properties (name, description, inventory serial, base mask, etc.) to a client | ||
1330 | /// </summary> | ||
1331 | /// <param name="client"></param> | ||
1332 | public void SendPropertiesToClient(IClientAPI client) | ||
1333 | { | ||
1334 | client.SendObjectPropertiesReply(this); | ||
1335 | } | ||
1336 | |||
1337 | /// <summary> | ||
1338 | /// For the scene object group to which this part belongs, send that scene object's root part properties to a client. | ||
1339 | /// </summary> | ||
1340 | /// <param name="AgentID"></param> | ||
1341 | private void SendRootPartPropertiesToClient(UUID AgentID) | ||
1331 | { | 1342 | { |
1332 | m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) | 1343 | m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) |
1333 | { | 1344 | { |
1334 | // Ugly reference :( | 1345 | // Ugly reference :( |
1335 | if (avatar.UUID == AgentID) | 1346 | if (avatar.UUID == AgentID) |
1336 | { | 1347 | { |
1337 | m_parentGroup.GetProperties(avatar.ControllingClient); | 1348 | m_parentGroup.SendPropertiesToClient(avatar.ControllingClient); |
1338 | } | 1349 | } |
1339 | }); | 1350 | }); |
1340 | } | 1351 | } |
@@ -1363,8 +1374,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1363 | // } | 1374 | // } |
1364 | // } | 1375 | // } |
1365 | 1376 | ||
1366 | #endregion Private Methods | ||
1367 | |||
1368 | #region Public Methods | 1377 | #region Public Methods |
1369 | 1378 | ||
1370 | public void ResetExpire() | 1379 | public void ResetExpire() |
@@ -1705,20 +1714,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1705 | Name, LocalId, id); | 1714 | Name, LocalId, id); |
1706 | } | 1715 | } |
1707 | 1716 | ||
1708 | public static SceneObjectPart Create() | ||
1709 | { | ||
1710 | SceneObjectPart part = new SceneObjectPart(); | ||
1711 | part.UUID = UUID.Random(); | ||
1712 | |||
1713 | PrimitiveBaseShape shape = PrimitiveBaseShape.Create(); | ||
1714 | part.Shape = shape; | ||
1715 | |||
1716 | part.Name = "Primitive"; | ||
1717 | part._ownerID = UUID.Random(); | ||
1718 | |||
1719 | return part; | ||
1720 | } | ||
1721 | |||
1722 | /// <summary> | 1717 | /// <summary> |
1723 | /// Do a physics property update for a NINJA joint. | 1718 | /// Do a physics property update for a NINJA joint. |
1724 | /// </summary> | 1719 | /// </summary> |
@@ -2030,11 +2025,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2030 | return Vector3.Zero; | 2025 | return Vector3.Zero; |
2031 | } | 2026 | } |
2032 | 2027 | ||
2033 | public void GetProperties(IClientAPI client) | ||
2034 | { | ||
2035 | client.SendObjectPropertiesReply(this); | ||
2036 | } | ||
2037 | |||
2038 | /// <summary> | 2028 | /// <summary> |
2039 | /// Method for a prim to get it's world position from the group. | 2029 | /// Method for a prim to get it's world position from the group. |
2040 | /// </summary> | 2030 | /// </summary> |
@@ -3453,7 +3443,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3453 | { | 3443 | { |
3454 | _groupID = groupID; | 3444 | _groupID = groupID; |
3455 | if (client != null) | 3445 | if (client != null) |
3456 | GetProperties(client); | 3446 | SendPropertiesToClient(client); |
3457 | m_updateFlag = 2; | 3447 | m_updateFlag = 2; |
3458 | } | 3448 | } |
3459 | 3449 | ||
@@ -4273,10 +4263,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
4273 | 4263 | ||
4274 | break; | 4264 | break; |
4275 | } | 4265 | } |
4276 | SendFullUpdateToAllClients(); | ||
4277 | 4266 | ||
4278 | SendObjectPropertiesToClient(AgentID); | 4267 | SendFullUpdateToAllClients(); |
4279 | 4268 | ||
4269 | SendRootPartPropertiesToClient(AgentID); | ||
4280 | } | 4270 | } |
4281 | } | 4271 | } |
4282 | 4272 | ||
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index e40e57d..9446741 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | |||
@@ -784,6 +784,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
784 | 784 | ||
785 | private bool CreateInventoryFile() | 785 | private bool CreateInventoryFile() |
786 | { | 786 | { |
787 | // m_log.DebugFormat( | ||
788 | // "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}", | ||
789 | // m_part.Name, m_part.UUID, m_part.LocalId, m_inventorySerial); | ||
790 | |||
787 | if (m_inventoryFileName == String.Empty || | 791 | if (m_inventoryFileName == String.Empty || |
788 | m_inventoryFileNameSerial < m_inventorySerial) | 792 | m_inventoryFileNameSerial < m_inventorySerial) |
789 | { | 793 | { |
@@ -797,6 +801,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
797 | { | 801 | { |
798 | foreach (TaskInventoryItem item in m_items.Values) | 802 | foreach (TaskInventoryItem item in m_items.Values) |
799 | { | 803 | { |
804 | // m_log.DebugFormat( | ||
805 | // "[PRIM INVENTORY]: Adding item {0} {1} for serial {2} on prim {3} {4} {5}", | ||
806 | // item.Name, item.ItemID, m_inventorySerial, m_part.Name, m_part.UUID, m_part.LocalId); | ||
807 | |||
800 | UUID ownerID = item.OwnerID; | 808 | UUID ownerID = item.OwnerID; |
801 | uint everyoneMask = 0; | 809 | uint everyoneMask = 0; |
802 | uint baseMask = item.BasePermissions; | 810 | uint baseMask = item.BasePermissions; |
@@ -856,28 +864,43 @@ namespace OpenSim.Region.Framework.Scenes | |||
856 | /// <param name="xferManager"></param> | 864 | /// <param name="xferManager"></param> |
857 | public void RequestInventoryFile(IClientAPI client, IXfer xferManager) | 865 | public void RequestInventoryFile(IClientAPI client, IXfer xferManager) |
858 | { | 866 | { |
859 | CreateInventoryFile(); | 867 | lock (m_items) |
860 | |||
861 | if (m_inventorySerial == 0) // No inventory | ||
862 | { | 868 | { |
863 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | 869 | // Don't send a inventory xfer name if there are no items. Doing so causes viewer 3 to crash when rezzing |
864 | return; | 870 | // a new script if any previous deletion has left the prim inventory empty. |
865 | } | 871 | if (m_items.Count == 0) // No inventory |
866 | 872 | { | |
867 | // In principle, we should only do the rest if the inventory changed; | 873 | // m_log.DebugFormat( |
868 | // by sending m_inventorySerial to the client, it ought to know | 874 | // "[PRIM INVENTORY]: Not sending inventory data for part {0} {1} {2} for {3} since no items", |
869 | // that nothing changed and that it doesn't need to request the file. | 875 | // m_part.Name, m_part.LocalId, m_part.UUID, client.Name); |
870 | // Unfortunately, it doesn't look like the client optimizes this; | ||
871 | // the client seems to always come back and request the Xfer, | ||
872 | // no matter what value m_inventorySerial has. | ||
873 | 876 | ||
874 | if (m_inventoryFileData.Length > 2) | 877 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); |
875 | // Add the file for Xfer | 878 | return; |
876 | xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); | 879 | } |
877 | 880 | ||
878 | // Tell the client we're ready to Xfer the file | 881 | CreateInventoryFile(); |
879 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, | 882 | |
880 | Util.StringToBytes256(m_inventoryFileName)); | 883 | // In principle, we should only do the rest if the inventory changed; |
884 | // by sending m_inventorySerial to the client, it ought to know | ||
885 | // that nothing changed and that it doesn't need to request the file. | ||
886 | // Unfortunately, it doesn't look like the client optimizes this; | ||
887 | // the client seems to always come back and request the Xfer, | ||
888 | // no matter what value m_inventorySerial has. | ||
889 | // FIXME: Could probably be > 0 here rather than > 2 | ||
890 | if (m_inventoryFileData.Length > 2) | ||
891 | { | ||
892 | // Add the file for Xfer | ||
893 | // m_log.DebugFormat( | ||
894 | // "[PRIM INVENTORY]: Adding inventory file {0} (length {1}) for transfer on {2} {3} {4}", | ||
895 | // m_inventoryFileName, m_inventoryFileData.Length, m_part.Name, m_part.UUID, m_part.LocalId); | ||
896 | |||
897 | xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); | ||
898 | } | ||
899 | |||
900 | // Tell the client we're ready to Xfer the file | ||
901 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, | ||
902 | Util.StringToBytes256(m_inventoryFileName)); | ||
903 | } | ||
881 | } | 904 | } |
882 | 905 | ||
883 | /// <summary> | 906 | /// <summary> |
@@ -1035,10 +1058,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1035 | item.BasePermissions = perms; | 1058 | item.BasePermissions = perms; |
1036 | } | 1059 | } |
1037 | } | 1060 | } |
1061 | |||
1038 | m_inventorySerial++; | 1062 | m_inventorySerial++; |
1039 | HasInventoryChanged = true; | 1063 | HasInventoryChanged = true; |
1040 | } | 1064 | } |
1041 | 1065 | ||
1066 | /// <summary> | ||
1067 | /// Returns true if this part inventory contains any scripts. False otherwise. | ||
1068 | /// </summary> | ||
1069 | /// <returns></returns> | ||
1042 | public bool ContainsScripts() | 1070 | public bool ContainsScripts() |
1043 | { | 1071 | { |
1044 | lock (m_items) | 1072 | lock (m_items) |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index f231a39..5b02c3b 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -70,7 +70,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
70 | { | 70 | { |
71 | // ~ScenePresence() | 71 | // ~ScenePresence() |
72 | // { | 72 | // { |
73 | // m_log.Debug("[ScenePresence] Destructor called"); | 73 | // m_log.Debug("[SCENE PRESENCE] Destructor called"); |
74 | // } | 74 | // } |
75 | 75 | ||
76 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 76 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
@@ -120,6 +120,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
120 | /// </remarks> | 120 | /// </remarks> |
121 | protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); | 121 | protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); |
122 | 122 | ||
123 | public Object AttachmentsSyncLock { get; private set; } | ||
124 | |||
123 | private Dictionary<UUID, ScriptControllers> scriptedcontrols = new Dictionary<UUID, ScriptControllers>(); | 125 | private Dictionary<UUID, ScriptControllers> scriptedcontrols = new Dictionary<UUID, ScriptControllers>(); |
124 | private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO; | 126 | private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO; |
125 | private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO; | 127 | private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO; |
@@ -176,8 +178,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
176 | 178 | ||
177 | private Quaternion m_bodyRot = Quaternion.Identity; | 179 | private Quaternion m_bodyRot = Quaternion.Identity; |
178 | 180 | ||
179 | private Quaternion m_bodyRotPrevious = Quaternion.Identity; | ||
180 | |||
181 | private const int LAND_VELOCITYMAG_MAX = 12; | 181 | private const int LAND_VELOCITYMAG_MAX = 12; |
182 | 182 | ||
183 | public bool IsRestrictedToRegion; | 183 | public bool IsRestrictedToRegion; |
@@ -186,7 +186,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
186 | 186 | ||
187 | private float m_health = 100f; | 187 | private float m_health = 100f; |
188 | 188 | ||
189 | protected RegionInfo m_regionInfo; | ||
190 | protected ulong crossingFromRegion; | 189 | protected ulong crossingFromRegion; |
191 | 190 | ||
192 | private readonly Vector3[] Dir_Vectors = new Vector3[9]; | 191 | private readonly Vector3[] Dir_Vectors = new Vector3[9]; |
@@ -221,6 +220,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
221 | public bool MovingToTarget { get; private set; } | 220 | public bool MovingToTarget { get; private set; } |
222 | public Vector3 MoveToPositionTarget { get; private set; } | 221 | public Vector3 MoveToPositionTarget { get; private set; } |
223 | 222 | ||
223 | /// <summary> | ||
224 | /// Controls whether an avatar automatically moving to a target will land when it gets there (if flying). | ||
225 | /// </summary> | ||
226 | public bool LandAtTarget { get; private set; } | ||
227 | |||
224 | private bool m_followCamAuto; | 228 | private bool m_followCamAuto; |
225 | 229 | ||
226 | private int m_movementUpdateCount; | 230 | private int m_movementUpdateCount; |
@@ -466,7 +470,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
466 | { | 470 | { |
467 | PhysicsActor actor = m_physicsActor; | 471 | PhysicsActor actor = m_physicsActor; |
468 | if (actor != null) | 472 | if (actor != null) |
473 | { | ||
469 | m_pos = actor.Position; | 474 | m_pos = actor.Position; |
475 | |||
476 | // m_log.DebugFormat( | ||
477 | // "[SCENE PRESENCE]: Set position {0} for {1} in {2} via getting AbsolutePosition!", | ||
478 | // m_pos, Name, Scene.RegionInfo.RegionName); | ||
479 | } | ||
470 | else | 480 | else |
471 | { | 481 | { |
472 | // Obtain the correct position of a seated avatar. | 482 | // Obtain the correct position of a seated avatar. |
@@ -510,19 +520,26 @@ namespace OpenSim.Region.Framework.Scenes | |||
510 | } | 520 | } |
511 | catch (Exception e) | 521 | catch (Exception e) |
512 | { | 522 | { |
513 | m_log.Error("[SCENEPRESENCE]: ABSOLUTE POSITION " + e.Message); | 523 | m_log.Error("[SCENE PRESENCE]: ABSOLUTE POSITION " + e.Message); |
514 | } | 524 | } |
515 | } | 525 | } |
516 | 526 | ||
517 | m_pos = value; | 527 | m_pos = value; |
518 | m_parentPosition = Vector3.Zero; | 528 | m_parentPosition = Vector3.Zero; |
529 | |||
530 | // m_log.DebugFormat( | ||
531 | // "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}", | ||
532 | // Scene.RegionInfo.RegionName, Name, m_pos); | ||
519 | } | 533 | } |
520 | } | 534 | } |
521 | 535 | ||
536 | /// <summary> | ||
537 | /// If sitting, returns the offset position from the prim the avatar is sitting on. | ||
538 | /// Otherwise, returns absolute position in the scene. | ||
539 | /// </summary> | ||
522 | public Vector3 OffsetPosition | 540 | public Vector3 OffsetPosition |
523 | { | 541 | { |
524 | get { return m_pos; } | 542 | get { return m_pos; } |
525 | set { m_pos = value; } | ||
526 | } | 543 | } |
527 | 544 | ||
528 | /// <summary> | 545 | /// <summary> |
@@ -534,8 +551,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
534 | { | 551 | { |
535 | PhysicsActor actor = m_physicsActor; | 552 | PhysicsActor actor = m_physicsActor; |
536 | if (actor != null) | 553 | if (actor != null) |
554 | { | ||
537 | m_velocity = actor.Velocity; | 555 | m_velocity = actor.Velocity; |
538 | 556 | ||
557 | // m_log.DebugFormat( | ||
558 | // "[SCENE PRESENCE]: Set velocity {0} for {1} in {2} via getting Velocity!", | ||
559 | // m_velocity, Name, Scene.RegionInfo.RegionName); | ||
560 | } | ||
561 | |||
539 | return m_velocity; | 562 | return m_velocity; |
540 | } | 563 | } |
541 | set | 564 | set |
@@ -550,24 +573,26 @@ namespace OpenSim.Region.Framework.Scenes | |||
550 | } | 573 | } |
551 | catch (Exception e) | 574 | catch (Exception e) |
552 | { | 575 | { |
553 | m_log.Error("[SCENEPRESENCE]: VELOCITY " + e.Message); | 576 | m_log.Error("[SCENE PRESENCE]: VELOCITY " + e.Message); |
554 | } | 577 | } |
555 | } | 578 | } |
556 | 579 | ||
557 | m_velocity = value; | 580 | m_velocity = value; |
581 | |||
582 | // m_log.DebugFormat( | ||
583 | // "[SCENE PRESENCE]: In {0} set velocity of {1} to {2}", | ||
584 | // Scene.RegionInfo.RegionName, Name, m_velocity); | ||
558 | } | 585 | } |
559 | } | 586 | } |
560 | 587 | ||
561 | public Quaternion Rotation | 588 | public Quaternion Rotation |
562 | { | 589 | { |
563 | get { return m_bodyRot; } | 590 | get { return m_bodyRot; } |
564 | set { m_bodyRot = value; } | 591 | set |
565 | } | 592 | { |
566 | 593 | m_bodyRot = value; | |
567 | public Quaternion PreviousRotation | 594 | // m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); |
568 | { | 595 | } |
569 | get { return m_bodyRotPrevious; } | ||
570 | set { m_bodyRotPrevious = value; } | ||
571 | } | 596 | } |
572 | 597 | ||
573 | /// <summary> | 598 | /// <summary> |
@@ -705,23 +730,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
705 | #endregion | 730 | #endregion |
706 | 731 | ||
707 | #region Constructor(s) | 732 | #region Constructor(s) |
708 | 733 | ||
709 | public ScenePresence( | 734 | public ScenePresence( |
710 | IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance, PresenceType type) | 735 | IClientAPI client, Scene world, AvatarAppearance appearance, PresenceType type) |
711 | { | 736 | { |
737 | AttachmentsSyncLock = new Object(); | ||
738 | |||
712 | m_sendCourseLocationsMethod = SendCoarseLocationsDefault; | 739 | m_sendCourseLocationsMethod = SendCoarseLocationsDefault; |
713 | m_sceneViewer = new SceneViewer(this); | 740 | m_sceneViewer = new SceneViewer(this); |
714 | m_animator = new ScenePresenceAnimator(this); | 741 | m_animator = new ScenePresenceAnimator(this); |
715 | PresenceType = type; | 742 | PresenceType = type; |
716 | m_DrawDistance = world.DefaultDrawDistance; | 743 | m_DrawDistance = world.DefaultDrawDistance; |
717 | m_rootRegionHandle = reginfo.RegionHandle; | 744 | m_rootRegionHandle = world.RegionInfo.RegionHandle; |
718 | m_controllingClient = client; | 745 | m_controllingClient = client; |
719 | m_firstname = m_controllingClient.FirstName; | 746 | m_firstname = m_controllingClient.FirstName; |
720 | m_lastname = m_controllingClient.LastName; | 747 | m_lastname = m_controllingClient.LastName; |
721 | m_name = String.Format("{0} {1}", m_firstname, m_lastname); | 748 | m_name = String.Format("{0} {1}", m_firstname, m_lastname); |
722 | m_scene = world; | 749 | m_scene = world; |
723 | m_uuid = client.AgentId; | 750 | m_uuid = client.AgentId; |
724 | m_regionInfo = reginfo; | ||
725 | m_localId = m_scene.AllocateLocalId(); | 751 | m_localId = m_scene.AllocateLocalId(); |
726 | 752 | ||
727 | UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); | 753 | UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); |
@@ -983,7 +1009,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
983 | Animator.ResetAnimations(); | 1009 | Animator.ResetAnimations(); |
984 | 1010 | ||
985 | // m_log.DebugFormat( | 1011 | // m_log.DebugFormat( |
986 | // "[SCENEPRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", | 1012 | // "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", |
987 | // Name, UUID, m_scene.RegionInfo.RegionName); | 1013 | // Name, UUID, m_scene.RegionInfo.RegionName); |
988 | 1014 | ||
989 | // Don't zero out the velocity since this can cause problems when an avatar is making a region crossing, | 1015 | // Don't zero out the velocity since this can cause problems when an avatar is making a region crossing, |
@@ -1150,9 +1176,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1150 | m_callbackURI = null; | 1176 | m_callbackURI = null; |
1151 | } | 1177 | } |
1152 | 1178 | ||
1153 | //m_log.DebugFormat("Completed movement"); | 1179 | //m_log.DebugFormat("[SCENE PRESENCE] Completed movement"); |
1154 | 1180 | ||
1155 | m_controllingClient.MoveAgentIntoRegion(m_regionInfo, AbsolutePosition, look); | 1181 | m_controllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); |
1156 | SendInitialData(); | 1182 | SendInitialData(); |
1157 | 1183 | ||
1158 | // Create child agents in neighbouring regions | 1184 | // Create child agents in neighbouring regions |
@@ -1217,7 +1243,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1217 | /// </summary> | 1243 | /// </summary> |
1218 | public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) | 1244 | public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) |
1219 | { | 1245 | { |
1220 | // m_log.DebugFormat("[SCENE PRESENCE]: Received agent update from {0}", remoteClient.Name); | 1246 | // m_log.DebugFormat( |
1247 | // "[SCENE PRESENCE]: In {0} received agent update from {1}", | ||
1248 | // Scene.RegionInfo.RegionName, remoteClient.Name); | ||
1221 | 1249 | ||
1222 | //if (m_isChildAgent) | 1250 | //if (m_isChildAgent) |
1223 | //{ | 1251 | //{ |
@@ -1658,7 +1686,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
1658 | /// This is to allow movement to targets that are known to be on an elevated platform with a continuous path | 1686 | /// This is to allow movement to targets that are known to be on an elevated platform with a continuous path |
1659 | /// from start to finish. | 1687 | /// from start to finish. |
1660 | /// </param> | 1688 | /// </param> |
1661 | public void MoveToTarget(Vector3 pos, bool noFly) | 1689 | /// <param name="landAtTarget"> |
1690 | /// If true and the avatar starts flying during the move then land at the target. | ||
1691 | /// </param> | ||
1692 | public void MoveToTarget(Vector3 pos, bool noFly, bool landAtTarget) | ||
1662 | { | 1693 | { |
1663 | m_log.DebugFormat( | 1694 | m_log.DebugFormat( |
1664 | "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}", | 1695 | "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}", |
@@ -1684,7 +1715,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1684 | 1715 | ||
1685 | // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is | 1716 | // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is |
1686 | // always slightly higher than the actual terrain height. | 1717 | // always slightly higher than the actual terrain height. |
1687 | // FIXME: This constrains NOC movements as well, so should be somewhere else. | 1718 | // FIXME: This constrains NPC movements as well, so should be somewhere else. |
1688 | if (pos.Z - terrainHeight < 0.2) | 1719 | if (pos.Z - terrainHeight < 0.2) |
1689 | pos.Z = terrainHeight; | 1720 | pos.Z = terrainHeight; |
1690 | 1721 | ||
@@ -1697,9 +1728,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
1697 | else if (pos.Z > terrainHeight) | 1728 | else if (pos.Z > terrainHeight) |
1698 | PhysicsActor.Flying = true; | 1729 | PhysicsActor.Flying = true; |
1699 | 1730 | ||
1731 | LandAtTarget = landAtTarget; | ||
1700 | MovingToTarget = true; | 1732 | MovingToTarget = true; |
1701 | MoveToPositionTarget = pos; | 1733 | MoveToPositionTarget = pos; |
1702 | 1734 | ||
1735 | // Rotate presence around the z-axis to point in same direction as movement. | ||
1736 | // Ignore z component of vector | ||
1737 | Vector3 localVectorToTarget3D = pos - AbsolutePosition; | ||
1738 | Vector3 localVectorToTarget2D = new Vector3((float)(localVectorToTarget3D.X), (float)(localVectorToTarget3D.Y), 0f); | ||
1739 | |||
1740 | // m_log.DebugFormat("[SCENE PRESENCE]: Local vector to target is {0}", localVectorToTarget2D); | ||
1741 | |||
1742 | // Calculate the yaw. | ||
1743 | Vector3 angle = new Vector3(0, 0, (float)(Math.Atan2(localVectorToTarget2D.Y, localVectorToTarget2D.X))); | ||
1744 | |||
1745 | // m_log.DebugFormat("[SCENE PRESENCE]: Angle is {0}", angle); | ||
1746 | |||
1747 | Rotation = Quaternion.CreateFromEulers(angle); | ||
1748 | // m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, Rotation); | ||
1749 | |||
1703 | Vector3 agent_control_v3 = new Vector3(); | 1750 | Vector3 agent_control_v3 = new Vector3(); |
1704 | HandleMoveToTargetUpdate(ref agent_control_v3); | 1751 | HandleMoveToTargetUpdate(ref agent_control_v3); |
1705 | AddNewMovement(agent_control_v3); | 1752 | AddNewMovement(agent_control_v3); |
@@ -2389,7 +2436,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2389 | Vector3 pos = m_pos; | 2436 | Vector3 pos = m_pos; |
2390 | pos.Z += m_appearance.HipOffset; | 2437 | pos.Z += m_appearance.HipOffset; |
2391 | 2438 | ||
2392 | //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); | 2439 | //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); |
2393 | 2440 | ||
2394 | remoteClient.SendPrimUpdate( | 2441 | remoteClient.SendPrimUpdate( |
2395 | this, | 2442 | this, |
@@ -2476,6 +2523,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2476 | /// </summary> | 2523 | /// </summary> |
2477 | private void SendInitialData() | 2524 | private void SendInitialData() |
2478 | { | 2525 | { |
2526 | //m_log.DebugFormat("[SCENE PRESENCE] SendInitialData: {0} ({1})", Name, UUID); | ||
2479 | // Moved this into CompleteMovement to ensure that m_appearance is initialized before | 2527 | // Moved this into CompleteMovement to ensure that m_appearance is initialized before |
2480 | // the inventory arrives | 2528 | // the inventory arrives |
2481 | // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); | 2529 | // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); |
@@ -2520,10 +2568,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
2520 | /// </summary> | 2568 | /// </summary> |
2521 | public void SendAvatarDataToAllAgents() | 2569 | public void SendAvatarDataToAllAgents() |
2522 | { | 2570 | { |
2571 | //m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAllAgents: {0} ({1})", Name, UUID); | ||
2523 | // only send update from root agents to other clients; children are only "listening posts" | 2572 | // only send update from root agents to other clients; children are only "listening posts" |
2524 | if (IsChildAgent) | 2573 | if (IsChildAgent) |
2525 | { | 2574 | { |
2526 | m_log.Warn("[SCENEPRESENCE] attempt to send avatar data from a child agent"); | 2575 | m_log.Warn("[SCENE PRESENCE] attempt to send avatar data from a child agent"); |
2527 | return; | 2576 | return; |
2528 | } | 2577 | } |
2529 | 2578 | ||
@@ -2573,7 +2622,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2573 | /// <param name="avatar"></param> | 2622 | /// <param name="avatar"></param> |
2574 | public void SendAvatarDataToAgent(ScenePresence avatar) | 2623 | public void SendAvatarDataToAgent(ScenePresence avatar) |
2575 | { | 2624 | { |
2576 | // m_log.WarnFormat("[SP] Send avatar data from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); | 2625 | //m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAgent from {0} ({1}) to {2} ({3})", Name, UUID, avatar.Name, avatar.UUID); |
2577 | 2626 | ||
2578 | avatar.ControllingClient.SendAvatarDataImmediate(this); | 2627 | avatar.ControllingClient.SendAvatarDataImmediate(this); |
2579 | if (Animator != null) | 2628 | if (Animator != null) |
@@ -2586,10 +2635,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
2586 | /// </summary> | 2635 | /// </summary> |
2587 | public void SendAppearanceToAllOtherAgents() | 2636 | public void SendAppearanceToAllOtherAgents() |
2588 | { | 2637 | { |
2638 | m_log.DebugFormat("[SCENE PRESENCE] SendAppearanceToAllOtherAgents: {0} ({1})", Name, UUID); | ||
2589 | // only send update from root agents to other clients; children are only "listening posts" | 2639 | // only send update from root agents to other clients; children are only "listening posts" |
2590 | if (IsChildAgent) | 2640 | if (IsChildAgent) |
2591 | { | 2641 | { |
2592 | m_log.Warn("[SCENEPRESENCE] attempt to send avatar data from a child agent"); | 2642 | m_log.Warn("[SCENE PRESENCE] attempt to send avatar data from a child agent"); |
2593 | return; | 2643 | return; |
2594 | } | 2644 | } |
2595 | 2645 | ||
@@ -2615,6 +2665,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2615 | /// </summary> | 2665 | /// </summary> |
2616 | public void SendOtherAgentsAppearanceToMe() | 2666 | public void SendOtherAgentsAppearanceToMe() |
2617 | { | 2667 | { |
2668 | //m_log.DebugFormat("[SCENE PRESENCE] SendOtherAgentsAppearanceToMe: {0} ({1})", Name, UUID); | ||
2618 | m_perfMonMS = Util.EnvironmentTickCount(); | 2669 | m_perfMonMS = Util.EnvironmentTickCount(); |
2619 | 2670 | ||
2620 | int count = 0; | 2671 | int count = 0; |
@@ -2873,8 +2924,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2873 | /// </returns> | 2924 | /// </returns> |
2874 | protected int HaveNeighbor(Cardinals car, ref int[] fix) | 2925 | protected int HaveNeighbor(Cardinals car, ref int[] fix) |
2875 | { | 2926 | { |
2876 | uint neighbourx = m_regionInfo.RegionLocX; | 2927 | uint neighbourx = m_scene.RegionInfo.RegionLocX; |
2877 | uint neighboury = m_regionInfo.RegionLocY; | 2928 | uint neighboury = m_scene.RegionInfo.RegionLocY; |
2878 | 2929 | ||
2879 | int dir = (int)car; | 2930 | int dir = (int)car; |
2880 | 2931 | ||
@@ -2894,8 +2945,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2894 | 2945 | ||
2895 | if (neighbourRegion == null) | 2946 | if (neighbourRegion == null) |
2896 | { | 2947 | { |
2897 | fix[0] = (int)(m_regionInfo.RegionLocX - neighbourx); | 2948 | fix[0] = (int)(m_scene.RegionInfo.RegionLocX - neighbourx); |
2898 | fix[1] = (int)(m_regionInfo.RegionLocY - neighboury); | 2949 | fix[1] = (int)(m_scene.RegionInfo.RegionLocY - neighboury); |
2899 | return dir * (-1); | 2950 | return dir * (-1); |
2900 | } | 2951 | } |
2901 | else | 2952 | else |
@@ -3141,26 +3192,30 @@ namespace OpenSim.Region.Framework.Scenes | |||
3141 | catch { } | 3192 | catch { } |
3142 | 3193 | ||
3143 | // Attachment objects | 3194 | // Attachment objects |
3144 | if (m_attachments != null && m_attachments.Count > 0) | 3195 | lock (m_attachments) |
3145 | { | 3196 | { |
3146 | cAgent.AttachmentObjects = new List<ISceneObject>(); | 3197 | if (m_attachments.Count > 0) |
3147 | cAgent.AttachmentObjectStates = new List<string>(); | ||
3148 | // IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>(); | ||
3149 | m_InTransitScriptStates.Clear(); | ||
3150 | foreach (SceneObjectGroup sog in m_attachments) | ||
3151 | { | 3198 | { |
3152 | // We need to make a copy and pass that copy | 3199 | cAgent.AttachmentObjects = new List<ISceneObject>(); |
3153 | // because of transfers withn the same sim | 3200 | cAgent.AttachmentObjectStates = new List<string>(); |
3154 | ISceneObject clone = sog.CloneForNewScene(); | 3201 | // IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>(); |
3155 | // Attachment module assumes that GroupPosition holds the offsets...! | 3202 | m_InTransitScriptStates.Clear(); |
3156 | ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; | 3203 | |
3157 | ((SceneObjectGroup)clone).IsAttachment = false; | 3204 | foreach (SceneObjectGroup sog in m_attachments) |
3158 | cAgent.AttachmentObjects.Add(clone); | 3205 | { |
3159 | string state = sog.GetStateSnapshot(); | 3206 | // We need to make a copy and pass that copy |
3160 | cAgent.AttachmentObjectStates.Add(state); | 3207 | // because of transfers withn the same sim |
3161 | m_InTransitScriptStates.Add(state); | 3208 | ISceneObject clone = sog.CloneForNewScene(); |
3162 | // Let's remove the scripts of the original object here | 3209 | // Attachment module assumes that GroupPosition holds the offsets...! |
3163 | sog.RemoveScriptInstances(true); | 3210 | ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; |
3211 | ((SceneObjectGroup)clone).IsAttachment = false; | ||
3212 | cAgent.AttachmentObjects.Add(clone); | ||
3213 | string state = sog.GetStateSnapshot(); | ||
3214 | cAgent.AttachmentObjectStates.Add(state); | ||
3215 | m_InTransitScriptStates.Add(state); | ||
3216 | // Let's remove the scripts of the original object here | ||
3217 | sog.RemoveScriptInstances(true); | ||
3218 | } | ||
3164 | } | 3219 | } |
3165 | } | 3220 | } |
3166 | } | 3221 | } |
@@ -3277,6 +3332,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
3277 | /// </summary> | 3332 | /// </summary> |
3278 | public void AddToPhysicalScene(bool isFlying) | 3333 | public void AddToPhysicalScene(bool isFlying) |
3279 | { | 3334 | { |
3335 | // m_log.DebugFormat( | ||
3336 | // "[SCENE PRESENCE]: Adding physics actor for {0}, ifFlying = {1} in {2}", | ||
3337 | // Name, isFlying, Scene.RegionInfo.RegionName); | ||
3338 | |||
3280 | if (m_appearance.AvatarHeight == 0) | 3339 | if (m_appearance.AvatarHeight == 0) |
3281 | m_appearance.SetHeight(); | 3340 | m_appearance.SetHeight(); |
3282 | 3341 | ||
@@ -3317,7 +3376,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3317 | //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) | 3376 | //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) |
3318 | // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents( | 3377 | // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents( |
3319 | // as of this comment the interval is set in AddToPhysicalScene | 3378 | // as of this comment the interval is set in AddToPhysicalScene |
3320 | if (Animator!=null) | 3379 | if (Animator != null) |
3321 | Animator.UpdateMovementAnimations(); | 3380 | Animator.UpdateMovementAnimations(); |
3322 | 3381 | ||
3323 | CollisionEventUpdate collisionData = (CollisionEventUpdate)e; | 3382 | CollisionEventUpdate collisionData = (CollisionEventUpdate)e; |
@@ -3398,7 +3457,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3398 | 3457 | ||
3399 | public void Close() | 3458 | public void Close() |
3400 | { | 3459 | { |
3401 | m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false); | 3460 | if (!IsChildAgent) |
3461 | m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false); | ||
3402 | 3462 | ||
3403 | lock (m_knownChildRegions) | 3463 | lock (m_knownChildRegions) |
3404 | { | 3464 | { |
@@ -3501,8 +3561,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
3501 | /// <summary> | 3561 | /// <summary> |
3502 | /// This is currently just being done for information. | 3562 | /// This is currently just being done for information. |
3503 | /// </summary> | 3563 | /// </summary> |
3504 | public void ValidateAttachments() | 3564 | public bool ValidateAttachments() |
3505 | { | 3565 | { |
3566 | bool validated = true; | ||
3567 | |||
3506 | lock (m_attachments) | 3568 | lock (m_attachments) |
3507 | { | 3569 | { |
3508 | // Validate | 3570 | // Validate |
@@ -3512,15 +3574,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
3512 | { | 3574 | { |
3513 | m_log.WarnFormat( | 3575 | m_log.WarnFormat( |
3514 | "[SCENE PRESENCE]: Failed to validate an attachment for {0} since it was null. Continuing", Name); | 3576 | "[SCENE PRESENCE]: Failed to validate an attachment for {0} since it was null. Continuing", Name); |
3577 | |||
3578 | validated = false; | ||
3515 | } | 3579 | } |
3516 | else if (gobj.IsDeleted) | 3580 | else if (gobj.IsDeleted) |
3517 | { | 3581 | { |
3518 | m_log.WarnFormat( | 3582 | m_log.WarnFormat( |
3519 | "[SCENE PRESENCE]: Failed to validate attachment {0} {1} for {2} since it had been deleted. Continuing", | 3583 | "[SCENE PRESENCE]: Failed to validate attachment {0} {1} for {2} since it had been deleted. Continuing", |
3520 | gobj.Name, gobj.UUID, Name); | 3584 | gobj.Name, gobj.UUID, Name); |
3585 | |||
3586 | validated = false; | ||
3521 | } | 3587 | } |
3522 | } | 3588 | } |
3523 | } | 3589 | } |
3590 | |||
3591 | return validated; | ||
3524 | } | 3592 | } |
3525 | 3593 | ||
3526 | /// <summary> | 3594 | /// <summary> |
@@ -3552,29 +3620,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
3552 | } | 3620 | } |
3553 | } | 3621 | } |
3554 | 3622 | ||
3555 | |||
3556 | public void initializeScenePresence(IClientAPI client, RegionInfo region, Scene scene) | ||
3557 | { | ||
3558 | m_controllingClient = client; | ||
3559 | m_regionInfo = region; | ||
3560 | m_scene = scene; | ||
3561 | |||
3562 | RegisterToEvents(); | ||
3563 | |||
3564 | /* | ||
3565 | AbsolutePosition = client.StartPos; | ||
3566 | |||
3567 | Animations = new AvatarAnimations(); | ||
3568 | Animations.LoadAnims(); | ||
3569 | |||
3570 | m_animations = new List<UUID>(); | ||
3571 | m_animations.Add(Animations.AnimsUUID["STAND"]); | ||
3572 | m_animationSeqs.Add(m_controllingClient.NextAnimationSequenceNumber); | ||
3573 | |||
3574 | SetDirectionVectors(); | ||
3575 | */ | ||
3576 | } | ||
3577 | |||
3578 | internal void PushForce(Vector3 impulse) | 3623 | internal void PushForce(Vector3 impulse) |
3579 | { | 3624 | { |
3580 | if (PhysicsActor != null) | 3625 | if (PhysicsActor != null) |
@@ -3602,6 +3647,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3602 | obj.ignoreControls = (ScriptControlled)controls; | 3647 | obj.ignoreControls = (ScriptControlled)controls; |
3603 | obj.eventControls = (ScriptControlled)controls; | 3648 | obj.eventControls = (ScriptControlled)controls; |
3604 | } | 3649 | } |
3650 | |||
3605 | if (pass_on == 1 && accept == 1) | 3651 | if (pass_on == 1 && accept == 1) |
3606 | { | 3652 | { |
3607 | IgnoredControls = ScriptControlled.CONTROL_ZERO; | 3653 | IgnoredControls = ScriptControlled.CONTROL_ZERO; |
@@ -3622,6 +3668,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3622 | scriptedcontrols[Script_item_UUID] = obj; | 3668 | scriptedcontrols[Script_item_UUID] = obj; |
3623 | } | 3669 | } |
3624 | } | 3670 | } |
3671 | |||
3625 | ControllingClient.SendTakeControls(controls, pass_on == 1 ? true : false, true); | 3672 | ControllingClient.SendTakeControls(controls, pass_on == 1 ? true : false, true); |
3626 | } | 3673 | } |
3627 | 3674 | ||
@@ -3803,4 +3850,4 @@ namespace OpenSim.Region.Framework.Scenes | |||
3803 | } | 3850 | } |
3804 | } | 3851 | } |
3805 | } | 3852 | } |
3806 | } \ No newline at end of file | 3853 | } |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs index 1ea2329..80f198d 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs | |||
@@ -52,22 +52,25 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
52 | TestHelpers.InMethod(); | 52 | TestHelpers.InMethod(); |
53 | 53 | ||
54 | Scene scene = SceneHelpers.SetupScene(); | 54 | Scene scene = SceneHelpers.SetupScene(); |
55 | int partsToTestCount = 3; | ||
55 | 56 | ||
56 | string objName = "obj1"; | 57 | SceneObjectGroup so |
57 | UUID objUuid = new UUID("00000000-0000-0000-0000-000000000001"); | 58 | = SceneHelpers.CreateSceneObject(partsToTestCount, TestHelpers.ParseTail(0x1), "obj1", 0x10); |
58 | 59 | SceneObjectPart[] parts = so.Parts; | |
59 | SceneObjectPart part | ||
60 | = new SceneObjectPart(UUID.Zero, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero) | ||
61 | { Name = objName, UUID = objUuid }; | ||
62 | 60 | ||
63 | Assert.That(scene.AddNewSceneObject(new SceneObjectGroup(part), false), Is.True); | 61 | Assert.That(scene.AddNewSceneObject(so, false), Is.True); |
64 | 62 | SceneObjectGroup retrievedSo = scene.GetSceneObjectGroup(so.UUID); | |
65 | SceneObjectPart retrievedPart = scene.GetSceneObjectPart(objUuid); | 63 | SceneObjectPart[] retrievedParts = retrievedSo.Parts; |
66 | 64 | ||
67 | //m_log.Debug("retrievedPart : {0}", retrievedPart); | 65 | //m_log.Debug("retrievedPart : {0}", retrievedPart); |
68 | // If the parts have the same UUID then we will consider them as one and the same | 66 | // If the parts have the same UUID then we will consider them as one and the same |
69 | Assert.That(retrievedPart.Name, Is.EqualTo(objName)); | 67 | Assert.That(retrievedSo.PrimCount, Is.EqualTo(partsToTestCount)); |
70 | Assert.That(retrievedPart.UUID, Is.EqualTo(objUuid)); | 68 | |
69 | for (int i = 0; i < partsToTestCount; i++) | ||
70 | { | ||
71 | Assert.That(retrievedParts[i].Name, Is.EqualTo(parts[i].Name)); | ||
72 | Assert.That(retrievedParts[i].UUID, Is.EqualTo(parts[i].UUID)); | ||
73 | } | ||
71 | } | 74 | } |
72 | 75 | ||
73 | [Test] | 76 | [Test] |
@@ -103,6 +106,39 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
103 | Assert.That(retrievedPart.Name, Is.EqualTo(obj1Name)); | 106 | Assert.That(retrievedPart.Name, Is.EqualTo(obj1Name)); |
104 | Assert.That(retrievedPart.UUID, Is.EqualTo(objUuid)); | 107 | Assert.That(retrievedPart.UUID, Is.EqualTo(objUuid)); |
105 | } | 108 | } |
109 | |||
110 | /// <summary> | ||
111 | /// Test retrieving a scene object via the local id of one of its parts. | ||
112 | /// </summary> | ||
113 | [Test] | ||
114 | public void TestGetSceneObjectByPartLocalId() | ||
115 | { | ||
116 | TestHelpers.InMethod(); | ||
117 | |||
118 | Scene scene = SceneHelpers.SetupScene(); | ||
119 | int partsToTestCount = 3; | ||
120 | |||
121 | SceneObjectGroup so | ||
122 | = SceneHelpers.CreateSceneObject(partsToTestCount, TestHelpers.ParseTail(0x1), "obj1", 0x10); | ||
123 | SceneObjectPart[] parts = so.Parts; | ||
124 | |||
125 | scene.AddNewSceneObject(so, false); | ||
126 | |||
127 | // Test getting via the root part's local id | ||
128 | Assert.That(scene.GetGroupByPrim(so.LocalId), Is.Not.Null); | ||
129 | |||
130 | // Test getting via a non root part's local id | ||
131 | Assert.That(scene.GetGroupByPrim(parts[partsToTestCount - 1].LocalId), Is.Not.Null); | ||
132 | |||
133 | // Test that we don't get back an object for a local id that doesn't exist | ||
134 | Assert.That(scene.GetGroupByPrim(999), Is.Null); | ||
135 | |||
136 | // Now delete the scene object and check again | ||
137 | scene.DeleteSceneObject(so, false); | ||
138 | |||
139 | Assert.That(scene.GetGroupByPrim(so.LocalId), Is.Null); | ||
140 | Assert.That(scene.GetGroupByPrim(parts[partsToTestCount - 1].LocalId), Is.Null); | ||
141 | } | ||
106 | 142 | ||
107 | /// <summary> | 143 | /// <summary> |
108 | /// Test deleting an object from a scene. | 144 | /// Test deleting an object from a scene. |
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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | using log4net; | ||
32 | using Nini.Config; | ||
33 | using NUnit.Framework; | ||
34 | using OpenMetaverse; | ||
35 | using OpenSim.Framework; | ||
36 | using OpenSim.Framework.Communications; | ||
37 | using OpenSim.Region.Framework.Interfaces; | ||
38 | using OpenSim.Region.Framework.Scenes; | ||
39 | using OpenSim.Tests.Common; | ||
40 | using OpenSim.Tests.Common.Mock; | ||
41 | |||
42 | namespace 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/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs index 77b1535..3acdaf8 100644 --- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs +++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs | |||
@@ -43,11 +43,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
43 | /// <summary> | 43 | /// <summary> |
44 | /// Gather uuids for a given entity. | 44 | /// Gather uuids for a given entity. |
45 | /// </summary> | 45 | /// </summary> |
46 | /// | 46 | /// <remarks> |
47 | /// This does a deep inspection of the entity to retrieve all the assets it uses (whether as textures, as scripts | 47 | /// This does a deep inspection of the entity to retrieve all the assets it uses (whether as textures, as scripts |
48 | /// contained in inventory, as scripts contained in objects contained in another object's inventory, etc. Assets | 48 | /// contained in inventory, as scripts contained in objects contained in another object's inventory, etc. Assets |
49 | /// are only retrieved when they are necessary to carry out the inspection (i.e. a serialized object needs to be | 49 | /// are only retrieved when they are necessary to carry out the inspection (i.e. a serialized object needs to be |
50 | /// retrieved to work out which assets it references). | 50 | /// retrieved to work out which assets it references). |
51 | /// </remarks> | ||
51 | public class UuidGatherer | 52 | public class UuidGatherer |
52 | { | 53 | { |
53 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 54 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
@@ -76,11 +77,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
76 | /// <summary> | 77 | /// <summary> |
77 | /// Gather all the asset uuids associated with the asset referenced by a given uuid | 78 | /// Gather all the asset uuids associated with the asset referenced by a given uuid |
78 | /// </summary> | 79 | /// </summary> |
79 | /// | 80 | /// <remarks> |
80 | /// This includes both those directly associated with | 81 | /// This includes both those directly associated with |
81 | /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained | 82 | /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained |
82 | /// within this object). | 83 | /// within this object). |
83 | /// | 84 | /// </remarks> |
84 | /// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param> | 85 | /// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param> |
85 | /// <param name="assetType">The type of the asset for the uuid given</param> | 86 | /// <param name="assetType">The type of the asset for the uuid given</param> |
86 | /// <param name="assetUuids">The assets gathered</param> | 87 | /// <param name="assetUuids">The assets gathered</param> |
@@ -123,11 +124,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
123 | /// <summary> | 124 | /// <summary> |
124 | /// Gather all the asset uuids associated with a given object. | 125 | /// Gather all the asset uuids associated with a given object. |
125 | /// </summary> | 126 | /// </summary> |
126 | /// | 127 | /// <remarks> |
127 | /// This includes both those directly associated with | 128 | /// This includes both those directly associated with |
128 | /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained | 129 | /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained |
129 | /// within this object). | 130 | /// within this object). |
130 | /// | 131 | /// </remarks> |
131 | /// <param name="sceneObject">The scene object for which to gather assets</param> | 132 | /// <param name="sceneObject">The scene object for which to gather assets</param> |
132 | /// <param name="assetUuids">The assets gathered</param> | 133 | /// <param name="assetUuids">The assets gathered</param> |
133 | public void GatherAssetUuids(SceneObjectGroup sceneObject, IDictionary<UUID, AssetType> assetUuids) | 134 | public void GatherAssetUuids(SceneObjectGroup sceneObject, IDictionary<UUID, AssetType> assetUuids) |
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index c413634..f6656c2 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 31e79fa..edb618e 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..1a0d0c7 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs | |||
@@ -182,18 +182,21 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
182 | scene.Update(); | 182 | scene.Update(); |
183 | Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); | 183 | Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); |
184 | 184 | ||
185 | Vector3 targetPos = startPos + new Vector3(0, 0, 10); | 185 | Vector3 targetPos = startPos + new Vector3(0, 10, 0); |
186 | npcModule.MoveToTarget(npc.UUID, scene, targetPos, false, false); | 186 | npcModule.MoveToTarget(npc.UUID, scene, targetPos, false, false); |
187 | 187 | ||
188 | Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); | 188 | Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); |
189 | //Assert.That(npc.Rotation, Is.EqualTo(new Quaternion(0, 0, 0.7071068f, 0.7071068f))); | ||
190 | Assert.That( | ||
191 | npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001)); | ||
189 | 192 | ||
190 | scene.Update(); | 193 | scene.Update(); |
191 | 194 | ||
192 | // We should really check the exact figure. | 195 | // We should really check the exact figure. |
193 | Assert.That(npc.AbsolutePosition.X, Is.EqualTo(startPos.X)); | 196 | Assert.That(npc.AbsolutePosition.X, Is.EqualTo(startPos.X)); |
194 | Assert.That(npc.AbsolutePosition.Y, Is.EqualTo(startPos.Y)); | 197 | Assert.That(npc.AbsolutePosition.Y, Is.GreaterThan(startPos.Y)); |
195 | Assert.That(npc.AbsolutePosition.Z, Is.GreaterThan(startPos.Z)); | 198 | Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); |
196 | Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.Z)); | 199 | Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.X)); |
197 | 200 | ||
198 | for (int i = 0; i < 10; i++) | 201 | for (int i = 0; i < 10; i++) |
199 | scene.Update(); | 202 | scene.Update(); |
@@ -208,6 +211,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
208 | targetPos = startPos + new Vector3(10, 0, 0); | 211 | targetPos = startPos + new Vector3(10, 0, 0); |
209 | npcModule.MoveToTarget(npc.UUID, scene, targetPos, false, false); | 212 | npcModule.MoveToTarget(npc.UUID, scene, targetPos, false, false); |
210 | 213 | ||
214 | Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); | ||
215 | // Assert.That(npc.Rotation, Is.EqualTo(new Quaternion(0, 0, 0, 1))); | ||
216 | Assert.That( | ||
217 | npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001)); | ||
218 | |||
211 | scene.Update(); | 219 | scene.Update(); |
212 | 220 | ||
213 | // We should really check the exact figure. | 221 | // 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 | |||
28 | using System.Reflection; | ||
29 | using 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 ac4e2b9..0000000 --- a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs +++ /dev/null | |||
@@ -1,1191 +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 | using System; | ||
29 | using System.Reflection; | ||
30 | using BulletDotNET; | ||
31 | using OpenMetaverse; | ||
32 | using OpenSim.Framework; | ||
33 | using OpenSim.Region.Physics.Manager; | ||
34 | using log4net; | ||
35 | |||
36 | namespace 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 | |||
629 | public override Quaternion APIDTarget | ||
630 | { | ||
631 | set { return; } | ||
632 | } | ||
633 | |||
634 | public override bool APIDActive | ||
635 | { | ||
636 | set { return; } | ||
637 | } | ||
638 | |||
639 | public override float APIDStrength | ||
640 | { | ||
641 | set { return; } | ||
642 | } | ||
643 | |||
644 | public override float APIDDamping | ||
645 | { | ||
646 | set { return; } | ||
647 | } | ||
648 | |||
649 | /// <summary> | ||
650 | /// Adds the force supplied to the Target Velocity | ||
651 | /// The PID controller takes this target velocity and tries to make it a reality | ||
652 | /// </summary> | ||
653 | /// <param name="force"></param> | ||
654 | /// <param name="pushforce">Is this a push by a script?</param> | ||
655 | public override void AddForce(Vector3 force, bool pushforce) | ||
656 | { | ||
657 | if (pushforce) | ||
658 | { | ||
659 | m_pidControllerActive = false; | ||
660 | force *= 100f; | ||
661 | doForce(force, false); | ||
662 | //System.Console.WriteLine("Push!"); | ||
663 | //_target_velocity.X += force.X; | ||
664 | // _target_velocity.Y += force.Y; | ||
665 | //_target_velocity.Z += force.Z; | ||
666 | } | ||
667 | else | ||
668 | { | ||
669 | m_pidControllerActive = true; | ||
670 | m_target_velocity.X += force.X; | ||
671 | m_target_velocity.Y += force.Y; | ||
672 | m_target_velocity.Z += force.Z; | ||
673 | } | ||
674 | //m_lastUpdateSent = false; | ||
675 | } | ||
676 | |||
677 | public void doForce(Vector3 force, bool now) | ||
678 | { | ||
679 | |||
680 | tempVector3.setValue(force.X, force.Y, force.Z); | ||
681 | if (now) | ||
682 | { | ||
683 | Body.applyCentralForce(tempVector3); | ||
684 | } | ||
685 | else | ||
686 | { | ||
687 | m_taintedForce += force; | ||
688 | m_parent_scene.AddPhysicsActorTaint(this); | ||
689 | } | ||
690 | } | ||
691 | |||
692 | public void doImpulse(Vector3 force, bool now) | ||
693 | { | ||
694 | |||
695 | tempVector3.setValue(force.X, force.Y, force.Z); | ||
696 | if (now) | ||
697 | { | ||
698 | Body.applyCentralImpulse(tempVector3); | ||
699 | } | ||
700 | else | ||
701 | { | ||
702 | m_taintedForce += force; | ||
703 | m_parent_scene.AddPhysicsActorTaint(this); | ||
704 | } | ||
705 | } | ||
706 | |||
707 | public override void AddAngularForce(Vector3 force, bool pushforce) | ||
708 | { | ||
709 | |||
710 | } | ||
711 | |||
712 | public override void SetMomentum(Vector3 momentum) | ||
713 | { | ||
714 | |||
715 | } | ||
716 | |||
717 | public override void SubscribeEvents(int ms) | ||
718 | { | ||
719 | m_eventsubscription = ms; | ||
720 | m_requestedUpdateFrequency = ms; | ||
721 | m_parent_scene.addCollisionEventReporting(this); | ||
722 | } | ||
723 | |||
724 | public override void UnSubscribeEvents() | ||
725 | { | ||
726 | m_parent_scene.remCollisionEventReporting(this); | ||
727 | m_eventsubscription = 0; | ||
728 | m_requestedUpdateFrequency = 0; | ||
729 | } | ||
730 | |||
731 | public override bool SubscribedEvents() | ||
732 | { | ||
733 | if (m_eventsubscription > 0) | ||
734 | return true; | ||
735 | return false; | ||
736 | } | ||
737 | |||
738 | public void AddCollision(uint collideWith, ContactPoint contact) | ||
739 | { | ||
740 | if (CollisionEventsThisFrame == null) | ||
741 | { | ||
742 | CollisionEventsThisFrame = new CollisionEventUpdate(); | ||
743 | } | ||
744 | CollisionEventsThisFrame.addCollider(collideWith, contact); | ||
745 | } | ||
746 | |||
747 | public void SendCollisions() | ||
748 | { | ||
749 | if (m_eventsubscription >= m_requestedUpdateFrequency) | ||
750 | { | ||
751 | if (CollisionEventsThisFrame != null) | ||
752 | { | ||
753 | base.SendCollisionUpdate(CollisionEventsThisFrame); | ||
754 | } | ||
755 | CollisionEventsThisFrame = new CollisionEventUpdate(); | ||
756 | m_eventsubscription = 0; | ||
757 | } | ||
758 | return; | ||
759 | } | ||
760 | |||
761 | internal void Dispose() | ||
762 | { | ||
763 | if (Body.isInWorld()) | ||
764 | m_parent_scene.removeFromWorld(Body); | ||
765 | |||
766 | if (m_aMotor.Handle != IntPtr.Zero) | ||
767 | m_parent_scene.getBulletWorld().removeConstraint(m_aMotor); | ||
768 | |||
769 | m_aMotor.Dispose(); m_aMotor = null; | ||
770 | ClosestCastResult.Dispose(); ClosestCastResult = null; | ||
771 | Body.Dispose(); Body = null; | ||
772 | Shell.Dispose(); Shell = null; | ||
773 | tempQuat1.Dispose(); | ||
774 | tempTrans1.Dispose(); | ||
775 | tempVector1.Dispose(); | ||
776 | tempVector2.Dispose(); | ||
777 | tempVector3.Dispose(); | ||
778 | tempVector4.Dispose(); | ||
779 | tempVector5RayCast.Dispose(); | ||
780 | tempVector6RayCast.Dispose(); | ||
781 | |||
782 | } | ||
783 | |||
784 | public void ProcessTaints(float timestep) | ||
785 | { | ||
786 | |||
787 | if (m_tainted_isPhysical != m_isPhysical) | ||
788 | { | ||
789 | if (m_tainted_isPhysical) | ||
790 | { | ||
791 | // Create avatar capsule and related ODE data | ||
792 | if (!(Shell == null && Body == null)) | ||
793 | { | ||
794 | m_log.Warn("[PHYSICS]: re-creating the following avatar ODE data, even though it already exists - " | ||
795 | + (Shell != null ? "Shell " : "") | ||
796 | + (Body != null ? "Body " : "")); | ||
797 | } | ||
798 | AvatarGeomAndBodyCreation(m_position.X, m_position.Y, m_position.Z); | ||
799 | |||
800 | |||
801 | } | ||
802 | else | ||
803 | { | ||
804 | // destroy avatar capsule and related ODE data | ||
805 | |||
806 | Dispose(); | ||
807 | tempVector1 = new btVector3(0, 0, 0); | ||
808 | tempVector2 = new btVector3(0, 0, 0); | ||
809 | tempVector3 = new btVector3(0, 0, 0); | ||
810 | tempVector4 = new btVector3(0, 0, 0); | ||
811 | |||
812 | tempVector5RayCast = new btVector3(0, 0, 0); | ||
813 | tempVector6RayCast = new btVector3(0, 0, 0); | ||
814 | tempVector7RayCast = new btVector3(0, 0, 0); | ||
815 | |||
816 | tempQuat1 = new btQuaternion(0, 0, 0, 1); | ||
817 | tempTrans1 = new btTransform(tempQuat1, tempVector1); | ||
818 | // m_movementComparision = new PhysicsVector(0, 0, 0); | ||
819 | m_CapsuleOrientationAxis = new btVector3(1, 0, 1); | ||
820 | } | ||
821 | |||
822 | m_isPhysical = m_tainted_isPhysical; | ||
823 | } | ||
824 | |||
825 | if (m_tainted_CAPSULE_LENGTH != CAPSULE_LENGTH) | ||
826 | { | ||
827 | if (Body != null) | ||
828 | { | ||
829 | |||
830 | m_pidControllerActive = true; | ||
831 | // no lock needed on _parent_scene.OdeLock because we are called from within the thread lock in OdePlugin's simulate() | ||
832 | //d.JointDestroy(Amotor); | ||
833 | float prevCapsule = CAPSULE_LENGTH; | ||
834 | CAPSULE_LENGTH = m_tainted_CAPSULE_LENGTH; | ||
835 | //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); | ||
836 | Dispose(); | ||
837 | |||
838 | tempVector1 = new btVector3(0, 0, 0); | ||
839 | tempVector2 = new btVector3(0, 0, 0); | ||
840 | tempVector3 = new btVector3(0, 0, 0); | ||
841 | tempVector4 = new btVector3(0, 0, 0); | ||
842 | |||
843 | tempVector5RayCast = new btVector3(0, 0, 0); | ||
844 | tempVector6RayCast = new btVector3(0, 0, 0); | ||
845 | tempVector7RayCast = new btVector3(0, 0, 0); | ||
846 | |||
847 | tempQuat1 = new btQuaternion(0, 0, 0, 1); | ||
848 | tempTrans1 = new btTransform(tempQuat1, tempVector1); | ||
849 | // m_movementComparision = new PhysicsVector(0, 0, 0); | ||
850 | m_CapsuleOrientationAxis = new btVector3(1, 0, 1); | ||
851 | |||
852 | AvatarGeomAndBodyCreation(m_position.X, m_position.Y, | ||
853 | m_position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2)); | ||
854 | Velocity = Vector3.Zero; | ||
855 | |||
856 | } | ||
857 | else | ||
858 | { | ||
859 | m_log.Warn("[PHYSICS]: trying to change capsule size, but the following ODE data is missing - " | ||
860 | + (Shell == null ? "Shell " : "") | ||
861 | + (Body == null ? "Body " : "")); | ||
862 | } | ||
863 | } | ||
864 | if (m_taintRemove) | ||
865 | { | ||
866 | Dispose(); | ||
867 | } | ||
868 | } | ||
869 | |||
870 | /// <summary> | ||
871 | /// Called from Simulate | ||
872 | /// This is the avatar's movement control + PID Controller | ||
873 | /// </summary> | ||
874 | /// <param name="timeStep"></param> | ||
875 | public void Move(float timeStep) | ||
876 | { | ||
877 | // no lock; for now it's only called from within Simulate() | ||
878 | |||
879 | // If the PID Controller isn't active then we set our force | ||
880 | // calculating base velocity to the current position | ||
881 | if (Body == null) | ||
882 | return; | ||
883 | tempTrans1.Dispose(); | ||
884 | tempTrans1 = Body.getInterpolationWorldTransform(); | ||
885 | tempVector1.Dispose(); | ||
886 | tempVector1 = tempTrans1.getOrigin(); | ||
887 | tempVector2.Dispose(); | ||
888 | tempVector2 = Body.getInterpolationLinearVelocity(); | ||
889 | |||
890 | if (m_pidControllerActive == false) | ||
891 | { | ||
892 | m_zeroPosition.X = tempVector1.getX(); | ||
893 | m_zeroPosition.Y = tempVector1.getY(); | ||
894 | m_zeroPosition.Z = tempVector1.getZ(); | ||
895 | } | ||
896 | //PidStatus = true; | ||
897 | |||
898 | Vector3 vec = Vector3.Zero; | ||
899 | |||
900 | Vector3 vel = new Vector3(tempVector2.getX(), tempVector2.getY(), tempVector2.getZ()); | ||
901 | |||
902 | float movementdivisor = 1f; | ||
903 | |||
904 | if (!m_alwaysRun) | ||
905 | { | ||
906 | movementdivisor = walkDivisor; | ||
907 | } | ||
908 | else | ||
909 | { | ||
910 | movementdivisor = runDivisor; | ||
911 | } | ||
912 | |||
913 | // if velocity is zero, use position control; otherwise, velocity control | ||
914 | if (m_target_velocity.X == 0.0f && m_target_velocity.Y == 0.0f && m_target_velocity.Z == 0.0f && m_iscolliding) | ||
915 | { | ||
916 | // keep track of where we stopped. No more slippin' & slidin' | ||
917 | if (!m_zeroFlag) | ||
918 | { | ||
919 | m_zeroFlag = true; | ||
920 | m_zeroPosition.X = tempVector1.getX(); | ||
921 | m_zeroPosition.Y = tempVector1.getY(); | ||
922 | m_zeroPosition.Z = tempVector1.getZ(); | ||
923 | } | ||
924 | if (m_pidControllerActive) | ||
925 | { | ||
926 | // We only want to deactivate the PID Controller if we think we want to have our surrogate | ||
927 | // react to the physics scene by moving it's position. | ||
928 | // Avatar to Avatar collisions | ||
929 | // Prim to avatar collisions | ||
930 | |||
931 | Vector3 pos = new Vector3(tempVector1.getX(), tempVector1.getY(), tempVector1.getZ()); | ||
932 | vec.X = (m_target_velocity.X - vel.X) * (PID_D) + (m_zeroPosition.X - pos.X) * (PID_P * 2); | ||
933 | vec.Y = (m_target_velocity.Y - vel.Y) * (PID_D) + (m_zeroPosition.Y - pos.Y) * (PID_P * 2); | ||
934 | if (m_flying) | ||
935 | { | ||
936 | vec.Z = (m_target_velocity.Z - vel.Z) * (PID_D) + (m_zeroPosition.Z - pos.Z) * PID_P; | ||
937 | } | ||
938 | } | ||
939 | //PidStatus = true; | ||
940 | } | ||
941 | else | ||
942 | { | ||
943 | m_pidControllerActive = true; | ||
944 | m_zeroFlag = false; | ||
945 | if (m_iscolliding && !m_flying) | ||
946 | { | ||
947 | // We're standing on something | ||
948 | vec.X = ((m_target_velocity.X / movementdivisor) - vel.X) * (PID_D); | ||
949 | vec.Y = ((m_target_velocity.Y / movementdivisor) - vel.Y) * (PID_D); | ||
950 | } | ||
951 | else if (m_iscolliding && m_flying) | ||
952 | { | ||
953 | // We're flying and colliding with something | ||
954 | vec.X = ((m_target_velocity.X / movementdivisor) - vel.X) * (PID_D / 16); | ||
955 | vec.Y = ((m_target_velocity.Y / movementdivisor) - vel.Y) * (PID_D / 16); | ||
956 | } | ||
957 | else if (!m_iscolliding && m_flying) | ||
958 | { | ||
959 | // we're in mid air suspended | ||
960 | vec.X = ((m_target_velocity.X / movementdivisor) - vel.X) * (PID_D / 6); | ||
961 | vec.Y = ((m_target_velocity.Y / movementdivisor) - vel.Y) * (PID_D / 6); | ||
962 | |||
963 | // We don't want linear velocity to cause our avatar to bounce, so we check target Z and actual velocity X, Y | ||
964 | // rebound preventing | ||
965 | if (m_target_velocity.Z < 0.025f && m_velocity.X < 0.25f && m_velocity.Y < 0.25f) | ||
966 | m_zeroFlag = true; | ||
967 | } | ||
968 | |||
969 | if (m_iscolliding && !m_flying && m_target_velocity.Z > 0.0f) | ||
970 | { | ||
971 | // We're colliding with something and we're not flying but we're moving | ||
972 | // This means we're walking or running. | ||
973 | Vector3 pos = new Vector3(tempVector1.getX(), tempVector1.getY(), tempVector1.getZ()); | ||
974 | vec.Z = (m_target_velocity.Z - vel.Z) * PID_D + (m_zeroPosition.Z - pos.Z) * PID_P; | ||
975 | if (m_target_velocity.X > 0) | ||
976 | { | ||
977 | vec.X = ((m_target_velocity.X - vel.X) / 1.2f) * PID_D; | ||
978 | } | ||
979 | if (m_target_velocity.Y > 0) | ||
980 | { | ||
981 | vec.Y = ((m_target_velocity.Y - vel.Y) / 1.2f) * PID_D; | ||
982 | } | ||
983 | } | ||
984 | else if (!m_iscolliding && !m_flying) | ||
985 | { | ||
986 | // we're not colliding and we're not flying so that means we're falling! | ||
987 | // m_iscolliding includes collisions with the ground. | ||
988 | |||
989 | // d.Vector3 pos = d.BodyGetPosition(Body); | ||
990 | if (m_target_velocity.X > 0) | ||
991 | { | ||
992 | vec.X = ((m_target_velocity.X - vel.X) / 1.2f) * PID_D; | ||
993 | } | ||
994 | if (m_target_velocity.Y > 0) | ||
995 | { | ||
996 | vec.Y = ((m_target_velocity.Y - vel.Y) / 1.2f) * PID_D; | ||
997 | } | ||
998 | } | ||
999 | |||
1000 | |||
1001 | if (m_flying) | ||
1002 | { | ||
1003 | vec.Z = (m_target_velocity.Z - vel.Z) * (PID_D); | ||
1004 | } | ||
1005 | } | ||
1006 | if (m_flying) | ||
1007 | { | ||
1008 | // Slight PID correction | ||
1009 | vec.Z += (((-1 * m_parent_scene.gravityz) * m_mass) * 0.06f); | ||
1010 | |||
1011 | |||
1012 | //auto fly height. Kitto Flora | ||
1013 | //d.Vector3 pos = d.BodyGetPosition(Body); | ||
1014 | float target_altitude = m_parent_scene.GetTerrainHeightAtXY(m_position.X, m_position.Y) + 5.0f; | ||
1015 | |||
1016 | if (m_position.Z < target_altitude) | ||
1017 | { | ||
1018 | vec.Z += (target_altitude - m_position.Z) * PID_P * 5.0f; | ||
1019 | } | ||
1020 | |||
1021 | } | ||
1022 | 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)))) | ||
1023 | { | ||
1024 | Body.setFriction(0.001f); | ||
1025 | //m_log.DebugFormat("[PHYSICS]: Avatar force applied: {0}, Target:{1}", vec.ToString(), m_target_velocity.ToString()); | ||
1026 | } | ||
1027 | |||
1028 | if (Body != null) | ||
1029 | { | ||
1030 | int activationstate = Body.getActivationState(); | ||
1031 | if (activationstate == 0) | ||
1032 | { | ||
1033 | Body.forceActivationState(1); | ||
1034 | } | ||
1035 | |||
1036 | |||
1037 | } | ||
1038 | doImpulse(vec, true); | ||
1039 | } | ||
1040 | |||
1041 | /// <summary> | ||
1042 | /// Updates the reported position and velocity. This essentially sends the data up to ScenePresence. | ||
1043 | /// </summary> | ||
1044 | public void UpdatePositionAndVelocity() | ||
1045 | { | ||
1046 | if (Body == null) | ||
1047 | return; | ||
1048 | //int val = Environment.TickCount; | ||
1049 | CheckIfStandingOnObject(); | ||
1050 | //m_log.DebugFormat("time:{0}", Environment.TickCount - val); | ||
1051 | |||
1052 | //IsColliding = Body.checkCollideWith(m_parent_scene.TerrainBody); | ||
1053 | |||
1054 | tempTrans1.Dispose(); | ||
1055 | tempTrans1 = Body.getInterpolationWorldTransform(); | ||
1056 | tempVector1.Dispose(); | ||
1057 | tempVector1 = tempTrans1.getOrigin(); | ||
1058 | tempVector2.Dispose(); | ||
1059 | tempVector2 = Body.getInterpolationLinearVelocity(); | ||
1060 | |||
1061 | // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! | ||
1062 | Vector3 vec = new Vector3(tempVector1.getX(), tempVector1.getY(), tempVector1.getZ()); | ||
1063 | |||
1064 | // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!) | ||
1065 | if (vec.X < -10.0f) vec.X = 0.0f; | ||
1066 | if (vec.Y < -10.0f) vec.Y = 0.0f; | ||
1067 | if (vec.X > (int)Constants.RegionSize + 10.2f) vec.X = (int)Constants.RegionSize + 10.2f; | ||
1068 | if (vec.Y > (int)Constants.RegionSize + 10.2f) vec.Y = (int)Constants.RegionSize + 10.2f; | ||
1069 | |||
1070 | m_position.X = vec.X; | ||
1071 | m_position.Y = vec.Y; | ||
1072 | m_position.Z = vec.Z; | ||
1073 | |||
1074 | // Did we move last? = zeroflag | ||
1075 | // This helps keep us from sliding all over | ||
1076 | |||
1077 | if (m_zeroFlag) | ||
1078 | { | ||
1079 | m_velocity.X = 0.0f; | ||
1080 | m_velocity.Y = 0.0f; | ||
1081 | m_velocity.Z = 0.0f; | ||
1082 | |||
1083 | // Did we send out the 'stopped' message? | ||
1084 | if (!m_lastUpdateSent) | ||
1085 | { | ||
1086 | m_lastUpdateSent = true; | ||
1087 | //base.RequestPhysicsterseUpdate(); | ||
1088 | |||
1089 | } | ||
1090 | } | ||
1091 | else | ||
1092 | { | ||
1093 | m_lastUpdateSent = false; | ||
1094 | vec = new Vector3(tempVector2.getX(), tempVector2.getY(), tempVector2.getZ()); | ||
1095 | m_velocity.X = (vec.X); | ||
1096 | m_velocity.Y = (vec.Y); | ||
1097 | |||
1098 | m_velocity.Z = (vec.Z); | ||
1099 | //m_log.Debug(m_target_velocity); | ||
1100 | if (m_velocity.Z < -6 && !m_hackSentFall) | ||
1101 | { | ||
1102 | m_hackSentFall = true; | ||
1103 | m_pidControllerActive = false; | ||
1104 | } | ||
1105 | else if (m_flying && !m_hackSentFly) | ||
1106 | { | ||
1107 | //m_hackSentFly = true; | ||
1108 | //base.SendCollisionUpdate(new CollisionEventUpdate()); | ||
1109 | } | ||
1110 | else | ||
1111 | { | ||
1112 | m_hackSentFly = false; | ||
1113 | m_hackSentFall = false; | ||
1114 | } | ||
1115 | } | ||
1116 | if (Body != null) | ||
1117 | { | ||
1118 | if (Body.getFriction() < 0.9f) | ||
1119 | Body.setFriction(0.9f); | ||
1120 | } | ||
1121 | //if (Body != null) | ||
1122 | // Body.clearForces(); | ||
1123 | } | ||
1124 | |||
1125 | public void CheckIfStandingOnObject() | ||
1126 | { | ||
1127 | |||
1128 | float capsuleHalfHeight = ((CAPSULE_LENGTH + 2*CAPSULE_RADIUS)*0.5f); | ||
1129 | |||
1130 | tempVector5RayCast.setValue(m_position.X, m_position.Y, m_position.Z); | ||
1131 | tempVector6RayCast.setValue(m_position.X, m_position.Y, m_position.Z - 1 * capsuleHalfHeight * 1.1f); | ||
1132 | |||
1133 | |||
1134 | ClosestCastResult.Dispose(); | ||
1135 | ClosestCastResult = new ClosestNotMeRayResultCallback(Body); | ||
1136 | |||
1137 | try | ||
1138 | { | ||
1139 | m_parent_scene.getBulletWorld().rayTest(tempVector5RayCast, tempVector6RayCast, ClosestCastResult); | ||
1140 | } | ||
1141 | catch (AccessViolationException) | ||
1142 | { | ||
1143 | m_log.Debug("BAD!"); | ||
1144 | } | ||
1145 | if (ClosestCastResult.hasHit()) | ||
1146 | { | ||
1147 | |||
1148 | if (tempVector7RayCast != null) | ||
1149 | tempVector7RayCast.Dispose(); | ||
1150 | |||
1151 | //tempVector7RayCast = ClosestCastResult.getHitPointWorld(); | ||
1152 | |||
1153 | /*if (tempVector7RayCast == null) // null == no result also | ||
1154 | { | ||
1155 | CollidingObj = false; | ||
1156 | IsColliding = false; | ||
1157 | CollidingGround = false; | ||
1158 | |||
1159 | return; | ||
1160 | } | ||
1161 | float zVal = tempVector7RayCast.getZ(); | ||
1162 | if (zVal != 0) | ||
1163 | m_log.Debug("[PHYSICS]: HAAAA"); | ||
1164 | if (zVal < m_position.Z && zVal > ((CAPSULE_LENGTH + 2 * CAPSULE_RADIUS) *0.5f)) | ||
1165 | { | ||
1166 | CollidingObj = true; | ||
1167 | IsColliding = true; | ||
1168 | } | ||
1169 | else | ||
1170 | { | ||
1171 | CollidingObj = false; | ||
1172 | IsColliding = false; | ||
1173 | CollidingGround = false; | ||
1174 | }*/ | ||
1175 | |||
1176 | //height+2*radius = capsule full length | ||
1177 | //CollidingObj = true; | ||
1178 | //IsColliding = true; | ||
1179 | m_iscolliding = true; | ||
1180 | } | ||
1181 | else | ||
1182 | { | ||
1183 | //CollidingObj = false; | ||
1184 | //IsColliding = false; | ||
1185 | //CollidingGround = false; | ||
1186 | m_iscolliding = false; | ||
1187 | } | ||
1188 | } | ||
1189 | } | ||
1190 | |||
1191 | } | ||
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 | |||
28 | using OpenSim.Region.Physics.Manager; | ||
29 | |||
30 | namespace 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/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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | using System.Runtime.InteropServices; | ||
32 | using System.Threading; | ||
33 | using log4net; | ||
34 | using OpenMetaverse; | ||
35 | using BulletDotNET; | ||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Region.Physics.Manager; | ||
38 | |||
39 | |||
40 | namespace 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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | using System.IO; | ||
32 | using System.Diagnostics; | ||
33 | using System.Threading; | ||
34 | using log4net; | ||
35 | using Nini.Config; | ||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Region.Physics.Manager; | ||
38 | using OpenMetaverse; | ||
39 | using BulletDotNET; | ||
40 | |||
41 | namespace 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 | |||
28 | using System.Reflection; | ||
29 | using 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 df62dbc..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 | |||
30 | using System; | ||
31 | using System.Collections.Generic; | ||
32 | using OpenMetaverse; | ||
33 | using MonoXnaCompactMaths; | ||
34 | using OpenSim.Framework; | ||
35 | using OpenSim.Region.Physics.Manager; | ||
36 | using XnaDevRu.BulletX; | ||
37 | using XnaDevRu.BulletX.Dynamics; | ||
38 | using Nini.Config; | ||
39 | using Vector3 = MonoXnaCompactMaths.Vector3; | ||
40 | using Quaternion = MonoXnaCompactMaths.Quaternion; | ||
41 | |||
42 | #endregion | ||
43 | |||
44 | namespace 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 | |||
34 | using System; | ||
35 | using System.Collections.Generic; | ||
36 | using MonoXnaCompactMaths; | ||
37 | using XnaDevRu.BulletX; | ||
38 | |||
39 | namespace 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 0a0d13f..4cc8c59 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 | ||
@@ -1325,7 +1329,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1325 | { | 1329 | { |
1326 | if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero) | 1330 | if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero) |
1327 | { | 1331 | { |
1328 | 1332 | // m_log.DebugFormat("[PHYSICS]: Changing capsule size"); | |
1333 | |||
1329 | m_pidControllerActive = true; | 1334 | m_pidControllerActive = true; |
1330 | // no lock needed on _parent_scene.OdeLock because we are called from within the thread lock in OdePlugin's simulate() | 1335 | // no lock needed on _parent_scene.OdeLock because we are called from within the thread lock in OdePlugin's simulate() |
1331 | d.JointDestroy(Amotor); | 1336 | d.JointDestroy(Amotor); |
@@ -1336,7 +1341,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1336 | d.GeomDestroy(Shell); | 1341 | d.GeomDestroy(Shell); |
1337 | AvatarGeomAndBodyCreation(_position.X, _position.Y, | 1342 | AvatarGeomAndBodyCreation(_position.X, _position.Y, |
1338 | _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2), m_tensor); | 1343 | _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2), m_tensor); |
1339 | Velocity = Vector3.Zero; | 1344 | |
1345 | // As with Size, we reset velocity. However, this isn't strictly necessary since it doesn't | ||
1346 | // appear to stall initial region crossings when done here. Being done for consistency. | ||
1347 | // Velocity = Vector3.Zero; | ||
1340 | 1348 | ||
1341 | _parent_scene.geom_name_map[Shell] = m_name; | 1349 | _parent_scene.geom_name_map[Shell] = m_name; |
1342 | _parent_scene.actor_name_map[Shell] = (PhysicsActor)this; | 1350 | _parent_scene.actor_name_map[Shell] = (PhysicsActor)this; |
@@ -1361,7 +1369,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1361 | _position.Z = m_taintPosition.Z; | 1369 | _position.Z = m_taintPosition.Z; |
1362 | } | 1370 | } |
1363 | } | 1371 | } |
1364 | |||
1365 | } | 1372 | } |
1366 | 1373 | ||
1367 | internal void AddCollisionFrameTime(int p) | 1374 | internal void AddCollisionFrameTime(int p) |
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 924d7c2..ac92b8b 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 88e884d..070cdc0 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -3591,7 +3591,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3591 | parentPrim.ScheduleGroupForFullUpdate(); | 3591 | parentPrim.ScheduleGroupForFullUpdate(); |
3592 | 3592 | ||
3593 | if (client != null) | 3593 | if (client != null) |
3594 | parentPrim.GetProperties(client); | 3594 | parentPrim.SendPropertiesToClient(client); |
3595 | 3595 | ||
3596 | ScriptSleep(1000); | 3596 | ScriptSleep(1000); |
3597 | } | 3597 | } |
@@ -6570,6 +6570,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6570 | 6570 | ||
6571 | protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) | 6571 | protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) |
6572 | { | 6572 | { |
6573 | float tempFloat; // Use in float expressions below to avoid byte cast precision issues. | ||
6573 | ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); | 6574 | ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); |
6574 | 6575 | ||
6575 | if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && | 6576 | if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && |
@@ -6651,8 +6652,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6651 | { | 6652 | { |
6652 | twist.y = 1.0f; | 6653 | twist.y = 1.0f; |
6653 | } | 6654 | } |
6654 | shapeBlock.PathTwistBegin = (sbyte)(100 * twist.x); | 6655 | // A fairly large precision error occurs for some calculations, |
6655 | shapeBlock.PathTwist = (sbyte)(100 * twist.y); | 6656 | // if a float or double is directly cast to a byte or sbyte |
6657 | // variable, in both .Net and Mono. In .Net, coding | ||
6658 | // "(sbyte)(float)(some expression)" corrects the precision | ||
6659 | // errors. But this does not work for Mono. This longer coding | ||
6660 | // form of creating a tempoary float variable from the | ||
6661 | // expression first, then casting that variable to a byte or | ||
6662 | // sbyte, works for both .Net and Mono. These types of | ||
6663 | // assignments occur in SetPrimtiveBlockShapeParams and | ||
6664 | // SetPrimitiveShapeParams in support of llSetPrimitiveParams. | ||
6665 | tempFloat = (float)(100.0d * twist.x); | ||
6666 | shapeBlock.PathTwistBegin = (sbyte)tempFloat; | ||
6667 | tempFloat = (float)(100.0d * twist.y); | ||
6668 | shapeBlock.PathTwist = (sbyte)tempFloat; | ||
6656 | 6669 | ||
6657 | shapeBlock.ObjectLocalID = part.LocalId; | 6670 | shapeBlock.ObjectLocalID = part.LocalId; |
6658 | 6671 | ||
@@ -6663,6 +6676,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6663 | // Prim type box, cylinder and prism. | 6676 | // Prim type box, cylinder and prism. |
6664 | protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve) | 6677 | protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve) |
6665 | { | 6678 | { |
6679 | float tempFloat; // Use in float expressions below to avoid byte cast precision issues. | ||
6666 | ObjectShapePacket.ObjectDataBlock shapeBlock; | 6680 | ObjectShapePacket.ObjectDataBlock shapeBlock; |
6667 | 6681 | ||
6668 | shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); | 6682 | shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); |
@@ -6683,8 +6697,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6683 | { | 6697 | { |
6684 | taper_b.y = 2f; | 6698 | taper_b.y = 2f; |
6685 | } | 6699 | } |
6686 | shapeBlock.PathScaleX = (byte)(100 * (2.0 - taper_b.x)); | 6700 | tempFloat = (float)(100.0d * (2.0d - taper_b.x)); |
6687 | shapeBlock.PathScaleY = (byte)(100 * (2.0 - taper_b.y)); | 6701 | shapeBlock.PathScaleX = (byte)tempFloat; |
6702 | tempFloat = (float)(100.0d * (2.0d - taper_b.y)); | ||
6703 | shapeBlock.PathScaleY = (byte)tempFloat; | ||
6688 | if (topshear.x < -0.5f) | 6704 | if (topshear.x < -0.5f) |
6689 | { | 6705 | { |
6690 | topshear.x = -0.5f; | 6706 | topshear.x = -0.5f; |
@@ -6701,8 +6717,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6701 | { | 6717 | { |
6702 | topshear.y = 0.5f; | 6718 | topshear.y = 0.5f; |
6703 | } | 6719 | } |
6704 | shapeBlock.PathShearX = (byte)(100 * topshear.x); | 6720 | tempFloat = (float)(100.0d * topshear.x); |
6705 | shapeBlock.PathShearY = (byte)(100 * topshear.y); | 6721 | shapeBlock.PathShearX = (byte)tempFloat; |
6722 | tempFloat = (float)(100.0d * topshear.y); | ||
6723 | shapeBlock.PathShearY = (byte)tempFloat; | ||
6706 | 6724 | ||
6707 | part.Shape.SculptEntry = false; | 6725 | part.Shape.SculptEntry = false; |
6708 | part.UpdateShape(shapeBlock); | 6726 | part.UpdateShape(shapeBlock); |
@@ -6752,6 +6770,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6752 | // Prim type torus, tube and ring. | 6770 | // Prim type torus, tube and ring. |
6753 | protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte profileshape, byte pathcurve) | 6771 | protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte profileshape, byte pathcurve) |
6754 | { | 6772 | { |
6773 | float tempFloat; // Use in float expressions below to avoid byte cast precision issues. | ||
6755 | ObjectShapePacket.ObjectDataBlock shapeBlock; | 6774 | ObjectShapePacket.ObjectDataBlock shapeBlock; |
6756 | 6775 | ||
6757 | shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); | 6776 | shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); |
@@ -6776,8 +6795,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6776 | { | 6795 | { |
6777 | holesize.y = 0.5f; | 6796 | holesize.y = 0.5f; |
6778 | } | 6797 | } |
6779 | shapeBlock.PathScaleX = (byte)(100 * (2 - holesize.x)); | 6798 | tempFloat = (float)(100.0d * (2.0d - holesize.x)); |
6780 | shapeBlock.PathScaleY = (byte)(100 * (2 - holesize.y)); | 6799 | shapeBlock.PathScaleX = (byte)tempFloat; |
6800 | tempFloat = (float)(100.0d * (2.0d - holesize.y)); | ||
6801 | shapeBlock.PathScaleY = (byte)tempFloat; | ||
6781 | if (topshear.x < -0.5f) | 6802 | if (topshear.x < -0.5f) |
6782 | { | 6803 | { |
6783 | topshear.x = -0.5f; | 6804 | topshear.x = -0.5f; |
@@ -6794,8 +6815,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6794 | { | 6815 | { |
6795 | topshear.y = 0.5f; | 6816 | topshear.y = 0.5f; |
6796 | } | 6817 | } |
6797 | shapeBlock.PathShearX = (byte)(100 * topshear.x); | 6818 | tempFloat = (float)(100.0d * topshear.x); |
6798 | shapeBlock.PathShearY = (byte)(100 * topshear.y); | 6819 | shapeBlock.PathShearX = (byte)tempFloat; |
6820 | tempFloat = (float)(100.0d * topshear.y); | ||
6821 | shapeBlock.PathShearY = (byte)tempFloat; | ||
6799 | if (profilecut.x < 0f) | 6822 | if (profilecut.x < 0f) |
6800 | { | 6823 | { |
6801 | profilecut.x = 0f; | 6824 | profilecut.x = 0f; |
@@ -6839,8 +6862,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6839 | { | 6862 | { |
6840 | taper_a.y = 1f; | 6863 | taper_a.y = 1f; |
6841 | } | 6864 | } |
6842 | shapeBlock.PathTaperX = (sbyte)(100 * taper_a.x); | 6865 | tempFloat = (float)(100.0d * taper_a.x); |
6843 | shapeBlock.PathTaperY = (sbyte)(100 * taper_a.y); | 6866 | shapeBlock.PathTaperX = (sbyte)tempFloat; |
6867 | tempFloat = (float)(100.0d * taper_a.y); | ||
6868 | shapeBlock.PathTaperY = (sbyte)tempFloat; | ||
6844 | if (revolutions < 1f) | 6869 | if (revolutions < 1f) |
6845 | { | 6870 | { |
6846 | revolutions = 1f; | 6871 | revolutions = 1f; |
@@ -6849,7 +6874,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6849 | { | 6874 | { |
6850 | revolutions = 4f; | 6875 | revolutions = 4f; |
6851 | } | 6876 | } |
6852 | shapeBlock.PathRevolutions = (byte)(66.666667 * (revolutions - 1.0)); | 6877 | tempFloat = 66.66667f * (revolutions - 1.0f); |
6878 | shapeBlock.PathRevolutions = (byte)tempFloat; | ||
6853 | // limits on radiusoffset depend on revolutions and hole size (how?) seems like the maximum range is 0 to 1 | 6879 | // limits on radiusoffset depend on revolutions and hole size (how?) seems like the maximum range is 0 to 1 |
6854 | if (radiusoffset < 0f) | 6880 | if (radiusoffset < 0f) |
6855 | { | 6881 | { |
@@ -6859,7 +6885,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6859 | { | 6885 | { |
6860 | radiusoffset = 1f; | 6886 | radiusoffset = 1f; |
6861 | } | 6887 | } |
6862 | shapeBlock.PathRadiusOffset = (sbyte)(100 * radiusoffset); | 6888 | tempFloat = 100.0f * radiusoffset; |
6889 | shapeBlock.PathRadiusOffset = (sbyte)tempFloat; | ||
6863 | if (skew < -0.95f) | 6890 | if (skew < -0.95f) |
6864 | { | 6891 | { |
6865 | skew = -0.95f; | 6892 | skew = -0.95f; |
@@ -6868,7 +6895,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6868 | { | 6895 | { |
6869 | skew = 0.95f; | 6896 | skew = 0.95f; |
6870 | } | 6897 | } |
6871 | shapeBlock.PathSkew = (sbyte)(100 * skew); | 6898 | tempFloat = 100.0f * skew; |
6899 | shapeBlock.PathSkew = (sbyte)tempFloat; | ||
6872 | 6900 | ||
6873 | part.Shape.SculptEntry = false; | 6901 | part.Shape.SculptEntry = false; |
6874 | part.UpdateShape(shapeBlock); | 6902 | part.UpdateShape(shapeBlock); |
@@ -7681,10 +7709,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7681 | res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0)); | 7709 | res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0)); |
7682 | 7710 | ||
7683 | // float revolutions | 7711 | // float revolutions |
7684 | res.Add(new LSL_Float((Shape.PathRevolutions * 0.015) + 1.0)); // Slightly inaccurate, because an unsigned | 7712 | res.Add(new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d); |
7685 | // byte is being used to represent the entire | 7713 | // Slightly inaccurate, because an unsigned byte is being used to represent |
7686 | // range of floating-point values from 1.0 | 7714 | // the entire range of floating-point values from 1.0 through 4.0 (which is how |
7687 | // through 4.0 (which is how SL does it). | 7715 | // SL does it). |
7716 | // | ||
7717 | // Using these formulas to store and retrieve PathRevolutions, it is not | ||
7718 | // possible to use all values between 1.00 and 4.00. For instance, you can't | ||
7719 | // represent 1.10. You can represent 1.09 and 1.11, but not 1.10. So, if you | ||
7720 | // use llSetPrimitiveParams to set revolutions to 1.10 and then retreive them | ||
7721 | // with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar | ||
7722 | // behavior in the viewer as you cannot set 1.10. The viewer jumps to 1.11. | ||
7723 | // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value | ||
7724 | // such as 1.10. So, SL must store and retreive the actual user input rather | ||
7725 | // than only storing the encoded value. | ||
7688 | 7726 | ||
7689 | // float radiusoffset | 7727 | // float radiusoffset |
7690 | res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0)); | 7728 | res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0)); |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs index 8cd1e84..0cbad41 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs | |||
@@ -49,7 +49,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
49 | 49 | ||
50 | private const double ANGLE_ACCURACY_IN_RADIANS = 1E-6; | 50 | private const double ANGLE_ACCURACY_IN_RADIANS = 1E-6; |
51 | private const double VECTOR_COMPONENT_ACCURACY = 0.0000005d; | 51 | private const double VECTOR_COMPONENT_ACCURACY = 0.0000005d; |
52 | private const double FLOAT_ACCURACY = 0.00005d; | 52 | private const float FLOAT_ACCURACY = 0.00005f; |
53 | private LSL_Api m_lslApi; | 53 | private LSL_Api m_lslApi; |
54 | 54 | ||
55 | [SetUp] | 55 | [SetUp] |
@@ -194,10 +194,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
194 | ScriptBaseClass.PRIM_TYPE_SPHERE, // Prim type | 194 | ScriptBaseClass.PRIM_TYPE_SPHERE, // Prim type |
195 | ScriptBaseClass.PRIM_HOLE_DEFAULT, // Prim hole type | 195 | ScriptBaseClass.PRIM_HOLE_DEFAULT, // Prim hole type |
196 | new LSL_Types.Vector3(0.0d, 0.075d, 0.0d), // Prim cut | 196 | new LSL_Types.Vector3(0.0d, 0.075d, 0.0d), // Prim cut |
197 | 0.80d, // Prim hollow | 197 | 0.80f, // Prim hollow |
198 | new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist | 198 | new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist |
199 | new LSL_Types.Vector3(0.32d, 0.76d, 0.0d), // Prim dimple | 199 | new LSL_Types.Vector3(0.32d, 0.76d, 0.0d), // Prim dimple |
200 | 0.80d); // Prim hollow check | 200 | 0.80f); // Prim hollow check |
201 | 201 | ||
202 | // Test a prism. | 202 | // Test a prism. |
203 | CheckllSetPrimitiveParams( | 203 | CheckllSetPrimitiveParams( |
@@ -206,11 +206,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
206 | ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type | 206 | ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type |
207 | ScriptBaseClass.PRIM_HOLE_CIRCLE, // Prim hole type | 207 | ScriptBaseClass.PRIM_HOLE_CIRCLE, // Prim hole type |
208 | new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut | 208 | new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut |
209 | 0.90d, // Prim hollow | 209 | 0.90f, // Prim hollow |
210 | new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist | 210 | new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist |
211 | new LSL_Types.Vector3(2.0d, 1.0d, 0.0d), // Prim taper | 211 | new LSL_Types.Vector3(2.0d, 1.0d, 0.0d), // Prim taper |
212 | new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear | 212 | new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear |
213 | 0.90d); // Prim hollow check | 213 | 0.90f); // Prim hollow check |
214 | 214 | ||
215 | // Test a box. | 215 | // Test a box. |
216 | CheckllSetPrimitiveParams( | 216 | CheckllSetPrimitiveParams( |
@@ -219,11 +219,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
219 | ScriptBaseClass.PRIM_TYPE_BOX, // Prim type | 219 | ScriptBaseClass.PRIM_TYPE_BOX, // Prim type |
220 | ScriptBaseClass.PRIM_HOLE_TRIANGLE, // Prim hole type | 220 | ScriptBaseClass.PRIM_HOLE_TRIANGLE, // Prim hole type |
221 | new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut | 221 | new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut |
222 | 0.95d, // Prim hollow | 222 | 0.95f, // Prim hollow |
223 | new LSL_Types.Vector3(1.0d, 0.0d, 0.0d), // Prim twist | 223 | new LSL_Types.Vector3(1.0d, 0.0d, 0.0d), // Prim twist |
224 | new LSL_Types.Vector3(1.0d, 1.0d, 0.0d), // Prim taper | 224 | new LSL_Types.Vector3(1.0d, 1.0d, 0.0d), // Prim taper |
225 | new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear | 225 | new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear |
226 | 0.95d); // Prim hollow check | 226 | 0.95f); // Prim hollow check |
227 | 227 | ||
228 | // Test a tube. | 228 | // Test a tube. |
229 | CheckllSetPrimitiveParams( | 229 | CheckllSetPrimitiveParams( |
@@ -232,16 +232,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
232 | ScriptBaseClass.PRIM_TYPE_TUBE, // Prim type | 232 | ScriptBaseClass.PRIM_TYPE_TUBE, // Prim type |
233 | ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type | 233 | ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type |
234 | new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut | 234 | new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut |
235 | 0.00d, // Prim hollow | 235 | 0.00f, // Prim hollow |
236 | new LSL_Types.Vector3(1.0d, -1.0d, 0.0d), // Prim twist | 236 | new LSL_Types.Vector3(1.0d, -1.0d, 0.0d), // Prim twist |
237 | new LSL_Types.Vector3(1.0d, 0.5d, 0.0d), // Prim hole size | 237 | new LSL_Types.Vector3(1.0d, 0.05d, 0.0d), // Prim hole size |
238 | new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear | 238 | // Expression for y selected to test precision problems during byte |
239 | // cast in SetPrimitiveShapeParams. | ||
240 | new LSL_Types.Vector3(0.0d, 0.35d + 0.1d, 0.0d), // Prim shear | ||
239 | new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim profile cut | 241 | new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim profile cut |
240 | new LSL_Types.Vector3(-1.0d, 1.0d, 0.0d), // Prim taper | 242 | // Expression for y selected to test precision problems during sbyte |
241 | 1.0d, // Prim revolutions | 243 | // cast in SetPrimitiveShapeParams. |
242 | 1.0d, // Prim radius | 244 | new LSL_Types.Vector3(-1.0d, 0.70d + 0.1d + 0.1d, 0.0d), // Prim taper |
243 | 0.0d, // Prim skew | 245 | 1.11f, // Prim revolutions |
244 | 0.00d); // Prim hollow check | 246 | 0.88f, // Prim radius |
247 | 0.95f, // Prim skew | ||
248 | 0.00f); // Prim hollow check | ||
245 | 249 | ||
246 | // Test a prism. | 250 | // Test a prism. |
247 | CheckllSetPrimitiveParams( | 251 | CheckllSetPrimitiveParams( |
@@ -250,11 +254,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
250 | ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type | 254 | ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type |
251 | ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type | 255 | ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type |
252 | new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut | 256 | new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut |
253 | 0.95d, // Prim hollow | 257 | 0.95f, // Prim hollow |
254 | new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist | 258 | // Expression for x selected to test precision problems during sbyte |
255 | new LSL_Types.Vector3(2.0d, 1.0d, 0.0d), // Prim taper | 259 | // cast in SetPrimitiveShapeBlockParams. |
260 | new LSL_Types.Vector3(0.7d + 0.2d, 0.0d, 0.0d), // Prim twist | ||
261 | // Expression for y selected to test precision problems during sbyte | ||
262 | // cast in SetPrimitiveShapeParams. | ||
263 | new LSL_Types.Vector3(2.0d, (1.3d + 0.1d), 0.0d), // Prim taper | ||
256 | new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear | 264 | new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear |
257 | 0.70d); // Prim hollow check | 265 | 0.70f); // Prim hollow check |
258 | 266 | ||
259 | // Test a sculpted prim. | 267 | // Test a sculpted prim. |
260 | CheckllSetPrimitiveParams( | 268 | CheckllSetPrimitiveParams( |
@@ -268,8 +276,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
268 | // Set prim params for a box, cylinder or prism and check results. | 276 | // Set prim params for a box, cylinder or prism and check results. |
269 | public void CheckllSetPrimitiveParams(string primTest, | 277 | public void CheckllSetPrimitiveParams(string primTest, |
270 | LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut, | 278 | LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut, |
271 | double primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primTaper, LSL_Types.Vector3 primShear, | 279 | float primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primTaper, LSL_Types.Vector3 primShear, |
272 | double primHollowCheck) | 280 | float primHollowCheck) |
273 | { | 281 | { |
274 | // Set the prim params. | 282 | // Set the prim params. |
275 | m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize, | 283 | m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize, |
@@ -297,7 +305,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
297 | // Set prim params for a sphere and check results. | 305 | // Set prim params for a sphere and check results. |
298 | public void CheckllSetPrimitiveParams(string primTest, | 306 | public void CheckllSetPrimitiveParams(string primTest, |
299 | LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut, | 307 | LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut, |
300 | double primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primDimple, double primHollowCheck) | 308 | float primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primDimple, float primHollowCheck) |
301 | { | 309 | { |
302 | // Set the prim params. | 310 | // Set the prim params. |
303 | m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize, | 311 | m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize, |
@@ -324,9 +332,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
324 | // Set prim params for a torus, tube or ring and check results. | 332 | // Set prim params for a torus, tube or ring and check results. |
325 | public void CheckllSetPrimitiveParams(string primTest, | 333 | public void CheckllSetPrimitiveParams(string primTest, |
326 | LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut, | 334 | LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut, |
327 | double primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primHoleSize, | 335 | float primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primHoleSize, |
328 | LSL_Types.Vector3 primShear, LSL_Types.Vector3 primProfCut, LSL_Types.Vector3 primTaper, | 336 | LSL_Types.Vector3 primShear, LSL_Types.Vector3 primProfCut, LSL_Types.Vector3 primTaper, |
329 | double primRev, double primRadius, double primSkew, double primHollowCheck) | 337 | float primRev, float primRadius, float primSkew, float primHollowCheck) |
330 | { | 338 | { |
331 | // Set the prim params. | 339 | // Set the prim params. |
332 | m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize, | 340 | m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize, |
@@ -353,7 +361,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
353 | CheckllSetPrimitiveParamsVector(primProfCut, m_lslApi.llList2Vector(primParams, 8), primTest + " prim profile cut"); | 361 | CheckllSetPrimitiveParamsVector(primProfCut, m_lslApi.llList2Vector(primParams, 8), primTest + " prim profile cut"); |
354 | CheckllSetPrimitiveParamsVector(primTaper, m_lslApi.llList2Vector(primParams, 9), primTest + " prim taper"); | 362 | CheckllSetPrimitiveParamsVector(primTaper, m_lslApi.llList2Vector(primParams, 9), primTest + " prim taper"); |
355 | Assert.AreEqual(primRev, m_lslApi.llList2Float(primParams, 10), FLOAT_ACCURACY, | 363 | Assert.AreEqual(primRev, m_lslApi.llList2Float(primParams, 10), FLOAT_ACCURACY, |
356 | "TestllSetPrimitiveParams " + primTest + " prim revolution fail"); | 364 | "TestllSetPrimitiveParams " + primTest + " prim revolutions fail"); |
357 | Assert.AreEqual(primRadius, m_lslApi.llList2Float(primParams, 11), FLOAT_ACCURACY, | 365 | Assert.AreEqual(primRadius, m_lslApi.llList2Float(primParams, 11), FLOAT_ACCURACY, |
358 | "TestllSetPrimitiveParams " + primTest + " prim radius fail"); | 366 | "TestllSetPrimitiveParams " + primTest + " prim radius fail"); |
359 | Assert.AreEqual(primSkew, m_lslApi.llList2Float(primParams, 12), FLOAT_ACCURACY, | 367 | Assert.AreEqual(primSkew, m_lslApi.llList2Float(primParams, 12), FLOAT_ACCURACY, |
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index c443669..156fd57 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | |||
@@ -339,7 +339,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
339 | m_ThreadPool.QueueWorkItem(new WorkItemCallback(this.DoBackup), | 339 | m_ThreadPool.QueueWorkItem(new WorkItemCallback(this.DoBackup), |
340 | new Object[] { m_SaveTime }); | 340 | new Object[] { m_SaveTime }); |
341 | } | 341 | } |
342 | } | ||
342 | 343 | ||
344 | public void StartProcessing() | ||
345 | { | ||
343 | m_ThreadPool.Start(); | 346 | m_ThreadPool.Start(); |
344 | } | 347 | } |
345 | 348 | ||
@@ -591,7 +594,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
591 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); | 594 | SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); |
592 | if (part == null) | 595 | if (part == null) |
593 | { | 596 | { |
594 | m_log.Error("[Script] SceneObjectPart unavailable. Script NOT started."); | 597 | m_log.ErrorFormat("[Script]: SceneObjectPart with localID {0} unavailable. Script NOT started.", localID); |
595 | m_ScriptErrorMessage += "SceneObjectPart unavailable. Script NOT started.\n"; | 598 | m_ScriptErrorMessage += "SceneObjectPart unavailable. Script NOT started.\n"; |
596 | m_ScriptFailCount++; | 599 | m_ScriptFailCount++; |
597 | return false; | 600 | return false; |
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 8b8a8f9..e071b94 100644 --- a/OpenSim/Services/UserAccountService/UserAccountService.cs +++ b/OpenSim/Services/UserAccountService/UserAccountService.cs | |||
@@ -28,15 +28,15 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using log4net; | ||
31 | using Nini.Config; | 32 | using Nini.Config; |
33 | using OpenMetaverse; | ||
32 | using OpenSim.Data; | 34 | using OpenSim.Data; |
35 | using OpenSim.Framework; | ||
33 | using OpenSim.Services.Interfaces; | 36 | using OpenSim.Services.Interfaces; |
34 | using OpenSim.Framework.Console; | 37 | using OpenSim.Framework.Console; |
35 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | 38 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; |
36 | 39 | ||
37 | using OpenMetaverse; | ||
38 | using log4net; | ||
39 | |||
40 | namespace OpenSim.Services.UserAccountService | 40 | namespace 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 |
@@ -330,7 +340,7 @@ namespace OpenSim.Services.UserAccountService | |||
330 | email = MainConsole.Instance.CmdPrompt("Email", ""); | 340 | email = MainConsole.Instance.CmdPrompt("Email", ""); |
331 | else email = cmdparams[5]; | 341 | else email = cmdparams[5]; |
332 | 342 | ||
333 | CreateUser(firstName, lastName, password, email); | 343 | CreateUser(UUID.Zero, firstName, lastName, password, email); |
334 | } | 344 | } |
335 | 345 | ||
336 | protected void HandleShowAccount(string module, string[] cmdparams) | 346 | protected void HandleShowAccount(string module, string[] cmdparams) |
@@ -442,11 +452,12 @@ namespace OpenSim.Services.UserAccountService | |||
442 | /// <summary> | 452 | /// <summary> |
443 | /// Create a user | 453 | /// Create a user |
444 | /// </summary> | 454 | /// </summary> |
455 | /// <param name="scopeID">Allows hosting of multiple grids in a single database. Normally left as UUID.Zero</param> | ||
445 | /// <param name="firstName"></param> | 456 | /// <param name="firstName"></param> |
446 | /// <param name="lastName"></param> | 457 | /// <param name="lastName"></param> |
447 | /// <param name="password"></param> | 458 | /// <param name="password"></param> |
448 | /// <param name="email"></param> | 459 | /// <param name="email"></param> |
449 | private void CreateUser(string firstName, string lastName, string password, string email) | 460 | public UserAccount CreateUser(UUID scopeID, string firstName, string lastName, string password, string email) |
450 | { | 461 | { |
451 | UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName); | 462 | UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName); |
452 | if (null == account) | 463 | if (null == account) |
@@ -493,12 +504,20 @@ namespace OpenSim.Services.UserAccountService | |||
493 | { | 504 | { |
494 | success = m_InventoryService.CreateUserInventory(account.PrincipalID); | 505 | success = m_InventoryService.CreateUserInventory(account.PrincipalID); |
495 | if (!success) | 506 | if (!success) |
507 | { | ||
496 | m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to create inventory for account {0} {1}.", | 508 | m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to create inventory for account {0} {1}.", |
497 | firstName, lastName); | 509 | firstName, lastName); |
510 | } | ||
511 | else if (m_CreateDefaultAvatarEntries) | ||
512 | { | ||
513 | CreateDefaultAppearanceEntries(account.PrincipalID); | ||
514 | } | ||
498 | } | 515 | } |
499 | 516 | ||
500 | m_log.InfoFormat("[USER ACCOUNT SERVICE]: Account {0} {1} created successfully", firstName, lastName); | 517 | m_log.InfoFormat("[USER ACCOUNT SERVICE]: Account {0} {1} created successfully", firstName, lastName); |
501 | } else { | 518 | } |
519 | else | ||
520 | { | ||
502 | m_log.ErrorFormat("[USER ACCOUNT SERVICE]: Account creation failed for account {0} {1}", firstName, lastName); | 521 | m_log.ErrorFormat("[USER ACCOUNT SERVICE]: Account creation failed for account {0} {1}", firstName, lastName); |
503 | } | 522 | } |
504 | } | 523 | } |
@@ -506,6 +525,128 @@ namespace OpenSim.Services.UserAccountService | |||
506 | { | 525 | { |
507 | m_log.ErrorFormat("[USER ACCOUNT SERVICE]: A user with the name {0} {1} already exists!", firstName, lastName); | 526 | m_log.ErrorFormat("[USER ACCOUNT SERVICE]: A user with the name {0} {1} already exists!", firstName, lastName); |
508 | } | 527 | } |
528 | |||
529 | return account; | ||
530 | } | ||
531 | |||
532 | private void CreateDefaultAppearanceEntries(UUID principalID) | ||
533 | { | ||
534 | m_log.DebugFormat("[USER ACCOUNT SERVICE]: Creating default appearance items for {0}", principalID); | ||
535 | |||
536 | InventoryFolderBase bodyPartsFolder = m_InventoryService.GetFolderForType(principalID, AssetType.Bodypart); | ||
537 | |||
538 | InventoryItemBase eyes = new InventoryItemBase(UUID.Random(), principalID); | ||
539 | eyes.AssetID = new UUID("4bb6fa4d-1cd2-498a-a84c-95c1a0e745a7"); | ||
540 | eyes.Name = "Default Eyes"; | ||
541 | eyes.CreatorId = principalID.ToString(); | ||
542 | eyes.AssetType = (int)AssetType.Bodypart; | ||
543 | eyes.InvType = (int)InventoryType.Wearable; | ||
544 | eyes.Folder = bodyPartsFolder.ID; | ||
545 | eyes.BasePermissions = (uint)PermissionMask.All; | ||
546 | eyes.CurrentPermissions = (uint)PermissionMask.All; | ||
547 | eyes.EveryOnePermissions = (uint)PermissionMask.All; | ||
548 | eyes.GroupPermissions = (uint)PermissionMask.All; | ||
549 | eyes.NextPermissions = (uint)PermissionMask.All; | ||
550 | eyes.Flags = (uint)WearableType.Eyes; | ||
551 | m_InventoryService.AddItem(eyes); | ||
552 | |||
553 | InventoryItemBase shape = new InventoryItemBase(UUID.Random(), principalID); | ||
554 | shape.AssetID = AvatarWearable.DEFAULT_BODY_ASSET; | ||
555 | shape.Name = "Default Shape"; | ||
556 | shape.CreatorId = principalID.ToString(); | ||
557 | shape.AssetType = (int)AssetType.Bodypart; | ||
558 | shape.InvType = (int)InventoryType.Wearable; | ||
559 | shape.Folder = bodyPartsFolder.ID; | ||
560 | shape.BasePermissions = (uint)PermissionMask.All; | ||
561 | shape.CurrentPermissions = (uint)PermissionMask.All; | ||
562 | shape.EveryOnePermissions = (uint)PermissionMask.All; | ||
563 | shape.GroupPermissions = (uint)PermissionMask.All; | ||
564 | shape.NextPermissions = (uint)PermissionMask.All; | ||
565 | shape.Flags = (uint)WearableType.Shape; | ||
566 | m_InventoryService.AddItem(shape); | ||
567 | |||
568 | InventoryItemBase skin = new InventoryItemBase(UUID.Random(), principalID); | ||
569 | skin.AssetID = AvatarWearable.DEFAULT_SKIN_ASSET; | ||
570 | skin.Name = "Default Skin"; | ||
571 | skin.CreatorId = principalID.ToString(); | ||
572 | skin.AssetType = (int)AssetType.Bodypart; | ||
573 | skin.InvType = (int)InventoryType.Wearable; | ||
574 | skin.Folder = bodyPartsFolder.ID; | ||
575 | skin.BasePermissions = (uint)PermissionMask.All; | ||
576 | skin.CurrentPermissions = (uint)PermissionMask.All; | ||
577 | skin.EveryOnePermissions = (uint)PermissionMask.All; | ||
578 | skin.GroupPermissions = (uint)PermissionMask.All; | ||
579 | skin.NextPermissions = (uint)PermissionMask.All; | ||
580 | skin.Flags = (uint)WearableType.Skin; | ||
581 | m_InventoryService.AddItem(skin); | ||
582 | |||
583 | InventoryItemBase hair = new InventoryItemBase(UUID.Random(), principalID); | ||
584 | hair.AssetID = AvatarWearable.DEFAULT_HAIR_ASSET; | ||
585 | hair.Name = "Default Hair"; | ||
586 | hair.CreatorId = principalID.ToString(); | ||
587 | hair.AssetType = (int)AssetType.Bodypart; | ||
588 | hair.InvType = (int)InventoryType.Wearable; | ||
589 | hair.Folder = bodyPartsFolder.ID; | ||
590 | hair.BasePermissions = (uint)PermissionMask.All; | ||
591 | hair.CurrentPermissions = (uint)PermissionMask.All; | ||
592 | hair.EveryOnePermissions = (uint)PermissionMask.All; | ||
593 | hair.GroupPermissions = (uint)PermissionMask.All; | ||
594 | hair.NextPermissions = (uint)PermissionMask.All; | ||
595 | hair.Flags = (uint)WearableType.Hair; | ||
596 | m_InventoryService.AddItem(hair); | ||
597 | |||
598 | InventoryFolderBase clothingFolder = m_InventoryService.GetFolderForType(principalID, AssetType.Clothing); | ||
599 | |||
600 | InventoryItemBase shirt = new InventoryItemBase(UUID.Random(), principalID); | ||
601 | shirt.AssetID = AvatarWearable.DEFAULT_SHIRT_ASSET; | ||
602 | shirt.Name = "Default Shirt"; | ||
603 | shirt.CreatorId = principalID.ToString(); | ||
604 | shirt.AssetType = (int)AssetType.Clothing; | ||
605 | shirt.InvType = (int)InventoryType.Wearable; | ||
606 | shirt.Folder = clothingFolder.ID; | ||
607 | shirt.BasePermissions = (uint)PermissionMask.All; | ||
608 | shirt.CurrentPermissions = (uint)PermissionMask.All; | ||
609 | shirt.EveryOnePermissions = (uint)PermissionMask.All; | ||
610 | shirt.GroupPermissions = (uint)PermissionMask.All; | ||
611 | shirt.NextPermissions = (uint)PermissionMask.All; | ||
612 | shirt.Flags = (uint)WearableType.Shirt; | ||
613 | m_InventoryService.AddItem(shirt); | ||
614 | |||
615 | InventoryItemBase pants = new InventoryItemBase(UUID.Random(), principalID); | ||
616 | pants.AssetID = AvatarWearable.DEFAULT_PANTS_ASSET; | ||
617 | pants.Name = "Default Pants"; | ||
618 | pants.CreatorId = principalID.ToString(); | ||
619 | pants.AssetType = (int)AssetType.Clothing; | ||
620 | pants.InvType = (int)InventoryType.Wearable; | ||
621 | pants.Folder = clothingFolder.ID; | ||
622 | pants.BasePermissions = (uint)PermissionMask.All; | ||
623 | pants.CurrentPermissions = (uint)PermissionMask.All; | ||
624 | pants.EveryOnePermissions = (uint)PermissionMask.All; | ||
625 | pants.GroupPermissions = (uint)PermissionMask.All; | ||
626 | pants.NextPermissions = (uint)PermissionMask.All; | ||
627 | pants.Flags = (uint)WearableType.Pants; | ||
628 | m_InventoryService.AddItem(pants); | ||
629 | |||
630 | if (m_AvatarService != null) | ||
631 | { | ||
632 | m_log.DebugFormat("[USER ACCOUNT SERVICE]: Creating default avatar entries for {0}", principalID); | ||
633 | |||
634 | AvatarWearable[] wearables = new AvatarWearable[6]; | ||
635 | wearables[AvatarWearable.EYES] = new AvatarWearable(eyes.ID, eyes.AssetID); | ||
636 | wearables[AvatarWearable.BODY] = new AvatarWearable(shape.ID, shape.AssetID); | ||
637 | wearables[AvatarWearable.SKIN] = new AvatarWearable(skin.ID, skin.AssetID); | ||
638 | wearables[AvatarWearable.HAIR] = new AvatarWearable(hair.ID, hair.AssetID); | ||
639 | wearables[AvatarWearable.SHIRT] = new AvatarWearable(shirt.ID, shirt.AssetID); | ||
640 | wearables[AvatarWearable.PANTS] = new AvatarWearable(pants.ID, pants.AssetID); | ||
641 | |||
642 | AvatarAppearance ap = new AvatarAppearance(); | ||
643 | for (int i = 0; i < 6; i++) | ||
644 | { | ||
645 | ap.SetWearable(i, wearables[i]); | ||
646 | } | ||
647 | |||
648 | m_AvatarService.SetAppearance(principalID, ap); | ||
649 | } | ||
509 | } | 650 | } |
510 | } | 651 | } |
511 | } | 652 | } \ No newline at end of file |
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index b7cefeb..71f2bf4 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 | |||
28 | using System; | ||
29 | using OpenMetaverse; | ||
30 | using NUnit.Framework; | ||
31 | using NUnit.Framework.Constraints; | ||
32 | |||
33 | namespace 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/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index c36d2a4..925c343 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example | |||
@@ -149,14 +149,13 @@ | |||
149 | 149 | ||
150 | ;; Choose one of the physics engines below | 150 | ;; Choose one of the physics engines below |
151 | ;; OpenDynamicsEngine is by some distance the most developed physics engine | 151 | ;; OpenDynamicsEngine is by some distance the most developed physics engine |
152 | ;; basicphysics effectively does not model physics at all, making all | 152 | ;; BulletSim is incomplete and experimental but in active development |
153 | ;; objects phantom | 153 | ;; basicphysics effectively does not model physics at all, making all objects phantom |
154 | ;; The Bullet plugins do not work properly right now. A better Bullet plugin is on the way. | ||
155 | ;; Default is OpenDynamicsEngine | 154 | ;; Default is OpenDynamicsEngine |
156 | ; physics = OpenDynamicsEngine | 155 | ; physics = OpenDynamicsEngine |
156 | ; physics = BulletSim | ||
157 | ; physics = basicphysics | 157 | ; physics = basicphysics |
158 | ; physics = POS | 158 | ; physics = POS |
159 | ; physics = modified_BulletX | ||
160 | 159 | ||
161 | ;# {permissionmodules} {} {Permission modules to use (may specify multiple modules, separated by space} {} DefaultPermissionsModule | 160 | ;# {permissionmodules} {} {Permission modules to use (may specify multiple modules, separated by space} {} DefaultPermissionsModule |
162 | ;; Permission modules to use, separated by space. | 161 | ;; Permission modules to use, separated by space. |
diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index 910ba02..7f2636c 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example | |||
@@ -166,6 +166,14 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 | |||
166 | PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService" | 166 | PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService" |
167 | GridService = "OpenSim.Services.GridService.dll:GridService" | 167 | GridService = "OpenSim.Services.GridService.dll:GridService" |
168 | InventoryService = "OpenSim.Services.InventoryService.dll:XInventoryService" | 168 | InventoryService = "OpenSim.Services.InventoryService.dll:XInventoryService" |
169 | ; AvatarService = "OpenSim.Services.AvatarService.dll:AvatarService" | ||
170 | |||
171 | ;; This switch creates the minimum set of body parts and avatar entries for a viewer 2 | ||
172 | ;; to show a default "Ruth" avatar rather than a cloud for a newly created user. | ||
173 | ;; Default is false | ||
174 | ;; If you enable this you will also need to uncomment the AvatarService line above | ||
175 | ; CreateDefaultAvatarEntries = false | ||
176 | |||
169 | 177 | ||
170 | [GridUserService] | 178 | [GridUserService] |
171 | ; for the server connector | 179 | ; for the server connector |
diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example index f7781ab..a299a73 100644 --- a/bin/Robust.ini.example +++ b/bin/Robust.ini.example | |||
@@ -149,6 +149,14 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 | |||
149 | PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService" | 149 | PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService" |
150 | GridService = "OpenSim.Services.GridService.dll:GridService" | 150 | GridService = "OpenSim.Services.GridService.dll:GridService" |
151 | InventoryService = "OpenSim.Services.InventoryService.dll:XInventoryService" | 151 | InventoryService = "OpenSim.Services.InventoryService.dll:XInventoryService" |
152 | ; AvatarService = "OpenSim.Services.AvatarService.dll:AvatarService" | ||
153 | |||
154 | ;; This switch creates the minimum set of body parts and avatar entries for a viewer 2 | ||
155 | ;; to show a default "Ruth" avatar rather than a cloud for a newly created user. | ||
156 | ;; Default is false | ||
157 | ;; If you enable this you will also need to uncomment the AvatarService line above | ||
158 | ; CreateDefaultAvatarEntries = false | ||
159 | |||
152 | 160 | ||
153 | [GridUserService] | 161 | [GridUserService] |
154 | ; for the server connector | 162 | ; for the server connector |
diff --git a/bin/assets/BodyPartsAssetSet/BodyPartsAssetSet.xml b/bin/assets/BodyPartsAssetSet/BodyPartsAssetSet.xml index 8ef0fe7..a3d7ba3 100644 --- a/bin/assets/BodyPartsAssetSet/BodyPartsAssetSet.xml +++ b/bin/assets/BodyPartsAssetSet/BodyPartsAssetSet.xml | |||
@@ -4,7 +4,7 @@ | |||
4 | <Key Name="assetID" Value="d342e6c0-b9d2-11dc-95ff-0800200c9a66"/> | 4 | <Key Name="assetID" Value="d342e6c0-b9d2-11dc-95ff-0800200c9a66"/> |
5 | <Key Name="name" Value="Hair"/> | 5 | <Key Name="name" Value="Hair"/> |
6 | <Key Name="assetType" Value="13" /> | 6 | <Key Name="assetType" Value="13" /> |
7 | <Key Name="fileName" Value="newhair.dat"/> | 7 | <Key Name="fileName" Value="base_hair.dat"/> |
8 | </Section> | 8 | </Section> |
9 | 9 | ||
10 | <Section Name="Skin"> | 10 | <Section Name="Skin"> |
@@ -34,6 +34,14 @@ | |||
34 | <Key Name="assetType" Value="13" /> | 34 | <Key Name="assetType" Value="13" /> |
35 | <Key Name="fileName" Value="base_shape.dat"/> | 35 | <Key Name="fileName" Value="base_shape.dat"/> |
36 | </Section> | 36 | </Section> |
37 | |||
38 | <Section Name="Eyes"> | ||
39 | <Key Name="assetID" Value="4bb6fa4d-1cd2-498a-a84c-95c1a0e745a7"/> | ||
40 | <Key Name="name" Value="Eyes"/> | ||
41 | <Key Name="assetType" Value="13" /> | ||
42 | <Key Name="fileName" Value="base_eyes.dat"/> | ||
43 | </Section> | ||
44 | |||
37 | <!-- | 45 | <!-- |
38 | <Section Name="Jim Shape"> | 46 | <Section Name="Jim Shape"> |
39 | <Key Name="assetID" Value="66c41e39-38f9-f75a-024e-585989bfab74"/> | 47 | <Key Name="assetID" Value="66c41e39-38f9-f75a-024e-585989bfab74"/> |
diff --git a/bin/assets/BodyPartsAssetSet/base_eyes.dat b/bin/assets/BodyPartsAssetSet/base_eyes.dat new file mode 100644 index 0000000..520157c --- /dev/null +++ b/bin/assets/BodyPartsAssetSet/base_eyes.dat | |||
@@ -0,0 +1,26 @@ | |||
1 | LLWearable version 22 | ||
2 | New Eyes | ||
3 | |||
4 | permissions 0 | ||
5 | { | ||
6 | base_mask 7fffffff | ||
7 | owner_mask 7fffffff | ||
8 | group_mask 00000000 | ||
9 | everyone_mask 00000000 | ||
10 | next_owner_mask 00082000 | ||
11 | creator_id 11111111-1111-0000-0000-000100bba000 | ||
12 | owner_id 11111111-1111-0000-0000-000100bba000 | ||
13 | last_owner_id 00000000-0000-0000-0000-000000000000 | ||
14 | group_id 00000000-0000-0000-0000-000000000000 | ||
15 | } | ||
16 | sale_info 0 | ||
17 | { | ||
18 | sale_type not | ||
19 | sale_price 10 | ||
20 | } | ||
21 | type 3 | ||
22 | parameters 2 | ||
23 | 98 0 | ||
24 | 99 0 | ||
25 | textures 1 | ||
26 | 3 6522e74d-1660-4e7f-b601-6f48c1659a77 | ||
diff --git a/bin/assets/BodyPartsAssetSet/newhair.dat b/bin/assets/BodyPartsAssetSet/base_hair.dat index 3c5a8c9..05e21d8 100644 --- a/bin/assets/BodyPartsAssetSet/newhair.dat +++ b/bin/assets/BodyPartsAssetSet/base_hair.dat | |||
@@ -8,8 +8,8 @@ New Hair | |||
8 | group_mask 00000000 | 8 | group_mask 00000000 |
9 | everyone_mask 00000000 | 9 | everyone_mask 00000000 |
10 | next_owner_mask 00082000 | 10 | next_owner_mask 00082000 |
11 | creator_id a52db6d0-e96c-4454-85e5-3523722daa25 | 11 | creator_id 11111111-1111-0000-0000-000100bba000 |
12 | owner_id a52db6d0-e96c-4454-85e5-3523722daa25 | 12 | owner_id 11111111-1111-0000-0000-000100bba000 |
13 | last_owner_id 00000000-0000-0000-0000-000000000000 | 13 | last_owner_id 00000000-0000-0000-0000-000000000000 |
14 | group_id 00000000-0000-0000-0000-000000000000 | 14 | group_id 00000000-0000-0000-0000-000000000000 |
15 | } | 15 | } |
@@ -19,7 +19,7 @@ New Hair | |||
19 | sale_price 10 | 19 | sale_price 10 |
20 | } | 20 | } |
21 | type 2 | 21 | type 2 |
22 | parameters 39 | 22 | parameters 90 |
23 | 16 0 | 23 | 16 0 |
24 | 31 .5 | 24 | 31 .5 |
25 | 112 0 | 25 | 112 0 |
@@ -38,26 +38,77 @@ parameters 39 | |||
38 | 140 0 | 38 | 140 0 |
39 | 141 0 | 39 | 141 0 |
40 | 142 0 | 40 | 142 0 |
41 | 143 .13 | 41 | 143 .12 |
42 | 144 .1 | ||
43 | 145 0 | ||
44 | 146 0 | ||
45 | 147 0 | ||
46 | 148 .22 | ||
47 | 149 0 | ||
42 | 166 0 | 48 | 166 0 |
43 | 167 0 | 49 | 167 0 |
44 | 168 0 | 50 | 168 0 |
45 | 169 0 | 51 | 169 0 |
52 | 171 0 | ||
53 | 172 .5 | ||
54 | 173 0 | ||
55 | 174 0 | ||
56 | 175 .3 | ||
57 | 176 0 | ||
46 | 177 0 | 58 | 177 0 |
59 | 178 0 | ||
60 | 179 0 | ||
61 | 180 .13 | ||
47 | 181 .14 | 62 | 181 .14 |
48 | 182 .7 | 63 | 182 .7 |
49 | 183 .05 | 64 | 183 .05 |
50 | 184 0 | 65 | 184 0 |
66 | 190 0 | ||
67 | 191 0 | ||
51 | 192 0 | 68 | 192 0 |
69 | 400 .75 | ||
70 | 640 0 | ||
71 | 641 0 | ||
72 | 642 0 | ||
73 | 643 0 | ||
74 | 644 0 | ||
75 | 645 0 | ||
52 | 674 -.3 | 76 | 674 -.3 |
53 | 750 .7 | 77 | 750 .7 |
78 | 751 0 | ||
54 | 752 .5 | 79 | 752 .5 |
55 | 754 0 | 80 | 754 0 |
56 | 755 .05 | 81 | 755 .05 |
57 | 757 -1 | 82 | 757 -1 |
83 | 761 0 | ||
58 | 762 0 | 84 | 762 0 |
59 | 763 .55 | 85 | 763 .55 |
86 | 771 0 | ||
87 | 774 0 | ||
88 | 782 0 | ||
89 | 783 0 | ||
90 | 784 0 | ||
60 | 785 0 | 91 | 785 0 |
92 | 786 0 | ||
93 | 787 0 | ||
94 | 788 0 | ||
61 | 789 0 | 95 | 789 0 |
96 | 790 0 | ||
97 | 870 -.29 | ||
98 | 871 0 | ||
99 | 872 .25 | ||
100 | 1000 .5 | ||
101 | 1001 .5 | ||
102 | 1002 .7 | ||
103 | 1003 .7 | ||
104 | 1004 0 | ||
105 | 1005 0 | ||
106 | 1006 0 | ||
107 | 1007 0 | ||
108 | 1008 0 | ||
109 | 1009 0 | ||
110 | 1010 0 | ||
111 | 1011 0 | ||
112 | 1012 .25 | ||
62 | textures 1 | 113 | textures 1 |
63 | 4 7ca39b4c-bd19-4699-aff7-f93fd03d3e7b | 114 | 4 7ca39b4c-bd19-4699-aff7-f93fd03d3e7b |
diff --git a/bin/assets/BodyPartsAssetSet/base_shape.dat b/bin/assets/BodyPartsAssetSet/base_shape.dat index d9a361f..bf719c9 100644 --- a/bin/assets/BodyPartsAssetSet/base_shape.dat +++ b/bin/assets/BodyPartsAssetSet/base_shape.dat | |||
@@ -1,105 +1,165 @@ | |||
1 | LLWearable version 22 | 1 | LLWearable version 22 |
2 | Female Shape and Outfit 3 Shape | 2 | New Shape |
3 | Created by system from avatar's appearance. | 3 | |
4 | permissions 0 | 4 | permissions 0 |
5 | { | 5 | { |
6 | base_mask 00000000 | 6 | base_mask 7fffffff |
7 | owner_mask 00000000 | 7 | owner_mask 7fffffff |
8 | group_mask 00000000 | 8 | group_mask 00000000 |
9 | everyone_mask 00000000 | 9 | everyone_mask 00000000 |
10 | next_owner_mask 00000000 | 10 | next_owner_mask 00082000 |
11 | creator_id 11111111-1111-0000-0000-000100bba000 | 11 | creator_id 11111111-1111-0000-0000-000100bba000 |
12 | owner_id 11111111-1111-0000-0000-000100bba000 | 12 | owner_id 11111111-1111-0000-0000-000100bba000 |
13 | last_owner_id 11111111-1111-0000-0000-000100bba000 | 13 | last_owner_id 00000000-0000-0000-0000-000000000000 |
14 | group_id 00000000-0000-0000-0000-000000000000 | 14 | group_id 00000000-0000-0000-0000-000000000000 |
15 | } | 15 | } |
16 | sale_info 0 | 16 | sale_info 0 |
17 | { | 17 | { |
18 | sale_type not | 18 | sale_type not |
19 | sale_price 0 | 19 | sale_price 10 |
20 | } | 20 | } |
21 | type 0 | 21 | type 0 |
22 | parameters 82 | 22 | parameters 142 |
23 | 1 .21 | 23 | 1 0 |
24 | 2 -.5 | 24 | 2 0 |
25 | 4 -.11 | 25 | 4 0 |
26 | 5 -.1 | 26 | 5 0 |
27 | 6 -.3 | 27 | 6 0 |
28 | 7 -.4 | 28 | 7 0 |
29 | 8 -.5 | 29 | 8 0 |
30 | 10 .7 | 30 | 10 0 |
31 | 11 .34 | 31 | 11 0 |
32 | 12 -.5 | 32 | 12 0 |
33 | 13 0 | 33 | 13 0 |
34 | 14 .04 | 34 | 14 0 |
35 | 15 .58 | 35 | 15 0 |
36 | 17 .56 | 36 | 17 0 |
37 | 18 -.26 | 37 | 18 0 |
38 | 19 -.73 | 38 | 19 0 |
39 | 20 -.34 | 39 | 20 0 |
40 | 21 -.01 | 40 | 21 0 |
41 | 22 1 | 41 | 22 0 |
42 | 23 -.5 | 42 | 23 0 |
43 | 24 -.63 | 43 | 24 0 |
44 | 25 .44 | 44 | 25 0 |
45 | 27 .05 | 45 | 26 0 |
46 | 33 -.24 | 46 | 27 0 |
47 | 34 -.7 | 47 | 28 0 |
48 | 35 -.16 | 48 | 29 .12 |
49 | 36 -.2 | 49 | 30 .12 |
50 | 37 -.98 | 50 | 32 0 |
51 | 38 -.5 | 51 | 33 0 |
52 | 34 0 | ||
53 | 35 0 | ||
54 | 36 -.5 | ||
55 | 37 0 | ||
56 | 38 0 | ||
57 | 40 0 | ||
52 | 80 0 | 58 | 80 0 |
53 | 105 .07 | 59 | 100 0 |
54 | 155 -.22 | 60 | 104 0 |
61 | 105 .5 | ||
62 | 106 0 | ||
63 | 151 0 | ||
64 | 152 0 | ||
65 | 153 0 | ||
66 | 155 0 | ||
67 | 156 0 | ||
55 | 157 0 | 68 | 157 0 |
56 | 185 -1 | 69 | 185 0 |
57 | 193 .86 | 70 | 186 0 |
58 | 196 -.74 | 71 | 187 0 |
59 | 505 .65 | 72 | 188 0 |
60 | 506 .12 | 73 | 189 0 |
61 | 507 -1.5 | 74 | 193 .5 |
75 | 194 .67 | ||
76 | 195 .33 | ||
77 | 196 0 | ||
78 | 505 .5 | ||
79 | 506 0 | ||
80 | 507 0 | ||
62 | 515 0 | 81 | 515 0 |
63 | 517 .16 | 82 | 517 0 |
64 | 518 .8 | 83 | 518 0 |
65 | 629 0 | 84 | 626 0 |
85 | 627 0 | ||
86 | 629 .5 | ||
87 | 630 0 | ||
88 | 631 0 | ||
89 | 633 0 | ||
90 | 634 0 | ||
91 | 635 0 | ||
66 | 637 0 | 92 | 637 0 |
67 | 646 .4 | 93 | 646 0 |
68 | 647 1 | 94 | 647 0 |
69 | 649 .36 | 95 | 648 0 |
70 | 650 .85 | 96 | 649 .5 |
71 | 652 .49 | 97 | 650 0 |
72 | 653 -1 | 98 | 651 0 |
99 | 652 .5 | ||
100 | 653 0 | ||
101 | 655 -.08 | ||
73 | 656 0 | 102 | 656 0 |
74 | 659 .65 | 103 | 657 0 |
104 | 658 0 | ||
105 | 659 .5 | ||
106 | 660 0 | ||
107 | 661 0 | ||
75 | 662 .5 | 108 | 662 .5 |
76 | 663 0 | 109 | 663 0 |
77 | 664 0 | 110 | 664 0 |
78 | 665 0 | 111 | 665 0 |
79 | 675 -.15 | 112 | 675 0 |
80 | 676 .26 | 113 | 676 0 |
81 | 678 .28 | 114 | 677 0 |
82 | 682 .27 | 115 | 678 .5 |
83 | 683 -.19 | 116 | 679 -.08 |
84 | 684 -.09 | 117 | 680 -.08 |
118 | 681 -.08 | ||
119 | 682 .5 | ||
120 | 683 -.15 | ||
121 | 684 0 | ||
85 | 685 0 | 122 | 685 0 |
86 | 690 .45 | 123 | 686 0 |
87 | 692 .4 | 124 | 687 0 |
88 | 693 -0 | 125 | 688 0 |
89 | 753 -.5 | 126 | 689 0 |
90 | 756 -.08 | 127 | 690 .5 |
91 | 758 .24 | 128 | 691 0 |
92 | 759 .6 | 129 | 692 0 |
93 | 760 .11 | 130 | 693 .6 |
94 | 764 -.38 | 131 | 694 -.08 |
95 | 765 -.3 | 132 | 695 0 |
96 | 769 .42 | 133 | 753 0 |
97 | 773 .51 | 134 | 756 0 |
98 | 795 .16 | 135 | 758 0 |
99 | 796 .11 | 136 | 759 .5 |
100 | 799 .36 | 137 | 760 0 |
138 | 764 0 | ||
139 | 765 0 | ||
140 | 767 0 | ||
141 | 768 0 | ||
142 | 769 .5 | ||
143 | 770 0 | ||
144 | 772 0 | ||
145 | 773 .5 | ||
146 | 794 .17 | ||
147 | 795 .25 | ||
148 | 796 0 | ||
149 | 797 0 | ||
150 | 798 0 | ||
151 | 799 .5 | ||
101 | 841 0 | 152 | 841 0 |
102 | 842 -.82 | 153 | 842 0 |
154 | 843 0 | ||
155 | 853 0 | ||
156 | 854 0 | ||
157 | 855 0 | ||
103 | 879 0 | 158 | 879 0 |
104 | 880 0 | 159 | 880 0 |
160 | 1103 0 | ||
161 | 1104 0 | ||
162 | 1105 0 | ||
163 | 1200 0 | ||
164 | 1201 0 | ||
105 | textures 0 | 165 | textures 0 |
diff --git a/bin/assets/TexturesAssetSet/TexturesAssetSet.xml b/bin/assets/TexturesAssetSet/TexturesAssetSet.xml index 3af9c99..ecf2005 100644 --- a/bin/assets/TexturesAssetSet/TexturesAssetSet.xml +++ b/bin/assets/TexturesAssetSet/TexturesAssetSet.xml | |||
@@ -430,6 +430,13 @@ | |||
430 | <Key Name="fileName" Value="default_avatar.jp2" /> | 430 | <Key Name="fileName" Value="default_avatar.jp2" /> |
431 | </Section> | 431 | </Section> |
432 | 432 | ||
433 | <Section Name="Default Iris"> | ||
434 | <Key Name="assetID" Value="6522e74d-1660-4e7f-b601-6f48c1659a77"/> | ||
435 | <Key Name="name" Value="Default Iris"/> | ||
436 | <Key Name="assetType" Value="0" /> | ||
437 | <Key Name="fileName" Value="default_iris.jp2" /> | ||
438 | </Section> | ||
439 | |||
433 | <Section Name="Cypress 1"> | 440 | <Section Name="Cypress 1"> |
434 | <Key Name="assetID" Value="fb2ae204-3fd1-df33-594f-c9f882830e66"/> | 441 | <Key Name="assetID" Value="fb2ae204-3fd1-df33-594f-c9f882830e66"/> |
435 | <Key Name="name" Value="Cypress 1"/> | 442 | <Key Name="name" Value="Cypress 1"/> |
diff --git a/bin/assets/TexturesAssetSet/default_iris.jp2 b/bin/assets/TexturesAssetSet/default_iris.jp2 new file mode 100644 index 0000000..b932a06 --- /dev/null +++ b/bin/assets/TexturesAssetSet/default_iris.jp2 | |||
Binary files differ | |||
diff --git a/bin/config-include/Standalone.ini b/bin/config-include/Standalone.ini index bf89d0b..6ad4ac9 100644 --- a/bin/config-include/Standalone.ini +++ b/bin/config-include/Standalone.ini | |||
@@ -17,12 +17,12 @@ | |||
17 | AvatarServices = "LocalAvatarServicesConnector" | 17 | AvatarServices = "LocalAvatarServicesConnector" |
18 | EntityTransferModule = "BasicEntityTransferModule" | 18 | EntityTransferModule = "BasicEntityTransferModule" |
19 | InventoryAccessModule = "BasicInventoryAccessModule" | 19 | InventoryAccessModule = "BasicInventoryAccessModule" |
20 | MapImageService = "MapImageServiceModule" | 20 | MapImageService = "MapImageServiceModule" |
21 | 21 | ||
22 | LibraryModule = true | 22 | LibraryModule = true |
23 | LLLoginServiceInConnector = true | 23 | LLLoginServiceInConnector = true |
24 | GridInfoServiceInConnector = true | 24 | GridInfoServiceInConnector = true |
25 | MapImageServiceInConnector = true | 25 | MapImageServiceInConnector = true |
26 | 26 | ||
27 | [Profile] | 27 | [Profile] |
28 | Module = "BasicProfileModule" | 28 | Module = "BasicProfileModule" |
@@ -70,6 +70,10 @@ | |||
70 | GridUserService = "OpenSim.Services.UserAccountService.dll:GridUserService" | 70 | GridUserService = "OpenSim.Services.UserAccountService.dll:GridUserService" |
71 | GridService = "OpenSim.Services.GridService.dll:GridService" | 71 | GridService = "OpenSim.Services.GridService.dll:GridService" |
72 | InventoryService = "OpenSim.Services.InventoryService.dll:XInventoryService" | 72 | InventoryService = "OpenSim.Services.InventoryService.dll:XInventoryService" |
73 | AvatarService = "OpenSim.Services.AvatarService.dll:AvatarService" | ||
74 | |||
75 | ;; This switch creates the minimum set of body parts and avatar entries for a viewer 2 to show a default "Ruth" avatar rather than a cloud. | ||
76 | CreateDefaultAvatarEntries = true | ||
73 | 77 | ||
74 | [GridUserService] | 78 | [GridUserService] |
75 | LocalServiceModule = "OpenSim.Services.UserAccountService.dll:GridUserService" | 79 | LocalServiceModule = "OpenSim.Services.UserAccountService.dll:GridUserService" |
diff --git a/bin/inventory/TexturesLibrary/TexturesLibraryItems.xml b/bin/inventory/TexturesLibrary/TexturesLibraryItems.xml index a018a0d..9b5080d 100644 --- a/bin/inventory/TexturesLibrary/TexturesLibraryItems.xml +++ b/bin/inventory/TexturesLibrary/TexturesLibraryItems.xml | |||
@@ -561,4 +561,14 @@ | |||
561 | <Key Name="assetType" Value="0" /> | 561 | <Key Name="assetType" Value="0" /> |
562 | <Key Name="inventoryType" Value="0" /> | 562 | <Key Name="inventoryType" Value="0" /> |
563 | </Section> | 563 | </Section> |
564 | |||
565 | <Section Name="Default Iris Texture"> | ||
566 | <Key Name="inventoryID" Value="00000000-0000-2222-9999-000000000013"/> | ||
567 | <Key Name="assetID" Value="6522e74d-1660-4e7f-b601-6f48c1659a77"/> | ||
568 | <Key Name="folderID" Value="00000112-000f-0000-0000-000100bba001"/> | ||
569 | <Key Name="description" Value=""/> | ||
570 | <Key Name="name" Value="Default Iris Texture" /> | ||
571 | <Key Name="assetType" Value="0" /> | ||
572 | <Key Name="inventoryType" Value="0" /> | ||
573 | </Section> | ||
564 | </Nini> | 574 | </Nini> |
diff --git a/prebuild.xml b/prebuild.xml index 392fbdc..690de5a 100644 --- a/prebuild.xml +++ b/prebuild.xml | |||
@@ -573,34 +573,6 @@ | |||
573 | </Files> | 573 | </Files> |
574 | </Project> | 574 | </Project> |
575 | 575 | ||
576 | <Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.BulletXPlugin" path="OpenSim/Region/Physics/BulletXPlugin" type="Library"> | ||
577 | <Configuration name="Debug"> | ||
578 | <Options> | ||
579 | <OutputPath>../../../../bin/Physics/</OutputPath> | ||
580 | </Options> | ||
581 | </Configuration> | ||
582 | <Configuration name="Release"> | ||
583 | <Options> | ||
584 | <OutputPath>../../../../bin/Physics/</OutputPath> | ||
585 | </Options> | ||
586 | </Configuration> | ||
587 | |||
588 | <ReferencePath>../../../../bin/</ReferencePath> | ||
589 | <Reference name="System"/> | ||
590 | <Reference name="OpenMetaverseTypes" path="../../../../bin/"/> | ||
591 | <Reference name="Nini" path="../../../../bin/"/> | ||
592 | <Reference name="OpenSim.Framework"/> | ||
593 | <Reference name="OpenSim.Framework.Console"/> | ||
594 | <Reference name="OpenSim.Region.Physics.Manager"/> | ||
595 | <Reference name="MonoXnaCompactMaths" path="../../../../bin/"/> | ||
596 | <Reference name="Modified.XnaDevRu.BulletX" path="../../../../bin/"/> | ||
597 | <Reference name="log4net" path="../../../../bin/"/> | ||
598 | |||
599 | <Files> | ||
600 | <Match pattern="*.cs" recurse="true"/> | ||
601 | </Files> | ||
602 | </Project> | ||
603 | |||
604 | <Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.ConvexDecompositionDotNet" path="OpenSim/Region/Physics/ConvexDecompositionDotNet" type="Library"> | 576 | <Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.ConvexDecompositionDotNet" path="OpenSim/Region/Physics/ConvexDecompositionDotNet" type="Library"> |
605 | <Configuration name="Debug"> | 577 | <Configuration name="Debug"> |
606 | <Options> | 578 | <Options> |
@@ -690,34 +662,6 @@ | |||
690 | </Files> | 662 | </Files> |
691 | </Project> | 663 | </Project> |
692 | 664 | ||
693 | <Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.BulletDotNETPlugin" path="OpenSim/Region/Physics/BulletDotNETPlugin" type="Library"> | ||
694 | <Configuration name="Debug"> | ||
695 | <Options> | ||
696 | <OutputPath>../../../../bin/Physics/</OutputPath> | ||
697 | </Options> | ||
698 | </Configuration> | ||
699 | <Configuration name="Release"> | ||
700 | <Options> | ||
701 | <OutputPath>../../../../bin/Physics/</OutputPath> | ||
702 | </Options> | ||
703 | </Configuration> | ||
704 | |||
705 | <ReferencePath>../../../../bin/</ReferencePath> | ||
706 | <Reference name="System"/> | ||
707 | <Reference name="OpenMetaverseTypes" path="../../../../bin/"/> | ||
708 | <Reference name="Nini" path="../../../../bin/"/> | ||
709 | <Reference name="OpenSim.Framework"/> | ||
710 | <Reference name="OpenSim.Framework.Console"/> | ||
711 | <Reference name="OpenSim.Region.Physics.Manager"/> | ||
712 | <Reference name="BulletDotNET" path="../../../../bin/"/> | ||
713 | <Reference name="nunit.framework" path="../../../../bin/"/> | ||
714 | <Reference name="log4net" path="../../../../bin/"/> | ||
715 | |||
716 | <Files> | ||
717 | <Match pattern="*.cs" recurse="true"/> | ||
718 | </Files> | ||
719 | </Project> | ||
720 | |||
721 | <Project frameworkVersion="v3_5" name="OpenSim.Capabilities" path="OpenSim/Capabilities" type="Library"> | 665 | <Project frameworkVersion="v3_5" name="OpenSim.Capabilities" path="OpenSim/Capabilities" type="Library"> |
722 | <Configuration name="Debug"> | 666 | <Configuration name="Debug"> |
723 | <Options> | 667 | <Options> |
@@ -1840,6 +1784,9 @@ | |||
1840 | <Reference name="OpenSim.Region.ClientStack"/> | 1784 | <Reference name="OpenSim.Region.ClientStack"/> |
1841 | <Reference name="OpenSim.Framework.Communications"/> | 1785 | <Reference name="OpenSim.Framework.Communications"/> |
1842 | <Reference name="OpenSim.Server.Base"/> | 1786 | <Reference name="OpenSim.Server.Base"/> |
1787 | <Reference name="OpenSim.Services.Base"/> | ||
1788 | <Reference name="OpenSim.Services.Interfaces"/> | ||
1789 | <Reference name="OpenSim.Services.UserAccountService"/> | ||
1843 | <Reference name="XMLRPC" path="../../../bin/"/> | 1790 | <Reference name="XMLRPC" path="../../../bin/"/> |
1844 | <Reference name="Nini" path="../../../bin/"/> | 1791 | <Reference name="Nini" path="../../../bin/"/> |
1845 | <Reference name="log4net" path="../../../bin/"/> | 1792 | <Reference name="log4net" path="../../../bin/"/> |