aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs6
-rw-r--r--OpenSim/Region/Framework/Interfaces/IBakedTextureModule.cs40
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs32
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs196
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs1008
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs14
6 files changed, 924 insertions, 372 deletions
diff --git a/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs b/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs
index 34aca33..d25c930 100644
--- a/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs
@@ -35,8 +35,8 @@ namespace OpenSim.Region.Framework.Interfaces
35 35
36 public interface IAvatarFactoryModule 36 public interface IAvatarFactoryModule
37 { 37 {
38 void SetAppearance(IScenePresence sp, AvatarAppearance appearance); 38 void SetAppearance(IScenePresence sp, AvatarAppearance appearance, WearableCacheItem[] cacheItems);
39 void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams); 39 void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, WearableCacheItem[] cacheItems);
40 40
41 /// <summary> 41 /// <summary>
42 /// Send the appearance of an avatar to others in the scene. 42 /// Send the appearance of an avatar to others in the scene.
@@ -52,6 +52,8 @@ namespace OpenSim.Region.Framework.Interfaces
52 /// <returns>An empty list if this agent has no baked textures (e.g. because it's a child agent)</returns> 52 /// <returns>An empty list if this agent has no baked textures (e.g. because it's a child agent)</returns>
53 Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(UUID agentId); 53 Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(UUID agentId);
54 54
55
56 WearableCacheItem[] GetCachedItems(UUID agentId);
55 /// <summary> 57 /// <summary>
56 /// Save the baked textures for the given agent permanently in the asset database. 58 /// Save the baked textures for the given agent permanently in the asset database.
57 /// </summary> 59 /// </summary>
diff --git a/OpenSim/Region/Framework/Interfaces/IBakedTextureModule.cs b/OpenSim/Region/Framework/Interfaces/IBakedTextureModule.cs
new file mode 100644
index 0000000..b536a49
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IBakedTextureModule.cs
@@ -0,0 +1,40 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using Nini.Config;
30using OpenSim.Framework;
31using OpenMetaverse;
32
33namespace OpenSim.Services.Interfaces
34{
35 public interface IBakedTextureModule
36 {
37 WearableCacheItem[] Get(UUID id);
38 void Store(UUID id, WearableCacheItem[] data);
39 }
40}
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
index 1c43a25..1949a90 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
@@ -35,6 +35,8 @@ using OpenSim.Region.Framework.Scenes;
35 35
36namespace OpenSim.Region.Framework.Interfaces 36namespace OpenSim.Region.Framework.Interfaces
37{ 37{
38 public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version);
39
38 public interface IEntityTransferModule 40 public interface IEntityTransferModule
39 { 41 {
40 /// <summary> 42 /// <summary>
@@ -50,30 +52,11 @@ namespace OpenSim.Region.Framework.Interfaces
50 /// <param name='teleportFlags'></param> 52 /// <param name='teleportFlags'></param>
51 void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags); 53 void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags);
52 54
53 /// <summary>
54 /// Teleport an agent directly to a given region without checking whether the region should be subsituted.
55 /// </summary>
56 /// <remarks>
57 /// Please use Teleport() instead unless you know exactly what you're doing.
58 /// Do not use for same region teleports.
59 /// </remarks>
60 /// <param name='sp'></param>
61 /// <param name='reg'></param>
62 /// <param name='finalDestination'>/param>
63 /// <param name='position'></param>
64 /// <param name='lookAt'></param>
65 /// <param name='teleportFlags'></param>
66 void DoTeleport(
67 ScenePresence sp, GridRegion reg, GridRegion finalDestination,
68 Vector3 position, Vector3 lookAt, uint teleportFlags);
69
70 /// <summary>
71 /// Teleports the agent for the given client to their home destination.
72 /// </summary>
73 /// <param name='id'></param>
74 /// <param name='client'></param>
75 bool TeleportHome(UUID id, IClientAPI client); 55 bool TeleportHome(UUID id, IClientAPI client);
76 56
57 void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination,
58 Vector3 position, Vector3 lookAt, uint teleportFlags);
59
77 /// <summary> 60 /// <summary>
78 /// Show whether the given agent is being teleported. 61 /// Show whether the given agent is being teleported.
79 /// </summary> 62 /// </summary>
@@ -89,7 +72,12 @@ namespace OpenSim.Region.Framework.Interfaces
89 72
90 void EnableChildAgent(ScenePresence agent, GridRegion region); 73 void EnableChildAgent(ScenePresence agent, GridRegion region);
91 74
75 GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos);
76
92 void Cross(SceneObjectGroup sog, Vector3 position, bool silent); 77 void Cross(SceneObjectGroup sog, Vector3 position, bool silent);
78
79 ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version);
80
93 } 81 }
94 82
95 public interface IUserAgentVerificationModule 83 public interface IUserAgentVerificationModule
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 4b4e4ba..a2e4417 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -118,6 +118,7 @@ namespace OpenSim.Region.Framework.Scenes
118 private bool m_hasGroupChanged = false; 118 private bool m_hasGroupChanged = false;
119 private long timeFirstChanged; 119 private long timeFirstChanged;
120 private long timeLastChanged; 120 private long timeLastChanged;
121 private List<ScenePresence> m_linkedAvatars = new List<ScenePresence>();
121 122
122 /// <summary> 123 /// <summary>
123 /// This indicates whether the object has changed such that it needs to be repersisted to permenant storage 124 /// This indicates whether the object has changed such that it needs to be repersisted to permenant storage
@@ -428,6 +429,12 @@ namespace OpenSim.Region.Framework.Scenes
428 return (IsAttachment || (m_rootPart.Shape.PCode == 9 && m_rootPart.Shape.State != 0)); 429 return (IsAttachment || (m_rootPart.Shape.PCode == 9 && m_rootPart.Shape.State != 0));
429 } 430 }
430 431
432 private struct avtocrossInfo
433 {
434 public ScenePresence av;
435 public uint ParentID;
436 }
437
431 /// <summary> 438 /// <summary>
432 /// The absolute position of this scene object in the scene 439 /// The absolute position of this scene object in the scene
433 /// </summary> 440 /// </summary>
@@ -455,13 +462,124 @@ namespace OpenSim.Region.Framework.Scenes
455 || Scene.TestBorderCross(val, Cardinals.S)) 462 || Scene.TestBorderCross(val, Cardinals.S))
456 && !IsAttachmentCheckFull() && (!Scene.LoadingPrims)) 463 && !IsAttachmentCheckFull() && (!Scene.LoadingPrims))
457 { 464 {
465 IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
466 uint x = 0;
467 uint y = 0;
468 string version = String.Empty;
469 Vector3 newpos = Vector3.Zero;
470 OpenSim.Services.Interfaces.GridRegion destination = null;
471
458 if (m_rootPart.KeyframeMotion != null) 472 if (m_rootPart.KeyframeMotion != null)
459 m_rootPart.KeyframeMotion.StartCrossingCheck(); 473 m_rootPart.KeyframeMotion.StartCrossingCheck();
460 474
461 m_scene.CrossPrimGroupIntoNewRegion(val, this, true); 475 bool canCross = true;
476 foreach (ScenePresence av in m_linkedAvatars)
477 {
478 // We need to cross these agents. First, let's find
479 // out if any of them can't cross for some reason.
480 // We have to deny the crossing entirely if any
481 // of them are banned. Alternatively, we could
482 // unsit banned agents....
483
484
485 // We set the avatar position as being the object
486 // position to get the region to send to
487 if ((destination = entityTransfer.GetDestination(m_scene, av.UUID, val, out x, out y, out version, out newpos)) == null)
488 {
489 canCross = false;
490 break;
491 }
492
493 m_log.DebugFormat("[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName);
494 }
495
496 if (canCross)
497 {
498 // We unparent the SP quietly so that it won't
499 // be made to stand up
500
501 List<avtocrossInfo> avsToCross = new List<avtocrossInfo>();
502
503 foreach (ScenePresence av in m_linkedAvatars)
504 {
505 avtocrossInfo avinfo = new avtocrossInfo();
506 SceneObjectPart parentPart = m_scene.GetSceneObjectPart(av.ParentID);
507 if (parentPart != null)
508 av.ParentUUID = parentPart.UUID;
509
510 avinfo.av = av;
511 avinfo.ParentID = av.ParentID;
512 avsToCross.Add(avinfo);
513
514 av.PrevSitOffset = av.OffsetPosition;
515 av.ParentID = 0;
516 }
517
518 // m_linkedAvatars.Clear();
519 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
520
521 // Normalize
522 if (val.X >= Constants.RegionSize)
523 val.X -= Constants.RegionSize;
524 if (val.Y >= Constants.RegionSize)
525 val.Y -= Constants.RegionSize;
526 if (val.X < 0)
527 val.X += Constants.RegionSize;
528 if (val.Y < 0)
529 val.Y += Constants.RegionSize;
530
531 // If it's deleted, crossing was successful
532 if (IsDeleted)
533 {
534 // foreach (ScenePresence av in m_linkedAvatars)
535 foreach (avtocrossInfo avinfo in avsToCross)
536 {
537 ScenePresence av = avinfo.av;
538 if (!av.IsInTransit) // just in case...
539 {
540 m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val);
541
542 av.IsInTransit = true;
543
544 CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync;
545 d.BeginInvoke(av, val, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d);
546 }
547 else
548 m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar alreasy in transit {0} to {1}", av.Name, val);
549 }
550 avsToCross.Clear();
551 return;
552 }
553 else // cross failed, put avas back ??
554 {
555 foreach (avtocrossInfo avinfo in avsToCross)
556 {
557 ScenePresence av = avinfo.av;
558 av.ParentUUID = UUID.Zero;
559 av.ParentID = avinfo.ParentID;
560// m_linkedAvatars.Add(av);
561 }
562 }
563 avsToCross.Clear();
564
565 }
566 else
567 {
568 if (m_rootPart.KeyframeMotion != null)
569 m_rootPart.KeyframeMotion.CrossingFailure();
570
571 if (RootPart.PhysActor != null)
572 {
573 RootPart.PhysActor.CrossingFailure();
574 }
575 }
576 Vector3 oldp = AbsolutePosition;
577 val.X = Util.Clamp<float>(oldp.X, 0.5f, (float)Constants.RegionSize - 0.5f);
578 val.Y = Util.Clamp<float>(oldp.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
579 val.Z = Util.Clamp<float>(oldp.Z, 0.5f, 4096.0f);
462 } 580 }
463 } 581 }
464 582
465 if (RootPart.GetStatusSandbox()) 583 if (RootPart.GetStatusSandbox())
466 { 584 {
467 if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) 585 if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10)
@@ -495,6 +613,39 @@ namespace OpenSim.Region.Framework.Scenes
495 } 613 }
496 } 614 }
497 615
616 public override Vector3 Velocity
617 {
618 get { return RootPart.Velocity; }
619 set { RootPart.Velocity = value; }
620 }
621
622 private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
623 {
624 CrossAgentToNewRegionDelegate icon = (CrossAgentToNewRegionDelegate)iar.AsyncState;
625 ScenePresence agent = icon.EndInvoke(iar);
626
627 //// If the cross was successful, this agent is a child agent
628 if (agent.IsChildAgent)
629 {
630 if (agent.ParentUUID != UUID.Zero)
631 {
632 agent.ParentPart = null;
633// agent.ParentPosition = Vector3.Zero;
634// agent.ParentUUID = UUID.Zero;
635 }
636 }
637
638 agent.ParentUUID = UUID.Zero;
639// agent.Reset();
640// else // Not successful
641// agent.RestoreInCurrentScene();
642
643 // In any case
644 agent.IsInTransit = false;
645
646 m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname);
647 }
648
498 public override uint LocalId 649 public override uint LocalId
499 { 650 {
500 get { return m_rootPart.LocalId; } 651 get { return m_rootPart.LocalId; }
@@ -1096,6 +1247,7 @@ namespace OpenSim.Region.Framework.Scenes
1096 } 1247 }
1097 } 1248 }
1098 1249
1250
1099 /// <summary> 1251 /// <summary>
1100 /// 1252 ///
1101 /// </summary> 1253 /// </summary>
@@ -1105,6 +1257,46 @@ namespace OpenSim.Region.Framework.Scenes
1105 part.ParentID = m_rootPart.LocalId; 1257 part.ParentID = m_rootPart.LocalId;
1106 part.ClearUndoState(); 1258 part.ClearUndoState();
1107 } 1259 }
1260 /// <summary>
1261 /// Add the avatar to this linkset (avatar is sat).
1262 /// </summary>
1263 /// <param name="agentID"></param>
1264 public void AddAvatar(UUID agentID)
1265 {
1266 ScenePresence presence;
1267 if (m_scene.TryGetScenePresence(agentID, out presence))
1268 {
1269 if (!m_linkedAvatars.Contains(presence))
1270 {
1271 m_linkedAvatars.Add(presence);
1272 }
1273 }
1274 }
1275
1276 /// <summary>
1277 /// Delete the avatar from this linkset (avatar is unsat).
1278 /// </summary>
1279 /// <param name="agentID"></param>
1280 public void DeleteAvatar(UUID agentID)
1281 {
1282 ScenePresence presence;
1283 if (m_scene.TryGetScenePresence(agentID, out presence))
1284 {
1285 if (m_linkedAvatars.Contains(presence))
1286 {
1287 m_linkedAvatars.Remove(presence);
1288 }
1289 }
1290 }
1291
1292 /// <summary>
1293 /// Returns the list of linked presences (avatars sat on this group)
1294 /// </summary>
1295 /// <param name="agentID"></param>
1296 public List<ScenePresence> GetLinkedAvatars()
1297 {
1298 return m_linkedAvatars;
1299 }
1108 1300
1109 public ushort GetTimeDilation() 1301 public ushort GetTimeDilation()
1110 { 1302 {
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 7ed3a4b..cf98ef2 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -65,6 +65,7 @@ namespace OpenSim.Region.Framework.Scenes
65 65
66 struct ScriptControllers 66 struct ScriptControllers
67 { 67 {
68 public UUID objectID;
68 public UUID itemID; 69 public UUID itemID;
69 public ScriptControlled ignoreControls; 70 public ScriptControlled ignoreControls;
70 public ScriptControlled eventControls; 71 public ScriptControlled eventControls;
@@ -120,7 +121,7 @@ namespace OpenSim.Region.Framework.Scenes
120 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 121 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
121 /// issue #1716 122 /// issue #1716
122 /// </summary> 123 /// </summary>
123 public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f); 124 public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.4f);
124 125
125 /// <summary> 126 /// <summary>
126 /// Movement updates for agents in neighboring regions are sent directly to clients. 127 /// Movement updates for agents in neighboring regions are sent directly to clients.
@@ -142,8 +143,6 @@ namespace OpenSim.Region.Framework.Scenes
142 /// <remarks> 143 /// <remarks>
143 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is 144 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is
144 /// necessary. 145 /// necessary.
145 /// NOTE: To avoid deadlocks, do not lock m_attachments and then perform other tasks under that lock. Take a copy
146 /// of the list and act on that instead.
147 /// </remarks> 146 /// </remarks>
148 private List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); 147 private List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
149 148
@@ -162,6 +161,10 @@ namespace OpenSim.Region.Framework.Scenes
162 private Vector3 m_lastPosition; 161 private Vector3 m_lastPosition;
163 private Quaternion m_lastRotation; 162 private Quaternion m_lastRotation;
164 private Vector3 m_lastVelocity; 163 private Vector3 m_lastVelocity;
164 private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f);
165
166 private bool m_followCamAuto = false;
167
165 168
166 private Vector3? m_forceToApply; 169 private Vector3? m_forceToApply;
167 private int m_userFlags; 170 private int m_userFlags;
@@ -194,6 +197,7 @@ namespace OpenSim.Region.Framework.Scenes
194// private int m_lastColCount = -1; //KF: Look for Collision chnages 197// private int m_lastColCount = -1; //KF: Look for Collision chnages
195// private int m_updateCount = 0; //KF: Update Anims for a while 198// private int m_updateCount = 0; //KF: Update Anims for a while
196// private static readonly int UPDATE_COUNT = 10; // how many frames to update for 199// private static readonly int UPDATE_COUNT = 10; // how many frames to update for
200 private List<uint> m_lastColliders = new List<uint>();
197 201
198 private TeleportFlags m_teleportFlags; 202 private TeleportFlags m_teleportFlags;
199 public TeleportFlags TeleportFlags 203 public TeleportFlags TeleportFlags
@@ -249,8 +253,6 @@ namespace OpenSim.Region.Framework.Scenes
249 /// </summary> 253 /// </summary>
250 public bool LandAtTarget { get; private set; } 254 public bool LandAtTarget { get; private set; }
251 255
252 private bool m_followCamAuto;
253
254 private int m_movementUpdateCount; 256 private int m_movementUpdateCount;
255 private const int NumMovementsBetweenRayCast = 5; 257 private const int NumMovementsBetweenRayCast = 5;
256 258
@@ -258,6 +260,13 @@ namespace OpenSim.Region.Framework.Scenes
258 //private int m_moveToPositionStateStatus; 260 //private int m_moveToPositionStateStatus;
259 //***************************************************** 261 //*****************************************************
260 262
263 private bool m_collisionEventFlag = false;
264 private object m_collisionEventLock = new Object();
265
266 private int m_movementAnimationUpdateCounter = 0;
267
268 public Vector3 PrevSitOffset { get; set; }
269
261 protected AvatarAppearance m_appearance; 270 protected AvatarAppearance m_appearance;
262 271
263 public AvatarAppearance Appearance 272 public AvatarAppearance Appearance
@@ -397,6 +406,9 @@ namespace OpenSim.Region.Framework.Scenes
397 /// </summary> 406 /// </summary>
398 protected Vector3 m_lastCameraPosition; 407 protected Vector3 m_lastCameraPosition;
399 408
409 private Vector4 m_lastCameraCollisionPlane = new Vector4(0f, 0f, 0f, 1);
410 private bool m_doingCamRayCast = false;
411
400 public Vector3 CameraPosition { get; set; } 412 public Vector3 CameraPosition { get; set; }
401 413
402 public Quaternion CameraRotation 414 public Quaternion CameraRotation
@@ -477,6 +489,10 @@ namespace OpenSim.Region.Framework.Scenes
477 get { return (IClientCore)ControllingClient; } 489 get { return (IClientCore)ControllingClient; }
478 } 490 }
479 491
492 public UUID COF { get; set; }
493
494// public Vector3 ParentPosition { get; set; }
495
480 /// <summary> 496 /// <summary>
481 /// Position of this avatar relative to the region the avatar is in 497 /// Position of this avatar relative to the region the avatar is in
482 /// </summary> 498 /// </summary>
@@ -603,7 +619,24 @@ namespace OpenSim.Region.Framework.Scenes
603// Scene.RegionInfo.RegionName, Name, m_velocity); 619// Scene.RegionInfo.RegionName, Name, m_velocity);
604 } 620 }
605 } 621 }
622/*
623 public override Vector3 AngularVelocity
624 {
625 get
626 {
627 if (PhysicsActor != null)
628 {
629 m_rotationalvelocity = PhysicsActor.RotationalVelocity;
630
631 // m_log.DebugFormat(
632 // "[SCENE PRESENCE]: Set velocity {0} for {1} in {2} via getting Velocity!",
633 // m_velocity, Name, Scene.RegionInfo.RegionName);
634 }
606 635
636 return m_rotationalvelocity;
637 }
638 }
639*/
607 private Quaternion m_bodyRot = Quaternion.Identity; 640 private Quaternion m_bodyRot = Quaternion.Identity;
608 641
609 /// <summary> 642 /// <summary>
@@ -626,8 +659,16 @@ namespace OpenSim.Region.Framework.Scenes
626 m_bodyRot = value; 659 m_bodyRot = value;
627 660
628 if (PhysicsActor != null) 661 if (PhysicsActor != null)
629 PhysicsActor.Orientation = m_bodyRot; 662 {
630 663 try
664 {
665 PhysicsActor.Orientation = m_bodyRot;
666 }
667 catch (Exception e)
668 {
669 m_log.Error("[SCENE PRESENCE]: Orientation " + e.Message);
670 }
671 }
631// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); 672// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot);
632 } 673 }
633 } 674 }
@@ -641,12 +682,20 @@ namespace OpenSim.Region.Framework.Scenes
641 } 682 }
642 683
643 public bool IsChildAgent { get; set; } 684 public bool IsChildAgent { get; set; }
685 public bool IsLoggingIn { get; set; }
644 686
645 /// <summary> 687 /// <summary>
646 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero. 688 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero.
647 /// </summary> 689 /// </summary>
648 public uint ParentID { get; set; } 690 public uint ParentID { get; set; }
649 691
692 public UUID ParentUUID
693 {
694 get { return m_parentUUID; }
695 set { m_parentUUID = value; }
696 }
697 private UUID m_parentUUID = UUID.Zero;
698
650 /// <summary> 699 /// <summary>
651 /// Are we sitting on an object? 700 /// Are we sitting on an object?
652 /// </summary> 701 /// </summary>
@@ -804,6 +853,7 @@ namespace OpenSim.Region.Framework.Scenes
804 AttachmentsSyncLock = new Object(); 853 AttachmentsSyncLock = new Object();
805 AllowMovement = true; 854 AllowMovement = true;
806 IsChildAgent = true; 855 IsChildAgent = true;
856 IsLoggingIn = false;
807 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault; 857 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault;
808 Animator = new ScenePresenceAnimator(this); 858 Animator = new ScenePresenceAnimator(this);
809 PresenceType = type; 859 PresenceType = type;
@@ -849,6 +899,33 @@ namespace OpenSim.Region.Framework.Scenes
849 m_stateMachine = new ScenePresenceStateMachine(this); 899 m_stateMachine = new ScenePresenceStateMachine(this);
850 } 900 }
851 901
902 private void RegionHeartbeatEnd(Scene scene)
903 {
904 if (IsChildAgent)
905 return;
906
907 m_movementAnimationUpdateCounter ++;
908 if (m_movementAnimationUpdateCounter >= 2)
909 {
910 m_movementAnimationUpdateCounter = 0;
911 if (Animator != null)
912 {
913 // If the parentID == 0 we are not sitting
914 // if !SitGournd then we are not sitting on the ground
915 // Fairly straightforward, now here comes the twist
916 // if ParentUUID is NOT UUID.Zero, we are looking to
917 // be sat on an object that isn't there yet. Should
918 // be treated as if sat.
919 if(ParentID == 0 && !SitGround && ParentUUID == UUID.Zero) // skip it if sitting
920 Animator.UpdateMovementAnimations();
921 }
922 else
923 {
924 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
925 }
926 }
927 }
928
852 public void RegisterToEvents() 929 public void RegisterToEvents()
853 { 930 {
854 ControllingClient.OnCompleteMovementToRegion += CompleteMovement; 931 ControllingClient.OnCompleteMovementToRegion += CompleteMovement;
@@ -919,6 +996,38 @@ namespace OpenSim.Region.Framework.Scenes
919// "[SCENE]: Upgrading child to root agent for {0} in {1}", 996// "[SCENE]: Upgrading child to root agent for {0} in {1}",
920// Name, m_scene.RegionInfo.RegionName); 997// Name, m_scene.RegionInfo.RegionName);
921 998
999 if (ParentUUID != UUID.Zero)
1000 {
1001 m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID);
1002 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID);
1003 if (part == null)
1004 {
1005 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
1006 }
1007 else
1008 {
1009 part.ParentGroup.AddAvatar(UUID);
1010 if (part.SitTargetPosition != Vector3.Zero)
1011 part.SitTargetAvatar = UUID;
1012// ParentPosition = part.GetWorldPosition();
1013 ParentID = part.LocalId;
1014 ParentPart = part;
1015 m_pos = PrevSitOffset;
1016// pos = ParentPosition;
1017 pos = part.GetWorldPosition();
1018 }
1019 ParentUUID = UUID.Zero;
1020
1021 IsChildAgent = false;
1022
1023// Animator.TrySetMovementAnimation("SIT");
1024 }
1025 else
1026 {
1027 IsChildAgent = false;
1028 IsLoggingIn = false;
1029 }
1030
922 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); 1031 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
923 1032
924 IsChildAgent = false; 1033 IsChildAgent = false;
@@ -936,70 +1045,106 @@ namespace OpenSim.Region.Framework.Scenes
936 1045
937 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); 1046 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
938 1047
939 // Moved this from SendInitialData to ensure that Appearance is initialized 1048 UUID groupUUID = UUID.Zero;
940 // before the inventory is processed in MakeRootAgent. This fixes a race condition 1049 string GroupName = string.Empty;
941 // related to the handling of attachments 1050 ulong groupPowers = 0;
942 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
943 1051
944 if (m_scene.TestBorderCross(pos, Cardinals.E)) 1052 // ----------------------------------
1053 // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status
1054 try
945 { 1055 {
946 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); 1056 if (gm != null)
947 pos.X = crossedBorder.BorderLine.Z - 1; 1057 {
1058 groupUUID = ControllingClient.ActiveGroupId;
1059 GroupRecord record = gm.GetGroupRecord(groupUUID);
1060 if (record != null)
1061 GroupName = record.GroupName;
1062 GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid);
1063 if (groupMembershipData != null)
1064 groupPowers = groupMembershipData.GroupPowers;
1065 }
1066 ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName,
1067 Grouptitle);
948 } 1068 }
949 1069 catch (Exception e)
950 if (m_scene.TestBorderCross(pos, Cardinals.N))
951 { 1070 {
952 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 1071 m_log.Debug("[AGENTUPDATE]: " + e.ToString());
953 pos.Y = crossedBorder.BorderLine.Z - 1;
954 } 1072 }
1073 // ------------------------------------
955 1074
956 CheckAndAdjustLandingPoint(ref pos); 1075 if (ParentID == 0)
957
958 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
959 { 1076 {
960 m_log.WarnFormat( 1077 // Moved this from SendInitialData to ensure that Appearance is initialized
961 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", 1078 // before the inventory is processed in MakeRootAgent. This fixes a race condition
962 pos, Name, UUID); 1079 // related to the handling of attachments
1080 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
1081 if (m_scene.TestBorderCross(pos, Cardinals.E))
1082 {
1083 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
1084 pos.X = crossedBorder.BorderLine.Z - 1;
1085 }
963 1086
964 if (pos.X < 0f) pos.X = 0f; 1087 if (m_scene.TestBorderCross(pos, Cardinals.N))
965 if (pos.Y < 0f) pos.Y = 0f; 1088 {
966 if (pos.Z < 0f) pos.Z = 0f; 1089 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
967 } 1090 pos.Y = crossedBorder.BorderLine.Z - 1;
1091 }
968 1092
969 float localAVHeight = 1.56f; 1093 CheckAndAdjustLandingPoint(ref pos);
970 if (Appearance.AvatarHeight > 0)
971 localAVHeight = Appearance.AvatarHeight;
972 1094
973 float posZLimit = 0; 1095 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
1096 {
1097 m_log.WarnFormat(
1098 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
1099 pos, Name, UUID);
974 1100
975 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) 1101 if (pos.X < 0f) pos.X = 0f;
976 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; 1102 if (pos.Y < 0f) pos.Y = 0f;
977 1103 if (pos.Z < 0f) pos.Z = 0f;
978 float newPosZ = posZLimit + localAVHeight / 2; 1104 }
979 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
980 {
981 pos.Z = newPosZ;
982 }
983 AbsolutePosition = pos;
984 1105
985 AddToPhysicalScene(isFlying); 1106 float localAVHeight = 1.56f;
1107 if (Appearance.AvatarHeight > 0)
1108 localAVHeight = Appearance.AvatarHeight;
986 1109
987 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a 1110 float posZLimit = 0;
988 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
989 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
990 // the value to a negative position which does not trigger the border cross.
991 // This may not be the best location for this.
992 CheckForBorderCrossing();
993 1111
994 if (ForceFly) 1112 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize)
995 { 1113 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
996 Flying = true; 1114
997 } 1115 float newPosZ = posZLimit + localAVHeight / 2;
998 else if (FlyDisabled) 1116 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
999 { 1117 {
1000 Flying = false; 1118 pos.Z = newPosZ;
1001 } 1119 }
1120 AbsolutePosition = pos;
1121
1122 if (m_teleportFlags == TeleportFlags.Default)
1123 {
1124 Vector3 vel = Velocity;
1125 AddToPhysicalScene(isFlying);
1126 if (PhysicsActor != null)
1127 PhysicsActor.SetMomentum(vel);
1128 }
1129 else
1130 AddToPhysicalScene(isFlying);
1131
1132 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a
1133 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
1134 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
1135 // the value to a negative position which does not trigger the border cross.
1136 // This may not be the best location for this.
1137 CheckForBorderCrossing();
1002 1138
1139 if (ForceFly)
1140 {
1141 Flying = true;
1142 }
1143 else if (FlyDisabled)
1144 {
1145 Flying = false;
1146 }
1147 }
1003 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying 1148 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying
1004 // avatar to return to the standing position in mid-air. On login it looks like this is being sent 1149 // avatar to return to the standing position in mid-air. On login it looks like this is being sent
1005 // elsewhere anyway 1150 // elsewhere anyway
@@ -1031,31 +1176,28 @@ namespace OpenSim.Region.Framework.Scenes
1031 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently 1176 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently
1032 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are 1177 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
1033 // not transporting the required data. 1178 // not transporting the required data.
1034 // 1179 lock (m_attachments)
1035 // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of
1036 // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here
1037 // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status.
1038 //
1039 // FIXME: In theory, this deadlock should not arise since scripts should not be processing events until ResumeScripts().
1040 // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing
1041 // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the
1042 // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine.
1043 List<SceneObjectGroup> attachments = GetAttachments();
1044
1045 if (attachments.Count > 0)
1046 { 1180 {
1047 m_log.DebugFormat( 1181 if (HasAttachments())
1048 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
1049
1050 // Resume scripts
1051 foreach (SceneObjectGroup sog in attachments)
1052 { 1182 {
1053 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); 1183 m_log.DebugFormat(
1054 sog.ResumeScripts(); 1184 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
1185
1186 // Resume scripts
1187 Util.FireAndForget(delegate(object x) {
1188 foreach (SceneObjectGroup sog in m_attachments)
1189 {
1190 sog.ScheduleGroupForFullUpdate();
1191 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1192 sog.ResumeScripts();
1193 }
1194 });
1055 } 1195 }
1056 } 1196 }
1057 } 1197 }
1058 1198
1199 SendAvatarDataToAllAgents();
1200
1059 // send the animations of the other presences to me 1201 // send the animations of the other presences to me
1060 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence) 1202 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
1061 { 1203 {
@@ -1066,6 +1208,7 @@ namespace OpenSim.Region.Framework.Scenes
1066 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will 1208 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will
1067 // stall on the border crossing since the existing child agent will still have the last movement 1209 // stall on the border crossing since the existing child agent will still have the last movement
1068 // recorded, which stops the input from being processed. 1210 // recorded, which stops the input from being processed.
1211
1069 MovementFlag = 0; 1212 MovementFlag = 0;
1070 1213
1071 m_scene.EventManager.TriggerOnMakeRootAgent(this); 1214 m_scene.EventManager.TriggerOnMakeRootAgent(this);
@@ -1097,12 +1240,16 @@ namespace OpenSim.Region.Framework.Scenes
1097 /// </remarks> 1240 /// </remarks>
1098 public void MakeChildAgent() 1241 public void MakeChildAgent()
1099 { 1242 {
1243 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
1244
1100 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName); 1245 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName);
1101 1246
1102 // Reset these so that teleporting in and walking out isn't seen 1247 // Reset these so that teleporting in and walking out isn't seen
1103 // as teleporting back 1248 // as teleporting back
1104 TeleportFlags = TeleportFlags.Default; 1249 TeleportFlags = TeleportFlags.Default;
1105 1250
1251 MovementFlag = 0;
1252
1106 // It looks like Animator is set to null somewhere, and MakeChild 1253 // It looks like Animator is set to null somewhere, and MakeChild
1107 // is called after that. Probably in aborted teleports. 1254 // is called after that. Probably in aborted teleports.
1108 if (Animator == null) 1255 if (Animator == null)
@@ -1110,6 +1257,7 @@ namespace OpenSim.Region.Framework.Scenes
1110 else 1257 else
1111 Animator.ResetAnimations(); 1258 Animator.ResetAnimations();
1112 1259
1260
1113// m_log.DebugFormat( 1261// m_log.DebugFormat(
1114// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", 1262// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}",
1115// Name, UUID, m_scene.RegionInfo.RegionName); 1263// Name, UUID, m_scene.RegionInfo.RegionName);
@@ -1121,6 +1269,7 @@ namespace OpenSim.Region.Framework.Scenes
1121 IsChildAgent = true; 1269 IsChildAgent = true;
1122 m_scene.SwapRootAgentCount(true); 1270 m_scene.SwapRootAgentCount(true);
1123 RemoveFromPhysicalScene(); 1271 RemoveFromPhysicalScene();
1272 ParentID = 0; // Child agents can't be sitting
1124 1273
1125 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into 1274 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into
1126 1275
@@ -1136,9 +1285,9 @@ namespace OpenSim.Region.Framework.Scenes
1136 { 1285 {
1137// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1286// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1138 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; 1287 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall;
1139 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1140 PhysicsActor.UnSubscribeEvents();
1141 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1288 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1289 PhysicsActor.UnSubscribeEvents();
1290 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1142 PhysicsActor = null; 1291 PhysicsActor = null;
1143 } 1292 }
1144// else 1293// else
@@ -1155,7 +1304,7 @@ namespace OpenSim.Region.Framework.Scenes
1155 /// <param name="pos"></param> 1304 /// <param name="pos"></param>
1156 public void Teleport(Vector3 pos) 1305 public void Teleport(Vector3 pos)
1157 { 1306 {
1158 TeleportWithMomentum(pos, null); 1307 TeleportWithMomentum(pos, Vector3.Zero);
1159 } 1308 }
1160 1309
1161 public void TeleportWithMomentum(Vector3 pos, Vector3? v) 1310 public void TeleportWithMomentum(Vector3 pos, Vector3? v)
@@ -1179,6 +1328,41 @@ namespace OpenSim.Region.Framework.Scenes
1179 SendTerseUpdateToAllClients(); 1328 SendTerseUpdateToAllClients();
1180 } 1329 }
1181 1330
1331 public void avnLocalTeleport(Vector3 newpos, Vector3? newvel, bool rotateToVelXY)
1332 {
1333 CheckLandingPoint(ref newpos);
1334 AbsolutePosition = newpos;
1335
1336 if (newvel.HasValue)
1337 {
1338 if ((Vector3)newvel == Vector3.Zero)
1339 {
1340 if (PhysicsActor != null)
1341 PhysicsActor.SetMomentum(Vector3.Zero);
1342 m_velocity = Vector3.Zero;
1343 }
1344 else
1345 {
1346 if (PhysicsActor != null)
1347 PhysicsActor.SetMomentum((Vector3)newvel);
1348 m_velocity = (Vector3)newvel;
1349
1350 if (rotateToVelXY)
1351 {
1352 Vector3 lookAt = (Vector3)newvel;
1353 lookAt.Z = 0;
1354 lookAt.Normalize();
1355 ControllingClient.SendLocalTeleport(newpos, lookAt, (uint)TeleportFlags.ViaLocation);
1356 return;
1357 }
1358 }
1359 }
1360
1361 SendTerseUpdateToAllClients();
1362 }
1363
1364
1365
1182 public void StopFlying() 1366 public void StopFlying()
1183 { 1367 {
1184 Vector3 pos = AbsolutePosition; 1368 Vector3 pos = AbsolutePosition;
@@ -1367,6 +1551,14 @@ namespace OpenSim.Region.Framework.Scenes
1367 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height); 1551 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height);
1368 } 1552 }
1369 1553
1554 public void SetSize(Vector3 size, float feetoffset)
1555 {
1556// TODO: Merge the physics bits
1557// if (PhysicsActor != null && !IsChildAgent)
1558// PhysicsActor.setAvatarSize(size, feetoffset);
1559
1560 }
1561
1370 private bool WaitForUpdateAgent(IClientAPI client) 1562 private bool WaitForUpdateAgent(IClientAPI client)
1371 { 1563 {
1372 // Before the source region executes UpdateAgent 1564 // Before the source region executes UpdateAgent
@@ -1426,7 +1618,8 @@ namespace OpenSim.Region.Framework.Scenes
1426 1618
1427 Vector3 look = Velocity; 1619 Vector3 look = Velocity;
1428 1620
1429 if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) 1621 // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
1622 if ((Math.Abs(look.X) < 0.1) && (Math.Abs(look.Y) < 0.1) && (Math.Abs(look.Z) < 0.1))
1430 { 1623 {
1431 look = new Vector3(0.99f, 0.042f, 0); 1624 look = new Vector3(0.99f, 0.042f, 0);
1432 } 1625 }
@@ -1489,11 +1682,12 @@ namespace OpenSim.Region.Framework.Scenes
1489 { 1682 {
1490 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 1683 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
1491 if (m_agentTransfer != null) 1684 if (m_agentTransfer != null)
1492 Util.FireAndForget(delegate { m_agentTransfer.EnableChildAgents(this); }); 1685 m_agentTransfer.EnableChildAgents(this);
1493 1686
1494 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); 1687 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
1495 if (friendsModule != null) 1688 if (friendsModule != null)
1496 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); 1689 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
1690
1497 } 1691 }
1498 1692
1499 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region 1693 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region
@@ -1519,36 +1713,69 @@ namespace OpenSim.Region.Framework.Scenes
1519 /// <param name="collisionPoint"></param> 1713 /// <param name="collisionPoint"></param>
1520 /// <param name="localid"></param> 1714 /// <param name="localid"></param>
1521 /// <param name="distance"></param> 1715 /// <param name="distance"></param>
1716 ///
1717
1718 private void UpdateCameraCollisionPlane(Vector4 plane)
1719 {
1720 if (m_lastCameraCollisionPlane != plane)
1721 {
1722 m_lastCameraCollisionPlane = plane;
1723 ControllingClient.SendCameraConstraint(plane);
1724 }
1725 }
1726
1522 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal) 1727 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal)
1523 { 1728 {
1524 const float POSITION_TOLERANCE = 0.02f; 1729 const float POSITION_TOLERANCE = 0.02f;
1525 const float VELOCITY_TOLERANCE = 0.02f;
1526 const float ROTATION_TOLERANCE = 0.02f; 1730 const float ROTATION_TOLERANCE = 0.02f;
1527 1731
1528 if (m_followCamAuto) 1732 m_doingCamRayCast = false;
1733 if (hitYN && localid != LocalId)
1529 { 1734 {
1530 if (hitYN) 1735 SceneObjectGroup group = m_scene.GetGroupByPrim(localid);
1736 bool IsPrim = group != null;
1737 if (IsPrim)
1531 { 1738 {
1532 CameraConstraintActive = true; 1739 SceneObjectPart part = group.GetPart(localid);
1533 //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance); 1740 if (part != null && !part.VolumeDetectActive)
1534 1741 {
1535 Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint); 1742 CameraConstraintActive = true;
1536 ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint))); 1743 pNormal.X = (float) Math.Round(pNormal.X, 2);
1744 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1745 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1746 pNormal.Normalize();
1747 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1748 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1749 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1750
1751 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1752 Vector3.Dot(collisionPoint, pNormal));
1753 UpdateCameraCollisionPlane(plane);
1754 }
1537 } 1755 }
1538 else 1756 else
1539 { 1757 {
1540 if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 1758 CameraConstraintActive = true;
1541 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || 1759 pNormal.X = (float) Math.Round(pNormal.X, 2);
1542 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) 1760 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1543 { 1761 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1544 if (CameraConstraintActive) 1762 pNormal.Normalize();
1545 { 1763 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1546 ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f)); 1764 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1547 CameraConstraintActive = false; 1765 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1548 } 1766
1549 } 1767 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1768 Vector3.Dot(collisionPoint, pNormal));
1769 UpdateCameraCollisionPlane(plane);
1550 } 1770 }
1551 } 1771 }
1772 else if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
1773 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE))
1774 {
1775 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -9000f); // not right...
1776 UpdateCameraCollisionPlane(plane);
1777 CameraConstraintActive = false;
1778 }
1552 } 1779 }
1553 1780
1554 /// <summary> 1781 /// <summary>
@@ -1622,6 +1849,41 @@ namespace OpenSim.Region.Framework.Scenes
1622 StandUp(); 1849 StandUp();
1623 } 1850 }
1624 1851
1852 // Raycast from the avatar's head to the camera to see if there's anything blocking the view
1853 // this exclude checks may not be complete
1854
1855 if (m_movementUpdateCount % NumMovementsBetweenRayCast == 0 && m_scene.PhysicsScene.SupportsRayCast())
1856 {
1857 if (!m_doingCamRayCast && !m_mouseLook && ParentID == 0)
1858 {
1859 Vector3 posAdjusted = AbsolutePosition;
1860// posAdjusted.Z += 0.5f * Appearance.AvatarSize.Z - 0.5f;
1861 posAdjusted.Z += 1.0f; // viewer current camera focus point
1862 Vector3 tocam = CameraPosition - posAdjusted;
1863 tocam.X = (float)Math.Round(tocam.X, 1);
1864 tocam.Y = (float)Math.Round(tocam.Y, 1);
1865 tocam.Z = (float)Math.Round(tocam.Z, 1);
1866
1867 float distTocamlen = tocam.Length();
1868 if (distTocamlen > 0.3f)
1869 {
1870 tocam *= (1.0f / distTocamlen);
1871 posAdjusted.X = (float)Math.Round(posAdjusted.X, 1);
1872 posAdjusted.Y = (float)Math.Round(posAdjusted.Y, 1);
1873 posAdjusted.Z = (float)Math.Round(posAdjusted.Z, 1);
1874
1875 m_doingCamRayCast = true;
1876 m_scene.PhysicsScene.RaycastWorld(posAdjusted, tocam, distTocamlen + 1.0f, RayCastCameraCallback);
1877 }
1878 }
1879 else if (CameraConstraintActive && (m_mouseLook || ParentID != 0))
1880 {
1881 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -10000f); // not right...
1882 UpdateCameraCollisionPlane(plane);
1883 CameraConstraintActive = false;
1884 }
1885 }
1886
1625 uint flagsForScripts = (uint)flags; 1887 uint flagsForScripts = (uint)flags;
1626 flags = RemoveIgnoredControls(flags, IgnoredControls); 1888 flags = RemoveIgnoredControls(flags, IgnoredControls);
1627 1889
@@ -2180,7 +2442,8 @@ namespace OpenSim.Region.Framework.Scenes
2180// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); 2442// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
2181 2443
2182 MovingToTarget = false; 2444 MovingToTarget = false;
2183 MoveToPositionTarget = Vector3.Zero; 2445// MoveToPositionTarget = Vector3.Zero;
2446 m_forceToApply = null; // cancel possible last action
2184 2447
2185 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct 2448 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct
2186 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag. 2449 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag.
@@ -2203,6 +2466,9 @@ namespace OpenSim.Region.Framework.Scenes
2203 2466
2204 if (satOnObject) 2467 if (satOnObject)
2205 { 2468 {
2469 PrevSitOffset = m_pos; // Save sit offset
2470 UnRegisterSeatControls(part.ParentGroup.UUID);
2471
2206 TaskInventoryDictionary taskIDict = part.TaskInventory; 2472 TaskInventoryDictionary taskIDict = part.TaskInventory;
2207 if (taskIDict != null) 2473 if (taskIDict != null)
2208 { 2474 {
@@ -2218,6 +2484,7 @@ namespace OpenSim.Region.Framework.Scenes
2218 } 2484 }
2219 } 2485 }
2220 2486
2487 part.ParentGroup.DeleteAvatar(UUID);
2221 Vector3 sitPartWorldPosition = part.GetWorldPosition(); 2488 Vector3 sitPartWorldPosition = part.GetWorldPosition();
2222 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2489 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
2223 2490
@@ -2278,6 +2545,9 @@ namespace OpenSim.Region.Framework.Scenes
2278 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 2545 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2279 } 2546 }
2280 2547
2548 else if (PhysicsActor == null)
2549 AddToPhysicalScene(false);
2550
2281 Animator.TrySetMovementAnimation("STAND"); 2551 Animator.TrySetMovementAnimation("STAND");
2282 TriggerScenePresenceUpdated(); 2552 TriggerScenePresenceUpdated();
2283 } 2553 }
@@ -2326,11 +2596,8 @@ namespace OpenSim.Region.Framework.Scenes
2326 if (part == null) 2596 if (part == null)
2327 return; 2597 return;
2328 2598
2329 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2330 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2331
2332 if (PhysicsActor != null) 2599 if (PhysicsActor != null)
2333 m_sitAvatarHeight = PhysicsActor.Size.Z; 2600 m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f;
2334 2601
2335 bool canSit = false; 2602 bool canSit = false;
2336 2603
@@ -2357,33 +2624,32 @@ namespace OpenSim.Region.Framework.Scenes
2357 } 2624 }
2358 else 2625 else
2359 { 2626 {
2627 if (PhysicsSit(part,offset)) // physics engine
2628 return;
2629
2360 Vector3 pos = part.AbsolutePosition + offset; 2630 Vector3 pos = part.AbsolutePosition + offset;
2361 2631
2362 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) 2632 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
2363 { 2633 {
2364// m_log.DebugFormat(
2365// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m",
2366// Name, part.Name, part.LocalId);
2367
2368 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 2634 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
2369 canSit = true; 2635 canSit = true;
2370 } 2636 }
2371// else
2372// {
2373// m_log.DebugFormat(
2374// "[SCENE PRESENCE]: Ignoring sit request of {0} on {1} {2} because sit target is unset and outside 10m",
2375// Name, part.Name, part.LocalId);
2376// }
2377 } 2637 }
2378 2638
2379 if (canSit) 2639 if (canSit)
2380 { 2640 {
2641
2381 if (PhysicsActor != null) 2642 if (PhysicsActor != null)
2382 { 2643 {
2383 // We can remove the physicsActor until they stand up. 2644 // We can remove the physicsActor until they stand up.
2384 RemoveFromPhysicalScene(); 2645 RemoveFromPhysicalScene();
2385 } 2646 }
2386 2647
2648 if (MovingToTarget)
2649 ResetMoveToTarget();
2650
2651 Velocity = Vector3.Zero;
2652
2387 part.AddSittingAvatar(UUID); 2653 part.AddSittingAvatar(UUID);
2388 2654
2389 cameraAtOffset = part.GetCameraAtOffset(); 2655 cameraAtOffset = part.GetCameraAtOffset();
@@ -2427,14 +2693,6 @@ namespace OpenSim.Region.Framework.Scenes
2427 m_requestedSitTargetID = part.LocalId; 2693 m_requestedSitTargetID = part.LocalId;
2428 m_requestedSitTargetUUID = part.UUID; 2694 m_requestedSitTargetUUID = part.UUID;
2429 2695
2430// m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
2431
2432 if (m_scene.PhysicsScene.SupportsRayCast())
2433 {
2434 //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback());
2435 //SitRayCastAvatarPosition(part);
2436 //return;
2437 }
2438 } 2696 }
2439 else 2697 else
2440 { 2698 {
@@ -2444,197 +2702,115 @@ namespace OpenSim.Region.Framework.Scenes
2444 SendSitResponse(targetID, offset, Quaternion.Identity); 2702 SendSitResponse(targetID, offset, Quaternion.Identity);
2445 } 2703 }
2446 2704
2447 /* 2705 // returns false if does not suport so older sit can be tried
2448 public void SitRayCastAvatarPosition(SceneObjectPart part) 2706 public bool PhysicsSit(SceneObjectPart part, Vector3 offset)
2449 {
2450 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2451 Vector3 StartRayCastPosition = AbsolutePosition;
2452 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2453 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2454 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionResponse);
2455 }
2456
2457 public void SitRayCastAvatarPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal)
2458 { 2707 {
2459 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); 2708// TODO: Pull in these bits
2460 if (part != null) 2709 return false;
2461 { 2710/*
2462 if (hitYN) 2711 if (part == null || part.ParentGroup.IsAttachment)
2463 {
2464 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2465 {
2466 SitRaycastFindEdge(collisionPoint, normal);
2467 m_log.DebugFormat("[SIT]: Raycast Avatar Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2468 }
2469 else
2470 {
2471 SitRayCastAvatarPositionCameraZ(part);
2472 }
2473 }
2474 else
2475 {
2476 SitRayCastAvatarPositionCameraZ(part);
2477 }
2478 }
2479 else
2480 { 2712 {
2481 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2713 return true;
2482 m_requestedSitTargetUUID = UUID.Zero;
2483 m_requestedSitTargetID = 0;
2484 m_requestedSitOffset = Vector3.Zero;
2485 } 2714 }
2486 2715
2487 } 2716 if ( m_scene.PhysicsScene == null)
2488 2717 return false;
2489 public void SitRayCastAvatarPositionCameraZ(SceneObjectPart part)
2490 {
2491 // Next, try to raycast from the camera Z position
2492 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2493 Vector3 StartRayCastPosition = AbsolutePosition; StartRayCastPosition.Z = CameraPosition.Z;
2494 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2495 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2496 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionCameraZResponse);
2497 }
2498 2718
2499 public void SitRayCastAvatarPositionCameraZResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2719 if (part.PhysActor == null)
2500 {
2501 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2502 if (part != null)
2503 { 2720 {
2504 if (hitYN) 2721 // none physcis shape
2505 { 2722 if (part.PhysicsShapeType == (byte)PhysicsShapeType.None)
2506 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) 2723 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2507 {
2508 SitRaycastFindEdge(collisionPoint, normal);
2509 m_log.DebugFormat("[SIT]: Raycast Avatar Position + CameraZ succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2510 }
2511 else
2512 {
2513 SitRayCastCameraPosition(part);
2514 }
2515 }
2516 else 2724 else
2517 { 2725 { // non physical phantom TODO
2518 SitRayCastCameraPosition(part); 2726 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2727 return false;
2519 } 2728 }
2520 } 2729 return true;
2521 else
2522 {
2523 ControllingClient.SendAlertMessage("Sit position no longer exists");
2524 m_requestedSitTargetUUID = UUID.Zero;
2525 m_requestedSitTargetID = 0;
2526 m_requestedSitOffset = Vector3.Zero;
2527 } 2730 }
2528 2731
2529 }
2530 2732
2531 public void SitRayCastCameraPosition(SceneObjectPart part) 2733 // not doing autopilot
2532 { 2734 m_requestedSitTargetID = 0;
2533 // Next, try to raycast from the camera position
2534 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2535 Vector3 StartRayCastPosition = CameraPosition;
2536 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2537 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2538 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastCameraPositionResponse);
2539 }
2540 2735
2541 public void SitRayCastCameraPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2736 if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0)
2542 { 2737 return true;
2543 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2544 if (part != null)
2545 {
2546 if (hitYN)
2547 {
2548 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2549 {
2550 SitRaycastFindEdge(collisionPoint, normal);
2551 m_log.DebugFormat("[SIT]: Raycast Camera Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2552 }
2553 else
2554 {
2555 SitRayHorizontal(part);
2556 }
2557 }
2558 else
2559 {
2560 SitRayHorizontal(part);
2561 }
2562 }
2563 else
2564 {
2565 ControllingClient.SendAlertMessage("Sit position no longer exists");
2566 m_requestedSitTargetUUID = UUID.Zero;
2567 m_requestedSitTargetID = 0;
2568 m_requestedSitOffset = Vector3.Zero;
2569 }
2570 2738
2739 return false;
2740*/
2571 } 2741 }
2572 2742
2573 public void SitRayHorizontal(SceneObjectPart part) 2743
2744 private bool CanEnterLandPosition(Vector3 testPos)
2574 { 2745 {
2575 // Next, try to raycast from the avatar position to fwd 2746 ILandObject land = m_scene.LandChannel.GetLandObject(testPos.X, testPos.Y);
2576 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2747
2577 Vector3 StartRayCastPosition = CameraPosition; 2748 if (land == null || land.LandData.Name == "NO_LAND")
2578 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); 2749 return true;
2579 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); 2750
2580 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastHorizontalResponse); 2751 return land.CanBeOnThisLand(UUID,testPos.Z);
2581 } 2752 }
2582 2753
2583 public void SitRayCastHorizontalResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2754 // status
2755 // < 0 ignore
2756 // 0 bad sit spot
2757 public void PhysicsSitResponse(int status, uint partID, Vector3 offset, Quaternion Orientation)
2584 { 2758 {
2585 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); 2759 if (status < 0)
2586 if (part != null) 2760 return;
2761
2762 if (status == 0)
2587 { 2763 {
2588 if (hitYN) 2764 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2589 { 2765 return;
2590 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2591 {
2592 SitRaycastFindEdge(collisionPoint, normal);
2593 m_log.DebugFormat("[SIT]: Raycast Horizontal Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2594 // Next, try to raycast from the camera position
2595 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2596 Vector3 StartRayCastPosition = CameraPosition;
2597 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2598 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2599 //m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastResponseAvatarPosition);
2600 }
2601 else
2602 {
2603 ControllingClient.SendAlertMessage("Sit position not accessable.");
2604 m_requestedSitTargetUUID = UUID.Zero;
2605 m_requestedSitTargetID = 0;
2606 m_requestedSitOffset = Vector3.Zero;
2607 }
2608 }
2609 else
2610 {
2611 ControllingClient.SendAlertMessage("Sit position not accessable.");
2612 m_requestedSitTargetUUID = UUID.Zero;
2613 m_requestedSitTargetID = 0;
2614 m_requestedSitOffset = Vector3.Zero;
2615 }
2616 } 2766 }
2617 else 2767
2768 SceneObjectPart part = m_scene.GetSceneObjectPart(partID);
2769 if (part == null)
2770 return;
2771
2772 Vector3 targetPos = part.GetWorldPosition() + offset * part.GetWorldRotation();
2773 if(!CanEnterLandPosition(targetPos))
2618 { 2774 {
2619 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2775 ControllingClient.SendAlertMessage(" Sit position on restricted land, try another spot");
2620 m_requestedSitTargetUUID = UUID.Zero; 2776 return;
2621 m_requestedSitTargetID = 0;
2622 m_requestedSitOffset = Vector3.Zero;
2623 } 2777 }
2624 2778
2625 } 2779 RemoveFromPhysicalScene();
2626 2780
2627 private void SitRaycastFindEdge(Vector3 collisionPoint, Vector3 collisionNormal) 2781 if (MovingToTarget)
2628 { 2782 ResetMoveToTarget();
2629 int i = 0; 2783
2630 //throw new NotImplementedException(); 2784 Velocity = Vector3.Zero;
2631 //m_requestedSitTargetUUID = UUID.Zero; 2785
2632 //m_requestedSitTargetID = 0; 2786 part.AddSittingAvatar(UUID);
2633 //m_requestedSitOffset = Vector3.Zero; 2787
2788 Vector3 cameraAtOffset = part.GetCameraAtOffset();
2789 Vector3 cameraEyeOffset = part.GetCameraEyeOffset();
2790 bool forceMouselook = part.GetForceMouselook();
2791
2792 ControllingClient.SendSitResponse(
2793 part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2794
2795 // not using autopilot
2796
2797 Rotation = Orientation;
2798 m_pos = offset;
2799
2800 m_requestedSitTargetID = 0;
2801 part.ParentGroup.AddAvatar(UUID);
2802
2803 ParentPart = part;
2804 ParentID = part.LocalId;
2805 if(status == 3)
2806 Animator.TrySetMovementAnimation("SIT_GROUND");
2807 else
2808 Animator.TrySetMovementAnimation("SIT");
2809 SendAvatarDataToAllAgents();
2634 2810
2635 SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); 2811 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2636 } 2812 }
2637 */ 2813
2638 2814
2639 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) 2815 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
2640 { 2816 {
@@ -2654,6 +2830,7 @@ namespace OpenSim.Region.Framework.Scenes
2654 return; 2830 return;
2655 } 2831 }
2656 2832
2833
2657 if (part.SitTargetAvatar == UUID) 2834 if (part.SitTargetAvatar == UUID)
2658 { 2835 {
2659 Vector3 sitTargetPos = part.SitTargetPosition; 2836 Vector3 sitTargetPos = part.SitTargetPosition;
@@ -2668,7 +2845,28 @@ namespace OpenSim.Region.Framework.Scenes
2668 2845
2669 //Quaternion result = (sitTargetOrient * vq) * nq; 2846 //Quaternion result = (sitTargetOrient * vq) * nq;
2670 2847
2671 Vector3 newPos = sitTargetPos + SIT_TARGET_ADJUSTMENT; 2848 double x, y, z, m;
2849
2850 Quaternion r = sitTargetOrient;
2851 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2852
2853 if (Math.Abs(1.0 - m) > 0.000001)
2854 {
2855 m = 1.0 / Math.Sqrt(m);
2856 r.X *= (float)m;
2857 r.Y *= (float)m;
2858 r.Z *= (float)m;
2859 r.W *= (float)m;
2860 }
2861
2862 x = 2 * (r.X * r.Z + r.Y * r.W);
2863 y = 2 * (-r.X * r.W + r.Y * r.Z);
2864 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2865
2866 Vector3 up = new Vector3((float)x, (float)y, (float)z);
2867 Vector3 sitOffset = up * Appearance.AvatarHeight * 0.02638f;
2868
2869 Vector3 newPos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT;
2672 Quaternion newRot; 2870 Quaternion newRot;
2673 2871
2674 if (part.IsRoot) 2872 if (part.IsRoot)
@@ -2685,6 +2883,9 @@ namespace OpenSim.Region.Framework.Scenes
2685 2883
2686 m_pos = newPos; 2884 m_pos = newPos;
2687 Rotation = newRot; 2885 Rotation = newRot;
2886
2887// ParentPosition = part.AbsolutePosition;
2888 part.ParentGroup.AddAvatar(UUID);
2688 } 2889 }
2689 else 2890 else
2690 { 2891 {
@@ -2692,6 +2893,9 @@ namespace OpenSim.Region.Framework.Scenes
2692 // being sat upon. 2893 // being sat upon.
2693 m_pos -= part.GroupPosition; 2894 m_pos -= part.GroupPosition;
2694 2895
2896// ParentPosition = part.AbsolutePosition;
2897 part.ParentGroup.AddAvatar(UUID);
2898
2695// m_log.DebugFormat( 2899// m_log.DebugFormat(
2696// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", 2900// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target",
2697// Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId); 2901// Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId);
@@ -2807,8 +3011,8 @@ namespace OpenSim.Region.Framework.Scenes
2807 direc.Z *= 2.6f; 3011 direc.Z *= 2.6f;
2808 3012
2809 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 3013 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
2810 Animator.TrySetMovementAnimation("PREJUMP"); 3014// Animator.TrySetMovementAnimation("PREJUMP");
2811 Animator.TrySetMovementAnimation("JUMP"); 3015// Animator.TrySetMovementAnimation("JUMP");
2812 } 3016 }
2813 } 3017 }
2814 } 3018 }
@@ -2817,6 +3021,7 @@ namespace OpenSim.Region.Framework.Scenes
2817 3021
2818 // TODO: Add the force instead of only setting it to support multiple forces per frame? 3022 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2819 m_forceToApply = direc; 3023 m_forceToApply = direc;
3024 Animator.UpdateMovementAnimations();
2820 } 3025 }
2821 3026
2822 #endregion 3027 #endregion
@@ -2834,16 +3039,12 @@ namespace OpenSim.Region.Framework.Scenes
2834 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to 3039 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to
2835 // grab the latest PhysicsActor velocity, whereas m_velocity is often 3040 // grab the latest PhysicsActor velocity, whereas m_velocity is often
2836 // storing a requested force instead of an actual traveling velocity 3041 // storing a requested force instead of an actual traveling velocity
3042 if (Appearance.AvatarSize != m_lastSize && !IsLoggingIn)
3043 SendAvatarDataToAllAgents();
2837 3044
2838 // Throw away duplicate or insignificant updates 3045 if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) ||
2839 if ( 3046 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
2840 // If the velocity has become zero, send it no matter what. 3047 !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
2841 (Velocity != m_lastVelocity && Velocity == Vector3.Zero)
2842 // otherwise, if things have changed reasonably, send the update
2843 || (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
2844 || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE)
2845 || !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)))
2846
2847 { 3048 {
2848 SendTerseUpdateToAllClients(); 3049 SendTerseUpdateToAllClients();
2849 3050
@@ -3003,9 +3204,7 @@ namespace OpenSim.Region.Framework.Scenes
3003 // again here... this comes after the cached appearance check because the avatars 3204 // again here... this comes after the cached appearance check because the avatars
3004 // appearance goes into the avatar update packet 3205 // appearance goes into the avatar update packet
3005 SendAvatarDataToAllAgents(); 3206 SendAvatarDataToAllAgents();
3006 3207 SendAppearanceToAgent(this);
3007 // This invocation always shows up in the viewer logs as an error.
3008 // SendAppearanceToAgent(this);
3009 3208
3010 // If we are using the the cached appearance then send it out to everyone 3209 // If we are using the the cached appearance then send it out to everyone
3011 if (cachedappearance) 3210 if (cachedappearance)
@@ -3036,6 +3235,8 @@ namespace OpenSim.Region.Framework.Scenes
3036 return; 3235 return;
3037 } 3236 }
3038 3237
3238 m_lastSize = Appearance.AvatarSize;
3239
3039 int count = 0; 3240 int count = 0;
3040 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) 3241 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
3041 { 3242 {
@@ -3143,6 +3344,8 @@ namespace OpenSim.Region.Framework.Scenes
3143 3344
3144 avatar.ControllingClient.SendAppearance( 3345 avatar.ControllingClient.SendAppearance(
3145 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); 3346 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes());
3347
3348
3146 } 3349 }
3147 3350
3148 #endregion 3351 #endregion
@@ -3216,8 +3419,9 @@ namespace OpenSim.Region.Framework.Scenes
3216 3419
3217 // If we don't have a PhysActor, we can't cross anyway 3420 // If we don't have a PhysActor, we can't cross anyway
3218 // Also don't do this while sat, sitting avatars cross with the 3421 // Also don't do this while sat, sitting avatars cross with the
3219 // object they sit on. 3422 // object they sit on. ParentUUID denoted a pending sit, don't
3220 if (ParentID != 0 || PhysicsActor == null) 3423 // interfere with it.
3424 if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero)
3221 return; 3425 return;
3222 3426
3223 if (!IsInTransit) 3427 if (!IsInTransit)
@@ -3561,6 +3765,9 @@ namespace OpenSim.Region.Framework.Scenes
3561 cAgent.AlwaysRun = SetAlwaysRun; 3765 cAgent.AlwaysRun = SetAlwaysRun;
3562 3766
3563 cAgent.Appearance = new AvatarAppearance(Appearance); 3767 cAgent.Appearance = new AvatarAppearance(Appearance);
3768
3769 cAgent.ParentPart = ParentUUID;
3770 cAgent.SitOffset = PrevSitOffset;
3564 3771
3565 lock (scriptedcontrols) 3772 lock (scriptedcontrols)
3566 { 3773 {
@@ -3569,7 +3776,7 @@ namespace OpenSim.Region.Framework.Scenes
3569 3776
3570 foreach (ScriptControllers c in scriptedcontrols.Values) 3777 foreach (ScriptControllers c in scriptedcontrols.Values)
3571 { 3778 {
3572 controls[i++] = new ControllerData(c.itemID, (uint)c.ignoreControls, (uint)c.eventControls); 3779 controls[i++] = new ControllerData(c.objectID, c.itemID, (uint)c.ignoreControls, (uint)c.eventControls);
3573 } 3780 }
3574 cAgent.Controllers = controls; 3781 cAgent.Controllers = controls;
3575 } 3782 }
@@ -3603,6 +3810,8 @@ namespace OpenSim.Region.Framework.Scenes
3603 CameraAtAxis = cAgent.AtAxis; 3810 CameraAtAxis = cAgent.AtAxis;
3604 CameraLeftAxis = cAgent.LeftAxis; 3811 CameraLeftAxis = cAgent.LeftAxis;
3605 CameraUpAxis = cAgent.UpAxis; 3812 CameraUpAxis = cAgent.UpAxis;
3813 ParentUUID = cAgent.ParentPart;
3814 PrevSitOffset = cAgent.SitOffset;
3606 3815
3607 // When we get to the point of re-computing neighbors everytime this 3816 // When we get to the point of re-computing neighbors everytime this
3608 // changes, then start using the agent's drawdistance rather than the 3817 // changes, then start using the agent's drawdistance rather than the
@@ -3640,6 +3849,7 @@ namespace OpenSim.Region.Framework.Scenes
3640 foreach (ControllerData c in cAgent.Controllers) 3849 foreach (ControllerData c in cAgent.Controllers)
3641 { 3850 {
3642 ScriptControllers sc = new ScriptControllers(); 3851 ScriptControllers sc = new ScriptControllers();
3852 sc.objectID = c.ObjectID;
3643 sc.itemID = c.ItemID; 3853 sc.itemID = c.ItemID;
3644 sc.ignoreControls = (ScriptControlled)c.IgnoreControls; 3854 sc.ignoreControls = (ScriptControlled)c.IgnoreControls;
3645 sc.eventControls = (ScriptControlled)c.EventControls; 3855 sc.eventControls = (ScriptControlled)c.EventControls;
@@ -3705,20 +3915,27 @@ namespace OpenSim.Region.Framework.Scenes
3705 } 3915 }
3706 3916
3707 if (Appearance.AvatarHeight == 0) 3917 if (Appearance.AvatarHeight == 0)
3708 Appearance.SetHeight(); 3918// Appearance.SetHeight();
3919 Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f));
3709 3920
3710 PhysicsScene scene = m_scene.PhysicsScene; 3921 PhysicsScene scene = m_scene.PhysicsScene;
3711 3922
3712 Vector3 pVec = AbsolutePosition; 3923 Vector3 pVec = AbsolutePosition;
3713 3924
3925/*
3926 PhysicsActor = scene.AddAvatar(
3927 LocalId, Firstname + "." + Lastname, pVec,
3928 new Vector3(0.45f, 0.6f, Appearance.AvatarHeight), isFlying);
3929*/
3930
3714 PhysicsActor = scene.AddAvatar( 3931 PhysicsActor = scene.AddAvatar(
3715 LocalId, Firstname + "." + Lastname, pVec, 3932 LocalId, Firstname + "." + Lastname, pVec,
3716 new Vector3(0f, 0f, Appearance.AvatarHeight), isFlying); 3933 Appearance.AvatarBoxSize, isFlying);
3717 3934
3718 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3935 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3719 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3936 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
3720 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong 3937 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
3721 PhysicsActor.SubscribeEvents(500); 3938 PhysicsActor.SubscribeEvents(100);
3722 PhysicsActor.LocalID = LocalId; 3939 PhysicsActor.LocalID = LocalId;
3723 } 3940 }
3724 3941
@@ -3732,6 +3949,7 @@ namespace OpenSim.Region.Framework.Scenes
3732 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true); 3949 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true);
3733 } 3950 }
3734 3951
3952
3735 /// <summary> 3953 /// <summary>
3736 /// Event called by the physics plugin to tell the avatar about a collision. 3954 /// Event called by the physics plugin to tell the avatar about a collision.
3737 /// </summary> 3955 /// </summary>
@@ -3745,7 +3963,7 @@ namespace OpenSim.Region.Framework.Scenes
3745 /// <param name="e"></param> 3963 /// <param name="e"></param>
3746 public void PhysicsCollisionUpdate(EventArgs e) 3964 public void PhysicsCollisionUpdate(EventArgs e)
3747 { 3965 {
3748 if (IsChildAgent) 3966 if (IsChildAgent || Animator == null)
3749 return; 3967 return;
3750 3968
3751 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3969 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
@@ -3762,7 +3980,6 @@ namespace OpenSim.Region.Framework.Scenes
3762 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3980 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3763 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3981 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3764 3982
3765 CollisionPlane = Vector4.UnitW;
3766 3983
3767// // No collisions at all means we may be flying. Update always 3984// // No collisions at all means we may be flying. Update always
3768// // to make falling work 3985// // to make falling work
@@ -3772,34 +3989,7 @@ namespace OpenSim.Region.Framework.Scenes
3772// m_lastColCount = coldata.Count; 3989// m_lastColCount = coldata.Count;
3773// } 3990// }
3774 3991
3775 if (coldata.Count != 0) 3992 CollisionPlane = Vector4.UnitW;
3776 {
3777 switch (Animator.CurrentMovementAnimation)
3778 {
3779 case "STAND":
3780 case "WALK":
3781 case "RUN":
3782 case "CROUCH":
3783 case "CROUCHWALK":
3784 {
3785 ContactPoint lowest;
3786 lowest.SurfaceNormal = Vector3.Zero;
3787 lowest.Position = Vector3.Zero;
3788 lowest.Position.Z = Single.NaN;
3789
3790 foreach (ContactPoint contact in coldata.Values)
3791 {
3792 if (Single.IsNaN(lowest.Position.Z) || contact.Position.Z < lowest.Position.Z)
3793 {
3794 lowest = contact;
3795 }
3796 }
3797
3798 CollisionPlane = new Vector4(-lowest.SurfaceNormal, -Vector3.Dot(lowest.Position, lowest.SurfaceNormal));
3799 }
3800 break;
3801 }
3802 }
3803 3993
3804 // Gods do not take damage and Invulnerable is set depending on parcel/region flags 3994 // Gods do not take damage and Invulnerable is set depending on parcel/region flags
3805 if (Invulnerable || GodLevel > 0) 3995 if (Invulnerable || GodLevel > 0)
@@ -3898,6 +4088,12 @@ namespace OpenSim.Region.Framework.Scenes
3898 // m_reprioritizationTimer.Dispose(); 4088 // m_reprioritizationTimer.Dispose();
3899 4089
3900 RemoveFromPhysicalScene(); 4090 RemoveFromPhysicalScene();
4091
4092 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
4093
4094// if (Animator != null)
4095// Animator.Close();
4096 Animator = null;
3901 4097
3902 LifecycleState = ScenePresenceState.Removed; 4098 LifecycleState = ScenePresenceState.Removed;
3903 } 4099 }
@@ -4133,10 +4329,18 @@ namespace OpenSim.Region.Framework.Scenes
4133 4329
4134 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID) 4330 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID)
4135 { 4331 {
4332 SceneObjectPart p = m_scene.GetSceneObjectPart(Obj_localID);
4333 if (p == null)
4334 return;
4335
4336 ControllingClient.SendTakeControls(controls, false, false);
4337 ControllingClient.SendTakeControls(controls, true, false);
4338
4136 ScriptControllers obj = new ScriptControllers(); 4339 ScriptControllers obj = new ScriptControllers();
4137 obj.ignoreControls = ScriptControlled.CONTROL_ZERO; 4340 obj.ignoreControls = ScriptControlled.CONTROL_ZERO;
4138 obj.eventControls = ScriptControlled.CONTROL_ZERO; 4341 obj.eventControls = ScriptControlled.CONTROL_ZERO;
4139 4342
4343 obj.objectID = p.ParentGroup.UUID;
4140 obj.itemID = Script_item_UUID; 4344 obj.itemID = Script_item_UUID;
4141 if (pass_on == 0 && accept == 0) 4345 if (pass_on == 0 && accept == 0)
4142 { 4346 {
@@ -4185,6 +4389,21 @@ namespace OpenSim.Region.Framework.Scenes
4185 ControllingClient.SendTakeControls(int.MaxValue, false, false); 4389 ControllingClient.SendTakeControls(int.MaxValue, false, false);
4186 } 4390 }
4187 4391
4392 private void UnRegisterSeatControls(UUID obj)
4393 {
4394 List<UUID> takers = new List<UUID>();
4395
4396 foreach (ScriptControllers c in scriptedcontrols.Values)
4397 {
4398 if (c.objectID == obj)
4399 takers.Add(c.itemID);
4400 }
4401 foreach (UUID t in takers)
4402 {
4403 UnRegisterControlEventsToScript(0, t);
4404 }
4405 }
4406
4188 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) 4407 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID)
4189 { 4408 {
4190 ScriptControllers takecontrols; 4409 ScriptControllers takecontrols;
@@ -4514,6 +4733,12 @@ namespace OpenSim.Region.Framework.Scenes
4514 4733
4515 private void CheckAndAdjustLandingPoint(ref Vector3 pos) 4734 private void CheckAndAdjustLandingPoint(ref Vector3 pos)
4516 { 4735 {
4736 string reason;
4737
4738 // Honor bans
4739 if (!m_scene.TestLandRestrictions(UUID, out reason, ref pos.X, ref pos.Y))
4740 return;
4741
4517 SceneObjectGroup telehub = null; 4742 SceneObjectGroup telehub = null;
4518 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null) 4743 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null)
4519 { 4744 {
@@ -4553,11 +4778,119 @@ namespace OpenSim.Region.Framework.Scenes
4553 pos = land.LandData.UserLocation; 4778 pos = land.LandData.UserLocation;
4554 } 4779 }
4555 } 4780 }
4556 4781
4557 land.SendLandUpdateToClient(ControllingClient); 4782 land.SendLandUpdateToClient(ControllingClient);
4558 } 4783 }
4559 } 4784 }
4560 4785
4786 private DetectedObject CreateDetObject(SceneObjectPart obj)
4787 {
4788 DetectedObject detobj = new DetectedObject();
4789 detobj.keyUUID = obj.UUID;
4790 detobj.nameStr = obj.Name;
4791 detobj.ownerUUID = obj.OwnerID;
4792 detobj.posVector = obj.AbsolutePosition;
4793 detobj.rotQuat = obj.GetWorldRotation();
4794 detobj.velVector = obj.Velocity;
4795 detobj.colliderType = 0;
4796 detobj.groupUUID = obj.GroupID;
4797
4798 return detobj;
4799 }
4800
4801 private DetectedObject CreateDetObject(ScenePresence av)
4802 {
4803 DetectedObject detobj = new DetectedObject();
4804 detobj.keyUUID = av.UUID;
4805 detobj.nameStr = av.ControllingClient.Name;
4806 detobj.ownerUUID = av.UUID;
4807 detobj.posVector = av.AbsolutePosition;
4808 detobj.rotQuat = av.Rotation;
4809 detobj.velVector = av.Velocity;
4810 detobj.colliderType = 0;
4811 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
4812
4813 return detobj;
4814 }
4815
4816 private DetectedObject CreateDetObjectForGround()
4817 {
4818 DetectedObject detobj = new DetectedObject();
4819 detobj.keyUUID = UUID.Zero;
4820 detobj.nameStr = "";
4821 detobj.ownerUUID = UUID.Zero;
4822 detobj.posVector = AbsolutePosition;
4823 detobj.rotQuat = Quaternion.Identity;
4824 detobj.velVector = Vector3.Zero;
4825 detobj.colliderType = 0;
4826 detobj.groupUUID = UUID.Zero;
4827
4828 return detobj;
4829 }
4830
4831 private ColliderArgs CreateColliderArgs(SceneObjectPart dest, List<uint> colliders)
4832 {
4833 ColliderArgs colliderArgs = new ColliderArgs();
4834 List<DetectedObject> colliding = new List<DetectedObject>();
4835 foreach (uint localId in colliders)
4836 {
4837 if (localId == 0)
4838 continue;
4839
4840 SceneObjectPart obj = m_scene.GetSceneObjectPart(localId);
4841 if (obj != null)
4842 {
4843 if (!dest.CollisionFilteredOut(obj.UUID, obj.Name))
4844 colliding.Add(CreateDetObject(obj));
4845 }
4846 else
4847 {
4848 ScenePresence av = m_scene.GetScenePresence(localId);
4849 if (av != null && (!av.IsChildAgent))
4850 {
4851 if (!dest.CollisionFilteredOut(av.UUID, av.Name))
4852 colliding.Add(CreateDetObject(av));
4853 }
4854 }
4855 }
4856
4857 colliderArgs.Colliders = colliding;
4858
4859 return colliderArgs;
4860 }
4861
4862 private delegate void ScriptCollidingNotification(uint localID, ColliderArgs message);
4863
4864 private void SendCollisionEvent(SceneObjectGroup dest, scriptEvents ev, List<uint> colliders, ScriptCollidingNotification notify)
4865 {
4866 ColliderArgs CollidingMessage;
4867
4868 if (colliders.Count > 0)
4869 {
4870 if ((dest.RootPart.ScriptEvents & ev) != 0)
4871 {
4872 CollidingMessage = CreateColliderArgs(dest.RootPart, colliders);
4873
4874 if (CollidingMessage.Colliders.Count > 0)
4875 notify(dest.RootPart.LocalId, CollidingMessage);
4876 }
4877 }
4878 }
4879
4880 private void SendLandCollisionEvent(SceneObjectGroup dest, scriptEvents ev, ScriptCollidingNotification notify)
4881 {
4882 if ((dest.RootPart.ScriptEvents & ev) != 0)
4883 {
4884 ColliderArgs LandCollidingMessage = new ColliderArgs();
4885 List<DetectedObject> colliding = new List<DetectedObject>();
4886
4887 colliding.Add(CreateDetObjectForGround());
4888 LandCollidingMessage.Colliders = colliding;
4889
4890 notify(dest.RootPart.LocalId, LandCollidingMessage);
4891 }
4892 }
4893
4561 private void TeleportFlagsDebug() { 4894 private void TeleportFlagsDebug() {
4562 4895
4563 // Some temporary debugging help to show all the TeleportFlags we have... 4896 // Some temporary debugging help to show all the TeleportFlags we have...
@@ -4582,6 +4915,5 @@ namespace OpenSim.Region.Framework.Scenes
4582 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************"); 4915 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************");
4583 4916
4584 } 4917 }
4585
4586 } 4918 }
4587} 4919}
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs
index acaeb90..0911f00 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs
@@ -111,15 +111,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests
111 111
112 SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart; 112 SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart;
113 113
114 // We need to preserve this here because phys actor is removed by the sit.
115 Vector3 spPhysActorSize = m_sp.PhysicsActor.Size;
114 m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero); 116 m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero);
115 117
116 // FIXME: This is different for live avatars - z position is adjusted. This is half the height of the
117 // default avatar.
118 // Curiously, Vector3.ToString() will not display the last two places of the float. For example,
119 // printing out npc.AbsolutePosition will give <0, 0, 0.8454993> not <0, 0, 0.845499337>
120 Assert.That( 118 Assert.That(
121 m_sp.AbsolutePosition, 119 m_sp.AbsolutePosition,
122 Is.EqualTo(part.AbsolutePosition + new Vector3(0, 0, 0.845499337f))); 120 Is.EqualTo(part.AbsolutePosition + new Vector3(0, 0, spPhysActorSize.Z / 2)));
123 121
124 m_sp.StandUp(); 122 m_sp.StandUp();
125 123
@@ -147,9 +145,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests
147 145
148 Assert.That(part.SitTargetAvatar, Is.EqualTo(m_sp.UUID)); 146 Assert.That(part.SitTargetAvatar, Is.EqualTo(m_sp.UUID));
149 Assert.That(m_sp.ParentID, Is.EqualTo(part.LocalId)); 147 Assert.That(m_sp.ParentID, Is.EqualTo(part.LocalId));
150 Assert.That( 148// Assert.That(
151 m_sp.AbsolutePosition, 149// m_sp.AbsolutePosition,
152 Is.EqualTo(part.AbsolutePosition + part.SitTargetPosition + ScenePresence.SIT_TARGET_ADJUSTMENT)); 150// Is.EqualTo(part.AbsolutePosition + part.SitTargetPosition + ScenePresence.SIT_TARGET_ADJUSTMENT));
153 Assert.That(m_sp.PhysicsActor, Is.Null); 151 Assert.That(m_sp.PhysicsActor, Is.Null);
154 152
155 Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(1)); 153 Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(1));