diff options
Diffstat (limited to 'OpenSim')
25 files changed, 882 insertions, 675 deletions
diff --git a/OpenSim/Framework/IScene.cs b/OpenSim/Framework/IScene.cs index f1b4732..76b731f 100644 --- a/OpenSim/Framework/IScene.cs +++ b/OpenSim/Framework/IScene.cs | |||
@@ -102,12 +102,28 @@ namespace OpenSim.Framework | |||
102 | 102 | ||
103 | bool TryGetScenePresence(UUID agentID, out object scenePresence); | 103 | bool TryGetScenePresence(UUID agentID, out object scenePresence); |
104 | 104 | ||
105 | T RequestModuleInterface<T>(); | 105 | /// <summary> |
106 | T[] RequestModuleInterfaces<T>(); | 106 | /// Register an interface to a region module. This allows module methods to be called directly as |
107 | 107 | /// well as via events. If there is already a module registered for this interface, it is not replaced | |
108 | /// (is this the best behaviour?) | ||
109 | /// </summary> | ||
110 | /// <param name="mod"></param> | ||
108 | void RegisterModuleInterface<M>(M mod); | 111 | void RegisterModuleInterface<M>(M mod); |
112 | |||
109 | void StackModuleInterface<M>(M mod); | 113 | void StackModuleInterface<M>(M mod); |
110 | 114 | ||
115 | /// <summary> | ||
116 | /// For the given interface, retrieve the region module which implements it. | ||
117 | /// </summary> | ||
118 | /// <returns>null if there is no registered module implementing that interface</returns> | ||
119 | T RequestModuleInterface<T>(); | ||
120 | |||
121 | /// <summary> | ||
122 | /// For the given interface, retrieve an array of region modules that implement it. | ||
123 | /// </summary> | ||
124 | /// <returns>an empty array if there are no registered modules implementing that interface</returns> | ||
125 | T[] RequestModuleInterfaces<T>(); | ||
126 | |||
111 | // void AddCommand(object module, string command, string shorthelp, string longhelp, CommandDelegate callback); | 127 | // void AddCommand(object module, string command, string shorthelp, string longhelp, CommandDelegate callback); |
112 | 128 | ||
113 | ISceneObject DeserializeObject(string representation); | 129 | ISceneObject DeserializeObject(string representation); |
diff --git a/OpenSim/Region/Application/ConfigurationLoader.cs b/OpenSim/Region/Application/ConfigurationLoader.cs index d0f6ab7..4a7c8b0 100644 --- a/OpenSim/Region/Application/ConfigurationLoader.cs +++ b/OpenSim/Region/Application/ConfigurationLoader.cs | |||
@@ -70,7 +70,7 @@ namespace OpenSim | |||
70 | /// <param name="networkInfo"></param> | 70 | /// <param name="networkInfo"></param> |
71 | /// <returns>A configuration that gets passed to modules</returns> | 71 | /// <returns>A configuration that gets passed to modules</returns> |
72 | public OpenSimConfigSource LoadConfigSettings( | 72 | public OpenSimConfigSource LoadConfigSettings( |
73 | IConfigSource argvSource, out ConfigSettings configSettings, | 73 | IConfigSource argvSource, EnvConfigSource envConfigSource, out ConfigSettings configSettings, |
74 | out NetworkServersInfo networkInfo) | 74 | out NetworkServersInfo networkInfo) |
75 | { | 75 | { |
76 | m_configSettings = configSettings = new ConfigSettings(); | 76 | m_configSettings = configSettings = new ConfigSettings(); |
@@ -195,6 +195,24 @@ namespace OpenSim | |||
195 | // Make sure command line options take precedence | 195 | // Make sure command line options take precedence |
196 | m_config.Source.Merge(argvSource); | 196 | m_config.Source.Merge(argvSource); |
197 | 197 | ||
198 | |||
199 | IConfig enVars = m_config.Source.Configs["Environment"]; | ||
200 | |||
201 | if( enVars != null ) | ||
202 | { | ||
203 | string[] env_keys = enVars.GetKeys(); | ||
204 | |||
205 | foreach ( string key in env_keys ) | ||
206 | { | ||
207 | envConfigSource.AddEnv(key, string.Empty); | ||
208 | } | ||
209 | |||
210 | envConfigSource.LoadEnv(); | ||
211 | m_config.Source.Merge(envConfigSource); | ||
212 | m_config.Source.ExpandKeyValues(); | ||
213 | } | ||
214 | |||
215 | |||
198 | ReadConfigSettings(); | 216 | ReadConfigSettings(); |
199 | 217 | ||
200 | return m_config; | 218 | return m_config; |
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index 542211a..8e1eb95 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs | |||
@@ -112,6 +112,13 @@ namespace OpenSim | |||
112 | get { return m_clientServers; } | 112 | get { return m_clientServers; } |
113 | } | 113 | } |
114 | 114 | ||
115 | protected EnvConfigSource m_EnvConfigSource = new EnvConfigSource(); | ||
116 | |||
117 | public EnvConfigSource envConfigSource | ||
118 | { | ||
119 | get { return m_EnvConfigSource; } | ||
120 | } | ||
121 | |||
115 | protected List<IClientNetworkServer> m_clientServers = new List<IClientNetworkServer>(); | 122 | protected List<IClientNetworkServer> m_clientServers = new List<IClientNetworkServer>(); |
116 | 123 | ||
117 | public uint HttpServerPort | 124 | public uint HttpServerPort |
@@ -146,7 +153,7 @@ namespace OpenSim | |||
146 | protected virtual void LoadConfigSettings(IConfigSource configSource) | 153 | protected virtual void LoadConfigSettings(IConfigSource configSource) |
147 | { | 154 | { |
148 | m_configLoader = new ConfigurationLoader(); | 155 | m_configLoader = new ConfigurationLoader(); |
149 | m_config = m_configLoader.LoadConfigSettings(configSource, out m_configSettings, out m_networkServersInfo); | 156 | m_config = m_configLoader.LoadConfigSettings(configSource, envConfigSource, out m_configSettings, out m_networkServersInfo); |
150 | ReadExtraConfigSettings(); | 157 | ReadExtraConfigSettings(); |
151 | } | 158 | } |
152 | 159 | ||
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 53f0f2e..245f258 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | |||
@@ -82,16 +82,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
82 | m_log.Info("[PRIM INVENTORY]: Starting scripts in scene"); | 82 | m_log.Info("[PRIM INVENTORY]: Starting scripts in scene"); |
83 | 83 | ||
84 | IScriptModule[] engines = RequestModuleInterfaces<IScriptModule>(); | 84 | IScriptModule[] engines = RequestModuleInterfaces<IScriptModule>(); |
85 | if (engines != null) | 85 | |
86 | { | 86 | foreach (IScriptModule engine in engines) |
87 | foreach (IScriptModule engine in engines) | 87 | engine.StartProcessing(); |
88 | { | ||
89 | if (engine != null) | ||
90 | { | ||
91 | engine.StartProcessing(); | ||
92 | } | ||
93 | } | ||
94 | } | ||
95 | } | 88 | } |
96 | 89 | ||
97 | public void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item) | 90 | public void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item) |
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs index 73e9392..0fd5164 100644 --- a/OpenSim/Region/Framework/Scenes/SceneBase.cs +++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs | |||
@@ -451,7 +451,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
451 | } | 451 | } |
452 | else | 452 | else |
453 | { | 453 | { |
454 | return new T[] { default(T) }; | 454 | return new T[] {}; |
455 | } | 455 | } |
456 | } | 456 | } |
457 | 457 | ||
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index e214f57..11040b7 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -252,7 +252,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
252 | private byte[] m_TextureAnimation; | 252 | private byte[] m_TextureAnimation; |
253 | private byte m_clickAction; | 253 | private byte m_clickAction; |
254 | private Color m_color = Color.Black; | 254 | private Color m_color = Color.Black; |
255 | private string m_description = String.Empty; | ||
256 | private readonly List<uint> m_lastColliders = new List<uint>(); | 255 | private readonly List<uint> m_lastColliders = new List<uint>(); |
257 | private int m_linkNum; | 256 | private int m_linkNum; |
258 | 257 | ||
@@ -331,11 +330,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
331 | /// </summary> | 330 | /// </summary> |
332 | public SceneObjectPart() | 331 | public SceneObjectPart() |
333 | { | 332 | { |
334 | // It's not necessary to persist this | ||
335 | m_TextureAnimation = Utils.EmptyBytes; | 333 | m_TextureAnimation = Utils.EmptyBytes; |
336 | m_particleSystem = Utils.EmptyBytes; | 334 | m_particleSystem = Utils.EmptyBytes; |
337 | Rezzed = DateTime.UtcNow; | 335 | Rezzed = DateTime.UtcNow; |
338 | 336 | Description = String.Empty; | |
337 | |||
338 | // Prims currently only contain a single folder (Contents). From looking at the Second Life protocol, | ||
339 | // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from | ||
340 | // the prim into an agent inventory (Linden client reports that the "Object not found for drop" in its log | ||
339 | m_inventory = new SceneObjectPartInventory(this); | 341 | m_inventory = new SceneObjectPartInventory(this); |
340 | } | 342 | } |
341 | 343 | ||
@@ -349,11 +351,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
349 | /// <param name="offsetPosition"></param> | 351 | /// <param name="offsetPosition"></param> |
350 | public SceneObjectPart( | 352 | public SceneObjectPart( |
351 | UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition, | 353 | UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition, |
352 | Quaternion rotationOffset, Vector3 offsetPosition) | 354 | Quaternion rotationOffset, Vector3 offsetPosition) : this() |
353 | { | 355 | { |
354 | m_name = "Object"; | 356 | m_name = "Object"; |
355 | 357 | ||
356 | Rezzed = DateTime.UtcNow; | ||
357 | CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed); | 358 | CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed); |
358 | LastOwnerID = CreatorID = OwnerID = ownerID; | 359 | LastOwnerID = CreatorID = OwnerID = ownerID; |
359 | UUID = UUID.Random(); | 360 | UUID = UUID.Random(); |
@@ -368,19 +369,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
368 | Velocity = Vector3.Zero; | 369 | Velocity = Vector3.Zero; |
369 | AngularVelocity = Vector3.Zero; | 370 | AngularVelocity = Vector3.Zero; |
370 | Acceleration = Vector3.Zero; | 371 | Acceleration = Vector3.Zero; |
371 | m_TextureAnimation = Utils.EmptyBytes; | ||
372 | m_particleSystem = Utils.EmptyBytes; | ||
373 | |||
374 | // Prims currently only contain a single folder (Contents). From looking at the Second Life protocol, | ||
375 | // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from | ||
376 | // the prim into an agent inventory (Linden client reports that the "Object not found for drop" in its log | ||
377 | |||
378 | Flags = 0; | 372 | Flags = 0; |
379 | CreateSelected = true; | 373 | CreateSelected = true; |
380 | 374 | ||
381 | TrimPermissions(); | 375 | TrimPermissions(); |
382 | |||
383 | m_inventory = new SceneObjectPartInventory(this); | ||
384 | } | 376 | } |
385 | 377 | ||
386 | #endregion Constructors | 378 | #endregion Constructors |
@@ -938,19 +930,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
938 | set { m_acceleration = value; } | 930 | set { m_acceleration = value; } |
939 | } | 931 | } |
940 | 932 | ||
941 | public string Description | 933 | public string Description { get; set; } |
942 | { | ||
943 | get { return m_description; } | ||
944 | set | ||
945 | { | ||
946 | m_description = value; | ||
947 | PhysicsActor actor = PhysActor; | ||
948 | if (actor != null) | ||
949 | { | ||
950 | actor.SOPDescription = value; | ||
951 | } | ||
952 | } | ||
953 | } | ||
954 | 934 | ||
955 | /// <value> | 935 | /// <value> |
956 | /// Text color. | 936 | /// Text color. |
@@ -1595,8 +1575,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1595 | // Basic Physics returns null.. joy joy joy. | 1575 | // Basic Physics returns null.. joy joy joy. |
1596 | if (PhysActor != null) | 1576 | if (PhysActor != null) |
1597 | { | 1577 | { |
1598 | PhysActor.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info | 1578 | PhysActor.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info |
1599 | PhysActor.SOPDescription = this.Description; | ||
1600 | PhysActor.SetMaterial(Material); | 1579 | PhysActor.SetMaterial(Material); |
1601 | DoPhysicsPropertyUpdate(RigidBody, true); | 1580 | DoPhysicsPropertyUpdate(RigidBody, true); |
1602 | PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0); | 1581 | PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0); |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 309f543..c485e87 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | |||
@@ -282,8 +282,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
282 | ArrayList ret = new ArrayList(); | 282 | ArrayList ret = new ArrayList(); |
283 | 283 | ||
284 | IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); | 284 | IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); |
285 | if (engines == null) // No engine at all | ||
286 | return ret; | ||
287 | 285 | ||
288 | foreach (IScriptModule e in engines) | 286 | foreach (IScriptModule e in engines) |
289 | { | 287 | { |
@@ -397,7 +395,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
397 | private void RestoreSavedScriptState(UUID oldID, UUID newID) | 395 | private void RestoreSavedScriptState(UUID oldID, UUID newID) |
398 | { | 396 | { |
399 | IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); | 397 | IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); |
400 | if (engines == null) // No engine at all | 398 | if (engines.Length == 0) // No engine at all |
401 | return; | 399 | return; |
402 | 400 | ||
403 | if (m_part.ParentGroup.m_savedScriptState.ContainsKey(oldID)) | 401 | if (m_part.ParentGroup.m_savedScriptState.ContainsKey(oldID)) |
@@ -437,6 +435,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
437 | 435 | ||
438 | m_part.ParentGroup.m_savedScriptState[oldID] = newDoc.OuterXml; | 436 | m_part.ParentGroup.m_savedScriptState[oldID] = newDoc.OuterXml; |
439 | } | 437 | } |
438 | |||
440 | foreach (IScriptModule e in engines) | 439 | foreach (IScriptModule e in engines) |
441 | { | 440 | { |
442 | if (e != null) | 441 | if (e != null) |
@@ -445,6 +444,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
445 | break; | 444 | break; |
446 | } | 445 | } |
447 | } | 446 | } |
447 | |||
448 | m_part.ParentGroup.m_savedScriptState.Remove(oldID); | 448 | m_part.ParentGroup.m_savedScriptState.Remove(oldID); |
449 | } | 449 | } |
450 | } | 450 | } |
@@ -1327,7 +1327,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1327 | 1327 | ||
1328 | IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); | 1328 | IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); |
1329 | 1329 | ||
1330 | if (engines == null) // No engine at all | 1330 | if (engines.Length == 0) // No engine at all |
1331 | return ret; | 1331 | return ret; |
1332 | 1332 | ||
1333 | Items.LockItemsForRead(true); | 1333 | Items.LockItemsForRead(true); |
@@ -1365,7 +1365,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1365 | public void ResumeScripts() | 1365 | public void ResumeScripts() |
1366 | { | 1366 | { |
1367 | IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); | 1367 | IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); |
1368 | if (engines == null) | 1368 | if (engines.Length == 0) |
1369 | return; | 1369 | return; |
1370 | 1370 | ||
1371 | 1371 | ||
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index d89c1c0..0eaac64 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -3535,23 +3535,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
3535 | /// <param name="args">The arguments for the event</param> | 3535 | /// <param name="args">The arguments for the event</param> |
3536 | public void SendScriptEventToAttachments(string eventName, Object[] args) | 3536 | public void SendScriptEventToAttachments(string eventName, Object[] args) |
3537 | { | 3537 | { |
3538 | if (m_scriptEngines != null) | 3538 | if (m_scriptEngines.Length == 0) |
3539 | return; | ||
3540 | |||
3541 | lock (m_attachments) | ||
3539 | { | 3542 | { |
3540 | lock (m_attachments) | 3543 | foreach (SceneObjectGroup grp in m_attachments) |
3541 | { | 3544 | { |
3542 | foreach (SceneObjectGroup grp in m_attachments) | 3545 | // 16384 is CHANGED_ANIMATION |
3546 | // | ||
3547 | // Send this to all attachment root prims | ||
3548 | // | ||
3549 | foreach (IScriptModule m in m_scriptEngines) | ||
3543 | { | 3550 | { |
3544 | // 16384 is CHANGED_ANIMATION | 3551 | if (m == null) // No script engine loaded |
3545 | // | 3552 | continue; |
3546 | // Send this to all attachment root prims | ||
3547 | // | ||
3548 | foreach (IScriptModule m in m_scriptEngines) | ||
3549 | { | ||
3550 | if (m == null) // No script engine loaded | ||
3551 | continue; | ||
3552 | 3553 | ||
3553 | m.PostObjectEvent(grp.RootPart.UUID, "changed", new Object[] { (int)Changed.ANIMATION }); | 3554 | m.PostObjectEvent(grp.RootPart.UUID, "changed", new Object[] { (int)Changed.ANIMATION }); |
3554 | } | ||
3555 | } | 3555 | } |
3556 | } | 3556 | } |
3557 | } | 3557 | } |
diff --git a/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs b/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs index 2a44360..23ef757 100755 --- a/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs +++ b/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs | |||
@@ -48,7 +48,7 @@ namespace OpenSim.Region.OptionalModules.PhysicsParameters | |||
48 | public class PhysicsParameters : ISharedRegionModule | 48 | public class PhysicsParameters : ISharedRegionModule |
49 | { | 49 | { |
50 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 50 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
51 | private static string LogHeader = "[PHYSICS PARAMETERS]"; | 51 | // private static string LogHeader = "[PHYSICS PARAMETERS]"; |
52 | 52 | ||
53 | private List<Scene> m_scenes = new List<Scene>(); | 53 | private List<Scene> m_scenes = new List<Scene>(); |
54 | private static bool m_commandsLoaded = false; | 54 | private static bool m_commandsLoaded = false; |
diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index 798a0a4..c2acf97 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs | |||
@@ -160,8 +160,19 @@ namespace OpenSim.Region.Physics.Manager | |||
160 | 160 | ||
161 | public abstract bool Selected { set; } | 161 | public abstract bool Selected { set; } |
162 | 162 | ||
163 | /// <summary> | ||
164 | /// Name of this actor. | ||
165 | /// </summary> | ||
166 | /// <remarks> | ||
167 | /// XXX: Bizarrely, this cannot be "Terrain" or "Water" right now unless it really is simulating terrain or | ||
168 | /// water. This is not a problem due to the formatting of names given by prims and avatars. | ||
169 | /// </remarks> | ||
170 | public string Name { get; protected set; } | ||
171 | |||
172 | /// <summary> | ||
173 | /// This is being used by ODE joint code. | ||
174 | /// </summary> | ||
163 | public string SOPName; | 175 | public string SOPName; |
164 | public string SOPDescription; | ||
165 | 176 | ||
166 | public abstract void CrossingFailure(); | 177 | public abstract void CrossingFailure(); |
167 | 178 | ||
diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index acedf44..1f631ee 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs | |||
@@ -224,15 +224,9 @@ namespace OpenSim.Region.Physics.Manager | |||
224 | return false; | 224 | return false; |
225 | } | 225 | } |
226 | 226 | ||
227 | public virtual void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents) | 227 | public virtual void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents) {} |
228 | { | ||
229 | return; | ||
230 | } | ||
231 | 228 | ||
232 | public virtual void UnCombine(PhysicsScene pScene) | 229 | public virtual void UnCombine(PhysicsScene pScene) {} |
233 | { | ||
234 | |||
235 | } | ||
236 | 230 | ||
237 | /// <summary> | 231 | /// <summary> |
238 | /// Queue a raycast against the physics scene. | 232 | /// Queue a raycast against the physics scene. |
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index c37d588..489a23a 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | |||
@@ -70,7 +70,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
70 | 70 | ||
71 | private Vector3 _position; | 71 | private Vector3 _position; |
72 | private d.Vector3 _zeroPosition; | 72 | private d.Vector3 _zeroPosition; |
73 | // private d.Matrix3 m_StandUpRotation; | ||
74 | private bool _zeroFlag = false; | 73 | private bool _zeroFlag = false; |
75 | private bool m_lastUpdateSent = false; | 74 | private bool m_lastUpdateSent = false; |
76 | private Vector3 _velocity; | 75 | private Vector3 _velocity; |
@@ -123,9 +122,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
123 | private float m_buoyancy = 0f; | 122 | private float m_buoyancy = 0f; |
124 | 123 | ||
125 | // private CollisionLocker ode; | 124 | // private CollisionLocker ode; |
126 | |||
127 | private string m_name = String.Empty; | ||
128 | |||
129 | private bool[] m_colliderarr = new bool[11]; | 125 | private bool[] m_colliderarr = new bool[11]; |
130 | private bool[] m_colliderGroundarr = new bool[11]; | 126 | private bool[] m_colliderGroundarr = new bool[11]; |
131 | 127 | ||
@@ -181,7 +177,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
181 | parent_scene.GetTerrainHeightAtXY(128f, 128f) + 10f); | 177 | parent_scene.GetTerrainHeightAtXY(128f, 128f) + 10f); |
182 | m_taintPosition = _position; | 178 | m_taintPosition = _position; |
183 | 179 | ||
184 | m_log.Warn("[PHYSICS]: Got NaN Position on Character Create"); | 180 | m_log.WarnFormat("[ODE CHARACTER]: Got NaN Position on Character Create for {0}", avName); |
185 | } | 181 | } |
186 | 182 | ||
187 | _parent_scene = parent_scene; | 183 | _parent_scene = parent_scene; |
@@ -204,7 +200,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
204 | m_colliderarr[i] = false; | 200 | m_colliderarr[i] = false; |
205 | } | 201 | } |
206 | CAPSULE_LENGTH = (size.Z * 1.15f) - CAPSULE_RADIUS * 2.0f; | 202 | CAPSULE_LENGTH = (size.Z * 1.15f) - CAPSULE_RADIUS * 2.0f; |
207 | //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); | 203 | //m_log.Info("[ODE CHARACTER]: " + CAPSULE_LENGTH.ToString()); |
208 | m_tainted_CAPSULE_LENGTH = CAPSULE_LENGTH; | 204 | m_tainted_CAPSULE_LENGTH = CAPSULE_LENGTH; |
209 | 205 | ||
210 | m_isPhysical = false; // current status: no ODE information exists | 206 | m_isPhysical = false; // current status: no ODE information exists |
@@ -212,7 +208,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
212 | 208 | ||
213 | _parent_scene.AddPhysicsActorTaint(this); | 209 | _parent_scene.AddPhysicsActorTaint(this); |
214 | 210 | ||
215 | m_name = avName; | 211 | Name = avName; |
216 | } | 212 | } |
217 | 213 | ||
218 | public override int PhysicsActorType | 214 | public override int PhysicsActorType |
@@ -269,7 +265,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
269 | set | 265 | set |
270 | { | 266 | { |
271 | flying = value; | 267 | flying = value; |
272 | // m_log.DebugFormat("[PHYSICS]: Set OdeCharacter Flying to {0}", flying); | 268 | // m_log.DebugFormat("[ODE CHARACTER]: Set OdeCharacter Flying to {0}", flying); |
273 | } | 269 | } |
274 | } | 270 | } |
275 | 271 | ||
@@ -440,7 +436,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
440 | } | 436 | } |
441 | else | 437 | else |
442 | { | 438 | { |
443 | m_log.Warn("[PHYSICS]: Got a NaN Position from Scene on a Character"); | 439 | m_log.WarnFormat("[ODE CHARACTER]: Got a NaN Position from Scene on character {0}", Name); |
444 | } | 440 | } |
445 | } | 441 | } |
446 | } | 442 | } |
@@ -467,7 +463,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
467 | 463 | ||
468 | Vector3 SetSize = value; | 464 | Vector3 SetSize = value; |
469 | m_tainted_CAPSULE_LENGTH = (SetSize.Z * 1.15f) - CAPSULE_RADIUS * 2.0f; | 465 | m_tainted_CAPSULE_LENGTH = (SetSize.Z * 1.15f) - CAPSULE_RADIUS * 2.0f; |
470 | // m_log.Info("[SIZE]: " + CAPSULE_LENGTH); | 466 | // m_log.Info("[ODE CHARACTER]: " + CAPSULE_LENGTH); |
471 | 467 | ||
472 | // If we reset velocity here, then an avatar stalls when it crosses a border for the first time | 468 | // If we reset velocity here, then an avatar stalls when it crosses a border for the first time |
473 | // (as the height of the new root agent is set). | 469 | // (as the height of the new root agent is set). |
@@ -477,7 +473,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
477 | } | 473 | } |
478 | else | 474 | else |
479 | { | 475 | { |
480 | m_log.Warn("[PHYSICS]: Got a NaN Size from Scene on a Character"); | 476 | m_log.WarnFormat("[ODE CHARACTER]: Got a NaN Size from Scene on {0}", Name); |
481 | } | 477 | } |
482 | } | 478 | } |
483 | } | 479 | } |
@@ -529,7 +525,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
529 | } | 525 | } |
530 | } | 526 | } |
531 | 527 | ||
532 | |||
533 | // movementVector.Z is zero | 528 | // movementVector.Z is zero |
534 | 529 | ||
535 | // calculate tilt components based on desired amount of tilt and current (snapped) heading. | 530 | // calculate tilt components based on desired amount of tilt and current (snapped) heading. |
@@ -537,7 +532,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
537 | float xTiltComponent = -movementVector.X * m_tiltMagnitudeWhenProjectedOnXYPlane; | 532 | float xTiltComponent = -movementVector.X * m_tiltMagnitudeWhenProjectedOnXYPlane; |
538 | float yTiltComponent = -movementVector.Y * m_tiltMagnitudeWhenProjectedOnXYPlane; | 533 | float yTiltComponent = -movementVector.Y * m_tiltMagnitudeWhenProjectedOnXYPlane; |
539 | 534 | ||
540 | //m_log.Debug("[PHYSICS] changing avatar tilt"); | 535 | //m_log.Debug("[ODE CHARACTER]: changing avatar tilt"); |
541 | d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, xTiltComponent); | 536 | d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, xTiltComponent); |
542 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, xTiltComponent); // must be same as lowstop, else a different, spurious tilt is introduced | 537 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, xTiltComponent); // must be same as lowstop, else a different, spurious tilt is introduced |
543 | d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, yTiltComponent); | 538 | d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, yTiltComponent); |
@@ -547,124 +542,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
547 | } | 542 | } |
548 | 543 | ||
549 | /// <summary> | 544 | /// <summary> |
550 | /// This creates the Avatar's physical Surrogate at the position supplied | ||
551 | /// </summary> | ||
552 | /// <param name="npositionX"></param> | ||
553 | /// <param name="npositionY"></param> | ||
554 | /// <param name="npositionZ"></param> | ||
555 | |||
556 | // WARNING: This MUST NOT be called outside of ProcessTaints, else we can have unsynchronized access | ||
557 | // to ODE internals. ProcessTaints is called from within thread-locked Simulate(), so it is the only | ||
558 | // place that is safe to call this routine AvatarGeomAndBodyCreation. | ||
559 | private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ, float tensor) | ||
560 | { | ||
561 | //CAPSULE_LENGTH = -5; | ||
562 | //CAPSULE_RADIUS = -5; | ||
563 | int dAMotorEuler = 1; | ||
564 | _parent_scene.waitForSpaceUnlock(_parent_scene.space); | ||
565 | if (CAPSULE_LENGTH <= 0) | ||
566 | { | ||
567 | m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!"); | ||
568 | CAPSULE_LENGTH = 0.01f; | ||
569 | |||
570 | } | ||
571 | |||
572 | if (CAPSULE_RADIUS <= 0) | ||
573 | { | ||
574 | m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!"); | ||
575 | CAPSULE_RADIUS = 0.01f; | ||
576 | |||
577 | } | ||
578 | Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH); | ||
579 | |||
580 | d.GeomSetCategoryBits(Shell, (int)m_collisionCategories); | ||
581 | d.GeomSetCollideBits(Shell, (int)m_collisionFlags); | ||
582 | |||
583 | d.MassSetCapsuleTotal(out ShellMass, m_mass, 2, CAPSULE_RADIUS, CAPSULE_LENGTH); | ||
584 | Body = d.BodyCreate(_parent_scene.world); | ||
585 | d.BodySetPosition(Body, npositionX, npositionY, npositionZ); | ||
586 | |||
587 | _position.X = npositionX; | ||
588 | _position.Y = npositionY; | ||
589 | _position.Z = npositionZ; | ||
590 | |||
591 | m_taintPosition = _position; | ||
592 | |||
593 | d.BodySetMass(Body, ref ShellMass); | ||
594 | d.Matrix3 m_caprot; | ||
595 | // 90 Stand up on the cap of the capped cyllinder | ||
596 | if (_parent_scene.IsAvCapsuleTilted) | ||
597 | { | ||
598 | d.RFromAxisAndAngle(out m_caprot, 1, 0, 1, (float)(Math.PI / 2)); | ||
599 | } | ||
600 | else | ||
601 | { | ||
602 | d.RFromAxisAndAngle(out m_caprot, 0, 0, 1, (float)(Math.PI / 2)); | ||
603 | } | ||
604 | |||
605 | |||
606 | d.GeomSetRotation(Shell, ref m_caprot); | ||
607 | d.BodySetRotation(Body, ref m_caprot); | ||
608 | |||
609 | d.GeomSetBody(Shell, Body); | ||
610 | |||
611 | |||
612 | // The purpose of the AMotor here is to keep the avatar's physical | ||
613 | // surrogate from rotating while moving | ||
614 | Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero); | ||
615 | d.JointAttach(Amotor, Body, IntPtr.Zero); | ||
616 | d.JointSetAMotorMode(Amotor, dAMotorEuler); | ||
617 | d.JointSetAMotorNumAxes(Amotor, 3); | ||
618 | d.JointSetAMotorAxis(Amotor, 0, 0, 1, 0, 0); | ||
619 | d.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0); | ||
620 | d.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1); | ||
621 | d.JointSetAMotorAngle(Amotor, 0, 0); | ||
622 | d.JointSetAMotorAngle(Amotor, 1, 0); | ||
623 | d.JointSetAMotorAngle(Amotor, 2, 0); | ||
624 | |||
625 | // These lowstops and high stops are effectively (no wiggle room) | ||
626 | if (_parent_scene.IsAvCapsuleTilted) | ||
627 | { | ||
628 | d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -0.000000000001f); | ||
629 | d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0.000000000001f); | ||
630 | d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -0.000000000001f); | ||
631 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.000000000001f); | ||
632 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0.000000000001f); | ||
633 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.000000000001f); | ||
634 | } | ||
635 | else | ||
636 | { | ||
637 | #region Documentation of capsule motor LowStop and HighStop parameters | ||
638 | // Intentionally introduce some tilt into the capsule by setting | ||
639 | // the motor stops to small epsilon values. This small tilt prevents | ||
640 | // the capsule from falling into the terrain; a straight-up capsule | ||
641 | // (with -0..0 motor stops) falls into the terrain for reasons yet | ||
642 | // to be comprehended in their entirety. | ||
643 | #endregion | ||
644 | AlignAvatarTiltWithCurrentDirectionOfMovement(Vector3.Zero); | ||
645 | d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, 0.08f); | ||
646 | d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0f); | ||
647 | d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, 0.08f); | ||
648 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.08f); // must be same as lowstop, else a different, spurious tilt is introduced | ||
649 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); // same as lowstop | ||
650 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.08f); // same as lowstop | ||
651 | } | ||
652 | |||
653 | // Fudge factor is 1f by default, we're setting it to 0. We don't want it to Fudge or the | ||
654 | // capped cyllinder will fall over | ||
655 | d.JointSetAMotorParam(Amotor, (int)dParam.FudgeFactor, 0f); | ||
656 | d.JointSetAMotorParam(Amotor, (int)dParam.FMax, tensor); | ||
657 | |||
658 | //d.Matrix3 bodyrotation = d.BodyGetRotation(Body); | ||
659 | //d.QfromR( | ||
660 | //d.Matrix3 checkrotation = new d.Matrix3(0.7071068,0.5, -0.7071068, | ||
661 | // | ||
662 | //m_log.Info("[PHYSICSAV]: Rotation: " + bodyrotation.M00 + " : " + bodyrotation.M01 + " : " + bodyrotation.M02 + " : " + bodyrotation.M10 + " : " + bodyrotation.M11 + " : " + bodyrotation.M12 + " : " + bodyrotation.M20 + " : " + bodyrotation.M21 + " : " + bodyrotation.M22); | ||
663 | //standupStraight(); | ||
664 | } | ||
665 | |||
666 | // | ||
667 | /// <summary> | ||
668 | /// Uses the capped cyllinder volume formula to calculate the avatar's mass. | 545 | /// Uses the capped cyllinder volume formula to calculate the avatar's mass. |
669 | /// This may be used in calculations in the scene/scenepresence | 546 | /// This may be used in calculations in the scene/scenepresence |
670 | /// </summary> | 547 | /// </summary> |
@@ -774,7 +651,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
774 | } | 651 | } |
775 | else | 652 | else |
776 | { | 653 | { |
777 | m_log.Warn("[PHYSICS]: Got a NaN velocity from Scene in a Character"); | 654 | m_log.WarnFormat("[ODE CHARACTER]: Got a NaN velocity from Scene for {0}", Name); |
778 | } | 655 | } |
779 | 656 | ||
780 | // m_log.DebugFormat("[PHYSICS]: Set target velocity of {0}", m_taintTargetVelocity); | 657 | // m_log.DebugFormat("[PHYSICS]: Set target velocity of {0}", m_taintTargetVelocity); |
@@ -836,7 +713,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
836 | m_taintForce += force; | 713 | m_taintForce += force; |
837 | _parent_scene.AddPhysicsActorTaint(this); | 714 | _parent_scene.AddPhysicsActorTaint(this); |
838 | 715 | ||
839 | //doForce(force); | ||
840 | // If uncommented, things get pushed off world | 716 | // If uncommented, things get pushed off world |
841 | // | 717 | // |
842 | // m_log.Debug("Push!"); | 718 | // m_log.Debug("Push!"); |
@@ -852,7 +728,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
852 | } | 728 | } |
853 | else | 729 | else |
854 | { | 730 | { |
855 | m_log.Warn("[PHYSICS]: Got a NaN force applied to a Character"); | 731 | m_log.WarnFormat("[ODE CHARACTER]: Got a NaN force applied to {0}", Name); |
856 | } | 732 | } |
857 | //m_lastUpdateSent = false; | 733 | //m_lastUpdateSent = false; |
858 | } | 734 | } |
@@ -861,15 +737,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
861 | { | 737 | { |
862 | } | 738 | } |
863 | 739 | ||
864 | /// <summary> | ||
865 | /// After all of the forces add up with 'add force' we apply them with doForce | ||
866 | /// </summary> | ||
867 | /// <param name="force"></param> | ||
868 | public void doForce(Vector3 force) | ||
869 | { | ||
870 | d.BodyAddForce(Body, force.X, force.Y, force.Z); | ||
871 | } | ||
872 | |||
873 | public override void SetMomentum(Vector3 momentum) | 740 | public override void SetMomentum(Vector3 momentum) |
874 | { | 741 | { |
875 | } | 742 | } |
@@ -878,9 +745,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
878 | /// Called from Simulate | 745 | /// Called from Simulate |
879 | /// This is the avatar's movement control + PID Controller | 746 | /// This is the avatar's movement control + PID Controller |
880 | /// </summary> | 747 | /// </summary> |
881 | /// <param name="defects"> | 748 | /// <param name="defects">The character will be added to this list if there is something wrong (non-finite |
882 | /// If there is something wrong with the character (e.g. its position is non-finite) | 749 | /// position or velocity). |
883 | /// then it is added to this list. The ODE structures associated with it are also destroyed. | ||
884 | /// </param> | 750 | /// </param> |
885 | internal void Move(List<OdeCharacter> defects) | 751 | internal void Move(List<OdeCharacter> defects) |
886 | { | 752 | { |
@@ -903,12 +769,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
903 | 769 | ||
904 | if (!localPos.IsFinite()) | 770 | if (!localPos.IsFinite()) |
905 | { | 771 | { |
906 | m_log.Warn("[PHYSICS]: Avatar Position is non-finite!"); | 772 | m_log.WarnFormat( |
773 | "[ODE CHARACTER]: Avatar position of {0} for {1} is non-finite! Removing from physics scene.", | ||
774 | localPos, Name); | ||
907 | 775 | ||
908 | defects.Add(this); | 776 | defects.Add(this); |
909 | // _parent_scene.RemoveCharacter(this); | ||
910 | |||
911 | DestroyOdeStructures(); | ||
912 | 777 | ||
913 | return; | 778 | return; |
914 | } | 779 | } |
@@ -1035,26 +900,31 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1035 | 900 | ||
1036 | if (vec.IsFinite()) | 901 | if (vec.IsFinite()) |
1037 | { | 902 | { |
1038 | doForce(vec); | 903 | // Apply the total force acting on this avatar |
904 | d.BodyAddForce(Body, vec.X, vec.Y, vec.Z); | ||
1039 | 905 | ||
1040 | if (!_zeroFlag) | 906 | if (!_zeroFlag) |
1041 | AlignAvatarTiltWithCurrentDirectionOfMovement(vec); | 907 | AlignAvatarTiltWithCurrentDirectionOfMovement(vec); |
1042 | } | 908 | } |
1043 | else | 909 | else |
1044 | { | 910 | { |
1045 | m_log.Warn("[PHYSICS]: Got a NaN force vector in Move()"); | 911 | m_log.WarnFormat( |
1046 | m_log.Warn("[PHYSICS]: Avatar Position is non-finite!"); | 912 | "[ODE CHARACTER]: Got a NaN force vector {0} in Move() for {1}. Removing character from physics scene.", |
913 | vec, Name); | ||
914 | |||
1047 | defects.Add(this); | 915 | defects.Add(this); |
1048 | // _parent_scene.RemoveCharacter(this); | ||
1049 | 916 | ||
1050 | DestroyOdeStructures(); | 917 | return; |
1051 | } | 918 | } |
1052 | } | 919 | } |
1053 | 920 | ||
1054 | /// <summary> | 921 | /// <summary> |
1055 | /// Updates the reported position and velocity. This essentially sends the data up to ScenePresence. | 922 | /// Updates the reported position and velocity. This essentially sends the data up to ScenePresence. |
1056 | /// </summary> | 923 | /// </summary> |
1057 | internal void UpdatePositionAndVelocity() | 924 | /// <param name="defects">The character will be added to this list if there is something wrong (non-finite |
925 | /// position or velocity). | ||
926 | /// </param> | ||
927 | internal void UpdatePositionAndVelocity(List<OdeCharacter> defects) | ||
1058 | { | 928 | { |
1059 | // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! | 929 | // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! |
1060 | d.Vector3 newPos; | 930 | d.Vector3 newPos; |
@@ -1065,10 +935,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1065 | catch (NullReferenceException) | 935 | catch (NullReferenceException) |
1066 | { | 936 | { |
1067 | bad = true; | 937 | bad = true; |
1068 | _parent_scene.BadCharacter(this); | 938 | defects.Add(this); |
1069 | newPos = new d.Vector3(_position.X, _position.Y, _position.Z); | 939 | newPos = new d.Vector3(_position.X, _position.Y, _position.Z); |
1070 | base.RaiseOutOfBounds(_position); // Tells ScenePresence that there's a problem! | 940 | base.RaiseOutOfBounds(_position); // Tells ScenePresence that there's a problem! |
1071 | m_log.WarnFormat("[ODEPLUGIN]: Avatar Null reference for Avatar {0}, physical actor {1}", m_name, m_uuid); | 941 | m_log.WarnFormat("[ODE CHARACTER]: Avatar Null reference for Avatar {0}, physical actor {1}", Name, m_uuid); |
942 | |||
943 | return; | ||
1072 | } | 944 | } |
1073 | 945 | ||
1074 | // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!) | 946 | // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!) |
@@ -1137,6 +1009,123 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1137 | } | 1009 | } |
1138 | 1010 | ||
1139 | /// <summary> | 1011 | /// <summary> |
1012 | /// This creates the Avatar's physical Surrogate in ODE at the position supplied | ||
1013 | /// </summary> | ||
1014 | /// <remarks> | ||
1015 | /// WARNING: This MUST NOT be called outside of ProcessTaints, else we can have unsynchronized access | ||
1016 | /// to ODE internals. ProcessTaints is called from within thread-locked Simulate(), so it is the only | ||
1017 | /// place that is safe to call this routine AvatarGeomAndBodyCreation. | ||
1018 | /// </remarks> | ||
1019 | /// <param name="npositionX"></param> | ||
1020 | /// <param name="npositionY"></param> | ||
1021 | /// <param name="npositionZ"></param> | ||
1022 | /// <param name="tensor"></param> | ||
1023 | private void CreateOdeStructures(float npositionX, float npositionY, float npositionZ, float tensor) | ||
1024 | { | ||
1025 | int dAMotorEuler = 1; | ||
1026 | // _parent_scene.waitForSpaceUnlock(_parent_scene.space); | ||
1027 | if (CAPSULE_LENGTH <= 0) | ||
1028 | { | ||
1029 | m_log.Warn("[ODE CHARACTER]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!"); | ||
1030 | CAPSULE_LENGTH = 0.01f; | ||
1031 | } | ||
1032 | |||
1033 | if (CAPSULE_RADIUS <= 0) | ||
1034 | { | ||
1035 | m_log.Warn("[ODE CHARACTER]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!"); | ||
1036 | CAPSULE_RADIUS = 0.01f; | ||
1037 | } | ||
1038 | |||
1039 | Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH); | ||
1040 | |||
1041 | d.GeomSetCategoryBits(Shell, (int)m_collisionCategories); | ||
1042 | d.GeomSetCollideBits(Shell, (int)m_collisionFlags); | ||
1043 | |||
1044 | d.MassSetCapsuleTotal(out ShellMass, m_mass, 2, CAPSULE_RADIUS, CAPSULE_LENGTH); | ||
1045 | Body = d.BodyCreate(_parent_scene.world); | ||
1046 | d.BodySetPosition(Body, npositionX, npositionY, npositionZ); | ||
1047 | |||
1048 | _position.X = npositionX; | ||
1049 | _position.Y = npositionY; | ||
1050 | _position.Z = npositionZ; | ||
1051 | |||
1052 | m_taintPosition = _position; | ||
1053 | |||
1054 | d.BodySetMass(Body, ref ShellMass); | ||
1055 | d.Matrix3 m_caprot; | ||
1056 | // 90 Stand up on the cap of the capped cyllinder | ||
1057 | if (_parent_scene.IsAvCapsuleTilted) | ||
1058 | { | ||
1059 | d.RFromAxisAndAngle(out m_caprot, 1, 0, 1, (float)(Math.PI / 2)); | ||
1060 | } | ||
1061 | else | ||
1062 | { | ||
1063 | d.RFromAxisAndAngle(out m_caprot, 0, 0, 1, (float)(Math.PI / 2)); | ||
1064 | } | ||
1065 | |||
1066 | d.GeomSetRotation(Shell, ref m_caprot); | ||
1067 | d.BodySetRotation(Body, ref m_caprot); | ||
1068 | |||
1069 | d.GeomSetBody(Shell, Body); | ||
1070 | |||
1071 | // The purpose of the AMotor here is to keep the avatar's physical | ||
1072 | // surrogate from rotating while moving | ||
1073 | Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero); | ||
1074 | d.JointAttach(Amotor, Body, IntPtr.Zero); | ||
1075 | d.JointSetAMotorMode(Amotor, dAMotorEuler); | ||
1076 | d.JointSetAMotorNumAxes(Amotor, 3); | ||
1077 | d.JointSetAMotorAxis(Amotor, 0, 0, 1, 0, 0); | ||
1078 | d.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0); | ||
1079 | d.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1); | ||
1080 | d.JointSetAMotorAngle(Amotor, 0, 0); | ||
1081 | d.JointSetAMotorAngle(Amotor, 1, 0); | ||
1082 | d.JointSetAMotorAngle(Amotor, 2, 0); | ||
1083 | |||
1084 | // These lowstops and high stops are effectively (no wiggle room) | ||
1085 | if (_parent_scene.IsAvCapsuleTilted) | ||
1086 | { | ||
1087 | d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -0.000000000001f); | ||
1088 | d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0.000000000001f); | ||
1089 | d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -0.000000000001f); | ||
1090 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.000000000001f); | ||
1091 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0.000000000001f); | ||
1092 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.000000000001f); | ||
1093 | } | ||
1094 | else | ||
1095 | { | ||
1096 | #region Documentation of capsule motor LowStop and HighStop parameters | ||
1097 | // Intentionally introduce some tilt into the capsule by setting | ||
1098 | // the motor stops to small epsilon values. This small tilt prevents | ||
1099 | // the capsule from falling into the terrain; a straight-up capsule | ||
1100 | // (with -0..0 motor stops) falls into the terrain for reasons yet | ||
1101 | // to be comprehended in their entirety. | ||
1102 | #endregion | ||
1103 | AlignAvatarTiltWithCurrentDirectionOfMovement(Vector3.Zero); | ||
1104 | d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, 0.08f); | ||
1105 | d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0f); | ||
1106 | d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, 0.08f); | ||
1107 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.08f); // must be same as lowstop, else a different, spurious tilt is introduced | ||
1108 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); // same as lowstop | ||
1109 | d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.08f); // same as lowstop | ||
1110 | } | ||
1111 | |||
1112 | // Fudge factor is 1f by default, we're setting it to 0. We don't want it to Fudge or the | ||
1113 | // capped cyllinder will fall over | ||
1114 | d.JointSetAMotorParam(Amotor, (int)dParam.FudgeFactor, 0f); | ||
1115 | d.JointSetAMotorParam(Amotor, (int)dParam.FMax, tensor); | ||
1116 | |||
1117 | //d.Matrix3 bodyrotation = d.BodyGetRotation(Body); | ||
1118 | //d.QfromR( | ||
1119 | //d.Matrix3 checkrotation = new d.Matrix3(0.7071068,0.5, -0.7071068, | ||
1120 | // | ||
1121 | //m_log.Info("[PHYSICSAV]: Rotation: " + bodyrotation.M00 + " : " + bodyrotation.M01 + " : " + bodyrotation.M02 + " : " + bodyrotation.M10 + " : " + bodyrotation.M11 + " : " + bodyrotation.M12 + " : " + bodyrotation.M20 + " : " + bodyrotation.M21 + " : " + bodyrotation.M22); | ||
1122 | //standupStraight(); | ||
1123 | |||
1124 | _parent_scene.geom_name_map[Shell] = Name; | ||
1125 | _parent_scene.actor_name_map[Shell] = this; | ||
1126 | } | ||
1127 | |||
1128 | /// <summary> | ||
1140 | /// Cleanup the things we use in the scene. | 1129 | /// Cleanup the things we use in the scene. |
1141 | /// </summary> | 1130 | /// </summary> |
1142 | internal void Destroy() | 1131 | internal void Destroy() |
@@ -1148,7 +1137,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1148 | /// <summary> | 1137 | /// <summary> |
1149 | /// Used internally to destroy the ODE structures associated with this character. | 1138 | /// Used internally to destroy the ODE structures associated with this character. |
1150 | /// </summary> | 1139 | /// </summary> |
1151 | private void DestroyOdeStructures() | 1140 | internal void DestroyOdeStructures() |
1152 | { | 1141 | { |
1153 | // destroy avatar capsule and related ODE data | 1142 | // destroy avatar capsule and related ODE data |
1154 | if (Amotor != IntPtr.Zero) | 1143 | if (Amotor != IntPtr.Zero) |
@@ -1159,13 +1148,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1159 | } | 1148 | } |
1160 | 1149 | ||
1161 | //kill the Geometry | 1150 | //kill the Geometry |
1162 | _parent_scene.waitForSpaceUnlock(_parent_scene.space); | 1151 | // _parent_scene.waitForSpaceUnlock(_parent_scene.space); |
1163 | 1152 | ||
1164 | if (Body != IntPtr.Zero) | 1153 | if (Body != IntPtr.Zero) |
1165 | { | 1154 | { |
1166 | //kill the body | 1155 | //kill the body |
1167 | d.BodyDestroy(Body); | 1156 | d.BodyDestroy(Body); |
1168 | |||
1169 | Body = IntPtr.Zero; | 1157 | Body = IntPtr.Zero; |
1170 | } | 1158 | } |
1171 | 1159 | ||
@@ -1173,6 +1161,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1173 | { | 1161 | { |
1174 | d.GeomDestroy(Shell); | 1162 | d.GeomDestroy(Shell); |
1175 | _parent_scene.geom_name_map.Remove(Shell); | 1163 | _parent_scene.geom_name_map.Remove(Shell); |
1164 | _parent_scene.actor_name_map.Remove(Shell); | ||
1165 | |||
1176 | Shell = IntPtr.Zero; | 1166 | Shell = IntPtr.Zero; |
1177 | } | 1167 | } |
1178 | } | 1168 | } |
@@ -1261,7 +1251,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1261 | // FIXME: This is not a good solution since it's subject to a race condition if a force is another | 1251 | // FIXME: This is not a good solution since it's subject to a race condition if a force is another |
1262 | // thread sets a new force while we're in this loop (since it could be obliterated by | 1252 | // thread sets a new force while we're in this loop (since it could be obliterated by |
1263 | // m_taintForce = Vector3.Zero. Need to lock ProcessTaints() when we set a new tainted force. | 1253 | // m_taintForce = Vector3.Zero. Need to lock ProcessTaints() when we set a new tainted force. |
1264 | doForce(m_taintForce); | 1254 | d.BodyAddForce(Body, m_taintForce.X, m_taintForce.Y, m_taintForce.Z); |
1265 | } | 1255 | } |
1266 | 1256 | ||
1267 | m_taintForce = Vector3.Zero; | 1257 | m_taintForce = Vector3.Zero; |
@@ -1277,15 +1267,13 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1277 | // Create avatar capsule and related ODE data | 1267 | // Create avatar capsule and related ODE data |
1278 | if (!(Shell == IntPtr.Zero && Body == IntPtr.Zero && Amotor == IntPtr.Zero)) | 1268 | if (!(Shell == IntPtr.Zero && Body == IntPtr.Zero && Amotor == IntPtr.Zero)) |
1279 | { | 1269 | { |
1280 | m_log.Warn("[PHYSICS]: re-creating the following avatar ODE data, even though it already exists - " | 1270 | m_log.Warn("[ODE CHARACTER]: re-creating the following avatar ODE data for " + Name + ", even though it already exists - " |
1281 | + (Shell!=IntPtr.Zero ? "Shell ":"") | 1271 | + (Shell!=IntPtr.Zero ? "Shell ":"") |
1282 | + (Body!=IntPtr.Zero ? "Body ":"") | 1272 | + (Body!=IntPtr.Zero ? "Body ":"") |
1283 | + (Amotor!=IntPtr.Zero ? "Amotor ":"")); | 1273 | + (Amotor!=IntPtr.Zero ? "Amotor ":"")); |
1284 | } | 1274 | } |
1285 | AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z, m_tensor); | 1275 | |
1286 | 1276 | CreateOdeStructures(_position.X, _position.Y, _position.Z, m_tensor); | |
1287 | _parent_scene.geom_name_map[Shell] = m_name; | ||
1288 | _parent_scene.actor_name_map[Shell] = (PhysicsActor)this; | ||
1289 | _parent_scene.AddCharacter(this); | 1277 | _parent_scene.AddCharacter(this); |
1290 | } | 1278 | } |
1291 | else | 1279 | else |
@@ -1301,17 +1289,19 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1301 | { | 1289 | { |
1302 | if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero) | 1290 | if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero) |
1303 | { | 1291 | { |
1304 | // m_log.DebugFormat("[PHYSICS]: Changing capsule size"); | 1292 | // m_log.DebugFormat( |
1293 | // "[ODE CHARACTER]: Changing capsule size from {0} to {1} for {2}", | ||
1294 | // CAPSULE_LENGTH, m_tainted_CAPSULE_LENGTH, Name); | ||
1305 | 1295 | ||
1306 | m_pidControllerActive = true; | 1296 | m_pidControllerActive = true; |
1297 | |||
1307 | // no lock needed on _parent_scene.OdeLock because we are called from within the thread lock in OdePlugin's simulate() | 1298 | // no lock needed on _parent_scene.OdeLock because we are called from within the thread lock in OdePlugin's simulate() |
1308 | d.JointDestroy(Amotor); | 1299 | DestroyOdeStructures(); |
1300 | |||
1309 | float prevCapsule = CAPSULE_LENGTH; | 1301 | float prevCapsule = CAPSULE_LENGTH; |
1310 | CAPSULE_LENGTH = m_tainted_CAPSULE_LENGTH; | 1302 | CAPSULE_LENGTH = m_tainted_CAPSULE_LENGTH; |
1311 | //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); | 1303 | |
1312 | d.BodyDestroy(Body); | 1304 | CreateOdeStructures( |
1313 | d.GeomDestroy(Shell); | ||
1314 | AvatarGeomAndBodyCreation( | ||
1315 | _position.X, | 1305 | _position.X, |
1316 | _position.Y, | 1306 | _position.Y, |
1317 | _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2), m_tensor); | 1307 | _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2), m_tensor); |
@@ -1319,13 +1309,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1319 | // As with Size, we reset velocity. However, this isn't strictly necessary since it doesn't | 1309 | // As with Size, we reset velocity. However, this isn't strictly necessary since it doesn't |
1320 | // appear to stall initial region crossings when done here. Being done for consistency. | 1310 | // appear to stall initial region crossings when done here. Being done for consistency. |
1321 | // Velocity = Vector3.Zero; | 1311 | // Velocity = Vector3.Zero; |
1322 | |||
1323 | _parent_scene.geom_name_map[Shell] = m_name; | ||
1324 | _parent_scene.actor_name_map[Shell] = (PhysicsActor)this; | ||
1325 | } | 1312 | } |
1326 | else | 1313 | else |
1327 | { | 1314 | { |
1328 | m_log.Warn("[PHYSICS]: trying to change capsule size, but the following ODE data is missing - " | 1315 | m_log.Warn("[ODE CHARACTER]: trying to change capsule size for " + Name + ", but the following ODE data is missing - " |
1329 | + (Shell==IntPtr.Zero ? "Shell ":"") | 1316 | + (Shell==IntPtr.Zero ? "Shell ":"") |
1330 | + (Body==IntPtr.Zero ? "Body ":"") | 1317 | + (Body==IntPtr.Zero ? "Body ":"") |
1331 | + (Amotor==IntPtr.Zero ? "Amotor ":"")); | 1318 | + (Amotor==IntPtr.Zero ? "Amotor ":"")); |
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index f07cf46..af05a15 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | |||
@@ -184,7 +184,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
184 | private bool m_lastUpdateSent; | 184 | private bool m_lastUpdateSent; |
185 | 185 | ||
186 | public IntPtr Body = IntPtr.Zero; | 186 | public IntPtr Body = IntPtr.Zero; |
187 | public String Name { get; private set; } | ||
188 | private Vector3 _target_velocity; | 187 | private Vector3 _target_velocity; |
189 | private d.Mass pMass; | 188 | private d.Mass pMass; |
190 | 189 | ||
@@ -273,7 +272,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
273 | 272 | ||
274 | m_taintadd = true; | 273 | m_taintadd = true; |
275 | _parent_scene.AddPhysicsActorTaint(this); | 274 | _parent_scene.AddPhysicsActorTaint(this); |
276 | // don't do .add() here; old geoms get recycled with the same hash | ||
277 | } | 275 | } |
278 | 276 | ||
279 | public override int PhysicsActorType | 277 | public override int PhysicsActorType |
@@ -857,7 +855,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
857 | m_MeshToTriMeshMap[mesh] = _triMeshData; | 855 | m_MeshToTriMeshMap[mesh] = _triMeshData; |
858 | } | 856 | } |
859 | 857 | ||
860 | _parent_scene.waitForSpaceUnlock(m_targetSpace); | 858 | // _parent_scene.waitForSpaceUnlock(m_targetSpace); |
861 | try | 859 | try |
862 | { | 860 | { |
863 | if (prim_geom == IntPtr.Zero) | 861 | if (prim_geom == IntPtr.Zero) |
@@ -1380,7 +1378,7 @@ Console.WriteLine("CreateGeom:"); | |||
1380 | { | 1378 | { |
1381 | if (((_size.X / 2f) > 0f)) | 1379 | if (((_size.X / 2f) > 0f)) |
1382 | { | 1380 | { |
1383 | _parent_scene.waitForSpaceUnlock(m_targetSpace); | 1381 | // _parent_scene.waitForSpaceUnlock(m_targetSpace); |
1384 | try | 1382 | try |
1385 | { | 1383 | { |
1386 | //Console.WriteLine(" CreateGeom 1"); | 1384 | //Console.WriteLine(" CreateGeom 1"); |
@@ -1394,7 +1392,7 @@ Console.WriteLine("CreateGeom:"); | |||
1394 | } | 1392 | } |
1395 | else | 1393 | else |
1396 | { | 1394 | { |
1397 | _parent_scene.waitForSpaceUnlock(m_targetSpace); | 1395 | // _parent_scene.waitForSpaceUnlock(m_targetSpace); |
1398 | try | 1396 | try |
1399 | { | 1397 | { |
1400 | //Console.WriteLine(" CreateGeom 2"); | 1398 | //Console.WriteLine(" CreateGeom 2"); |
@@ -1409,7 +1407,7 @@ Console.WriteLine("CreateGeom:"); | |||
1409 | } | 1407 | } |
1410 | else | 1408 | else |
1411 | { | 1409 | { |
1412 | _parent_scene.waitForSpaceUnlock(m_targetSpace); | 1410 | // _parent_scene.waitForSpaceUnlock(m_targetSpace); |
1413 | try | 1411 | try |
1414 | { | 1412 | { |
1415 | //Console.WriteLine(" CreateGeom 3"); | 1413 | //Console.WriteLine(" CreateGeom 3"); |
@@ -1424,7 +1422,7 @@ Console.WriteLine("CreateGeom:"); | |||
1424 | } | 1422 | } |
1425 | else | 1423 | else |
1426 | { | 1424 | { |
1427 | _parent_scene.waitForSpaceUnlock(m_targetSpace); | 1425 | // _parent_scene.waitForSpaceUnlock(m_targetSpace); |
1428 | try | 1426 | try |
1429 | { | 1427 | { |
1430 | //Console.WriteLine(" CreateGeom 4"); | 1428 | //Console.WriteLine(" CreateGeom 4"); |
@@ -1577,17 +1575,17 @@ Console.WriteLine(" JointCreateFixed"); | |||
1577 | { | 1575 | { |
1578 | // string primScenAvatarIn = _parent_scene.whichspaceamIin(_position); | 1576 | // string primScenAvatarIn = _parent_scene.whichspaceamIin(_position); |
1579 | // int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position); | 1577 | // int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position); |
1580 | _parent_scene.waitForSpaceUnlock(m_targetSpace); | 1578 | // _parent_scene.waitForSpaceUnlock(m_targetSpace); |
1581 | 1579 | ||
1582 | IntPtr tempspace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position, m_targetSpace); | 1580 | IntPtr tempspace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position, m_targetSpace); |
1583 | m_targetSpace = tempspace; | 1581 | m_targetSpace = tempspace; |
1584 | 1582 | ||
1585 | _parent_scene.waitForSpaceUnlock(m_targetSpace); | 1583 | // _parent_scene.waitForSpaceUnlock(m_targetSpace); |
1586 | if (prim_geom != IntPtr.Zero) | 1584 | if (prim_geom != IntPtr.Zero) |
1587 | { | 1585 | { |
1588 | d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); | 1586 | d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); |
1589 | 1587 | ||
1590 | _parent_scene.waitForSpaceUnlock(m_targetSpace); | 1588 | // _parent_scene.waitForSpaceUnlock(m_targetSpace); |
1591 | d.SpaceAdd(m_targetSpace, prim_geom); | 1589 | d.SpaceAdd(m_targetSpace, prim_geom); |
1592 | } | 1590 | } |
1593 | } | 1591 | } |
@@ -1978,7 +1976,7 @@ Console.WriteLine(" JointCreateFixed"); | |||
1978 | 1976 | ||
1979 | if (d.SpaceQuery(m_targetSpace, prim_geom)) | 1977 | if (d.SpaceQuery(m_targetSpace, prim_geom)) |
1980 | { | 1978 | { |
1981 | _parent_scene.waitForSpaceUnlock(m_targetSpace); | 1979 | // _parent_scene.waitForSpaceUnlock(m_targetSpace); |
1982 | d.SpaceRemove(m_targetSpace, prim_geom); | 1980 | d.SpaceRemove(m_targetSpace, prim_geom); |
1983 | } | 1981 | } |
1984 | 1982 | ||
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 43d852b..0456f56 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs | |||
@@ -188,8 +188,20 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
188 | private d.NearCallback nearCallback; | 188 | private d.NearCallback nearCallback; |
189 | public d.TriCallback triCallback; | 189 | public d.TriCallback triCallback; |
190 | public d.TriArrayCallback triArrayCallback; | 190 | public d.TriArrayCallback triArrayCallback; |
191 | |||
192 | /// <summary> | ||
193 | /// Avatars in the physics scene. | ||
194 | /// </summary> | ||
191 | private readonly HashSet<OdeCharacter> _characters = new HashSet<OdeCharacter>(); | 195 | private readonly HashSet<OdeCharacter> _characters = new HashSet<OdeCharacter>(); |
196 | |||
197 | /// <summary> | ||
198 | /// Prims in the physics scene. | ||
199 | /// </summary> | ||
192 | private readonly HashSet<OdePrim> _prims = new HashSet<OdePrim>(); | 200 | private readonly HashSet<OdePrim> _prims = new HashSet<OdePrim>(); |
201 | |||
202 | /// <summary> | ||
203 | /// Prims in the physics scene that are subject to physics, not just collisions. | ||
204 | /// </summary> | ||
193 | private readonly HashSet<OdePrim> _activeprims = new HashSet<OdePrim>(); | 205 | private readonly HashSet<OdePrim> _activeprims = new HashSet<OdePrim>(); |
194 | 206 | ||
195 | /// <summary> | 207 | /// <summary> |
@@ -215,7 +227,14 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
215 | /// </remarks> | 227 | /// </remarks> |
216 | private readonly HashSet<OdePrim> _taintedPrimH = new HashSet<OdePrim>(); | 228 | private readonly HashSet<OdePrim> _taintedPrimH = new HashSet<OdePrim>(); |
217 | 229 | ||
230 | /// <summary> | ||
231 | /// Record a character that has taints to be processed. | ||
232 | /// </summary> | ||
218 | private readonly HashSet<OdeCharacter> _taintedActors = new HashSet<OdeCharacter>(); | 233 | private readonly HashSet<OdeCharacter> _taintedActors = new HashSet<OdeCharacter>(); |
234 | |||
235 | /// <summary> | ||
236 | /// Keep record of contacts in the physics loop so that we can remove duplicates. | ||
237 | /// </summary> | ||
219 | private readonly List<d.ContactGeom> _perloopContact = new List<d.ContactGeom>(); | 238 | private readonly List<d.ContactGeom> _perloopContact = new List<d.ContactGeom>(); |
220 | 239 | ||
221 | /// <summary> | 240 | /// <summary> |
@@ -227,18 +246,58 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
227 | /// A dictionary of collision event changes that are waiting to be processed. | 246 | /// A dictionary of collision event changes that are waiting to be processed. |
228 | /// </summary> | 247 | /// </summary> |
229 | private readonly Dictionary<uint, PhysicsActor> _collisionEventPrimChanges = new Dictionary<uint, PhysicsActor>(); | 248 | private readonly Dictionary<uint, PhysicsActor> _collisionEventPrimChanges = new Dictionary<uint, PhysicsActor>(); |
230 | 249 | ||
231 | private readonly HashSet<OdeCharacter> _badCharacter = new HashSet<OdeCharacter>(); | 250 | /// <summary> |
251 | /// Maps a unique geometry id (a memory location) to a physics actor name. | ||
252 | /// </summary> | ||
253 | /// <remarks> | ||
254 | /// Only actors participating in collisions have geometries. This has to be maintained separately from | ||
255 | /// actor_name_map because terrain and water currently don't conceptually have a physics actor of their own | ||
256 | /// apart from the singleton PANull | ||
257 | /// </remarks> | ||
232 | public Dictionary<IntPtr, String> geom_name_map = new Dictionary<IntPtr, String>(); | 258 | public Dictionary<IntPtr, String> geom_name_map = new Dictionary<IntPtr, String>(); |
259 | |||
260 | /// <summary> | ||
261 | /// Maps a unique geometry id (a memory location) to a physics actor. | ||
262 | /// </summary> | ||
263 | /// <remarks> | ||
264 | /// Only actors participating in collisions have geometries. | ||
265 | /// </remarks> | ||
233 | public Dictionary<IntPtr, PhysicsActor> actor_name_map = new Dictionary<IntPtr, PhysicsActor>(); | 266 | public Dictionary<IntPtr, PhysicsActor> actor_name_map = new Dictionary<IntPtr, PhysicsActor>(); |
267 | |||
268 | /// <summary> | ||
269 | /// Defects list to remove characters that no longer have finite positions due to some other bug. | ||
270 | /// </summary> | ||
271 | /// <remarks> | ||
272 | /// Used repeatedly in Simulate() but initialized once here. | ||
273 | /// </remarks> | ||
274 | private readonly List<OdeCharacter> defects = new List<OdeCharacter>(); | ||
275 | |||
234 | private bool m_NINJA_physics_joints_enabled = false; | 276 | private bool m_NINJA_physics_joints_enabled = false; |
235 | //private Dictionary<String, IntPtr> jointpart_name_map = new Dictionary<String,IntPtr>(); | 277 | //private Dictionary<String, IntPtr> jointpart_name_map = new Dictionary<String,IntPtr>(); |
236 | private readonly Dictionary<String, List<PhysicsJoint>> joints_connecting_actor = new Dictionary<String, List<PhysicsJoint>>(); | 278 | private readonly Dictionary<String, List<PhysicsJoint>> joints_connecting_actor = new Dictionary<String, List<PhysicsJoint>>(); |
237 | private d.ContactGeom[] contacts; | 279 | private d.ContactGeom[] contacts; |
238 | private readonly List<PhysicsJoint> requestedJointsToBeCreated = new List<PhysicsJoint>(); // lock only briefly. accessed by external code (to request new joints) and by OdeScene.Simulate() to move those joints into pending/active | 280 | |
239 | private readonly List<PhysicsJoint> pendingJoints = new List<PhysicsJoint>(); // can lock for longer. accessed only by OdeScene. | 281 | /// <summary> |
240 | private readonly List<PhysicsJoint> activeJoints = new List<PhysicsJoint>(); // can lock for longer. accessed only by OdeScene. | 282 | /// Lock only briefly. accessed by external code (to request new joints) and by OdeScene.Simulate() to move those joints into pending/active |
241 | private readonly List<string> requestedJointsToBeDeleted = new List<string>(); // lock only briefly. accessed by external code (to request deletion of joints) and by OdeScene.Simulate() to move those joints out of pending/active | 283 | /// </summary> |
284 | private readonly List<PhysicsJoint> requestedJointsToBeCreated = new List<PhysicsJoint>(); | ||
285 | |||
286 | /// <summary> | ||
287 | /// can lock for longer. accessed only by OdeScene. | ||
288 | /// </summary> | ||
289 | private readonly List<PhysicsJoint> pendingJoints = new List<PhysicsJoint>(); | ||
290 | |||
291 | /// <summary> | ||
292 | /// can lock for longer. accessed only by OdeScene. | ||
293 | /// </summary> | ||
294 | private readonly List<PhysicsJoint> activeJoints = new List<PhysicsJoint>(); | ||
295 | |||
296 | /// <summary> | ||
297 | /// lock only briefly. accessed by external code (to request deletion of joints) and by OdeScene.Simulate() to move those joints out of pending/active | ||
298 | /// </summary> | ||
299 | private readonly List<string> requestedJointsToBeDeleted = new List<string>(); | ||
300 | |||
242 | private Object externalJointRequestsLock = new Object(); | 301 | private Object externalJointRequestsLock = new Object(); |
243 | private readonly Dictionary<String, PhysicsJoint> SOPName_to_activeJoint = new Dictionary<String, PhysicsJoint>(); | 302 | private readonly Dictionary<String, PhysicsJoint> SOPName_to_activeJoint = new Dictionary<String, PhysicsJoint>(); |
244 | private readonly Dictionary<String, PhysicsJoint> SOPName_to_pendingJoint = new Dictionary<String, PhysicsJoint>(); | 303 | private readonly Dictionary<String, PhysicsJoint> SOPName_to_pendingJoint = new Dictionary<String, PhysicsJoint>(); |
@@ -318,8 +377,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
318 | /// <param value="name">Name of the scene. Useful in debug messages.</param> | 377 | /// <param value="name">Name of the scene. Useful in debug messages.</param> |
319 | public OdeScene(string name) | 378 | public OdeScene(string name) |
320 | { | 379 | { |
321 | m_log | 380 | m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType.ToString() + "." + name); |
322 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType.ToString() + "." + name); | ||
323 | 381 | ||
324 | Name = name; | 382 | Name = name; |
325 | 383 | ||
@@ -663,11 +721,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
663 | } | 721 | } |
664 | } | 722 | } |
665 | 723 | ||
666 | internal void waitForSpaceUnlock(IntPtr space) | 724 | // internal void waitForSpaceUnlock(IntPtr space) |
667 | { | 725 | // { |
668 | //if (space != IntPtr.Zero) | 726 | // //if (space != IntPtr.Zero) |
669 | //while (d.SpaceLockQuery(space)) { } // Wait and do nothing | 727 | // //while (d.SpaceLockQuery(space)) { } // Wait and do nothing |
670 | } | 728 | // } |
671 | 729 | ||
672 | // /// <summary> | 730 | // /// <summary> |
673 | // /// Debug space message for printing the space that a prim/avatar is in. | 731 | // /// Debug space message for printing the space that a prim/avatar is in. |
@@ -710,7 +768,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
710 | } | 768 | } |
711 | catch (AccessViolationException) | 769 | catch (AccessViolationException) |
712 | { | 770 | { |
713 | m_log.Warn("[PHYSICS]: Unable to collide test a space"); | 771 | m_log.Warn("[ODE SCENE]: Unable to collide test a space"); |
714 | return; | 772 | return; |
715 | } | 773 | } |
716 | //Colliding a space or a geom with a space or a geom. so drill down | 774 | //Colliding a space or a geom with a space or a geom. so drill down |
@@ -760,22 +818,19 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
760 | if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) | 818 | if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) |
761 | return; | 819 | return; |
762 | 820 | ||
763 | lock (contacts) | 821 | count = d.Collide(g1, g2, contacts.Length, contacts, d.ContactGeom.SizeOf); |
764 | { | 822 | if (count > contacts.Length) |
765 | count = d.Collide(g1, g2, contacts.Length, contacts, d.ContactGeom.SizeOf); | 823 | m_log.Error("[ODE SCENE]: Got " + count + " contacts when we asked for a maximum of " + contacts.Length); |
766 | if (count > contacts.Length) | ||
767 | m_log.Error("[PHYSICS]: Got " + count + " contacts when we asked for a maximum of " + contacts.Length); | ||
768 | } | ||
769 | } | 824 | } |
770 | catch (SEHException) | 825 | catch (SEHException) |
771 | { | 826 | { |
772 | m_log.Error( | 827 | m_log.Error( |
773 | "[PHYSICS]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim."); | 828 | "[ODE SCENE]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim."); |
774 | base.TriggerPhysicsBasedRestart(); | 829 | base.TriggerPhysicsBasedRestart(); |
775 | } | 830 | } |
776 | catch (Exception e) | 831 | catch (Exception e) |
777 | { | 832 | { |
778 | m_log.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e.Message); | 833 | m_log.WarnFormat("[ODE SCENE]: Unable to collide test an object: {0}", e.Message); |
779 | return; | 834 | return; |
780 | } | 835 | } |
781 | 836 | ||
@@ -1029,6 +1084,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1029 | 1084 | ||
1030 | if (!skipThisContact) | 1085 | if (!skipThisContact) |
1031 | { | 1086 | { |
1087 | _perloopContact.Add(curContact); | ||
1088 | |||
1032 | // If we're colliding against terrain | 1089 | // If we're colliding against terrain |
1033 | if (name1 == "Terrain" || name2 == "Terrain") | 1090 | if (name1 == "Terrain" || name2 == "Terrain") |
1034 | { | 1091 | { |
@@ -1038,7 +1095,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1038 | { | 1095 | { |
1039 | // Use the movement terrain contact | 1096 | // Use the movement terrain contact |
1040 | AvatarMovementTerrainContact.geom = curContact; | 1097 | AvatarMovementTerrainContact.geom = curContact; |
1041 | _perloopContact.Add(curContact); | 1098 | |
1042 | if (m_global_contactcount < maxContactsbeforedeath) | 1099 | if (m_global_contactcount < maxContactsbeforedeath) |
1043 | { | 1100 | { |
1044 | joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact); | 1101 | joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact); |
@@ -1051,7 +1108,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1051 | { | 1108 | { |
1052 | // Use the non moving terrain contact | 1109 | // Use the non moving terrain contact |
1053 | TerrainContact.geom = curContact; | 1110 | TerrainContact.geom = curContact; |
1054 | _perloopContact.Add(curContact); | 1111 | |
1055 | if (m_global_contactcount < maxContactsbeforedeath) | 1112 | if (m_global_contactcount < maxContactsbeforedeath) |
1056 | { | 1113 | { |
1057 | joint = d.JointCreateContact(world, contactgroup, ref TerrainContact); | 1114 | joint = d.JointCreateContact(world, contactgroup, ref TerrainContact); |
@@ -1077,7 +1134,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1077 | 1134 | ||
1078 | //m_log.DebugFormat("Material: {0}", material); | 1135 | //m_log.DebugFormat("Material: {0}", material); |
1079 | m_materialContacts[material, movintYN].geom = curContact; | 1136 | m_materialContacts[material, movintYN].geom = curContact; |
1080 | _perloopContact.Add(curContact); | ||
1081 | 1137 | ||
1082 | if (m_global_contactcount < maxContactsbeforedeath) | 1138 | if (m_global_contactcount < maxContactsbeforedeath) |
1083 | { | 1139 | { |
@@ -1098,9 +1154,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1098 | 1154 | ||
1099 | if (p2 is OdePrim) | 1155 | if (p2 is OdePrim) |
1100 | material = ((OdePrim)p2).m_material; | 1156 | material = ((OdePrim)p2).m_material; |
1157 | |||
1101 | //m_log.DebugFormat("Material: {0}", material); | 1158 | //m_log.DebugFormat("Material: {0}", material); |
1102 | m_materialContacts[material, movintYN].geom = curContact; | 1159 | m_materialContacts[material, movintYN].geom = curContact; |
1103 | _perloopContact.Add(curContact); | ||
1104 | 1160 | ||
1105 | if (m_global_contactcount < maxContactsbeforedeath) | 1161 | if (m_global_contactcount < maxContactsbeforedeath) |
1106 | { | 1162 | { |
@@ -1133,8 +1189,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1133 | //contact.normal = new d.Vector3(0, 0, 1); | 1189 | //contact.normal = new d.Vector3(0, 0, 1); |
1134 | //contact.pos = new d.Vector3(0, 0, contact.pos.Z - 5f); | 1190 | //contact.pos = new d.Vector3(0, 0, contact.pos.Z - 5f); |
1135 | } | 1191 | } |
1192 | |||
1136 | WaterContact.geom = curContact; | 1193 | WaterContact.geom = curContact; |
1137 | _perloopContact.Add(curContact); | 1194 | |
1138 | if (m_global_contactcount < maxContactsbeforedeath) | 1195 | if (m_global_contactcount < maxContactsbeforedeath) |
1139 | { | 1196 | { |
1140 | joint = d.JointCreateContact(world, contactgroup, ref WaterContact); | 1197 | joint = d.JointCreateContact(world, contactgroup, ref WaterContact); |
@@ -1152,7 +1209,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1152 | { | 1209 | { |
1153 | // Use the Movement prim contact | 1210 | // Use the Movement prim contact |
1154 | AvatarMovementprimContact.geom = curContact; | 1211 | AvatarMovementprimContact.geom = curContact; |
1155 | _perloopContact.Add(curContact); | 1212 | |
1156 | if (m_global_contactcount < maxContactsbeforedeath) | 1213 | if (m_global_contactcount < maxContactsbeforedeath) |
1157 | { | 1214 | { |
1158 | joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact); | 1215 | joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact); |
@@ -1182,13 +1239,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1182 | 1239 | ||
1183 | //m_log.DebugFormat("Material: {0}", material); | 1240 | //m_log.DebugFormat("Material: {0}", material); |
1184 | m_materialContacts[material, 0].geom = curContact; | 1241 | m_materialContacts[material, 0].geom = curContact; |
1185 | _perloopContact.Add(curContact); | ||
1186 | 1242 | ||
1187 | if (m_global_contactcount < maxContactsbeforedeath) | 1243 | if (m_global_contactcount < maxContactsbeforedeath) |
1188 | { | 1244 | { |
1189 | joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, 0]); | 1245 | joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, 0]); |
1190 | m_global_contactcount++; | 1246 | m_global_contactcount++; |
1191 | |||
1192 | } | 1247 | } |
1193 | } | 1248 | } |
1194 | } | 1249 | } |
@@ -1217,69 +1272,65 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1217 | 1272 | ||
1218 | private bool checkDupe(d.ContactGeom contactGeom, int atype) | 1273 | private bool checkDupe(d.ContactGeom contactGeom, int atype) |
1219 | { | 1274 | { |
1220 | bool result = false; | ||
1221 | //return result; | ||
1222 | if (!m_filterCollisions) | 1275 | if (!m_filterCollisions) |
1223 | return false; | 1276 | return false; |
1224 | 1277 | ||
1278 | bool result = false; | ||
1279 | |||
1225 | ActorTypes at = (ActorTypes)atype; | 1280 | ActorTypes at = (ActorTypes)atype; |
1226 | lock (_perloopContact) | 1281 | |
1282 | foreach (d.ContactGeom contact in _perloopContact) | ||
1227 | { | 1283 | { |
1228 | foreach (d.ContactGeom contact in _perloopContact) | 1284 | //if ((contact.g1 == contactGeom.g1 && contact.g2 == contactGeom.g2)) |
1285 | //{ | ||
1286 | // || (contact.g2 == contactGeom.g1 && contact.g1 == contactGeom.g2) | ||
1287 | if (at == ActorTypes.Agent) | ||
1229 | { | 1288 | { |
1230 | //if ((contact.g1 == contactGeom.g1 && contact.g2 == contactGeom.g2)) | 1289 | if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f) |
1231 | //{ | 1290 | && (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f) |
1232 | // || (contact.g2 == contactGeom.g1 && contact.g1 == contactGeom.g2) | 1291 | && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f)) |
1233 | if (at == ActorTypes.Agent) | 1292 | && contactGeom.g1 != LandGeom && contactGeom.g2 != LandGeom) |
1234 | { | 1293 | { |
1235 | if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f) && (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f) && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f)) && contactGeom.g1 != LandGeom && contactGeom.g2 != LandGeom) | 1294 | if (Math.Abs(contact.depth - contactGeom.depth) < 0.052f) |
1236 | { | 1295 | { |
1237 | 1296 | //contactGeom.depth *= .00005f; | |
1238 | if (Math.Abs(contact.depth - contactGeom.depth) < 0.052f) | 1297 | //m_log.DebugFormat("[Collsion]: Depth {0}", Math.Abs(contact.depth - contactGeom.depth)); |
1239 | { | 1298 | // m_log.DebugFormat("[Collision]: <{0},{1},{2}>", Math.Abs(contactGeom.normal.X - contact.normal.X), Math.Abs(contactGeom.normal.Y - contact.normal.Y), Math.Abs(contactGeom.normal.Z - contact.normal.Z)); |
1240 | //contactGeom.depth *= .00005f; | 1299 | result = true; |
1241 | //m_log.DebugFormat("[Collsion]: Depth {0}", Math.Abs(contact.depth - contactGeom.depth)); | 1300 | break; |
1242 | // m_log.DebugFormat("[Collision]: <{0},{1},{2}>", Math.Abs(contactGeom.normal.X - contact.normal.X), Math.Abs(contactGeom.normal.Y - contact.normal.Y), Math.Abs(contactGeom.normal.Z - contact.normal.Z)); | 1301 | } |
1243 | result = true; | 1302 | // else |
1244 | break; | 1303 | // { |
1245 | } | 1304 | // //m_log.DebugFormat("[Collsion]: Depth {0}", Math.Abs(contact.depth - contactGeom.depth)); |
1246 | else | 1305 | // } |
1247 | { | 1306 | } |
1248 | //m_log.DebugFormat("[Collsion]: Depth {0}", Math.Abs(contact.depth - contactGeom.depth)); | 1307 | // else |
1249 | } | 1308 | // { |
1250 | } | 1309 | // //m_log.DebugFormat("[Collision]: <{0},{1},{2}>", Math.Abs(contactGeom.normal.X - contact.normal.X), Math.Abs(contactGeom.normal.Y - contact.normal.Y), Math.Abs(contactGeom.normal.Z - contact.normal.Z)); |
1251 | else | 1310 | // //int i = 0; |
1252 | { | 1311 | // } |
1253 | //m_log.DebugFormat("[Collision]: <{0},{1},{2}>", Math.Abs(contactGeom.normal.X - contact.normal.X), Math.Abs(contactGeom.normal.Y - contact.normal.Y), Math.Abs(contactGeom.normal.Z - contact.normal.Z)); | 1312 | } |
1254 | //int i = 0; | 1313 | else if (at == ActorTypes.Prim) |
1255 | } | 1314 | { |
1256 | } | 1315 | //d.AABB aabb1 = new d.AABB(); |
1257 | else if (at == ActorTypes.Prim) | 1316 | //d.AABB aabb2 = new d.AABB(); |
1317 | |||
1318 | //d.GeomGetAABB(contactGeom.g2, out aabb2); | ||
1319 | //d.GeomGetAABB(contactGeom.g1, out aabb1); | ||
1320 | //aabb1. | ||
1321 | if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f) && (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f) && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f)) && contactGeom.g1 != LandGeom && contactGeom.g2 != LandGeom) | ||
1258 | { | 1322 | { |
1259 | //d.AABB aabb1 = new d.AABB(); | 1323 | if (contactGeom.normal.X == contact.normal.X && contactGeom.normal.Y == contact.normal.Y && contactGeom.normal.Z == contact.normal.Z) |
1260 | //d.AABB aabb2 = new d.AABB(); | 1324 | { |
1261 | 1325 | if (Math.Abs(contact.depth - contactGeom.depth) < 0.272f) | |
1262 | //d.GeomGetAABB(contactGeom.g2, out aabb2); | ||
1263 | //d.GeomGetAABB(contactGeom.g1, out aabb1); | ||
1264 | //aabb1. | ||
1265 | if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f) && (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f) && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f)) && contactGeom.g1 != LandGeom && contactGeom.g2 != LandGeom) | ||
1266 | { | 1326 | { |
1267 | if (contactGeom.normal.X == contact.normal.X && contactGeom.normal.Y == contact.normal.Y && contactGeom.normal.Z == contact.normal.Z) | 1327 | result = true; |
1268 | { | 1328 | break; |
1269 | if (Math.Abs(contact.depth - contactGeom.depth) < 0.272f) | ||
1270 | { | ||
1271 | result = true; | ||
1272 | break; | ||
1273 | } | ||
1274 | } | ||
1275 | //m_log.DebugFormat("[Collsion]: Depth {0}", Math.Abs(contact.depth - contactGeom.depth)); | ||
1276 | //m_log.DebugFormat("[Collision]: <{0},{1},{2}>", Math.Abs(contactGeom.normal.X - contact.normal.X), Math.Abs(contactGeom.normal.Y - contact.normal.Y), Math.Abs(contactGeom.normal.Z - contact.normal.Z)); | ||
1277 | } | 1329 | } |
1278 | 1330 | } | |
1331 | //m_log.DebugFormat("[Collsion]: Depth {0}", Math.Abs(contact.depth - contactGeom.depth)); | ||
1332 | //m_log.DebugFormat("[Collision]: <{0},{1},{2}>", Math.Abs(contactGeom.normal.X - contact.normal.X), Math.Abs(contactGeom.normal.Y - contact.normal.Y), Math.Abs(contactGeom.normal.Z - contact.normal.Z)); | ||
1279 | } | 1333 | } |
1280 | |||
1281 | //} | ||
1282 | |||
1283 | } | 1334 | } |
1284 | } | 1335 | } |
1285 | 1336 | ||
@@ -1482,90 +1533,77 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1482 | { | 1533 | { |
1483 | _perloopContact.Clear(); | 1534 | _perloopContact.Clear(); |
1484 | 1535 | ||
1485 | lock (_characters) | 1536 | foreach (OdeCharacter chr in _characters) |
1486 | { | 1537 | { |
1487 | foreach (OdeCharacter chr in _characters) | 1538 | // Reset the collision values to false |
1539 | // since we don't know if we're colliding yet | ||
1540 | if (chr.Shell == IntPtr.Zero || chr.Body == IntPtr.Zero) | ||
1541 | continue; | ||
1542 | |||
1543 | chr.IsColliding = false; | ||
1544 | chr.CollidingGround = false; | ||
1545 | chr.CollidingObj = false; | ||
1546 | |||
1547 | // test the avatar's geometry for collision with the space | ||
1548 | // This will return near and the space that they are the closest to | ||
1549 | // And we'll run this again against the avatar and the space segment | ||
1550 | // This will return with a bunch of possible objects in the space segment | ||
1551 | // and we'll run it again on all of them. | ||
1552 | try | ||
1488 | { | 1553 | { |
1489 | // Reset the collision values to false | 1554 | d.SpaceCollide2(space, chr.Shell, IntPtr.Zero, nearCallback); |
1490 | // since we don't know if we're colliding yet | ||
1491 | |||
1492 | // For some reason this can happen. Don't ask... | ||
1493 | // | ||
1494 | if (chr == null) | ||
1495 | continue; | ||
1496 | |||
1497 | if (chr.Shell == IntPtr.Zero || chr.Body == IntPtr.Zero) | ||
1498 | continue; | ||
1499 | |||
1500 | chr.IsColliding = false; | ||
1501 | chr.CollidingGround = false; | ||
1502 | chr.CollidingObj = false; | ||
1503 | |||
1504 | // test the avatar's geometry for collision with the space | ||
1505 | // This will return near and the space that they are the closest to | ||
1506 | // And we'll run this again against the avatar and the space segment | ||
1507 | // This will return with a bunch of possible objects in the space segment | ||
1508 | // and we'll run it again on all of them. | ||
1509 | try | ||
1510 | { | ||
1511 | d.SpaceCollide2(space, chr.Shell, IntPtr.Zero, nearCallback); | ||
1512 | } | ||
1513 | catch (AccessViolationException) | ||
1514 | { | ||
1515 | m_log.Warn("[PHYSICS]: Unable to space collide"); | ||
1516 | } | ||
1517 | //float terrainheight = GetTerrainHeightAtXY(chr.Position.X, chr.Position.Y); | ||
1518 | //if (chr.Position.Z + (chr.Velocity.Z * timeStep) < terrainheight + 10) | ||
1519 | //{ | ||
1520 | //chr.Position.Z = terrainheight + 10.0f; | ||
1521 | //forcedZ = true; | ||
1522 | //} | ||
1523 | } | 1555 | } |
1556 | catch (AccessViolationException) | ||
1557 | { | ||
1558 | m_log.WarnFormat("[ODE SCENE]: Unable to space collide {0}", Name); | ||
1559 | } | ||
1560 | |||
1561 | //float terrainheight = GetTerrainHeightAtXY(chr.Position.X, chr.Position.Y); | ||
1562 | //if (chr.Position.Z + (chr.Velocity.Z * timeStep) < terrainheight + 10) | ||
1563 | //{ | ||
1564 | //chr.Position.Z = terrainheight + 10.0f; | ||
1565 | //forcedZ = true; | ||
1566 | //} | ||
1524 | } | 1567 | } |
1525 | 1568 | ||
1526 | lock (_activeprims) | 1569 | List<OdePrim> removeprims = null; |
1570 | foreach (OdePrim chr in _activeprims) | ||
1527 | { | 1571 | { |
1528 | List<OdePrim> removeprims = null; | 1572 | if (chr.Body != IntPtr.Zero && d.BodyIsEnabled(chr.Body) && (!chr.m_disabled)) |
1529 | foreach (OdePrim chr in _activeprims) | ||
1530 | { | 1573 | { |
1531 | if (chr.Body != IntPtr.Zero && d.BodyIsEnabled(chr.Body) && (!chr.m_disabled)) | 1574 | try |
1532 | { | 1575 | { |
1533 | try | 1576 | lock (chr) |
1534 | { | 1577 | { |
1535 | lock (chr) | 1578 | if (space != IntPtr.Zero && chr.prim_geom != IntPtr.Zero && chr.m_taintremove == false) |
1536 | { | 1579 | { |
1537 | if (space != IntPtr.Zero && chr.prim_geom != IntPtr.Zero && chr.m_taintremove == false) | 1580 | d.SpaceCollide2(space, chr.prim_geom, IntPtr.Zero, nearCallback); |
1538 | { | 1581 | } |
1539 | d.SpaceCollide2(space, chr.prim_geom, IntPtr.Zero, nearCallback); | 1582 | else |
1540 | } | 1583 | { |
1541 | else | 1584 | if (removeprims == null) |
1542 | { | 1585 | { |
1543 | if (removeprims == null) | 1586 | removeprims = new List<OdePrim>(); |
1544 | { | ||
1545 | removeprims = new List<OdePrim>(); | ||
1546 | } | ||
1547 | removeprims.Add(chr); | ||
1548 | m_log.Debug("[PHYSICS]: unable to collide test active prim against space. The space was zero, the geom was zero or it was in the process of being removed. Removed it from the active prim list. This needs to be fixed!"); | ||
1549 | } | 1587 | } |
1588 | removeprims.Add(chr); | ||
1589 | m_log.Debug("[ODE SCENE]: unable to collide test active prim against space. The space was zero, the geom was zero or it was in the process of being removed. Removed it from the active prim list. This needs to be fixed!"); | ||
1550 | } | 1590 | } |
1551 | } | 1591 | } |
1552 | catch (AccessViolationException) | ||
1553 | { | ||
1554 | m_log.Warn("[PHYSICS]: Unable to space collide"); | ||
1555 | } | ||
1556 | } | 1592 | } |
1557 | } | 1593 | catch (AccessViolationException) |
1558 | |||
1559 | if (removeprims != null) | ||
1560 | { | ||
1561 | foreach (OdePrim chr in removeprims) | ||
1562 | { | 1594 | { |
1563 | _activeprims.Remove(chr); | 1595 | m_log.Warn("[ODE SCENE]: Unable to space collide"); |
1564 | } | 1596 | } |
1565 | } | 1597 | } |
1566 | } | 1598 | } |
1567 | 1599 | ||
1568 | _perloopContact.Clear(); | 1600 | if (removeprims != null) |
1601 | { | ||
1602 | foreach (OdePrim chr in removeprims) | ||
1603 | { | ||
1604 | _activeprims.Remove(chr); | ||
1605 | } | ||
1606 | } | ||
1569 | } | 1607 | } |
1570 | 1608 | ||
1571 | #endregion | 1609 | #endregion |
@@ -1685,35 +1723,29 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1685 | 1723 | ||
1686 | internal void AddCharacter(OdeCharacter chr) | 1724 | internal void AddCharacter(OdeCharacter chr) |
1687 | { | 1725 | { |
1688 | lock (_characters) | 1726 | if (!_characters.Contains(chr)) |
1689 | { | 1727 | { |
1690 | if (!_characters.Contains(chr)) | 1728 | _characters.Add(chr); |
1691 | { | ||
1692 | _characters.Add(chr); | ||
1693 | if (chr.bad) | ||
1694 | m_log.DebugFormat("[PHYSICS] Added BAD actor {0} to characters list", chr.m_uuid); | ||
1695 | } | ||
1696 | } | ||
1697 | } | ||
1698 | 1729 | ||
1699 | internal void RemoveCharacter(OdeCharacter chr) | 1730 | if (chr.bad) |
1700 | { | 1731 | m_log.ErrorFormat("[ODE SCENE]: Added BAD actor {0} to characters list", chr.m_uuid); |
1701 | lock (_characters) | 1732 | } |
1733 | else | ||
1702 | { | 1734 | { |
1703 | if (_characters.Contains(chr)) | 1735 | m_log.ErrorFormat( |
1704 | { | 1736 | "[ODE SCENE]: Tried to add character {0} {1} but they are already in the set!", |
1705 | _characters.Remove(chr); | 1737 | chr.Name, chr.LocalID); |
1706 | } | ||
1707 | } | 1738 | } |
1708 | } | 1739 | } |
1709 | 1740 | ||
1710 | internal void BadCharacter(OdeCharacter chr) | 1741 | internal void RemoveCharacter(OdeCharacter chr) |
1711 | { | 1742 | { |
1712 | lock (_badCharacter) | 1743 | if (_characters.Contains(chr)) |
1713 | { | 1744 | _characters.Remove(chr); |
1714 | if (!_badCharacter.Contains(chr)) | 1745 | else |
1715 | _badCharacter.Add(chr); | 1746 | m_log.ErrorFormat( |
1716 | } | 1747 | "[ODE SCENE]: Tried to remove character {0} {1} but they are not in the list!", |
1748 | chr.Name, chr.LocalID); | ||
1717 | } | 1749 | } |
1718 | 1750 | ||
1719 | private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation, | 1751 | private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation, |
@@ -1742,13 +1774,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1742 | internal void ActivatePrim(OdePrim prim) | 1774 | internal void ActivatePrim(OdePrim prim) |
1743 | { | 1775 | { |
1744 | // adds active prim.. (ones that should be iterated over in collisions_optimized | 1776 | // adds active prim.. (ones that should be iterated over in collisions_optimized |
1745 | lock (_activeprims) | 1777 | if (!_activeprims.Contains(prim)) |
1746 | { | 1778 | _activeprims.Add(prim); |
1747 | if (!_activeprims.Contains(prim)) | 1779 | //else |
1748 | _activeprims.Add(prim); | 1780 | // m_log.Warn("[PHYSICS]: Double Entry in _activeprims detected, potential crash immenent"); |
1749 | //else | ||
1750 | // m_log.Warn("[PHYSICS]: Double Entry in _activeprims detected, potential crash immenent"); | ||
1751 | } | ||
1752 | } | 1781 | } |
1753 | 1782 | ||
1754 | public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, | 1783 | public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, |
@@ -2027,7 +2056,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2027 | //m_log.Debug("RemoveAllJointsConnectedToActor: start"); | 2056 | //m_log.Debug("RemoveAllJointsConnectedToActor: start"); |
2028 | if (actor.SOPName != null && joints_connecting_actor.ContainsKey(actor.SOPName) && joints_connecting_actor[actor.SOPName] != null) | 2057 | if (actor.SOPName != null && joints_connecting_actor.ContainsKey(actor.SOPName) && joints_connecting_actor[actor.SOPName] != null) |
2029 | { | 2058 | { |
2030 | |||
2031 | List<PhysicsJoint> jointsToRemove = new List<PhysicsJoint>(); | 2059 | List<PhysicsJoint> jointsToRemove = new List<PhysicsJoint>(); |
2032 | //TODO: merge these 2 loops (originally it was needed to avoid altering a list being iterated over, but it is no longer needed due to the joint request queue mechanism) | 2060 | //TODO: merge these 2 loops (originally it was needed to avoid altering a list being iterated over, but it is no longer needed due to the joint request queue mechanism) |
2033 | foreach (PhysicsJoint j in joints_connecting_actor[actor.SOPName]) | 2061 | foreach (PhysicsJoint j in joints_connecting_actor[actor.SOPName]) |
@@ -2122,8 +2150,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2122 | /// <param name="prim"></param> | 2150 | /// <param name="prim"></param> |
2123 | internal void DeactivatePrim(OdePrim prim) | 2151 | internal void DeactivatePrim(OdePrim prim) |
2124 | { | 2152 | { |
2125 | lock (_activeprims) | 2153 | _activeprims.Remove(prim); |
2126 | _activeprims.Remove(prim); | ||
2127 | } | 2154 | } |
2128 | 2155 | ||
2129 | public override void RemovePrim(PhysicsActor prim) | 2156 | public override void RemovePrim(PhysicsActor prim) |
@@ -2138,7 +2165,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2138 | 2165 | ||
2139 | p.setPrimForRemoval(); | 2166 | p.setPrimForRemoval(); |
2140 | AddPhysicsActorTaint(prim); | 2167 | AddPhysicsActorTaint(prim); |
2141 | //RemovePrimThreadLocked(p); | ||
2142 | } | 2168 | } |
2143 | } | 2169 | } |
2144 | } | 2170 | } |
@@ -2206,7 +2232,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2206 | //m_log.Warn(prim.prim_geom); | 2232 | //m_log.Warn(prim.prim_geom); |
2207 | 2233 | ||
2208 | if (!prim.RemoveGeom()) | 2234 | if (!prim.RemoveGeom()) |
2209 | m_log.Warn("[PHYSICS]: Unable to remove prim from physics scene"); | 2235 | m_log.Warn("[ODE SCENE]: Unable to remove prim from physics scene"); |
2210 | 2236 | ||
2211 | lock (_prims) | 2237 | lock (_prims) |
2212 | _prims.Remove(prim); | 2238 | _prims.Remove(prim); |
@@ -2293,12 +2319,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2293 | { | 2319 | { |
2294 | if (d.GeomIsSpace(currentspace)) | 2320 | if (d.GeomIsSpace(currentspace)) |
2295 | { | 2321 | { |
2296 | waitForSpaceUnlock(currentspace); | 2322 | // waitForSpaceUnlock(currentspace); |
2297 | d.SpaceRemove(currentspace, geom); | 2323 | d.SpaceRemove(currentspace, geom); |
2298 | } | 2324 | } |
2299 | else | 2325 | else |
2300 | { | 2326 | { |
2301 | m_log.Info("[Physics]: Invalid Scene passed to 'recalculatespace':" + currentspace + | 2327 | m_log.Info("[ODE SCENE]: Invalid Scene passed to 'recalculatespace':" + currentspace + |
2302 | " Geom:" + geom); | 2328 | " Geom:" + geom); |
2303 | } | 2329 | } |
2304 | } | 2330 | } |
@@ -2309,12 +2335,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2309 | { | 2335 | { |
2310 | if (d.GeomIsSpace(currentspace)) | 2336 | if (d.GeomIsSpace(currentspace)) |
2311 | { | 2337 | { |
2312 | waitForSpaceUnlock(sGeomIsIn); | 2338 | // waitForSpaceUnlock(sGeomIsIn); |
2313 | d.SpaceRemove(sGeomIsIn, geom); | 2339 | d.SpaceRemove(sGeomIsIn, geom); |
2314 | } | 2340 | } |
2315 | else | 2341 | else |
2316 | { | 2342 | { |
2317 | m_log.Info("[Physics]: Invalid Scene passed to 'recalculatespace':" + | 2343 | m_log.Info("[ODE SCENE]: Invalid Scene passed to 'recalculatespace':" + |
2318 | sGeomIsIn + " Geom:" + geom); | 2344 | sGeomIsIn + " Geom:" + geom); |
2319 | } | 2345 | } |
2320 | } | 2346 | } |
@@ -2327,8 +2353,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2327 | { | 2353 | { |
2328 | if (d.GeomIsSpace(currentspace)) | 2354 | if (d.GeomIsSpace(currentspace)) |
2329 | { | 2355 | { |
2330 | waitForSpaceUnlock(currentspace); | 2356 | // waitForSpaceUnlock(currentspace); |
2331 | waitForSpaceUnlock(space); | 2357 | // waitForSpaceUnlock(space); |
2332 | d.SpaceRemove(space, currentspace); | 2358 | d.SpaceRemove(space, currentspace); |
2333 | // free up memory used by the space. | 2359 | // free up memory used by the space. |
2334 | 2360 | ||
@@ -2337,7 +2363,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2337 | } | 2363 | } |
2338 | else | 2364 | else |
2339 | { | 2365 | { |
2340 | m_log.Info("[Physics]: Invalid Scene passed to 'recalculatespace':" + | 2366 | m_log.Info("[ODE SCENE]: Invalid Scene passed to 'recalculatespace':" + |
2341 | currentspace + " Geom:" + geom); | 2367 | currentspace + " Geom:" + geom); |
2342 | } | 2368 | } |
2343 | } | 2369 | } |
@@ -2352,12 +2378,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2352 | { | 2378 | { |
2353 | if (d.GeomIsSpace(currentspace)) | 2379 | if (d.GeomIsSpace(currentspace)) |
2354 | { | 2380 | { |
2355 | waitForSpaceUnlock(currentspace); | 2381 | // waitForSpaceUnlock(currentspace); |
2356 | d.SpaceRemove(currentspace, geom); | 2382 | d.SpaceRemove(currentspace, geom); |
2357 | } | 2383 | } |
2358 | else | 2384 | else |
2359 | { | 2385 | { |
2360 | m_log.Info("[Physics]: Invalid Scene passed to 'recalculatespace':" + | 2386 | m_log.Info("[ODE SCENE]: Invalid Scene passed to 'recalculatespace':" + |
2361 | currentspace + " Geom:" + geom); | 2387 | currentspace + " Geom:" + geom); |
2362 | } | 2388 | } |
2363 | } | 2389 | } |
@@ -2368,12 +2394,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2368 | { | 2394 | { |
2369 | if (d.GeomIsSpace(sGeomIsIn)) | 2395 | if (d.GeomIsSpace(sGeomIsIn)) |
2370 | { | 2396 | { |
2371 | waitForSpaceUnlock(sGeomIsIn); | 2397 | // waitForSpaceUnlock(sGeomIsIn); |
2372 | d.SpaceRemove(sGeomIsIn, geom); | 2398 | d.SpaceRemove(sGeomIsIn, geom); |
2373 | } | 2399 | } |
2374 | else | 2400 | else |
2375 | { | 2401 | { |
2376 | m_log.Info("[Physics]: Invalid Scene passed to 'recalculatespace':" + | 2402 | m_log.Info("[ODE SCENE]: Invalid Scene passed to 'recalculatespace':" + |
2377 | sGeomIsIn + " Geom:" + geom); | 2403 | sGeomIsIn + " Geom:" + geom); |
2378 | } | 2404 | } |
2379 | } | 2405 | } |
@@ -2407,9 +2433,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2407 | // creating a new space for prim and inserting it into main space. | 2433 | // creating a new space for prim and inserting it into main space. |
2408 | staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY] = d.HashSpaceCreate(IntPtr.Zero); | 2434 | staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY] = d.HashSpaceCreate(IntPtr.Zero); |
2409 | d.GeomSetCategoryBits(staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY], (int)CollisionCategories.Space); | 2435 | d.GeomSetCategoryBits(staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY], (int)CollisionCategories.Space); |
2410 | waitForSpaceUnlock(space); | 2436 | // waitForSpaceUnlock(space); |
2411 | d.SpaceSetSublevel(space, 1); | 2437 | d.SpaceSetSublevel(space, 1); |
2412 | d.SpaceAdd(space, staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY]); | 2438 | d.SpaceAdd(space, staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY]); |
2439 | |||
2413 | return staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY]; | 2440 | return staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY]; |
2414 | } | 2441 | } |
2415 | 2442 | ||
@@ -2584,15 +2611,17 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2584 | 2611 | ||
2585 | /// <summary> | 2612 | /// <summary> |
2586 | /// Called after our prim properties are set Scale, position etc. | 2613 | /// Called after our prim properties are set Scale, position etc. |
2614 | /// </summary> | ||
2615 | /// <remarks> | ||
2587 | /// We use this event queue like method to keep changes to the physical scene occuring in the threadlocked mutex | 2616 | /// We use this event queue like method to keep changes to the physical scene occuring in the threadlocked mutex |
2588 | /// This assures us that we have no race conditions | 2617 | /// This assures us that we have no race conditions |
2589 | /// </summary> | 2618 | /// </remarks> |
2590 | /// <param name="prim"></param> | 2619 | /// <param name="actor"></param> |
2591 | public override void AddPhysicsActorTaint(PhysicsActor prim) | 2620 | public override void AddPhysicsActorTaint(PhysicsActor actor) |
2592 | { | 2621 | { |
2593 | if (prim is OdePrim) | 2622 | if (actor is OdePrim) |
2594 | { | 2623 | { |
2595 | OdePrim taintedprim = ((OdePrim) prim); | 2624 | OdePrim taintedprim = ((OdePrim)actor); |
2596 | lock (_taintedPrimLock) | 2625 | lock (_taintedPrimLock) |
2597 | { | 2626 | { |
2598 | if (!(_taintedPrimH.Contains(taintedprim))) | 2627 | if (!(_taintedPrimH.Contains(taintedprim))) |
@@ -2604,18 +2633,17 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); | |||
2604 | _taintedPrimL.Add(taintedprim); // List for ordered readout | 2633 | _taintedPrimL.Add(taintedprim); // List for ordered readout |
2605 | } | 2634 | } |
2606 | } | 2635 | } |
2607 | return; | ||
2608 | } | 2636 | } |
2609 | else if (prim is OdeCharacter) | 2637 | else if (actor is OdeCharacter) |
2610 | { | 2638 | { |
2611 | OdeCharacter taintedchar = ((OdeCharacter)prim); | 2639 | OdeCharacter taintedchar = ((OdeCharacter)actor); |
2612 | lock (_taintedActors) | 2640 | lock (_taintedActors) |
2613 | { | 2641 | { |
2614 | if (!(_taintedActors.Contains(taintedchar))) | 2642 | if (!(_taintedActors.Contains(taintedchar))) |
2615 | { | 2643 | { |
2616 | _taintedActors.Add(taintedchar); | 2644 | _taintedActors.Add(taintedchar); |
2617 | if (taintedchar.bad) | 2645 | if (taintedchar.bad) |
2618 | m_log.DebugFormat("[PHYSICS]: Added BAD actor {0} to tainted actors", taintedchar.m_uuid); | 2646 | m_log.DebugFormat("[ODE SCENE]: Added BAD actor {0} to tainted actors", taintedchar.m_uuid); |
2619 | } | 2647 | } |
2620 | } | 2648 | } |
2621 | } | 2649 | } |
@@ -2711,29 +2739,18 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); | |||
2711 | { | 2739 | { |
2712 | try | 2740 | try |
2713 | { | 2741 | { |
2714 | // Insert, remove Characters | ||
2715 | bool processedtaints = false; | ||
2716 | |||
2717 | lock (_taintedActors) | 2742 | lock (_taintedActors) |
2718 | { | 2743 | { |
2719 | if (_taintedActors.Count > 0) | 2744 | if (_taintedActors.Count > 0) |
2720 | { | 2745 | { |
2721 | foreach (OdeCharacter character in _taintedActors) | 2746 | foreach (OdeCharacter character in _taintedActors) |
2722 | { | ||
2723 | character.ProcessTaints(); | 2747 | character.ProcessTaints(); |
2724 | 2748 | ||
2725 | processedtaints = true; | 2749 | if (_taintedActors.Count > 0) |
2726 | //character.m_collisionscore = 0; | ||
2727 | } | ||
2728 | |||
2729 | if (processedtaints) | ||
2730 | _taintedActors.Clear(); | 2750 | _taintedActors.Clear(); |
2731 | } | 2751 | } |
2732 | } | 2752 | } |
2733 | 2753 | ||
2734 | // Modify other objects in the scene. | ||
2735 | processedtaints = false; | ||
2736 | |||
2737 | lock (_taintedPrimLock) | 2754 | lock (_taintedPrimLock) |
2738 | { | 2755 | { |
2739 | foreach (OdePrim prim in _taintedPrimL) | 2756 | foreach (OdePrim prim in _taintedPrimL) |
@@ -2749,7 +2766,6 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); | |||
2749 | prim.ProcessTaints(); | 2766 | prim.ProcessTaints(); |
2750 | } | 2767 | } |
2751 | 2768 | ||
2752 | processedtaints = true; | ||
2753 | prim.m_collisionscore = 0; | 2769 | prim.m_collisionscore = 0; |
2754 | 2770 | ||
2755 | // This loop can block up the Heartbeat for a very long time on large regions. | 2771 | // This loop can block up the Heartbeat for a very long time on large regions. |
@@ -2762,7 +2778,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); | |||
2762 | if (SupportsNINJAJoints) | 2778 | if (SupportsNINJAJoints) |
2763 | SimulatePendingNINJAJoints(); | 2779 | SimulatePendingNINJAJoints(); |
2764 | 2780 | ||
2765 | if (processedtaints) | 2781 | if (_taintedPrimL.Count > 0) |
2766 | { | 2782 | { |
2767 | //Console.WriteLine("Simulate calls Clear of _taintedPrim list"); | 2783 | //Console.WriteLine("Simulate calls Clear of _taintedPrim list"); |
2768 | _taintedPrimH.Clear(); | 2784 | _taintedPrimH.Clear(); |
@@ -2771,31 +2787,25 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); | |||
2771 | } | 2787 | } |
2772 | 2788 | ||
2773 | // Move characters | 2789 | // Move characters |
2774 | lock (_characters) | 2790 | foreach (OdeCharacter actor in _characters) |
2791 | actor.Move(defects); | ||
2792 | |||
2793 | if (defects.Count != 0) | ||
2775 | { | 2794 | { |
2776 | List<OdeCharacter> defects = new List<OdeCharacter>(); | 2795 | foreach (OdeCharacter actor in defects) |
2777 | foreach (OdeCharacter actor in _characters) | ||
2778 | { | ||
2779 | if (actor != null) | ||
2780 | actor.Move(defects); | ||
2781 | } | ||
2782 | if (0 != defects.Count) | ||
2783 | { | 2796 | { |
2784 | foreach (OdeCharacter defect in defects) | 2797 | RemoveCharacter(actor); |
2785 | { | 2798 | actor.DestroyOdeStructures(); |
2786 | RemoveCharacter(defect); | ||
2787 | } | ||
2788 | } | 2799 | } |
2800 | |||
2801 | defects.Clear(); | ||
2789 | } | 2802 | } |
2790 | 2803 | ||
2791 | // Move other active objects | 2804 | // Move other active objects |
2792 | lock (_activeprims) | 2805 | foreach (OdePrim prim in _activeprims) |
2793 | { | 2806 | { |
2794 | foreach (OdePrim prim in _activeprims) | 2807 | prim.m_collisionscore = 0; |
2795 | { | 2808 | prim.Move(timeStep); |
2796 | prim.m_collisionscore = 0; | ||
2797 | prim.Move(timeStep); | ||
2798 | } | ||
2799 | } | 2809 | } |
2800 | 2810 | ||
2801 | //if ((framecount % m_randomizeWater) == 0) | 2811 | //if ((framecount % m_randomizeWater) == 0) |
@@ -2836,53 +2846,41 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); | |||
2836 | } | 2846 | } |
2837 | catch (Exception e) | 2847 | catch (Exception e) |
2838 | { | 2848 | { |
2839 | m_log.ErrorFormat("[PHYSICS]: {0}, {1}, {2}", e.Message, e.TargetSite, e); | 2849 | m_log.ErrorFormat("[ODE SCENE]: {0}, {1}, {2}", e.Message, e.TargetSite, e); |
2840 | } | 2850 | } |
2841 | 2851 | ||
2842 | timeLeft -= ODE_STEPSIZE; | 2852 | timeLeft -= ODE_STEPSIZE; |
2843 | } | 2853 | } |
2844 | 2854 | ||
2845 | lock (_characters) | 2855 | foreach (OdeCharacter actor in _characters) |
2846 | { | 2856 | { |
2847 | foreach (OdeCharacter actor in _characters) | 2857 | if (actor.bad) |
2848 | { | 2858 | m_log.WarnFormat("[ODE SCENE]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid); |
2849 | if (actor != null) | ||
2850 | { | ||
2851 | if (actor.bad) | ||
2852 | m_log.WarnFormat("[PHYSICS]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid); | ||
2853 | 2859 | ||
2854 | actor.UpdatePositionAndVelocity(); | 2860 | actor.UpdatePositionAndVelocity(defects); |
2855 | } | ||
2856 | } | ||
2857 | } | 2861 | } |
2858 | 2862 | ||
2859 | lock (_badCharacter) | 2863 | if (defects.Count != 0) |
2860 | { | 2864 | { |
2861 | if (_badCharacter.Count > 0) | 2865 | foreach (OdeCharacter actor in defects) |
2862 | { | 2866 | { |
2863 | foreach (OdeCharacter chr in _badCharacter) | 2867 | RemoveCharacter(actor); |
2864 | { | 2868 | actor.DestroyOdeStructures(); |
2865 | RemoveCharacter(chr); | ||
2866 | } | ||
2867 | |||
2868 | _badCharacter.Clear(); | ||
2869 | } | 2869 | } |
2870 | |||
2871 | defects.Clear(); | ||
2870 | } | 2872 | } |
2871 | 2873 | ||
2872 | lock (_activeprims) | 2874 | //if (timeStep < 0.2f) |
2875 | |||
2876 | foreach (OdePrim prim in _activeprims) | ||
2873 | { | 2877 | { |
2874 | //if (timeStep < 0.2f) | 2878 | if (prim.IsPhysical && (d.BodyIsEnabled(prim.Body) || !prim._zeroFlag)) |
2875 | { | 2879 | { |
2876 | foreach (OdePrim prim in _activeprims) | 2880 | prim.UpdatePositionAndVelocity(); |
2877 | { | ||
2878 | if (prim.IsPhysical && (d.BodyIsEnabled(prim.Body) || !prim._zeroFlag)) | ||
2879 | { | ||
2880 | prim.UpdatePositionAndVelocity(); | ||
2881 | 2881 | ||
2882 | if (SupportsNINJAJoints) | 2882 | if (SupportsNINJAJoints) |
2883 | SimulateActorPendingJoints(prim); | 2883 | SimulateActorPendingJoints(prim); |
2884 | } | ||
2885 | } | ||
2886 | } | 2884 | } |
2887 | } | 2885 | } |
2888 | 2886 | ||
@@ -3417,7 +3415,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); | |||
3417 | { | 3415 | { |
3418 | if (Single.IsNaN(resultarr2[y, x]) || Single.IsInfinity(resultarr2[y, x])) | 3416 | if (Single.IsNaN(resultarr2[y, x]) || Single.IsInfinity(resultarr2[y, x])) |
3419 | { | 3417 | { |
3420 | m_log.Warn("[PHYSICS]: Non finite heightfield element detected. Setting it to 0"); | 3418 | m_log.Warn("[ODE SCENE]: Non finite heightfield element detected. Setting it to 0"); |
3421 | resultarr2[y, x] = 0; | 3419 | resultarr2[y, x] = 0; |
3422 | } | 3420 | } |
3423 | returnarr[i] = resultarr2[y, x]; | 3421 | returnarr[i] = resultarr2[y, x]; |
@@ -3448,7 +3446,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); | |||
3448 | private void SetTerrain(float[] heightMap, Vector3 pOffset) | 3446 | private void SetTerrain(float[] heightMap, Vector3 pOffset) |
3449 | { | 3447 | { |
3450 | int startTime = Util.EnvironmentTickCount(); | 3448 | int startTime = Util.EnvironmentTickCount(); |
3451 | m_log.DebugFormat("[PHYSICS]: Setting terrain for {0}", Name); | 3449 | m_log.DebugFormat("[ODE SCENE]: Setting terrain for {0}", Name); |
3452 | 3450 | ||
3453 | // this._heightmap[i] = (double)heightMap[i]; | 3451 | // this._heightmap[i] = (double)heightMap[i]; |
3454 | // dbm (danx0r) -- creating a buffer zone of one extra sample all around | 3452 | // dbm (danx0r) -- creating a buffer zone of one extra sample all around |
@@ -3573,7 +3571,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); | |||
3573 | } | 3571 | } |
3574 | 3572 | ||
3575 | m_log.DebugFormat( | 3573 | m_log.DebugFormat( |
3576 | "[PHYSICS]: Setting terrain for {0} took {1}ms", Name, Util.EnvironmentTickCountSubtract(startTime)); | 3574 | "[ODE SCENE]: Setting terrain for {0} took {1}ms", Name, Util.EnvironmentTickCountSubtract(startTime)); |
3577 | } | 3575 | } |
3578 | 3576 | ||
3579 | public override void DeleteTerrain() | 3577 | public override void DeleteTerrain() |
@@ -3590,64 +3588,64 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); | |||
3590 | return true; | 3588 | return true; |
3591 | } | 3589 | } |
3592 | 3590 | ||
3593 | public override void UnCombine(PhysicsScene pScene) | 3591 | // public override void UnCombine(PhysicsScene pScene) |
3594 | { | 3592 | // { |
3595 | IntPtr localGround = IntPtr.Zero; | 3593 | // IntPtr localGround = IntPtr.Zero; |
3596 | // float[] localHeightfield; | 3594 | //// float[] localHeightfield; |
3597 | bool proceed = false; | 3595 | // bool proceed = false; |
3598 | List<IntPtr> geomDestroyList = new List<IntPtr>(); | 3596 | // List<IntPtr> geomDestroyList = new List<IntPtr>(); |
3599 | 3597 | // | |
3600 | lock (OdeLock) | 3598 | // lock (OdeLock) |
3601 | { | 3599 | // { |
3602 | if (RegionTerrain.TryGetValue(Vector3.Zero, out localGround)) | 3600 | // if (RegionTerrain.TryGetValue(Vector3.Zero, out localGround)) |
3603 | { | 3601 | // { |
3604 | foreach (IntPtr geom in TerrainHeightFieldHeights.Keys) | 3602 | // foreach (IntPtr geom in TerrainHeightFieldHeights.Keys) |
3605 | { | 3603 | // { |
3606 | if (geom == localGround) | 3604 | // if (geom == localGround) |
3607 | { | 3605 | // { |
3608 | // localHeightfield = TerrainHeightFieldHeights[geom]; | 3606 | //// localHeightfield = TerrainHeightFieldHeights[geom]; |
3609 | proceed = true; | 3607 | // proceed = true; |
3610 | } | 3608 | // } |
3611 | else | 3609 | // else |
3612 | { | 3610 | // { |
3613 | geomDestroyList.Add(geom); | 3611 | // geomDestroyList.Add(geom); |
3614 | } | 3612 | // } |
3615 | } | 3613 | // } |
3616 | 3614 | // | |
3617 | if (proceed) | 3615 | // if (proceed) |
3618 | { | 3616 | // { |
3619 | m_worldOffset = Vector3.Zero; | 3617 | // m_worldOffset = Vector3.Zero; |
3620 | WorldExtents = new Vector2((int)Constants.RegionSize, (int)Constants.RegionSize); | 3618 | // WorldExtents = new Vector2((int)Constants.RegionSize, (int)Constants.RegionSize); |
3621 | m_parentScene = null; | 3619 | // m_parentScene = null; |
3622 | 3620 | // | |
3623 | foreach (IntPtr g in geomDestroyList) | 3621 | // foreach (IntPtr g in geomDestroyList) |
3624 | { | 3622 | // { |
3625 | // removingHeightField needs to be done or the garbage collector will | 3623 | // // removingHeightField needs to be done or the garbage collector will |
3626 | // collect the terrain data before we tell ODE to destroy it causing | 3624 | // // collect the terrain data before we tell ODE to destroy it causing |
3627 | // memory corruption | 3625 | // // memory corruption |
3628 | if (TerrainHeightFieldHeights.ContainsKey(g)) | 3626 | // if (TerrainHeightFieldHeights.ContainsKey(g)) |
3629 | { | 3627 | // { |
3630 | // float[] removingHeightField = TerrainHeightFieldHeights[g]; | 3628 | //// float[] removingHeightField = TerrainHeightFieldHeights[g]; |
3631 | TerrainHeightFieldHeights.Remove(g); | 3629 | // TerrainHeightFieldHeights.Remove(g); |
3632 | 3630 | // | |
3633 | if (RegionTerrain.ContainsKey(g)) | 3631 | // if (RegionTerrain.ContainsKey(g)) |
3634 | { | 3632 | // { |
3635 | RegionTerrain.Remove(g); | 3633 | // RegionTerrain.Remove(g); |
3636 | } | 3634 | // } |
3637 | 3635 | // | |
3638 | d.GeomDestroy(g); | 3636 | // d.GeomDestroy(g); |
3639 | //removingHeightField = new float[0]; | 3637 | // //removingHeightField = new float[0]; |
3640 | } | 3638 | // } |
3641 | } | 3639 | // } |
3642 | 3640 | // | |
3643 | } | 3641 | // } |
3644 | else | 3642 | // else |
3645 | { | 3643 | // { |
3646 | m_log.Warn("[PHYSICS]: Couldn't proceed with UnCombine. Region has inconsistant data."); | 3644 | // m_log.Warn("[PHYSICS]: Couldn't proceed with UnCombine. Region has inconsistant data."); |
3647 | } | 3645 | // } |
3648 | } | 3646 | // } |
3649 | } | 3647 | // } |
3650 | } | 3648 | // } |
3651 | 3649 | ||
3652 | public override void SetWaterLevel(float baseheight) | 3650 | public override void SetWaterLevel(float baseheight) |
3653 | { | 3651 | { |
@@ -3894,30 +3892,28 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); | |||
3894 | } | 3892 | } |
3895 | } | 3893 | } |
3896 | ds.SetColor(1.0f, 0.0f, 0.0f); | 3894 | ds.SetColor(1.0f, 0.0f, 0.0f); |
3897 | lock (_characters) | 3895 | |
3896 | foreach (OdeCharacter chr in _characters) | ||
3898 | { | 3897 | { |
3899 | foreach (OdeCharacter chr in _characters) | 3898 | if (chr.Shell != IntPtr.Zero) |
3900 | { | 3899 | { |
3901 | if (chr.Shell != IntPtr.Zero) | 3900 | IntPtr body = d.GeomGetBody(chr.Shell); |
3902 | { | ||
3903 | IntPtr body = d.GeomGetBody(chr.Shell); | ||
3904 | 3901 | ||
3905 | d.Vector3 pos; | 3902 | d.Vector3 pos; |
3906 | d.GeomCopyPosition(chr.Shell, out pos); | 3903 | d.GeomCopyPosition(chr.Shell, out pos); |
3907 | //d.BodyCopyPosition(body, out pos); | 3904 | //d.BodyCopyPosition(body, out pos); |
3908 | 3905 | ||
3909 | d.Matrix3 R; | 3906 | d.Matrix3 R; |
3910 | d.GeomCopyRotation(chr.Shell, out R); | 3907 | d.GeomCopyRotation(chr.Shell, out R); |
3911 | //d.BodyCopyRotation(body, out R); | 3908 | //d.BodyCopyRotation(body, out R); |
3912 | 3909 | ||
3913 | ds.DrawCapsule(ref pos, ref R, chr.Size.Z, 0.35f); | 3910 | ds.DrawCapsule(ref pos, ref R, chr.Size.Z, 0.35f); |
3914 | d.Vector3 sides = new d.Vector3(); | 3911 | d.Vector3 sides = new d.Vector3(); |
3915 | sides.X = 0.5f; | 3912 | sides.X = 0.5f; |
3916 | sides.Y = 0.5f; | 3913 | sides.Y = 0.5f; |
3917 | sides.Z = 0.5f; | 3914 | sides.Z = 0.5f; |
3918 | 3915 | ||
3919 | ds.DrawBox(ref pos, ref R, ref sides); | 3916 | ds.DrawBox(ref pos, ref R, ref sides); |
3920 | } | ||
3921 | } | 3917 | } |
3922 | } | 3918 | } |
3923 | } | 3919 | } |
diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index 1413535..e4a3ba0 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs | |||
@@ -759,33 +759,33 @@ namespace OpenSim.Region.RegionCombinerModule | |||
759 | { | 759 | { |
760 | } | 760 | } |
761 | 761 | ||
762 | /// <summary> | 762 | // /// <summary> |
763 | /// TODO: | 763 | // /// TODO: |
764 | /// </summary> | 764 | // /// </summary> |
765 | /// <param name="rdata"></param> | 765 | // /// <param name="rdata"></param> |
766 | public void UnCombineRegion(RegionData rdata) | 766 | // public void UnCombineRegion(RegionData rdata) |
767 | { | 767 | // { |
768 | lock (m_regions) | 768 | // lock (m_regions) |
769 | { | 769 | // { |
770 | if (m_regions.ContainsKey(rdata.RegionId)) | 770 | // if (m_regions.ContainsKey(rdata.RegionId)) |
771 | { | 771 | // { |
772 | // uncombine root region and virtual regions | 772 | // // uncombine root region and virtual regions |
773 | } | 773 | // } |
774 | else | 774 | // else |
775 | { | 775 | // { |
776 | foreach (RegionConnections r in m_regions.Values) | 776 | // foreach (RegionConnections r in m_regions.Values) |
777 | { | 777 | // { |
778 | foreach (RegionData rd in r.ConnectedRegions) | 778 | // foreach (RegionData rd in r.ConnectedRegions) |
779 | { | 779 | // { |
780 | if (rd.RegionId == rdata.RegionId) | 780 | // if (rd.RegionId == rdata.RegionId) |
781 | { | 781 | // { |
782 | // uncombine virtual region | 782 | // // uncombine virtual region |
783 | } | 783 | // } |
784 | } | 784 | // } |
785 | } | 785 | // } |
786 | } | 786 | // } |
787 | } | 787 | // } |
788 | } | 788 | // } |
789 | 789 | ||
790 | // Create a set of infinite borders around the whole aabb of the combined island. | 790 | // Create a set of infinite borders around the whole aabb of the combined island. |
791 | private void AdjustLargeRegionBounds() | 791 | private void AdjustLargeRegionBounds() |
diff --git a/OpenSim/Services/Connectors/Neighbour/NeighbourServiceConnector.cs b/OpenSim/Services/Connectors/Neighbour/NeighbourServiceConnector.cs index 2cae02d..888b072 100644 --- a/OpenSim/Services/Connectors/Neighbour/NeighbourServiceConnector.cs +++ b/OpenSim/Services/Connectors/Neighbour/NeighbourServiceConnector.cs | |||
@@ -87,12 +87,26 @@ namespace OpenSim.Services.Connectors | |||
87 | public bool DoHelloNeighbourCall(GridRegion region, RegionInfo thisRegion) | 87 | public bool DoHelloNeighbourCall(GridRegion region, RegionInfo thisRegion) |
88 | { | 88 | { |
89 | string uri = region.ServerURI + "region/" + thisRegion.RegionID + "/"; | 89 | string uri = region.ServerURI + "region/" + thisRegion.RegionID + "/"; |
90 | //m_log.Debug(" >>> DoHelloNeighbourCall <<< " + uri); | 90 | // m_log.Debug(" >>> DoHelloNeighbourCall <<< " + uri); |
91 | 91 | ||
92 | WebRequest HelloNeighbourRequest = WebRequest.Create(uri); | 92 | WebRequest helloNeighbourRequest; |
93 | HelloNeighbourRequest.Method = "POST"; | 93 | |
94 | HelloNeighbourRequest.ContentType = "application/json"; | 94 | try |
95 | HelloNeighbourRequest.Timeout = 10000; | 95 | { |
96 | helloNeighbourRequest = WebRequest.Create(uri); | ||
97 | } | ||
98 | catch (Exception e) | ||
99 | { | ||
100 | m_log.WarnFormat( | ||
101 | "[NEIGHBOUR SERVICE CONNCTOR]: Unable to parse uri {0} to send HelloNeighbour from {1} to {2}. Exception {3}{4}", | ||
102 | uri, thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace); | ||
103 | |||
104 | return false; | ||
105 | } | ||
106 | |||
107 | helloNeighbourRequest.Method = "POST"; | ||
108 | helloNeighbourRequest.ContentType = "application/json"; | ||
109 | helloNeighbourRequest.Timeout = 10000; | ||
96 | 110 | ||
97 | // Fill it in | 111 | // Fill it in |
98 | OSDMap args = null; | 112 | OSDMap args = null; |
@@ -102,38 +116,48 @@ namespace OpenSim.Services.Connectors | |||
102 | } | 116 | } |
103 | catch (Exception e) | 117 | catch (Exception e) |
104 | { | 118 | { |
105 | m_log.Debug("[REST COMMS]: PackRegionInfoData failed with exception: " + e.Message); | 119 | m_log.WarnFormat( |
120 | "[NEIGHBOUR SERVICE CONNCTOR]: PackRegionInfoData failed for HelloNeighbour from {0} to {1}. Exception {2}{3}", | ||
121 | thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace); | ||
122 | |||
106 | return false; | 123 | return false; |
107 | } | 124 | } |
125 | |||
108 | // Add the regionhandle of the destination region | 126 | // Add the regionhandle of the destination region |
109 | args["destination_handle"] = OSD.FromString(region.RegionHandle.ToString()); | 127 | args["destination_handle"] = OSD.FromString(region.RegionHandle.ToString()); |
110 | 128 | ||
111 | string strBuffer = ""; | 129 | string strBuffer = ""; |
112 | byte[] buffer = new byte[1]; | 130 | byte[] buffer = new byte[1]; |
131 | |||
113 | try | 132 | try |
114 | { | 133 | { |
115 | strBuffer = OSDParser.SerializeJsonString(args); | 134 | strBuffer = OSDParser.SerializeJsonString(args); |
116 | UTF8Encoding str = new UTF8Encoding(); | 135 | UTF8Encoding str = new UTF8Encoding(); |
117 | buffer = str.GetBytes(strBuffer); | 136 | buffer = str.GetBytes(strBuffer); |
118 | |||
119 | } | 137 | } |
120 | catch (Exception e) | 138 | catch (Exception e) |
121 | { | 139 | { |
122 | m_log.WarnFormat("[REST COMMS]: Exception thrown on serialization of HelloNeighbour: {0}", e.Message); | 140 | m_log.WarnFormat( |
141 | "[NEIGHBOUR SERVICE CONNCTOR]: Exception thrown on serialization of HelloNeighbour from {0} to {1}. Exception {2}{3}", | ||
142 | thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace); | ||
143 | |||
123 | return false; | 144 | return false; |
124 | } | 145 | } |
125 | 146 | ||
126 | Stream os = null; | 147 | Stream os = null; |
127 | try | 148 | try |
128 | { // send the Post | 149 | { // send the Post |
129 | HelloNeighbourRequest.ContentLength = buffer.Length; //Count bytes to send | 150 | helloNeighbourRequest.ContentLength = buffer.Length; //Count bytes to send |
130 | os = HelloNeighbourRequest.GetRequestStream(); | 151 | os = helloNeighbourRequest.GetRequestStream(); |
131 | os.Write(buffer, 0, strBuffer.Length); //Send it | 152 | os.Write(buffer, 0, strBuffer.Length); //Send it |
132 | //m_log.InfoFormat("[REST COMMS]: Posted HelloNeighbour request to remote sim {0}", uri); | 153 | //m_log.InfoFormat("[REST COMMS]: Posted HelloNeighbour request to remote sim {0}", uri); |
133 | } | 154 | } |
134 | catch (Exception ex) | 155 | catch (Exception e) |
135 | { | 156 | { |
136 | m_log.InfoFormat("[REST COMMS]: Unable to send HelloNeighbour to {0}: {1}", region.RegionName, ex.Message); | 157 | m_log.WarnFormat( |
158 | "[NEIGHBOUR SERVICE CONNCTOR]: Unable to send HelloNeighbour from {0} to {1}. Exception {2}{3}", | ||
159 | thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace); | ||
160 | |||
137 | return false; | 161 | return false; |
138 | } | 162 | } |
139 | finally | 163 | finally |
@@ -148,10 +172,12 @@ namespace OpenSim.Services.Connectors | |||
148 | StreamReader sr = null; | 172 | StreamReader sr = null; |
149 | try | 173 | try |
150 | { | 174 | { |
151 | WebResponse webResponse = HelloNeighbourRequest.GetResponse(); | 175 | WebResponse webResponse = helloNeighbourRequest.GetResponse(); |
152 | if (webResponse == null) | 176 | if (webResponse == null) |
153 | { | 177 | { |
154 | m_log.Info("[REST COMMS]: Null reply on DoHelloNeighbourCall post"); | 178 | m_log.DebugFormat( |
179 | "[REST COMMS]: Null reply on DoHelloNeighbourCall post from {0} to {1}", | ||
180 | thisRegion.RegionName, region.RegionName); | ||
155 | } | 181 | } |
156 | 182 | ||
157 | sr = new StreamReader(webResponse.GetResponseStream()); | 183 | sr = new StreamReader(webResponse.GetResponseStream()); |
@@ -160,9 +186,12 @@ namespace OpenSim.Services.Connectors | |||
160 | //m_log.InfoFormat("[REST COMMS]: DoHelloNeighbourCall reply was {0} ", reply); | 186 | //m_log.InfoFormat("[REST COMMS]: DoHelloNeighbourCall reply was {0} ", reply); |
161 | 187 | ||
162 | } | 188 | } |
163 | catch (Exception ex) | 189 | catch (Exception e) |
164 | { | 190 | { |
165 | m_log.InfoFormat("[REST COMMS]: exception on reply of DoHelloNeighbourCall {0}", ex.Message); | 191 | m_log.WarnFormat( |
192 | "[NEIGHBOUR SERVICE CONNCTOR]: Exception on reply of DoHelloNeighbourCall from {0} back to {1}. Exception {2}{3}", | ||
193 | region.RegionName, thisRegion.RegionName, e.Message, e.StackTrace); | ||
194 | |||
166 | return false; | 195 | return false; |
167 | } | 196 | } |
168 | finally | 197 | finally |
@@ -172,8 +201,6 @@ namespace OpenSim.Services.Connectors | |||
172 | } | 201 | } |
173 | 202 | ||
174 | return true; | 203 | return true; |
175 | |||
176 | } | 204 | } |
177 | |||
178 | } | 205 | } |
179 | } | 206 | } \ No newline at end of file |
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs index d8089ac..9573e21 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs | |||
@@ -334,7 +334,9 @@ namespace OpenSim.Services.Connectors.SimianGrid | |||
334 | // Make the remote storage request | 334 | // Make the remote storage request |
335 | try | 335 | try |
336 | { | 336 | { |
337 | HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_serverUrl); | 337 | // Simian does not require the asset ID to be in the URL because it's in the post data. |
338 | // By appending it to the URL also, we allow caching proxies (squid) to invalidate asset URLs | ||
339 | HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_serverUrl + asset.FullID.ToString()); | ||
338 | 340 | ||
339 | HttpWebResponse response = MultipartForm.Post(request, postParameters); | 341 | HttpWebResponse response = MultipartForm.Post(request, postParameters); |
340 | using (Stream responseStream = response.GetResponseStream()) | 342 | using (Stream responseStream = response.GetResponseStream()) |
diff --git a/OpenSim/Tests/ConfigurationLoaderTest.cs b/OpenSim/Tests/ConfigurationLoaderTest.cs index c777acc..067264d 100644 --- a/OpenSim/Tests/ConfigurationLoaderTest.cs +++ b/OpenSim/Tests/ConfigurationLoaderTest.cs | |||
@@ -109,11 +109,13 @@ namespace OpenSim.Tests | |||
109 | // Prepare call to ConfigurationLoader.LoadConfigSettings() | 109 | // Prepare call to ConfigurationLoader.LoadConfigSettings() |
110 | ConfigurationLoader cl = new ConfigurationLoader(); | 110 | ConfigurationLoader cl = new ConfigurationLoader(); |
111 | IConfigSource argvSource = new IniConfigSource(); | 111 | IConfigSource argvSource = new IniConfigSource(); |
112 | EnvConfigSource envConfigSource = new EnvConfigSource(); | ||
112 | argvSource.AddConfig("Startup").Set("inifile", mainIniFile); | 113 | argvSource.AddConfig("Startup").Set("inifile", mainIniFile); |
113 | ConfigSettings configSettings; | 114 | ConfigSettings configSettings; |
114 | NetworkServersInfo networkInfo; | 115 | NetworkServersInfo networkInfo; |
115 | 116 | ||
116 | OpenSimConfigSource source = cl.LoadConfigSettings(argvSource, out configSettings, out networkInfo); | 117 | OpenSimConfigSource source = cl.LoadConfigSettings(argvSource, envConfigSource, |
118 | out configSettings, out networkInfo); | ||
117 | 119 | ||
118 | // Remove default config | 120 | // Remove default config |
119 | config = source.Source.Configs["Startup"]; | 121 | config = source.Source.Configs["Startup"]; |
diff --git a/OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs index 7084ab4..0a6d5d2 100644 --- a/OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs | |||
@@ -41,6 +41,8 @@ namespace pCampBot | |||
41 | /// </remarks> | 41 | /// </remarks> |
42 | public class GrabbingBehaviour : IBehaviour | 42 | public class GrabbingBehaviour : IBehaviour |
43 | { | 43 | { |
44 | public string Name { get { return "Grabbing"; } } | ||
45 | |||
44 | public void Action(Bot bot) | 46 | public void Action(Bot bot) |
45 | { | 47 | { |
46 | Dictionary<UUID, Primitive> objects = bot.Objects; | 48 | Dictionary<UUID, Primitive> objects = bot.Objects; |
diff --git a/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs index 3ce08bf..f782bb5 100644 --- a/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs | |||
@@ -42,6 +42,8 @@ namespace pCampBot | |||
42 | /// </remarks> | 42 | /// </remarks> |
43 | public class PhysicsBehaviour : IBehaviour | 43 | public class PhysicsBehaviour : IBehaviour |
44 | { | 44 | { |
45 | public string Name { get { return "Physics"; } } | ||
46 | |||
45 | private string[] talkarray; | 47 | private string[] talkarray; |
46 | 48 | ||
47 | public PhysicsBehaviour() | 49 | public PhysicsBehaviour() |
diff --git a/OpenSim/Tools/pCampBot/Behaviours/TeleportBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/TeleportBehaviour.cs new file mode 100644 index 0000000..fc2ed2c --- /dev/null +++ b/OpenSim/Tools/pCampBot/Behaviours/TeleportBehaviour.cs | |||
@@ -0,0 +1,75 @@ | |||
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.Linq; | ||
31 | using System.Reflection; | ||
32 | using log4net; | ||
33 | using OpenMetaverse; | ||
34 | using pCampBot.Interfaces; | ||
35 | |||
36 | namespace pCampBot | ||
37 | { | ||
38 | /// <summary> | ||
39 | /// Teleport to a random region on the grid. | ||
40 | /// </summary> | ||
41 | public class TeleportBehaviour : IBehaviour | ||
42 | { | ||
43 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
44 | |||
45 | public string Name { get { return "Teleport"; } } | ||
46 | |||
47 | public void Action(Bot bot) | ||
48 | { | ||
49 | Random rng = bot.Manager.Rng; | ||
50 | GridRegion[] knownRegions; | ||
51 | |||
52 | lock (bot.Manager.RegionsKnown) | ||
53 | { | ||
54 | if (bot.Manager.RegionsKnown.Count == 0) | ||
55 | { | ||
56 | m_log.DebugFormat( | ||
57 | "[TELEPORT BEHAVIOUR]: Ignoring teleport action for {0} since no regions are known yet", bot.Name); | ||
58 | return; | ||
59 | } | ||
60 | |||
61 | knownRegions = bot.Manager.RegionsKnown.Values.ToArray(); | ||
62 | } | ||
63 | |||
64 | Simulator sourceRegion = bot.Client.Network.CurrentSim; | ||
65 | GridRegion destRegion = knownRegions[rng.Next(knownRegions.Length)]; | ||
66 | Vector3 destPosition = new Vector3(rng.Next(255), rng.Next(255), 50); | ||
67 | |||
68 | m_log.DebugFormat( | ||
69 | "[TELEPORT BEHAVIOUR]: Teleporting {0} from {1} {2} to {3} {4}", | ||
70 | bot.Name, sourceRegion.Name, bot.Client.Self.SimPosition, destRegion.Name, destPosition); | ||
71 | |||
72 | bot.Client.Self.Teleport(destRegion.RegionHandle, destPosition); | ||
73 | } | ||
74 | } | ||
75 | } \ No newline at end of file | ||
diff --git a/OpenSim/Tools/pCampBot/Bot.cs b/OpenSim/Tools/pCampBot/Bot.cs index 7f941a4..7a73e3f 100644 --- a/OpenSim/Tools/pCampBot/Bot.cs +++ b/OpenSim/Tools/pCampBot/Bot.cs | |||
@@ -49,8 +49,15 @@ namespace pCampBot | |||
49 | 49 | ||
50 | public delegate void AnEvent(Bot callbot, EventType someevent); // event delegate for bot events | 50 | public delegate void AnEvent(Bot callbot, EventType someevent); // event delegate for bot events |
51 | 51 | ||
52 | public BotManager BotManager { get; private set; } | 52 | /// <summary> |
53 | private IConfig startupConfig; // bot config, passed from BotManager | 53 | /// Bot manager. |
54 | /// </summary> | ||
55 | public BotManager Manager { get; private set; } | ||
56 | |||
57 | /// <summary> | ||
58 | /// Bot config, passed from BotManager. | ||
59 | /// </summary> | ||
60 | private IConfig startupConfig; | ||
54 | 61 | ||
55 | /// <summary> | 62 | /// <summary> |
56 | /// Behaviours implemented by this bot. | 63 | /// Behaviours implemented by this bot. |
@@ -132,7 +139,7 @@ namespace pCampBot | |||
132 | Password = password; | 139 | Password = password; |
133 | LoginUri = loginUri; | 140 | LoginUri = loginUri; |
134 | 141 | ||
135 | BotManager = bm; | 142 | Manager = bm; |
136 | startupConfig = bm.Config; | 143 | startupConfig = bm.Config; |
137 | readconfig(); | 144 | readconfig(); |
138 | 145 | ||
@@ -218,7 +225,19 @@ namespace pCampBot | |||
218 | { | 225 | { |
219 | MakeDefaultAppearance(wear); | 226 | MakeDefaultAppearance(wear); |
220 | } | 227 | } |
228 | |||
221 | Client.Self.Jump(true); | 229 | Client.Self.Jump(true); |
230 | |||
231 | // Extract nearby region information. | ||
232 | Client.Grid.GridRegion += Manager.Grid_GridRegion; | ||
233 | uint xUint, yUint; | ||
234 | Utils.LongToUInts(Client.Network.CurrentSim.Handle, out xUint, out yUint); | ||
235 | ushort minX, minY, maxX, maxY; | ||
236 | minX = (ushort)Math.Min(0, xUint - 5); | ||
237 | minY = (ushort)Math.Min(0, yUint - 5); | ||
238 | maxX = (ushort)(xUint + 5); | ||
239 | maxY = (ushort)(yUint + 5); | ||
240 | Client.Grid.RequestMapBlocks(GridLayerType.Terrain, minX, minY, maxX, maxY, false); | ||
222 | } | 241 | } |
223 | else | 242 | else |
224 | { | 243 | { |
@@ -472,13 +491,13 @@ namespace pCampBot | |||
472 | 491 | ||
473 | private void GetTexture(UUID textureID) | 492 | private void GetTexture(UUID textureID) |
474 | { | 493 | { |
475 | lock (BotManager.AssetsReceived) | 494 | lock (Manager.AssetsReceived) |
476 | { | 495 | { |
477 | // Don't request assets more than once. | 496 | // Don't request assets more than once. |
478 | if (BotManager.AssetsReceived.ContainsKey(textureID)) | 497 | if (Manager.AssetsReceived.ContainsKey(textureID)) |
479 | return; | 498 | return; |
480 | 499 | ||
481 | BotManager.AssetsReceived[textureID] = false; | 500 | Manager.AssetsReceived[textureID] = false; |
482 | Client.Assets.RequestImage(textureID, ImageType.Normal, Asset_TextureCallback_Texture); | 501 | Client.Assets.RequestImage(textureID, ImageType.Normal, Asset_TextureCallback_Texture); |
483 | } | 502 | } |
484 | } | 503 | } |
@@ -490,8 +509,8 @@ namespace pCampBot | |||
490 | 509 | ||
491 | public void Asset_ReceivedCallback(AssetDownload transfer, Asset asset) | 510 | public void Asset_ReceivedCallback(AssetDownload transfer, Asset asset) |
492 | { | 511 | { |
493 | lock (BotManager.AssetsReceived) | 512 | lock (Manager.AssetsReceived) |
494 | BotManager.AssetsReceived[asset.AssetID] = true; | 513 | Manager.AssetsReceived[asset.AssetID] = true; |
495 | 514 | ||
496 | // if (wear == "save") | 515 | // if (wear == "save") |
497 | // { | 516 | // { |
diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index f5dd5e0..29cb1ba 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Linq; | ||
30 | using System.Reflection; | 31 | using System.Reflection; |
31 | using System.Threading; | 32 | using System.Threading; |
32 | using OpenMetaverse; | 33 | using OpenMetaverse; |
@@ -48,9 +49,24 @@ namespace pCampBot | |||
48 | { | 49 | { |
49 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 50 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
50 | 51 | ||
52 | /// <summary> | ||
53 | /// Command console | ||
54 | /// </summary> | ||
51 | protected CommandConsole m_console; | 55 | protected CommandConsole m_console; |
56 | |||
57 | /// <summary> | ||
58 | /// Created bots, whether active or inactive. | ||
59 | /// </summary> | ||
52 | protected List<Bot> m_lBot; | 60 | protected List<Bot> m_lBot; |
53 | protected Random somthing = new Random(Environment.TickCount); | 61 | |
62 | /// <summary> | ||
63 | /// Random number generator. | ||
64 | /// </summary> | ||
65 | public Random Rng { get; private set; } | ||
66 | |||
67 | /// <summary> | ||
68 | /// Overall configuration. | ||
69 | /// </summary> | ||
54 | public IConfig Config { get; private set; } | 70 | public IConfig Config { get; private set; } |
55 | 71 | ||
56 | /// <summary> | 72 | /// <summary> |
@@ -59,11 +75,18 @@ namespace pCampBot | |||
59 | public Dictionary<UUID, bool> AssetsReceived { get; private set; } | 75 | public Dictionary<UUID, bool> AssetsReceived { get; private set; } |
60 | 76 | ||
61 | /// <summary> | 77 | /// <summary> |
78 | /// The regions that we know about. | ||
79 | /// </summary> | ||
80 | public Dictionary<ulong, GridRegion> RegionsKnown { get; private set; } | ||
81 | |||
82 | /// <summary> | ||
62 | /// Constructor Creates MainConsole.Instance to take commands and provide the place to write data | 83 | /// Constructor Creates MainConsole.Instance to take commands and provide the place to write data |
63 | /// </summary> | 84 | /// </summary> |
64 | public BotManager() | 85 | public BotManager() |
65 | { | 86 | { |
87 | Rng = new Random(Environment.TickCount); | ||
66 | AssetsReceived = new Dictionary<UUID, bool>(); | 88 | AssetsReceived = new Dictionary<UUID, bool>(); |
89 | RegionsKnown = new Dictionary<ulong, GridRegion>(); | ||
67 | 90 | ||
68 | m_console = CreateConsole(); | 91 | m_console = CreateConsole(); |
69 | MainConsole.Instance = m_console; | 92 | MainConsole.Instance = m_console; |
@@ -93,8 +116,13 @@ namespace pCampBot | |||
93 | "Shutdown bots and exit", | 116 | "Shutdown bots and exit", |
94 | HandleShutdown); | 117 | HandleShutdown); |
95 | 118 | ||
96 | m_console.Commands.AddCommand("bot", false, "show status", | 119 | m_console.Commands.AddCommand("bot", false, "show regions", |
97 | "show status", | 120 | "show regions", |
121 | "Show regions known to bots", | ||
122 | HandleShowRegions); | ||
123 | |||
124 | m_console.Commands.AddCommand("bot", false, "show bots", | ||
125 | "show bots", | ||
98 | "Shows the status of all bots", | 126 | "Shows the status of all bots", |
99 | HandleShowStatus); | 127 | HandleShowStatus); |
100 | 128 | ||
@@ -123,19 +151,26 @@ namespace pCampBot | |||
123 | Array.ForEach<string>( | 151 | Array.ForEach<string>( |
124 | cs.GetString("behaviours", "p").Split(new char[] { ',' }), b => behaviourSwitches.Add(b)); | 152 | cs.GetString("behaviours", "p").Split(new char[] { ',' }), b => behaviourSwitches.Add(b)); |
125 | 153 | ||
154 | List<IBehaviour> behaviours = new List<IBehaviour>(); | ||
155 | |||
156 | // Hard-coded for now | ||
157 | if (behaviourSwitches.Contains("p")) | ||
158 | behaviours.Add(new PhysicsBehaviour()); | ||
159 | |||
160 | if (behaviourSwitches.Contains("g")) | ||
161 | behaviours.Add(new GrabbingBehaviour()); | ||
162 | |||
163 | if (behaviourSwitches.Contains("t")) | ||
164 | behaviours.Add(new TeleportBehaviour()); | ||
165 | |||
166 | MainConsole.Instance.OutputFormat( | ||
167 | "[BOT MANAGER]: Bots configured for behaviours {0}", | ||
168 | string.Join(",", behaviours.ConvertAll<string>(b => b.Name).ToArray())); | ||
169 | |||
126 | for (int i = 0; i < botcount; i++) | 170 | for (int i = 0; i < botcount; i++) |
127 | { | 171 | { |
128 | string lastName = string.Format("{0}_{1}", lastNameStem, i); | 172 | string lastName = string.Format("{0}_{1}", lastNameStem, i); |
129 | 173 | ||
130 | List<IBehaviour> behaviours = new List<IBehaviour>(); | ||
131 | |||
132 | // Hard-coded for now | ||
133 | if (behaviourSwitches.Contains("p")) | ||
134 | behaviours.Add(new PhysicsBehaviour()); | ||
135 | |||
136 | if (behaviourSwitches.Contains("g")) | ||
137 | behaviours.Add(new GrabbingBehaviour()); | ||
138 | |||
139 | StartBot(this, behaviours, firstName, lastName, password, loginUri); | 174 | StartBot(this, behaviours, firstName, lastName, password, loginUri); |
140 | } | 175 | } |
141 | } | 176 | } |
@@ -240,17 +275,33 @@ namespace pCampBot | |||
240 | }); | 275 | }); |
241 | } | 276 | } |
242 | 277 | ||
278 | private void HandleShowRegions(string module, string[] cmd) | ||
279 | { | ||
280 | string outputFormat = "{0,-30} {1, -20} {2, -5} {3, -5}"; | ||
281 | MainConsole.Instance.OutputFormat(outputFormat, "Name", "Handle", "X", "Y"); | ||
282 | |||
283 | lock (RegionsKnown) | ||
284 | { | ||
285 | foreach (GridRegion region in RegionsKnown.Values) | ||
286 | { | ||
287 | MainConsole.Instance.OutputFormat( | ||
288 | outputFormat, region.Name, region.RegionHandle, region.X, region.Y); | ||
289 | } | ||
290 | } | ||
291 | } | ||
292 | |||
243 | private void HandleShowStatus(string module, string[] cmd) | 293 | private void HandleShowStatus(string module, string[] cmd) |
244 | { | 294 | { |
245 | string outputFormat = "{0,-30} {1,-14}"; | 295 | string outputFormat = "{0,-30} {1, -30} {2,-14}"; |
246 | MainConsole.Instance.OutputFormat(outputFormat, "Name", "Status"); | 296 | MainConsole.Instance.OutputFormat(outputFormat, "Name", "Region", "Status"); |
247 | 297 | ||
248 | lock (m_lBot) | 298 | lock (m_lBot) |
249 | { | 299 | { |
250 | foreach (Bot pb in m_lBot) | 300 | foreach (Bot pb in m_lBot) |
251 | { | 301 | { |
252 | MainConsole.Instance.OutputFormat( | 302 | MainConsole.Instance.OutputFormat( |
253 | outputFormat, pb.Name, (pb.IsConnected ? "Connected" : "Disconnected")); | 303 | outputFormat, |
304 | pb.Name, pb.Client.Network.CurrentSim.Name, pb.IsConnected ? "Connected" : "Disconnected"); | ||
254 | } | 305 | } |
255 | } | 306 | } |
256 | } | 307 | } |
@@ -274,5 +325,24 @@ namespace pCampBot | |||
274 | // if (newbots > 0) | 325 | // if (newbots > 0) |
275 | // addbots(newbots); | 326 | // addbots(newbots); |
276 | // } | 327 | // } |
328 | |||
329 | internal void Grid_GridRegion(object o, GridRegionEventArgs args) | ||
330 | { | ||
331 | lock (RegionsKnown) | ||
332 | { | ||
333 | GridRegion newRegion = args.Region; | ||
334 | |||
335 | if (RegionsKnown.ContainsKey(newRegion.RegionHandle)) | ||
336 | { | ||
337 | return; | ||
338 | } | ||
339 | else | ||
340 | { | ||
341 | m_log.DebugFormat( | ||
342 | "[BOT MANAGER]: Adding {0} {1} to known regions", newRegion.Name, newRegion.RegionHandle); | ||
343 | RegionsKnown[newRegion.RegionHandle] = newRegion; | ||
344 | } | ||
345 | } | ||
346 | } | ||
277 | } | 347 | } |
278 | } | 348 | } |
diff --git a/OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs b/OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs index d4ae0f0..912216f 100644 --- a/OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs | |||
@@ -31,6 +31,15 @@ namespace pCampBot.Interfaces | |||
31 | { | 31 | { |
32 | public interface IBehaviour | 32 | public interface IBehaviour |
33 | { | 33 | { |
34 | /// <summary> | ||
35 | /// Name of this behaviour. | ||
36 | /// </summary> | ||
37 | string Name { get; } | ||
38 | |||
39 | /// <summary> | ||
40 | /// Action to take when this behaviour is invoked. | ||
41 | /// </summary> | ||
42 | /// <param name="bot"></param> | ||
34 | void Action(Bot bot); | 43 | void Action(Bot bot); |
35 | } | 44 | } |
36 | } \ No newline at end of file | 45 | } \ No newline at end of file |
diff --git a/OpenSim/Tools/pCampBot/pCampBot.cs b/OpenSim/Tools/pCampBot/pCampBot.cs index 4d3b06d..e7288d5 100644 --- a/OpenSim/Tools/pCampBot/pCampBot.cs +++ b/OpenSim/Tools/pCampBot/pCampBot.cs | |||
@@ -111,7 +111,7 @@ namespace pCampBot | |||
111 | " -firstname first name for the bots\n" + | 111 | " -firstname first name for the bots\n" + |
112 | " -lastname lastname for the bots. Each lastname will have _<bot-number> appended, e.g. Ima Bot_0\n" + | 112 | " -lastname lastname for the bots. Each lastname will have _<bot-number> appended, e.g. Ima Bot_0\n" + |
113 | " -password password for the bots\n" + | 113 | " -password password for the bots\n" + |
114 | " -b, behaviours behaviours for bots. Current options p (physics), g (grab). Comma separated, e.g. p,g. Default is p", | 114 | " -b, behaviours behaviours for bots. Current options p (physics), g (grab), t (teleport). Comma separated, e.g. p,g. Default is p", |
115 | " -wear set appearance folder to load from (default: no)\n" + | 115 | " -wear set appearance folder to load from (default: no)\n" + |
116 | " -h, -help show this message" | 116 | " -h, -help show this message" |
117 | ); | 117 | ); |