aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Scenes/ScenePresence.cs
diff options
context:
space:
mode:
authorDr Scofield2009-02-06 16:55:34 +0000
committerDr Scofield2009-02-06 16:55:34 +0000
commit9b66108081a8c8cf79faaa6c541554091c40850e (patch)
tree095a232ae5a9de3a9244bcd34da08294f61eeea5 /OpenSim/Region/Environment/Scenes/ScenePresence.cs
parent* removed superfluous constants class (diff)
downloadopensim-SC_OLD-9b66108081a8c8cf79faaa6c541554091c40850e.zip
opensim-SC_OLD-9b66108081a8c8cf79faaa6c541554091c40850e.tar.gz
opensim-SC_OLD-9b66108081a8c8cf79faaa6c541554091c40850e.tar.bz2
opensim-SC_OLD-9b66108081a8c8cf79faaa6c541554091c40850e.tar.xz
This changeset is the step 1 of 2 in refactoring
OpenSim.Region.Environment into a "framework" part and a modules only part. This first changeset refactors OpenSim.Region.Environment.Scenes, OpenSim.Region.Environment.Interfaces, and OpenSim.Region.Interfaces into OpenSim.Region.Framework.{Interfaces,Scenes} leaving only region modules in OpenSim.Region.Environment. The next step will be to move region modules up from OpenSim.Region.Environment.Modules to OpenSim.Region.CoreModules and then sort out which modules are really core modules and which should move out to forge. I've been very careful to NOT BREAK anything. i hope i've succeeded. as this is the work of a whole week i hope i managed to keep track with the applied patches of the last week --- could any of you that did check in stuff have a look at whether it survived? thx!
Diffstat (limited to 'OpenSim/Region/Environment/Scenes/ScenePresence.cs')
-rw-r--r--OpenSim/Region/Environment/Scenes/ScenePresence.cs3651
1 files changed, 0 insertions, 3651 deletions
diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs
deleted file mode 100644
index ed455f4..0000000
--- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs
+++ /dev/null
@@ -1,3651 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Runtime.Serialization;
32using System.Security.Permissions;
33using OpenMetaverse;
34using OpenMetaverse.Packets;
35using log4net;
36using OpenSim.Framework;
37using OpenSim.Framework.Client;
38using OpenSim.Framework.Communications.Cache;
39using OpenSim.Region.Environment.Interfaces;
40using OpenSim.Region.Environment.Types;
41using OpenSim.Region.Interfaces;
42using OpenSim.Region.Physics.Manager;
43using OSD = OpenMetaverse.StructuredData.OSD;
44
45namespace OpenSim.Region.Environment.Scenes
46{
47 enum ScriptControlled : uint
48 {
49 CONTROL_ZERO = 0,
50 CONTROL_FWD = 1,
51 CONTROL_BACK = 2,
52 CONTROL_LEFT = 4,
53 CONTROL_RIGHT = 8,
54 CONTROL_UP = 16,
55 CONTROL_DOWN = 32,
56 CONTROL_ROT_LEFT = 256,
57 CONTROL_ROT_RIGHT = 512,
58 CONTROL_LBUTTON = 268435456,
59 CONTROL_ML_LBUTTON = 1073741824
60 }
61
62 struct ScriptControllers
63 {
64 public UUID itemID;
65 public uint objID;
66 public ScriptControlled ignoreControls;
67 public ScriptControlled eventControls;
68 }
69
70 [Serializable]
71 public class ScenePresence : EntityBase, ISerializable
72 {
73// ~ScenePresence()
74// {
75// System.Console.WriteLine("[ScenePresence] Destructor called");
76// }
77
78 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
79
80 public static byte[] DefaultTexture;
81
82 public UUID currentParcelUUID = UUID.Zero;
83 private AnimationSet m_animations = new AnimationSet();
84 private Dictionary<UUID, ScriptControllers> scriptedcontrols = new Dictionary<UUID, ScriptControllers>();
85 private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO;
86 private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO;
87 private bool MouseDown = false;
88 private SceneObjectGroup proxyObjectGroup = null;
89 //private SceneObjectPart proxyObjectPart = null;
90
91 public Vector3 lastKnownAllowedPosition = new Vector3();
92 public bool sentMessageAboutRestrictedParcelFlyingDown = false;
93
94 private bool m_updateflag = false;
95 private byte m_movementflag = 0;
96 private readonly List<NewForce> m_forcesList = new List<NewForce>();
97 private short m_updateCount = 0;
98 private uint m_requestedSitTargetID = 0;
99 private UUID m_requestedSitTargetUUID = UUID.Zero;
100
101 private bool m_startAnimationSet = false;
102
103 private Vector3 m_requestedSitOffset = new Vector3();
104
105 private Vector3 m_LastFinitePos = new Vector3();
106
107 private float m_sitAvatarHeight = 2.0f;
108
109 // experimentally determined "fudge factor" to make sit-target positions
110 // the same as in SecondLife. Fudge factor was tested for 36 different
111 // test cases including prims of type box, sphere, cylinder, and torus,
112 // with varying parameters for sit target location, prim size, prim
113 // rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
114 // issue #1716
115 private static readonly Vector3 m_sitTargetCorrectionOffset = new Vector3(0.1f, 0.0f, 0.3f);
116 private float m_godlevel = 0;
117
118 private bool m_invulnerable = true;
119
120 private Vector3 m_LastChildAgentUpdatePosition = new Vector3();
121
122 private int m_perfMonMS = 0;
123
124 private bool m_setAlwaysRun = false;
125
126 private Quaternion m_bodyRot= Quaternion.Identity;
127
128 public bool IsRestrictedToRegion = false;
129
130 public string JID = string.Empty;
131
132 // Agent moves with a PID controller causing a force to be exerted.
133 private bool m_newForce = false;
134 private bool m_newCoarseLocations = true;
135 private float m_health = 100f;
136
137 private Vector3 m_lastVelocity = Vector3.Zero;
138
139 // Default AV Height
140 private float m_avHeight = 127.0f;
141
142 protected RegionInfo m_regionInfo;
143 protected ulong crossingFromRegion = 0;
144
145 private readonly Vector3[] Dir_Vectors = new Vector3[6];
146
147 /// <value>
148 /// The avatar position last sent to clients
149 /// </value>
150 private Vector3 lastPhysPos = Vector3.Zero;
151
152 /// <value>
153 /// The avatar body rotation last sent to clients
154 /// </value>
155 private Quaternion lastPhysRot = Quaternion.Identity;
156
157 // Position of agent's camera in world (region cordinates)
158 protected Vector3 m_CameraCenter = Vector3.Zero;
159
160 // Use these three vectors to figure out what the agent is looking at
161 // Convert it to a Matrix and/or Quaternion
162 protected Vector3 m_CameraAtAxis = Vector3.Zero;
163 protected Vector3 m_CameraLeftAxis = Vector3.Zero;
164 protected Vector3 m_CameraUpAxis = Vector3.Zero;
165 private uint m_AgentControlFlags = 0;
166 private Quaternion m_headrotation = Quaternion.Identity;
167 private byte m_state = 0;
168
169 //Reuse the Vector3 instead of creating a new one on the UpdateMovement method
170 private Vector3 movementvector = Vector3.Zero;
171
172 private bool m_autopilotMoving = false;
173 private Vector3 m_autoPilotTarget = Vector3.Zero;
174 private bool m_sitAtAutoTarget = false;
175
176 private string m_nextSitAnimation = String.Empty;
177
178 //PauPaw:Proper PID Controler for autopilot************
179 private bool m_moveToPositionInProgress = false;
180 private Vector3 m_moveToPositionTarget = Vector3.Zero;
181 //private int m_moveToPositionStateStatus = 0;
182 //*****************************************************
183
184 // Agent's Draw distance.
185 protected float m_DrawDistance = 0f;
186
187 protected AvatarAppearance m_appearance;
188
189 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
190
191 // neighbouring regions we have enabled a child agent in
192 // holds the seed cap for the child agent in that region
193 private Dictionary<ulong, string> m_knownChildRegions = new Dictionary<ulong, string>();
194
195 /// <summary>
196 /// Implemented Control Flags
197 /// </summary>
198 private enum Dir_ControlFlags
199 {
200 DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS,
201 DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG,
202 DIR_CONTROL_FLAG_LEFT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS,
203 DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG,
204 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
205 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
206 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
207 }
208
209 /// <summary>
210 /// Position at which a significant movement was made
211 /// </summary>
212 private Vector3 posLastSignificantMove = new Vector3();
213
214 private UpdateQueue m_partsUpdateQueue = new UpdateQueue();
215 private Queue<SceneObjectGroup> m_pendingObjects = null;
216
217 private Dictionary<UUID, ScenePartUpdate> m_updateTimes = new Dictionary<UUID, ScenePartUpdate>();
218
219 // For teleports and crossings callbacks
220 string m_callbackURI;
221 ulong m_rootRegionHandle;
222
223 #region Properties
224
225 /// <summary>
226 /// Physical scene representation of this Avatar.
227 /// </summary>
228 public PhysicsActor PhysicsActor
229 {
230 set { m_physicsActor = value; }
231 get { return m_physicsActor; }
232 }
233
234 public byte MovementFlag
235 {
236 set { m_movementflag = value; }
237 get { return m_movementflag; }
238 }
239
240 public bool Updated
241 {
242 set { m_updateflag = value; }
243 get { return m_updateflag; }
244 }
245
246 public bool Invulnerable
247 {
248 set { m_invulnerable = value; }
249 get { return m_invulnerable; }
250 }
251
252 public float GodLevel
253 {
254 get { return m_godlevel; }
255 }
256
257 private readonly ulong m_regionHandle;
258
259 public ulong RegionHandle
260 {
261 get { return m_regionHandle; }
262 }
263
264 public Vector3 CameraPosition
265 {
266 get { return m_CameraCenter; }
267 }
268
269 public Quaternion CameraRotation
270 {
271 get { return Util.Axes2Rot(m_CameraAtAxis, m_CameraLeftAxis, m_CameraUpAxis); }
272 }
273
274 public Vector3 Lookat
275 {
276 get
277 {
278 Vector3 a = new Vector3(m_CameraAtAxis.X, m_CameraAtAxis.Y, 0);
279
280 if (a == Vector3.Zero)
281 return a;
282
283 return Util.GetNormalizedVector(a);
284 }
285 }
286
287 private readonly string m_firstname;
288
289 public string Firstname
290 {
291 get { return m_firstname; }
292 }
293
294 private readonly string m_lastname;
295
296 public string Lastname
297 {
298 get { return m_lastname; }
299 }
300
301 private string m_grouptitle;
302
303 public string Grouptitle
304 {
305 get { return m_grouptitle; }
306 set { m_grouptitle = value; }
307 }
308
309 public float DrawDistance
310 {
311 get { return m_DrawDistance; }
312 }
313
314 protected bool m_allowMovement = true;
315
316 public bool AllowMovement
317 {
318 get { return m_allowMovement; }
319 set { m_allowMovement = value; }
320 }
321
322 public bool SetAlwaysRun
323 {
324 get
325 {
326 if (PhysicsActor != null)
327 {
328 return PhysicsActor.SetAlwaysRun;
329 }
330 else
331 {
332 return m_setAlwaysRun;
333 }
334 }
335 set
336 {
337 m_setAlwaysRun = value;
338 if (PhysicsActor != null)
339 {
340 PhysicsActor.SetAlwaysRun = value;
341 }
342 }
343 }
344
345 public byte State
346 {
347 get { return m_state; }
348 set { m_state = value; }
349 }
350
351 public uint AgentControlFlags
352 {
353 get { return m_AgentControlFlags; }
354 set { m_AgentControlFlags = value; }
355 }
356
357 /// <summary>
358 /// This works out to be the ClientView object associated with this avatar, or it's client connection manager
359 /// </summary>
360 private IClientAPI m_controllingClient;
361
362 protected PhysicsActor m_physicsActor;
363
364 /// <value>
365 /// The client controlling this presence
366 /// </value>
367 public IClientAPI ControllingClient
368 {
369 get { return m_controllingClient; }
370 }
371
372 public IClientCore ClientView
373 {
374 get { return (IClientCore) m_controllingClient; }
375 }
376
377 protected Vector3 m_parentPosition = new Vector3();
378 public Vector3 ParentPosition
379 {
380 get { return m_parentPosition; }
381 set { m_parentPosition = value; }
382 }
383
384 /// <summary>
385 /// Absolute position of this avatar in 'region cordinates'
386 /// </summary>
387 public override Vector3 AbsolutePosition
388 {
389 get
390 {
391 if (m_physicsActor != null)
392 {
393 m_pos.X = m_physicsActor.Position.X;
394 m_pos.Y = m_physicsActor.Position.Y;
395 m_pos.Z = m_physicsActor.Position.Z;
396 }
397
398 return m_parentPosition + m_pos;
399 }
400 set
401 {
402 if (m_physicsActor != null)
403 {
404 try
405 {
406 lock (m_scene.SyncRoot)
407 {
408 m_physicsActor.Position = new PhysicsVector(value.X, value.Y, value.Z);
409 }
410 }
411 catch (Exception e)
412 {
413 Console.WriteLine("[SCENEPRESENCE]: ABSOLUTE POSITION " + e.Message);
414 }
415 }
416
417 m_pos = value;
418 m_parentPosition = new Vector3(0, 0, 0);
419 }
420 }
421
422 /// <summary>
423 /// Current velocity of the avatar.
424 /// </summary>
425 public override Vector3 Velocity
426 {
427 get
428 {
429 if (m_physicsActor != null)
430 {
431 m_velocity.X = m_physicsActor.Velocity.X;
432 m_velocity.Y = m_physicsActor.Velocity.Y;
433 m_velocity.Z = m_physicsActor.Velocity.Z;
434 }
435
436 return m_velocity;
437 }
438 set
439 {
440 //m_log.DebugFormat("In {0} setting velocity of {1} to {2}", m_scene.RegionInfo.RegionName, Name, value);
441
442 if (m_physicsActor != null)
443 {
444 try
445 {
446 lock (m_scene.SyncRoot)
447 {
448 m_physicsActor.Velocity = new PhysicsVector(value.X, value.Y, value.Z);
449 }
450 }
451 catch (Exception e)
452 {
453 Console.WriteLine("[SCENEPRESENCE]: VELOCITY " + e.Message);
454 }
455 }
456
457 m_velocity = value;
458 }
459 }
460
461 /// <summary>
462 /// If this is true, agent doesn't have a representation in this scene.
463 /// this is an agent 'looking into' this scene from a nearby scene(region)
464 ///
465 /// if False, this agent has a representation in this scene
466 /// </summary>
467 private bool m_isChildAgent = true;
468
469 public bool IsChildAgent
470 {
471 get { return m_isChildAgent; }
472 set { m_isChildAgent = value; }
473 }
474
475 private uint m_parentID = 0;
476
477 public uint ParentID
478 {
479 get { return m_parentID; }
480 set { m_parentID = value; }
481 }
482 public float Health
483 {
484 get { return m_health; }
485 set { m_health = value; }
486 }
487
488 /// <summary>
489 /// These are the region handles known by the avatar.
490 /// </summary>
491 public List<ulong> KnownChildRegionHandles
492 {
493 get
494 {
495 if (m_knownChildRegions.Count == 0)
496 return new List<ulong>();
497 else
498 return new List<ulong>(m_knownChildRegions.Keys);
499 }
500 }
501
502 public Dictionary<ulong, string> KnownRegions
503 {
504 get { return m_knownChildRegions; }
505 set
506 {
507 m_knownChildRegions = value;
508 }
509 }
510
511 public void AdjustKnownSeeds()
512 {
513 Dictionary<ulong, string> seeds = Scene.CapsModule.GetChildrenSeeds(UUID);
514 List<ulong> old = new List<ulong>();
515 foreach (ulong handle in seeds.Keys)
516 {
517 uint x, y;
518 Utils.LongToUInts(handle, out x, out y);
519 x = x / Constants.RegionSize;
520 y = y / Constants.RegionSize;
521 if (Util.IsOutsideView(x, Scene.RegionInfo.RegionLocX, y, Scene.RegionInfo.RegionLocY))
522 {
523 old.Add(handle);
524 }
525 }
526 DropOldNeighbours(old);
527 Scene.CapsModule.SetChildrenSeed(UUID, seeds);
528 KnownRegions = seeds;
529 //Console.WriteLine(" ++++++++++AFTER+++++++++++++ ");
530 //DumpKnownRegions();
531 }
532
533 public void DumpKnownRegions()
534 {
535 Console.WriteLine("================ KnownRegions {0} ================", Scene.RegionInfo.RegionName);
536 foreach (KeyValuePair<ulong, string> kvp in KnownRegions)
537 {
538 uint x, y;
539 Utils.LongToUInts(kvp.Key, out x, out y);
540 x = x / Constants.RegionSize;
541 y = y / Constants.RegionSize;
542 Console.WriteLine(" >> {0}, {1}: {2}", x, y, kvp.Value);
543 }
544 }
545
546 public AnimationSet Animations
547 {
548 get { return m_animations; }
549 }
550
551 #endregion
552
553 #region Constructor(s)
554
555 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo)
556 {
557 m_regionHandle = reginfo.RegionHandle;
558 m_controllingClient = client;
559 m_firstname = m_controllingClient.FirstName;
560 m_lastname = m_controllingClient.LastName;
561 m_name = String.Format("{0} {1}", m_firstname, m_lastname);
562
563 m_scene = world;
564 m_uuid = client.AgentId;
565 m_regionInfo = reginfo;
566 m_localId = m_scene.AllocateLocalId();
567
568 IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
569 if (gm != null)
570 m_grouptitle = gm.GetGroupTitle(m_uuid);
571
572 AbsolutePosition = m_controllingClient.StartPos;
573 AdjustKnownSeeds();
574
575 TrySetMovementAnimation("STAND"); // TODO: I think, this won't send anything, as we are still a child here...
576
577 // we created a new ScenePresence (a new child agent) in a fresh region.
578 // Request info about all the (root) agents in this region
579 // Note: This won't send data *to* other clients in that region (children don't send)
580 SendInitialFullUpdateToAllClients();
581
582 RegisterToEvents();
583 SetDirectionVectors();
584
585 CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(m_uuid);
586 if (userInfo != null)
587 userInfo.OnItemReceived += ItemReceived;
588 }
589
590 public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, byte[] visualParams,
591 AvatarWearable[] wearables)
592 : this(client, world, reginfo)
593 {
594 m_appearance = new AvatarAppearance(m_uuid, wearables, visualParams);
595 }
596
597 public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance)
598 : this(client, world, reginfo)
599 {
600 m_appearance = appearance;
601 }
602
603 public void RegisterToEvents()
604 {
605 m_controllingClient.OnRequestWearables += SendWearables;
606 m_controllingClient.OnSetAppearance += SetAppearance;
607 m_controllingClient.OnCompleteMovementToRegion += CompleteMovement;
608 m_controllingClient.OnCompleteMovementToRegion += SendInitialData;
609 m_controllingClient.OnAgentUpdate += HandleAgentUpdate;
610 m_controllingClient.OnAgentRequestSit += HandleAgentRequestSit;
611 m_controllingClient.OnAgentSit += HandleAgentSit;
612 m_controllingClient.OnSetAlwaysRun += HandleSetAlwaysRun;
613 m_controllingClient.OnStartAnim += HandleStartAnim;
614 m_controllingClient.OnStopAnim += HandleStopAnim;
615 m_controllingClient.OnForceReleaseControls += HandleForceReleaseControls;
616 m_controllingClient.OnAutoPilotGo += DoAutoPilot;
617 m_controllingClient.AddGenericPacketHandler("autopilot", DoMoveToPosition);
618
619 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange);
620 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement);
621 }
622
623 private void SetDirectionVectors()
624 {
625 Dir_Vectors[0] = new Vector3(1, 0, 0); //FORWARD
626 Dir_Vectors[1] = new Vector3(-1, 0, 0); //BACK
627 Dir_Vectors[2] = new Vector3(0, 1, 0); //LEFT
628 Dir_Vectors[3] = new Vector3(0, -1, 0); //RIGHT
629 Dir_Vectors[4] = new Vector3(0, 0, 1); //UP
630 Dir_Vectors[5] = new Vector3(0, 0, -1); //DOWN
631 Dir_Vectors[5] = new Vector3(0, 0, -0.5f); //DOWN_Nudge
632 }
633
634 #endregion
635
636 /// <summary>
637 /// Add the part to the queue of parts for which we need to send an update to the client
638 /// </summary>
639 /// <param name="part"></param>
640 public void QueuePartForUpdate(SceneObjectPart part)
641 {
642 //if (InterestList.Contains(part.ParentGroup))
643 //{
644 lock (m_partsUpdateQueue)
645 {
646 m_partsUpdateQueue.Enqueue(part);
647 }
648 // }
649 }
650
651 public uint GenerateClientFlags(UUID ObjectID)
652 {
653 return m_scene.Permissions.GenerateClientFlags(m_uuid, ObjectID);
654 }
655
656 /// <summary>
657 /// Send updates to the client about prims which have been placed on the update queue. We don't
658 /// necessarily send updates for all the parts on the queue, e.g. if an updates with a more recent
659 /// timestamp has already been sent.
660 /// </summary>
661 public void SendPrimUpdates()
662 {
663 // if (m_scene.QuadTree.GetNodeID(this.AbsolutePosition.X, this.AbsolutePosition.Y) != m_currentQuadNode)
664 //{
665 // this.UpdateQuadTreeNode();
666 //this.RefreshQuadObject();
667 //}
668 m_perfMonMS = System.Environment.TickCount;
669
670 if (m_pendingObjects == null)
671 {
672 if (!m_isChildAgent || m_scene.m_seeIntoRegionFromNeighbor)
673 {
674 m_pendingObjects = new Queue<SceneObjectGroup>();
675
676 List<EntityBase> ents = new List<EntityBase>(m_scene.Entities);
677 if (!m_isChildAgent) // Proximity sort makes no sense for
678 { // Child agents
679 ents.Sort(delegate(EntityBase a, EntityBase b)
680 {
681 return Vector3.Distance(AbsolutePosition, a.AbsolutePosition).CompareTo(Vector3.Distance(AbsolutePosition, b.AbsolutePosition));
682 });
683 }
684
685 foreach (EntityBase e in ents)
686 {
687 if (e is SceneObjectGroup)
688 m_pendingObjects.Enqueue((SceneObjectGroup)e);
689 }
690 }
691 }
692
693 while (m_pendingObjects.Count > 0 && m_partsUpdateQueue.Count < 60)
694 {
695 SceneObjectGroup g = m_pendingObjects.Dequeue();
696
697 // This is where we should check for draw distance
698 // do culling and stuff. Problem with that is that until
699 // we recheck in movement, that won't work right.
700 // So it's not implemented now.
701 //
702
703 // Don't even queue if we have sent this one
704 //
705 if (!m_updateTimes.ContainsKey(g.UUID))
706 g.ScheduleFullUpdateToAvatar(this);
707 }
708
709 int updateCount = 0;
710
711 while (m_partsUpdateQueue.Count > 0)
712 {
713 SceneObjectPart part = m_partsUpdateQueue.Dequeue();
714
715 if (part.ParentGroup == null || part.ParentGroup.IsDeleted)
716 continue;
717
718 if (m_updateTimes.ContainsKey(part.UUID))
719 {
720 ScenePartUpdate update = m_updateTimes[part.UUID];
721
722 // We deal with the possibility that two updates occur at
723 // the same unix time at the update point itself.
724
725 if ((update.LastFullUpdateTime < part.TimeStampFull) ||
726 part.IsAttachment)
727 {
728// m_log.DebugFormat(
729// "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}",
730// part.Name, part.UUID, part.TimeStampFull);
731
732 part.SendFullUpdate(ControllingClient,
733 GenerateClientFlags(part.UUID));
734
735 // We'll update to the part's timestamp rather than
736 // the current time to avoid the race condition
737 // whereby the next tick occurs while we are doing
738 // this update. If this happened, then subsequent
739 // updates which occurred on the same tick or the
740 // next tick of the last update would be ignored.
741
742 update.LastFullUpdateTime = part.TimeStampFull;
743
744 updateCount++;
745 }
746 else if (update.LastTerseUpdateTime <= part.TimeStampTerse)
747 {
748// m_log.DebugFormat(
749// "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}",
750// part.Name, part.UUID, part.TimeStampTerse);
751
752 part.SendTerseUpdateToClient(ControllingClient);
753
754 update.LastTerseUpdateTime = part.TimeStampTerse;
755 updateCount++;
756 }
757 }
758 else
759 {
760 //never been sent to client before so do full update
761 ScenePartUpdate update = new ScenePartUpdate();
762 update.FullID = part.UUID;
763 update.LastFullUpdateTime = part.TimeStampFull;
764 m_updateTimes.Add(part.UUID, update);
765
766 // Attachment handling
767 //
768 if (part.ParentGroup.RootPart.Shape.PCode == 9 && part.ParentGroup.RootPart.Shape.State != 0)
769 {
770 if (part != part.ParentGroup.RootPart)
771 continue;
772
773 part.ParentGroup.SendFullUpdateToClient(ControllingClient);
774 continue;
775 }
776
777 part.SendFullUpdate(ControllingClient,
778 GenerateClientFlags(part.UUID));
779 updateCount++;
780 }
781
782 if (updateCount > 60)
783 break;
784 }
785
786 m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS);
787 }
788
789 #region Status Methods
790
791 /// <summary>
792 /// This turns a child agent, into a root agent
793 /// This is called when an agent teleports into a region, or if an
794 /// agent crosses into this region from a neighbor over the border
795 /// </summary>
796 public void MakeRootAgent(Vector3 pos, bool isFlying)
797 {
798 m_log.DebugFormat(
799 "[SCENE]: Upgrading child to root agent for {0} in {1}",
800 Name, m_scene.RegionInfo.RegionName);
801
802 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
803
804 IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
805 if (gm != null)
806 m_grouptitle = gm.GetGroupTitle(m_uuid);
807
808 m_scene.SetRootAgentScene(m_uuid);
809
810 // Moved this from SendInitialData to ensure that m_appearance is initialized
811 // before the inventory is processed in MakeRootAgent. This fixes a race condition
812 // related to the handling of attachments
813 m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance);
814
815 if (pos.X < 0 || pos.X > Constants.RegionSize || pos.Y < 0 || pos.Y > Constants.RegionSize || pos.Z < 0)
816 {
817 Vector3 emergencyPos = new Vector3(128, 128, 128);
818
819 m_log.WarnFormat(
820 "[SCENE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}",
821 pos, Name, UUID, emergencyPos);
822
823 pos = emergencyPos;
824 }
825
826 m_isChildAgent = false;
827
828 float localAVHeight = 1.56f;
829 if (m_avHeight != 127.0f)
830 {
831 localAVHeight = m_avHeight;
832 }
833
834 float posZLimit = (float)m_scene.GetLandHeight((int)pos.X, (int)pos.Y);
835 float newPosZ = posZLimit + localAVHeight / 2;
836 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
837 {
838 pos.Z = newPosZ;
839 }
840 AbsolutePosition = pos;
841
842 AddToPhysicalScene();
843 m_physicsActor.Flying = isFlying;
844
845 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying
846 // avatar to return to the standing position in mid-air. On login it looks like this is being sent
847 // elsewhere anyway
848 //SendAnimPack();
849
850 m_scene.SwapRootAgentCount(false);
851 m_scene.CommsManager.UserProfileCacheService.RequestInventoryForUser(m_uuid);
852 m_scene.CapsModule.AddCapsHandler(m_uuid);
853
854 // On the next prim update, all objects will be sent
855 //
856 m_pendingObjects = null;
857
858 m_scene.EventManager.TriggerOnMakeRootAgent(this);
859 }
860
861 /// <summary>
862 /// This turns a root agent into a child agent
863 /// when an agent departs this region for a neighbor, this gets called.
864 ///
865 /// It doesn't get called for a teleport. Reason being, an agent that
866 /// teleports out may not end up anywhere near this region
867 /// </summary>
868 public void MakeChildAgent()
869 {
870 m_animations.Clear();
871
872// m_log.DebugFormat(
873// "[SCENEPRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}",
874// Name, UUID, m_scene.RegionInfo.RegionName);
875
876 // Don't zero out the velocity since this can cause problems when an avatar is making a region crossing,
877 // depending on the exact timing. This shouldn't matter anyway since child agent positions are not updated.
878 //Velocity = new Vector3(0, 0, 0);
879
880 m_isChildAgent = true;
881 m_scene.SwapRootAgentCount(true);
882 RemoveFromPhysicalScene();
883 m_scene.EventManager.TriggerOnMakeChildAgent(this);
884 }
885
886 /// <summary>
887 /// Removes physics plugin scene representation of this agent if it exists.
888 /// </summary>
889 private void RemoveFromPhysicalScene()
890 {
891 if (PhysicsActor != null)
892 {
893 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
894 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
895 m_physicsActor.UnSubscribeEvents();
896 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
897 PhysicsActor = null;
898 }
899 }
900
901 /// <summary>
902 ///
903 /// </summary>
904 /// <param name="pos"></param>
905 public void Teleport(Vector3 pos)
906 {
907 RemoveFromPhysicalScene();
908 Velocity = new Vector3(0, 0, 0);
909 AbsolutePosition = pos;
910 AddToPhysicalScene();
911 SendTerseUpdateToAllClients();
912 }
913
914 /// <summary>
915 ///
916 /// </summary>
917 public void StopMovement()
918 {
919 }
920
921 public void StopFlying()
922 {
923 // It turns out to get the agent to stop flying, you have to feed it stop flying velocities
924 // and send a full object update.
925 // There's no message to send the client to tell it to stop flying
926
927 // Add 1/6 the avatar's height to it's position so it doesn't shoot into the air
928 // when the avatar stands up
929
930 if (m_avHeight != 127.0f)
931 {
932 AbsolutePosition = AbsolutePosition + new Vector3(0, 0, (m_avHeight / 6f));
933 }
934 else
935 {
936 AbsolutePosition = AbsolutePosition + new Vector3(0, 0, (1.56f / 6f));
937 }
938 TrySetMovementAnimation("LAND");
939 SendFullUpdateToAllClients();
940 }
941
942 public void AddNeighbourRegion(ulong regionHandle, string cap)
943 {
944 lock (m_knownChildRegions)
945 {
946 if (!m_knownChildRegions.ContainsKey(regionHandle))
947 {
948 uint x, y;
949 Utils.LongToUInts(regionHandle, out x, out y);
950 m_knownChildRegions.Add(regionHandle, cap);
951 }
952 }
953 }
954
955 public void RemoveNeighbourRegion(ulong regionHandle)
956 {
957 lock (m_knownChildRegions)
958 {
959 if (m_knownChildRegions.ContainsKey(regionHandle))
960 {
961 m_knownChildRegions.Remove(regionHandle);
962 //Console.WriteLine(" !!! removing known region {0} in {1}. Count = {2}", regionHandle, Scene.RegionInfo.RegionName, m_knownChildRegions.Count);
963 }
964 }
965 }
966
967 public void DropOldNeighbours(List<ulong> oldRegions)
968 {
969 foreach (ulong handle in oldRegions)
970 {
971 RemoveNeighbourRegion(handle);
972 Scene.CapsModule.DropChildSeed(UUID, handle);
973 }
974 }
975
976 public List<ulong> GetKnownRegionList()
977 {
978 return new List<ulong>(m_knownChildRegions.Keys);
979 }
980
981 #endregion
982
983 #region Event Handlers
984
985 /// <summary>
986 /// Sets avatar height in the phyiscs plugin
987 /// </summary>
988 internal void SetHeight(float height)
989 {
990 m_avHeight = height;
991 if (PhysicsActor != null)
992 {
993 PhysicsVector SetSize = new PhysicsVector(0.45f, 0.6f, m_avHeight);
994 PhysicsActor.Size = SetSize;
995 }
996 }
997
998 /// <summary>
999 /// Complete Avatar's movement into the region
1000 /// </summary>
1001 public void CompleteMovement()
1002 {
1003 Vector3 look = Velocity;
1004 if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
1005 {
1006 look = new Vector3(0.99f, 0.042f, 0);
1007 }
1008
1009 m_controllingClient.MoveAgentIntoRegion(m_regionInfo, AbsolutePosition, look);
1010
1011 if (m_isChildAgent)
1012 {
1013 m_isChildAgent = false;
1014
1015 MakeRootAgent(AbsolutePosition, false);
1016
1017 if ((m_callbackURI != null) && !m_callbackURI.Equals(""))
1018 {
1019 m_log.DebugFormat("[SCENE PRESENCE]: Releasing agent in URI {0}", m_callbackURI);
1020 Scene.SendReleaseAgent(m_rootRegionHandle, UUID, m_callbackURI);
1021 m_callbackURI = null;
1022 }
1023
1024 //m_log.DebugFormat("Completed movement");
1025 }
1026 }
1027
1028 /// <summary>
1029 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1030 /// </summary>
1031 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
1032 {
1033 //if (m_isChildAgent)
1034 //{
1035 // // Console.WriteLine("DEBUG: HandleAgentUpdate: child agent");
1036 // return;
1037 //}
1038
1039 // Must check for standing up even when PhysicsActor is null,
1040 // since sitting currently removes avatar from physical scene
1041 //m_log.Debug("agentPos:" + AbsolutePosition.ToString());
1042
1043 // This is irritating. Really.
1044 if (!AbsolutePosition.IsFinite())
1045 {
1046 RemoveFromPhysicalScene();
1047 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error# 9999902");
1048
1049 m_pos = m_LastFinitePos;
1050 if (!m_pos.IsFinite())
1051 {
1052 m_pos.X = 127f;
1053 m_pos.Y = 127f;
1054 m_pos.Z = 127f;
1055 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error# 9999903");
1056 }
1057
1058 AddToPhysicalScene();
1059 }
1060 else
1061 {
1062 m_LastFinitePos = m_pos;
1063 }
1064 //m_physicsActor.AddForce(new PhysicsVector(999999999, 99999999, 999999999999999), true);
1065
1066
1067 //ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
1068 //if (land != null)
1069 //{
1070 //if (land.landData.landingType == (byte)1 && land.landData.userLocation != Vector3.Zero)
1071 //{
1072 // agent.startpos = land.landData.userLocation;
1073 //}
1074 //}
1075
1076 m_perfMonMS = System.Environment.TickCount;
1077
1078 uint flags = agentData.ControlFlags;
1079 Quaternion bodyRotation = agentData.BodyRotation;
1080
1081 // Camera location in world. We'll need to raytrace
1082 // from this location from time to time.
1083 m_CameraCenter = agentData.CameraCenter;
1084
1085 // Use these three vectors to figure out what the agent is looking at
1086 // Convert it to a Matrix and/or Quaternion
1087 m_CameraAtAxis = agentData.CameraAtAxis;
1088 m_CameraLeftAxis = agentData.CameraLeftAxis;
1089 m_CameraUpAxis = agentData.CameraUpAxis;
1090
1091 // The Agent's Draw distance setting
1092 m_DrawDistance = agentData.Far;
1093
1094 if ((flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0)
1095 {
1096 StandUp();
1097 }
1098 lock (scriptedcontrols)
1099 {
1100 if (scriptedcontrols.Count > 0)
1101 {
1102 SendControlToScripts(flags);
1103 flags = this.RemoveIgnoredControls(flags, IgnoredControls);
1104
1105 }
1106 }
1107
1108 if (PhysicsActor == null)
1109 {
1110 return;
1111 }
1112
1113 if (m_autopilotMoving)
1114 CheckAtSitTarget();
1115
1116 if ((flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1117 {
1118 // TODO: This doesn't prevent the user from walking yet.
1119 // Setting parent ID would fix this, if we knew what value
1120 // to use. Or we could add a m_isSitting variable.
1121
1122 TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1123 }
1124 // In the future, these values might need to go global.
1125 // Here's where you get them.
1126
1127 m_AgentControlFlags = flags;
1128 m_headrotation = agentData.HeadRotation;
1129 m_state = agentData.State;
1130
1131 if (m_allowMovement)
1132 {
1133 int i = 0;
1134 bool update_movementflag = false;
1135 bool update_rotation = false;
1136 bool DCFlagKeyPressed = false;
1137 Vector3 agent_control_v3 = new Vector3(0, 0, 0);
1138 Quaternion q = bodyRotation;
1139 if (PhysicsActor != null)
1140 {
1141 bool oldflying = PhysicsActor.Flying;
1142
1143 PhysicsActor.Flying = ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1144
1145 if (PhysicsActor.Flying != oldflying)
1146 {
1147 update_movementflag = true;
1148 }
1149 }
1150
1151 if (q != m_bodyRot)
1152 {
1153 m_bodyRot = q;
1154 update_rotation = true;
1155 }
1156
1157 if (m_parentID == 0)
1158 {
1159 bool bAllowUpdateMoveToPosition = false;
1160 bool bResetMoveToPosition = false;
1161 foreach (Dir_ControlFlags DCF in Enum.GetValues(typeof (Dir_ControlFlags)))
1162 {
1163 if ((flags & (uint) DCF) != 0)
1164 {
1165 bResetMoveToPosition = true;
1166 DCFlagKeyPressed = true;
1167 try
1168 {
1169 agent_control_v3 += Dir_Vectors[i];
1170 }
1171 catch (IndexOutOfRangeException)
1172 {
1173 // Why did I get this?
1174 }
1175
1176 if ((m_movementflag & (uint) DCF) == 0)
1177 {
1178 m_movementflag += (byte) (uint) DCF;
1179 update_movementflag = true;
1180 }
1181 }
1182 else
1183 {
1184 if ((m_movementflag & (uint) DCF) != 0)
1185 {
1186 m_movementflag -= (byte) (uint) DCF;
1187 update_movementflag = true;
1188 }
1189 else
1190 {
1191 bAllowUpdateMoveToPosition = true;
1192 }
1193 }
1194 i++;
1195 }
1196
1197 //Paupaw:Do Proper PID for Autopilot here
1198 if (bResetMoveToPosition)
1199 {
1200 m_moveToPositionTarget = Vector3.Zero;
1201 m_moveToPositionInProgress = false;
1202 update_movementflag = true;
1203 bAllowUpdateMoveToPosition = false;
1204 }
1205
1206 if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving))
1207 {
1208 //Check the error term of the current position in relation to the target position
1209 if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 1.5)
1210 {
1211 // we are close enough to the target
1212 m_moveToPositionTarget = Vector3.Zero;
1213 m_moveToPositionInProgress = false;
1214 update_movementflag = true;
1215 }
1216 else
1217 {
1218 try
1219 {
1220 // move avatar in 2D at one meter/second towards target, in avatar coordinate frame.
1221 // This movement vector gets added to the velocity through AddNewMovement().
1222 // Theoretically we might need a more complex PID approach here if other
1223 // unknown forces are acting on the avatar and we need to adaptively respond
1224 // to such forces, but the following simple approach seems to works fine.
1225 Vector3 LocalVectorToTarget3D =
1226 (m_moveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1227 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords
1228 // Ignore z component of vector
1229 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1230 LocalVectorToTarget2D.Normalize();
1231 agent_control_v3 += LocalVectorToTarget2D;
1232
1233 // update avatar movement flags. the avatar coordinate system is as follows:
1234 //
1235 // +X (forward)
1236 //
1237 // ^
1238 // |
1239 // |
1240 // |
1241 // |
1242 // (left) +Y <--------o--------> -Y
1243 // avatar
1244 // |
1245 // |
1246 // |
1247 // |
1248 // v
1249 // -X
1250 //
1251
1252 // based on the above avatar coordinate system, classify the movement into
1253 // one of left/right/back/forward.
1254 if (LocalVectorToTarget2D.Y > 0)//MoveLeft
1255 {
1256 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
1257 update_movementflag = true;
1258 }
1259 else if (LocalVectorToTarget2D.Y < 0) //MoveRight
1260 {
1261 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
1262 update_movementflag = true;
1263 }
1264 if (LocalVectorToTarget2D.X < 0) //MoveBack
1265 {
1266 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
1267 update_movementflag = true;
1268 }
1269 else if (LocalVectorToTarget2D.X > 0) //Move Forward
1270 {
1271 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
1272 update_movementflag = true;
1273 }
1274 }
1275 catch (Exception)
1276 {
1277
1278 //Avoid system crash, can be slower but...
1279 }
1280
1281 }
1282 }
1283 }
1284
1285 // Cause the avatar to stop flying if it's colliding
1286 // with something with the down arrow pressed.
1287
1288 // Only do this if we're flying
1289 if (m_physicsActor != null && m_physicsActor.Flying)
1290 {
1291 // Are the landing controls requirements filled?
1292 bool controlland = (((flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) ||
1293 ((flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
1294
1295 // Are the collision requirements fulfilled?
1296 bool colliding = (m_physicsActor.IsColliding == true);
1297
1298 if (m_physicsActor.Flying && colliding && controlland)
1299 {
1300 StopFlying();
1301 }
1302 }
1303
1304 if (update_movementflag || (update_rotation && DCFlagKeyPressed))
1305 {
1306// m_log.DebugFormat("{0} {1}", update_movementflag, (update_rotation && DCFlagKeyPressed));
1307// m_log.DebugFormat(
1308// "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1309
1310 AddNewMovement(agent_control_v3, q);
1311
1312 if (update_movementflag)
1313 UpdateMovementAnimations();
1314 }
1315 }
1316
1317 m_scene.EventManager.TriggerOnClientMovement(this);
1318
1319 m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS);
1320 }
1321
1322 public void DoAutoPilot(uint not_used, Vector3 Pos, IClientAPI remote_client)
1323 {
1324 m_autopilotMoving = true;
1325 m_autoPilotTarget = Pos;
1326 m_sitAtAutoTarget = false;
1327 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1328 //proxy.PCode = (byte)PCode.ParticleSystem;
1329
1330 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1331 proxyObjectGroup.AttachToScene(m_scene);
1332
1333 // Commented out this code since it could never have executed, but might still be informative.
1334// if (proxyObjectGroup != null)
1335// {
1336 proxyObjectGroup.SendGroupFullUpdate();
1337 remote_client.SendSitResponse(proxyObjectGroup.UUID, Vector3.Zero, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false);
1338 m_scene.DeleteSceneObject(proxyObjectGroup, false);
1339// }
1340// else
1341// {
1342// m_autopilotMoving = false;
1343// m_autoPilotTarget = Vector3.Zero;
1344// ControllingClient.SendAlertMessage("Autopilot cancelled");
1345// }
1346 }
1347
1348 public void DoMoveToPosition(Object sender, string method, List<String> args)
1349 {
1350 try
1351 {
1352 float locx = 0f;
1353 float locy = 0f;
1354 float locz = 0f;
1355 uint regionX = 0;
1356 uint regionY = 0;
1357 try
1358 {
1359 Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY);
1360 locx = Convert.ToSingle(args[0]) - (float)regionX;
1361 locy = Convert.ToSingle(args[1]) - (float)regionY;
1362 locz = Convert.ToSingle(args[2]);
1363 }
1364 catch (InvalidCastException)
1365 {
1366 m_log.Error("[CLIENT]: Invalid autopilot request");
1367 return;
1368 }
1369 m_moveToPositionInProgress = true;
1370 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1371 }
1372 catch (Exception ex)
1373 {
1374 //Why did I get this error?
1375 Console.WriteLine("[SCENEPRESENCE]: DoMoveToPosition" + ex.ToString());
1376 }
1377 }
1378
1379 private void CheckAtSitTarget()
1380 {
1381 //m_log.Debug("[AUTOPILOT]: " + Util.GetDistanceTo(AbsolutePosition, m_autoPilotTarget).ToString());
1382 if (Util.GetDistanceTo(AbsolutePosition, m_autoPilotTarget) <= 1.5)
1383 {
1384 if (m_sitAtAutoTarget)
1385 {
1386 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetUUID);
1387 if (part != null)
1388 {
1389 AbsolutePosition = part.AbsolutePosition;
1390 Velocity = new Vector3(0, 0, 0);
1391 SendFullUpdateToAllClients();
1392
1393 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID);
1394 }
1395 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1396 m_requestedSitTargetUUID = UUID.Zero;
1397 }
1398 else
1399 {
1400 //ControllingClient.SendAlertMessage("Autopilot cancelled");
1401 //SendTerseUpdateToAllClients();
1402 //PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1403 //proxy.PCode = (byte)PCode.ParticleSystem;
1404 ////uint nextUUID = m_scene.NextLocalId;
1405
1406 //proxyObjectGroup = new SceneObjectGroup(m_scene, m_scene.RegionInfo.RegionHandle, UUID, nextUUID, m_autoPilotTarget, Quaternion.Identity, proxy);
1407 //if (proxyObjectGroup != null)
1408 //{
1409 //proxyObjectGroup.SendGroupFullUpdate();
1410 //ControllingClient.SendSitResponse(UUID.Zero, m_autoPilotTarget, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false);
1411 //m_scene.DeleteSceneObject(proxyObjectGroup);
1412 //}
1413 }
1414
1415 m_autoPilotTarget = Vector3.Zero;
1416 m_autopilotMoving = false;
1417 }
1418 }
1419 /// <summary>
1420 /// Perform the logic necessary to stand the client up. This method also executes
1421 /// the stand animation.
1422 /// </summary>
1423 public void StandUp()
1424 {
1425 if (m_parentID != 0)
1426 {
1427 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1428 if (part != null)
1429 {
1430 TaskInventoryDictionary taskIDict = part.TaskInventory;
1431 if (taskIDict != null)
1432 {
1433 lock (taskIDict)
1434 {
1435 foreach (UUID taskID in taskIDict.Keys)
1436 {
1437 UnRegisterControlEventsToScript(LocalId, taskID);
1438 taskIDict[taskID].PermsMask &= ~(
1439 2048 | //PERMISSION_CONTROL_CAMERA
1440 4); // PERMISSION_TAKE_CONTROLS
1441 }
1442 }
1443
1444 }
1445 // Reset sit target.
1446 if (part.GetAvatarOnSitTarget() == UUID)
1447 part.SetAvatarOnSitTarget(UUID.Zero);
1448
1449 m_parentPosition = part.GetWorldPosition();
1450 }
1451
1452 if (m_physicsActor == null)
1453 {
1454 AddToPhysicalScene();
1455 }
1456
1457 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight);
1458 m_parentPosition = new Vector3();
1459
1460 m_parentID = 0;
1461 SendFullUpdateToAllClients();
1462 m_requestedSitTargetID = 0;
1463 if (m_physicsActor != null)
1464 {
1465 SetHeight(m_avHeight);
1466 }
1467 }
1468
1469 TrySetMovementAnimation("STAND");
1470 }
1471
1472 private SceneObjectPart FindNextAvailableSitTarget(UUID targetID)
1473 {
1474 SceneObjectPart targetPart = m_scene.GetSceneObjectPart(targetID);
1475 if (targetPart == null)
1476 return null;
1477
1478 // If the primitive the player clicked on has a sit target and that sit target is not full, that sit target is used.
1479 // 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.
1480
1481 // Get our own copy of the part array, and sort into the order we want to test
1482 SceneObjectPart[] partArray = targetPart.ParentGroup.GetParts();
1483 Array.Sort(partArray, delegate(SceneObjectPart p1, SceneObjectPart p2)
1484 {
1485 // we want the originally selected part first, then the rest in link order -- so make the selected part link num (-1)
1486 int linkNum1 = p1==targetPart ? -1 : p1.LinkNum;
1487 int linkNum2 = p2==targetPart ? -1 : p2.LinkNum;
1488 return linkNum1 - linkNum2;
1489 }
1490 );
1491
1492 //look for prims with explicit sit targets that are available
1493 foreach (SceneObjectPart part in partArray)
1494 {
1495 // Is a sit target available?
1496 Vector3 avSitOffSet = part.SitTargetPosition;
1497 Quaternion avSitOrientation = part.SitTargetOrientation;
1498 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1499
1500 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
1501 bool SitTargetisSet =
1502 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1503 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1504
1505 if (SitTargetisSet && SitTargetUnOccupied)
1506 {
1507 //switch the target to this prim
1508 return part;
1509 }
1510 }
1511
1512 // no explicit sit target found - use original target
1513 return targetPart;
1514 }
1515
1516 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset)
1517 {
1518 bool autopilot = true;
1519 Vector3 pos = new Vector3();
1520 Quaternion sitOrientation = Quaternion.Identity;
1521 Vector3 cameraEyeOffset = Vector3.Zero;
1522 Vector3 cameraAtOffset = Vector3.Zero;
1523 bool forceMouselook = false;
1524
1525 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1526 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1527 if (part != null)
1528 {
1529 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1530 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1531
1532 // Is a sit target available?
1533 Vector3 avSitOffSet = part.SitTargetPosition;
1534 Quaternion avSitOrientation = part.SitTargetOrientation;
1535 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1536
1537 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
1538 bool SitTargetisSet =
1539 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 0f &&
1540 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f));
1541
1542 if (SitTargetisSet && SitTargetUnOccupied)
1543 {
1544 part.SetAvatarOnSitTarget(UUID);
1545 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z);
1546 sitOrientation = avSitOrientation;
1547 autopilot = false;
1548 }
1549
1550 pos = part.AbsolutePosition + offset;
1551 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1)
1552 //{
1553 // offset = pos;
1554 //autopilot = false;
1555 //}
1556 if (m_physicsActor != null)
1557 {
1558 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1559 // We can remove the physicsActor until they stand up.
1560 m_sitAvatarHeight = m_physicsActor.Size.Z;
1561
1562 if (autopilot)
1563 {
1564 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5)
1565 {
1566 autopilot = false;
1567
1568 RemoveFromPhysicalScene();
1569 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
1570 }
1571 }
1572 else
1573 {
1574 RemoveFromPhysicalScene();
1575 }
1576 }
1577
1578 cameraAtOffset = part.GetCameraAtOffset();
1579 cameraEyeOffset = part.GetCameraEyeOffset();
1580 forceMouselook = part.GetForceMouselook();
1581 }
1582
1583 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1584 m_requestedSitTargetUUID = targetID;
1585 // This calls HandleAgentSit twice, once from here, and the client calls
1586 // HandleAgentSit itself after it gets to the location
1587 // It doesn't get to the location until we've moved them there though
1588 // which happens in HandleAgentSit :P
1589 m_autopilotMoving = autopilot;
1590 m_autoPilotTarget = pos;
1591 m_sitAtAutoTarget = autopilot;
1592 if (!autopilot)
1593 HandleAgentSit(remoteClient, UUID);
1594 }
1595
1596 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset)
1597 {
1598 if (m_parentID != 0)
1599 {
1600 StandUp();
1601 }
1602 m_nextSitAnimation = "SIT";
1603
1604 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1605 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1606
1607 if (part != null)
1608 {
1609 if (!String.IsNullOrEmpty(part.SitAnimation))
1610 {
1611 m_nextSitAnimation = part.SitAnimation;
1612 }
1613 m_requestedSitTargetID = part.LocalId;
1614 m_requestedSitOffset = offset;
1615 }
1616 else
1617 {
1618
1619 m_log.Warn("Sit requested on unknown object: " + targetID.ToString());
1620 }
1621 SendSitResponse(remoteClient, targetID, offset);
1622 }
1623
1624 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset, string sitAnimation)
1625 {
1626 if (m_parentID != 0)
1627 {
1628 StandUp();
1629 }
1630 if (!String.IsNullOrEmpty(sitAnimation))
1631 {
1632 m_nextSitAnimation = sitAnimation;
1633 }
1634 else
1635 {
1636 m_nextSitAnimation = "SIT";
1637 }
1638
1639 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1640 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1641 if (part != null)
1642 {
1643 m_requestedSitTargetID = part.LocalId;
1644 m_requestedSitOffset = offset;
1645 }
1646 else
1647 {
1648 m_log.Warn("Sit requested on unknown object: " + targetID.ToString());
1649 }
1650 SendSitResponse(remoteClient, targetID, offset);
1651 }
1652
1653 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
1654 {
1655 if (!String.IsNullOrEmpty(m_nextSitAnimation))
1656 {
1657 HandleAgentSit(remoteClient, agentID, m_nextSitAnimation);
1658 }
1659 else
1660 {
1661 HandleAgentSit(remoteClient, agentID, "SIT");
1662 }
1663 }
1664
1665 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID, string sitAnimation)
1666 {
1667 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
1668
1669 if (m_sitAtAutoTarget || !m_autopilotMoving)
1670 {
1671 if (part != null)
1672 {
1673 if (part.GetAvatarOnSitTarget() == UUID)
1674 {
1675 Vector3 sitTargetPos = part.SitTargetPosition;
1676 Quaternion sitTargetOrient = part.SitTargetOrientation;
1677
1678 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
1679 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
1680
1681 //Quaternion result = (sitTargetOrient * vq) * nq;
1682
1683 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
1684 m_pos += m_sitTargetCorrectionOffset;
1685 m_bodyRot = sitTargetOrient;
1686 //Rotation = sitTargetOrient;
1687 m_parentPosition = part.AbsolutePosition;
1688
1689 //SendTerseUpdateToAllClients();
1690 }
1691 else
1692 {
1693 m_pos -= part.AbsolutePosition;
1694 m_parentPosition = part.AbsolutePosition;
1695 }
1696 }
1697 else
1698 {
1699 return;
1700 }
1701 }
1702 m_parentID = m_requestedSitTargetID;
1703
1704 Velocity = new Vector3(0, 0, 0);
1705 RemoveFromPhysicalScene();
1706
1707 TrySetMovementAnimation(sitAnimation);
1708 SendFullUpdateToAllClients();
1709 // This may seem stupid, but Our Full updates don't send avatar rotation :P
1710 // So we're also sending a terse update (which has avatar rotation)
1711 // [Update] We do now.
1712 //SendTerseUpdateToAllClients();
1713 }
1714
1715 /// <summary>
1716 /// Event handler for the 'Always run' setting on the client
1717 /// Tells the physics plugin to increase speed of movement.
1718 /// </summary>
1719 public void HandleSetAlwaysRun(IClientAPI remoteClient, bool SetAlwaysRun)
1720 {
1721 m_setAlwaysRun = SetAlwaysRun;
1722 if (PhysicsActor != null)
1723 {
1724 PhysicsActor.SetAlwaysRun = SetAlwaysRun;
1725 }
1726 }
1727
1728 public void AddAnimation(UUID animID)
1729 {
1730 if (m_isChildAgent)
1731 return;
1732
1733 if (m_animations.Add(animID, m_controllingClient.NextAnimationSequenceNumber))
1734 {
1735 SendAnimPack();
1736 }
1737 }
1738
1739 public void AddAnimation(string name)
1740 {
1741 if (m_isChildAgent)
1742 return;
1743
1744 UUID animID = m_controllingClient.GetDefaultAnimation(name);
1745 if (animID == UUID.Zero)
1746 return;
1747
1748 AddAnimation(animID);
1749 }
1750
1751 public void RemoveAnimation(UUID animID)
1752 {
1753 if (m_isChildAgent)
1754 return;
1755
1756 if (m_animations.Remove(animID))
1757 {
1758 SendAnimPack();
1759 }
1760 }
1761
1762 public void RemoveAnimation(string name)
1763 {
1764 if (m_isChildAgent)
1765 return;
1766
1767 UUID animID = m_controllingClient.GetDefaultAnimation(name);
1768 if (animID == UUID.Zero)
1769 return;
1770
1771 RemoveAnimation(animID);
1772 }
1773
1774 public UUID[] GetAnimationArray()
1775 {
1776 UUID[] animIDs;
1777 int[] sequenceNums;
1778 m_animations.GetArrays( out animIDs, out sequenceNums );
1779 return animIDs;
1780 }
1781
1782 public void HandleStartAnim(IClientAPI remoteClient, UUID animID)
1783 {
1784 AddAnimation(animID);
1785 }
1786
1787 public void HandleStopAnim(IClientAPI remoteClient, UUID animID)
1788 {
1789 RemoveAnimation(animID);
1790 }
1791
1792 /// <summary>
1793 /// The movement animation is reserved for "main" animations
1794 /// that are mutually exclusive, e.g. flying and sitting.
1795 /// </summary>
1796 protected void TrySetMovementAnimation(string anim)
1797 {
1798 //m_log.DebugFormat("Updating movement animation to {0}", anim);
1799
1800 if (m_animations.TrySetDefaultAnimation(anim, m_controllingClient.NextAnimationSequenceNumber))
1801 {
1802 SendAnimPack();
1803 }
1804 }
1805
1806 /// <summary>
1807 /// This method determines the proper movement related animation
1808 /// </summary>
1809 public string GetMovementAnimation()
1810 {
1811 if (m_movementflag != 0)
1812 {
1813 // We are moving
1814 if (PhysicsActor != null && PhysicsActor.Flying)
1815 {
1816 return "FLY";
1817 }
1818 else if (PhysicsActor != null && (m_movementflag & (uint) AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0 &&
1819 PhysicsActor.IsColliding)
1820 {
1821 if ((m_movementflag & (uint) AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 ||
1822 (m_movementflag & (uint) AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0)
1823 {
1824 return "CROUCHWALK";
1825 }
1826 else
1827 {
1828 return "CROUCH";
1829 }
1830 }
1831 else if (PhysicsActor != null && !PhysicsActor.IsColliding && PhysicsActor.Velocity.Z < -2)
1832 {
1833 return "FALLDOWN";
1834 }
1835 else if (PhysicsActor != null && !PhysicsActor.IsColliding && Velocity.Z > 1e-6 &&
1836 (m_movementflag & (uint) AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0)
1837 {
1838 return "JUMP";
1839 }
1840 else if (m_setAlwaysRun)
1841 {
1842 return "RUN";
1843 }
1844 else
1845 {
1846 return "WALK";
1847 }
1848 }
1849 else
1850 {
1851 // We are not moving
1852 if (PhysicsActor != null && !PhysicsActor.IsColliding && PhysicsActor.Velocity.Z < -2 && !PhysicsActor.Flying)
1853 {
1854 return "FALLDOWN";
1855 }
1856 else if (PhysicsActor != null && !PhysicsActor.IsColliding && Velocity.Z > 6 && !PhysicsActor.Flying)
1857 {
1858 // HACK: We check if Velocity.Z > 6 for this animation in order to avoid false positives during normal movement.
1859 // TODO: set this animation only when on the ground and UP_POS is received?
1860
1861 // This is the standing jump
1862 return "JUMP";
1863 }
1864 else if (PhysicsActor != null && PhysicsActor.Flying)
1865 {
1866 return "HOVER";
1867 }
1868 else
1869 {
1870 return "STAND";
1871 }
1872 }
1873 }
1874
1875 /// <summary>
1876 /// Update the movement animation of this avatar according to its current state
1877 /// </summary>
1878 protected void UpdateMovementAnimations()
1879 {
1880 string animation = GetMovementAnimation();
1881 TrySetMovementAnimation(animation);
1882 }
1883
1884 /// <summary>
1885 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector
1886 /// </summary>
1887 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
1888 /// <param name="rotation">The direction in which this avatar should now face.
1889 public void AddNewMovement(Vector3 vec, Quaternion rotation)
1890 {
1891 if (m_isChildAgent)
1892 {
1893 Console.WriteLine("DEBUG: AddNewMovement: child agent");
1894 return;
1895 }
1896
1897 m_perfMonMS = System.Environment.TickCount;
1898
1899 m_rotation = rotation;
1900 NewForce newVelocity = new NewForce();
1901 Vector3 direc = vec * rotation;
1902 direc.Normalize();
1903
1904 direc *= 0.03f * 128f;
1905 if (m_physicsActor.Flying)
1906 {
1907 direc *= 4;
1908 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
1909 //bool colliding = (m_physicsActor.IsColliding==true);
1910 //if (controlland)
1911 // m_log.Info("[AGENT]: landCommand");
1912 //if (colliding)
1913 // m_log.Info("[AGENT]: colliding");
1914 //if (m_physicsActor.Flying && colliding && controlland)
1915 //{
1916 // StopFlying();
1917 // m_log.Info("[AGENT]: Stop FLying");
1918 //}
1919 }
1920 else
1921 {
1922 if (!m_physicsActor.Flying && m_physicsActor.IsColliding)
1923 {
1924 if (direc.Z > 2.0f)
1925 {
1926 direc.Z *= 3;
1927
1928 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
1929 TrySetMovementAnimation("PREJUMP");
1930 TrySetMovementAnimation("JUMP");
1931 }
1932 }
1933 }
1934
1935 newVelocity.X = direc.X;
1936 newVelocity.Y = direc.Y;
1937 newVelocity.Z = direc.Z;
1938 m_forcesList.Add(newVelocity);
1939
1940 m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS);
1941 }
1942
1943 #endregion
1944
1945 #region Overridden Methods
1946
1947 public override void Update()
1948 {
1949 SendPrimUpdates();
1950
1951 if (m_newCoarseLocations)
1952 {
1953 SendCoarseLocations();
1954 m_newCoarseLocations = false;
1955 }
1956
1957 if (m_isChildAgent == false)
1958 {
1959 if (m_newForce) // user movement 'forces' (ie commands to move)
1960 {
1961 SendTerseUpdateToAllClients();
1962 m_updateCount = 0;
1963 }
1964 else if (m_movementflag != 0) // scripted movement (?)
1965 {
1966 m_updateCount++;
1967 if (m_updateCount > 3)
1968 {
1969 SendTerseUpdateToAllClients();
1970 m_updateCount = 0;
1971 }
1972 }
1973 else if ((Util.GetDistanceTo(lastPhysPos, AbsolutePosition) > 0.02)
1974 || (Util.GetDistanceTo(m_lastVelocity, m_velocity) > 0.02)
1975 || lastPhysRot != m_bodyRot)
1976 {
1977 // Send Terse Update to all clients updates lastPhysPos and m_lastVelocity
1978 // doing the above assures us that we know what we sent the clients last
1979 SendTerseUpdateToAllClients();
1980 m_updateCount = 0;
1981 }
1982
1983 // followed suggestion from mic bowman. reversed the two lines below.
1984 CheckForBorderCrossing();
1985 CheckForSignificantMovement(); // sends update to the modules.
1986 }
1987 }
1988
1989 #endregion
1990
1991 #region Update Client(s)
1992
1993 /// <summary>
1994 /// Sends a location update to the client connected to this scenePresence
1995 /// </summary>
1996 /// <param name="remoteClient"></param>
1997 public void SendTerseUpdateToClient(IClientAPI remoteClient)
1998 {
1999 m_perfMonMS = System.Environment.TickCount;
2000
2001 Vector3 pos = m_pos;
2002 Vector3 vel = Velocity;
2003 Quaternion rot = m_bodyRot;
2004 pos.Z -= m_appearance.HipOffset;
2005 remoteClient.SendAvatarTerseUpdate(m_regionHandle, (ushort)(m_scene.TimeDilation * (float)ushort.MaxValue), LocalId, new Vector3(pos.X, pos.Y, pos.Z),
2006 new Vector3(vel.X, vel.Y, vel.Z), rot);
2007
2008 m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS);
2009 m_scene.AddAgentUpdates(1);
2010 }
2011
2012 /// <summary>
2013 /// Send a location/velocity/accelleration update to all agents in scene
2014 /// </summary>
2015 public void SendTerseUpdateToAllClients()
2016 {
2017 m_perfMonMS = System.Environment.TickCount;
2018
2019 m_scene.Broadcast(SendTerseUpdateToClient);
2020
2021 m_lastVelocity = m_velocity;
2022 lastPhysPos = AbsolutePosition;
2023 lastPhysRot = m_bodyRot;
2024
2025 m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS);
2026
2027 }
2028
2029 public void SendCoarseLocations()
2030 {
2031 m_perfMonMS = System.Environment.TickCount;
2032
2033 List<Vector3> CoarseLocations = new List<Vector3>();
2034 List<ScenePresence> avatars = m_scene.GetAvatars();
2035 for (int i = 0; i < avatars.Count; i++)
2036 {
2037 if (avatars[i] != this)
2038 {
2039 if (avatars[i].ParentID != 0)
2040 {
2041 // sitting avatar
2042 SceneObjectPart sop = m_scene.GetSceneObjectPart(avatars[i].ParentID);
2043 if (sop != null)
2044 {
2045 CoarseLocations.Add(sop.AbsolutePosition + avatars[i].m_pos);
2046 }
2047 else
2048 {
2049 // we can't find the parent.. ! arg!
2050 CoarseLocations.Add(avatars[i].m_pos);
2051 }
2052 }
2053 else
2054 {
2055 CoarseLocations.Add(avatars[i].m_pos);
2056 }
2057 }
2058 }
2059
2060 m_controllingClient.SendCoarseLocationUpdate(CoarseLocations);
2061
2062 m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS);
2063 }
2064
2065 public void CoarseLocationChange()
2066 {
2067 m_newCoarseLocations = true;
2068 }
2069
2070 /// <summary>
2071 /// Tell other client about this avatar (The client previously didn't know or had outdated details about this avatar)
2072 /// </summary>
2073 /// <param name="remoteAvatar"></param>
2074 public void SendFullUpdateToOtherClient(ScenePresence remoteAvatar)
2075 {
2076 // 2 stage check is needed.
2077 if (remoteAvatar == null)
2078 return;
2079 IClientAPI cl=remoteAvatar.ControllingClient;
2080 if (cl == null)
2081 return;
2082 if (m_appearance.Texture == null)
2083 return;
2084
2085 // Note: because Quaternion is a struct, it can't be null
2086 Quaternion rot = m_bodyRot;
2087
2088 Vector3 pos = m_pos;
2089 pos.Z -= m_appearance.HipOffset;
2090
2091 remoteAvatar.m_controllingClient.SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid,
2092 LocalId, m_pos, m_appearance.Texture.ToBytes(),
2093 m_parentID, rot);
2094 m_scene.AddAgentUpdates(1);
2095 }
2096
2097 /// <summary>
2098 /// Tell *ALL* agents about this agent
2099 /// </summary>
2100 public void SendInitialFullUpdateToAllClients()
2101 {
2102 m_perfMonMS = System.Environment.TickCount;
2103
2104 List<ScenePresence> avatars = m_scene.GetScenePresences();
2105 foreach (ScenePresence avatar in avatars)
2106 {
2107 // only send if this is the root (children are only "listening posts" in a foreign region)
2108 if (!IsChildAgent)
2109 {
2110 SendFullUpdateToOtherClient(avatar);
2111 }
2112
2113 if (avatar.LocalId != LocalId)
2114 {
2115 if (!avatar.IsChildAgent)
2116 {
2117 avatar.SendFullUpdateToOtherClient(this);
2118 avatar.SendAppearanceToOtherAgent(this);
2119 avatar.SendAnimPackToClient(this.ControllingClient);
2120 }
2121 }
2122 }
2123 m_scene.AddAgentUpdates(avatars.Count);
2124 m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS);
2125 }
2126
2127 public void SendFullUpdateToAllClients()
2128 {
2129 m_perfMonMS = System.Environment.TickCount;
2130
2131 // only send update from root agents to other clients; children are only "listening posts"
2132 List<ScenePresence> avatars = m_scene.GetAvatars();
2133 foreach (ScenePresence avatar in avatars)
2134 {
2135 SendFullUpdateToOtherClient(avatar);
2136
2137 }
2138 m_scene.AddAgentUpdates(avatars.Count);
2139 m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS);
2140
2141 SendAnimPack();
2142 }
2143
2144 /// <summary>
2145 /// Do everything required once a client completes its movement into a region
2146 /// </summary>
2147 public void SendInitialData()
2148 {
2149 // Moved this into CompleteMovement to ensure that m_appearance is initialized before
2150 // the inventory arrives
2151 // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance);
2152
2153 // Note: because Quaternion is a struct, it can't be null
2154 Quaternion rot = m_bodyRot;
2155
2156 Vector3 pos = m_pos;
2157 pos.Z -= m_appearance.HipOffset;
2158
2159 m_controllingClient.SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId,
2160 m_pos, m_appearance.Texture.ToBytes(), m_parentID, rot);
2161
2162 if (!m_isChildAgent)
2163 {
2164 m_scene.InformClientOfNeighbours(this);
2165 }
2166
2167 SendInitialFullUpdateToAllClients();
2168 SendAppearanceToAllOtherAgents();
2169 }
2170
2171 /// <summary>
2172 /// Tell the client for this scene presence what items it should be wearing now
2173 /// </summary>
2174 /// <param name="client"></param>
2175 public void SendWearables()
2176 {
2177 ControllingClient.SendWearables(m_appearance.Wearables, m_appearance.Serial++);
2178 }
2179
2180 /// <summary>
2181 ///
2182 /// </summary>
2183 public void SendAppearanceToAllOtherAgents()
2184 {
2185 m_perfMonMS = System.Environment.TickCount;
2186
2187 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
2188 {
2189 if (scenePresence.UUID != UUID)
2190 {
2191 SendAppearanceToOtherAgent(scenePresence);
2192 }
2193 });
2194
2195 m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS);
2196 }
2197
2198 /// <summary>
2199 /// Send appearance data to an agent that isn't this one.
2200 /// </summary>
2201 /// <param name="avatar"></param>
2202 public void SendAppearanceToOtherAgent(ScenePresence avatar)
2203 {
2204 avatar.ControllingClient.SendAppearance(
2205 m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.ToBytes());
2206 }
2207
2208 /// <summary>
2209 /// Set appearance data (textureentry and slider settings) received from the client
2210 /// </summary>
2211 /// <param name="texture"></param>
2212 /// <param name="visualParam"></param>
2213 public void SetAppearance(byte[] texture, List<byte> visualParam)
2214 {
2215 if (m_physicsActor != null)
2216 {
2217 // This may seem like it's redundant, remove the avatar from the physics scene
2218 // just to add it back again, but it saves us from having to update
2219 // 3 variables 10 times a second.
2220 m_scene.PhysicsScene.RemoveAvatar(m_physicsActor);
2221 AddToPhysicalScene();
2222 }
2223 m_appearance.SetAppearance(texture, visualParam);
2224 SetHeight(m_appearance.AvatarHeight);
2225 m_scene.CommsManager.AvatarService.UpdateUserAppearance(m_controllingClient.AgentId, m_appearance);
2226
2227 SendAppearanceToAllOtherAgents();
2228 //SendWearables();
2229 if (!m_startAnimationSet)
2230 {
2231 UpdateMovementAnimations();
2232 m_startAnimationSet = true;
2233 }
2234 }
2235
2236 public void SetWearable(int wearableId, AvatarWearable wearable)
2237 {
2238 m_appearance.SetWearable(wearableId, wearable);
2239 m_scene.CommsManager.AvatarService.UpdateUserAppearance(m_controllingClient.AgentId, m_appearance);
2240 m_controllingClient.SendWearables(m_appearance.Wearables, m_appearance.Serial++);
2241 }
2242
2243 // Because appearance setting is in a module, we actually need
2244 // to give it access to our appearance directly, otherwise we
2245 // get a synchronization issue.
2246 public AvatarAppearance Appearance
2247 {
2248 get { return m_appearance; }
2249 set { m_appearance = value; }
2250 }
2251
2252 /// <summary>
2253 ///
2254 /// </summary>
2255 /// <param name="animations"></param>
2256 /// <param name="seqs"></param>
2257 public void SendAnimPack(UUID[] animations, int[] seqs)
2258 {
2259 if (m_isChildAgent)
2260 return;
2261
2262 m_scene.Broadcast(
2263 delegate(IClientAPI client) { client.SendAnimations(animations, seqs, m_controllingClient.AgentId); });
2264 }
2265
2266 public void SendAnimPackToClient(IClientAPI client)
2267 {
2268 if (m_isChildAgent)
2269 return;
2270 UUID[] animIDs;
2271 int[] sequenceNums;
2272
2273 m_animations.GetArrays(out animIDs, out sequenceNums);
2274
2275 client.SendAnimations(animIDs, sequenceNums, m_controllingClient.AgentId);
2276 }
2277
2278 /// <summary>
2279 /// Send animation information about this avatar to all clients.
2280 /// </summary>
2281 public void SendAnimPack()
2282 {
2283 //m_log.Debug("Sending animation pack");
2284
2285 if (m_isChildAgent)
2286 return;
2287
2288 UUID[] animIDs;
2289 int[] sequenceNums;
2290
2291 m_animations.GetArrays(out animIDs, out sequenceNums);
2292
2293 SendAnimPack(animIDs, sequenceNums);
2294 }
2295
2296 #endregion
2297
2298 #region Significant Movement Method
2299
2300 /// <summary>
2301 /// This checks for a significant movement and sends a courselocationchange update
2302 /// </summary>
2303 protected void CheckForSignificantMovement()
2304 {
2305 if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > 0.5)
2306 {
2307 posLastSignificantMove = AbsolutePosition;
2308 m_scene.EventManager.TriggerSignificantClientMovement(m_controllingClient);
2309 m_scene.NotifyMyCoarseLocationChange();
2310 }
2311
2312 // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m
2313 if (Util.GetDistanceTo(AbsolutePosition,m_LastChildAgentUpdatePosition) > 32)
2314 {
2315 ChildAgentDataUpdate cadu = new ChildAgentDataUpdate();
2316 cadu.ActiveGroupID = UUID.Zero.Guid;
2317 cadu.AgentID = UUID.Guid;
2318 cadu.alwaysrun = m_setAlwaysRun;
2319 cadu.AVHeight = m_avHeight;
2320 sLLVector3 tempCameraCenter = new sLLVector3(new Vector3(m_CameraCenter.X, m_CameraCenter.Y, m_CameraCenter.Z));
2321 cadu.cameraPosition = tempCameraCenter;
2322 cadu.drawdistance = m_DrawDistance;
2323 if (m_scene.Permissions.IsGod(new UUID(cadu.AgentID)))
2324 cadu.godlevel = m_godlevel;
2325 cadu.GroupAccess = 0;
2326 cadu.Position = new sLLVector3(AbsolutePosition);
2327 cadu.regionHandle = m_scene.RegionInfo.RegionHandle;
2328 float multiplier = 1;
2329 int innacurateNeighbors = m_scene.GetInaccurateNeighborCount();
2330 if (innacurateNeighbors != 0)
2331 {
2332 multiplier = 1f / (float)innacurateNeighbors;
2333 }
2334 if (multiplier <= 0f)
2335 {
2336 multiplier = 0.25f;
2337 }
2338
2339 //m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString());
2340 cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier);
2341 cadu.Velocity = new sLLVector3(Velocity);
2342
2343 AgentPosition agentpos = new AgentPosition();
2344 agentpos.CopyFrom(cadu);
2345
2346 m_scene.SendOutChildAgentUpdates(agentpos, this);
2347
2348 m_LastChildAgentUpdatePosition.X = AbsolutePosition.X;
2349 m_LastChildAgentUpdatePosition.Y = AbsolutePosition.Y;
2350 m_LastChildAgentUpdatePosition.Z = AbsolutePosition.Z;
2351 }
2352 }
2353
2354 #endregion
2355
2356 #region Border Crossing Methods
2357
2358 /// <summary>
2359 /// Checks to see if the avatar is in range of a border and calls CrossToNewRegion
2360 /// </summary>
2361 protected void CheckForBorderCrossing()
2362 {
2363 if (IsChildAgent)
2364 return;
2365
2366 Vector3 pos2 = AbsolutePosition;
2367 Vector3 vel = Velocity;
2368
2369 float timeStep = 0.1f;
2370 pos2.X = pos2.X + (vel.X*timeStep);
2371 pos2.Y = pos2.Y + (vel.Y*timeStep);
2372 pos2.Z = pos2.Z + (vel.Z*timeStep);
2373
2374 if ((pos2.X < 0) || (pos2.X > Constants.RegionSize))
2375 {
2376 CrossToNewRegion();
2377 }
2378
2379 if ((pos2.Y < 0) || (pos2.Y > Constants.RegionSize))
2380 {
2381 CrossToNewRegion();
2382 }
2383 }
2384
2385 /// <summary>
2386 /// Moves the agent outside the region bounds
2387 /// Tells neighbor region that we're crossing to it
2388 /// If the neighbor accepts, remove the agent's viewable avatar from this scene
2389 /// set them to a child agent.
2390 /// </summary>
2391 protected void CrossToNewRegion()
2392 {
2393 Vector3 pos = AbsolutePosition;
2394 Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z);
2395 uint neighbourx = m_regionInfo.RegionLocX;
2396 uint neighboury = m_regionInfo.RegionLocY;
2397
2398 // distance to edge that will trigger crossing
2399 const float boundaryDistance = 1.7f;
2400
2401 // distance into new region to place avatar
2402 const float enterDistance = 0.1f;
2403
2404 if (pos.X < boundaryDistance)
2405 {
2406 neighbourx--;
2407 newpos.X = Constants.RegionSize - enterDistance;
2408 }
2409 else if (pos.X > Constants.RegionSize - boundaryDistance)
2410 {
2411 neighbourx++;
2412 newpos.X = enterDistance;
2413 }
2414
2415 if (pos.Y < boundaryDistance)
2416 {
2417 neighboury--;
2418 newpos.Y = Constants.RegionSize - enterDistance;
2419 }
2420 else if (pos.Y > Constants.RegionSize - boundaryDistance)
2421 {
2422 neighboury++;
2423 newpos.Y = enterDistance;
2424 }
2425
2426 Vector3 vel = m_velocity;
2427 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
2428 SimpleRegionInfo neighbourRegion = m_scene.RequestNeighbouringRegionInfo(neighbourHandle);
2429 if (neighbourRegion != null && ValidateAttachments())
2430 {
2431 // When the neighbour is informed of the border crossing, it will set up CAPS handlers for the avatar
2432 // This means we need to remove the current caps handler here and possibly compensate later,
2433 // in case both scenes are being hosted on the same region server. Messy
2434 //m_scene.RemoveCapsHandler(UUID);
2435 newpos = newpos + (vel);
2436
2437 CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(UUID);
2438 if (userInfo != null)
2439 {
2440 userInfo.DropInventory();
2441 }
2442 else
2443 {
2444 m_log.WarnFormat("[SCENE PRESENCE]: No cached user info found for {0} {1} on leaving region", Name, UUID);
2445 }
2446
2447 bool crossingSuccessful =
2448 m_scene.InformNeighbourOfCrossing(neighbourHandle, m_controllingClient.AgentId, newpos,
2449 m_physicsActor.Flying);
2450 if (crossingSuccessful)
2451 {
2452 // Next, let's close the child agent connections that are too far away.
2453 CloseChildAgents(neighbourx, neighboury);
2454
2455 //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo();
2456 m_controllingClient.RequestClientInfo();
2457
2458 //Console.WriteLine("BEFORE CROSS");
2459 //Scene.DumpChildrenSeeds(UUID);
2460 //DumpKnownRegions();
2461 string agentcaps;
2462 if (!m_knownChildRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
2463 {
2464 m_log.ErrorFormat("[SCENE PRESENCE]: No CAPS information for region handle {0}, exiting CrossToNewRegion.",
2465 neighbourRegion.RegionHandle);
2466 return;
2467 }
2468 // TODO Should construct this behind a method
2469 string capsPath =
2470 "http://" + neighbourRegion.ExternalHostName + ":" + neighbourRegion.HttpPort
2471 + "/CAPS/" + agentcaps /*circuitdata.CapsPath*/ + "0000/";
2472
2473 m_log.DebugFormat("[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, m_uuid);
2474
2475 IEventQueue eq = m_scene.RequestModuleInterface<IEventQueue>();
2476 if (eq != null)
2477 {
2478 OSD Item = EventQueueHelper.CrossRegion(neighbourHandle, newpos, vel, neighbourRegion.ExternalEndPoint,
2479 capsPath, UUID, ControllingClient.SessionId);
2480 eq.Enqueue(Item, UUID);
2481 }
2482 else
2483 {
2484 m_controllingClient.CrossRegion(neighbourHandle, newpos, vel, neighbourRegion.ExternalEndPoint,
2485 capsPath);
2486 }
2487
2488 MakeChildAgent();
2489 // now we have a child agent in this region. Request all interesting data about other (root) agents
2490 SendInitialFullUpdateToAllClients();
2491
2492 CrossAttachmentsIntoNewRegion(neighbourHandle, true);
2493
2494 // m_scene.SendKillObject(m_localId);
2495
2496 m_scene.NotifyMyCoarseLocationChange();
2497 // the user may change their profile information in other region,
2498 // so the userinfo in UserProfileCache is not reliable any more, delete it
2499 if (m_scene.NeedSceneCacheClear(UUID))
2500 {
2501 m_scene.CommsManager.UserProfileCacheService.RemoveUser(UUID);
2502 m_log.DebugFormat(
2503 "[SCENE PRESENCE]: User {0} is going to another region, profile cache removed", UUID);
2504 }
2505 }
2506 else
2507 {
2508 // Restore the user structures that we needed to delete before asking the receiving region to complete the crossing
2509 m_scene.CommsManager.UserProfileCacheService.RequestInventoryForUser(UUID);
2510 m_scene.CapsModule.AddCapsHandler(UUID);
2511 }
2512 }
2513
2514 //Console.WriteLine("AFTER CROSS");
2515 //Scene.DumpChildrenSeeds(UUID);
2516 //DumpKnownRegions();
2517 }
2518
2519 /// <summary>
2520 /// Computes which child agents to close when the scene presence moves to another region.
2521 /// Removes those regions from m_knownRegions.
2522 /// </summary>
2523 /// <param name="newRegionX">The new region's x on the map</param>
2524 /// <param name="newRegionY">The new region's y on the map</param>
2525 /// <returns></returns>
2526 public void CloseChildAgents(uint newRegionX, uint newRegionY)
2527 {
2528 List<ulong> byebyeRegions = new List<ulong>();
2529 m_log.DebugFormat(
2530 "[SCENE PRESENCE]: Closing child agents. Checking {0} regions in {1}",
2531 m_knownChildRegions.Keys.Count, Scene.RegionInfo.RegionName);
2532 //DumpKnownRegions();
2533
2534 lock (m_knownChildRegions)
2535 {
2536 foreach (ulong handle in m_knownChildRegions.Keys)
2537 {
2538 // Don't close the agent on this region yet
2539 if (handle != Scene.RegionInfo.RegionHandle)
2540 {
2541 uint x, y;
2542 Utils.LongToUInts(handle, out x, out y);
2543 x = x / Constants.RegionSize;
2544 y = y / Constants.RegionSize;
2545
2546 //Console.WriteLine("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX)));
2547 //Console.WriteLine("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY)));
2548 if (Util.IsOutsideView(x, newRegionX, y, newRegionY))
2549 {
2550 byebyeRegions.Add(handle);
2551 }
2552 }
2553 }
2554 }
2555
2556 if (byebyeRegions.Count > 0)
2557 {
2558 m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents");
2559 m_scene.SceneGridService.SendCloseChildAgentConnections(m_controllingClient.AgentId, byebyeRegions);
2560 }
2561
2562 foreach (ulong handle in byebyeRegions)
2563 {
2564 RemoveNeighbourRegion(handle);
2565 }
2566
2567 }
2568
2569 #endregion
2570
2571 /// <summary>
2572 /// This allows the Sim owner the abiility to kick users from their sim currently.
2573 /// It tells the client that the agent has permission to do so.
2574 /// </summary>
2575 public void GrantGodlikePowers(UUID agentID, UUID sessionID, UUID token, bool godStatus)
2576 {
2577 if (godStatus)
2578 {
2579 // For now, assign god level 200 to anyone
2580 // who is granted god powers, but has no god level set.
2581 //
2582 CachedUserInfo profile = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(agentID);
2583 if (profile.UserProfile.GodLevel > 0)
2584 m_godlevel = profile.UserProfile.GodLevel;
2585 else
2586 m_godlevel = 200;
2587 }
2588 else
2589 {
2590 m_godlevel = 0;
2591 }
2592
2593 ControllingClient.SendAdminResponse(token, (uint)m_godlevel);
2594 }
2595
2596 #region Child Agent Updates
2597
2598 public void ChildAgentDataUpdate(AgentData cAgentData)
2599 {
2600 //Console.WriteLine(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName);
2601 if (!IsChildAgent)
2602 return;
2603
2604 CopyFrom(cAgentData);
2605 }
2606
2607 /// <summary>
2608 /// This updates important decision making data about a child agent
2609 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region
2610 /// </summary>
2611 public void ChildAgentDataUpdate(AgentPosition cAgentData, uint tRegionX, uint tRegionY, uint rRegionX, uint rRegionY)
2612 {
2613 if (!IsChildAgent)
2614 return;
2615
2616 //Console.WriteLine(" >>> ChildAgentPositionUpdate <<< " + rRegionX + "-" + rRegionY);
2617 int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize;
2618 int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize;
2619
2620 m_DrawDistance = cAgentData.Far;
2621 if (cAgentData.Position != new Vector3(-1, -1, -1)) // UGH!!
2622 m_pos = new Vector3(cAgentData.Position.X + shiftx, cAgentData.Position.Y + shifty, cAgentData.Position.Z);
2623
2624 // It's hard to say here.. We can't really tell where the camera position is unless it's in world cordinates from the sending region
2625 m_CameraCenter = cAgentData.Center;
2626
2627 m_avHeight = cAgentData.Size.Z;
2628 //SetHeight(cAgentData.AVHeight);
2629
2630 if ((cAgentData.Throttles != null) && cAgentData.Throttles.Length > 0)
2631 ControllingClient.SetChildAgentThrottle(cAgentData.Throttles);
2632
2633 // Sends out the objects in the user's draw distance if m_sendTasksToChild is true.
2634 if (m_scene.m_seeIntoRegionFromNeighbor)
2635 m_pendingObjects = null;
2636
2637 //cAgentData.AVHeight;
2638 //cAgentData.regionHandle;
2639 //m_velocity = cAgentData.Velocity;
2640 }
2641
2642 public void CopyTo(AgentData cAgent)
2643 {
2644 cAgent.AgentID = UUID;
2645 cAgent.RegionHandle = m_scene.RegionInfo.RegionHandle;
2646
2647 cAgent.Position = m_pos;
2648 cAgent.Velocity = m_velocity;
2649 cAgent.Center = m_CameraCenter;
2650 cAgent.Size = new Vector3(0, 0, m_avHeight);
2651 cAgent.AtAxis = m_CameraAtAxis;
2652 cAgent.LeftAxis = m_CameraLeftAxis;
2653 cAgent.UpAxis = m_CameraUpAxis;
2654
2655 cAgent.Far = m_DrawDistance;
2656
2657 // Throttles
2658 float multiplier = 1;
2659 int innacurateNeighbors = m_scene.GetInaccurateNeighborCount();
2660 if (innacurateNeighbors != 0)
2661 {
2662 multiplier = 1f / (float)innacurateNeighbors;
2663 }
2664 if (multiplier <= 0f)
2665 {
2666 multiplier = 0.25f;
2667 }
2668 //m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString());
2669 cAgent.Throttles = ControllingClient.GetThrottlesPacked(multiplier);
2670
2671 cAgent.HeadRotation = m_headrotation;
2672 cAgent.BodyRotation = m_bodyRot;
2673 cAgent.ControlFlags = m_AgentControlFlags;
2674 if ((m_physicsActor != null) && (m_physicsActor.Flying))
2675 {
2676 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
2677 }
2678
2679 if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID)))
2680 cAgent.GodLevel = (byte)m_godlevel;
2681 else
2682 cAgent.GodLevel = (byte) 0;
2683
2684 cAgent.AlwaysRun = m_setAlwaysRun;
2685
2686 //cAgent.AgentTextures = ???
2687 //cAgent.GroupID = ??
2688 // Groups???
2689
2690 // Animations???
2691
2692 cAgent.VisualParams = m_appearance.VisualParams;
2693 }
2694
2695 public void CopyFrom(AgentData cAgent)
2696 {
2697 m_rootRegionHandle= cAgent.RegionHandle;
2698 m_callbackURI = cAgent.CallbackURI;
2699
2700 m_pos = cAgent.Position;
2701 m_velocity = cAgent.Velocity;
2702 m_CameraCenter = cAgent.Center;
2703 m_avHeight = cAgent.Size.Z;
2704 m_CameraAtAxis = cAgent.AtAxis;
2705 m_CameraLeftAxis = cAgent.LeftAxis;
2706 m_CameraUpAxis = cAgent.UpAxis;
2707
2708 m_DrawDistance = cAgent.Far;
2709
2710 if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0)
2711 ControllingClient.SetChildAgentThrottle(cAgent.Throttles);
2712
2713 m_headrotation = cAgent.HeadRotation;
2714 m_bodyRot = cAgent.BodyRotation;
2715 m_AgentControlFlags = cAgent.ControlFlags; // We need more flags!
2716 if (m_physicsActor != null)
2717 {
2718 m_physicsActor.Flying = ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
2719 }
2720 if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID)))
2721 m_godlevel = cAgent.GodLevel;
2722 m_setAlwaysRun = cAgent.AlwaysRun;
2723
2724 //cAgent.AgentTextures = ???
2725
2726 //cAgent.GroupID = ??
2727 //Groups???
2728
2729 // Animations???
2730
2731 m_appearance.VisualParams = cAgent.VisualParams;
2732 }
2733
2734 #endregion Child Agent Updates
2735
2736 /// <summary>
2737 /// Handles part of the PID controller function for moving an avatar.
2738 /// </summary>
2739 public override void UpdateMovement()
2740 {
2741 m_newForce = false;
2742 lock (m_forcesList)
2743 {
2744 if (m_forcesList.Count > 0)
2745 {
2746 for (int i = 0; i < m_forcesList.Count; i++)
2747 {
2748 NewForce force = m_forcesList[i];
2749
2750 m_updateflag = true;
2751 try
2752 {
2753 movementvector.X = force.X;
2754 movementvector.Y = force.Y;
2755 movementvector.Z = force.Z;
2756 Velocity = movementvector;
2757 }
2758 catch (NullReferenceException)
2759 {
2760 // Under extreme load, this returns a NullReference Exception that we can ignore.
2761 // Ignoring this causes no movement to be sent to the physics engine...
2762 // which when the scene is moving at 1 frame every 10 seconds, it doesn't really matter!
2763 }
2764 m_newForce = true;
2765 }
2766 for (int i = 0; i < m_forcesList.Count; i++)
2767 {
2768 m_forcesList.RemoveAt(0);
2769 }
2770 }
2771 }
2772 }
2773
2774 static ScenePresence()
2775 {
2776 Primitive.TextureEntry textu = AvatarAppearance.GetDefaultTexture();
2777 DefaultTexture = textu.ToBytes();
2778 }
2779
2780 [Serializable]
2781 public class NewForce
2782 {
2783 public float X;
2784 public float Y;
2785 public float Z;
2786
2787 public NewForce()
2788 {
2789 }
2790 }
2791
2792 [Serializable]
2793 public class ScenePartUpdate : ISerializable
2794 {
2795 public UUID FullID;
2796 public uint LastFullUpdateTime;
2797 public uint LastTerseUpdateTime;
2798
2799 public ScenePartUpdate()
2800 {
2801 FullID = UUID.Zero;
2802 LastFullUpdateTime = 0;
2803 LastTerseUpdateTime = 0;
2804 }
2805
2806 protected ScenePartUpdate(SerializationInfo info, StreamingContext context)
2807 {
2808 //System.Console.WriteLine("ScenePartUpdate Deserialize BGN");
2809
2810 if (info == null)
2811 {
2812 throw new ArgumentNullException("info");
2813 }
2814
2815 FullID = new UUID((Guid)info.GetValue("FullID", typeof(Guid)));
2816 LastFullUpdateTime = (uint)info.GetValue("LastFullUpdateTime", typeof(uint));
2817 LastTerseUpdateTime = (uint)info.GetValue("LastTerseUpdateTime", typeof(uint));
2818
2819 //System.Console.WriteLine("ScenePartUpdate Deserialize END");
2820 }
2821
2822 [SecurityPermission(SecurityAction.LinkDemand,
2823 Flags = SecurityPermissionFlag.SerializationFormatter)]
2824 public virtual void GetObjectData(
2825 SerializationInfo info, StreamingContext context)
2826 {
2827 if (info == null)
2828 {
2829 throw new ArgumentNullException("info");
2830 }
2831
2832 info.AddValue("FullID", FullID.Guid);
2833 info.AddValue("LastFullUpdateTime", LastFullUpdateTime);
2834 info.AddValue("LastTerseUpdateTime", LastTerseUpdateTime);
2835 }
2836 }
2837
2838 public override void SetText(string text, Vector3 color, double alpha)
2839 {
2840 throw new Exception("Can't set Text on avatar.");
2841 }
2842
2843 /// <summary>
2844 /// Adds a physical representation of the avatar to the Physics plugin
2845 /// </summary>
2846 public void AddToPhysicalScene()
2847 {
2848 PhysicsScene scene = m_scene.PhysicsScene;
2849
2850 PhysicsVector pVec =
2851 new PhysicsVector(AbsolutePosition.X, AbsolutePosition.Y,
2852 AbsolutePosition.Z);
2853
2854 if (m_avHeight == 127.0f)
2855 {
2856 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, new PhysicsVector(0, 0, 1.56f));
2857 }
2858 else
2859 {
2860 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, new PhysicsVector(0, 0, m_avHeight));
2861 }
2862
2863 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
2864 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
2865 m_physicsActor.SubscribeEvents(1000);
2866 m_physicsActor.LocalID = LocalId;
2867 }
2868
2869 // Event called by the physics plugin to tell the avatar about a collision.
2870 private void PhysicsCollisionUpdate(EventArgs e)
2871 {
2872 if (e == null)
2873 return;
2874 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
2875 Dictionary<uint, float> coldata = collisionData.m_objCollisionList;
2876 float starthealth = Health;
2877 uint killerObj = 0;
2878 foreach (uint localid in coldata.Keys)
2879 {
2880 if (coldata[localid] <= 0.10f || m_invulnerable)
2881 continue;
2882 //if (localid == 0)
2883 //continue;
2884
2885 Health -= coldata[localid] * 5;
2886
2887 if (Health <= 0)
2888 {
2889 if (localid != 0)
2890 killerObj = localid;
2891 }
2892 //m_log.Debug("[AVATAR]: Collision with localid: " + localid.ToString() + " at depth: " + coldata[localid].ToString());
2893 }
2894 //Health = 100;
2895 if (!m_invulnerable)
2896 {
2897 if (starthealth != Health)
2898 {
2899 ControllingClient.SendHealth(Health);
2900 }
2901 if (m_health <= 0)
2902 m_scene.EventManager.TriggerAvatarKill(killerObj, this);
2903 }
2904
2905 if (Velocity.X > 0 || Velocity.Y > 0)
2906 UpdateMovementAnimations();
2907 }
2908
2909 public void setHealthWithUpdate(float health)
2910 {
2911 Health = health;
2912 ControllingClient.SendHealth(Health);
2913 }
2914
2915 public void Close()
2916 {
2917 lock (m_attachments)
2918 {
2919 // Delete attachments from scene
2920 // Don't try to save, as this thread won't live long
2921 // enough to complete the save. This would cause no copy
2922 // attachments to poof!
2923 //
2924 foreach (SceneObjectGroup grp in m_attachments)
2925 {
2926 m_scene.DeleteSceneObject(grp, false);
2927 }
2928 m_attachments.Clear();
2929 }
2930 lock (m_knownChildRegions)
2931 {
2932 m_knownChildRegions.Clear();
2933 }
2934 lock (m_updateTimes)
2935 {
2936 m_updateTimes.Clear();
2937 }
2938 lock (m_partsUpdateQueue)
2939 {
2940 m_partsUpdateQueue.Clear();
2941 }
2942
2943 RemoveFromPhysicalScene();
2944 GC.Collect();
2945 }
2946
2947 public ScenePresence()
2948 {
2949/* JB
2950 if (Animations == null)
2951 {
2952 Animations = new AvatarAnimations();
2953 Animations.LoadAnims();
2954 }
2955*/
2956 if (DefaultTexture == null)
2957 {
2958 Primitive.TextureEntry textu = AvatarAppearance.GetDefaultTexture();
2959 DefaultTexture = textu.ToBytes();
2960 }
2961 }
2962
2963 public void AddAttachment(SceneObjectGroup gobj)
2964 {
2965 lock (m_attachments)
2966 {
2967 m_attachments.Add(gobj);
2968 }
2969 }
2970
2971 public bool HasAttachments()
2972 {
2973 return m_attachments.Count > 0;
2974 }
2975
2976 public bool HasScriptedAttachments()
2977 {
2978 lock (m_attachments)
2979 {
2980 foreach (SceneObjectGroup gobj in m_attachments)
2981 {
2982 if (gobj != null)
2983 {
2984 if (gobj.RootPart.Inventory.ContainsScripts())
2985 return true;
2986 }
2987 }
2988 }
2989 return false;
2990 }
2991
2992 public void RemoveAttachment(SceneObjectGroup gobj)
2993 {
2994 lock (m_attachments)
2995 {
2996 if (m_attachments.Contains(gobj))
2997 {
2998 m_attachments.Remove(gobj);
2999 }
3000 }
3001 }
3002
3003 public bool ValidateAttachments()
3004 {
3005 lock (m_attachments)
3006 {
3007 // Validate
3008 foreach (SceneObjectGroup gobj in m_attachments)
3009 {
3010 if (gobj == null)
3011 return false;
3012
3013 if (gobj.IsDeleted)
3014 return false;
3015 }
3016 }
3017 return true;
3018 }
3019
3020 public bool CrossAttachmentsIntoNewRegion(ulong regionHandle, bool silent)
3021 {
3022 lock (m_attachments)
3023 {
3024 // Validate
3025 foreach (SceneObjectGroup gobj in m_attachments)
3026 {
3027 if (gobj == null || gobj.IsDeleted)
3028 return false;
3029 }
3030
3031 foreach (SceneObjectGroup gobj in m_attachments)
3032 {
3033 // If the prim group is null then something must have happened to it!
3034 if (gobj != null && gobj.RootPart != null)
3035 {
3036 // Set the parent localID to 0 so it transfers over properly.
3037 gobj.RootPart.SetParentLocalId(0);
3038 gobj.RootPart.IsAttachment = false;
3039 gobj.AbsolutePosition = gobj.RootPart.AttachedPos;
3040 gobj.RootPart.LastOwnerID = gobj.GetFromAssetID();
3041 m_log.DebugFormat("[ATTACHMENT]: Sending attachment {0} to region {1}", gobj.UUID, regionHandle);
3042 m_scene.CrossPrimGroupIntoNewRegion(regionHandle, gobj, silent);
3043 }
3044 }
3045 m_attachments.Clear();
3046
3047 return true;
3048 }
3049 }
3050
3051 public void initializeScenePresence(IClientAPI client, RegionInfo region, Scene scene)
3052 {
3053 m_controllingClient = client;
3054 m_regionInfo = region;
3055 m_scene = scene;
3056
3057 RegisterToEvents();
3058
3059 /*
3060 AbsolutePosition = client.StartPos;
3061
3062 Animations = new AvatarAnimations();
3063 Animations.LoadAnims();
3064
3065 m_animations = new List<UUID>();
3066 m_animations.Add(Animations.AnimsUUID["STAND"]);
3067 m_animationSeqs.Add(m_controllingClient.NextAnimationSequenceNumber);
3068
3069 SetDirectionVectors();
3070 */
3071 }
3072
3073 protected ScenePresence(SerializationInfo info, StreamingContext context)
3074 : base (info, context)
3075 {
3076 //System.Console.WriteLine("ScenePresence Deserialize BGN");
3077
3078 if (info == null)
3079 {
3080 throw new ArgumentNullException("info");
3081 }
3082/* JB
3083 if (Animations == null)
3084 {
3085 Animations = new AvatarAnimations();
3086 Animations.LoadAnims();
3087 }
3088*/
3089 if (DefaultTexture == null)
3090 {
3091 Primitive.TextureEntry textu = AvatarAppearance.GetDefaultTexture();
3092 DefaultTexture = textu.ToBytes();
3093 }
3094
3095 m_animations = (AnimationSet)info.GetValue("m_animations", typeof(AnimationSet));
3096 m_updateflag = (bool)info.GetValue("m_updateflag", typeof(bool));
3097 m_movementflag = (byte)info.GetValue("m_movementflag", typeof(byte));
3098 m_forcesList = (List<NewForce>)info.GetValue("m_forcesList", typeof(List<NewForce>));
3099 m_updateCount = (short)info.GetValue("m_updateCount", typeof(short));
3100 m_requestedSitTargetID = (uint)info.GetValue("m_requestedSitTargetID", typeof(uint));
3101
3102 m_requestedSitOffset
3103 = new Vector3(
3104 (float)info.GetValue("m_requestedSitOffset.X", typeof(float)),
3105 (float)info.GetValue("m_requestedSitOffset.Y", typeof(float)),
3106 (float)info.GetValue("m_requestedSitOffset.Z", typeof(float)));
3107
3108 m_sitAvatarHeight = (float)info.GetValue("m_sitAvatarHeight", typeof(float));
3109 m_godlevel = (float)info.GetValue("m_godlevel", typeof(float));
3110 m_setAlwaysRun = (bool)info.GetValue("m_setAlwaysRun", typeof(bool));
3111
3112 m_bodyRot
3113 = new Quaternion(
3114 (float)info.GetValue("m_bodyRot.X", typeof(float)),
3115 (float)info.GetValue("m_bodyRot.Y", typeof(float)),
3116 (float)info.GetValue("m_bodyRot.Z", typeof(float)),
3117 (float)info.GetValue("m_bodyRot.W", typeof(float)));
3118
3119 IsRestrictedToRegion = (bool)info.GetValue("IsRestrictedToRegion", typeof(bool));
3120 m_newForce = (bool)info.GetValue("m_newForce", typeof(bool));
3121 //m_newAvatar = (bool)info.GetValue("m_newAvatar", typeof(bool));
3122 m_newCoarseLocations = (bool)info.GetValue("m_newCoarseLocations", typeof(bool));
3123 m_avHeight = (float)info.GetValue("m_avHeight", typeof(float));
3124 crossingFromRegion = (ulong)info.GetValue("crossingFromRegion", typeof(ulong));
3125
3126 List<float[]> Dir_Vectors_work = (List<float[]>)info.GetValue("Dir_Vectors", typeof(List<float[]>));
3127 List<Vector3> Dir_Vectors_work2 = new List<Vector3>();
3128
3129 foreach (float[] f3 in Dir_Vectors_work)
3130 {
3131 Dir_Vectors_work2.Add(new Vector3(f3[0], f3[1], f3[2]));
3132 }
3133
3134 Dir_Vectors = Dir_Vectors_work2.ToArray();
3135
3136 lastPhysPos
3137 = new Vector3(
3138 (float)info.GetValue("lastPhysPos.X", typeof(float)),
3139 (float)info.GetValue("lastPhysPos.Y", typeof(float)),
3140 (float)info.GetValue("lastPhysPos.Z", typeof(float)));
3141
3142 // Possibly we should store lastPhysRot. But there may well be not much point since rotation changes
3143 // wouldn't carry us across borders anyway
3144
3145 m_CameraCenter
3146 = new Vector3(
3147 (float)info.GetValue("m_CameraCenter.X", typeof(float)),
3148 (float)info.GetValue("m_CameraCenter.Y", typeof(float)),
3149 (float)info.GetValue("m_CameraCenter.Z", typeof(float)));
3150
3151 m_CameraAtAxis
3152 = new Vector3(
3153 (float)info.GetValue("m_CameraAtAxis.X", typeof(float)),
3154 (float)info.GetValue("m_CameraAtAxis.Y", typeof(float)),
3155 (float)info.GetValue("m_CameraAtAxis.Z", typeof(float)));
3156
3157 m_CameraLeftAxis
3158 = new Vector3(
3159 (float)info.GetValue("m_CameraLeftAxis.X", typeof(float)),
3160 (float)info.GetValue("m_CameraLeftAxis.Y", typeof(float)),
3161 (float)info.GetValue("m_CameraLeftAxis.Z", typeof(float)));
3162
3163 m_CameraUpAxis
3164 = new Vector3(
3165 (float)info.GetValue("m_CameraUpAxis.X", typeof(float)),
3166 (float)info.GetValue("m_CameraUpAxis.Y", typeof(float)),
3167 (float)info.GetValue("m_CameraUpAxis.Z", typeof(float)));
3168
3169 m_DrawDistance = (float)info.GetValue("m_DrawDistance", typeof(float));
3170 m_appearance = (AvatarAppearance)info.GetValue("m_appearance", typeof(AvatarAppearance));
3171
3172 m_knownChildRegions = (Dictionary<ulong, string>)info.GetValue("m_knownChildRegions", typeof(Dictionary<ulong, string>));
3173
3174 posLastSignificantMove
3175 = new Vector3(
3176 (float)info.GetValue("posLastSignificantMove.X", typeof(float)),
3177 (float)info.GetValue("posLastSignificantMove.Y", typeof(float)),
3178 (float)info.GetValue("posLastSignificantMove.Z", typeof(float)));
3179
3180 // m_partsUpdateQueue = (UpdateQueue)info.GetValue("m_partsUpdateQueue", typeof(UpdateQueue));
3181
3182 /*
3183 Dictionary<Guid, ScenePartUpdate> updateTimes_work
3184 = (Dictionary<Guid, ScenePartUpdate>)info.GetValue("m_updateTimes", typeof(Dictionary<Guid, ScenePartUpdate>));
3185
3186 foreach (Guid id in updateTimes_work.Keys)
3187 {
3188 m_updateTimes.Add(new UUID(id), updateTimes_work[id]);
3189 }
3190 */
3191 m_regionHandle = (ulong)info.GetValue("m_regionHandle", typeof(ulong));
3192 m_firstname = (string)info.GetValue("m_firstname", typeof(string));
3193 m_lastname = (string)info.GetValue("m_lastname", typeof(string));
3194 m_allowMovement = (bool)info.GetValue("m_allowMovement", typeof(bool));
3195 m_parentPosition = new Vector3((float)info.GetValue("m_parentPosition.X", typeof(float)),
3196 (float)info.GetValue("m_parentPosition.Y", typeof(float)),
3197 (float)info.GetValue("m_parentPosition.Z", typeof(float)));
3198
3199 m_isChildAgent = (bool)info.GetValue("m_isChildAgent", typeof(bool));
3200 m_parentID = (uint)info.GetValue("m_parentID", typeof(uint));
3201
3202// for OpenSim_v0.5
3203 currentParcelUUID = new UUID((Guid)info.GetValue("currentParcelUUID", typeof(Guid)));
3204
3205 lastKnownAllowedPosition
3206 = new Vector3(
3207 (float)info.GetValue("lastKnownAllowedPosition.X", typeof(float)),
3208 (float)info.GetValue("lastKnownAllowedPosition.Y", typeof(float)),
3209 (float)info.GetValue("lastKnownAllowedPosition.Z", typeof(float)));
3210
3211 sentMessageAboutRestrictedParcelFlyingDown = (bool)info.GetValue("sentMessageAboutRestrictedParcelFlyingDown", typeof(bool));
3212
3213 m_LastChildAgentUpdatePosition
3214 = new Vector3(
3215 (float)info.GetValue("m_LastChildAgentUpdatePosition.X", typeof(float)),
3216 (float)info.GetValue("m_LastChildAgentUpdatePosition.Y", typeof(float)),
3217 (float)info.GetValue("m_LastChildAgentUpdatePosition.Z", typeof(float)));
3218
3219 m_perfMonMS = (int)info.GetValue("m_perfMonMS", typeof(int));
3220 m_AgentControlFlags = (uint)info.GetValue("m_AgentControlFlags", typeof(uint));
3221
3222 m_headrotation
3223 = new Quaternion(
3224 (float)info.GetValue("m_headrotation.X", typeof(float)),
3225 (float)info.GetValue("m_headrotation.Y", typeof(float)),
3226 (float)info.GetValue("m_headrotation.Z", typeof(float)),
3227 (float)info.GetValue("m_headrotation.W", typeof(float)));
3228
3229 m_state = (byte)info.GetValue("m_state", typeof(byte));
3230
3231 //System.Console.WriteLine("ScenePresence Deserialize END");
3232 }
3233
3234 [SecurityPermission(SecurityAction.LinkDemand,
3235 Flags = SecurityPermissionFlag.SerializationFormatter)]
3236 public override void GetObjectData(
3237 SerializationInfo info, StreamingContext context)
3238 {
3239 if (info == null)
3240 {
3241 throw new ArgumentNullException("info");
3242 }
3243
3244 base.GetObjectData(info, context);
3245
3246 info.AddValue("m_animations", m_animations);
3247 info.AddValue("m_updateflag", m_updateflag);
3248 info.AddValue("m_movementflag", m_movementflag);
3249 info.AddValue("m_forcesList", m_forcesList);
3250 info.AddValue("m_updateCount", m_updateCount);
3251 info.AddValue("m_requestedSitTargetID", m_requestedSitTargetID);
3252
3253 // Vector3
3254 info.AddValue("m_requestedSitOffset.X", m_requestedSitOffset.X);
3255 info.AddValue("m_requestedSitOffset.Y", m_requestedSitOffset.Y);
3256 info.AddValue("m_requestedSitOffset.Z", m_requestedSitOffset.Z);
3257
3258 info.AddValue("m_sitAvatarHeight", m_sitAvatarHeight);
3259 info.AddValue("m_godlevel", m_godlevel);
3260 info.AddValue("m_setAlwaysRun", m_setAlwaysRun);
3261
3262 // Quaternion
3263 info.AddValue("m_bodyRot.X", m_bodyRot.X);
3264 info.AddValue("m_bodyRot.Y", m_bodyRot.Y);
3265 info.AddValue("m_bodyRot.Z", m_bodyRot.Z);
3266 info.AddValue("m_bodyRot.W", m_bodyRot.W);
3267
3268 info.AddValue("IsRestrictedToRegion", IsRestrictedToRegion);
3269 info.AddValue("m_newForce", m_newForce);
3270 //info.AddValue("m_newAvatar", m_newAvatar);
3271 info.AddValue("m_newCoarseLocations", m_newCoarseLocations);
3272 info.AddValue("m_gotAPrimitivesInScene", false);
3273 info.AddValue("m_avHeight", m_avHeight);
3274
3275 // info.AddValue("m_regionInfo", m_regionInfo);
3276
3277 info.AddValue("crossingFromRegion", crossingFromRegion);
3278
3279 List<float[]> Dir_Vectors_work = new List<float[]>();
3280
3281 foreach (Vector3 v3 in Dir_Vectors)
3282 {
3283 Dir_Vectors_work.Add(new float[] { v3.X, v3.Y, v3.Z });
3284 }
3285
3286 info.AddValue("Dir_Vectors", Dir_Vectors_work);
3287
3288 // Vector3
3289 info.AddValue("lastPhysPos.X", lastPhysPos.X);
3290 info.AddValue("lastPhysPos.Y", lastPhysPos.Y);
3291 info.AddValue("lastPhysPos.Z", lastPhysPos.Z);
3292
3293 // Possibly we should retrieve lastPhysRot. But there may well be not much point since rotation changes
3294 // wouldn't carry us across borders anyway
3295
3296 // Vector3
3297 info.AddValue("m_CameraCenter.X", m_CameraCenter.X);
3298 info.AddValue("m_CameraCenter.Y", m_CameraCenter.Y);
3299 info.AddValue("m_CameraCenter.Z", m_CameraCenter.Z);
3300
3301 // Vector3
3302 info.AddValue("m_CameraAtAxis.X", m_CameraAtAxis.X);
3303 info.AddValue("m_CameraAtAxis.Y", m_CameraAtAxis.Y);
3304 info.AddValue("m_CameraAtAxis.Z", m_CameraAtAxis.Z);
3305
3306 // Vector3
3307 info.AddValue("m_CameraLeftAxis.X", m_CameraLeftAxis.X);
3308 info.AddValue("m_CameraLeftAxis.Y", m_CameraLeftAxis.Y);
3309 info.AddValue("m_CameraLeftAxis.Z", m_CameraLeftAxis.Z);
3310
3311 // Vector3
3312 info.AddValue("m_CameraUpAxis.X", m_CameraUpAxis.X);
3313 info.AddValue("m_CameraUpAxis.Y", m_CameraUpAxis.Y);
3314 info.AddValue("m_CameraUpAxis.Z", m_CameraUpAxis.Z);
3315
3316 info.AddValue("m_DrawDistance", m_DrawDistance);
3317 info.AddValue("m_appearance", m_appearance);
3318 info.AddValue("m_knownChildRegions", m_knownChildRegions);
3319
3320 // Vector3
3321 info.AddValue("posLastSignificantMove.X", posLastSignificantMove.X);
3322 info.AddValue("posLastSignificantMove.Y", posLastSignificantMove.Y);
3323 info.AddValue("posLastSignificantMove.Z", posLastSignificantMove.Z);
3324
3325 //info.AddValue("m_partsUpdateQueue", m_partsUpdateQueue);
3326
3327 /*
3328 Dictionary<Guid, ScenePartUpdate> updateTimes_work = new Dictionary<Guid, ScenePartUpdate>();
3329
3330 foreach (UUID id in m_updateTimes.Keys)
3331 {
3332 updateTimes_work.Add(id.UUID, m_updateTimes[id]);
3333 }
3334
3335 info.AddValue("m_updateTimes", updateTimes_work);
3336 */
3337
3338 info.AddValue("m_regionHandle", m_regionHandle);
3339 info.AddValue("m_firstname", m_firstname);
3340 info.AddValue("m_lastname", m_lastname);
3341 info.AddValue("m_allowMovement", m_allowMovement);
3342 //info.AddValue("m_physicsActor", m_physicsActor);
3343 info.AddValue("m_parentPosition.X", m_parentPosition.X);
3344 info.AddValue("m_parentPosition.Y", m_parentPosition.Y);
3345 info.AddValue("m_parentPosition.Z", m_parentPosition.Z);
3346 info.AddValue("m_isChildAgent", m_isChildAgent);
3347 info.AddValue("m_parentID", m_parentID);
3348
3349// for OpenSim_v0.5
3350 info.AddValue("currentParcelUUID", currentParcelUUID.Guid);
3351
3352 info.AddValue("lastKnownAllowedPosition.X", lastKnownAllowedPosition.X);
3353 info.AddValue("lastKnownAllowedPosition.Y", lastKnownAllowedPosition.Y);
3354 info.AddValue("lastKnownAllowedPosition.Z", lastKnownAllowedPosition.Z);
3355
3356 info.AddValue("sentMessageAboutRestrictedParcelFlyingDown", sentMessageAboutRestrictedParcelFlyingDown);
3357
3358 info.AddValue("m_LastChildAgentUpdatePosition.X", m_LastChildAgentUpdatePosition.X);
3359 info.AddValue("m_LastChildAgentUpdatePosition.Y", m_LastChildAgentUpdatePosition.Y);
3360 info.AddValue("m_LastChildAgentUpdatePosition.Z", m_LastChildAgentUpdatePosition.Z);
3361
3362 info.AddValue("m_perfMonMS", m_perfMonMS);
3363 info.AddValue("m_AgentControlFlags", m_AgentControlFlags);
3364
3365 info.AddValue("m_headrotation.W", m_headrotation.W);
3366 info.AddValue("m_headrotation.X", m_headrotation.X);
3367 info.AddValue("m_headrotation.Y", m_headrotation.Y);
3368 info.AddValue("m_headrotation.Z", m_headrotation.Z);
3369
3370 info.AddValue("m_state", m_state);
3371
3372 List<Guid> knownPrimUUID_work = new List<Guid>();
3373
3374 info.AddValue("m_knownPrimUUID", knownPrimUUID_work);
3375 }
3376
3377 internal void PushForce(PhysicsVector impulse)
3378 {
3379 if (PhysicsActor != null)
3380 {
3381 PhysicsActor.AddForce(impulse,true);
3382 }
3383 }
3384
3385 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID)
3386 {
3387 ScriptControllers obj = new ScriptControllers();
3388 obj.ignoreControls = ScriptControlled.CONTROL_ZERO;
3389 obj.eventControls = ScriptControlled.CONTROL_ZERO;
3390
3391 obj.itemID = Script_item_UUID;
3392 obj.objID = Obj_localID;
3393 if (pass_on == 0 && accept == 0)
3394 {
3395 IgnoredControls |= (ScriptControlled)controls;
3396 obj.ignoreControls = (ScriptControlled)controls;
3397 }
3398
3399 if (pass_on == 0 && accept == 1)
3400 {
3401 IgnoredControls |= (ScriptControlled)controls;
3402 obj.ignoreControls = (ScriptControlled)controls;
3403 obj.eventControls = (ScriptControlled)controls;
3404 }
3405 if (pass_on == 1 && accept == 1)
3406 {
3407 IgnoredControls = ScriptControlled.CONTROL_ZERO;
3408 obj.eventControls = (ScriptControlled)controls;
3409 obj.ignoreControls = ScriptControlled.CONTROL_ZERO;
3410 }
3411
3412 lock (scriptedcontrols)
3413 {
3414 if (pass_on == 1 && accept == 0)
3415 {
3416 IgnoredControls &= ~(ScriptControlled)controls;
3417 if (scriptedcontrols.ContainsKey(Script_item_UUID))
3418 scriptedcontrols.Remove(Script_item_UUID);
3419
3420 }
3421 else
3422 {
3423
3424 if (scriptedcontrols.ContainsKey(Script_item_UUID))
3425 {
3426 scriptedcontrols[Script_item_UUID] = obj;
3427 }
3428 else
3429 {
3430 scriptedcontrols.Add(Script_item_UUID, obj);
3431 }
3432 }
3433 }
3434 ControllingClient.SendTakeControls(controls, pass_on == 1 ? true : false, true);
3435 }
3436
3437 public void HandleForceReleaseControls(IClientAPI remoteClient, UUID agentID)
3438 {
3439 IgnoredControls = ScriptControlled.CONTROL_ZERO;
3440 lock (scriptedcontrols)
3441 {
3442 scriptedcontrols.Clear();
3443 }
3444 ControllingClient.SendTakeControls(int.MaxValue, false, false);
3445 }
3446
3447 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID)
3448 {
3449 lock (scriptedcontrols)
3450 {
3451 if (scriptedcontrols.ContainsKey(Script_item_UUID))
3452 {
3453 ScriptControllers takecontrolls = scriptedcontrols[Script_item_UUID];
3454 ScriptControlled sctc = takecontrolls.eventControls;
3455 ControllingClient.SendTakeControls((int)sctc, false, false);
3456 ControllingClient.SendTakeControls((int)sctc, true, false);
3457
3458 scriptedcontrols.Remove(Script_item_UUID);
3459 IgnoredControls = ScriptControlled.CONTROL_ZERO;
3460 foreach (ScriptControllers scData in scriptedcontrols.Values)
3461 {
3462 IgnoredControls |= scData.ignoreControls;
3463 }
3464 }
3465
3466 }
3467 }
3468
3469 internal void SendControlToScripts(uint flags)
3470 {
3471
3472 ScriptControlled allflags = ScriptControlled.CONTROL_ZERO;
3473
3474 if (MouseDown)
3475 {
3476 allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON);
3477 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 || (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0)
3478 {
3479 allflags = ScriptControlled.CONTROL_ZERO;
3480 MouseDown = true;
3481 }
3482 }
3483
3484 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0)
3485 {
3486 allflags |= ScriptControlled.CONTROL_ML_LBUTTON;
3487 MouseDown = true;
3488 }
3489 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0)
3490 {
3491 allflags |= ScriptControlled.CONTROL_LBUTTON;
3492 MouseDown = true;
3493 }
3494
3495 // find all activated controls, whether the scripts are interested in them or not
3496 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) != 0)
3497 {
3498 allflags |= ScriptControlled.CONTROL_FWD;
3499 }
3500 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) != 0)
3501 {
3502 allflags |= ScriptControlled.CONTROL_BACK;
3503 }
3504 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS) != 0)
3505 {
3506 allflags |= ScriptControlled.CONTROL_UP;
3507 }
3508 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)
3509 {
3510 allflags |= ScriptControlled.CONTROL_DOWN;
3511 }
3512 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) != 0)
3513 {
3514 allflags |= ScriptControlled.CONTROL_LEFT;
3515 }
3516 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) != 0)
3517 {
3518 allflags |= ScriptControlled.CONTROL_RIGHT;
3519 }
3520 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
3521 {
3522 allflags |= ScriptControlled.CONTROL_ROT_RIGHT;
3523 }
3524 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0)
3525 {
3526 allflags |= ScriptControlled.CONTROL_ROT_LEFT;
3527 }
3528 // optimization; we have to check per script, but if nothing is pressed and nothing changed, we can skip that
3529 if (allflags != ScriptControlled.CONTROL_ZERO || allflags != LastCommands)
3530 {
3531 lock (scriptedcontrols)
3532 {
3533 foreach (UUID scriptUUID in scriptedcontrols.Keys)
3534 {
3535 ScriptControllers scriptControlData = scriptedcontrols[scriptUUID];
3536 ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us
3537 ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle
3538 ScriptControlled localChange = localHeld ^ localLast; // the changed bits
3539 if (localHeld != ScriptControlled.CONTROL_ZERO || localChange != ScriptControlled.CONTROL_ZERO)
3540 {
3541 // only send if still pressed or just changed
3542 m_scene.EventManager.TriggerControlEvent(scriptControlData.objID, scriptUUID, UUID, (uint)localHeld, (uint)localChange);
3543 }
3544 }
3545 }
3546 }
3547
3548 LastCommands = allflags;
3549 }
3550
3551 internal uint RemoveIgnoredControls(uint flags, ScriptControlled Ignored)
3552 {
3553 if (Ignored == ScriptControlled.CONTROL_ZERO)
3554 return flags;
3555 if ((Ignored & ScriptControlled.CONTROL_BACK) != 0)
3556 flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG);
3557 if ((Ignored & ScriptControlled.CONTROL_FWD) != 0)
3558 flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS | (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS);
3559 if ((Ignored & ScriptControlled.CONTROL_DOWN) != 0)
3560 flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG | (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG);
3561 if ((Ignored & ScriptControlled.CONTROL_UP) != 0)
3562 flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS | (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS);
3563 if ((Ignored & ScriptControlled.CONTROL_LEFT) != 0)
3564 flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS);
3565 if ((Ignored & ScriptControlled.CONTROL_RIGHT) != 0)
3566 flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG | (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG);
3567 if ((Ignored & ScriptControlled.CONTROL_ROT_LEFT) != 0)
3568 flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG);
3569 if ((Ignored & ScriptControlled.CONTROL_ROT_RIGHT) != 0)
3570 flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS);
3571 if ((Ignored & ScriptControlled.CONTROL_ML_LBUTTON) != 0)
3572 flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN);
3573 if ((Ignored & ScriptControlled.CONTROL_LBUTTON) != 0)
3574 flags &= ~((uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP | (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN);
3575 //DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS,
3576 //DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG,
3577 //DIR_CONTROL_FLAG_LEFT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS,
3578 //DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG,
3579 //DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
3580 //DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
3581 //DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
3582 return flags;
3583 }
3584
3585 private void ItemReceived(UUID itemID)
3586 {
3587 if (IsChildAgent)
3588 return;
3589
3590 if (null == m_appearance)
3591 {
3592 m_log.Warn("[ATTACHMENT] Appearance has not been initialized");
3593 return;
3594 }
3595
3596 int attachpoint = m_appearance.GetAttachpoint(itemID);
3597 if (attachpoint == 0)
3598 return;
3599
3600 UUID asset = m_appearance.GetAttachedAsset(attachpoint);
3601 if (UUID.Zero == asset) // We have just logged in
3602 {
3603 try
3604 {
3605 // Rez from inventory
3606 asset = m_scene.RezSingleAttachment(ControllingClient,
3607 itemID, (uint)attachpoint);
3608 // Corner case: We are not yet a Scene Entity
3609 // Setting attachment info in RezSingleAttachment will fail
3610 // Set it here
3611 //
3612 m_appearance.SetAttachment((int)attachpoint, itemID,
3613 asset);
3614 m_log.InfoFormat("[ATTACHMENT] Rezzed attachment {0}, inworld asset {1}",
3615 itemID.ToString(), asset);
3616
3617 }
3618 catch (Exception e)
3619 {
3620 m_log.ErrorFormat("[ATTACHMENT] Unable to rez attachment: {0}", e.ToString());
3621 }
3622
3623 return;
3624 }
3625
3626 SceneObjectPart att = m_scene.GetSceneObjectPart(asset);
3627
3628
3629 // If this is null, then the asset has not yet appeared in world
3630 // so we revisit this when it does
3631 //
3632 if (att != null && att.UUID != asset) // Yes. It's really needed
3633 {
3634 m_log.DebugFormat("[ATTACHMENT]: Attach from in world: ItemID {0}, Asset ID {1}, Attachment inworld: {2}", itemID.ToString(), asset.ToString(), att.UUID.ToString());
3635
3636 // This will throw if crossing katty-korner
3637 // So catch it here to avoid the noid
3638 //
3639 try
3640 {
3641 // Attach from world, if not already attached
3642 if (att.ParentGroup != null && !att.IsAttachment)
3643 m_scene.AttachObject(ControllingClient, att.ParentGroup.LocalId, (uint)0, Quaternion.Identity, att.ParentGroup.AbsolutePosition, false);
3644 }
3645 catch (NullReferenceException)
3646 {
3647 }
3648 }
3649 }
3650 }
3651}