aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorDiva Canto2015-05-25 15:19:27 -0700
committerDiva Canto2015-05-25 15:19:27 -0700
commit22ee1c30e3de30537e236259a3ebdb6927d00a04 (patch)
tree32346c0c0d098053005645f6ff84cb7da89e2f16 /OpenSim/Region
parentMinor change of statement order in unit test (diff)
parentFix mesh cache race condition in llCastRay V3. (diff)
downloadopensim-SC-22ee1c30e3de30537e236259a3ebdb6927d00a04.zip
opensim-SC-22ee1c30e3de30537e236259a3ebdb6927d00a04.tar.gz
opensim-SC-22ee1c30e3de30537e236259a3ebdb6927d00a04.tar.bz2
opensim-SC-22ee1c30e3de30537e236259a3ebdb6927d00a04.tar.xz
Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs1
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs29
-rwxr-xr-xOpenSim/Region/Framework/Scenes/Scene.cs1405
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/Framework/Scenes/SceneGraph.cs59
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs30
-rwxr-xr-xOpenSim/Region/Framework/Scenes/SimStatsReporter.cs221
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs678
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/ScriptEngine/XEngine/XEngine.cs36
8 files changed, 1451 insertions, 1008 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 855342f..284c5fa 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -3747,6 +3747,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3747 avp.Sender.IsTrial = false; 3747 avp.Sender.IsTrial = false;
3748 avp.Sender.ID = agentID; 3748 avp.Sender.ID = agentID;
3749 avp.AppearanceData = new AvatarAppearancePacket.AppearanceDataBlock[0]; 3749 avp.AppearanceData = new AvatarAppearancePacket.AppearanceDataBlock[0];
3750 avp.AppearanceHover = new AvatarAppearancePacket.AppearanceHoverBlock[0];
3750 //m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString()); 3751 //m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString());
3751 OutPacket(avp, ThrottleOutPacketType.Task); 3752 OutPacket(avp, ThrottleOutPacketType.Task);
3752 } 3753 }
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index ba71dc5..7ecbd26 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -154,7 +154,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
154 154
155 #endregion ISharedRegionModule 155 #endregion ISharedRegionModule
156 156
157 157
158 #region Event Handlers 158 #region Event Handlers
159 159
160 void EventManager_OnPrimsLoaded(Scene s) 160 void EventManager_OnPrimsLoaded(Scene s)
@@ -180,7 +180,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
180 void HandleUUIDNameRequest(UUID uuid, IClientAPI client) 180 void HandleUUIDNameRequest(UUID uuid, IClientAPI client)
181 { 181 {
182// m_log.DebugFormat( 182// m_log.DebugFormat(
183// "[USER MANAGEMENT MODULE]: Handling request for name binding of UUID {0} from {1}", 183// "[USER MANAGEMENT MODULE]: Handling request for name binding of UUID {0} from {1}",
184// uuid, remote_client.Name); 184// uuid, remote_client.Name);
185 185
186 if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid)) 186 if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid))
@@ -212,7 +212,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
212 // appear to clear this when the user asks it to clear the cache, but others may not. 212 // appear to clear this when the user asks it to clear the cache, but others may not.
213 // 213 //
214 // So to avoid clients 214 // So to avoid clients
215 // (particularly Hypergrid clients) permanently binding "Unknown User" to a given UUID, we will 215 // (particularly Hypergrid clients) permanently binding "Unknown User" to a given UUID, we will
216 // instead drop the request entirely. 216 // instead drop the request entirely.
217 if (GetUser(uuid, out user)) 217 if (GetUser(uuid, out user))
218 { 218 {
@@ -220,7 +220,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
220 } 220 }
221// else 221// else
222// m_log.DebugFormat( 222// m_log.DebugFormat(
223// "[USER MANAGEMENT MODULE]: No bound name for {0} found, ignoring request from {1}", 223// "[USER MANAGEMENT MODULE]: No bound name for {0} found, ignoring request from {1}",
224// uuid, client.Name); 224// uuid, client.Name);
225 }); 225 });
226 } 226 }
@@ -416,7 +416,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
416 m_log.Debug("[USER MANAGEMENT MODULE]: GetServerURLs call failed ", e); 416 m_log.Debug("[USER MANAGEMENT MODULE]: GetServerURLs call failed ", e);
417 userdata.ServerURLs = new Dictionary<string, object>(); 417 userdata.ServerURLs = new Dictionary<string, object>();
418 } 418 }
419 419
420 if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null) 420 if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null)
421 return userdata.ServerURLs[serverType].ToString(); 421 return userdata.ServerURLs[serverType].ToString();
422 } 422 }
@@ -620,7 +620,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
620 AddUser(id, string.Empty, string.Empty, string.Empty); 620 AddUser(id, string.Empty, string.Empty, string.Empty);
621 } 621 }
622 else 622 else
623 { 623 {
624 string homeURL; 624 string homeURL;
625 string firstname = string.Empty; 625 string firstname = string.Empty;
626 string lastname = string.Empty; 626 string lastname = string.Empty;
@@ -676,7 +676,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
676 else 676 else
677 { 677 {
678 lock(m_UserCache) 678 lock(m_UserCache)
679 { 679 {
680 if(!m_UserCache.ContainsKey(id)) 680 if(!m_UserCache.ContainsKey(id))
681 { 681 {
682 UserData newUser = new UserData(); 682 UserData newUser = new UserData();
@@ -726,6 +726,21 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
726 "Show the bindings between user UUIDs and user names", 726 "Show the bindings between user UUIDs and user names",
727 String.Empty, 727 String.Empty,
728 HandleShowUsers); 728 HandleShowUsers);
729
730 MainConsole.Instance.Commands.AddCommand("Users", true,
731 "reset user cache",
732 "reset user cache",
733 "reset user cache to allow changed settings to be applied",
734 String.Empty,
735 HandleResetUserCache);
736 }
737
738 private void HandleResetUserCache(string module, string[] cmd)
739 {
740 lock(m_UserCache)
741 {
742 m_UserCache.Clear();
743 }
729 } 744 }
730 745
731 private void HandleShowUser(string module, string[] cmd) 746 private void HandleShowUser(string module, string[] cmd)
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 906c862..c539f1f 100755
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1,29 +1,29 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2* Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4*
5 * Redistribution and use in source and binary forms, with or without 5* Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6* modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7* * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8* notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9* * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10* notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11* documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the 12* * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products 13* names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14* derived from this software without specific prior written permission.
15 * 15*
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 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 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 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 24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26*/
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
@@ -48,7 +48,7 @@ using OpenSim.Region.Framework.Interfaces;
48using OpenSim.Region.Framework.Scenes.Scripting; 48using OpenSim.Region.Framework.Scenes.Scripting;
49using OpenSim.Region.Framework.Scenes.Serialization; 49using OpenSim.Region.Framework.Scenes.Serialization;
50using OpenSim.Region.Physics.Manager; 50using OpenSim.Region.Physics.Manager;
51using Timer=System.Timers.Timer; 51using Timer = System.Timers.Timer;
52using TPFlags = OpenSim.Framework.Constants.TeleportFlags; 52using TPFlags = OpenSim.Framework.Constants.TeleportFlags;
53using GridRegion = OpenSim.Services.Interfaces.GridRegion; 53using GridRegion = OpenSim.Services.Interfaces.GridRegion;
54using PermissionMask = OpenSim.Framework.PermissionMask; 54using PermissionMask = OpenSim.Framework.PermissionMask;
@@ -61,6 +61,8 @@ namespace OpenSim.Region.Framework.Scenes
61 { 61 {
62 private const long DEFAULT_MIN_TIME_FOR_PERSISTENCE = 60L; 62 private const long DEFAULT_MIN_TIME_FOR_PERSISTENCE = 60L;
63 private const long DEFAULT_MAX_TIME_FOR_PERSISTENCE = 600L; 63 private const long DEFAULT_MAX_TIME_FOR_PERSISTENCE = 600L;
64
65 public const int m_defaultNumberFramesStored = 10;
64 66
65 public delegate void SynchronizeSceneHandler(Scene scene); 67 public delegate void SynchronizeSceneHandler(Scene scene);
66 68
@@ -103,9 +105,9 @@ namespace OpenSim.Region.Framework.Scenes
103 /// <summary> 105 /// <summary>
104 /// If false then physical objects are disabled, though collisions will continue as normal. 106 /// If false then physical objects are disabled, though collisions will continue as normal.
105 /// </summary> 107 /// </summary>
106 public bool PhysicsEnabled 108 public bool PhysicsEnabled
107 { 109 {
108 get 110 get
109 { 111 {
110 return m_physicsEnabled; 112 return m_physicsEnabled;
111 } 113 }
@@ -119,8 +121,8 @@ namespace OpenSim.Region.Framework.Scenes
119 IPhysicsParameters physScene = PhysicsScene as IPhysicsParameters; 121 IPhysicsParameters physScene = PhysicsScene as IPhysicsParameters;
120 122
121 if (physScene != null) 123 if (physScene != null)
122 physScene.SetPhysicsParameter( 124 physScene.SetPhysicsParameter(
123 "Active", m_physicsEnabled.ToString(), PhysParameterEntry.APPLY_TO_NONE); 125 "Active", m_physicsEnabled.ToString(), PhysParameterEntry.APPLY_TO_NONE);
124 } 126 }
125 } 127 }
126 } 128 }
@@ -130,10 +132,10 @@ namespace OpenSim.Region.Framework.Scenes
130 /// <summary> 132 /// <summary>
131 /// If false then scripts are not enabled on the smiulator 133 /// If false then scripts are not enabled on the smiulator
132 /// </summary> 134 /// </summary>
133 public bool ScriptsEnabled 135 public bool ScriptsEnabled
134 { 136 {
135 get { return m_scripts_enabled; } 137 get { return m_scripts_enabled; }
136 set 138 set
137 { 139 {
138 if (m_scripts_enabled != value) 140 if (m_scripts_enabled != value)
139 { 141 {
@@ -145,13 +147,13 @@ namespace OpenSim.Region.Framework.Scenes
145 foreach (EntityBase ent in entities) 147 foreach (EntityBase ent in entities)
146 { 148 {
147 if (ent is SceneObjectGroup) 149 if (ent is SceneObjectGroup)
148 ((SceneObjectGroup)ent).RemoveScriptInstances(false); 150 ((SceneObjectGroup)ent).RemoveScriptInstances(false);
149 } 151 }
150 } 152 }
151 else 153 else
152 { 154 {
153 m_log.Info("Starting all Scripts in Scene"); 155 m_log.Info("Starting all Scripts in Scene");
154 156
155 EntityBase[] entities = Entities.GetEntities(); 157 EntityBase[] entities = Entities.GetEntities();
156 foreach (EntityBase ent in entities) 158 foreach (EntityBase ent in entities)
157 { 159 {
@@ -236,8 +238,8 @@ namespace OpenSim.Region.Framework.Scenes
236 /// <summary> 238 /// <summary>
237 /// Temporarily setting to trigger appearance resends at 60 second intervals. 239 /// Temporarily setting to trigger appearance resends at 60 second intervals.
238 /// </summary> 240 /// </summary>
239 public bool SendPeriodicAppearanceUpdates { get; set; } 241 public bool SendPeriodicAppearanceUpdates { get; set; }
240 242
241 /// <summary> 243 /// <summary>
242 /// How much a root agent has to change position before updates are sent to viewers. 244 /// How much a root agent has to change position before updates are sent to viewers.
243 /// </summary> 245 /// </summary>
@@ -264,10 +266,11 @@ namespace OpenSim.Region.Framework.Scenes
264 public int ChildTerseUpdatePeriod { get; set; } 266 public int ChildTerseUpdatePeriod { get; set; }
265 267
266 protected float m_defaultDrawDistance = 255.0f; 268 protected float m_defaultDrawDistance = 255.0f;
267 public float DefaultDrawDistance 269 public float DefaultDrawDistance
268 { 270 {
269 // get { return m_defaultDrawDistance; } 271 // get { return m_defaultDrawDistance; }
270 get { 272 get
273 {
271 if (RegionInfo != null) 274 if (RegionInfo != null)
272 { 275 {
273 float largestDimension = Math.Max(RegionInfo.RegionSizeX, RegionInfo.RegionSizeY); 276 float largestDimension = Math.Max(RegionInfo.RegionSizeX, RegionInfo.RegionSizeY);
@@ -280,7 +283,7 @@ namespace OpenSim.Region.Framework.Scenes
280 283
281 private List<string> m_AllowedViewers = new List<string>(); 284 private List<string> m_AllowedViewers = new List<string>();
282 private List<string> m_BannedViewers = new List<string>(); 285 private List<string> m_BannedViewers = new List<string>();
283 286
284 // TODO: need to figure out how allow client agents but deny 287 // TODO: need to figure out how allow client agents but deny
285 // root agents when ACL denies access to root agent 288 // root agents when ACL denies access to root agent
286 public bool m_strictAccessControl = true; 289 public bool m_strictAccessControl = true;
@@ -367,15 +370,15 @@ namespace OpenSim.Region.Framework.Scenes
367 /// One can tweak this number to experiment. One current effect of reducing it is to make avatar animations 370 /// One can tweak this number to experiment. One current effect of reducing it is to make avatar animations
368 /// occur too quickly (viewer 1) or with even more slide (viewer 2). 371 /// occur too quickly (viewer 1) or with even more slide (viewer 2).
369 /// </remarks> 372 /// </remarks>
370 public int MinFrameTicks 373 public int MinFrameTicks
371 { 374 {
372 get { return m_minFrameTicks; } 375 get { return m_minFrameTicks; }
373 private set 376 private set
374 { 377 {
375 m_minFrameTicks = value; 378 m_minFrameTicks = value;
376 MinFrameSeconds = (float)m_minFrameTicks / 1000; 379 MinFrameSeconds = (float)m_minFrameTicks / 1000;
377 } 380 }
378 } 381 }
379 private int m_minFrameTicks; 382 private int m_minFrameTicks;
380 383
381 /// <summary> 384 /// <summary>
@@ -403,7 +406,7 @@ namespace OpenSim.Region.Framework.Scenes
403 private int m_update_events = 1; 406 private int m_update_events = 1;
404 private int m_update_backup = 200; 407 private int m_update_backup = 200;
405 private int m_update_terrain = 50; 408 private int m_update_terrain = 50;
406// private int m_update_land = 1; 409 // private int m_update_land = 1;
407 private int m_update_coarse_locations = 50; 410 private int m_update_coarse_locations = 50;
408 private int m_update_temp_cleaning = 180; 411 private int m_update_temp_cleaning = 180;
409 412
@@ -434,7 +437,7 @@ namespace OpenSim.Region.Framework.Scenes
434 /// asynchronously from the update loop. 437 /// asynchronously from the update loop.
435 /// </summary> 438 /// </summary>
436 private bool m_cleaningTemps = false; 439 private bool m_cleaningTemps = false;
437 440
438 /// <summary> 441 /// <summary>
439 /// Used to control main scene thread looping time when not updating via timer. 442 /// Used to control main scene thread looping time when not updating via timer.
440 /// </summary> 443 /// </summary>
@@ -454,6 +457,12 @@ namespace OpenSim.Region.Framework.Scenes
454 457
455 private string m_defaultScriptEngine; 458 private string m_defaultScriptEngine;
456 459
460 private int m_unixStartTime;
461 public int UnixStartTime
462 {
463 get { return m_unixStartTime; }
464 }
465
457 /// <summary> 466 /// <summary>
458 /// Tick at which the last login occurred. 467 /// Tick at which the last login occurred.
459 /// </summary> 468 /// </summary>
@@ -489,7 +498,7 @@ namespace OpenSim.Region.Framework.Scenes
489 if (value) 498 if (value)
490 { 499 {
491 if (!m_active) 500 if (!m_active)
492 Start(false); 501 Start(false);
493 } 502 }
494 else 503 else
495 { 504 {
@@ -526,6 +535,13 @@ namespace OpenSim.Region.Framework.Scenes
526 get { return m_sceneGraph.PhysicsScene.TimeDilation; } 535 get { return m_sceneGraph.PhysicsScene.TimeDilation; }
527 } 536 }
528 537
538 public void setThreadCount(int inUseThreads)
539 {
540 // Just pass the thread count information on its way as the Scene
541 // does not require the value for anything at this time
542 StatsReporter.SetThreadCount(inUseThreads);
543 }
544
529 public SceneCommunicationService SceneGridService 545 public SceneCommunicationService SceneGridService
530 { 546 {
531 get { return m_sceneGridService; } 547 get { return m_sceneGridService; }
@@ -584,7 +600,7 @@ namespace OpenSim.Region.Framework.Scenes
584 return m_AssetService; 600 return m_AssetService;
585 } 601 }
586 } 602 }
587 603
588 public IAuthorizationService AuthorizationService 604 public IAuthorizationService AuthorizationService
589 { 605 {
590 get 606 get
@@ -645,7 +661,7 @@ namespace OpenSim.Region.Framework.Scenes
645 get 661 get
646 { 662 {
647 if (m_LibraryService == null) 663 if (m_LibraryService == null)
648 m_LibraryService = RequestModuleInterface<ILibraryService>(); 664 m_LibraryService = RequestModuleInterface<ILibraryService>();
649 665
650 return m_LibraryService; 666 return m_LibraryService;
651 } 667 }
@@ -656,7 +672,7 @@ namespace OpenSim.Region.Framework.Scenes
656 get 672 get
657 { 673 {
658 if (m_simulationService == null) 674 if (m_simulationService == null)
659 m_simulationService = RequestModuleInterface<ISimulationService>(); 675 m_simulationService = RequestModuleInterface<ISimulationService>();
660 676
661 return m_simulationService; 677 return m_simulationService;
662 } 678 }
@@ -667,7 +683,7 @@ namespace OpenSim.Region.Framework.Scenes
667 get 683 get
668 { 684 {
669 if (m_AuthenticationService == null) 685 if (m_AuthenticationService == null)
670 m_AuthenticationService = RequestModuleInterface<IAuthenticationService>(); 686 m_AuthenticationService = RequestModuleInterface<IAuthenticationService>();
671 return m_AuthenticationService; 687 return m_AuthenticationService;
672 } 688 }
673 } 689 }
@@ -677,7 +693,7 @@ namespace OpenSim.Region.Framework.Scenes
677 get 693 get
678 { 694 {
679 if (m_PresenceService == null) 695 if (m_PresenceService == null)
680 m_PresenceService = RequestModuleInterface<IPresenceService>(); 696 m_PresenceService = RequestModuleInterface<IPresenceService>();
681 return m_PresenceService; 697 return m_PresenceService;
682 } 698 }
683 } 699 }
@@ -687,7 +703,7 @@ namespace OpenSim.Region.Framework.Scenes
687 get 703 get
688 { 704 {
689 if (m_UserAccountService == null) 705 if (m_UserAccountService == null)
690 m_UserAccountService = RequestModuleInterface<IUserAccountService>(); 706 m_UserAccountService = RequestModuleInterface<IUserAccountService>();
691 return m_UserAccountService; 707 return m_UserAccountService;
692 } 708 }
693 } 709 }
@@ -697,7 +713,7 @@ namespace OpenSim.Region.Framework.Scenes
697 get 713 get
698 { 714 {
699 if (m_AvatarService == null) 715 if (m_AvatarService == null)
700 m_AvatarService = RequestModuleInterface<IAvatarService>(); 716 m_AvatarService = RequestModuleInterface<IAvatarService>();
701 return m_AvatarService; 717 return m_AvatarService;
702 } 718 }
703 } 719 }
@@ -707,7 +723,7 @@ namespace OpenSim.Region.Framework.Scenes
707 get 723 get
708 { 724 {
709 if (m_GridUserService == null) 725 if (m_GridUserService == null)
710 m_GridUserService = RequestModuleInterface<IGridUserService>(); 726 m_GridUserService = RequestModuleInterface<IGridUserService>();
711 return m_GridUserService; 727 return m_GridUserService;
712 } 728 }
713 } 729 }
@@ -721,7 +737,7 @@ namespace OpenSim.Region.Framework.Scenes
721 { 737 {
722 get { return m_AvatarFactory; } 738 get { return m_AvatarFactory; }
723 } 739 }
724 740
725 public ICapabilitiesModule CapsModule 741 public ICapabilitiesModule CapsModule
726 { 742 {
727 get { return m_capsModule; } 743 get { return m_capsModule; }
@@ -787,18 +803,20 @@ namespace OpenSim.Region.Framework.Scenes
787 get { return m_sceneGraph.Entities; } 803 get { return m_sceneGraph.Entities; }
788 } 804 }
789 805
790 806
791 // used in sequence see: SpawnPoint() 807 // used in sequence see: SpawnPoint()
792 private int m_SpawnPoint; 808 private int m_SpawnPoint;
793 // can be closest/random/sequence 809 // can be closest/random/sequence
794 public string SpawnPointRouting 810 public string SpawnPointRouting
795 { 811 {
796 get; private set; 812 get;
813 private set;
797 } 814 }
798 // allow landmarks to pass 815 // allow landmarks to pass
799 public bool TelehubAllowLandmarks 816 public bool TelehubAllowLandmarks
800 { 817 {
801 get; private set; 818 get;
819 private set;
802 } 820 }
803 821
804 #endregion Properties 822 #endregion Properties
@@ -806,10 +824,10 @@ namespace OpenSim.Region.Framework.Scenes
806 #region Constructors 824 #region Constructors
807 825
808 public Scene(RegionInfo regInfo, AgentCircuitManager authen, PhysicsScene physicsScene, 826 public Scene(RegionInfo regInfo, AgentCircuitManager authen, PhysicsScene physicsScene,
809 SceneCommunicationService sceneGridService, 827 SceneCommunicationService sceneGridService,
810 ISimulationDataService simDataService, IEstateDataService estateDataService, 828 ISimulationDataService simDataService, IEstateDataService estateDataService,
811 IConfigSource config, string simulatorVersion) 829 IConfigSource config, string simulatorVersion)
812 : this(regInfo, physicsScene) 830 : this(regInfo, physicsScene)
813 { 831 {
814 m_config = config; 832 m_config = config;
815 MinFrameTicks = 89; 833 MinFrameTicks = 89;
@@ -866,20 +884,20 @@ namespace OpenSim.Region.Framework.Scenes
866 } 884 }
867 885
868 if (updatedTerrainTextures) 886 if (updatedTerrainTextures)
869 rs.Save(); 887 rs.Save();
870 888
871 RegionInfo.RegionSettings = rs; 889 RegionInfo.RegionSettings = rs;
872 890
873 if (estateDataService != null) 891 if (estateDataService != null)
874 RegionInfo.EstateSettings = estateDataService.LoadEstateSettings(RegionInfo.RegionID, false); 892 RegionInfo.EstateSettings = estateDataService.LoadEstateSettings(RegionInfo.RegionID, false);
875 893
876 #endregion Region Settings 894 #endregion Region Settings
877 895
878 //Bind Storage Manager functions to some land manager functions for this scene 896 //Bind Storage Manager functions to some land manager functions for this scene
879 EventManager.OnLandObjectAdded += 897 EventManager.OnLandObjectAdded +=
880 new EventManager.LandObjectAdded(simDataService.StoreLandObject); 898 new EventManager.LandObjectAdded(simDataService.StoreLandObject);
881 EventManager.OnLandObjectRemoved += 899 EventManager.OnLandObjectRemoved +=
882 new EventManager.LandObjectRemoved(simDataService.RemoveLandObject); 900 new EventManager.LandObjectRemoved(simDataService.RemoveLandObject);
883 901
884 RegisterDefaultSceneEvents(); 902 RegisterDefaultSceneEvents();
885 903
@@ -904,8 +922,8 @@ namespace OpenSim.Region.Framework.Scenes
904 m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance", m_defaultDrawDistance); 922 m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance", m_defaultDrawDistance);
905 UseBackup = startupConfig.GetBoolean("UseSceneBackup", UseBackup); 923 UseBackup = startupConfig.GetBoolean("UseSceneBackup", UseBackup);
906 if (!UseBackup) 924 if (!UseBackup)
907 m_log.InfoFormat("[SCENE]: Backup has been disabled for {0}", RegionInfo.RegionName); 925 m_log.InfoFormat("[SCENE]: Backup has been disabled for {0}", RegionInfo.RegionName);
908 926
909 //Animation states 927 //Animation states
910 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); 928 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
911 929
@@ -959,10 +977,10 @@ namespace OpenSim.Region.Framework.Scenes
959 m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries); 977 m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries);
960 m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings); 978 m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings);
961 m_dontPersistBefore = 979 m_dontPersistBefore =
962 startupConfig.GetLong("MinimumTimeBeforePersistenceConsidered", DEFAULT_MIN_TIME_FOR_PERSISTENCE); 980 startupConfig.GetLong("MinimumTimeBeforePersistenceConsidered", DEFAULT_MIN_TIME_FOR_PERSISTENCE);
963 m_dontPersistBefore *= 10000000; 981 m_dontPersistBefore *= 10000000;
964 m_persistAfter = 982 m_persistAfter =
965 startupConfig.GetLong("MaximumTimeBeforePersistenceConsidered", DEFAULT_MAX_TIME_FOR_PERSISTENCE); 983 startupConfig.GetLong("MaximumTimeBeforePersistenceConsidered", DEFAULT_MAX_TIME_FOR_PERSISTENCE);
966 m_persistAfter *= 10000000; 984 m_persistAfter *= 10000000;
967 985
968 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); 986 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine");
@@ -974,8 +992,8 @@ namespace OpenSim.Region.Framework.Scenes
974 992
975 string[] possibleMapConfigSections = new string[] { "Map", "Startup" }; 993 string[] possibleMapConfigSections = new string[] { "Map", "Startup" };
976 994
977 m_generateMaptiles 995 m_generateMaptiles
978 = Util.GetConfigVarFromSections<bool>(config, "GenerateMaptiles", possibleMapConfigSections, true); 996 = Util.GetConfigVarFromSections<bool>(config, "GenerateMaptiles", possibleMapConfigSections, true);
979 997
980 if (m_generateMaptiles) 998 if (m_generateMaptiles)
981 { 999 {
@@ -991,9 +1009,9 @@ namespace OpenSim.Region.Framework.Scenes
991 } 1009 }
992 else 1010 else
993 { 1011 {
994 string tile 1012 string tile
995 = Util.GetConfigVarFromSections<string>( 1013 = Util.GetConfigVarFromSections<string>(
996 config, "MaptileStaticUUID", possibleMapConfigSections, UUID.Zero.ToString()); 1014 config, "MaptileStaticUUID", possibleMapConfigSections, UUID.Zero.ToString());
997 1015
998 UUID tileID; 1016 UUID tileID;
999 1017
@@ -1010,9 +1028,9 @@ namespace OpenSim.Region.Framework.Scenes
1010 1028
1011 string[] possibleAccessControlConfigSections = new string[] { "AccessControl", "Startup" }; 1029 string[] possibleAccessControlConfigSections = new string[] { "AccessControl", "Startup" };
1012 1030
1013 string grant 1031 string grant
1014 = Util.GetConfigVarFromSections<string>( 1032 = Util.GetConfigVarFromSections<string>(
1015 config, "AllowedClients", possibleAccessControlConfigSections, ""); 1033 config, "AllowedClients", possibleAccessControlConfigSections, "");
1016 1034
1017 if (grant.Length > 0) 1035 if (grant.Length > 0)
1018 { 1036 {
@@ -1022,9 +1040,9 @@ namespace OpenSim.Region.Framework.Scenes
1022 } 1040 }
1023 } 1041 }
1024 1042
1025 grant 1043 grant
1026 = Util.GetConfigVarFromSections<string>( 1044 = Util.GetConfigVarFromSections<string>(
1027 config, "BannedClients", possibleAccessControlConfigSections, ""); 1045 config, "BannedClients", possibleAccessControlConfigSections, "");
1028 1046
1029 if (grant.Length > 0) 1047 if (grant.Length > 0)
1030 { 1048 {
@@ -1035,27 +1053,27 @@ namespace OpenSim.Region.Framework.Scenes
1035 } 1053 }
1036 1054
1037 if (startupConfig.Contains("MinFrameTime")) 1055 if (startupConfig.Contains("MinFrameTime"))
1038 MinFrameTicks = (int)(startupConfig.GetFloat("MinFrameTime") * 1000); 1056 MinFrameTicks = (int)(startupConfig.GetFloat("MinFrameTime") * 1000);
1039 1057
1040 m_update_backup = startupConfig.GetInt( "UpdateStorageEveryNFrames", m_update_backup); 1058 m_update_backup = startupConfig.GetInt("UpdateStorageEveryNFrames", m_update_backup);
1041 m_update_coarse_locations = startupConfig.GetInt( "UpdateCoarseLocationsEveryNFrames", m_update_coarse_locations); 1059 m_update_coarse_locations = startupConfig.GetInt("UpdateCoarseLocationsEveryNFrames", m_update_coarse_locations);
1042 m_update_entitymovement = startupConfig.GetInt( "UpdateEntityMovementEveryNFrames", m_update_entitymovement); 1060 m_update_entitymovement = startupConfig.GetInt("UpdateEntityMovementEveryNFrames", m_update_entitymovement);
1043 m_update_events = startupConfig.GetInt( "UpdateEventsEveryNFrames", m_update_events); 1061 m_update_events = startupConfig.GetInt("UpdateEventsEveryNFrames", m_update_events);
1044 m_update_objects = startupConfig.GetInt( "UpdateObjectsEveryNFrames", m_update_objects); 1062 m_update_objects = startupConfig.GetInt("UpdateObjectsEveryNFrames", m_update_objects);
1045 m_update_physics = startupConfig.GetInt( "UpdatePhysicsEveryNFrames", m_update_physics); 1063 m_update_physics = startupConfig.GetInt("UpdatePhysicsEveryNFrames", m_update_physics);
1046 m_update_presences = startupConfig.GetInt( "UpdateAgentsEveryNFrames", m_update_presences); 1064 m_update_presences = startupConfig.GetInt("UpdateAgentsEveryNFrames", m_update_presences);
1047 m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain); 1065 m_update_terrain = startupConfig.GetInt("UpdateTerrainEveryNFrames", m_update_terrain);
1048 m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNSeconds", m_update_temp_cleaning); 1066 m_update_temp_cleaning = startupConfig.GetInt("UpdateTempCleaningEveryNSeconds", m_update_temp_cleaning);
1049 } 1067 }
1050 1068
1051 // FIXME: Ultimately this should be in a module. 1069 // FIXME: Ultimately this should be in a module.
1052 SendPeriodicAppearanceUpdates = false; 1070 SendPeriodicAppearanceUpdates = false;
1053 1071
1054 IConfig appearanceConfig = m_config.Configs["Appearance"]; 1072 IConfig appearanceConfig = m_config.Configs["Appearance"];
1055 if (appearanceConfig != null) 1073 if (appearanceConfig != null)
1056 { 1074 {
1057 SendPeriodicAppearanceUpdates 1075 SendPeriodicAppearanceUpdates
1058 = appearanceConfig.GetBoolean("ResendAppearanceUpdates", SendPeriodicAppearanceUpdates); 1076 = appearanceConfig.GetBoolean("ResendAppearanceUpdates", SendPeriodicAppearanceUpdates);
1059 } 1077 }
1060 1078
1061 #endregion Region Config 1079 #endregion Region Config
@@ -1083,58 +1101,68 @@ namespace OpenSim.Region.Framework.Scenes
1083 UpdatePrioritizationScheme = UpdatePrioritizationSchemes.Time; 1101 UpdatePrioritizationScheme = UpdatePrioritizationSchemes.Time;
1084 } 1102 }
1085 1103
1086 IsReprioritizationEnabled 1104 IsReprioritizationEnabled
1087 = interestConfig.GetBoolean("ReprioritizationEnabled", IsReprioritizationEnabled); 1105 = interestConfig.GetBoolean("ReprioritizationEnabled", IsReprioritizationEnabled);
1088 ReprioritizationInterval 1106 ReprioritizationInterval
1089 = interestConfig.GetDouble("ReprioritizationInterval", ReprioritizationInterval); 1107 = interestConfig.GetDouble("ReprioritizationInterval", ReprioritizationInterval);
1090 RootReprioritizationDistance 1108 RootReprioritizationDistance
1091 = interestConfig.GetDouble("RootReprioritizationDistance", RootReprioritizationDistance); 1109 = interestConfig.GetDouble("RootReprioritizationDistance", RootReprioritizationDistance);
1092 ChildReprioritizationDistance 1110 ChildReprioritizationDistance
1093 = interestConfig.GetDouble("ChildReprioritizationDistance", ChildReprioritizationDistance); 1111 = interestConfig.GetDouble("ChildReprioritizationDistance", ChildReprioritizationDistance);
1094 1112
1095 RootTerseUpdatePeriod = interestConfig.GetInt("RootTerseUpdatePeriod", RootTerseUpdatePeriod); 1113 RootTerseUpdatePeriod = interestConfig.GetInt("RootTerseUpdatePeriod", RootTerseUpdatePeriod);
1096 ChildTerseUpdatePeriod = interestConfig.GetInt("ChildTerseUpdatePeriod", ChildTerseUpdatePeriod); 1114 ChildTerseUpdatePeriod = interestConfig.GetInt("ChildTerseUpdatePeriod", ChildTerseUpdatePeriod);
1097 1115
1098 RootPositionUpdateTolerance 1116 RootPositionUpdateTolerance
1099 = interestConfig.GetFloat("RootPositionUpdateTolerance", RootPositionUpdateTolerance); 1117 = interestConfig.GetFloat("RootPositionUpdateTolerance", RootPositionUpdateTolerance);
1100 RootRotationUpdateTolerance 1118 RootRotationUpdateTolerance
1101 = interestConfig.GetFloat("RootRotationUpdateTolerance", RootRotationUpdateTolerance); 1119 = interestConfig.GetFloat("RootRotationUpdateTolerance", RootRotationUpdateTolerance);
1102 RootVelocityUpdateTolerance 1120 RootVelocityUpdateTolerance
1103 = interestConfig.GetFloat("RootVelocityUpdateTolerance", RootVelocityUpdateTolerance); 1121 = interestConfig.GetFloat("RootVelocityUpdateTolerance", RootVelocityUpdateTolerance);
1104 } 1122 }
1105 1123
1106 m_log.DebugFormat("[SCENE]: Using the {0} prioritization scheme", UpdatePrioritizationScheme); 1124 m_log.DebugFormat("[SCENE]: Using the {0} prioritization scheme", UpdatePrioritizationScheme);
1107 1125
1108 #endregion Interest Management 1126 #endregion Interest Management
1109 1127
1128 // The timer used by the Stopwatch class depends on the system hardware and operating system; inform
1129 // if the timer is based on a high-resolution performance counter or based on the system timer;
1130 // the performance counter will provide a more precise time than the system timer
1131 if (Stopwatch.IsHighResolution)
1132 m_log.InfoFormat("[SCENE]: Using high-resolution performance counter for statistics.");
1133 else
1134 m_log.InfoFormat("[SCENE]: Using system timer for statistics.");
1135
1110 // Acquire the statistics section of the OpenSim.ini file located 1136 // Acquire the statistics section of the OpenSim.ini file located
1111 // in the bin directory 1137 // in the bin directory
1112 IConfig statisticsConfig = m_config.Configs["Statistics"]; 1138 IConfig statisticsConfig = m_config.Configs["Statistics"];
1113 1139
1114 // Confirm that the statistics section existed in the configuration 1140 // Confirm that the statistics section existed in the configuration
1115 // file 1141 // file
1116 if (statisticsConfig != null) 1142 if (statisticsConfig != null)
1117 { 1143 {
1118 // Create the StatsReporter using the number of frames to store 1144 // Create the StatsReporter using the number of frames to store
1119 // for the frame time statistics, or 10 frames if the config 1145 // for the frame time statistics, or 10 frames if the config
1120 // file doesn't contain a value 1146 // file doesn't contain a value
1121 StatsReporter = new SimStatsReporter(this, 1147 StatsReporter = new SimStatsReporter(this,
1122 statisticsConfig.GetInt("NumberOfFrames", 10)); 1148 statisticsConfig.GetInt("NumberOfFrames",
1149 m_defaultNumberFramesStored));
1123 } 1150 }
1124 else 1151 else
1125 { 1152 {
1126 // Create a StatsReporter with the current scene and a default 1153 // Create a StatsReporter with the current scene and a default
1127 // 10 frames stored for the frame time statistics 1154 // 10 frames stored for the frame time statistics
1128 StatsReporter = new SimStatsReporter(this); 1155 StatsReporter = new SimStatsReporter(this);
1129 } 1156 }
1130 1157
1131 StatsReporter.OnSendStatsResult += SendSimStatsPackets; 1158 StatsReporter.OnSendStatsResult += SendSimStatsPackets;
1132 StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats; 1159 StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats;
1133 1160
1134 } 1161 }
1135 1162
1136 public Scene(RegionInfo regInfo, PhysicsScene physicsScene) : base(regInfo) 1163 public Scene(RegionInfo regInfo, PhysicsScene physicsScene)
1137 { 1164 : base(regInfo)
1165 {
1138 m_sceneGraph = new SceneGraph(this); 1166 m_sceneGraph = new SceneGraph(this);
1139 m_sceneGraph.PhysicsScene = physicsScene; 1167 m_sceneGraph.PhysicsScene = physicsScene;
1140 1168
@@ -1144,11 +1172,11 @@ namespace OpenSim.Region.Framework.Scenes
1144 // 1172 //
1145 // Out of memory 1173 // Out of memory
1146 // Operating system has killed the plugin 1174 // Operating system has killed the plugin
1147 m_sceneGraph.UnRecoverableError 1175 m_sceneGraph.UnRecoverableError
1148 += () => 1176 += () =>
1149 { 1177 {
1150 m_log.ErrorFormat("[SCENE]: Restarting region {0} due to unrecoverable physics crash", Name); 1178 m_log.ErrorFormat("[SCENE]: Restarting region {0} due to unrecoverable physics crash", Name);
1151 RestartNow(); 1179 RestartNow();
1152 }; 1180 };
1153 1181
1154 PhysicalPrims = true; 1182 PhysicalPrims = true;
@@ -1193,7 +1221,7 @@ namespace OpenSim.Region.Framework.Scenes
1193 IDialogModule dm = RequestModuleInterface<IDialogModule>(); 1221 IDialogModule dm = RequestModuleInterface<IDialogModule>();
1194 1222
1195 if (dm != null) 1223 if (dm != null)
1196 m_eventManager.OnPermissionError += dm.SendAlertToUser; 1224 m_eventManager.OnPermissionError += dm.SendAlertToUser;
1197 1225
1198 m_eventManager.OnSignificantClientMovement += HandleOnSignificantClientMovement; 1226 m_eventManager.OnSignificantClientMovement += HandleOnSignificantClientMovement;
1199 } 1227 }
@@ -1223,7 +1251,7 @@ namespace OpenSim.Region.Framework.Scenes
1223 //int resultY = Math.Abs((int)ycell - (int)RegionInfo.RegionLocY); 1251 //int resultY = Math.Abs((int)ycell - (int)RegionInfo.RegionLocY);
1224 //if (resultX <= 1 && resultY <= 1) 1252 //if (resultX <= 1 && resultY <= 1)
1225 float dist = (float)Math.Max(DefaultDrawDistance, 1253 float dist = (float)Math.Max(DefaultDrawDistance,
1226 (float)Math.Max(RegionInfo.RegionSizeX, RegionInfo.RegionSizeY)); 1254 (float)Math.Max(RegionInfo.RegionSizeX, RegionInfo.RegionSizeY));
1227 uint newRegionX, newRegionY, thisRegionX, thisRegionY; 1255 uint newRegionX, newRegionY, thisRegionX, thisRegionY;
1228 Util.RegionHandleToRegionLoc(otherRegion.RegionHandle, out newRegionX, out newRegionY); 1256 Util.RegionHandleToRegionLoc(otherRegion.RegionHandle, out newRegionX, out newRegionY);
1229 Util.RegionHandleToRegionLoc(RegionInfo.RegionHandle, out thisRegionX, out thisRegionY); 1257 Util.RegionHandleToRegionLoc(RegionInfo.RegionHandle, out thisRegionX, out thisRegionY);
@@ -1247,7 +1275,7 @@ namespace OpenSim.Region.Framework.Scenes
1247 old.Add(otherRegion.RegionHandle); 1275 old.Add(otherRegion.RegionHandle);
1248 agent.DropOldNeighbours(old); 1276 agent.DropOldNeighbours(old);
1249 if (EntityTransferModule != null && agent.PresenceType != PresenceType.Npc) 1277 if (EntityTransferModule != null && agent.PresenceType != PresenceType.Npc)
1250 EntityTransferModule.EnableChildAgent(agent, otherRegion); 1278 EntityTransferModule.EnableChildAgent(agent, otherRegion);
1251 }); 1279 });
1252 } 1280 }
1253 catch (NullReferenceException) 1281 catch (NullReferenceException)
@@ -1260,8 +1288,8 @@ namespace OpenSim.Region.Framework.Scenes
1260 else 1288 else
1261 { 1289 {
1262 m_log.InfoFormat( 1290 m_log.InfoFormat(
1263 "[SCENE]: Got notice about far away Region: {0} at ({1}, {2})", 1291 "[SCENE]: Got notice about far away Region: {0} at ({1}, {2})",
1264 otherRegion.RegionName, otherRegion.RegionLocX, otherRegion.RegionLocY); 1292 otherRegion.RegionName, otherRegion.RegionLocX, otherRegion.RegionLocY);
1265 } 1293 }
1266 } 1294 }
1267 } 1295 }
@@ -1339,7 +1367,7 @@ namespace OpenSim.Region.Framework.Scenes
1339 ForEachRootScenePresence(delegate(ScenePresence agent) 1367 ForEachRootScenePresence(delegate(ScenePresence agent)
1340 { 1368 {
1341 if (EntityTransferModule != null && agent.PresenceType != PresenceType.Npc) 1369 if (EntityTransferModule != null && agent.PresenceType != PresenceType.Npc)
1342 EntityTransferModule.EnableChildAgent(agent, r); 1370 EntityTransferModule.EnableChildAgent(agent, r);
1343 }); 1371 });
1344 } 1372 }
1345 catch (NullReferenceException) 1373 catch (NullReferenceException)
@@ -1377,14 +1405,14 @@ namespace OpenSim.Region.Framework.Scenes
1377 1405
1378 // Kick all ROOT agents with the message, 'The simulator is going down' 1406 // Kick all ROOT agents with the message, 'The simulator is going down'
1379 ForEachScenePresence(delegate(ScenePresence avatar) 1407 ForEachScenePresence(delegate(ScenePresence avatar)
1380 { 1408 {
1381 avatar.RemoveNeighbourRegion(RegionInfo.RegionHandle); 1409 avatar.RemoveNeighbourRegion(RegionInfo.RegionHandle);
1382 1410
1383 if (!avatar.IsChildAgent) 1411 if (!avatar.IsChildAgent)
1384 avatar.ControllingClient.Kick("The simulator is going down."); 1412 avatar.ControllingClient.Kick("The simulator is going down.");
1385 1413
1386 avatar.ControllingClient.SendShutdownConnectionNotice(); 1414 avatar.ControllingClient.SendShutdownConnectionNotice();
1387 }); 1415 });
1388 1416
1389 // Stop updating the scene objects and agents. 1417 // Stop updating the scene objects and agents.
1390 m_shuttingDown = true; 1418 m_shuttingDown = true;
@@ -1403,7 +1431,7 @@ namespace OpenSim.Region.Framework.Scenes
1403 m_sceneGraph.Close(); 1431 m_sceneGraph.Close();
1404 1432
1405 if (!GridService.DeregisterRegion(RegionInfo.RegionID)) 1433 if (!GridService.DeregisterRegion(RegionInfo.RegionID))
1406 m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name); 1434 m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name);
1407 1435
1408 base.Close(); 1436 base.Close();
1409 1437
@@ -1434,11 +1462,12 @@ namespace OpenSim.Region.Framework.Scenes
1434 public void Start(bool startScripts) 1462 public void Start(bool startScripts)
1435 { 1463 {
1436 if (IsRunning) 1464 if (IsRunning)
1437 return; 1465 return;
1438 1466
1439 m_isRunning = true; 1467 m_isRunning = true;
1440 m_active = true; 1468 m_active = true;
1441 1469
1470 m_unixStartTime = Util.UnixTimeSinceEpoch();
1442// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); 1471// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName);
1443 if (m_heartbeatThread != null) 1472 if (m_heartbeatThread != null)
1444 { 1473 {
@@ -1447,8 +1476,8 @@ namespace OpenSim.Region.Framework.Scenes
1447 } 1476 }
1448 1477
1449 m_heartbeatThread 1478 m_heartbeatThread
1450 = WorkManager.StartThread( 1479 = WorkManager.StartThread(
1451 Heartbeat, string.Format("Heartbeat-({0})", RegionInfo.RegionName.Replace(" ", "_")), ThreadPriority.Normal, false, false); 1480 Heartbeat, string.Format("Heartbeat-({0})", RegionInfo.RegionName.Replace(" ", "_")), ThreadPriority.Normal, false, false);
1452 1481
1453 StartScripts(); 1482 StartScripts();
1454 } 1483 }
@@ -1489,7 +1518,7 @@ namespace OpenSim.Region.Framework.Scenes
1489 Update(1); 1518 Update(1);
1490 1519
1491 WorkManager.StartThread( 1520 WorkManager.StartThread(
1492 Maintenance, string.Format("Maintenance ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, true); 1521 Maintenance, string.Format("Maintenance ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, true);
1493 1522
1494 Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true; 1523 Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true;
1495 m_lastFrameTick = Util.EnvironmentTickCount(); 1524 m_lastFrameTick = Util.EnvironmentTickCount();
@@ -1513,15 +1542,15 @@ namespace OpenSim.Region.Framework.Scenes
1513 private volatile bool m_isTimerUpdateRunning; 1542 private volatile bool m_isTimerUpdateRunning;
1514 1543
1515 private void Update(object sender, ElapsedEventArgs e) 1544 private void Update(object sender, ElapsedEventArgs e)
1516 { 1545 {
1517 if (m_isTimerUpdateRunning) 1546 if (m_isTimerUpdateRunning)
1518 return; 1547 return;
1519 1548
1520 m_isTimerUpdateRunning = true; 1549 m_isTimerUpdateRunning = true;
1521 1550
1522 // If the last frame did not complete on time, then immediately start the next update on the same thread 1551 // If the last frame did not complete on time, then immediately start the next update on the same thread
1523 // and ignore further timed updates until we have a frame that had spare time. 1552 // and ignore further timed updates until we have a frame that had spare time.
1524 while (!Update(1) && Active) {} 1553 while (!Update(1) && Active) { }
1525 1554
1526 if (!Active || m_shuttingDown) 1555 if (!Active || m_shuttingDown)
1527 { 1556 {
@@ -1547,7 +1576,7 @@ namespace OpenSim.Region.Framework.Scenes
1547 int previousMaintenanceTick; 1576 int previousMaintenanceTick;
1548 1577
1549 if (runs >= 0) 1578 if (runs >= 0)
1550 endRun = MaintenanceRun + runs; 1579 endRun = MaintenanceRun + runs;
1551 1580
1552 List<Vector3> coarseLocations; 1581 List<Vector3> coarseLocations;
1553 List<UUID> avatarUUIDs; 1582 List<UUID> avatarUUIDs;
@@ -1557,7 +1586,7 @@ namespace OpenSim.Region.Framework.Scenes
1557 runtc = Util.EnvironmentTickCount(); 1586 runtc = Util.EnvironmentTickCount();
1558 ++MaintenanceRun; 1587 ++MaintenanceRun;
1559 1588
1560// m_log.DebugFormat("[SCENE]: Maintenance run {0} in {1}", MaintenanceRun, Name); 1589 // m_log.DebugFormat("[SCENE]: Maintenance run {0} in {1}", MaintenanceRun, Name);
1561 1590
1562 // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client) 1591 // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client)
1563 if (MaintenanceRun % (m_update_coarse_locations / 10) == 0) 1592 if (MaintenanceRun % (m_update_coarse_locations / 10) == 0)
@@ -1572,7 +1601,7 @@ namespace OpenSim.Region.Framework.Scenes
1572 1601
1573 if (SendPeriodicAppearanceUpdates && MaintenanceRun % 60 == 0) 1602 if (SendPeriodicAppearanceUpdates && MaintenanceRun % 60 == 0)
1574 { 1603 {
1575// m_log.DebugFormat("[SCENE]: Sending periodic appearance updates"); 1604 // m_log.DebugFormat("[SCENE]: Sending periodic appearance updates");
1576 1605
1577 if (AvatarFactory != null) 1606 if (AvatarFactory != null)
1578 { 1607 {
@@ -1583,14 +1612,14 @@ namespace OpenSim.Region.Framework.Scenes
1583 // Delete temp-on-rez stuff 1612 // Delete temp-on-rez stuff
1584 if (MaintenanceRun % m_update_temp_cleaning == 0 && !m_cleaningTemps) 1613 if (MaintenanceRun % m_update_temp_cleaning == 0 && !m_cleaningTemps)
1585 { 1614 {
1586// m_log.DebugFormat("[SCENE]: Running temp-on-rez cleaning in {0}", Name); 1615 // m_log.DebugFormat("[SCENE]: Running temp-on-rez cleaning in {0}", Name);
1587 tmpMS = Util.EnvironmentTickCount(); 1616 tmpMS = Util.EnvironmentTickCount();
1588 m_cleaningTemps = true; 1617 m_cleaningTemps = true;
1589 1618
1590 WorkManager.RunInThread( 1619 WorkManager.RunInThread(
1591 delegate { CleanTempObjects(); m_cleaningTemps = false; }, 1620 delegate { CleanTempObjects(); m_cleaningTemps = false; },
1592 null, 1621 null,
1593 string.Format("CleanTempObjects ({0})", Name)); 1622 string.Format("CleanTempObjects ({0})", Name));
1594 1623
1595 tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpMS); 1624 tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpMS);
1596 } 1625 }
@@ -1601,19 +1630,19 @@ namespace OpenSim.Region.Framework.Scenes
1601 m_lastMaintenanceTick = Util.EnvironmentTickCount(); 1630 m_lastMaintenanceTick = Util.EnvironmentTickCount();
1602 runtc = Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, runtc); 1631 runtc = Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, runtc);
1603 runtc = MinMaintenanceTicks - runtc; 1632 runtc = MinMaintenanceTicks - runtc;
1604 1633
1605 if (runtc > 0) 1634 if (runtc > 0)
1606 m_maintenanceWaitEvent.WaitOne(runtc); 1635 m_maintenanceWaitEvent.WaitOne(runtc);
1607 1636
1608 // Optionally warn if a frame takes double the amount of time that it should. 1637 // Optionally warn if a frame takes double the amount of time that it should.
1609 if (DebugUpdates 1638 if (DebugUpdates
1610 && Util.EnvironmentTickCountSubtract( 1639 && Util.EnvironmentTickCountSubtract(
1611 m_lastMaintenanceTick, previousMaintenanceTick) > MinMaintenanceTicks * 2) 1640 m_lastMaintenanceTick, previousMaintenanceTick) > MinMaintenanceTicks * 2)
1612 m_log.WarnFormat( 1641 m_log.WarnFormat(
1613 "[SCENE]: Maintenance took {0} ms (desired max {1} ms) in {2}", 1642 "[SCENE]: Maintenance took {0} ms (desired max {1} ms) in {2}",
1614 Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, previousMaintenanceTick), 1643 Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, previousMaintenanceTick),
1615 MinMaintenanceTicks, 1644 MinMaintenanceTicks,
1616 RegionInfo.RegionName); 1645 RegionInfo.RegionName);
1617 } 1646 }
1618 } 1647 }
1619 1648
@@ -1622,7 +1651,7 @@ namespace OpenSim.Region.Framework.Scenes
1622 long? endFrame = null; 1651 long? endFrame = null;
1623 1652
1624 if (frames >= 0) 1653 if (frames >= 0)
1625 endFrame = Frame + frames; 1654 endFrame = Frame + frames;
1626 1655
1627 float physicsFPS = 0f; 1656 float physicsFPS = 0f;
1628 int previousFrameTick, tmpMS; 1657 int previousFrameTick, tmpMS;
@@ -1641,12 +1670,12 @@ namespace OpenSim.Region.Framework.Scenes
1641 // Begin the stopwatch to keep track of the time that the frame 1670 // Begin the stopwatch to keep track of the time that the frame
1642 // started running to determine how long the frame took to complete 1671 // started running to determine how long the frame took to complete
1643 totalFrameStopwatch.Start(); 1672 totalFrameStopwatch.Start();
1644 1673
1645 while (!m_shuttingDown && ((endFrame == null && Active) || Frame < endFrame)) 1674 while (!m_shuttingDown && ((endFrame == null && Active) || Frame < endFrame))
1646 { 1675 {
1647 ++Frame; 1676 ++Frame;
1648 1677
1649// m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName); 1678 // m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName);
1650 1679
1651 agentMS = eventMS = backupMS = terrainMS = landMS = spareMS = 0; 1680 agentMS = eventMS = backupMS = terrainMS = landMS = spareMS = 0;
1652 1681
@@ -1667,48 +1696,56 @@ namespace OpenSim.Region.Framework.Scenes
1667 // at this point in time, the precise values all begin 1696 // at this point in time, the precise values all begin
1668 // with the keyword precise 1697 // with the keyword precise
1669 tmpMS = Util.EnvironmentTickCount(); 1698 tmpMS = Util.EnvironmentTickCount();
1670
1671 simFrameStopwatch.Start(); 1699 simFrameStopwatch.Start();
1672 UpdateTerrain(); 1700 UpdateTerrain();
1673 1701
1674 // Get the simulation frame time that the avatar force 1702 // Get the simulation frame time that the avatar force
1675 // input took 1703 // input took
1676 simFrameStopwatch.Stop(); 1704 simFrameStopwatch.Stop();
1677 preciseSimFrameTime = 1705 preciseSimFrameTime =
1678 simFrameStopwatch.Elapsed.TotalMilliseconds; 1706 simFrameStopwatch.Elapsed.TotalMilliseconds;
1679 terrainMS = Util.EnvironmentTickCountSubtract(tmpMS); 1707 terrainMS = Util.EnvironmentTickCountSubtract(tmpMS);
1680 } 1708 }
1681 1709
1710 // At several points inside the code there was a need to
1711 // create a more precise measurement of time elapsed. This
1712 // led to the addition of variables that have a similar
1713 // function and thus remain tightly connected to their
1714 // original counterparts. However, the original code is
1715 // not receiving comments from our group because we don't
1716 // feel right modifying the code to that degree at this
1717 // point in time, the precise values all begin with the
1718 // keyword precise
1719
1682 tmpMS = Util.EnvironmentTickCount(); 1720 tmpMS = Util.EnvironmentTickCount();
1683 1721
1684 // Begin the stopwatch to track the time to prepare physics 1722 // Begin the stopwatch to track the time to prepare physics
1685 physicsFrameStopwatch.Start(); 1723 physicsFrameStopwatch.Start();
1686 if (PhysicsEnabled && Frame % m_update_physics == 0) 1724 if (PhysicsEnabled && Frame % m_update_physics == 0)
1687 m_sceneGraph.UpdatePreparePhysics(); 1725 m_sceneGraph.UpdatePreparePhysics();
1688 1726
1689 // Get the time it took to prepare the physics, this 1727 // Get the time it took to prepare the physics, this
1690 // would report the most precise time that physics was 1728 // would report the most precise time that physics was
1691 // running on the machine and should the physics not be 1729 // running on the machine and should the physics not be
1692 // enabled will report the time it took to check if physics 1730 // enabled will report the time it took to check if physics
1693 // was enabled 1731 // was enabled
1694 physicsFrameStopwatch.Stop(); 1732 physicsFrameStopwatch.Stop();
1695 precisePhysicsFrameTime = 1733 precisePhysicsFrameTime = physicsFrameStopwatch.Elapsed.TotalMilliseconds;
1696 physicsFrameStopwatch.Elapsed.TotalMilliseconds;
1697 physicsMS2 = Util.EnvironmentTickCountSubtract(tmpMS); 1734 physicsMS2 = Util.EnvironmentTickCountSubtract(tmpMS);
1698 1735
1699 // Apply any pending avatar force input to the avatar's velocity 1736 // Apply any pending avatar force input to the avatar's velocity
1700 tmpMS = Util.EnvironmentTickCount(); 1737 tmpMS = Util.EnvironmentTickCount();
1701 simFrameStopwatch.Restart(); 1738 simFrameStopwatch.Restart();
1702 if (Frame % m_update_entitymovement == 0) 1739 if (Frame % m_update_entitymovement == 0)
1703 m_sceneGraph.UpdateScenePresenceMovement(); 1740 m_sceneGraph.UpdateScenePresenceMovement();
1704 1741
1705 // Get the simulation frame time that the avatar force input 1742 // Get the simulation frame time that the avatar force input
1706 // took 1743 // took
1707 simFrameStopwatch.Stop(); 1744 simFrameStopwatch.Stop();
1708 preciseSimFrameTime += 1745 preciseSimFrameTime +=
1709 simFrameStopwatch.Elapsed.TotalMilliseconds; 1746 simFrameStopwatch.Elapsed.TotalMilliseconds;
1710 agentMS = Util.EnvironmentTickCountSubtract(tmpMS); 1747 agentMS = Util.EnvironmentTickCountSubtract(tmpMS);
1711 1748
1712 // Perform the main physics update. This will do the actual work of moving objects and avatars according to their 1749 // Perform the main physics update. This will do the actual work of moving objects and avatars according to their
1713 // velocity 1750 // velocity
1714 tmpMS = Util.EnvironmentTickCount(); 1751 tmpMS = Util.EnvironmentTickCount();
@@ -1716,63 +1753,61 @@ namespace OpenSim.Region.Framework.Scenes
1716 if (Frame % m_update_physics == 0) 1753 if (Frame % m_update_physics == 0)
1717 { 1754 {
1718 if (PhysicsEnabled) 1755 if (PhysicsEnabled)
1719 physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameSeconds); 1756 physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameSeconds);
1720 1757
1721 if (SynchronizeScene != null) 1758 if (SynchronizeScene != null)
1722 SynchronizeScene(this); 1759 SynchronizeScene(this);
1723 } 1760 }
1724 1761
1725 // Add the main physics update time to the prepare physics 1762 // Add the main physics update time to the prepare physics time
1726 // time
1727 physicsFrameStopwatch.Stop(); 1763 physicsFrameStopwatch.Stop();
1728 precisePhysicsFrameTime += 1764 precisePhysicsFrameTime += physicsFrameStopwatch.Elapsed.TotalMilliseconds;
1729 physicsFrameStopwatch.Elapsed.TotalMilliseconds;
1730 physicsMS = Util.EnvironmentTickCountSubtract(tmpMS); 1765 physicsMS = Util.EnvironmentTickCountSubtract(tmpMS);
1731 1766
1732 // Start the stopwatch for the remainder of the simulation 1767 // Start the stopwatch for the remainder of the simulation
1733 simFrameStopwatch.Restart(); 1768 simFrameStopwatch.Restart();
1734 tmpMS = Util.EnvironmentTickCount(); 1769 tmpMS = Util.EnvironmentTickCount();
1735 1770
1736 // Check if any objects have reached their targets 1771 // Check if any objects have reached their targets
1737 CheckAtTargets(); 1772 CheckAtTargets();
1738 1773
1739 // Update SceneObjectGroups that have scheduled themselves for updates 1774 // Update SceneObjectGroups that have scheduled themselves for updates
1740 // Objects queue their updates onto all scene presences 1775 // Objects queue their updates onto all scene presences
1741 if (Frame % m_update_objects == 0) 1776 if (Frame % m_update_objects == 0)
1742 m_sceneGraph.UpdateObjectGroups(); 1777 m_sceneGraph.UpdateObjectGroups();
1743 1778
1744 // Run through all ScenePresences looking for updates 1779 // Run through all ScenePresences looking for updates
1745 // Presence updates and queued object updates for each presence are sent to clients 1780 // Presence updates and queued object updates for each presence are sent to clients
1746 if (Frame % m_update_presences == 0) 1781 if (Frame % m_update_presences == 0)
1747 m_sceneGraph.UpdatePresences(); 1782 m_sceneGraph.UpdatePresences();
1748 1783
1749 agentMS += Util.EnvironmentTickCountSubtract(tmpMS); 1784 agentMS += Util.EnvironmentTickCountSubtract(tmpMS);
1750 1785
1751 if (Frame % m_update_events == 0) 1786 if (Frame % m_update_events == 0)
1752 { 1787 {
1753 tmpMS = Util.EnvironmentTickCount(); 1788 tmpMS = Util.EnvironmentTickCount();
1754 UpdateEvents(); 1789 UpdateEvents();
1755 eventMS = Util.EnvironmentTickCountSubtract(tmpMS); 1790 eventMS = Util.EnvironmentTickCountSubtract(tmpMS);
1756 } 1791 }
1757 1792
1758 if (PeriodicBackup && Frame % m_update_backup == 0) 1793 if (PeriodicBackup && Frame % m_update_backup == 0)
1759 { 1794 {
1760 tmpMS = Util.EnvironmentTickCount(); 1795 tmpMS = Util.EnvironmentTickCount();
1761 UpdateStorageBackup(); 1796 UpdateStorageBackup();
1762 backupMS = Util.EnvironmentTickCountSubtract(tmpMS); 1797 backupMS = Util.EnvironmentTickCountSubtract(tmpMS);
1763 } 1798 }
1764 1799
1765 //if (Frame % m_update_land == 0) 1800 //if (Frame % m_update_land == 0)
1766 //{ 1801 //{
1767 // int ldMS = Util.EnvironmentTickCount(); 1802 // int ldMS = Util.EnvironmentTickCount();
1768 // UpdateLand(); 1803 // UpdateLand();
1769 // landMS = Util.EnvironmentTickCountSubtract(ldMS); 1804 // landMS = Util.EnvironmentTickCountSubtract(ldMS);
1770 //} 1805 //}
1771 1806
1772 if (!LoginsEnabled && Frame == 20) 1807 if (!LoginsEnabled && Frame == 20)
1773 { 1808 {
1774 // m_log.DebugFormat("{0} {1} {2}", LoginsDisabled, m_sceneGraph.GetActiveScriptsCount(), LoginLock); 1809 // m_log.DebugFormat("{0} {1} {2}", LoginsDisabled, m_sceneGraph.GetActiveScriptsCount(), LoginLock);
1775 1810
1776 // In 99.9% of cases it is a bad idea to manually force garbage collection. However, 1811 // In 99.9% of cases it is a bad idea to manually force garbage collection. However,
1777 // this is a rare case where we know we have just went through a long cycle of heap 1812 // this is a rare case where we know we have just went through a long cycle of heap
1778 // allocations, and there is no more work to be done until someone logs in 1813 // allocations, and there is no more work to be done until someone logs in
@@ -1787,7 +1822,7 @@ namespace OpenSim.Region.Framework.Scenes
1787 } 1822 }
1788 1823
1789 m_sceneGridService.InformNeighborsThatRegionisUp( 1824 m_sceneGridService.InformNeighborsThatRegionisUp(
1790 RequestModuleInterface<INeighbourService>(), RegionInfo); 1825 RequestModuleInterface<INeighbourService>(), RegionInfo);
1791 1826
1792 // Region ready should always be set 1827 // Region ready should always be set
1793 Ready = true; 1828 Ready = true;
@@ -1798,7 +1833,7 @@ namespace OpenSim.Region.Framework.Scenes
1798 if (m_sceneGraph.GetActiveScriptsCount() == 0) 1833 if (m_sceneGraph.GetActiveScriptsCount() == 0)
1799 { 1834 {
1800 // In this case, we leave it to the IRegionReadyModule to enable logins 1835 // In this case, we leave it to the IRegionReadyModule to enable logins
1801 1836
1802 // LoginLock can currently only be set by a region module implementation. 1837 // LoginLock can currently only be set by a region module implementation.
1803 // If somehow this hasn't been done then the quickest way to bugfix is to see the 1838 // If somehow this hasn't been done then the quickest way to bugfix is to see the
1804 // NullReferenceException 1839 // NullReferenceException
@@ -1811,18 +1846,18 @@ namespace OpenSim.Region.Framework.Scenes
1811 catch (Exception e) 1846 catch (Exception e)
1812 { 1847 {
1813 m_log.ErrorFormat( 1848 m_log.ErrorFormat(
1814 "[SCENE]: Failed on region {0} with exception {1}{2}", 1849 "[SCENE]: Failed on region {0} with exception {1}{2}",
1815 RegionInfo.RegionName, e.Message, e.StackTrace); 1850 RegionInfo.RegionName, e.Message, e.StackTrace);
1816 } 1851 }
1817 1852
1818 EventManager.TriggerRegionHeartbeatEnd(this); 1853 EventManager.TriggerRegionHeartbeatEnd(this);
1819 otherMS = eventMS + backupMS + terrainMS + landMS; 1854 otherMS = eventMS + backupMS + terrainMS + landMS;
1820 1855
1821 // Get the elapsed time for the simulation frame 1856 // Get the elapsed time for the simulation frame
1822 simFrameStopwatch.Stop(); 1857 simFrameStopwatch.Stop();
1823 preciseSimFrameTime += 1858 preciseSimFrameTime +=
1824 simFrameStopwatch.Elapsed.TotalMilliseconds; 1859 simFrameStopwatch.Elapsed.TotalMilliseconds;
1825 1860
1826 if (!UpdateOnTimer) 1861 if (!UpdateOnTimer)
1827 { 1862 {
1828 Watchdog.UpdateThread(); 1863 Watchdog.UpdateThread();
@@ -1830,9 +1865,9 @@ namespace OpenSim.Region.Framework.Scenes
1830 spareMS = MinFrameTicks - Util.EnvironmentTickCountSubtract(m_lastFrameTick); 1865 spareMS = MinFrameTicks - Util.EnvironmentTickCountSubtract(m_lastFrameTick);
1831 1866
1832 if (spareMS > 0) 1867 if (spareMS > 0)
1833 m_updateWaitEvent.WaitOne(spareMS); 1868 m_updateWaitEvent.WaitOne(spareMS);
1834 else 1869 else
1835 spareMS = 0; 1870 spareMS = 0;
1836 } 1871 }
1837 else 1872 else
1838 { 1873 {
@@ -1841,15 +1876,15 @@ namespace OpenSim.Region.Framework.Scenes
1841 1876
1842 // Get the total frame time 1877 // Get the total frame time
1843 totalFrameStopwatch.Stop(); 1878 totalFrameStopwatch.Stop();
1844 preciseTotalFrameTime = 1879 preciseTotalFrameTime =
1845 totalFrameStopwatch.Elapsed.TotalMilliseconds; 1880 totalFrameStopwatch.Elapsed.TotalMilliseconds;
1846 1881
1847 // Restart the stopwatch for the total time of the next frame 1882 // Restart the stopwatch for the total time of the next frame
1848 totalFrameStopwatch.Restart(); 1883 totalFrameStopwatch.Restart();
1849 1884
1850 previousFrameTick = m_lastFrameTick; 1885 previousFrameTick = m_lastFrameTick;
1851 frameMS = Util.EnvironmentTickCountSubtract(m_lastFrameTick); 1886 frameMS = Util.EnvironmentTickCountSubtract(m_lastFrameTick);
1852 m_lastFrameTick = Util.EnvironmentTickCount(); 1887 m_lastFrameTick = Util.EnvironmentTickCount();
1853 1888
1854 // if (Frame%m_update_avatars == 0) 1889 // if (Frame%m_update_avatars == 0)
1855 // UpdateInWorldTime(); 1890 // UpdateInWorldTime();
@@ -1866,37 +1901,40 @@ namespace OpenSim.Region.Framework.Scenes
1866 1901
1867 // Send the correct time values to the stats reporter for the 1902 // Send the correct time values to the stats reporter for the
1868 // frame times 1903 // frame times
1869 StatsReporter.addFrameTimeMilliseconds(preciseTotalFrameTime, 1904 StatsReporter.addFrameTimeMilliseconds(preciseTotalFrameTime,
1870 preciseSimFrameTime, precisePhysicsFrameTime, 0.0); 1905 preciseSimFrameTime, precisePhysicsFrameTime, 0.0);
1871 1906
1872 // Send the correct number of frames that the physics library 1907 // Send the correct number of frames that the physics library
1873 // has processed to the stats reporter 1908 // has processed to the stats reporter
1874 StatsReporter.addPhysicsFrame(1); 1909 StatsReporter.addPhysicsFrame(1);
1875 1910
1876 // Optionally warn if a frame takes double the amount of time that it should. 1911 // Optionally warn if a frame takes double the amount of time that it should.
1877 if (DebugUpdates 1912 if (DebugUpdates
1878 && Util.EnvironmentTickCountSubtract( 1913 && Util.EnvironmentTickCountSubtract(
1879 m_lastFrameTick, previousFrameTick) > MinFrameTicks * 2) 1914 m_lastFrameTick, previousFrameTick) > MinFrameTicks * 2)
1880 m_log.WarnFormat( 1915 m_log.WarnFormat(
1881 "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}", 1916 "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}",
1882 Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick), 1917 Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick),
1883 MinFrameTicks, 1918 MinFrameTicks,
1884 RegionInfo.RegionName); 1919 RegionInfo.RegionName);
1885 } 1920 }
1886 1921
1922 // Finished updating scene frame, so stop the total frame's Stopwatch
1923 totalFrameStopwatch.Stop();
1924
1887 return spareMS >= 0; 1925 return spareMS >= 0;
1888 } 1926 }
1889 1927
1890 public void AddGroupTarget(SceneObjectGroup grp) 1928 public void AddGroupTarget(SceneObjectGroup grp)
1891 { 1929 {
1892 lock (m_groupsWithTargets) 1930 lock (m_groupsWithTargets)
1893 m_groupsWithTargets[grp.UUID] = grp; 1931 m_groupsWithTargets[grp.UUID] = grp;
1894 } 1932 }
1895 1933
1896 public void RemoveGroupTarget(SceneObjectGroup grp) 1934 public void RemoveGroupTarget(SceneObjectGroup grp)
1897 { 1935 {
1898 lock (m_groupsWithTargets) 1936 lock (m_groupsWithTargets)
1899 m_groupsWithTargets.Remove(grp.UUID); 1937 m_groupsWithTargets.Remove(grp.UUID);
1900 } 1938 }
1901 1939
1902 private void CheckAtTargets() 1940 private void CheckAtTargets()
@@ -1906,13 +1944,13 @@ namespace OpenSim.Region.Framework.Scenes
1906 lock (m_groupsWithTargets) 1944 lock (m_groupsWithTargets)
1907 { 1945 {
1908 if (m_groupsWithTargets.Count != 0) 1946 if (m_groupsWithTargets.Count != 0)
1909 objs = new List<SceneObjectGroup>(m_groupsWithTargets.Values); 1947 objs = new List<SceneObjectGroup>(m_groupsWithTargets.Values);
1910 } 1948 }
1911 1949
1912 if (objs != null) 1950 if (objs != null)
1913 { 1951 {
1914 foreach (SceneObjectGroup entry in objs) 1952 foreach (SceneObjectGroup entry in objs)
1915 entry.checkAtTargets(); 1953 entry.checkAtTargets();
1916 } 1954 }
1917 } 1955 }
1918 1956
@@ -1955,7 +1993,7 @@ namespace OpenSim.Region.Framework.Scenes
1955 { 1993 {
1956 m_eventManager.TriggerOnFrame(); 1994 m_eventManager.TriggerOnFrame();
1957 } 1995 }
1958 1996
1959 /// <summary> 1997 /// <summary>
1960 /// Backup the scene. 1998 /// Backup the scene.
1961 /// </summary> 1999 /// </summary>
@@ -1995,13 +2033,13 @@ namespace OpenSim.Region.Framework.Scenes
1995 // We must fill in a null-terminated 'empty' string here since bytes[0] will crash viewer 3. 2033 // We must fill in a null-terminated 'empty' string here since bytes[0] will crash viewer 3.
1996 msg.binaryBucket = Util.StringToBytes256("\0"); 2034 msg.binaryBucket = Util.StringToBytes256("\0");
1997 if (ret.Value.count > 1) 2035 if (ret.Value.count > 1)
1998 msg.message = string.Format("Your {0} objects were returned from {1} in region {2} due to {3}", ret.Value.count, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason); 2036 msg.message = string.Format("Your {0} objects were returned from {1} in region {2} due to {3}", ret.Value.count, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason);
1999 else 2037 else
2000 msg.message = string.Format("Your object {0} was returned from {1} in region {2} due to {3}", ret.Value.objectName, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason); 2038 msg.message = string.Format("Your object {0} was returned from {1} in region {2} due to {3}", ret.Value.objectName, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason);
2001 2039
2002 IMessageTransferModule tr = RequestModuleInterface<IMessageTransferModule>(); 2040 IMessageTransferModule tr = RequestModuleInterface<IMessageTransferModule>();
2003 if (tr != null) 2041 if (tr != null)
2004 tr.SendInstantMessage(msg, delegate(bool success) {}); 2042 tr.SendInstantMessage(msg, delegate(bool success) { });
2005 } 2043 }
2006 m_returns.Clear(); 2044 m_returns.Clear();
2007 } 2045 }
@@ -2092,7 +2130,7 @@ namespace OpenSim.Region.Framework.Scenes
2092 IConfig terrainConfig = m_config.Configs["Terrain"]; 2130 IConfig terrainConfig = m_config.Configs["Terrain"];
2093 String m_InitialTerrain = "pinhead-island"; 2131 String m_InitialTerrain = "pinhead-island";
2094 if (terrainConfig != null) 2132 if (terrainConfig != null)
2095 m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain); 2133 m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain);
2096 2134
2097 m_log.InfoFormat("[TERRAIN]: No default terrain. Generating a new terrain {0}.", m_InitialTerrain); 2135 m_log.InfoFormat("[TERRAIN]: No default terrain. Generating a new terrain {0}.", m_InitialTerrain);
2098 Heightmap = new TerrainChannel(m_InitialTerrain, (int)RegionInfo.RegionSizeX, (int)RegionInfo.RegionSizeY, (int)RegionInfo.RegionSizeZ); 2136 Heightmap = new TerrainChannel(m_InitialTerrain, (int)RegionInfo.RegionSizeX, (int)RegionInfo.RegionSizeY, (int)RegionInfo.RegionSizeZ);
@@ -2107,11 +2145,11 @@ namespace OpenSim.Region.Framework.Scenes
2107 catch (IOException e) 2145 catch (IOException e)
2108 { 2146 {
2109 m_log.WarnFormat( 2147 m_log.WarnFormat(
2110 "[TERRAIN]: Scene.cs: LoadWorldMap() - Regenerating as failed with exception {0}{1}", 2148 "[TERRAIN]: Scene.cs: LoadWorldMap() - Regenerating as failed with exception {0}{1}",
2111 e.Message, e.StackTrace); 2149 e.Message, e.StackTrace);
2112 2150
2113 // Non standard region size. If there's an old terrain in the database, it might read past the buffer 2151 // Non standard region size. If there's an old terrain in the database, it might read past the buffer
2114 #pragma warning disable 0162 2152#pragma warning disable 0162
2115 if ((int)Constants.RegionSize != 256) 2153 if ((int)Constants.RegionSize != 256)
2116 { 2154 {
2117 Heightmap = new TerrainChannel(); 2155 Heightmap = new TerrainChannel();
@@ -2122,7 +2160,7 @@ namespace OpenSim.Region.Framework.Scenes
2122 catch (Exception e) 2160 catch (Exception e)
2123 { 2161 {
2124 m_log.WarnFormat( 2162 m_log.WarnFormat(
2125 "[TERRAIN]: Scene.cs: LoadWorldMap() - Failed with exception {0}{1}", e.Message, e.StackTrace); 2163 "[TERRAIN]: Scene.cs: LoadWorldMap() - Failed with exception {0}{1}", e.Message, e.StackTrace);
2126 } 2164 }
2127 } 2165 }
2128 2166
@@ -2139,18 +2177,18 @@ namespace OpenSim.Region.Framework.Scenes
2139 //// stored in the GridService, because that's what the world map module uses 2177 //// stored in the GridService, because that's what the world map module uses
2140 //// to send the map image UUIDs (of other regions) to the viewer... 2178 //// to send the map image UUIDs (of other regions) to the viewer...
2141 if (m_generateMaptiles) 2179 if (m_generateMaptiles)
2142 RegenerateMaptile(); 2180 RegenerateMaptile();
2143 2181
2144 GridRegion region = new GridRegion(RegionInfo); 2182 GridRegion region = new GridRegion(RegionInfo);
2145 string error = GridService.RegisterRegion(RegionInfo.ScopeID, region); 2183 string error = GridService.RegisterRegion(RegionInfo.ScopeID, region);
2146// m_log.DebugFormat("[SCENE]: RegisterRegionWithGrid. name={0},id={1},loc=<{2},{3}>,size=<{4},{5}>", 2184 // m_log.DebugFormat("[SCENE]: RegisterRegionWithGrid. name={0},id={1},loc=<{2},{3}>,size=<{4},{5}>",
2147// m_regionName, 2185 // m_regionName,
2148// RegionInfo.RegionID, 2186 // RegionInfo.RegionID,
2149// RegionInfo.RegionLocX, RegionInfo.RegionLocY, 2187 // RegionInfo.RegionLocX, RegionInfo.RegionLocY,
2150// RegionInfo.RegionSizeX, RegionInfo.RegionSizeY); 2188 // RegionInfo.RegionSizeX, RegionInfo.RegionSizeY);
2151 2189
2152 if (error != String.Empty) 2190 if (error != String.Empty)
2153 throw new Exception(error); 2191 throw new Exception(error);
2154 } 2192 }
2155 2193
2156 #endregion 2194 #endregion
@@ -2209,7 +2247,7 @@ namespace OpenSim.Region.Framework.Scenes
2209 rootPart.TrimPermissions(); 2247 rootPart.TrimPermissions();
2210 2248
2211 // Don't do this here - it will get done later on when sculpt data is loaded. 2249 // Don't do this here - it will get done later on when sculpt data is loaded.
2212// group.CheckSculptAndLoad(); 2250 // group.CheckSculptAndLoad();
2213 } 2251 }
2214 2252
2215 LoadingPrims = false; 2253 LoadingPrims = false;
@@ -2219,15 +2257,15 @@ namespace OpenSim.Region.Framework.Scenes
2219 public bool SupportsRayCastFiltered() 2257 public bool SupportsRayCastFiltered()
2220 { 2258 {
2221 if (PhysicsScene == null) 2259 if (PhysicsScene == null)
2222 return false; 2260 return false;
2223 return PhysicsScene.SupportsRaycastWorldFiltered(); 2261 return PhysicsScene.SupportsRaycastWorldFiltered();
2224 } 2262 }
2225 2263
2226 public object RayCastFiltered(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter) 2264 public object RayCastFiltered(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter)
2227 { 2265 {
2228 if (PhysicsScene == null) 2266 if (PhysicsScene == null)
2229 return null; 2267 return null;
2230 return PhysicsScene.RaycastWorld(position, direction, length, Count,filter); 2268 return PhysicsScene.RaycastWorld(position, direction, length, Count, filter);
2231 } 2269 }
2232 2270
2233 /// <summary> 2271 /// <summary>
@@ -2295,7 +2333,7 @@ namespace OpenSim.Region.Framework.Scenes
2295 //And in cases when we weren't rezzing from inventory we were re-adding the 0.25 straight after calling this method 2333 //And in cases when we weren't rezzing from inventory we were re-adding the 0.25 straight after calling this method
2296 // Un-offset the prim (it gets offset later by the consumer method) 2334 // Un-offset the prim (it gets offset later by the consumer method)
2297 //pos.Z -= 0.25F; 2335 //pos.Z -= 0.25F;
2298 2336
2299 } 2337 }
2300 2338
2301 return pos; 2339 return pos;
@@ -2312,7 +2350,7 @@ namespace OpenSim.Region.Framework.Scenes
2312 if (ei.HitTF) 2350 if (ei.HitTF)
2313 { 2351 {
2314 pos = ei.ipoint; 2352 pos = ei.ipoint;
2315 } 2353 }
2316 else 2354 else
2317 { 2355 {
2318 // fall back to our stupid functionality 2356 // fall back to our stupid functionality
@@ -2348,8 +2386,8 @@ namespace OpenSim.Region.Framework.Scenes
2348 /// <param name="RayTargetID"></param> 2386 /// <param name="RayTargetID"></param>
2349 /// <param name="RayEndIsIntersection"></param> 2387 /// <param name="RayEndIsIntersection"></param>
2350 public virtual void AddNewPrim(UUID ownerID, UUID groupID, Vector3 RayEnd, Quaternion rot, PrimitiveBaseShape shape, 2388 public virtual void AddNewPrim(UUID ownerID, UUID groupID, Vector3 RayEnd, Quaternion rot, PrimitiveBaseShape shape,
2351 byte bypassRaycast, Vector3 RayStart, UUID RayTargetID, 2389 byte bypassRaycast, Vector3 RayStart, UUID RayTargetID,
2352 byte RayEndIsIntersection) 2390 byte RayEndIsIntersection)
2353 { 2391 {
2354 Vector3 pos = GetNewRezLocation(RayStart, RayEnd, RayTargetID, rot, bypassRaycast, RayEndIsIntersection, true, new Vector3(0.5f, 0.5f, 0.5f), false); 2392 Vector3 pos = GetNewRezLocation(RayStart, RayEnd, RayTargetID, rot, bypassRaycast, RayEndIsIntersection, true, new Vector3(0.5f, 0.5f, 0.5f), false);
2355 2393
@@ -2364,18 +2402,18 @@ namespace OpenSim.Region.Framework.Scenes
2364 { 2402 {
2365 IClientAPI client = null; 2403 IClientAPI client = null;
2366 if (TryGetClient(ownerID, out client)) 2404 if (TryGetClient(ownerID, out client))
2367 client.SendAlertMessage("You cannot create objects here."); 2405 client.SendAlertMessage("You cannot create objects here.");
2368 } 2406 }
2369 } 2407 }
2370 2408
2371 public virtual SceneObjectGroup AddNewPrim( 2409 public virtual SceneObjectGroup AddNewPrim(
2372 UUID ownerID, UUID groupID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape) 2410 UUID ownerID, UUID groupID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape)
2373 { 2411 {
2374 //m_log.DebugFormat( 2412 //m_log.DebugFormat(
2375 // "[SCENE]: Scene.AddNewPrim() pcode {0} called for {1} in {2}", shape.PCode, ownerID, RegionInfo.RegionName); 2413 // "[SCENE]: Scene.AddNewPrim() pcode {0} called for {1} in {2}", shape.PCode, ownerID, RegionInfo.RegionName);
2376 2414
2377 SceneObjectGroup sceneObject = null; 2415 SceneObjectGroup sceneObject = null;
2378 2416
2379 // If an entity creator has been registered for this prim type then use that 2417 // If an entity creator has been registered for this prim type then use that
2380 if (m_entityCreators.ContainsKey((PCode)shape.PCode)) 2418 if (m_entityCreators.ContainsKey((PCode)shape.PCode))
2381 { 2419 {
@@ -2390,13 +2428,13 @@ namespace OpenSim.Region.Framework.Scenes
2390 } 2428 }
2391 2429
2392 if (UserManagementModule != null) 2430 if (UserManagementModule != null)
2393 sceneObject.RootPart.CreatorIdentification = UserManagementModule.GetUserUUI(ownerID); 2431 sceneObject.RootPart.CreatorIdentification = UserManagementModule.GetUserUUI(ownerID);
2394 2432
2395 sceneObject.ScheduleGroupForFullUpdate(); 2433 sceneObject.ScheduleGroupForFullUpdate();
2396 2434
2397 return sceneObject; 2435 return sceneObject;
2398 } 2436 }
2399 2437
2400 /// <summary> 2438 /// <summary>
2401 /// Add an object into the scene that has come from storage 2439 /// Add an object into the scene that has come from storage
2402 /// </summary> 2440 /// </summary>
@@ -2418,7 +2456,7 @@ namespace OpenSim.Region.Framework.Scenes
2418 /// true if the object was added, false if an object with the same uuid was already in the scene 2456 /// true if the object was added, false if an object with the same uuid was already in the scene
2419 /// </returns> 2457 /// </returns>
2420 public bool AddRestoredSceneObject( 2458 public bool AddRestoredSceneObject(
2421 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 2459 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
2422 { 2460 {
2423 if (m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates)) 2461 if (m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates))
2424 { 2462 {
@@ -2429,7 +2467,7 @@ namespace OpenSim.Region.Framework.Scenes
2429 return false; 2467 return false;
2430 2468
2431 } 2469 }
2432 2470
2433 /// <summary> 2471 /// <summary>
2434 /// Add an object into the scene that has come from storage 2472 /// Add an object into the scene that has come from storage
2435 /// </summary> 2473 /// </summary>
@@ -2447,7 +2485,7 @@ namespace OpenSim.Region.Framework.Scenes
2447 /// true if the object was added, false if an object with the same uuid was already in the scene 2485 /// true if the object was added, false if an object with the same uuid was already in the scene
2448 /// </returns> 2486 /// </returns>
2449 public bool AddRestoredSceneObject( 2487 public bool AddRestoredSceneObject(
2450 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) 2488 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted)
2451 { 2489 {
2452 return AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, true); 2490 return AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, true);
2453 } 2491 }
@@ -2465,7 +2503,7 @@ namespace OpenSim.Region.Framework.Scenes
2465 { 2503 {
2466 return AddNewSceneObject(sceneObject, attachToBackup, true); 2504 return AddNewSceneObject(sceneObject, attachToBackup, true);
2467 } 2505 }
2468 2506
2469 /// <summary> 2507 /// <summary>
2470 /// Add a newly created object to the scene 2508 /// Add a newly created object to the scene
2471 /// </summary> 2509 /// </summary>
@@ -2480,16 +2518,16 @@ namespace OpenSim.Region.Framework.Scenes
2480 /// </param> 2518 /// </param>
2481 /// <returns>true if the object was added. false if not</returns> 2519 /// <returns>true if the object was added. false if not</returns>
2482 public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) 2520 public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
2483 { 2521 {
2484 if (m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, sendClientUpdates)) 2522 if (m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, sendClientUpdates))
2485 { 2523 {
2486 EventManager.TriggerObjectAddedToScene(sceneObject); 2524 EventManager.TriggerObjectAddedToScene(sceneObject);
2487 return true; 2525 return true;
2488 } 2526 }
2489 2527
2490 return false; 2528 return false;
2491 } 2529 }
2492 2530
2493 /// <summary> 2531 /// <summary>
2494 /// Add a newly created object to the scene. 2532 /// Add a newly created object to the scene.
2495 /// </summary> 2533 /// </summary>
@@ -2503,10 +2541,10 @@ namespace OpenSim.Region.Framework.Scenes
2503 /// <param name="vel">Velocity of the object. This parameter only has an effect if the object is physical</param> 2541 /// <param name="vel">Velocity of the object. This parameter only has an effect if the object is physical</param>
2504 /// <returns></returns> 2542 /// <returns></returns>
2505 public bool AddNewSceneObject( 2543 public bool AddNewSceneObject(
2506 SceneObjectGroup sceneObject, bool attachToBackup, Vector3? pos, Quaternion? rot, Vector3 vel) 2544 SceneObjectGroup sceneObject, bool attachToBackup, Vector3? pos, Quaternion? rot, Vector3 vel)
2507 { 2545 {
2508 if (m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, pos, rot, vel)) 2546 if (m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, pos, rot, vel))
2509 { 2547 {
2510 EventManager.TriggerObjectAddedToScene(sceneObject); 2548 EventManager.TriggerObjectAddedToScene(sceneObject);
2511 return true; 2549 return true;
2512 } 2550 }
@@ -2528,7 +2566,7 @@ namespace OpenSim.Region.Framework.Scenes
2528 { 2566 {
2529 SceneObjectGroup sog = (SceneObjectGroup)e; 2567 SceneObjectGroup sog = (SceneObjectGroup)e;
2530 if (!sog.IsAttachment) 2568 if (!sog.IsAttachment)
2531 DeleteSceneObject((SceneObjectGroup)e, false); 2569 DeleteSceneObject((SceneObjectGroup)e, false);
2532 } 2570 }
2533 } 2571 }
2534 } 2572 }
@@ -2554,13 +2592,13 @@ namespace OpenSim.Region.Framework.Scenes
2554 /// <param name="silent">Suppress broadcasting changes to other clients.</param> 2592 /// <param name="silent">Suppress broadcasting changes to other clients.</param>
2555 /// <param name="removeScripts">If true, then scripts are removed. If false, then they are only stopped.</para> 2593 /// <param name="removeScripts">If true, then scripts are removed. If false, then they are only stopped.</para>
2556 public void DeleteSceneObject(SceneObjectGroup group, bool silent, bool removeScripts) 2594 public void DeleteSceneObject(SceneObjectGroup group, bool silent, bool removeScripts)
2557 { 2595 {
2558// m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID); 2596 // m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID);
2559 2597
2560 if (removeScripts) 2598 if (removeScripts)
2561 group.RemoveScriptInstances(true); 2599 group.RemoveScriptInstances(true);
2562 else 2600 else
2563 group.StopScriptInstances(); 2601 group.StopScriptInstances();
2564 2602
2565 SceneObjectPart[] partList = group.Parts; 2603 SceneObjectPart[] partList = group.Parts;
2566 2604
@@ -2590,7 +2628,7 @@ namespace OpenSim.Region.Framework.Scenes
2590 2628
2591 group.DeleteGroupFromScene(silent); 2629 group.DeleteGroupFromScene(silent);
2592 2630
2593// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); 2631 // m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);
2594 } 2632 }
2595 2633
2596 /// <summary> 2634 /// <summary>
@@ -2610,12 +2648,12 @@ namespace OpenSim.Region.Framework.Scenes
2610 // database update, because RemoveObject() works by searching on the SceneGroupID. 2648 // database update, because RemoveObject() works by searching on the SceneGroupID.
2611 // This is an expensive thing to do so only do it if absolutely necessary. 2649 // This is an expensive thing to do so only do it if absolutely necessary.
2612 if (so.GroupContainsForeignPrims) 2650 if (so.GroupContainsForeignPrims)
2613 ForceSceneObjectBackup(so); 2651 ForceSceneObjectBackup(so);
2614 2652
2615 so.DetachFromBackup(); 2653 so.DetachFromBackup();
2616 SimulationDataService.RemoveObject(so.UUID, RegionInfo.RegionID); 2654 SimulationDataService.RemoveObject(so.UUID, RegionInfo.RegionID);
2617 } 2655 }
2618 2656
2619 // We need to keep track of this state in case this group is still queued for further backup. 2657 // We need to keep track of this state in case this group is still queued for further backup.
2620 so.IsDeleted = true; 2658 so.IsDeleted = true;
2621 2659
@@ -2635,9 +2673,9 @@ namespace OpenSim.Region.Framework.Scenes
2635 public void CrossPrimGroupIntoNewRegion(Vector3 attemptedPosition, SceneObjectGroup grp, bool silent) 2673 public void CrossPrimGroupIntoNewRegion(Vector3 attemptedPosition, SceneObjectGroup grp, bool silent)
2636 { 2674 {
2637 if (grp == null) 2675 if (grp == null)
2638 return; 2676 return;
2639 if (grp.IsDeleted) 2677 if (grp.IsDeleted)
2640 return; 2678 return;
2641 2679
2642 if (grp.RootPart.DIE_AT_EDGE) 2680 if (grp.RootPart.DIE_AT_EDGE)
2643 { 2681 {
@@ -2671,7 +2709,7 @@ namespace OpenSim.Region.Framework.Scenes
2671 } 2709 }
2672 2710
2673 if (EntityTransferModule != null) 2711 if (EntityTransferModule != null)
2674 EntityTransferModule.Cross(grp, attemptedPosition, silent); 2712 EntityTransferModule.Cross(grp, attemptedPosition, silent);
2675 } 2713 }
2676 2714
2677 // Simple test to see if a position is in the current region. 2715 // Simple test to see if a position is in the current region.
@@ -2684,14 +2722,14 @@ namespace OpenSim.Region.Framework.Scenes
2684 int xx = (int)Math.Floor(pos.X); 2722 int xx = (int)Math.Floor(pos.X);
2685 int yy = (int)Math.Floor(pos.Y); 2723 int yy = (int)Math.Floor(pos.Y);
2686 if (xx < 0 || yy < 0) 2724 if (xx < 0 || yy < 0)
2687 return false; 2725 return false;
2688 2726
2689 IRegionCombinerModule regionCombinerModule = RequestModuleInterface<IRegionCombinerModule>(); 2727 IRegionCombinerModule regionCombinerModule = RequestModuleInterface<IRegionCombinerModule>();
2690 if (regionCombinerModule == null) 2728 if (regionCombinerModule == null)
2691 { 2729 {
2692 // Regular region. Just check for region size 2730 // Regular region. Just check for region size
2693 if (xx < RegionInfo.RegionSizeX && yy < RegionInfo.RegionSizeY ) 2731 if (xx < RegionInfo.RegionSizeX && yy < RegionInfo.RegionSizeY)
2694 ret = true; 2732 ret = true;
2695 } 2733 }
2696 else 2734 else
2697 { 2735 {
@@ -2725,7 +2763,7 @@ namespace OpenSim.Region.Framework.Scenes
2725 } 2763 }
2726 2764
2727 if (!EntityTransferModule.HandleIncomingSceneObject(newObject, newPosition)) 2765 if (!EntityTransferModule.HandleIncomingSceneObject(newObject, newPosition))
2728 return false; 2766 return false;
2729 2767
2730 // Do this as late as possible so that listeners have full access to the incoming object 2768 // Do this as late as possible so that listeners have full access to the incoming object
2731 EventManager.TriggerOnIncomingSceneObject(newObject); 2769 EventManager.TriggerOnIncomingSceneObject(newObject);
@@ -2746,13 +2784,13 @@ namespace OpenSim.Region.Framework.Scenes
2746 // 2784 //
2747 SceneObjectPart[] parts = sceneObject.Parts; 2785 SceneObjectPart[] parts = sceneObject.Parts;
2748 for (int i = 0; i < parts.Length; i++) 2786 for (int i = 0; i < parts.Length; i++)
2749 parts[i].LocalId = 0; 2787 parts[i].LocalId = 0;
2750 2788
2751 if (sceneObject.IsAttachmentCheckFull()) // Attachment 2789 if (sceneObject.IsAttachmentCheckFull()) // Attachment
2752 { 2790 {
2753 sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez); 2791 sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez);
2754 sceneObject.RootPart.AddFlag(PrimFlags.Phantom); 2792 sceneObject.RootPart.AddFlag(PrimFlags.Phantom);
2755 2793
2756 // Don't sent a full update here because this will cause full updates to be sent twice for 2794 // Don't sent a full update here because this will cause full updates to be sent twice for
2757 // attachments on region crossings, resulting in viewer glitches. 2795 // attachments on region crossings, resulting in viewer glitches.
2758 AddRestoredSceneObject(sceneObject, false, false, false); 2796 AddRestoredSceneObject(sceneObject, false, false, false);
@@ -2767,10 +2805,10 @@ namespace OpenSim.Region.Framework.Scenes
2767 { 2805 {
2768 SceneObjectGroup grp = sceneObject; 2806 SceneObjectGroup grp = sceneObject;
2769 2807
2770// m_log.DebugFormat( 2808 // m_log.DebugFormat(
2771// "[ATTACHMENT]: Received attachment {0}, inworld asset id {1}", grp.FromItemID, grp.UUID); 2809 // "[ATTACHMENT]: Received attachment {0}, inworld asset id {1}", grp.FromItemID, grp.UUID);
2772// m_log.DebugFormat( 2810 // m_log.DebugFormat(
2773// "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition); 2811 // "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition);
2774 2812
2775 RootPrim.RemFlag(PrimFlags.TemporaryOnRez); 2813 RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
2776 2814
@@ -2778,7 +2816,7 @@ namespace OpenSim.Region.Framework.Scenes
2778 // information that this is due to a teleport/border cross rather than an ordinary attachment. 2816 // information that this is due to a teleport/border cross rather than an ordinary attachment.
2779 // We currently do this in Scene.MakeRootAgent() instead. 2817 // We currently do this in Scene.MakeRootAgent() instead.
2780 if (AttachmentsModule != null) 2818 if (AttachmentsModule != null)
2781 AttachmentsModule.AttachObject(sp, grp, 0, false, false, true); 2819 AttachmentsModule.AttachObject(sp, grp, 0, false, false, true);
2782 } 2820 }
2783 else 2821 else
2784 { 2822 {
@@ -2804,6 +2842,9 @@ namespace OpenSim.Region.Framework.Scenes
2804 bool vialogin; 2842 bool vialogin;
2805 bool reallyNew = true; 2843 bool reallyNew = true;
2806 2844
2845 // Update the number of users attempting to login
2846 StatsReporter.UpdateUsersLoggingIn(true);
2847
2807 // Validation occurs in LLUDPServer 2848 // Validation occurs in LLUDPServer
2808 // 2849 //
2809 // XXX: A race condition exists here where two simultaneous calls to AddNewAgent can interfere with 2850 // XXX: A race condition exists here where two simultaneous calls to AddNewAgent can interfere with
@@ -2824,11 +2865,11 @@ namespace OpenSim.Region.Framework.Scenes
2824 lock (aCircuit) 2865 lock (aCircuit)
2825 { 2866 {
2826 vialogin 2867 vialogin
2827 = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 2868 = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0
2828 || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; 2869 || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
2829 2870
2830 // CheckHeartbeat(); 2871 // CheckHeartbeat();
2831 2872
2832 sp = GetScenePresence(client.AgentId); 2873 sp = GetScenePresence(client.AgentId);
2833 2874
2834 // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this 2875 // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this
@@ -2838,9 +2879,9 @@ namespace OpenSim.Region.Framework.Scenes
2838 if (sp == null) 2879 if (sp == null)
2839 { 2880 {
2840 m_log.DebugFormat( 2881 m_log.DebugFormat(
2841 "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}", 2882 "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}",
2842 client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos); 2883 client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos);
2843 2884
2844 sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type); 2885 sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
2845 2886
2846 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the 2887 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the
@@ -2857,7 +2898,7 @@ namespace OpenSim.Region.Framework.Scenes
2857 m_clientManager.Add(client); 2898 m_clientManager.Add(client);
2858 SubscribeToClientEvents(client); 2899 SubscribeToClientEvents(client);
2859 m_eventManager.TriggerOnNewPresence(sp); 2900 m_eventManager.TriggerOnNewPresence(sp);
2860 2901
2861 sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags; 2902 sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags;
2862 } 2903 }
2863 else 2904 else
@@ -2870,24 +2911,28 @@ namespace OpenSim.Region.Framework.Scenes
2870 client.SceneAgent = sp; 2911 client.SceneAgent = sp;
2871 2912
2872 m_log.WarnFormat( 2913 m_log.WarnFormat(
2873 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", 2914 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence",
2874 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName); 2915 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName);
2875 2916
2876 reallyNew = false; 2917 reallyNew = false;
2877 } 2918 }
2878 2919
2879 // This is currently also being done earlier in NewUserConnection for real users to see if this 2920 // This is currently also being done earlier in NewUserConnection for real users to see if this
2880 // resolves problems where HG agents are occasionally seen by others as "Unknown user" in chat and other 2921 // resolves problems where HG agents are occasionally seen by others as "Unknown user" in chat and other
2881 // places. However, we still need to do it here for NPCs. 2922 // places. However, we still need to do it here for NPCs.
2882 CacheUserName(sp, aCircuit); 2923 CacheUserName(sp, aCircuit);
2883 2924
2884 if (reallyNew) 2925 if (reallyNew)
2885 EventManager.TriggerOnNewClient(client); 2926 EventManager.TriggerOnNewClient(client);
2886 2927
2887 if (vialogin) 2928 if (vialogin)
2888 EventManager.TriggerOnClientLogin(client); 2929 EventManager.TriggerOnClientLogin(client);
2889 } 2930 }
2890 2931
2932 // User has logged into the scene so update the list of users logging
2933 // in
2934 StatsReporter.UpdateUsersLoggingIn(false);
2935
2891 m_LastLogin = Util.EnvironmentTickCount(); 2936 m_LastLogin = Util.EnvironmentTickCount();
2892 2937
2893 return sp; 2938 return sp;
@@ -2900,9 +2945,9 @@ namespace OpenSim.Region.Framework.Scenes
2900 { 2945 {
2901 AgentCircuitData circuit = AuthenticateHandler.GetAgentCircuitData(agentID); 2946 AgentCircuitData circuit = AuthenticateHandler.GetAgentCircuitData(agentID);
2902 if (circuit != null && circuit.ServiceURLs != null && circuit.ServiceURLs.ContainsKey("HomeURI")) 2947 if (circuit != null && circuit.ServiceURLs != null && circuit.ServiceURLs.ContainsKey("HomeURI"))
2903 return circuit.ServiceURLs["HomeURI"].ToString(); 2948 return circuit.ServiceURLs["HomeURI"].ToString();
2904 else 2949 else
2905 return null; 2950 return null;
2906 } 2951 }
2907 2952
2908 /// <summary> 2953 /// <summary>
@@ -2925,7 +2970,7 @@ namespace OpenSim.Region.Framework.Scenes
2925 string homeURL = string.Empty; 2970 string homeURL = string.Empty;
2926 2971
2927 if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) 2972 if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
2928 homeURL = aCircuit.ServiceURLs["HomeURI"].ToString(); 2973 homeURL = aCircuit.ServiceURLs["HomeURI"].ToString();
2929 2974
2930 if (aCircuit.lastname.StartsWith("@")) 2975 if (aCircuit.lastname.StartsWith("@"))
2931 { 2976 {
@@ -2945,7 +2990,7 @@ namespace OpenSim.Region.Framework.Scenes
2945 private bool VerifyClient(AgentCircuitData aCircuit, System.Net.IPEndPoint ep, out bool vialogin) 2990 private bool VerifyClient(AgentCircuitData aCircuit, System.Net.IPEndPoint ep, out bool vialogin)
2946 { 2991 {
2947 vialogin = false; 2992 vialogin = false;
2948 2993
2949 // Do the verification here 2994 // Do the verification here
2950 if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0) 2995 if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
2951 { 2996 {
@@ -2961,7 +3006,7 @@ namespace OpenSim.Region.Framework.Scenes
2961 return false; 3006 return false;
2962 } 3007 }
2963 else 3008 else
2964 m_log.DebugFormat("[SCENE]: User Client Verification for {0} {1} in {2} returned true", aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName); 3009 m_log.DebugFormat("[SCENE]: User Client Verification for {0} {1} in {2} returned true", aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName);
2965 3010
2966 } 3011 }
2967 } 3012 }
@@ -2969,7 +3014,7 @@ namespace OpenSim.Region.Framework.Scenes
2969 else if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0) 3014 else if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0)
2970 { 3015 {
2971 m_log.DebugFormat("[SCENE]: Incoming client {0} {1} in region {2} via regular login. Client IP verification not performed.", 3016 m_log.DebugFormat("[SCENE]: Incoming client {0} {1} in region {2} via regular login. Client IP verification not performed.",
2972 aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName); 3017 aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName);
2973 vialogin = true; 3018 vialogin = true;
2974 } 3019 }
2975 3020
@@ -3013,7 +3058,7 @@ namespace OpenSim.Region.Framework.Scenes
3013 } 3058 }
3014 } 3059 }
3015 else 3060 else
3016 return true; 3061 return true;
3017 } 3062 }
3018 3063
3019 return false; 3064 return false;
@@ -3040,7 +3085,7 @@ namespace OpenSim.Region.Framework.Scenes
3040 { 3085 {
3041 client.OnRegionHandShakeReply += SendLayerData; 3086 client.OnRegionHandShakeReply += SendLayerData;
3042 } 3087 }
3043 3088
3044 public virtual void SubscribeToClientPrimEvents(IClientAPI client) 3089 public virtual void SubscribeToClientPrimEvents(IClientAPI client)
3045 { 3090 {
3046 client.OnUpdatePrimGroupPosition += m_sceneGraph.UpdatePrimGroupPosition; 3091 client.OnUpdatePrimGroupPosition += m_sceneGraph.UpdatePrimGroupPosition;
@@ -3050,7 +3095,7 @@ namespace OpenSim.Region.Framework.Scenes
3050 client.OnUpdatePrimGroupMouseRotation += m_sceneGraph.UpdatePrimGroupRotation; 3095 client.OnUpdatePrimGroupMouseRotation += m_sceneGraph.UpdatePrimGroupRotation;
3051 client.OnUpdatePrimSingleRotation += m_sceneGraph.UpdatePrimSingleRotation; 3096 client.OnUpdatePrimSingleRotation += m_sceneGraph.UpdatePrimSingleRotation;
3052 client.OnUpdatePrimSingleRotationPosition += m_sceneGraph.UpdatePrimSingleRotationPosition; 3097 client.OnUpdatePrimSingleRotationPosition += m_sceneGraph.UpdatePrimSingleRotationPosition;
3053 3098
3054 client.OnUpdatePrimScale += m_sceneGraph.UpdatePrimScale; 3099 client.OnUpdatePrimScale += m_sceneGraph.UpdatePrimScale;
3055 client.OnUpdatePrimGroupScale += m_sceneGraph.UpdatePrimGroupScale; 3100 client.OnUpdatePrimGroupScale += m_sceneGraph.UpdatePrimGroupScale;
3056 client.OnUpdateExtraParams += m_sceneGraph.UpdateExtraParam; 3101 client.OnUpdateExtraParams += m_sceneGraph.UpdateExtraParam;
@@ -3063,7 +3108,7 @@ namespace OpenSim.Region.Framework.Scenes
3063 client.OnSpinStart += m_sceneGraph.SpinStart; 3108 client.OnSpinStart += m_sceneGraph.SpinStart;
3064 client.OnSpinUpdate += m_sceneGraph.SpinObject; 3109 client.OnSpinUpdate += m_sceneGraph.SpinObject;
3065 client.OnDeRezObject += DeRezObjects; 3110 client.OnDeRezObject += DeRezObjects;
3066 3111
3067 client.OnObjectName += m_sceneGraph.PrimName; 3112 client.OnObjectName += m_sceneGraph.PrimName;
3068 client.OnObjectClickAction += m_sceneGraph.PrimClickAction; 3113 client.OnObjectClickAction += m_sceneGraph.PrimClickAction;
3069 client.OnObjectMaterial += m_sceneGraph.PrimMaterial; 3114 client.OnObjectMaterial += m_sceneGraph.PrimMaterial;
@@ -3075,7 +3120,7 @@ namespace OpenSim.Region.Framework.Scenes
3075 client.OnRequestObjectPropertiesFamily += m_sceneGraph.RequestObjectPropertiesFamily; 3120 client.OnRequestObjectPropertiesFamily += m_sceneGraph.RequestObjectPropertiesFamily;
3076 client.OnObjectPermissions += HandleObjectPermissionsUpdate; 3121 client.OnObjectPermissions += HandleObjectPermissionsUpdate;
3077 client.OnGrabObject += ProcessObjectGrab; 3122 client.OnGrabObject += ProcessObjectGrab;
3078 client.OnGrabUpdate += ProcessObjectGrabUpdate; 3123 client.OnGrabUpdate += ProcessObjectGrabUpdate;
3079 client.OnDeGrabObject += ProcessObjectDeGrab; 3124 client.OnDeGrabObject += ProcessObjectDeGrab;
3080 client.OnUndo += m_sceneGraph.HandleUndo; 3125 client.OnUndo += m_sceneGraph.HandleUndo;
3081 client.OnRedo += m_sceneGraph.HandleRedo; 3126 client.OnRedo += m_sceneGraph.HandleRedo;
@@ -3136,7 +3181,7 @@ namespace OpenSim.Region.Framework.Scenes
3136 //client.OnNameFromUUIDRequest += HandleUUIDNameRequest; 3181 //client.OnNameFromUUIDRequest += HandleUUIDNameRequest;
3137 client.OnMoneyTransferRequest += ProcessMoneyTransferRequest; 3182 client.OnMoneyTransferRequest += ProcessMoneyTransferRequest;
3138 } 3183 }
3139 3184
3140 public virtual void SubscribeToClientNetworkEvents(IClientAPI client) 3185 public virtual void SubscribeToClientNetworkEvents(IClientAPI client)
3141 { 3186 {
3142 client.OnNetworkStatsUpdate += StatsReporter.AddPacketsStats; 3187 client.OnNetworkStatsUpdate += StatsReporter.AddPacketsStats;
@@ -3297,7 +3342,7 @@ namespace OpenSim.Region.Framework.Scenes
3297 { 3342 {
3298 SceneObjectGroup copy = SceneGraph.DuplicateObject(originalPrim, offset, flags, AgentID, GroupID, Quaternion.Identity); 3343 SceneObjectGroup copy = SceneGraph.DuplicateObject(originalPrim, offset, flags, AgentID, GroupID, Quaternion.Identity);
3299 if (copy != null) 3344 if (copy != null)
3300 EventManager.TriggerObjectAddedToScene(copy); 3345 EventManager.TriggerObjectAddedToScene(copy);
3301 } 3346 }
3302 3347
3303 /// <summary> 3348 /// <summary>
@@ -3316,8 +3361,8 @@ namespace OpenSim.Region.Framework.Scenes
3316 /// <param name="CopyCenters">Position the object at the center of the face that it's colliding with</param> 3361 /// <param name="CopyCenters">Position the object at the center of the face that it's colliding with</param>
3317 /// <param name="CopyRotates">Rotate the object the same as the localID object</param> 3362 /// <param name="CopyRotates">Rotate the object the same as the localID object</param>
3318 public void doObjectDuplicateOnRay(uint localID, uint dupeFlags, UUID AgentID, UUID GroupID, 3363 public void doObjectDuplicateOnRay(uint localID, uint dupeFlags, UUID AgentID, UUID GroupID,
3319 UUID RayTargetObj, Vector3 RayEnd, Vector3 RayStart, 3364 UUID RayTargetObj, Vector3 RayEnd, Vector3 RayStart,
3320 bool BypassRaycast, bool RayEndIsIntersection, bool CopyCenters, bool CopyRotates) 3365 bool BypassRaycast, bool RayEndIsIntersection, bool CopyCenters, bool CopyRotates)
3321 { 3366 {
3322 Vector3 pos; 3367 Vector3 pos;
3323 const bool frontFacesOnly = true; 3368 const bool frontFacesOnly = true;
@@ -3378,7 +3423,7 @@ namespace OpenSim.Region.Framework.Scenes
3378 } 3423 }
3379 3424
3380 if (copy != null) 3425 if (copy != null)
3381 EventManager.TriggerObjectAddedToScene(copy); 3426 EventManager.TriggerObjectAddedToScene(copy);
3382 } 3427 }
3383 } 3428 }
3384 } 3429 }
@@ -3429,25 +3474,25 @@ namespace OpenSim.Region.Framework.Scenes
3429 if (acd == null) 3474 if (acd == null)
3430 { 3475 {
3431 m_log.ErrorFormat( 3476 m_log.ErrorFormat(
3432 "[SCENE]: No agent circuit found for {0} in {1}, aborting Scene.RemoveClient", agentID, Name); 3477 "[SCENE]: No agent circuit found for {0} in {1}, aborting Scene.RemoveClient", agentID, Name);
3433 3478
3434 return; 3479 return;
3435 } 3480 }
3436 3481
3437 // TODO: Can we now remove this lock? 3482 // TODO: Can we now remove this lock?
3438 lock (acd) 3483 lock (acd)
3439 { 3484 {
3440 bool isChildAgent = false; 3485 bool isChildAgent = false;
3441 3486
3442 ScenePresence avatar = GetScenePresence(agentID); 3487 ScenePresence avatar = GetScenePresence(agentID);
3443 3488
3444 // Shouldn't be necessary since RemoveClient() is currently only called by IClientAPI.Close() which 3489 // Shouldn't be necessary since RemoveClient() is currently only called by IClientAPI.Close() which
3445 // in turn is only called by Scene.IncomingCloseAgent() which checks whether the presence exists or not 3490 // in turn is only called by Scene.IncomingCloseAgent() which checks whether the presence exists or not
3446 // However, will keep for now just in case. 3491 // However, will keep for now just in case.
3447 if (avatar == null) 3492 if (avatar == null)
3448 { 3493 {
3449 m_log.ErrorFormat( 3494 m_log.ErrorFormat(
3450 "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID); 3495 "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID);
3451 m_authenticateHandler.RemoveCircuit(agentID); 3496 m_authenticateHandler.RemoveCircuit(agentID);
3452 3497
3453 return; 3498 return;
@@ -3458,9 +3503,9 @@ namespace OpenSim.Region.Framework.Scenes
3458 isChildAgent = avatar.IsChildAgent; 3503 isChildAgent = avatar.IsChildAgent;
3459 3504
3460 m_log.DebugFormat( 3505 m_log.DebugFormat(
3461 "[SCENE]: Removing {0} agent {1} {2} from {3}", 3506 "[SCENE]: Removing {0} agent {1} {2} from {3}",
3462 isChildAgent ? "child" : "root", avatar.Name, agentID, Name); 3507 isChildAgent ? "child" : "root", avatar.Name, agentID, Name);
3463 3508
3464 // Don't do this to root agents, it's not nice for the viewer 3509 // Don't do this to root agents, it's not nice for the viewer
3465 if (closeChildAgents && isChildAgent) 3510 if (closeChildAgents && isChildAgent)
3466 { 3511 {
@@ -3468,20 +3513,20 @@ namespace OpenSim.Region.Framework.Scenes
3468 // Let's do this via UDP 3513 // Let's do this via UDP
3469 avatar.ControllingClient.SendShutdownConnectionNotice(); 3514 avatar.ControllingClient.SendShutdownConnectionNotice();
3470 } 3515 }
3471 3516
3472 // Only applies to root agents. 3517 // Only applies to root agents.
3473 if (avatar.ParentID != 0) 3518 if (avatar.ParentID != 0)
3474 { 3519 {
3475 avatar.StandUp(); 3520 avatar.StandUp();
3476 } 3521 }
3477 3522
3478 m_sceneGraph.removeUserCount(!isChildAgent); 3523 m_sceneGraph.removeUserCount(!isChildAgent);
3479 3524
3480 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop 3525 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop
3481 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI 3526 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI
3482 if (closeChildAgents && CapsModule != null) 3527 if (closeChildAgents && CapsModule != null)
3483 CapsModule.RemoveCaps(agentID); 3528 CapsModule.RemoveCaps(agentID);
3484 3529
3485 if (closeChildAgents && !isChildAgent) 3530 if (closeChildAgents && !isChildAgent)
3486 { 3531 {
3487 List<ulong> regions = avatar.KnownRegionHandles; 3532 List<ulong> regions = avatar.KnownRegionHandles;
@@ -3490,10 +3535,10 @@ namespace OpenSim.Region.Framework.Scenes
3490 // This ends up being done asynchronously so that a logout isn't held up where there are many present but unresponsive neighbours. 3535 // This ends up being done asynchronously so that a logout isn't held up where there are many present but unresponsive neighbours.
3491 m_sceneGridService.SendCloseChildAgentConnections(agentID, acd.SessionID.ToString(), regions); 3536 m_sceneGridService.SendCloseChildAgentConnections(agentID, acd.SessionID.ToString(), regions);
3492 } 3537 }
3493 3538
3494 m_eventManager.TriggerClientClosed(agentID, this); 3539 m_eventManager.TriggerClientClosed(agentID, this);
3495 m_eventManager.TriggerOnRemovePresence(agentID); 3540 m_eventManager.TriggerOnRemovePresence(agentID);
3496 3541
3497 if (!isChildAgent) 3542 if (!isChildAgent)
3498 { 3543 {
3499 if (AttachmentsModule != null) 3544 if (AttachmentsModule != null)
@@ -3502,22 +3547,22 @@ namespace OpenSim.Region.Framework.Scenes
3502 } 3547 }
3503 3548
3504 ForEachClient( 3549 ForEachClient(
3505 delegate(IClientAPI client) 3550 delegate(IClientAPI client)
3506 { 3551 {
3507 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway 3552 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3508 try { client.SendKillObject(new List<uint> { avatar.LocalId }); } 3553 try { client.SendKillObject(new List<uint> { avatar.LocalId }); }
3509 catch (NullReferenceException) { } 3554 catch (NullReferenceException) { }
3510 }); 3555 });
3511 } 3556 }
3512 3557
3513 // It's possible for child agents to have transactions if changes are being made cross-border. 3558 // It's possible for child agents to have transactions if changes are being made cross-border.
3514 if (AgentTransactionsModule != null) 3559 if (AgentTransactionsModule != null)
3515 AgentTransactionsModule.RemoveAgentAssetTransactions(agentID); 3560 AgentTransactionsModule.RemoveAgentAssetTransactions(agentID);
3516 } 3561 }
3517 catch (Exception e) 3562 catch (Exception e)
3518 { 3563 {
3519 m_log.Error( 3564 m_log.Error(
3520 string.Format("[SCENE]: Exception removing {0} from {1}. Cleaning up. Exception ", avatar.Name, Name), e); 3565 string.Format("[SCENE]: Exception removing {0} from {1}. Cleaning up. Exception ", avatar.Name, Name), e);
3521 } 3566 }
3522 finally 3567 finally
3523 { 3568 {
@@ -3529,13 +3574,13 @@ namespace OpenSim.Region.Framework.Scenes
3529 m_authenticateHandler.RemoveCircuit(agentID); 3574 m_authenticateHandler.RemoveCircuit(agentID);
3530 m_sceneGraph.RemoveScenePresence(agentID); 3575 m_sceneGraph.RemoveScenePresence(agentID);
3531 m_clientManager.Remove(agentID); 3576 m_clientManager.Remove(agentID);
3532 3577
3533 avatar.Close(); 3578 avatar.Close();
3534 } 3579 }
3535 catch (Exception e) 3580 catch (Exception e)
3536 { 3581 {
3537 m_log.Error( 3582 m_log.Error(
3538 string.Format("[SCENE]: Exception in final clean up of {0} in {1}. Exception ", avatar.Name, Name), e); 3583 string.Format("[SCENE]: Exception in final clean up of {0} in {1}. Exception ", avatar.Name, Name), e);
3539 } 3584 }
3540 } 3585 }
3541 } 3586 }
@@ -3581,7 +3626,7 @@ namespace OpenSim.Region.Framework.Scenes
3581 if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid 3626 if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid
3582 { 3627 {
3583 if (part.ParentGroup.RootPart != part) // Child part 3628 if (part.ParentGroup.RootPart != part) // Child part
3584 continue; 3629 continue;
3585 } 3630 }
3586 } 3631 }
3587 deleteIDs.Add(localID); 3632 deleteIDs.Add(localID);
@@ -3634,7 +3679,7 @@ namespace OpenSim.Region.Framework.Scenes
3634 public bool NewUserConnection(AgentCircuitData acd, uint teleportFlags, GridRegion source, out string reason, bool requirePresenceLookup) 3679 public bool NewUserConnection(AgentCircuitData acd, uint teleportFlags, GridRegion source, out string reason, bool requirePresenceLookup)
3635 { 3680 {
3636 bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 || 3681 bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 ||
3637 (teleportFlags & (uint)TPFlags.ViaHGLogin) != 0); 3682 (teleportFlags & (uint)TPFlags.ViaHGLogin) != 0);
3638 bool viahome = ((teleportFlags & (uint)TPFlags.ViaHome) != 0); 3683 bool viahome = ((teleportFlags & (uint)TPFlags.ViaHome) != 0);
3639 bool godlike = ((teleportFlags & (uint)TPFlags.Godlike) != 0); 3684 bool godlike = ((teleportFlags & (uint)TPFlags.Godlike) != 0);
3640 3685
@@ -3650,18 +3695,18 @@ namespace OpenSim.Region.Framework.Scenes
3650 // Don't disable this log message - it's too helpful 3695 // Don't disable this log message - it's too helpful
3651 string curViewer = Util.GetViewerName(acd); 3696 string curViewer = Util.GetViewerName(acd);
3652 m_log.DebugFormat( 3697 m_log.DebugFormat(
3653 "[SCENE]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, IP {6}, viewer {7}, teleportflags ({8}), position {9}. {10}", 3698 "[SCENE]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, IP {6}, viewer {7}, teleportflags ({8}), position {9}. {10}",
3654 RegionInfo.RegionName, 3699 RegionInfo.RegionName,
3655 (acd.child ? "child" : "root"), 3700 (acd.child ? "child" : "root"),
3656 acd.firstname, 3701 acd.firstname,
3657 acd.lastname, 3702 acd.lastname,
3658 acd.AgentID, 3703 acd.AgentID,
3659 acd.circuitcode, 3704 acd.circuitcode,
3660 acd.IPAddress, 3705 acd.IPAddress,
3661 curViewer, 3706 curViewer,
3662 ((TPFlags)teleportFlags).ToString(), 3707 ((TPFlags)teleportFlags).ToString(),
3663 acd.startpos, 3708 acd.startpos,
3664 (source == null) ? "" : string.Format("From region {0} ({1}){2}", source.RegionName, source.RegionID, (source.RawServerURI == null) ? "" : " @ " + source.ServerURI) 3709 (source == null) ? "" : string.Format("From region {0} ({1}){2}", source.RegionName, source.RegionID, (source.RawServerURI == null) ? "" : " @ " + source.ServerURI)
3665 ); 3710 );
3666 3711
3667 if (!LoginsEnabled) 3712 if (!LoginsEnabled)
@@ -3707,8 +3752,8 @@ namespace OpenSim.Region.Framework.Scenes
3707 if (ViewerDenied) 3752 if (ViewerDenied)
3708 { 3753 {
3709 m_log.DebugFormat( 3754 m_log.DebugFormat(
3710 "[SCENE]: Access denied for {0} {1} using {2}", 3755 "[SCENE]: Access denied for {0} {1} using {2}",
3711 acd.firstname, acd.lastname, curViewer); 3756 acd.firstname, acd.lastname, curViewer);
3712 reason = "Access denied, your viewer is banned by the region owner"; 3757 reason = "Access denied, your viewer is banned by the region owner";
3713 return false; 3758 return false;
3714 } 3759 }
@@ -3722,13 +3767,13 @@ namespace OpenSim.Region.Framework.Scenes
3722 3767
3723 // We need to ensure that we are not already removing the scene presence before we ask it not to be 3768 // We need to ensure that we are not already removing the scene presence before we ask it not to be
3724 // closed. 3769 // closed.
3725 if (sp != null && sp.IsChildAgent 3770 if (sp != null && sp.IsChildAgent
3726 && (sp.LifecycleState == ScenePresenceState.Running 3771 && (sp.LifecycleState == ScenePresenceState.Running
3727 || sp.LifecycleState == ScenePresenceState.PreRemove)) 3772 || sp.LifecycleState == ScenePresenceState.PreRemove))
3728 { 3773 {
3729 m_log.DebugFormat( 3774 m_log.DebugFormat(
3730 "[SCENE]: Reusing existing child scene presence for {0}, state {1} in {2}", 3775 "[SCENE]: Reusing existing child scene presence for {0}, state {1} in {2}",
3731 sp.Name, sp.LifecycleState, Name); 3776 sp.Name, sp.LifecycleState, Name);
3732 3777
3733 // In the case where, for example, an A B C D region layout, an avatar may 3778 // In the case where, for example, an A B C D region layout, an avatar may
3734 // teleport from A -> D, but then -> C before A has asked B to close its old child agent. When C 3779 // teleport from A -> D, but then -> C before A has asked B to close its old child agent. When C
@@ -3740,15 +3785,15 @@ namespace OpenSim.Region.Framework.Scenes
3740 // vulnerable to an issue when a viewer quits a region without sending a proper logout but then 3785 // vulnerable to an issue when a viewer quits a region without sending a proper logout but then
3741 // re-establishes the connection on a relogin. This could wrongly set the DoNotCloseAfterTeleport 3786 // re-establishes the connection on a relogin. This could wrongly set the DoNotCloseAfterTeleport
3742 // flag when no teleport had taken place (and hence no close was going to come). 3787 // flag when no teleport had taken place (and hence no close was going to come).
3743// if (!acd.ChildrenCapSeeds.ContainsKey(RegionInfo.RegionHandle)) 3788 // if (!acd.ChildrenCapSeeds.ContainsKey(RegionInfo.RegionHandle))
3744// { 3789 // {
3745// m_log.DebugFormat( 3790 // m_log.DebugFormat(
3746// "[SCENE]: Setting DoNotCloseAfterTeleport for child scene presence {0} in {1} because source will attempt close.", 3791 // "[SCENE]: Setting DoNotCloseAfterTeleport for child scene presence {0} in {1} because source will attempt close.",
3747// sp.Name, Name); 3792 // sp.Name, Name);
3748// 3793 //
3749// sp.DoNotCloseAfterTeleport = true; 3794 // sp.DoNotCloseAfterTeleport = true;
3750// } 3795 // }
3751// else if (EntityTransferModule.IsInTransit(sp.UUID)) 3796 // else if (EntityTransferModule.IsInTransit(sp.UUID))
3752 3797
3753 sp.LifecycleState = ScenePresenceState.Running; 3798 sp.LifecycleState = ScenePresenceState.Running;
3754 3799
@@ -3757,8 +3802,8 @@ namespace OpenSim.Region.Framework.Scenes
3757 sp.DoNotCloseAfterTeleport = true; 3802 sp.DoNotCloseAfterTeleport = true;
3758 3803
3759 m_log.DebugFormat( 3804 m_log.DebugFormat(
3760 "[SCENE]: Set DoNotCloseAfterTeleport for child scene presence {0} in {1} because this region will attempt end-of-teleport close from a previous close.", 3805 "[SCENE]: Set DoNotCloseAfterTeleport for child scene presence {0} in {1} because this region will attempt end-of-teleport close from a previous close.",
3761 sp.Name, Name); 3806 sp.Name, Name);
3762 } 3807 }
3763 } 3808 }
3764 } 3809 }
@@ -3772,21 +3817,21 @@ namespace OpenSim.Region.Framework.Scenes
3772 int pollsLeft = polls; 3817 int pollsLeft = polls;
3773 3818
3774 while (sp.LifecycleState == ScenePresenceState.Removing && pollsLeft-- > 0) 3819 while (sp.LifecycleState == ScenePresenceState.Removing && pollsLeft-- > 0)
3775 Thread.Sleep(pollInterval); 3820 Thread.Sleep(pollInterval);
3776 3821
3777 if (sp.LifecycleState == ScenePresenceState.Removing) 3822 if (sp.LifecycleState == ScenePresenceState.Removing)
3778 { 3823 {
3779 m_log.WarnFormat( 3824 m_log.WarnFormat(
3780 "[SCENE]: Agent {0} in {1} was still being removed after {2}s. Aborting NewUserConnection.", 3825 "[SCENE]: Agent {0} in {1} was still being removed after {2}s. Aborting NewUserConnection.",
3781 sp.Name, Name, polls * pollInterval / 1000); 3826 sp.Name, Name, polls * pollInterval / 1000);
3782 3827
3783 return false; 3828 return false;
3784 } 3829 }
3785 else if (polls != pollsLeft) 3830 else if (polls != pollsLeft)
3786 { 3831 {
3787 m_log.DebugFormat( 3832 m_log.DebugFormat(
3788 "[SCENE]: NewUserConnection for agent {0} in {1} had to wait {2}s for in-progress removal to complete on an old presence.", 3833 "[SCENE]: NewUserConnection for agent {0} in {1} had to wait {2}s for in-progress removal to complete on an old presence.",
3789 sp.Name, Name, polls * pollInterval / 1000); 3834 sp.Name, Name, polls * pollInterval / 1000);
3790 } 3835 }
3791 } 3836 }
3792 3837
@@ -3802,11 +3847,11 @@ namespace OpenSim.Region.Framework.Scenes
3802 // Or the same user is trying to be root twice here, won't work. 3847 // Or the same user is trying to be root twice here, won't work.
3803 // Kill it. 3848 // Kill it.
3804 m_log.WarnFormat( 3849 m_log.WarnFormat(
3805 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", 3850 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
3806 sp.Name, sp.UUID, RegionInfo.RegionName); 3851 sp.Name, sp.UUID, RegionInfo.RegionName);
3807 3852
3808 if (sp.ControllingClient != null) 3853 if (sp.ControllingClient != null)
3809 CloseAgent(sp.UUID, true); 3854 CloseAgent(sp.UUID, true);
3810 3855
3811 sp = null; 3856 sp = null;
3812 } 3857 }
@@ -3821,7 +3866,7 @@ namespace OpenSim.Region.Framework.Scenes
3821 m_authenticateHandler.AddNewCircuit(acd.circuitcode, acd); 3866 m_authenticateHandler.AddNewCircuit(acd.circuitcode, acd);
3822 3867
3823 land = LandChannel.GetLandObject(acd.startpos.X, acd.startpos.Y); 3868 land = LandChannel.GetLandObject(acd.startpos.X, acd.startpos.Y);
3824 3869
3825 // On login test land permisions 3870 // On login test land permisions
3826 if (vialogin) 3871 if (vialogin)
3827 { 3872 {
@@ -3831,7 +3876,7 @@ namespace OpenSim.Region.Framework.Scenes
3831 return false; 3876 return false;
3832 } 3877 }
3833 } 3878 }
3834 3879
3835 if (sp == null) // We don't have an [child] agent here already 3880 if (sp == null) // We don't have an [child] agent here already
3836 { 3881 {
3837 if (requirePresenceLookup) 3882 if (requirePresenceLookup)
@@ -3847,13 +3892,13 @@ namespace OpenSim.Region.Framework.Scenes
3847 catch (Exception e) 3892 catch (Exception e)
3848 { 3893 {
3849 m_log.ErrorFormat( 3894 m_log.ErrorFormat(
3850 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); 3895 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace);
3851 3896
3852 m_authenticateHandler.RemoveCircuit(acd.circuitcode); 3897 m_authenticateHandler.RemoveCircuit(acd.circuitcode);
3853 return false; 3898 return false;
3854 } 3899 }
3855 } 3900 }
3856 3901
3857 try 3902 try
3858 { 3903 {
3859 if (!AuthorizeUser(acd, (vialogin ? false : SeeIntoRegion), out reason)) 3904 if (!AuthorizeUser(acd, (vialogin ? false : SeeIntoRegion), out reason))
@@ -3865,17 +3910,17 @@ namespace OpenSim.Region.Framework.Scenes
3865 catch (Exception e) 3910 catch (Exception e)
3866 { 3911 {
3867 m_log.ErrorFormat( 3912 m_log.ErrorFormat(
3868 "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace); 3913 "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace);
3869 3914
3870 m_authenticateHandler.RemoveCircuit(acd.circuitcode); 3915 m_authenticateHandler.RemoveCircuit(acd.circuitcode);
3871 return false; 3916 return false;
3872 } 3917 }
3873 3918
3874 m_log.InfoFormat( 3919 m_log.InfoFormat(
3875 "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})", 3920 "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})",
3876 Name, (acd.child ? "child" : "root"), acd.firstname, acd.lastname, 3921 Name, (acd.child ? "child" : "root"), acd.firstname, acd.lastname,
3877 acd.AgentID, acd.circuitcode); 3922 acd.AgentID, acd.circuitcode);
3878 3923
3879 if (CapsModule != null) 3924 if (CapsModule != null)
3880 { 3925 {
3881 CapsModule.SetAgentCapsSeeds(acd); 3926 CapsModule.SetAgentCapsSeeds(acd);
@@ -3887,13 +3932,13 @@ namespace OpenSim.Region.Framework.Scenes
3887 // Let the SP know how we got here. This has a lot of interesting 3932 // Let the SP know how we got here. This has a lot of interesting
3888 // uses down the line. 3933 // uses down the line.
3889 sp.TeleportFlags = (TPFlags)teleportFlags; 3934 sp.TeleportFlags = (TPFlags)teleportFlags;
3890 3935
3891 if (sp.IsChildAgent) 3936 if (sp.IsChildAgent)
3892 { 3937 {
3893 m_log.DebugFormat( 3938 m_log.DebugFormat(
3894 "[SCENE]: Adjusting known seeds for existing agent {0} in {1}", 3939 "[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
3895 acd.AgentID, RegionInfo.RegionName); 3940 acd.AgentID, RegionInfo.RegionName);
3896 3941
3897 sp.AdjustKnownSeeds(); 3942 sp.AdjustKnownSeeds();
3898 3943
3899 if (CapsModule != null) 3944 if (CapsModule != null)
@@ -3912,7 +3957,7 @@ namespace OpenSim.Region.Framework.Scenes
3912 3957
3913 if (vialogin) 3958 if (vialogin)
3914 { 3959 {
3915// CleanDroppedAttachments(); 3960 // CleanDroppedAttachments();
3916 3961
3917 // Make sure avatar position is in the region (why it wouldn't be is a mystery but do sanity checking) 3962 // Make sure avatar position is in the region (why it wouldn't be is a mystery but do sanity checking)
3918 if (acd.startpos.X < 0) acd.startpos.X = 1f; 3963 if (acd.startpos.X < 0) acd.startpos.X = 1f;
@@ -3920,14 +3965,14 @@ namespace OpenSim.Region.Framework.Scenes
3920 if (acd.startpos.Y < 0) acd.startpos.Y = 1f; 3965 if (acd.startpos.Y < 0) acd.startpos.Y = 1f;
3921 if (acd.startpos.Y >= RegionInfo.RegionSizeY) acd.startpos.Y = RegionInfo.RegionSizeY - 1f; 3966 if (acd.startpos.Y >= RegionInfo.RegionSizeY) acd.startpos.Y = RegionInfo.RegionSizeY - 1f;
3922 3967
3923// m_log.DebugFormat( 3968 // m_log.DebugFormat(
3924// "[SCENE]: Found telehub object {0} for new user connection {1} to {2}", 3969 // "[SCENE]: Found telehub object {0} for new user connection {1} to {2}",
3925// RegionInfo.RegionSettings.TelehubObject, acd.Name, Name); 3970 // RegionInfo.RegionSettings.TelehubObject, acd.Name, Name);
3926 3971
3927 // Honor Estate teleport routing via Telehubs excluding ViaHome and GodLike TeleportFlags 3972 // Honor Estate teleport routing via Telehubs excluding ViaHome and GodLike TeleportFlags
3928 if (RegionInfo.RegionSettings.TelehubObject != UUID.Zero && 3973 if (RegionInfo.RegionSettings.TelehubObject != UUID.Zero &&
3929 RegionInfo.EstateSettings.AllowDirectTeleport == false && 3974 RegionInfo.EstateSettings.AllowDirectTeleport == false &&
3930 !viahome && !godlike) 3975 !viahome && !godlike)
3931 { 3976 {
3932 SceneObjectGroup telehub = GetSceneObjectGroup(RegionInfo.RegionSettings.TelehubObject); 3977 SceneObjectGroup telehub = GetSceneObjectGroup(RegionInfo.RegionSettings.TelehubObject);
3933 3978
@@ -3939,15 +3984,15 @@ namespace OpenSim.Region.Framework.Scenes
3939 { 3984 {
3940 // We have multiple SpawnPoints, Route the agent to a random or sequential one 3985 // We have multiple SpawnPoints, Route the agent to a random or sequential one
3941 if (SpawnPointRouting == "random") 3986 if (SpawnPointRouting == "random")
3942 acd.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count) - 1].GetLocation( 3987 acd.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count) - 1].GetLocation(
3943 telehub.AbsolutePosition, 3988 telehub.AbsolutePosition,
3944 telehub.GroupRotation 3989 telehub.GroupRotation
3945 ); 3990 );
3946 else 3991 else
3947 acd.startpos = spawnpoints[SpawnPoint()].GetLocation( 3992 acd.startpos = spawnpoints[SpawnPoint()].GetLocation(
3948 telehub.AbsolutePosition, 3993 telehub.AbsolutePosition,
3949 telehub.GroupRotation 3994 telehub.GroupRotation
3950 ); 3995 );
3951 } 3996 }
3952 else if (spawnpoints.Count == 1) 3997 else if (spawnpoints.Count == 1)
3953 { 3998 {
@@ -3957,15 +4002,15 @@ namespace OpenSim.Region.Framework.Scenes
3957 else 4002 else
3958 { 4003 {
3959 m_log.DebugFormat( 4004 m_log.DebugFormat(
3960 "[SCENE]: No spawnpoints defined for telehub {0} for {1} in {2}. Continuing.", 4005 "[SCENE]: No spawnpoints defined for telehub {0} for {1} in {2}. Continuing.",
3961 RegionInfo.RegionSettings.TelehubObject, acd.Name, Name); 4006 RegionInfo.RegionSettings.TelehubObject, acd.Name, Name);
3962 } 4007 }
3963 } 4008 }
3964 else 4009 else
3965 { 4010 {
3966 m_log.DebugFormat( 4011 m_log.DebugFormat(
3967 "[SCENE]: No telehub {0} found to direct {1} in {2}. Continuing.", 4012 "[SCENE]: No telehub {0} found to direct {1} in {2}. Continuing.",
3968 RegionInfo.RegionSettings.TelehubObject, acd.Name, Name); 4013 RegionInfo.RegionSettings.TelehubObject, acd.Name, Name);
3969 } 4014 }
3970 4015
3971 // Final permissions check; this time we don't allow changing the position 4016 // Final permissions check; this time we don't allow changing the position
@@ -4002,7 +4047,7 @@ namespace OpenSim.Region.Framework.Scenes
4002 { 4047 {
4003 ILandObject land = LandChannel.GetLandObject(pos); 4048 ILandObject land = LandChannel.GetLandObject(pos);
4004 if (land == null) 4049 if (land == null)
4005 return true; 4050 return true;
4006 4051
4007 if (land.IsBannedFromLand(agentID) || land.IsRestrictedFromLand(agentID)) 4052 if (land.IsBannedFromLand(agentID) || land.IsRestrictedFromLand(agentID))
4008 { 4053 {
@@ -4016,21 +4061,21 @@ namespace OpenSim.Region.Framework.Scenes
4016 public bool TestLandRestrictions(UUID agentID, out string reason, ref float posX, ref float posY) 4061 public bool TestLandRestrictions(UUID agentID, out string reason, ref float posX, ref float posY)
4017 { 4062 {
4018 if (posX < 0) 4063 if (posX < 0)
4019 posX = 0; 4064 posX = 0;
4020 else if (posX >= (float)RegionInfo.RegionSizeX) 4065 else if (posX >= (float)RegionInfo.RegionSizeX)
4021 posX = (float)RegionInfo.RegionSizeX - 0.001f; 4066 posX = (float)RegionInfo.RegionSizeX - 0.001f;
4022 if (posY < 0) 4067 if (posY < 0)
4023 posY = 0; 4068 posY = 0;
4024 else if (posY >= (float)RegionInfo.RegionSizeY) 4069 else if (posY >= (float)RegionInfo.RegionSizeY)
4025 posY = (float)RegionInfo.RegionSizeY - 0.001f; 4070 posY = (float)RegionInfo.RegionSizeY - 0.001f;
4026 4071
4027 reason = String.Empty; 4072 reason = String.Empty;
4028 if (Permissions.IsGod(agentID)) 4073 if (Permissions.IsGod(agentID))
4029 return true; 4074 return true;
4030 4075
4031 ILandObject land = LandChannel.GetLandObject(posX, posY); 4076 ILandObject land = LandChannel.GetLandObject(posX, posY);
4032 if (land == null) 4077 if (land == null)
4033 return false; 4078 return false;
4034 4079
4035 bool banned = land.IsBannedFromLand(agentID); 4080 bool banned = land.IsBannedFromLand(agentID);
4036 bool restricted = land.IsRestrictedFromLand(agentID); 4081 bool restricted = land.IsRestrictedFromLand(agentID);
@@ -4054,7 +4099,7 @@ namespace OpenSim.Region.Framework.Scenes
4054 else 4099 else
4055 { 4100 {
4056 reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.", 4101 reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.",
4057 RegionInfo.RegionName); 4102 RegionInfo.RegionName);
4058 } 4103 }
4059 return false; 4104 return false;
4060 } 4105 }
@@ -4105,15 +4150,15 @@ namespace OpenSim.Region.Framework.Scenes
4105 4150
4106 if (!m_strictAccessControl) return true; 4151 if (!m_strictAccessControl) return true;
4107 if (Permissions.IsGod(agent.AgentID)) return true; 4152 if (Permissions.IsGod(agent.AgentID)) return true;
4108 4153
4109 if (AuthorizationService != null) 4154 if (AuthorizationService != null)
4110 { 4155 {
4111 if (!AuthorizationService.IsAuthorizedForRegion( 4156 if (!AuthorizationService.IsAuthorizedForRegion(
4112 agent.AgentID.ToString(), agent.firstname, agent.lastname, RegionInfo.RegionID.ToString(), out reason)) 4157 agent.AgentID.ToString(), agent.firstname, agent.lastname, RegionInfo.RegionID.ToString(), out reason))
4113 { 4158 {
4114 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because: {4}", 4159 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because: {4}",
4115 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName, reason); 4160 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName, reason);
4116 4161
4117 return false; 4162 return false;
4118 } 4163 }
4119 } 4164 }
@@ -4129,9 +4174,9 @@ namespace OpenSim.Region.Framework.Scenes
4129 if (RegionInfo.EstateSettings.IsBanned(agent.AgentID)) 4174 if (RegionInfo.EstateSettings.IsBanned(agent.AgentID))
4130 { 4175 {
4131 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", 4176 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
4132 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 4177 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
4133 reason = String.Format("Denied access to region {0}: You have been banned from that region.", 4178 reason = String.Format("Denied access to region {0}: You have been banned from that region.",
4134 RegionInfo.RegionName); 4179 RegionInfo.RegionName);
4135 return false; 4180 return false;
4136 } 4181 }
4137 } 4182 }
@@ -4149,7 +4194,7 @@ namespace OpenSim.Region.Framework.Scenes
4149 if (GroupMembership != null) 4194 if (GroupMembership != null)
4150 { 4195 {
4151 for (int i = 0; i < GroupMembership.Length; i++) 4196 for (int i = 0; i < GroupMembership.Length; i++)
4152 agentGroups.Add(GroupMembership[i].GroupID); 4197 agentGroups.Add(GroupMembership[i].GroupID);
4153 } 4198 }
4154 else 4199 else
4155 { 4200 {
@@ -4177,13 +4222,13 @@ namespace OpenSim.Region.Framework.Scenes
4177 } 4222 }
4178 4223
4179 if (!RegionInfo.EstateSettings.PublicAccess && 4224 if (!RegionInfo.EstateSettings.PublicAccess &&
4180 !RegionInfo.EstateSettings.HasAccess(agent.AgentID) && 4225 !RegionInfo.EstateSettings.HasAccess(agent.AgentID) &&
4181 !groupAccess) 4226 !groupAccess)
4182 { 4227 {
4183 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the estate", 4228 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the estate",
4184 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 4229 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
4185 reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.", 4230 reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.",
4186 RegionInfo.RegionName); 4231 RegionInfo.RegionName);
4187 return false; 4232 return false;
4188 } 4233 }
4189 } 4234 }
@@ -4239,69 +4284,69 @@ namespace OpenSim.Region.Framework.Scenes
4239 return m_authenticateHandler.TryChangeCiruitCode(oldcc, newcc); 4284 return m_authenticateHandler.TryChangeCiruitCode(oldcc, newcc);
4240 } 4285 }
4241 4286
4242// /// <summary> 4287 // /// <summary>
4243// /// The Grid has requested that we log-off a user. Log them off. 4288 // /// The Grid has requested that we log-off a user. Log them off.
4244// /// </summary> 4289 // /// </summary>
4245// /// <param name="AvatarID">Unique ID of the avatar to log-off</param> 4290 // /// <param name="AvatarID">Unique ID of the avatar to log-off</param>
4246// /// <param name="RegionSecret">SecureSessionID of the user, or the RegionSecret text when logging on to the grid</param> 4291 // /// <param name="RegionSecret">SecureSessionID of the user, or the RegionSecret text when logging on to the grid</param>
4247// /// <param name="message">message to display to the user. Reason for being logged off</param> 4292 // /// <param name="message">message to display to the user. Reason for being logged off</param>
4248// public void HandleLogOffUserFromGrid(UUID AvatarID, UUID RegionSecret, string message) 4293 // public void HandleLogOffUserFromGrid(UUID AvatarID, UUID RegionSecret, string message)
4249// { 4294 // {
4250// ScenePresence loggingOffUser = GetScenePresence(AvatarID); 4295 // ScenePresence loggingOffUser = GetScenePresence(AvatarID);
4251// if (loggingOffUser != null) 4296 // if (loggingOffUser != null)
4252// { 4297 // {
4253// UUID localRegionSecret = UUID.Zero; 4298 // UUID localRegionSecret = UUID.Zero;
4254// bool parsedsecret = UUID.TryParse(RegionInfo.regionSecret, out localRegionSecret); 4299 // bool parsedsecret = UUID.TryParse(RegionInfo.regionSecret, out localRegionSecret);
4255// 4300 //
4256// // Region Secret is used here in case a new sessionid overwrites an old one on the user server. 4301 // // Region Secret is used here in case a new sessionid overwrites an old one on the user server.
4257// // Will update the user server in a few revisions to use it. 4302 // // Will update the user server in a few revisions to use it.
4258// 4303 //
4259// if (RegionSecret == loggingOffUser.ControllingClient.SecureSessionId || (parsedsecret && RegionSecret == localRegionSecret)) 4304 // if (RegionSecret == loggingOffUser.ControllingClient.SecureSessionId || (parsedsecret && RegionSecret == localRegionSecret))
4260// { 4305 // {
4261// m_sceneGridService.SendCloseChildAgentConnections(loggingOffUser.UUID, loggingOffUser.KnownRegionHandles); 4306 // m_sceneGridService.SendCloseChildAgentConnections(loggingOffUser.UUID, loggingOffUser.KnownRegionHandles);
4262// loggingOffUser.ControllingClient.Kick(message); 4307 // loggingOffUser.ControllingClient.Kick(message);
4263// // Give them a second to receive the message! 4308 // // Give them a second to receive the message!
4264// Thread.Sleep(1000); 4309 // Thread.Sleep(1000);
4265// loggingOffUser.ControllingClient.Close(); 4310 // loggingOffUser.ControllingClient.Close();
4266// } 4311 // }
4267// else 4312 // else
4268// { 4313 // {
4269// m_log.Info("[USERLOGOFF]: System sending the LogOff user message failed to sucessfully authenticate"); 4314 // m_log.Info("[USERLOGOFF]: System sending the LogOff user message failed to sucessfully authenticate");
4270// } 4315 // }
4271// } 4316 // }
4272// else 4317 // else
4273// { 4318 // {
4274// m_log.InfoFormat("[USERLOGOFF]: Got a logoff request for {0} but the user isn't here. The user might already have been logged out", AvatarID.ToString()); 4319 // m_log.InfoFormat("[USERLOGOFF]: Got a logoff request for {0} but the user isn't here. The user might already have been logged out", AvatarID.ToString());
4275// } 4320 // }
4276// } 4321 // }
4277 4322
4278// /// <summary> 4323 // /// <summary>
4279// /// Triggered when an agent crosses into this sim. Also happens on initial login. 4324 // /// Triggered when an agent crosses into this sim. Also happens on initial login.
4280// /// </summary> 4325 // /// </summary>
4281// /// <param name="agentID"></param> 4326 // /// <param name="agentID"></param>
4282// /// <param name="position"></param> 4327 // /// <param name="position"></param>
4283// /// <param name="isFlying"></param> 4328 // /// <param name="isFlying"></param>
4284// public virtual void AgentCrossing(UUID agentID, Vector3 position, bool isFlying) 4329 // public virtual void AgentCrossing(UUID agentID, Vector3 position, bool isFlying)
4285// { 4330 // {
4286// ScenePresence presence = GetScenePresence(agentID); 4331 // ScenePresence presence = GetScenePresence(agentID);
4287// if (presence != null) 4332 // if (presence != null)
4288// { 4333 // {
4289// try 4334 // try
4290// { 4335 // {
4291// presence.MakeRootAgent(position, isFlying); 4336 // presence.MakeRootAgent(position, isFlying);
4292// } 4337 // }
4293// catch (Exception e) 4338 // catch (Exception e)
4294// { 4339 // {
4295// m_log.ErrorFormat("[SCENE]: Unable to do agent crossing, exception {0}{1}", e.Message, e.StackTrace); 4340 // m_log.ErrorFormat("[SCENE]: Unable to do agent crossing, exception {0}{1}", e.Message, e.StackTrace);
4296// } 4341 // }
4297// } 4342 // }
4298// else 4343 // else
4299// { 4344 // {
4300// m_log.ErrorFormat( 4345 // m_log.ErrorFormat(
4301// "[SCENE]: Could not find presence for agent {0} crossing into scene {1}", 4346 // "[SCENE]: Could not find presence for agent {0} crossing into scene {1}",
4302// agentID, RegionInfo.RegionName); 4347 // agentID, RegionInfo.RegionName);
4303// } 4348 // }
4304// } 4349 // }
4305 4350
4306 /// <summary> 4351 /// <summary>
4307 /// We've got an update about an agent that sees into this region, 4352 /// We've got an update about an agent that sees into this region,
@@ -4313,15 +4358,15 @@ namespace OpenSim.Region.Framework.Scenes
4313 public virtual bool IncomingUpdateChildAgent(AgentData cAgentData) 4358 public virtual bool IncomingUpdateChildAgent(AgentData cAgentData)
4314 { 4359 {
4315 m_log.DebugFormat( 4360 m_log.DebugFormat(
4316 "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName); 4361 "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName);
4317 4362
4318 // TODO: This check should probably be in QueryAccess(). 4363 // TODO: This check should probably be in QueryAccess().
4319 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, RegionInfo.RegionSizeX / 2, RegionInfo.RegionSizeY / 2); 4364 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, RegionInfo.RegionSizeX / 2, RegionInfo.RegionSizeY / 2);
4320 if (nearestParcel == null) 4365 if (nearestParcel == null)
4321 { 4366 {
4322 m_log.InfoFormat( 4367 m_log.InfoFormat(
4323 "[SCENE]: Denying root agent entry to {0} in {1}: no allowed parcel", 4368 "[SCENE]: Denying root agent entry to {0} in {1}: no allowed parcel",
4324 cAgentData.AgentID, RegionInfo.RegionName); 4369 cAgentData.AgentID, RegionInfo.RegionName);
4325 4370
4326 return false; 4371 return false;
4327 } 4372 }
@@ -4337,11 +4382,11 @@ namespace OpenSim.Region.Framework.Scenes
4337 if (cAgentData.SessionID != sp.ControllingClient.SessionId) 4382 if (cAgentData.SessionID != sp.ControllingClient.SessionId)
4338 { 4383 {
4339 m_log.WarnFormat( 4384 m_log.WarnFormat(
4340 "[SCENE]: Attempt to update agent {0} with invalid session id {1} (possibly from simulator in older version; tell them to update).", 4385 "[SCENE]: Attempt to update agent {0} with invalid session id {1} (possibly from simulator in older version; tell them to update).",
4341 sp.UUID, cAgentData.SessionID); 4386 sp.UUID, cAgentData.SessionID);
4342 4387
4343 Console.WriteLine(String.Format("[SCENE]: Attempt to update agent {0} ({1}) with invalid session id {2}", 4388 Console.WriteLine(String.Format("[SCENE]: Attempt to update agent {0} ({1}) with invalid session id {2}",
4344 sp.UUID, sp.ControllingClient.SessionId, cAgentData.SessionID)); 4389 sp.UUID, sp.ControllingClient.SessionId, cAgentData.SessionID));
4345 } 4390 }
4346 4391
4347 sp.UpdateChildAgent(cAgentData); 4392 sp.UpdateChildAgent(cAgentData);
@@ -4350,19 +4395,19 @@ namespace OpenSim.Region.Framework.Scenes
4350 if (cAgentData.SenderWantsToWaitForRoot) 4395 if (cAgentData.SenderWantsToWaitForRoot)
4351 { 4396 {
4352 while (sp.IsChildAgent && ntimes-- > 0) 4397 while (sp.IsChildAgent && ntimes-- > 0)
4353 Thread.Sleep(1000); 4398 Thread.Sleep(1000);
4354 4399
4355 if (sp.IsChildAgent) 4400 if (sp.IsChildAgent)
4356 m_log.WarnFormat( 4401 m_log.WarnFormat(
4357 "[SCENE]: Found presence {0} {1} unexpectedly still child in {2}", 4402 "[SCENE]: Found presence {0} {1} unexpectedly still child in {2}",
4358 sp.Name, sp.UUID, Name); 4403 sp.Name, sp.UUID, Name);
4359 else 4404 else
4360 m_log.InfoFormat( 4405 m_log.InfoFormat(
4361 "[SCENE]: Found presence {0} {1} as root in {2} after {3} waits", 4406 "[SCENE]: Found presence {0} {1} as root in {2} after {3} waits",
4362 sp.Name, sp.UUID, Name, 20 - ntimes); 4407 sp.Name, sp.UUID, Name, 20 - ntimes);
4363 4408
4364 if (sp.IsChildAgent) 4409 if (sp.IsChildAgent)
4365 return false; 4410 return false;
4366 } 4411 }
4367 4412
4368 return true; 4413 return true;
@@ -4379,17 +4424,17 @@ namespace OpenSim.Region.Framework.Scenes
4379 /// <returns>true if we handled it.</returns> 4424 /// <returns>true if we handled it.</returns>
4380 public virtual bool IncomingUpdateChildAgent(AgentPosition cAgentData) 4425 public virtual bool IncomingUpdateChildAgent(AgentPosition cAgentData)
4381 { 4426 {
4382// m_log.DebugFormat( 4427 // m_log.DebugFormat(
4383// "[SCENE PRESENCE]: IncomingChildAgentDataUpdate POSITION for {0} in {1}, position {2}", 4428 // "[SCENE PRESENCE]: IncomingChildAgentDataUpdate POSITION for {0} in {1}, position {2}",
4384// cAgentData.AgentID, Name, cAgentData.Position); 4429 // cAgentData.AgentID, Name, cAgentData.Position);
4385 4430
4386 ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID); 4431 ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID);
4387 if (childAgentUpdate != null) 4432 if (childAgentUpdate != null)
4388 { 4433 {
4389// if (childAgentUpdate.ControllingClient.SessionId != cAgentData.SessionID) 4434 // if (childAgentUpdate.ControllingClient.SessionId != cAgentData.SessionID)
4390// // Only warn for now 4435 // // Only warn for now
4391// m_log.WarnFormat("[SCENE]: Attempt at updating position of agent {0} with invalid session id {1}. Neighbor running older version?", 4436 // m_log.WarnFormat("[SCENE]: Attempt at updating position of agent {0} with invalid session id {1}. Neighbor running older version?",
4392// childAgentUpdate.UUID, cAgentData.SessionID); 4437 // childAgentUpdate.UUID, cAgentData.SessionID);
4393 4438
4394 // I can't imagine *yet* why we would get an update if the agent is a root agent.. 4439 // I can't imagine *yet* why we would get an update if the agent is a root agent..
4395 // however to avoid a race condition crossing borders.. 4440 // however to avoid a race condition crossing borders..
@@ -4421,12 +4466,12 @@ namespace OpenSim.Region.Framework.Scenes
4421 int ntimes = 20; 4466 int ntimes = 20;
4422 ScenePresence sp = null; 4467 ScenePresence sp = null;
4423 while ((sp = GetScenePresence(agentID)) == null && (ntimes-- > 0)) 4468 while ((sp = GetScenePresence(agentID)) == null && (ntimes-- > 0))
4424 Thread.Sleep(1000); 4469 Thread.Sleep(1000);
4425 4470
4426 if (sp == null) 4471 if (sp == null)
4427 m_log.WarnFormat( 4472 m_log.WarnFormat(
4428 "[SCENE PRESENCE]: Did not find presence with id {0} in {1} before timeout", 4473 "[SCENE PRESENCE]: Did not find presence with id {0} in {1} before timeout",
4429 agentID, RegionInfo.RegionName); 4474 agentID, RegionInfo.RegionName);
4430 4475
4431 return sp; 4476 return sp;
4432 } 4477 }
@@ -4448,8 +4493,8 @@ namespace OpenSim.Region.Framework.Scenes
4448 if (acd == null) 4493 if (acd == null)
4449 { 4494 {
4450 m_log.DebugFormat( 4495 m_log.DebugFormat(
4451 "[SCENE]: Request to close agent {0} but no such agent in scene {1}. May have been closed previously.", 4496 "[SCENE]: Request to close agent {0} but no such agent in scene {1}. May have been closed previously.",
4452 agentID, Name); 4497 agentID, Name);
4453 4498
4454 return false; 4499 return false;
4455 } 4500 }
@@ -4461,8 +4506,8 @@ namespace OpenSim.Region.Framework.Scenes
4461 else 4506 else
4462 { 4507 {
4463 m_log.WarnFormat( 4508 m_log.WarnFormat(
4464 "[SCENE]: Request to close agent {0} with invalid authorization token {1} in {2}", 4509 "[SCENE]: Request to close agent {0} with invalid authorization token {1} in {2}",
4465 agentID, auth_token, Name); 4510 agentID, auth_token, Name);
4466 } 4511 }
4467 4512
4468 return false; 4513 return false;
@@ -4488,8 +4533,8 @@ namespace OpenSim.Region.Framework.Scenes
4488 if (sp.DoNotCloseAfterTeleport) 4533 if (sp.DoNotCloseAfterTeleport)
4489 { 4534 {
4490 m_log.DebugFormat( 4535 m_log.DebugFormat(
4491 "[SCENE]: Not pre-closing {0} agent {1} in {2} since another simulator has re-established the child connection", 4536 "[SCENE]: Not pre-closing {0} agent {1} in {2} since another simulator has re-established the child connection",
4492 sp.IsChildAgent ? "child" : "root", sp.Name, Name); 4537 sp.IsChildAgent ? "child" : "root", sp.Name, Name);
4493 4538
4494 // Need to reset the flag so that a subsequent close after another teleport can succeed. 4539 // Need to reset the flag so that a subsequent close after another teleport can succeed.
4495 sp.DoNotCloseAfterTeleport = false; 4540 sp.DoNotCloseAfterTeleport = false;
@@ -4500,8 +4545,8 @@ namespace OpenSim.Region.Framework.Scenes
4500 if (sp.LifecycleState != ScenePresenceState.Running) 4545 if (sp.LifecycleState != ScenePresenceState.Running)
4501 { 4546 {
4502 m_log.DebugFormat( 4547 m_log.DebugFormat(
4503 "[SCENE]: Called IncomingPreCloseAgent() for {0} in {1} but presence is already in state {2}", 4548 "[SCENE]: Called IncomingPreCloseAgent() for {0} in {1} but presence is already in state {2}",
4504 sp.Name, Name, sp.LifecycleState); 4549 sp.Name, Name, sp.LifecycleState);
4505 4550
4506 return false; 4551 return false;
4507 } 4552 }
@@ -4527,21 +4572,21 @@ namespace OpenSim.Region.Framework.Scenes
4527 lock (m_removeClientLock) 4572 lock (m_removeClientLock)
4528 { 4573 {
4529 sp = GetScenePresence(agentID); 4574 sp = GetScenePresence(agentID);
4530 4575
4531 if (sp == null) 4576 if (sp == null)
4532 { 4577 {
4533 m_log.DebugFormat( 4578 m_log.DebugFormat(
4534 "[SCENE]: Called CloseClient() with agent ID {0} but no such presence is in {1}", 4579 "[SCENE]: Called CloseClient() with agent ID {0} but no such presence is in {1}",
4535 agentID, Name); 4580 agentID, Name);
4536 4581
4537 return false; 4582 return false;
4538 } 4583 }
4539 4584
4540 if (sp.LifecycleState != ScenePresenceState.Running && sp.LifecycleState != ScenePresenceState.PreRemove) 4585 if (sp.LifecycleState != ScenePresenceState.Running && sp.LifecycleState != ScenePresenceState.PreRemove)
4541 { 4586 {
4542 m_log.DebugFormat( 4587 m_log.DebugFormat(
4543 "[SCENE]: Called CloseClient() for {0} in {1} but presence is already in state {2}", 4588 "[SCENE]: Called CloseClient() for {0} in {1} but presence is already in state {2}",
4544 sp.Name, Name, sp.LifecycleState); 4589 sp.Name, Name, sp.LifecycleState);
4545 4590
4546 return false; 4591 return false;
4547 } 4592 }
@@ -4552,8 +4597,8 @@ namespace OpenSim.Region.Framework.Scenes
4552 if (sp.DoNotCloseAfterTeleport) 4597 if (sp.DoNotCloseAfterTeleport)
4553 { 4598 {
4554 m_log.DebugFormat( 4599 m_log.DebugFormat(
4555 "[SCENE]: Not closing {0} agent {1} in {2} since another simulator has re-established the child connection", 4600 "[SCENE]: Not closing {0} agent {1} in {2} since another simulator has re-established the child connection",
4556 sp.IsChildAgent ? "child" : "root", sp.Name, Name); 4601 sp.IsChildAgent ? "child" : "root", sp.Name, Name);
4557 4602
4558 // Need to reset the flag so that a subsequent close after another teleport can succeed. 4603 // Need to reset the flag so that a subsequent close after another teleport can succeed.
4559 sp.DoNotCloseAfterTeleport = false; 4604 sp.DoNotCloseAfterTeleport = false;
@@ -4581,7 +4626,7 @@ namespace OpenSim.Region.Framework.Scenes
4581 /// <param name="lookAt"></param> 4626 /// <param name="lookAt"></param>
4582 /// <param name="teleportFlags"></param> 4627 /// <param name="teleportFlags"></param>
4583 public void RequestTeleportLocation(IClientAPI remoteClient, string regionName, Vector3 position, 4628 public void RequestTeleportLocation(IClientAPI remoteClient, string regionName, Vector3 position,
4584 Vector3 lookat, uint teleportFlags) 4629 Vector3 lookat, uint teleportFlags)
4585 { 4630 {
4586 GridRegion region = GridService.GetRegionByName(RegionInfo.ScopeID, regionName); 4631 GridRegion region = GridService.GetRegionByName(RegionInfo.ScopeID, regionName);
4587 4632
@@ -4604,7 +4649,7 @@ namespace OpenSim.Region.Framework.Scenes
4604 /// <param name="lookAt"></param> 4649 /// <param name="lookAt"></param>
4605 /// <param name="teleportFlags"></param> 4650 /// <param name="teleportFlags"></param>
4606 public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position, 4651 public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position,
4607 Vector3 lookAt, uint teleportFlags) 4652 Vector3 lookAt, uint teleportFlags)
4608 { 4653 {
4609 ScenePresence sp = GetScenePresence(remoteClient.AgentId); 4654 ScenePresence sp = GetScenePresence(remoteClient.AgentId);
4610 if (sp != null) 4655 if (sp != null)
@@ -4703,8 +4748,8 @@ namespace OpenSim.Region.Framework.Scenes
4703 if (part.Name == cmdparams[2]) 4748 if (part.Name == cmdparams[2])
4704 { 4749 {
4705 part.Resize( 4750 part.Resize(
4706 new Vector3(Convert.ToSingle(cmdparams[3]), Convert.ToSingle(cmdparams[4]), 4751 new Vector3(Convert.ToSingle(cmdparams[3]), Convert.ToSingle(cmdparams[4]),
4707 Convert.ToSingle(cmdparams[5]))); 4752 Convert.ToSingle(cmdparams[5])));
4708 4753
4709 m_log.DebugFormat("Edited scale of Primitive: {0}", part.Name); 4754 m_log.DebugFormat("Edited scale of Primitive: {0}", part.Name);
4710 } 4755 }
@@ -4749,7 +4794,7 @@ namespace OpenSim.Region.Framework.Scenes
4749 4794
4750 #region Script Engine 4795 #region Script Engine
4751 4796
4752 private bool ScriptDanger(SceneObjectPart part,Vector3 pos) 4797 private bool ScriptDanger(SceneObjectPart part, Vector3 pos)
4753 { 4798 {
4754 ILandObject parcel = LandChannel.GetLandObject(pos.X, pos.Y); 4799 ILandObject parcel = LandChannel.GetLandObject(pos.X, pos.Y);
4755 if (part != null) 4800 if (part != null)
@@ -4765,7 +4810,7 @@ namespace OpenSim.Region.Framework.Scenes
4765 return true; 4810 return true;
4766 } 4811 }
4767 else if (((parcel.LandData.Flags & (uint)ParcelFlags.AllowGroupScripts) != 0) 4812 else if (((parcel.LandData.Flags & (uint)ParcelFlags.AllowGroupScripts) != 0)
4768 && (parcel.LandData.GroupID != UUID.Zero) && (parcel.LandData.GroupID == part.GroupID)) 4813 && (parcel.LandData.GroupID != UUID.Zero) && (parcel.LandData.GroupID == part.GroupID))
4769 { 4814 {
4770 return true; 4815 return true;
4771 } 4816 }
@@ -5107,15 +5152,15 @@ namespace OpenSim.Region.Framework.Scenes
5107 #endregion 5152 #endregion
5108 5153
5109 5154
5110// Commented pending deletion since this method no longer appears to do anything at all 5155 // Commented pending deletion since this method no longer appears to do anything at all
5111// public bool NeedSceneCacheClear(UUID agentID) 5156 // public bool NeedSceneCacheClear(UUID agentID)
5112// { 5157 // {
5113// IInventoryTransferModule inv = RequestModuleInterface<IInventoryTransferModule>(); 5158 // IInventoryTransferModule inv = RequestModuleInterface<IInventoryTransferModule>();
5114// if (inv == null) 5159 // if (inv == null)
5115// return true; 5160 // return true;
5116// 5161 //
5117// return inv.NeedSceneCacheClear(agentID, this); 5162 // return inv.NeedSceneCacheClear(agentID, this);
5118// } 5163 // }
5119 5164
5120 public void CleanTempObjects() 5165 public void CleanTempObjects()
5121 { 5166 {
@@ -5131,7 +5176,7 @@ namespace OpenSim.Region.Framework.Scenes
5131 if ((grp.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) 5176 if ((grp.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
5132 { 5177 {
5133 if (grp.RootPart.Expires <= DateTime.Now) 5178 if (grp.RootPart.Expires <= DateTime.Now)
5134 DeleteSceneObject(grp, false); 5179 DeleteSceneObject(grp, false);
5135 } 5180 }
5136 } 5181 }
5137 } 5182 }
@@ -5157,21 +5202,21 @@ namespace OpenSim.Region.Framework.Scenes
5157 // 3 = We have seen a new user enter within the past 4 minutes 5202 // 3 = We have seen a new user enter within the past 4 minutes
5158 // which can be seen as positive confirmation of sim health 5203 // which can be seen as positive confirmation of sim health
5159 // 5204 //
5160 int health=1; // Start at 1, means we're up 5205 int health = 1; // Start at 1, means we're up
5161 5206
5162 if ((Util.EnvironmentTickCountSubtract(m_lastFrameTick)) < 1000) 5207 if ((Util.EnvironmentTickCountSubtract(m_lastFrameTick)) < 1000)
5163 health += 1; 5208 health += 1;
5164 else 5209 else
5165 return health; 5210 return health;
5166 5211
5167 // A login in the last 4 mins? We can't be doing too badly 5212 // A login in the last 4 mins? We can't be doing too badly
5168 // 5213 //
5169 if ((Util.EnvironmentTickCountSubtract(m_LastLogin)) < 240000) 5214 if ((Util.EnvironmentTickCountSubtract(m_LastLogin)) < 240000)
5170 health++; 5215 health++;
5171 else 5216 else
5172 return health; 5217 return health;
5173 5218
5174// CheckHeartbeat(); 5219 // CheckHeartbeat();
5175 5220
5176 return health; 5221 return health;
5177 } 5222 }
@@ -5201,41 +5246,41 @@ namespace OpenSim.Region.Framework.Scenes
5201 jointProxyObject.AngularVelocity = trackedBody.AngularVelocity; 5246 jointProxyObject.AngularVelocity = trackedBody.AngularVelocity;
5202 switch (joint.Type) 5247 switch (joint.Type)
5203 { 5248 {
5204 case PhysicsJointType.Ball: 5249 case PhysicsJointType.Ball:
5205 { 5250 {
5206 Vector3 jointAnchor = PhysicsScene.GetJointAnchor(joint); 5251 Vector3 jointAnchor = PhysicsScene.GetJointAnchor(joint);
5207 Vector3 proxyPos = jointAnchor; 5252 Vector3 proxyPos = jointAnchor;
5208 jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update 5253 jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update
5209 } 5254 }
5210 break; 5255 break;
5211 5256
5212 case PhysicsJointType.Hinge: 5257 case PhysicsJointType.Hinge:
5213 { 5258 {
5214 Vector3 jointAnchor = PhysicsScene.GetJointAnchor(joint); 5259 Vector3 jointAnchor = PhysicsScene.GetJointAnchor(joint);
5215 5260
5216 // Normally, we would just ask the physics scene to return the axis for the joint. 5261 // Normally, we would just ask the physics scene to return the axis for the joint.
5217 // Unfortunately, ODE sometimes returns <0,0,0> for the joint axis, which should 5262 // Unfortunately, ODE sometimes returns <0,0,0> for the joint axis, which should
5218 // never occur. Therefore we cannot rely on ODE to always return a correct joint axis. 5263 // never occur. Therefore we cannot rely on ODE to always return a correct joint axis.
5219 // Therefore the following call does not always work: 5264 // Therefore the following call does not always work:
5220 //PhysicsVector phyJointAxis = _PhyScene.GetJointAxis(joint); 5265 //PhysicsVector phyJointAxis = _PhyScene.GetJointAxis(joint);
5221 5266
5222 // instead we compute the joint orientation by saving the original joint orientation 5267 // instead we compute the joint orientation by saving the original joint orientation
5223 // relative to one of the jointed bodies, and applying this transformation 5268 // relative to one of the jointed bodies, and applying this transformation
5224 // to the current position of the jointed bodies (the tracked body) to compute the 5269 // to the current position of the jointed bodies (the tracked body) to compute the
5225 // current joint orientation. 5270 // current joint orientation.
5226 5271
5227 if (joint.TrackedBodyName == null) 5272 if (joint.TrackedBodyName == null)
5228 { 5273 {
5229 jointErrorMessage(joint, "joint.TrackedBodyName is null, joint " + joint.ObjectNameInScene); 5274 jointErrorMessage(joint, "joint.TrackedBodyName is null, joint " + joint.ObjectNameInScene);
5230 } 5275 }
5231 5276
5232 Vector3 proxyPos = jointAnchor; 5277 Vector3 proxyPos = jointAnchor;
5233 Quaternion q = trackedBody.RotationOffset * joint.LocalRotation; 5278 Quaternion q = trackedBody.RotationOffset * joint.LocalRotation;
5234 5279
5235 jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update 5280 jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update
5236 jointProxyObject.ParentGroup.UpdateGroupRotationR(q); // schedules the entire group for a terse update 5281 jointProxyObject.ParentGroup.UpdateGroupRotationR(q); // schedules the entire group for a terse update
5237 } 5282 }
5238 break; 5283 break;
5239 } 5284 }
5240 } 5285 }
5241 5286
@@ -5276,30 +5321,30 @@ namespace OpenSim.Region.Framework.Scenes
5276 if (joint != null) 5321 if (joint != null)
5277 { 5322 {
5278 if (joint.ErrorMessageCount > PhysicsJoint.maxErrorMessages) 5323 if (joint.ErrorMessageCount > PhysicsJoint.maxErrorMessages)
5279 return; 5324 return;
5280 5325
5281 SceneObjectPart jointProxyObject = GetSceneObjectPart(joint.ObjectNameInScene); 5326 SceneObjectPart jointProxyObject = GetSceneObjectPart(joint.ObjectNameInScene);
5282 if (jointProxyObject != null) 5327 if (jointProxyObject != null)
5283 { 5328 {
5284 SimChat(Utils.StringToBytes("[NINJA]: " + message), 5329 SimChat(Utils.StringToBytes("[NINJA]: " + message),
5285 ChatTypeEnum.DebugChannel, 5330 ChatTypeEnum.DebugChannel,
5286 2147483647, 5331 2147483647,
5287 jointProxyObject.AbsolutePosition, 5332 jointProxyObject.AbsolutePosition,
5288 jointProxyObject.Name, 5333 jointProxyObject.Name,
5289 jointProxyObject.UUID, 5334 jointProxyObject.UUID,
5290 false); 5335 false);
5291 5336
5292 joint.ErrorMessageCount++; 5337 joint.ErrorMessageCount++;
5293 5338
5294 if (joint.ErrorMessageCount > PhysicsJoint.maxErrorMessages) 5339 if (joint.ErrorMessageCount > PhysicsJoint.maxErrorMessages)
5295 { 5340 {
5296 SimChat(Utils.StringToBytes("[NINJA]: Too many messages for this joint, suppressing further messages."), 5341 SimChat(Utils.StringToBytes("[NINJA]: Too many messages for this joint, suppressing further messages."),
5297 ChatTypeEnum.DebugChannel, 5342 ChatTypeEnum.DebugChannel,
5298 2147483647, 5343 2147483647,
5299 jointProxyObject.AbsolutePosition, 5344 jointProxyObject.AbsolutePosition,
5300 jointProxyObject.Name, 5345 jointProxyObject.Name,
5301 jointProxyObject.UUID, 5346 jointProxyObject.UUID,
5302 false); 5347 false);
5303 } 5348 }
5304 } 5349 }
5305 else 5350 else
@@ -5312,9 +5357,9 @@ namespace OpenSim.Region.Framework.Scenes
5312 public Scene ConsoleScene() 5357 public Scene ConsoleScene()
5313 { 5358 {
5314 if (MainConsole.Instance == null) 5359 if (MainConsole.Instance == null)
5315 return null; 5360 return null;
5316 if (MainConsole.Instance.ConsoleScene is Scene) 5361 if (MainConsole.Instance.ConsoleScene is Scene)
5317 return (Scene)MainConsole.Instance.ConsoleScene; 5362 return (Scene)MainConsole.Instance.ConsoleScene;
5318 return null; 5363 return null;
5319 } 5364 }
5320 5365
@@ -5325,13 +5370,13 @@ namespace OpenSim.Region.Framework.Scenes
5325 public float GetGroundHeight(float x, float y) 5370 public float GetGroundHeight(float x, float y)
5326 { 5371 {
5327 if (x < 0) 5372 if (x < 0)
5328 x = 0; 5373 x = 0;
5329 if (x >= Heightmap.Width) 5374 if (x >= Heightmap.Width)
5330 x = Heightmap.Width - 1; 5375 x = Heightmap.Width - 1;
5331 if (y < 0) 5376 if (y < 0)
5332 y = 0; 5377 y = 0;
5333 if (y >= Heightmap.Height) 5378 if (y >= Heightmap.Height)
5334 y = Heightmap.Height - 1; 5379 y = Heightmap.Height - 1;
5335 5380
5336 Vector3 p0 = new Vector3(x, y, (float)Heightmap[(int)x, (int)y]); 5381 Vector3 p0 = new Vector3(x, y, (float)Heightmap[(int)x, (int)y]);
5337 Vector3 p1 = p0; 5382 Vector3 p1 = p0;
@@ -5339,11 +5384,11 @@ namespace OpenSim.Region.Framework.Scenes
5339 5384
5340 p1.X += 1.0f; 5385 p1.X += 1.0f;
5341 if (p1.X < Heightmap.Width) 5386 if (p1.X < Heightmap.Width)
5342 p1.Z = (float)Heightmap[(int)p1.X, (int)p1.Y]; 5387 p1.Z = (float)Heightmap[(int)p1.X, (int)p1.Y];
5343 5388
5344 p2.Y += 1.0f; 5389 p2.Y += 1.0f;
5345 if (p2.Y < Heightmap.Height) 5390 if (p2.Y < Heightmap.Height)
5346 p2.Z = (float)Heightmap[(int)p2.X, (int)p2.Y]; 5391 p2.Z = (float)Heightmap[(int)p2.X, (int)p2.Y];
5347 5392
5348 Vector3 v0 = new Vector3(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z); 5393 Vector3 v0 = new Vector3(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z);
5349 Vector3 v1 = new Vector3(p2.X - p0.X, p2.Y - p0.Y, p2.Z - p0.Z); 5394 Vector3 v1 = new Vector3(p2.X - p0.X, p2.Y - p0.Y, p2.Z - p0.Z);
@@ -5363,14 +5408,14 @@ namespace OpenSim.Region.Framework.Scenes
5363 return (((vsn.X * xdiff) + (vsn.Y * ydiff)) / (-1 * vsn.Z)) + p0.Z; 5408 return (((vsn.X * xdiff) + (vsn.Y * ydiff)) / (-1 * vsn.Z)) + p0.Z;
5364 } 5409 }
5365 5410
5366// private void CheckHeartbeat() 5411 // private void CheckHeartbeat()
5367// { 5412 // {
5368// if (m_firstHeartbeat) 5413 // if (m_firstHeartbeat)
5369// return; 5414 // return;
5370// 5415 //
5371// if (Util.EnvironmentTickCountSubtract(m_lastFrameTick) > 2000) 5416 // if (Util.EnvironmentTickCountSubtract(m_lastFrameTick) > 2000)
5372// StartTimer(); 5417 // StartTimer();
5373// } 5418 // }
5374 5419
5375 public override ISceneObject DeserializeObject(string representation) 5420 public override ISceneObject DeserializeObject(string representation)
5376 { 5421 {
@@ -5413,7 +5458,7 @@ namespace OpenSim.Region.Framework.Scenes
5413 } 5458 }
5414 5459
5415 ILandObject dest = LandChannel.GetLandObject(avatar.lastKnownAllowedPosition.X, avatar.lastKnownAllowedPosition.Y); 5460 ILandObject dest = LandChannel.GetLandObject(avatar.lastKnownAllowedPosition.X, avatar.lastKnownAllowedPosition.Y);
5416 if (dest != excludeParcel) 5461 if (dest != excludeParcel)
5417 { 5462 {
5418 // Ultimate backup if we have no idea where they are and 5463 // Ultimate backup if we have no idea where they are and
5419 // the last allowed position was in another parcel 5464 // the last allowed position was in another parcel
@@ -5523,9 +5568,9 @@ namespace OpenSim.Region.Framework.Scenes
5523 private Vector3 GetNearestRegionEdgePosition(ScenePresence avatar) 5568 private Vector3 GetNearestRegionEdgePosition(ScenePresence avatar)
5524 { 5569 {
5525 float xdistance = avatar.AbsolutePosition.X < RegionInfo.RegionSizeX / 2 5570 float xdistance = avatar.AbsolutePosition.X < RegionInfo.RegionSizeX / 2
5526 ? avatar.AbsolutePosition.X : RegionInfo.RegionSizeX - avatar.AbsolutePosition.X; 5571 ? avatar.AbsolutePosition.X : RegionInfo.RegionSizeX - avatar.AbsolutePosition.X;
5527 float ydistance = avatar.AbsolutePosition.Y < RegionInfo.RegionSizeY / 2 5572 float ydistance = avatar.AbsolutePosition.Y < RegionInfo.RegionSizeY / 2
5528 ? avatar.AbsolutePosition.Y : RegionInfo.RegionSizeY - avatar.AbsolutePosition.Y; 5573 ? avatar.AbsolutePosition.Y : RegionInfo.RegionSizeY - avatar.AbsolutePosition.Y;
5529 5574
5530 //find out what vertical edge to go to 5575 //find out what vertical edge to go to
5531 if (xdistance < ydistance) 5576 if (xdistance < ydistance)
@@ -5572,7 +5617,7 @@ namespace OpenSim.Region.Framework.Scenes
5572 { 5617 {
5573 IEstateDataService estateDataService = EstateDataService; 5618 IEstateDataService estateDataService = EstateDataService;
5574 if (estateDataService == null) 5619 if (estateDataService == null)
5575 return new List<UUID>(0); 5620 return new List<UUID>(0);
5576 5621
5577 return estateDataService.GetRegions(estateID); 5622 return estateDataService.GetRegions(estateID);
5578 } 5623 }
@@ -5595,8 +5640,8 @@ namespace OpenSim.Region.Framework.Scenes
5595 private void HandleReloadEstate(string module, string[] cmd) 5640 private void HandleReloadEstate(string module, string[] cmd)
5596 { 5641 {
5597 if (MainConsole.Instance.ConsoleScene == null || 5642 if (MainConsole.Instance.ConsoleScene == null ||
5598 (MainConsole.Instance.ConsoleScene is Scene && 5643 (MainConsole.Instance.ConsoleScene is Scene &&
5599 (Scene)MainConsole.Instance.ConsoleScene == this)) 5644 (Scene)MainConsole.Instance.ConsoleScene == this))
5600 { 5645 {
5601 ReloadEstateData(); 5646 ReloadEstateData();
5602 } 5647 }
@@ -5614,8 +5659,8 @@ namespace OpenSim.Region.Framework.Scenes
5614 /// <param name="maxZ"></param> 5659 /// <param name="maxZ"></param>
5615 /// <returns></returns> 5660 /// <returns></returns>
5616 public static Vector3[] GetCombinedBoundingBox( 5661 public static Vector3[] GetCombinedBoundingBox(
5617 List<SceneObjectGroup> objects, 5662 List<SceneObjectGroup> objects,
5618 out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ) 5663 out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ)
5619 { 5664 {
5620 minX = float.MaxValue; 5665 minX = float.MaxValue;
5621 maxX = float.MinValue; 5666 maxX = float.MinValue;
@@ -5633,10 +5678,10 @@ namespace OpenSim.Region.Framework.Scenes
5633 Vector3 vec = g.AbsolutePosition; 5678 Vector3 vec = g.AbsolutePosition;
5634 5679
5635 g.GetAxisAlignedBoundingBoxRaw(out ominX, out omaxX, out ominY, out omaxY, out ominZ, out omaxZ); 5680 g.GetAxisAlignedBoundingBoxRaw(out ominX, out omaxX, out ominY, out omaxY, out ominZ, out omaxZ);
5636 5681
5637// m_log.DebugFormat( 5682 // m_log.DebugFormat(
5638// "[SCENE]: For {0} found AxisAlignedBoundingBoxRaw {1}, {2}", 5683 // "[SCENE]: For {0} found AxisAlignedBoundingBoxRaw {1}, {2}",
5639// g.Name, new Vector3(ominX, ominY, ominZ), new Vector3(omaxX, omaxY, omaxZ)); 5684 // g.Name, new Vector3(ominX, ominY, ominZ), new Vector3(omaxX, omaxY, omaxZ));
5640 5685
5641 ominX += vec.X; 5686 ominX += vec.X;
5642 omaxX += vec.X; 5687 omaxX += vec.X;
@@ -5646,17 +5691,17 @@ namespace OpenSim.Region.Framework.Scenes
5646 omaxZ += vec.Z; 5691 omaxZ += vec.Z;
5647 5692
5648 if (minX > ominX) 5693 if (minX > ominX)
5649 minX = ominX; 5694 minX = ominX;
5650 if (minY > ominY) 5695 if (minY > ominY)
5651 minY = ominY; 5696 minY = ominY;
5652 if (minZ > ominZ) 5697 if (minZ > ominZ)
5653 minZ = ominZ; 5698 minZ = ominZ;
5654 if (maxX < omaxX) 5699 if (maxX < omaxX)
5655 maxX = omaxX; 5700 maxX = omaxX;
5656 if (maxY < omaxY) 5701 if (maxY < omaxY)
5657 maxY = omaxY; 5702 maxY = omaxY;
5658 if (maxZ < omaxZ) 5703 if (maxZ < omaxZ)
5659 maxZ = omaxZ; 5704 maxZ = omaxZ;
5660 } 5705 }
5661 5706
5662 foreach (SceneObjectGroup g in objects) 5707 foreach (SceneObjectGroup g in objects)
@@ -5681,7 +5726,7 @@ namespace OpenSim.Region.Framework.Scenes
5681 { 5726 {
5682 IWorldMapModule mapModule = RequestModuleInterface<IWorldMapModule>(); 5727 IWorldMapModule mapModule = RequestModuleInterface<IWorldMapModule>();
5683 if (mapModule != null) 5728 if (mapModule != null)
5684 mapModule.GenerateMaptile(); 5729 mapModule.GenerateMaptile();
5685 } 5730 }
5686 5731
5687 private void RegenerateMaptileAndReregister(object sender, ElapsedEventArgs e) 5732 private void RegenerateMaptileAndReregister(object sender, ElapsedEventArgs e)
@@ -5692,7 +5737,7 @@ namespace OpenSim.Region.Framework.Scenes
5692 // so that all simulators can retrieve it 5737 // so that all simulators can retrieve it
5693 string error = GridService.RegisterRegion(RegionInfo.ScopeID, new GridRegion(RegionInfo)); 5738 string error = GridService.RegisterRegion(RegionInfo.ScopeID, new GridRegion(RegionInfo));
5694 if (error != string.Empty) 5739 if (error != string.Empty)
5695 throw new Exception(error); 5740 throw new Exception(error);
5696 } 5741 }
5697 5742
5698 /// <summary> 5743 /// <summary>
@@ -5722,7 +5767,7 @@ namespace OpenSim.Region.Framework.Scenes
5722 } 5767 }
5723 5768
5724 if (!AllowAvatarCrossing && !viaTeleport) 5769 if (!AllowAvatarCrossing && !viaTeleport)
5725 return false; 5770 return false;
5726 5771
5727 // FIXME: Root agent count is currently known to be inaccurate. This forces a recount before we check. 5772 // FIXME: Root agent count is currently known to be inaccurate. This forces a recount before we check.
5728 // However, the long term fix is to make sure root agent count is always accurate. 5773 // However, the long term fix is to make sure root agent count is always accurate.
@@ -5737,8 +5782,8 @@ namespace OpenSim.Region.Framework.Scenes
5737 reason = "The region is full"; 5782 reason = "The region is full";
5738 5783
5739 m_log.DebugFormat( 5784 m_log.DebugFormat(
5740 "[SCENE]: Denying presence with id {0} entry into {1} since region is at agent limit of {2}", 5785 "[SCENE]: Denying presence with id {0} entry into {1} since region is at agent limit of {2}",
5741 agentID, RegionInfo.RegionName, RegionInfo.RegionSettings.AgentLimit); 5786 agentID, RegionInfo.RegionName, RegionInfo.RegionSettings.AgentLimit);
5742 5787
5743 return false; 5788 return false;
5744 } 5789 }
@@ -5752,7 +5797,7 @@ namespace OpenSim.Region.Framework.Scenes
5752 { 5797 {
5753 client = presence.ControllingClient; 5798 client = presence.ControllingClient;
5754 if (client != null) 5799 if (client != null)
5755 aCircuit = client.RequestClientInfo(); 5800 aCircuit = client.RequestClientInfo();
5756 } 5801 }
5757 5802
5758 // We may be called before there is a presence or a client. 5803 // We may be called before there is a presence or a client.
@@ -5775,7 +5820,7 @@ namespace OpenSim.Region.Framework.Scenes
5775 } 5820 }
5776 catch (Exception e) 5821 catch (Exception e)
5777 { 5822 {
5778 m_log.DebugFormat("[SCENE]: Exception authorizing agent: {0} "+ e.StackTrace, e.Message); 5823 m_log.DebugFormat("[SCENE]: Exception authorizing agent: {0} " + e.StackTrace, e.Message);
5779 reason = "Error authorizing agent: " + e.Message; 5824 reason = "Error authorizing agent: " + e.Message;
5780 return false; 5825 return false;
5781 } 5826 }
@@ -5794,16 +5839,16 @@ namespace OpenSim.Region.Framework.Scenes
5794 Vector3 spawnPoint = sp.GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); 5839 Vector3 spawnPoint = sp.GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
5795 ILandObject land = LandChannel.GetLandObject(spawnPoint.X, spawnPoint.Y); 5840 ILandObject land = LandChannel.GetLandObject(spawnPoint.X, spawnPoint.Y);
5796 if (land == null) 5841 if (land == null)
5797 continue; 5842 continue;
5798 if (land.IsEitherBannedOrRestricted(agentID)) 5843 if (land.IsEitherBannedOrRestricted(agentID))
5799 continue; 5844 continue;
5800 banned = false; 5845 banned = false;
5801 break; 5846 break;
5802 } 5847 }
5803 5848
5804 if (banned) 5849 if (banned)
5805 { 5850 {
5806 if(Permissions.IsAdministrator(agentID) == false || Permissions.IsGridGod(agentID) == false) 5851 if (Permissions.IsAdministrator(agentID) == false || Permissions.IsGridGod(agentID) == false)
5807 { 5852 {
5808 reason = "No suitable landing point found"; 5853 reason = "No suitable landing point found";
5809 return false; 5854 return false;
@@ -5839,9 +5884,9 @@ namespace OpenSim.Region.Framework.Scenes
5839 if (banned || restricted) 5884 if (banned || restricted)
5840 { 5885 {
5841 if (banned) 5886 if (banned)
5842 reason = "You are banned from the parcel"; 5887 reason = "You are banned from the parcel";
5843 else 5888 else
5844 reason = "The parcel is restricted"; 5889 reason = "The parcel is restricted";
5845 return false; 5890 return false;
5846 } 5891 }
5847 } 5892 }
@@ -5863,15 +5908,15 @@ namespace OpenSim.Region.Framework.Scenes
5863 if (presence.MovingToTarget) 5908 if (presence.MovingToTarget)
5864 { 5909 {
5865 double distanceToTarget = Util.GetDistanceTo(presence.AbsolutePosition, presence.MoveToPositionTarget); 5910 double distanceToTarget = Util.GetDistanceTo(presence.AbsolutePosition, presence.MoveToPositionTarget);
5866// m_log.DebugFormat( 5911 // m_log.DebugFormat(
5867// "[SCENE]: Abs pos of {0} is {1}, target {2}, distance {3}", 5912 // "[SCENE]: Abs pos of {0} is {1}, target {2}, distance {3}",
5868// presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget, distanceToTarget); 5913 // presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget, distanceToTarget);
5869 5914
5870 // Check the error term of the current position in relation to the target position 5915 // Check the error term of the current position in relation to the target position
5871 if (distanceToTarget <= ScenePresence.SIGNIFICANT_MOVEMENT) 5916 if (distanceToTarget <= ScenePresence.SIGNIFICANT_MOVEMENT)
5872 { 5917 {
5873 // We are close enough to the target 5918 // We are close enough to the target
5874// m_log.DebugFormat("[SCENEE]: Stopping autopilot of {0}", presence.Name); 5919 // m_log.DebugFormat("[SCENEE]: Stopping autopilot of {0}", presence.Name);
5875 5920
5876 presence.Velocity = Vector3.Zero; 5921 presence.Velocity = Vector3.Zero;
5877 presence.AbsolutePosition = presence.MoveToPositionTarget; 5922 presence.AbsolutePosition = presence.MoveToPositionTarget;
@@ -5885,28 +5930,28 @@ namespace OpenSim.Region.Framework.Scenes
5885 // least be able to set collision status once, rather than 5 times to give it enough 5930 // least be able to set collision status once, rather than 5 times to give it enough
5886 // weighting so that that PhysicsActor thinks it really is colliding. 5931 // weighting so that that PhysicsActor thinks it really is colliding.
5887 for (int i = 0; i < 5; i++) 5932 for (int i = 0; i < 5; i++)
5888 presence.IsColliding = true; 5933 presence.IsColliding = true;
5889 5934
5890 if (presence.LandAtTarget) 5935 if (presence.LandAtTarget)
5891 presence.Flying = false; 5936 presence.Flying = false;
5892 5937
5893// Vector3 targetPos = presence.MoveToPositionTarget; 5938 // Vector3 targetPos = presence.MoveToPositionTarget;
5894// float terrainHeight = (float)presence.Scene.Heightmap[(int)targetPos.X, (int)targetPos.Y]; 5939 // float terrainHeight = (float)presence.Scene.Heightmap[(int)targetPos.X, (int)targetPos.Y];
5895// if (targetPos.Z - terrainHeight < 0.2) 5940 // if (targetPos.Z - terrainHeight < 0.2)
5896// { 5941 // {
5897// presence.Flying = false; 5942 // presence.Flying = false;
5898// } 5943 // }
5899 } 5944 }
5900 5945
5901// m_log.DebugFormat( 5946 // m_log.DebugFormat(
5902// "[SCENE]: AgentControlFlags {0}, MovementFlag {1} for {2}", 5947 // "[SCENE]: AgentControlFlags {0}, MovementFlag {1} for {2}",
5903// presence.AgentControlFlags, presence.MovementFlag, presence.Name); 5948 // presence.AgentControlFlags, presence.MovementFlag, presence.Name);
5904 } 5949 }
5905 else 5950 else
5906 { 5951 {
5907// m_log.DebugFormat( 5952 // m_log.DebugFormat(
5908// "[SCENE]: Updating npc {0} at {1} for next movement to {2}", 5953 // "[SCENE]: Updating npc {0} at {1} for next movement to {2}",
5909// presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget); 5954 // presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget);
5910 5955
5911 Vector3 agent_control_v3 = new Vector3(); 5956 Vector3 agent_control_v3 = new Vector3();
5912 presence.HandleMoveToTargetUpdate(1, ref agent_control_v3); 5957 presence.HandleMoveToTargetUpdate(1, ref agent_control_v3);
@@ -5921,11 +5966,11 @@ namespace OpenSim.Region.Framework.Scenes
5921 int spawnpoints = RegionInfo.RegionSettings.SpawnPoints().Count; 5966 int spawnpoints = RegionInfo.RegionSettings.SpawnPoints().Count;
5922 5967
5923 if (spawnpoints == 0) 5968 if (spawnpoints == 0)
5924 return 0; 5969 return 0;
5925 5970
5926 m_SpawnPoint++; 5971 m_SpawnPoint++;
5927 if (m_SpawnPoint > spawnpoints) 5972 if (m_SpawnPoint > spawnpoints)
5928 m_SpawnPoint = 1; 5973 m_SpawnPoint = 1;
5929 return m_SpawnPoint - 1; 5974 return m_SpawnPoint - 1;
5930 } 5975 }
5931 5976
@@ -5955,12 +6000,12 @@ namespace OpenSim.Region.Framework.Scenes
5955 public string GetExtraSetting(string name) 6000 public string GetExtraSetting(string name)
5956 { 6001 {
5957 if (m_extraSettings == null) 6002 if (m_extraSettings == null)
5958 return String.Empty; 6003 return String.Empty;
5959 6004
5960 string val; 6005 string val;
5961 6006
5962 if (!m_extraSettings.TryGetValue(name, out val)) 6007 if (!m_extraSettings.TryGetValue(name, out val))
5963 return String.Empty; 6008 return String.Empty;
5964 6009
5965 return val; 6010 return val;
5966 } 6011 }
@@ -5968,14 +6013,14 @@ namespace OpenSim.Region.Framework.Scenes
5968 public void StoreExtraSetting(string name, string val) 6013 public void StoreExtraSetting(string name, string val)
5969 { 6014 {
5970 if (m_extraSettings == null) 6015 if (m_extraSettings == null)
5971 return; 6016 return;
5972 6017
5973 string oldVal; 6018 string oldVal;
5974 6019
5975 if (m_extraSettings.TryGetValue(name, out oldVal)) 6020 if (m_extraSettings.TryGetValue(name, out oldVal))
5976 { 6021 {
5977 if (oldVal == val) 6022 if (oldVal == val)
5978 return; 6023 return;
5979 } 6024 }
5980 6025
5981 m_extraSettings[name] = val; 6026 m_extraSettings[name] = val;
@@ -5988,10 +6033,10 @@ namespace OpenSim.Region.Framework.Scenes
5988 public void RemoveExtraSetting(string name) 6033 public void RemoveExtraSetting(string name)
5989 { 6034 {
5990 if (m_extraSettings == null) 6035 if (m_extraSettings == null)
5991 return; 6036 return;
5992 6037
5993 if (!m_extraSettings.ContainsKey(name)) 6038 if (!m_extraSettings.ContainsKey(name))
5994 return; 6039 return;
5995 6040
5996 m_extraSettings.Remove(name); 6041 m_extraSettings.Remove(name);
5997 6042
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 51f50d9..c2e9b61 100644..100755
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -67,7 +67,9 @@ namespace OpenSim.Region.Framework.Scenes
67 protected Scene m_parentScene; 67 protected Scene m_parentScene;
68 protected Dictionary<UUID, SceneObjectGroup> m_updateList = new Dictionary<UUID, SceneObjectGroup>(); 68 protected Dictionary<UUID, SceneObjectGroup> m_updateList = new Dictionary<UUID, SceneObjectGroup>();
69 protected int m_numRootAgents = 0; 69 protected int m_numRootAgents = 0;
70 protected int m_numTotalPrim = 0;
70 protected int m_numPrim = 0; 71 protected int m_numPrim = 0;
72 protected int m_numMesh = 0;
71 protected int m_numChildAgents = 0; 73 protected int m_numChildAgents = 0;
72 protected int m_physicalPrim = 0; 74 protected int m_physicalPrim = 0;
73 75
@@ -368,7 +370,8 @@ namespace OpenSim.Region.Framework.Scenes
368 370
369 SceneObjectPart[] parts = sceneObject.Parts; 371 SceneObjectPart[] parts = sceneObject.Parts;
370 372
371 // Clamp child prim sizes and add child prims to the m_numPrim count 373 // Clamp the sizes (scales) of the child prims and add the child prims to the count of all primitives
374 // (meshes and geometric primitives) in the scene; add child prims to m_numTotalPrim count
372 if (m_parentScene.m_clampPrimSize) 375 if (m_parentScene.m_clampPrimSize)
373 { 376 {
374 foreach (SceneObjectPart part in parts) 377 foreach (SceneObjectPart part in parts)
@@ -382,7 +385,19 @@ namespace OpenSim.Region.Framework.Scenes
382 part.Shape.Scale = scale; 385 part.Shape.Scale = scale;
383 } 386 }
384 } 387 }
385 m_numPrim += parts.Length; 388 m_numTotalPrim += parts.Length;
389
390 // Go through all parts (geometric primitives and meshes) of this Scene Object
391 foreach (SceneObjectPart part in parts)
392 {
393 // Keep track of the total number of meshes or geometric primitives now in the scene;
394 // determine which object this is based on its primitive type: sculpted (sculpt) prim refers to
395 // a mesh and all other prims (i.e. box, sphere, etc) are geometric primitives
396 if (part.GetPrimType() == PrimType.SCULPT)
397 m_numMesh++;
398 else
399 m_numPrim++;
400 }
386 401
387 sceneObject.AttachToScene(m_parentScene); 402 sceneObject.AttachToScene(m_parentScene);
388 403
@@ -437,7 +452,21 @@ namespace OpenSim.Region.Framework.Scenes
437 452
438 if (!resultOfObjectLinked) 453 if (!resultOfObjectLinked)
439 { 454 {
440 m_numPrim -= grp.PrimCount; 455 // Decrement the total number of primitives (meshes and geometric primitives)
456 // that are part of the Scene Object being removed
457 m_numTotalPrim -= grp.PrimCount;
458
459 // Go through all parts (primitives and meshes) of this Scene Object
460 foreach (SceneObjectPart part in grp.Parts)
461 {
462 // Keep track of the total number of meshes or geometric primitives left in the scene;
463 // determine which object this is based on its primitive type: sculpted (sculpt) prim refers to
464 // a mesh and all other prims (i.e. box, sphere, etc) are geometric primitives
465 if (part.GetPrimType() == PrimType.SCULPT)
466 m_numMesh--;
467 else
468 m_numPrim--;
469 }
441 470
442 if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) 471 if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
443 RemovePhysicalPrim(grp.PrimCount); 472 RemovePhysicalPrim(grp.PrimCount);
@@ -687,9 +716,19 @@ namespace OpenSim.Region.Framework.Scenes
687 716
688 public int GetTotalObjectsCount() 717 public int GetTotalObjectsCount()
689 { 718 {
719 return m_numTotalPrim;
720 }
721
722 public int GetTotalPrimObjectsCount()
723 {
690 return m_numPrim; 724 return m_numPrim;
691 } 725 }
692 726
727 public int GetTotalMeshObjectsCount()
728 {
729 return m_numMesh;
730 }
731
693 public int GetActiveObjectsCount() 732 public int GetActiveObjectsCount()
694 { 733 {
695 return m_physicalPrim; 734 return m_physicalPrim;
@@ -1970,7 +2009,19 @@ namespace OpenSim.Region.Framework.Scenes
1970 // think it's selected, so it will never send a deselect... 2009 // think it's selected, so it will never send a deselect...
1971 copy.IsSelected = false; 2010 copy.IsSelected = false;
1972 2011
1973 m_numPrim += copy.Parts.Length; 2012 m_numTotalPrim += copy.Parts.Length;
2013
2014 // Go through all parts (primitives and meshes) of this Scene Object
2015 foreach (SceneObjectPart part in copy.Parts)
2016 {
2017 // Keep track of the total number of meshes or geometric primitives now in the scene;
2018 // determine which object this is based on its primitive type: sculpted (sculpt) prim refers to
2019 // a mesh and all other prims (i.e. box, sphere, etc) are geometric primitives
2020 if (part.GetPrimType() == PrimType.SCULPT)
2021 m_numMesh++;
2022 else
2023 m_numPrim++;
2024 }
1974 2025
1975 if (rot != Quaternion.Identity) 2026 if (rot != Quaternion.Identity)
1976 { 2027 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 0a1a226..866a43c 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -2672,20 +2672,27 @@ namespace OpenSim.Region.Framework.Scenes
2672 } 2672 }
2673 else 2673 else
2674 { 2674 {
2675 //NonPhysicalGrabMovement(pos); 2675 NonPhysicalGrabMovement(pos);
2676 } 2676 }
2677 } 2677 }
2678 else 2678 else
2679 { 2679 {
2680 //NonPhysicalGrabMovement(pos); 2680 NonPhysicalGrabMovement(pos);
2681 } 2681 }
2682 } 2682 }
2683 } 2683 }
2684 2684
2685 /// <summary>
2686 /// Apply possition for grabbing non-physical linksets (Ctrl+Drag)
2687 /// This MUST be blocked for linksets that contain touch scripts because the viewer triggers grab on the touch
2688 /// event (Viewer Bug?) This would allow anyone to drag a linkset with a touch script. SL behaviour is also to
2689 /// block grab on prims with touch events.
2690 /// </summary>
2691 /// <param name="pos">New Position</param>
2685 public void NonPhysicalGrabMovement(Vector3 pos) 2692 public void NonPhysicalGrabMovement(Vector3 pos)
2686 { 2693 {
2687 AbsolutePosition = pos; 2694 if(!IsAttachment && ScriptCount() == 0)
2688 m_rootPart.SendTerseUpdateToAllClients(); 2695 UpdateGroupPosition(pos);
2689 } 2696 }
2690 2697
2691 /// <summary> 2698 /// <summary>
@@ -2781,17 +2788,28 @@ namespace OpenSim.Region.Framework.Scenes
2781 } 2788 }
2782 else 2789 else
2783 { 2790 {
2784 //NonPhysicalSpinMovement(pos); 2791 NonPhysicalSpinMovement(newOrientation);
2785 } 2792 }
2786 } 2793 }
2787 else 2794 else
2788 { 2795 {
2789 //NonPhysicalSpinMovement(pos); 2796 NonPhysicalSpinMovement(newOrientation);
2790 } 2797 }
2791 } 2798 }
2792 } 2799 }
2793 2800
2794 /// <summary> 2801 /// <summary>
2802 /// Apply rotation for spinning non-physical linksets (Ctrl+Shift+Drag)
2803 /// As with dragging, scripted objects must be blocked from spinning
2804 /// </summary>
2805 /// <param name="newOrientation">New Rotation</param>
2806 private void NonPhysicalSpinMovement(Quaternion newOrientation)
2807 {
2808 if(!IsAttachment && ScriptCount() == 0)
2809 UpdateGroupRotationR(newOrientation);
2810 }
2811
2812 /// <summary>
2795 /// Set the name of a prim 2813 /// Set the name of a prim
2796 /// </summary> 2814 /// </summary>
2797 /// <param name="name"></param> 2815 /// <param name="name"></param>
diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
index 6182bcd..8918c3b 100755
--- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
+++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
@@ -61,6 +61,10 @@ namespace OpenSim.Region.Framework.Scenes
61 61
62 private YourStatsAreWrong handlerStatsIncorrect; 62 private YourStatsAreWrong handlerStatsIncorrect;
63 63
64 // Determines the size of the array that is used to collect StatBlocks
65 // for sending to the SimStats and SimExtraStatsCollector
66 private const int m_statisticArraySize = 27;
67
64 /// <summary> 68 /// <summary>
65 /// These are the IDs of stats sent in the StatsPacket to the viewer. 69 /// These are the IDs of stats sent in the StatsPacket to the viewer.
66 /// </summary> 70 /// </summary>
@@ -104,7 +108,12 @@ namespace OpenSim.Region.Framework.Scenes
104 ScriptEps = 31, 108 ScriptEps = 31,
105 SimSpareMs = 32, 109 SimSpareMs = 32,
106 SimSleepMs = 33, 110 SimSleepMs = 33,
107 SimIoPumpTime = 34 111 SimIoPumpTime = 34,
112 FrameDilation = 35,
113 UsersLoggingIn = 36,
114 TotalGeoPrim = 37,
115 TotalMesh = 38,
116 ThreadCount = 39
108 } 117 }
109 118
110 /// <summary> 119 /// <summary>
@@ -175,7 +184,7 @@ namespace OpenSim.Region.Framework.Scenes
175 184
176 // saved last reported value so there is something available for llGetRegionFPS 185 // saved last reported value so there is something available for llGetRegionFPS
177 private float lastReportedSimFPS; 186 private float lastReportedSimFPS;
178 private float[] lastReportedSimStats = new float[22]; 187 private float[] lastReportedSimStats = new float[m_statisticArraySize];
179 private float m_pfps; 188 private float m_pfps;
180 189
181 /// <summary> 190 /// <summary>
@@ -202,6 +211,8 @@ namespace OpenSim.Region.Framework.Scenes
202 private int m_rootAgents; 211 private int m_rootAgents;
203 private int m_childAgents; 212 private int m_childAgents;
204 private int m_numPrim; 213 private int m_numPrim;
214 private int m_numGeoPrim;
215 private int m_numMesh;
205 private int m_inPacketsPerSecond; 216 private int m_inPacketsPerSecond;
206 private int m_outPacketsPerSecond; 217 private int m_outPacketsPerSecond;
207 private int m_activePrim; 218 private int m_activePrim;
@@ -214,26 +225,33 @@ namespace OpenSim.Region.Framework.Scenes
214 private int m_objectCapacity = 45000; 225 private int m_objectCapacity = 45000;
215 226
216 // This is the number of frames that will be stored and then averaged for 227 // This is the number of frames that will be stored and then averaged for
217 // the Total, Simulation, Physics, and Network Frame Time; It is set to 228 // the Total, Simulation, Physics, and Network Frame Time; It is set to
218 // 10 by default but can be changed by the OpenSim.ini configuration file 229 // 10 by default but can be changed by the OpenSim.ini configuration file
219 // NumberOfFrames parameter 230 // NumberOfFrames parameter
220 private int m_numberFramesStored = 10; 231 private int m_numberFramesStored = Scene.m_defaultNumberFramesStored;
221 232
222 // The arrays that will hold the time it took to run the past N frames, 233 // The arrays that will hold the time it took to run the past N frames,
223 // where N is the num_frames_to_average given by the configuration file 234 // where N is the num_frames_to_average given by the configuration file
224 private double[] m_totalFrameTimeMilliseconds; 235 private double[] m_totalFrameTimeMilliseconds;
225 private double[] m_simulationFrameTimeMilliseconds; 236 private double[] m_simulationFrameTimeMilliseconds;
226 private double[] m_physicsFrameTimeMilliseconds; 237 private double[] m_physicsFrameTimeMilliseconds;
227 private double[] m_networkFrameTimeMilliseconds; 238 private double[] m_networkFrameTimeMilliseconds;
228 239
229 // The location of the next time in milliseconds that will be 240 // The location of the next time in milliseconds that will be
230 // (over)written when the next frame completes 241 // (over)written when the next frame completes
231 private int m_nextLocation = 0; 242 private int m_nextLocation = 0;
232 243
233 // The correct number of frames that have completed since the last stats 244 // The correct number of frames that have completed since the last stats
234 // update for physics 245 // update for physics
235 private int m_numberPhysicsFrames; 246 private int m_numberPhysicsFrames;
236 247
248 // The current number of users attempting to login to the region
249 private int m_usersLoggingIn;
250
251 // The last reported value of threads from the SmartThreadPool inside of
252 // XEngine
253 private int m_inUseThreads;
254
237 private Scene m_scene; 255 private Scene m_scene;
238 256
239 private RegionInfo ReportingRegion; 257 private RegionInfo ReportingRegion;
@@ -246,11 +264,13 @@ namespace OpenSim.Region.Framework.Scenes
246 { 264 {
247 // Initialize the different frame time arrays to the correct sizes 265 // Initialize the different frame time arrays to the correct sizes
248 m_totalFrameTimeMilliseconds = new double[m_numberFramesStored]; 266 m_totalFrameTimeMilliseconds = new double[m_numberFramesStored];
249 m_simulationFrameTimeMilliseconds = new 267 m_simulationFrameTimeMilliseconds = new double[m_numberFramesStored];
250 double[m_numberFramesStored];
251 m_physicsFrameTimeMilliseconds = new double[m_numberFramesStored]; 268 m_physicsFrameTimeMilliseconds = new double[m_numberFramesStored];
252 m_networkFrameTimeMilliseconds = new double[m_numberFramesStored]; 269 m_networkFrameTimeMilliseconds = new double[m_numberFramesStored];
253 270
271 // Initialize the current number of users logging into the region
272 m_usersLoggingIn = 0;
273
254 m_scene = scene; 274 m_scene = scene;
255 m_reportedFpsCorrectionFactor = scene.MinFrameSeconds * m_nominalReportedFps; 275 m_reportedFpsCorrectionFactor = scene.MinFrameSeconds * m_nominalReportedFps;
256 m_statsUpdateFactor = (float)(m_statsUpdatesEveryMS / 1000); 276 m_statsUpdateFactor = (float)(m_statsUpdatesEveryMS / 1000);
@@ -284,13 +304,14 @@ namespace OpenSim.Region.Framework.Scenes
284 StatsManager.RegisterStat(SlowFramesStat); 304 StatsManager.RegisterStat(SlowFramesStat);
285 } 305 }
286 306
307
287 public SimStatsReporter(Scene scene, int numberOfFrames) : this (scene) 308 public SimStatsReporter(Scene scene, int numberOfFrames) : this (scene)
288 { 309 {
289 // Store the number of frames from the OpenSim.ini configuration 310 // Store the number of frames from the OpenSim.ini configuration file
290 // file 311 m_numberFramesStored = numberOfFrames;
291 m_numberFramesStored = numberOfFrames;
292 } 312 }
293 313
314
294 public void Close() 315 public void Close()
295 { 316 {
296 m_report.Elapsed -= TriggerStatsHeartbeat; 317 m_report.Elapsed -= TriggerStatsHeartbeat;
@@ -328,11 +349,17 @@ namespace OpenSim.Region.Framework.Scenes
328 double simulationSumFrameTime; 349 double simulationSumFrameTime;
329 double physicsSumFrameTime; 350 double physicsSumFrameTime;
330 double networkSumFrameTime; 351 double networkSumFrameTime;
331 352 float frameDilation;
353 int currentFrame;
354
332 if (!m_scene.Active) 355 if (!m_scene.Active)
333 return; 356 return;
334 357
335 SimStatsPacket.StatBlock[] sb = new SimStatsPacket.StatBlock[22]; 358 // Create arrays to hold the statistics for this current scene,
359 // these will be passed to the SimExtraStatsCollector, they are also
360 // sent to the SimStats class
361 SimStatsPacket.StatBlock[] sb = new
362 SimStatsPacket.StatBlock[m_statisticArraySize];
336 SimStatsPacket.RegionBlock rb = new SimStatsPacket.RegionBlock(); 363 SimStatsPacket.RegionBlock rb = new SimStatsPacket.RegionBlock();
337 364
338 // Know what's not thread safe in Mono... modifying timers. 365 // Know what's not thread safe in Mono... modifying timers.
@@ -354,21 +381,21 @@ namespace OpenSim.Region.Framework.Scenes
354 381
355#region various statistic googly moogly 382#region various statistic googly moogly
356 383
357 // ORIGINAL code commented out until we have time to add our own 384 // ORIGINAL code commented out until we have time to add our own
358 // statistics to the statistics window, this will be done as a 385 // statistics to the statistics window, this will be done as a
359 // new section given the title of our current project 386 // new section given the title of our current project
360 // We're going to lie about the FPS because we've been lying since 2008. The actual FPS is currently 387 // We're going to lie about the FPS because we've been lying since 2008. The actual FPS is currently
361 // locked at a maximum of 11. Maybe at some point this can change so that we're not lying. 388 // locked at a maximum of 11. Maybe at some point this can change so that we're not lying.
362 //int reportedFPS = (int)(m_fps * m_reportedFpsCorrectionFactor); 389 //int reportedFPS = (int)(m_fps * m_reportedFpsCorrectionFactor);
363 int reportedFPS = m_fps; 390 int reportedFPS = m_fps;
364 391
365 // save the reported value so there is something available for llGetRegionFPS 392 // save the reported value so there is something available for llGetRegionFPS
366 lastReportedSimFPS = reportedFPS / m_statsUpdateFactor; 393 lastReportedSimFPS = reportedFPS / m_statsUpdateFactor;
367 394
368 // ORIGINAL code commented out until we have time to add our own 395 // ORIGINAL code commented out until we have time to add our own
369 // statistics to the statistics window 396 // statistics to the statistics window
370 //float physfps = ((m_pfps / 1000)); 397 //float physfps = ((m_pfps / 1000));
371 float physfps = m_numberPhysicsFrames; 398 float physfps = m_numberPhysicsFrames;
372 399
373 //if (physfps > 600) 400 //if (physfps > 600)
374 //physfps = physfps - (physfps - 600); 401 //physfps = physfps - (physfps - 600);
@@ -381,6 +408,8 @@ namespace OpenSim.Region.Framework.Scenes
381 m_rootAgents = m_scene.SceneGraph.GetRootAgentCount(); 408 m_rootAgents = m_scene.SceneGraph.GetRootAgentCount();
382 m_childAgents = m_scene.SceneGraph.GetChildAgentCount(); 409 m_childAgents = m_scene.SceneGraph.GetChildAgentCount();
383 m_numPrim = m_scene.SceneGraph.GetTotalObjectsCount(); 410 m_numPrim = m_scene.SceneGraph.GetTotalObjectsCount();
411 m_numGeoPrim = m_scene.SceneGraph.GetTotalPrimObjectsCount();
412 m_numMesh = m_scene.SceneGraph.GetTotalMeshObjectsCount();
384 m_activePrim = m_scene.SceneGraph.GetActiveObjectsCount(); 413 m_activePrim = m_scene.SceneGraph.GetActiveObjectsCount();
385 m_activeScripts = m_scene.SceneGraph.GetActiveScriptsCount(); 414 m_activeScripts = m_scene.SceneGraph.GetActiveScriptsCount();
386 415
@@ -406,11 +435,11 @@ namespace OpenSim.Region.Framework.Scenes
406 if (framesUpdated == 0) 435 if (framesUpdated == 0)
407 framesUpdated = 1; 436 framesUpdated = 1;
408 437
409 for (int i = 0; i < 22; i++) 438 for (int i = 0; i < m_statisticArraySize; i++)
410 { 439 {
411 sb[i] = new SimStatsPacket.StatBlock(); 440 sb[i] = new SimStatsPacket.StatBlock();
412 } 441 }
413 442
414 // Resetting the sums of the frame times to prevent any errors 443 // Resetting the sums of the frame times to prevent any errors
415 // in calculating the moving average for frame time 444 // in calculating the moving average for frame time
416 totalSumFrameTime = 0; 445 totalSumFrameTime = 0;
@@ -425,12 +454,25 @@ namespace OpenSim.Region.Framework.Scenes
425 // Sum up each frame time in order to calculate the moving 454 // Sum up each frame time in order to calculate the moving
426 // average of frame time 455 // average of frame time
427 totalSumFrameTime += m_totalFrameTimeMilliseconds[i]; 456 totalSumFrameTime += m_totalFrameTimeMilliseconds[i];
428 simulationSumFrameTime += 457 simulationSumFrameTime +=
429 m_simulationFrameTimeMilliseconds[i]; 458 m_simulationFrameTimeMilliseconds[i];
430 physicsSumFrameTime += m_physicsFrameTimeMilliseconds[i]; 459 physicsSumFrameTime += m_physicsFrameTimeMilliseconds[i];
431 networkSumFrameTime += m_networkFrameTimeMilliseconds[i]; 460 networkSumFrameTime += m_networkFrameTimeMilliseconds[i];
432 } 461 }
433 462
463 // Get the index that represents the current frame based on the next one known; go back
464 // to the last index if next one is stated to restart at 0
465 if (m_nextLocation == 0)
466 currentFrame = m_numberFramesStored - 1;
467 else
468 currentFrame = m_nextLocation - 1;
469
470 // Calculate the frame dilation; which is currently based on the ratio between the sum of the
471 // physics and simulation rate, and the set minimum time to run a scene's frame
472 frameDilation = (float)(m_simulationFrameTimeMilliseconds[currentFrame] +
473 m_physicsFrameTimeMilliseconds[currentFrame]) / m_scene.MinFrameTicks;
474
475 // ORIGINAL code commented out until we have time to add our own
434 sb[0].StatID = (uint) Stats.TimeDilation; 476 sb[0].StatID = (uint) Stats.TimeDilation;
435 sb[0].StatValue = (Single.IsNaN(m_timeDilation)) ? 0.1f : m_timeDilation ; //((((m_timeDilation + (0.10f * statsUpdateFactor)) /10) / statsUpdateFactor)); 477 sb[0].StatValue = (Single.IsNaN(m_timeDilation)) ? 0.1f : m_timeDilation ; //((((m_timeDilation + (0.10f * statsUpdateFactor)) /10) / statsUpdateFactor));
436 478
@@ -455,31 +497,28 @@ namespace OpenSim.Region.Framework.Scenes
455 sb[7].StatID = (uint) Stats.ActivePrim; 497 sb[7].StatID = (uint) Stats.ActivePrim;
456 sb[7].StatValue = m_activePrim; 498 sb[7].StatValue = m_activePrim;
457 499
458 // ORIGINAL code commented out until we have time to add our own 500 // ORIGINAL code commented out until we have time to add our own
459 // statistics to the statistics window 501 // statistics to the statistics window
460 sb[8].StatID = (uint)Stats.FrameMS; 502 sb[8].StatID = (uint)Stats.FrameMS;
461 //sb[8].StatValue = m_frameMS / framesUpdated; 503 //sb[8].StatValue = m_frameMS / framesUpdated;
462 sb[8].StatValue = (float) totalSumFrameTime / 504 sb[8].StatValue = (float) totalSumFrameTime / m_numberFramesStored;
463 m_numberFramesStored;
464 505
465 sb[9].StatID = (uint)Stats.NetMS; 506 sb[9].StatID = (uint)Stats.NetMS;
466 //sb[9].StatValue = m_netMS / framesUpdated; 507 //sb[9].StatValue = m_netMS / framesUpdated;
467 sb[9].StatValue = (float) networkSumFrameTime / 508 sb[9].StatValue = (float) networkSumFrameTime / m_numberFramesStored;
468 m_numberFramesStored;
469 509
470 sb[10].StatID = (uint)Stats.PhysicsMS; 510 sb[10].StatID = (uint)Stats.PhysicsMS;
471 //sb[10].StatValue = m_physicsMS / framesUpdated; 511 //sb[10].StatValue = m_physicsMS / framesUpdated;
472 sb[10].StatValue = (float) physicsSumFrameTime / 512 sb[10].StatValue = (float) physicsSumFrameTime / m_numberFramesStored;
473 m_numberFramesStored;
474 513
475 sb[11].StatID = (uint)Stats.ImageMS ; 514 sb[11].StatID = (uint)Stats.ImageMS ;
476 sb[11].StatValue = m_imageMS / framesUpdated; 515 sb[11].StatValue = m_imageMS / framesUpdated;
477 516
478 sb[12].StatID = (uint)Stats.OtherMS; 517 sb[12].StatID = (uint)Stats.OtherMS;
479 //sb[12].StatValue = m_otherMS / framesUpdated; 518 //sb[12].StatValue = m_otherMS / framesUpdated;
480 sb[12].StatValue = (float) simulationSumFrameTime / 519 sb[12].StatValue = (float) simulationSumFrameTime /
481 m_numberFramesStored; 520 m_numberFramesStored;
482 521
483 sb[13].StatID = (uint)Stats.InPacketsPerSecond; 522 sb[13].StatID = (uint)Stats.InPacketsPerSecond;
484 sb[13].StatValue = (m_inPacketsPerSecond / m_statsUpdateFactor); 523 sb[13].StatValue = (m_inPacketsPerSecond / m_statsUpdateFactor);
485 524
@@ -507,7 +546,28 @@ namespace OpenSim.Region.Framework.Scenes
507 sb[21].StatID = (uint)Stats.SimSpareMs; 546 sb[21].StatID = (uint)Stats.SimSpareMs;
508 sb[21].StatValue = m_spareMS / framesUpdated; 547 sb[21].StatValue = m_spareMS / framesUpdated;
509 548
510 for (int i = 0; i < 22; i++) 549 // Current ratio between the sum of physics and sim rate, and the
550 // minimum time to run a scene's frame
551 sb[22].StatID = (uint)Stats.FrameDilation;
552 sb[22].StatValue = frameDilation;
553
554 // Current number of users currently attemptint to login to region
555 sb[23].StatID = (uint)Stats.UsersLoggingIn;
556 sb[23].StatValue = m_usersLoggingIn;
557
558 // Total number of geometric primitives in the scene
559 sb[24].StatID = (uint)Stats.TotalGeoPrim;
560 sb[24].StatValue = m_numGeoPrim;
561
562 // Total number of mesh objects in the scene
563 sb[25].StatID = (uint)Stats.TotalMesh;
564 sb[25].StatValue = m_numMesh;
565
566 // Current number of threads that XEngine is using
567 sb[26].StatID = (uint)Stats.ThreadCount;
568 sb[26].StatValue = m_inUseThreads;
569
570 for (int i = 0; i < m_statisticArraySize; i++)
511 { 571 {
512 lastReportedSimStats[i] = sb[i].StatValue; 572 lastReportedSimStats[i] = sb[i].StatValue;
513 } 573 }
@@ -554,8 +614,8 @@ namespace OpenSim.Region.Framework.Scenes
554 { 614 {
555 // Reset the number of frames that the physics library has 615 // Reset the number of frames that the physics library has
556 // processed since the last stats report 616 // processed since the last stats report
557 m_numberPhysicsFrames = 0; 617 m_numberPhysicsFrames = 0;
558 618
559 m_timeDilation = 0; 619 m_timeDilation = 0;
560 m_fps = 0; 620 m_fps = 0;
561 m_pfps = 0; 621 m_pfps = 0;
@@ -686,32 +746,32 @@ namespace OpenSim.Region.Framework.Scenes
686 m_otherMS += ms; 746 m_otherMS += ms;
687 } 747 }
688 748
689 public void addPhysicsFrame(int frames) 749 public void addPhysicsFrame(int frames)
690 { 750 {
691 // Add the number of physics frames to the correct total physics 751 // Add the number of physics frames to the correct total physics
692 // frames 752 // frames
693 m_numberPhysicsFrames += frames; 753 m_numberPhysicsFrames += frames;
694 } 754 }
695 755
696 public void addFrameTimeMilliseconds(double total, double simulation, 756 public void addFrameTimeMilliseconds(double total, double simulation,
697 double physics, double network) 757 double physics, double network)
698 { 758 {
699 // Save the frame times from the current frame into the appropriate 759 // Save the frame times from the current frame into the appropriate
700 // arrays 760 // arrays
701 m_totalFrameTimeMilliseconds[m_nextLocation] = total; 761 m_totalFrameTimeMilliseconds[m_nextLocation] = total;
702 m_simulationFrameTimeMilliseconds[m_nextLocation] = simulation; 762 m_simulationFrameTimeMilliseconds[m_nextLocation] = simulation;
703 m_physicsFrameTimeMilliseconds[m_nextLocation] = physics; 763 m_physicsFrameTimeMilliseconds[m_nextLocation] = physics;
704 m_networkFrameTimeMilliseconds[m_nextLocation] = network; 764 m_networkFrameTimeMilliseconds[m_nextLocation] = network;
705 765
706 // Update to the next location in the list 766 // Update to the next location in the list
707 m_nextLocation++; 767 m_nextLocation++;
768
769 // Since the list will begin to overwrite the oldest frame values
770 // first, the next location needs to loop back to the beginning of the
771 // list whenever it reaches the end
772 m_nextLocation = m_nextLocation % m_numberFramesStored;
773 }
708 774
709 // Since the list will begin to overwrite the oldest frame values
710 // first, the next location needs to loop back to the beginning of the
711 // list whenever it reaches the end
712 m_nextLocation = m_nextLocation % m_numberFramesStored;
713 }
714
715 public void AddPendingDownloads(int count) 775 public void AddPendingDownloads(int count)
716 { 776 {
717 m_pendingDownloads += count; 777 m_pendingDownloads += count;
@@ -734,6 +794,31 @@ namespace OpenSim.Region.Framework.Scenes
734 AddunAckedBytes(unAckedBytes); 794 AddunAckedBytes(unAckedBytes);
735 } 795 }
736 796
797 public void UpdateUsersLoggingIn(bool isLoggingIn)
798 {
799 // Determine whether the user has started logging in or has completed
800 // logging into the region
801 if (isLoggingIn)
802 {
803 // The user is starting to login to the region so increment the
804 // number of users attempting to login to the region
805 m_usersLoggingIn++;
806 }
807 else
808 {
809 // The user has finished logging into the region so decrement the
810 // number of users logging into the region
811 m_usersLoggingIn--;
812 }
813 }
814
815 public void SetThreadCount(int inUseThreads)
816 {
817 // Save the new number of threads to our member variable to send to
818 // the extra stats collector
819 m_inUseThreads = inUseThreads;
820 }
821
737 #endregion 822 #endregion
738 823
739 public Dictionary<string, float> GetExtraSimStats() 824 public Dictionary<string, float> GetExtraSimStats()
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index c90f015..c5e02a6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics;
31using System.Drawing; 32using System.Drawing;
32using System.Drawing.Imaging; 33using System.Drawing.Imaging;
33using System.Runtime.Remoting.Lifetime; 34using System.Runtime.Remoting.Lifetime;
@@ -221,15 +222,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
221 protected float m_primSafetyCoeffX = 2.414214f; 222 protected float m_primSafetyCoeffX = 2.414214f;
222 protected float m_primSafetyCoeffY = 2.414214f; 223 protected float m_primSafetyCoeffY = 2.414214f;
223 protected float m_primSafetyCoeffZ = 1.618034f; 224 protected float m_primSafetyCoeffZ = 1.618034f;
224 protected float m_floatToleranceInCastRay = 0.000001f; 225 protected bool m_useCastRayV3 = false;
225 protected float m_floatTolerance2InCastRay = 0.0001f; 226 protected float m_floatToleranceInCastRay = 0.00001f;
227 protected float m_floatTolerance2InCastRay = 0.001f;
228 protected DetailLevel m_primLodInCastRay = DetailLevel.Medium;
229 protected DetailLevel m_sculptLodInCastRay = DetailLevel.Medium;
230 protected DetailLevel m_meshLodInCastRay = DetailLevel.Highest;
231 protected DetailLevel m_avatarLodInCastRay = DetailLevel.Medium;
226 protected int m_maxHitsInCastRay = 16; 232 protected int m_maxHitsInCastRay = 16;
227 protected int m_maxHitsPerPrimInCastRay = 16; 233 protected int m_maxHitsPerPrimInCastRay = 16;
228 protected int m_maxHitsPerObjectInCastRay = 16; 234 protected int m_maxHitsPerObjectInCastRay = 16;
229 protected bool m_detectExitsInCastRay = false; 235 protected bool m_detectExitsInCastRay = false;
230 protected bool m_filterPartsInCastRay = false; 236 protected bool m_filterPartsInCastRay = false;
231 protected bool m_doAttachmentsInCastRay = false; 237 protected bool m_doAttachmentsInCastRay = false;
232 protected bool m_useCastRayV1 = true; 238 protected int m_msThrottleInCastRay = 200;
239 protected int m_msPerRegionInCastRay = 40;
240 protected int m_msPerAvatarInCastRay = 10;
241 protected int m_msMinInCastRay = 2;
242 protected int m_msMaxInCastRay = 40;
243 protected static List<CastRayCall> m_castRayCalls = new List<CastRayCall>();
244 protected bool m_useMeshCacheInCastRay = true;
245 protected static Dictionary<ulong, FacetedMesh> m_cachedMeshes = new Dictionary<ulong, FacetedMesh>();
233 246
234 //An array of HTTP/1.1 headers that are not allowed to be used 247 //An array of HTTP/1.1 headers that are not allowed to be used
235 //as custom headers by llHTTPRequest. 248 //as custom headers by llHTTPRequest.
@@ -336,15 +349,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
336 m_primSafetyCoeffX = lslConfig.GetFloat("PrimBoundingBoxSafetyCoefficientX", m_primSafetyCoeffX); 349 m_primSafetyCoeffX = lslConfig.GetFloat("PrimBoundingBoxSafetyCoefficientX", m_primSafetyCoeffX);
337 m_primSafetyCoeffY = lslConfig.GetFloat("PrimBoundingBoxSafetyCoefficientY", m_primSafetyCoeffY); 350 m_primSafetyCoeffY = lslConfig.GetFloat("PrimBoundingBoxSafetyCoefficientY", m_primSafetyCoeffY);
338 m_primSafetyCoeffZ = lslConfig.GetFloat("PrimBoundingBoxSafetyCoefficientZ", m_primSafetyCoeffZ); 351 m_primSafetyCoeffZ = lslConfig.GetFloat("PrimBoundingBoxSafetyCoefficientZ", m_primSafetyCoeffZ);
352 m_useCastRayV3 = lslConfig.GetBoolean("UseLlCastRayV3", m_useCastRayV3);
339 m_floatToleranceInCastRay = lslConfig.GetFloat("FloatToleranceInLlCastRay", m_floatToleranceInCastRay); 353 m_floatToleranceInCastRay = lslConfig.GetFloat("FloatToleranceInLlCastRay", m_floatToleranceInCastRay);
340 m_floatTolerance2InCastRay = lslConfig.GetFloat("FloatTolerance2InLlCastRay", m_floatTolerance2InCastRay); 354 m_floatTolerance2InCastRay = lslConfig.GetFloat("FloatTolerance2InLlCastRay", m_floatTolerance2InCastRay);
355 m_primLodInCastRay = (DetailLevel)lslConfig.GetInt("PrimDetailLevelInLlCastRay", (int)m_primLodInCastRay);
356 m_sculptLodInCastRay = (DetailLevel)lslConfig.GetInt("SculptDetailLevelInLlCastRay", (int)m_sculptLodInCastRay);
357 m_meshLodInCastRay = (DetailLevel)lslConfig.GetInt("MeshDetailLevelInLlCastRay", (int)m_meshLodInCastRay);
358 m_avatarLodInCastRay = (DetailLevel)lslConfig.GetInt("AvatarDetailLevelInLlCastRay", (int)m_avatarLodInCastRay);
341 m_maxHitsInCastRay = lslConfig.GetInt("MaxHitsInLlCastRay", m_maxHitsInCastRay); 359 m_maxHitsInCastRay = lslConfig.GetInt("MaxHitsInLlCastRay", m_maxHitsInCastRay);
342 m_maxHitsPerPrimInCastRay = lslConfig.GetInt("MaxHitsPerPrimInLlCastRay", m_maxHitsPerPrimInCastRay); 360 m_maxHitsPerPrimInCastRay = lslConfig.GetInt("MaxHitsPerPrimInLlCastRay", m_maxHitsPerPrimInCastRay);
343 m_maxHitsPerObjectInCastRay = lslConfig.GetInt("MaxHitsPerObjectInLlCastRay", m_maxHitsPerObjectInCastRay); 361 m_maxHitsPerObjectInCastRay = lslConfig.GetInt("MaxHitsPerObjectInLlCastRay", m_maxHitsPerObjectInCastRay);
344 m_detectExitsInCastRay = lslConfig.GetBoolean("DetectExitHitsInLlCastRay", m_detectExitsInCastRay); 362 m_detectExitsInCastRay = lslConfig.GetBoolean("DetectExitHitsInLlCastRay", m_detectExitsInCastRay);
345 m_filterPartsInCastRay = lslConfig.GetBoolean("FilterPartsInLlCastRay", m_filterPartsInCastRay); 363 m_filterPartsInCastRay = lslConfig.GetBoolean("FilterPartsInLlCastRay", m_filterPartsInCastRay);
346 m_doAttachmentsInCastRay = lslConfig.GetBoolean("DoAttachmentsInLlCastRay", m_doAttachmentsInCastRay); 364 m_doAttachmentsInCastRay = lslConfig.GetBoolean("DoAttachmentsInLlCastRay", m_doAttachmentsInCastRay);
347 m_useCastRayV1 = lslConfig.GetBoolean("UseLlCastRayV1", m_useCastRayV1); 365 m_msThrottleInCastRay = lslConfig.GetInt("ThrottleTimeInMsInLlCastRay", m_msThrottleInCastRay);
366 m_msPerRegionInCastRay = lslConfig.GetInt("AvailableTimeInMsPerRegionInLlCastRay", m_msPerRegionInCastRay);
367 m_msPerAvatarInCastRay = lslConfig.GetInt("AvailableTimeInMsPerAvatarInLlCastRay", m_msPerAvatarInCastRay);
368 m_msMinInCastRay = lslConfig.GetInt("RequiredAvailableTimeInMsInLlCastRay", m_msMinInCastRay);
369 m_msMaxInCastRay = lslConfig.GetInt("MaximumAvailableTimeInMsInLlCastRay", m_msMaxInCastRay);
370 m_useMeshCacheInCastRay = lslConfig.GetBoolean("UseMeshCacheInLlCastRay", m_useMeshCacheInCastRay);
348 } 371 }
349 372
350 IConfig smtpConfig = seConfigSource.Configs["SMTP"]; 373 IConfig smtpConfig = seConfigSource.Configs["SMTP"];
@@ -5777,7 +5800,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5777 public LSL_String llGetEnv(LSL_String name) 5800 public LSL_String llGetEnv(LSL_String name)
5778 { 5801 {
5779 m_host.AddScriptLPS(1); 5802 m_host.AddScriptLPS(1);
5780 if (name == "dynamic_pathfinding") 5803 if (name == "agent_limit")
5804 {
5805 return World.RegionInfo.RegionSettings.AgentLimit.ToString();
5806 }
5807 else if (name == "dynamic_pathfinding")
5781 { 5808 {
5782 return "0"; 5809 return "0";
5783 } 5810 }
@@ -5785,14 +5812,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5785 { 5812 {
5786 return World.RegionInfo.EstateSettings.EstateID.ToString(); 5813 return World.RegionInfo.EstateSettings.EstateID.ToString();
5787 } 5814 }
5815 else if (name == "estate_name")
5816 {
5817 return World.RegionInfo.EstateSettings.EstateName;
5818 }
5788 else if (name == "frame_number") 5819 else if (name == "frame_number")
5789 { 5820 {
5790 return World.Frame.ToString(); 5821 return World.Frame.ToString();
5791 } 5822 }
5823 else if (name == "region_cpu_ratio")
5824 {
5825 return "1";
5826 }
5792 else if (name == "region_idle") 5827 else if (name == "region_idle")
5793 { 5828 {
5794 return "0"; 5829 return "0";
5795 } 5830 }
5831 else if (name == "region_product_name")
5832 {
5833 if (World.RegionInfo.RegionType != String.Empty)
5834 return World.RegionInfo.RegionType;
5835 else
5836 return "";
5837 }
5838 else if (name == "region_product_sku")
5839 {
5840 return "OpenSim";
5841 }
5842 else if (name == "region_start_time")
5843 {
5844 return World.UnixStartTime.ToString();
5845 }
5796 else if (name == "sim_channel") 5846 else if (name == "sim_channel")
5797 { 5847 {
5798 return "OpenSim"; 5848 return "OpenSim";
@@ -5801,6 +5851,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5801 { 5851 {
5802 return World.GetSimulatorVersion(); 5852 return World.GetSimulatorVersion();
5803 } 5853 }
5854 else if (name == "simulator_hostname")
5855 {
5856 IUrlModule UrlModule = World.RequestModuleInterface<IUrlModule>();
5857 return UrlModule.ExternalHostNameForLSL;
5858 }
5804 else 5859 else
5805 { 5860 {
5806 return ""; 5861 return "";
@@ -13811,8 +13866,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13811 return contacts[0]; 13866 return contacts[0];
13812 } 13867 }
13813 13868
13814 public LSL_List llCastRayV1(LSL_Vector start, LSL_Vector end, LSL_List options) 13869 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
13815 { 13870 {
13871 // Use llCastRay V3 if configured
13872 if (m_useCastRayV3)
13873 return llCastRayV3(start, end, options);
13874
13816 LSL_List list = new LSL_List(); 13875 LSL_List list = new LSL_List();
13817 13876
13818 m_host.AddScriptLPS(1); 13877 m_host.AddScriptLPS(1);
@@ -14003,29 +14062,75 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14003 } 14062 }
14004 14063
14005 /// <summary> 14064 /// <summary>
14006 /// Full implementation of llCastRay similar to SL 2015-04-21. 14065 /// Implementation of llCastRay similar to SL 2015-04-21.
14007 /// http://wiki.secondlife.com/wiki/LlCastRay 14066 /// http://wiki.secondlife.com/wiki/LlCastRay
14008 /// Uses pure geometry, bounding shapes, meshing and no physics 14067 /// Uses pure geometry, bounding shapes, meshing and no physics
14009 /// for prims, sculpts, meshes, avatars and terrain. 14068 /// for prims, sculpts, meshes, avatars and terrain.
14010 /// Implements all flags, reject types and data flags. 14069 /// Implements all flags, reject types and data flags.
14011 /// Can handle both objects/groups and prims/parts, by config. 14070 /// Can handle both objects/groups and prims/parts, by config.
14012 /// May give poor results with multi-part meshes where "root" 14071 /// May sometimes be inaccurate owing to calculation precision,
14013 /// part doesn't dominate, owing to "guessed" bounding boxes. 14072 /// meshing detail level and a bug in libopenmetaverse PrimMesher.
14014 /// May sometimes be inaccurate owing to calculation precision
14015 /// and a bug in libopenmetaverse PrimMesher.
14016 /// </summary> 14073 /// </summary>
14017 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 14074 public LSL_List llCastRayV3(LSL_Vector start, LSL_Vector end, LSL_List options)
14018 { 14075 {
14019 // Use llCastRay v1 if configured 14076 m_host.AddScriptLPS(1);
14020 if (m_useCastRayV1) 14077 LSL_List result = new LSL_List();
14021 return llCastRayV1(start, end, options); 14078
14079 // Prepare throttle data
14080 int calledMs = Environment.TickCount;
14081 Stopwatch stopWatch = new Stopwatch();
14082 stopWatch.Start();
14083 UUID regionId = World.RegionInfo.RegionID;
14084 UUID userId = UUID.Zero;
14085 int msAvailable = 0;
14086 // Throttle per owner when attachment or "vehicle" (sat upon)
14087 if (m_host.ParentGroup.IsAttachment || m_host.ParentGroup.GetSittingAvatars().Count > 0)
14088 {
14089 userId = m_host.OwnerID;
14090 msAvailable = m_msPerAvatarInCastRay;
14091 }
14092 // Throttle per parcel when not attachment or vehicle
14093 else
14094 {
14095 LandData land = World.GetLandData(m_host.GetWorldPosition());
14096 if (land != null)
14097 msAvailable = m_msPerRegionInCastRay * land.Area / 65536;
14098 }
14099 // Clamp for "oversized" parcels on varregions
14100 if (msAvailable > m_msMaxInCastRay)
14101 msAvailable = m_msMaxInCastRay;
14102
14103 // Check throttle data
14104 int fromCalledMs = calledMs - m_msThrottleInCastRay;
14105 lock (m_castRayCalls)
14106 {
14107 for (int i = m_castRayCalls.Count - 1; i >= 0; i--)
14108 {
14109 // Delete old calls from throttle data
14110 if (m_castRayCalls[i].CalledMs < fromCalledMs)
14111 m_castRayCalls.RemoveAt(i);
14112 // Use current region (in multi-region sims)
14113 else if (m_castRayCalls[i].RegionId == regionId)
14114 {
14115 // Reduce available time with recent calls
14116 if (m_castRayCalls[i].UserId == userId)
14117 msAvailable -= m_castRayCalls[i].UsedMs;
14118 }
14119 }
14120 }
14121
14122 // Return failure if not enough available time
14123 if (msAvailable < m_msMinInCastRay)
14124 {
14125 result.Add(new LSL_Integer(ScriptBaseClass.RCERR_CAST_TIME_EXCEEDED));
14126 return result;
14127 }
14022 14128
14023 // Initialize 14129 // Initialize
14024 m_host.AddScriptLPS(1);
14025 List<RayHit> rayHits = new List<RayHit>(); 14130 List<RayHit> rayHits = new List<RayHit>();
14026 LSL_List result = new LSL_List();
14027 float tol = m_floatToleranceInCastRay; 14131 float tol = m_floatToleranceInCastRay;
14028 float tol2 = m_floatTolerance2InCastRay; 14132 Vector3 pos1Ray = start;
14133 Vector3 pos2Ray = end;
14029 14134
14030 // Get input options 14135 // Get input options
14031 int rejectTypes = 0; 14136 int rejectTypes = 0;
@@ -14054,25 +14159,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14054 bool getLinkNum = ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) != 0); 14159 bool getLinkNum = ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) != 0);
14055 14160
14056 // Calculate some basic parameters 14161 // Calculate some basic parameters
14057 Vector3 ray = end - start; 14162 Vector3 vecRay = pos2Ray - pos1Ray;
14058 float rayLength = ray.Length(); 14163 float rayLength = vecRay.Length();
14059 14164
14060 // Try to get a mesher and return failure if none or degenerate ray 14165 // Try to get a mesher and return failure if none, degenerate ray, or max 0 hits
14061 IRendering primMesher = null; 14166 IRendering primMesher = null;
14062 List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory()); 14167 List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory());
14063 if (renderers.Count < 1 || rayLength < tol) 14168 if (renderers.Count < 1 || rayLength < tol || m_maxHitsInCastRay < 1)
14064 { 14169 {
14065 result.Add(new LSL_Integer(ScriptBaseClass.RCERR_UNKNOWN)); 14170 result.Add(new LSL_Integer(ScriptBaseClass.RCERR_UNKNOWN));
14066 return result; 14171 return result;
14067 } 14172 }
14068 primMesher = RenderingLoader.LoadRenderer(renderers[0]); 14173 primMesher = RenderingLoader.LoadRenderer(renderers[0]);
14069 14174
14070 // Used to translate and rotate world so ray is along negative Z axis from origo and
14071 // calculations mostly simplified to a 2D projecttion on the X-Y plane
14072 Vector3 posProj = new Vector3(-start);
14073 Quaternion rotProj = Vector3.RotationBetween(ray, new Vector3(0.0f, 0.0f, -1.0f));
14074 Quaternion rotBack = Quaternion.Inverse(rotProj);
14075
14076 // Iterate over all objects/groups and prims/parts in region 14175 // Iterate over all objects/groups and prims/parts in region
14077 World.ForEachSOG( 14176 World.ForEachSOG(
14078 delegate(SceneObjectGroup group) 14177 delegate(SceneObjectGroup group)
@@ -14115,83 +14214,118 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14115 if (!doPart) 14214 if (!doPart)
14116 continue; 14215 continue;
14117 } 14216 }
14118 // Parse prim/part if passed filters
14119 14217
14120 // Estimate bounding box from size box 14218 // Parse prim/part and project ray if passed filters
14121 Vector3 scaleSafe = part.Scale; 14219 Vector3 scalePart = part.Scale;
14122 if (!part.Shape.SculptEntry) 14220 Vector3 posPart = part.GetWorldPosition();
14123 scaleSafe = scaleSafe * (new Vector3(m_primSafetyCoeffX, m_primSafetyCoeffY, m_primSafetyCoeffZ)); 14221 Quaternion rotPart = part.GetWorldRotation();
14222 Quaternion rotPartInv = Quaternion.Inverse(rotPart);
14223 Vector3 pos1RayProj = ((pos1Ray - posPart) * rotPartInv) / scalePart;
14224 Vector3 pos2RayProj = ((pos2Ray - posPart) * rotPartInv) / scalePart;
14124 14225
14125 // Filter parts by bounding shapes 14226 // Filter parts by shape bounding boxes
14126 Vector3 posPartRel = part.GetWorldPosition() + posProj; 14227 Vector3 shapeBoxMax = new Vector3(0.5f, 0.5f, 0.5f);
14127 Vector3 posPartProj = posPartRel * rotProj; 14228 if (!part.Shape.SculptEntry)
14128 if (InBoundingShapes(ray, rayLength, scaleSafe, posPartRel, posPartProj, rotProj)) 14229 shapeBoxMax = shapeBoxMax * (new Vector3(m_primSafetyCoeffX, m_primSafetyCoeffY, m_primSafetyCoeffZ));
14230 shapeBoxMax = shapeBoxMax + (new Vector3(tol, tol, tol));
14231 if (RayIntersectsShapeBox(pos1RayProj, pos2RayProj, shapeBoxMax))
14129 { 14232 {
14130 // Prepare data needed to check for ray hits 14233 // Prepare data needed to check for ray hits
14131 RayTrans rayTrans = new RayTrans(); 14234 RayTrans rayTrans = new RayTrans();
14132 rayTrans.PartId = part.UUID; 14235 rayTrans.PartId = part.UUID;
14133 rayTrans.GroupId = part.ParentGroup.UUID; 14236 rayTrans.GroupId = part.ParentGroup.UUID;
14134 rayTrans.Link = group.PrimCount > 1 ? part.LinkNum : 0; 14237 rayTrans.Link = group.PrimCount > 1 ? part.LinkNum : 0;
14135 rayTrans.Scale = part.Scale; 14238 rayTrans.ScalePart = scalePart;
14136 rayTrans.PositionPartProj = posPartProj; 14239 rayTrans.PositionPart = posPart;
14137 rayTrans.PositionProj = posProj; 14240 rayTrans.RotationPart = rotPart;
14138 rayTrans.RotationPartProj = rotProj * part.GetWorldRotation(); 14241 rayTrans.ShapeNeedsEnds = true;
14139 rayTrans.RotationBack = rotBack; 14242 rayTrans.Position1Ray = pos1Ray;
14140 rayTrans.NeedsEnds = true; 14243 rayTrans.Position1RayProj = pos1RayProj;
14141 rayTrans.RayLength = rayLength; 14244 rayTrans.VectorRayProj = pos2RayProj - pos1RayProj;
14142 rayTrans.Tolerance = tol; 14245
14143 rayTrans.Tolerance2 = tol2; 14246 // Get detail level depending on type
14144 14247 int lod = 0;
14145 // Make an OMV prim to be able to mesh part 14248 // Mesh detail level
14146 Primitive omvPrim = part.Shape.ToOmvPrimitive(posPartProj, rayTrans.RotationPartProj); 14249 if (part.Shape.SculptEntry && part.Shape.SculptType == (byte)SculptType.Mesh)
14147 byte[] sculptAsset = null; 14250 lod = (int)m_meshLodInCastRay;
14148 if (omvPrim.Sculpt != null) 14251 // Sculpt detail level
14149 sculptAsset = World.AssetService.GetData(omvPrim.Sculpt.SculptTexture.ToString()); 14252 else if (part.Shape.SculptEntry && part.Shape.SculptType == (byte)SculptType.Mesh)
14150 14253 lod = (int)m_sculptLodInCastRay;
14151 // When part is mesh, get and check mesh 14254 // Shape detail level
14152 if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type == SculptType.Mesh && sculptAsset != null) 14255 else if (!part.Shape.SculptEntry)
14256 lod = (int)m_primLodInCastRay;
14257
14258 // Try to get cached mesh if configured
14259 ulong meshKey = 0;
14260 FacetedMesh mesh = null;
14261 if (m_useMeshCacheInCastRay)
14153 { 14262 {
14154 AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset); 14263 meshKey = part.Shape.GetMeshKey(Vector3.One, (float)(4 << lod));
14155 FacetedMesh mesh = null; 14264 lock (m_cachedMeshes)
14156 FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, DetailLevel.Highest, out mesh); 14265 {
14157 meshAsset = null; 14266 m_cachedMeshes.TryGetValue(meshKey, out mesh);
14158 AddRayInFacetedMesh(mesh, rayTrans, ref rayHits); 14267 }
14159 mesh = null;
14160 } 14268 }
14161 14269
14162 // When part is sculpt, create and check mesh 14270 // Create mesh if no cached mesh
14163 // Quirk: Generated sculpt mesh is about 2.8% smaller in X and Y than visual sculpt. 14271 if (mesh == null)
14164 else if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type != SculptType.Mesh && sculptAsset != null)
14165 { 14272 {
14166 IJ2KDecoder imgDecoder = World.RequestModuleInterface<IJ2KDecoder>(); 14273 // Make an OMV prim to be able to mesh part
14167 if (imgDecoder != null) 14274 Primitive omvPrim = part.Shape.ToOmvPrimitive(posPart, rotPart);
14275 byte[] sculptAsset = null;
14276 if (omvPrim.Sculpt != null)
14277 sculptAsset = World.AssetService.GetData(omvPrim.Sculpt.SculptTexture.ToString());
14278
14279 // When part is mesh, get mesh
14280 if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type == SculptType.Mesh && sculptAsset != null)
14281 {
14282 AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset);
14283 FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, m_meshLodInCastRay, out mesh);
14284 meshAsset = null;
14285 }
14286
14287 // When part is sculpt, create mesh
14288 // Quirk: Generated sculpt mesh is about 2.8% smaller in X and Y than visual sculpt.
14289 else if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type != SculptType.Mesh && sculptAsset != null)
14168 { 14290 {
14169 Image sculpt = imgDecoder.DecodeToImage(sculptAsset); 14291 IJ2KDecoder imgDecoder = World.RequestModuleInterface<IJ2KDecoder>();
14170 if (sculpt != null) 14292 if (imgDecoder != null)
14171 { 14293 {
14172 SimpleMesh mesh = primMesher.GenerateSimpleSculptMesh(omvPrim, (Bitmap)sculpt, DetailLevel.Medium); 14294 Image sculpt = imgDecoder.DecodeToImage(sculptAsset);
14173 sculpt.Dispose(); 14295 if (sculpt != null)
14174 AddRayInSimpleMesh(mesh, rayTrans, ref rayHits); 14296 {
14175 mesh = null; 14297 mesh = primMesher.GenerateFacetedSculptMesh(omvPrim, (Bitmap)sculpt, m_sculptLodInCastRay);
14298 sculpt.Dispose();
14299 }
14176 } 14300 }
14301 }
14302
14303 // When part is shape, create mesh
14304 else if (omvPrim.Sculpt == null)
14305 {
14306 if (
14307 omvPrim.PrimData.PathBegin == 0.0 && omvPrim.PrimData.PathEnd == 1.0 &&
14308 omvPrim.PrimData.PathTaperX == 0.0 && omvPrim.PrimData.PathTaperY == 0.0 &&
14309 omvPrim.PrimData.PathSkew == 0.0 &&
14310 omvPrim.PrimData.PathTwist - omvPrim.PrimData.PathTwistBegin == 0.0
14311 )
14312 rayTrans.ShapeNeedsEnds = false;
14313 mesh = primMesher.GenerateFacetedMesh(omvPrim, m_primLodInCastRay);
14177 } 14314 }
14178 }
14179 14315
14180 // When part is prim, create and check mesh 14316 // Cache mesh if configured
14181 else if (omvPrim.Sculpt == null) 14317 if (m_useMeshCacheInCastRay && mesh != null)
14182 { 14318 {
14183 if ( 14319 lock(m_cachedMeshes)
14184 omvPrim.PrimData.PathBegin == 0.0 && omvPrim.PrimData.PathEnd == 1.0 && 14320 {
14185 omvPrim.PrimData.PathTaperX == 0.0 && omvPrim.PrimData.PathTaperY == 0.0 && 14321 if (!m_cachedMeshes.ContainsKey(meshKey))
14186 omvPrim.PrimData.PathSkew == 0.0 && 14322 m_cachedMeshes.Add(meshKey, mesh);
14187 omvPrim.PrimData.PathTwist - omvPrim.PrimData.PathTwistBegin == 0.0 14323 }
14188 ) 14324 }
14189 rayTrans.NeedsEnds = false;
14190 SimpleMesh mesh = primMesher.GenerateSimpleMesh(omvPrim, DetailLevel.Medium);
14191 AddRayInSimpleMesh(mesh, rayTrans, ref rayHits);
14192 mesh = null;
14193 } 14325 }
14194 14326 // Check mesh for ray hits
14327 AddRayInFacetedMesh(mesh, rayTrans, ref rayHits);
14328 mesh = null;
14195 } 14329 }
14196 } 14330 }
14197 } 14331 }
@@ -14205,38 +14339,71 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14205 World.ForEachRootScenePresence( 14339 World.ForEachRootScenePresence(
14206 delegate (ScenePresence sp) 14340 delegate (ScenePresence sp)
14207 { 14341 {
14208 // Parse avatar
14209
14210 // Get bounding box 14342 // Get bounding box
14211 Vector3 lower; 14343 Vector3 lower;
14212 Vector3 upper; 14344 Vector3 upper;
14213 BoundingBoxOfScenePresence(sp, out lower, out upper); 14345 BoundingBoxOfScenePresence(sp, out lower, out upper);
14214 Vector3 scale = upper - lower; 14346 // Parse avatar
14215 14347 Vector3 scalePart = upper - lower;
14216 // Filter avatars by bounding shapes 14348 Vector3 posPart = sp.AbsolutePosition;
14217 Vector3 posPartRel = sp.AbsolutePosition + posProj + (lower + upper) * 0.5f * sp.Rotation; 14349 Quaternion rotPart = sp.GetWorldRotation();
14218 Vector3 posPartProj = posPartRel * rotProj; 14350 Quaternion rotPartInv = Quaternion.Inverse(rotPart);
14219 if (InBoundingShapes(ray, rayLength, scale, posPartRel, posPartProj, rotProj)) 14351 posPart = posPart + (lower + upper) * 0.5f * rotPart;
14352 // Project ray
14353 Vector3 pos1RayProj = ((pos1Ray - posPart) * rotPartInv) / scalePart;
14354 Vector3 pos2RayProj = ((pos2Ray - posPart) * rotPartInv) / scalePart;
14355
14356 // Filter avatars by shape bounding boxes
14357 Vector3 shapeBoxMax = new Vector3(0.5f + tol, 0.5f + tol, 0.5f + tol);
14358 if (RayIntersectsShapeBox(pos1RayProj, pos2RayProj, shapeBoxMax))
14220 { 14359 {
14221 // Prepare data needed to check for ray hits 14360 // Prepare data needed to check for ray hits
14222 RayTrans rayTrans = new RayTrans(); 14361 RayTrans rayTrans = new RayTrans();
14223 rayTrans.PartId = sp.UUID; 14362 rayTrans.PartId = sp.UUID;
14224 rayTrans.GroupId = sp.ParentPart != null ? sp.ParentPart.ParentGroup.UUID : sp.UUID; 14363 rayTrans.GroupId = sp.ParentPart != null ? sp.ParentPart.ParentGroup.UUID : sp.UUID;
14225 rayTrans.Link = sp.ParentPart != null ? UUID2LinkNumber(sp.ParentPart, sp.UUID) : 0; 14364 rayTrans.Link = sp.ParentPart != null ? UUID2LinkNumber(sp.ParentPart, sp.UUID) : 0;
14226 rayTrans.Scale = scale; 14365 rayTrans.ScalePart = scalePart;
14227 rayTrans.PositionPartProj = posPartProj; 14366 rayTrans.PositionPart = posPart;
14228 rayTrans.PositionProj = posProj; 14367 rayTrans.RotationPart = rotPart;
14229 rayTrans.RotationPartProj = rotProj * sp.Rotation; 14368 rayTrans.ShapeNeedsEnds = false;
14230 rayTrans.RotationBack = rotBack; 14369 rayTrans.Position1Ray = pos1Ray;
14231 rayTrans.NeedsEnds = false; 14370 rayTrans.Position1RayProj = pos1RayProj;
14232 rayTrans.RayLength = rayLength; 14371 rayTrans.VectorRayProj = pos2RayProj - pos1RayProj;
14233 rayTrans.Tolerance = tol; 14372
14234 rayTrans.Tolerance2 = tol2; 14373 // Try to get cached mesh if configured
14235 14374 PrimitiveBaseShape prim = PrimitiveBaseShape.CreateSphere();
14236 // Make OMV prim, create and check mesh 14375 int lod = (int)m_avatarLodInCastRay;
14237 Primitive omvPrim = MakeOpenMetaversePrim(scale, posPartProj, rayTrans.RotationPartProj, ScriptBaseClass.PRIM_TYPE_SPHERE); 14376 ulong meshKey = prim.GetMeshKey(Vector3.One, (float)(4 << lod));
14238 SimpleMesh mesh = primMesher.GenerateSimpleMesh(omvPrim, DetailLevel.Medium); 14377 FacetedMesh mesh = null;
14239 AddRayInSimpleMesh(mesh, rayTrans, ref rayHits); 14378 if (m_useMeshCacheInCastRay)
14379 {
14380 lock (m_cachedMeshes)
14381 {
14382 m_cachedMeshes.TryGetValue(meshKey, out mesh);
14383 }
14384 }
14385
14386 // Create mesh if no cached mesh
14387 if (mesh == null)
14388 {
14389 // Make OMV prim and create mesh
14390 prim.Scale = scalePart;
14391 Primitive omvPrim = prim.ToOmvPrimitive(posPart, rotPart);
14392 mesh = primMesher.GenerateFacetedMesh(omvPrim, m_avatarLodInCastRay);
14393
14394 // Cache mesh if configured
14395 if (m_useMeshCacheInCastRay && mesh != null)
14396 {
14397 lock(m_cachedMeshes)
14398 {
14399 if (!m_cachedMeshes.ContainsKey(meshKey))
14400 m_cachedMeshes.Add(meshKey, mesh);
14401 }
14402 }
14403 }
14404
14405 // Check mesh for ray hits
14406 AddRayInFacetedMesh(mesh, rayTrans, ref rayHits);
14240 mesh = null; 14407 mesh = null;
14241 } 14408 }
14242 } 14409 }
@@ -14248,32 +14415,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14248 { 14415 {
14249 // Parse terrain 14416 // Parse terrain
14250 14417
14251 // Mesh terrain and check projected bounding box 14418 // Mesh terrain and check bounding box
14252 Vector3 posPartProj = posProj * rotProj;
14253 Quaternion rotPartProj = rotProj;
14254 Vector3 lower; 14419 Vector3 lower;
14255 Vector3 upper; 14420 Vector3 upper;
14256 List<Tri> triangles = TrisFromHeightmapUnderRay(start, end, out lower, out upper); 14421 List<Tri> triangles = TrisFromHeightmapUnderRay(pos1Ray, pos2Ray, out lower, out upper);
14257 Vector3 lowerBox = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); 14422 lower.Z -= tol;
14258 Vector3 upperBox = new Vector3(float.MinValue, float.MinValue, float.MinValue); 14423 upper.Z += tol;
14259 int dummy = 0; 14424 if ((pos1Ray.Z >= lower.Z || pos2Ray.Z >= lower.Z) && (pos1Ray.Z <= upper.Z || pos2Ray.Z <= upper.Z))
14260 AddBoundingBoxOfSimpleBox(lower, upper, posPartProj, rotPartProj, true, ref lowerBox, ref upperBox, ref dummy);
14261 if (lowerBox.X <= tol && lowerBox.Y <= tol && lowerBox.Z <= tol && upperBox.X >= -tol && upperBox.Y >= -tol && upperBox.Z >= -rayLength - tol)
14262 { 14425 {
14263 // Prepare data needed to check for ray hits 14426 // Prepare data needed to check for ray hits
14264 RayTrans rayTrans = new RayTrans(); 14427 RayTrans rayTrans = new RayTrans();
14265 rayTrans.PartId = UUID.Zero; 14428 rayTrans.PartId = UUID.Zero;
14266 rayTrans.GroupId = UUID.Zero; 14429 rayTrans.GroupId = UUID.Zero;
14267 rayTrans.Link = 0; 14430 rayTrans.Link = 0;
14268 rayTrans.Scale = new Vector3 (1.0f, 1.0f, 1.0f); 14431 rayTrans.ScalePart = new Vector3 (1.0f, 1.0f, 1.0f);
14269 rayTrans.PositionPartProj = posPartProj; 14432 rayTrans.PositionPart = Vector3.Zero;
14270 rayTrans.PositionProj = posProj; 14433 rayTrans.RotationPart = Quaternion.Identity;
14271 rayTrans.RotationPartProj = rotPartProj; 14434 rayTrans.ShapeNeedsEnds = true;
14272 rayTrans.RotationBack = rotBack; 14435 rayTrans.Position1Ray = pos1Ray;
14273 rayTrans.NeedsEnds = true; 14436 rayTrans.Position1RayProj = pos1Ray;
14274 rayTrans.RayLength = rayLength; 14437 rayTrans.VectorRayProj = vecRay;
14275 rayTrans.Tolerance = tol;
14276 rayTrans.Tolerance2 = tol2;
14277 14438
14278 // Check mesh 14439 // Check mesh
14279 AddRayInTris(triangles, rayTrans, ref rayHits); 14440 AddRayInTris(triangles, rayTrans, ref rayHits);
@@ -14347,6 +14508,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14347 result.Add(new LSL_Vector(rayHit.Normal)); 14508 result.Add(new LSL_Vector(rayHit.Normal));
14348 } 14509 }
14349 result.Add(new LSL_Integer(hitCount)); 14510 result.Add(new LSL_Integer(hitCount));
14511
14512 // Add to throttle data
14513 stopWatch.Stop();
14514 CastRayCall castRayCall = new CastRayCall();
14515 castRayCall.RegionId = regionId;
14516 castRayCall.UserId = userId;
14517 castRayCall.CalledMs = calledMs;
14518 castRayCall.UsedMs = (int)stopWatch.ElapsedMilliseconds;
14519 lock (m_castRayCalls)
14520 {
14521 m_castRayCalls.Add(castRayCall);
14522 }
14523
14524 // Return hits
14350 return result; 14525 return result;
14351 } 14526 }
14352 14527
@@ -14358,15 +14533,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14358 public UUID PartId; 14533 public UUID PartId;
14359 public UUID GroupId; 14534 public UUID GroupId;
14360 public int Link; 14535 public int Link;
14361 public Vector3 Scale; 14536 public Vector3 ScalePart;
14362 public Vector3 PositionPartProj; 14537 public Vector3 PositionPart;
14363 public Vector3 PositionProj; 14538 public Quaternion RotationPart;
14364 public Quaternion RotationPartProj; 14539 public bool ShapeNeedsEnds;
14365 public Quaternion RotationBack; 14540 public Vector3 Position1Ray;
14366 public bool NeedsEnds; 14541 public Vector3 Position1RayProj;
14367 public float RayLength; 14542 public Vector3 VectorRayProj;
14368 public float Tolerance;
14369 public float Tolerance2;
14370 } 14543 }
14371 14544
14372 /// <summary> 14545 /// <summary>
@@ -14383,21 +14556,74 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14383 } 14556 }
14384 14557
14385 /// <summary> 14558 /// <summary>
14386 /// Helper to parse SimpleMesh for ray hits. 14559 /// Struct for llCastRay throttle data.
14387 /// </summary> 14560 /// </summary>
14388 private void AddRayInSimpleMesh(SimpleMesh mesh, RayTrans rayTrans, ref List<RayHit> rayHits) 14561 public struct CastRayCall
14389 { 14562 {
14390 if (mesh != null) 14563 public UUID RegionId;
14564 public UUID UserId;
14565 public int CalledMs;
14566 public int UsedMs;
14567 }
14568
14569 /// <summary>
14570 /// Helper to check if a ray intersects a shape bounding box.
14571 /// </summary>
14572 private bool RayIntersectsShapeBox(Vector3 pos1RayProj, Vector3 pos2RayProj, Vector3 shapeBoxMax)
14573 {
14574 // Skip if ray can't intersect bounding box;
14575 Vector3 rayBoxProjMin = Vector3.Min(pos1RayProj, pos2RayProj);
14576 Vector3 rayBoxProjMax = Vector3.Max(pos1RayProj, pos2RayProj);
14577 if (
14578 rayBoxProjMin.X > shapeBoxMax.X || rayBoxProjMin.Y > shapeBoxMax.Y || rayBoxProjMin.Z > shapeBoxMax.Z ||
14579 rayBoxProjMax.X < -shapeBoxMax.X || rayBoxProjMax.Y < -shapeBoxMax.Y || rayBoxProjMax.Z < -shapeBoxMax.Z
14580 )
14581 return false;
14582
14583 // Check if ray intersect any bounding box side
14584 int sign = 0;
14585 float dist = 0.0f;
14586 Vector3 posProj = Vector3.Zero;
14587 Vector3 vecRayProj = pos2RayProj - pos1RayProj;
14588
14589 // Check both X sides unless ray is parallell to them
14590 if (Math.Abs(vecRayProj.X) > m_floatToleranceInCastRay)
14591 {
14592 for (sign = -1; sign <= 1; sign += 2)
14593 {
14594 dist = ((float)sign * shapeBoxMax.X - pos1RayProj.X) / vecRayProj.X;
14595 posProj = pos1RayProj + vecRayProj * dist;
14596 if (Math.Abs(posProj.Y) <= shapeBoxMax.Y && Math.Abs(posProj.Z) <= shapeBoxMax.Z)
14597 return true;
14598 }
14599 }
14600
14601 // Check both Y sides unless ray is parallell to them
14602 if (Math.Abs(vecRayProj.Y) > m_floatToleranceInCastRay)
14603 {
14604 for (sign = -1; sign <= 1; sign += 2)
14605 {
14606 dist = ((float)sign * shapeBoxMax.Y - pos1RayProj.Y) / vecRayProj.Y;
14607 posProj = pos1RayProj + vecRayProj * dist;
14608 if (Math.Abs(posProj.X) <= shapeBoxMax.X && Math.Abs(posProj.Z) <= shapeBoxMax.Z)
14609 return true;
14610 }
14611 }
14612
14613 // Check both Z sides unless ray is parallell to them
14614 if (Math.Abs(vecRayProj.Z) > m_floatToleranceInCastRay)
14391 { 14615 {
14392 for (int i = 0; i < mesh.Indices.Count; i += 3) 14616 for (sign = -1; sign <= 1; sign += 2)
14393 { 14617 {
14394 Tri triangle = new Tri(); 14618 dist = ((float)sign * shapeBoxMax.Z - pos1RayProj.Z) / vecRayProj.Z;
14395 triangle.p1 = mesh.Vertices[mesh.Indices[i]].Position; 14619 posProj = pos1RayProj + vecRayProj * dist;
14396 triangle.p2 = mesh.Vertices[mesh.Indices[i + 1]].Position; 14620 if (Math.Abs(posProj.X) <= shapeBoxMax.X && Math.Abs(posProj.Y) <= shapeBoxMax.Y)
14397 triangle.p3 = mesh.Vertices[mesh.Indices[i + 2]].Position; 14621 return true;
14398 AddRayInTri(triangle, rayTrans, ref rayHits);
14399 } 14622 }
14400 } 14623 }
14624
14625 // No hits on bounding box so return false
14626 return false;
14401 } 14627 }
14402 14628
14403 /// <summary> 14629 /// <summary>
@@ -14409,7 +14635,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14409 { 14635 {
14410 foreach (Face face in mesh.Faces) 14636 foreach (Face face in mesh.Faces)
14411 { 14637 {
14412 for (int i = 0; i <face.Indices.Count; i += 3) 14638 for (int i = 0; i < face.Indices.Count; i += 3)
14413 { 14639 {
14414 Tri triangle = new Tri(); 14640 Tri triangle = new Tri();
14415 triangle.p1 = face.Vertices[face.Indices[i]].Position; 14641 triangle.p1 = face.Vertices[face.Indices[i]].Position;
@@ -14435,23 +14661,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14435 /// <summary> 14661 /// <summary>
14436 /// Helper to add ray hit in a Tri (triangle). 14662 /// Helper to add ray hit in a Tri (triangle).
14437 /// </summary> 14663 /// </summary>
14438 private void AddRayInTri(Tri triangle, RayTrans rayTrans, ref List<RayHit> rayHits) 14664 private void AddRayInTri(Tri triProj, RayTrans rayTrans, ref List<RayHit> rayHits)
14439 { 14665 {
14440 // Check for hit in triangle 14666 // Check for hit in triangle
14441 float distance; 14667 Vector3 posHitProj;
14442 Vector3 posHit; 14668 Vector3 normalProj;
14443 Vector3 normal; 14669 if (HitRayInTri(triProj, rayTrans.Position1RayProj, rayTrans.VectorRayProj, out posHitProj, out normalProj))
14444 if (HitRayInTri(triangle, rayTrans, out distance, out posHit, out normal)) 14670 {
14445 { 14671 // Hack to circumvent ghost face bug in PrimMesher by removing hits in (ghost) face plane through shape center
14446 // Project hit part back to normal coordinate system 14672 if (Math.Abs(Vector3.Dot(posHitProj, normalProj)) < m_floatToleranceInCastRay && !rayTrans.ShapeNeedsEnds)
14447 Vector3 posPart = rayTrans.PositionPartProj * rayTrans.RotationBack - rayTrans.PositionProj;
14448 // Hack to circumvent ghost face bug in PrimMesher by removing hits in (ghost) faces plane through shape center
14449 if (Math.Abs(Vector3.Dot(posPart, normal) - Vector3.Dot(posHit, normal)) < rayTrans.Tolerance && !rayTrans.NeedsEnds)
14450 return; 14673 return;
14451 // Remove duplicate hits at triangle edges and intersections 14674
14675 // Transform hit and normal to region coordinate system
14676 Vector3 posHit = rayTrans.PositionPart + (posHitProj * rayTrans.ScalePart) * rayTrans.RotationPart;
14677 Vector3 normal = Vector3.Normalize((normalProj * rayTrans.ScalePart) * rayTrans.RotationPart);
14678
14679 // Remove duplicate hits at triangle intersections
14680 float distance = Vector3.Distance(rayTrans.Position1Ray, posHit);
14452 for (int i = rayHits.Count - 1; i >= 0; i--) 14681 for (int i = rayHits.Count - 1; i >= 0; i--)
14453 { 14682 {
14454 if (rayHits[i].PartId == rayTrans.PartId && Math.Abs(rayHits[i].Distance - distance) < rayTrans.Tolerance2) 14683 if (rayHits[i].PartId != rayTrans.PartId)
14684 break;
14685 if (Math.Abs(rayHits[i].Distance - distance) < m_floatTolerance2InCastRay)
14455 return; 14686 return;
14456 } 14687 }
14457 14688
@@ -14468,76 +14699,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14468 } 14699 }
14469 14700
14470 /// <summary> 14701 /// <summary>
14471 /// Helper to find ray hit in a Tri (triangle). 14702 /// Helper to find ray hit in triangle
14472 /// </summary> 14703 /// </summary>
14473 private bool HitRayInTri(Tri triangle, RayTrans rayTrans, out float distance, out Vector3 posHit, out Vector3 normal) 14704 bool HitRayInTri(Tri triProj, Vector3 pos1RayProj, Vector3 vecRayProj, out Vector3 posHitProj, out Vector3 normalProj)
14474 { 14705 {
14475 // Initialize 14706 float tol = m_floatToleranceInCastRay;
14476 distance = 0.0f; 14707 posHitProj = Vector3.Zero;
14477 posHit = Vector3.Zero; 14708
14478 normal = Vector3.Zero; 14709 // Calculate triangle edge vectors
14479 float tol = rayTrans.Tolerance; 14710 Vector3 vec1Proj = triProj.p2 - triProj.p1;
14480 14711 Vector3 vec2Proj = triProj.p3 - triProj.p2;
14481 // Project triangle on X-Y plane 14712 Vector3 vec3Proj = triProj.p1 - triProj.p3;
14482 Vector3 pos1 = triangle.p1 * rayTrans.Scale * rayTrans.RotationPartProj + rayTrans.PositionPartProj;
14483 Vector3 pos2 = triangle.p2 * rayTrans.Scale * rayTrans.RotationPartProj + rayTrans.PositionPartProj;
14484 Vector3 pos3 = triangle.p3 * rayTrans.Scale * rayTrans.RotationPartProj + rayTrans.PositionPartProj;
14485
14486 // Check if ray/origo inside triangle bounding rectangle
14487 Vector3 lower = Vector3.Min(pos1, Vector3.Min(pos2, pos3));
14488 Vector3 upper = Vector3.Max(pos1, Vector3.Max(pos2, pos3));
14489 if (lower.X > tol || lower.Y > tol || lower.Z > tol || upper.X < -tol || upper.Y < -tol || upper.Z < -rayTrans.RayLength - tol)
14490 return false;
14491 14713
14492 // Check if ray/origo inside every edge or reverse "outside" every edge on exit 14714 // Calculate triangle normal
14493 float dist; 14715 normalProj = Vector3.Cross(vec1Proj, vec2Proj);
14494 bool inside = true; 14716
14495 bool outside = true; 14717 // Skip if degenerate triangle or ray parallell with triangle plane
14496 Vector3 vec1 = pos2 - pos1; 14718 float divisor = Vector3.Dot(vecRayProj, normalProj);
14497 dist = pos1.X * vec1.Y - pos1.Y * vec1.X; 14719 if (Math.Abs(divisor) < tol)
14498 if (dist < -tol)
14499 inside = false;
14500 if (dist > tol)
14501 outside = false;
14502 Vector3 vec2 = pos3 - pos2;
14503 dist = pos2.X * vec2.Y - pos2.Y * vec2.X;
14504 if (dist < -tol)
14505 inside = false;
14506 if (dist > tol)
14507 outside = false;
14508 Vector3 vec3 = pos1 - pos3;
14509 dist = pos3.X * vec3.Y - pos3.Y * vec3.X;
14510 if (dist < -tol)
14511 inside = false;
14512 if (dist > tol)
14513 outside = false;
14514
14515 // Skip if ray/origo outside
14516 if (!inside && !(outside && m_detectExitsInCastRay))
14517 return false; 14720 return false;
14518 14721
14519 // Calculate normal 14722 // Skip if exit and not configured to detect
14520 Vector3 normalProj = Vector3.Cross(vec1, vec2); 14723 if (divisor > tol && !m_detectExitsInCastRay)
14521 float normalLength = normalProj.Length();
14522 // Skip if degenerate triangle
14523 if (normalLength < tol)
14524 return false; 14724 return false;
14525 normalProj = normalProj / normalLength; 14725
14526 // Skip if ray parallell to triangle plane 14726 // Skip if outside ray ends
14527 if (Math.Abs(normalProj.Z) < tol) 14727 float distanceProj = Vector3.Dot(triProj.p1 - pos1RayProj, normalProj) / divisor;
14728 if (distanceProj < -tol || distanceProj > 1 + tol)
14528 return false; 14729 return false;
14529 14730
14530 // Calculate distance 14731 // Calculate hit position in triangle
14531 distance = Vector3.Dot(normalProj, pos2) / normalProj.Z * -1.0f; 14732 posHitProj = pos1RayProj + vecRayProj * distanceProj;
14532 // Skip if outside ray 14733
14533 if (distance < -tol || distance > rayTrans.RayLength + tol) 14734 // Skip if outside triangle bounding box
14735 Vector3 triProjMin = Vector3.Min(Vector3.Min(triProj.p1, triProj.p2), triProj.p3);
14736 Vector3 triProjMax = Vector3.Max(Vector3.Max(triProj.p1, triProj.p2), triProj.p3);
14737 if (
14738 posHitProj.X < triProjMin.X - tol || posHitProj.Y < triProjMin.Y - tol || posHitProj.Z < triProjMin.Z - tol ||
14739 posHitProj.X > triProjMax.X + tol || posHitProj.Y > triProjMax.Y + tol || posHitProj.Z > triProjMax.Z + tol
14740 )
14534 return false; 14741 return false;
14535 14742
14536 // Calculate projected hit position 14743 // Skip if outside triangle
14537 Vector3 posHitProj = new Vector3(0.0f, 0.0f, -distance); 14744 if (
14538 // Project hit back to normal coordinate system 14745 Vector3.Dot(Vector3.Cross(vec1Proj, normalProj), posHitProj - triProj.p1) > tol ||
14539 posHit = posHitProj * rayTrans.RotationBack - rayTrans.PositionProj; 14746 Vector3.Dot(Vector3.Cross(vec2Proj, normalProj), posHitProj - triProj.p2) > tol ||
14540 normal = normalProj * rayTrans.RotationBack; 14747 Vector3.Dot(Vector3.Cross(vec3Proj, normalProj), posHitProj - triProj.p3) > tol
14748 )
14749 return false;
14750
14751 // Return hit
14541 return true; 14752 return true;
14542 } 14753 }
14543 14754
@@ -14660,24 +14871,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14660 y = Util.Clamp<int>(yInt+1, 0, World.Heightmap.Height - 1); 14871 y = Util.Clamp<int>(yInt+1, 0, World.Heightmap.Height - 1);
14661 Vector3 pos2 = new Vector3(x, y, (float)World.Heightmap[x, y]); 14872 Vector3 pos2 = new Vector3(x, y, (float)World.Heightmap[x, y]);
14662 // Adjust bounding box 14873 // Adjust bounding box
14663 zLower = Math.Min(zLower, pos1.Z); 14874 zLower = Math.Min(zLower, pos2.Z);
14664 zUpper = Math.Max(zUpper, pos1.Z); 14875 zUpper = Math.Max(zUpper, pos2.Z);
14665 14876
14666 // Corner 3 of 1x1 rectangle 14877 // Corner 3 of 1x1 rectangle
14667 x = Util.Clamp<int>(xInt, 0, World.Heightmap.Width - 1); 14878 x = Util.Clamp<int>(xInt, 0, World.Heightmap.Width - 1);
14668 y = Util.Clamp<int>(yInt, 0, World.Heightmap.Height - 1); 14879 y = Util.Clamp<int>(yInt, 0, World.Heightmap.Height - 1);
14669 Vector3 pos3 = new Vector3(x, y, (float)World.Heightmap[x, y]); 14880 Vector3 pos3 = new Vector3(x, y, (float)World.Heightmap[x, y]);
14670 // Adjust bounding box 14881 // Adjust bounding box
14671 zLower = Math.Min(zLower, pos1.Z); 14882 zLower = Math.Min(zLower, pos3.Z);
14672 zUpper = Math.Max(zUpper, pos1.Z); 14883 zUpper = Math.Max(zUpper, pos3.Z);
14673 14884
14674 // Corner 4 of 1x1 rectangle 14885 // Corner 4 of 1x1 rectangle
14675 x = Util.Clamp<int>(xInt+1, 0, World.Heightmap.Width - 1); 14886 x = Util.Clamp<int>(xInt+1, 0, World.Heightmap.Width - 1);
14676 y = Util.Clamp<int>(yInt, 0, World.Heightmap.Height - 1); 14887 y = Util.Clamp<int>(yInt, 0, World.Heightmap.Height - 1);
14677 Vector3 pos4 = new Vector3(x, y, (float)World.Heightmap[x, y]); 14888 Vector3 pos4 = new Vector3(x, y, (float)World.Heightmap[x, y]);
14678 // Adjust bounding box 14889 // Adjust bounding box
14679 zLower = Math.Min(zLower, pos1.Z); 14890 zLower = Math.Min(zLower, pos4.Z);
14680 zUpper = Math.Max(zUpper, pos1.Z); 14891 zUpper = Math.Max(zUpper, pos4.Z);
14681 14892
14682 // Add triangle 1 14893 // Add triangle 1
14683 Tri triangle1 = new Tri(); 14894 Tri triangle1 = new Tri();
@@ -14695,25 +14906,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14695 } 14906 }
14696 14907
14697 /// <summary> 14908 /// <summary>
14698 /// Helper to check if a ray intersects bounding shapes.
14699 /// </summary>
14700 private bool InBoundingShapes(Vector3 ray, float rayLength, Vector3 scale, Vector3 posPartRel, Vector3 posPartProj, Quaternion rotProj)
14701 {
14702 float tol = m_floatToleranceInCastRay;
14703
14704 // Check if ray intersects projected bounding box
14705 Vector3 lowerBox = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
14706 Vector3 upperBox = new Vector3(float.MinValue, float.MinValue, float.MinValue);
14707 int dummy = 0;
14708 AddBoundingBoxOfSimpleBox(scale * -0.5f, scale * 0.5f, posPartProj, rotProj, true, ref lowerBox, ref upperBox, ref dummy);
14709 if (lowerBox.X > tol || lowerBox.Y > tol || lowerBox.Z > tol || upperBox.X < -tol || upperBox.Y < -tol || upperBox.Z < -rayLength - tol)
14710 return false;
14711
14712 // Passed bounding shape filters, so return true
14713 return true;
14714 }
14715
14716 /// <summary>
14717 /// Helper to get link number for a UUID. 14909 /// Helper to get link number for a UUID.
14718 /// </summary> 14910 /// </summary>
14719 private int UUID2LinkNumber(SceneObjectPart part, UUID id) 14911 private int UUID2LinkNumber(SceneObjectPart part, UUID id)
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 54620d1..4e383f8 100644..100755
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -1872,6 +1872,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1872 IScriptInstance instance = GetInstance(itemID); 1872 IScriptInstance instance = GetInstance(itemID);
1873 if (instance != null) 1873 if (instance != null)
1874 instance.ApiResetScript(); 1874 instance.ApiResetScript();
1875
1876 // Send the new number of threads that are in use by the thread
1877 // pool, I believe that by adding them to the locations where the
1878 // script is changing states that I will catch all changes to the
1879 // thread pool
1880 m_Scene.setThreadCount(m_ThreadPool.InUseThreads);
1875 } 1881 }
1876 1882
1877 public void ResetScript(UUID itemID) 1883 public void ResetScript(UUID itemID)
@@ -1879,6 +1885,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1879 IScriptInstance instance = GetInstance(itemID); 1885 IScriptInstance instance = GetInstance(itemID);
1880 if (instance != null) 1886 if (instance != null)
1881 instance.ResetScript(m_WaitForEventCompletionOnScriptStop); 1887 instance.ResetScript(m_WaitForEventCompletionOnScriptStop);
1888
1889 // Send the new number of threads that are in use by the thread
1890 // pool, I believe that by adding them to the locations where the
1891 // script is changing states that I will catch all changes to the
1892 // thread pool
1893 m_Scene.setThreadCount(m_ThreadPool.InUseThreads);
1882 } 1894 }
1883 1895
1884 public void StartScript(UUID itemID) 1896 public void StartScript(UUID itemID)
@@ -1888,6 +1900,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1888 instance.Start(); 1900 instance.Start();
1889 else 1901 else
1890 m_runFlags.AddOrUpdate(itemID, true, 240); 1902 m_runFlags.AddOrUpdate(itemID, true, 240);
1903
1904 // Send the new number of threads that are in use by the thread
1905 // pool, I believe that by adding them to the locations where the
1906 // script is changing states that I will catch all changes to the
1907 // thread pool
1908 m_Scene.setThreadCount(m_ThreadPool.InUseThreads);
1891 } 1909 }
1892 1910
1893 public void StopScript(UUID itemID) 1911 public void StopScript(UUID itemID)
@@ -1903,6 +1921,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1903// m_log.DebugFormat("[XENGINE]: Could not find script with ID {0} to stop in {1}", itemID, World.Name); 1921// m_log.DebugFormat("[XENGINE]: Could not find script with ID {0} to stop in {1}", itemID, World.Name);
1904 m_runFlags.AddOrUpdate(itemID, false, 240); 1922 m_runFlags.AddOrUpdate(itemID, false, 240);
1905 } 1923 }
1924
1925 // Send the new number of threads that are in use by the thread
1926 // pool, I believe that by adding them to the locations where the
1927 // script is changing states that I will catch all changes to the
1928 // thread pool
1929 m_Scene.setThreadCount(m_ThreadPool.InUseThreads);
1906 } 1930 }
1907 1931
1908 public DetectParams GetDetectParams(UUID itemID, int idx) 1932 public DetectParams GetDetectParams(UUID itemID, int idx)
@@ -2393,6 +2417,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
2393 instance.Suspend(); 2417 instance.Suspend();
2394// else 2418// else
2395// m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID); 2419// m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID);
2420
2421 // Send the new number of threads that are in use by the thread
2422 // pool, I believe that by adding them to the locations where the
2423 // script is changing states that I will catch all changes to the
2424 // thread pool
2425 m_Scene.setThreadCount(m_ThreadPool.InUseThreads);
2396 } 2426 }
2397 2427
2398 public void ResumeScript(UUID itemID) 2428 public void ResumeScript(UUID itemID)
@@ -2404,6 +2434,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
2404 instance.Resume(); 2434 instance.Resume();
2405// else 2435// else
2406// m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID); 2436// m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID);
2437
2438 // Send the new number of threads that are in use by the thread
2439 // pool, I believe that by adding them to the locations where the
2440 // script is changing states that I will catch all changes to the
2441 // thread pool
2442 m_Scene.setThreadCount(m_ThreadPool.InUseThreads);
2407 } 2443 }
2408 2444
2409 public bool HasScript(UUID itemID, out bool running) 2445 public bool HasScript(UUID itemID, out bool running)