diff options
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 8656 |
1 files changed, 4328 insertions, 4328 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index b3fa2f4..882f4a7 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -1,4328 +1,4328 @@ | |||
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 | ||
28 | using System; | 28 | using System; |
29 | using System.Xml; | 29 | using System.Xml; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Reflection; | 31 | using System.Reflection; |
32 | using System.Timers; | 32 | using System.Timers; |
33 | using OpenMetaverse; | 33 | using OpenMetaverse; |
34 | using log4net; | 34 | using log4net; |
35 | using OpenSim.Framework; | 35 | using OpenSim.Framework; |
36 | using OpenSim.Framework.Client; | 36 | using OpenSim.Framework.Client; |
37 | using OpenSim.Region.Framework.Interfaces; | 37 | using OpenSim.Region.Framework.Interfaces; |
38 | using OpenSim.Region.Framework.Scenes.Animation; | 38 | using OpenSim.Region.Framework.Scenes.Animation; |
39 | using OpenSim.Region.Framework.Scenes.Types; | 39 | using OpenSim.Region.Framework.Scenes.Types; |
40 | using OpenSim.Region.Physics.Manager; | 40 | using OpenSim.Region.Physics.Manager; |
41 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | 41 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; |
42 | using OpenSim.Services.Interfaces; | 42 | using OpenSim.Services.Interfaces; |
43 | 43 | ||
44 | namespace OpenSim.Region.Framework.Scenes | 44 | namespace OpenSim.Region.Framework.Scenes |
45 | { | 45 | { |
46 | enum ScriptControlled : uint | 46 | enum ScriptControlled : uint |
47 | { | 47 | { |
48 | CONTROL_ZERO = 0, | 48 | CONTROL_ZERO = 0, |
49 | CONTROL_FWD = 1, | 49 | CONTROL_FWD = 1, |
50 | CONTROL_BACK = 2, | 50 | CONTROL_BACK = 2, |
51 | CONTROL_LEFT = 4, | 51 | CONTROL_LEFT = 4, |
52 | CONTROL_RIGHT = 8, | 52 | CONTROL_RIGHT = 8, |
53 | CONTROL_UP = 16, | 53 | CONTROL_UP = 16, |
54 | CONTROL_DOWN = 32, | 54 | CONTROL_DOWN = 32, |
55 | CONTROL_ROT_LEFT = 256, | 55 | CONTROL_ROT_LEFT = 256, |
56 | CONTROL_ROT_RIGHT = 512, | 56 | CONTROL_ROT_RIGHT = 512, |
57 | CONTROL_LBUTTON = 268435456, | 57 | CONTROL_LBUTTON = 268435456, |
58 | CONTROL_ML_LBUTTON = 1073741824 | 58 | CONTROL_ML_LBUTTON = 1073741824 |
59 | } | 59 | } |
60 | 60 | ||
61 | struct ScriptControllers | 61 | struct ScriptControllers |
62 | { | 62 | { |
63 | public UUID itemID; | 63 | public UUID itemID; |
64 | public ScriptControlled ignoreControls; | 64 | public ScriptControlled ignoreControls; |
65 | public ScriptControlled eventControls; | 65 | public ScriptControlled eventControls; |
66 | } | 66 | } |
67 | 67 | ||
68 | public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence, List<Vector3> coarseLocations, List<UUID> avatarUUIDs); | 68 | public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence, List<Vector3> coarseLocations, List<UUID> avatarUUIDs); |
69 | 69 | ||
70 | public class ScenePresence : EntityBase, ISceneEntity | 70 | public class ScenePresence : EntityBase, ISceneEntity |
71 | { | 71 | { |
72 | // ~ScenePresence() | 72 | // ~ScenePresence() |
73 | // { | 73 | // { |
74 | // m_log.Debug("[ScenePresence] Destructor called"); | 74 | // m_log.Debug("[ScenePresence] Destructor called"); |
75 | // } | 75 | // } |
76 | 76 | ||
77 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 77 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
78 | 78 | ||
79 | private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; | 79 | private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; |
80 | // private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); | 80 | // private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); |
81 | private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); | 81 | private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); |
82 | private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); | 82 | private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); |
83 | 83 | ||
84 | /// <summary> | 84 | /// <summary> |
85 | /// Experimentally determined "fudge factor" to make sit-target positions | 85 | /// Experimentally determined "fudge factor" to make sit-target positions |
86 | /// the same as in SecondLife. Fudge factor was tested for 36 different | 86 | /// the same as in SecondLife. Fudge factor was tested for 36 different |
87 | /// test cases including prims of type box, sphere, cylinder, and torus, | 87 | /// test cases including prims of type box, sphere, cylinder, and torus, |
88 | /// with varying parameters for sit target location, prim size, prim | 88 | /// with varying parameters for sit target location, prim size, prim |
89 | /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis | 89 | /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis |
90 | /// issue #1716 | 90 | /// issue #1716 |
91 | /// </summary> | 91 | /// </summary> |
92 | // private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); | 92 | // private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); |
93 | // Value revised by KF 091121 by comparison with SL. | 93 | // Value revised by KF 091121 by comparison with SL. |
94 | private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f); | 94 | private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f); |
95 | 95 | ||
96 | public UUID currentParcelUUID = UUID.Zero; | 96 | public UUID currentParcelUUID = UUID.Zero; |
97 | 97 | ||
98 | private ISceneViewer m_sceneViewer; | 98 | private ISceneViewer m_sceneViewer; |
99 | 99 | ||
100 | /// <value> | 100 | /// <value> |
101 | /// The animator for this avatar | 101 | /// The animator for this avatar |
102 | /// </value> | 102 | /// </value> |
103 | public ScenePresenceAnimator Animator | 103 | public ScenePresenceAnimator Animator |
104 | { | 104 | { |
105 | get { return m_animator; } | 105 | get { return m_animator; } |
106 | } | 106 | } |
107 | protected ScenePresenceAnimator m_animator; | 107 | protected ScenePresenceAnimator m_animator; |
108 | 108 | ||
109 | /// <value> | 109 | /// <value> |
110 | /// The scene objects attached to this avatar. Do not change this list directly - use methods such as | 110 | /// The scene objects attached to this avatar. Do not change this list directly - use methods such as |
111 | /// AddAttachment() and RemoveAttachment(). Lock this list when performing any read operations upon it. | 111 | /// AddAttachment() and RemoveAttachment(). Lock this list when performing any read operations upon it. |
112 | /// </value> | 112 | /// </value> |
113 | public List<SceneObjectGroup> Attachments | 113 | public List<SceneObjectGroup> Attachments |
114 | { | 114 | { |
115 | get { return m_attachments; } | 115 | get { return m_attachments; } |
116 | } | 116 | } |
117 | protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); | 117 | protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); |
118 | 118 | ||
119 | private Dictionary<UUID, ScriptControllers> scriptedcontrols = new Dictionary<UUID, ScriptControllers>(); | 119 | private Dictionary<UUID, ScriptControllers> scriptedcontrols = new Dictionary<UUID, ScriptControllers>(); |
120 | private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO; | 120 | private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO; |
121 | private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO; | 121 | private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO; |
122 | private bool MouseDown = false; | 122 | private bool MouseDown = false; |
123 | private SceneObjectGroup proxyObjectGroup; | 123 | private SceneObjectGroup proxyObjectGroup; |
124 | //private SceneObjectPart proxyObjectPart = null; | 124 | //private SceneObjectPart proxyObjectPart = null; |
125 | public Vector3 lastKnownAllowedPosition; | 125 | public Vector3 lastKnownAllowedPosition; |
126 | public bool sentMessageAboutRestrictedParcelFlyingDown; | 126 | public bool sentMessageAboutRestrictedParcelFlyingDown; |
127 | public Vector4 CollisionPlane = Vector4.UnitW; | 127 | public Vector4 CollisionPlane = Vector4.UnitW; |
128 | 128 | ||
129 | private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation | 129 | private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation |
130 | private Vector3 m_avUnscriptedSitPos; // for non-scripted prims | 130 | private Vector3 m_avUnscriptedSitPos; // for non-scripted prims |
131 | private Vector3 m_lastPosition; | 131 | private Vector3 m_lastPosition; |
132 | private Vector3 m_lastWorldPosition; | 132 | private Vector3 m_lastWorldPosition; |
133 | private Quaternion m_lastRotation; | 133 | private Quaternion m_lastRotation; |
134 | private Vector3 m_lastVelocity; | 134 | private Vector3 m_lastVelocity; |
135 | //private int m_lastTerseSent; | 135 | //private int m_lastTerseSent; |
136 | 136 | ||
137 | private bool m_updateflag; | 137 | private bool m_updateflag; |
138 | private byte m_movementflag; | 138 | private byte m_movementflag; |
139 | private Vector3? m_forceToApply; | 139 | private Vector3? m_forceToApply; |
140 | private uint m_requestedSitTargetID; | 140 | private uint m_requestedSitTargetID; |
141 | private UUID m_requestedSitTargetUUID; | 141 | private UUID m_requestedSitTargetUUID; |
142 | public bool SitGround = false; | 142 | public bool SitGround = false; |
143 | 143 | ||
144 | private SendCourseLocationsMethod m_sendCourseLocationsMethod; | 144 | private SendCourseLocationsMethod m_sendCourseLocationsMethod; |
145 | 145 | ||
146 | private bool m_startAnimationSet; | 146 | private bool m_startAnimationSet; |
147 | 147 | ||
148 | //private Vector3 m_requestedSitOffset = new Vector3(); | 148 | //private Vector3 m_requestedSitOffset = new Vector3(); |
149 | 149 | ||
150 | private Vector3 m_LastFinitePos; | 150 | private Vector3 m_LastFinitePos; |
151 | 151 | ||
152 | private float m_sitAvatarHeight = 2.0f; | 152 | private float m_sitAvatarHeight = 2.0f; |
153 | 153 | ||
154 | private int m_godLevel; | 154 | private int m_godLevel; |
155 | private int m_userLevel; | 155 | private int m_userLevel; |
156 | 156 | ||
157 | private bool m_invulnerable = true; | 157 | private bool m_invulnerable = true; |
158 | 158 | ||
159 | private Vector3 m_lastChildAgentUpdatePosition; | 159 | private Vector3 m_lastChildAgentUpdatePosition; |
160 | private Vector3 m_lastChildAgentUpdateCamPosition; | 160 | private Vector3 m_lastChildAgentUpdateCamPosition; |
161 | 161 | ||
162 | private int m_perfMonMS; | 162 | private int m_perfMonMS; |
163 | 163 | ||
164 | private bool m_setAlwaysRun; | 164 | private bool m_setAlwaysRun; |
165 | private bool m_forceFly; | 165 | private bool m_forceFly; |
166 | private bool m_flyDisabled; | 166 | private bool m_flyDisabled; |
167 | 167 | ||
168 | private float m_speedModifier = 1.0f; | 168 | private float m_speedModifier = 1.0f; |
169 | 169 | ||
170 | private Quaternion m_bodyRot= Quaternion.Identity; | 170 | private Quaternion m_bodyRot= Quaternion.Identity; |
171 | 171 | ||
172 | private Quaternion m_bodyRotPrevious = Quaternion.Identity; | 172 | private Quaternion m_bodyRotPrevious = Quaternion.Identity; |
173 | 173 | ||
174 | private const int LAND_VELOCITYMAG_MAX = 12; | 174 | private const int LAND_VELOCITYMAG_MAX = 12; |
175 | 175 | ||
176 | public bool IsRestrictedToRegion; | 176 | public bool IsRestrictedToRegion; |
177 | 177 | ||
178 | public string JID = String.Empty; | 178 | public string JID = String.Empty; |
179 | 179 | ||
180 | private float m_health = 100f; | 180 | private float m_health = 100f; |
181 | 181 | ||
182 | // Default AV Height | 182 | // Default AV Height |
183 | private float m_avHeight = 127.0f; | 183 | private float m_avHeight = 127.0f; |
184 | 184 | ||
185 | protected RegionInfo m_regionInfo; | 185 | protected RegionInfo m_regionInfo; |
186 | protected ulong crossingFromRegion; | 186 | protected ulong crossingFromRegion; |
187 | 187 | ||
188 | private readonly Vector3[] Dir_Vectors = new Vector3[11]; | 188 | private readonly Vector3[] Dir_Vectors = new Vector3[11]; |
189 | private bool m_isNudging = false; | 189 | private bool m_isNudging = false; |
190 | 190 | ||
191 | // Position of agent's camera in world (region cordinates) | 191 | // Position of agent's camera in world (region cordinates) |
192 | protected Vector3 m_CameraCenter; | 192 | protected Vector3 m_CameraCenter; |
193 | protected Vector3 m_lastCameraCenter; | 193 | protected Vector3 m_lastCameraCenter; |
194 | 194 | ||
195 | protected Timer m_reprioritization_timer; | 195 | protected Timer m_reprioritization_timer; |
196 | protected bool m_reprioritizing; | 196 | protected bool m_reprioritizing; |
197 | protected bool m_reprioritization_called; | 197 | protected bool m_reprioritization_called; |
198 | 198 | ||
199 | // Use these three vectors to figure out what the agent is looking at | 199 | // Use these three vectors to figure out what the agent is looking at |
200 | // Convert it to a Matrix and/or Quaternion | 200 | // Convert it to a Matrix and/or Quaternion |
201 | protected Vector3 m_CameraAtAxis; | 201 | protected Vector3 m_CameraAtAxis; |
202 | protected Vector3 m_CameraLeftAxis; | 202 | protected Vector3 m_CameraLeftAxis; |
203 | protected Vector3 m_CameraUpAxis; | 203 | protected Vector3 m_CameraUpAxis; |
204 | private AgentManager.ControlFlags m_AgentControlFlags; | 204 | private AgentManager.ControlFlags m_AgentControlFlags; |
205 | private Quaternion m_headrotation = Quaternion.Identity; | 205 | private Quaternion m_headrotation = Quaternion.Identity; |
206 | private byte m_state; | 206 | private byte m_state; |
207 | 207 | ||
208 | //Reuse the Vector3 instead of creating a new one on the UpdateMovement method | 208 | //Reuse the Vector3 instead of creating a new one on the UpdateMovement method |
209 | // private Vector3 movementvector; | 209 | // private Vector3 movementvector; |
210 | 210 | ||
211 | private bool m_autopilotMoving; | 211 | private bool m_autopilotMoving; |
212 | private Vector3 m_autoPilotTarget; | 212 | private Vector3 m_autoPilotTarget; |
213 | private bool m_sitAtAutoTarget; | 213 | private bool m_sitAtAutoTarget; |
214 | private Vector3 m_initialSitTarget = Vector3.Zero; //KF: First estimate of where to sit | 214 | private Vector3 m_initialSitTarget = Vector3.Zero; //KF: First estimate of where to sit |
215 | 215 | ||
216 | private string m_nextSitAnimation = String.Empty; | 216 | private string m_nextSitAnimation = String.Empty; |
217 | 217 | ||
218 | //PauPaw:Proper PID Controler for autopilot************ | 218 | //PauPaw:Proper PID Controler for autopilot************ |
219 | private bool m_moveToPositionInProgress; | 219 | private bool m_moveToPositionInProgress; |
220 | private Vector3 m_moveToPositionTarget; | 220 | private Vector3 m_moveToPositionTarget; |
221 | private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); | 221 | private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); |
222 | 222 | ||
223 | private bool m_followCamAuto; | 223 | private bool m_followCamAuto; |
224 | 224 | ||
225 | private int m_movementUpdateCount; | 225 | private int m_movementUpdateCount; |
226 | private int m_lastColCount = -1; //KF: Look for Collision chnages | 226 | private int m_lastColCount = -1; //KF: Look for Collision chnages |
227 | private int m_updateCount = 0; //KF: Update Anims for a while | 227 | private int m_updateCount = 0; //KF: Update Anims for a while |
228 | private static readonly int UPDATE_COUNT = 10; // how many frames to update for | 228 | private static readonly int UPDATE_COUNT = 10; // how many frames to update for |
229 | private const int NumMovementsBetweenRayCast = 5; | 229 | private const int NumMovementsBetweenRayCast = 5; |
230 | private List<uint> m_lastColliders = new List<uint>(); | 230 | private List<uint> m_lastColliders = new List<uint>(); |
231 | 231 | ||
232 | private bool CameraConstraintActive; | 232 | private bool CameraConstraintActive; |
233 | //private int m_moveToPositionStateStatus; | 233 | //private int m_moveToPositionStateStatus; |
234 | //***************************************************** | 234 | //***************************************************** |
235 | 235 | ||
236 | // Agent's Draw distance. | 236 | // Agent's Draw distance. |
237 | protected float m_DrawDistance; | 237 | protected float m_DrawDistance; |
238 | 238 | ||
239 | protected AvatarAppearance m_appearance; | 239 | protected AvatarAppearance m_appearance; |
240 | 240 | ||
241 | // neighbouring regions we have enabled a child agent in | 241 | // neighbouring regions we have enabled a child agent in |
242 | // holds the seed cap for the child agent in that region | 242 | // holds the seed cap for the child agent in that region |
243 | private Dictionary<ulong, string> m_knownChildRegions = new Dictionary<ulong, string>(); | 243 | private Dictionary<ulong, string> m_knownChildRegions = new Dictionary<ulong, string>(); |
244 | 244 | ||
245 | /// <summary> | 245 | /// <summary> |
246 | /// Implemented Control Flags | 246 | /// Implemented Control Flags |
247 | /// </summary> | 247 | /// </summary> |
248 | private enum Dir_ControlFlags | 248 | private enum Dir_ControlFlags |
249 | { | 249 | { |
250 | DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS, | 250 | DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS, |
251 | DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG, | 251 | DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG, |
252 | DIR_CONTROL_FLAG_LEFT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS, | 252 | DIR_CONTROL_FLAG_LEFT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS, |
253 | DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, | 253 | DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, |
254 | DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, | 254 | DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, |
255 | DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, | 255 | DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, |
256 | DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, | 256 | DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, |
257 | DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, | 257 | DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, |
258 | DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS, | 258 | DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS, |
259 | DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG, | 259 | DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG, |
260 | DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG | 260 | DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG |
261 | } | 261 | } |
262 | 262 | ||
263 | /// <summary> | 263 | /// <summary> |
264 | /// Position at which a significant movement was made | 264 | /// Position at which a significant movement was made |
265 | /// </summary> | 265 | /// </summary> |
266 | private Vector3 posLastSignificantMove; | 266 | private Vector3 posLastSignificantMove; |
267 | 267 | ||
268 | // For teleports and crossings callbacks | 268 | // For teleports and crossings callbacks |
269 | string m_callbackURI; | 269 | string m_callbackURI; |
270 | UUID m_originRegionID; | 270 | UUID m_originRegionID; |
271 | 271 | ||
272 | ulong m_rootRegionHandle; | 272 | ulong m_rootRegionHandle; |
273 | 273 | ||
274 | /// <value> | 274 | /// <value> |
275 | /// Script engines present in the scene | 275 | /// Script engines present in the scene |
276 | /// </value> | 276 | /// </value> |
277 | private IScriptModule[] m_scriptEngines; | 277 | private IScriptModule[] m_scriptEngines; |
278 | 278 | ||
279 | #region Properties | 279 | #region Properties |
280 | 280 | ||
281 | /// <summary> | 281 | /// <summary> |
282 | /// Physical scene representation of this Avatar. | 282 | /// Physical scene representation of this Avatar. |
283 | /// </summary> | 283 | /// </summary> |
284 | public PhysicsActor PhysicsActor | 284 | public PhysicsActor PhysicsActor |
285 | { | 285 | { |
286 | set { m_physicsActor = value; } | 286 | set { m_physicsActor = value; } |
287 | get { return m_physicsActor; } | 287 | get { return m_physicsActor; } |
288 | } | 288 | } |
289 | 289 | ||
290 | public byte MovementFlag | 290 | public byte MovementFlag |
291 | { | 291 | { |
292 | set { m_movementflag = value; } | 292 | set { m_movementflag = value; } |
293 | get { return m_movementflag; } | 293 | get { return m_movementflag; } |
294 | } | 294 | } |
295 | 295 | ||
296 | public bool Updated | 296 | public bool Updated |
297 | { | 297 | { |
298 | set { m_updateflag = value; } | 298 | set { m_updateflag = value; } |
299 | get { return m_updateflag; } | 299 | get { return m_updateflag; } |
300 | } | 300 | } |
301 | 301 | ||
302 | public bool Invulnerable | 302 | public bool Invulnerable |
303 | { | 303 | { |
304 | set { m_invulnerable = value; } | 304 | set { m_invulnerable = value; } |
305 | get { return m_invulnerable; } | 305 | get { return m_invulnerable; } |
306 | } | 306 | } |
307 | 307 | ||
308 | public int UserLevel | 308 | public int UserLevel |
309 | { | 309 | { |
310 | get { return m_userLevel; } | 310 | get { return m_userLevel; } |
311 | } | 311 | } |
312 | 312 | ||
313 | public int GodLevel | 313 | public int GodLevel |
314 | { | 314 | { |
315 | get { return m_godLevel; } | 315 | get { return m_godLevel; } |
316 | } | 316 | } |
317 | 317 | ||
318 | public ulong RegionHandle | 318 | public ulong RegionHandle |
319 | { | 319 | { |
320 | get { return m_rootRegionHandle; } | 320 | get { return m_rootRegionHandle; } |
321 | } | 321 | } |
322 | 322 | ||
323 | public Vector3 CameraPosition | 323 | public Vector3 CameraPosition |
324 | { | 324 | { |
325 | get { return m_CameraCenter; } | 325 | get { return m_CameraCenter; } |
326 | } | 326 | } |
327 | 327 | ||
328 | public Quaternion CameraRotation | 328 | public Quaternion CameraRotation |
329 | { | 329 | { |
330 | get { return Util.Axes2Rot(m_CameraAtAxis, m_CameraLeftAxis, m_CameraUpAxis); } | 330 | get { return Util.Axes2Rot(m_CameraAtAxis, m_CameraLeftAxis, m_CameraUpAxis); } |
331 | } | 331 | } |
332 | 332 | ||
333 | public Vector3 CameraAtAxis | 333 | public Vector3 CameraAtAxis |
334 | { | 334 | { |
335 | get { return m_CameraAtAxis; } | 335 | get { return m_CameraAtAxis; } |
336 | } | 336 | } |
337 | 337 | ||
338 | public Vector3 CameraLeftAxis | 338 | public Vector3 CameraLeftAxis |
339 | { | 339 | { |
340 | get { return m_CameraLeftAxis; } | 340 | get { return m_CameraLeftAxis; } |
341 | } | 341 | } |
342 | 342 | ||
343 | public Vector3 CameraUpAxis | 343 | public Vector3 CameraUpAxis |
344 | { | 344 | { |
345 | get { return m_CameraUpAxis; } | 345 | get { return m_CameraUpAxis; } |
346 | } | 346 | } |
347 | 347 | ||
348 | public Vector3 Lookat | 348 | public Vector3 Lookat |
349 | { | 349 | { |
350 | get | 350 | get |
351 | { | 351 | { |
352 | Vector3 a = new Vector3(m_CameraAtAxis.X, m_CameraAtAxis.Y, 0); | 352 | Vector3 a = new Vector3(m_CameraAtAxis.X, m_CameraAtAxis.Y, 0); |
353 | 353 | ||
354 | if (a == Vector3.Zero) | 354 | if (a == Vector3.Zero) |
355 | return a; | 355 | return a; |
356 | 356 | ||
357 | return Util.GetNormalizedVector(a); | 357 | return Util.GetNormalizedVector(a); |
358 | } | 358 | } |
359 | } | 359 | } |
360 | 360 | ||
361 | private readonly string m_firstname; | 361 | private readonly string m_firstname; |
362 | 362 | ||
363 | public string Firstname | 363 | public string Firstname |
364 | { | 364 | { |
365 | get { return m_firstname; } | 365 | get { return m_firstname; } |
366 | } | 366 | } |
367 | 367 | ||
368 | private readonly string m_lastname; | 368 | private readonly string m_lastname; |
369 | 369 | ||
370 | public string Lastname | 370 | public string Lastname |
371 | { | 371 | { |
372 | get { return m_lastname; } | 372 | get { return m_lastname; } |
373 | } | 373 | } |
374 | 374 | ||
375 | private string m_grouptitle; | 375 | private string m_grouptitle; |
376 | 376 | ||
377 | public string Grouptitle | 377 | public string Grouptitle |
378 | { | 378 | { |
379 | get { return m_grouptitle; } | 379 | get { return m_grouptitle; } |
380 | set { m_grouptitle = value; } | 380 | set { m_grouptitle = value; } |
381 | } | 381 | } |
382 | 382 | ||
383 | public float DrawDistance | 383 | public float DrawDistance |
384 | { | 384 | { |
385 | get { return m_DrawDistance; } | 385 | get { return m_DrawDistance; } |
386 | } | 386 | } |
387 | 387 | ||
388 | protected bool m_allowMovement = true; | 388 | protected bool m_allowMovement = true; |
389 | 389 | ||
390 | public bool AllowMovement | 390 | public bool AllowMovement |
391 | { | 391 | { |
392 | get { return m_allowMovement; } | 392 | get { return m_allowMovement; } |
393 | set { m_allowMovement = value; } | 393 | set { m_allowMovement = value; } |
394 | } | 394 | } |
395 | 395 | ||
396 | public bool SetAlwaysRun | 396 | public bool SetAlwaysRun |
397 | { | 397 | { |
398 | get | 398 | get |
399 | { | 399 | { |
400 | if (PhysicsActor != null) | 400 | if (PhysicsActor != null) |
401 | { | 401 | { |
402 | return PhysicsActor.SetAlwaysRun; | 402 | return PhysicsActor.SetAlwaysRun; |
403 | } | 403 | } |
404 | else | 404 | else |
405 | { | 405 | { |
406 | return m_setAlwaysRun; | 406 | return m_setAlwaysRun; |
407 | } | 407 | } |
408 | } | 408 | } |
409 | set | 409 | set |
410 | { | 410 | { |
411 | m_setAlwaysRun = value; | 411 | m_setAlwaysRun = value; |
412 | if (PhysicsActor != null) | 412 | if (PhysicsActor != null) |
413 | { | 413 | { |
414 | PhysicsActor.SetAlwaysRun = value; | 414 | PhysicsActor.SetAlwaysRun = value; |
415 | } | 415 | } |
416 | } | 416 | } |
417 | } | 417 | } |
418 | 418 | ||
419 | public byte State | 419 | public byte State |
420 | { | 420 | { |
421 | get { return m_state; } | 421 | get { return m_state; } |
422 | set { m_state = value; } | 422 | set { m_state = value; } |
423 | } | 423 | } |
424 | 424 | ||
425 | public uint AgentControlFlags | 425 | public uint AgentControlFlags |
426 | { | 426 | { |
427 | get { return (uint)m_AgentControlFlags; } | 427 | get { return (uint)m_AgentControlFlags; } |
428 | set { m_AgentControlFlags = (AgentManager.ControlFlags)value; } | 428 | set { m_AgentControlFlags = (AgentManager.ControlFlags)value; } |
429 | } | 429 | } |
430 | 430 | ||
431 | /// <summary> | 431 | /// <summary> |
432 | /// This works out to be the ClientView object associated with this avatar, or it's client connection manager | 432 | /// This works out to be the ClientView object associated with this avatar, or it's client connection manager |
433 | /// </summary> | 433 | /// </summary> |
434 | private IClientAPI m_controllingClient; | 434 | private IClientAPI m_controllingClient; |
435 | 435 | ||
436 | protected PhysicsActor m_physicsActor; | 436 | protected PhysicsActor m_physicsActor; |
437 | 437 | ||
438 | /// <value> | 438 | /// <value> |
439 | /// The client controlling this presence | 439 | /// The client controlling this presence |
440 | /// </value> | 440 | /// </value> |
441 | public IClientAPI ControllingClient | 441 | public IClientAPI ControllingClient |
442 | { | 442 | { |
443 | get { return m_controllingClient; } | 443 | get { return m_controllingClient; } |
444 | } | 444 | } |
445 | 445 | ||
446 | public IClientCore ClientView | 446 | public IClientCore ClientView |
447 | { | 447 | { |
448 | get { return (IClientCore) m_controllingClient; } | 448 | get { return (IClientCore) m_controllingClient; } |
449 | } | 449 | } |
450 | 450 | ||
451 | protected Vector3 m_parentPosition; | 451 | protected Vector3 m_parentPosition; |
452 | public Vector3 ParentPosition | 452 | public Vector3 ParentPosition |
453 | { | 453 | { |
454 | get { return m_parentPosition; } | 454 | get { return m_parentPosition; } |
455 | set { m_parentPosition = value; } | 455 | set { m_parentPosition = value; } |
456 | } | 456 | } |
457 | 457 | ||
458 | /// <summary> | 458 | /// <summary> |
459 | /// Position of this avatar relative to the region the avatar is in | 459 | /// Position of this avatar relative to the region the avatar is in |
460 | /// </summary> | 460 | /// </summary> |
461 | public override Vector3 AbsolutePosition | 461 | public override Vector3 AbsolutePosition |
462 | { | 462 | { |
463 | get | 463 | get |
464 | { | 464 | { |
465 | PhysicsActor actor = m_physicsActor; | 465 | PhysicsActor actor = m_physicsActor; |
466 | // if (actor != null) | 466 | // if (actor != null) |
467 | if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting! | 467 | if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting! |
468 | m_pos = actor.Position; | 468 | m_pos = actor.Position; |
469 | 469 | ||
470 | // If we're sitting, we need to update our position | 470 | // If we're sitting, we need to update our position |
471 | if (m_parentID != 0) | 471 | if (m_parentID != 0) |
472 | { | 472 | { |
473 | SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); | 473 | SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); |
474 | if (part != null) | 474 | if (part != null) |
475 | m_parentPosition = part.AbsolutePosition; | 475 | m_parentPosition = part.AbsolutePosition; |
476 | } | 476 | } |
477 | 477 | ||
478 | return m_parentPosition + m_pos; | 478 | return m_parentPosition + m_pos; |
479 | } | 479 | } |
480 | set | 480 | set |
481 | { | 481 | { |
482 | PhysicsActor actor = m_physicsActor; | 482 | PhysicsActor actor = m_physicsActor; |
483 | if (actor != null) | 483 | if (actor != null) |
484 | { | 484 | { |
485 | try | 485 | try |
486 | { | 486 | { |
487 | lock (m_scene.SyncRoot) | 487 | lock (m_scene.SyncRoot) |
488 | m_physicsActor.Position = value; | 488 | m_physicsActor.Position = value; |
489 | } | 489 | } |
490 | catch (Exception e) | 490 | catch (Exception e) |
491 | { | 491 | { |
492 | m_log.Error("[SCENEPRESENCE]: ABSOLUTE POSITION " + e.Message); | 492 | m_log.Error("[SCENEPRESENCE]: ABSOLUTE POSITION " + e.Message); |
493 | } | 493 | } |
494 | } | 494 | } |
495 | 495 | ||
496 | if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting! | 496 | if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting! |
497 | m_pos = value; | 497 | m_pos = value; |
498 | m_parentPosition = Vector3.Zero; | 498 | m_parentPosition = Vector3.Zero; |
499 | } | 499 | } |
500 | } | 500 | } |
501 | 501 | ||
502 | public Vector3 OffsetPosition | 502 | public Vector3 OffsetPosition |
503 | { | 503 | { |
504 | get { return m_pos; } | 504 | get { return m_pos; } |
505 | set { m_pos = value; } | 505 | set { m_pos = value; } |
506 | } | 506 | } |
507 | 507 | ||
508 | /// <summary> | 508 | /// <summary> |
509 | /// Current velocity of the avatar. | 509 | /// Current velocity of the avatar. |
510 | /// </summary> | 510 | /// </summary> |
511 | public override Vector3 Velocity | 511 | public override Vector3 Velocity |
512 | { | 512 | { |
513 | get | 513 | get |
514 | { | 514 | { |
515 | PhysicsActor actor = m_physicsActor; | 515 | PhysicsActor actor = m_physicsActor; |
516 | if (actor != null) | 516 | if (actor != null) |
517 | m_velocity = actor.Velocity; | 517 | m_velocity = actor.Velocity; |
518 | 518 | ||
519 | return m_velocity; | 519 | return m_velocity; |
520 | } | 520 | } |
521 | set | 521 | set |
522 | { | 522 | { |
523 | PhysicsActor actor = m_physicsActor; | 523 | PhysicsActor actor = m_physicsActor; |
524 | if (actor != null) | 524 | if (actor != null) |
525 | { | 525 | { |
526 | try | 526 | try |
527 | { | 527 | { |
528 | lock (m_scene.SyncRoot) | 528 | lock (m_scene.SyncRoot) |
529 | actor.Velocity = value; | 529 | actor.Velocity = value; |
530 | } | 530 | } |
531 | catch (Exception e) | 531 | catch (Exception e) |
532 | { | 532 | { |
533 | m_log.Error("[SCENEPRESENCE]: VELOCITY " + e.Message); | 533 | m_log.Error("[SCENEPRESENCE]: VELOCITY " + e.Message); |
534 | } | 534 | } |
535 | } | 535 | } |
536 | 536 | ||
537 | m_velocity = value; | 537 | m_velocity = value; |
538 | } | 538 | } |
539 | } | 539 | } |
540 | 540 | ||
541 | public Quaternion OffsetRotation | 541 | public Quaternion OffsetRotation |
542 | { | 542 | { |
543 | get { return m_offsetRotation; } | 543 | get { return m_offsetRotation; } |
544 | set { m_offsetRotation = value; } | 544 | set { m_offsetRotation = value; } |
545 | } | 545 | } |
546 | 546 | ||
547 | public Quaternion Rotation | 547 | public Quaternion Rotation |
548 | { | 548 | { |
549 | get { | 549 | get { |
550 | if (m_parentID != 0) | 550 | if (m_parentID != 0) |
551 | { | 551 | { |
552 | if (m_offsetRotation != null) | 552 | if (m_offsetRotation != null) |
553 | { | 553 | { |
554 | return m_offsetRotation; | 554 | return m_offsetRotation; |
555 | } | 555 | } |
556 | else | 556 | else |
557 | { | 557 | { |
558 | return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); | 558 | return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); |
559 | } | 559 | } |
560 | 560 | ||
561 | } | 561 | } |
562 | else | 562 | else |
563 | { | 563 | { |
564 | return m_bodyRot; | 564 | return m_bodyRot; |
565 | } | 565 | } |
566 | } | 566 | } |
567 | set { | 567 | set { |
568 | m_bodyRot = value; | 568 | m_bodyRot = value; |
569 | if (m_parentID != 0) | 569 | if (m_parentID != 0) |
570 | { | 570 | { |
571 | m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); | 571 | m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); |
572 | } | 572 | } |
573 | } | 573 | } |
574 | } | 574 | } |
575 | 575 | ||
576 | public Quaternion PreviousRotation | 576 | public Quaternion PreviousRotation |
577 | { | 577 | { |
578 | get { return m_bodyRotPrevious; } | 578 | get { return m_bodyRotPrevious; } |
579 | set { m_bodyRotPrevious = value; } | 579 | set { m_bodyRotPrevious = value; } |
580 | } | 580 | } |
581 | 581 | ||
582 | /// <summary> | 582 | /// <summary> |
583 | /// If this is true, agent doesn't have a representation in this scene. | 583 | /// If this is true, agent doesn't have a representation in this scene. |
584 | /// this is an agent 'looking into' this scene from a nearby scene(region) | 584 | /// this is an agent 'looking into' this scene from a nearby scene(region) |
585 | /// | 585 | /// |
586 | /// if False, this agent has a representation in this scene | 586 | /// if False, this agent has a representation in this scene |
587 | /// </summary> | 587 | /// </summary> |
588 | private bool m_isChildAgent = true; | 588 | private bool m_isChildAgent = true; |
589 | 589 | ||
590 | public bool IsChildAgent | 590 | public bool IsChildAgent |
591 | { | 591 | { |
592 | get { return m_isChildAgent; } | 592 | get { return m_isChildAgent; } |
593 | set { m_isChildAgent = value; } | 593 | set { m_isChildAgent = value; } |
594 | } | 594 | } |
595 | 595 | ||
596 | private uint m_parentID; | 596 | private uint m_parentID; |
597 | 597 | ||
598 | 598 | ||
599 | private UUID m_linkedPrim; | 599 | private UUID m_linkedPrim; |
600 | 600 | ||
601 | public uint ParentID | 601 | public uint ParentID |
602 | { | 602 | { |
603 | get { return m_parentID; } | 603 | get { return m_parentID; } |
604 | set { m_parentID = value; } | 604 | set { m_parentID = value; } |
605 | } | 605 | } |
606 | 606 | ||
607 | public UUID LinkedPrim | 607 | public UUID LinkedPrim |
608 | { | 608 | { |
609 | get { return m_linkedPrim; } | 609 | get { return m_linkedPrim; } |
610 | set { m_linkedPrim = value; } | 610 | set { m_linkedPrim = value; } |
611 | } | 611 | } |
612 | 612 | ||
613 | public float Health | 613 | public float Health |
614 | { | 614 | { |
615 | get { return m_health; } | 615 | get { return m_health; } |
616 | set { m_health = value; } | 616 | set { m_health = value; } |
617 | } | 617 | } |
618 | 618 | ||
619 | /// <summary> | 619 | /// <summary> |
620 | /// These are the region handles known by the avatar. | 620 | /// These are the region handles known by the avatar. |
621 | /// </summary> | 621 | /// </summary> |
622 | public List<ulong> KnownChildRegionHandles | 622 | public List<ulong> KnownChildRegionHandles |
623 | { | 623 | { |
624 | get | 624 | get |
625 | { | 625 | { |
626 | if (m_knownChildRegions.Count == 0) | 626 | if (m_knownChildRegions.Count == 0) |
627 | return new List<ulong>(); | 627 | return new List<ulong>(); |
628 | else | 628 | else |
629 | return new List<ulong>(m_knownChildRegions.Keys); | 629 | return new List<ulong>(m_knownChildRegions.Keys); |
630 | } | 630 | } |
631 | } | 631 | } |
632 | 632 | ||
633 | public Dictionary<ulong, string> KnownRegions | 633 | public Dictionary<ulong, string> KnownRegions |
634 | { | 634 | { |
635 | get { return m_knownChildRegions; } | 635 | get { return m_knownChildRegions; } |
636 | set | 636 | set |
637 | { | 637 | { |
638 | m_knownChildRegions = value; | 638 | m_knownChildRegions = value; |
639 | } | 639 | } |
640 | } | 640 | } |
641 | 641 | ||
642 | public ISceneViewer SceneViewer | 642 | public ISceneViewer SceneViewer |
643 | { | 643 | { |
644 | get { return m_sceneViewer; } | 644 | get { return m_sceneViewer; } |
645 | } | 645 | } |
646 | 646 | ||
647 | public void AdjustKnownSeeds() | 647 | public void AdjustKnownSeeds() |
648 | { | 648 | { |
649 | Dictionary<ulong, string> seeds; | 649 | Dictionary<ulong, string> seeds; |
650 | 650 | ||
651 | if (Scene.CapsModule != null) | 651 | if (Scene.CapsModule != null) |
652 | seeds = Scene.CapsModule.GetChildrenSeeds(UUID); | 652 | seeds = Scene.CapsModule.GetChildrenSeeds(UUID); |
653 | else | 653 | else |
654 | seeds = new Dictionary<ulong, string>(); | 654 | seeds = new Dictionary<ulong, string>(); |
655 | 655 | ||
656 | List<ulong> old = new List<ulong>(); | 656 | List<ulong> old = new List<ulong>(); |
657 | foreach (ulong handle in seeds.Keys) | 657 | foreach (ulong handle in seeds.Keys) |
658 | { | 658 | { |
659 | uint x, y; | 659 | uint x, y; |
660 | Utils.LongToUInts(handle, out x, out y); | 660 | Utils.LongToUInts(handle, out x, out y); |
661 | x = x / Constants.RegionSize; | 661 | x = x / Constants.RegionSize; |
662 | y = y / Constants.RegionSize; | 662 | y = y / Constants.RegionSize; |
663 | if (Util.IsOutsideView(x, Scene.RegionInfo.RegionLocX, y, Scene.RegionInfo.RegionLocY)) | 663 | if (Util.IsOutsideView(x, Scene.RegionInfo.RegionLocX, y, Scene.RegionInfo.RegionLocY)) |
664 | { | 664 | { |
665 | old.Add(handle); | 665 | old.Add(handle); |
666 | } | 666 | } |
667 | } | 667 | } |
668 | DropOldNeighbours(old); | 668 | DropOldNeighbours(old); |
669 | 669 | ||
670 | if (Scene.CapsModule != null) | 670 | if (Scene.CapsModule != null) |
671 | Scene.CapsModule.SetChildrenSeed(UUID, seeds); | 671 | Scene.CapsModule.SetChildrenSeed(UUID, seeds); |
672 | 672 | ||
673 | KnownRegions = seeds; | 673 | KnownRegions = seeds; |
674 | //m_log.Debug(" ++++++++++AFTER+++++++++++++ "); | 674 | //m_log.Debug(" ++++++++++AFTER+++++++++++++ "); |
675 | //DumpKnownRegions(); | 675 | //DumpKnownRegions(); |
676 | } | 676 | } |
677 | 677 | ||
678 | public void DumpKnownRegions() | 678 | public void DumpKnownRegions() |
679 | { | 679 | { |
680 | m_log.Info("================ KnownRegions "+Scene.RegionInfo.RegionName+" ================"); | 680 | m_log.Info("================ KnownRegions "+Scene.RegionInfo.RegionName+" ================"); |
681 | foreach (KeyValuePair<ulong, string> kvp in KnownRegions) | 681 | foreach (KeyValuePair<ulong, string> kvp in KnownRegions) |
682 | { | 682 | { |
683 | uint x, y; | 683 | uint x, y; |
684 | Utils.LongToUInts(kvp.Key, out x, out y); | 684 | Utils.LongToUInts(kvp.Key, out x, out y); |
685 | x = x / Constants.RegionSize; | 685 | x = x / Constants.RegionSize; |
686 | y = y / Constants.RegionSize; | 686 | y = y / Constants.RegionSize; |
687 | m_log.Info(" >> "+x+", "+y+": "+kvp.Value); | 687 | m_log.Info(" >> "+x+", "+y+": "+kvp.Value); |
688 | } | 688 | } |
689 | } | 689 | } |
690 | 690 | ||
691 | private bool m_inTransit; | 691 | private bool m_inTransit; |
692 | private bool m_mouseLook; | 692 | private bool m_mouseLook; |
693 | private bool m_leftButtonDown; | 693 | private bool m_leftButtonDown; |
694 | 694 | ||
695 | public bool IsInTransit | 695 | public bool IsInTransit |
696 | { | 696 | { |
697 | get { return m_inTransit; } | 697 | get { return m_inTransit; } |
698 | set { m_inTransit = value; } | 698 | set { m_inTransit = value; } |
699 | } | 699 | } |
700 | 700 | ||
701 | public float SpeedModifier | 701 | public float SpeedModifier |
702 | { | 702 | { |
703 | get { return m_speedModifier; } | 703 | get { return m_speedModifier; } |
704 | set { m_speedModifier = value; } | 704 | set { m_speedModifier = value; } |
705 | } | 705 | } |
706 | 706 | ||
707 | public bool ForceFly | 707 | public bool ForceFly |
708 | { | 708 | { |
709 | get { return m_forceFly; } | 709 | get { return m_forceFly; } |
710 | set { m_forceFly = value; } | 710 | set { m_forceFly = value; } |
711 | } | 711 | } |
712 | 712 | ||
713 | public bool FlyDisabled | 713 | public bool FlyDisabled |
714 | { | 714 | { |
715 | get { return m_flyDisabled; } | 715 | get { return m_flyDisabled; } |
716 | set { m_flyDisabled = value; } | 716 | set { m_flyDisabled = value; } |
717 | } | 717 | } |
718 | 718 | ||
719 | public string Viewer | 719 | public string Viewer |
720 | { | 720 | { |
721 | get { return m_scene.AuthenticateHandler.GetAgentCircuitData(ControllingClient.CircuitCode).Viewer; } | 721 | get { return m_scene.AuthenticateHandler.GetAgentCircuitData(ControllingClient.CircuitCode).Viewer; } |
722 | } | 722 | } |
723 | 723 | ||
724 | #endregion | 724 | #endregion |
725 | 725 | ||
726 | #region Constructor(s) | 726 | #region Constructor(s) |
727 | 727 | ||
728 | public ScenePresence() | 728 | public ScenePresence() |
729 | { | 729 | { |
730 | m_sendCourseLocationsMethod = SendCoarseLocationsDefault; | 730 | m_sendCourseLocationsMethod = SendCoarseLocationsDefault; |
731 | CreateSceneViewer(); | 731 | CreateSceneViewer(); |
732 | m_animator = new ScenePresenceAnimator(this); | 732 | m_animator = new ScenePresenceAnimator(this); |
733 | } | 733 | } |
734 | 734 | ||
735 | private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this() | 735 | private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this() |
736 | { | 736 | { |
737 | m_rootRegionHandle = reginfo.RegionHandle; | 737 | m_rootRegionHandle = reginfo.RegionHandle; |
738 | m_controllingClient = client; | 738 | m_controllingClient = client; |
739 | m_firstname = m_controllingClient.FirstName; | 739 | m_firstname = m_controllingClient.FirstName; |
740 | m_lastname = m_controllingClient.LastName; | 740 | m_lastname = m_controllingClient.LastName; |
741 | m_name = String.Format("{0} {1}", m_firstname, m_lastname); | 741 | m_name = String.Format("{0} {1}", m_firstname, m_lastname); |
742 | m_scene = world; | 742 | m_scene = world; |
743 | m_uuid = client.AgentId; | 743 | m_uuid = client.AgentId; |
744 | m_regionInfo = reginfo; | 744 | m_regionInfo = reginfo; |
745 | m_localId = m_scene.AllocateLocalId(); | 745 | m_localId = m_scene.AllocateLocalId(); |
746 | 746 | ||
747 | UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); | 747 | UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); |
748 | 748 | ||
749 | if (account != null) | 749 | if (account != null) |
750 | m_userLevel = account.UserLevel; | 750 | m_userLevel = account.UserLevel; |
751 | 751 | ||
752 | IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); | 752 | IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); |
753 | if (gm != null) | 753 | if (gm != null) |
754 | m_grouptitle = gm.GetGroupTitle(m_uuid); | 754 | m_grouptitle = gm.GetGroupTitle(m_uuid); |
755 | 755 | ||
756 | m_scriptEngines = m_scene.RequestModuleInterfaces<IScriptModule>(); | 756 | m_scriptEngines = m_scene.RequestModuleInterfaces<IScriptModule>(); |
757 | 757 | ||
758 | AbsolutePosition = posLastSignificantMove = m_CameraCenter = | 758 | AbsolutePosition = posLastSignificantMove = m_CameraCenter = |
759 | m_lastCameraCenter = m_controllingClient.StartPos; | 759 | m_lastCameraCenter = m_controllingClient.StartPos; |
760 | 760 | ||
761 | m_reprioritization_timer = new Timer(world.ReprioritizationInterval); | 761 | m_reprioritization_timer = new Timer(world.ReprioritizationInterval); |
762 | m_reprioritization_timer.Elapsed += new ElapsedEventHandler(Reprioritize); | 762 | m_reprioritization_timer.Elapsed += new ElapsedEventHandler(Reprioritize); |
763 | m_reprioritization_timer.AutoReset = false; | 763 | m_reprioritization_timer.AutoReset = false; |
764 | 764 | ||
765 | AdjustKnownSeeds(); | 765 | AdjustKnownSeeds(); |
766 | Animator.TrySetMovementAnimation("STAND"); | 766 | Animator.TrySetMovementAnimation("STAND"); |
767 | // we created a new ScenePresence (a new child agent) in a fresh region. | 767 | // we created a new ScenePresence (a new child agent) in a fresh region. |
768 | // Request info about all the (root) agents in this region | 768 | // Request info about all the (root) agents in this region |
769 | // Note: This won't send data *to* other clients in that region (children don't send) | 769 | // Note: This won't send data *to* other clients in that region (children don't send) |
770 | SendInitialFullUpdateToAllClients(); | 770 | SendInitialFullUpdateToAllClients(); |
771 | RegisterToEvents(); | 771 | RegisterToEvents(); |
772 | if (m_controllingClient != null) | 772 | if (m_controllingClient != null) |
773 | { | 773 | { |
774 | m_controllingClient.ProcessPendingPackets(); | 774 | m_controllingClient.ProcessPendingPackets(); |
775 | } | 775 | } |
776 | SetDirectionVectors(); | 776 | SetDirectionVectors(); |
777 | } | 777 | } |
778 | 778 | ||
779 | public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, byte[] visualParams, | 779 | public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, byte[] visualParams, |
780 | AvatarWearable[] wearables) | 780 | AvatarWearable[] wearables) |
781 | : this(client, world, reginfo) | 781 | : this(client, world, reginfo) |
782 | { | 782 | { |
783 | m_appearance = new AvatarAppearance(m_uuid, wearables, visualParams); | 783 | m_appearance = new AvatarAppearance(m_uuid, wearables, visualParams); |
784 | } | 784 | } |
785 | 785 | ||
786 | public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance) | 786 | public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance) |
787 | : this(client, world, reginfo) | 787 | : this(client, world, reginfo) |
788 | { | 788 | { |
789 | m_appearance = appearance; | 789 | m_appearance = appearance; |
790 | } | 790 | } |
791 | 791 | ||
792 | private void CreateSceneViewer() | 792 | private void CreateSceneViewer() |
793 | { | 793 | { |
794 | m_sceneViewer = new SceneViewer(this); | 794 | m_sceneViewer = new SceneViewer(this); |
795 | } | 795 | } |
796 | 796 | ||
797 | public void RegisterToEvents() | 797 | public void RegisterToEvents() |
798 | { | 798 | { |
799 | m_controllingClient.OnRequestWearables += SendWearables; | 799 | m_controllingClient.OnRequestWearables += SendWearables; |
800 | m_controllingClient.OnSetAppearance += SetAppearance; | 800 | m_controllingClient.OnSetAppearance += SetAppearance; |
801 | m_controllingClient.OnCompleteMovementToRegion += CompleteMovement; | 801 | m_controllingClient.OnCompleteMovementToRegion += CompleteMovement; |
802 | //m_controllingClient.OnCompleteMovementToRegion += SendInitialData; | 802 | //m_controllingClient.OnCompleteMovementToRegion += SendInitialData; |
803 | m_controllingClient.OnAgentUpdate += HandleAgentUpdate; | 803 | m_controllingClient.OnAgentUpdate += HandleAgentUpdate; |
804 | m_controllingClient.OnAgentRequestSit += HandleAgentRequestSit; | 804 | m_controllingClient.OnAgentRequestSit += HandleAgentRequestSit; |
805 | m_controllingClient.OnAgentSit += HandleAgentSit; | 805 | m_controllingClient.OnAgentSit += HandleAgentSit; |
806 | m_controllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; | 806 | m_controllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; |
807 | m_controllingClient.OnStartAnim += HandleStartAnim; | 807 | m_controllingClient.OnStartAnim += HandleStartAnim; |
808 | m_controllingClient.OnStopAnim += HandleStopAnim; | 808 | m_controllingClient.OnStopAnim += HandleStopAnim; |
809 | m_controllingClient.OnForceReleaseControls += HandleForceReleaseControls; | 809 | m_controllingClient.OnForceReleaseControls += HandleForceReleaseControls; |
810 | m_controllingClient.OnAutoPilotGo += DoAutoPilot; | 810 | m_controllingClient.OnAutoPilotGo += DoAutoPilot; |
811 | m_controllingClient.AddGenericPacketHandler("autopilot", DoMoveToPosition); | 811 | m_controllingClient.AddGenericPacketHandler("autopilot", DoMoveToPosition); |
812 | 812 | ||
813 | // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); | 813 | // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); |
814 | // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); | 814 | // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); |
815 | } | 815 | } |
816 | 816 | ||
817 | private void SetDirectionVectors() | 817 | private void SetDirectionVectors() |
818 | { | 818 | { |
819 | Dir_Vectors[0] = Vector3.UnitX; //FORWARD | 819 | Dir_Vectors[0] = Vector3.UnitX; //FORWARD |
820 | Dir_Vectors[1] = -Vector3.UnitX; //BACK | 820 | Dir_Vectors[1] = -Vector3.UnitX; //BACK |
821 | Dir_Vectors[2] = Vector3.UnitY; //LEFT | 821 | Dir_Vectors[2] = Vector3.UnitY; //LEFT |
822 | Dir_Vectors[3] = -Vector3.UnitY; //RIGHT | 822 | Dir_Vectors[3] = -Vector3.UnitY; //RIGHT |
823 | Dir_Vectors[4] = Vector3.UnitZ; //UP | 823 | Dir_Vectors[4] = Vector3.UnitZ; //UP |
824 | Dir_Vectors[5] = -Vector3.UnitZ; //DOWN | 824 | Dir_Vectors[5] = -Vector3.UnitZ; //DOWN |
825 | Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE | 825 | Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE |
826 | Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE | 826 | Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE |
827 | Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE | 827 | Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE |
828 | Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE | 828 | Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE |
829 | Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge | 829 | Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge |
830 | } | 830 | } |
831 | 831 | ||
832 | private Vector3[] GetWalkDirectionVectors() | 832 | private Vector3[] GetWalkDirectionVectors() |
833 | { | 833 | { |
834 | Vector3[] vector = new Vector3[11]; | 834 | Vector3[] vector = new Vector3[11]; |
835 | vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD | 835 | vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD |
836 | vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK | 836 | vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK |
837 | vector[2] = Vector3.UnitY; //LEFT | 837 | vector[2] = Vector3.UnitY; //LEFT |
838 | vector[3] = -Vector3.UnitY; //RIGHT | 838 | vector[3] = -Vector3.UnitY; //RIGHT |
839 | vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP | 839 | vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP |
840 | vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN | 840 | vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN |
841 | vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE | 841 | vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE |
842 | vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE | 842 | vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE |
843 | vector[8] = Vector3.UnitY; //LEFT_NUDGE | 843 | vector[8] = Vector3.UnitY; //LEFT_NUDGE |
844 | vector[9] = -Vector3.UnitY; //RIGHT_NUDGE | 844 | vector[9] = -Vector3.UnitY; //RIGHT_NUDGE |
845 | vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE | 845 | vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE |
846 | return vector; | 846 | return vector; |
847 | } | 847 | } |
848 | 848 | ||
849 | private bool[] GetDirectionIsNudge() | 849 | private bool[] GetDirectionIsNudge() |
850 | { | 850 | { |
851 | bool[] isNudge = new bool[11]; | 851 | bool[] isNudge = new bool[11]; |
852 | isNudge[0] = false; //FORWARD | 852 | isNudge[0] = false; //FORWARD |
853 | isNudge[1] = false; //BACK | 853 | isNudge[1] = false; //BACK |
854 | isNudge[2] = false; //LEFT | 854 | isNudge[2] = false; //LEFT |
855 | isNudge[3] = false; //RIGHT | 855 | isNudge[3] = false; //RIGHT |
856 | isNudge[4] = false; //UP | 856 | isNudge[4] = false; //UP |
857 | isNudge[5] = false; //DOWN | 857 | isNudge[5] = false; //DOWN |
858 | isNudge[6] = true; //FORWARD_NUDGE | 858 | isNudge[6] = true; //FORWARD_NUDGE |
859 | isNudge[7] = true; //BACK_NUDGE | 859 | isNudge[7] = true; //BACK_NUDGE |
860 | isNudge[8] = true; //LEFT_NUDGE | 860 | isNudge[8] = true; //LEFT_NUDGE |
861 | isNudge[9] = true; //RIGHT_NUDGE | 861 | isNudge[9] = true; //RIGHT_NUDGE |
862 | isNudge[10] = true; //DOWN_Nudge | 862 | isNudge[10] = true; //DOWN_Nudge |
863 | return isNudge; | 863 | return isNudge; |
864 | } | 864 | } |
865 | 865 | ||
866 | 866 | ||
867 | #endregion | 867 | #endregion |
868 | 868 | ||
869 | public uint GenerateClientFlags(UUID ObjectID) | 869 | public uint GenerateClientFlags(UUID ObjectID) |
870 | { | 870 | { |
871 | return m_scene.Permissions.GenerateClientFlags(m_uuid, ObjectID); | 871 | return m_scene.Permissions.GenerateClientFlags(m_uuid, ObjectID); |
872 | } | 872 | } |
873 | 873 | ||
874 | /// <summary> | 874 | /// <summary> |
875 | /// Send updates to the client about prims which have been placed on the update queue. We don't | 875 | /// Send updates to the client about prims which have been placed on the update queue. We don't |
876 | /// necessarily send updates for all the parts on the queue, e.g. if an updates with a more recent | 876 | /// necessarily send updates for all the parts on the queue, e.g. if an updates with a more recent |
877 | /// timestamp has already been sent. | 877 | /// timestamp has already been sent. |
878 | /// </summary> | 878 | /// </summary> |
879 | public void SendPrimUpdates() | 879 | public void SendPrimUpdates() |
880 | { | 880 | { |
881 | m_perfMonMS = Util.EnvironmentTickCount(); | 881 | m_perfMonMS = Util.EnvironmentTickCount(); |
882 | 882 | ||
883 | m_sceneViewer.SendPrimUpdates(); | 883 | m_sceneViewer.SendPrimUpdates(); |
884 | 884 | ||
885 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); | 885 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); |
886 | } | 886 | } |
887 | 887 | ||
888 | #region Status Methods | 888 | #region Status Methods |
889 | 889 | ||
890 | /// <summary> | 890 | /// <summary> |
891 | /// This turns a child agent, into a root agent | 891 | /// This turns a child agent, into a root agent |
892 | /// This is called when an agent teleports into a region, or if an | 892 | /// This is called when an agent teleports into a region, or if an |
893 | /// agent crosses into this region from a neighbor over the border | 893 | /// agent crosses into this region from a neighbor over the border |
894 | /// </summary> | 894 | /// </summary> |
895 | public void MakeRootAgent(Vector3 pos, bool isFlying) | 895 | public void MakeRootAgent(Vector3 pos, bool isFlying) |
896 | { | 896 | { |
897 | m_log.DebugFormat( | 897 | m_log.DebugFormat( |
898 | "[SCENE]: Upgrading child to root agent for {0} in {1}", | 898 | "[SCENE]: Upgrading child to root agent for {0} in {1}", |
899 | Name, m_scene.RegionInfo.RegionName); | 899 | Name, m_scene.RegionInfo.RegionName); |
900 | 900 | ||
901 | //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); | 901 | //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); |
902 | 902 | ||
903 | IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); | 903 | IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); |
904 | if (gm != null) | 904 | if (gm != null) |
905 | m_grouptitle = gm.GetGroupTitle(m_uuid); | 905 | m_grouptitle = gm.GetGroupTitle(m_uuid); |
906 | 906 | ||
907 | m_rootRegionHandle = m_scene.RegionInfo.RegionHandle; | 907 | m_rootRegionHandle = m_scene.RegionInfo.RegionHandle; |
908 | m_scene.SetRootAgentScene(m_uuid); | 908 | m_scene.SetRootAgentScene(m_uuid); |
909 | 909 | ||
910 | // Moved this from SendInitialData to ensure that m_appearance is initialized | 910 | // Moved this from SendInitialData to ensure that m_appearance is initialized |
911 | // before the inventory is processed in MakeRootAgent. This fixes a race condition | 911 | // before the inventory is processed in MakeRootAgent. This fixes a race condition |
912 | // related to the handling of attachments | 912 | // related to the handling of attachments |
913 | //m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); | 913 | //m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); |
914 | if (m_scene.TestBorderCross(pos, Cardinals.E)) | 914 | if (m_scene.TestBorderCross(pos, Cardinals.E)) |
915 | { | 915 | { |
916 | Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); | 916 | Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); |
917 | pos.X = crossedBorder.BorderLine.Z - 1; | 917 | pos.X = crossedBorder.BorderLine.Z - 1; |
918 | } | 918 | } |
919 | 919 | ||
920 | if (m_scene.TestBorderCross(pos, Cardinals.N)) | 920 | if (m_scene.TestBorderCross(pos, Cardinals.N)) |
921 | { | 921 | { |
922 | Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); | 922 | Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); |
923 | pos.Y = crossedBorder.BorderLine.Z - 1; | 923 | pos.Y = crossedBorder.BorderLine.Z - 1; |
924 | } | 924 | } |
925 | 925 | ||
926 | //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet. | 926 | //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet. |
927 | //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent, | 927 | //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent, |
928 | //they'll bypass the landing point. But I can't think of any decent way of fixing this. | 928 | //they'll bypass the landing point. But I can't think of any decent way of fixing this. |
929 | if (KnownChildRegionHandles.Count == 0) | 929 | if (KnownChildRegionHandles.Count == 0) |
930 | { | 930 | { |
931 | ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); | 931 | ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); |
932 | if (land != null) | 932 | if (land != null) |
933 | { | 933 | { |
934 | //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni. | 934 | //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni. |
935 | if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && UserLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid) | 935 | if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && UserLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid) |
936 | { | 936 | { |
937 | pos = land.LandData.UserLocation; | 937 | pos = land.LandData.UserLocation; |
938 | } | 938 | } |
939 | } | 939 | } |
940 | } | 940 | } |
941 | 941 | ||
942 | if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) | 942 | if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) |
943 | { | 943 | { |
944 | Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128); | 944 | Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128); |
945 | 945 | ||
946 | if (pos.X < 0) | 946 | if (pos.X < 0) |
947 | { | 947 | { |
948 | emergencyPos.X = (int)Constants.RegionSize + pos.X; | 948 | emergencyPos.X = (int)Constants.RegionSize + pos.X; |
949 | if (!(pos.Y < 0)) | 949 | if (!(pos.Y < 0)) |
950 | emergencyPos.Y = pos.Y; | 950 | emergencyPos.Y = pos.Y; |
951 | if (!(pos.Z < 0)) | 951 | if (!(pos.Z < 0)) |
952 | emergencyPos.Z = pos.Z; | 952 | emergencyPos.Z = pos.Z; |
953 | } | 953 | } |
954 | if (pos.Y < 0) | 954 | if (pos.Y < 0) |
955 | { | 955 | { |
956 | emergencyPos.Y = (int)Constants.RegionSize + pos.Y; | 956 | emergencyPos.Y = (int)Constants.RegionSize + pos.Y; |
957 | if (!(pos.X < 0)) | 957 | if (!(pos.X < 0)) |
958 | emergencyPos.X = pos.X; | 958 | emergencyPos.X = pos.X; |
959 | if (!(pos.Z < 0)) | 959 | if (!(pos.Z < 0)) |
960 | emergencyPos.Z = pos.Z; | 960 | emergencyPos.Z = pos.Z; |
961 | } | 961 | } |
962 | if (pos.Z < 0) | 962 | if (pos.Z < 0) |
963 | { | 963 | { |
964 | emergencyPos.Z = 128; | 964 | emergencyPos.Z = 128; |
965 | if (!(pos.Y < 0)) | 965 | if (!(pos.Y < 0)) |
966 | emergencyPos.Y = pos.Y; | 966 | emergencyPos.Y = pos.Y; |
967 | if (!(pos.X < 0)) | 967 | if (!(pos.X < 0)) |
968 | emergencyPos.X = pos.X; | 968 | emergencyPos.X = pos.X; |
969 | } | 969 | } |
970 | } | 970 | } |
971 | 971 | ||
972 | if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) | 972 | if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) |
973 | { | 973 | { |
974 | m_log.WarnFormat( | 974 | m_log.WarnFormat( |
975 | "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", | 975 | "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", |
976 | pos, Name, UUID); | 976 | pos, Name, UUID); |
977 | 977 | ||
978 | if (pos.X < 0f) pos.X = 0f; | 978 | if (pos.X < 0f) pos.X = 0f; |
979 | if (pos.Y < 0f) pos.Y = 0f; | 979 | if (pos.Y < 0f) pos.Y = 0f; |
980 | if (pos.Z < 0f) pos.Z = 0f; | 980 | if (pos.Z < 0f) pos.Z = 0f; |
981 | } | 981 | } |
982 | 982 | ||
983 | float localAVHeight = 1.56f; | 983 | float localAVHeight = 1.56f; |
984 | if (m_avHeight != 127.0f) | 984 | if (m_avHeight != 127.0f) |
985 | { | 985 | { |
986 | localAVHeight = m_avHeight; | 986 | localAVHeight = m_avHeight; |
987 | } | 987 | } |
988 | 988 | ||
989 | float posZLimit = 0; | 989 | float posZLimit = 0; |
990 | 990 | ||
991 | if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) | 991 | if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) |
992 | posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; | 992 | posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; |
993 | 993 | ||
994 | float newPosZ = posZLimit + localAVHeight / 2; | 994 | float newPosZ = posZLimit + localAVHeight / 2; |
995 | if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) | 995 | if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) |
996 | { | 996 | { |
997 | pos.Z = newPosZ; | 997 | pos.Z = newPosZ; |
998 | } | 998 | } |
999 | AbsolutePosition = pos; | 999 | AbsolutePosition = pos; |
1000 | 1000 | ||
1001 | AddToPhysicalScene(isFlying); | 1001 | AddToPhysicalScene(isFlying); |
1002 | 1002 | ||
1003 | if (m_forceFly) | 1003 | if (m_forceFly) |
1004 | { | 1004 | { |
1005 | m_physicsActor.Flying = true; | 1005 | m_physicsActor.Flying = true; |
1006 | } | 1006 | } |
1007 | else if (m_flyDisabled) | 1007 | else if (m_flyDisabled) |
1008 | { | 1008 | { |
1009 | m_physicsActor.Flying = false; | 1009 | m_physicsActor.Flying = false; |
1010 | } | 1010 | } |
1011 | 1011 | ||
1012 | if (m_appearance != null) | 1012 | if (m_appearance != null) |
1013 | { | 1013 | { |
1014 | if (m_appearance.AvatarHeight > 0) | 1014 | if (m_appearance.AvatarHeight > 0) |
1015 | SetHeight(m_appearance.AvatarHeight); | 1015 | SetHeight(m_appearance.AvatarHeight); |
1016 | } | 1016 | } |
1017 | else | 1017 | else |
1018 | { | 1018 | { |
1019 | m_log.ErrorFormat("[SCENE PRESENCE]: null appearance in MakeRoot in {0}", Scene.RegionInfo.RegionName); | 1019 | m_log.ErrorFormat("[SCENE PRESENCE]: null appearance in MakeRoot in {0}", Scene.RegionInfo.RegionName); |
1020 | // emergency; this really shouldn't happen | 1020 | // emergency; this really shouldn't happen |
1021 | m_appearance = new AvatarAppearance(UUID); | 1021 | m_appearance = new AvatarAppearance(UUID); |
1022 | } | 1022 | } |
1023 | 1023 | ||
1024 | // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying | 1024 | // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying |
1025 | // avatar to return to the standing position in mid-air. On login it looks like this is being sent | 1025 | // avatar to return to the standing position in mid-air. On login it looks like this is being sent |
1026 | // elsewhere anyway | 1026 | // elsewhere anyway |
1027 | // Animator.SendAnimPack(); | 1027 | // Animator.SendAnimPack(); |
1028 | 1028 | ||
1029 | m_scene.SwapRootAgentCount(false); | 1029 | m_scene.SwapRootAgentCount(false); |
1030 | 1030 | ||
1031 | //CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(m_uuid); | 1031 | //CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(m_uuid); |
1032 | //if (userInfo != null) | 1032 | //if (userInfo != null) |
1033 | // userInfo.FetchInventory(); | 1033 | // userInfo.FetchInventory(); |
1034 | //else | 1034 | //else |
1035 | // m_log.ErrorFormat("[SCENE]: Could not find user info for {0} when making it a root agent", m_uuid); | 1035 | // m_log.ErrorFormat("[SCENE]: Could not find user info for {0} when making it a root agent", m_uuid); |
1036 | 1036 | ||
1037 | // On the next prim update, all objects will be sent | 1037 | // On the next prim update, all objects will be sent |
1038 | // | 1038 | // |
1039 | m_sceneViewer.Reset(); | 1039 | m_sceneViewer.Reset(); |
1040 | 1040 | ||
1041 | m_isChildAgent = false; | 1041 | m_isChildAgent = false; |
1042 | 1042 | ||
1043 | // send the animations of the other presences to me | 1043 | // send the animations of the other presences to me |
1044 | m_scene.ForEachScenePresence(delegate(ScenePresence presence) | 1044 | m_scene.ForEachScenePresence(delegate(ScenePresence presence) |
1045 | { | 1045 | { |
1046 | if (presence != this) | 1046 | if (presence != this) |
1047 | presence.Animator.SendAnimPackToClient(ControllingClient); | 1047 | presence.Animator.SendAnimPackToClient(ControllingClient); |
1048 | }); | 1048 | }); |
1049 | 1049 | ||
1050 | m_scene.EventManager.TriggerOnMakeRootAgent(this); | 1050 | m_scene.EventManager.TriggerOnMakeRootAgent(this); |
1051 | } | 1051 | } |
1052 | 1052 | ||
1053 | /// <summary> | 1053 | /// <summary> |
1054 | /// This turns a root agent into a child agent | 1054 | /// This turns a root agent into a child agent |
1055 | /// when an agent departs this region for a neighbor, this gets called. | 1055 | /// when an agent departs this region for a neighbor, this gets called. |
1056 | /// | 1056 | /// |
1057 | /// It doesn't get called for a teleport. Reason being, an agent that | 1057 | /// It doesn't get called for a teleport. Reason being, an agent that |
1058 | /// teleports out may not end up anywhere near this region | 1058 | /// teleports out may not end up anywhere near this region |
1059 | /// </summary> | 1059 | /// </summary> |
1060 | public void MakeChildAgent() | 1060 | public void MakeChildAgent() |
1061 | { | 1061 | { |
1062 | // It looks like m_animator is set to null somewhere, and MakeChild | 1062 | // It looks like m_animator is set to null somewhere, and MakeChild |
1063 | // is called after that. Probably in aborted teleports. | 1063 | // is called after that. Probably in aborted teleports. |
1064 | if (m_animator == null) | 1064 | if (m_animator == null) |
1065 | m_animator = new ScenePresenceAnimator(this); | 1065 | m_animator = new ScenePresenceAnimator(this); |
1066 | else | 1066 | else |
1067 | Animator.ResetAnimations(); | 1067 | Animator.ResetAnimations(); |
1068 | 1068 | ||
1069 | // m_log.DebugFormat( | 1069 | // m_log.DebugFormat( |
1070 | // "[SCENEPRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", | 1070 | // "[SCENEPRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", |
1071 | // Name, UUID, m_scene.RegionInfo.RegionName); | 1071 | // Name, UUID, m_scene.RegionInfo.RegionName); |
1072 | 1072 | ||
1073 | // Don't zero out the velocity since this can cause problems when an avatar is making a region crossing, | 1073 | // Don't zero out the velocity since this can cause problems when an avatar is making a region crossing, |
1074 | // depending on the exact timing. This shouldn't matter anyway since child agent positions are not updated. | 1074 | // depending on the exact timing. This shouldn't matter anyway since child agent positions are not updated. |
1075 | //Velocity = new Vector3(0, 0, 0); | 1075 | //Velocity = new Vector3(0, 0, 0); |
1076 | 1076 | ||
1077 | m_isChildAgent = true; | 1077 | m_isChildAgent = true; |
1078 | m_scene.SwapRootAgentCount(true); | 1078 | m_scene.SwapRootAgentCount(true); |
1079 | RemoveFromPhysicalScene(); | 1079 | RemoveFromPhysicalScene(); |
1080 | 1080 | ||
1081 | // FIXME: Set m_rootRegionHandle to the region handle of the scene this agent is moving into | 1081 | // FIXME: Set m_rootRegionHandle to the region handle of the scene this agent is moving into |
1082 | 1082 | ||
1083 | m_scene.EventManager.TriggerOnMakeChildAgent(this); | 1083 | m_scene.EventManager.TriggerOnMakeChildAgent(this); |
1084 | } | 1084 | } |
1085 | 1085 | ||
1086 | /// <summary> | 1086 | /// <summary> |
1087 | /// Removes physics plugin scene representation of this agent if it exists. | 1087 | /// Removes physics plugin scene representation of this agent if it exists. |
1088 | /// </summary> | 1088 | /// </summary> |
1089 | private void RemoveFromPhysicalScene() | 1089 | private void RemoveFromPhysicalScene() |
1090 | { | 1090 | { |
1091 | if (PhysicsActor != null) | 1091 | if (PhysicsActor != null) |
1092 | { | 1092 | { |
1093 | m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; | 1093 | m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; |
1094 | m_physicsActor.OnOutOfBounds -= OutOfBoundsCall; | 1094 | m_physicsActor.OnOutOfBounds -= OutOfBoundsCall; |
1095 | m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); | 1095 | m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); |
1096 | m_physicsActor.UnSubscribeEvents(); | 1096 | m_physicsActor.UnSubscribeEvents(); |
1097 | m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; | 1097 | m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; |
1098 | PhysicsActor = null; | 1098 | PhysicsActor = null; |
1099 | } | 1099 | } |
1100 | } | 1100 | } |
1101 | 1101 | ||
1102 | /// <summary> | 1102 | /// <summary> |
1103 | /// | 1103 | /// |
1104 | /// </summary> | 1104 | /// </summary> |
1105 | /// <param name="pos"></param> | 1105 | /// <param name="pos"></param> |
1106 | public void Teleport(Vector3 pos) | 1106 | public void Teleport(Vector3 pos) |
1107 | { | 1107 | { |
1108 | bool isFlying = false; | 1108 | bool isFlying = false; |
1109 | 1109 | ||
1110 | if (m_physicsActor != null) | 1110 | if (m_physicsActor != null) |
1111 | isFlying = m_physicsActor.Flying; | 1111 | isFlying = m_physicsActor.Flying; |
1112 | 1112 | ||
1113 | RemoveFromPhysicalScene(); | 1113 | RemoveFromPhysicalScene(); |
1114 | Velocity = Vector3.Zero; | 1114 | Velocity = Vector3.Zero; |
1115 | AbsolutePosition = pos; | 1115 | AbsolutePosition = pos; |
1116 | AddToPhysicalScene(isFlying); | 1116 | AddToPhysicalScene(isFlying); |
1117 | if (m_appearance != null) | 1117 | if (m_appearance != null) |
1118 | { | 1118 | { |
1119 | if (m_appearance.AvatarHeight > 0) | 1119 | if (m_appearance.AvatarHeight > 0) |
1120 | SetHeight(m_appearance.AvatarHeight); | 1120 | SetHeight(m_appearance.AvatarHeight); |
1121 | } | 1121 | } |
1122 | 1122 | ||
1123 | SendTerseUpdateToAllClients(); | 1123 | SendTerseUpdateToAllClients(); |
1124 | 1124 | ||
1125 | } | 1125 | } |
1126 | 1126 | ||
1127 | public void TeleportWithMomentum(Vector3 pos) | 1127 | public void TeleportWithMomentum(Vector3 pos) |
1128 | { | 1128 | { |
1129 | bool isFlying = false; | 1129 | bool isFlying = false; |
1130 | if (m_physicsActor != null) | 1130 | if (m_physicsActor != null) |
1131 | isFlying = m_physicsActor.Flying; | 1131 | isFlying = m_physicsActor.Flying; |
1132 | 1132 | ||
1133 | RemoveFromPhysicalScene(); | 1133 | RemoveFromPhysicalScene(); |
1134 | AbsolutePosition = pos; | 1134 | AbsolutePosition = pos; |
1135 | AddToPhysicalScene(isFlying); | 1135 | AddToPhysicalScene(isFlying); |
1136 | if (m_appearance != null) | 1136 | if (m_appearance != null) |
1137 | { | 1137 | { |
1138 | if (m_appearance.AvatarHeight > 0) | 1138 | if (m_appearance.AvatarHeight > 0) |
1139 | SetHeight(m_appearance.AvatarHeight); | 1139 | SetHeight(m_appearance.AvatarHeight); |
1140 | } | 1140 | } |
1141 | 1141 | ||
1142 | SendTerseUpdateToAllClients(); | 1142 | SendTerseUpdateToAllClients(); |
1143 | } | 1143 | } |
1144 | 1144 | ||
1145 | /// <summary> | 1145 | /// <summary> |
1146 | /// | 1146 | /// |
1147 | /// </summary> | 1147 | /// </summary> |
1148 | public void StopMovement() | 1148 | public void StopMovement() |
1149 | { | 1149 | { |
1150 | } | 1150 | } |
1151 | 1151 | ||
1152 | public void StopFlying() | 1152 | public void StopFlying() |
1153 | { | 1153 | { |
1154 | ControllingClient.StopFlying(this); | 1154 | ControllingClient.StopFlying(this); |
1155 | } | 1155 | } |
1156 | 1156 | ||
1157 | public void AddNeighbourRegion(ulong regionHandle, string cap) | 1157 | public void AddNeighbourRegion(ulong regionHandle, string cap) |
1158 | { | 1158 | { |
1159 | lock (m_knownChildRegions) | 1159 | lock (m_knownChildRegions) |
1160 | { | 1160 | { |
1161 | if (!m_knownChildRegions.ContainsKey(regionHandle)) | 1161 | if (!m_knownChildRegions.ContainsKey(regionHandle)) |
1162 | { | 1162 | { |
1163 | uint x, y; | 1163 | uint x, y; |
1164 | Utils.LongToUInts(regionHandle, out x, out y); | 1164 | Utils.LongToUInts(regionHandle, out x, out y); |
1165 | m_knownChildRegions.Add(regionHandle, cap); | 1165 | m_knownChildRegions.Add(regionHandle, cap); |
1166 | } | 1166 | } |
1167 | } | 1167 | } |
1168 | } | 1168 | } |
1169 | 1169 | ||
1170 | public void RemoveNeighbourRegion(ulong regionHandle) | 1170 | public void RemoveNeighbourRegion(ulong regionHandle) |
1171 | { | 1171 | { |
1172 | lock (m_knownChildRegions) | 1172 | lock (m_knownChildRegions) |
1173 | { | 1173 | { |
1174 | if (m_knownChildRegions.ContainsKey(regionHandle)) | 1174 | if (m_knownChildRegions.ContainsKey(regionHandle)) |
1175 | { | 1175 | { |
1176 | m_knownChildRegions.Remove(regionHandle); | 1176 | m_knownChildRegions.Remove(regionHandle); |
1177 | //m_log.Debug(" !!! removing known region {0} in {1}. Count = {2}", regionHandle, Scene.RegionInfo.RegionName, m_knownChildRegions.Count); | 1177 | //m_log.Debug(" !!! removing known region {0} in {1}. Count = {2}", regionHandle, Scene.RegionInfo.RegionName, m_knownChildRegions.Count); |
1178 | } | 1178 | } |
1179 | } | 1179 | } |
1180 | } | 1180 | } |
1181 | 1181 | ||
1182 | public void DropOldNeighbours(List<ulong> oldRegions) | 1182 | public void DropOldNeighbours(List<ulong> oldRegions) |
1183 | { | 1183 | { |
1184 | foreach (ulong handle in oldRegions) | 1184 | foreach (ulong handle in oldRegions) |
1185 | { | 1185 | { |
1186 | RemoveNeighbourRegion(handle); | 1186 | RemoveNeighbourRegion(handle); |
1187 | Scene.CapsModule.DropChildSeed(UUID, handle); | 1187 | Scene.CapsModule.DropChildSeed(UUID, handle); |
1188 | } | 1188 | } |
1189 | } | 1189 | } |
1190 | 1190 | ||
1191 | public List<ulong> GetKnownRegionList() | 1191 | public List<ulong> GetKnownRegionList() |
1192 | { | 1192 | { |
1193 | return new List<ulong>(m_knownChildRegions.Keys); | 1193 | return new List<ulong>(m_knownChildRegions.Keys); |
1194 | } | 1194 | } |
1195 | 1195 | ||
1196 | #endregion | 1196 | #endregion |
1197 | 1197 | ||
1198 | #region Event Handlers | 1198 | #region Event Handlers |
1199 | 1199 | ||
1200 | /// <summary> | 1200 | /// <summary> |
1201 | /// Sets avatar height in the phyiscs plugin | 1201 | /// Sets avatar height in the phyiscs plugin |
1202 | /// </summary> | 1202 | /// </summary> |
1203 | internal void SetHeight(float height) | 1203 | internal void SetHeight(float height) |
1204 | { | 1204 | { |
1205 | m_avHeight = height; | 1205 | m_avHeight = height; |
1206 | if (PhysicsActor != null && !IsChildAgent) | 1206 | if (PhysicsActor != null && !IsChildAgent) |
1207 | { | 1207 | { |
1208 | Vector3 SetSize = new Vector3(0.45f, 0.6f, m_avHeight); | 1208 | Vector3 SetSize = new Vector3(0.45f, 0.6f, m_avHeight); |
1209 | PhysicsActor.Size = SetSize; | 1209 | PhysicsActor.Size = SetSize; |
1210 | } | 1210 | } |
1211 | } | 1211 | } |
1212 | 1212 | ||
1213 | /// <summary> | 1213 | /// <summary> |
1214 | /// Complete Avatar's movement into the region. | 1214 | /// Complete Avatar's movement into the region. |
1215 | /// This is called upon a very important packet sent from the client, | 1215 | /// This is called upon a very important packet sent from the client, |
1216 | /// so it's client-controlled. Never call this method directly. | 1216 | /// so it's client-controlled. Never call this method directly. |
1217 | /// </summary> | 1217 | /// </summary> |
1218 | public void CompleteMovement(IClientAPI client) | 1218 | public void CompleteMovement(IClientAPI client) |
1219 | { | 1219 | { |
1220 | //m_log.Debug("[SCENE PRESENCE]: CompleteMovement"); | 1220 | //m_log.Debug("[SCENE PRESENCE]: CompleteMovement"); |
1221 | 1221 | ||
1222 | Vector3 look = Velocity; | 1222 | Vector3 look = Velocity; |
1223 | if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) | 1223 | if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) |
1224 | { | 1224 | { |
1225 | look = new Vector3(0.99f, 0.042f, 0); | 1225 | look = new Vector3(0.99f, 0.042f, 0); |
1226 | } | 1226 | } |
1227 | 1227 | ||
1228 | // Prevent teleporting to an underground location | 1228 | // Prevent teleporting to an underground location |
1229 | // (may crash client otherwise) | 1229 | // (may crash client otherwise) |
1230 | // | 1230 | // |
1231 | Vector3 pos = AbsolutePosition; | 1231 | Vector3 pos = AbsolutePosition; |
1232 | float ground = m_scene.GetGroundHeight(pos.X, pos.Y); | 1232 | float ground = m_scene.GetGroundHeight(pos.X, pos.Y); |
1233 | if (pos.Z < ground + 1.5f) | 1233 | if (pos.Z < ground + 1.5f) |
1234 | { | 1234 | { |
1235 | pos.Z = ground + 1.5f; | 1235 | pos.Z = ground + 1.5f; |
1236 | AbsolutePosition = pos; | 1236 | AbsolutePosition = pos; |
1237 | } | 1237 | } |
1238 | m_isChildAgent = false; | 1238 | m_isChildAgent = false; |
1239 | bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); | 1239 | bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); |
1240 | MakeRootAgent(AbsolutePosition, m_flying); | 1240 | MakeRootAgent(AbsolutePosition, m_flying); |
1241 | 1241 | ||
1242 | if ((m_callbackURI != null) && !m_callbackURI.Equals("")) | 1242 | if ((m_callbackURI != null) && !m_callbackURI.Equals("")) |
1243 | { | 1243 | { |
1244 | m_log.DebugFormat("[SCENE PRESENCE]: Releasing agent in URI {0}", m_callbackURI); | 1244 | m_log.DebugFormat("[SCENE PRESENCE]: Releasing agent in URI {0}", m_callbackURI); |
1245 | Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); | 1245 | Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); |
1246 | m_callbackURI = null; | 1246 | m_callbackURI = null; |
1247 | } | 1247 | } |
1248 | 1248 | ||
1249 | //m_log.DebugFormat("Completed movement"); | 1249 | //m_log.DebugFormat("Completed movement"); |
1250 | 1250 | ||
1251 | m_controllingClient.MoveAgentIntoRegion(m_regionInfo, AbsolutePosition, look); | 1251 | m_controllingClient.MoveAgentIntoRegion(m_regionInfo, AbsolutePosition, look); |
1252 | SendInitialData(); | 1252 | SendInitialData(); |
1253 | 1253 | ||
1254 | // Create child agents in neighbouring regions | 1254 | // Create child agents in neighbouring regions |
1255 | if (!m_isChildAgent) | 1255 | if (!m_isChildAgent) |
1256 | { | 1256 | { |
1257 | IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); | 1257 | IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); |
1258 | if (m_agentTransfer != null) | 1258 | if (m_agentTransfer != null) |
1259 | m_agentTransfer.EnableChildAgents(this); | 1259 | m_agentTransfer.EnableChildAgents(this); |
1260 | else | 1260 | else |
1261 | m_log.DebugFormat("[SCENE PRESENCE]: Unable to create child agents in neighbours, because AgentTransferModule is not active"); | 1261 | m_log.DebugFormat("[SCENE PRESENCE]: Unable to create child agents in neighbours, because AgentTransferModule is not active"); |
1262 | 1262 | ||
1263 | IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); | 1263 | IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); |
1264 | if (friendsModule != null) | 1264 | if (friendsModule != null) |
1265 | friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); | 1265 | friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); |
1266 | } | 1266 | } |
1267 | 1267 | ||
1268 | } | 1268 | } |
1269 | 1269 | ||
1270 | /// <summary> | 1270 | /// <summary> |
1271 | /// Callback for the Camera view block check. Gets called with the results of the camera view block test | 1271 | /// Callback for the Camera view block check. Gets called with the results of the camera view block test |
1272 | /// hitYN is true when there's something in the way. | 1272 | /// hitYN is true when there's something in the way. |
1273 | /// </summary> | 1273 | /// </summary> |
1274 | /// <param name="hitYN"></param> | 1274 | /// <param name="hitYN"></param> |
1275 | /// <param name="collisionPoint"></param> | 1275 | /// <param name="collisionPoint"></param> |
1276 | /// <param name="localid"></param> | 1276 | /// <param name="localid"></param> |
1277 | /// <param name="distance"></param> | 1277 | /// <param name="distance"></param> |
1278 | public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal) | 1278 | public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal) |
1279 | { | 1279 | { |
1280 | const float POSITION_TOLERANCE = 0.02f; | 1280 | const float POSITION_TOLERANCE = 0.02f; |
1281 | const float VELOCITY_TOLERANCE = 0.02f; | 1281 | const float VELOCITY_TOLERANCE = 0.02f; |
1282 | const float ROTATION_TOLERANCE = 0.02f; | 1282 | const float ROTATION_TOLERANCE = 0.02f; |
1283 | 1283 | ||
1284 | if (m_followCamAuto) | 1284 | if (m_followCamAuto) |
1285 | { | 1285 | { |
1286 | if (hitYN) | 1286 | if (hitYN) |
1287 | { | 1287 | { |
1288 | CameraConstraintActive = true; | 1288 | CameraConstraintActive = true; |
1289 | //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance); | 1289 | //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance); |
1290 | 1290 | ||
1291 | Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint); | 1291 | Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint); |
1292 | ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint))); | 1292 | ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint))); |
1293 | } | 1293 | } |
1294 | else | 1294 | else |
1295 | { | 1295 | { |
1296 | if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || | 1296 | if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || |
1297 | !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || | 1297 | !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || |
1298 | !m_bodyRot.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) | 1298 | !m_bodyRot.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) |
1299 | { | 1299 | { |
1300 | if (CameraConstraintActive) | 1300 | if (CameraConstraintActive) |
1301 | { | 1301 | { |
1302 | ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f)); | 1302 | ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f)); |
1303 | CameraConstraintActive = false; | 1303 | CameraConstraintActive = false; |
1304 | } | 1304 | } |
1305 | } | 1305 | } |
1306 | } | 1306 | } |
1307 | } | 1307 | } |
1308 | } | 1308 | } |
1309 | 1309 | ||
1310 | /// <summary> | 1310 | /// <summary> |
1311 | /// This is the event handler for client movement. If a client is moving, this event is triggering. | 1311 | /// This is the event handler for client movement. If a client is moving, this event is triggering. |
1312 | /// </summary> | 1312 | /// </summary> |
1313 | public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) | 1313 | public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) |
1314 | { | 1314 | { |
1315 | //if (m_isChildAgent) | 1315 | //if (m_isChildAgent) |
1316 | //{ | 1316 | //{ |
1317 | // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent"); | 1317 | // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent"); |
1318 | // return; | 1318 | // return; |
1319 | //} | 1319 | //} |
1320 | 1320 | ||
1321 | m_perfMonMS = Util.EnvironmentTickCount(); | 1321 | m_perfMonMS = Util.EnvironmentTickCount(); |
1322 | 1322 | ||
1323 | ++m_movementUpdateCount; | 1323 | ++m_movementUpdateCount; |
1324 | if (m_movementUpdateCount < 1) | 1324 | if (m_movementUpdateCount < 1) |
1325 | m_movementUpdateCount = 1; | 1325 | m_movementUpdateCount = 1; |
1326 | 1326 | ||
1327 | #region Sanity Checking | 1327 | #region Sanity Checking |
1328 | 1328 | ||
1329 | // This is irritating. Really. | 1329 | // This is irritating. Really. |
1330 | if (!AbsolutePosition.IsFinite()) | 1330 | if (!AbsolutePosition.IsFinite()) |
1331 | { | 1331 | { |
1332 | RemoveFromPhysicalScene(); | 1332 | RemoveFromPhysicalScene(); |
1333 | m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); | 1333 | m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); |
1334 | 1334 | ||
1335 | m_pos = m_LastFinitePos; | 1335 | m_pos = m_LastFinitePos; |
1336 | 1336 | ||
1337 | if (!m_pos.IsFinite()) | 1337 | if (!m_pos.IsFinite()) |
1338 | { | 1338 | { |
1339 | m_pos.X = 127f; | 1339 | m_pos.X = 127f; |
1340 | m_pos.Y = 127f; | 1340 | m_pos.Y = 127f; |
1341 | m_pos.Z = 127f; | 1341 | m_pos.Z = 127f; |
1342 | m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999903"); | 1342 | m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999903"); |
1343 | } | 1343 | } |
1344 | 1344 | ||
1345 | AddToPhysicalScene(false); | 1345 | AddToPhysicalScene(false); |
1346 | } | 1346 | } |
1347 | else | 1347 | else |
1348 | { | 1348 | { |
1349 | m_LastFinitePos = m_pos; | 1349 | m_LastFinitePos = m_pos; |
1350 | } | 1350 | } |
1351 | 1351 | ||
1352 | #endregion Sanity Checking | 1352 | #endregion Sanity Checking |
1353 | 1353 | ||
1354 | #region Inputs | 1354 | #region Inputs |
1355 | 1355 | ||
1356 | AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags; | 1356 | AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags; |
1357 | Quaternion bodyRotation = agentData.BodyRotation; | 1357 | Quaternion bodyRotation = agentData.BodyRotation; |
1358 | 1358 | ||
1359 | // Camera location in world. We'll need to raytrace | 1359 | // Camera location in world. We'll need to raytrace |
1360 | // from this location from time to time. | 1360 | // from this location from time to time. |
1361 | m_CameraCenter = agentData.CameraCenter; | 1361 | m_CameraCenter = agentData.CameraCenter; |
1362 | if (Vector3.Distance(m_lastCameraCenter, m_CameraCenter) >= Scene.RootReprioritizationDistance) | 1362 | if (Vector3.Distance(m_lastCameraCenter, m_CameraCenter) >= Scene.RootReprioritizationDistance) |
1363 | { | 1363 | { |
1364 | ReprioritizeUpdates(); | 1364 | ReprioritizeUpdates(); |
1365 | m_lastCameraCenter = m_CameraCenter; | 1365 | m_lastCameraCenter = m_CameraCenter; |
1366 | } | 1366 | } |
1367 | 1367 | ||
1368 | // Use these three vectors to figure out what the agent is looking at | 1368 | // Use these three vectors to figure out what the agent is looking at |
1369 | // Convert it to a Matrix and/or Quaternion | 1369 | // Convert it to a Matrix and/or Quaternion |
1370 | m_CameraAtAxis = agentData.CameraAtAxis; | 1370 | m_CameraAtAxis = agentData.CameraAtAxis; |
1371 | m_CameraLeftAxis = agentData.CameraLeftAxis; | 1371 | m_CameraLeftAxis = agentData.CameraLeftAxis; |
1372 | m_CameraUpAxis = agentData.CameraUpAxis; | 1372 | m_CameraUpAxis = agentData.CameraUpAxis; |
1373 | 1373 | ||
1374 | // The Agent's Draw distance setting | 1374 | // The Agent's Draw distance setting |
1375 | m_DrawDistance = agentData.Far; | 1375 | m_DrawDistance = agentData.Far; |
1376 | 1376 | ||
1377 | // Check if Client has camera in 'follow cam' or 'build' mode. | 1377 | // Check if Client has camera in 'follow cam' or 'build' mode. |
1378 | Vector3 camdif = (Vector3.One * m_bodyRot - Vector3.One * CameraRotation); | 1378 | Vector3 camdif = (Vector3.One * m_bodyRot - Vector3.One * CameraRotation); |
1379 | 1379 | ||
1380 | m_followCamAuto = ((m_CameraUpAxis.Z > 0.959f && m_CameraUpAxis.Z < 0.98f) | 1380 | m_followCamAuto = ((m_CameraUpAxis.Z > 0.959f && m_CameraUpAxis.Z < 0.98f) |
1381 | && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false; | 1381 | && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false; |
1382 | 1382 | ||
1383 | m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0; | 1383 | m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0; |
1384 | m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0; | 1384 | m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0; |
1385 | 1385 | ||
1386 | #endregion Inputs | 1386 | #endregion Inputs |
1387 | 1387 | ||
1388 | if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0) | 1388 | if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0) |
1389 | { | 1389 | { |
1390 | StandUp(); | 1390 | StandUp(); |
1391 | } | 1391 | } |
1392 | 1392 | ||
1393 | //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto); | 1393 | //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto); |
1394 | // Raycast from the avatar's head to the camera to see if there's anything blocking the view | 1394 | // Raycast from the avatar's head to the camera to see if there's anything blocking the view |
1395 | if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast()) | 1395 | if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast()) |
1396 | { | 1396 | { |
1397 | if (m_followCamAuto) | 1397 | if (m_followCamAuto) |
1398 | { | 1398 | { |
1399 | Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT; | 1399 | Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT; |
1400 | m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); | 1400 | m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); |
1401 | } | 1401 | } |
1402 | } | 1402 | } |
1403 | lock (scriptedcontrols) | 1403 | lock (scriptedcontrols) |
1404 | { | 1404 | { |
1405 | if (scriptedcontrols.Count > 0) | 1405 | if (scriptedcontrols.Count > 0) |
1406 | { | 1406 | { |
1407 | SendControlToScripts((uint)flags); | 1407 | SendControlToScripts((uint)flags); |
1408 | flags = RemoveIgnoredControls(flags, IgnoredControls); | 1408 | flags = RemoveIgnoredControls(flags, IgnoredControls); |
1409 | } | 1409 | } |
1410 | } | 1410 | } |
1411 | 1411 | ||
1412 | if (m_autopilotMoving) | 1412 | if (m_autopilotMoving) |
1413 | CheckAtSitTarget(); | 1413 | CheckAtSitTarget(); |
1414 | 1414 | ||
1415 | if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) | 1415 | if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) |
1416 | { | 1416 | { |
1417 | m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick. | 1417 | m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick. |
1418 | Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); | 1418 | Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); |
1419 | 1419 | ||
1420 | // TODO: This doesn't prevent the user from walking yet. | 1420 | // TODO: This doesn't prevent the user from walking yet. |
1421 | // Setting parent ID would fix this, if we knew what value | 1421 | // Setting parent ID would fix this, if we knew what value |
1422 | // to use. Or we could add a m_isSitting variable. | 1422 | // to use. Or we could add a m_isSitting variable. |
1423 | //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); | 1423 | //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); |
1424 | SitGround = true; | 1424 | SitGround = true; |
1425 | } | 1425 | } |
1426 | 1426 | ||
1427 | // In the future, these values might need to go global. | 1427 | // In the future, these values might need to go global. |
1428 | // Here's where you get them. | 1428 | // Here's where you get them. |
1429 | m_AgentControlFlags = flags; | 1429 | m_AgentControlFlags = flags; |
1430 | m_headrotation = agentData.HeadRotation; | 1430 | m_headrotation = agentData.HeadRotation; |
1431 | m_state = agentData.State; | 1431 | m_state = agentData.State; |
1432 | 1432 | ||
1433 | PhysicsActor actor = PhysicsActor; | 1433 | PhysicsActor actor = PhysicsActor; |
1434 | if (actor == null) | 1434 | if (actor == null) |
1435 | { | 1435 | { |
1436 | return; | 1436 | return; |
1437 | } | 1437 | } |
1438 | 1438 | ||
1439 | bool update_movementflag = false; | 1439 | bool update_movementflag = false; |
1440 | 1440 | ||
1441 | if (m_allowMovement && !SitGround) | 1441 | if (m_allowMovement && !SitGround) |
1442 | { | 1442 | { |
1443 | if (agentData.UseClientAgentPosition) | 1443 | if (agentData.UseClientAgentPosition) |
1444 | { | 1444 | { |
1445 | m_moveToPositionInProgress = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f; | 1445 | m_moveToPositionInProgress = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f; |
1446 | m_moveToPositionTarget = agentData.ClientAgentPosition; | 1446 | m_moveToPositionTarget = agentData.ClientAgentPosition; |
1447 | } | 1447 | } |
1448 | 1448 | ||
1449 | int i = 0; | 1449 | int i = 0; |
1450 | 1450 | ||
1451 | bool update_rotation = false; | 1451 | bool update_rotation = false; |
1452 | bool DCFlagKeyPressed = false; | 1452 | bool DCFlagKeyPressed = false; |
1453 | Vector3 agent_control_v3 = Vector3.Zero; | 1453 | Vector3 agent_control_v3 = Vector3.Zero; |
1454 | Quaternion q = bodyRotation; | 1454 | Quaternion q = bodyRotation; |
1455 | 1455 | ||
1456 | bool oldflying = PhysicsActor.Flying; | 1456 | bool oldflying = PhysicsActor.Flying; |
1457 | 1457 | ||
1458 | if (m_forceFly) | 1458 | if (m_forceFly) |
1459 | actor.Flying = true; | 1459 | actor.Flying = true; |
1460 | else if (m_flyDisabled) | 1460 | else if (m_flyDisabled) |
1461 | actor.Flying = false; | 1461 | actor.Flying = false; |
1462 | else | 1462 | else |
1463 | actor.Flying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); | 1463 | actor.Flying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); |
1464 | 1464 | ||
1465 | if (actor.Flying != oldflying) | 1465 | if (actor.Flying != oldflying) |
1466 | update_movementflag = true; | 1466 | update_movementflag = true; |
1467 | 1467 | ||
1468 | if (q != m_bodyRot) | 1468 | if (q != m_bodyRot) |
1469 | { | 1469 | { |
1470 | m_bodyRot = q; | 1470 | m_bodyRot = q; |
1471 | update_rotation = true; | 1471 | update_rotation = true; |
1472 | } | 1472 | } |
1473 | 1473 | ||
1474 | //guilty until proven innocent.. | 1474 | //guilty until proven innocent.. |
1475 | bool Nudging = true; | 1475 | bool Nudging = true; |
1476 | //Basically, if there is at least one non-nudge control then we don't need | 1476 | //Basically, if there is at least one non-nudge control then we don't need |
1477 | //to worry about stopping the avatar | 1477 | //to worry about stopping the avatar |
1478 | 1478 | ||
1479 | if (m_parentID == 0) | 1479 | if (m_parentID == 0) |
1480 | { | 1480 | { |
1481 | bool bAllowUpdateMoveToPosition = false; | 1481 | bool bAllowUpdateMoveToPosition = false; |
1482 | bool bResetMoveToPosition = false; | 1482 | bool bResetMoveToPosition = false; |
1483 | 1483 | ||
1484 | Vector3[] dirVectors; | 1484 | Vector3[] dirVectors; |
1485 | 1485 | ||
1486 | // use camera up angle when in mouselook and not flying or when holding the left mouse button down and not flying | 1486 | // use camera up angle when in mouselook and not flying or when holding the left mouse button down and not flying |
1487 | // this prevents 'jumping' in inappropriate situations. | 1487 | // this prevents 'jumping' in inappropriate situations. |
1488 | if ((m_mouseLook && !m_physicsActor.Flying) || (m_leftButtonDown && !m_physicsActor.Flying)) | 1488 | if ((m_mouseLook && !m_physicsActor.Flying) || (m_leftButtonDown && !m_physicsActor.Flying)) |
1489 | dirVectors = GetWalkDirectionVectors(); | 1489 | dirVectors = GetWalkDirectionVectors(); |
1490 | else | 1490 | else |
1491 | dirVectors = Dir_Vectors; | 1491 | dirVectors = Dir_Vectors; |
1492 | 1492 | ||
1493 | bool[] isNudge = GetDirectionIsNudge(); | 1493 | bool[] isNudge = GetDirectionIsNudge(); |
1494 | 1494 | ||
1495 | 1495 | ||
1496 | 1496 | ||
1497 | 1497 | ||
1498 | 1498 | ||
1499 | foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) | 1499 | foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) |
1500 | { | 1500 | { |
1501 | if (((uint)flags & (uint)DCF) != 0) | 1501 | if (((uint)flags & (uint)DCF) != 0) |
1502 | { | 1502 | { |
1503 | bResetMoveToPosition = true; | 1503 | bResetMoveToPosition = true; |
1504 | DCFlagKeyPressed = true; | 1504 | DCFlagKeyPressed = true; |
1505 | try | 1505 | try |
1506 | { | 1506 | { |
1507 | agent_control_v3 += dirVectors[i]; | 1507 | agent_control_v3 += dirVectors[i]; |
1508 | if (isNudge[i] == false) | 1508 | if (isNudge[i] == false) |
1509 | { | 1509 | { |
1510 | Nudging = false; | 1510 | Nudging = false; |
1511 | } | 1511 | } |
1512 | } | 1512 | } |
1513 | catch (IndexOutOfRangeException) | 1513 | catch (IndexOutOfRangeException) |
1514 | { | 1514 | { |
1515 | // Why did I get this? | 1515 | // Why did I get this? |
1516 | } | 1516 | } |
1517 | 1517 | ||
1518 | if ((m_movementflag & (uint)DCF) == 0) | 1518 | if ((m_movementflag & (uint)DCF) == 0) |
1519 | { | 1519 | { |
1520 | m_movementflag += (byte)(uint)DCF; | 1520 | m_movementflag += (byte)(uint)DCF; |
1521 | update_movementflag = true; | 1521 | update_movementflag = true; |
1522 | } | 1522 | } |
1523 | } | 1523 | } |
1524 | else | 1524 | else |
1525 | { | 1525 | { |
1526 | if ((m_movementflag & (uint)DCF) != 0) | 1526 | if ((m_movementflag & (uint)DCF) != 0) |
1527 | { | 1527 | { |
1528 | m_movementflag -= (byte)(uint)DCF; | 1528 | m_movementflag -= (byte)(uint)DCF; |
1529 | update_movementflag = true; | 1529 | update_movementflag = true; |
1530 | } | 1530 | } |
1531 | else | 1531 | else |
1532 | { | 1532 | { |
1533 | bAllowUpdateMoveToPosition = true; | 1533 | bAllowUpdateMoveToPosition = true; |
1534 | } | 1534 | } |
1535 | } | 1535 | } |
1536 | i++; | 1536 | i++; |
1537 | } | 1537 | } |
1538 | //Paupaw:Do Proper PID for Autopilot here | 1538 | //Paupaw:Do Proper PID for Autopilot here |
1539 | if (bResetMoveToPosition) | 1539 | if (bResetMoveToPosition) |
1540 | { | 1540 | { |
1541 | m_moveToPositionTarget = Vector3.Zero; | 1541 | m_moveToPositionTarget = Vector3.Zero; |
1542 | m_moveToPositionInProgress = false; | 1542 | m_moveToPositionInProgress = false; |
1543 | update_movementflag = true; | 1543 | update_movementflag = true; |
1544 | bAllowUpdateMoveToPosition = false; | 1544 | bAllowUpdateMoveToPosition = false; |
1545 | } | 1545 | } |
1546 | 1546 | ||
1547 | if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving)) | 1547 | if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving)) |
1548 | { | 1548 | { |
1549 | //Check the error term of the current position in relation to the target position | 1549 | //Check the error term of the current position in relation to the target position |
1550 | if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f) | 1550 | if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f) |
1551 | { | 1551 | { |
1552 | // we are close enough to the target | 1552 | // we are close enough to the target |
1553 | m_moveToPositionTarget = Vector3.Zero; | 1553 | m_moveToPositionTarget = Vector3.Zero; |
1554 | m_moveToPositionInProgress = false; | 1554 | m_moveToPositionInProgress = false; |
1555 | update_movementflag = true; | 1555 | update_movementflag = true; |
1556 | } | 1556 | } |
1557 | else | 1557 | else |
1558 | { | 1558 | { |
1559 | try | 1559 | try |
1560 | { | 1560 | { |
1561 | // move avatar in 2D at one meter/second towards target, in avatar coordinate frame. | 1561 | // move avatar in 2D at one meter/second towards target, in avatar coordinate frame. |
1562 | // This movement vector gets added to the velocity through AddNewMovement(). | 1562 | // This movement vector gets added to the velocity through AddNewMovement(). |
1563 | // Theoretically we might need a more complex PID approach here if other | 1563 | // Theoretically we might need a more complex PID approach here if other |
1564 | // unknown forces are acting on the avatar and we need to adaptively respond | 1564 | // unknown forces are acting on the avatar and we need to adaptively respond |
1565 | // to such forces, but the following simple approach seems to works fine. | 1565 | // to such forces, but the following simple approach seems to works fine. |
1566 | Vector3 LocalVectorToTarget3D = | 1566 | Vector3 LocalVectorToTarget3D = |
1567 | (m_moveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords | 1567 | (m_moveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords |
1568 | * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords | 1568 | * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords |
1569 | // Ignore z component of vector | 1569 | // Ignore z component of vector |
1570 | Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); | 1570 | Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); |
1571 | LocalVectorToTarget2D.Normalize(); | 1571 | LocalVectorToTarget2D.Normalize(); |
1572 | 1572 | ||
1573 | //We're not nudging | 1573 | //We're not nudging |
1574 | Nudging = false; | 1574 | Nudging = false; |
1575 | agent_control_v3 += LocalVectorToTarget2D; | 1575 | agent_control_v3 += LocalVectorToTarget2D; |
1576 | 1576 | ||
1577 | // update avatar movement flags. the avatar coordinate system is as follows: | 1577 | // update avatar movement flags. the avatar coordinate system is as follows: |
1578 | // | 1578 | // |
1579 | // +X (forward) | 1579 | // +X (forward) |
1580 | // | 1580 | // |
1581 | // ^ | 1581 | // ^ |
1582 | // | | 1582 | // | |
1583 | // | | 1583 | // | |
1584 | // | | 1584 | // | |
1585 | // | | 1585 | // | |
1586 | // (left) +Y <--------o--------> -Y | 1586 | // (left) +Y <--------o--------> -Y |
1587 | // avatar | 1587 | // avatar |
1588 | // | | 1588 | // | |
1589 | // | | 1589 | // | |
1590 | // | | 1590 | // | |
1591 | // | | 1591 | // | |
1592 | // v | 1592 | // v |
1593 | // -X | 1593 | // -X |
1594 | // | 1594 | // |
1595 | 1595 | ||
1596 | // based on the above avatar coordinate system, classify the movement into | 1596 | // based on the above avatar coordinate system, classify the movement into |
1597 | // one of left/right/back/forward. | 1597 | // one of left/right/back/forward. |
1598 | if (LocalVectorToTarget2D.Y > 0)//MoveLeft | 1598 | if (LocalVectorToTarget2D.Y > 0)//MoveLeft |
1599 | { | 1599 | { |
1600 | m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; | 1600 | m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; |
1601 | //AgentControlFlags | 1601 | //AgentControlFlags |
1602 | AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; | 1602 | AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; |
1603 | update_movementflag = true; | 1603 | update_movementflag = true; |
1604 | } | 1604 | } |
1605 | else if (LocalVectorToTarget2D.Y < 0) //MoveRight | 1605 | else if (LocalVectorToTarget2D.Y < 0) //MoveRight |
1606 | { | 1606 | { |
1607 | m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; | 1607 | m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; |
1608 | AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; | 1608 | AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; |
1609 | update_movementflag = true; | 1609 | update_movementflag = true; |
1610 | } | 1610 | } |
1611 | if (LocalVectorToTarget2D.X < 0) //MoveBack | 1611 | if (LocalVectorToTarget2D.X < 0) //MoveBack |
1612 | { | 1612 | { |
1613 | m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; | 1613 | m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; |
1614 | AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; | 1614 | AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; |
1615 | update_movementflag = true; | 1615 | update_movementflag = true; |
1616 | } | 1616 | } |
1617 | else if (LocalVectorToTarget2D.X > 0) //Move Forward | 1617 | else if (LocalVectorToTarget2D.X > 0) //Move Forward |
1618 | { | 1618 | { |
1619 | m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; | 1619 | m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; |
1620 | AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; | 1620 | AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; |
1621 | update_movementflag = true; | 1621 | update_movementflag = true; |
1622 | } | 1622 | } |
1623 | } | 1623 | } |
1624 | catch (Exception e) | 1624 | catch (Exception e) |
1625 | { | 1625 | { |
1626 | //Avoid system crash, can be slower but... | 1626 | //Avoid system crash, can be slower but... |
1627 | m_log.DebugFormat("Crash! {0}", e.ToString()); | 1627 | m_log.DebugFormat("Crash! {0}", e.ToString()); |
1628 | } | 1628 | } |
1629 | } | 1629 | } |
1630 | } | 1630 | } |
1631 | } | 1631 | } |
1632 | 1632 | ||
1633 | // Cause the avatar to stop flying if it's colliding | 1633 | // Cause the avatar to stop flying if it's colliding |
1634 | // with something with the down arrow pressed. | 1634 | // with something with the down arrow pressed. |
1635 | 1635 | ||
1636 | // Only do this if we're flying | 1636 | // Only do this if we're flying |
1637 | if (m_physicsActor != null && m_physicsActor.Flying && !m_forceFly) | 1637 | if (m_physicsActor != null && m_physicsActor.Flying && !m_forceFly) |
1638 | { | 1638 | { |
1639 | // Landing detection code | 1639 | // Landing detection code |
1640 | 1640 | ||
1641 | // Are the landing controls requirements filled? | 1641 | // Are the landing controls requirements filled? |
1642 | bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || | 1642 | bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || |
1643 | ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); | 1643 | ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); |
1644 | 1644 | ||
1645 | // Are the collision requirements fulfilled? | 1645 | // Are the collision requirements fulfilled? |
1646 | bool colliding = (m_physicsActor.IsColliding == true); | 1646 | bool colliding = (m_physicsActor.IsColliding == true); |
1647 | 1647 | ||
1648 | if (m_physicsActor.Flying && colliding && controlland) | 1648 | if (m_physicsActor.Flying && colliding && controlland) |
1649 | { | 1649 | { |
1650 | // nesting this check because LengthSquared() is expensive and we don't | 1650 | // nesting this check because LengthSquared() is expensive and we don't |
1651 | // want to do it every step when flying. | 1651 | // want to do it every step when flying. |
1652 | if ((Velocity.LengthSquared() <= LAND_VELOCITYMAG_MAX)) | 1652 | if ((Velocity.LengthSquared() <= LAND_VELOCITYMAG_MAX)) |
1653 | StopFlying(); | 1653 | StopFlying(); |
1654 | } | 1654 | } |
1655 | } | 1655 | } |
1656 | 1656 | ||
1657 | if (update_movementflag || (update_rotation && DCFlagKeyPressed)) | 1657 | if (update_movementflag || (update_rotation && DCFlagKeyPressed)) |
1658 | { | 1658 | { |
1659 | // m_log.DebugFormat("{0} {1}", update_movementflag, (update_rotation && DCFlagKeyPressed)); | 1659 | // m_log.DebugFormat("{0} {1}", update_movementflag, (update_rotation && DCFlagKeyPressed)); |
1660 | // m_log.DebugFormat( | 1660 | // m_log.DebugFormat( |
1661 | // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); | 1661 | // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); |
1662 | 1662 | ||
1663 | AddNewMovement(agent_control_v3, q, Nudging); | 1663 | AddNewMovement(agent_control_v3, q, Nudging); |
1664 | 1664 | ||
1665 | 1665 | ||
1666 | } | 1666 | } |
1667 | } | 1667 | } |
1668 | 1668 | ||
1669 | if (update_movementflag && !SitGround) | 1669 | if (update_movementflag && !SitGround) |
1670 | Animator.UpdateMovementAnimations(); | 1670 | Animator.UpdateMovementAnimations(); |
1671 | 1671 | ||
1672 | m_scene.EventManager.TriggerOnClientMovement(this); | 1672 | m_scene.EventManager.TriggerOnClientMovement(this); |
1673 | 1673 | ||
1674 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); | 1674 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); |
1675 | } | 1675 | } |
1676 | 1676 | ||
1677 | public void DoAutoPilot(uint not_used, Vector3 Pos, IClientAPI remote_client) | 1677 | public void DoAutoPilot(uint not_used, Vector3 Pos, IClientAPI remote_client) |
1678 | { | 1678 | { |
1679 | m_autopilotMoving = true; | 1679 | m_autopilotMoving = true; |
1680 | m_autoPilotTarget = Pos; | 1680 | m_autoPilotTarget = Pos; |
1681 | m_sitAtAutoTarget = false; | 1681 | m_sitAtAutoTarget = false; |
1682 | PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; | 1682 | PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; |
1683 | //proxy.PCode = (byte)PCode.ParticleSystem; | 1683 | //proxy.PCode = (byte)PCode.ParticleSystem; |
1684 | proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); | 1684 | proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); |
1685 | proxyObjectGroup.AttachToScene(m_scene); | 1685 | proxyObjectGroup.AttachToScene(m_scene); |
1686 | 1686 | ||
1687 | // Commented out this code since it could never have executed, but might still be informative. | 1687 | // Commented out this code since it could never have executed, but might still be informative. |
1688 | // if (proxyObjectGroup != null) | 1688 | // if (proxyObjectGroup != null) |
1689 | // { | 1689 | // { |
1690 | proxyObjectGroup.SendGroupFullUpdate(); | 1690 | proxyObjectGroup.SendGroupFullUpdate(); |
1691 | remote_client.SendSitResponse(proxyObjectGroup.UUID, Vector3.Zero, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false); | 1691 | remote_client.SendSitResponse(proxyObjectGroup.UUID, Vector3.Zero, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false); |
1692 | m_scene.DeleteSceneObject(proxyObjectGroup, false); | 1692 | m_scene.DeleteSceneObject(proxyObjectGroup, false); |
1693 | // } | 1693 | // } |
1694 | // else | 1694 | // else |
1695 | // { | 1695 | // { |
1696 | // m_autopilotMoving = false; | 1696 | // m_autopilotMoving = false; |
1697 | // m_autoPilotTarget = Vector3.Zero; | 1697 | // m_autoPilotTarget = Vector3.Zero; |
1698 | // ControllingClient.SendAlertMessage("Autopilot cancelled"); | 1698 | // ControllingClient.SendAlertMessage("Autopilot cancelled"); |
1699 | // } | 1699 | // } |
1700 | } | 1700 | } |
1701 | 1701 | ||
1702 | public void DoMoveToPosition(Object sender, string method, List<String> args) | 1702 | public void DoMoveToPosition(Object sender, string method, List<String> args) |
1703 | { | 1703 | { |
1704 | try | 1704 | try |
1705 | { | 1705 | { |
1706 | float locx = 0f; | 1706 | float locx = 0f; |
1707 | float locy = 0f; | 1707 | float locy = 0f; |
1708 | float locz = 0f; | 1708 | float locz = 0f; |
1709 | uint regionX = 0; | 1709 | uint regionX = 0; |
1710 | uint regionY = 0; | 1710 | uint regionY = 0; |
1711 | try | 1711 | try |
1712 | { | 1712 | { |
1713 | Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY); | 1713 | Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY); |
1714 | locx = Convert.ToSingle(args[0]) - (float)regionX; | 1714 | locx = Convert.ToSingle(args[0]) - (float)regionX; |
1715 | locy = Convert.ToSingle(args[1]) - (float)regionY; | 1715 | locy = Convert.ToSingle(args[1]) - (float)regionY; |
1716 | locz = Convert.ToSingle(args[2]); | 1716 | locz = Convert.ToSingle(args[2]); |
1717 | } | 1717 | } |
1718 | catch (InvalidCastException) | 1718 | catch (InvalidCastException) |
1719 | { | 1719 | { |
1720 | m_log.Error("[CLIENT]: Invalid autopilot request"); | 1720 | m_log.Error("[CLIENT]: Invalid autopilot request"); |
1721 | return; | 1721 | return; |
1722 | } | 1722 | } |
1723 | m_moveToPositionInProgress = true; | 1723 | m_moveToPositionInProgress = true; |
1724 | m_moveToPositionTarget = new Vector3(locx, locy, locz); | 1724 | m_moveToPositionTarget = new Vector3(locx, locy, locz); |
1725 | } | 1725 | } |
1726 | catch (Exception ex) | 1726 | catch (Exception ex) |
1727 | { | 1727 | { |
1728 | //Why did I get this error? | 1728 | //Why did I get this error? |
1729 | m_log.Error("[SCENEPRESENCE]: DoMoveToPosition" + ex); | 1729 | m_log.Error("[SCENEPRESENCE]: DoMoveToPosition" + ex); |
1730 | } | 1730 | } |
1731 | } | 1731 | } |
1732 | 1732 | ||
1733 | private void CheckAtSitTarget() | 1733 | private void CheckAtSitTarget() |
1734 | { | 1734 | { |
1735 | //m_log.Debug("[AUTOPILOT]: " + Util.GetDistanceTo(AbsolutePosition, m_autoPilotTarget).ToString()); | 1735 | //m_log.Debug("[AUTOPILOT]: " + Util.GetDistanceTo(AbsolutePosition, m_autoPilotTarget).ToString()); |
1736 | if (Util.GetDistanceTo(AbsolutePosition, m_autoPilotTarget) <= 1.5) | 1736 | if (Util.GetDistanceTo(AbsolutePosition, m_autoPilotTarget) <= 1.5) |
1737 | { | 1737 | { |
1738 | if (m_sitAtAutoTarget) | 1738 | if (m_sitAtAutoTarget) |
1739 | { | 1739 | { |
1740 | SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetUUID); | 1740 | SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetUUID); |
1741 | if (part != null) | 1741 | if (part != null) |
1742 | { | 1742 | { |
1743 | AbsolutePosition = part.AbsolutePosition; | 1743 | AbsolutePosition = part.AbsolutePosition; |
1744 | Velocity = Vector3.Zero; | 1744 | Velocity = Vector3.Zero; |
1745 | SendFullUpdateToAllClients(); | 1745 | SendFullUpdateToAllClients(); |
1746 | 1746 | ||
1747 | HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ?? | 1747 | HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ?? |
1748 | } | 1748 | } |
1749 | //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); | 1749 | //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); |
1750 | m_requestedSitTargetUUID = UUID.Zero; | 1750 | m_requestedSitTargetUUID = UUID.Zero; |
1751 | } | 1751 | } |
1752 | /* | 1752 | /* |
1753 | else | 1753 | else |
1754 | { | 1754 | { |
1755 | //ControllingClient.SendAlertMessage("Autopilot cancelled"); | 1755 | //ControllingClient.SendAlertMessage("Autopilot cancelled"); |
1756 | //SendTerseUpdateToAllClients(); | 1756 | //SendTerseUpdateToAllClients(); |
1757 | //PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; | 1757 | //PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; |
1758 | //proxy.PCode = (byte)PCode.ParticleSystem; | 1758 | //proxy.PCode = (byte)PCode.ParticleSystem; |
1759 | ////uint nextUUID = m_scene.NextLocalId; | 1759 | ////uint nextUUID = m_scene.NextLocalId; |
1760 | 1760 | ||
1761 | //proxyObjectGroup = new SceneObjectGroup(m_scene, m_scene.RegionInfo.RegionHandle, UUID, nextUUID, m_autoPilotTarget, Quaternion.Identity, proxy); | 1761 | //proxyObjectGroup = new SceneObjectGroup(m_scene, m_scene.RegionInfo.RegionHandle, UUID, nextUUID, m_autoPilotTarget, Quaternion.Identity, proxy); |
1762 | //if (proxyObjectGroup != null) | 1762 | //if (proxyObjectGroup != null) |
1763 | //{ | 1763 | //{ |
1764 | //proxyObjectGroup.SendGroupFullUpdate(); | 1764 | //proxyObjectGroup.SendGroupFullUpdate(); |
1765 | //ControllingClient.SendSitResponse(UUID.Zero, m_autoPilotTarget, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false); | 1765 | //ControllingClient.SendSitResponse(UUID.Zero, m_autoPilotTarget, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false); |
1766 | //m_scene.DeleteSceneObject(proxyObjectGroup); | 1766 | //m_scene.DeleteSceneObject(proxyObjectGroup); |
1767 | //} | 1767 | //} |
1768 | } | 1768 | } |
1769 | */ | 1769 | */ |
1770 | m_autoPilotTarget = Vector3.Zero; | 1770 | m_autoPilotTarget = Vector3.Zero; |
1771 | m_autopilotMoving = false; | 1771 | m_autopilotMoving = false; |
1772 | } | 1772 | } |
1773 | } | 1773 | } |
1774 | /// <summary> | 1774 | /// <summary> |
1775 | /// Perform the logic necessary to stand the avatar up. This method also executes | 1775 | /// Perform the logic necessary to stand the avatar up. This method also executes |
1776 | /// the stand animation. | 1776 | /// the stand animation. |
1777 | /// </summary> | 1777 | /// </summary> |
1778 | public void StandUp() | 1778 | public void StandUp() |
1779 | { | 1779 | { |
1780 | SitGround = false; | 1780 | SitGround = false; |
1781 | 1781 | ||
1782 | if (m_parentID != 0) | 1782 | if (m_parentID != 0) |
1783 | { | 1783 | { |
1784 | SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); | 1784 | SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); |
1785 | if (part != null) | 1785 | if (part != null) |
1786 | { | 1786 | { |
1787 | part.TaskInventory.LockItemsForRead(true); | 1787 | part.TaskInventory.LockItemsForRead(true); |
1788 | TaskInventoryDictionary taskIDict = part.TaskInventory; | 1788 | TaskInventoryDictionary taskIDict = part.TaskInventory; |
1789 | if (taskIDict != null) | 1789 | if (taskIDict != null) |
1790 | { | 1790 | { |
1791 | foreach (UUID taskID in taskIDict.Keys) | 1791 | foreach (UUID taskID in taskIDict.Keys) |
1792 | { | 1792 | { |
1793 | UnRegisterControlEventsToScript(LocalId, taskID); | 1793 | UnRegisterControlEventsToScript(LocalId, taskID); |
1794 | taskIDict[taskID].PermsMask &= ~( | 1794 | taskIDict[taskID].PermsMask &= ~( |
1795 | 2048 | //PERMISSION_CONTROL_CAMERA | 1795 | 2048 | //PERMISSION_CONTROL_CAMERA |
1796 | 4); // PERMISSION_TAKE_CONTROLS | 1796 | 4); // PERMISSION_TAKE_CONTROLS |
1797 | } | 1797 | } |
1798 | } | 1798 | } |
1799 | part.TaskInventory.LockItemsForRead(false); | 1799 | part.TaskInventory.LockItemsForRead(false); |
1800 | // Reset sit target. | 1800 | // Reset sit target. |
1801 | if (part.GetAvatarOnSitTarget() == UUID) | 1801 | if (part.GetAvatarOnSitTarget() == UUID) |
1802 | part.SetAvatarOnSitTarget(UUID.Zero); | 1802 | part.SetAvatarOnSitTarget(UUID.Zero); |
1803 | m_parentPosition = part.GetWorldPosition(); | 1803 | m_parentPosition = part.GetWorldPosition(); |
1804 | ControllingClient.SendClearFollowCamProperties(part.ParentUUID); | 1804 | ControllingClient.SendClearFollowCamProperties(part.ParentUUID); |
1805 | } | 1805 | } |
1806 | // part.GetWorldRotation() is the rotation of the object being sat on | 1806 | // part.GetWorldRotation() is the rotation of the object being sat on |
1807 | // Rotation is the sittiing Av's rotation | 1807 | // Rotation is the sittiing Av's rotation |
1808 | 1808 | ||
1809 | Quaternion partRot; | 1809 | Quaternion partRot; |
1810 | // if (part.LinkNum == 1) | 1810 | // if (part.LinkNum == 1) |
1811 | // { // Root prim of linkset | 1811 | // { // Root prim of linkset |
1812 | // partRot = part.ParentGroup.RootPart.RotationOffset; | 1812 | // partRot = part.ParentGroup.RootPart.RotationOffset; |
1813 | // } | 1813 | // } |
1814 | // else | 1814 | // else |
1815 | // { // single or child prim | 1815 | // { // single or child prim |
1816 | 1816 | ||
1817 | // } | 1817 | // } |
1818 | if (part == null) //CW: Part may be gone. llDie() for example. | 1818 | if (part == null) //CW: Part may be gone. llDie() for example. |
1819 | { | 1819 | { |
1820 | partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); | 1820 | partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); |
1821 | } | 1821 | } |
1822 | else | 1822 | else |
1823 | { | 1823 | { |
1824 | partRot = part.GetWorldRotation(); | 1824 | partRot = part.GetWorldRotation(); |
1825 | } | 1825 | } |
1826 | 1826 | ||
1827 | Quaternion partIRot = Quaternion.Inverse(partRot); | 1827 | Quaternion partIRot = Quaternion.Inverse(partRot); |
1828 | 1828 | ||
1829 | Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av | 1829 | Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av |
1830 | Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av | 1830 | Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av |
1831 | 1831 | ||
1832 | 1832 | ||
1833 | if (m_physicsActor == null) | 1833 | if (m_physicsActor == null) |
1834 | { | 1834 | { |
1835 | AddToPhysicalScene(false); | 1835 | AddToPhysicalScene(false); |
1836 | } | 1836 | } |
1837 | //CW: If the part isn't null then we can set the current position | 1837 | //CW: If the part isn't null then we can set the current position |
1838 | if (part != null) | 1838 | if (part != null) |
1839 | { | 1839 | { |
1840 | Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset! | 1840 | Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset! |
1841 | AbsolutePosition = avWorldStandUp; //KF: Fix stand up. | 1841 | AbsolutePosition = avWorldStandUp; //KF: Fix stand up. |
1842 | part.IsOccupied = false; | 1842 | part.IsOccupied = false; |
1843 | part.ParentGroup.DeleteAvatar(ControllingClient.AgentId); | 1843 | part.ParentGroup.DeleteAvatar(ControllingClient.AgentId); |
1844 | } | 1844 | } |
1845 | else | 1845 | else |
1846 | { | 1846 | { |
1847 | //CW: Since the part doesn't exist, a coarse standup position isn't an issue | 1847 | //CW: Since the part doesn't exist, a coarse standup position isn't an issue |
1848 | AbsolutePosition = m_lastWorldPosition; | 1848 | AbsolutePosition = m_lastWorldPosition; |
1849 | } | 1849 | } |
1850 | 1850 | ||
1851 | m_parentPosition = Vector3.Zero; | 1851 | m_parentPosition = Vector3.Zero; |
1852 | m_parentID = 0; | 1852 | m_parentID = 0; |
1853 | m_linkedPrim = UUID.Zero; | 1853 | m_linkedPrim = UUID.Zero; |
1854 | m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); | 1854 | m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); |
1855 | SendFullUpdateToAllClients(); | 1855 | SendFullUpdateToAllClients(); |
1856 | m_requestedSitTargetID = 0; | 1856 | m_requestedSitTargetID = 0; |
1857 | 1857 | ||
1858 | if ((m_physicsActor != null) && (m_avHeight > 0)) | 1858 | if ((m_physicsActor != null) && (m_avHeight > 0)) |
1859 | { | 1859 | { |
1860 | SetHeight(m_avHeight); | 1860 | SetHeight(m_avHeight); |
1861 | } | 1861 | } |
1862 | } | 1862 | } |
1863 | Animator.TrySetMovementAnimation("STAND"); | 1863 | Animator.TrySetMovementAnimation("STAND"); |
1864 | } | 1864 | } |
1865 | 1865 | ||
1866 | private SceneObjectPart FindNextAvailableSitTarget(UUID targetID) | 1866 | private SceneObjectPart FindNextAvailableSitTarget(UUID targetID) |
1867 | { | 1867 | { |
1868 | SceneObjectPart targetPart = m_scene.GetSceneObjectPart(targetID); | 1868 | SceneObjectPart targetPart = m_scene.GetSceneObjectPart(targetID); |
1869 | if (targetPart == null) | 1869 | if (targetPart == null) |
1870 | return null; | 1870 | return null; |
1871 | 1871 | ||
1872 | // If the primitive the player clicked on has a sit target and that sit target is not full, that sit target is used. | 1872 | // If the primitive the player clicked on has a sit target and that sit target is not full, that sit target is used. |
1873 | // If the primitive the player clicked on has no sit target, and one or more other linked objects have sit targets that are not full, the sit target of the object with the lowest link number will be used. | 1873 | // If the primitive the player clicked on has no sit target, and one or more other linked objects have sit targets that are not full, the sit target of the object with the lowest link number will be used. |
1874 | 1874 | ||
1875 | // Get our own copy of the part array, and sort into the order we want to test | 1875 | // Get our own copy of the part array, and sort into the order we want to test |
1876 | SceneObjectPart[] partArray = targetPart.ParentGroup.GetParts(); | 1876 | SceneObjectPart[] partArray = targetPart.ParentGroup.GetParts(); |
1877 | Array.Sort(partArray, delegate(SceneObjectPart p1, SceneObjectPart p2) | 1877 | Array.Sort(partArray, delegate(SceneObjectPart p1, SceneObjectPart p2) |
1878 | { | 1878 | { |
1879 | // we want the originally selected part first, then the rest in link order -- so make the selected part link num (-1) | 1879 | // we want the originally selected part first, then the rest in link order -- so make the selected part link num (-1) |
1880 | int linkNum1 = p1==targetPart ? -1 : p1.LinkNum; | 1880 | int linkNum1 = p1==targetPart ? -1 : p1.LinkNum; |
1881 | int linkNum2 = p2==targetPart ? -1 : p2.LinkNum; | 1881 | int linkNum2 = p2==targetPart ? -1 : p2.LinkNum; |
1882 | return linkNum1 - linkNum2; | 1882 | return linkNum1 - linkNum2; |
1883 | } | 1883 | } |
1884 | ); | 1884 | ); |
1885 | 1885 | ||
1886 | //look for prims with explicit sit targets that are available | 1886 | //look for prims with explicit sit targets that are available |
1887 | foreach (SceneObjectPart part in partArray) | 1887 | foreach (SceneObjectPart part in partArray) |
1888 | { | 1888 | { |
1889 | // Is a sit target available? | 1889 | // Is a sit target available? |
1890 | Vector3 avSitOffSet = part.SitTargetPosition; | 1890 | Vector3 avSitOffSet = part.SitTargetPosition; |
1891 | Quaternion avSitOrientation = part.SitTargetOrientation; | 1891 | Quaternion avSitOrientation = part.SitTargetOrientation; |
1892 | UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); | 1892 | UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); |
1893 | bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero); | 1893 | bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero); |
1894 | bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored. | 1894 | bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored. |
1895 | if (SitTargetisSet && !SitTargetOccupied) | 1895 | if (SitTargetisSet && !SitTargetOccupied) |
1896 | { | 1896 | { |
1897 | //switch the target to this prim | 1897 | //switch the target to this prim |
1898 | return part; | 1898 | return part; |
1899 | } | 1899 | } |
1900 | } | 1900 | } |
1901 | 1901 | ||
1902 | // no explicit sit target found - use original target | 1902 | // no explicit sit target found - use original target |
1903 | return targetPart; | 1903 | return targetPart; |
1904 | } | 1904 | } |
1905 | 1905 | ||
1906 | private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) | 1906 | private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) |
1907 | { | 1907 | { |
1908 | bool autopilot = true; | 1908 | bool autopilot = true; |
1909 | Vector3 autopilotTarget = new Vector3(); | 1909 | Vector3 autopilotTarget = new Vector3(); |
1910 | Quaternion sitOrientation = Quaternion.Identity; | 1910 | Quaternion sitOrientation = Quaternion.Identity; |
1911 | Vector3 pos = new Vector3(); | 1911 | Vector3 pos = new Vector3(); |
1912 | Vector3 cameraEyeOffset = Vector3.Zero; | 1912 | Vector3 cameraEyeOffset = Vector3.Zero; |
1913 | Vector3 cameraAtOffset = Vector3.Zero; | 1913 | Vector3 cameraAtOffset = Vector3.Zero; |
1914 | bool forceMouselook = false; | 1914 | bool forceMouselook = false; |
1915 | 1915 | ||
1916 | //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); | 1916 | //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); |
1917 | SceneObjectPart part = FindNextAvailableSitTarget(targetID); | 1917 | SceneObjectPart part = FindNextAvailableSitTarget(targetID); |
1918 | if (part == null) return; | 1918 | if (part == null) return; |
1919 | 1919 | ||
1920 | // TODO: determine position to sit at based on scene geometry; don't trust offset from client | 1920 | // TODO: determine position to sit at based on scene geometry; don't trust offset from client |
1921 | // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it | 1921 | // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it |
1922 | 1922 | ||
1923 | // part is the prim to sit on | 1923 | // part is the prim to sit on |
1924 | // offset is the world-ref vector distance from that prim center to the click-spot | 1924 | // offset is the world-ref vector distance from that prim center to the click-spot |
1925 | // UUID is the UUID of the Avatar doing the clicking | 1925 | // UUID is the UUID of the Avatar doing the clicking |
1926 | 1926 | ||
1927 | m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation | 1927 | m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation |
1928 | 1928 | ||
1929 | // Is a sit target available? | 1929 | // Is a sit target available? |
1930 | Vector3 avSitOffSet = part.SitTargetPosition; | 1930 | Vector3 avSitOffSet = part.SitTargetPosition; |
1931 | Quaternion avSitOrientation = part.SitTargetOrientation; | 1931 | Quaternion avSitOrientation = part.SitTargetOrientation; |
1932 | 1932 | ||
1933 | bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored. | 1933 | bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored. |
1934 | // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation()); | 1934 | // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation()); |
1935 | Quaternion partRot; | 1935 | Quaternion partRot; |
1936 | // if (part.LinkNum == 1) | 1936 | // if (part.LinkNum == 1) |
1937 | // { // Root prim of linkset | 1937 | // { // Root prim of linkset |
1938 | // partRot = part.ParentGroup.RootPart.RotationOffset; | 1938 | // partRot = part.ParentGroup.RootPart.RotationOffset; |
1939 | // } | 1939 | // } |
1940 | // else | 1940 | // else |
1941 | // { // single or child prim | 1941 | // { // single or child prim |
1942 | partRot = part.GetWorldRotation(); | 1942 | partRot = part.GetWorldRotation(); |
1943 | // } | 1943 | // } |
1944 | Quaternion partIRot = Quaternion.Inverse(partRot); | 1944 | Quaternion partIRot = Quaternion.Inverse(partRot); |
1945 | //Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet); | 1945 | //Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet); |
1946 | // Sit analysis rewritten by KF 091125 | 1946 | // Sit analysis rewritten by KF 091125 |
1947 | if (SitTargetisSet) // scipted sit | 1947 | if (SitTargetisSet) // scipted sit |
1948 | { | 1948 | { |
1949 | if (!part.IsOccupied) | 1949 | if (!part.IsOccupied) |
1950 | { | 1950 | { |
1951 | //Console.WriteLine("Scripted, unoccupied"); | 1951 | //Console.WriteLine("Scripted, unoccupied"); |
1952 | part.SetAvatarOnSitTarget(UUID); // set that Av will be on it | 1952 | part.SetAvatarOnSitTarget(UUID); // set that Av will be on it |
1953 | offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one | 1953 | offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one |
1954 | 1954 | ||
1955 | Quaternion nrot = avSitOrientation; | 1955 | Quaternion nrot = avSitOrientation; |
1956 | if (!part.IsRoot) | 1956 | if (!part.IsRoot) |
1957 | { | 1957 | { |
1958 | nrot = part.RotationOffset * avSitOrientation; | 1958 | nrot = part.RotationOffset * avSitOrientation; |
1959 | } | 1959 | } |
1960 | sitOrientation = nrot; // Change rotatione to the scripted one | 1960 | sitOrientation = nrot; // Change rotatione to the scripted one |
1961 | OffsetRotation = nrot; | 1961 | OffsetRotation = nrot; |
1962 | autopilot = false; // Jump direct to scripted llSitPos() | 1962 | autopilot = false; // Jump direct to scripted llSitPos() |
1963 | } | 1963 | } |
1964 | else | 1964 | else |
1965 | { | 1965 | { |
1966 | //Console.WriteLine("Scripted, occupied"); | 1966 | //Console.WriteLine("Scripted, occupied"); |
1967 | return; | 1967 | return; |
1968 | } | 1968 | } |
1969 | } | 1969 | } |
1970 | else // Not Scripted | 1970 | else // Not Scripted |
1971 | { | 1971 | { |
1972 | if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) ) | 1972 | if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) ) |
1973 | { | 1973 | { |
1974 | // large prim & offset, ignore if other Avs sitting | 1974 | // large prim & offset, ignore if other Avs sitting |
1975 | // offset.Z -= 0.05f; | 1975 | // offset.Z -= 0.05f; |
1976 | m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked | 1976 | m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked |
1977 | autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point | 1977 | autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point |
1978 | 1978 | ||
1979 | //Console.WriteLine(" offset ={0}", offset); | 1979 | //Console.WriteLine(" offset ={0}", offset); |
1980 | //Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos); | 1980 | //Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos); |
1981 | //Console.WriteLine(" autopilotTarget={0}", autopilotTarget); | 1981 | //Console.WriteLine(" autopilotTarget={0}", autopilotTarget); |
1982 | 1982 | ||
1983 | } | 1983 | } |
1984 | else // small offset | 1984 | else // small offset |
1985 | { | 1985 | { |
1986 | //Console.WriteLine("Small offset"); | 1986 | //Console.WriteLine("Small offset"); |
1987 | if (!part.IsOccupied) | 1987 | if (!part.IsOccupied) |
1988 | { | 1988 | { |
1989 | m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center | 1989 | m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center |
1990 | autopilotTarget = part.AbsolutePosition; | 1990 | autopilotTarget = part.AbsolutePosition; |
1991 | //Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget); | 1991 | //Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget); |
1992 | } | 1992 | } |
1993 | else return; // occupied small | 1993 | else return; // occupied small |
1994 | } // end large/small | 1994 | } // end large/small |
1995 | } // end Scripted/not | 1995 | } // end Scripted/not |
1996 | cameraAtOffset = part.GetCameraAtOffset(); | 1996 | cameraAtOffset = part.GetCameraAtOffset(); |
1997 | cameraEyeOffset = part.GetCameraEyeOffset(); | 1997 | cameraEyeOffset = part.GetCameraEyeOffset(); |
1998 | forceMouselook = part.GetForceMouselook(); | 1998 | forceMouselook = part.GetForceMouselook(); |
1999 | if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); // | 1999 | if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); // |
2000 | if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); // | 2000 | if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); // |
2001 | 2001 | ||
2002 | if (m_physicsActor != null) | 2002 | if (m_physicsActor != null) |
2003 | { | 2003 | { |
2004 | // If we're not using the client autopilot, we're immediately warping the avatar to the location | 2004 | // If we're not using the client autopilot, we're immediately warping the avatar to the location |
2005 | // We can remove the physicsActor until they stand up. | 2005 | // We can remove the physicsActor until they stand up. |
2006 | m_sitAvatarHeight = m_physicsActor.Size.Z; | 2006 | m_sitAvatarHeight = m_physicsActor.Size.Z; |
2007 | if (autopilot) | 2007 | if (autopilot) |
2008 | { // its not a scripted sit | 2008 | { // its not a scripted sit |
2009 | // if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5) | 2009 | // if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5) |
2010 | if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) ) | 2010 | if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) ) |
2011 | { | 2011 | { |
2012 | autopilot = false; // close enough | 2012 | autopilot = false; // close enough |
2013 | m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup. | 2013 | m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup. |
2014 | Not using the part's position because returning the AV to the last known standing | 2014 | Not using the part's position because returning the AV to the last known standing |
2015 | position is likely to be more friendly, isn't it? */ | 2015 | position is likely to be more friendly, isn't it? */ |
2016 | RemoveFromPhysicalScene(); | 2016 | RemoveFromPhysicalScene(); |
2017 | AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target | 2017 | AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target |
2018 | } // else the autopilot will get us close | 2018 | } // else the autopilot will get us close |
2019 | } | 2019 | } |
2020 | else | 2020 | else |
2021 | { // its a scripted sit | 2021 | { // its a scripted sit |
2022 | m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup. | 2022 | m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup. |
2023 | I *am* using the part's position this time because we have no real idea how far away | 2023 | I *am* using the part's position this time because we have no real idea how far away |
2024 | the avatar is from the sit target. */ | 2024 | the avatar is from the sit target. */ |
2025 | RemoveFromPhysicalScene(); | 2025 | RemoveFromPhysicalScene(); |
2026 | } | 2026 | } |
2027 | } | 2027 | } |
2028 | else return; // physactor is null! | 2028 | else return; // physactor is null! |
2029 | 2029 | ||
2030 | Vector3 offsetr; // = offset * partIRot; | 2030 | Vector3 offsetr; // = offset * partIRot; |
2031 | // KF: In a linkset, offsetr needs to be relative to the group root! 091208 | 2031 | // KF: In a linkset, offsetr needs to be relative to the group root! 091208 |
2032 | // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot); | 2032 | // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot); |
2033 | // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error. | 2033 | // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error. |
2034 | // { // Single, or Root prim of linkset, target is ClickOffset * RootRot | 2034 | // { // Single, or Root prim of linkset, target is ClickOffset * RootRot |
2035 | //offsetr = offset * partIRot; | 2035 | //offsetr = offset * partIRot; |
2036 | // | 2036 | // |
2037 | // else | 2037 | // else |
2038 | // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot) | 2038 | // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot) |
2039 | // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + | 2039 | // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + |
2040 | // (offset * partRot); | 2040 | // (offset * partRot); |
2041 | // } | 2041 | // } |
2042 | 2042 | ||
2043 | //Console.WriteLine(" "); | 2043 | //Console.WriteLine(" "); |
2044 | //Console.WriteLine("link number ={0}", part.LinkNum); | 2044 | //Console.WriteLine("link number ={0}", part.LinkNum); |
2045 | //Console.WriteLine("Prim offset ={0}", part.OffsetPosition ); | 2045 | //Console.WriteLine("Prim offset ={0}", part.OffsetPosition ); |
2046 | //Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset); | 2046 | //Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset); |
2047 | //Console.WriteLine("Click offst ={0}", offset); | 2047 | //Console.WriteLine("Click offst ={0}", offset); |
2048 | //Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation()); | 2048 | //Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation()); |
2049 | //Console.WriteLine("offsetr ={0}", offsetr); | 2049 | //Console.WriteLine("offsetr ={0}", offsetr); |
2050 | //Console.WriteLine("Camera At ={0}", cameraAtOffset); | 2050 | //Console.WriteLine("Camera At ={0}", cameraAtOffset); |
2051 | //Console.WriteLine("Camera Eye ={0}", cameraEyeOffset); | 2051 | //Console.WriteLine("Camera Eye ={0}", cameraEyeOffset); |
2052 | 2052 | ||
2053 | //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child | 2053 | //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child |
2054 | ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); | 2054 | ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); |
2055 | 2055 | ||
2056 | m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target | 2056 | m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target |
2057 | // This calls HandleAgentSit twice, once from here, and the client calls | 2057 | // This calls HandleAgentSit twice, once from here, and the client calls |
2058 | // HandleAgentSit itself after it gets to the location | 2058 | // HandleAgentSit itself after it gets to the location |
2059 | // It doesn't get to the location until we've moved them there though | 2059 | // It doesn't get to the location until we've moved them there though |
2060 | // which happens in HandleAgentSit :P | 2060 | // which happens in HandleAgentSit :P |
2061 | m_autopilotMoving = autopilot; | 2061 | m_autopilotMoving = autopilot; |
2062 | m_autoPilotTarget = autopilotTarget; | 2062 | m_autoPilotTarget = autopilotTarget; |
2063 | m_sitAtAutoTarget = autopilot; | 2063 | m_sitAtAutoTarget = autopilot; |
2064 | m_initialSitTarget = autopilotTarget; | 2064 | m_initialSitTarget = autopilotTarget; |
2065 | if (!autopilot) | 2065 | if (!autopilot) |
2066 | HandleAgentSit(remoteClient, UUID); | 2066 | HandleAgentSit(remoteClient, UUID); |
2067 | } | 2067 | } |
2068 | 2068 | ||
2069 | public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset) | 2069 | public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset) |
2070 | { | 2070 | { |
2071 | if (m_parentID != 0) | 2071 | if (m_parentID != 0) |
2072 | { | 2072 | { |
2073 | StandUp(); | 2073 | StandUp(); |
2074 | } | 2074 | } |
2075 | m_nextSitAnimation = "SIT"; | 2075 | m_nextSitAnimation = "SIT"; |
2076 | 2076 | ||
2077 | //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); | 2077 | //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); |
2078 | SceneObjectPart part = FindNextAvailableSitTarget(targetID); | 2078 | SceneObjectPart part = FindNextAvailableSitTarget(targetID); |
2079 | 2079 | ||
2080 | if (part != null) | 2080 | if (part != null) |
2081 | { | 2081 | { |
2082 | if (!String.IsNullOrEmpty(part.SitAnimation)) | 2082 | if (!String.IsNullOrEmpty(part.SitAnimation)) |
2083 | { | 2083 | { |
2084 | m_nextSitAnimation = part.SitAnimation; | 2084 | m_nextSitAnimation = part.SitAnimation; |
2085 | } | 2085 | } |
2086 | m_requestedSitTargetID = part.LocalId; | 2086 | m_requestedSitTargetID = part.LocalId; |
2087 | //m_requestedSitOffset = offset; | 2087 | //m_requestedSitOffset = offset; |
2088 | m_requestedSitTargetUUID = targetID; | 2088 | m_requestedSitTargetUUID = targetID; |
2089 | 2089 | ||
2090 | m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset); | 2090 | m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset); |
2091 | 2091 | ||
2092 | if (m_scene.PhysicsScene.SupportsRayCast()) | 2092 | if (m_scene.PhysicsScene.SupportsRayCast()) |
2093 | { | 2093 | { |
2094 | //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback()); | 2094 | //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback()); |
2095 | //SitRayCastAvatarPosition(part); | 2095 | //SitRayCastAvatarPosition(part); |
2096 | //return; | 2096 | //return; |
2097 | } | 2097 | } |
2098 | } | 2098 | } |
2099 | else | 2099 | else |
2100 | { | 2100 | { |
2101 | 2101 | ||
2102 | m_log.Warn("Sit requested on unknown object: " + targetID.ToString()); | 2102 | m_log.Warn("Sit requested on unknown object: " + targetID.ToString()); |
2103 | } | 2103 | } |
2104 | 2104 | ||
2105 | 2105 | ||
2106 | 2106 | ||
2107 | SendSitResponse(remoteClient, targetID, offset, Quaternion.Identity); | 2107 | SendSitResponse(remoteClient, targetID, offset, Quaternion.Identity); |
2108 | } | 2108 | } |
2109 | /* | 2109 | /* |
2110 | public void SitRayCastAvatarPosition(SceneObjectPart part) | 2110 | public void SitRayCastAvatarPosition(SceneObjectPart part) |
2111 | { | 2111 | { |
2112 | Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; | 2112 | Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; |
2113 | Vector3 StartRayCastPosition = AbsolutePosition; | 2113 | Vector3 StartRayCastPosition = AbsolutePosition; |
2114 | Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); | 2114 | Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); |
2115 | float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); | 2115 | float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); |
2116 | m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionResponse); | 2116 | m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionResponse); |
2117 | } | 2117 | } |
2118 | 2118 | ||
2119 | public void SitRayCastAvatarPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) | 2119 | public void SitRayCastAvatarPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) |
2120 | { | 2120 | { |
2121 | SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); | 2121 | SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); |
2122 | if (part != null) | 2122 | if (part != null) |
2123 | { | 2123 | { |
2124 | if (hitYN) | 2124 | if (hitYN) |
2125 | { | 2125 | { |
2126 | if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) | 2126 | if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) |
2127 | { | 2127 | { |
2128 | SitRaycastFindEdge(collisionPoint, normal); | 2128 | SitRaycastFindEdge(collisionPoint, normal); |
2129 | m_log.DebugFormat("[SIT]: Raycast Avatar Position succeeded at point: {0}, normal:{1}", collisionPoint, normal); | 2129 | m_log.DebugFormat("[SIT]: Raycast Avatar Position succeeded at point: {0}, normal:{1}", collisionPoint, normal); |
2130 | } | 2130 | } |
2131 | else | 2131 | else |
2132 | { | 2132 | { |
2133 | SitRayCastAvatarPositionCameraZ(part); | 2133 | SitRayCastAvatarPositionCameraZ(part); |
2134 | } | 2134 | } |
2135 | } | 2135 | } |
2136 | else | 2136 | else |
2137 | { | 2137 | { |
2138 | SitRayCastAvatarPositionCameraZ(part); | 2138 | SitRayCastAvatarPositionCameraZ(part); |
2139 | } | 2139 | } |
2140 | } | 2140 | } |
2141 | else | 2141 | else |
2142 | { | 2142 | { |
2143 | ControllingClient.SendAlertMessage("Sit position no longer exists"); | 2143 | ControllingClient.SendAlertMessage("Sit position no longer exists"); |
2144 | m_requestedSitTargetUUID = UUID.Zero; | 2144 | m_requestedSitTargetUUID = UUID.Zero; |
2145 | m_requestedSitTargetID = 0; | 2145 | m_requestedSitTargetID = 0; |
2146 | m_requestedSitOffset = Vector3.Zero; | 2146 | m_requestedSitOffset = Vector3.Zero; |
2147 | } | 2147 | } |
2148 | 2148 | ||
2149 | } | 2149 | } |
2150 | 2150 | ||
2151 | public void SitRayCastAvatarPositionCameraZ(SceneObjectPart part) | 2151 | public void SitRayCastAvatarPositionCameraZ(SceneObjectPart part) |
2152 | { | 2152 | { |
2153 | // Next, try to raycast from the camera Z position | 2153 | // Next, try to raycast from the camera Z position |
2154 | Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; | 2154 | Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; |
2155 | Vector3 StartRayCastPosition = AbsolutePosition; StartRayCastPosition.Z = CameraPosition.Z; | 2155 | Vector3 StartRayCastPosition = AbsolutePosition; StartRayCastPosition.Z = CameraPosition.Z; |
2156 | Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); | 2156 | Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); |
2157 | float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); | 2157 | float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); |
2158 | m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionCameraZResponse); | 2158 | m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionCameraZResponse); |
2159 | } | 2159 | } |
2160 | 2160 | ||
2161 | public void SitRayCastAvatarPositionCameraZResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) | 2161 | public void SitRayCastAvatarPositionCameraZResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) |
2162 | { | 2162 | { |
2163 | SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); | 2163 | SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); |
2164 | if (part != null) | 2164 | if (part != null) |
2165 | { | 2165 | { |
2166 | if (hitYN) | 2166 | if (hitYN) |
2167 | { | 2167 | { |
2168 | if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) | 2168 | if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) |
2169 | { | 2169 | { |
2170 | SitRaycastFindEdge(collisionPoint, normal); | 2170 | SitRaycastFindEdge(collisionPoint, normal); |
2171 | m_log.DebugFormat("[SIT]: Raycast Avatar Position + CameraZ succeeded at point: {0}, normal:{1}", collisionPoint, normal); | 2171 | m_log.DebugFormat("[SIT]: Raycast Avatar Position + CameraZ succeeded at point: {0}, normal:{1}", collisionPoint, normal); |
2172 | } | 2172 | } |
2173 | else | 2173 | else |
2174 | { | 2174 | { |
2175 | SitRayCastCameraPosition(part); | 2175 | SitRayCastCameraPosition(part); |
2176 | } | 2176 | } |
2177 | } | 2177 | } |
2178 | else | 2178 | else |
2179 | { | 2179 | { |
2180 | SitRayCastCameraPosition(part); | 2180 | SitRayCastCameraPosition(part); |
2181 | } | 2181 | } |
2182 | } | 2182 | } |
2183 | else | 2183 | else |
2184 | { | 2184 | { |
2185 | ControllingClient.SendAlertMessage("Sit position no longer exists"); | 2185 | ControllingClient.SendAlertMessage("Sit position no longer exists"); |
2186 | m_requestedSitTargetUUID = UUID.Zero; | 2186 | m_requestedSitTargetUUID = UUID.Zero; |
2187 | m_requestedSitTargetID = 0; | 2187 | m_requestedSitTargetID = 0; |
2188 | m_requestedSitOffset = Vector3.Zero; | 2188 | m_requestedSitOffset = Vector3.Zero; |
2189 | } | 2189 | } |
2190 | 2190 | ||
2191 | } | 2191 | } |
2192 | 2192 | ||
2193 | public void SitRayCastCameraPosition(SceneObjectPart part) | 2193 | public void SitRayCastCameraPosition(SceneObjectPart part) |
2194 | { | 2194 | { |
2195 | // Next, try to raycast from the camera position | 2195 | // Next, try to raycast from the camera position |
2196 | Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; | 2196 | Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; |
2197 | Vector3 StartRayCastPosition = CameraPosition; | 2197 | Vector3 StartRayCastPosition = CameraPosition; |
2198 | Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); | 2198 | Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); |
2199 | float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); | 2199 | float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); |
2200 | m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastCameraPositionResponse); | 2200 | m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastCameraPositionResponse); |
2201 | } | 2201 | } |
2202 | 2202 | ||
2203 | public void SitRayCastCameraPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) | 2203 | public void SitRayCastCameraPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) |
2204 | { | 2204 | { |
2205 | SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); | 2205 | SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); |
2206 | if (part != null) | 2206 | if (part != null) |
2207 | { | 2207 | { |
2208 | if (hitYN) | 2208 | if (hitYN) |
2209 | { | 2209 | { |
2210 | if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) | 2210 | if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) |
2211 | { | 2211 | { |
2212 | SitRaycastFindEdge(collisionPoint, normal); | 2212 | SitRaycastFindEdge(collisionPoint, normal); |
2213 | m_log.DebugFormat("[SIT]: Raycast Camera Position succeeded at point: {0}, normal:{1}", collisionPoint, normal); | 2213 | m_log.DebugFormat("[SIT]: Raycast Camera Position succeeded at point: {0}, normal:{1}", collisionPoint, normal); |
2214 | } | 2214 | } |
2215 | else | 2215 | else |
2216 | { | 2216 | { |
2217 | SitRayHorizontal(part); | 2217 | SitRayHorizontal(part); |
2218 | } | 2218 | } |
2219 | } | 2219 | } |
2220 | else | 2220 | else |
2221 | { | 2221 | { |
2222 | SitRayHorizontal(part); | 2222 | SitRayHorizontal(part); |
2223 | } | 2223 | } |
2224 | } | 2224 | } |
2225 | else | 2225 | else |
2226 | { | 2226 | { |
2227 | ControllingClient.SendAlertMessage("Sit position no longer exists"); | 2227 | ControllingClient.SendAlertMessage("Sit position no longer exists"); |
2228 | m_requestedSitTargetUUID = UUID.Zero; | 2228 | m_requestedSitTargetUUID = UUID.Zero; |
2229 | m_requestedSitTargetID = 0; | 2229 | m_requestedSitTargetID = 0; |
2230 | m_requestedSitOffset = Vector3.Zero; | 2230 | m_requestedSitOffset = Vector3.Zero; |
2231 | } | 2231 | } |
2232 | 2232 | ||
2233 | } | 2233 | } |
2234 | 2234 | ||
2235 | public void SitRayHorizontal(SceneObjectPart part) | 2235 | public void SitRayHorizontal(SceneObjectPart part) |
2236 | { | 2236 | { |
2237 | // Next, try to raycast from the avatar position to fwd | 2237 | // Next, try to raycast from the avatar position to fwd |
2238 | Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; | 2238 | Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; |
2239 | Vector3 StartRayCastPosition = CameraPosition; | 2239 | Vector3 StartRayCastPosition = CameraPosition; |
2240 | Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); | 2240 | Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); |
2241 | float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); | 2241 | float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); |
2242 | m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastHorizontalResponse); | 2242 | m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastHorizontalResponse); |
2243 | } | 2243 | } |
2244 | 2244 | ||
2245 | public void SitRayCastHorizontalResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) | 2245 | public void SitRayCastHorizontalResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) |
2246 | { | 2246 | { |
2247 | SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); | 2247 | SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); |
2248 | if (part != null) | 2248 | if (part != null) |
2249 | { | 2249 | { |
2250 | if (hitYN) | 2250 | if (hitYN) |
2251 | { | 2251 | { |
2252 | if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) | 2252 | if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) |
2253 | { | 2253 | { |
2254 | SitRaycastFindEdge(collisionPoint, normal); | 2254 | SitRaycastFindEdge(collisionPoint, normal); |
2255 | m_log.DebugFormat("[SIT]: Raycast Horizontal Position succeeded at point: {0}, normal:{1}", collisionPoint, normal); | 2255 | m_log.DebugFormat("[SIT]: Raycast Horizontal Position succeeded at point: {0}, normal:{1}", collisionPoint, normal); |
2256 | // Next, try to raycast from the camera position | 2256 | // Next, try to raycast from the camera position |
2257 | Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; | 2257 | Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; |
2258 | Vector3 StartRayCastPosition = CameraPosition; | 2258 | Vector3 StartRayCastPosition = CameraPosition; |
2259 | Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); | 2259 | Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); |
2260 | float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); | 2260 | float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); |
2261 | //m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastResponseAvatarPosition); | 2261 | //m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastResponseAvatarPosition); |
2262 | } | 2262 | } |
2263 | else | 2263 | else |
2264 | { | 2264 | { |
2265 | ControllingClient.SendAlertMessage("Sit position not accessable."); | 2265 | ControllingClient.SendAlertMessage("Sit position not accessable."); |
2266 | m_requestedSitTargetUUID = UUID.Zero; | 2266 | m_requestedSitTargetUUID = UUID.Zero; |
2267 | m_requestedSitTargetID = 0; | 2267 | m_requestedSitTargetID = 0; |
2268 | m_requestedSitOffset = Vector3.Zero; | 2268 | m_requestedSitOffset = Vector3.Zero; |
2269 | } | 2269 | } |
2270 | } | 2270 | } |
2271 | else | 2271 | else |
2272 | { | 2272 | { |
2273 | ControllingClient.SendAlertMessage("Sit position not accessable."); | 2273 | ControllingClient.SendAlertMessage("Sit position not accessable."); |
2274 | m_requestedSitTargetUUID = UUID.Zero; | 2274 | m_requestedSitTargetUUID = UUID.Zero; |
2275 | m_requestedSitTargetID = 0; | 2275 | m_requestedSitTargetID = 0; |
2276 | m_requestedSitOffset = Vector3.Zero; | 2276 | m_requestedSitOffset = Vector3.Zero; |
2277 | } | 2277 | } |
2278 | } | 2278 | } |
2279 | else | 2279 | else |
2280 | { | 2280 | { |
2281 | ControllingClient.SendAlertMessage("Sit position no longer exists"); | 2281 | ControllingClient.SendAlertMessage("Sit position no longer exists"); |
2282 | m_requestedSitTargetUUID = UUID.Zero; | 2282 | m_requestedSitTargetUUID = UUID.Zero; |
2283 | m_requestedSitTargetID = 0; | 2283 | m_requestedSitTargetID = 0; |
2284 | m_requestedSitOffset = Vector3.Zero; | 2284 | m_requestedSitOffset = Vector3.Zero; |
2285 | } | 2285 | } |
2286 | 2286 | ||
2287 | } | 2287 | } |
2288 | 2288 | ||
2289 | private void SitRaycastFindEdge(Vector3 collisionPoint, Vector3 collisionNormal) | 2289 | private void SitRaycastFindEdge(Vector3 collisionPoint, Vector3 collisionNormal) |
2290 | { | 2290 | { |
2291 | int i = 0; | 2291 | int i = 0; |
2292 | //throw new NotImplementedException(); | 2292 | //throw new NotImplementedException(); |
2293 | //m_requestedSitTargetUUID = UUID.Zero; | 2293 | //m_requestedSitTargetUUID = UUID.Zero; |
2294 | //m_requestedSitTargetID = 0; | 2294 | //m_requestedSitTargetID = 0; |
2295 | //m_requestedSitOffset = Vector3.Zero; | 2295 | //m_requestedSitOffset = Vector3.Zero; |
2296 | 2296 | ||
2297 | SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); | 2297 | SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); |
2298 | } | 2298 | } |
2299 | */ | 2299 | */ |
2300 | public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset, string sitAnimation) | 2300 | public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset, string sitAnimation) |
2301 | { | 2301 | { |
2302 | if (m_parentID != 0) | 2302 | if (m_parentID != 0) |
2303 | { | 2303 | { |
2304 | StandUp(); | 2304 | StandUp(); |
2305 | } | 2305 | } |
2306 | if (!String.IsNullOrEmpty(sitAnimation)) | 2306 | if (!String.IsNullOrEmpty(sitAnimation)) |
2307 | { | 2307 | { |
2308 | m_nextSitAnimation = sitAnimation; | 2308 | m_nextSitAnimation = sitAnimation; |
2309 | } | 2309 | } |
2310 | else | 2310 | else |
2311 | { | 2311 | { |
2312 | m_nextSitAnimation = "SIT"; | 2312 | m_nextSitAnimation = "SIT"; |
2313 | } | 2313 | } |
2314 | 2314 | ||
2315 | //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); | 2315 | //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); |
2316 | SceneObjectPart part = FindNextAvailableSitTarget(targetID); | 2316 | SceneObjectPart part = FindNextAvailableSitTarget(targetID); |
2317 | if (part != null) | 2317 | if (part != null) |
2318 | { | 2318 | { |
2319 | m_requestedSitTargetID = part.LocalId; | 2319 | m_requestedSitTargetID = part.LocalId; |
2320 | //m_requestedSitOffset = offset; | 2320 | //m_requestedSitOffset = offset; |
2321 | m_requestedSitTargetUUID = targetID; | 2321 | m_requestedSitTargetUUID = targetID; |
2322 | 2322 | ||
2323 | m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset); | 2323 | m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset); |
2324 | 2324 | ||
2325 | if (m_scene.PhysicsScene.SupportsRayCast()) | 2325 | if (m_scene.PhysicsScene.SupportsRayCast()) |
2326 | { | 2326 | { |
2327 | //SitRayCastAvatarPosition(part); | 2327 | //SitRayCastAvatarPosition(part); |
2328 | //return; | 2328 | //return; |
2329 | } | 2329 | } |
2330 | } | 2330 | } |
2331 | else | 2331 | else |
2332 | { | 2332 | { |
2333 | m_log.Warn("Sit requested on unknown object: " + targetID); | 2333 | m_log.Warn("Sit requested on unknown object: " + targetID); |
2334 | } | 2334 | } |
2335 | 2335 | ||
2336 | SendSitResponse(remoteClient, targetID, offset, Quaternion.Identity); | 2336 | SendSitResponse(remoteClient, targetID, offset, Quaternion.Identity); |
2337 | } | 2337 | } |
2338 | 2338 | ||
2339 | public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) | 2339 | public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) |
2340 | { | 2340 | { |
2341 | if (!String.IsNullOrEmpty(m_nextSitAnimation)) | 2341 | if (!String.IsNullOrEmpty(m_nextSitAnimation)) |
2342 | { | 2342 | { |
2343 | HandleAgentSit(remoteClient, agentID, m_nextSitAnimation); | 2343 | HandleAgentSit(remoteClient, agentID, m_nextSitAnimation); |
2344 | } | 2344 | } |
2345 | else | 2345 | else |
2346 | { | 2346 | { |
2347 | HandleAgentSit(remoteClient, agentID, "SIT"); | 2347 | HandleAgentSit(remoteClient, agentID, "SIT"); |
2348 | } | 2348 | } |
2349 | } | 2349 | } |
2350 | 2350 | ||
2351 | public void HandleAgentSit(IClientAPI remoteClient, UUID agentID, string sitAnimation) | 2351 | public void HandleAgentSit(IClientAPI remoteClient, UUID agentID, string sitAnimation) |
2352 | { | 2352 | { |
2353 | SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); | 2353 | SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); |
2354 | 2354 | ||
2355 | if (m_sitAtAutoTarget || !m_autopilotMoving) | 2355 | if (m_sitAtAutoTarget || !m_autopilotMoving) |
2356 | { | 2356 | { |
2357 | if (part != null) | 2357 | if (part != null) |
2358 | { | 2358 | { |
2359 | //Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation()); | 2359 | //Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation()); |
2360 | if (part.GetAvatarOnSitTarget() == UUID) | 2360 | if (part.GetAvatarOnSitTarget() == UUID) |
2361 | { | 2361 | { |
2362 | //Console.WriteLine("Scripted Sit"); | 2362 | //Console.WriteLine("Scripted Sit"); |
2363 | // Scripted sit | 2363 | // Scripted sit |
2364 | Vector3 sitTargetPos = part.SitTargetPosition; | 2364 | Vector3 sitTargetPos = part.SitTargetPosition; |
2365 | Quaternion sitTargetOrient = part.SitTargetOrientation; | 2365 | Quaternion sitTargetOrient = part.SitTargetOrientation; |
2366 | m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); | 2366 | m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); |
2367 | m_pos += SIT_TARGET_ADJUSTMENT; | 2367 | m_pos += SIT_TARGET_ADJUSTMENT; |
2368 | if (!part.IsRoot) | 2368 | if (!part.IsRoot) |
2369 | { | 2369 | { |
2370 | m_pos *= part.RotationOffset; | 2370 | m_pos *= part.RotationOffset; |
2371 | } | 2371 | } |
2372 | m_bodyRot = sitTargetOrient; | 2372 | m_bodyRot = sitTargetOrient; |
2373 | m_parentPosition = part.AbsolutePosition; | 2373 | m_parentPosition = part.AbsolutePosition; |
2374 | part.IsOccupied = true; | 2374 | part.IsOccupied = true; |
2375 | part.ParentGroup.AddAvatar(agentID); | 2375 | part.ParentGroup.AddAvatar(agentID); |
2376 | Console.WriteLine("Scripted Sit ofset {0}", m_pos); | 2376 | Console.WriteLine("Scripted Sit ofset {0}", m_pos); |
2377 | } | 2377 | } |
2378 | else | 2378 | else |
2379 | { | 2379 | { |
2380 | // if m_avUnscriptedSitPos is zero then Av sits above center | 2380 | // if m_avUnscriptedSitPos is zero then Av sits above center |
2381 | // Else Av sits at m_avUnscriptedSitPos | 2381 | // Else Av sits at m_avUnscriptedSitPos |
2382 | 2382 | ||
2383 | // Non-scripted sit by Kitto Flora 21Nov09 | 2383 | // Non-scripted sit by Kitto Flora 21Nov09 |
2384 | // Calculate angle of line from prim to Av | 2384 | // Calculate angle of line from prim to Av |
2385 | Quaternion partIRot; | 2385 | Quaternion partIRot; |
2386 | // if (part.LinkNum == 1) | 2386 | // if (part.LinkNum == 1) |
2387 | // { // Root prim of linkset | 2387 | // { // Root prim of linkset |
2388 | // partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset); | 2388 | // partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset); |
2389 | // } | 2389 | // } |
2390 | // else | 2390 | // else |
2391 | // { // single or child prim | 2391 | // { // single or child prim |
2392 | partIRot = Quaternion.Inverse(part.GetWorldRotation()); | 2392 | partIRot = Quaternion.Inverse(part.GetWorldRotation()); |
2393 | // } | 2393 | // } |
2394 | Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos; | 2394 | Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos; |
2395 | float y_diff = (m_avInitialPos.Y - sitTargetPos.Y); | 2395 | float y_diff = (m_avInitialPos.Y - sitTargetPos.Y); |
2396 | float x_diff = ( m_avInitialPos.X - sitTargetPos.X); | 2396 | float x_diff = ( m_avInitialPos.X - sitTargetPos.X); |
2397 | if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0 | 2397 | if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0 |
2398 | if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0 | 2398 | if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0 |
2399 | float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff); | 2399 | float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff); |
2400 | // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'. | 2400 | // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'. |
2401 | // Av sits at world euler <0,0, z>, translated by part rotation | 2401 | // Av sits at world euler <0,0, z>, translated by part rotation |
2402 | m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click | 2402 | m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click |
2403 | 2403 | ||
2404 | m_parentPosition = part.AbsolutePosition; | 2404 | m_parentPosition = part.AbsolutePosition; |
2405 | part.IsOccupied = true; | 2405 | part.IsOccupied = true; |
2406 | part.ParentGroup.AddAvatar(agentID); | 2406 | part.ParentGroup.AddAvatar(agentID); |
2407 | m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation | 2407 | m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation |
2408 | (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center | 2408 | (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center |
2409 | (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) + | 2409 | (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) + |
2410 | m_avUnscriptedSitPos; // adds click offset, if any | 2410 | m_avUnscriptedSitPos; // adds click offset, if any |
2411 | //Set up raytrace to find top surface of prim | 2411 | //Set up raytrace to find top surface of prim |
2412 | Vector3 size = part.Scale; | 2412 | Vector3 size = part.Scale; |
2413 | float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z)); | 2413 | float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z)); |
2414 | Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag); | 2414 | Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag); |
2415 | Vector3 down = new Vector3(0f, 0f, -1f); | 2415 | Vector3 down = new Vector3(0f, 0f, -1f); |
2416 | //Console.WriteLine("st={0} do={1} ma={2}", start, down, mag); | 2416 | //Console.WriteLine("st={0} do={1} ma={2}", start, down, mag); |
2417 | m_scene.PhysicsScene.RaycastWorld( | 2417 | m_scene.PhysicsScene.RaycastWorld( |
2418 | start, // Vector3 position, | 2418 | start, // Vector3 position, |
2419 | down, // Vector3 direction, | 2419 | down, // Vector3 direction, |
2420 | mag, // float length, | 2420 | mag, // float length, |
2421 | SitAltitudeCallback); // retMethod | 2421 | SitAltitudeCallback); // retMethod |
2422 | } // end scripted/not | 2422 | } // end scripted/not |
2423 | } | 2423 | } |
2424 | else // no Av | 2424 | else // no Av |
2425 | { | 2425 | { |
2426 | return; | 2426 | return; |
2427 | } | 2427 | } |
2428 | } | 2428 | } |
2429 | 2429 | ||
2430 | //We want our offsets to reference the root prim, not the child we may have sat on | 2430 | //We want our offsets to reference the root prim, not the child we may have sat on |
2431 | if (!part.IsRoot) | 2431 | if (!part.IsRoot) |
2432 | { | 2432 | { |
2433 | m_parentID = part.ParentGroup.RootPart.LocalId; | 2433 | m_parentID = part.ParentGroup.RootPart.LocalId; |
2434 | m_pos += part.OffsetPosition; | 2434 | m_pos += part.OffsetPosition; |
2435 | } | 2435 | } |
2436 | else | 2436 | else |
2437 | { | 2437 | { |
2438 | m_parentID = m_requestedSitTargetID; | 2438 | m_parentID = m_requestedSitTargetID; |
2439 | } | 2439 | } |
2440 | 2440 | ||
2441 | m_linkedPrim = part.UUID; | 2441 | m_linkedPrim = part.UUID; |
2442 | 2442 | ||
2443 | Velocity = Vector3.Zero; | 2443 | Velocity = Vector3.Zero; |
2444 | RemoveFromPhysicalScene(); | 2444 | RemoveFromPhysicalScene(); |
2445 | 2445 | Animator.TrySetMovementAnimation(sitAnimation); | |
2446 | Animator.TrySetMovementAnimation(sitAnimation); | 2446 | SendFullUpdateToAllClients(); |
2447 | SendFullUpdateToAllClients(); | 2447 | SendTerseUpdateToAllClients(); |
2448 | } | 2448 | } |
2449 | 2449 | ||
2450 | public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal) | 2450 | public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal) |
2451 | { | 2451 | { |
2452 | // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer | 2452 | // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer |
2453 | // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height. | 2453 | // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height. |
2454 | if(hitYN) | 2454 | if(hitYN) |
2455 | { | 2455 | { |
2456 | // m_pos = Av offset from prim center to make look like on center | 2456 | // m_pos = Av offset from prim center to make look like on center |
2457 | // m_parentPosition = Actual center pos of prim | 2457 | // m_parentPosition = Actual center pos of prim |
2458 | // collisionPoint = spot on prim where we want to sit | 2458 | // collisionPoint = spot on prim where we want to sit |
2459 | // collisionPoint.Z = global sit surface height | 2459 | // collisionPoint.Z = global sit surface height |
2460 | SceneObjectPart part = m_scene.GetSceneObjectPart(localid); | 2460 | SceneObjectPart part = m_scene.GetSceneObjectPart(localid); |
2461 | Quaternion partIRot; | 2461 | Quaternion partIRot; |
2462 | // if (part.LinkNum == 1) | 2462 | // if (part.LinkNum == 1) |
2463 | /// { // Root prim of linkset | 2463 | /// { // Root prim of linkset |
2464 | // partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset); | 2464 | // partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset); |
2465 | // } | 2465 | // } |
2466 | // else | 2466 | // else |
2467 | // { // single or child prim | 2467 | // { // single or child prim |
2468 | partIRot = Quaternion.Inverse(part.GetWorldRotation()); | 2468 | partIRot = Quaternion.Inverse(part.GetWorldRotation()); |
2469 | // } | 2469 | // } |
2470 | if (m_initialSitTarget != null) | 2470 | if (m_initialSitTarget != null) |
2471 | { | 2471 | { |
2472 | float offZ = collisionPoint.Z - m_initialSitTarget.Z; | 2472 | float offZ = collisionPoint.Z - m_initialSitTarget.Z; |
2473 | Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction | 2473 | Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction |
2474 | //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset); | 2474 | //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset); |
2475 | m_pos += offset; | 2475 | m_pos += offset; |
2476 | // ControllingClient.SendClearFollowCamProperties(part.UUID); | 2476 | // ControllingClient.SendClearFollowCamProperties(part.UUID); |
2477 | } | 2477 | } |
2478 | 2478 | ||
2479 | } | 2479 | } |
2480 | } // End SitAltitudeCallback KF. | 2480 | } // End SitAltitudeCallback KF. |
2481 | 2481 | ||
2482 | /// <summary> | 2482 | /// <summary> |
2483 | /// Event handler for the 'Always run' setting on the client | 2483 | /// Event handler for the 'Always run' setting on the client |
2484 | /// Tells the physics plugin to increase speed of movement. | 2484 | /// Tells the physics plugin to increase speed of movement. |
2485 | /// </summary> | 2485 | /// </summary> |
2486 | public void HandleSetAlwaysRun(IClientAPI remoteClient, bool pSetAlwaysRun) | 2486 | public void HandleSetAlwaysRun(IClientAPI remoteClient, bool pSetAlwaysRun) |
2487 | { | 2487 | { |
2488 | m_setAlwaysRun = pSetAlwaysRun; | 2488 | m_setAlwaysRun = pSetAlwaysRun; |
2489 | if (PhysicsActor != null) | 2489 | if (PhysicsActor != null) |
2490 | { | 2490 | { |
2491 | PhysicsActor.SetAlwaysRun = pSetAlwaysRun; | 2491 | PhysicsActor.SetAlwaysRun = pSetAlwaysRun; |
2492 | } | 2492 | } |
2493 | } | 2493 | } |
2494 | 2494 | ||
2495 | public void HandleStartAnim(IClientAPI remoteClient, UUID animID) | 2495 | public void HandleStartAnim(IClientAPI remoteClient, UUID animID) |
2496 | { | 2496 | { |
2497 | Animator.AddAnimation(animID, UUID.Zero); | 2497 | Animator.AddAnimation(animID, UUID.Zero); |
2498 | } | 2498 | } |
2499 | 2499 | ||
2500 | public void HandleStopAnim(IClientAPI remoteClient, UUID animID) | 2500 | public void HandleStopAnim(IClientAPI remoteClient, UUID animID) |
2501 | { | 2501 | { |
2502 | Animator.RemoveAnimation(animID); | 2502 | Animator.RemoveAnimation(animID); |
2503 | } | 2503 | } |
2504 | 2504 | ||
2505 | /// <summary> | 2505 | /// <summary> |
2506 | /// Rotate the avatar to the given rotation and apply a movement in the given relative vector | 2506 | /// Rotate the avatar to the given rotation and apply a movement in the given relative vector |
2507 | /// </summary> | 2507 | /// </summary> |
2508 | /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> | 2508 | /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> |
2509 | /// <param name="rotation">The direction in which this avatar should now face. | 2509 | /// <param name="rotation">The direction in which this avatar should now face. |
2510 | public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging) | 2510 | public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging) |
2511 | { | 2511 | { |
2512 | if (m_isChildAgent) | 2512 | if (m_isChildAgent) |
2513 | { | 2513 | { |
2514 | // WHAT??? | 2514 | // WHAT??? |
2515 | m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent, making root agent!"); | 2515 | m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent, making root agent!"); |
2516 | 2516 | ||
2517 | // we have to reset the user's child agent connections. | 2517 | // we have to reset the user's child agent connections. |
2518 | // Likely, here they've lost the eventqueue for other regions so border | 2518 | // Likely, here they've lost the eventqueue for other regions so border |
2519 | // crossings will fail at this point unless we reset them. | 2519 | // crossings will fail at this point unless we reset them. |
2520 | 2520 | ||
2521 | List<ulong> regions = new List<ulong>(KnownChildRegionHandles); | 2521 | List<ulong> regions = new List<ulong>(KnownChildRegionHandles); |
2522 | regions.Remove(m_scene.RegionInfo.RegionHandle); | 2522 | regions.Remove(m_scene.RegionInfo.RegionHandle); |
2523 | 2523 | ||
2524 | MakeRootAgent(new Vector3(127f, 127f, 127f), true); | 2524 | MakeRootAgent(new Vector3(127f, 127f, 127f), true); |
2525 | 2525 | ||
2526 | // Async command | 2526 | // Async command |
2527 | if (m_scene.SceneGridService != null) | 2527 | if (m_scene.SceneGridService != null) |
2528 | { | 2528 | { |
2529 | m_scene.SceneGridService.SendCloseChildAgentConnections(UUID, regions); | 2529 | m_scene.SceneGridService.SendCloseChildAgentConnections(UUID, regions); |
2530 | 2530 | ||
2531 | // Give the above command some time to try and close the connections. | 2531 | // Give the above command some time to try and close the connections. |
2532 | // this is really an emergency.. so sleep, or we'll get all discombobulated. | 2532 | // this is really an emergency.. so sleep, or we'll get all discombobulated. |
2533 | System.Threading.Thread.Sleep(500); | 2533 | System.Threading.Thread.Sleep(500); |
2534 | } | 2534 | } |
2535 | 2535 | ||
2536 | if (m_scene.SceneGridService != null) | 2536 | if (m_scene.SceneGridService != null) |
2537 | { | 2537 | { |
2538 | IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); | 2538 | IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); |
2539 | if (m_agentTransfer != null) | 2539 | if (m_agentTransfer != null) |
2540 | m_agentTransfer.EnableChildAgents(this); | 2540 | m_agentTransfer.EnableChildAgents(this); |
2541 | } | 2541 | } |
2542 | 2542 | ||
2543 | return; | 2543 | return; |
2544 | } | 2544 | } |
2545 | 2545 | ||
2546 | m_perfMonMS = Util.EnvironmentTickCount(); | 2546 | m_perfMonMS = Util.EnvironmentTickCount(); |
2547 | 2547 | ||
2548 | Rotation = rotation; | 2548 | Rotation = rotation; |
2549 | Vector3 direc = vec * rotation; | 2549 | Vector3 direc = vec * rotation; |
2550 | direc.Normalize(); | 2550 | direc.Normalize(); |
2551 | PhysicsActor actor = m_physicsActor; | 2551 | PhysicsActor actor = m_physicsActor; |
2552 | if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up. | 2552 | if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up. |
2553 | 2553 | ||
2554 | direc *= 0.03f * 128f * m_speedModifier; | 2554 | direc *= 0.03f * 128f * m_speedModifier; |
2555 | 2555 | ||
2556 | if (actor != null) | 2556 | if (actor != null) |
2557 | { | 2557 | { |
2558 | if (actor.Flying) | 2558 | if (actor.Flying) |
2559 | { | 2559 | { |
2560 | direc *= 4.0f; | 2560 | direc *= 4.0f; |
2561 | //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); | 2561 | //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); |
2562 | //bool colliding = (m_physicsActor.IsColliding==true); | 2562 | //bool colliding = (m_physicsActor.IsColliding==true); |
2563 | //if (controlland) | 2563 | //if (controlland) |
2564 | // m_log.Info("[AGENT]: landCommand"); | 2564 | // m_log.Info("[AGENT]: landCommand"); |
2565 | //if (colliding) | 2565 | //if (colliding) |
2566 | // m_log.Info("[AGENT]: colliding"); | 2566 | // m_log.Info("[AGENT]: colliding"); |
2567 | //if (m_physicsActor.Flying && colliding && controlland) | 2567 | //if (m_physicsActor.Flying && colliding && controlland) |
2568 | //{ | 2568 | //{ |
2569 | // StopFlying(); | 2569 | // StopFlying(); |
2570 | // m_log.Info("[AGENT]: Stop FLying"); | 2570 | // m_log.Info("[AGENT]: Stop FLying"); |
2571 | //} | 2571 | //} |
2572 | } | 2572 | } |
2573 | else if (!actor.Flying && actor.IsColliding) | 2573 | else if (!actor.Flying && actor.IsColliding) |
2574 | { | 2574 | { |
2575 | if (direc.Z > 2.0f) | 2575 | if (direc.Z > 2.0f) |
2576 | { | 2576 | { |
2577 | if(m_animator.m_animTickJump == -1) | 2577 | if(m_animator.m_animTickJump == -1) |
2578 | { | 2578 | { |
2579 | direc.Z *= 3.0f; // jump | 2579 | direc.Z *= 3.0f; // jump |
2580 | } | 2580 | } |
2581 | else | 2581 | else |
2582 | { | 2582 | { |
2583 | direc.Z *= 0.1f; // prejump | 2583 | direc.Z *= 0.1f; // prejump |
2584 | } | 2584 | } |
2585 | /* Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs | 2585 | /* Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs |
2586 | Animator.TrySetMovementAnimation("PREJUMP"); | 2586 | Animator.TrySetMovementAnimation("PREJUMP"); |
2587 | Animator.TrySetMovementAnimation("JUMP"); | 2587 | Animator.TrySetMovementAnimation("JUMP"); |
2588 | */ | 2588 | */ |
2589 | } | 2589 | } |
2590 | } | 2590 | } |
2591 | } | 2591 | } |
2592 | 2592 | ||
2593 | // TODO: Add the force instead of only setting it to support multiple forces per frame? | 2593 | // TODO: Add the force instead of only setting it to support multiple forces per frame? |
2594 | m_forceToApply = direc; | 2594 | m_forceToApply = direc; |
2595 | m_isNudging = Nudging; | 2595 | m_isNudging = Nudging; |
2596 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); | 2596 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); |
2597 | } | 2597 | } |
2598 | 2598 | ||
2599 | #endregion | 2599 | #endregion |
2600 | 2600 | ||
2601 | #region Overridden Methods | 2601 | #region Overridden Methods |
2602 | 2602 | ||
2603 | public override void Update() | 2603 | public override void Update() |
2604 | { | 2604 | { |
2605 | const float ROTATION_TOLERANCE = 0.01f; | 2605 | const float ROTATION_TOLERANCE = 0.01f; |
2606 | const float VELOCITY_TOLERANCE = 0.001f; | 2606 | const float VELOCITY_TOLERANCE = 0.001f; |
2607 | const float POSITION_TOLERANCE = 0.05f; | 2607 | const float POSITION_TOLERANCE = 0.05f; |
2608 | //const int TIME_MS_TOLERANCE = 3000; | 2608 | //const int TIME_MS_TOLERANCE = 3000; |
2609 | 2609 | ||
2610 | 2610 | ||
2611 | 2611 | ||
2612 | if (m_isChildAgent == false) | 2612 | if (m_isChildAgent == false) |
2613 | { | 2613 | { |
2614 | // PhysicsActor actor = m_physicsActor; | 2614 | // PhysicsActor actor = m_physicsActor; |
2615 | 2615 | ||
2616 | // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to | 2616 | // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to |
2617 | // grab the latest PhysicsActor velocity, whereas m_velocity is often | 2617 | // grab the latest PhysicsActor velocity, whereas m_velocity is often |
2618 | // storing a requested force instead of an actual traveling velocity | 2618 | // storing a requested force instead of an actual traveling velocity |
2619 | 2619 | ||
2620 | // Throw away duplicate or insignificant updates | 2620 | // Throw away duplicate or insignificant updates |
2621 | if (!m_bodyRot.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || | 2621 | if (!m_bodyRot.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || |
2622 | !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || | 2622 | !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || |
2623 | !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)) | 2623 | !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)) |
2624 | //Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) | 2624 | //Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) |
2625 | { | 2625 | { |
2626 | SendTerseUpdateToAllClients(); | 2626 | SendTerseUpdateToAllClients(); |
2627 | 2627 | ||
2628 | // Update the "last" values | 2628 | // Update the "last" values |
2629 | m_lastPosition = m_pos; | 2629 | m_lastPosition = m_pos; |
2630 | m_lastRotation = m_bodyRot; | 2630 | m_lastRotation = m_bodyRot; |
2631 | m_lastVelocity = Velocity; | 2631 | m_lastVelocity = Velocity; |
2632 | //m_lastTerseSent = Environment.TickCount; | 2632 | //m_lastTerseSent = Environment.TickCount; |
2633 | } | 2633 | } |
2634 | 2634 | ||
2635 | // followed suggestion from mic bowman. reversed the two lines below. | 2635 | // followed suggestion from mic bowman. reversed the two lines below. |
2636 | if (m_parentID == 0 && m_physicsActor != null || m_parentID != 0) // Check that we have a physics actor or we're sitting on something | 2636 | if (m_parentID == 0 && m_physicsActor != null || m_parentID != 0) // Check that we have a physics actor or we're sitting on something |
2637 | CheckForBorderCrossing(); | 2637 | CheckForBorderCrossing(); |
2638 | CheckForSignificantMovement(); // sends update to the modules. | 2638 | CheckForSignificantMovement(); // sends update to the modules. |
2639 | } | 2639 | } |
2640 | 2640 | ||
2641 | //Sending prim updates AFTER the avatar terse updates are sent | 2641 | //Sending prim updates AFTER the avatar terse updates are sent |
2642 | SendPrimUpdates(); | 2642 | SendPrimUpdates(); |
2643 | } | 2643 | } |
2644 | 2644 | ||
2645 | #endregion | 2645 | #endregion |
2646 | 2646 | ||
2647 | #region Update Client(s) | 2647 | #region Update Client(s) |
2648 | 2648 | ||
2649 | /// <summary> | 2649 | /// <summary> |
2650 | /// Sends a location update to the client connected to this scenePresence | 2650 | /// Sends a location update to the client connected to this scenePresence |
2651 | /// </summary> | 2651 | /// </summary> |
2652 | /// <param name="remoteClient"></param> | 2652 | /// <param name="remoteClient"></param> |
2653 | public void SendTerseUpdateToClient(IClientAPI remoteClient) | 2653 | public void SendTerseUpdateToClient(IClientAPI remoteClient) |
2654 | { | 2654 | { |
2655 | // If the client is inactive, it's getting its updates from another | 2655 | // If the client is inactive, it's getting its updates from another |
2656 | // server. | 2656 | // server. |
2657 | if (remoteClient.IsActive) | 2657 | if (remoteClient.IsActive) |
2658 | { | 2658 | { |
2659 | m_perfMonMS = Util.EnvironmentTickCount(); | 2659 | m_perfMonMS = Util.EnvironmentTickCount(); |
2660 | 2660 | ||
2661 | PhysicsActor actor = m_physicsActor; | 2661 | PhysicsActor actor = m_physicsActor; |
2662 | Vector3 velocity = (actor != null) ? actor.Velocity : Vector3.Zero; | 2662 | Vector3 velocity = (actor != null) ? actor.Velocity : Vector3.Zero; |
2663 | 2663 | ||
2664 | Vector3 pos = m_pos; | 2664 | Vector3 pos = m_pos; |
2665 | pos.Z += m_appearance.HipOffset; | 2665 | pos.Z += m_appearance.HipOffset; |
2666 | 2666 | ||
2667 | //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); | 2667 | //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); |
2668 | 2668 | ||
2669 | remoteClient.SendPrimUpdate(this, PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); | 2669 | remoteClient.SendPrimUpdate(this, PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); |
2670 | 2670 | ||
2671 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); | 2671 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); |
2672 | m_scene.StatsReporter.AddAgentUpdates(1); | 2672 | m_scene.StatsReporter.AddAgentUpdates(1); |
2673 | } | 2673 | } |
2674 | } | 2674 | } |
2675 | 2675 | ||
2676 | /// <summary> | 2676 | /// <summary> |
2677 | /// Send a location/velocity/accelleration update to all agents in scene | 2677 | /// Send a location/velocity/accelleration update to all agents in scene |
2678 | /// </summary> | 2678 | /// </summary> |
2679 | public void SendTerseUpdateToAllClients() | 2679 | public void SendTerseUpdateToAllClients() |
2680 | { | 2680 | { |
2681 | m_perfMonMS = Util.EnvironmentTickCount(); | 2681 | m_perfMonMS = Util.EnvironmentTickCount(); |
2682 | 2682 | ||
2683 | m_scene.ForEachClient(SendTerseUpdateToClient); | 2683 | m_scene.ForEachClient(SendTerseUpdateToClient); |
2684 | 2684 | ||
2685 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); | 2685 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); |
2686 | } | 2686 | } |
2687 | 2687 | ||
2688 | public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs) | 2688 | public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs) |
2689 | { | 2689 | { |
2690 | SendCourseLocationsMethod d = m_sendCourseLocationsMethod; | 2690 | SendCourseLocationsMethod d = m_sendCourseLocationsMethod; |
2691 | if (d != null) | 2691 | if (d != null) |
2692 | { | 2692 | { |
2693 | d.Invoke(m_scene.RegionInfo.originRegionID, this, coarseLocations, avatarUUIDs); | 2693 | d.Invoke(m_scene.RegionInfo.originRegionID, this, coarseLocations, avatarUUIDs); |
2694 | } | 2694 | } |
2695 | } | 2695 | } |
2696 | 2696 | ||
2697 | public void SetSendCourseLocationMethod(SendCourseLocationsMethod d) | 2697 | public void SetSendCourseLocationMethod(SendCourseLocationsMethod d) |
2698 | { | 2698 | { |
2699 | if (d != null) | 2699 | if (d != null) |
2700 | m_sendCourseLocationsMethod = d; | 2700 | m_sendCourseLocationsMethod = d; |
2701 | } | 2701 | } |
2702 | 2702 | ||
2703 | public void SendCoarseLocationsDefault(UUID sceneId, ScenePresence p, List<Vector3> coarseLocations, List<UUID> avatarUUIDs) | 2703 | public void SendCoarseLocationsDefault(UUID sceneId, ScenePresence p, List<Vector3> coarseLocations, List<UUID> avatarUUIDs) |
2704 | { | 2704 | { |
2705 | m_perfMonMS = Util.EnvironmentTickCount(); | 2705 | m_perfMonMS = Util.EnvironmentTickCount(); |
2706 | m_controllingClient.SendCoarseLocationUpdate(avatarUUIDs, coarseLocations); | 2706 | m_controllingClient.SendCoarseLocationUpdate(avatarUUIDs, coarseLocations); |
2707 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); | 2707 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); |
2708 | } | 2708 | } |
2709 | 2709 | ||
2710 | /// <summary> | 2710 | /// <summary> |
2711 | /// Tell other client about this avatar (The client previously didn't know or had outdated details about this avatar) | 2711 | /// Tell other client about this avatar (The client previously didn't know or had outdated details about this avatar) |
2712 | /// </summary> | 2712 | /// </summary> |
2713 | /// <param name="remoteAvatar"></param> | 2713 | /// <param name="remoteAvatar"></param> |
2714 | public void SendFullUpdateToOtherClient(ScenePresence remoteAvatar) | 2714 | public void SendFullUpdateToOtherClient(ScenePresence remoteAvatar) |
2715 | { | 2715 | { |
2716 | // 2 stage check is needed. | 2716 | // 2 stage check is needed. |
2717 | if (remoteAvatar == null) | 2717 | if (remoteAvatar == null) |
2718 | return; | 2718 | return; |
2719 | IClientAPI cl=remoteAvatar.ControllingClient; | 2719 | IClientAPI cl=remoteAvatar.ControllingClient; |
2720 | if (cl == null) | 2720 | if (cl == null) |
2721 | return; | 2721 | return; |
2722 | if (m_appearance.Texture == null) | 2722 | if (m_appearance.Texture == null) |
2723 | return; | 2723 | return; |
2724 | 2724 | ||
2725 | Vector3 pos = m_pos; | 2725 | Vector3 pos = m_pos; |
2726 | pos.Z += m_appearance.HipOffset; | 2726 | pos.Z += m_appearance.HipOffset; |
2727 | 2727 | ||
2728 | remoteAvatar.m_controllingClient.SendAvatarDataImmediate(this); | 2728 | remoteAvatar.m_controllingClient.SendAvatarDataImmediate(this); |
2729 | m_scene.StatsReporter.AddAgentUpdates(1); | 2729 | m_scene.StatsReporter.AddAgentUpdates(1); |
2730 | } | 2730 | } |
2731 | 2731 | ||
2732 | /// <summary> | 2732 | /// <summary> |
2733 | /// Tell *ALL* agents about this agent | 2733 | /// Tell *ALL* agents about this agent |
2734 | /// </summary> | 2734 | /// </summary> |
2735 | public void SendInitialFullUpdateToAllClients() | 2735 | public void SendInitialFullUpdateToAllClients() |
2736 | { | 2736 | { |
2737 | m_perfMonMS = Util.EnvironmentTickCount(); | 2737 | m_perfMonMS = Util.EnvironmentTickCount(); |
2738 | int avUpdates = 0; | 2738 | int avUpdates = 0; |
2739 | m_scene.ForEachScenePresence(delegate(ScenePresence avatar) | 2739 | m_scene.ForEachScenePresence(delegate(ScenePresence avatar) |
2740 | { | 2740 | { |
2741 | ++avUpdates; | 2741 | ++avUpdates; |
2742 | // only send if this is the root (children are only "listening posts" in a foreign region) | 2742 | // only send if this is the root (children are only "listening posts" in a foreign region) |
2743 | if (!IsChildAgent) | 2743 | if (!IsChildAgent) |
2744 | { | 2744 | { |
2745 | SendFullUpdateToOtherClient(avatar); | 2745 | SendFullUpdateToOtherClient(avatar); |
2746 | } | 2746 | } |
2747 | 2747 | ||
2748 | if (avatar.LocalId != LocalId) | 2748 | if (avatar.LocalId != LocalId) |
2749 | { | 2749 | { |
2750 | if (!avatar.IsChildAgent) | 2750 | if (!avatar.IsChildAgent) |
2751 | { | 2751 | { |
2752 | avatar.SendFullUpdateToOtherClient(this); | 2752 | avatar.SendFullUpdateToOtherClient(this); |
2753 | avatar.SendAppearanceToOtherAgent(this); | 2753 | avatar.SendAppearanceToOtherAgent(this); |
2754 | avatar.Animator.SendAnimPackToClient(ControllingClient); | 2754 | avatar.Animator.SendAnimPackToClient(ControllingClient); |
2755 | } | 2755 | } |
2756 | } | 2756 | } |
2757 | }); | 2757 | }); |
2758 | 2758 | ||
2759 | m_scene.StatsReporter.AddAgentUpdates(avUpdates); | 2759 | m_scene.StatsReporter.AddAgentUpdates(avUpdates); |
2760 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); | 2760 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); |
2761 | 2761 | ||
2762 | //Animator.SendAnimPack(); | 2762 | //Animator.SendAnimPack(); |
2763 | } | 2763 | } |
2764 | 2764 | ||
2765 | public void SendFullUpdateToAllClients() | 2765 | public void SendFullUpdateToAllClients() |
2766 | { | 2766 | { |
2767 | m_perfMonMS = Util.EnvironmentTickCount(); | 2767 | m_perfMonMS = Util.EnvironmentTickCount(); |
2768 | 2768 | ||
2769 | // only send update from root agents to other clients; children are only "listening posts" | 2769 | // only send update from root agents to other clients; children are only "listening posts" |
2770 | int count = 0; | 2770 | int count = 0; |
2771 | m_scene.ForEachScenePresence(delegate(ScenePresence sp) | 2771 | m_scene.ForEachScenePresence(delegate(ScenePresence sp) |
2772 | { | 2772 | { |
2773 | if (sp.IsChildAgent) | 2773 | if (sp.IsChildAgent) |
2774 | return; | 2774 | return; |
2775 | SendFullUpdateToOtherClient(sp); | 2775 | SendFullUpdateToOtherClient(sp); |
2776 | ++count; | 2776 | ++count; |
2777 | }); | 2777 | }); |
2778 | m_scene.StatsReporter.AddAgentUpdates(count); | 2778 | m_scene.StatsReporter.AddAgentUpdates(count); |
2779 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); | 2779 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); |
2780 | 2780 | ||
2781 | Animator.SendAnimPack(); | 2781 | Animator.SendAnimPack(); |
2782 | } | 2782 | } |
2783 | 2783 | ||
2784 | /// <summary> | 2784 | /// <summary> |
2785 | /// Do everything required once a client completes its movement into a region | 2785 | /// Do everything required once a client completes its movement into a region |
2786 | /// </summary> | 2786 | /// </summary> |
2787 | public void SendInitialData() | 2787 | public void SendInitialData() |
2788 | { | 2788 | { |
2789 | // Moved this into CompleteMovement to ensure that m_appearance is initialized before | 2789 | // Moved this into CompleteMovement to ensure that m_appearance is initialized before |
2790 | // the inventory arrives | 2790 | // the inventory arrives |
2791 | // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); | 2791 | // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); |
2792 | 2792 | ||
2793 | Vector3 pos = m_pos; | 2793 | Vector3 pos = m_pos; |
2794 | pos.Z += m_appearance.HipOffset; | 2794 | pos.Z += m_appearance.HipOffset; |
2795 | 2795 | ||
2796 | m_controllingClient.SendAvatarDataImmediate(this); | 2796 | m_controllingClient.SendAvatarDataImmediate(this); |
2797 | 2797 | ||
2798 | SendInitialFullUpdateToAllClients(); | 2798 | SendInitialFullUpdateToAllClients(); |
2799 | SendAppearanceToAllOtherAgents(); | 2799 | SendAppearanceToAllOtherAgents(); |
2800 | } | 2800 | } |
2801 | 2801 | ||
2802 | /// <summary> | 2802 | /// <summary> |
2803 | /// Tell the client for this scene presence what items it should be wearing now | 2803 | /// Tell the client for this scene presence what items it should be wearing now |
2804 | /// </summary> | 2804 | /// </summary> |
2805 | public void SendWearables() | 2805 | public void SendWearables() |
2806 | { | 2806 | { |
2807 | m_log.DebugFormat("[SCENE]: Received request for wearables of {0}", Name); | 2807 | m_log.DebugFormat("[SCENE]: Received request for wearables of {0}", Name); |
2808 | 2808 | ||
2809 | ControllingClient.SendWearables(m_appearance.Wearables, m_appearance.Serial++); | 2809 | ControllingClient.SendWearables(m_appearance.Wearables, m_appearance.Serial++); |
2810 | } | 2810 | } |
2811 | 2811 | ||
2812 | /// <summary> | 2812 | /// <summary> |
2813 | /// | 2813 | /// |
2814 | /// </summary> | 2814 | /// </summary> |
2815 | public void SendAppearanceToAllOtherAgents() | 2815 | public void SendAppearanceToAllOtherAgents() |
2816 | { | 2816 | { |
2817 | m_perfMonMS = Util.EnvironmentTickCount(); | 2817 | m_perfMonMS = Util.EnvironmentTickCount(); |
2818 | 2818 | ||
2819 | m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) | 2819 | m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) |
2820 | { | 2820 | { |
2821 | if (scenePresence.UUID != UUID) | 2821 | if (scenePresence.UUID != UUID) |
2822 | { | 2822 | { |
2823 | SendAppearanceToOtherAgent(scenePresence); | 2823 | SendAppearanceToOtherAgent(scenePresence); |
2824 | } | 2824 | } |
2825 | }); | 2825 | }); |
2826 | 2826 | ||
2827 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); | 2827 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); |
2828 | } | 2828 | } |
2829 | 2829 | ||
2830 | /// <summary> | 2830 | /// <summary> |
2831 | /// Send appearance data to an agent that isn't this one. | 2831 | /// Send appearance data to an agent that isn't this one. |
2832 | /// </summary> | 2832 | /// </summary> |
2833 | /// <param name="avatar"></param> | 2833 | /// <param name="avatar"></param> |
2834 | public void SendAppearanceToOtherAgent(ScenePresence avatar) | 2834 | public void SendAppearanceToOtherAgent(ScenePresence avatar) |
2835 | { | 2835 | { |
2836 | avatar.ControllingClient.SendAppearance( | 2836 | avatar.ControllingClient.SendAppearance( |
2837 | m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); | 2837 | m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); |
2838 | } | 2838 | } |
2839 | 2839 | ||
2840 | /// <summary> | 2840 | /// <summary> |
2841 | /// Set appearance data (textureentry and slider settings) received from the client | 2841 | /// Set appearance data (textureentry and slider settings) received from the client |
2842 | /// </summary> | 2842 | /// </summary> |
2843 | /// <param name="texture"></param> | 2843 | /// <param name="texture"></param> |
2844 | /// <param name="visualParam"></param> | 2844 | /// <param name="visualParam"></param> |
2845 | public void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams) | 2845 | public void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams) |
2846 | { | 2846 | { |
2847 | if (m_physicsActor != null) | 2847 | if (m_physicsActor != null) |
2848 | { | 2848 | { |
2849 | if (!IsChildAgent) | 2849 | if (!IsChildAgent) |
2850 | { | 2850 | { |
2851 | // This may seem like it's redundant, remove the avatar from the physics scene | 2851 | // This may seem like it's redundant, remove the avatar from the physics scene |
2852 | // just to add it back again, but it saves us from having to update | 2852 | // just to add it back again, but it saves us from having to update |
2853 | // 3 variables 10 times a second. | 2853 | // 3 variables 10 times a second. |
2854 | bool flyingTemp = m_physicsActor.Flying; | 2854 | bool flyingTemp = m_physicsActor.Flying; |
2855 | RemoveFromPhysicalScene(); | 2855 | RemoveFromPhysicalScene(); |
2856 | //m_scene.PhysicsScene.RemoveAvatar(m_physicsActor); | 2856 | //m_scene.PhysicsScene.RemoveAvatar(m_physicsActor); |
2857 | 2857 | ||
2858 | //PhysicsActor = null; | 2858 | //PhysicsActor = null; |
2859 | 2859 | ||
2860 | AddToPhysicalScene(flyingTemp); | 2860 | AddToPhysicalScene(flyingTemp); |
2861 | } | 2861 | } |
2862 | } | 2862 | } |
2863 | 2863 | ||
2864 | #region Bake Cache Check | 2864 | #region Bake Cache Check |
2865 | 2865 | ||
2866 | if (textureEntry != null) | 2866 | if (textureEntry != null) |
2867 | { | 2867 | { |
2868 | for (int i = 0; i < BAKE_INDICES.Length; i++) | 2868 | for (int i = 0; i < BAKE_INDICES.Length; i++) |
2869 | { | 2869 | { |
2870 | int j = BAKE_INDICES[i]; | 2870 | int j = BAKE_INDICES[i]; |
2871 | Primitive.TextureEntryFace face = textureEntry.FaceTextures[j]; | 2871 | Primitive.TextureEntryFace face = textureEntry.FaceTextures[j]; |
2872 | 2872 | ||
2873 | if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) | 2873 | if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) |
2874 | { | 2874 | { |
2875 | if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) | 2875 | if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) |
2876 | { | 2876 | { |
2877 | m_log.Warn("[APPEARANCE]: Missing baked texture " + face.TextureID + " (" + j + ") for avatar " + this.Name); | 2877 | m_log.Warn("[APPEARANCE]: Missing baked texture " + face.TextureID + " (" + j + ") for avatar " + this.Name); |
2878 | this.ControllingClient.SendRebakeAvatarTextures(face.TextureID); | 2878 | this.ControllingClient.SendRebakeAvatarTextures(face.TextureID); |
2879 | } | 2879 | } |
2880 | } | 2880 | } |
2881 | } | 2881 | } |
2882 | 2882 | ||
2883 | } | 2883 | } |
2884 | 2884 | ||
2885 | 2885 | ||
2886 | #endregion Bake Cache Check | 2886 | #endregion Bake Cache Check |
2887 | 2887 | ||
2888 | m_appearance.SetAppearance(textureEntry, visualParams); | 2888 | m_appearance.SetAppearance(textureEntry, visualParams); |
2889 | if (m_appearance.AvatarHeight > 0) | 2889 | if (m_appearance.AvatarHeight > 0) |
2890 | SetHeight(m_appearance.AvatarHeight); | 2890 | SetHeight(m_appearance.AvatarHeight); |
2891 | 2891 | ||
2892 | // This is not needed, because only the transient data changed | 2892 | // This is not needed, because only the transient data changed |
2893 | //AvatarData adata = new AvatarData(m_appearance); | 2893 | //AvatarData adata = new AvatarData(m_appearance); |
2894 | //m_scene.AvatarService.SetAvatar(m_controllingClient.AgentId, adata); | 2894 | //m_scene.AvatarService.SetAvatar(m_controllingClient.AgentId, adata); |
2895 | 2895 | ||
2896 | SendAppearanceToAllOtherAgents(); | 2896 | SendAppearanceToAllOtherAgents(); |
2897 | if (!m_startAnimationSet) | 2897 | if (!m_startAnimationSet) |
2898 | { | 2898 | { |
2899 | Animator.UpdateMovementAnimations(); | 2899 | Animator.UpdateMovementAnimations(); |
2900 | m_startAnimationSet = true; | 2900 | m_startAnimationSet = true; |
2901 | } | 2901 | } |
2902 | 2902 | ||
2903 | Vector3 pos = m_pos; | 2903 | Vector3 pos = m_pos; |
2904 | pos.Z += m_appearance.HipOffset; | 2904 | pos.Z += m_appearance.HipOffset; |
2905 | 2905 | ||
2906 | m_controllingClient.SendAvatarDataImmediate(this); | 2906 | m_controllingClient.SendAvatarDataImmediate(this); |
2907 | } | 2907 | } |
2908 | 2908 | ||
2909 | public void SetWearable(int wearableId, AvatarWearable wearable) | 2909 | public void SetWearable(int wearableId, AvatarWearable wearable) |
2910 | { | 2910 | { |
2911 | m_appearance.SetWearable(wearableId, wearable); | 2911 | m_appearance.SetWearable(wearableId, wearable); |
2912 | AvatarData adata = new AvatarData(m_appearance); | 2912 | AvatarData adata = new AvatarData(m_appearance); |
2913 | m_scene.AvatarService.SetAvatar(m_controllingClient.AgentId, adata); | 2913 | m_scene.AvatarService.SetAvatar(m_controllingClient.AgentId, adata); |
2914 | m_controllingClient.SendWearables(m_appearance.Wearables, m_appearance.Serial++); | 2914 | m_controllingClient.SendWearables(m_appearance.Wearables, m_appearance.Serial++); |
2915 | } | 2915 | } |
2916 | 2916 | ||
2917 | // Because appearance setting is in a module, we actually need | 2917 | // Because appearance setting is in a module, we actually need |
2918 | // to give it access to our appearance directly, otherwise we | 2918 | // to give it access to our appearance directly, otherwise we |
2919 | // get a synchronization issue. | 2919 | // get a synchronization issue. |
2920 | public AvatarAppearance Appearance | 2920 | public AvatarAppearance Appearance |
2921 | { | 2921 | { |
2922 | get { return m_appearance; } | 2922 | get { return m_appearance; } |
2923 | set { m_appearance = value; } | 2923 | set { m_appearance = value; } |
2924 | } | 2924 | } |
2925 | 2925 | ||
2926 | #endregion | 2926 | #endregion |
2927 | 2927 | ||
2928 | #region Significant Movement Method | 2928 | #region Significant Movement Method |
2929 | 2929 | ||
2930 | /// <summary> | 2930 | /// <summary> |
2931 | /// This checks for a significant movement and sends a courselocationchange update | 2931 | /// This checks for a significant movement and sends a courselocationchange update |
2932 | /// </summary> | 2932 | /// </summary> |
2933 | protected void CheckForSignificantMovement() | 2933 | protected void CheckForSignificantMovement() |
2934 | { | 2934 | { |
2935 | // Movement updates for agents in neighboring regions are sent directly to clients. | 2935 | // Movement updates for agents in neighboring regions are sent directly to clients. |
2936 | // This value only affects how often agent positions are sent to neighbor regions | 2936 | // This value only affects how often agent positions are sent to neighbor regions |
2937 | // for things such as distance-based update prioritization | 2937 | // for things such as distance-based update prioritization |
2938 | const float SIGNIFICANT_MOVEMENT = 2.0f; | 2938 | const float SIGNIFICANT_MOVEMENT = 2.0f; |
2939 | 2939 | ||
2940 | if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > SIGNIFICANT_MOVEMENT) | 2940 | if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > SIGNIFICANT_MOVEMENT) |
2941 | { | 2941 | { |
2942 | posLastSignificantMove = AbsolutePosition; | 2942 | posLastSignificantMove = AbsolutePosition; |
2943 | m_scene.EventManager.TriggerSignificantClientMovement(m_controllingClient); | 2943 | m_scene.EventManager.TriggerSignificantClientMovement(m_controllingClient); |
2944 | } | 2944 | } |
2945 | 2945 | ||
2946 | // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m | 2946 | // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m |
2947 | if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance || | 2947 | if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance || |
2948 | Util.GetDistanceTo(CameraPosition, m_lastChildAgentUpdateCamPosition) >= Scene.ChildReprioritizationDistance) | 2948 | Util.GetDistanceTo(CameraPosition, m_lastChildAgentUpdateCamPosition) >= Scene.ChildReprioritizationDistance) |
2949 | { | 2949 | { |
2950 | m_lastChildAgentUpdatePosition = AbsolutePosition; | 2950 | m_lastChildAgentUpdatePosition = AbsolutePosition; |
2951 | m_lastChildAgentUpdateCamPosition = CameraPosition; | 2951 | m_lastChildAgentUpdateCamPosition = CameraPosition; |
2952 | 2952 | ||
2953 | ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); | 2953 | ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); |
2954 | cadu.ActiveGroupID = UUID.Zero.Guid; | 2954 | cadu.ActiveGroupID = UUID.Zero.Guid; |
2955 | cadu.AgentID = UUID.Guid; | 2955 | cadu.AgentID = UUID.Guid; |
2956 | cadu.alwaysrun = m_setAlwaysRun; | 2956 | cadu.alwaysrun = m_setAlwaysRun; |
2957 | cadu.AVHeight = m_avHeight; | 2957 | cadu.AVHeight = m_avHeight; |
2958 | Vector3 tempCameraCenter = m_CameraCenter; | 2958 | Vector3 tempCameraCenter = m_CameraCenter; |
2959 | cadu.cameraPosition = tempCameraCenter; | 2959 | cadu.cameraPosition = tempCameraCenter; |
2960 | cadu.drawdistance = m_DrawDistance; | 2960 | cadu.drawdistance = m_DrawDistance; |
2961 | cadu.GroupAccess = 0; | 2961 | cadu.GroupAccess = 0; |
2962 | cadu.Position = AbsolutePosition; | 2962 | cadu.Position = AbsolutePosition; |
2963 | cadu.regionHandle = m_rootRegionHandle; | 2963 | cadu.regionHandle = m_rootRegionHandle; |
2964 | float multiplier = 1; | 2964 | float multiplier = 1; |
2965 | int innacurateNeighbors = m_scene.GetInaccurateNeighborCount(); | 2965 | int innacurateNeighbors = m_scene.GetInaccurateNeighborCount(); |
2966 | if (innacurateNeighbors != 0) | 2966 | if (innacurateNeighbors != 0) |
2967 | { | 2967 | { |
2968 | multiplier = 1f / (float)innacurateNeighbors; | 2968 | multiplier = 1f / (float)innacurateNeighbors; |
2969 | } | 2969 | } |
2970 | if (multiplier <= 0f) | 2970 | if (multiplier <= 0f) |
2971 | { | 2971 | { |
2972 | multiplier = 0.25f; | 2972 | multiplier = 0.25f; |
2973 | } | 2973 | } |
2974 | 2974 | ||
2975 | //m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString()); | 2975 | //m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString()); |
2976 | cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier); | 2976 | cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier); |
2977 | cadu.Velocity = Velocity; | 2977 | cadu.Velocity = Velocity; |
2978 | 2978 | ||
2979 | AgentPosition agentpos = new AgentPosition(); | 2979 | AgentPosition agentpos = new AgentPosition(); |
2980 | agentpos.CopyFrom(cadu); | 2980 | agentpos.CopyFrom(cadu); |
2981 | 2981 | ||
2982 | m_scene.SendOutChildAgentUpdates(agentpos, this); | 2982 | m_scene.SendOutChildAgentUpdates(agentpos, this); |
2983 | } | 2983 | } |
2984 | } | 2984 | } |
2985 | 2985 | ||
2986 | #endregion | 2986 | #endregion |
2987 | 2987 | ||
2988 | #region Border Crossing Methods | 2988 | #region Border Crossing Methods |
2989 | 2989 | ||
2990 | /// <summary> | 2990 | /// <summary> |
2991 | /// Checks to see if the avatar is in range of a border and calls CrossToNewRegion | 2991 | /// Checks to see if the avatar is in range of a border and calls CrossToNewRegion |
2992 | /// </summary> | 2992 | /// </summary> |
2993 | protected void CheckForBorderCrossing() | 2993 | protected void CheckForBorderCrossing() |
2994 | { | 2994 | { |
2995 | if (IsChildAgent) | 2995 | if (IsChildAgent) |
2996 | return; | 2996 | return; |
2997 | 2997 | ||
2998 | Vector3 pos2 = AbsolutePosition; | 2998 | Vector3 pos2 = AbsolutePosition; |
2999 | Vector3 vel = Velocity; | 2999 | Vector3 vel = Velocity; |
3000 | int neighbor = 0; | 3000 | int neighbor = 0; |
3001 | int[] fix = new int[2]; | 3001 | int[] fix = new int[2]; |
3002 | 3002 | ||
3003 | float timeStep = 0.1f; | 3003 | float timeStep = 0.1f; |
3004 | pos2.X = pos2.X + (vel.X*timeStep); | 3004 | pos2.X = pos2.X + (vel.X*timeStep); |
3005 | pos2.Y = pos2.Y + (vel.Y*timeStep); | 3005 | pos2.Y = pos2.Y + (vel.Y*timeStep); |
3006 | pos2.Z = pos2.Z + (vel.Z*timeStep); | 3006 | pos2.Z = pos2.Z + (vel.Z*timeStep); |
3007 | 3007 | ||
3008 | if (!IsInTransit) | 3008 | if (!IsInTransit) |
3009 | { | 3009 | { |
3010 | // Checks if where it's headed exists a region | 3010 | // Checks if where it's headed exists a region |
3011 | 3011 | ||
3012 | bool needsTransit = false; | 3012 | bool needsTransit = false; |
3013 | if (m_scene.TestBorderCross(pos2, Cardinals.W)) | 3013 | if (m_scene.TestBorderCross(pos2, Cardinals.W)) |
3014 | { | 3014 | { |
3015 | if (m_scene.TestBorderCross(pos2, Cardinals.S)) | 3015 | if (m_scene.TestBorderCross(pos2, Cardinals.S)) |
3016 | { | 3016 | { |
3017 | needsTransit = true; | 3017 | needsTransit = true; |
3018 | neighbor = HaveNeighbor(Cardinals.SW, ref fix); | 3018 | neighbor = HaveNeighbor(Cardinals.SW, ref fix); |
3019 | } | 3019 | } |
3020 | else if (m_scene.TestBorderCross(pos2, Cardinals.N)) | 3020 | else if (m_scene.TestBorderCross(pos2, Cardinals.N)) |
3021 | { | 3021 | { |
3022 | needsTransit = true; | 3022 | needsTransit = true; |
3023 | neighbor = HaveNeighbor(Cardinals.NW, ref fix); | 3023 | neighbor = HaveNeighbor(Cardinals.NW, ref fix); |
3024 | } | 3024 | } |
3025 | else | 3025 | else |
3026 | { | 3026 | { |
3027 | needsTransit = true; | 3027 | needsTransit = true; |
3028 | neighbor = HaveNeighbor(Cardinals.W, ref fix); | 3028 | neighbor = HaveNeighbor(Cardinals.W, ref fix); |
3029 | } | 3029 | } |
3030 | } | 3030 | } |
3031 | else if (m_scene.TestBorderCross(pos2, Cardinals.E)) | 3031 | else if (m_scene.TestBorderCross(pos2, Cardinals.E)) |
3032 | { | 3032 | { |
3033 | if (m_scene.TestBorderCross(pos2, Cardinals.S)) | 3033 | if (m_scene.TestBorderCross(pos2, Cardinals.S)) |
3034 | { | 3034 | { |
3035 | needsTransit = true; | 3035 | needsTransit = true; |
3036 | neighbor = HaveNeighbor(Cardinals.SE, ref fix); | 3036 | neighbor = HaveNeighbor(Cardinals.SE, ref fix); |
3037 | } | 3037 | } |
3038 | else if (m_scene.TestBorderCross(pos2, Cardinals.N)) | 3038 | else if (m_scene.TestBorderCross(pos2, Cardinals.N)) |
3039 | { | 3039 | { |
3040 | needsTransit = true; | 3040 | needsTransit = true; |
3041 | neighbor = HaveNeighbor(Cardinals.NE, ref fix); | 3041 | neighbor = HaveNeighbor(Cardinals.NE, ref fix); |
3042 | } | 3042 | } |
3043 | else | 3043 | else |
3044 | { | 3044 | { |
3045 | needsTransit = true; | 3045 | needsTransit = true; |
3046 | neighbor = HaveNeighbor(Cardinals.E, ref fix); | 3046 | neighbor = HaveNeighbor(Cardinals.E, ref fix); |
3047 | } | 3047 | } |
3048 | } | 3048 | } |
3049 | else if (m_scene.TestBorderCross(pos2, Cardinals.S)) | 3049 | else if (m_scene.TestBorderCross(pos2, Cardinals.S)) |
3050 | { | 3050 | { |
3051 | needsTransit = true; | 3051 | needsTransit = true; |
3052 | neighbor = HaveNeighbor(Cardinals.S, ref fix); | 3052 | neighbor = HaveNeighbor(Cardinals.S, ref fix); |
3053 | } | 3053 | } |
3054 | else if (m_scene.TestBorderCross(pos2, Cardinals.N)) | 3054 | else if (m_scene.TestBorderCross(pos2, Cardinals.N)) |
3055 | { | 3055 | { |
3056 | needsTransit = true; | 3056 | needsTransit = true; |
3057 | neighbor = HaveNeighbor(Cardinals.N, ref fix); | 3057 | neighbor = HaveNeighbor(Cardinals.N, ref fix); |
3058 | } | 3058 | } |
3059 | 3059 | ||
3060 | 3060 | ||
3061 | // Makes sure avatar does not end up outside region | 3061 | // Makes sure avatar does not end up outside region |
3062 | if (neighbor <= 0) | 3062 | if (neighbor <= 0) |
3063 | { | 3063 | { |
3064 | if (!needsTransit) | 3064 | if (!needsTransit) |
3065 | { | 3065 | { |
3066 | if (m_requestedSitTargetUUID == UUID.Zero) | 3066 | if (m_requestedSitTargetUUID == UUID.Zero) |
3067 | { | 3067 | { |
3068 | Vector3 pos = AbsolutePosition; | 3068 | Vector3 pos = AbsolutePosition; |
3069 | if (AbsolutePosition.X < 0) | 3069 | if (AbsolutePosition.X < 0) |
3070 | pos.X += Velocity.X; | 3070 | pos.X += Velocity.X; |
3071 | else if (AbsolutePosition.X > Constants.RegionSize) | 3071 | else if (AbsolutePosition.X > Constants.RegionSize) |
3072 | pos.X -= Velocity.X; | 3072 | pos.X -= Velocity.X; |
3073 | if (AbsolutePosition.Y < 0) | 3073 | if (AbsolutePosition.Y < 0) |
3074 | pos.Y += Velocity.Y; | 3074 | pos.Y += Velocity.Y; |
3075 | else if (AbsolutePosition.Y > Constants.RegionSize) | 3075 | else if (AbsolutePosition.Y > Constants.RegionSize) |
3076 | pos.Y -= Velocity.Y; | 3076 | pos.Y -= Velocity.Y; |
3077 | AbsolutePosition = pos; | 3077 | AbsolutePosition = pos; |
3078 | } | 3078 | } |
3079 | } | 3079 | } |
3080 | } | 3080 | } |
3081 | else if (neighbor > 0) | 3081 | else if (neighbor > 0) |
3082 | CrossToNewRegion(); | 3082 | CrossToNewRegion(); |
3083 | } | 3083 | } |
3084 | else | 3084 | else |
3085 | { | 3085 | { |
3086 | RemoveFromPhysicalScene(); | 3086 | RemoveFromPhysicalScene(); |
3087 | // This constant has been inferred from experimentation | 3087 | // This constant has been inferred from experimentation |
3088 | // I'm not sure what this value should be, so I tried a few values. | 3088 | // I'm not sure what this value should be, so I tried a few values. |
3089 | timeStep = 0.04f; | 3089 | timeStep = 0.04f; |
3090 | pos2 = AbsolutePosition; | 3090 | pos2 = AbsolutePosition; |
3091 | pos2.X = pos2.X + (vel.X * timeStep); | 3091 | pos2.X = pos2.X + (vel.X * timeStep); |
3092 | pos2.Y = pos2.Y + (vel.Y * timeStep); | 3092 | pos2.Y = pos2.Y + (vel.Y * timeStep); |
3093 | pos2.Z = pos2.Z + (vel.Z * timeStep); | 3093 | pos2.Z = pos2.Z + (vel.Z * timeStep); |
3094 | m_pos = pos2; | 3094 | m_pos = pos2; |
3095 | } | 3095 | } |
3096 | } | 3096 | } |
3097 | 3097 | ||
3098 | protected int HaveNeighbor(Cardinals car, ref int[] fix) | 3098 | protected int HaveNeighbor(Cardinals car, ref int[] fix) |
3099 | { | 3099 | { |
3100 | uint neighbourx = m_regionInfo.RegionLocX; | 3100 | uint neighbourx = m_regionInfo.RegionLocX; |
3101 | uint neighboury = m_regionInfo.RegionLocY; | 3101 | uint neighboury = m_regionInfo.RegionLocY; |
3102 | 3102 | ||
3103 | int dir = (int)car; | 3103 | int dir = (int)car; |
3104 | 3104 | ||
3105 | if (dir > 1 && dir < 5) //Heading East | 3105 | if (dir > 1 && dir < 5) //Heading East |
3106 | neighbourx++; | 3106 | neighbourx++; |
3107 | else if (dir > 5) // Heading West | 3107 | else if (dir > 5) // Heading West |
3108 | neighbourx--; | 3108 | neighbourx--; |
3109 | 3109 | ||
3110 | if (dir < 3 || dir == 8) // Heading North | 3110 | if (dir < 3 || dir == 8) // Heading North |
3111 | neighboury++; | 3111 | neighboury++; |
3112 | else if (dir > 3 && dir < 7) // Heading Sout | 3112 | else if (dir > 3 && dir < 7) // Heading Sout |
3113 | neighboury--; | 3113 | neighboury--; |
3114 | 3114 | ||
3115 | int x = (int)(neighbourx * Constants.RegionSize); | 3115 | int x = (int)(neighbourx * Constants.RegionSize); |
3116 | int y = (int)(neighboury * Constants.RegionSize); | 3116 | int y = (int)(neighboury * Constants.RegionSize); |
3117 | GridRegion neighbourRegion = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, x, y); | 3117 | GridRegion neighbourRegion = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, x, y); |
3118 | 3118 | ||
3119 | if (neighbourRegion == null) | 3119 | if (neighbourRegion == null) |
3120 | { | 3120 | { |
3121 | fix[0] = (int)(m_regionInfo.RegionLocX - neighbourx); | 3121 | fix[0] = (int)(m_regionInfo.RegionLocX - neighbourx); |
3122 | fix[1] = (int)(m_regionInfo.RegionLocY - neighboury); | 3122 | fix[1] = (int)(m_regionInfo.RegionLocY - neighboury); |
3123 | return dir * (-1); | 3123 | return dir * (-1); |
3124 | } | 3124 | } |
3125 | else | 3125 | else |
3126 | return dir; | 3126 | return dir; |
3127 | } | 3127 | } |
3128 | 3128 | ||
3129 | /// <summary> | 3129 | /// <summary> |
3130 | /// Moves the agent outside the region bounds | 3130 | /// Moves the agent outside the region bounds |
3131 | /// Tells neighbor region that we're crossing to it | 3131 | /// Tells neighbor region that we're crossing to it |
3132 | /// If the neighbor accepts, remove the agent's viewable avatar from this scene | 3132 | /// If the neighbor accepts, remove the agent's viewable avatar from this scene |
3133 | /// set them to a child agent. | 3133 | /// set them to a child agent. |
3134 | /// </summary> | 3134 | /// </summary> |
3135 | protected void CrossToNewRegion() | 3135 | protected void CrossToNewRegion() |
3136 | { | 3136 | { |
3137 | InTransit(); | 3137 | InTransit(); |
3138 | try | 3138 | try |
3139 | { | 3139 | { |
3140 | m_scene.CrossAgentToNewRegion(this, m_physicsActor.Flying); | 3140 | m_scene.CrossAgentToNewRegion(this, m_physicsActor.Flying); |
3141 | } | 3141 | } |
3142 | catch | 3142 | catch |
3143 | { | 3143 | { |
3144 | m_scene.CrossAgentToNewRegion(this, false); | 3144 | m_scene.CrossAgentToNewRegion(this, false); |
3145 | } | 3145 | } |
3146 | } | 3146 | } |
3147 | 3147 | ||
3148 | public void InTransit() | 3148 | public void InTransit() |
3149 | { | 3149 | { |
3150 | m_inTransit = true; | 3150 | m_inTransit = true; |
3151 | 3151 | ||
3152 | if ((m_physicsActor != null) && m_physicsActor.Flying) | 3152 | if ((m_physicsActor != null) && m_physicsActor.Flying) |
3153 | m_AgentControlFlags |= AgentManager.ControlFlags.AGENT_CONTROL_FLY; | 3153 | m_AgentControlFlags |= AgentManager.ControlFlags.AGENT_CONTROL_FLY; |
3154 | else if ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0) | 3154 | else if ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0) |
3155 | m_AgentControlFlags &= ~AgentManager.ControlFlags.AGENT_CONTROL_FLY; | 3155 | m_AgentControlFlags &= ~AgentManager.ControlFlags.AGENT_CONTROL_FLY; |
3156 | } | 3156 | } |
3157 | 3157 | ||
3158 | public void NotInTransit() | 3158 | public void NotInTransit() |
3159 | { | 3159 | { |
3160 | m_inTransit = false; | 3160 | m_inTransit = false; |
3161 | } | 3161 | } |
3162 | 3162 | ||
3163 | public void RestoreInCurrentScene() | 3163 | public void RestoreInCurrentScene() |
3164 | { | 3164 | { |
3165 | AddToPhysicalScene(false); // not exactly false | 3165 | AddToPhysicalScene(false); // not exactly false |
3166 | } | 3166 | } |
3167 | 3167 | ||
3168 | public void Reset() | 3168 | public void Reset() |
3169 | { | 3169 | { |
3170 | // Put the child agent back at the center | 3170 | // Put the child agent back at the center |
3171 | AbsolutePosition | 3171 | AbsolutePosition |
3172 | = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f), 70); | 3172 | = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f), 70); |
3173 | Animator.ResetAnimations(); | 3173 | Animator.ResetAnimations(); |
3174 | } | 3174 | } |
3175 | 3175 | ||
3176 | /// <summary> | 3176 | /// <summary> |
3177 | /// Computes which child agents to close when the scene presence moves to another region. | 3177 | /// Computes which child agents to close when the scene presence moves to another region. |
3178 | /// Removes those regions from m_knownRegions. | 3178 | /// Removes those regions from m_knownRegions. |
3179 | /// </summary> | 3179 | /// </summary> |
3180 | /// <param name="newRegionX">The new region's x on the map</param> | 3180 | /// <param name="newRegionX">The new region's x on the map</param> |
3181 | /// <param name="newRegionY">The new region's y on the map</param> | 3181 | /// <param name="newRegionY">The new region's y on the map</param> |
3182 | /// <returns></returns> | 3182 | /// <returns></returns> |
3183 | public void CloseChildAgents(uint newRegionX, uint newRegionY) | 3183 | public void CloseChildAgents(uint newRegionX, uint newRegionY) |
3184 | { | 3184 | { |
3185 | List<ulong> byebyeRegions = new List<ulong>(); | 3185 | List<ulong> byebyeRegions = new List<ulong>(); |
3186 | m_log.DebugFormat( | 3186 | m_log.DebugFormat( |
3187 | "[SCENE PRESENCE]: Closing child agents. Checking {0} regions in {1}", | 3187 | "[SCENE PRESENCE]: Closing child agents. Checking {0} regions in {1}", |
3188 | m_knownChildRegions.Keys.Count, Scene.RegionInfo.RegionName); | 3188 | m_knownChildRegions.Keys.Count, Scene.RegionInfo.RegionName); |
3189 | //DumpKnownRegions(); | 3189 | //DumpKnownRegions(); |
3190 | 3190 | ||
3191 | lock (m_knownChildRegions) | 3191 | lock (m_knownChildRegions) |
3192 | { | 3192 | { |
3193 | foreach (ulong handle in m_knownChildRegions.Keys) | 3193 | foreach (ulong handle in m_knownChildRegions.Keys) |
3194 | { | 3194 | { |
3195 | // Don't close the agent on this region yet | 3195 | // Don't close the agent on this region yet |
3196 | if (handle != Scene.RegionInfo.RegionHandle) | 3196 | if (handle != Scene.RegionInfo.RegionHandle) |
3197 | { | 3197 | { |
3198 | uint x, y; | 3198 | uint x, y; |
3199 | Utils.LongToUInts(handle, out x, out y); | 3199 | Utils.LongToUInts(handle, out x, out y); |
3200 | x = x / Constants.RegionSize; | 3200 | x = x / Constants.RegionSize; |
3201 | y = y / Constants.RegionSize; | 3201 | y = y / Constants.RegionSize; |
3202 | 3202 | ||
3203 | //m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); | 3203 | //m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); |
3204 | //m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); | 3204 | //m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); |
3205 | if (Util.IsOutsideView(x, newRegionX, y, newRegionY)) | 3205 | if (Util.IsOutsideView(x, newRegionX, y, newRegionY)) |
3206 | { | 3206 | { |
3207 | byebyeRegions.Add(handle); | 3207 | byebyeRegions.Add(handle); |
3208 | } | 3208 | } |
3209 | } | 3209 | } |
3210 | } | 3210 | } |
3211 | } | 3211 | } |
3212 | 3212 | ||
3213 | if (byebyeRegions.Count > 0) | 3213 | if (byebyeRegions.Count > 0) |
3214 | { | 3214 | { |
3215 | m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents"); | 3215 | m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents"); |
3216 | m_scene.SceneGridService.SendCloseChildAgentConnections(m_controllingClient.AgentId, byebyeRegions); | 3216 | m_scene.SceneGridService.SendCloseChildAgentConnections(m_controllingClient.AgentId, byebyeRegions); |
3217 | } | 3217 | } |
3218 | 3218 | ||
3219 | foreach (ulong handle in byebyeRegions) | 3219 | foreach (ulong handle in byebyeRegions) |
3220 | { | 3220 | { |
3221 | RemoveNeighbourRegion(handle); | 3221 | RemoveNeighbourRegion(handle); |
3222 | } | 3222 | } |
3223 | } | 3223 | } |
3224 | 3224 | ||
3225 | #endregion | 3225 | #endregion |
3226 | 3226 | ||
3227 | /// <summary> | 3227 | /// <summary> |
3228 | /// This allows the Sim owner the abiility to kick users from their sim currently. | 3228 | /// This allows the Sim owner the abiility to kick users from their sim currently. |
3229 | /// It tells the client that the agent has permission to do so. | 3229 | /// It tells the client that the agent has permission to do so. |
3230 | /// </summary> | 3230 | /// </summary> |
3231 | public void GrantGodlikePowers(UUID agentID, UUID sessionID, UUID token, bool godStatus) | 3231 | public void GrantGodlikePowers(UUID agentID, UUID sessionID, UUID token, bool godStatus) |
3232 | { | 3232 | { |
3233 | if (godStatus) | 3233 | if (godStatus) |
3234 | { | 3234 | { |
3235 | // For now, assign god level 200 to anyone | 3235 | // For now, assign god level 200 to anyone |
3236 | // who is granted god powers, but has no god level set. | 3236 | // who is granted god powers, but has no god level set. |
3237 | // | 3237 | // |
3238 | UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, agentID); | 3238 | UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, agentID); |
3239 | if (account != null) | 3239 | if (account != null) |
3240 | { | 3240 | { |
3241 | if (account.UserLevel > 0) | 3241 | if (account.UserLevel > 0) |
3242 | m_godLevel = account.UserLevel; | 3242 | m_godLevel = account.UserLevel; |
3243 | else | 3243 | else |
3244 | m_godLevel = 200; | 3244 | m_godLevel = 200; |
3245 | } | 3245 | } |
3246 | } | 3246 | } |
3247 | else | 3247 | else |
3248 | { | 3248 | { |
3249 | m_godLevel = 0; | 3249 | m_godLevel = 0; |
3250 | } | 3250 | } |
3251 | 3251 | ||
3252 | ControllingClient.SendAdminResponse(token, (uint)m_godLevel); | 3252 | ControllingClient.SendAdminResponse(token, (uint)m_godLevel); |
3253 | } | 3253 | } |
3254 | 3254 | ||
3255 | #region Child Agent Updates | 3255 | #region Child Agent Updates |
3256 | 3256 | ||
3257 | public void ChildAgentDataUpdate(AgentData cAgentData) | 3257 | public void ChildAgentDataUpdate(AgentData cAgentData) |
3258 | { | 3258 | { |
3259 | //m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); | 3259 | //m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); |
3260 | if (!IsChildAgent) | 3260 | if (!IsChildAgent) |
3261 | return; | 3261 | return; |
3262 | 3262 | ||
3263 | CopyFrom(cAgentData); | 3263 | CopyFrom(cAgentData); |
3264 | } | 3264 | } |
3265 | 3265 | ||
3266 | /// <summary> | 3266 | /// <summary> |
3267 | /// This updates important decision making data about a child agent | 3267 | /// This updates important decision making data about a child agent |
3268 | /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region | 3268 | /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region |
3269 | /// </summary> | 3269 | /// </summary> |
3270 | public void ChildAgentDataUpdate(AgentPosition cAgentData, uint tRegionX, uint tRegionY, uint rRegionX, uint rRegionY) | 3270 | public void ChildAgentDataUpdate(AgentPosition cAgentData, uint tRegionX, uint tRegionY, uint rRegionX, uint rRegionY) |
3271 | { | 3271 | { |
3272 | if (!IsChildAgent) | 3272 | if (!IsChildAgent) |
3273 | return; | 3273 | return; |
3274 | 3274 | ||
3275 | //m_log.Debug(" >>> ChildAgentPositionUpdate <<< " + rRegionX + "-" + rRegionY); | 3275 | //m_log.Debug(" >>> ChildAgentPositionUpdate <<< " + rRegionX + "-" + rRegionY); |
3276 | int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize; | 3276 | int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize; |
3277 | int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize; | 3277 | int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize; |
3278 | 3278 | ||
3279 | Vector3 offset = new Vector3(shiftx, shifty, 0f); | 3279 | Vector3 offset = new Vector3(shiftx, shifty, 0f); |
3280 | 3280 | ||
3281 | m_DrawDistance = cAgentData.Far; | 3281 | m_DrawDistance = cAgentData.Far; |
3282 | if (cAgentData.Position != new Vector3(-1f, -1f, -1f)) // UGH!! | 3282 | if (cAgentData.Position != new Vector3(-1f, -1f, -1f)) // UGH!! |
3283 | m_pos = cAgentData.Position + offset; | 3283 | m_pos = cAgentData.Position + offset; |
3284 | 3284 | ||
3285 | if (Vector3.Distance(AbsolutePosition, posLastSignificantMove) >= Scene.ChildReprioritizationDistance) | 3285 | if (Vector3.Distance(AbsolutePosition, posLastSignificantMove) >= Scene.ChildReprioritizationDistance) |
3286 | { | 3286 | { |
3287 | posLastSignificantMove = AbsolutePosition; | 3287 | posLastSignificantMove = AbsolutePosition; |
3288 | ReprioritizeUpdates(); | 3288 | ReprioritizeUpdates(); |
3289 | } | 3289 | } |
3290 | 3290 | ||
3291 | m_CameraCenter = cAgentData.Center + offset; | 3291 | m_CameraCenter = cAgentData.Center + offset; |
3292 | 3292 | ||
3293 | m_avHeight = cAgentData.Size.Z; | 3293 | m_avHeight = cAgentData.Size.Z; |
3294 | //SetHeight(cAgentData.AVHeight); | 3294 | //SetHeight(cAgentData.AVHeight); |
3295 | 3295 | ||
3296 | if ((cAgentData.Throttles != null) && cAgentData.Throttles.Length > 0) | 3296 | if ((cAgentData.Throttles != null) && cAgentData.Throttles.Length > 0) |
3297 | ControllingClient.SetChildAgentThrottle(cAgentData.Throttles); | 3297 | ControllingClient.SetChildAgentThrottle(cAgentData.Throttles); |
3298 | 3298 | ||
3299 | // Sends out the objects in the user's draw distance if m_sendTasksToChild is true. | 3299 | // Sends out the objects in the user's draw distance if m_sendTasksToChild is true. |
3300 | if (m_scene.m_seeIntoRegionFromNeighbor) | 3300 | if (m_scene.m_seeIntoRegionFromNeighbor) |
3301 | m_sceneViewer.Reset(); | 3301 | m_sceneViewer.Reset(); |
3302 | 3302 | ||
3303 | //cAgentData.AVHeight; | 3303 | //cAgentData.AVHeight; |
3304 | m_rootRegionHandle = cAgentData.RegionHandle; | 3304 | m_rootRegionHandle = cAgentData.RegionHandle; |
3305 | //m_velocity = cAgentData.Velocity; | 3305 | //m_velocity = cAgentData.Velocity; |
3306 | } | 3306 | } |
3307 | 3307 | ||
3308 | public void CopyTo(AgentData cAgent) | 3308 | public void CopyTo(AgentData cAgent) |
3309 | { | 3309 | { |
3310 | cAgent.AgentID = UUID; | 3310 | cAgent.AgentID = UUID; |
3311 | cAgent.RegionID = Scene.RegionInfo.RegionID; | 3311 | cAgent.RegionID = Scene.RegionInfo.RegionID; |
3312 | 3312 | ||
3313 | cAgent.Position = AbsolutePosition; | 3313 | cAgent.Position = AbsolutePosition; |
3314 | cAgent.Velocity = m_velocity; | 3314 | cAgent.Velocity = m_velocity; |
3315 | cAgent.Center = m_CameraCenter; | 3315 | cAgent.Center = m_CameraCenter; |
3316 | // Don't copy the size; it is inferred from apearance parameters | 3316 | // Don't copy the size; it is inferred from apearance parameters |
3317 | //cAgent.Size = new Vector3(0, 0, m_avHeight); | 3317 | //cAgent.Size = new Vector3(0, 0, m_avHeight); |
3318 | cAgent.AtAxis = m_CameraAtAxis; | 3318 | cAgent.AtAxis = m_CameraAtAxis; |
3319 | cAgent.LeftAxis = m_CameraLeftAxis; | 3319 | cAgent.LeftAxis = m_CameraLeftAxis; |
3320 | cAgent.UpAxis = m_CameraUpAxis; | 3320 | cAgent.UpAxis = m_CameraUpAxis; |
3321 | 3321 | ||
3322 | cAgent.Far = m_DrawDistance; | 3322 | cAgent.Far = m_DrawDistance; |
3323 | 3323 | ||
3324 | // Throttles | 3324 | // Throttles |
3325 | float multiplier = 1; | 3325 | float multiplier = 1; |
3326 | int innacurateNeighbors = m_scene.GetInaccurateNeighborCount(); | 3326 | int innacurateNeighbors = m_scene.GetInaccurateNeighborCount(); |
3327 | if (innacurateNeighbors != 0) | 3327 | if (innacurateNeighbors != 0) |
3328 | { | 3328 | { |
3329 | multiplier = 1f / innacurateNeighbors; | 3329 | multiplier = 1f / innacurateNeighbors; |
3330 | } | 3330 | } |
3331 | if (multiplier <= 0f) | 3331 | if (multiplier <= 0f) |
3332 | { | 3332 | { |
3333 | multiplier = 0.25f; | 3333 | multiplier = 0.25f; |
3334 | } | 3334 | } |
3335 | //m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString()); | 3335 | //m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString()); |
3336 | cAgent.Throttles = ControllingClient.GetThrottlesPacked(multiplier); | 3336 | cAgent.Throttles = ControllingClient.GetThrottlesPacked(multiplier); |
3337 | 3337 | ||
3338 | cAgent.HeadRotation = m_headrotation; | 3338 | cAgent.HeadRotation = m_headrotation; |
3339 | cAgent.BodyRotation = m_bodyRot; | 3339 | cAgent.BodyRotation = m_bodyRot; |
3340 | cAgent.ControlFlags = (uint)m_AgentControlFlags; | 3340 | cAgent.ControlFlags = (uint)m_AgentControlFlags; |
3341 | 3341 | ||
3342 | if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID))) | 3342 | if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID))) |
3343 | cAgent.GodLevel = (byte)m_godLevel; | 3343 | cAgent.GodLevel = (byte)m_godLevel; |
3344 | else | 3344 | else |
3345 | cAgent.GodLevel = (byte) 0; | 3345 | cAgent.GodLevel = (byte) 0; |
3346 | 3346 | ||
3347 | cAgent.AlwaysRun = m_setAlwaysRun; | 3347 | cAgent.AlwaysRun = m_setAlwaysRun; |
3348 | 3348 | ||
3349 | try | 3349 | try |
3350 | { | 3350 | { |
3351 | // We might not pass the Wearables in all cases... | 3351 | // We might not pass the Wearables in all cases... |
3352 | // They're only needed so that persistent changes to the appearance | 3352 | // They're only needed so that persistent changes to the appearance |
3353 | // are preserved in the new region where the user is moving to. | 3353 | // are preserved in the new region where the user is moving to. |
3354 | // But in Hypergrid we might not let this happen. | 3354 | // But in Hypergrid we might not let this happen. |
3355 | int i = 0; | 3355 | int i = 0; |
3356 | UUID[] wears = new UUID[m_appearance.Wearables.Length * 2]; | 3356 | UUID[] wears = new UUID[m_appearance.Wearables.Length * 2]; |
3357 | foreach (AvatarWearable aw in m_appearance.Wearables) | 3357 | foreach (AvatarWearable aw in m_appearance.Wearables) |
3358 | { | 3358 | { |
3359 | if (aw != null) | 3359 | if (aw != null) |
3360 | { | 3360 | { |
3361 | wears[i++] = aw.ItemID; | 3361 | wears[i++] = aw.ItemID; |
3362 | wears[i++] = aw.AssetID; | 3362 | wears[i++] = aw.AssetID; |
3363 | } | 3363 | } |
3364 | else | 3364 | else |
3365 | { | 3365 | { |
3366 | wears[i++] = UUID.Zero; | 3366 | wears[i++] = UUID.Zero; |
3367 | wears[i++] = UUID.Zero; | 3367 | wears[i++] = UUID.Zero; |
3368 | } | 3368 | } |
3369 | } | 3369 | } |
3370 | cAgent.Wearables = wears; | 3370 | cAgent.Wearables = wears; |
3371 | 3371 | ||
3372 | cAgent.VisualParams = m_appearance.VisualParams; | 3372 | cAgent.VisualParams = m_appearance.VisualParams; |
3373 | 3373 | ||
3374 | if (m_appearance.Texture != null) | 3374 | if (m_appearance.Texture != null) |
3375 | cAgent.AgentTextures = m_appearance.Texture.GetBytes(); | 3375 | cAgent.AgentTextures = m_appearance.Texture.GetBytes(); |
3376 | } | 3376 | } |
3377 | catch (Exception e) | 3377 | catch (Exception e) |
3378 | { | 3378 | { |
3379 | m_log.Warn("[SCENE PRESENCE]: exception in CopyTo " + e.Message); | 3379 | m_log.Warn("[SCENE PRESENCE]: exception in CopyTo " + e.Message); |
3380 | } | 3380 | } |
3381 | 3381 | ||
3382 | //Attachments | 3382 | //Attachments |
3383 | List<int> attPoints = m_appearance.GetAttachedPoints(); | 3383 | List<int> attPoints = m_appearance.GetAttachedPoints(); |
3384 | if (attPoints != null) | 3384 | if (attPoints != null) |
3385 | { | 3385 | { |
3386 | //m_log.DebugFormat("[SCENE PRESENCE]: attachments {0}", attPoints.Count); | 3386 | //m_log.DebugFormat("[SCENE PRESENCE]: attachments {0}", attPoints.Count); |
3387 | int i = 0; | 3387 | int i = 0; |
3388 | AttachmentData[] attachs = new AttachmentData[attPoints.Count]; | 3388 | AttachmentData[] attachs = new AttachmentData[attPoints.Count]; |
3389 | foreach (int point in attPoints) | 3389 | foreach (int point in attPoints) |
3390 | { | 3390 | { |
3391 | attachs[i++] = new AttachmentData(point, m_appearance.GetAttachedItem(point), m_appearance.GetAttachedAsset(point)); | 3391 | attachs[i++] = new AttachmentData(point, m_appearance.GetAttachedItem(point), m_appearance.GetAttachedAsset(point)); |
3392 | } | 3392 | } |
3393 | cAgent.Attachments = attachs; | 3393 | cAgent.Attachments = attachs; |
3394 | } | 3394 | } |
3395 | 3395 | ||
3396 | lock (scriptedcontrols) | 3396 | lock (scriptedcontrols) |
3397 | { | 3397 | { |
3398 | ControllerData[] controls = new ControllerData[scriptedcontrols.Count]; | 3398 | ControllerData[] controls = new ControllerData[scriptedcontrols.Count]; |
3399 | int i = 0; | 3399 | int i = 0; |
3400 | 3400 | ||
3401 | foreach (ScriptControllers c in scriptedcontrols.Values) | 3401 | foreach (ScriptControllers c in scriptedcontrols.Values) |
3402 | { | 3402 | { |
3403 | controls[i++] = new ControllerData(c.itemID, (uint)c.ignoreControls, (uint)c.eventControls); | 3403 | controls[i++] = new ControllerData(c.itemID, (uint)c.ignoreControls, (uint)c.eventControls); |
3404 | } | 3404 | } |
3405 | cAgent.Controllers = controls; | 3405 | cAgent.Controllers = controls; |
3406 | } | 3406 | } |
3407 | 3407 | ||
3408 | // Animations | 3408 | // Animations |
3409 | try | 3409 | try |
3410 | { | 3410 | { |
3411 | cAgent.Anims = Animator.Animations.ToArray(); | 3411 | cAgent.Anims = Animator.Animations.ToArray(); |
3412 | } | 3412 | } |
3413 | catch { } | 3413 | catch { } |
3414 | 3414 | ||
3415 | // cAgent.GroupID = ?? | 3415 | // cAgent.GroupID = ?? |
3416 | // Groups??? | 3416 | // Groups??? |
3417 | 3417 | ||
3418 | } | 3418 | } |
3419 | 3419 | ||
3420 | public void CopyFrom(AgentData cAgent) | 3420 | public void CopyFrom(AgentData cAgent) |
3421 | { | 3421 | { |
3422 | m_originRegionID = cAgent.RegionID; | 3422 | m_originRegionID = cAgent.RegionID; |
3423 | 3423 | ||
3424 | m_callbackURI = cAgent.CallbackURI; | 3424 | m_callbackURI = cAgent.CallbackURI; |
3425 | 3425 | ||
3426 | m_pos = cAgent.Position; | 3426 | m_pos = cAgent.Position; |
3427 | 3427 | ||
3428 | m_velocity = cAgent.Velocity; | 3428 | m_velocity = cAgent.Velocity; |
3429 | m_CameraCenter = cAgent.Center; | 3429 | m_CameraCenter = cAgent.Center; |
3430 | //m_avHeight = cAgent.Size.Z; | 3430 | //m_avHeight = cAgent.Size.Z; |
3431 | m_CameraAtAxis = cAgent.AtAxis; | 3431 | m_CameraAtAxis = cAgent.AtAxis; |
3432 | m_CameraLeftAxis = cAgent.LeftAxis; | 3432 | m_CameraLeftAxis = cAgent.LeftAxis; |
3433 | m_CameraUpAxis = cAgent.UpAxis; | 3433 | m_CameraUpAxis = cAgent.UpAxis; |
3434 | 3434 | ||
3435 | m_DrawDistance = cAgent.Far; | 3435 | m_DrawDistance = cAgent.Far; |
3436 | 3436 | ||
3437 | if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0) | 3437 | if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0) |
3438 | ControllingClient.SetChildAgentThrottle(cAgent.Throttles); | 3438 | ControllingClient.SetChildAgentThrottle(cAgent.Throttles); |
3439 | 3439 | ||
3440 | m_headrotation = cAgent.HeadRotation; | 3440 | m_headrotation = cAgent.HeadRotation; |
3441 | m_bodyRot = cAgent.BodyRotation; | 3441 | m_bodyRot = cAgent.BodyRotation; |
3442 | m_AgentControlFlags = (AgentManager.ControlFlags)cAgent.ControlFlags; | 3442 | m_AgentControlFlags = (AgentManager.ControlFlags)cAgent.ControlFlags; |
3443 | 3443 | ||
3444 | if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID))) | 3444 | if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID))) |
3445 | m_godLevel = cAgent.GodLevel; | 3445 | m_godLevel = cAgent.GodLevel; |
3446 | m_setAlwaysRun = cAgent.AlwaysRun; | 3446 | m_setAlwaysRun = cAgent.AlwaysRun; |
3447 | 3447 | ||
3448 | uint i = 0; | 3448 | uint i = 0; |
3449 | try | 3449 | try |
3450 | { | 3450 | { |
3451 | if (cAgent.Wearables == null) | 3451 | if (cAgent.Wearables == null) |
3452 | cAgent.Wearables = new UUID[0]; | 3452 | cAgent.Wearables = new UUID[0]; |
3453 | AvatarWearable[] wears = new AvatarWearable[cAgent.Wearables.Length / 2]; | 3453 | AvatarWearable[] wears = new AvatarWearable[cAgent.Wearables.Length / 2]; |
3454 | for (uint n = 0; n < cAgent.Wearables.Length; n += 2) | 3454 | for (uint n = 0; n < cAgent.Wearables.Length; n += 2) |
3455 | { | 3455 | { |
3456 | UUID itemId = cAgent.Wearables[n]; | 3456 | UUID itemId = cAgent.Wearables[n]; |
3457 | UUID assetId = cAgent.Wearables[n + 1]; | 3457 | UUID assetId = cAgent.Wearables[n + 1]; |
3458 | wears[i++] = new AvatarWearable(itemId, assetId); | 3458 | wears[i++] = new AvatarWearable(itemId, assetId); |
3459 | } | 3459 | } |
3460 | m_appearance.Wearables = wears; | 3460 | m_appearance.Wearables = wears; |
3461 | Primitive.TextureEntry te; | 3461 | Primitive.TextureEntry te; |
3462 | if (cAgent.AgentTextures != null && cAgent.AgentTextures.Length > 1) | 3462 | if (cAgent.AgentTextures != null && cAgent.AgentTextures.Length > 1) |
3463 | te = new Primitive.TextureEntry(cAgent.AgentTextures, 0, cAgent.AgentTextures.Length); | 3463 | te = new Primitive.TextureEntry(cAgent.AgentTextures, 0, cAgent.AgentTextures.Length); |
3464 | else | 3464 | else |
3465 | te = AvatarAppearance.GetDefaultTexture(); | 3465 | te = AvatarAppearance.GetDefaultTexture(); |
3466 | if ((cAgent.VisualParams == null) || (cAgent.VisualParams.Length < AvatarAppearance.VISUALPARAM_COUNT)) | 3466 | if ((cAgent.VisualParams == null) || (cAgent.VisualParams.Length < AvatarAppearance.VISUALPARAM_COUNT)) |
3467 | cAgent.VisualParams = AvatarAppearance.GetDefaultVisualParams(); | 3467 | cAgent.VisualParams = AvatarAppearance.GetDefaultVisualParams(); |
3468 | m_appearance.SetAppearance(te, (byte[])cAgent.VisualParams.Clone()); | 3468 | m_appearance.SetAppearance(te, (byte[])cAgent.VisualParams.Clone()); |
3469 | } | 3469 | } |
3470 | catch (Exception e) | 3470 | catch (Exception e) |
3471 | { | 3471 | { |
3472 | m_log.Warn("[SCENE PRESENCE]: exception in CopyFrom " + e.Message); | 3472 | m_log.Warn("[SCENE PRESENCE]: exception in CopyFrom " + e.Message); |
3473 | } | 3473 | } |
3474 | 3474 | ||
3475 | // Attachments | 3475 | // Attachments |
3476 | try | 3476 | try |
3477 | { | 3477 | { |
3478 | if (cAgent.Attachments != null) | 3478 | if (cAgent.Attachments != null) |
3479 | { | 3479 | { |
3480 | m_appearance.ClearAttachments(); | 3480 | m_appearance.ClearAttachments(); |
3481 | foreach (AttachmentData att in cAgent.Attachments) | 3481 | foreach (AttachmentData att in cAgent.Attachments) |
3482 | { | 3482 | { |
3483 | m_appearance.SetAttachment(att.AttachPoint, att.ItemID, att.AssetID); | 3483 | m_appearance.SetAttachment(att.AttachPoint, att.ItemID, att.AssetID); |
3484 | } | 3484 | } |
3485 | } | 3485 | } |
3486 | } | 3486 | } |
3487 | catch { } | 3487 | catch { } |
3488 | 3488 | ||
3489 | try | 3489 | try |
3490 | { | 3490 | { |
3491 | lock (scriptedcontrols) | 3491 | lock (scriptedcontrols) |
3492 | { | 3492 | { |
3493 | if (cAgent.Controllers != null) | 3493 | if (cAgent.Controllers != null) |
3494 | { | 3494 | { |
3495 | scriptedcontrols.Clear(); | 3495 | scriptedcontrols.Clear(); |
3496 | 3496 | ||
3497 | foreach (ControllerData c in cAgent.Controllers) | 3497 | foreach (ControllerData c in cAgent.Controllers) |
3498 | { | 3498 | { |
3499 | ScriptControllers sc = new ScriptControllers(); | 3499 | ScriptControllers sc = new ScriptControllers(); |
3500 | sc.itemID = c.ItemID; | 3500 | sc.itemID = c.ItemID; |
3501 | sc.ignoreControls = (ScriptControlled)c.IgnoreControls; | 3501 | sc.ignoreControls = (ScriptControlled)c.IgnoreControls; |
3502 | sc.eventControls = (ScriptControlled)c.EventControls; | 3502 | sc.eventControls = (ScriptControlled)c.EventControls; |
3503 | 3503 | ||
3504 | scriptedcontrols[sc.itemID] = sc; | 3504 | scriptedcontrols[sc.itemID] = sc; |
3505 | } | 3505 | } |
3506 | } | 3506 | } |
3507 | } | 3507 | } |
3508 | } | 3508 | } |
3509 | catch { } | 3509 | catch { } |
3510 | // Animations | 3510 | // Animations |
3511 | try | 3511 | try |
3512 | { | 3512 | { |
3513 | Animator.ResetAnimations(); | 3513 | Animator.ResetAnimations(); |
3514 | Animator.Animations.FromArray(cAgent.Anims); | 3514 | Animator.Animations.FromArray(cAgent.Anims); |
3515 | } | 3515 | } |
3516 | catch { } | 3516 | catch { } |
3517 | 3517 | ||
3518 | //cAgent.GroupID = ?? | 3518 | //cAgent.GroupID = ?? |
3519 | //Groups??? | 3519 | //Groups??? |
3520 | } | 3520 | } |
3521 | 3521 | ||
3522 | public bool CopyAgent(out IAgentData agent) | 3522 | public bool CopyAgent(out IAgentData agent) |
3523 | { | 3523 | { |
3524 | agent = new CompleteAgentData(); | 3524 | agent = new CompleteAgentData(); |
3525 | CopyTo((AgentData)agent); | 3525 | CopyTo((AgentData)agent); |
3526 | return true; | 3526 | return true; |
3527 | } | 3527 | } |
3528 | 3528 | ||
3529 | #endregion Child Agent Updates | 3529 | #endregion Child Agent Updates |
3530 | 3530 | ||
3531 | /// <summary> | 3531 | /// <summary> |
3532 | /// Handles part of the PID controller function for moving an avatar. | 3532 | /// Handles part of the PID controller function for moving an avatar. |
3533 | /// </summary> | 3533 | /// </summary> |
3534 | public override void UpdateMovement() | 3534 | public override void UpdateMovement() |
3535 | { | 3535 | { |
3536 | if (m_forceToApply.HasValue) | 3536 | if (m_forceToApply.HasValue) |
3537 | { | 3537 | { |
3538 | 3538 | ||
3539 | Vector3 force = m_forceToApply.Value; | 3539 | Vector3 force = m_forceToApply.Value; |
3540 | m_updateflag = true; | 3540 | m_updateflag = true; |
3541 | Velocity = force; | 3541 | Velocity = force; |
3542 | 3542 | ||
3543 | m_forceToApply = null; | 3543 | m_forceToApply = null; |
3544 | } | 3544 | } |
3545 | else | 3545 | else |
3546 | { | 3546 | { |
3547 | if (m_isNudging) | 3547 | if (m_isNudging) |
3548 | { | 3548 | { |
3549 | Vector3 force = Vector3.Zero; | 3549 | Vector3 force = Vector3.Zero; |
3550 | 3550 | ||
3551 | m_updateflag = true; | 3551 | m_updateflag = true; |
3552 | Velocity = force; | 3552 | Velocity = force; |
3553 | m_isNudging = false; | 3553 | m_isNudging = false; |
3554 | m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND" | 3554 | m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND" |
3555 | } | 3555 | } |
3556 | } | 3556 | } |
3557 | } | 3557 | } |
3558 | 3558 | ||
3559 | public override void SetText(string text, Vector3 color, double alpha) | 3559 | public override void SetText(string text, Vector3 color, double alpha) |
3560 | { | 3560 | { |
3561 | throw new Exception("Can't set Text on avatar."); | 3561 | throw new Exception("Can't set Text on avatar."); |
3562 | } | 3562 | } |
3563 | 3563 | ||
3564 | /// <summary> | 3564 | /// <summary> |
3565 | /// Adds a physical representation of the avatar to the Physics plugin | 3565 | /// Adds a physical representation of the avatar to the Physics plugin |
3566 | /// </summary> | 3566 | /// </summary> |
3567 | public void AddToPhysicalScene(bool isFlying) | 3567 | public void AddToPhysicalScene(bool isFlying) |
3568 | { | 3568 | { |
3569 | PhysicsScene scene = m_scene.PhysicsScene; | 3569 | PhysicsScene scene = m_scene.PhysicsScene; |
3570 | 3570 | ||
3571 | Vector3 pVec = AbsolutePosition; | 3571 | Vector3 pVec = AbsolutePosition; |
3572 | 3572 | ||
3573 | // Old bug where the height was in centimeters instead of meters | 3573 | // Old bug where the height was in centimeters instead of meters |
3574 | if (m_avHeight == 127.0f) | 3574 | if (m_avHeight == 127.0f) |
3575 | { | 3575 | { |
3576 | m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, new Vector3(0f, 0f, 1.56f), | 3576 | m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, new Vector3(0f, 0f, 1.56f), |
3577 | isFlying); | 3577 | isFlying); |
3578 | } | 3578 | } |
3579 | else | 3579 | else |
3580 | { | 3580 | { |
3581 | m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, | 3581 | m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, |
3582 | new Vector3(0f, 0f, m_avHeight), isFlying); | 3582 | new Vector3(0f, 0f, m_avHeight), isFlying); |
3583 | } | 3583 | } |
3584 | scene.AddPhysicsActorTaint(m_physicsActor); | 3584 | scene.AddPhysicsActorTaint(m_physicsActor); |
3585 | //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; | 3585 | //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; |
3586 | m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; | 3586 | m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; |
3587 | m_physicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong | 3587 | m_physicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong |
3588 | m_physicsActor.SubscribeEvents(500); | 3588 | m_physicsActor.SubscribeEvents(500); |
3589 | m_physicsActor.LocalID = LocalId; | 3589 | m_physicsActor.LocalID = LocalId; |
3590 | } | 3590 | } |
3591 | 3591 | ||
3592 | private void OutOfBoundsCall(Vector3 pos) | 3592 | private void OutOfBoundsCall(Vector3 pos) |
3593 | { | 3593 | { |
3594 | //bool flying = m_physicsActor.Flying; | 3594 | //bool flying = m_physicsActor.Flying; |
3595 | //RemoveFromPhysicalScene(); | 3595 | //RemoveFromPhysicalScene(); |
3596 | 3596 | ||
3597 | //AddToPhysicalScene(flying); | 3597 | //AddToPhysicalScene(flying); |
3598 | if (ControllingClient != null) | 3598 | if (ControllingClient != null) |
3599 | ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true); | 3599 | ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true); |
3600 | } | 3600 | } |
3601 | 3601 | ||
3602 | // Event called by the physics plugin to tell the avatar about a collision. | 3602 | // Event called by the physics plugin to tell the avatar about a collision. |
3603 | private void PhysicsCollisionUpdate(EventArgs e) | 3603 | private void PhysicsCollisionUpdate(EventArgs e) |
3604 | { | 3604 | { |
3605 | if (e == null) | 3605 | if (e == null) |
3606 | return; | 3606 | return; |
3607 | 3607 | ||
3608 | // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents( | 3608 | // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents( |
3609 | // as of this comment the interval is set in AddToPhysicalScene | 3609 | // as of this comment the interval is set in AddToPhysicalScene |
3610 | if (Animator!=null) | 3610 | if (Animator!=null) |
3611 | { | 3611 | { |
3612 | if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper, | 3612 | if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper, |
3613 | { // else its will lock out other animation changes, like ground sit. | 3613 | { // else its will lock out other animation changes, like ground sit. |
3614 | Animator.UpdateMovementAnimations(); | 3614 | Animator.UpdateMovementAnimations(); |
3615 | m_updateCount--; | 3615 | m_updateCount--; |
3616 | } | 3616 | } |
3617 | } | 3617 | } |
3618 | 3618 | ||
3619 | CollisionEventUpdate collisionData = (CollisionEventUpdate)e; | 3619 | CollisionEventUpdate collisionData = (CollisionEventUpdate)e; |
3620 | Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; | 3620 | Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; |
3621 | 3621 | ||
3622 | CollisionPlane = Vector4.UnitW; | 3622 | CollisionPlane = Vector4.UnitW; |
3623 | 3623 | ||
3624 | if (m_lastColCount != coldata.Count) | 3624 | if (m_lastColCount != coldata.Count) |
3625 | { | 3625 | { |
3626 | m_updateCount = UPDATE_COUNT; | 3626 | m_updateCount = UPDATE_COUNT; |
3627 | m_lastColCount = coldata.Count; | 3627 | m_lastColCount = coldata.Count; |
3628 | } | 3628 | } |
3629 | 3629 | ||
3630 | if (coldata.Count != 0 && Animator != null) | 3630 | if (coldata.Count != 0 && Animator != null) |
3631 | { | 3631 | { |
3632 | switch (Animator.CurrentMovementAnimation) | 3632 | switch (Animator.CurrentMovementAnimation) |
3633 | { | 3633 | { |
3634 | case "STAND": | 3634 | case "STAND": |
3635 | case "WALK": | 3635 | case "WALK": |
3636 | case "RUN": | 3636 | case "RUN": |
3637 | case "CROUCH": | 3637 | case "CROUCH": |
3638 | case "CROUCHWALK": | 3638 | case "CROUCHWALK": |
3639 | { | 3639 | { |
3640 | ContactPoint lowest; | 3640 | ContactPoint lowest; |
3641 | lowest.SurfaceNormal = Vector3.Zero; | 3641 | lowest.SurfaceNormal = Vector3.Zero; |
3642 | lowest.Position = Vector3.Zero; | 3642 | lowest.Position = Vector3.Zero; |
3643 | lowest.Position.Z = Single.NaN; | 3643 | lowest.Position.Z = Single.NaN; |
3644 | 3644 | ||
3645 | foreach (ContactPoint contact in coldata.Values) | 3645 | foreach (ContactPoint contact in coldata.Values) |
3646 | { | 3646 | { |
3647 | if (Single.IsNaN(lowest.Position.Z) || contact.Position.Z < lowest.Position.Z) | 3647 | if (Single.IsNaN(lowest.Position.Z) || contact.Position.Z < lowest.Position.Z) |
3648 | { | 3648 | { |
3649 | lowest = contact; | 3649 | lowest = contact; |
3650 | } | 3650 | } |
3651 | } | 3651 | } |
3652 | 3652 | ||
3653 | CollisionPlane = new Vector4(-lowest.SurfaceNormal, -Vector3.Dot(lowest.Position, lowest.SurfaceNormal)); | 3653 | CollisionPlane = new Vector4(-lowest.SurfaceNormal, -Vector3.Dot(lowest.Position, lowest.SurfaceNormal)); |
3654 | } | 3654 | } |
3655 | break; | 3655 | break; |
3656 | } | 3656 | } |
3657 | } | 3657 | } |
3658 | 3658 | ||
3659 | List<uint> thisHitColliders = new List<uint>(); | 3659 | List<uint> thisHitColliders = new List<uint>(); |
3660 | List<uint> endedColliders = new List<uint>(); | 3660 | List<uint> endedColliders = new List<uint>(); |
3661 | List<uint> startedColliders = new List<uint>(); | 3661 | List<uint> startedColliders = new List<uint>(); |
3662 | 3662 | ||
3663 | foreach (uint localid in coldata.Keys) | 3663 | foreach (uint localid in coldata.Keys) |
3664 | { | 3664 | { |
3665 | thisHitColliders.Add(localid); | 3665 | thisHitColliders.Add(localid); |
3666 | if (!m_lastColliders.Contains(localid)) | 3666 | if (!m_lastColliders.Contains(localid)) |
3667 | { | 3667 | { |
3668 | startedColliders.Add(localid); | 3668 | startedColliders.Add(localid); |
3669 | } | 3669 | } |
3670 | //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString()); | 3670 | //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString()); |
3671 | } | 3671 | } |
3672 | 3672 | ||
3673 | // calculate things that ended colliding | 3673 | // calculate things that ended colliding |
3674 | foreach (uint localID in m_lastColliders) | 3674 | foreach (uint localID in m_lastColliders) |
3675 | { | 3675 | { |
3676 | if (!thisHitColliders.Contains(localID)) | 3676 | if (!thisHitColliders.Contains(localID)) |
3677 | { | 3677 | { |
3678 | endedColliders.Add(localID); | 3678 | endedColliders.Add(localID); |
3679 | } | 3679 | } |
3680 | } | 3680 | } |
3681 | //add the items that started colliding this time to the last colliders list. | 3681 | //add the items that started colliding this time to the last colliders list. |
3682 | foreach (uint localID in startedColliders) | 3682 | foreach (uint localID in startedColliders) |
3683 | { | 3683 | { |
3684 | m_lastColliders.Add(localID); | 3684 | m_lastColliders.Add(localID); |
3685 | } | 3685 | } |
3686 | // remove things that ended colliding from the last colliders list | 3686 | // remove things that ended colliding from the last colliders list |
3687 | foreach (uint localID in endedColliders) | 3687 | foreach (uint localID in endedColliders) |
3688 | { | 3688 | { |
3689 | m_lastColliders.Remove(localID); | 3689 | m_lastColliders.Remove(localID); |
3690 | } | 3690 | } |
3691 | 3691 | ||
3692 | // do event notification | 3692 | // do event notification |
3693 | if (startedColliders.Count > 0) | 3693 | if (startedColliders.Count > 0) |
3694 | { | 3694 | { |
3695 | ColliderArgs StartCollidingMessage = new ColliderArgs(); | 3695 | ColliderArgs StartCollidingMessage = new ColliderArgs(); |
3696 | List<DetectedObject> colliding = new List<DetectedObject>(); | 3696 | List<DetectedObject> colliding = new List<DetectedObject>(); |
3697 | foreach (uint localId in startedColliders) | 3697 | foreach (uint localId in startedColliders) |
3698 | { | 3698 | { |
3699 | if (localId == 0) | 3699 | if (localId == 0) |
3700 | continue; | 3700 | continue; |
3701 | 3701 | ||
3702 | SceneObjectPart obj = Scene.GetSceneObjectPart(localId); | 3702 | SceneObjectPart obj = Scene.GetSceneObjectPart(localId); |
3703 | string data = ""; | 3703 | string data = ""; |
3704 | if (obj != null) | 3704 | if (obj != null) |
3705 | { | 3705 | { |
3706 | DetectedObject detobj = new DetectedObject(); | 3706 | DetectedObject detobj = new DetectedObject(); |
3707 | detobj.keyUUID = obj.UUID; | 3707 | detobj.keyUUID = obj.UUID; |
3708 | detobj.nameStr = obj.Name; | 3708 | detobj.nameStr = obj.Name; |
3709 | detobj.ownerUUID = obj.OwnerID; | 3709 | detobj.ownerUUID = obj.OwnerID; |
3710 | detobj.posVector = obj.AbsolutePosition; | 3710 | detobj.posVector = obj.AbsolutePosition; |
3711 | detobj.rotQuat = obj.GetWorldRotation(); | 3711 | detobj.rotQuat = obj.GetWorldRotation(); |
3712 | detobj.velVector = obj.Velocity; | 3712 | detobj.velVector = obj.Velocity; |
3713 | detobj.colliderType = 0; | 3713 | detobj.colliderType = 0; |
3714 | detobj.groupUUID = obj.GroupID; | 3714 | detobj.groupUUID = obj.GroupID; |
3715 | colliding.Add(detobj); | 3715 | colliding.Add(detobj); |
3716 | } | 3716 | } |
3717 | } | 3717 | } |
3718 | 3718 | ||
3719 | if (colliding.Count > 0) | 3719 | if (colliding.Count > 0) |
3720 | { | 3720 | { |
3721 | StartCollidingMessage.Colliders = colliding; | 3721 | StartCollidingMessage.Colliders = colliding; |
3722 | 3722 | ||
3723 | foreach (SceneObjectGroup att in Attachments) | 3723 | foreach (SceneObjectGroup att in Attachments) |
3724 | Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage); | 3724 | Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage); |
3725 | } | 3725 | } |
3726 | } | 3726 | } |
3727 | 3727 | ||
3728 | if (endedColliders.Count > 0) | 3728 | if (endedColliders.Count > 0) |
3729 | { | 3729 | { |
3730 | ColliderArgs EndCollidingMessage = new ColliderArgs(); | 3730 | ColliderArgs EndCollidingMessage = new ColliderArgs(); |
3731 | List<DetectedObject> colliding = new List<DetectedObject>(); | 3731 | List<DetectedObject> colliding = new List<DetectedObject>(); |
3732 | foreach (uint localId in endedColliders) | 3732 | foreach (uint localId in endedColliders) |
3733 | { | 3733 | { |
3734 | if (localId == 0) | 3734 | if (localId == 0) |
3735 | continue; | 3735 | continue; |
3736 | 3736 | ||
3737 | SceneObjectPart obj = Scene.GetSceneObjectPart(localId); | 3737 | SceneObjectPart obj = Scene.GetSceneObjectPart(localId); |
3738 | string data = ""; | 3738 | string data = ""; |
3739 | if (obj != null) | 3739 | if (obj != null) |
3740 | { | 3740 | { |
3741 | DetectedObject detobj = new DetectedObject(); | 3741 | DetectedObject detobj = new DetectedObject(); |
3742 | detobj.keyUUID = obj.UUID; | 3742 | detobj.keyUUID = obj.UUID; |
3743 | detobj.nameStr = obj.Name; | 3743 | detobj.nameStr = obj.Name; |
3744 | detobj.ownerUUID = obj.OwnerID; | 3744 | detobj.ownerUUID = obj.OwnerID; |
3745 | detobj.posVector = obj.AbsolutePosition; | 3745 | detobj.posVector = obj.AbsolutePosition; |
3746 | detobj.rotQuat = obj.GetWorldRotation(); | 3746 | detobj.rotQuat = obj.GetWorldRotation(); |
3747 | detobj.velVector = obj.Velocity; | 3747 | detobj.velVector = obj.Velocity; |
3748 | detobj.colliderType = 0; | 3748 | detobj.colliderType = 0; |
3749 | detobj.groupUUID = obj.GroupID; | 3749 | detobj.groupUUID = obj.GroupID; |
3750 | colliding.Add(detobj); | 3750 | colliding.Add(detobj); |
3751 | } | 3751 | } |
3752 | } | 3752 | } |
3753 | 3753 | ||
3754 | if (colliding.Count > 0) | 3754 | if (colliding.Count > 0) |
3755 | { | 3755 | { |
3756 | EndCollidingMessage.Colliders = colliding; | 3756 | EndCollidingMessage.Colliders = colliding; |
3757 | 3757 | ||
3758 | foreach (SceneObjectGroup att in Attachments) | 3758 | foreach (SceneObjectGroup att in Attachments) |
3759 | Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage); | 3759 | Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage); |
3760 | } | 3760 | } |
3761 | } | 3761 | } |
3762 | 3762 | ||
3763 | if (thisHitColliders.Count > 0) | 3763 | if (thisHitColliders.Count > 0) |
3764 | { | 3764 | { |
3765 | ColliderArgs CollidingMessage = new ColliderArgs(); | 3765 | ColliderArgs CollidingMessage = new ColliderArgs(); |
3766 | List<DetectedObject> colliding = new List<DetectedObject>(); | 3766 | List<DetectedObject> colliding = new List<DetectedObject>(); |
3767 | foreach (uint localId in thisHitColliders) | 3767 | foreach (uint localId in thisHitColliders) |
3768 | { | 3768 | { |
3769 | if (localId == 0) | 3769 | if (localId == 0) |
3770 | continue; | 3770 | continue; |
3771 | 3771 | ||
3772 | SceneObjectPart obj = Scene.GetSceneObjectPart(localId); | 3772 | SceneObjectPart obj = Scene.GetSceneObjectPart(localId); |
3773 | string data = ""; | 3773 | string data = ""; |
3774 | if (obj != null) | 3774 | if (obj != null) |
3775 | { | 3775 | { |
3776 | DetectedObject detobj = new DetectedObject(); | 3776 | DetectedObject detobj = new DetectedObject(); |
3777 | detobj.keyUUID = obj.UUID; | 3777 | detobj.keyUUID = obj.UUID; |
3778 | detobj.nameStr = obj.Name; | 3778 | detobj.nameStr = obj.Name; |
3779 | detobj.ownerUUID = obj.OwnerID; | 3779 | detobj.ownerUUID = obj.OwnerID; |
3780 | detobj.posVector = obj.AbsolutePosition; | 3780 | detobj.posVector = obj.AbsolutePosition; |
3781 | detobj.rotQuat = obj.GetWorldRotation(); | 3781 | detobj.rotQuat = obj.GetWorldRotation(); |
3782 | detobj.velVector = obj.Velocity; | 3782 | detobj.velVector = obj.Velocity; |
3783 | detobj.colliderType = 0; | 3783 | detobj.colliderType = 0; |
3784 | detobj.groupUUID = obj.GroupID; | 3784 | detobj.groupUUID = obj.GroupID; |
3785 | colliding.Add(detobj); | 3785 | colliding.Add(detobj); |
3786 | } | 3786 | } |
3787 | } | 3787 | } |
3788 | 3788 | ||
3789 | if (colliding.Count > 0) | 3789 | if (colliding.Count > 0) |
3790 | { | 3790 | { |
3791 | CollidingMessage.Colliders = colliding; | 3791 | CollidingMessage.Colliders = colliding; |
3792 | 3792 | ||
3793 | lock (m_attachments) | 3793 | lock (m_attachments) |
3794 | { | 3794 | { |
3795 | foreach (SceneObjectGroup att in m_attachments) | 3795 | foreach (SceneObjectGroup att in m_attachments) |
3796 | Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage); | 3796 | Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage); |
3797 | } | 3797 | } |
3798 | } | 3798 | } |
3799 | } | 3799 | } |
3800 | 3800 | ||
3801 | if (m_invulnerable) | 3801 | if (m_invulnerable) |
3802 | return; | 3802 | return; |
3803 | 3803 | ||
3804 | float starthealth = Health; | 3804 | float starthealth = Health; |
3805 | uint killerObj = 0; | 3805 | uint killerObj = 0; |
3806 | foreach (uint localid in coldata.Keys) | 3806 | foreach (uint localid in coldata.Keys) |
3807 | { | 3807 | { |
3808 | SceneObjectPart part = Scene.GetSceneObjectPart(localid); | 3808 | SceneObjectPart part = Scene.GetSceneObjectPart(localid); |
3809 | 3809 | ||
3810 | if (part != null && part.ParentGroup.Damage != -1.0f) | 3810 | if (part != null && part.ParentGroup.Damage != -1.0f) |
3811 | Health -= part.ParentGroup.Damage; | 3811 | Health -= part.ParentGroup.Damage; |
3812 | else | 3812 | else |
3813 | { | 3813 | { |
3814 | if (coldata[localid].PenetrationDepth >= 0.10f) | 3814 | if (coldata[localid].PenetrationDepth >= 0.10f) |
3815 | Health -= coldata[localid].PenetrationDepth * 5.0f; | 3815 | Health -= coldata[localid].PenetrationDepth * 5.0f; |
3816 | } | 3816 | } |
3817 | 3817 | ||
3818 | if (Health <= 0.0f) | 3818 | if (Health <= 0.0f) |
3819 | { | 3819 | { |
3820 | if (localid != 0) | 3820 | if (localid != 0) |
3821 | killerObj = localid; | 3821 | killerObj = localid; |
3822 | } | 3822 | } |
3823 | //m_log.Debug("[AVATAR]: Collision with localid: " + localid.ToString() + " at depth: " + coldata[localid].ToString()); | 3823 | //m_log.Debug("[AVATAR]: Collision with localid: " + localid.ToString() + " at depth: " + coldata[localid].ToString()); |
3824 | } | 3824 | } |
3825 | //Health = 100; | 3825 | //Health = 100; |
3826 | if (!m_invulnerable) | 3826 | if (!m_invulnerable) |
3827 | { | 3827 | { |
3828 | if (starthealth != Health) | 3828 | if (starthealth != Health) |
3829 | { | 3829 | { |
3830 | ControllingClient.SendHealth(Health); | 3830 | ControllingClient.SendHealth(Health); |
3831 | } | 3831 | } |
3832 | if (m_health <= 0) | 3832 | if (m_health <= 0) |
3833 | m_scene.EventManager.TriggerAvatarKill(killerObj, this); | 3833 | m_scene.EventManager.TriggerAvatarKill(killerObj, this); |
3834 | } | 3834 | } |
3835 | } | 3835 | } |
3836 | 3836 | ||
3837 | public void setHealthWithUpdate(float health) | 3837 | public void setHealthWithUpdate(float health) |
3838 | { | 3838 | { |
3839 | Health = health; | 3839 | Health = health; |
3840 | ControllingClient.SendHealth(Health); | 3840 | ControllingClient.SendHealth(Health); |
3841 | } | 3841 | } |
3842 | 3842 | ||
3843 | public void Close() | 3843 | public void Close() |
3844 | { | 3844 | { |
3845 | lock (m_attachments) | 3845 | lock (m_attachments) |
3846 | { | 3846 | { |
3847 | // Delete attachments from scene | 3847 | // Delete attachments from scene |
3848 | // Don't try to save, as this thread won't live long | 3848 | // Don't try to save, as this thread won't live long |
3849 | // enough to complete the save. This would cause no copy | 3849 | // enough to complete the save. This would cause no copy |
3850 | // attachments to poof! | 3850 | // attachments to poof! |
3851 | // | 3851 | // |
3852 | foreach (SceneObjectGroup grp in m_attachments) | 3852 | foreach (SceneObjectGroup grp in m_attachments) |
3853 | { | 3853 | { |
3854 | m_scene.DeleteSceneObject(grp, false); | 3854 | m_scene.DeleteSceneObject(grp, false); |
3855 | } | 3855 | } |
3856 | m_attachments.Clear(); | 3856 | m_attachments.Clear(); |
3857 | } | 3857 | } |
3858 | 3858 | ||
3859 | lock (m_knownChildRegions) | 3859 | lock (m_knownChildRegions) |
3860 | { | 3860 | { |
3861 | m_knownChildRegions.Clear(); | 3861 | m_knownChildRegions.Clear(); |
3862 | } | 3862 | } |
3863 | 3863 | ||
3864 | lock (m_reprioritization_timer) | 3864 | lock (m_reprioritization_timer) |
3865 | { | 3865 | { |
3866 | m_reprioritization_timer.Enabled = false; | 3866 | m_reprioritization_timer.Enabled = false; |
3867 | m_reprioritization_timer.Elapsed -= new ElapsedEventHandler(Reprioritize); | 3867 | m_reprioritization_timer.Elapsed -= new ElapsedEventHandler(Reprioritize); |
3868 | } | 3868 | } |
3869 | 3869 | ||
3870 | // I don't get it but mono crashes when you try to dispose of this timer, | 3870 | // I don't get it but mono crashes when you try to dispose of this timer, |
3871 | // unsetting the elapsed callback should be enough to allow for cleanup however. | 3871 | // unsetting the elapsed callback should be enough to allow for cleanup however. |
3872 | // m_reprioritizationTimer.Dispose(); | 3872 | // m_reprioritizationTimer.Dispose(); |
3873 | 3873 | ||
3874 | m_sceneViewer.Close(); | 3874 | m_sceneViewer.Close(); |
3875 | 3875 | ||
3876 | RemoveFromPhysicalScene(); | 3876 | RemoveFromPhysicalScene(); |
3877 | m_animator.Close(); | 3877 | m_animator.Close(); |
3878 | m_animator = null; | 3878 | m_animator = null; |
3879 | } | 3879 | } |
3880 | 3880 | ||
3881 | public void AddAttachment(SceneObjectGroup gobj) | 3881 | public void AddAttachment(SceneObjectGroup gobj) |
3882 | { | 3882 | { |
3883 | lock (m_attachments) | 3883 | lock (m_attachments) |
3884 | { | 3884 | { |
3885 | m_attachments.Add(gobj); | 3885 | m_attachments.Add(gobj); |
3886 | } | 3886 | } |
3887 | } | 3887 | } |
3888 | 3888 | ||
3889 | public bool HasAttachments() | 3889 | public bool HasAttachments() |
3890 | { | 3890 | { |
3891 | return m_attachments.Count > 0; | 3891 | return m_attachments.Count > 0; |
3892 | } | 3892 | } |
3893 | 3893 | ||
3894 | public bool HasScriptedAttachments() | 3894 | public bool HasScriptedAttachments() |
3895 | { | 3895 | { |
3896 | lock (m_attachments) | 3896 | lock (m_attachments) |
3897 | { | 3897 | { |
3898 | foreach (SceneObjectGroup gobj in m_attachments) | 3898 | foreach (SceneObjectGroup gobj in m_attachments) |
3899 | { | 3899 | { |
3900 | if (gobj != null) | 3900 | if (gobj != null) |
3901 | { | 3901 | { |
3902 | if (gobj.RootPart.Inventory.ContainsScripts()) | 3902 | if (gobj.RootPart.Inventory.ContainsScripts()) |
3903 | return true; | 3903 | return true; |
3904 | } | 3904 | } |
3905 | } | 3905 | } |
3906 | } | 3906 | } |
3907 | return false; | 3907 | return false; |
3908 | } | 3908 | } |
3909 | 3909 | ||
3910 | public void RemoveAttachment(SceneObjectGroup gobj) | 3910 | public void RemoveAttachment(SceneObjectGroup gobj) |
3911 | { | 3911 | { |
3912 | lock (m_attachments) | 3912 | lock (m_attachments) |
3913 | { | 3913 | { |
3914 | if (m_attachments.Contains(gobj)) | 3914 | if (m_attachments.Contains(gobj)) |
3915 | { | 3915 | { |
3916 | m_attachments.Remove(gobj); | 3916 | m_attachments.Remove(gobj); |
3917 | } | 3917 | } |
3918 | } | 3918 | } |
3919 | } | 3919 | } |
3920 | 3920 | ||
3921 | public bool ValidateAttachments() | 3921 | public bool ValidateAttachments() |
3922 | { | 3922 | { |
3923 | lock (m_attachments) | 3923 | lock (m_attachments) |
3924 | { | 3924 | { |
3925 | // Validate | 3925 | // Validate |
3926 | foreach (SceneObjectGroup gobj in m_attachments) | 3926 | foreach (SceneObjectGroup gobj in m_attachments) |
3927 | { | 3927 | { |
3928 | if (gobj == null) | 3928 | if (gobj == null) |
3929 | return false; | 3929 | return false; |
3930 | 3930 | ||
3931 | if (gobj.IsDeleted) | 3931 | if (gobj.IsDeleted) |
3932 | return false; | 3932 | return false; |
3933 | } | 3933 | } |
3934 | } | 3934 | } |
3935 | return true; | 3935 | return true; |
3936 | } | 3936 | } |
3937 | 3937 | ||
3938 | /// <summary> | 3938 | /// <summary> |
3939 | /// Send a script event to this scene presence's attachments | 3939 | /// Send a script event to this scene presence's attachments |
3940 | /// </summary> | 3940 | /// </summary> |
3941 | /// <param name="eventName">The name of the event</param> | 3941 | /// <param name="eventName">The name of the event</param> |
3942 | /// <param name="args">The arguments for the event</param> | 3942 | /// <param name="args">The arguments for the event</param> |
3943 | public void SendScriptEventToAttachments(string eventName, Object[] args) | 3943 | public void SendScriptEventToAttachments(string eventName, Object[] args) |
3944 | { | 3944 | { |
3945 | if (m_scriptEngines != null) | 3945 | if (m_scriptEngines != null) |
3946 | { | 3946 | { |
3947 | lock (m_attachments) | 3947 | lock (m_attachments) |
3948 | { | 3948 | { |
3949 | foreach (SceneObjectGroup grp in m_attachments) | 3949 | foreach (SceneObjectGroup grp in m_attachments) |
3950 | { | 3950 | { |
3951 | // 16384 is CHANGED_ANIMATION | 3951 | // 16384 is CHANGED_ANIMATION |
3952 | // | 3952 | // |
3953 | // Send this to all attachment root prims | 3953 | // Send this to all attachment root prims |
3954 | // | 3954 | // |
3955 | foreach (IScriptModule m in m_scriptEngines) | 3955 | foreach (IScriptModule m in m_scriptEngines) |
3956 | { | 3956 | { |
3957 | if (m == null) // No script engine loaded | 3957 | if (m == null) // No script engine loaded |
3958 | continue; | 3958 | continue; |
3959 | 3959 | ||
3960 | m.PostObjectEvent(grp.RootPart.UUID, "changed", new Object[] { (int)Changed.ANIMATION }); | 3960 | m.PostObjectEvent(grp.RootPart.UUID, "changed", new Object[] { (int)Changed.ANIMATION }); |
3961 | } | 3961 | } |
3962 | } | 3962 | } |
3963 | } | 3963 | } |
3964 | } | 3964 | } |
3965 | } | 3965 | } |
3966 | 3966 | ||
3967 | 3967 | ||
3968 | public void initializeScenePresence(IClientAPI client, RegionInfo region, Scene scene) | 3968 | public void initializeScenePresence(IClientAPI client, RegionInfo region, Scene scene) |
3969 | { | 3969 | { |
3970 | m_controllingClient = client; | 3970 | m_controllingClient = client; |
3971 | m_regionInfo = region; | 3971 | m_regionInfo = region; |
3972 | m_scene = scene; | 3972 | m_scene = scene; |
3973 | 3973 | ||
3974 | RegisterToEvents(); | 3974 | RegisterToEvents(); |
3975 | if (m_controllingClient != null) | 3975 | if (m_controllingClient != null) |
3976 | { | 3976 | { |
3977 | m_controllingClient.ProcessPendingPackets(); | 3977 | m_controllingClient.ProcessPendingPackets(); |
3978 | } | 3978 | } |
3979 | /* | 3979 | /* |
3980 | AbsolutePosition = client.StartPos; | 3980 | AbsolutePosition = client.StartPos; |
3981 | 3981 | ||
3982 | Animations = new AvatarAnimations(); | 3982 | Animations = new AvatarAnimations(); |
3983 | Animations.LoadAnims(); | 3983 | Animations.LoadAnims(); |
3984 | 3984 | ||
3985 | m_animations = new List<UUID>(); | 3985 | m_animations = new List<UUID>(); |
3986 | m_animations.Add(Animations.AnimsUUID["STAND"]); | 3986 | m_animations.Add(Animations.AnimsUUID["STAND"]); |
3987 | m_animationSeqs.Add(m_controllingClient.NextAnimationSequenceNumber); | 3987 | m_animationSeqs.Add(m_controllingClient.NextAnimationSequenceNumber); |
3988 | 3988 | ||
3989 | SetDirectionVectors(); | 3989 | SetDirectionVectors(); |
3990 | */ | 3990 | */ |
3991 | } | 3991 | } |
3992 | 3992 | ||
3993 | internal void PushForce(Vector3 impulse) | 3993 | internal void PushForce(Vector3 impulse) |
3994 | { | 3994 | { |
3995 | if (PhysicsActor != null) | 3995 | if (PhysicsActor != null) |
3996 | { | 3996 | { |
3997 | PhysicsActor.AddForce(impulse,true); | 3997 | PhysicsActor.AddForce(impulse,true); |
3998 | } | 3998 | } |
3999 | } | 3999 | } |
4000 | 4000 | ||
4001 | public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID) | 4001 | public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID) |
4002 | { | 4002 | { |
4003 | ScriptControllers obj = new ScriptControllers(); | 4003 | ScriptControllers obj = new ScriptControllers(); |
4004 | obj.ignoreControls = ScriptControlled.CONTROL_ZERO; | 4004 | obj.ignoreControls = ScriptControlled.CONTROL_ZERO; |
4005 | obj.eventControls = ScriptControlled.CONTROL_ZERO; | 4005 | obj.eventControls = ScriptControlled.CONTROL_ZERO; |
4006 | 4006 | ||
4007 | obj.itemID = Script_item_UUID; | 4007 | obj.itemID = Script_item_UUID; |
4008 | if (pass_on == 0 && accept == 0) | 4008 | if (pass_on == 0 && accept == 0) |
4009 | { | 4009 | { |
4010 | IgnoredControls |= (ScriptControlled)controls; | 4010 | IgnoredControls |= (ScriptControlled)controls; |
4011 | obj.ignoreControls = (ScriptControlled)controls; | 4011 | obj.ignoreControls = (ScriptControlled)controls; |
4012 | } | 4012 | } |
4013 | 4013 | ||
4014 | if (pass_on == 0 && accept == 1) | 4014 | if (pass_on == 0 && accept == 1) |
4015 | { | 4015 | { |
4016 | IgnoredControls |= (ScriptControlled)controls; | 4016 | IgnoredControls |= (ScriptControlled)controls; |
4017 | obj.ignoreControls = (ScriptControlled)controls; | 4017 | obj.ignoreControls = (ScriptControlled)controls; |
4018 | obj.eventControls = (ScriptControlled)controls; | 4018 | obj.eventControls = (ScriptControlled)controls; |
4019 | } | 4019 | } |
4020 | if (pass_on == 1 && accept == 1) | 4020 | if (pass_on == 1 && accept == 1) |
4021 | { | 4021 | { |
4022 | IgnoredControls = ScriptControlled.CONTROL_ZERO; | 4022 | IgnoredControls = ScriptControlled.CONTROL_ZERO; |
4023 | obj.eventControls = (ScriptControlled)controls; | 4023 | obj.eventControls = (ScriptControlled)controls; |
4024 | obj.ignoreControls = ScriptControlled.CONTROL_ZERO; | 4024 | obj.ignoreControls = ScriptControlled.CONTROL_ZERO; |
4025 | } | 4025 | } |
4026 | 4026 | ||
4027 | lock (scriptedcontrols) | 4027 | lock (scriptedcontrols) |
4028 | { | 4028 | { |
4029 | if (pass_on == 1 && accept == 0) | 4029 | if (pass_on == 1 && accept == 0) |
4030 | { | 4030 | { |
4031 | IgnoredControls &= ~(ScriptControlled)controls; | 4031 | IgnoredControls &= ~(ScriptControlled)controls; |
4032 | if (scriptedcontrols.ContainsKey(Script_item_UUID)) | 4032 | if (scriptedcontrols.ContainsKey(Script_item_UUID)) |
4033 | scriptedcontrols.Remove(Script_item_UUID); | 4033 | scriptedcontrols.Remove(Script_item_UUID); |
4034 | } | 4034 | } |
4035 | else | 4035 | else |
4036 | { | 4036 | { |
4037 | scriptedcontrols[Script_item_UUID] = obj; | 4037 | scriptedcontrols[Script_item_UUID] = obj; |
4038 | } | 4038 | } |
4039 | } | 4039 | } |
4040 | ControllingClient.SendTakeControls(controls, pass_on == 1 ? true : false, true); | 4040 | ControllingClient.SendTakeControls(controls, pass_on == 1 ? true : false, true); |
4041 | } | 4041 | } |
4042 | 4042 | ||
4043 | public void HandleForceReleaseControls(IClientAPI remoteClient, UUID agentID) | 4043 | public void HandleForceReleaseControls(IClientAPI remoteClient, UUID agentID) |
4044 | { | 4044 | { |
4045 | IgnoredControls = ScriptControlled.CONTROL_ZERO; | 4045 | IgnoredControls = ScriptControlled.CONTROL_ZERO; |
4046 | lock (scriptedcontrols) | 4046 | lock (scriptedcontrols) |
4047 | { | 4047 | { |
4048 | scriptedcontrols.Clear(); | 4048 | scriptedcontrols.Clear(); |
4049 | } | 4049 | } |
4050 | ControllingClient.SendTakeControls(int.MaxValue, false, false); | 4050 | ControllingClient.SendTakeControls(int.MaxValue, false, false); |
4051 | } | 4051 | } |
4052 | 4052 | ||
4053 | public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) | 4053 | public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) |
4054 | { | 4054 | { |
4055 | ScriptControllers takecontrols; | 4055 | ScriptControllers takecontrols; |
4056 | 4056 | ||
4057 | lock (scriptedcontrols) | 4057 | lock (scriptedcontrols) |
4058 | { | 4058 | { |
4059 | if (scriptedcontrols.TryGetValue(Script_item_UUID, out takecontrols)) | 4059 | if (scriptedcontrols.TryGetValue(Script_item_UUID, out takecontrols)) |
4060 | { | 4060 | { |
4061 | ScriptControlled sctc = takecontrols.eventControls; | 4061 | ScriptControlled sctc = takecontrols.eventControls; |
4062 | 4062 | ||
4063 | ControllingClient.SendTakeControls((int)sctc, false, false); | 4063 | ControllingClient.SendTakeControls((int)sctc, false, false); |
4064 | ControllingClient.SendTakeControls((int)sctc, true, false); | 4064 | ControllingClient.SendTakeControls((int)sctc, true, false); |
4065 | 4065 | ||
4066 | scriptedcontrols.Remove(Script_item_UUID); | 4066 | scriptedcontrols.Remove(Script_item_UUID); |
4067 | IgnoredControls = ScriptControlled.CONTROL_ZERO; | 4067 | IgnoredControls = ScriptControlled.CONTROL_ZERO; |
4068 | foreach (ScriptControllers scData in scriptedcontrols.Values) | 4068 | foreach (ScriptControllers scData in scriptedcontrols.Values) |
4069 | { | 4069 | { |
4070 | IgnoredControls |= scData.ignoreControls; | 4070 | IgnoredControls |= scData.ignoreControls; |
4071 | } | 4071 | } |
4072 | } | 4072 | } |
4073 | } | 4073 | } |
4074 | } | 4074 | } |
4075 | 4075 | ||
4076 | internal void SendControlToScripts(uint flags) | 4076 | internal void SendControlToScripts(uint flags) |
4077 | { | 4077 | { |
4078 | ScriptControlled allflags = ScriptControlled.CONTROL_ZERO; | 4078 | ScriptControlled allflags = ScriptControlled.CONTROL_ZERO; |
4079 | 4079 | ||
4080 | if (MouseDown) | 4080 | if (MouseDown) |
4081 | { | 4081 | { |
4082 | allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON); | 4082 | allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON); |
4083 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 || (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0) | 4083 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 || (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0) |
4084 | { | 4084 | { |
4085 | allflags = ScriptControlled.CONTROL_ZERO; | 4085 | allflags = ScriptControlled.CONTROL_ZERO; |
4086 | MouseDown = true; | 4086 | MouseDown = true; |
4087 | } | 4087 | } |
4088 | } | 4088 | } |
4089 | 4089 | ||
4090 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0) | 4090 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0) |
4091 | { | 4091 | { |
4092 | allflags |= ScriptControlled.CONTROL_ML_LBUTTON; | 4092 | allflags |= ScriptControlled.CONTROL_ML_LBUTTON; |
4093 | MouseDown = true; | 4093 | MouseDown = true; |
4094 | } | 4094 | } |
4095 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0) | 4095 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0) |
4096 | { | 4096 | { |
4097 | allflags |= ScriptControlled.CONTROL_LBUTTON; | 4097 | allflags |= ScriptControlled.CONTROL_LBUTTON; |
4098 | MouseDown = true; | 4098 | MouseDown = true; |
4099 | } | 4099 | } |
4100 | 4100 | ||
4101 | // find all activated controls, whether the scripts are interested in them or not | 4101 | // find all activated controls, whether the scripts are interested in them or not |
4102 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) != 0) | 4102 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) != 0) |
4103 | { | 4103 | { |
4104 | allflags |= ScriptControlled.CONTROL_FWD; | 4104 | allflags |= ScriptControlled.CONTROL_FWD; |
4105 | } | 4105 | } |
4106 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) != 0) | 4106 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) != 0) |
4107 | { | 4107 | { |
4108 | allflags |= ScriptControlled.CONTROL_BACK; | 4108 | allflags |= ScriptControlled.CONTROL_BACK; |
4109 | } | 4109 | } |
4110 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS) != 0) | 4110 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS) != 0) |
4111 | { | 4111 | { |
4112 | allflags |= ScriptControlled.CONTROL_UP; | 4112 | allflags |= ScriptControlled.CONTROL_UP; |
4113 | } | 4113 | } |
4114 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0) | 4114 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0) |
4115 | { | 4115 | { |
4116 | allflags |= ScriptControlled.CONTROL_DOWN; | 4116 | allflags |= ScriptControlled.CONTROL_DOWN; |
4117 | } | 4117 | } |
4118 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) != 0) | 4118 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) != 0) |
4119 | { | 4119 | { |
4120 | allflags |= ScriptControlled.CONTROL_LEFT; | 4120 | allflags |= ScriptControlled.CONTROL_LEFT; |
4121 | } | 4121 | } |
4122 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) != 0) | 4122 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) != 0) |
4123 | { | 4123 | { |
4124 | allflags |= ScriptControlled.CONTROL_RIGHT; | 4124 | allflags |= ScriptControlled.CONTROL_RIGHT; |
4125 | } | 4125 | } |
4126 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0) | 4126 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0) |
4127 | { | 4127 | { |
4128 | allflags |= ScriptControlled.CONTROL_ROT_RIGHT; | 4128 | allflags |= ScriptControlled.CONTROL_ROT_RIGHT; |
4129 | } | 4129 | } |
4130 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0) | 4130 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0) |
4131 | { | 4131 | { |
4132 | allflags |= ScriptControlled.CONTROL_ROT_LEFT; | 4132 | allflags |= ScriptControlled.CONTROL_ROT_LEFT; |
4133 | } | 4133 | } |
4134 | // optimization; we have to check per script, but if nothing is pressed and nothing changed, we can skip that | 4134 | // optimization; we have to check per script, but if nothing is pressed and nothing changed, we can skip that |
4135 | if (allflags != ScriptControlled.CONTROL_ZERO || allflags != LastCommands) | 4135 | if (allflags != ScriptControlled.CONTROL_ZERO || allflags != LastCommands) |
4136 | { | 4136 | { |
4137 | lock (scriptedcontrols) | 4137 | lock (scriptedcontrols) |
4138 | { | 4138 | { |
4139 | foreach (KeyValuePair<UUID, ScriptControllers> kvp in scriptedcontrols) | 4139 | foreach (KeyValuePair<UUID, ScriptControllers> kvp in scriptedcontrols) |
4140 | { | 4140 | { |
4141 | UUID scriptUUID = kvp.Key; | 4141 | UUID scriptUUID = kvp.Key; |
4142 | ScriptControllers scriptControlData = kvp.Value; | 4142 | ScriptControllers scriptControlData = kvp.Value; |
4143 | 4143 | ||
4144 | ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us | 4144 | ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us |
4145 | ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle | 4145 | ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle |
4146 | ScriptControlled localChange = localHeld ^ localLast; // the changed bits | 4146 | ScriptControlled localChange = localHeld ^ localLast; // the changed bits |
4147 | if (localHeld != ScriptControlled.CONTROL_ZERO || localChange != ScriptControlled.CONTROL_ZERO) | 4147 | if (localHeld != ScriptControlled.CONTROL_ZERO || localChange != ScriptControlled.CONTROL_ZERO) |
4148 | { | 4148 | { |
4149 | // only send if still pressed or just changed | 4149 | // only send if still pressed or just changed |
4150 | m_scene.EventManager.TriggerControlEvent(scriptUUID, UUID, (uint)localHeld, (uint)localChange); | 4150 | m_scene.EventManager.TriggerControlEvent(scriptUUID, UUID, (uint)localHeld, (uint)localChange); |
4151 | } | 4151 | } |
4152 | } | 4152 | } |
4153 | } | 4153 | } |
4154 | } | 4154 | } |
4155 | 4155 | ||
4156 | LastCommands = allflags; | 4156 | LastCommands = allflags; |
4157 | } | 4157 | } |
4158 | 4158 | ||
4159 | internal static AgentManager.ControlFlags RemoveIgnoredControls(AgentManager.ControlFlags flags, ScriptControlled ignored) | 4159 | internal static AgentManager.ControlFlags RemoveIgnoredControls(AgentManager.ControlFlags flags, ScriptControlled ignored) |
4160 | { | 4160 | { |
4161 | if (ignored == ScriptControlled.CONTROL_ZERO) | 4161 | if (ignored == ScriptControlled.CONTROL_ZERO) |
4162 | return flags; | 4162 | return flags; |
4163 | 4163 | ||
4164 | if ((ignored & ScriptControlled.CONTROL_BACK) != 0) | 4164 | if ((ignored & ScriptControlled.CONTROL_BACK) != 0) |
4165 | flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG); | 4165 | flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG); |
4166 | if ((ignored & ScriptControlled.CONTROL_FWD) != 0) | 4166 | if ((ignored & ScriptControlled.CONTROL_FWD) != 0) |
4167 | flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_AT_POS); | 4167 | flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_AT_POS); |
4168 | if ((ignored & ScriptControlled.CONTROL_DOWN) != 0) | 4168 | if ((ignored & ScriptControlled.CONTROL_DOWN) != 0) |
4169 | flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG); | 4169 | flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG); |
4170 | if ((ignored & ScriptControlled.CONTROL_UP) != 0) | 4170 | if ((ignored & ScriptControlled.CONTROL_UP) != 0) |
4171 | flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS | AgentManager.ControlFlags.AGENT_CONTROL_UP_POS); | 4171 | flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS | AgentManager.ControlFlags.AGENT_CONTROL_UP_POS); |
4172 | if ((ignored & ScriptControlled.CONTROL_LEFT) != 0) | 4172 | if ((ignored & ScriptControlled.CONTROL_LEFT) != 0) |
4173 | flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS); | 4173 | flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS); |
4174 | if ((ignored & ScriptControlled.CONTROL_RIGHT) != 0) | 4174 | if ((ignored & ScriptControlled.CONTROL_RIGHT) != 0) |
4175 | flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG); | 4175 | flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG); |
4176 | if ((ignored & ScriptControlled.CONTROL_ROT_LEFT) != 0) | 4176 | if ((ignored & ScriptControlled.CONTROL_ROT_LEFT) != 0) |
4177 | flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG); | 4177 | flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG); |
4178 | if ((ignored & ScriptControlled.CONTROL_ROT_RIGHT) != 0) | 4178 | if ((ignored & ScriptControlled.CONTROL_ROT_RIGHT) != 0) |
4179 | flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS); | 4179 | flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS); |
4180 | if ((ignored & ScriptControlled.CONTROL_ML_LBUTTON) != 0) | 4180 | if ((ignored & ScriptControlled.CONTROL_ML_LBUTTON) != 0) |
4181 | flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN); | 4181 | flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN); |
4182 | if ((ignored & ScriptControlled.CONTROL_LBUTTON) != 0) | 4182 | if ((ignored & ScriptControlled.CONTROL_LBUTTON) != 0) |
4183 | flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP | AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN); | 4183 | flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP | AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN); |
4184 | 4184 | ||
4185 | //DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS, | 4185 | //DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS, |
4186 | //DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG, | 4186 | //DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG, |
4187 | //DIR_CONTROL_FLAG_LEFT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS, | 4187 | //DIR_CONTROL_FLAG_LEFT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS, |
4188 | //DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, | 4188 | //DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, |
4189 | //DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, | 4189 | //DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, |
4190 | //DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, | 4190 | //DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, |
4191 | //DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG | 4191 | //DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG |
4192 | 4192 | ||
4193 | return flags; | 4193 | return flags; |
4194 | } | 4194 | } |
4195 | 4195 | ||
4196 | /// <summary> | 4196 | /// <summary> |
4197 | /// RezAttachments. This should only be called upon login on the first region. | 4197 | /// RezAttachments. This should only be called upon login on the first region. |
4198 | /// Attachment rezzings on crossings and TPs are done in a different way. | 4198 | /// Attachment rezzings on crossings and TPs are done in a different way. |
4199 | /// </summary> | 4199 | /// </summary> |
4200 | public void RezAttachments() | 4200 | public void RezAttachments() |
4201 | { | 4201 | { |
4202 | if (null == m_appearance) | 4202 | if (null == m_appearance) |
4203 | { | 4203 | { |
4204 | m_log.WarnFormat("[ATTACHMENT]: Appearance has not been initialized for agent {0}", UUID); | 4204 | m_log.WarnFormat("[ATTACHMENT]: Appearance has not been initialized for agent {0}", UUID); |
4205 | return; | 4205 | return; |
4206 | } | 4206 | } |
4207 | 4207 | ||
4208 | XmlDocument doc = new XmlDocument(); | 4208 | XmlDocument doc = new XmlDocument(); |
4209 | string stateData = String.Empty; | 4209 | string stateData = String.Empty; |
4210 | 4210 | ||
4211 | IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>(); | 4211 | IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>(); |
4212 | if (attServ != null) | 4212 | if (attServ != null) |
4213 | { | 4213 | { |
4214 | m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service"); | 4214 | m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service"); |
4215 | stateData = attServ.Get(ControllingClient.AgentId.ToString()); | 4215 | stateData = attServ.Get(ControllingClient.AgentId.ToString()); |
4216 | if (stateData != String.Empty) | 4216 | if (stateData != String.Empty) |
4217 | { | 4217 | { |
4218 | try | 4218 | try |
4219 | { | 4219 | { |
4220 | doc.LoadXml(stateData); | 4220 | doc.LoadXml(stateData); |
4221 | } | 4221 | } |
4222 | catch { } | 4222 | catch { } |
4223 | } | 4223 | } |
4224 | } | 4224 | } |
4225 | 4225 | ||
4226 | Dictionary<UUID, string> itemData = new Dictionary<UUID, string>(); | 4226 | Dictionary<UUID, string> itemData = new Dictionary<UUID, string>(); |
4227 | 4227 | ||
4228 | XmlNodeList nodes = doc.GetElementsByTagName("Attachment"); | 4228 | XmlNodeList nodes = doc.GetElementsByTagName("Attachment"); |
4229 | if (nodes.Count > 0) | 4229 | if (nodes.Count > 0) |
4230 | { | 4230 | { |
4231 | foreach (XmlNode n in nodes) | 4231 | foreach (XmlNode n in nodes) |
4232 | { | 4232 | { |
4233 | XmlElement elem = (XmlElement)n; | 4233 | XmlElement elem = (XmlElement)n; |
4234 | string itemID = elem.GetAttribute("ItemID"); | 4234 | string itemID = elem.GetAttribute("ItemID"); |
4235 | string xml = elem.InnerXml; | 4235 | string xml = elem.InnerXml; |
4236 | 4236 | ||
4237 | itemData[new UUID(itemID)] = xml; | 4237 | itemData[new UUID(itemID)] = xml; |
4238 | } | 4238 | } |
4239 | } | 4239 | } |
4240 | 4240 | ||
4241 | List<int> attPoints = m_appearance.GetAttachedPoints(); | 4241 | List<int> attPoints = m_appearance.GetAttachedPoints(); |
4242 | foreach (int p in attPoints) | 4242 | foreach (int p in attPoints) |
4243 | { | 4243 | { |
4244 | if (m_isDeleted) | 4244 | if (m_isDeleted) |
4245 | return; | 4245 | return; |
4246 | 4246 | ||
4247 | UUID itemID = m_appearance.GetAttachedItem(p); | 4247 | UUID itemID = m_appearance.GetAttachedItem(p); |
4248 | UUID assetID = m_appearance.GetAttachedAsset(p); | 4248 | UUID assetID = m_appearance.GetAttachedAsset(p); |
4249 | 4249 | ||
4250 | // For some reason assetIDs are being written as Zero's in the DB -- need to track tat down | 4250 | // For some reason assetIDs are being written as Zero's in the DB -- need to track tat down |
4251 | // But they're not used anyway, the item is being looked up for now, so let's proceed. | 4251 | // But they're not used anyway, the item is being looked up for now, so let's proceed. |
4252 | //if (UUID.Zero == assetID) | 4252 | //if (UUID.Zero == assetID) |
4253 | //{ | 4253 | //{ |
4254 | // m_log.DebugFormat("[ATTACHMENT]: Cannot rez attachment in point {0} with itemID {1}", p, itemID); | 4254 | // m_log.DebugFormat("[ATTACHMENT]: Cannot rez attachment in point {0} with itemID {1}", p, itemID); |
4255 | // continue; | 4255 | // continue; |
4256 | //} | 4256 | //} |
4257 | 4257 | ||
4258 | try | 4258 | try |
4259 | { | 4259 | { |
4260 | string xmlData; | 4260 | string xmlData; |
4261 | XmlDocument d = new XmlDocument(); | 4261 | XmlDocument d = new XmlDocument(); |
4262 | UUID asset; | 4262 | UUID asset; |
4263 | if (itemData.TryGetValue(itemID, out xmlData)) | 4263 | if (itemData.TryGetValue(itemID, out xmlData)) |
4264 | { | 4264 | { |
4265 | d.LoadXml(xmlData); | 4265 | d.LoadXml(xmlData); |
4266 | m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID); | 4266 | m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID); |
4267 | 4267 | ||
4268 | // Rez from inventory | 4268 | // Rez from inventory |
4269 | asset | 4269 | asset |
4270 | = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d); | 4270 | = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d); |
4271 | 4271 | ||
4272 | } | 4272 | } |
4273 | else | 4273 | else |
4274 | { | 4274 | { |
4275 | // Rez from inventory (with a null doc to let | 4275 | // Rez from inventory (with a null doc to let |
4276 | // CHANGED_OWNER happen) | 4276 | // CHANGED_OWNER happen) |
4277 | asset | 4277 | asset |
4278 | = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null); | 4278 | = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null); |
4279 | } | 4279 | } |
4280 | 4280 | ||
4281 | m_log.InfoFormat( | 4281 | m_log.InfoFormat( |
4282 | "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})", | 4282 | "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})", |
4283 | p, itemID, assetID, asset); | 4283 | p, itemID, assetID, asset); |
4284 | } | 4284 | } |
4285 | catch (Exception e) | 4285 | catch (Exception e) |
4286 | { | 4286 | { |
4287 | m_log.ErrorFormat("[ATTACHMENT]: Unable to rez attachment: {0}", e.ToString()); | 4287 | m_log.ErrorFormat("[ATTACHMENT]: Unable to rez attachment: {0}", e.ToString()); |
4288 | } | 4288 | } |
4289 | } | 4289 | } |
4290 | } | 4290 | } |
4291 | 4291 | ||
4292 | private void ReprioritizeUpdates() | 4292 | private void ReprioritizeUpdates() |
4293 | { | 4293 | { |
4294 | if (Scene.IsReprioritizationEnabled && Scene.UpdatePrioritizationScheme != UpdatePrioritizationSchemes.Time) | 4294 | if (Scene.IsReprioritizationEnabled && Scene.UpdatePrioritizationScheme != UpdatePrioritizationSchemes.Time) |
4295 | { | 4295 | { |
4296 | lock (m_reprioritization_timer) | 4296 | lock (m_reprioritization_timer) |
4297 | { | 4297 | { |
4298 | if (!m_reprioritizing) | 4298 | if (!m_reprioritizing) |
4299 | m_reprioritization_timer.Enabled = m_reprioritizing = true; | 4299 | m_reprioritization_timer.Enabled = m_reprioritizing = true; |
4300 | else | 4300 | else |
4301 | m_reprioritization_called = true; | 4301 | m_reprioritization_called = true; |
4302 | } | 4302 | } |
4303 | } | 4303 | } |
4304 | } | 4304 | } |
4305 | 4305 | ||
4306 | private void Reprioritize(object sender, ElapsedEventArgs e) | 4306 | private void Reprioritize(object sender, ElapsedEventArgs e) |
4307 | { | 4307 | { |
4308 | m_controllingClient.ReprioritizeUpdates(); | 4308 | m_controllingClient.ReprioritizeUpdates(); |
4309 | 4309 | ||
4310 | lock (m_reprioritization_timer) | 4310 | lock (m_reprioritization_timer) |
4311 | { | 4311 | { |
4312 | m_reprioritization_timer.Enabled = m_reprioritizing = m_reprioritization_called; | 4312 | m_reprioritization_timer.Enabled = m_reprioritizing = m_reprioritization_called; |
4313 | m_reprioritization_called = false; | 4313 | m_reprioritization_called = false; |
4314 | } | 4314 | } |
4315 | } | 4315 | } |
4316 | 4316 | ||
4317 | private Vector3 Quat2Euler(Quaternion rot){ | 4317 | private Vector3 Quat2Euler(Quaternion rot){ |
4318 | float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) , | 4318 | float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) , |
4319 | (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z))); | 4319 | (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z))); |
4320 | float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W))); | 4320 | float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W))); |
4321 | float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) , | 4321 | float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) , |
4322 | (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z))); | 4322 | (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z))); |
4323 | return(new Vector3(x,y,z)); | 4323 | return(new Vector3(x,y,z)); |
4324 | } | 4324 | } |
4325 | 4325 | ||
4326 | 4326 | ||
4327 | } | 4327 | } |
4328 | } | 4328 | } |