diff options
Diffstat (limited to '')
23 files changed, 477 insertions, 91 deletions
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index f520a01..0852b49 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs | |||
@@ -2148,7 +2148,7 @@ namespace OpenSim.Framework | |||
2148 | /// <param name="secret">the secret part</param> | 2148 | /// <param name="secret">the secret part</param> |
2149 | public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret) | 2149 | public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret) |
2150 | { | 2150 | { |
2151 | uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; secret = string.Empty; | 2151 | uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "UserUPUUI"; secret = string.Empty; |
2152 | 2152 | ||
2153 | string[] parts = value.Split(';'); | 2153 | string[] parts = value.Split(';'); |
2154 | if (parts.Length >= 1) | 2154 | if (parts.Length >= 1) |
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 8056030..4613344 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs | |||
@@ -371,7 +371,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
371 | foreach (string fid in outstanding) | 371 | foreach (string fid in outstanding) |
372 | { | 372 | { |
373 | UUID fromAgentID; | 373 | UUID fromAgentID; |
374 | string firstname = "Unknown", lastname = "User"; | 374 | string firstname = "Unknown", lastname = "UserFMSFOIN"; |
375 | if (!GetAgentInfo(client.Scene.RegionInfo.ScopeID, fid, out fromAgentID, out firstname, out lastname)) | 375 | if (!GetAgentInfo(client.Scene.RegionInfo.ScopeID, fid, out fromAgentID, out firstname, out lastname)) |
376 | { | 376 | { |
377 | m_log.DebugFormat("[FRIENDS MODULE]: skipping malformed friend {0}", fid); | 377 | m_log.DebugFormat("[FRIENDS MODULE]: skipping malformed friend {0}", fid); |
@@ -397,7 +397,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
397 | 397 | ||
398 | protected virtual bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) | 398 | protected virtual bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) |
399 | { | 399 | { |
400 | first = "Unknown"; last = "User"; | 400 | first = "Unknown"; last = "UserFMGAI"; |
401 | if (!UUID.TryParse(fid, out agentID)) | 401 | if (!UUID.TryParse(fid, out agentID)) |
402 | return false; | 402 | return false; |
403 | 403 | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index bf5c0bb..b3e3aa2 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs | |||
@@ -293,7 +293,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
293 | 293 | ||
294 | protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) | 294 | protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) |
295 | { | 295 | { |
296 | first = "Unknown"; last = "User"; | 296 | first = "Unknown"; last = "UserHGGAI"; |
297 | if (base.GetAgentInfo(scopeID, fid, out agentID, out first, out last)) | 297 | if (base.GetAgentInfo(scopeID, fid, out agentID, out first, out last)) |
298 | return true; | 298 | return true; |
299 | 299 | ||
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index 6847e57..a720d7b 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs | |||
@@ -157,13 +157,16 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
157 | } | 157 | } |
158 | else | 158 | else |
159 | { | 159 | { |
160 | string[] names = GetUserNames(uuid); | 160 | string[] names; |
161 | bool foundRealName = TryGetUserNames(uuid, out names); | ||
162 | |||
161 | if (names.Length == 2) | 163 | if (names.Length == 2) |
162 | { | 164 | { |
163 | //m_log.DebugFormat("[XXX] HandleUUIDNameRequest {0} is {1} {2}", uuid, names[0], names[1]); | 165 | if (!foundRealName) |
166 | m_log.DebugFormat("[USER MANAGEMENT MODULE]: Sending {0} {1} for {2} to {3} since no bound name found", names[0], names[1], uuid, remote_client.Name); | ||
167 | |||
164 | remote_client.SendNameReply(uuid, names[0], names[1]); | 168 | remote_client.SendNameReply(uuid, names[0], names[1]); |
165 | } | 169 | } |
166 | |||
167 | } | 170 | } |
168 | } | 171 | } |
169 | 172 | ||
@@ -246,10 +249,15 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
246 | } | 249 | } |
247 | 250 | ||
248 | // search the local cache | 251 | // search the local cache |
249 | foreach (UserData data in m_UserCache.Values) | 252 | lock (m_UserCache) |
250 | if (users.Find(delegate(UserData d) { return d.Id == data.Id; }) == null && | 253 | { |
251 | (data.FirstName.ToLower().StartsWith(query.ToLower()) || data.LastName.ToLower().StartsWith(query.ToLower()))) | 254 | foreach (UserData data in m_UserCache.Values) |
252 | users.Add(data); | 255 | { |
256 | if (users.Find(delegate(UserData d) { return d.Id == data.Id; }) == null && | ||
257 | (data.FirstName.ToLower().StartsWith(query.ToLower()) || data.LastName.ToLower().StartsWith(query.ToLower()))) | ||
258 | users.Add(data); | ||
259 | } | ||
260 | } | ||
253 | 261 | ||
254 | AddAdditionalUsers(query, users); | 262 | AddAdditionalUsers(query, users); |
255 | 263 | ||
@@ -272,17 +280,24 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
272 | } | 280 | } |
273 | } | 281 | } |
274 | 282 | ||
275 | private string[] GetUserNames(UUID uuid) | 283 | /// <summary> |
284 | /// Try to get the names bound to the given uuid. | ||
285 | /// </summary> | ||
286 | /// <returns>True if the name was found, false if not.</returns> | ||
287 | /// <param name='uuid'></param> | ||
288 | /// <param name='names'>The array of names if found. If not found, then names[0] = "Unknown" and names[1] = "User"</param> | ||
289 | private bool TryGetUserNames(UUID uuid, out string[] names) | ||
276 | { | 290 | { |
277 | string[] returnstring = new string[2]; | 291 | names = new string[2]; |
278 | 292 | ||
279 | lock (m_UserCache) | 293 | lock (m_UserCache) |
280 | { | 294 | { |
281 | if (m_UserCache.ContainsKey(uuid)) | 295 | if (m_UserCache.ContainsKey(uuid)) |
282 | { | 296 | { |
283 | returnstring[0] = m_UserCache[uuid].FirstName; | 297 | names[0] = m_UserCache[uuid].FirstName; |
284 | returnstring[1] = m_UserCache[uuid].LastName; | 298 | names[1] = m_UserCache[uuid].LastName; |
285 | return returnstring; | 299 | |
300 | return true; | ||
286 | } | 301 | } |
287 | } | 302 | } |
288 | 303 | ||
@@ -290,8 +305,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
290 | 305 | ||
291 | if (account != null) | 306 | if (account != null) |
292 | { | 307 | { |
293 | returnstring[0] = account.FirstName; | 308 | names[0] = account.FirstName; |
294 | returnstring[1] = account.LastName; | 309 | names[1] = account.LastName; |
295 | 310 | ||
296 | UserData user = new UserData(); | 311 | UserData user = new UserData(); |
297 | user.FirstName = account.FirstName; | 312 | user.FirstName = account.FirstName; |
@@ -299,14 +314,16 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
299 | 314 | ||
300 | lock (m_UserCache) | 315 | lock (m_UserCache) |
301 | m_UserCache[uuid] = user; | 316 | m_UserCache[uuid] = user; |
317 | |||
318 | return true; | ||
302 | } | 319 | } |
303 | else | 320 | else |
304 | { | 321 | { |
305 | returnstring[0] = "Unknown"; | 322 | names[0] = "Unknown"; |
306 | returnstring[1] = "User"; | 323 | names[1] = "UserUMMTGUN"; |
307 | } | ||
308 | 324 | ||
309 | return returnstring; | 325 | return false; |
326 | } | ||
310 | } | 327 | } |
311 | 328 | ||
312 | #region IUserManagement | 329 | #region IUserManagement |
@@ -342,15 +359,17 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
342 | 359 | ||
343 | public string GetUserName(UUID uuid) | 360 | public string GetUserName(UUID uuid) |
344 | { | 361 | { |
345 | string[] names = GetUserNames(uuid); | 362 | string[] names; |
363 | TryGetUserNames(uuid, out names); | ||
364 | |||
346 | if (names.Length == 2) | 365 | if (names.Length == 2) |
347 | { | 366 | { |
348 | string firstname = names[0]; | 367 | string firstname = names[0]; |
349 | string lastname = names[1]; | 368 | string lastname = names[1]; |
350 | 369 | ||
351 | return firstname + " " + lastname; | 370 | return firstname + " " + lastname; |
352 | |||
353 | } | 371 | } |
372 | |||
354 | return "(hippos)"; | 373 | return "(hippos)"; |
355 | } | 374 | } |
356 | 375 | ||
@@ -466,12 +485,13 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
466 | //ignore updates without creator data | 485 | //ignore updates without creator data |
467 | return; | 486 | return; |
468 | } | 487 | } |
488 | |||
469 | //try update unknown users | 489 | //try update unknown users |
470 | //and creator's home URL's | 490 | //and creator's home URL's |
471 | if ((oldUser.FirstName == "Unknown" && !creatorData.Contains ("Unknown")) || (oldUser.HomeURL != null && !creatorData.StartsWith (oldUser.HomeURL))) | 491 | if ((oldUser.FirstName == "Unknown" && !creatorData.Contains ("Unknown")) || (oldUser.HomeURL != null && !creatorData.StartsWith (oldUser.HomeURL))) |
472 | { | 492 | { |
473 | m_UserCache.Remove (id); | 493 | m_UserCache.Remove (id); |
474 | // m_log.DebugFormat("[USER MANAGEMENT MODULE]: Re-adding user with id {0}, creatorData [{1}] and old HomeURL {2}", id, creatorData,oldUser.HomeURL); | 494 | m_log.DebugFormat("[USER MANAGEMENT MODULE]: Re-adding user with id {0}, creatorData [{1}] and old HomeURL {2}", id, creatorData, oldUser.HomeURL); |
475 | } | 495 | } |
476 | else | 496 | else |
477 | { | 497 | { |
@@ -516,7 +536,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
516 | else | 536 | else |
517 | { | 537 | { |
518 | user.FirstName = "Unknown"; | 538 | user.FirstName = "Unknown"; |
519 | user.LastName = "User"; | 539 | user.LastName = "UserUMMAU"; |
520 | } | 540 | } |
521 | 541 | ||
522 | AddUserInternal (user); | 542 | AddUserInternal (user); |
@@ -548,6 +568,13 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
548 | protected void RegisterConsoleCmds() | 568 | protected void RegisterConsoleCmds() |
549 | { | 569 | { |
550 | MainConsole.Instance.Commands.AddCommand("Users", true, | 570 | MainConsole.Instance.Commands.AddCommand("Users", true, |
571 | "show name", | ||
572 | "show name <uuid>", | ||
573 | "Show the bindings between a single user UUID and a user name", | ||
574 | String.Empty, | ||
575 | HandleShowUser); | ||
576 | |||
577 | MainConsole.Instance.Commands.AddCommand("Users", true, | ||
551 | "show names", | 578 | "show names", |
552 | "show names", | 579 | "show names", |
553 | "Show the bindings between user UUIDs and user names", | 580 | "Show the bindings between user UUIDs and user names", |
@@ -555,26 +582,54 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
555 | HandleShowUsers); | 582 | HandleShowUsers); |
556 | } | 583 | } |
557 | 584 | ||
558 | private void HandleShowUsers(string module, string[] cmd) | 585 | private void HandleShowUser(string module, string[] cmd) |
559 | { | 586 | { |
587 | if (cmd.Length < 3) | ||
588 | { | ||
589 | MainConsole.Instance.OutputFormat("Usage: show name <uuid>"); | ||
590 | return; | ||
591 | } | ||
592 | |||
593 | UUID userId; | ||
594 | if (!ConsoleUtil.TryParseConsoleUuid(MainConsole.Instance, cmd[2], out userId)) | ||
595 | return; | ||
596 | |||
597 | string[] names; | ||
598 | |||
599 | UserData ud; | ||
600 | |||
560 | lock (m_UserCache) | 601 | lock (m_UserCache) |
561 | { | 602 | { |
562 | if (m_UserCache.Count == 0) | 603 | if (!m_UserCache.TryGetValue(userId, out ud)) |
563 | { | 604 | { |
564 | MainConsole.Instance.Output("No users found"); | 605 | MainConsole.Instance.OutputFormat("No name known for user with id {0}", userId); |
565 | return; | 606 | return; |
566 | } | 607 | } |
567 | 608 | } | |
568 | MainConsole.Instance.Output("UUID User Name"); | 609 | |
569 | MainConsole.Instance.Output("-----------------------------------------------------------------------------"); | 610 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); |
611 | cdt.AddColumn("UUID", 36); | ||
612 | cdt.AddColumn("Name", 30); | ||
613 | cdt.AddColumn("HomeURL", 40); | ||
614 | cdt.AddRow(userId, string.Format("{0} {1}", ud.FirstName, ud.LastName), ud.HomeURL); | ||
615 | |||
616 | MainConsole.Instance.Output(cdt.ToString()); | ||
617 | } | ||
618 | |||
619 | private void HandleShowUsers(string module, string[] cmd) | ||
620 | { | ||
621 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); | ||
622 | cdt.AddColumn("UUID", 36); | ||
623 | cdt.AddColumn("Name", 30); | ||
624 | cdt.AddColumn("HomeURL", 40); | ||
625 | |||
626 | lock (m_UserCache) | ||
627 | { | ||
570 | foreach (KeyValuePair<UUID, UserData> kvp in m_UserCache) | 628 | foreach (KeyValuePair<UUID, UserData> kvp in m_UserCache) |
571 | { | 629 | cdt.AddRow(kvp.Key, string.Format("{0} {1}", kvp.Value.FirstName, kvp.Value.LastName), kvp.Value.HomeURL); |
572 | MainConsole.Instance.Output(String.Format("{0} {1} {2} ({3})", | ||
573 | kvp.Key, kvp.Value.FirstName, kvp.Value.LastName, kvp.Value.HomeURL)); | ||
574 | } | ||
575 | |||
576 | return; | ||
577 | } | 630 | } |
631 | |||
632 | MainConsole.Instance.Output(cdt.ToString()); | ||
578 | } | 633 | } |
579 | } | 634 | } |
580 | } \ No newline at end of file | 635 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs index 883045a..d093224 100644 --- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs +++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs | |||
@@ -369,6 +369,15 @@ namespace OpenSim.Region.CoreModules.World.Sound | |||
369 | }); | 369 | }); |
370 | } | 370 | } |
371 | 371 | ||
372 | public void SetSoundQueueing(UUID objectID, bool shouldQueue) | ||
373 | { | ||
374 | SceneObjectPart part; | ||
375 | if (!m_scene.TryGetSceneObjectPart(objectID, out part)) | ||
376 | return; | ||
377 | |||
378 | part.SoundQueueing = shouldQueue; | ||
379 | } | ||
380 | |||
372 | #endregion | 381 | #endregion |
373 | } | 382 | } |
374 | } | 383 | } |
diff --git a/OpenSim/Region/Framework/Interfaces/ISoundModule.cs b/OpenSim/Region/Framework/Interfaces/ISoundModule.cs index 68af492..8372ddd 100644 --- a/OpenSim/Region/Framework/Interfaces/ISoundModule.cs +++ b/OpenSim/Region/Framework/Interfaces/ISoundModule.cs | |||
@@ -104,7 +104,6 @@ namespace OpenSim.Region.Framework.Interfaces | |||
104 | /// <param name="sound">Sound asset ID</param> | 104 | /// <param name="sound">Sound asset ID</param> |
105 | /// <param name="volume">Sound volume</param> | 105 | /// <param name="volume">Sound volume</param> |
106 | /// <param name="triggered">Triggered or not.</param> | 106 | /// <param name="triggered">Triggered or not.</param> |
107 | /// <param name="flags"></param> | ||
108 | /// <param name="radius">Sound radius</param> | 107 | /// <param name="radius">Sound radius</param> |
109 | /// <param name="useMaster">Play using sound master</param> | 108 | /// <param name="useMaster">Play using sound master</param> |
110 | /// <param name="isMaster">Play as sound master</param> | 109 | /// <param name="isMaster">Play as sound master</param> |
@@ -123,5 +122,12 @@ namespace OpenSim.Region.Framework.Interfaces | |||
123 | /// <param name="max">AABB top north-east corner</param> | 122 | /// <param name="max">AABB top north-east corner</param> |
124 | void TriggerSoundLimited(UUID objectID, UUID sound, double volume, | 123 | void TriggerSoundLimited(UUID objectID, UUID sound, double volume, |
125 | Vector3 min, Vector3 max); | 124 | Vector3 min, Vector3 max); |
125 | |||
126 | /// <summary> | ||
127 | /// Set whether sounds on the given prim should be queued. | ||
128 | /// </summary> | ||
129 | /// <param name='objectID'></param> | ||
130 | /// <param name='shouldQueue'></param> | ||
131 | void SetSoundQueueing(UUID objectID, bool shouldQueue); | ||
126 | } | 132 | } |
127 | } \ No newline at end of file | 133 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 9e644aa..2b5a6f9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -231,6 +231,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
231 | 231 | ||
232 | public double SoundRadius; | 232 | public double SoundRadius; |
233 | 233 | ||
234 | /// <summary> | ||
235 | /// Should sounds played from this prim be queued? | ||
236 | /// </summary> | ||
237 | /// <remarks> | ||
238 | /// This should only be changed by sound modules. It is up to sound modules as to how they interpret this setting. | ||
239 | /// </remarks> | ||
240 | public bool SoundQueueing { get; set; } | ||
234 | 241 | ||
235 | public uint TimeStampFull; | 242 | public uint TimeStampFull; |
236 | 243 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs index 231f0f8..12a0c17 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | |||
@@ -251,6 +251,16 @@ public override BulletShape CreateMeshShape(BulletWorld world, | |||
251 | BSPhysicsShapeType.SHAPE_MESH); | 251 | BSPhysicsShapeType.SHAPE_MESH); |
252 | } | 252 | } |
253 | 253 | ||
254 | public override BulletShape CreateGImpactShape(BulletWorld world, | ||
255 | int indicesCount, int[] indices, | ||
256 | int verticesCount, float[] vertices) | ||
257 | { | ||
258 | BulletWorldUnman worldu = world as BulletWorldUnman; | ||
259 | return new BulletShapeUnman( | ||
260 | BSAPICPP.CreateGImpactShape2(worldu.ptr, indicesCount, indices, verticesCount, vertices), | ||
261 | BSPhysicsShapeType.SHAPE_GIMPACT); | ||
262 | } | ||
263 | |||
254 | public override BulletShape CreateHullShape(BulletWorld world, int hullCount, float[] hulls) | 264 | public override BulletShape CreateHullShape(BulletWorld world, int hullCount, float[] hulls) |
255 | { | 265 | { |
256 | BulletWorldUnman worldu = world as BulletWorldUnman; | 266 | BulletWorldUnman worldu = world as BulletWorldUnman; |
@@ -1426,6 +1436,11 @@ public static extern IntPtr CreateMeshShape2(IntPtr world, | |||
1426 | int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices ); | 1436 | int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices ); |
1427 | 1437 | ||
1428 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 1438 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
1439 | public static extern IntPtr CreateGImpactShape2(IntPtr world, | ||
1440 | int indicesCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices, | ||
1441 | int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices ); | ||
1442 | |||
1443 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||
1429 | public static extern IntPtr CreateHullShape2(IntPtr world, | 1444 | public static extern IntPtr CreateHullShape2(IntPtr world, |
1430 | int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls); | 1445 | int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls); |
1431 | 1446 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs index 59780ae..6db5f5e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs | |||
@@ -1475,7 +1475,7 @@ private sealed class BulletConstraintXNA : BulletConstraint | |||
1475 | ret = BSPhysicsShapeType.SHAPE_UNKNOWN; | 1475 | ret = BSPhysicsShapeType.SHAPE_UNKNOWN; |
1476 | break; | 1476 | break; |
1477 | case BroadphaseNativeTypes.CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE: | 1477 | case BroadphaseNativeTypes.CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE: |
1478 | ret = BSPhysicsShapeType.SHAPE_MESH; | 1478 | ret = BSPhysicsShapeType.SHAPE_CONVEXHULL; |
1479 | break; | 1479 | break; |
1480 | case BroadphaseNativeTypes.CONVEX_HULL_SHAPE_PROXYTYPE: | 1480 | case BroadphaseNativeTypes.CONVEX_HULL_SHAPE_PROXYTYPE: |
1481 | ret = BSPhysicsShapeType.SHAPE_HULL; | 1481 | ret = BSPhysicsShapeType.SHAPE_HULL; |
@@ -1503,7 +1503,7 @@ private sealed class BulletConstraintXNA : BulletConstraint | |||
1503 | ret = BSPhysicsShapeType.SHAPE_CONE; | 1503 | ret = BSPhysicsShapeType.SHAPE_CONE; |
1504 | break; | 1504 | break; |
1505 | case BroadphaseNativeTypes.CONVEX_SHAPE_PROXYTYPE: | 1505 | case BroadphaseNativeTypes.CONVEX_SHAPE_PROXYTYPE: |
1506 | ret = BSPhysicsShapeType.SHAPE_UNKNOWN; | 1506 | ret = BSPhysicsShapeType.SHAPE_CONVEXHULL; |
1507 | break; | 1507 | break; |
1508 | case BroadphaseNativeTypes.CYLINDER_SHAPE_PROXYTYPE: | 1508 | case BroadphaseNativeTypes.CYLINDER_SHAPE_PROXYTYPE: |
1509 | ret = BSPhysicsShapeType.SHAPE_CYLINDER; | 1509 | ret = BSPhysicsShapeType.SHAPE_CYLINDER; |
@@ -1547,7 +1547,7 @@ private sealed class BulletConstraintXNA : BulletConstraint | |||
1547 | break; | 1547 | break; |
1548 | ///Used for GIMPACT Trimesh integration | 1548 | ///Used for GIMPACT Trimesh integration |
1549 | case BroadphaseNativeTypes.GIMPACT_SHAPE_PROXYTYPE: | 1549 | case BroadphaseNativeTypes.GIMPACT_SHAPE_PROXYTYPE: |
1550 | ret = BSPhysicsShapeType.SHAPE_MESH; | 1550 | ret = BSPhysicsShapeType.SHAPE_GIMPACT; |
1551 | break; | 1551 | break; |
1552 | ///Multimaterial mesh | 1552 | ///Multimaterial mesh |
1553 | case BroadphaseNativeTypes.MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE: | 1553 | case BroadphaseNativeTypes.MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE: |
@@ -1820,6 +1820,11 @@ private sealed class BulletConstraintXNA : BulletConstraint | |||
1820 | return new BulletShapeXNA(meshShape, BSPhysicsShapeType.SHAPE_MESH); | 1820 | return new BulletShapeXNA(meshShape, BSPhysicsShapeType.SHAPE_MESH); |
1821 | 1821 | ||
1822 | } | 1822 | } |
1823 | public override BulletShape CreateGImpactShape(BulletWorld pWorld, int pIndicesCount, int[] indices, int pVerticesCount, float[] verticesAsFloats) | ||
1824 | { | ||
1825 | // TODO: | ||
1826 | return null; | ||
1827 | } | ||
1823 | public static void DumpRaw(ObjectArray<int>indices, ObjectArray<float> vertices, int pIndicesCount,int pVerticesCount ) | 1828 | public static void DumpRaw(ObjectArray<int>indices, ObjectArray<float> vertices, int pIndicesCount,int pVerticesCount ) |
1824 | { | 1829 | { |
1825 | 1830 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index 3378c93..6cdc112 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs | |||
@@ -71,6 +71,7 @@ public enum BSPhysicsShapeType | |||
71 | SHAPE_HEIGHTMAP = 23, | 71 | SHAPE_HEIGHTMAP = 23, |
72 | SHAPE_AVATAR = 24, | 72 | SHAPE_AVATAR = 24, |
73 | SHAPE_CONVEXHULL= 25, | 73 | SHAPE_CONVEXHULL= 25, |
74 | SHAPE_GIMPACT = 26, | ||
74 | }; | 75 | }; |
75 | 76 | ||
76 | // The native shapes have predefined shape hash keys | 77 | // The native shapes have predefined shape hash keys |
@@ -321,6 +322,10 @@ public abstract BulletShape CreateMeshShape(BulletWorld world, | |||
321 | int indicesCount, int[] indices, | 322 | int indicesCount, int[] indices, |
322 | int verticesCount, float[] vertices ); | 323 | int verticesCount, float[] vertices ); |
323 | 324 | ||
325 | public abstract BulletShape CreateGImpactShape(BulletWorld world, | ||
326 | int indicesCount, int[] indices, | ||
327 | int verticesCount, float[] vertices ); | ||
328 | |||
324 | public abstract BulletShape CreateHullShape(BulletWorld world, | 329 | public abstract BulletShape CreateHullShape(BulletWorld world, |
325 | int hullCount, float[] hulls); | 330 | int hullCount, float[] hulls); |
326 | 331 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index ff5b6ab..48f842e 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | |||
@@ -483,8 +483,15 @@ public sealed class BSCharacter : BSPhysObject | |||
483 | { | 483 | { |
484 | // Bullet assumes we know what we are doing when forcing orientation | 484 | // Bullet assumes we know what we are doing when forcing orientation |
485 | // so it lets us go against all the rules and just compensates for them later. | 485 | // so it lets us go against all the rules and just compensates for them later. |
486 | // This keeps us from flipping the capsule over which the veiwer does not understand. | 486 | // This forces rotation to be only around the Z axis and doesn't change any of the other axis. |
487 | ForceOrientation = new OMV.Quaternion(0, 0, _orientation.Z,0); | 487 | // This keeps us from flipping the capsule over which the veiwer does not understand. |
488 | float oRoll, oPitch, oYaw; | ||
489 | _orientation.GetEulerAngles(out oRoll, out oPitch, out oYaw); | ||
490 | OMV.Quaternion trimmedOrientation = OMV.Quaternion.CreateFromEulers(0f, 0f, oYaw); | ||
491 | // DetailLog("{0},BSCharacter.setOrientation,taint,val={1},valDir={2},conv={3},convDir={4}", | ||
492 | // LocalID, _orientation, OMV.Vector3.UnitX * _orientation, | ||
493 | // trimmedOrientation, OMV.Vector3.UnitX * trimmedOrientation); | ||
494 | ForceOrientation = trimmedOrientation; | ||
488 | }); | 495 | }); |
489 | } | 496 | } |
490 | } | 497 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index d33292f..5cff668 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | |||
@@ -89,6 +89,8 @@ public static class BSParam | |||
89 | public static bool ShouldRemoveZeroWidthTriangles { get; private set; } | 89 | public static bool ShouldRemoveZeroWidthTriangles { get; private set; } |
90 | public static bool ShouldUseBulletHACD { get; set; } | 90 | public static bool ShouldUseBulletHACD { get; set; } |
91 | public static bool ShouldUseSingleConvexHullForPrims { get; set; } | 91 | public static bool ShouldUseSingleConvexHullForPrims { get; set; } |
92 | public static bool ShouldUseGImpactShapeForPrims { get; set; } | ||
93 | public static bool ShouldUseAssetHulls { get; set; } | ||
92 | 94 | ||
93 | public static float TerrainImplementation { get; set; } | 95 | public static float TerrainImplementation { get; set; } |
94 | public static int TerrainMeshMagnification { get; private set; } | 96 | public static int TerrainMeshMagnification { get; private set; } |
@@ -369,6 +371,10 @@ public static class BSParam | |||
369 | false ), | 371 | false ), |
370 | new ParameterDefn<bool>("ShouldUseSingleConvexHullForPrims", "If true, use a single convex hull shape for physical prims", | 372 | new ParameterDefn<bool>("ShouldUseSingleConvexHullForPrims", "If true, use a single convex hull shape for physical prims", |
371 | true ), | 373 | true ), |
374 | new ParameterDefn<bool>("ShouldUseGImpactShapeForPrims", "If true, use a GImpact shape for prims with cuts and twists", | ||
375 | false ), | ||
376 | new ParameterDefn<bool>("UseAssetHulls", "If true, use hull if specified in the mesh asset info", | ||
377 | false ), | ||
372 | 378 | ||
373 | new ParameterDefn<int>("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions", | 379 | new ParameterDefn<int>("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions", |
374 | 5 ), | 380 | 5 ), |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 3f407ce..39f5b0a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | |||
@@ -268,6 +268,12 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
268 | // Do any replacements in the parameters | 268 | // Do any replacements in the parameters |
269 | m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName); | 269 | m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName); |
270 | } | 270 | } |
271 | else | ||
272 | { | ||
273 | BulletEngineName = "BulletUnmanaged"; | ||
274 | m_physicsLoggingEnabled = false; | ||
275 | VehicleLoggingEnabled = false; | ||
276 | } | ||
271 | 277 | ||
272 | // The material characteristics. | 278 | // The material characteristics. |
273 | BSMaterials.InitializeFromDefaults(Params); | 279 | BSMaterials.InitializeFromDefaults(Params); |
@@ -322,6 +328,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
322 | BSParam.ShouldUseBulletHACD = false; | 328 | BSParam.ShouldUseBulletHACD = false; |
323 | m_log.InfoFormat("{0} Disabling ShouldUseSingleConvexHullForPrims", LogHeader); | 329 | m_log.InfoFormat("{0} Disabling ShouldUseSingleConvexHullForPrims", LogHeader); |
324 | BSParam.ShouldUseSingleConvexHullForPrims = false; | 330 | BSParam.ShouldUseSingleConvexHullForPrims = false; |
331 | m_log.InfoFormat("{0} Disabling ShouldUseGImpactShapeForPrims", LogHeader); | ||
332 | BSParam.ShouldUseGImpactShapeForPrims = false; | ||
325 | m_log.InfoFormat("{0} Setting terrain implimentation to Heightmap", LogHeader); | 333 | m_log.InfoFormat("{0} Setting terrain implimentation to Heightmap", LogHeader); |
326 | BSParam.TerrainImplementation = (float)BSTerrainPhys.TerrainImplementation.Heightmap; | 334 | BSParam.TerrainImplementation = (float)BSTerrainPhys.TerrainImplementation.Heightmap; |
327 | break; | 335 | break; |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 64aaa15..32bbc8f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | |||
@@ -230,6 +230,7 @@ public sealed class BSShapeCollection : IDisposable | |||
230 | BSShape potentialHull = null; | 230 | BSShape potentialHull = null; |
231 | 231 | ||
232 | PrimitiveBaseShape pbs = prim.BaseShape; | 232 | PrimitiveBaseShape pbs = prim.BaseShape; |
233 | // Use a simple, one section convex shape for prims that are probably convex (no cuts or twists) | ||
233 | if (BSParam.ShouldUseSingleConvexHullForPrims | 234 | if (BSParam.ShouldUseSingleConvexHullForPrims |
234 | && pbs != null | 235 | && pbs != null |
235 | && !pbs.SculptEntry | 236 | && !pbs.SculptEntry |
@@ -238,7 +239,17 @@ public sealed class BSShapeCollection : IDisposable | |||
238 | { | 239 | { |
239 | potentialHull = BSShapeConvexHull.GetReference(m_physicsScene, false /* forceRebuild */, prim); | 240 | potentialHull = BSShapeConvexHull.GetReference(m_physicsScene, false /* forceRebuild */, prim); |
240 | } | 241 | } |
241 | else | 242 | // Use the GImpact shape if it is a prim that has some concaveness |
243 | if (potentialHull == null | ||
244 | && BSParam.ShouldUseGImpactShapeForPrims | ||
245 | && pbs != null | ||
246 | && !pbs.SculptEntry | ||
247 | ) | ||
248 | { | ||
249 | potentialHull = BSShapeGImpact.GetReference(m_physicsScene, false /* forceRebuild */, prim); | ||
250 | } | ||
251 | // If not any of the simple cases, just make a hull | ||
252 | if (potentialHull == null) | ||
242 | { | 253 | { |
243 | potentialHull = BSShapeHull.GetReference(m_physicsScene, false /*forceRebuild*/, prim); | 254 | potentialHull = BSShapeHull.GetReference(m_physicsScene, false /*forceRebuild*/, prim); |
244 | } | 255 | } |
@@ -261,7 +272,7 @@ public sealed class BSShapeCollection : IDisposable | |||
261 | } | 272 | } |
262 | else | 273 | else |
263 | { | 274 | { |
264 | // Update prim.BSShape to reference a mesh of this shape. | 275 | // Non-physical objects should be just meshes. |
265 | BSShape potentialMesh = BSShapeMesh.GetReference(m_physicsScene, false /*forceRebuild*/, prim); | 276 | BSShape potentialMesh = BSShapeMesh.GetReference(m_physicsScene, false /*forceRebuild*/, prim); |
266 | // If the current shape is not what is on the prim at the moment, time to change. | 277 | // If the current shape is not what is on the prim at the moment, time to change. |
267 | if (!prim.PhysShape.HasPhysicalShape | 278 | if (!prim.PhysShape.HasPhysicalShape |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs index 6b09468..fca4258 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | |||
@@ -31,6 +31,7 @@ using System.Text; | |||
31 | 31 | ||
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | using OpenSim.Region.Physics.Manager; | 33 | using OpenSim.Region.Physics.Manager; |
34 | using OpenSim.Region.Physics.Meshing; | ||
34 | using OpenSim.Region.Physics.ConvexDecompositionDotNet; | 35 | using OpenSim.Region.Physics.ConvexDecompositionDotNet; |
35 | 36 | ||
36 | using OMV = OpenMetaverse; | 37 | using OMV = OpenMetaverse; |
@@ -422,9 +423,22 @@ public class BSShapeMesh : BSShape | |||
422 | outMesh = foundDesc; | 423 | outMesh = foundDesc; |
423 | return ret; | 424 | return ret; |
424 | } | 425 | } |
426 | |||
427 | public delegate BulletShape CreateShapeCall(BulletWorld world, int indicesCount, int[] indices, int verticesCount, float[] vertices ); | ||
425 | private BulletShape CreatePhysicalMesh(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, | 428 | private BulletShape CreatePhysicalMesh(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, |
426 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | 429 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) |
427 | { | 430 | { |
431 | return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod, | ||
432 | (w, iC, i, vC, v) => physicsScene.PE.CreateMeshShape(w, iC, i, vC, v) ); | ||
433 | } | ||
434 | |||
435 | // Code that uses the mesher to create the index/vertices info for a trimesh shape. | ||
436 | // This is used by the passed 'makeShape' call to create the Bullet mesh shape. | ||
437 | // The actual build call is passed so this logic can be used by several of the shapes that use a | ||
438 | // simple mesh as their base shape. | ||
439 | public static BulletShape CreatePhysicalMeshShape(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, | ||
440 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod, CreateShapeCall makeShape) | ||
441 | { | ||
428 | BulletShape newShape = new BulletShape(); | 442 | BulletShape newShape = new BulletShape(); |
429 | 443 | ||
430 | IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, | 444 | IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, |
@@ -484,8 +498,7 @@ public class BSShapeMesh : BSShape | |||
484 | 498 | ||
485 | if (realIndicesIndex != 0) | 499 | if (realIndicesIndex != 0) |
486 | { | 500 | { |
487 | newShape = physicsScene.PE.CreateMeshShape(physicsScene.World, | 501 | newShape = makeShape(physicsScene.World, realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats); |
488 | realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats); | ||
489 | } | 502 | } |
490 | else | 503 | else |
491 | { | 504 | { |
@@ -563,9 +576,56 @@ public class BSShapeHull : BSShape | |||
563 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | 576 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) |
564 | { | 577 | { |
565 | BulletShape newShape = new BulletShape(); | 578 | BulletShape newShape = new BulletShape(); |
566 | IntPtr hullPtr = IntPtr.Zero; | 579 | newShape.shapeKey = newHullKey; |
580 | |||
581 | // Pass true for physicalness as this prevents the creation of bounding box which is not needed | ||
582 | IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */, false, false); | ||
567 | 583 | ||
568 | if (BSParam.ShouldUseBulletHACD) | 584 | // If there is hull data in the mesh asset, build the hull from that |
585 | if (meshData != null && BSParam.ShouldUseAssetHulls) | ||
586 | { | ||
587 | Meshmerizer realMesher = physicsScene.mesher as Meshmerizer; | ||
588 | if (realMesher != null) | ||
589 | { | ||
590 | List<List<OMV.Vector3>> allHulls = realMesher.GetConvexHulls(size); | ||
591 | if (allHulls != null) | ||
592 | { | ||
593 | int hullCount = allHulls.Count; | ||
594 | int totalVertices = 1; // include one for the count of the hulls | ||
595 | // Using the structure described for HACD hulls, create the memory sturcture | ||
596 | // to pass the hull data to the creater. | ||
597 | foreach (List<OMV.Vector3> hullVerts in allHulls) | ||
598 | { | ||
599 | totalVertices += 4; // add four for the vertex count and centroid | ||
600 | totalVertices += hullVerts.Count * 3; // one vertex is three dimensions | ||
601 | } | ||
602 | float[] convHulls = new float[totalVertices]; | ||
603 | |||
604 | convHulls[0] = (float)hullCount; | ||
605 | int jj = 1; | ||
606 | foreach (List<OMV.Vector3> hullVerts in allHulls) | ||
607 | { | ||
608 | convHulls[jj + 0] = hullVerts.Count; | ||
609 | convHulls[jj + 1] = 0f; // centroid x,y,z | ||
610 | convHulls[jj + 2] = 0f; | ||
611 | convHulls[jj + 3] = 0f; | ||
612 | jj += 4; | ||
613 | foreach (OMV.Vector3 oneVert in hullVerts) | ||
614 | { | ||
615 | convHulls[jj + 0] = oneVert.X; | ||
616 | convHulls[jj + 1] = oneVert.Y; | ||
617 | convHulls[jj + 2] = oneVert.Z; | ||
618 | jj += 3; | ||
619 | } | ||
620 | } | ||
621 | |||
622 | // create the hull data structure in Bullet | ||
623 | newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls); | ||
624 | } | ||
625 | } | ||
626 | } | ||
627 | // If no hull specified in the asset and we should use Bullet's HACD approximation... | ||
628 | if (!newShape.HasPhysicalShape && BSParam.ShouldUseBulletHACD) | ||
569 | { | 629 | { |
570 | // Build the hull shape from an existing mesh shape. | 630 | // Build the hull shape from an existing mesh shape. |
571 | // The mesh should have already been created in Bullet. | 631 | // The mesh should have already been created in Bullet. |
@@ -594,11 +654,10 @@ public class BSShapeHull : BSShape | |||
594 | } | 654 | } |
595 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); | 655 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); |
596 | } | 656 | } |
657 | // If no hull specified, use our HACD hull approximation. | ||
597 | if (!newShape.HasPhysicalShape) | 658 | if (!newShape.HasPhysicalShape) |
598 | { | 659 | { |
599 | // Build a new hull in the physical world using the C# HACD algorigthm. | 660 | // Build a new hull in the physical world using the C# HACD algorigthm. |
600 | // Pass true for physicalness as this prevents the creation of bounding box which is not needed | ||
601 | IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */, false, false); | ||
602 | if (meshData != null) | 661 | if (meshData != null) |
603 | { | 662 | { |
604 | if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) | 663 | if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) |
@@ -805,6 +864,7 @@ public class BSShapeCompound : BSShape | |||
805 | // Called at taint-time. | 864 | // Called at taint-time. |
806 | private void DereferenceAnonCollisionShape(BSScene physicsScene, BulletShape pShape) | 865 | private void DereferenceAnonCollisionShape(BSScene physicsScene, BulletShape pShape) |
807 | { | 866 | { |
867 | // TODO: figure a better way to go through all the shape types and find a possible instance. | ||
808 | BSShapeMesh meshDesc; | 868 | BSShapeMesh meshDesc; |
809 | if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc)) | 869 | if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc)) |
810 | { | 870 | { |
@@ -826,17 +886,25 @@ public class BSShapeCompound : BSShape | |||
826 | } | 886 | } |
827 | else | 887 | else |
828 | { | 888 | { |
829 | if (physicsScene.PE.IsCompound(pShape)) | 889 | BSShapeGImpact gImpactDesc; |
890 | if (BSShapeGImpact.TryGetGImpactByPtr(pShape, out gImpactDesc)) | ||
830 | { | 891 | { |
831 | BSShapeCompound recursiveCompound = new BSShapeCompound(pShape); | 892 | gImpactDesc.Dereference(physicsScene); |
832 | recursiveCompound.Dereference(physicsScene); | ||
833 | } | 893 | } |
834 | else | 894 | else |
835 | { | 895 | { |
836 | if (physicsScene.PE.IsNativeShape(pShape)) | 896 | if (physicsScene.PE.IsCompound(pShape)) |
837 | { | 897 | { |
838 | BSShapeNative nativeShape = new BSShapeNative(pShape); | 898 | BSShapeCompound recursiveCompound = new BSShapeCompound(pShape); |
839 | nativeShape.Dereference(physicsScene); | 899 | recursiveCompound.Dereference(physicsScene); |
900 | } | ||
901 | else | ||
902 | { | ||
903 | if (physicsScene.PE.IsNativeShape(pShape)) | ||
904 | { | ||
905 | BSShapeNative nativeShape = new BSShapeNative(pShape); | ||
906 | nativeShape.Dereference(physicsScene); | ||
907 | } | ||
840 | } | 908 | } |
841 | } | 909 | } |
842 | } | 910 | } |
@@ -859,7 +927,7 @@ public class BSShapeConvexHull : BSShape | |||
859 | float lod; | 927 | float lod; |
860 | System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); | 928 | System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); |
861 | 929 | ||
862 | physicsScene.DetailLog("{0},BSShapeMesh,getReference,newKey={1},size={2},lod={3}", | 930 | physicsScene.DetailLog("{0},BSShapeConvexHull,getReference,newKey={1},size={2},lod={3}", |
863 | prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod); | 931 | prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod); |
864 | 932 | ||
865 | BSShapeConvexHull retConvexHull = null; | 933 | BSShapeConvexHull retConvexHull = null; |
@@ -939,6 +1007,97 @@ public class BSShapeConvexHull : BSShape | |||
939 | return ret; | 1007 | return ret; |
940 | } | 1008 | } |
941 | } | 1009 | } |
1010 | // ============================================================================================================ | ||
1011 | public class BSShapeGImpact : BSShape | ||
1012 | { | ||
1013 | private static string LogHeader = "[BULLETSIM SHAPE GIMPACT]"; | ||
1014 | public static Dictionary<System.UInt64, BSShapeGImpact> GImpacts = new Dictionary<System.UInt64, BSShapeGImpact>(); | ||
1015 | |||
1016 | public BSShapeGImpact(BulletShape pShape) : base(pShape) | ||
1017 | { | ||
1018 | } | ||
1019 | public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) | ||
1020 | { | ||
1021 | float lod; | ||
1022 | System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); | ||
1023 | |||
1024 | physicsScene.DetailLog("{0},BSShapeGImpact,getReference,newKey={1},size={2},lod={3}", | ||
1025 | prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod); | ||
1026 | |||
1027 | BSShapeGImpact retGImpact = null; | ||
1028 | lock (GImpacts) | ||
1029 | { | ||
1030 | if (GImpacts.TryGetValue(newMeshKey, out retGImpact)) | ||
1031 | { | ||
1032 | // The mesh has already been created. Return a new reference to same. | ||
1033 | retGImpact.IncrementReference(); | ||
1034 | } | ||
1035 | else | ||
1036 | { | ||
1037 | retGImpact = new BSShapeGImpact(new BulletShape()); | ||
1038 | BulletShape newShape = retGImpact.CreatePhysicalGImpact(physicsScene, prim, newMeshKey, prim.BaseShape, prim.Size, lod); | ||
1039 | |||
1040 | // Check to see if mesh was created (might require an asset). | ||
1041 | newShape = VerifyMeshCreated(physicsScene, newShape, prim); | ||
1042 | if (!newShape.isNativeShape || prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Failed) | ||
1043 | { | ||
1044 | // If a mesh was what was created, remember the built shape for later sharing. | ||
1045 | // Also note that if meshing failed we put it in the mesh list as there is nothing else to do about the mesh. | ||
1046 | GImpacts.Add(newMeshKey, retGImpact); | ||
1047 | } | ||
1048 | |||
1049 | retGImpact.physShapeInfo = newShape; | ||
1050 | } | ||
1051 | } | ||
1052 | return retGImpact; | ||
1053 | } | ||
1054 | |||
1055 | private BulletShape CreatePhysicalGImpact(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, | ||
1056 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | ||
1057 | { | ||
1058 | return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod, | ||
1059 | (w, iC, i, vC, v) => physicsScene.PE.CreateGImpactShape(w, iC, i, vC, v) ); | ||
1060 | } | ||
1061 | |||
1062 | public override BSShape GetReference(BSScene physicsScene, BSPhysObject prim) | ||
1063 | { | ||
1064 | // Calling this reference means we want another handle to an existing shape | ||
1065 | // (usually linksets) so return this copy. | ||
1066 | IncrementReference(); | ||
1067 | return this; | ||
1068 | } | ||
1069 | // Dereferencing a compound shape releases the hold on all the child shapes. | ||
1070 | public override void Dereference(BSScene physicsScene) | ||
1071 | { | ||
1072 | lock (GImpacts) | ||
1073 | { | ||
1074 | this.DecrementReference(); | ||
1075 | physicsScene.DetailLog("{0},BSShapeGImpact.Dereference,shape={1}", BSScene.DetailLogZero, this); | ||
1076 | // TODO: schedule aging and destruction of unused meshes. | ||
1077 | } | ||
1078 | } | ||
1079 | // Loop through all the known hulls and return the description based on the physical address. | ||
1080 | public static bool TryGetGImpactByPtr(BulletShape pShape, out BSShapeGImpact outHull) | ||
1081 | { | ||
1082 | bool ret = false; | ||
1083 | BSShapeGImpact foundDesc = null; | ||
1084 | lock (GImpacts) | ||
1085 | { | ||
1086 | foreach (BSShapeGImpact sh in GImpacts.Values) | ||
1087 | { | ||
1088 | if (sh.physShapeInfo.ReferenceSame(pShape)) | ||
1089 | { | ||
1090 | foundDesc = sh; | ||
1091 | ret = true; | ||
1092 | break; | ||
1093 | } | ||
1094 | |||
1095 | } | ||
1096 | } | ||
1097 | outHull = foundDesc; | ||
1098 | return ret; | ||
1099 | } | ||
1100 | } | ||
942 | 1101 | ||
943 | // ============================================================================================================ | 1102 | // ============================================================================================================ |
944 | public class BSShapeAvatar : BSShape | 1103 | public class BSShapeAvatar : BSShape |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 5792ae6..df1da63 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | |||
@@ -1,16 +1,12 @@ | |||
1 | PROBLEMS TO LOOK INTO | 1 | CURRENT PROBLEMS TO FIX AND/OR LOOK AT |
2 | ================================================= | 2 | ================================================= |
3 | Nebadon vehicle ride, get up, ride again. Second time vehicle does not act correctly. | 3 | Script changing rotation of child prim while vehicle moving (eg turning wheel) causes |
4 | the wheel to appear to jump back. Looks like sending position from previous update. | ||
5 | Vehicle ride, get up, ride again. Second time vehicle does not act correctly. | ||
4 | Have to rez new vehicle and delete the old to fix situation. | 6 | Have to rez new vehicle and delete the old to fix situation. |
5 | Hitting RESET on Nebadon's vehicle while riding causes vehicle to get into odd | 7 | Hitting RESET on Nebadon's vehicle while riding causes vehicle to get into odd |
6 | position state where it will not settle onto ground properly, etc | 8 | position state where it will not settle onto ground properly, etc |
7 | Two of Nebadon vehicles in a sim max the CPU. This is new. | 9 | Two of Nebadon vehicles in a sim max the CPU. This is new. |
8 | A sitting, active vehicle bobs up and down a small amount. | ||
9 | |||
10 | CURRENT PRIORITIES | ||
11 | ================================================= | ||
12 | Use the HACD convex hull routine in Bullet rather than the C# version. | ||
13 | Speed up hullifying large meshes. | ||
14 | Enable vehicle border crossings (at least as poorly as ODE) | 10 | Enable vehicle border crossings (at least as poorly as ODE) |
15 | Terrain skirts | 11 | Terrain skirts |
16 | Avatar created in previous region and not new region when crossing border | 12 | Avatar created in previous region and not new region when crossing border |
@@ -361,4 +357,6 @@ Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE. | |||
361 | Nebadon vehicles turning funny in arena (DONE) | 357 | Nebadon vehicles turning funny in arena (DONE) |
362 | Lock axis (DONE 20130401) | 358 | Lock axis (DONE 20130401) |
363 | Terrain detail: double terrain mesh detail (DONE) | 359 | Terrain detail: double terrain mesh detail (DONE) |
360 | Use the HACD convex hull routine in Bullet rather than the C# version. | ||
361 | Speed up hullifying large meshes. (DONE) | ||
364 | 362 | ||
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 42929ec..db5d962 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs | |||
@@ -79,6 +79,8 @@ namespace OpenSim.Region.Physics.Meshing | |||
79 | 79 | ||
80 | private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh | 80 | private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh |
81 | 81 | ||
82 | private List<List<Vector3>> mConvexHulls = null; | ||
83 | |||
82 | private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>(); | 84 | private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>(); |
83 | 85 | ||
84 | public Meshmerizer(IConfigSource config) | 86 | public Meshmerizer(IConfigSource config) |
@@ -363,6 +365,57 @@ namespace OpenSim.Region.Physics.Meshing | |||
363 | else if (map.ContainsKey("high_lod")) | 365 | else if (map.ContainsKey("high_lod")) |
364 | physicsParms = (OSDMap)map["high_lod"]; // if all else fails, use highest LOD display mesh and hope it works :) | 366 | physicsParms = (OSDMap)map["high_lod"]; // if all else fails, use highest LOD display mesh and hope it works :) |
365 | 367 | ||
368 | if (map.ContainsKey("physics_convex")) | ||
369 | { // pull this out also in case physics engine can use it | ||
370 | try | ||
371 | { | ||
372 | OSDMap convexBlock = (OSDMap)map["physics_convex"]; | ||
373 | if (convexBlock.ContainsKey("HullList")) | ||
374 | { | ||
375 | byte[] hullList = convexBlock["HullList"].AsBinary(); | ||
376 | Vector3 min = new Vector3(-0.5f, -0.5f, -0.5f); | ||
377 | if (convexBlock.ContainsKey("Min")) min = convexBlock["Min"].AsVector3(); | ||
378 | Vector3 max = new Vector3(0.5f, 0.5f, 0.5f); | ||
379 | if (convexBlock.ContainsKey("Max")) max = convexBlock["Max"].AsVector3(); | ||
380 | |||
381 | // decompress and decode hull points | ||
382 | byte[] posBytes = DecompressOsd(convexBlock["Positions"].AsBinary()).AsBinary(); | ||
383 | |||
384 | List<List<Vector3>> hulls = new List<List<Vector3>>(); | ||
385 | int posNdx = 0; | ||
386 | |||
387 | foreach (byte cnt in hullList) | ||
388 | { | ||
389 | int count = cnt == 0 ? 256 : cnt; | ||
390 | List<Vector3> hull = new List<Vector3>(); | ||
391 | |||
392 | for (int i = 0; i < count; i++) | ||
393 | { | ||
394 | ushort uX = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; | ||
395 | ushort uY = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; | ||
396 | ushort uZ = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; | ||
397 | |||
398 | Vector3 pos = new Vector3( | ||
399 | Utils.UInt16ToFloat(uX, min.X, max.X), | ||
400 | Utils.UInt16ToFloat(uY, min.Y, max.Y), | ||
401 | Utils.UInt16ToFloat(uZ, min.Z, max.Z) | ||
402 | ); | ||
403 | |||
404 | hull.Add(pos); | ||
405 | } | ||
406 | |||
407 | hulls.Add(hull); | ||
408 | } | ||
409 | |||
410 | mConvexHulls = hulls; | ||
411 | } | ||
412 | } | ||
413 | catch (Exception e) | ||
414 | { | ||
415 | m_log.WarnFormat("[MESH]: exception decoding convex block: {0}", e.Message); | ||
416 | } | ||
417 | } | ||
418 | |||
366 | if (physicsParms == null) | 419 | if (physicsParms == null) |
367 | { | 420 | { |
368 | m_log.WarnFormat("[MESH]: No recognized physics mesh found in mesh asset for {0}", primName); | 421 | m_log.WarnFormat("[MESH]: No recognized physics mesh found in mesh asset for {0}", primName); |
@@ -381,27 +434,7 @@ namespace OpenSim.Region.Physics.Meshing | |||
381 | // byte[] decompressed = new byte[physSize * 5]; | 434 | // byte[] decompressed = new byte[physSize * 5]; |
382 | try | 435 | try |
383 | { | 436 | { |
384 | using (MemoryStream inMs = new MemoryStream(meshBytes)) | 437 | decodedMeshOsd = DecompressOsd(meshBytes); |
385 | { | ||
386 | using (MemoryStream outMs = new MemoryStream()) | ||
387 | { | ||
388 | using (ZOutputStream zOut = new ZOutputStream(outMs)) | ||
389 | { | ||
390 | byte[] readBuffer = new byte[2048]; | ||
391 | int readLen = 0; | ||
392 | while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0) | ||
393 | { | ||
394 | zOut.Write(readBuffer, 0, readLen); | ||
395 | } | ||
396 | zOut.Flush(); | ||
397 | outMs.Seek(0, SeekOrigin.Begin); | ||
398 | |||
399 | byte[] decompressedBuf = outMs.GetBuffer(); | ||
400 | |||
401 | decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf); | ||
402 | } | ||
403 | } | ||
404 | } | ||
405 | } | 438 | } |
406 | catch (Exception e) | 439 | catch (Exception e) |
407 | { | 440 | { |
@@ -428,6 +461,41 @@ namespace OpenSim.Region.Physics.Meshing | |||
428 | return true; | 461 | return true; |
429 | } | 462 | } |
430 | 463 | ||
464 | |||
465 | /// <summary> | ||
466 | /// decompresses a gzipped OSD object | ||
467 | /// </summary> | ||
468 | /// <param name="decodedOsd"></param> the OSD object | ||
469 | /// <param name="meshBytes"></param> | ||
470 | /// <returns></returns> | ||
471 | private static OSD DecompressOsd(byte[] meshBytes) | ||
472 | { | ||
473 | OSD decodedOsd = null; | ||
474 | |||
475 | using (MemoryStream inMs = new MemoryStream(meshBytes)) | ||
476 | { | ||
477 | using (MemoryStream outMs = new MemoryStream()) | ||
478 | { | ||
479 | using (ZOutputStream zOut = new ZOutputStream(outMs)) | ||
480 | { | ||
481 | byte[] readBuffer = new byte[2048]; | ||
482 | int readLen = 0; | ||
483 | while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0) | ||
484 | { | ||
485 | zOut.Write(readBuffer, 0, readLen); | ||
486 | } | ||
487 | zOut.Flush(); | ||
488 | outMs.Seek(0, SeekOrigin.Begin); | ||
489 | |||
490 | byte[] decompressedBuf = outMs.GetBuffer(); | ||
491 | |||
492 | decodedOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf); | ||
493 | } | ||
494 | } | ||
495 | } | ||
496 | return decodedOsd; | ||
497 | } | ||
498 | |||
431 | /// <summary> | 499 | /// <summary> |
432 | /// Generate the co-ords and faces necessary to construct a mesh from the sculpt data the accompanies a prim. | 500 | /// Generate the co-ords and faces necessary to construct a mesh from the sculpt data the accompanies a prim. |
433 | /// </summary> | 501 | /// </summary> |
@@ -704,6 +772,27 @@ namespace OpenSim.Region.Physics.Meshing | |||
704 | return true; | 772 | return true; |
705 | } | 773 | } |
706 | 774 | ||
775 | /// <summary> | ||
776 | /// temporary prototype code - please do not use until the interface has been finalized! | ||
777 | /// </summary> | ||
778 | /// <param name="size">value to scale the hull points by</param> | ||
779 | /// <returns>a list of hulls if they exist and have been successfully decoded, otherwise null</returns> | ||
780 | public List<List<Vector3>> GetConvexHulls(Vector3 size) | ||
781 | { | ||
782 | if (mConvexHulls == null) | ||
783 | return null; | ||
784 | |||
785 | List<List<Vector3>> hulls = new List<List<Vector3>>(); | ||
786 | foreach (var hull in mConvexHulls) | ||
787 | { | ||
788 | List<Vector3> verts = new List<Vector3>(); | ||
789 | foreach (var vert in hull) | ||
790 | verts.Add(vert * size); | ||
791 | } | ||
792 | |||
793 | return hulls; | ||
794 | } | ||
795 | |||
707 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) | 796 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) |
708 | { | 797 | { |
709 | return CreateMesh(primName, primShape, size, lod, false, true); | 798 | return CreateMesh(primName, primShape, size, lod, false, true); |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index bc35272..0199461 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -2772,9 +2772,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2772 | // send the sound, once, to all clients in range | 2772 | // send the sound, once, to all clients in range |
2773 | if (m_SoundModule != null) | 2773 | if (m_SoundModule != null) |
2774 | { | 2774 | { |
2775 | m_SoundModule.SendSound(m_host.UUID, | 2775 | m_SoundModule.SendSound( |
2776 | ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, false, 0, | 2776 | m_host.UUID, |
2777 | 0, false, false); | 2777 | ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), |
2778 | volume, false, m_host.SoundQueueing ? (byte)SoundFlags.Queue : (byte)SoundFlags.None, | ||
2779 | 0, false, false); | ||
2778 | } | 2780 | } |
2779 | } | 2781 | } |
2780 | 2782 | ||
@@ -12644,6 +12646,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12644 | public void llSetSoundQueueing(int queue) | 12646 | public void llSetSoundQueueing(int queue) |
12645 | { | 12647 | { |
12646 | m_host.AddScriptLPS(1); | 12648 | m_host.AddScriptLPS(1); |
12649 | |||
12650 | if (m_SoundModule != null) | ||
12651 | m_SoundModule.SetSoundQueueing(m_host.UUID, queue == ScriptBaseClass.TRUE.value); | ||
12647 | } | 12652 | } |
12648 | 12653 | ||
12649 | public void llCollisionSprite(string impact_sprite) | 12654 | public void llCollisionSprite(string impact_sprite) |
diff --git a/bin/lib32/BulletSim.dll b/bin/lib32/BulletSim.dll index 1e94d05..d63ee1d 100755 --- a/bin/lib32/BulletSim.dll +++ b/bin/lib32/BulletSim.dll | |||
Binary files differ | |||
diff --git a/bin/lib32/libBulletSim.so b/bin/lib32/libBulletSim.so index 6216a65..03de631 100755 --- a/bin/lib32/libBulletSim.so +++ b/bin/lib32/libBulletSim.so | |||
Binary files differ | |||
diff --git a/bin/lib64/BulletSim.dll b/bin/lib64/BulletSim.dll index 68cfcc4..e155f0e 100755 --- a/bin/lib64/BulletSim.dll +++ b/bin/lib64/BulletSim.dll | |||
Binary files differ | |||
diff --git a/bin/lib64/libBulletSim.so b/bin/lib64/libBulletSim.so index 08c00af..ac64a40 100755 --- a/bin/lib64/libBulletSim.so +++ b/bin/lib64/libBulletSim.so | |||
Binary files differ | |||
diff --git a/prebuild.xml b/prebuild.xml index ef07bdc..c611cb9 100644 --- a/prebuild.xml +++ b/prebuild.xml | |||
@@ -1878,6 +1878,7 @@ | |||
1878 | <Reference name="OpenSim.Region.CoreModules"/> | 1878 | <Reference name="OpenSim.Region.CoreModules"/> |
1879 | <Reference name="OpenSim.Framework.Console"/> | 1879 | <Reference name="OpenSim.Framework.Console"/> |
1880 | <Reference name="OpenSim.Region.Physics.Manager"/> | 1880 | <Reference name="OpenSim.Region.Physics.Manager"/> |
1881 | <Reference name="OpenSim.Region.Physics.Meshing" path="../../../../bin/Physics/"/> | ||
1881 | <Reference name="OpenSim.Region.Physics.ConvexDecompositionDotNet"/> | 1882 | <Reference name="OpenSim.Region.Physics.ConvexDecompositionDotNet"/> |
1882 | <Reference name="BulletXNA.dll" path="../../../../bin/"/> | 1883 | <Reference name="BulletXNA.dll" path="../../../../bin/"/> |
1883 | <Reference name="log4net.dll" path="../../../../bin/"/> | 1884 | <Reference name="log4net.dll" path="../../../../bin/"/> |